Repository navigation
v0.2.0
v0.2.0
新增
- 可视化设置面板。 插件在 DSH 设置里有了一张自己的卡片,32 项可直接改(开关与枚举,外加一个数字输入),9 项只读展示在折叠的「高级」区,另有 2 项只能改文件。面板没有自己的存储:保存写进当前 profile 的
cordis.patch.yml并提交进运行中的配置,不需要重启。保存成功会在底部给一行提示——官方表单只报失败不报成功,而这张表单有 32 个字段。 - 四类安全守卫补齐。 v0.1.0 只有 git 守卫,其余三类此前只是写在文档里的承诺。现在都有了:命令守卫(
rm -rf /、mkfs、dd指向块设备、fork 炸弹、chmod -R 777 /)、敏感文件守卫(.env、*.pem、*.key、*.p12、.npmrc、secrets/等,命中即拒,理由里只说文件名与规则、从不打开文件)、密钥守卫(AWS / GitHub / Slack token 与私钥头,只报模式名,绝不回显匹配到的值)、审计记录(脱敏后逐行写入.dev-docs/audit-log.jsonl)。 - 第五道守卫
outward-guard:拦下「本机没事、但别人立刻看得见」的动作。 此前四道守卫守的都是「东西会丢」,而 agent 抢在用户点头之前把分支推上去、把标签打上、把 PR 开出来、把版本发出去——本机一样东西都没丢,用户却已经被对外宣称同意了。四个策略键默认全为ask(不是deny:这是唯一一道本机不会造成任何损失的守卫,要的是同意而不是禁止)。 - PR 触发器与发版触发器。 三个约定触发器齐备:
gh pr create校验 PR 标题(直接复用提交信息检查——squash merge 后标题就是 main 上的提交信息)、描述的三段与未勾选的清单项;git tag/npm publish/pnpm publish校验 SemVer、tag 与package.json版本是否一致、预发布是否被推到latest、CHANGELOG 是否有[Unreleased]段与合法分类。 gitGuard.rememberApproved:记住一次批准,同一操作本会话不再询问。 DSH 的审批是一次性的,守卫把ask交出去后看不到答案,所以开启后守卫自己发起审批、自己读结果:批准则放行并记进会话,拒绝 / 取消 / 无审批服务一律拒绝。按会话隔离,插件重新加载即清空,不落盘。- 配置面补齐并全部标记为可变:新增九个字段,包括
commitCheck.onFailure(block/warn)、commitCheck.requireScope、docsCheck.requireReadmeOnConfig、docs.exclude。 docs/ADR/从两份扩到五份,补上此前只在代码注释里存在的推理过程。
修复
git push --force-with-lease会短路掉强推判定:只要参数里有它就整表提前返回,于是git push --force --force-with-lease放行,而 plain--force压过 lease 并真的覆盖远端。现在只有不带--force/-f/+refspec时 lease 才免检。- 透明前缀使守卫看不见真实命令:
sudo git push --force、nohup rm -rf /、npx npm publish一律漏过。现在五道守卫共用一处修复。 ${HOME}永远匹配不上:rm -rf ${HOME}被拆成无从判断的碎片。现在${VAR}保留为一个词,rm -rf $HOME/、rm -rf ~/与rm -rf /一样命中。npm publish --dry-run会被当成一次发布。现在对--dry-run/-n短路。- PR 检查表把模板之外的复选框也算进去:作者自加的
## Remaining work段会被误判。现在只在模板要求的段落之内数。 .env.example被当成机密:示例文件按惯例不含真实凭据,且是仓库里最需要被读的文件之一。现在example/sample/template/dist/defaults五个变体放行。git push --delete只是文档里的承诺:删远端分支既不问也不入审计。现在归gitGuard.branchDelete管,与本地git branch -D同一份损失、同一个策略键。
升级
dsh plugin --profile <profile> add @melosic/dsh-dev-workflow@0.2.0这是 0.x 阶段的一次 MINOR 升级,可能包含破坏性变更。 对已装用户的实际影响:新增的三道守卫默认 enabled: true,因此 .env 之类的敏感文件读取从此会被拒绝;如果不希望如此,在面板或配置文件里关掉对应守卫。
已知问题
minimumReleaseAge:应用内插件管理器走 pnpm 11,其默认值为 1440 分钟,所以新版本发布不到 24 小时时,不带版本号的安装会静默回退到上一版。指名版本安装可绕过。详见docs/PUBLISHING.md。
v0.2.0
Added
- A visual settings panel. The plugin now has its own card in DSH settings: 32 fields are editable there (switches and enums, plus one number input), 9 are read-only in a collapsed Advanced section, and 2 can only be changed in the file. The panel has no storage of its own — saving writes to the current profile's
cordis.patch.ymland commits it into the running configuration, no restart needed. A successful save shows a line at the bottom, because the official form reports failures only and this one has 32 fields. - Three more guards. v0.1.0 had only the git guard; the other three were promises in the docs. Now they exist: a command guard (
rm -rf /,mkfs,ddinto a block device, fork bombs,chmod -R 777 /), a sensitive-file guard (.env,*.pem,*.key,*.p12,.npmrc,secrets/— a deny that names the file and the rule and never opens the file), a secret guard (AWS / GitHub / Slack tokens and private-key headers, reporting only the pattern name and never the matched value), and an audit log (redacted, one JSON object per line in.dev-docs/audit-log.jsonl). - A fifth guard,
outward-guard, for actions that cost nothing locally but are visible to everyone immediately. The other four guard things that would be lost; this one covers the agent pushing a branch, creating a tag, opening a pull request, or publishing a version before the user has agreed — nothing local is lost, but the user has been spoken for. All four tiers default toaskrather thandeny, because this is the one guard that cannot damage the machine; it wants agreement, not prohibition. - Pull-request and release triggers.
gh pr createchecks the PR title (reusing the commit-message check, because a squash merge makes the title the commit message on main), the description sections, and unticked boxes;git tag,npm publish, andpnpm publishcheck SemVer, tag/manifest agreement, a prerelease going tolatest, and the presence and categories of the[Unreleased]section. gitGuard.rememberApprovedremembers one approval for the rest of the session. DSH approvals are one-shot and a guard cannot see the answer after handingaskover, so with this on the guard raises the approval itself and reads the result: allowed-once passes and is remembered; rejected, cancelled, or no approval service all deny. Per session, cleared on reload, never persisted.- Nine new configuration fields, including
commitCheck.onFailure(block/warn),commitCheck.requireScope,docsCheck.requireReadmeOnConfig, anddocs.exclude. docs/ADR/grew from two records to five.
Fixed
git push --force-with-leaseshort-circuited the force-push check: its mere presence returned early, sogit push --force --force-with-leasepassed while the plain--forceoverrode the lease and really did overwrite the remote. The lease form is now exempt only when no--force/-f/+refspecis present.- Transparent prefixes hid the real command:
sudo git push --force,nohup rm -rf /,npx npm publishall slipped through. All five guards now share one fix. ${HOME}never matched:rm -rf ${HOME}was split into unusable fragments.${VAR}now stays one word, andrm -rf $HOME/andrm -rf ~/match likerm -rf /.npm publish --dry-runwas reported as a real release.- The PR checklist counted boxes outside the template, so an author's own
## Remaining worksection was misjudged. It now counts only inside the required sections. .env.examplewas treated as a secret; theexample/sample/template/dist/defaultsvariants are now allowed.git push --deletewas only a promise in the docs: deleting a remote branch neither asked nor audited. It now belongs togitGuard.branchDelete— the same loss and the same policy key as a localgit branch -D.
Upgrade
dsh plugin --profile <profile> add @melosic/dsh-dev-workflow@0.2.0This is a MINOR bump during 0.x, so it may contain breaking changes. The practical effect on an existing install: the three new guards default to enabled: true, so reading something like .env is now denied. Turn the relevant guard off in the panel or the config file if you do not want that.
Known issues
minimumReleaseAge: the in-app plugin manager runs pnpm 11, whose default is 1440 minutes, so an install without an explicit version silently falls back to the previous release for the first 24 hours after a publish. Naming the version works around it; seedocs/PUBLISHING.md.
Full Changelog: v0.1.0...v0.2.0