@rowansenne/workflow-run 0.21.1 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/README.md +68 -11
- package/bin/lib/docsrepo.mjs +52 -18
- package/bin/lib/doctor.mjs +4 -1
- package/bin/lib/install.mjs +21 -4
- package/bin/workflow-run.mjs +7 -2
- package/create-release-md-doc/SKILL.md.tpl +1 -1
- package/create-tech-md-doc/SKILL.md.tpl +1 -1
- package/dev/SKILL.md.tpl +20 -14
- package/dev/references/delivery-template.md +8 -3
- package/dev/skill.json +2 -2
- package/md-to-wiki/SKILL.md.tpl +1 -1
- package/package.json +1 -1
- package/project-review/SKILL.md.tpl +3 -2
- package/workflow/SKILL.md.tpl +2 -2
- package/workflow/references/feedback.md +34 -0
- package/workflow/references/profile.md +1 -1
- package/workflow/references/requirements.md +11 -9
- package/workflow/scripts/artifacts.mjs +6 -5
- package/workflow/scripts/feedback.mjs +189 -0
- package/workflow/scripts/requirement.mjs +79 -19
- package/workflow/scripts/resolve.mjs +4 -3
- package/workflow/scripts/view.mjs +5 -4
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,39 @@
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.22.0] - 2026-10-19
|
|
8
|
+
|
|
9
|
+
### 新增
|
|
10
|
+
- 运行反馈:dev 和 project-review 每跑完一次,用新脚本 `workflow/scripts/feedback.mjs add` 静默追加一行过程记录到 `workflow-run/feedback/<git 用户名>.jsonl`(模型、规模 / 深度、快速通道、提问轮数、用户纠正理解的次数、验收项验证情况、跳过的步骤、不清楚或做不到的规则、用户的抱怨),不记代码和业务名词,不额外问用户。每人一个文件,随 `workflow-run/` 提交;安装器在 `.gitattributes` 加 `workflow-run/feedback/*.jsonl merge=union`(独立文档仓库模式加在文档仓库里),多个分支都有记录时合并不冲突。新命令 `npx @rowansenne/workflow-run feedback [--json]` 汇总,跳过的步骤和不清楚的规则按 SKILL.md 章节归类,作为精简 skill 的依据。`init` / `upgrade` 装了新版本时清掉本项目旧版本的记录,从新版本重新收集。字段与规则见 `workflow/references/feedback.md`。dev 内部调用 project-review 自审时只由 dev 记一行。
|
|
11
|
+
|
|
12
|
+
### 变更(破坏性)
|
|
13
|
+
- 随代码提交和独立文档仓库两种用法的目录结构统一为 `workflow-run/docs/requirements/<需求名>/<项目名>/`(归档的上一版同样在 `tmp/old-artifacts/<需求名>/<项目名>/`)。随代码提交时项目名不用配置,取 git 远端仓库名(没有远端用目录名),第一次 `bind` 时写进 `workflow/profile.json` 的 `artifacts.project`。
|
|
14
|
+
- 旧结构自动迁移:`init` / `upgrade` 把 `<需求名>/` 下直接放的文件挪到 `<需求名>/<项目名>/`(被 git 跟踪的用 `git mv`),结尾列出迁移的需求,改动由你提交;目标里已有同名文件的需求不动并提示。`doctor` 提示还没迁移的需求。
|
|
15
|
+
- `docs-repo` 支持原地切换:`workflow-run/` 里已有产物、DocNexus 时不再停下,而是原地 `git init` 并接上远端。远端是空仓库时本地内容就是第一批内容;远端已有内容时检出远端,本地和远端同路径冲突就退回原状并列出冲突的文件。
|
|
16
|
+
|
|
17
|
+
### 变更
|
|
18
|
+
- `--with-docnexus` 不再往项目的 `.gitignore` 追加 `node_modules/`:DocNexus 的依赖和检索库由它自带的 `docnexus/.gitignore` 忽略,随代码提交和独立文档仓库两种模式都适用。已追加过的这一行保留不动。
|
|
19
|
+
- `dev` 的 `project-review` 从 optional 改为 requires:`--skills dev` 会一起装上 `project-review`,已按子集装了 `dev` 的项目 `upgrade` 时自动补上。dev 自审必做,且要经 `resolve.mjs template project-review checklist.md` 取审查清单;之前没装 project-review 时这条命令报错,dev 写的「按清单手动自审」降级走不通。
|
|
20
|
+
- dev 自审调用 project-review 时只走第 1~6 步,跳过落盘审查报告和 DocNexus 询问,问题表、影响面、未覆盖项交回 dev 在交付时统一给出(DocNexus 只在 dev 交付时问一次);两边的 SKILL.md 都写明了这条边界。
|
|
21
|
+
- dev 交付说明的「验证」节加「验收项 → 测试 / 操作 → 结果」对照表,每条验收标准写明靠什么验证,没法验证的标「未验证」和原因;新增「开工前已有的失败」一行。快速通道在对话里给同样的对应。
|
|
22
|
+
- dev 开工前先跑一次基线(构建 + 相关测试,不必全量),记下已有的失败,之后只对新增失败负责;构建从「每个可编译单元」改为一步改完再编译,测试改为先相关、最后全量一次。
|
|
23
|
+
- dev 开工时工作区有未提交改动或未跟踪文件,改为问用户哪些属于本需求:属于的(如先手写了一部分再让 dev 接着做)和 dev 的改动一样进影响面、测试、自审和交付说明;不属于的照常被测试跑到,但自审发现写进「范围外发现」、提交时不 add。之前只说「无关的告知用户」,没说怎么处理,用户手写的部分也可能被当成无关。自审补上本次新建的未跟踪文件。
|
|
24
|
+
- dev 规模判定加入权限和资金:涉及鉴权、数据可见范围、金额计算、扣款、退款、对账的改动,文件再少也至少按 M,需求理解和方案都要用户确认,也不走快速通道(功能开发和缺陷修复都适用)。M 规模的两次确认(F3 理解、F4 方案)保留,不合并。
|
|
25
|
+
|
|
26
|
+
### 修复
|
|
27
|
+
- `resolve.mjs template <skill> …` 在该 skill 没安装时提示「没有安装」并让重跑安装带上它,不再误报「没有登记模板」。
|
|
28
|
+
|
|
29
|
+
### 测试
|
|
30
|
+
- 新增检查:SKILL.md 里经 `resolve.mjs template <其他 skill>` 取模板的,必须把那个 skill 声明为 requires。
|
|
31
|
+
|
|
32
|
+
### 文档
|
|
33
|
+
- 新增图文教程 `docs/full-install.html`:带 DocNexus 与 CodeGraph 的全量安装、团队接入、独立文档仓库(原地切换、新服务接入、旧项目改用)、升级与卸载。
|
|
34
|
+
|
|
35
|
+
## [0.21.2] - 2026-10-19
|
|
36
|
+
|
|
37
|
+
### 文档
|
|
38
|
+
- README 新增「哪些文件提交、哪些忽略」:集中列出要提交的 skills 目录、软链接、项目画像、需求产物等,以及安装器追加的各条 `.gitignore` 规则、忽略的内容和追加时机,附 `git check-ignore` 检查命令。
|
|
39
|
+
|
|
7
40
|
## [0.21.1] - 2026-10-18
|
|
8
41
|
|
|
9
42
|
### 修复
|
package/README.md
CHANGED
|
@@ -25,6 +25,8 @@ npx @rowansenne/workflow-run
|
|
|
25
25
|
|
|
26
26
|
按提示:选择环境(编号多选,回车 = 全部)→ 确认 / 填写数据库连接 → 自动生成。装完后在 agent 里运行 `/workflow profile` 填写项目画像。
|
|
27
27
|
|
|
28
|
+
同时接入 DocNexus 与 CodeGraph 的全量安装,见图文教程 [docs/full-install.html](docs/full-install.html)(下载后用浏览器打开)。
|
|
29
|
+
|
|
28
30
|
非交互示例(bash、zsh、PowerShell 写法一样):
|
|
29
31
|
|
|
30
32
|
```
|
|
@@ -44,8 +46,9 @@ npx @rowansenne/workflow-run uninstall # 按
|
|
|
44
46
|
| `doctor` | 自检:已装版本与当前包对比、手改 / 缺失的文件、软链接是否断开、项目画像、DocNexus 模板是否齐全、各数据库连接能否只读 `SELECT 1`(`--offline` 跳过)、`.gitignore` 是否忽略了凭据。有错误时退出码 1 |
|
|
45
47
|
| `uninstall` | 等价于 `--uninstall` |
|
|
46
48
|
| `report` | 本地效果报告:只读统计 `workflow-run/docs/requirements/` 下的产物(`--since YYYY-MM-DD`、`--all-branches`、`--json`),见「workflow:入口与项目画像」 |
|
|
49
|
+
| `feedback` | 运行反馈汇总:dev / project-review 每次运行记录到 `workflow-run/feedback/<用户>.jsonl` 的过程数据(`--json`),见「运行反馈」 |
|
|
47
50
|
| `view` | 项目文档视图:按需求浏览开发方案、交付说明、审查记录(含复审修复情况)、技术 / 上线方案,生成本地静态页面(`--out <文件>`、`--open`) |
|
|
48
|
-
| `docs-repo <仓库地址>` |
|
|
51
|
+
| `docs-repo <仓库地址>` | 改用团队文档仓库:`workflow-run/` 是空的就克隆,已有内容就原地接上远端(目录结构相同,文件不用挪)、代码仓库忽略它、配置本项目的项目名(`--project`,默认 git 远端仓库名)、接上仓库里的 DocNexus;不带地址显示当前状态,见「产物输出规范」 |
|
|
49
52
|
| `seed-templates` | 只把默认文档模板导入 DocNexus,不重装 skills。`--update` 把导入后未改动的模板更新为新版;`--diff` 只读打印团队改过的模板与新默认模板的差异,供手动合并 |
|
|
50
53
|
|
|
51
54
|
```
|
|
@@ -129,6 +132,14 @@ npx @rowansenne/workflow-run docs-repo git@git.example.com:team/team-docs.git
|
|
|
129
132
|
* 知识:交付与审查的 DocNexus 沉淀率、正文引用了知识库文档的产物占比;
|
|
130
133
|
* 各分支链路:开发方案、交付说明、审查报告、技术方案、上线方案齐不齐,哪些文档还没发布到 wiki。
|
|
131
134
|
|
|
135
|
+
**运行反馈**(`npx @rowansenne/workflow-run feedback [--json]`):效果报告只看落盘的产物,看不到过程。dev 和 project-review 每跑完一次,用 `workflow/scripts/feedback.mjs add` 静默追加一行到 `workflow-run/feedback/<git 用户名>.jsonl`:模型、规模 / 深度、是否走快速通道、向用户提问几轮、用户纠正过几次理解、验收项验证了几条、跳过了哪些步骤、**哪条规则读不懂或做不到**、用户主动说的抱怨。只记过程,不记代码和业务名词;不额外问用户。每人一个文件,随 `workflow-run/` 提交,多人不冲突;安装器在 `.gitattributes` 里给这些文件配 `merge=union`,同一个人在几个分支上都有记录时合并也不冲突。用来定期精简 skill:
|
|
136
|
+
|
|
137
|
+
1. 团队照常用两三周;
|
|
138
|
+
2. 运行 `feedback` 汇总(或直接拿 `workflow-run/feedback/` 下的文件),按「常被跳过的步骤」「读不懂的规则」「提问太多」精简 SKILL.md,发新版本;
|
|
139
|
+
3. 各项目 `upgrade` 时清掉本项目旧版本的记录(git 历史里仍可找回),从新版本重新收集,回到第 1 步。
|
|
140
|
+
|
|
141
|
+
字段与记录规则见 `workflow/references/feedback.md`。
|
|
142
|
+
|
|
132
143
|
**PR / MR 描述**:`node <skills>/workflow/scripts/pr-desc.mjs [--branch b] [--base main] [--out 文件]` 把本分支的交付说明(做了什么、已确认的决定、改动、验证、配置 / SQL)、审查报告(结论、CRITICAL / HIGH、影响面)和相关文档路径汇总成描述;没有交付说明时退回用提交记录和改动文件列表。dev 交付后要提 PR 时会调用它;创建 PR 要你同意。
|
|
133
144
|
|
|
134
145
|
`workflow/profile.json` 是所有 skill 共用的项目事实,模板里不再写死任何公司或项目约定。缺失字段视为空,文档中对应位置写「待填写」。示例:
|
|
@@ -166,7 +177,7 @@ npx @rowansenne/workflow-run docs-repo git@git.example.com:team/team-docs.git
|
|
|
166
177
|
/dev --bug <现象 | 报错 | 日志> # 缺陷修复
|
|
167
178
|
```
|
|
168
179
|
|
|
169
|
-
* **功能开发**:理解需求(可读 PRD、查 DocNexus 历史决策)→ 调研现有代码 → 需求澄清(借鉴 grill-me:按决策树分轮提问,每题给推荐答案;事实自己查、决定交给用户;S 规模无未定决定时跳过)→ 按规模出方案(S 直接做;M 对话内方案待确认;L 落盘方案文档待确认)→ 小步实现并编译 → 补测试并运行 → 用 project-review 自审 → 交付说明落盘到 `workflow-run/docs/requirements
|
|
180
|
+
* **功能开发**:理解需求(可读 PRD、查 DocNexus 历史决策)→ 调研现有代码 → 需求澄清(借鉴 grill-me:按决策树分轮提问,每题给推荐答案;事实自己查、决定交给用户;S 规模无未定决定时跳过)→ 按规模出方案(S 直接做;M 对话内方案待确认;L 落盘方案文档待确认)→ 小步实现并编译 → 补测试并运行 → 用 project-review 自审 → 交付说明落盘到 `workflow-run/docs/requirements/<需求名>/<项目名>/delivery.md`(带分支元信息;改动、验证结果、配置清单、未执行的 SQL),已接入 DocNexus 时每次都问要不要沉淀(同意后以 `dev-notes` 分类写入,并把库内路径记回交付说明)。审查和上线方案会按分支自动读取这份交付说明。
|
|
170
181
|
* **S 规模快速通道**:S 规模且不涉及配置、SQL / DDL、对外接口、表结构,也没有需要澄清的决定时,编译、测试、自审照常,但只在对话里交付,不落盘交付说明、不问沉淀;实现中碰到上述任何一项或改动超过 3 个文件,就退回完整流程。缺陷修复同样适用(根因仍须在对话里写清楚)。
|
|
171
182
|
* **缺陷修复**:收集现象 → 用失败测试复现 → 用证据定位根因 → 最小修复让测试转绿 → 自审 → 交付(必须写明根因)。
|
|
172
183
|
* 守则:不写库、不改凭据、不擅自 commit / push、不装新依赖;测试没跑就写「未验证」。
|
|
@@ -198,8 +209,9 @@ npx @rowansenne/workflow-run docs-repo git@git.example.com:team/team-docs.git
|
|
|
198
209
|
|
|
199
210
|
1. 检查 Node >= 22.13 与 npm(不满足时**在安装任何文件之前**报错退出);
|
|
200
211
|
2. 在 `workflow-run/` 下执行 `npm install --prefix ./docnexus --save-exact @rowansenne/docnexus`:装在 `workflow-run/docnexus/` 下,npm 清单、锁文件和依赖不进宿主项目的 `package.json`;
|
|
201
|
-
3. 在 `workflow-run/` 下执行 `./docnexus/node_modules/.bin/docnexus init --agent none`:创建 `workflow-run/docnexus/` 工作区,把 DocNexus 的 skills 同步到 `workflow-run/docnexus/skills/`;再由本工具把它们软链接到所选环境的 skills 目录、写入 `CLAUDE.md` / `AGENTS.md` 的段落(见下方「DocNexus
|
|
202
|
-
|
|
212
|
+
3. 在 `workflow-run/` 下执行 `./docnexus/node_modules/.bin/docnexus init --agent none`:创建 `workflow-run/docnexus/` 工作区,把 DocNexus 的 skills 同步到 `workflow-run/docnexus/skills/`;再由本工具把它们软链接到所选环境的 skills 目录、写入 `CLAUDE.md` / `AGENTS.md` 的段落(见下方「DocNexus 的位置」)。
|
|
213
|
+
|
|
214
|
+
依赖和检索库(`node_modules/`、`store/`)由 DocNexus 自带的 `docnexus/.gitignore` 忽略,它随工作区一起提交,所以随代码提交和独立文档仓库两种模式都不用另加规则。
|
|
203
215
|
|
|
204
216
|
环境映射(本工具链接 DocNexus 的 skills、写段落):
|
|
205
217
|
|
|
@@ -224,7 +236,7 @@ npx @rowansenne/workflow-run docs-repo git@git.example.com:team/team-docs.git
|
|
|
224
236
|
* DocNexus 装在 `workflow-run/docnexus/`,以 `workflow-run/` 为项目根运行(`docnexus init --agent none`:它自己不往 `workflow-run/` 里链接 skills、写 `CLAUDE.md`)。
|
|
225
237
|
* 本项目里由 workflow-run 接上:把 `workflow-run/docnexus/skills/*` 相对链接到 `.claude/skills` / `.agents/skills` / `.qwen/skills` / `.codebuddy/skills`,在 `CLAUDE.md` / `AGENTS.md` 写一段说明(概念索引 `@workflow-run/docnexus/CONCEPTS.md`;docnexus 系列 skill 的命令改用 `node <skills>/workflow/scripts/docnexus.mjs` 运行,不用先 `cd`),用自己的标记,不碰手写内容。升级时刷新,卸载时撤掉,`workflow-run/docnexus/` 本身不动。
|
|
226
238
|
* 各 skill 的脚本已按位置处理:`resolve.mjs status` 给出 `docnexus.root` 与 `run`(`node <skills>/workflow/scripts/docnexus.mjs`),`knowledge.mjs` 在那里运行并给出从项目根读正文的路径。
|
|
227
|
-
* `workflow-run/` 是独立文档仓库时,知识库随文档仓库提交,各服务共用;沉淀后的改动和产物一样由你确认后提交(`requirement.mjs pending` 单独列出)。DocNexus 的依赖和检索库(`node_modules/`、`store
|
|
239
|
+
* `workflow-run/` 是独立文档仓库时,知识库随文档仓库提交,各服务共用;沉淀后的改动和产物一样由你确认后提交(`requirement.mjs pending` 单独列出)。DocNexus 的依赖和检索库(`node_modules/`、`store/`)由 `docnexus/.gitignore` 忽略、不进仓库,各自 `--with-docnexus` 装一次。
|
|
228
240
|
|
|
229
241
|
## CodeGraph 代码图谱与 code-graph skill(可选)
|
|
230
242
|
|
|
@@ -370,7 +382,7 @@ npx @rowansenne/workflow-run uninstall
|
|
|
370
382
|
|
|
371
383
|
`tests/test-skills-meta.mjs` 会检查:skill 的文件里出现了别的 skill 的路径(如 `md-to-wiki/scripts/…`、`workflow/scripts/…`),就必须在 `requires` 或 `optional` 里声明;`requires` 声明了就必须真的用到,而且不能成环。
|
|
372
384
|
|
|
373
|
-
当前依赖关系:`workflow` 是共享核心(模板来源、画像、文档自检脚本),`dev`、`project-review`、两个文档 skill 依赖它;`database-query`、`md-to-wiki` 完全独立;wiki 凭据只由 `md-to-wiki` 的脚本读取,其他 skill 拉 PRD 统一调用 `upload.mjs get`。
|
|
385
|
+
当前依赖关系:`workflow` 是共享核心(模板来源、画像、文档自检脚本),`dev`、`project-review`、两个文档 skill 依赖它;`dev` 还依赖 `project-review`(自审必做,要读它的审查清单);`database-query`、`md-to-wiki` 完全独立;wiki 凭据只由 `md-to-wiki` 的脚本读取,其他 skill 拉 PRD 统一调用 `upload.mjs get`。
|
|
374
386
|
|
|
375
387
|
新增一个 skill 就是新建目录、写 `SKILL.md.tpl` 和 `skill.json`,再加进 `package.json` 的 `files`。`tests/test-skills-meta.mjs` 会检查它们是否一致。
|
|
376
388
|
|
|
@@ -389,10 +401,11 @@ npx @rowansenne/workflow-run uninstall
|
|
|
389
401
|
| `workflow/scripts/resolve.mjs status` | `/workflow status` 的能力探测(不输出任何凭据) |
|
|
390
402
|
| `workflow/scripts/resolve.mjs infer-profile` | 按固定规则从构建文件、Makefile、依赖与配置文件、git 推断项目画像草稿,每个字段附依据;不写文件 |
|
|
391
403
|
| `workflow/scripts/lint-doc.mjs <文档> --skill <skill> [--facts]` | 对照当前生效的模板检查生成的文档:必填章节、残留 `{{...}}` 占位符、元信息行为错误;缺普通章节、顺序不一致为警告;列出待填写位置。`--facts` 再核对正文里的类名、文件、接口、表名:在对比分支的 diff 和代码里都找不到的记为警告(防编造) |
|
|
392
|
-
| `workflow/scripts/requirement.mjs which / bind / path / sync / pending / list / config` | 产物按需求归档(`workflow-run/docs/requirements
|
|
404
|
+
| `workflow/scripts/requirement.mjs which / bind / path / sync / pending / list / config` | 产物按需求归档(`workflow-run/docs/requirements/<需求>/<项目>/`,两种模式结构相同):查当前分支绑定的需求(没绑定时给出按分支名生成的建议名)、绑定需求名、给出本次落盘路径(不覆盖,带上一版的 wiki 记录)、重建 `meta.json`、列出所有需求;`config` 设置产物位置(文档仓库、项目名、提交提示),`pending` 看文档仓库里还没提交的产物 |
|
|
393
405
|
| `workflow/scripts/view.mjs [--out f] [--open]` | 项目文档视图(`/workflow view`、`npx @rowansenne/workflow-run view`):读需求目录里的产物,生成单个 HTML,按需求列出各阶段、审查记录(各级别数量、复核、与上次对比)、交付记录、沉淀到的知识文档,正文直接渲染;顶部「知识文档」列出每篇知识文档来自哪个需求、哪份产物;数据内嵌,只读、不联网,默认写到 `workflow-run/tmp/view/index.html` |
|
|
394
406
|
| `workflow/scripts/artifacts.mjs [--branch b \| --all]` | 按分支汇总 `workflow-run/docs/requirements/` 下的开发方案、交付说明、审查报告、技术方案、上线方案及其 wiki 发布记录,给出下一步建议;分支取自文档元信息行,不另存记录。上线方案没传 `--tech` 时据此自动引用同分支的技术方案;project-review 据此对照本分支方案、识别复审 |
|
|
395
407
|
| `workflow/scripts/report.mjs [--since d] [--all-branches] [--json]` | 本地效果报告(`/workflow report`、`npx @rowansenne/workflow-run report`):审查发现与修复率、复核率、需求澄清、沉淀率、知识引用、各分支链路 |
|
|
408
|
+
| `workflow/scripts/feedback.mjs add … / summary [--json]` | 运行反馈:dev / project-review 交付后追加一行过程记录到 `workflow-run/feedback/<用户>.jsonl`;`summary` 按 skill 汇总,跳过的步骤和不清楚的规则按 SKILL.md 章节归类(`npx @rowansenne/workflow-run feedback`);`init` / `upgrade` 装了新版本时清掉本项目旧版本的记录 |
|
|
396
409
|
| `workflow/scripts/tables.mjs [--diff b...h \| --base b \| --files a,b]` | 找出改动涉及哪些表:实体注解(`@TableName` / `@Table`,没写表名时按类名推断)、Mapper XML 与代码里的 SQL、DDL 脚本;标出 DDL、是否在 `schema.md` 里,并给出拉表结构的命令。dev 调研 / 自检与 project-review 审 SQL / DDL 时使用 |
|
|
397
410
|
| `workflow/scripts/template.mjs list / draft / check / save <模板>` | 修改 / 创建模板(`/workflow template`):把当前模板复制成草稿(或 `--from <样例>` 抽骨架),`check` 校验格式、列出章节变化、拿最近几份已生成文档试跑 lint 看影响,`save` 给出写入 DocNexus 知识库的 capture 指引,不直接写知识库;未接入 DocNexus 时 `draft` / `save` 提示先接入(默认模板只读) |
|
|
398
411
|
| `workflow/scripts/pr-desc.mjs [--branch b] [--base m] [--out f]` | 按本分支产物生成 PR / MR 描述;没有交付说明时退回用 git 记录 |
|
|
@@ -424,6 +437,45 @@ CI(`.github/workflows/test.yml`)在 push 到 main 和每个 PR 上运行:m
|
|
|
424
437
|
2. 推送 `vx.y.z` tag:`.github/workflows/release.yml` 校验 tag 与版本、CHANGELOG 一致,跑测试,然后用 npm Trusted Publishing 发布(不需要 npm token / OTP)。
|
|
425
438
|
3. Trusted Publisher 只能给 npm 上已存在的包配置:新包名第一次要在本机登录 npm 后手动 `npm publish --access public`,之后在 npmjs.com 的包设置 → Trusted Publisher 里登记 GitHub 仓库 `guilianerde/skills-init` 与工作流 `release.yml`。
|
|
426
439
|
|
|
440
|
+
## 哪些文件提交、哪些忽略
|
|
441
|
+
|
|
442
|
+
安装 / 升级时安装器只往项目的 `.gitignore` 追加缺失的规则(已有内容不动),`doctor` 会检查凭据规则还在不在。团队成员照下面两张表即可。
|
|
443
|
+
|
|
444
|
+
**提交**(团队共享):
|
|
445
|
+
|
|
446
|
+
| 路径 | 说明 |
|
|
447
|
+
| --- | --- |
|
|
448
|
+
| `.agents/skills/` | skills 单一来源,含安装清单 `.workflow-run.json` |
|
|
449
|
+
| `.claude/skills/`、`.qwen/skills/`、`.codebuddy/skills/` | 指向 `.agents/skills/` 的相对软链接(Windows 上 clone 需 `git config core.symlinks true`) |
|
|
450
|
+
| `.agents/skills/workflow/profile.json` | 项目画像(无凭据),产物目录用的项目名也在这里 |
|
|
451
|
+
| `.agents/skills/database-query/references/schema.md` | 表结构速查,补齐后提交 |
|
|
452
|
+
| `workflow-run/docs/requirements/` | 需求产物;独立文档仓库模式下提交到文档仓库 |
|
|
453
|
+
| `workflow-run/feedback/` | 运行反馈,每人一个文件;独立文档仓库模式下提交到文档仓库 |
|
|
454
|
+
| `workflow-run/docnexus/` | DocNexus 工作区与定制的文档模板;依赖和检索库由它自带的 `docnexus/.gitignore` 忽略。独立文档仓库模式下提交到文档仓库 |
|
|
455
|
+
| `.ignore` | 让代码搜索跳过需求目录(不影响 git) |
|
|
456
|
+
| `.gitignore`、`.gitattributes`、`CLAUDE.md` / `AGENTS.md` | 安装器追加的忽略规则、运行反馈的合并规则、DocNexus 说明段落 |
|
|
457
|
+
|
|
458
|
+
**忽略**(每人每机器一份,或可重新生成):
|
|
459
|
+
|
|
460
|
+
| `.gitignore` 规则 | 忽略的内容 | 何时追加 |
|
|
461
|
+
| --- | --- | --- |
|
|
462
|
+
| `**/database-query/config.json` | 数据库连接(含密码) | 总是 |
|
|
463
|
+
| `**/wiki-config.json` | wiki 地址与 token | 总是 |
|
|
464
|
+
| `**/workflow/profile.local.json` | 个人设置:本机系统与终端、提交提示开关 | 总是 |
|
|
465
|
+
| `/workflow-run/tmp/` | 临时产物:查询导出、wiki 临时 XHTML、旧版产物归档、升级 / 卸载备份、`view` 页面 | `workflow-run/` 不是独立 git 仓库时 |
|
|
466
|
+
| `/workflow-run/` | 整个文档仓库(它自己提交);同时在文档仓库的 `.git/info/exclude` 加 `/tmp/` | 独立文档仓库模式(`docs-repo`) |
|
|
467
|
+
| `.codegraph/` | CodeGraph 本地索引(SQLite) | `--with-codegraph` |
|
|
468
|
+
|
|
469
|
+
查某个文件为什么被忽略、看当前所有被忽略的文件:
|
|
470
|
+
|
|
471
|
+
```bash
|
|
472
|
+
git check-ignore -v .agents/skills/database-query/config.json
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
```bash
|
|
476
|
+
git status --short --ignored
|
|
477
|
+
```
|
|
478
|
+
|
|
427
479
|
## 凭据安全
|
|
428
480
|
|
|
429
481
|
|
|
@@ -473,7 +525,7 @@ CI(`.github/workflows/test.yml`)在 push 到 main 和每个 PR 上运行:m
|
|
|
473
525
|
一个需求的文档产物放在**同一个需求目录**里,开发方案、交付说明、审查报告、技术方案、上线方案一起看:
|
|
474
526
|
|
|
475
527
|
```
|
|
476
|
-
workflow-run/docs/requirements
|
|
528
|
+
workflow-run/docs/requirements/<需求名>/<项目名>/
|
|
477
529
|
├── meta.json # 需求名、绑定的分支、各产物(版本、日期、wiki 发布记录、DocNexus 沉淀),给以后的可视化用
|
|
478
530
|
├── plan.md # 开发方案(dev,L 规模)
|
|
479
531
|
├── delivery.md # 交付说明(dev,每次完整交付都写)
|
|
@@ -482,8 +534,10 @@ workflow-run/docs/requirements/<需求名>/
|
|
|
482
534
|
└── release-doc.md # 上线方案
|
|
483
535
|
```
|
|
484
536
|
|
|
537
|
+
* **随代码提交和独立文档仓库两种用法的结构完全一样**,切换时文件不用挪。一个需求横跨多个服务时,各服务在同一个需求目录下各占一个 `<项目名>/`。项目名写在 `workflow/profile.json` 的 `artifacts.project`:随代码提交时不用配置,取 git 远端仓库名(没有远端用目录名),第一次落盘时自动写进去;独立文档仓库时由 `docs-repo` 配置。
|
|
538
|
+
* 旧版本随代码提交时没有 `<项目名>/` 这一层;`upgrade` 会把这些需求目录里的文件迁到 `<需求>/<项目名>/`(被 git 跟踪的用 `git mv`,保留历史),结尾列出迁移了哪些需求,改动由你提交。目标里已有同名文件的需求不动,并提示手动处理;`doctor` 也会提示还没迁移的需求。
|
|
485
539
|
* **需求名由你定**:dev 确定是 M / L 规模(要落盘)时,或从 `/workflow` 完整链路开始时,如果当前分支还没有绑定需求,会问你这个需求叫什么(默认值按分支名生成;也可以选已有的需求,例如修 bug 的新分支挂到原需求下)。你不起名就按分支名生成。绑定后,同一分支上的各 skill 都写到这个目录,不再问。一个需求可以绑定多个分支。
|
|
486
|
-
* 路径由 `workflow/scripts/requirement.mjs path <种类>` 给出,每种产物文件名固定,目录里只留最新版,引用不会失效;版本号记在 `meta.json` 的 `versions`。已有旧版时,上一版先复制到 `workflow-run/tmp/old-artifacts
|
|
540
|
+
* 路径由 `workflow/scripts/requirement.mjs path <种类>` 给出,每种产物文件名固定,目录里只留最新版,引用不会失效;版本号记在 `meta.json` 的 `versions`。已有旧版时,上一版先复制到 `workflow-run/tmp/old-artifacts/<需求>/<项目>/<种类>_v<N>.md`(不提交),新版直接覆盖写入;skill 会列出归档的文件,请你确认后自己删除。上一版发布过 wiki 时,新版沿用同一个页面。
|
|
487
541
|
* 需求目录写在项目根的 `.ignore` 里,ripgrep 和 agent 的代码搜索会跳过它,产物多了不会污染搜索结果(找历史决策用 DocNexus)。git 不受影响,建议随代码提交。
|
|
488
542
|
|
|
489
543
|
**独立文档仓库(可选)**:不想让产物进代码仓库、或一个需求横跨多个服务时,装好 skills 后在项目根运行一条命令:
|
|
@@ -492,9 +546,12 @@ workflow-run/docs/requirements/<需求名>/
|
|
|
492
546
|
npx @rowansenne/workflow-run docs-repo <团队文档仓库地址> [--project <项目名>]
|
|
493
547
|
```
|
|
494
548
|
|
|
495
|
-
|
|
549
|
+
它会:
|
|
550
|
+
- `workflow-run/` 里没有内容(或只有 `tmp/`)时,把文档仓库克隆到这里(`tmp/` 先挪开再放回);
|
|
551
|
+
- 已有随项目提交的产物、DocNexus 时,原地 `git init` 并接上远端,文件不用挪(旧结构的产物先迁到 `<需求>/<项目名>/`)。远端是空仓库时,本地内容就是文档仓库的第一批内容;远端已有内容时检出远端,本地文件和远端同路径冲突(多半是两边都有 DocNexus 知识库)就退回原状并列出冲突的文件,不合并;代码仓库还跟踪着 `workflow-run/` 时提示 `git rm -r --cached workflow-run`;
|
|
552
|
+
- 然后代码仓库的 `.gitignore` 加 `/workflow-run/`,文档仓库的 `.git/info/exclude` 加 `/tmp/`;把项目名写进 `workflow/profile.json`(默认沿用已配置的,其次 git 远端仓库名;`profile.json` 随代码提交,记得提交它);文档仓库里有 DocNexus 时接上本项目的链接和段落,本机还没装它的依赖时提示运行 `upgrade --with-docnexus`。不带地址运行显示当前状态;只改项目名:`docs-repo --project <项目名>`。
|
|
496
553
|
|
|
497
|
-
`workflow-run/` 自己是 git
|
|
554
|
+
`workflow-run/` 自己是 git 仓库就是这个模式:目录结构不变,各服务在同一个需求目录下各占一个子目录,DocNexus 知识库也在这个仓库里各服务共用。项目名写在 `workflow/profile.json` 的 `artifacts.project`,只配一次(`docs-repo` 会配好;没配时 skill 会问你一次)。文档里引用产物写成「文档仓库名:路径」,各服务、各人的克隆里都一样。
|
|
498
555
|
|
|
499
556
|
* 写完产物后 skill 会列出文档仓库里没提交的文件和建议的提交信息,你确认后才提交,推送另外问。不想被提示:`requirement.mjs config --commit-prompt off --local`(写在个人的 `workflow/profile.local.json`,已加入 `.gitignore`,不影响团队)。
|
|
500
557
|
* 其他服务的需求要先在 `workflow-run/` 里拉下来(`git -C workflow-run pull`),绑定时才看得到。
|
package/bin/lib/docsrepo.mjs
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
// docs-repo
|
|
2
|
-
// -
|
|
1
|
+
// docs-repo:让 workflow-run/ 成为团队文档仓库,一步切到独立文档仓库模式。两种模式目录结构相同,所以文件不用挪:
|
|
2
|
+
// - workflow-run/ 里没有内容(或只有 tmp/):直接克隆
|
|
3
|
+
// - 已有产物、DocNexus 等内容:原地 git init 并接上远端。远端是空仓库时本地内容就是文档仓库的第一批内容;
|
|
4
|
+
// 远端已有内容时检出远端,本地文件和远端同路径冲突就退回原状、列出冲突的文件(不合并)
|
|
5
|
+
// - 先把旧结构的产物迁到 <需求>/<项目名>/
|
|
3
6
|
// - 代码仓库 .gitignore 加 /workflow-run/;文档仓库的 .git/info/exclude 加 /tmp/(本机临时文件不进文档仓库)
|
|
4
7
|
// - 项目名写进 workflow/profile.json 的 artifacts.project(--project,或沿用已有的,默认 git 远端仓库名)
|
|
5
8
|
// - 文档仓库里有 DocNexus 时接上本项目的链接与段落;还没装依赖时提示
|
|
@@ -9,9 +12,9 @@ import fs from 'node:fs';
|
|
|
9
12
|
import path from 'node:path';
|
|
10
13
|
import { spawnSync } from 'node:child_process';
|
|
11
14
|
import { HOME, step, ok, warn, toPosix, findManifests, docnexusBin, docnexusRoot } from './core.mjs';
|
|
12
|
-
import { updateGitignore, excludeHomeTmp } from './install.mjs';
|
|
15
|
+
import { updateGitignore, excludeHomeTmp, reportMigration } from './install.mjs';
|
|
13
16
|
import { refreshDocNexusLinks } from './docnexus.mjs';
|
|
14
|
-
import { layout, setConfig, artifactsConfig, suggestProject } from '../../workflow/scripts/requirement.mjs';
|
|
17
|
+
import { layout, setConfig, artifactsConfig, suggestProject, migrateLayout } from '../../workflow/scripts/requirement.mjs';
|
|
15
18
|
|
|
16
19
|
const git = (cwd, args, opts = {}) => spawnSync('git', args, { cwd, encoding: 'utf8', ...opts });
|
|
17
20
|
|
|
@@ -28,6 +31,36 @@ function show(root) {
|
|
|
28
31
|
return 0;
|
|
29
32
|
}
|
|
30
33
|
|
|
34
|
+
// workflow-run/ 里已有内容:原地变成文档仓库。返回是否成功;失败时 workflow-run/ 保持原样(只多了迁移到新结构的产物)
|
|
35
|
+
function inPlace(root, home, url, project, installed) {
|
|
36
|
+
// 先定项目名,再把旧结构迁到 <需求>/<项目名>/,这样和文档仓库里其他服务的目录对得上
|
|
37
|
+
if (project && installed) setConfig(root, { project });
|
|
38
|
+
reportMigration(migrateLayout(root));
|
|
39
|
+
const remote = git(root, ['ls-remote', '--symref', url]);
|
|
40
|
+
if (remote.status !== 0) { warn(`连不上 ${url}(地址、权限或网络),没有改动`); return false; }
|
|
41
|
+
const heads = remote.stdout.split('\n').filter((l) => /\trefs\/heads\//.test(l)).map((l) => l.split('\t')[1].replace('refs/heads/', ''));
|
|
42
|
+
const def = /^ref: refs\/heads\/(\S+)\tHEAD$/m.exec(remote.stdout)?.[1] ?? (heads.includes('main') ? 'main' : heads[0]);
|
|
43
|
+
step(`把 ${HOME}/ 原地变成文档仓库(${url})`);
|
|
44
|
+
const undo = () => fs.rmSync(path.join(home, '.git'), { recursive: true, force: true });
|
|
45
|
+
if (git(home, ['init', '-q']).status !== 0 || git(home, ['remote', 'add', 'origin', url]).status !== 0) { undo(); warn('git init 失败,没有改动'); return false; }
|
|
46
|
+
if (!heads.length) {
|
|
47
|
+
git(home, ['symbolic-ref', 'HEAD', 'refs/heads/main']);
|
|
48
|
+
ok(`远端是空仓库:${HOME}/ 里现有的内容就是文档仓库的第一批内容(分支 main)`);
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
if (git(home, ['fetch', '-q', 'origin']).status !== 0) { undo(); warn('git fetch 失败,没有改动'); return false; }
|
|
52
|
+
const co = git(home, ['checkout', '-q', '-b', def, '--track', `origin/${def}`]);
|
|
53
|
+
if (co.status !== 0) {
|
|
54
|
+
undo();
|
|
55
|
+
const files = co.stderr.split('\n').filter((l) => /^\t/.test(l)).map((l) => l.trim());
|
|
56
|
+
warn(`文档仓库里已有和 ${HOME}/ 同路径的文件,没有改动${files.length ? `:${files.join('、')}` : `(${co.stderr.trim()})`}。
|
|
57
|
+
产物在各自的 <需求>/<项目名>/ 下,一般不会冲突;冲突多半来自 DocNexus:文档仓库里已有其他服务的知识库时,先按 DocNexus 的写入流程把本项目沉淀的内容写进去,再挪走本地的 docnexus/ 后重跑。`);
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
ok(`已接上文档仓库 ${def} 分支;${HOME}/ 里本项目的内容还没提交`);
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
|
|
31
64
|
export function docsRepo(root, { url, project }) {
|
|
32
65
|
const home = path.join(root, HOME);
|
|
33
66
|
if (!url && !project) return show(root);
|
|
@@ -41,23 +74,22 @@ export function docsRepo(root, { url, project }) {
|
|
|
41
74
|
if (!url) { warn(`${HOME}/ 还不是文档仓库,需要给出仓库地址:docs-repo <仓库地址>`); return 1; }
|
|
42
75
|
const entries = fs.existsSync(home) ? fs.readdirSync(home).filter((e) => e !== 'tmp' && e !== '.DS_Store') : [];
|
|
43
76
|
if (entries.length) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
77
|
+
if (!inPlace(root, home, url, project, installed)) return 1;
|
|
78
|
+
} else {
|
|
79
|
+
// tmp/ 是本机临时文件,克隆前挪开、克隆后放回
|
|
80
|
+
const tmp = path.join(home, 'tmp');
|
|
81
|
+
const park = fs.existsSync(tmp) ? path.join(root, `.${HOME}-tmp-${process.pid}`) : null;
|
|
82
|
+
if (park) fs.renameSync(tmp, park);
|
|
83
|
+
if (fs.existsSync(home)) fs.rmSync(home, { recursive: true, force: true });
|
|
84
|
+
step(`克隆文档仓库到 ${HOME}/`);
|
|
85
|
+
const r = spawnSync('git', ['clone', url, HOME], { cwd: root, stdio: 'inherit' });
|
|
86
|
+
if (park) { fs.mkdirSync(home, { recursive: true }); fs.renameSync(park, path.join(home, 'tmp')); }
|
|
87
|
+
if (r.status !== 0) { warn('git clone 失败(地址、权限或网络),没有改动'); return 1; }
|
|
88
|
+
ok(`已克隆到 ${HOME}/`);
|
|
47
89
|
}
|
|
48
|
-
// tmp/ 是本机临时文件,克隆前挪开、克隆后放回
|
|
49
|
-
const tmp = path.join(home, 'tmp');
|
|
50
|
-
const park = fs.existsSync(tmp) ? path.join(root, `.${HOME}-tmp-${process.pid}`) : null;
|
|
51
|
-
if (park) fs.renameSync(tmp, park);
|
|
52
|
-
if (fs.existsSync(home)) fs.rmSync(home, { recursive: true, force: true });
|
|
53
|
-
step(`克隆文档仓库到 ${HOME}/`);
|
|
54
|
-
const r = spawnSync('git', ['clone', url, HOME], { cwd: root, stdio: 'inherit' });
|
|
55
|
-
if (park) { fs.mkdirSync(home, { recursive: true }); fs.renameSync(park, path.join(home, 'tmp')); }
|
|
56
|
-
if (r.status !== 0) { warn('git clone 失败(地址、权限或网络),没有改动'); return 1; }
|
|
57
|
-
ok(`已克隆到 ${HOME}/`);
|
|
58
90
|
}
|
|
59
91
|
|
|
60
|
-
updateGitignore(root
|
|
92
|
+
updateGitignore(root);
|
|
61
93
|
excludeHomeTmp(root);
|
|
62
94
|
const tracked = git(root, ['ls-files', '--', HOME]).stdout.trim();
|
|
63
95
|
if (tracked) warn(`代码仓库里还跟踪着 ${HOME}/ 下的文件,运行 git rm -r --cached ${HOME} 后提交,代码仓库就不再管它`);
|
|
@@ -76,7 +108,9 @@ export function docsRepo(root, { url, project }) {
|
|
|
76
108
|
else warn(`文档仓库里有 DocNexus,本机还没装它的依赖:运行 npx @rowansenne/workflow-run upgrade --with-docnexus`);
|
|
77
109
|
}
|
|
78
110
|
const L = layout(root);
|
|
111
|
+
const todo = git(home, ['status', '--porcelain', '--untracked-files=normal']).stdout.split('\n').filter(Boolean).length;
|
|
79
112
|
step('完成');
|
|
113
|
+
if (todo) console.log(` ${HOME}/ 里有 ${todo} 处改动还没提交到文档仓库:git -C ${HOME} status 查看,确认后 git -C ${HOME} add -A && git -C ${HOME} commit,再 push`);
|
|
80
114
|
console.log(` 产物写到 ${toPosix(path.join(HOME, 'docs', 'requirements'))}/<需求名>/${L.project}/,引用写「${L.repo_name}:docs/requirements/...」`);
|
|
81
115
|
console.log(` 写完产物后 skill 会列出文档仓库里没提交的文件,你确认后才提交;推送另外问`);
|
|
82
116
|
return 0;
|
package/bin/lib/doctor.mjs
CHANGED
|
@@ -6,6 +6,7 @@ import { spawnSync } from 'node:child_process';
|
|
|
6
6
|
import { PKG, CANON_DIR, INSTALL_BASES, LINK_ENVS, HOME, DOCNEXUS_PKG, docnexusUpgradeCmd, SKILLS, step, ok, warn, fail, toPosix, fileHash, readManifest, lstat, findManifests, cmpVersion } from './core.mjs';
|
|
7
7
|
import { reportTemplateStatus, docnexusSupportsCategory, docnexusSupportsRecallCategory } from './docnexus.mjs';
|
|
8
8
|
import { codegraphVersion } from './codegraph.mjs';
|
|
9
|
+
import { legacyRequirements } from '../../workflow/scripts/requirement.mjs';
|
|
9
10
|
|
|
10
11
|
// upgrade = 用清单里记录的环境与模式非交互重装;数据库配置原样保留
|
|
11
12
|
export function upgradeOptions(o) {
|
|
@@ -98,7 +99,9 @@ export function doctor(root, offline) {
|
|
|
98
99
|
// 产出目录:都在 workflow-run/
|
|
99
100
|
const mode = st.artifacts?.mode === 'repo' ? `独立文档仓库(${HOME}/ 自己是 git 仓库)` : '随项目提交';
|
|
100
101
|
if (st.artifacts && !st.artifacts.ok) meh(`产出目录 ${HOME}/:${mode},${st.artifacts.how}`);
|
|
101
|
-
else ok(`产出目录 ${HOME}/:${mode}`);
|
|
102
|
+
else ok(`产出目录 ${HOME}/:${mode}${st.artifacts?.project ? `,本项目的产物在 docs/requirements/<需求>/${st.artifacts.project}/` : ''}`);
|
|
103
|
+
const legacy = legacyRequirements(root);
|
|
104
|
+
if (legacy.length) meh(`${legacy.length} 个需求还是旧结构(文件直接放在 docs/requirements/<需求>/ 下):运行 npx @rowansenne/workflow-run upgrade 迁到 <需求>/<项目名>/`);
|
|
102
105
|
if (st.docnexus.ok) {
|
|
103
106
|
if (!reportTemplateStatus(root, meh)) ok('DocNexus 已接入,文档模板齐全且与默认模板同步(或为团队定制版)');
|
|
104
107
|
if (docnexusSupportsCategory(root) === false) meh(`已装的 DocNexus 不支持 draft seal --category:各 skill 的分类只能经 metadata.category 写入,不记为调用方指定。升级:${docnexusUpgradeCmd()}`);
|
package/bin/lib/install.mjs
CHANGED
|
@@ -4,8 +4,9 @@ import fs from 'node:fs';
|
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { TPL_DIR, PKG, CANON_DIR, INSTALL_BASES, SKILLS, SKILL_LIST, USER_FILES, MANIFEST, ok, warn, readJson, walk, toPosix, sameFile, writeFile, render, sha256, fileHash, readManifest, removeEmptyDirs, lstat, timestamp, removeLink, HOME } from './core.mjs';
|
|
6
6
|
import { writeDbConfig } from './db.mjs';
|
|
7
|
-
import { layout, ensureIgnore, homeIsRepo, IGNORE_LINE, TMP_DIR } from '../../workflow/scripts/requirement.mjs';
|
|
7
|
+
import { layout, ensureIgnore, homeIsRepo, migrateLayout, IGNORE_LINE, TMP_DIR } from '../../workflow/scripts/requirement.mjs';
|
|
8
8
|
import { detectEnv } from '../../workflow/scripts/resolve.mjs';
|
|
9
|
+
import { rotate as rotateFeedback, ensureUnionMerge } from '../../workflow/scripts/feedback.mjs';
|
|
9
10
|
|
|
10
11
|
// 结尾汇总:被手改过、已用新版覆盖(原文件已备份)的 / 模板已删除、手改过而备份后删除的文件 /
|
|
11
12
|
// 没有安装清单、内容与新版不同而备份后覆盖的文件(无从判断是否手改)
|
|
@@ -207,11 +208,11 @@ export function linkSkills(root, envName, rel, skills = SKILLS) {
|
|
|
207
208
|
}
|
|
208
209
|
|
|
209
210
|
// ---------------------------------------------------------------- 4. .gitignore 保护
|
|
210
|
-
// workflow-run/
|
|
211
|
-
|
|
211
|
+
// workflow-run/ 是独立文档仓库时整个忽略(它自己提交);否则只忽略其中的临时文件。
|
|
212
|
+
// DocNexus 的依赖与检索库由它自带的 docnexus/.gitignore 忽略,随工作区走,两种模式都不用这里加规则
|
|
213
|
+
export function updateGitignore(root, withCodeGraph = false) {
|
|
212
214
|
const gi = path.join(root, '.gitignore');
|
|
213
215
|
const rules = ['**/database-query/config.json', '**/wiki-config.json', '**/workflow/profile.local.json', homeIsRepo(root) ? `/${HOME}/` : `/${TMP_DIR}/`];
|
|
214
|
-
if (withDocNexus) rules.push('node_modules/');
|
|
215
216
|
if (withCodeGraph) rules.push('.codegraph/'); // 本地索引(SQLite),各人各建
|
|
216
217
|
const existing = fs.existsSync(gi) ? fs.readFileSync(gi, 'utf8').split(/\r?\n/).map((l) => l.trim()) : [];
|
|
217
218
|
const missing = rules.filter((r) => !existing.includes(r));
|
|
@@ -255,4 +256,20 @@ export function setupHome(root) {
|
|
|
255
256
|
excludeHomeTmp(root);
|
|
256
257
|
const L = layout(root);
|
|
257
258
|
if (L.mode === 'repo' && !L.ok) warn(`${HOME}/ 是独立的文档仓库,还没配置本项目的项目名:${L.hint}`);
|
|
259
|
+
reportMigration(migrateLayout(root));
|
|
260
|
+
// 运行反馈只收当前版本的:装了新版本就清掉本项目旧版本的记录(随 workflow-run/ 提交过的,git 历史里仍可找回)
|
|
261
|
+
const removed = rotateFeedback(root, PKG.version);
|
|
262
|
+
const attr = ensureUnionMerge(root);
|
|
263
|
+
if (attr) ok(`${attr.file} 已加上 ${attr.rule}(运行反馈多分支合并时保留两边的记录)`);
|
|
264
|
+
if (removed) ok(`运行反馈:已清空旧版本的 ${removed} 条记录(${HOME}/feedback/),从这一版重新收集;改动需要你提交`);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// 旧结构(<需求>/ 下直接放文件)迁到 <需求>/<项目名>/ 的结果
|
|
268
|
+
export function reportMigration(r) {
|
|
269
|
+
if (r.moved.length) {
|
|
270
|
+
const reqs = [...new Set(r.moved.map((m) => path.posix.dirname(m.from)))];
|
|
271
|
+
ok(`需求产物已迁到新结构 <需求>/${r.project}/(${reqs.length} 个需求、${r.moved.length} 个文件,被 git 跟踪的用 git mv):${reqs.join('、')}`);
|
|
272
|
+
ok(`项目名 ${r.project} 记在 workflow/profile.json;迁移的改动(含 profile.json)需要你提交`);
|
|
273
|
+
}
|
|
274
|
+
for (const s of r.skipped) warn(`${s.dir} 没有迁移:${s.reason}。处理后重跑 npx @rowansenne/workflow-run upgrade`);
|
|
258
275
|
}
|
package/bin/workflow-run.mjs
CHANGED
|
@@ -29,7 +29,7 @@ import { docsRepo } from './lib/docsrepo.mjs';
|
|
|
29
29
|
import { findLegacy, legacyMessage } from './lib/legacy.mjs';
|
|
30
30
|
|
|
31
31
|
// ---------------------------------------------------------------- 参数
|
|
32
|
-
const COMMANDS = ['init', 'upgrade', 'doctor', 'uninstall', 'seed-templates', 'report', 'view', 'docs-repo'];
|
|
32
|
+
const COMMANDS = ['init', 'upgrade', 'doctor', 'uninstall', 'seed-templates', 'report', 'feedback', 'view', 'docs-repo'];
|
|
33
33
|
const HELP = `用法: workflow-run [命令] [选项]
|
|
34
34
|
|
|
35
35
|
命令:
|
|
@@ -40,6 +40,7 @@ const HELP = `用法: workflow-run [命令] [选项]
|
|
|
40
40
|
uninstall 按安装清单卸载本项目装的 skills 与链接(用户配置备份到 workflow-run/tmp/uninstall-backup/)
|
|
41
41
|
seed-templates 只把自带的文档模板导入 DocNexus(workflow-run/docnexus/library/templates/,已有的不覆盖)
|
|
42
42
|
report 本地效果报告:只读统计 workflow-run/docs/requirements/ 下的产物(审查发现与修复率、需求澄清、DocNexus 沉淀与复用、各分支链路)
|
|
43
|
+
feedback 运行反馈汇总:dev / project-review 每次运行追加到 workflow-run/feedback/<用户>.jsonl 的过程记录(提问轮数、跳过的步骤、不清楚的规则),精简 skill 的依据;--json 输出 JSON
|
|
43
44
|
view 项目文档视图:按需求浏览方案、交付、审查(含复审修复情况)、技术 / 上线方案,生成本地静态页面
|
|
44
45
|
docs-repo <仓库地址> 改用团队文档仓库:克隆到 workflow-run/、代码仓库忽略它、配置本项目的项目名、接上仓库里的 DocNexus;
|
|
45
46
|
不带地址时显示当前状态
|
|
@@ -149,6 +150,10 @@ async function main() {
|
|
|
149
150
|
const { main: report } = await import(new URL('../workflow/scripts/report.mjs', import.meta.url));
|
|
150
151
|
return report(['--root', o.root, ...(o.since ? ['--since', o.since] : []), ...(o.json ? ['--json'] : []), ...(o.allBranches ? ['--all-branches'] : [])]);
|
|
151
152
|
}
|
|
153
|
+
if (o.cmd === 'feedback') {
|
|
154
|
+
const { main: feedback } = await import(new URL('../workflow/scripts/feedback.mjs', import.meta.url));
|
|
155
|
+
return feedback(['--root', o.root, 'summary', ...(o.json ? ['--json'] : [])]);
|
|
156
|
+
}
|
|
152
157
|
if (o.cmd === 'view') {
|
|
153
158
|
const { main: view } = await import(new URL('../workflow/scripts/view.mjs', import.meta.url));
|
|
154
159
|
return view(['--root', o.root, ...(o.out ? ['--out', o.out] : []), ...(o.open ? ['--open'] : [])]);
|
|
@@ -225,7 +230,7 @@ async function main() {
|
|
|
225
230
|
}
|
|
226
231
|
closePrompt(); // 模板冲突时可能还要询问,装完再关
|
|
227
232
|
|
|
228
|
-
updateGitignore(o.root, o.
|
|
233
|
+
updateGitignore(o.root, o.withCodeGraph);
|
|
229
234
|
setupHome(o.root);
|
|
230
235
|
recordEnv(o.root);
|
|
231
236
|
const docnexus = o.withDocNexus ? setupDocNexus(o.root, sel) : 'skipped';
|
|
@@ -70,7 +70,7 @@ description: "Generate a Markdown release/deployment plan (上线方案) from th
|
|
|
70
70
|
|
|
71
71
|
### Step 4 — 写文件
|
|
72
72
|
|
|
73
|
-
- 路径:运行 `node <skills>/workflow/scripts/requirement.mjs path release --branch <dev分支>`,写到输出的 `path`(`workflow-run/docs/requirements
|
|
73
|
+
- 路径:运行 `node <skills>/workflow/scripts/requirement.mjs path release --branch <dev分支>`,写到输出的 `path`(`workflow-run/docs/requirements/<需求名>/<项目名>/release-doc.md`,文件名固定;已有旧版时直接写新版,上一版由脚本归档到输出的 `previous`)。规则见 `<skills>/workflow/references/requirements.md`。
|
|
74
74
|
- 退出码 2(这个分支还没绑定需求):问用户这个需求叫什么,默认值用输出的 `suggested_name`,再 `requirement.mjs bind --name "<需求名>" --branch <dev分支>`;用户不给名字时 `bind` 按分支名生成。
|
|
75
75
|
- `wiki_record` 非空:上一版已发布到 wiki,新版第一行原样写这条记录,重新发布时更新同一页面。
|
|
76
76
|
- 写完运行 `requirement.mjs sync <path>` 更新 `meta.json`;输出里 `archived` 非空(上一版已归档到 `workflow-run/tmp/old-artifacts/`)时告诉用户归档了哪些文件,请用户确认不再需要后自己删除;输出里 `commit` 非空(独立文档仓库模式)时按 `<skills>/workflow/references/requirements.md`「文档仓库的提交」处理。文档里引用其他产物(「参考产物」等)写 `requirement.mjs path` 输出的 `cite`。
|
|
@@ -68,7 +68,7 @@ description: "Generate a Markdown technical design doc (技术方案) from the d
|
|
|
68
68
|
|
|
69
69
|
### Step 4 — 写文件
|
|
70
70
|
|
|
71
|
-
- 路径:运行 `node <skills>/workflow/scripts/requirement.mjs path tech --branch <dev分支>`,写到输出的 `path`(`workflow-run/docs/requirements
|
|
71
|
+
- 路径:运行 `node <skills>/workflow/scripts/requirement.mjs path tech --branch <dev分支>`,写到输出的 `path`(`workflow-run/docs/requirements/<需求名>/<项目名>/tech-doc.md`,文件名固定;已有旧版时直接写新版,上一版由脚本归档到输出的 `previous`)。规则见 `<skills>/workflow/references/requirements.md`。
|
|
72
72
|
- 退出码 2(这个分支还没绑定需求):问用户这个需求叫什么,默认值用输出的 `suggested_name`,再 `requirement.mjs bind --name "<需求名>" --branch <dev分支>`;用户不给名字时 `bind` 按分支名生成。
|
|
73
73
|
- `wiki_record` 非空:上一版已发布到 wiki,新版第一行原样写这条记录,重新发布时更新同一页面。
|
|
74
74
|
- 写完运行 `requirement.mjs sync <path>` 更新 `meta.json`;输出里 `archived` 非空(上一版已归档到 `workflow-run/tmp/old-artifacts/`)时告诉用户归档了哪些文件,请用户确认不再需要后自己删除;输出里 `commit` 非空(独立文档仓库模式)时按 `<skills>/workflow/references/requirements.md`「文档仓库的提交」处理。文档里引用其他产物(「参考产物」等)写 `requirement.mjs path` 输出的 `cite`。
|
package/dev/SKILL.md.tpl
CHANGED
|
@@ -13,7 +13,7 @@ description: "Implement a feature or fix a bug in this project end to end: under
|
|
|
13
13
|
| 项目约定 / 历史决策 | DocNexus(`docnexus-recall` skill) | 读 `CLAUDE.md` / `AGENTS.md` 与代码 |
|
|
14
14
|
| 读代码 / 调用链 / 影响面 | CodeGraph(见 `<skills>/workflow/references/codegraph.md`) | grep / 读文件 |
|
|
15
15
|
| 涉及哪些表 / 实际表结构 / 数据核对 | `workflow/scripts/tables.mjs` 定位表 → `database-query`(`query.mjs --schema --tables … --indexes`,只读) | 读 `schema.md` 与 DDL 脚本,注明「未与实际库核对」 |
|
|
16
|
-
| 自审 | `project-review
|
|
16
|
+
| 自审 | `project-review`(随 dev 一起安装;内部调用的边界见 F7) | — |
|
|
17
17
|
| 交付文档 | `create-tech-md-doc` / `create-release-md-doc` | 只在对话中汇总 |
|
|
18
18
|
|
|
19
19
|
## Command Format
|
|
@@ -30,9 +30,12 @@ description: "Implement a feature or fix a bug in this project end to end: under
|
|
|
30
30
|
1. **项目画像**:运行 `node <skills>/workflow/scripts/resolve.mjs profile`,读输出的 `profile` 与 `empty`(空字段列表;字段含义见 `workflow` skill)。本 skill 用到 `main_branch`、`build`、`test`、`test_single`(`{target}` 替换为测试类或文件)、`lint`、`config_center`、`notes`。
|
|
31
31
|
- 需要的字段为空 → 按 `<skills>/workflow/references/profile.md`「填写与更新」的步骤推断,经用户确认后写回;用户不确认就只在本次使用,不落盘。
|
|
32
32
|
2. **工作区状态**:`git status --short` 与当前分支。
|
|
33
|
-
-
|
|
33
|
+
- 有未提交改动或未跟踪文件 → 列出这些文件,**问用户哪些属于本需求**(例如用户先手写了一部分,让你接着做);可以和后面的澄清问题一起问。不要替用户 stash / 丢弃。
|
|
34
|
+
- 属于本需求的:和你之后的改动同等对待,影响面、相关测试、自审、交付说明「改动」节都纳入。
|
|
35
|
+
- 不属于的:照常在测试里跑到(测试跑的是整个工作区),但不算本次改动——自审在这些文件里发现的问题写进「范围外发现」,交付说明单独列出,提交时不 add。同一个文件里两边都改了的,告诉用户,自审只按本需求那部分下结论。
|
|
34
36
|
- 当前在主分支(`profile.main_branch`)上 → 建议先建特性分支,用户同意后再建。
|
|
35
37
|
3. **增强能力探测**:运行 `node <skills>/workflow/scripts/resolve.mjs status`,按输出的 `wiki` / `docnexus` / `database` 判断是否可用(wiki MCP 脚本探测不到,另看当前环境有没有 wiki 工具)。都不阻塞,不可用就跳过对应增强,并在交付说明中注明。
|
|
38
|
+
4. **基线**:动代码前运行一次 `profile.build`,再跑和本需求相关的测试(`profile.test_single` 或相关模块,不必全量),记下已经失败的测试和编译错误。之后只对新增的失败负责:已有失败不顺手修,写进交付说明「开工前已有的失败」。跑不了就记「未跑基线」和原因。
|
|
36
39
|
|
|
37
40
|
## 功能开发流程
|
|
38
41
|
|
|
@@ -64,21 +67,21 @@ description: "Implement a feature or fix a bug in this project end to end: under
|
|
|
64
67
|
|
|
65
68
|
| 规模 | 判定 | 做法 |
|
|
66
69
|
|---|---|---|
|
|
67
|
-
| **S** | ≤3 个文件,无接口签名 / 表结构 /
|
|
70
|
+
| **S** | ≤3 个文件,无接口签名 / 表结构 / 配置项变更,不涉及权限 / 资金 | 在对话中列改动步骤,直接开始 |
|
|
68
71
|
| **M** | 新增或修改接口、配置项、少量表字段 | 在对话中给出简要方案(方案模板的精简版),**等用户确认后再写代码** |
|
|
69
72
|
| **L** | 新模块、跨服务、表结构较大变更、数据迁移 | 按方案模板写方案文档落盘(见 Artifact Location),用户确认后再写代码;完成后建议用 `create-tech-md-doc` 生成正式技术方案 |
|
|
70
73
|
|
|
71
|
-
|
|
74
|
+
规模拿不准时按大一级处理。涉及权限(鉴权、角色、数据可见范围)或资金(金额计算、扣款、退款、对账)的改动,文件再少也至少按 M:需求理解(F3)和方案都要用户确认。
|
|
72
75
|
|
|
73
76
|
**M / L 规模先定需求名**:规模定下来、确定要落盘时,按 Artifact Location 运行 `requirement.mjs which`,当前分支没绑定需求就在这一轮问用户这个需求叫什么(可以和澄清问题一起问),之后的方案、交付、审查、技术方案、上线方案都归到这个需求下。
|
|
74
77
|
|
|
75
|
-
**S 规模快速通道**:S 规模,且改动**不涉及**配置项、SQL / DDL、对外接口(HTTP 接口签名、MQ 消息体、对外 DTO
|
|
78
|
+
**S 规模快速通道**:S 规模,且改动**不涉及**配置项、SQL / DDL、对外接口(HTTP 接口签名、MQ 消息体、对外 DTO)、表结构、权限、资金,也没有 F3 中确认过的决定 → 走快速通道:F5~F7 照常(编译、测试、自审都不省),F8 只在对话里交付,不落盘交付说明、不问 DocNexus 沉淀(见 F8「快速通道交付」)。开工时用一句话告诉用户「按快速通道处理,不落盘交付说明」。实现中一旦碰到上面任何一项、改动超过 3 个文件,或用户要求落盘 → 退出快速通道,按完整 F8 交付。小改动也要走完整流程是用户绕开 dev 的主要原因,所以只在上面这些会影响上线和团队的情况下才落盘。
|
|
76
79
|
|
|
77
80
|
方案模板:在项目根运行 `node <skills>/workflow/scripts/resolve.mjs template dev plan-template.md`,读输出的 `path`;退出码 2(已接入 DocNexus 但缺模板)时停下并按 `hint` 处理。L 规模的方案文档落盘后运行 `node <skills>/workflow/scripts/lint-doc.mjs <方案路径> --skill dev` 自检,再请用户确认。
|
|
78
81
|
|
|
79
82
|
### F5 — 实现
|
|
80
83
|
|
|
81
|
-
-
|
|
84
|
+
- **小步推进**:按逻辑分步实现,一步改完(或改了公共签名、跨了模块)运行 `profile.build`(没有则用对应构建工具的编译命令)确认通过,再进入下一步。不必每改一个文件就编译,代码没变时不重复跑。
|
|
82
85
|
- **改动前看影响面**:要改公共方法、接口签名、DTO 字段时,先 `node <skills>/code-graph/scripts/cg.mjs entry <Class.method>`(code-graph skill;退出码 2 时用 grep),把会被波及的入口和调用方纳入本次改动或写进交付说明。
|
|
83
86
|
- **贴合现有代码**:沿用参照实现的写法;不顺手重构、不改无关代码、不升级依赖。看到范围外的问题记进交付说明,不在本次修。
|
|
84
87
|
- **配置**:新增配置项记入配置清单(key、位置、用途、建议默认值、上线前需下发的环境),按 `profile.config_center` 与审查清单的配置维度处理(清单路径用 `node <skills>/workflow/scripts/resolve.mjs template project-review checklist.md` 取,接入 DocNexus 时是团队维护的版本)。
|
|
@@ -88,26 +91,29 @@ description: "Implement a feature or fix a bug in this project end to end: under
|
|
|
88
91
|
### F6 — 验证
|
|
89
92
|
|
|
90
93
|
- 按验收标准补充或更新单元测试 / 集成测试,测试放在项目既有测试目录、沿用既有测试框架。
|
|
91
|
-
-
|
|
94
|
+
- **验收项对应到证据**:F1 / F3 的每条验收标准写明靠哪个测试或手动操作验证、结果如何;没有测试也没法操作的标「未验证」并写原因。交付说明「验证」节的表格按这个填,快速通道在对话里列同样的对应。
|
|
95
|
+
- 先跑相关测试(`profile.test_single`,或代码图谱的 `impact` 选出的测试),修到通过;最后跑一次 `profile.test` 全量(之后又改了代码就再跑)。有 `profile.lint` 时一并运行。全量里出现、基线没跑到的失败,先看失败的测试是否碰到本次改动的代码,确认无关的按已有失败记录并写明依据。代码图谱可用时相关测试取自 `node <skills>/code-graph/scripts/cg.mjs impact --base <main_branch>` 输出的 `tests`;`impact` 的 `entry_points`、`sql`、`config_keys` 写进交付说明(受影响的接口 / 消费者 / 定时任务、表、配置)。改动碰到 SQL、实体或 DDL 时运行 `node <skills>/workflow/scripts/tables.mjs --base <main_branch>`,对其中的表再核对一次实际表结构(见 `<skills>/workflow/references/tables.md`),结果写进交付说明的 SQL 节。
|
|
92
96
|
- 如实报告结果:失败就给出失败输出并继续修;环境跑不了(缺依赖、缺中间件)就明确写「未验证」以及用户该如何验证。**不得声称未运行的测试已通过。**
|
|
93
97
|
|
|
94
98
|
### F7 — 自审
|
|
95
99
|
|
|
96
|
-
- 按 `project-review` skill 审本次改动:分支已有提交时用 `git diff <main_branch>...HEAD`,再加上 `git diff HEAD`
|
|
100
|
+
- 按 `project-review` skill 审本次改动:分支已有提交时用 `git diff <main_branch>...HEAD`,再加上 `git diff HEAD` 的未提交部分,以及 `git status --short` 里本次新建、还没跟踪的文件(`git diff` 看不到,逐个读)。Step 0 确认不属于本需求的文件不计入本次结论(见 Step 0「工作区状态」)。
|
|
101
|
+
- 只走 project-review 的第 1~6 步(范围与深度、建立理解、对比、过清单、影响面、复核);**跳过第 7 步落盘报告、第 8 步 DocNexus 询问和第 9 步运行反馈**——结论由 dev 在 F8 统一交付,沉淀只在 F8 问一次,反馈也只由 dev 记一行。用户要求单独的审查报告时,再按 project-review 的第 7 步和产物规范落盘。
|
|
102
|
+
- 交给 F8 的是:问题表(文件:行号、严重级别、触发条件、复核结果)、影响面、未覆盖与待确认。
|
|
97
103
|
- CRITICAL / HIGH 必须修掉后重新跑 F6;MEDIUM / LOW 修掉或写进交付说明。
|
|
98
|
-
- 自审结论放进交付说明即可,不单独落盘审查报告(用户要求时再按 project-review 的产物规范落盘)。
|
|
99
104
|
|
|
100
105
|
### F8 — 交付
|
|
101
106
|
|
|
102
|
-
**快速通道交付**(见 F4「S 规模快速通道」):不落盘、不跑 lint、不问 DocNexus
|
|
107
|
+
**快速通道交付**(见 F4「S 规模快速通道」):不落盘、不跑 lint、不问 DocNexus 沉淀。对话里给:结果一句话、改动文件、验证(验收项 → 测试 / 操作 → 结果,构建 / 测试命令与结果,开工前已有的失败,未验证项如实写)、自审结论;按完整流程第 4 步记录运行反馈;然后只问提交(建议的 commit message)。用户说「落盘交付说明」或之后要出上线方案时,再按下面的完整流程补落盘。
|
|
103
108
|
|
|
104
109
|
完整流程:
|
|
105
110
|
|
|
106
111
|
1. **落盘交付说明**:模板路径用 `node <skills>/workflow/scripts/resolve.mjs template dev delivery-template.md` 取(退出码 2 时停下并按 `hint` 处理),写到 `requirement.mjs path delivery` 给出的路径(见 Artifact Location)。元信息行的「对比分支」写当前分支和 `profile.main_branch`,`artifacts.mjs`、project-review、上线方案靠它找到这份交付;有开发方案时「参考产物」写方案路径。小改动每节一两行即可,不适用的节写「无」,但验证结果必须如实。
|
|
107
112
|
2. **自检**:运行 `node <skills>/workflow/scripts/lint-doc.mjs <交付路径> --skill dev --template delivery-template.md`,有「错误」先修正。
|
|
108
113
|
3. **对话里给摘要**:结果、验证(含未验证项)、配置 / SQL 有无、交付文件路径;不必把全文贴进对话。
|
|
109
|
-
4.
|
|
110
|
-
|
|
114
|
+
4. **记录运行反馈**(不问用户):按 `<skills>/workflow/references/feedback.md` 运行 `node <skills>/workflow/scripts/feedback.mjs add --skill dev --model <模型名> --mode <feature|bug> --size <S|M|L> --fast <yes|no> --rounds <提问轮数> --corrections <用户纠正理解的次数> --acceptance <已验证>/<总数> --baseline-failures <n>`,有跳过的步骤、不清楚或做不到的规则、用户的抱怨时再加 `--skipped` / `--unclear` / `--feedback`。只写过程,不写代码和业务名词;报错就提一句,不影响交付。
|
|
115
|
+
5. **询问下一步**,不要自行执行:
|
|
116
|
+
- 提交:给出建议的 commit message 和要 add 的文件(只含本需求的改动,Step 0 确认无关的不 add;建议把交付说明一起提交,随分支保留),用户同意后再 `git commit`;**不 push**,除非用户明确要求。
|
|
111
117
|
- PR / MR:用户要提 PR / MR 时,运行 `node <skills>/workflow/scripts/pr-desc.mjs`(缺省当前分支、基线 `profile.main_branch`),它把本分支的交付说明、审查报告、技术方案、上线方案汇总成描述(没有交付说明时退回用提交记录和改动文件),把输出给用户;用 `gh pr create` / `glab mr create` 创建要用户明确同意。
|
|
112
118
|
- 文档:运行 `node <skills>/workflow/scripts/artifacts.mjs` 看本分支已有哪些产物(开发方案、交付说明、审查报告、技术方案、上线方案及 wiki 发布记录),按输出的 `next` 建议下一步:M / L 规模缺技术方案时建议 `create-tech-md-doc`,要上线时建议 `create-release-md-doc`(会自动引用本分支的技术方案和交付说明)。
|
|
113
119
|
- **沉淀到 DocNexus**(`resolve.mjs status` 的 `docnexus.ok` 为 true 时**每次都问**):明确问用户「要不要启动 DocNexus 流程,把本次交付沉淀到 DocNexus?」,并从交付说明里列出建议沉淀的内容(已确认的决定、新约定、踩到的坑、缺陷根因、配置 / 表结构变化);没有特别值得记的也照问,并说明这一点。
|
|
@@ -140,7 +146,7 @@ description: "Implement a feature or fix a bug in this project end to end: under
|
|
|
140
146
|
|
|
141
147
|
### B5 — 自审与交付
|
|
142
148
|
|
|
143
|
-
同 F7、F8(交付说明同样落盘,「类型」写缺陷修复)。快速通道同样适用于缺陷修复:S 规模、不涉及配置 / SQL / 对外接口 /
|
|
149
|
+
同 F7、F8(交付说明同样落盘,「类型」写缺陷修复)。快速通道同样适用于缺陷修复:S 规模、不涉及配置 / SQL / 对外接口 / 表结构 / 权限 / 资金,且同类风险排查没有发现其他调用方受影响时,在对话里交付,但根因(证据链、修复方式)必须在对话里写清楚。交付说明的「根因」节必须写:证据链、修复方式、为什么这样修、同类风险排查结果;DocNexus 沉淀时根因是首要候选。
|
|
144
150
|
|
|
145
151
|
## Rules
|
|
146
152
|
|
|
@@ -152,7 +158,7 @@ description: "Implement a feature or fix a bug in this project end to end: under
|
|
|
152
158
|
|
|
153
159
|
## Artifact Location
|
|
154
160
|
|
|
155
|
-
产物按需求归档在 `workflow-run/docs/requirements
|
|
161
|
+
产物按需求归档在 `workflow-run/docs/requirements/<需求名>/<项目名>/`,规则见 `<skills>/workflow/references/requirements.md`:
|
|
156
162
|
|
|
157
163
|
- **需求名**:确定规模为 M / L(要落盘)时,先运行 `node <skills>/workflow/scripts/requirement.mjs which`;当前分支还没绑定需求就问用户这个需求叫什么(默认值用输出的 `suggested_name`),再 `requirement.mjs bind --name "<需求名>"`;用户不给名字时 `bind` 按分支名生成。S 规模快速通道不落盘,不问。缺陷修复同样处理(可以选择挂到原需求下)。
|
|
158
164
|
- **路径**:交付说明用 `requirement.mjs path delivery`,L 规模方案(或用户要求落盘的 M 规模方案)用 `requirement.mjs path plan`,写到输出的 `path`;文件名固定,已有旧版时直接写新版,上一版由脚本归档(输出的 `previous`)。
|