@kunlv/atdc 1.0.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 (222) hide show
  1. package/AGENTS.md +58 -0
  2. package/GO.md +245 -0
  3. package/bin/add-command.py +144 -0
  4. package/bin/atdc.js +460 -0
  5. package/bin/cls.js +98 -0
  6. package/central/link.sh +60 -0
  7. package/central/ticket_center_server/.handoffs/TASK-238389_QYinVipLimit.md +128 -0
  8. package/central/ticket_center_server/.test_plans/TASK-227254-SupportMembership-self-test-plan.md +566 -0
  9. package/central/ticket_center_server/.test_plans/task-238389-qyin-vip-limit-self-test-plan.md +210 -0
  10. package/commands/claude/atd.md +3 -0
  11. package/commands/claude/atdc/1-spec.md +5 -0
  12. package/commands/claude/atdc/1-update.md +5 -0
  13. package/commands/claude/atdc/2-qa.md +3 -0
  14. package/commands/claude/atdc/3-impl-skip-spec.md +5 -0
  15. package/commands/claude/atdc/3-impl.md +3 -0
  16. package/commands/claude/atdc/4-verify.md +3 -0
  17. package/commands/claude/atdc/5-done.md +3 -0
  18. package/commands/claude/atdc/add-command.md +4 -0
  19. package/commands/claude/atdc/add-to-hc.md +3 -0
  20. package/commands/claude/atdc/analysis-cls-log.md +4 -0
  21. package/commands/claude/atdc/article.md +6 -0
  22. package/commands/claude/atdc/bugfix.md +4 -0
  23. package/commands/claude/atdc/code-simplifier.md +8 -0
  24. package/commands/claude/atdc/commit.md +4 -0
  25. package/commands/claude/atdc/compound.md +5 -0
  26. package/commands/claude/atdc/context.md +3 -0
  27. package/commands/claude/atdc/diagnose.md +8 -0
  28. package/commands/claude/atdc/git-guardrails.md +18 -0
  29. package/commands/claude/atdc/grill-with-docs.md +8 -0
  30. package/commands/claude/atdc/handoff.md +8 -0
  31. package/commands/claude/atdc/health.md +3 -0
  32. package/commands/claude/atdc/learn.md +4 -0
  33. package/commands/claude/atdc/review.md +10 -0
  34. package/commands/claude/atdc/search.md +4 -0
  35. package/commands/claude/atdc/strategy.md +3 -0
  36. package/commands/claude/atdc/table2xlsx.md +4 -0
  37. package/commands/claude/atdc/test-plan.md +5 -0
  38. package/commands/claude/atdc/travel-planner.md +4 -0
  39. package/commands/claude/atdc/xlsx2sql-insert.md +4 -0
  40. package/commands/claude/atdc/xlsx2sql-update.md +4 -0
  41. package/commands/claude/atdc/zoom-out.md +8 -0
  42. package/commands/codex/atdc/SKILL.md +8 -0
  43. package/commands/codex/atdc-1-spec/SKILL.md +8 -0
  44. package/commands/codex/atdc-1-update/SKILL.md +8 -0
  45. package/commands/codex/atdc-2-qa/SKILL.md +8 -0
  46. package/commands/codex/atdc-3-impl/SKILL.md +8 -0
  47. package/commands/codex/atdc-3-impl-skip-spec/SKILL.md +8 -0
  48. package/commands/codex/atdc-4-verify/SKILL.md +8 -0
  49. package/commands/codex/atdc-5-done/SKILL.md +8 -0
  50. package/commands/codex/atdc-add-command/SKILL.md +7 -0
  51. package/commands/codex/atdc-add-to-hc/SKILL.md +8 -0
  52. package/commands/codex/atdc-analysis-cls-log/SKILL.md +5 -0
  53. package/commands/codex/atdc-article/SKILL.md +8 -0
  54. package/commands/codex/atdc-bugfix/SKILL.md +5 -0
  55. package/commands/codex/atdc-code-simplifier/SKILL.md +7 -0
  56. package/commands/codex/atdc-commit/SKILL.md +7 -0
  57. package/commands/codex/atdc-compound/SKILL.md +8 -0
  58. package/commands/codex/atdc-context/SKILL.md +8 -0
  59. package/commands/codex/atdc-diagnose/SKILL.md +9 -0
  60. package/commands/codex/atdc-git-guardrails/SKILL.md +19 -0
  61. package/commands/codex/atdc-grill-with-docs/SKILL.md +9 -0
  62. package/commands/codex/atdc-handoff/SKILL.md +9 -0
  63. package/commands/codex/atdc-health/SKILL.md +8 -0
  64. package/commands/codex/atdc-learn/SKILL.md +7 -0
  65. package/commands/codex/atdc-review/SKILL.md +49 -0
  66. package/commands/codex/atdc-search/SKILL.md +5 -0
  67. package/commands/codex/atdc-strategy/SKILL.md +8 -0
  68. package/commands/codex/atdc-table2xlsx/SKILL.md +8 -0
  69. package/commands/codex/atdc-test-plan/SKILL.md +13 -0
  70. package/commands/codex/atdc-travel-planner/SKILL.md +7 -0
  71. package/commands/codex/atdc-xlsx2sql-insert/SKILL.md +8 -0
  72. package/commands/codex/atdc-xlsx2sql-update/SKILL.md +8 -0
  73. package/commands/codex/atdc-zoom-out/SKILL.md +9 -0
  74. package/commands/cursor/atdc/SKILL.md +8 -0
  75. package/commands/cursor/atdc-1-spec/SKILL.md +8 -0
  76. package/commands/cursor/atdc-1-update/SKILL.md +8 -0
  77. package/commands/cursor/atdc-2-qa/SKILL.md +8 -0
  78. package/commands/cursor/atdc-3-impl/SKILL.md +8 -0
  79. package/commands/cursor/atdc-3-impl-skip-spec/SKILL.md +8 -0
  80. package/commands/cursor/atdc-4-verify/SKILL.md +8 -0
  81. package/commands/cursor/atdc-5-done/SKILL.md +8 -0
  82. package/commands/cursor/atdc-add-command/SKILL.md +7 -0
  83. package/commands/cursor/atdc-add-to-hc/SKILL.md +8 -0
  84. package/commands/cursor/atdc-analysis-cls-log/SKILL.md +5 -0
  85. package/commands/cursor/atdc-article/SKILL.md +8 -0
  86. package/commands/cursor/atdc-bugfix/SKILL.md +5 -0
  87. package/commands/cursor/atdc-code-simplifier/SKILL.md +7 -0
  88. package/commands/cursor/atdc-commit/SKILL.md +7 -0
  89. package/commands/cursor/atdc-compound/SKILL.md +8 -0
  90. package/commands/cursor/atdc-context/SKILL.md +8 -0
  91. package/commands/cursor/atdc-diagnose/SKILL.md +8 -0
  92. package/commands/cursor/atdc-git-guardrails/SKILL.md +18 -0
  93. package/commands/cursor/atdc-grill-with-docs/SKILL.md +8 -0
  94. package/commands/cursor/atdc-handoff/SKILL.md +8 -0
  95. package/commands/cursor/atdc-health/SKILL.md +8 -0
  96. package/commands/cursor/atdc-learn/SKILL.md +7 -0
  97. package/commands/cursor/atdc-review/SKILL.md +49 -0
  98. package/commands/cursor/atdc-search/SKILL.md +5 -0
  99. package/commands/cursor/atdc-strategy/SKILL.md +8 -0
  100. package/commands/cursor/atdc-table2xlsx/SKILL.md +8 -0
  101. package/commands/cursor/atdc-test-plan/SKILL.md +7 -0
  102. package/commands/cursor/atdc-travel-planner/SKILL.md +7 -0
  103. package/commands/cursor/atdc-xlsx2sql-insert/SKILL.md +8 -0
  104. package/commands/cursor/atdc-xlsx2sql-update/SKILL.md +8 -0
  105. package/commands/cursor/atdc-zoom-out/SKILL.md +8 -0
  106. package/commands/opencode/atd.md +6 -0
  107. package/commands/opencode/atdc/1-spec.md +8 -0
  108. package/commands/opencode/atdc/1-update.md +8 -0
  109. package/commands/opencode/atdc/2-qa.md +6 -0
  110. package/commands/opencode/atdc/3-impl-skip-spec.md +8 -0
  111. package/commands/opencode/atdc/3-impl.md +6 -0
  112. package/commands/opencode/atdc/4-verify.md +6 -0
  113. package/commands/opencode/atdc/5-done.md +6 -0
  114. package/commands/opencode/atdc/add-command.md +6 -0
  115. package/commands/opencode/atdc/add-to-hc.md +6 -0
  116. package/commands/opencode/atdc/analysis-cls-log.md +6 -0
  117. package/commands/opencode/atdc/article.md +6 -0
  118. package/commands/opencode/atdc/bugfix.md +6 -0
  119. package/commands/opencode/atdc/code-simplifier.md +8 -0
  120. package/commands/opencode/atdc/commit.md +6 -0
  121. package/commands/opencode/atdc/compound.md +8 -0
  122. package/commands/opencode/atdc/context.md +6 -0
  123. package/commands/opencode/atdc/diagnose.md +8 -0
  124. package/commands/opencode/atdc/git-guardrails.md +18 -0
  125. package/commands/opencode/atdc/grill-with-docs.md +8 -0
  126. package/commands/opencode/atdc/handoff.md +8 -0
  127. package/commands/opencode/atdc/health.md +6 -0
  128. package/commands/opencode/atdc/learn.md +6 -0
  129. package/commands/opencode/atdc/review.md +7 -0
  130. package/commands/opencode/atdc/search.md +6 -0
  131. package/commands/opencode/atdc/strategy.md +6 -0
  132. package/commands/opencode/atdc/table2xlsx.md +6 -0
  133. package/commands/opencode/atdc/test-plan.md +6 -0
  134. package/commands/opencode/atdc/travel-planner.md +6 -0
  135. package/commands/opencode/atdc/xlsx2sql-insert.md +6 -0
  136. package/commands/opencode/atdc/xlsx2sql-update.md +6 -0
  137. package/commands/opencode/atdc/zoom-out.md +8 -0
  138. package/config/cls-defaults.json +19 -0
  139. package/hooks/atd-archive.sh +86 -0
  140. package/hooks/atd-state.sh +165 -0
  141. package/hooks/evidence-hook.sh +88 -0
  142. package/hooks/evidence-log.sh +54 -0
  143. package/hooks/guardrails.sh +65 -0
  144. package/hooks/handoff-compress.sh +104 -0
  145. package/hooks/phase-guard.sh +134 -0
  146. package/hooks/phase-write-guard.sh +96 -0
  147. package/hooks/ponytail-fix.sh +179 -0
  148. package/hooks/ponytail-guard.sh +66 -0
  149. package/hooks/ponytail-scan.sh +62 -0
  150. package/install.sh +276 -0
  151. package/package.json +20 -0
  152. package/packages/cls/bin/cls.js +146 -0
  153. package/packages/cls/config/defaults.json +17 -0
  154. package/packages/cls/mcp/server.js +142 -0
  155. package/packages/cls/package.json +29 -0
  156. package/packages/cls/scripts/postinstall.js +19 -0
  157. package/packages/cls/src/client.js +262 -0
  158. package/prompts/1-spec.md +271 -0
  159. package/prompts/1-update.md +198 -0
  160. package/prompts/2-qa.md +164 -0
  161. package/prompts/3-impl-bugfix.md +271 -0
  162. package/prompts/3-impl.md +419 -0
  163. package/prompts/4-verify.md +160 -0
  164. package/prompts/5-done.md +227 -0
  165. package/prompts/6-article.md +571 -0
  166. package/prompts/X-add-command.md +60 -0
  167. package/prompts/X-add-to-hc.md +178 -0
  168. package/prompts/X-analysis-cls-log.md +68 -0
  169. package/prompts/X-bugfix.md +10 -0
  170. package/prompts/X-code-simplifier.md +38 -0
  171. package/prompts/X-commit.md +116 -0
  172. package/prompts/X-compound.md +188 -0
  173. package/prompts/X-context-scan.md +101 -0
  174. package/prompts/X-diagnose.md +116 -0
  175. package/prompts/X-grill-with-docs.md +120 -0
  176. package/prompts/X-handoff.md +80 -0
  177. package/prompts/X-health.md +78 -0
  178. package/prompts/X-learn.md +151 -0
  179. package/prompts/X-review.md +417 -0
  180. package/prompts/X-search.md +74 -0
  181. package/prompts/X-strategy.md +95 -0
  182. package/prompts/X-table2xlsx.md +46 -0
  183. package/prompts/X-test-plan.md +436 -0
  184. package/prompts/X-travel-planner.md +22 -0
  185. package/prompts/X-xlsx2sql-insert.md +34 -0
  186. package/prompts/X-xlsx2sql-update.md +40 -0
  187. package/prompts/X-zoom-out.md +119 -0
  188. package/reference/diagnose-loop.md +66 -0
  189. package/reference/gates.md +90 -0
  190. package/reference/git-guardrails.md +71 -0
  191. package/reference/guards.md +275 -0
  192. package/reference/learn.md +100 -0
  193. package/reference/memory.md +190 -0
  194. package/reference/risk.md +74 -0
  195. package/reference/tdd.md +40 -0
  196. package/scripts/svg2png.js +46 -0
  197. package/src/cls/client.js +244 -0
  198. package/src/constants.js +49 -0
  199. package/src/evidence/ai-draft-metrics.js +157 -0
  200. package/src/evidence/canvas.js +184 -0
  201. package/src/evidence/index.js +98 -0
  202. package/src/evidence/sink-events.js +165 -0
  203. package/src/evidence/stage-timing.js +112 -0
  204. package/src/installers/claude.js +79 -0
  205. package/src/installers/codex.js +62 -0
  206. package/src/installers/opencode.js +72 -0
  207. package/src/manifest/ponytail-patterns.json +185 -0
  208. package/src/mcp/cls-mcp-server.js +142 -0
  209. package/src/utils.js +79 -0
  210. package/src/validators/state-validate.js +123 -0
  211. package/templates/.phase-state.json +13 -0
  212. package/templates/adr.md +62 -0
  213. package/templates/changelog.md +21 -0
  214. package/templates/concepts.md +35 -0
  215. package/templates/design.md +47 -0
  216. package/templates/handoff.md +64 -0
  217. package/templates/learn-skill.md +43 -0
  218. package/templates/progress.json +17 -0
  219. package/templates/proposal.md +29 -0
  220. package/templates/solution.md +36 -0
  221. package/templates/strategy.md +39 -0
  222. package/templates/tasks.md +41 -0
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: Git Commit Message 规范化生成,跳过自动路由
3
+ ---
4
+ 用 Read 工具读取 ${ATDC_DIR}/prompts/X-commit.md,然后直接开始执行。
5
+
6
+ $ARGUMENTS
@@ -0,0 +1,8 @@
1
+ ---
2
+ description: 知识沉淀(docs/solutions/ + CONCEPTS.md),跳过自动路由
3
+ ---
4
+ 请用 Read 工具读取 ${ATDC_DIR}/prompts/X-compound.md,然后根据以下参数开始执行:
5
+
6
+ $ARGUMENTS
7
+
8
+ 跳过 GO.md 路由,直接进行知识沉淀。无参数时进入交互模式。
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: 首次入场扫描,生成项目全景文档 CONTEXT.md,跳过自动路由
3
+ ---
4
+ 请用 Read 工具读取 ${ATDC_DIR}/prompts/X-context-scan.md,然后直接开始执行。
5
+
6
+ 跳过 GO.md 路由,直接进入 context 阶段:首次入场扫描,生成项目全景文档 CONTEXT.md。
@@ -0,0 +1,8 @@
1
+ ---
2
+ description: 结构化调试循环(复现→最小化→假设→插桩→修复→回归)。用法 /atdc:diagnose <bug描述>
3
+ ---
4
+ 请用 Read 工具读取 ${ATDC_DIR}/prompts/X-diagnose.md,然后根据以下输入开始执行:
5
+
6
+ $ARGUMENTS
7
+
8
+ 跳过 GO.md 路由,直接进入结构化调试循环。
@@ -0,0 +1,18 @@
1
+ ---
2
+ description: Git 安全防护(安装/检查 pre-push hook,拦截危险命令)。用法 /atdc:git-guardrails [install|check]
3
+ ---
4
+ 执行以下步骤:
5
+
6
+ 1. 检查 hook 是否已安装:
7
+ ```bash
8
+ ls -la .git/hooks/pre-push 2>/dev/null && echo "✅ 已安装" || echo "❌ 未安装"
9
+ ```
10
+
11
+ 2. 如果用户说 `install` 或未安装:
12
+ ```bash
13
+ ln -sf ~/atdc/hooks/guardrails.sh .git/hooks/pre-push && echo "✅ git-guardrails 已安装"
14
+ ```
15
+
16
+ 3. 输出当前防护状态(参考 reference/git-guardrails.md 说明规则)
17
+
18
+ $ARGUMENTS
@@ -0,0 +1,8 @@
1
+ ---
2
+ description: 深度拷问 + 文档沉淀(挑战领域模型、更新CONTEXT.md、生成ADR)。用法 /atdc:grill-with-docs [<change-name>]
3
+ ---
4
+ 请用 Read 工具读取 ${ATDC_DIR}/prompts/X-grill-with-docs.md,然后根据以下输入开始执行:
5
+
6
+ $ARGUMENTS
7
+
8
+ 跳过 GO.md 路由,直接进入深度拷问 + 文档沉淀。
@@ -0,0 +1,8 @@
1
+ ---
2
+ description: 会话交接文档生成(决策上下文、关键文件、未解决问题)。用法 /atdc:handoff [<change-name>]
3
+ ---
4
+ 请用 Read 工具读取 ${ATDC_DIR}/prompts/X-handoff.md,然后根据以下输入开始执行:
5
+
6
+ $ARGUMENTS
7
+
8
+ 跳过 GO.md 路由,直接生成交接文档。
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: 项目健康巡检(活跃 change、记忆文件、野代码、spec 覆盖率、CRG+CodeGraph 图引擎健康),跳过自动路由
3
+ ---
4
+ 执行前先运行 `~/.claude/scripts/link-crg.sh` 确保 CRG 图数据就绪,然后用 Read 工具读取 ${ATDC_DIR}/prompts/X-health.md 开始执行。
5
+
6
+ 跳过 GO.md 路由,直接进行项目健康巡检。
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: self-learning 桥接:从 session 中检测 golden path 并自动沉淀为 atd skill/memory/command,跳过自动路由
3
+ ---
4
+ 用 Read 工具读取 ${ATDC_DIR}/prompts/X-learn.md,然后直接开始执行。
5
+
6
+ $ARGUMENTS
@@ -0,0 +1,7 @@
1
+ 请用 Read 工具读取 ${ATDC_DIR}/prompts/X-review.md,然后根据以下参数开始执行:
2
+
3
+ $ARGUMENTS
4
+
5
+ 跳过 GO.md 路由,直接进行代码级 review。无参数时执行全量 review。
6
+
7
+ 子模式:delta=仅变更 | pr=PR review | gaps=仅测试缺口 | flows=仅受影响流程 | arch=架构健康检查 | crg=CRG 深度分析
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: Semble代码搜索(语义+词法双路检索),跳过自动路由
3
+ ---
4
+ 用 Read 工具读取 ${ATDC_DIR}/prompts/X-search.md,然后直接开始执行。
5
+
6
+ $ARGUMENTS
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: 产品策略锚点(STRATEGY.md 创建/更新),跳过自动路由
3
+ ---
4
+ 请用 Read 工具读取 ${ATDC_DIR}/prompts/X-strategy.md,然后直接开始执行。
5
+
6
+ 跳过 GO.md 路由,直接创建或更新 STRATEGY.md。
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: 解析 CREATE TABLE DDL 生成 Excel 模板,跳过自动路由
3
+ ---
4
+ 用 Read 工具读取 ${ATDC_DIR}/prompts/X-table2xlsx.md,然后直接开始执行。
5
+
6
+ $ARGUMENTS
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: 自测计划阶段:基于 change 的 tasks.md 生成可执行自测计划文档和集成测试文件
3
+ ---
4
+ 请用 Read 工具读取 ${ATDC_DIR}/prompts/X-test-plan.md,然后直接开始执行。
5
+
6
+ 跳过 GO.md 路由,直接进入自测计划阶段:生成自测计划文档 + 集成测试 Go 文件。
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: 全栈旅行规划助手:目的地推荐→深度研究→智能规划→精美攻略生成,跳过自动路由
3
+ ---
4
+ 用 skill 工具加载 travel-planner skill,然后根据用户需求执行旅行规划。
5
+
6
+ 用户需求:$ARGUMENTS
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: Excel → INSERT SQL,跳过自动路由
3
+ ---
4
+ 用 Read 工具读取 ${ATDC_DIR}/prompts/X-xlsx2sql-insert.md,然后直接开始执行。
5
+
6
+ $ARGUMENTS
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: Excel → UPDATE SQL,跳过自动路由
3
+ ---
4
+ 用 Read 工具读取 ${ATDC_DIR}/prompts/X-xlsx2sql-update.md,然后直接开始执行。
5
+
6
+ $ARGUMENTS
@@ -0,0 +1,8 @@
1
+ ---
2
+ description: 代码全景分析(系统定位、数据流、影响面、架构一致性)。用法 /atdc:zoom-out <文件/函数/模块>
3
+ ---
4
+ 请用 Read 工具读取 ${ATDC_DIR}/prompts/X-zoom-out.md,然后根据以下输入开始执行:
5
+
6
+ $ARGUMENTS
7
+
8
+ 跳过 GO.md 路由,直接进行代码全景分析。
@@ -0,0 +1,19 @@
1
+ {
2
+ "_comment": "CLS MCP Client 配置文件。cls --init 自动生成,请按需修改。",
3
+ "skill_dir": "/Users/lvkun/Documents/Codes/agent-skills/cls-log-query",
4
+ "python": "python3",
5
+ "accounts": {
6
+ "tcs": { "account": "ticket", "project_id": "11559" }
7
+ },
8
+ "defaults": {
9
+ "limit": 200,
10
+ "out_dir": "~/.cls/logs",
11
+ "topic_type": "error",
12
+ "regions": "gz,bj",
13
+ "time_range": "15m"
14
+ },
15
+ "output": {
16
+ "format": "jsonl",
17
+ "filename": "{account}_{query}_{ts}-{suffix}.jsonl"
18
+ }
19
+ }
@@ -0,0 +1,86 @@
1
+ #!/bin/sh
2
+ # atd-archive.sh — one-command archive automation
3
+ # Merges delta specs, moves change to archive, updates state.
4
+ #
5
+ # Usage:
6
+ # atd-archive.sh <change-name> archive
7
+ # atd-archive.sh --dry-run <change-name> preview only
8
+
9
+ set -e
10
+
11
+ DIR=$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd)
12
+ GUARD_SH="$DIR/phase-guard.sh"
13
+ STATE_SH="$DIR/atd-state.sh"
14
+
15
+ die() { echo "[HARD STOP] $*" >&2; exit 1; }
16
+ ok() { echo " ✓ $*"; }
17
+
18
+ _dry=false
19
+ _name=""
20
+
21
+ for arg in "$@"; do
22
+ case "$arg" in
23
+ --dry-run) _dry=true;;
24
+ *) _name="$arg";;
25
+ esac
26
+ done
27
+
28
+ [ -z "$_name" ] && die "Usage: atd-archive.sh [--dry-run] <change-name>"
29
+
30
+ _d="openspec/changes/$_name"
31
+ [ -d "$_d" ] || die "change directory not found: $_d"
32
+
33
+ # Step 1: guard check
34
+ echo "⚙ atd-archive: checking preconditions for $_name"
35
+ sh "$GUARD_SH" "$_name" archive || die "archive guard failed"
36
+
37
+ if $_dry; then
38
+ echo ""
39
+ echo "📋 DRY RUN — would archive: $_name"
40
+ echo " merge specs:"
41
+ for spec in "$_d"/specs/*/spec.md; do
42
+ [ -f "$spec" ] || continue
43
+ _module=$(basename "$(dirname "$spec")")
44
+ echo " $spec → openspec/specs/$_module/spec.md"
45
+ done
46
+ echo " move: $_d → openspec/changes/archive/$_name"
47
+ echo " state: archived = true"
48
+ exit 0
49
+ fi
50
+
51
+ # Step 2: merge delta specs
52
+ echo ""
53
+ echo "📦 merging specs..."
54
+ for spec in "$_d"/specs/*/spec.md; do
55
+ [ -f "$spec" ] || continue
56
+ _module=$(basename "$(dirname "$spec")")
57
+ _target="openspec/specs/$_module/spec.md"
58
+ mkdir -p "$(dirname "$_target")"
59
+ if [ -f "$_target" ]; then
60
+ echo " appending: $_module/spec.md → $_target"
61
+ echo "" >> "$_target"
62
+ echo "<!-- merged from change $_name -->" >> "$_target"
63
+ cat "$spec" >> "$_target"
64
+ else
65
+ echo " creating: $_module/spec.md"
66
+ cp "$spec" "$_target"
67
+ fi
68
+ ok "merged $_module/spec.md"
69
+ done
70
+
71
+ # Step 3: update state (before move, while file is still accessible)
72
+ echo ""
73
+ echo "📝 updating state..."
74
+ sh "$STATE_SH" set "$_name" archived true
75
+ ok "archived = true"
76
+
77
+ # Step 4: move to archive
78
+ echo ""
79
+ echo "📁 moving to archive..."
80
+ _archive_dir="openspec/changes/archive"
81
+ mkdir -p "$_archive_dir"
82
+ mv "$_d" "$_archive_dir/$_name"
83
+ ok "moved to $_archive_dir/$_name"
84
+
85
+ echo ""
86
+ echo "✅ archive complete: $_name"
@@ -0,0 +1,165 @@
1
+ #!/bin/sh
2
+ # atd-state.sh — unified state management for .phase-state.json
3
+ # Usage: atd-state.sh <cmd> [args...]
4
+ # init <change-name> create .phase-state.json in openspec/changes/<name>/
5
+ # set <key> <value> update a field
6
+ # get <key> read a field
7
+ # check <phase> validate current phase legality
8
+ # transition <from> <to> execute phase transition with guard check
9
+
10
+ set -e
11
+
12
+ DIR=$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd)
13
+ EVIDENCE_LOG="$DIR/evidence-log.sh"
14
+
15
+ die() { echo "$@" >&2; exit 1; }
16
+ warn() { echo "$@" >&2; }
17
+
18
+ # JSON helper — prefer jq, fallback to node -e
19
+ _json_get() {
20
+ if command -v jq >/dev/null 2>&1; then
21
+ jq -r ".$2 // \"\"" "$1"
22
+ elif command -v node >/dev/null 2>&1; then
23
+ node -e "try{var d=require('$(cd "$(dirname "$1")" && pwd)/$(basename "$1")');console.log(d.$2||'')}catch(e){console.log('')}"
24
+ else
25
+ die "jq or node required for JSON operations"
26
+ fi
27
+ }
28
+
29
+ _json_set() {
30
+ local file="$1" key="$2" value="$3"
31
+ if command -v jq >/dev/null 2>&1; then
32
+ jq ".$key = $value" "$file" > "${file}.tmp" && mv "${file}.tmp" "$file"
33
+ elif command -v node >/dev/null 2>&1; then
34
+ node -e "
35
+ var fs=require('fs');
36
+ var d=JSON.parse(fs.readFileSync('$file','utf8'));
37
+ d.$key = $value;
38
+ fs.writeFileSync('$file',JSON.stringify(d,null,2)+'\n');
39
+ "
40
+ else
41
+ die "jq or node required for JSON operations"
42
+ fi
43
+ }
44
+
45
+ # Valid phase sequence: open -> design -> build -> verify -> archive
46
+ _valid_phases="open design build verify archive"
47
+ _phase_index() {
48
+ _i=0; for _p in $_valid_phases; do
49
+ [ "$_p" = "$1" ] && echo "$_i" && return 0
50
+ _i=$((_i + 1))
51
+ done
52
+ echo "-1"
53
+ }
54
+
55
+ # Resolve change dir from current directory or explicit name
56
+ _find_change_dir() {
57
+ local name="$1"
58
+ [ -z "$name" ] && die "change name required"
59
+ local d="openspec/changes/$name"
60
+ [ -d "$d" ] || die "change directory not found: $d"
61
+ echo "$d"
62
+ }
63
+
64
+ _state_file() {
65
+ echo "$(_find_change_dir "$1")/.phase-state.json"
66
+ }
67
+
68
+ cmd_init() {
69
+ local name="$1" mode="${2:-full}"
70
+ [ -z "$name" ] && die "Usage: atd-state.sh init <change-name> [mode]"
71
+ local d="openspec/changes/$name"
72
+ mkdir -p "$d"
73
+ local sf="$d/.phase-state.json"
74
+ local ts now
75
+ ts=$(date -u +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || echo "")
76
+ cat > "$sf" <<EOF
77
+ {
78
+ "change": "$name",
79
+ "phase": "open",
80
+ "mode": "$mode",
81
+ "tasks": { "total": 0, "completed": 0 },
82
+ "verifiedAt": null,
83
+ "archived": false,
84
+ "verificationReport": null,
85
+ "branchStatus": "pending",
86
+ "startedAt": "$ts",
87
+ "updatedAt": "$ts"
88
+ }
89
+ EOF
90
+ echo "initialized $sf"
91
+ sh "$EVIDENCE_LOG" intake "$name" "$mode" 2>/dev/null || true
92
+ }
93
+
94
+ cmd_get() {
95
+ [ -z "$1" ] && die "Usage: atd-state.sh get <change-name> <key>"
96
+ local sf
97
+ sf=$(_state_file "$1")
98
+ [ -f "$sf" ] || die "state file not found: $sf"
99
+ shift
100
+ _json_get "$sf" "$1"
101
+ }
102
+
103
+ cmd_set() {
104
+ [ -z "$1" ] && die "Usage: atd-state.sh set <change-name> <key> <value>"
105
+ local name="$1"; shift
106
+ local sf
107
+ sf=$(_state_file "$name")
108
+ [ -f "$sf" ] || die "state file not found: $sf"
109
+ local key="$1" value="$2"
110
+ # Auto-wrap non-JSON values in double quotes for jq compatibility
111
+ case "$value" in
112
+ \"*\"|true|false|null|{*|\[*) ;; # already valid JSON
113
+ *) value="\"$value\"" ;; # wrap string in quotes
114
+ esac
115
+ _json_set "$sf" "$key" "$value"
116
+ # update updatedAt
117
+ local ts
118
+ ts=$(date -u +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || echo "")
119
+ _json_set "$sf" "updatedAt" "\"$ts\""
120
+ echo "ok"
121
+ }
122
+
123
+ cmd_check() {
124
+ [ -z "$1" ] && die "Usage: atd-state.sh check <change-name> <target-phase>"
125
+ local name="$1" target="$2"
126
+ local sf cur
127
+ sf=$(_state_file "$name")
128
+ [ -f "$sf" ] || die "state file not found: $sf"
129
+ cur=$(_json_get "$sf" "phase")
130
+ local ci ti
131
+ ci=$(_phase_index "$cur")
132
+ ti=$(_phase_index "$target")
133
+ [ "$ci" -lt 0 ] && die "invalid current phase: $cur"
134
+ [ "$ti" -lt 0 ] && die "invalid target phase: $target"
135
+ [ "$ti" -le "$ci" ] && die "cannot go backward: $cur -> $target"
136
+ [ $((ti - ci)) -gt 1 ] && die "cannot skip phases: $cur -> $target (must go through intermediate)"
137
+ echo "phase check ok: $cur -> $target"
138
+ }
139
+
140
+ cmd_transition() {
141
+ [ -z "$1" ] && die "Usage: atd-state.sh transition <change-name> <from> <to>"
142
+ local name="$1" from="$2" to="$3"
143
+ cmd_check "$name" "$to" || die "transition check failed"
144
+ local sf
145
+ sf=$(_state_file "$name")
146
+ local cur
147
+ cur=$(_json_get "$sf" "phase")
148
+ [ "$cur" = "$from" ] || die "current phase mismatch: expected $from, got $cur"
149
+ _json_set "$sf" "phase" "\"$to\""
150
+ local ts
151
+ ts=$(date -u +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || echo "")
152
+ _json_set "$sf" "updatedAt" "\"$ts\""
153
+ [ "$to" = "verify" ] && _json_set "$sf" "verifiedAt" "\"$ts\""
154
+ echo "transitioned: $from -> $to"
155
+ sh "$EVIDENCE_LOG" phase "$name" "$from" "$to" 2>/dev/null || true
156
+ }
157
+
158
+ case "${1:-}" in
159
+ init) shift; cmd_init "$@";;
160
+ get) shift; cmd_get "$@";;
161
+ set) shift; cmd_set "$@";;
162
+ check) shift; cmd_check "$@";;
163
+ transition) shift; cmd_transition "$@";;
164
+ *) die "Usage: atd-state.sh {init|set|get|check|transition} ...";;
165
+ esac
@@ -0,0 +1,88 @@
1
+ #!/bin/sh
2
+ # evidence-hook.sh — PostToolUse hook for automatic evidence recording
3
+ # Detects writes to .phase-state.json / .progress.json and records events.
4
+ # No agent compliance needed — fires automatically on every tool use.
5
+ #
6
+ # Registered via: atdc hook install
7
+ # Detects events:
8
+ # - Write to .phase-state.json with phase change → phase_transition event
9
+ # - Write to .progress.json with new completed task → task_complete event
10
+
11
+ DIR=$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd)
12
+ EVIDENCE_LOG="$DIR/evidence-log.sh"
13
+ STATE_SH="$DIR/atd-state.sh"
14
+
15
+ _file="${1:-}"
16
+ [ -z "$_file" ] && exit 0
17
+
18
+ _file=$(echo "$_file" | sed 's|^\./||')
19
+
20
+ # Only care about state file writes
21
+ case "$_file" in
22
+ */.phase-state.json)
23
+ ;;
24
+ */.progress.json)
25
+ ;;
26
+ *)
27
+ exit 0
28
+ ;;
29
+ esac
30
+
31
+ [ -f "$_file" ] || exit 0
32
+
33
+ _record_phase() {
34
+ local f="$1"
35
+ if ! command -v node >/dev/null 2>&1; then exit 0; fi
36
+ local change_dir
37
+ change_dir=$(dirname "$f")
38
+ local change_name
39
+ change_name=$(basename "$change_dir")
40
+ local phase mode
41
+ phase=$(python3 -c "import json; print(json.load(open('$f')).get('phase',''))" 2>/dev/null || node -e "console.log(JSON.parse(require('fs').readFileSync('$f','utf8')).phase||'')" 2>/dev/null)
42
+ mode=$(python3 -c "import json; print(json.load(open('$f')).get('mode','full'))" 2>/dev/null || node -e "console.log(JSON.parse(require('fs').readFileSync('$f','utf8')).mode||'full')" 2>/dev/null)
43
+ [ -z "$phase" ] && exit 0
44
+
45
+ local stamp="$change_dir/.evidence/.phase-stamp"
46
+ local prev=""
47
+ [ -f "$stamp" ] && prev=$(cat "$stamp")
48
+
49
+ if [ "$prev" != "$phase" ]; then
50
+ local from="${prev:-init}"
51
+ local to="$phase"
52
+ sh "$EVIDENCE_LOG" phase "$change_name" "$from" "$to" 2>/dev/null
53
+ mkdir -p "$(dirname "$stamp")"
54
+ echo "$phase" > "$stamp"
55
+ fi
56
+ }
57
+
58
+ _record_progress() {
59
+ local f="$1"
60
+ if ! command -v node >/dev/null 2>&1; then exit 0; fi
61
+ local change_dir change_name
62
+ change_dir=$(dirname "$f")
63
+ change_name=$(basename "$change_dir")
64
+
65
+ local status
66
+ status=$(python3 -c "import json; print(json.load(open('$f')).get('status',''))" 2>/dev/null || node -e "console.log(JSON.parse(require('fs').readFileSync('$f','utf8')).status||'')" 2>/dev/null)
67
+
68
+ local stamp="$change_dir/.evidence/.progress-stamp"
69
+ local prev=""
70
+ [ -f "$stamp" ] && prev=$(cat "$stamp")
71
+
72
+ if [ "$status" = "completed" ] && [ "$prev" != "completed" ]; then
73
+ sh "$EVIDENCE_LOG" done "$change_name" 2>/dev/null
74
+ mkdir -p "$(dirname "$stamp")"
75
+ echo "completed" > "$stamp"
76
+ fi
77
+ }
78
+
79
+ case "$_file" in
80
+ */.phase-state.json)
81
+ _record_phase "$_file"
82
+ ;;
83
+ */.progress.json)
84
+ _record_progress "$_file"
85
+ ;;
86
+ esac
87
+
88
+ exit 0
@@ -0,0 +1,54 @@
1
+ #!/bin/sh
2
+ # evidence-log.sh — record evidence events during phase transitions
3
+ # Usage:
4
+ # evidence-log.sh record <change-name> <event-type> [--phase=<p>] [--key=value...]
5
+ #
6
+ # Called automatically by atd-state.sh during transitions.
7
+
8
+ DIR=$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd)
9
+ ATD_BIN="$DIR/../bin/atdc.js"
10
+
11
+ _record() {
12
+ local change="$1" type="$2" phase="${3:-unknown}"
13
+ shift 3 2>/dev/null || true
14
+
15
+ local extra=""
16
+ for arg in "$@"; do
17
+ extra="$extra $arg"
18
+ done
19
+
20
+ if command -v node >/dev/null 2>&1; then
21
+ node "$ATD_BIN" evidence record "$change" "$type" "--phase=$phase" $extra 2>/dev/null || true
22
+ fi
23
+ }
24
+
25
+ _phase_event() {
26
+ local change="$1" from="$2" to="$3"
27
+ _record "$change" "phase_transition" "$to" "--from=$from" "--to=$to"
28
+ }
29
+
30
+ _intake_event() {
31
+ local change="$1" mode="$2"
32
+ _record "$change" "intake" "open" "--mode=$mode"
33
+ }
34
+
35
+ _gate_event() {
36
+ local change="$1" gate="$2" result="$3"
37
+ _record "$change" "gate_check" "build" "--gate=$gate" "--result=$result"
38
+ }
39
+
40
+ _done_event() {
41
+ local change="$1"
42
+ _record "$change" "done" "archive"
43
+ }
44
+
45
+ case "${1:-}" in
46
+ phase) shift; _phase_event "$@";;
47
+ intake) shift; _intake_event "$@";;
48
+ gate) shift; _gate_event "$@";;
49
+ done) shift; _done_event "$@";;
50
+ record) shift; _record "$@";;
51
+ *)
52
+ echo "Usage: evidence-log.sh {phase|intake|gate|done|record} ..." >&2
53
+ ;;
54
+ esac
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env bash
2
+ # atdc git guardrails — pre-push hook
3
+ # 拦截危险 git 命令,保护 main/master 分支
4
+ # 安装:ln -sf ~/atdc/hooks/guardrails.sh .git/hooks/pre-push
5
+ # 卸载:rm .git/hooks/pre-push
6
+
7
+ set -e
8
+
9
+ REMOTE="$1"
10
+ REMOTE_URL="$2"
11
+
12
+ # 当前分支
13
+ CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
14
+
15
+ # 保护分支列表
16
+ PROTECTED_BRANCHES="main master"
17
+
18
+ # ── 检查是否推送到保护分支 ──
19
+ for branch in $PROTECTED_BRANCHES; do
20
+ if [ "$CURRENT_BRANCH" = "$branch" ]; then
21
+ echo "🔒 atdc guardrails: 禁止直接推送到 $branch 分支"
22
+ echo ""
23
+ echo " 请使用 PR/MR 方式合并代码。"
24
+ echo " 如果必须直推(紧急 hotfix),运行:"
25
+ echo " git push --no-verify"
26
+ echo ""
27
+ exit 1
28
+ fi
29
+ done
30
+
31
+ # ── 检查 WIP commit ──
32
+ while read local_ref local_sha remote_ref remote_sha; do
33
+ if [ "$local_sha" = "0000000000000000000000000000000000000000" ]; then
34
+ # 删除远程分支,允许
35
+ continue
36
+ fi
37
+
38
+ if [ "$remote_sha" = "0000000000000000000000000000000000000000" ]; then
39
+ # 新分支首次推送,检查所有新 commit
40
+ WIP_COUNT=$(git log "$local_sha" --not --all --oneline 2>/dev/null | grep -ci "WIP" || true)
41
+ else
42
+ WIP_COUNT=$(git log "$remote_sha..$local_sha" --oneline 2>/dev/null | grep -ci "WIP" || true)
43
+ fi
44
+
45
+ if [ "$WIP_COUNT" -gt 0 ]; then
46
+ echo "⚠️ atdc guardrails: 检测到 $WIP_COUNT 个 WIP commit"
47
+ echo ""
48
+ echo " 建议 squash 后再推送。"
49
+ echo " 继续推送:git push --no-verify"
50
+ echo ""
51
+ exit 1
52
+ fi
53
+ done
54
+
55
+ # ── CUSTOM RULES ──────────────────────────────────────────
56
+ # 在此处添加项目特定的检查规则
57
+ # 示例:
58
+ # if git log $remote_sha..$local_sha --oneline | grep -q "TODO"; then
59
+ # echo "❌ commit 中包含 TODO,请处理后再推送"
60
+ # exit 1
61
+ # fi
62
+ # ───────────────────────────────────────────────────────────
63
+
64
+ echo "✅ atdc guardrails: 检查通过"
65
+ exit 0