Back to home

LittleFishStars

dsh-init-command

DSH plugin: /init slash command that generates an AGENTS.md guide for the current project with a two-stage model call

Stars
0
Language
JavaScript
Created
Aug 15, 2026
Updated
Aug 15, 2026

Introduction

dsh-init-command

License: MIT

一个 DeepSeek Harness (DSH) 插件:添加 /init 斜杠命令,用大模型为当前项目生成 AGENTS.md

/init 两阶段调用大模型:

  1. 项目分析:收集项目两层目录结构,连同提示词发送给模型,让其判断项目类型与工具链(语言、框架、构建工具等),输出结构化 JSON。
  2. 生成 AGENTS.md:把判断结果与目录结构嵌入提示词(参考 opencode 的 /init 及其 fork kimi-cli),生成并写入 AGENTS.md——要求模型按实际项目内容编写(Project overview、Build and test commands、Code style guidelines、Testing instructions、Security considerations、AI agent guidelines 等小节,并使用项目自身注释/文档的主要语言)。其中 AI agent guidelines 小节强制包含一条规则:每次完成任务后修正 AGENTS.md,让文件随项目演进保持准确。

功能

  • 两阶段 LLM 生成:先判断、后生成,判断结果作为上下文嵌入生成提示词,避免模型凭空猜测
  • 阶段二显示思考过程、隐藏最终输出:生成阶段默认只转发模型的 reasoning 流块(思考过程实时可见),AGENTS.md 正文直接写入文件、不进入会话;--dry-run 时完整流式预览
  • 阶段一默认不思考:分类任务简单,默认以 reasoningEffort: 'off' 关闭思考模式(仅当路由模型支持时才传参),更快更省 token;需要思考时加 --think
  • 两层目录结构:自动收集项目根目录及每个子目录的条目(过滤 .gitnode_modules 等噪音,超限自动折叠),作为模型判断的依据;--depth 可调深度(-1 不限制),--ignore 可额外跳过指定条目
  • 空目录询问:目录为空时(项目还未制作)不盲目生成,而是询问用户项目内容;用 --desc "<项目描述>" 提供描述后,生成一份注明"尚未制作"的规划稿
  • 已存在直接替换AGENTS.md 已存在时直接覆盖,旧内容提供给模型作为改写参考
  • --git 初始化仓库:仓库不存在时 git init、默认分支 mastermain、按项目类型从 github/gitignore 下载 .gitignore(已存在不覆盖;无匹配模板时跳过并说明)
  • --commit 初始提交:生成后创建初始 git 提交(隐式启用 --git
  • 模型路由自动回退:插件配置 → 会话最近一次请求 → agent 选项
  • 零依赖、无需构建:仅使用 Node 内置模块,可从源码、--patch 覆盖层或 npm/git 安装加载;命令注册是 Cordis effect,插件卸载时自动注销

安装

方式一:作为 bundle 安装(推荐)

在包含本插件目录的路径下执行:

dsh plugin --profile <profile-name> add ./dsh-init-command

DSH 会把插件作为 bundle 装入 profile(dsh.profile.bundles),插件行由包内的 cordis.patch.yml 提供。验证并启动:

dsh --profile <profile-name> --dump-config   # 应出现 "# == dsh-init-command" 层
dsh --profile <profile-name>

也可以先 pnpm pack 生成 tarball 后 dsh plugin --profile <name> add ./dsh-init-command-0.1.0.tgz,或发布到 npm 后按包名安装。

方式二:本地 patch 加载

从 DSH 源码仓库运行时,可直接用 --patch 挂载本插件的源码(路径需为绝对路径):

pnpm dsh web --patch /path/to/dsh-init-command/cordis.patch.yml

如果直接引用插件文件而非 bundle 包名,把 cordis.patch.yml 中的 name: dsh-init-command 改成插件文件的绝对路径(如 /path/to/dsh-init-command/index.js)。

配置

/init 需要可用的模型路由,按以下优先级解析(满足其一即可):

  1. 插件行的 config(推荐,最明确):

    # cordis.patch.yml 或 profile 的 patch 层
    - insert:
        - id: init
          name: dsh-init-command
          config:
            provider: deepseek
            model: deepseek-chat
    
  2. 会话最近一次请求使用的 provider/model(session.requestHeader().config

  3. agent 选项(agent.options.provider / agent.options.model

三者都不可用时,/init 返回明确错误,不会调用模型。

使用

在 DSH Web UI 或任意命令适配器的输入框中输入:

命令行为
/init两阶段调用模型,在工作区根目录生成或替换 AGENTS.md(已存在时直接覆盖,旧内容作为改写参考);阶段二默认显示思考过程、正文直接写入文件,会话中追加完成信息与成功状态消息;阶段一默认关闭思考模式
/init --dry-run调用模型生成内容但不写文件,两阶段完整流式预览
/init --think阶段一(项目分析)改用模型的思考模式;默认不思考(更快更省 token)
/init --git生成 AGENTS.md 后额外执行 git 初始化:仓库不存在时 git init、默认分支 mastermain、按项目类型从 github/gitignore 下载 .gitignore(已存在时不覆盖)
/init --commit生成 AGENTS.md 后创建初始 git 提交(隐式启用 --git);未配置 git 身份时只提示、不失败
/init --depth <n>目录树收集深度:1 仅顶层、2 两层(默认)、-1 不限制
/init --ignore <pattern>额外跳过名字匹配的条目(可重复使用或用逗号分隔多个)
/init --desc <text>目录为空时描述项目内容(放在最后,可含空格);生成注明"此项目还未制作"的规划稿
/init --help显示用法与全部参数说明(-h 亦可)
/init --git --dry-run组合使用:只提示将做什么(初始化仓库、下载哪个模板),不执行任何写入

目录为空/init 不会盲目生成,而是询问项目内容(注明此项目还未制作)。可用 /init --desc "<项目描述>" 提供描述后生成规划稿,或先创建项目文件再运行。

示例输出(--git):

Initialized /home/user/project/AGENTS.md (Node.js web application). Review the generated AGENTS.md and adjust it to your conventions.

Git: initialized a new git repository; renamed the default branch master → main; downloaded .gitignore from github/gitignore (Node)

Model calls:
1. classify — deepseek/deepseek-chat — prompt: 14 lines (You are a senior software engineer analyzing a repo...) — result: Node.js web application [JavaScript] [npm]
2. generate — deepseek/deepseek-chat — prompt: 26 lines (You are a software engineering expert...) — result: AGENTS.md (1234 chars)

生成的文件是模型的初稿:命令、目录结构等信息均来自两层目录结构,请审阅后按项目实际约定调整。

会话可见性

  • 阶段一(项目分析)完整显示:提示词以插件注入的 notice 上下文进入对话流(GUI 渲染为可折叠行:默认收起显示一行摘要、点击展开全文),发送给模型的也正是这段文本;模型的每个流块(正文与 reasoning)实时转发为 assistant/chunk 事件,GUI 按帧渲染,效果与思考过程一致
  • 阶段二(生成)只显示思考过程:阶段二提示词同样为可折叠 notice 行;reasoning 流块实时转发可见,text 流块被过滤、不追加最终 assistant/message——AGENTS.md 正文不进入会话、直接写入文件;成功后追加完成信息(notice 折叠行:路径、字符数)与一条形如模型输出的成功状态消息;--dry-run 时与阶段一一样完整显示
  • 全程可追溯:提示词、流块、token 用量、完成信息、成功状态均为标准会话事件,随会话持久化、重启后安全加载;两次调用记录(阶段、路由、提示词摘要、结果)随命令结果(command/done)写入对话历史。事件类型全部位于会话恢复白名单 KNOWN_SESSION_EVENT_TYPES 内——直接 session.append() 自定义事件类型会被恢复路径拒绝加载
  • 实现细节:合成显示只写 step 层事件、不写 turn/start/turn/end——正数 turn 会与 agent 循环的编号冲突,turn 0 的 turn/end 又会被会话持久化读取路径拒绝(turn < 1 视为 malformed pre-react-loop);固定 turn 0 + 递增 step 两全,多次 /init 互不冲突

目录结构

dsh-init-command/
├── package.json            # npm 清单,声明 dsh.bundle(patch 层)
├── cordis.patch.yml        # 插入插件行的 patch 层
├── index.js                # 插件入口:注册 /init,再导出公共 API
├── lib/
│   ├── tree.js             # 两层目录树收集与文件存在性检查
│   ├── prompts.js          # 两阶段提示词、分类解析、调用记录格式化
│   ├── model.js            # LLM 流式调用与会话可见性(组装器、路由、step 显示)
│   ├── gitignore.js        # .gitignore 模板匹配与下载(node:https + 系统 CA 回退)
│   ├── git.js              # --git 步骤(仓库初始化、master → main、落盘)
│   └── init.js             # /init 主流程(两阶段调用、写入 AGENTS.md)
├── scripts/
│   └── smoke-loader.mjs    # 真实 Loader 组合冒烟测试(需要 DSH 源码环境)
├── test/
│   └── init.test.js        # 单元测试(node:test,零依赖,mock LLM 服务)
└── README.md

开发与测试

单元测试(无需 DSH 仓库,LLM 服务为 mock):

npm test

冒烟测试(在已构建 lib/ 产物的 DSH 源码检出上运行,验证插件在真实 Cordis Loader 组合中工作;LLM 服务为 Service 子类 fake,agent/session/commands 均为真实实现):

mkdir -p node_modules && ln -s <harness>/packages/feedback/command-feedback/node_modules node_modules
node scripts/smoke-loader.mjs
rm node_modules   # 该符号链接仅用于测试,不属于发布内容

AI 声明

  • 本项目(代码与文档,含本 README)在开发过程中使用了 AI 辅助编程工具(如 DeepSeek Harness)协助编写,并经过人工审阅与调整。
  • 本插件通过 /init 生成的所有 AGENTS.md 内容均为大模型输出(模型初稿):其中命令、目录结构等信息来自项目实际的两层目录结构,请在审阅后按项目实际约定调整再使用。

许可证

MIT,见 LICENSE