dsh-init-command
一个 DeepSeek Harness (DSH) 插件:添加 /init 斜杠命令,用大模型为当前项目生成 AGENTS.md。
/init 两阶段调用大模型:
- 项目分析:收集项目两层目录结构,连同提示词发送给模型,让其判断项目类型与工具链(语言、框架、构建工具等),输出结构化 JSON。
- 生成 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 - 两层目录结构:自动收集项目根目录及每个子目录的条目(过滤
.git、node_modules等噪音,超限自动折叠),作为模型判断的依据;--depth可调深度(-1不限制),--ignore可额外跳过指定条目 - 空目录询问:目录为空时(项目还未制作)不盲目生成,而是询问用户项目内容;用
--desc "<项目描述>"提供描述后,生成一份注明"尚未制作"的规划稿 - 已存在直接替换:
AGENTS.md已存在时直接覆盖,旧内容提供给模型作为改写参考 --git初始化仓库:仓库不存在时git init、默认分支master→main、按项目类型从 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 需要可用的模型路由,按以下优先级解析(满足其一即可):
插件行的
config(推荐,最明确):# cordis.patch.yml 或 profile 的 patch 层 - insert: - id: init name: dsh-init-command config: provider: deepseek model: deepseek-chat会话最近一次请求使用的 provider/model(
session.requestHeader().config)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、默认分支 master → main、按项目类型从 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。
No comments yet. Be the first to write one.