agentic-flow-kit 0.2.0 → 0.3.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.
Files changed (70) hide show
  1. package/README.md +4 -2
  2. package/modules/gates/dotnet-ca/check-architecture.sh +14 -10
  3. package/modules/hosts/trae/commands/wf-build.md +14 -14
  4. package/modules/hosts/trae/commands/wf-deploy.md +13 -13
  5. package/modules/hosts/trae/commands/wf-design.md +13 -13
  6. package/modules/hosts/trae/commands/wf-maintain.md +13 -13
  7. package/modules/hosts/trae/commands/wf-new-task.md +13 -13
  8. package/modules/hosts/trae/commands/wf-plan.md +13 -13
  9. package/modules/hosts/trae/commands/wf-review.md +13 -13
  10. package/modules/hosts/trae/commands/wf-test.md +14 -14
  11. package/modules/hosts/trae/hooks/post-edit-check.cjs +10 -0
  12. package/modules/hosts/trae/hooks/pre-shell-check.cjs +14 -4
  13. package/modules/hosts/trae/hooks/resolve-shell.cjs +30 -21
  14. package/modules/hosts/trae/rules/beautify-input-chinese.md +6 -6
  15. package/modules/hosts/trae/rules/git-commit-message.md +10 -10
  16. package/package.json +10 -2
  17. package/src/add-gate.mjs +8 -1
  18. package/src/add-host.mjs +4 -0
  19. package/src/cli.mjs +8 -5
  20. package/src/doctor.mjs +9 -2
  21. package/src/init.mjs +96 -12
  22. package/src/init.test.mjs +56 -0
  23. package/src/profiles.mjs +8 -0
  24. package/src/render.mjs +8 -9
  25. package/src/run-tests.mjs +1 -0
  26. package/src/sync.mjs +20 -4
  27. package/src/sync.test.mjs +40 -1
  28. package/templates/AGENTS.md +3 -2
  29. package/templates/_agents/board/index.html +449 -382
  30. package/templates/_agents/board/marked.min.js +6 -6
  31. package/templates/_agents/cache/kb-index.json +1 -1
  32. package/templates/_agents/commands/build.md +1 -1
  33. package/templates/_agents/commands/design.md +1 -1
  34. package/templates/_agents/commands/maintain.md +1 -1
  35. package/templates/_agents/commands/new-task.md +73 -73
  36. package/templates/_agents/commands/plan.md +2 -2
  37. package/templates/_agents/commands/test.md +2 -1
  38. package/templates/_agents/hooks/check-pairing-incremental.sh +30 -29
  39. package/templates/_agents/hooks/commit-check.cjs +6 -1
  40. package/templates/_agents/scripts/agg-delegations.cjs +35 -18
  41. package/templates/_agents/scripts/agg-delegations.test.mjs +95 -0
  42. package/templates/_agents/scripts/check-loop.sh +6 -0
  43. package/templates/_agents/scripts/check-loop.test.sh +1042 -1042
  44. package/templates/_agents/scripts/commit-check-trigger.test.mjs +94 -0
  45. package/templates/_agents/scripts/ensure-board.ps1 +1 -1
  46. package/templates/_agents/scripts/gen-wiki-board.mjs +13 -3
  47. package/templates/_agents/scripts/gen-wiki-board.test.mjs +22 -0
  48. package/templates/_agents/scripts/gen-workflow-index.mjs +7 -2
  49. package/templates/_agents/scripts/gen-workflow-index.test.mjs +27 -0
  50. package/templates/_agents/scripts/gen-workflow-metrics.mjs +17 -3
  51. package/templates/_agents/scripts/gen-workflow-metrics.test.mjs +21 -0
  52. package/templates/_agents/scripts/kb-search.mjs +2 -1
  53. package/templates/_agents/scripts/rule-budget.sh +8 -2
  54. package/templates/_agents/scripts/verify-wiki-consistency.mjs +6 -1
  55. package/templates/_agents/scripts/verify.mjs +36 -0
  56. package/templates/_agents/scripts/verify.test.mjs +77 -0
  57. package/templates/_agents/scripts/workflow-board-server.mjs +245 -244
  58. package/templates/_githooks/commit-msg +4 -2
  59. package/templates/_githooks/pre-push +32 -32
  60. package/templates/wiki/INDEX.md +9 -2
  61. package/templates/wiki//344/272/247/345/223/201/351/234/200/346/261/202/README.md +3 -0
  62. package/templates/wiki//345/274/200/345/217/221/346/226/271/346/241/210/README.md +3 -0
  63. package/templates/wiki//346/225/260/346/215/256/347/273/264/346/212/244/README.md +3 -0
  64. package/templates/wiki//346/265/213/350/257/225/346/212/245/345/221/212/README.md +3 -0
  65. package/templates/wiki//347/224/250/346/210/267/345/212/237/350/203/275/README.md +3 -0
  66. package/templates/wiki//351/241/271/347/233/256/350/247/204/350/214/203/README.md +3 -0
  67. package/templates/wiki//351/241/271/347/233/256/350/256/241/345/210/222/README.md +3 -0
  68. package/templates/workflow/README.md +2 -2
  69. package/templates/workflow/intents/_TEMPLATE.md +40 -40
  70. package/templates/workflow/specs/_TEMPLATE.md +41 -41
package/README.md CHANGED
@@ -46,7 +46,7 @@ modules/gates/ 可选门禁模块(dotnet-ca:Clean Architecture 参考
46
46
 
47
47
  **两态文件模型**:`.agents/kit.json` 记录 managed(引擎件,随包升级)与 owned(项目内容,永不覆盖)清单及 sha256;`doctor` 会校验漂移。已存在的文件 init 保守跳过(`--force` 覆盖)。
48
48
 
49
- **升级语义(sync)**:managed 文件三方比对(台账 sha / 磁盘 sha / 新版渲染 sha)——未改动 → 直接覆盖新版;本地已改 → 跳过并报告(`--force` 才覆盖,git diff 自查差异);改动恰好等于新版 → 视为已最新。包内新增文件自动安装;包内已删文件仅报告不删盘;缺失的 managed 文件自动恢复。INDEX / wiki 看板等生成器目标不比对 sha,收尾重跑生成器走锚点重写。门禁模块(add-gate 装入)归项目所有,sync 永不覆盖。
49
+ **升级语义(sync)**:managed 文件三方比对(台账 sha / 磁盘 sha / 新版渲染 sha)——未改动 → 直接覆盖新版;本地已改 → 跳过并报告(`--force` 才覆盖,git diff 自查差异;跳过件的台账保持包侧基线,后续每次 sync 持续报告,不会在下次升级被静默覆盖——消除报告的办法:`--force` 覆盖,或把本地内容改回与新版一致);改动恰好等于新版 → 视为已最新。包内新增文件自动安装;包内已删文件仅报告不删盘;缺失的 managed 文件自动恢复。INDEX / wiki 看板等生成器目标不比对 sha,收尾重跑生成器走锚点重写。门禁模块(add-gate 装入)归项目所有,sync 永不覆盖。add-host 对已存在的宿主文件保守跳过且不入台账——后续 sync 不升级(仅报告「已存在未入台账」),要纳入包管理用 `--force` 覆盖。owned 件归项目所有、sync 永不覆盖;其台账哈希仅记账不约束,sync 每次按盘面自愈刷新(手改后无须手工对账),add-gate 接线 local-pre-commit 后同步刷新其记账。
50
50
 
51
51
  ## 设计原则
52
52
 
@@ -59,4 +59,6 @@ modules/gates/ 可选门禁模块(dotnet-ca:Clean Architecture 参考
59
59
 
60
60
  - [x] v0.1.0:init(flags 模式)+ doctor + 4 宿主适配 + dotnet-ca 门禁模块
61
61
  - [x] v0.2.0:sync 升级(未动覆盖 / 已改跳过报告 + `--force` / 生成器锚点重写)+ add-host / add-gate
62
- - [ ] npm 发布
62
+ - [x] v0.2.0 已发布:npm view agentic-flow-kit(npx agentic-flow-kit init 即用;默认镜像源用户需等 npmmirror 同步或 --registry npmjs)
63
+ - [x] v0.2.1:Shipyard 回流第二笔(模板引用去死链 + owned 台账记账策略:add-gate 接线刷新 + sync 盘面自愈)+ 全项目审查修复(量化台账 fail-loud / 生成器锚点与 ENOENT 守卫 / sync 跳过件持续报告 / P4 清账 / metrics glob 词表收口)——已发布
64
+ - [x] v0.3.0:init 交互升级(序号菜单 + ANSI 色彩降级 + ts/js 技术栈别名归一 node)+ AGENTS.md 骨架探测补齐(已存在无标记时文末追加,原内容保留)+ wiki 模板预置 7 主题内容目录 + 关单 verify 固定编排(npm test + check-loop 一键过门,非绿不关单)+ workflow 看板纸墨视觉改版
@@ -78,6 +78,8 @@ if [ -z "$PY_BIN" ]; then
78
78
  violations="$violations
79
79
  - 红线 4.3 无法执行:未找到 python/python3/py(Domain 导航属性扫描依赖 Python;门禁 fail-closed,不静默放行)"
80
80
  else
81
+ # 2026-09-24:①python 运行期报错也 fail-closed(原只对「没装 python」兜底,脚本报错时 nav_hits 为空即放行);
82
+ # ②属性匹配改全文 finditer——支持「{ 换行」与 expression-bodied(=>)形态,先剥注释防误报
81
83
  nav_hits=$(DOMAIN_ENTITIES_DIR="$DOMAIN_ENTITIES_DIR" SHARED_TYPES="$SHARED_TYPES" "$PY_BIN" - <<'PYEOF'
82
84
  import re, glob, os
83
85
  from os import environ
@@ -91,19 +93,20 @@ for f in files:
91
93
  hits = []
92
94
  for f in files:
93
95
  with open(f, encoding='utf-8-sig') as fh:
94
- for i, line in enumerate(fh, 1):
95
- m = re.match(r'\s*public\s+(?:virtual\s+)?([\w<>,\s\.\?]+?)\s+(\w+)\s*\{', line)
96
- if not m:
97
- continue
98
- typ = m.group(1).strip()
99
- mm = re.search(r'(?:ICollection|List|IEnumerable|IReadOnlyCollection|IReadOnlyList)<\s*(\w+)\s*>', typ)
100
- core = mm.group(1) if mm else (typ.rstrip('?') if re.fullmatch(r'\w+\??', typ) else None)
101
- if core and (core in names or core in shared):
102
- hits.append(f"{os.path.basename(f)}:{i} {m.group(2)} : {typ}")
96
+ src = re.sub(r'/\*.*?\*/', '', fh.read(), flags=re.S)
97
+ src = re.sub(r'//[^\n]*', '', src)
98
+ for m in re.finditer(r'\bpublic\s+(?:virtual\s+)?([\w<>, \t.\?]+?)\s+(\w+)\s*(?:\{|=>)', src):
99
+ typ = m.group(1).strip()
100
+ mm = re.search(r'(?:ICollection|List|IEnumerable|IReadOnlyCollection|IReadOnlyList)<\s*(\w+)\s*>', typ)
101
+ core = mm.group(1) if mm else (typ.rstrip('?') if re.fullmatch(r'\w+\??', typ) else None)
102
+ if core and (core in names or core in shared):
103
+ ln = src.count('\n', 0, m.start()) + 1
104
+ hits.append(f"{os.path.basename(f)}:{ln} {m.group(2)} : {typ}")
103
105
  if hits:
104
106
  print('\n'.join(hits))
105
107
  PYEOF
106
- )
108
+ ) || violations="$violations
109
+ - 红线 4.3 无法执行:python 扫描异常退出(fail-closed,不静默放行;诊断见上方 stderr)"
107
110
  fi
108
111
  if [ -n "$nav_hits" ]; then
109
112
  violations="$violations
@@ -112,6 +115,7 @@ $nav_hits"
112
115
  fi
113
116
 
114
117
  # 红线 5:Controller 禁把 InnerException 原文透传进响应体(详情只许进日志)
118
+ # 已知天花板:grep 按整行排除 Log 调用——透传与 Log 写在同一行可绕过;语义级排除需 AST 工具,参考实现门禁按接受记录(2026-09-24)
115
119
  inner_hits=$(grep -rn "InnerException" "$CONTROLLERS_DIR" --include="*.cs" 2>/dev/null \
116
120
  | grep -v -e "/obj/" -e "/bin/" \
117
121
  | grep -vE "Log(Warning|Error|Information|Debug|Trace)")
@@ -1,14 +1,14 @@
1
- ---
2
- name: wf-build
3
- description: Build 阶段 · 起 plan + 实现代码 + 自验(两道确认门,确认后才动代码)
4
- ---
5
-
6
- 严格按 AGENTS.md 与 .agents/commands/build.md 执行:Build 阶段 · 起 plan + 实现代码 + 自验。
7
-
8
- 先完整读取上述两个文件并完全遵循,读不到即停下报告阻塞;本文件不内联步骤副本,避免与权威版本漂移。
9
-
10
- 【Trae 宿主注记】
11
- - 两道确认门:① plan 草稿确认(draft→approved)② 计划模式列改动文件清单确认——两道全过才动代码。
12
- - 范围明确的工作包可委派 implementer(.trae/agents/implementer.md);子智能体未开启时按 fallback: main 由主智能体按同一角色契约执行。
13
- - 实现中需偏离已确认 plan(公共接口 / 未列文件 / 新依赖 / 判据影响)→ 停下向用户说明,确认后再继续。
14
- - 完成后进 wf-test。
1
+ ---
2
+ name: wf-build
3
+ description: Build 阶段 · 起 plan + 实现代码 + 自验(两道确认门,确认后才动代码)
4
+ ---
5
+
6
+ 严格按 AGENTS.md 与 .agents/commands/build.md 执行:Build 阶段 · 起 plan + 实现代码 + 自验。
7
+
8
+ 先完整读取上述两个文件并完全遵循,读不到即停下报告阻塞;本文件不内联步骤副本,避免与权威版本漂移。
9
+
10
+ 【Trae 宿主注记】
11
+ - 两道确认门:① plan 草稿确认(draft→approved)② 计划模式列改动文件清单确认——两道全过才动代码。
12
+ - 范围明确的工作包可委派 implementer(.trae/agents/implementer.md);子智能体未开启时按 fallback: main 由主智能体按同一角色契约执行。
13
+ - 实现中需偏离已确认 plan(公共接口 / 未列文件 / 新依赖 / 判据影响)→ 停下向用户说明,确认后再继续。
14
+ - 完成后进 wf-test。
@@ -1,13 +1,13 @@
1
- ---
2
- name: wf-deploy
3
- description: Deploy 阶段 · prod 上线清单(静态门 / 配对 / 回归 / DB / 授权 / 24h 观察;关单在 wf-test)
4
- ---
5
-
6
- 严格按 AGENTS.md 与 .agents/commands/deploy.md 执行:Deploy 阶段 · prod 上线清单(静态门 / 配对检查 / 回归 / DB / 授权 / 24h 观察;文档关单在 wf-test,本阶段不重复关单)。
7
-
8
- 先完整读取上述两个文件并完全遵循,读不到即停下报告阻塞;本文件不内联步骤副本,避免与权威版本漂移。
9
-
10
- 【Trae 宿主注记】
11
- - 确认门:上线授权 = 用户对话内一句确认 + release/<日期> tag 留痕;无第二审批人,AI 不得自行上线。
12
- - 本阶段不委派子智能体;回滚 SQL 等数据安全判断由主智能体做、用户拍板。
13
- - 异常进 wf-maintain;用户确认无异常 = prod 闭环,AI 不得自行宣告。
1
+ ---
2
+ name: wf-deploy
3
+ description: Deploy 阶段 · prod 上线清单(静态门 / 配对 / 回归 / DB / 授权 / 24h 观察;关单在 wf-test)
4
+ ---
5
+
6
+ 严格按 AGENTS.md 与 .agents/commands/deploy.md 执行:Deploy 阶段 · prod 上线清单(静态门 / 配对检查 / 回归 / DB / 授权 / 24h 观察;文档关单在 wf-test,本阶段不重复关单)。
7
+
8
+ 先完整读取上述两个文件并完全遵循,读不到即停下报告阻塞;本文件不内联步骤副本,避免与权威版本漂移。
9
+
10
+ 【Trae 宿主注记】
11
+ - 确认门:上线授权 = 用户对话内一句确认 + release/<日期> tag 留痕;无第二审批人,AI 不得自行上线。
12
+ - 本阶段不委派子智能体;回滚 SQL 等数据安全判断由主智能体做、用户拍板。
13
+ - 异常进 wf-maintain;用户确认无异常 = prod 闭环,AI 不得自行宣告。
@@ -1,13 +1,13 @@
1
- ---
2
- name: wf-design
3
- description: Design 阶段 · 起 spec(L2/L3 强制,L1 可省略直接进 wf-build)
4
- ---
5
-
6
- 严格按 AGENTS.md 与 .agents/commands/design.md 执行:Design 阶段 · 起 spec(L2/L3 强制,L1 可省略直接进 wf-build)。
7
-
8
- 先完整读取上述两个文件并完全遵循,读不到即停下报告阻塞;本文件不内联步骤副本,避免与权威版本漂移。
9
-
10
- 【Trae 宿主注记】
11
- - 确认门:spec 草稿经用户确认;L3 另有独立复核门,复核未过不得确认。
12
- - L3 独立复核委派 independent-reviewer(.trae/agents/independent-reviewer.md);子智能体未开启时按 fallback: new-session 另开新会话,不得由原会话自查冒充。
13
- - 确认后进 wf-build。
1
+ ---
2
+ name: wf-design
3
+ description: Design 阶段 · 起 spec(L2/L3 强制,L1 可省略直接进 wf-build)
4
+ ---
5
+
6
+ 严格按 AGENTS.md 与 .agents/commands/design.md 执行:Design 阶段 · 起 spec(L2/L3 强制,L1 可省略直接进 wf-build)。
7
+
8
+ 先完整读取上述两个文件并完全遵循,读不到即停下报告阻塞;本文件不内联步骤副本,避免与权威版本漂移。
9
+
10
+ 【Trae 宿主注记】
11
+ - 确认门:spec 草稿经用户确认;L3 另有独立复核门,复核未过不得确认。
12
+ - L3 独立复核委派 independent-reviewer(.trae/agents/independent-reviewer.md);子智能体未开启时按 fallback: new-session 另开新会话,不得由原会话自查冒充。
13
+ - 确认后进 wf-build。
@@ -1,13 +1,13 @@
1
- ---
2
- name: wf-maintain
3
- description: Maintain 阶段 · 立 incident + 复盘三件套(incident 在 L1+ 即 intent 等价物)
4
- ---
5
-
6
- 严格按 AGENTS.md 与 .agents/commands/maintain.md 执行:Maintain 阶段 · 立 incident + 复盘三件套(incident 在 L1+ 即 intent 等价物,不必另造 intent)。
7
-
8
- 先完整读取上述两个文件并完全遵循,读不到即停下报告阻塞;本文件不内联步骤副本,避免与权威版本漂移。
9
-
10
- 【Trae 宿主注记】
11
- - 确认门:止血方案由用户拍板(AI 只执行选定方案);三件套草稿经用户确认后才落地。
12
- - 配 plan 的时点与形态以权威文件为准——incident≡intent 免掉的是 intent,plan 不可免(commit / push 两处门禁按同名硬拦)。
13
- - 复现路径与验收明确的局部热修可委派 implementer(.trae/agents/implementer.md);事故诊断、根因定性与三件套起草不委派。
1
+ ---
2
+ name: wf-maintain
3
+ description: Maintain 阶段 · 立 incident + 复盘三件套(incident 在 L1+ 即 intent 等价物)
4
+ ---
5
+
6
+ 严格按 AGENTS.md 与 .agents/commands/maintain.md 执行:Maintain 阶段 · 立 incident + 复盘三件套(incident 在 L1+ 即 intent 等价物,不必另造 intent)。
7
+
8
+ 先完整读取上述两个文件并完全遵循,读不到即停下报告阻塞;本文件不内联步骤副本,避免与权威版本漂移。
9
+
10
+ 【Trae 宿主注记】
11
+ - 确认门:止血方案由用户拍板(AI 只执行选定方案);三件套草稿经用户确认后才落地。
12
+ - 配 plan 的时点与形态以权威文件为准——incident≡intent 免掉的是 intent,plan 不可免(commit / push 两处门禁按同名硬拦)。
13
+ - 复现路径与验收明确的局部热修可委派 implementer(.trae/agents/implementer.md);事故诊断、根因定性与三件套起草不委派。
@@ -1,13 +1,13 @@
1
- ---
2
- name: wf-new-task
3
- description: 闭环总入口 · 路由判断(新需求 → wf-plan / 修复 → wf-maintain)+ 级别判断(L0-L3)
4
- ---
5
-
6
- 严格按 AGENTS.md 与 .agents/commands/new-task.md 执行:闭环总入口 · 路由判断(新需求 intent → wf-plan / 修复 incident → wf-maintain)+ 级别判断(L0-L3)。
7
-
8
- 先完整读取上述两个文件并完全遵循,读不到即停下报告阻塞;本文件不内联步骤副本,避免与权威版本漂移。
9
-
10
- 【Trae 宿主注记】
11
- - 输出路由结论与级别,指明进入哪个 wf-*.md;不并阶段、不跳阶段。
12
- - approval_required 阶段产出未经用户对话内一句话确认,不得进入下一阶段。
13
- - 宿主级差异(规则惰性加载 / 终端 shell / 子智能体开关 / 门禁冗余)见 alwaysApply 规则 `.trae/rules/project-workflow.md`,不在此重复。
1
+ ---
2
+ name: wf-new-task
3
+ description: 闭环总入口 · 路由判断(新需求 → wf-plan / 修复 → wf-maintain)+ 级别判断(L0-L3)
4
+ ---
5
+
6
+ 严格按 AGENTS.md 与 .agents/commands/new-task.md 执行:闭环总入口 · 路由判断(新需求 intent → wf-plan / 修复 incident → wf-maintain)+ 级别判断(L0-L3)。
7
+
8
+ 先完整读取上述两个文件并完全遵循,读不到即停下报告阻塞;本文件不内联步骤副本,避免与权威版本漂移。
9
+
10
+ 【Trae 宿主注记】
11
+ - 输出路由结论与级别,指明进入哪个 wf-*.md;不并阶段、不跳阶段。
12
+ - approval_required 阶段产出未经用户对话内一句话确认,不得进入下一阶段。
13
+ - 宿主级差异(规则惰性加载 / 终端 shell / 子智能体开关 / 门禁冗余)见 alwaysApply 规则 `.trae/rules/project-workflow.md`,不在此重复。
@@ -1,13 +1,13 @@
1
- ---
2
- name: wf-plan
3
- description: Plan 阶段 · 立 intent(AI 起草、用户确认;本阶段不委派子智能体)
4
- ---
5
-
6
- 严格按 AGENTS.md 与 .agents/commands/plan.md 执行:Plan 阶段 · 立 intent(AI 起草、用户确认;本阶段不委派子智能体)。
7
-
8
- 先完整读取上述两个文件并完全遵循,读不到即停下报告阻塞;本文件不内联步骤副本,避免与权威版本漂移。
9
-
10
- 【Trae 宿主注记】
11
- - 确认门:intent 草稿全文输出给用户过目,一句"可以"即确认(draft→approved),确认前不进下一阶段。
12
- - 已有 approved intent 时按级别跳转:L1 → wf-build;L2/L3 → wf-design。
13
- - 本阶段不委派子智能体,由主智能体起草;任务入口动作与红线勾选口径以权威文件为准。
1
+ ---
2
+ name: wf-plan
3
+ description: Plan 阶段 · 立 intent(AI 起草、用户确认;本阶段不委派子智能体)
4
+ ---
5
+
6
+ 严格按 AGENTS.md 与 .agents/commands/plan.md 执行:Plan 阶段 · 立 intent(AI 起草、用户确认;本阶段不委派子智能体)。
7
+
8
+ 先完整读取上述两个文件并完全遵循,读不到即停下报告阻塞;本文件不内联步骤副本,避免与权威版本漂移。
9
+
10
+ 【Trae 宿主注记】
11
+ - 确认门:intent 草稿全文输出给用户过目,一句"可以"即确认(draft→approved),确认前不进下一阶段。
12
+ - 已有 approved intent 时按级别跳转:L1 → wf-build;L2/L3 → wf-design。
13
+ - 本阶段不委派子智能体,由主智能体起草;任务入口动作与红线勾选口径以权威文件为准。
@@ -1,13 +1,13 @@
1
- ---
2
- name: wf-review
3
- description: Review · 代码评审(横切,合入前使用;P0/P1/P2 分级清单 + 用户定性与合入时机)
4
- ---
5
-
6
- 严格按 AGENTS.md 与 .agents/commands/review.md 执行:Review · 代码评审(横切,合入前使用;P0/P1/P2 分级清单 + 用户定性与合入时机)。
7
-
8
- 先完整读取上述两个文件并完全遵循,读不到即停下报告阻塞;本文件不内联步骤副本,避免与权威版本漂移。
9
-
10
- 【Trae 宿主注记】
11
- - 顺序:机器门禁自动拦 → independent-reviewer 复核(L2/L3 强制独立,子智能体未开启时另开新会话)→ 分级清单交用户定性与决定合入时机。
12
- - 确认门:P0/P1 未清回 wf-build;清零且用户确认后才可合入。
13
- - finding 报告门(防误报)与机器兜底清单以权威文件为准。
1
+ ---
2
+ name: wf-review
3
+ description: Review · 代码评审(横切,合入前使用;P0/P1/P2 分级清单 + 用户定性与合入时机)
4
+ ---
5
+
6
+ 严格按 AGENTS.md 与 .agents/commands/review.md 执行:Review · 代码评审(横切,合入前使用;P0/P1/P2 分级清单 + 用户定性与合入时机)。
7
+
8
+ 先完整读取上述两个文件并完全遵循,读不到即停下报告阻塞;本文件不内联步骤副本,避免与权威版本漂移。
9
+
10
+ 【Trae 宿主注记】
11
+ - 顺序:机器门禁自动拦 → independent-reviewer 复核(L2/L3 强制独立,子智能体未开启时另开新会话)→ 分级清单交用户定性与决定合入时机。
12
+ - 确认门:P0/P1 未清回 wf-build;清零且用户确认后才可合入。
13
+ - finding 报告门(防误报)与机器兜底清单以权威文件为准。
@@ -1,14 +1,14 @@
1
- ---
2
- name: wf-test
3
- description: Test 阶段 · 静态门 + 切库冒烟 + UI 实测 + L2/L3 独立复核(关单在本阶段)
4
- ---
5
-
6
- 严格按 AGENTS.md 与 .agents/commands/test.md 执行:Test 阶段 · 静态门全过 + 切库冒烟(如触发)+ UI 实测 + L2/L3 独立复核。
7
-
8
- 先完整读取上述两个文件并完全遵循,读不到即停下报告阻塞;本文件不内联步骤副本,避免与权威版本漂移。
9
-
10
- 【Trae 宿主注记】
11
- - 确认门:全过后用户确认才关单;**关单在本阶段**(勾验收 / incident 状态 / 委派留痕的口径以权威文件为准)。
12
- - UI 实测委派 ui-verifier(.trae/agents/ui-verifier.md);L2/L3 独立复核委派 independent-reviewer,子智能体未开启时另开新会话。
13
- - 失败项修复仍回 wf-build,不在本阶段顺手改代码。
14
- - L1 到此结束;L2/L3 仅当用户确认要上 prod 才进 wf-deploy。
1
+ ---
2
+ name: wf-test
3
+ description: Test 阶段 · 静态门 + 切库冒烟 + UI 实测 + L2/L3 独立复核(关单在本阶段)
4
+ ---
5
+
6
+ 严格按 AGENTS.md 与 .agents/commands/test.md 执行:Test 阶段 · 静态门全过 + 切库冒烟(如触发)+ UI 实测 + L2/L3 独立复核。
7
+
8
+ 先完整读取上述两个文件并完全遵循,读不到即停下报告阻塞;本文件不内联步骤副本,避免与权威版本漂移。
9
+
10
+ 【Trae 宿主注记】
11
+ - 确认门:全过后用户确认才关单;**关单在本阶段**(勾验收 / incident 状态 / 委派留痕的口径以权威文件为准)。
12
+ - UI 实测委派 ui-verifier(.trae/agents/ui-verifier.md);L2/L3 独立复核委派 independent-reviewer,子智能体未开启时另开新会话。
13
+ - 失败项修复仍回 wf-build,不在本阶段顺手改代码。
14
+ - L1 到此结束;L2/L3 仅当用户确认要上 prod 才进 wf-deploy。
@@ -75,6 +75,16 @@ try {
75
75
  }));
76
76
  process.exit(0);
77
77
  }
78
+ // 门禁脚本未装(未跑 add-gate dotnet-ca)≠ 发现违例——区分口径,对齐 pre-shell-check 的 ENOENT 处理(2026-09-24)
79
+ if (e.code === 'ENOENT') {
80
+ console.log(JSON.stringify({
81
+ hookSpecificOutput: {
82
+ hookEventName: 'PostToolUse',
83
+ additionalContext: '⚠️ 架构红线检查未执行:check-architecture.sh 未安装(flow-kit add-gate dotnet-ca 装入)——本次编辑未验证。'
84
+ }
85
+ }));
86
+ process.exit(0);
87
+ }
78
88
  const err = String((e.stderr || '') + (e.stdout || '')).slice(0, 800);
79
89
  console.log(JSON.stringify({
80
90
  hookSpecificOutput: {
@@ -4,7 +4,7 @@
4
4
  * 1) deny/ask 命令门禁(口径同 .agents/settings.json 的 deny/ask 策略)
5
5
  * 2) git commit / git push 前置检查:直接调 .githooks/pre-commit / pre-push
6
6
  *
7
- * 为什么调 .githooks/*:那是项目唯一的门禁权威(pre-commit 六项 + pre-push 闭环断档)。
7
+ * 为什么调 .githooks/*:那是项目唯一的门禁权威(pre-commit 门禁链 + pre-push 闭环断档)。
8
8
  * 本钩子是**宿主侧冗余**——core.hooksPath 漏配时 git 侧门禁静默失效(2026-09-16 Trae 侧缺档事故),
9
9
  * 由这里在命令执行前拦下;门禁清单只维护 .githooks/ 一份,本文件不复制。
10
10
  *
@@ -90,13 +90,23 @@ const askList = [
90
90
  { pat: 'rm -rf', reason: '可能递归删除文件' }
91
91
  ];
92
92
 
93
+ // gateMatch:比裸 includes 收紧两处(2026-09-24)——
94
+ // ① token 边界:'git push --force' 不再误拦 '--force-with-lease'、'git commit' 不再误吃 'git commit-msg'
95
+ // ② 剥离 git 全局参 -c <k=v> 与 -m <msg> 后以剥后文本为准——堵 'git -c x=y push --force' 绕过,
96
+ // 也免得消息字样误触发;剥不出(norm===cmd)再按原文匹配
97
+ function gateMatch(cmd, pat) {
98
+ const re = new RegExp(pat.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + '(?![\\w-])');
99
+ const norm = cmd.replace(/(^|\s)-[cm]\s+\S+(?=\s|$)/g, ' ').replace(/\s+/g, ' ').trim();
100
+ return norm !== cmd ? re.test(norm) : re.test(cmd);
101
+ }
102
+
93
103
  for (const d of denyList) {
94
- if (command.includes(d.pat)) {
104
+ if (gateMatch(command, d.pat)) {
95
105
  deny(`禁止执行: ${d.pat}(项目红线:${d.reason})`);
96
106
  }
97
107
  }
98
108
  for (const a of askList) {
99
- if (command.includes(a.pat)) {
109
+ if (gateMatch(command, a.pat)) {
100
110
  ask(`需确认: ${a.pat}(项目 ask 策略:${a.reason})`);
101
111
  }
102
112
  }
@@ -135,7 +145,7 @@ function runGate(scriptRelPath, label, budgetMs) {
135
145
  }
136
146
 
137
147
  if (isCommit) {
138
- // pre-commit 六项:架构红线 + 审计字段 + 删除拦截 + 闭环配对(增量)+ 敏感信息 + 条件编译
148
+ // pre-commit 门禁链(通用包口径):闭环配对(增量)+ wiki 台账(增量)+ 常驻面预算 + 项目门禁(local-pre-commit)+ 敏感信息扫描与条件构建
139
149
  // 预算 5 分钟覆盖 dotnet build / npm run build(.githooks/pre-commit 内部无超时)
140
150
  runGate('.githooks/pre-commit', '提交前门禁', 300000);
141
151
  }
@@ -1,21 +1,30 @@
1
- // shell 探测(供 .trae/hooks/ 各钩子共用)
2
- // Windows 下 bash 常不在 PATH:优先 Git Bash 绝对路径,回退 PATH 的 bash/sh。
3
- // 返回 null 表示不可用——调用方须 fail-closed 报告「门禁未执行」,不要当成检查通过。
4
- const { execFileSync } = require('child_process');
5
- const fs = require('fs');
6
-
7
- function resolveShell() {
8
- const candidates = [
9
- 'C:\\Program Files\\Git\\bin\\bash.exe',
10
- 'C:\\Program Files (x86)\\Git\\bin\\bash.exe'
11
- ];
12
- for (const p of candidates) {
13
- try { fs.accessSync(p); return p; } catch { /* 尝试下一个 */ }
14
- }
15
- for (const c of ['bash', 'sh']) {
16
- try { execFileSync(c, ['-c', 'exit 0'], { stdio: 'pipe', timeout: 5000 }); return c; } catch { /* 尝试下一个 */ }
17
- }
18
- return null;
19
- }
20
-
21
- module.exports = { resolveShell };
1
+ // shell 探测(供 .trae/hooks/ 各钩子共用)
2
+ // Windows 下 bash 常不在 PATH:优先 Git Bash 绝对路径,回退 PATH 的 bash/sh。
3
+ // 返回 null 表示不可用——调用方须 fail-closed 报告「门禁未执行」,不要当成检查通过。
4
+ const { execFileSync } = require('child_process');
5
+ const fs = require('fs');
6
+
7
+ function resolveShell() {
8
+ const candidates = [
9
+ 'C:\\Program Files\\Git\\bin\\bash.exe',
10
+ 'C:\\Program Files (x86)\\Git\\bin\\bash.exe'
11
+ ];
12
+ for (const p of candidates) {
13
+ try { fs.accessSync(p); return p; } catch { /* 尝试下一个 */ }
14
+ }
15
+ // PATH 回退须避开 WSL 启动器:C:\Windows\System32\bash.exe 能过 exit 0 探测,但路径/行尾语义是 Linux 侧的(2026-09-24)
16
+ for (const c of ['bash', 'sh']) {
17
+ let cand = c;
18
+ try {
19
+ const hits = execFileSync('where.exe', [c], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] })
20
+ .split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
21
+ const good = hits.find((p) => !/system32/i.test(p)); // 全部命中都在 System32(纯 WSL)→ 跳过该候选
22
+ if (good) cand = good;
23
+ else continue;
24
+ } catch { /* where 不可用(非 Windows):按原名探测,保持旧行为 */ }
25
+ try { execFileSync(cand, ['-c', 'exit 0'], { stdio: 'pipe', timeout: 5000 }); return cand; } catch { /* 尝试下一个 */ }
26
+ }
27
+ return null;
28
+ }
29
+
30
+ module.exports = { resolveShell };
@@ -1,6 +1,6 @@
1
- ---
2
- alwaysApply: false
3
- scene: beautify_input
4
- ---
5
-
6
- 请使用中文回复。所有解释、说明、注释和对话均使用中文。
1
+ ---
2
+ alwaysApply: false
3
+ scene: beautify_input
4
+ ---
5
+
6
+ 请使用中文回复。所有解释、说明、注释和对话均使用中文。
@@ -1,10 +1,10 @@
1
- ---
2
- alwaysApply: false
3
- scene: git_message
4
- ---
5
-
6
- 提交信息一律中文,遵循 Conventional Commits:`<类型>(<范围>): <说明>`,例如 `fix(采购订单): 页签切换浮层收纳`、`docs(trae): 同步工作流适配层`。
7
-
8
- - 类型枚举:feat / fix / docs / style / refactor / perf;`.githooks/commit-msg` 按此硬校验首行,非枚举前缀会被拦下,merge / revert 提交豁免。
9
- - 范围可省:`fix: 说明` 同样合法;分隔符 `:` 或 `(` 均可。
10
- - 禁止 `[feat] 说明` 这类方括号写法。
1
+ ---
2
+ alwaysApply: false
3
+ scene: git_message
4
+ ---
5
+
6
+ 提交信息一律中文,遵循 Conventional Commits:`<类型>(<范围>): <说明>`,例如 `fix(采购订单): 页签切换浮层收纳`、`docs(trae): 同步工作流适配层`。
7
+
8
+ - 类型枚举:feat / fix / docs / style / refactor / perf;`.githooks/commit-msg` 按此硬校验首行,非枚举前缀会被拦下,merge / revert 提交豁免。
9
+ - 范围可省:`fix: 说明` 同样合法;分隔符 `:` 或 `(` 均可。
10
+ - 禁止 `[feat] 说明` 这类方括号写法。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-flow-kit",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "AI-Native 闭环工作流 + wiki 知识层脚手架——flow-kit init 一条命令为新项目装好 .agents 工作流引擎(阶段命令/角色契约/门禁钩子/kb 检索/看板/规则面预算)+ workflow 文档闭环 + wiki 知识库,装完自包含、零运行时依赖",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -30,5 +30,13 @@
30
30
  "closed-loop"
31
31
  ],
32
32
  "license": "MIT",
33
- "private": false
33
+ "private": false,
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "git+https://github.com/zerosloney/agentic-flow-kit.git"
37
+ },
38
+ "bugs": {
39
+ "url": "https://github.com/zerosloney/agentic-flow-kit/issues"
40
+ },
41
+ "homepage": "https://github.com/zerosloney/agentic-flow-kit#readme"
34
42
  }
package/src/add-gate.mjs CHANGED
@@ -52,6 +52,7 @@ export function addGate(args, pkgRoot) {
52
52
  if (skipped.length) console.log(` 跳过(已存在,--force 覆盖):${skipped.join('、')}`);
53
53
 
54
54
  // 接线 local-pre-commit(幂等:挂载行已存在不重复;旧装态尾部 exit 0 会吞掉其后门禁的失败——归一化剥掉)
55
+ let wiredLp = false;
55
56
  if (wireLine) {
56
57
  const lpPath = path.join(hooksDir, 'local-pre-commit');
57
58
  const cur = fs.existsSync(lpPath) ? fs.readFileSync(lpPath, 'utf8') : '';
@@ -67,15 +68,21 @@ export function addGate(args, pkgRoot) {
67
68
  const body = lines.length ? `${lines.join('\n')}\n` : '#!/bin/sh\nset -e\n';
68
69
  fs.writeFileSync(lpPath, `${body}${wireLine}\n`);
69
70
  console.log(` local-pre-commit 接线:+ ${wireLine}`);
71
+ wiredLp = true;
70
72
  }
71
73
  }
72
74
 
73
- // owned 台账补记(归项目所有,sync 永不覆盖)
75
+ // owned 台账补记(归项目所有,sync 永不覆盖)。接线改写了 local-pre-commit(init 时按模板态记账)——
76
+ // 须同步刷新其 owned 哈希,否则台账停在模板态(Shipyard 回流发现的漂移根因,2026-09-24)
74
77
  const ownedLedger = new Map((kit.owned || []).map((f) => [f.rel, f]));
75
78
  for (const name of installed) {
76
79
  const rel = `.agents/hooks/${name}`;
77
80
  ownedLedger.set(rel, { rel, sha256: sha256(fs.readFileSync(path.join(hooksDir, name))) });
78
81
  }
82
+ if (wiredLp) {
83
+ const lpRel = '.agents/hooks/local-pre-commit';
84
+ ownedLedger.set(lpRel, { rel: lpRel, sha256: sha256(fs.readFileSync(path.join(hooksDir, 'local-pre-commit'))) });
85
+ }
79
86
  kit.owned = [...ownedLedger.values()].sort((a, b) => a.rel.localeCompare(b.rel));
80
87
  fs.writeFileSync(kitPath, `${JSON.stringify(kit, null, 2)}\n`);
81
88
 
package/src/add-host.mjs CHANGED
@@ -39,6 +39,10 @@ export function addHost(args, pkgRoot) {
39
39
  const r = renderTree(path.join(pkgRoot, 'modules', 'hosts', host), path.join(target, HOSTS[host].dir), vars, { force });
40
40
  if (!r.written.length && r.skipped.length) console.log(' 跳过(已存在,未覆盖):' + r.skipped.join('、'));
41
41
  else console.log(` 安装 ${r.written.length} 份${r.skipped.length ? `,跳过已存在 ${r.skipped.length} 份` : ''}`);
42
+ if (r.skipped.length) {
43
+ // 跳过的文件不入 managed 台账(不接管既有内容)——后续 sync 只报「已存在未入台账」,永不升级;纳入包管理须 --force
44
+ console.log(' ⚠️ 跳过文件不入 managed 台账、后续 sync 不升级(每次仅报告);纳入包管理用 --force 覆盖');
45
+ }
42
46
 
43
47
  // managed 台账按 rel 去重补记
44
48
  const ledger = new Map((kit.managed || []).map((f) => [f.rel, f]));
package/src/cli.mjs CHANGED
@@ -14,15 +14,18 @@ const PKG_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'
14
14
  export const HELP = `flow-kit — AI-Native 闭环工作流 + wiki 知识层脚手架(agentic-flow-kit)
15
15
 
16
16
  用法:
17
- flow-kit init 安装到当前项目(裸跑无参数 → 交互确认环节;带参数直接执行)
18
- flow-kit sync 升级 managed 文件(未改动→覆盖新版;本地已改→跳过并报告,--force 才覆盖;
19
- INDEX/看板等生成器目标重跑锚点重写;owned 文件永不触碰)
20
- flow-kit add-host <宿主> 后补宿主适配层:zcode | opencode | trae | omp
17
+ flow-kit init 安装到当前项目(裸跑无参数 → 交互确认环节;带参数直接执行;
18
+ 已存在的 AGENTS.md 无工作流骨架时文末追加补齐,其余已存在文件保守跳过)
19
+ flow-kit sync 升级 managed 文件(未改动→覆盖新版;本地已改→跳过并持续报告——台账不基线化,
20
+ 不会被下次升级静默覆盖;--force 才覆盖;INDEX/看板等生成器目标重跑锚点重写;
21
+ owned 文件永不触碰)
22
+ flow-kit add-host <宿主> 后补宿主适配层:zcode | opencode | trae | omp(已存在文件跳过且不入台账,--force 接管)
21
23
  flow-kit add-gate <门禁> 装门禁模块并接线 local-pre-commit(当前:dotnet-ca;装后归项目所有)
22
24
  flow-kit doctor 体检:目录布局 / git 钩子 / managed 清单 / 索引漂移 / check-loop
23
25
 
24
26
  init 选项(全部可选,均有默认值):
25
- --stack <技术栈> dotnet | node | python | go | none(默认 none)——门禁配置三处:commit-check
27
+ --stack <技术栈> dotnet | node(ts/js) | python | go | none(默认 none;ts/js/typescript/javascript
28
+ 归一为 node)——门禁配置三处:commit-check
26
29
  条件编译检查(builds)与质量检测(checks:lint/类型/vet 等秒级确定性检查,
27
30
  有对应配置文件才启用)、settings.json 自检验命令权限(allow)、
28
31
  AGENTS.md「项目适配区」命令预填
package/src/doctor.mjs CHANGED
@@ -120,6 +120,13 @@ export function doctor(args, pkgRoot) {
120
120
  if (idx.status === 0) add('PASS', 'workflow/INDEX.md 无漂移');
121
121
  else add('WARN', `workflow/INDEX.md 漂移——跑 node .agents/scripts/gen-workflow-index.mjs 重生成`);
122
122
 
123
+ // 6.5 delegations 台账结构(量化层非门禁:结构漂移曾静默吞掉全部记录,2026-09-24)
124
+ if (fs.existsSync(path.join(target, '.agents/scripts/agg-delegations.cjs'))) {
125
+ const agg = spawnSync(process.execPath, ['.agents/scripts/agg-delegations.cjs'], { cwd: target, encoding: 'utf8' });
126
+ if (agg.status === 0) add('PASS', 'delegations 台账结构有效(agg 可解析)');
127
+ else add('WARN', `delegations 台账结构漂移——${String(agg.stderr || agg.stdout || '').split('\n')[0]}`);
128
+ }
129
+
123
130
  // 7. check-loop
124
131
  const cl = spawnSync('sh', ['.agents/scripts/check-loop.sh'], { cwd: target, encoding: 'utf8' });
125
132
  if (cl.status === 0) {
@@ -135,8 +142,8 @@ export function doctor(args, pkgRoot) {
135
142
  portInUse(port).then((inUse) => {
136
143
  print(results);
137
144
  console.log(inUse
138
- ? `ℹ️ 看板端口 ${port} 已有监听(幂等拉起会探活复用;他人进程不 kill,见 workflow/README.md)`
139
- : `ℹ️ 看板端口 ${port} 空闲(首次访问任务入口时由 ensure-board 拉起,或手动 node .agents/scripts/workflow-board-server.mjs)`);
145
+ ? `ℹ️ 看板端口 ${port} 已有监听(ensure-board 探活复用;他人进程不 kill,见 workflow/README.md)`
146
+ : `ℹ️ 看板端口 ${port} 空闲(看板默认不拉起;需要时手动 .agents/scripts/ensure-board.ps1 或 node .agents/scripts/workflow-board-server.mjs)`);
140
147
  process.exit(results.some((r) => r.level === 'FAIL') ? 1 : 0);
141
148
  });
142
149
  }