@rowansenne/workflow-run 0.21.0 → 0.21.2

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 CHANGED
@@ -4,6 +4,16 @@
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.21.2] - 2026-10-19
8
+
9
+ ### 文档
10
+ - README 新增「哪些文件提交、哪些忽略」:集中列出要提交的 skills 目录、软链接、项目画像、需求产物等,以及安装器追加的各条 `.gitignore` 规则、忽略的内容和追加时机,附 `git check-ignore` 检查命令。
11
+
12
+ ## [0.21.1] - 2026-10-18
13
+
14
+ ### 修复
15
+ - 提示里的命令改成完整的 `npx @rowansenne/workflow-run <子命令>`(如 `seed-templates --update`、`upgrade`):之前写的是 `workflow-run ...`,用 npx 安装、没有全局安装时会报命令找不到。
16
+
7
17
  ## [0.21.0] - 2026-10-18
8
18
 
9
19
  ### 变更(破坏性)
package/README.md CHANGED
@@ -122,7 +122,7 @@ npx @rowansenne/workflow-run docs-repo git@git.example.com:team/team-docs.git
122
122
  /workflow report # 本地效果报告(也可以直接运行 npx @rowansenne/workflow-run report)
123
123
  ```
124
124
 
125
- **效果报告**(`/workflow report` 或 `workflow-run report [--since YYYY-MM-DD] [--all-branches] [--json]`)只读统计 `workflow-run/docs/requirements/` 下已落盘的产物,不上报、不另存记录,用来回答「用了以后有没有更好」。默认只看工作区;产物随特性分支提交、还没合并时加 `--all-branches`,用 git 只读扫描所有本地分支(同一路径以工作区为准)。统计内容:
125
+ **效果报告**(`/workflow report` 或 `npx @rowansenne/workflow-run report [--since YYYY-MM-DD] [--all-branches] [--json]`)只读统计 `workflow-run/docs/requirements/` 下已落盘的产物,不上报、不另存记录,用来回答「用了以后有没有更好」。默认只看工作区;产物随特性分支提交、还没合并时加 `--all-branches`,用 git 只读扫描所有本地分支(同一路径以工作区为准)。统计内容:
126
126
 
127
127
  * 审查:各级别发现条数、严重问题复核通过率、复审时上次问题的修复率;
128
128
  * 交付:功能 / 缺陷、S / M / L、开工前经需求澄清确认的决定条数、带「未验证项」的交付;
@@ -276,7 +276,7 @@ dev、project-review、技术方案、上线方案都在对应环节调用它:
276
276
 
277
277
  ## 重跑与升级
278
278
 
279
- 可以放心重复执行 init 来升级模板;只想按原来的环境升级时用 `workflow-run upgrade`,不用再选一遍:
279
+ 可以放心重复执行 init 来升级模板;只想按原来的环境升级时用 `npx @rowansenne/workflow-run upgrade`,不用再选一遍:
280
280
 
281
281
  * `SKILL.md`、`references/checklist.md`、`template.md`、脚本等**模板文件会被更新**;但被你**手动改过**的模板文件不会被静默覆盖(见下方「安装清单」);
282
282
  * 新版本模板里已删除的文件会被清理;你改过的不删,保留并在结尾提示;
@@ -390,9 +390,9 @@ npx @rowansenne/workflow-run uninstall
390
390
  | `workflow/scripts/resolve.mjs infer-profile` | 按固定规则从构建文件、Makefile、依赖与配置文件、git 推断项目画像草稿,每个字段附依据;不写文件 |
391
391
  | `workflow/scripts/lint-doc.mjs <文档> --skill <skill> [--facts]` | 对照当前生效的模板检查生成的文档:必填章节、残留 `{{...}}` 占位符、元信息行为错误;缺普通章节、顺序不一致为警告;列出待填写位置。`--facts` 再核对正文里的类名、文件、接口、表名:在对比分支的 diff 和代码里都找不到的记为警告(防编造) |
392
392
  | `workflow/scripts/requirement.mjs which / bind / path / sync / pending / list / config` | 产物按需求归档(`workflow-run/docs/requirements/<需求>/`,独立文档仓库模式再分 `<项目>/`):查当前分支绑定的需求(没绑定时给出按分支名生成的建议名)、绑定需求名、给出本次落盘路径(不覆盖,带上一版的 wiki 记录)、重建 `meta.json`、列出所有需求;`config` 设置产物位置(文档仓库、项目名、提交提示),`pending` 看文档仓库里还没提交的产物 |
393
- | `workflow/scripts/view.mjs [--out f] [--open]` | 项目文档视图(`/workflow view`、`workflow-run view`):读需求目录里的产物,生成单个 HTML,按需求列出各阶段、审查记录(各级别数量、复核、与上次对比)、交付记录、沉淀到的知识文档,正文直接渲染;顶部「知识文档」列出每篇知识文档来自哪个需求、哪份产物;数据内嵌,只读、不联网,默认写到 `workflow-run/tmp/view/index.html` |
393
+ | `workflow/scripts/view.mjs [--out f] [--open]` | 项目文档视图(`/workflow view`、`npx @rowansenne/workflow-run view`):读需求目录里的产物,生成单个 HTML,按需求列出各阶段、审查记录(各级别数量、复核、与上次对比)、交付记录、沉淀到的知识文档,正文直接渲染;顶部「知识文档」列出每篇知识文档来自哪个需求、哪份产物;数据内嵌,只读、不联网,默认写到 `workflow-run/tmp/view/index.html` |
394
394
  | `workflow/scripts/artifacts.mjs [--branch b \| --all]` | 按分支汇总 `workflow-run/docs/requirements/` 下的开发方案、交付说明、审查报告、技术方案、上线方案及其 wiki 发布记录,给出下一步建议;分支取自文档元信息行,不另存记录。上线方案没传 `--tech` 时据此自动引用同分支的技术方案;project-review 据此对照本分支方案、识别复审 |
395
- | `workflow/scripts/report.mjs [--since d] [--all-branches] [--json]` | 本地效果报告(`/workflow report`、`workflow-run report`):审查发现与修复率、复核率、需求澄清、沉淀率、知识引用、各分支链路 |
395
+ | `workflow/scripts/report.mjs [--since d] [--all-branches] [--json]` | 本地效果报告(`/workflow report`、`npx @rowansenne/workflow-run report`):审查发现与修复率、复核率、需求澄清、沉淀率、知识引用、各分支链路 |
396
396
  | `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
397
  | `workflow/scripts/template.mjs list / draft / check / save <模板>` | 修改 / 创建模板(`/workflow template`):把当前模板复制成草稿(或 `--from <样例>` 抽骨架),`check` 校验格式、列出章节变化、拿最近几份已生成文档试跑 lint 看影响,`save` 给出写入 DocNexus 知识库的 capture 指引,不直接写知识库;未接入 DocNexus 时 `draft` / `save` 提示先接入(默认模板只读) |
398
398
  | `workflow/scripts/pr-desc.mjs [--branch b] [--base m] [--out f]` | 按本分支产物生成 PR / MR 描述;没有交付说明时退回用 git 记录 |
@@ -424,6 +424,45 @@ CI(`.github/workflows/test.yml`)在 push 到 main 和每个 PR 上运行:m
424
424
  2. 推送 `vx.y.z` tag:`.github/workflows/release.yml` 校验 tag 与版本、CHANGELOG 一致,跑测试,然后用 npm Trusted Publishing 发布(不需要 npm token / OTP)。
425
425
  3. Trusted Publisher 只能给 npm 上已存在的包配置:新包名第一次要在本机登录 npm 后手动 `npm publish --access public`,之后在 npmjs.com 的包设置 → Trusted Publisher 里登记 GitHub 仓库 `guilianerde/skills-init` 与工作流 `release.yml`。
426
426
 
427
+ ## 哪些文件提交、哪些忽略
428
+
429
+ 安装 / 升级时安装器只往项目的 `.gitignore` 追加缺失的规则(已有内容不动),`doctor` 会检查凭据规则还在不在。团队成员照下面两张表即可。
430
+
431
+ **提交**(团队共享):
432
+
433
+ | 路径 | 说明 |
434
+ | --- | --- |
435
+ | `.agents/skills/` | skills 单一来源,含安装清单 `.workflow-run.json` |
436
+ | `.claude/skills/`、`.qwen/skills/`、`.codebuddy/skills/` | 指向 `.agents/skills/` 的相对软链接(Windows 上 clone 需 `git config core.symlinks true`) |
437
+ | `.agents/skills/workflow/profile.json` | 项目画像(无凭据),独立文档仓库模式的项目名也在这里 |
438
+ | `.agents/skills/database-query/references/schema.md` | 表结构速查,补齐后提交 |
439
+ | `workflow-run/docs/requirements/` | 需求产物;独立文档仓库模式下提交到文档仓库 |
440
+ | `workflow-run/docnexus/`(依赖和检索库除外) | DocNexus 工作区与定制的文档模板;独立文档仓库模式下提交到文档仓库 |
441
+ | `.ignore` | 让代码搜索跳过需求目录(不影响 git) |
442
+ | `.gitignore`、`CLAUDE.md` / `AGENTS.md` | 安装器追加的忽略规则、DocNexus 说明段落 |
443
+
444
+ **忽略**(每人每机器一份,或可重新生成):
445
+
446
+ | `.gitignore` 规则 | 忽略的内容 | 何时追加 |
447
+ | --- | --- | --- |
448
+ | `**/database-query/config.json` | 数据库连接(含密码) | 总是 |
449
+ | `**/wiki-config.json` | wiki 地址与 token | 总是 |
450
+ | `**/workflow/profile.local.json` | 个人设置:本机系统与终端、提交提示开关 | 总是 |
451
+ | `/workflow-run/tmp/` | 临时产物:查询导出、wiki 临时 XHTML、旧版产物归档、升级 / 卸载备份、`view` 页面 | `workflow-run/` 不是独立 git 仓库时 |
452
+ | `/workflow-run/` | 整个文档仓库(它自己提交);同时在文档仓库的 `.git/info/exclude` 加 `/tmp/` | 独立文档仓库模式(`docs-repo`) |
453
+ | `node_modules/` | DocNexus 的依赖 | `--with-docnexus` |
454
+ | `.codegraph/` | CodeGraph 本地索引(SQLite) | `--with-codegraph` |
455
+
456
+ 查某个文件为什么被忽略、看当前所有被忽略的文件:
457
+
458
+ ```bash
459
+ git check-ignore -v .agents/skills/database-query/config.json
460
+ ```
461
+
462
+ ```bash
463
+ git status --short --ignored
464
+ ```
465
+
427
466
  ## 凭据安全
428
467
 
429
468
 
@@ -500,7 +539,7 @@ npx @rowansenne/workflow-run docs-repo <团队文档仓库地址> [--project <
500
539
  * 其他服务的需求要先在 `workflow-run/` 里拉下来(`git -C workflow-run pull`),绑定时才看得到。
501
540
  * `/workflow view` 在这个模式下显示文档仓库里所有项目的需求。
502
541
 
503
- **浏览**:`/workflow view` 或 `workflow-run view --open` 生成一个本地页面(`workflow-run/tmp/view/index.html`)。左边是需求列表,可按名称或分支搜索;右边是这个需求的各阶段、审查记录(每轮的级别数量、复核、与上次对比的修复情况)、交付记录,以及各份文档的渲染正文。页面是生成那一刻的快照,产物有更新时重新生成。
542
+ **浏览**:`/workflow view` 或 `npx @rowansenne/workflow-run view --open` 生成一个本地页面(`workflow-run/tmp/view/index.html`)。左边是需求列表,可按名称或分支搜索;右边是这个需求的各阶段、审查记录(每轮的级别数量、复核、与上次对比的修复情况)、交付记录,以及各份文档的渲染正文。页面是生成那一刻的快照,产物有更新时重新生成。
504
543
 
505
544
  其他产物:
506
545
 
@@ -36,7 +36,7 @@ export function doctor(root, offline) {
36
36
  if (!found.length) { bad('未找到安装清单:本项目还没用 workflow-run 安装过'); return 1; }
37
37
  const m = found[0].m;
38
38
  const c = cmpVersion(m.version ?? '0', PKG.version);
39
- if (c < 0) meh(`已安装 ${m.version},当前包是 ${PKG.version}:运行 workflow-run upgrade 升级`);
39
+ if (c < 0) meh(`已安装 ${m.version},当前包是 ${PKG.version}:运行 npx @rowansenne/workflow-run upgrade 升级`);
40
40
  else if (c > 0) meh(`已安装 ${m.version},比当前包 ${PKG.version} 新(当前包版本过旧)`);
41
41
  else ok(`已安装版本 ${m.version}(环境 ${(m.envs ?? []).join(',')},模式 ${m.mode})`);
42
42
 
@@ -45,11 +45,11 @@ export function doctor(root, offline) {
45
45
  let modified = 0, missing = 0;
46
46
  for (const [skill, entry] of Object.entries(man.skills)) {
47
47
  const dir = path.join(base, skill);
48
- if (!fs.existsSync(dir)) { bad(`${toPosix(path.join(rel, skill))} 不存在:运行 workflow-run upgrade 恢复`); continue; }
48
+ if (!fs.existsSync(dir)) { bad(`${toPosix(path.join(rel, skill))} 不存在:运行 npx @rowansenne/workflow-run upgrade 恢复`); continue; }
49
49
  for (const [f, h] of Object.entries(entry.files ?? {})) {
50
50
  const file = path.join(dir, f);
51
51
  const label = toPosix(path.join(rel, skill, f));
52
- if (!fs.existsSync(file)) { missing++; meh(`缺少 ${label}:运行 workflow-run upgrade 恢复`); }
52
+ if (!fs.existsSync(file)) { missing++; meh(`缺少 ${label}:运行 npx @rowansenne/workflow-run upgrade 恢复`); }
53
53
  else if (fileHash(file) !== h) { modified++; meh(`${label} 被手动修改过(升级时会被新版覆盖,原文件备份到 workflow-run/tmp/upgrade-backup/;项目定制请放到 profile.json 或 DocNexus,模板只能在 DocNexus 里定制)`); }
54
54
  }
55
55
  }
@@ -67,7 +67,7 @@ export function doctor(root, offline) {
67
67
  for (const skill of Object.keys(canon.m.skills)) {
68
68
  const link = path.join(dir, skill);
69
69
  const st = lstat(link);
70
- if (!st) bad(`${d}/${skill} 不存在:运行 workflow-run upgrade 重建`);
70
+ if (!st) bad(`${d}/${skill} 不存在:运行 npx @rowansenne/workflow-run upgrade 重建`);
71
71
  else if (!st.isSymbolicLink()) { if (!readManifest(dir)) meh(`${d}/${skill} 是普通目录而非软链接(可能是建链接失败后的独立拷贝)`); else good++; }
72
72
  else if (!fs.existsSync(link)) bad(`${d}/${skill} 是断开的软链接`);
73
73
  else good++;
@@ -84,7 +84,7 @@ export function doctor(root, offline) {
84
84
  if (fs.existsSync(resolveJs)) {
85
85
  const r = spawnSync(process.execPath, [resolveJs, '--root', root, 'status'], { encoding: 'utf8' });
86
86
  try { st = JSON.parse(r.stdout); } catch { bad(`resolve.mjs status 执行失败:${(r.stderr || '').trim().split('\n')[0]}`); }
87
- } else bad('缺少 workflow/scripts/resolve.mjs:运行 workflow-run upgrade');
87
+ } else bad('缺少 workflow/scripts/resolve.mjs:运行 npx @rowansenne/workflow-run upgrade');
88
88
  if (st) {
89
89
  if (st.profile.ok) ok('项目画像已填写'); else meh(`项目画像未完成(空字段:${st.profile.empty.join('、')}):运行 /workflow profile`);
90
90
  if (st.wiki.ok) ok('wiki 已配置'); else console.log(' -- wiki 未配置(可选;也可能通过 wiki MCP 提供)');
@@ -93,7 +93,7 @@ export function doctor(root, offline) {
93
93
  const linked = INSTALL_BASES.some((b) => lstat(path.join(root, b, 'docnexus-recall'))?.isSymbolicLink());
94
94
  const ctx = ['CLAUDE.md', 'AGENTS.md'].some((f) => { try { return fs.readFileSync(path.join(root, f), 'utf8').includes('workflow-run:docnexus:start'); } catch { return false; } });
95
95
  if (linked && ctx) ok(`DocNexus 在 ${HOME}/docnexus/,本项目已链接它的 skills 并写入段落`);
96
- else meh(`DocNexus 在 ${HOME}/docnexus/,但本项目${linked ? '' : '缺少 docnexus skill 链接'}${!linked && !ctx ? '、' : ''}${ctx ? '' : '缺少 CLAUDE.md / AGENTS.md 里的 DocNexus 段落'}:运行 workflow-run upgrade`);
96
+ else meh(`DocNexus 在 ${HOME}/docnexus/,但本项目${linked ? '' : '缺少 docnexus skill 链接'}${!linked && !ctx ? '、' : ''}${ctx ? '' : '缺少 CLAUDE.md / AGENTS.md 里的 DocNexus 段落'}:运行 npx @rowansenne/workflow-run upgrade`);
97
97
  }
98
98
  // 产出目录:都在 workflow-run/
99
99
  const mode = st.artifacts?.mode === 'repo' ? `独立文档仓库(${HOME}/ 自己是 git 仓库)` : '随项目提交';
@@ -107,11 +107,11 @@ export function doctor(root, offline) {
107
107
  else ok('DocNexus 支持按分类检索(recall --category)');
108
108
  } else console.log(' -- DocNexus 未接入(可选;未接入时只能用 skills 自带的默认模板,不能修改)');
109
109
  // workflow-run/templates/ 已不再生效:模板定制只放 DocNexus
110
- for (const f of st.docnexus.stale_project_templates ?? []) meh(st.docnexus.ok ? `${f} 已不再生效:确认已导入 DocNexus 知识库后删除` : `${f} 已不再生效(模板定制只放 DocNexus):重跑 workflow-run 并加 --with-docnexus 接入后导入知识库,再删除`);
111
- for (const t of st.templates_need_docnexus ?? []) console.log(` -- ${t.skill} 的模板 ${t.id} 不随 skills 提供,要先接入 DocNexus 才能创建(重跑 workflow-run 并加 --with-docnexus)`);
110
+ for (const f of st.docnexus.stale_project_templates ?? []) meh(st.docnexus.ok ? `${f} 已不再生效:确认已导入 DocNexus 知识库后删除` : `${f} 已不再生效(模板定制只放 DocNexus):重跑 npx @rowansenne/workflow-run 并加 --with-docnexus 接入后导入知识库,再删除`);
111
+ for (const t of st.templates_need_docnexus ?? []) console.log(` -- ${t.skill} 的模板 ${t.id} 不随 skills 提供,要先接入 DocNexus 才能创建(重跑 npx @rowansenne/workflow-run 并加 --with-docnexus)`);
112
112
  for (const t of st.templates_to_create ?? []) console.log(` -- ${t.skill} 的模板 ${t.id} 还没有创建(不随 skills 提供):第一次生成文档时会请你给一份样例文档来创建,保存到 ${t.expected}`);
113
113
  if (st.codegraph?.ok) ok(`CodeGraph 已接入(codegraph ${codegraphVersion(root)},索引在 .codegraph/)`);
114
- else if (st.codegraph?.indexed) meh('有 .codegraph/ 索引但找不到 codegraph 命令:npm i -g @colbymchenry/codegraph,或重跑 workflow-run 并加 --with-codegraph');
114
+ else if (st.codegraph?.indexed) meh('有 .codegraph/ 索引但找不到 codegraph 命令:npm i -g @colbymchenry/codegraph,或重跑 npx @rowansenne/workflow-run 并加 --with-codegraph');
115
115
  else if (st.codegraph?.cli) console.log(' -- 已装 codegraph,但本项目没有建索引(可选:在项目根运行 codegraph init)');
116
116
  else console.log(' -- CodeGraph 未接入(可选)');
117
117
  if (!st.database.ok) console.log(' -- 数据库未配置(可选)');
@@ -135,7 +135,7 @@ export function doctor(root, offline) {
135
135
  const lines = fs.existsSync(gi) ? fs.readFileSync(gi, 'utf8').split(/\r?\n/).map((l) => l.trim()) : [];
136
136
  const need = ['**/database-query/config.json', '**/wiki-config.json'];
137
137
  const lack = need.filter((r) => !lines.includes(r));
138
- if (lack.length) bad(`.gitignore 缺少 ${lack.join(' ')}:凭据可能被提交,重跑 workflow-run upgrade 补齐`); else ok('凭据文件已被忽略');
138
+ if (lack.length) bad(`.gitignore 缺少 ${lack.join(' ')}:凭据可能被提交,重跑 npx @rowansenne/workflow-run upgrade 补齐`); else ok('凭据文件已被忽略');
139
139
 
140
140
  console.log(`\n${errors.length} 个错误,${warns.length} 个警告`);
141
141
  return errors.length ? 1 : 0;
@@ -140,9 +140,9 @@ export function updateTemplates(root, tplDir, records = {}, { ok = console.log,
140
140
 
141
141
  export const STATUS_TEXT = {
142
142
  current: '与默认模板一致',
143
- outdated: '默认模板有新版,库中模板未改动:运行 workflow-run seed-templates --update 更新',
144
- customized: '团队改过,默认模板也有新版:运行 workflow-run seed-templates --diff 查看差异后手动合并',
143
+ outdated: '默认模板有新版,库中模板未改动:运行 npx @rowansenne/workflow-run seed-templates --update 更新',
144
+ customized: '团队改过,默认模板也有新版:运行 npx @rowansenne/workflow-run seed-templates --diff 查看差异后手动合并',
145
145
  edited: '团队改过(默认模板无变化)',
146
- untracked: '没有导入记录,内容与默认模板不同:如需采用新默认模板,运行 workflow-run seed-templates --diff 对比',
147
- missing: '知识库中缺失:运行 workflow-run seed-templates 导入(upgrade 时会自动导入)',
146
+ untracked: '没有导入记录,内容与默认模板不同:如需采用新默认模板,运行 npx @rowansenne/workflow-run seed-templates --diff 对比',
147
+ missing: '知识库中缺失:运行 npx @rowansenne/workflow-run seed-templates 导入(upgrade 时会自动导入)',
148
148
  };
@@ -244,7 +244,7 @@ async function main() {
244
244
  // upgrade 顺带的导入是尽力而为:失败只提示,不让升级本身算失败
245
245
  const explicit = o.seedTemplates || o.withDocNexus;
246
246
  seedFailed = explicit && r.failed.length > 0;
247
- if (!explicit && r.failed.length) warn('新增模板导入失败(skills 已升级):修复后运行 workflow-run seed-templates 重试');
247
+ if (!explicit && r.failed.length) warn('新增模板导入失败(skills 已升级):修复后运行 npx @rowansenne/workflow-run seed-templates 重试');
248
248
  if (upgradeSeed && !r.seeded.length && !r.failed.length) ok('知识库里的文档模板齐全,无需导入');
249
249
  } catch (e) { warn(e.message); seedFailed = o.seedTemplates || o.withDocNexus; }
250
250
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rowansenne/workflow-run",
3
- "version": "0.21.0",
3
+ "version": "0.21.2",
4
4
  "description": "项目级 Agent Skills 一键初始化:workflow / dev / project-review / code-graph / database-query / md-to-wiki / 技术与上线方案生成",
5
5
  "keywords": [
6
6
  "agent-skills",
@@ -36,7 +36,7 @@ description: "Entry point for this project's dev workflow skills: routes a reque
36
36
  | 改技术方案 / 上线方案 / 交付说明 / 审查报告的模板,按样例建模板 | `/workflow template` | 草稿 → 校验与影响 → 用户确认后写入 DocNexus(默认模板只读,未接入 DocNexus 时不能改) |
37
37
  | 记住 / 查找项目决策与约定 | DocNexus(入口 skill `docnexus`) | 需已接入;写入必须用户授权 |
38
38
 
39
- 意图明确时直接按对应 skill 执行,不必先输出这张表。目标 skill 没有安装(`resolve.mjs status` 输出的 `skills` 里没有它,安装时用了 `--skills` 子集)→ 告诉用户可以运行 `workflow-run --skills <名称>` 补装,不要假装执行。意图横跨多个阶段时按下面的「完整链路」逐段推进,每段结束告诉用户下一段是什么,由用户决定是否继续。走到哪一步不靠记忆:运行 `node <skills>/workflow/scripts/artifacts.mjs [--branch <分支>]`,它扫描 `workflow-run/docs/requirements/` 下的产物,按元信息行里的分支归组,输出每类最新的一份、wiki 发布记录和 `next`(下一步建议)。
39
+ 意图明确时直接按对应 skill 执行,不必先输出这张表。目标 skill 没有安装(`resolve.mjs status` 输出的 `skills` 里没有它,安装时用了 `--skills` 子集)→ 告诉用户可以运行 `npx @rowansenne/workflow-run --skills <名称>` 补装,不要假装执行。意图横跨多个阶段时按下面的「完整链路」逐段推进,每段结束告诉用户下一段是什么,由用户决定是否继续。走到哪一步不靠记忆:运行 `node <skills>/workflow/scripts/artifacts.mjs [--branch <分支>]`,它扫描 `workflow-run/docs/requirements/` 下的产物,按元信息行里的分支归组,输出每类最新的一份、wiki 发布记录和 `next`(下一步建议)。
40
40
 
41
41
  ### 完整链路(从需求到上线)
42
42
 
@@ -9,9 +9,9 @@
9
9
  |---|---|---|
10
10
  | 项目画像 | ✅ / ⚠️ 部分字段为空 | <空字段>;运行 /workflow profile |
11
11
  | wiki | ✅ / ❌ | 填写 md-to-wiki/wiki-config.json 或接入 wiki MCP |
12
- | DocNexus | ✅ / ❌ | 重跑 workflow-run 并加 --with-docnexus;已接入但缺模板时列出缺的模板并提示 `workflow-run seed-templates`;未接入时说明默认模板只读、不能定制,技术方案 / 上线方案要先接入(`templates_need_docnexus`);`stale_project_templates` 非空时提示这些项目模板已不再生效 |
12
+ | DocNexus | ✅ / ❌ | 重跑 npx @rowansenne/workflow-run 并加 --with-docnexus;已接入但缺模板时列出缺的模板并提示 `npx @rowansenne/workflow-run seed-templates`;未接入时说明默认模板只读、不能定制,技术方案 / 上线方案要先接入(`templates_need_docnexus`);`stale_project_templates` 非空时提示这些项目模板已不再生效 |
13
13
  | 数据库 | ✅ / ❌ | 重跑 `npx @rowansenne/workflow-run` 补配 |
14
- | 代码图谱 | ✅ / ⚠️ 已装未建索引 / ❌ | 重跑 workflow-run 并加 --with-codegraph;已装 codegraph 但没有 .codegraph/ 时提示用户自己运行 codegraph init |
14
+ | 代码图谱 | ✅ / ⚠️ 已装未建索引 / ❌ | 重跑 npx @rowansenne/workflow-run 并加 --with-codegraph;已装 codegraph 但没有 .codegraph/ 时提示用户自己运行 codegraph init |
15
15
 
16
16
  ## 当前分支 <分支>
17
17
  | 环节 | 产物 | wiki |
@@ -13,18 +13,18 @@ node <skills>/workflow/scripts/resolve.mjs template <skill> <文件名>
13
13
  判定规则(实现在脚本里,这里只是说明):
14
14
 
15
15
  - **已接入 DocNexus**:只用 `workflow-run/docnexus/library/templates/<skill>/<文件名>`(分类 `doc-template`,普通 Markdown,手工改动立即生效)。不使用 skill 默认模板,也不使用 `workflow-run/templates/`——知识库是唯一来源,避免几份模板各自演化。
16
- - 缺模板时退出码 2,输出 `expected`(应在的位置)、`import_from`(可导入的来源)和 `hint`。**停下这一步**,告诉用户缺哪份模板,给两个选择:在项目根运行 `workflow-run seed-templates`(或重跑安装加 `--seed-templates`);或者由你在用户确认后按 DocNexus 的 capture 流程把 `import_from` 写入 `expected`,以显式分类封存(`draft seal ... --category doc-template`,metadata.category 也写 `doc-template`)。导入后再继续。
16
+ - 缺模板时退出码 2,输出 `expected`(应在的位置)、`import_from`(可导入的来源)和 `hint`。**停下这一步**,告诉用户缺哪份模板,给两个选择:在项目根运行 `npx @rowansenne/workflow-run seed-templates`(或重跑安装加 `--seed-templates`);或者由你在用户确认后按 DocNexus 的 capture 流程把 `import_from` 写入 `expected`,以显式分类封存(`draft seal ... --category doc-template`,metadata.category 也写 `doc-template`)。导入后再继续。
17
17
  - **未接入 DocNexus**:只用 skill 默认模板,不能修改或新建模板。
18
18
  - 输出里 `stale_project_file` 非空:`workflow-run/templates/` 下的这份已不再生效,提醒用户导入 DocNexus 后删除(未接入时先接入)。
19
19
  - **技术方案、上线方案没有默认模板**(`create-tech-md-doc`、`create-release-md-doc` 的 `template.md`):各团队发到 wiki 的格式不同,skills 不自带固定格式,第一次使用时按样例创建到知识库。
20
20
  - 已接入 DocNexus、还没创建:退出码 2,输出 `on_demand: true`、`expected`(知识库里的位置)和 `hint`,按下面「创建模板」处理。
21
- - 未接入 DocNexus:退出码 2,输出 `need_docnexus: true` 和 `hint`。**停下这一步**,告诉用户这两类文档的模板只保存在 DocNexus 里,要先重跑 workflow-run 并加 `--with-docnexus` 接入,再创建模板。不要自己编一份模板凑数。
21
+ - 未接入 DocNexus:退出码 2,输出 `need_docnexus: true` 和 `hint`。**停下这一步**,告诉用户这两类文档的模板只保存在 DocNexus 里,要先重跑 npx @rowansenne/workflow-run 并加 `--with-docnexus` 接入,再创建模板。不要自己编一份模板凑数。
22
22
 
23
- `resolve.mjs templates` 列出所有登记模板的来源;登记表在各 skill 的 `skill.json`(`templates` 字段)。`--with-docnexus` 接入时会自动导入默认模板,之后可运行 `workflow-run seed-templates` 补导入(已存在的不覆盖)。
23
+ `resolve.mjs templates` 列出所有登记模板的来源;登记表在各 skill 的 `skill.json`(`templates` 字段)。`--with-docnexus` 接入时会自动导入默认模板,之后可运行 `npx @rowansenne/workflow-run seed-templates` 补导入(已存在的不覆盖)。
24
24
 
25
25
  ## 修改模板(/workflow template)
26
26
 
27
- 用户要改某份模板(「技术方案模板加一节回滚」「上线方案去掉灰度那节」「审查报告的严重问题表加一列」),或要新建、按样例重做模板时,用 `template.mjs` 一路走完,不要直接编辑生效中的模板文件。未接入 DocNexus 时 `draft` / `save` 退出码 2、输出 `need_docnexus: true`:告诉用户默认模板不能改,要先接入 DocNexus(重跑 workflow-run 并加 `--with-docnexus`),不要另找地方保存。`<模板>` 写别名 `tech` / `release` / `plan` / `delivery` / `review` / `checklist`,或 `<skill>/<文件名>`;没说哪份时先 `template.mjs list` 列出来问。
27
+ 用户要改某份模板(「技术方案模板加一节回滚」「上线方案去掉灰度那节」「审查报告的严重问题表加一列」),或要新建、按样例重做模板时,用 `template.mjs` 一路走完,不要直接编辑生效中的模板文件。未接入 DocNexus 时 `draft` / `save` 退出码 2、输出 `need_docnexus: true`:告诉用户默认模板不能改,要先接入 DocNexus(重跑 npx @rowansenne/workflow-run 并加 `--with-docnexus`),不要另找地方保存。`<模板>` 写别名 `tech` / `release` / `plan` / `delivery` / `review` / `checklist`,或 `<skill>/<文件名>`;没说哪份时先 `template.mjs list` 列出来问。
28
28
 
29
29
  1. **起草稿**:`node <skills>/workflow/scripts/template.mjs draft <模板>`,把当前生效的模板复制到 `workflow-run/tmp/template-draft/<skill>/<文件名>`(输出的 `draft`)。草稿已存在会沿用(上次没改完);要从当前模板重来加 `--force`。
30
30
  - 退出码 2、`need_sample: true`:还没有这份模板,按下面「创建模板」第 1 步向用户要样例,再运行 `draft <模板> --from <样例文件>`(从 stdin 读用 `--from -`)。用户要「按这份文档重做模板」时同样用 `--from`。
@@ -39,7 +39,7 @@ export function run(root, args, opts = {}) {
39
39
  const entry = cliEntry(root);
40
40
  if (entry) return spawnSync(process.execPath, [entry, ...args], o);
41
41
  const bin = docnexusBin(root);
42
- if (!bin) return { status: 1, error: 'DocNexus 没装:重跑 workflow-run 并加 --with-docnexus' };
42
+ if (!bin) return { status: 1, error: 'DocNexus 没装:重跑 npx @rowansenne/workflow-run 并加 --with-docnexus' };
43
43
  return spawnSync(path.resolve(root, bin), args, { ...o, shell: process.platform === 'win32' });
44
44
  }
45
45
 
@@ -58,7 +58,7 @@ export function codegraphStatus(root) {
58
58
  const cli = r.status === 0;
59
59
  return {
60
60
  ok: indexed && cli, cli, indexed,
61
- how: cli && indexed ? null : !cli ? '重跑 workflow-run 并加 --with-codegraph(或 npm i -g @colbymchenry/codegraph)' : '在项目根运行 codegraph init 建索引(由用户决定)',
61
+ how: cli && indexed ? null : !cli ? '重跑 npx @rowansenne/workflow-run 并加 --with-codegraph(或 npm i -g @colbymchenry/codegraph)' : '在项目根运行 codegraph init 建索引(由用户决定)',
62
62
  };
63
63
  }
64
64
 
@@ -90,7 +90,7 @@ export function resolveTemplate(root, skill, id) {
90
90
  return {
91
91
  ok: false, ...res, error: 'missing', expected: rel(root, lib),
92
92
  import_from: fs.existsSync(project) ? rel(root, project) : rel(root, builtin),
93
- hint: '已接入 DocNexus,只使用知识库中的模板。停下这一步告诉用户缺这份模板:可在项目根运行 workflow-run seed-templates(或重跑安装加 --seed-templates),或经用户确认后把 import_from 按 capture 流程写入 expected(以显式分类 --category doc-template 封存)。',
93
+ hint: '已接入 DocNexus,只使用知识库中的模板。停下这一步告诉用户缺这份模板:可在项目根运行 npx @rowansenne/workflow-run seed-templates(或重跑安装加 --seed-templates),或经用户确认后把 import_from 按 capture 流程写入 expected(以显式分类 --category doc-template 封存)。',
94
94
  };
95
95
  }
96
96
  // 未接入 DocNexus:只用 skill 自带的默认模板(只读,不能改);没有默认版本的(技术方案、上线方案)要先接入 DocNexus 才能创建
@@ -98,7 +98,7 @@ export function resolveTemplate(root, skill, id) {
98
98
  if (!builtin) {
99
99
  return {
100
100
  ok: false, ...res, error: 'missing', need_docnexus: true, expected: rel(root, lib),
101
- hint: `这份模板不随 skills 提供,自定义模板只保存在 DocNexus 知识库里(便于团队共享),本项目还没有接入 DocNexus。停下这一步告诉用户:先重跑 workflow-run 并加 --with-docnexus 接入${stale ? `(项目里的 ${stale} 已不再生效,接入后可导入知识库)` : ''},再${CREATE}。`,
101
+ hint: `这份模板不随 skills 提供,自定义模板只保存在 DocNexus 知识库里(便于团队共享),本项目还没有接入 DocNexus。停下这一步告诉用户:先重跑 npx @rowansenne/workflow-run 并加 --with-docnexus 接入${stale ? `(项目里的 ${stale} 已不再生效,接入后可导入知识库)` : ''},再${CREATE}。`,
102
102
  };
103
103
  }
104
104
  return { ok: true, ...res, source: 'default', path: rel(root, builtin) };
@@ -193,7 +193,7 @@ export function status(root) {
193
193
  stale_project_templates: templates.map((t) => t.stale_project_file).filter(Boolean),
194
194
  // 各 skill 写入时使用的显式分类(没声明的 skill 不列出)
195
195
  categories: Object.fromEntries(skillMetas().map((m) => [m.name, resolveCategory(root, m.name)]).filter(([, c]) => c.ok).map(([n, c]) => [n, c.category])),
196
- how: dn ? '缺模板时运行 workflow-run seed-templates' : '重跑 workflow-run 并加 --with-docnexus',
196
+ how: dn ? '缺模板时运行 npx @rowansenne/workflow-run seed-templates' : '重跑 npx @rowansenne/workflow-run 并加 --with-docnexus',
197
197
  },
198
198
  // 产物位置:项目里(默认)或独立文档仓库(workflow/references/requirements.md)
199
199
  artifacts: (() => { const L = layout(root); return { mode: L.mode, ok: L.ok, ...(L.mode === 'repo' ? { repo: L.repo_rel, project: L.project, commit_prompt: L.commit_prompt } : { dir: 'workflow-run/docs/requirements' }), how: L.ok ? null : L.hint }; })(),
@@ -203,7 +203,7 @@ export function status(root) {
203
203
  ok: !!db?.connections && Object.keys(db.connections).length > 0,
204
204
  default: db?.default_connection ?? (db?.connections?.default ? 'default' : null),
205
205
  connections: Object.fromEntries(Object.entries(db?.connections ?? {}).map(([k, c]) => [k, { driver: c.driver ?? 'mysql', readonly: c.readonly !== false }])),
206
- how: '重跑 workflow-run 补配数据库',
206
+ how: '重跑 npx @rowansenne/workflow-run 补配数据库',
207
207
  },
208
208
  templates: templates.map(({ skill, id, source, path: p2, ok, on_demand, need_docnexus, expected }) => ({ skill, id, ok, source: source ?? 'missing', path: p2 ?? null, ...(on_demand ? { on_demand: true, expected } : {}), ...(need_docnexus ? { need_docnexus: true } : {}) })),
209
209
  // 不随 skills 提供、还没创建的模板(技术方案、上线方案):第一次生成文档时按「创建模板」引导用户创建
@@ -51,7 +51,7 @@ export function target(name) {
51
51
  }
52
52
 
53
53
  // 未接入 DocNexus:默认模板只读,不能改也不能新建
54
- const NEED_DOCNEXUS = '默认模板随 skills 提供、只读不能改;自定义模板只保存在 DocNexus 知识库里,便于团队共享。告诉用户先重跑 workflow-run 并加 --with-docnexus 接入,再修改或创建模板。';
54
+ const NEED_DOCNEXUS = '默认模板随 skills 提供、只读不能改;自定义模板只保存在 DocNexus 知识库里,便于团队共享。告诉用户先重跑 npx @rowansenne/workflow-run 并加 --with-docnexus 接入,再修改或创建模板。';
55
55
  const needDocNexus = (t, r) => ({ code: 2, out: { ok: false, skill: t.skill, id: t.id, docnexus: false, need_docnexus: true, current: r.ok ? r.path : null, hint: NEED_DOCNEXUS } });
56
56
 
57
57
  const draftPath = (root, { skill, id }) => path.join(root, 'workflow-run', 'tmp', 'template-draft', skill, id);