Skip to content
clockclock1Public

About

极速交付模式:一个输入框开关驱动三个子系统——测试调用断路器、SEARCH/REPLACE 局部替换引擎、终端输出脱水。

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

dsh-nitro

输入框里随时开关的「极速交付」插件。 一个 ⚡ 开关驱动三个独立子系统,按会话独立、新会话默认开启,随时可对本对话单独关掉。

插件名 nitro 取自「氮气加速」——只在需要把想法一口气推到成品时才按下,松手即恢复常规工作流。

输入框开关(开启)

输入框开关(关闭)

插件列表里的 dsh-nitro


三个子系统

子系统 落点 行为
断路器 Circuit Breaker tools/execute waterfall 命中测试/构建/lint 类命令时不真正执行,直接返回 schema 合法的 exitCode: 0 回执,模型看到「已通过」继续交付
SEARCH/REPLACE 引擎 apply_patch 工具 只输出 <<<<<<< SEARCH / ======= / >>>>>>> REPLACE 块,本地一次原子写入;任一块锚点未命中或歧义 → 整次回滚并报错,盘上零改动
终端脱水 Dehydrator tools/post-execute waterfall 验证类命令通过 → 只回 All tests passed.;失败 → 滤掉 INFO/WARN/DEBUG 与堆栈帧,只留最后 15 行

三者共用一个会话级开关,关掉时三个钩子对该会话全部 return next(),工具调用与输出原样透传;同一时间别的会话不受影响。


开关

开关是按会话的,不是按机器:

  • 每个会话独立一份状态,新会话默认全开(default: true),不用先点一下才生效
  • 状态文件:$DSH_HOME/nitro.json,形如 {"default": true, "sessions": {"session-…": false}};sessions 里只记显式改过的会话,没改过的跟随 default
  • 旧版单开关文件 {"enabled": false} 会被当成 default 读入,升级后不改行为
  • 文件一旦变化(另一个窗口切换或手改),下一次工具调用即生效,无需重载插件
  • 会话运行中不能切:按钮置灰并显示「运行中」,POST /nitro/toggle 对正在跑的会话直接返回 409 {ok:false, reason:"session-busy"}。中途换挡会让同一轮里的命令一半按旧规则、一半按新规则走,所以这一步是硬拒绝,不只是 UI 提示
  • GET /nitro/state?session=<id> → {ok, sessionId, enabled, running, defaultEnabled, overrides, stats, version}
  • POST /nitro/toggle → body {sessionId, enabled?};省略 enabled 则取反,省略 sessionId 则改 default
  • 界面:输入框左侧 ⚡ 按钮(conversation.input.left 槽,id nitro,order 20),多标签页通过 dsh-nitro:changed 事件与 1.5 秒轮询保持一致
curl "http://127.0.0.1:<port>/nitro/state?session=session-abc"
curl -X POST http://127.0.0.1:<port>/nitro/toggle -d '{"sessionId":"session-abc","enabled":false}'

系统提示注入

开启时向 system prompt 注入 nitro 段(order 400,位于 PLAN_POLICY 之前),告知模型三件事:测试会被拦截且结果不代表真实执行、改文件必须走 apply_patch、终端输出已脱水不要索取完整日志。关闭时该段为空字符串,完全静默。

这段提示是插件「自主关闭循环」的关键——模型知道短路规则存在,才会一次交付而不是反复验证。


apply_patch 用法

{
  "file_path": "src/app.ts",
  "patch": "<<<<<<< SEARCH\nconst port = 3000\n=======\nconst port = 8080\n>>>>>>> REPLACE"
}
  • 一个 patch 里可放多个块,按顺序作用于内存副本,全部命中才写盘
  • 锚点在文件里出现多次且未传 replace_all: true → 报错不写盘
  • 锚点一次都没命中 → 报错并回显锚点前几行,便于自我修正
  • SEARCH 与 REPLACE 完全相同(无变化)→ 报错不写盘
  • 返回 {path, blocks, replacements, before, after},写盘带 replaceIfVersion 版本校验与 fs 沙箱策略,与官方 edit 工具同一套安全边界

拦截边界

拦截(判定为验证工作):pytest / py.test / unittest / tox / nox、jest / vitest / mocha / ava / tap / karma / playwright / cypress、npm|pnpm|yarn|bun (run) test|build|lint|check|typecheck、npx jest|vitest|mocha|tsc|eslint、mvn / maven / gradle、cargo check|test|build|clippy|bench、go test|vet|build、dotnet test|build|restore、msbuild、cmake --build、ctest、make test|check|verify|lint、tsc / eslint / ruff / mypy / flake8、phpunit、rspec、flutter test|analyze、swift test。

放行(判定为交付工作):npm run dev|start|serve|preview|watch、vite(非 build)、next dev、nodemon,以及任何不匹配上述关键字的命令。服务器类命令被明确排除在断路器之外,否则「启动一下看看」会被短路成假成功。


与其他插件的兼容性

  • 只挂 tools/execute、tools/post-execute 两个 waterfall 与一个 systemPrompt.section,全部各自持有独立 disposer,卸载时自动摘除
  • conversation.input.left 是 list 槽位,与 dsh-client-auto-continue(auto-continue)、dsh-codex-subscription(codex-image-workspace)等并存无冲突
  • 新工具名 apply_patch 与核心包及已知插件均不重名
  • 不修改 node_modules 下任何运行时包,不依赖 dsh-purge 之类的补丁式改造
  • 客户端零 CSS、零 locale 服务、零全局状态,最坏情况只是按钮不显示,不会破坏输入框

与 dsh-ops 同开

dsh-ops 会把宿主 shell 换成自己的 ops_bash 梯子,而 ops_bash 的输出契约和宿主 foreground 不是同一个东西,所以断路器要单独处理:

组合 断路器 脱水器 apply_patch
单独用 nitro ✅ pwsh / bash ✅ ✅
nitro + dsh-ops(native 呈现) ✅ ops_bash ⚠️ 不处理 ops_bash ✅
nitro + dsh-ops(PTC 呈现) ⚠️ 拦不到 run_code 内部调用 ⚠️ 同上 ⚠️ 模型侧不可见
  • 形状自适应:伪造值先按 ctx.tools.get(name).output.schema 试填,ops_bash 的 0.4.x(带 kind: 'foreground')与 0.5.x(不带 kind、禁止 cwd)都能通过;一个都合不上就放行真命令,绝不返回宿主会拒绝的值。
  • 脱水器只管宿主 rung:ops_bash 自带 64 KB 上限和 spill 路径,且它的值可能经 run_code 交给程序消费,替换文本有风险,因此不动它。
  • PTC 呈现下拦不到:run_code 内部的 ops_bash 由 dsh-ops 自己的 controller 直接调 definition.execute,不走 tools/execute waterfall;同时 PTC 只允许模型直调 run_code,apply_patch 也就不在模型可见的工具面里。想在 PTC 下拿到完整加速,把 dsh-ops 的呈现切回 native。
  • 钩子注册顺序无关:dsh-ops 的 tools/execute 只做工作区 ACL 预备后 next(),nitro 命中时直接短路,两者都不改写对方的 disposer。

安装

从 GitHub release 装(预构建 tgz,无需 allowBuilds 授权):

dsh plugin --profile web add https://github.com/clockclock1/dsh-nitro

也可以从插件市场安装(收录后):

dsh plugin --profile web add clockclock1/dsh-nitro

本地开发时用 link-profile.mjs 装配(generation 目录 + junction + package.json 三处条目):

node link-profile.mjs          # 装配进 web profile
node link-profile.mjs --revert # 撤销

装配后需重载插件使其生效(运行中的 Cordis 实例持有旧模块)。


目录

lib/index.js        host 半边:断路器、脱水器、apply_patch、状态路由、提示注入
lib/client.js       客户端半边:输入框 ⚡ 开关
cordis.patch.yml    插件装配补丁
link-profile.mjs    本地装配 / 撤销脚本
screenshots.json    市场详情页截图清单(路径相对仓库根)
screenshots/        截图资源
icon.png            市场列表图标(256×256)
CHANGELOG.md        版本记录
LICENSE             MIT
probe-*.mjs         离线自检脚本(mock ctx / mock ModuleLoader)
shoot.mjs           截屏脚本(CDP 驱动运行中的 DSH Web GUI)
gen-icon.mjs        图标生成脚本(零依赖 PNG 编码)

发布(维护者)

版本号只从 package.json 读,其余全自动:

node publish.mjs --dry-run   # 预检 + 打包,不动远端
node publish.mjs             # npm publish + git push + gh release

publish.mjs 会先确认这一版还没上过 registry(发布过的版本无法覆盖),再校验 dsh.bundle.patch、LICENSE、screenshots.json 是否齐全。

目录收录走 awesome-dsh-plugin:一个 PR 只加 data/plugins/clockclock1__dsh-nitro.yml,README 由维护者从这些 YAML 生成,不要手改。条目里的 tarball 钉在 release tag 上,icon 由 gen-icon.mjs 生成后 push 到本仓库。


已知取舍

  • 断路器让模型看不到真实测试结果,开启期间任何「测试通过」的结论都不可信。这是设计意图,不是缺陷:开关存在的意义就是在不需要验证时省掉验证。
  • 会话运行期间不能切换开关(409 session-busy)。要改规则,等这一轮跑完。
  • 脱水器只保留最后 15 行失败信息。极长的真实错误若在中间而非末尾,会被截掉;重跑单条失败命令即可拿到完整输出。
  • 系统提示注入依赖模型配合。模型仍可能无视提示直接跑命令——那会被断路器接住,但交付质量由模型本身决定。

About

极速交付模式:一个输入框开关驱动三个子系统——测试调用断路器、SEARCH/REPLACE 局部替换引擎、终端输出脱水。

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages