@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
package/install.sh ADDED
@@ -0,0 +1,276 @@
1
+ #!/usr/bin/env bash
2
+ # atdc 安装脚本
3
+ # 用法:bash ~/atdc/install.sh
4
+ # 可重复执行,幂等。
5
+
6
+ set -e
7
+
8
+ ATDC_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
9
+ HOME_DIR="$HOME"
10
+
11
+ echo "atdc 目录:$ATDC_DIR"
12
+ echo "Home 目录:$HOME_DIR"
13
+ echo ""
14
+
15
+ # ── Step 1:替换 commands/ 下的 {{ATDC_DIR}} 占位符 ──────────────────
16
+
17
+ echo "Step 1:修正命令文件中的路径..."
18
+
19
+ if grep -rq '{{ATDC_DIR}}' "$ATDC_DIR/commands" --include="*.md"; then
20
+ find "$ATDC_DIR/commands" -name "*.md" -type f -exec sed -i '' "s|{{ATDC_DIR}}|$ATDC_DIR|g" {} +
21
+ echo " ✓ {{ATDC_DIR}} → $ATDC_DIR"
22
+ else
23
+ echo " 路径已是最新,无需替换。"
24
+ fi
25
+
26
+ echo ""
27
+
28
+ # ── Step 2:创建 memory 目录 ────────────────────────────────────────────────
29
+
30
+ echo "Step 2:创建 memory 目录..."
31
+ mkdir -p "$HOME_DIR/.atdc/memory"
32
+ echo " ✓ ~/.atdc/memory/"
33
+
34
+ echo ""
35
+
36
+ # ── Step 2.5:检测 RTK ─────────────────────────────────────────────────
37
+
38
+ echo "Step 2.5:检测 RTK..."
39
+
40
+ if command -v rtk &>/dev/null; then
41
+ RTK_VER=$(LC_ALL=C rtk --version 2>/dev/null | head -1)
42
+ echo " ✓ RTK 已安装($RTK_VER)"
43
+
44
+ # 检测 OpenCode 插件
45
+ if [ -f "$HOME_DIR/.config/opencode/plugins/rtk.ts" ]; then
46
+ echo " ✓ OpenCode RTK 插件已配置"
47
+ else
48
+ echo " ⚠️ RTK 已安装但 OpenCode 插件未配置,运行:rtk init -g --opencode"
49
+ fi
50
+
51
+ # 检测 Claude Code hook
52
+ if [ -f "$HOME_DIR/.claude/hooks/rtk-rewrite.sh" ]; then
53
+ echo " ✓ Claude Code RTK hook 已配置"
54
+ else
55
+ echo " ⚠️ Claude Code RTK hook 未配置,运行:rtk init -g"
56
+ fi
57
+ else
58
+ echo " ⚠️ RTK 未安装(可选,用于压缩 AI 工具 shell 输出、节省 60-90% token)"
59
+ echo " 安装方式:brew install rtk && rtk init -g --opencode"
60
+ fi
61
+
62
+ echo ""
63
+
64
+ # ── Step 2.6:Migrate old flow-kit symlinks ─────────────────────────────
65
+
66
+ echo "Step 2.6:检查旧 flow-kit symlink 迁移..."
67
+
68
+ MIGRATED=0
69
+
70
+ # Claude Code
71
+ if [ -L "$HOME_DIR/.claude/commands/atd.md" ]; then
72
+ rm -f "$HOME_DIR/.claude/commands/atd.md"
73
+ echo " ✓ 移除旧 symlink ~/.claude/commands/atd.md"
74
+ MIGRATED=1
75
+ fi
76
+ if [ -L "$HOME_DIR/.claude/commands/atd" ]; then
77
+ rm -rf "$HOME_DIR/.claude/commands/atd"
78
+ echo " ✓ 移除旧 symlink ~/.claude/commands/atd/"
79
+ MIGRATED=1
80
+ fi
81
+
82
+ # OpenCode
83
+ if [ -L "$HOME_DIR/.config/opencode/commands/atd.md" ]; then
84
+ rm -f "$HOME_DIR/.config/opencode/commands/atd.md"
85
+ echo " ✓ 移除旧 symlink ~/.config/opencode/commands/atd.md"
86
+ MIGRATED=1
87
+ fi
88
+ if [ -L "$HOME_DIR/.config/opencode/commands/atd" ]; then
89
+ rm -rf "$HOME_DIR/.config/opencode/commands/atd"
90
+ echo " ✓ 移除旧 symlink ~/.config/opencode/commands/atd/"
91
+ MIGRATED=1
92
+ fi
93
+
94
+ # Codex skills
95
+ if [ -d "$HOME_DIR/.agents/skills" ]; then
96
+ for old in "$HOME_DIR/.agents/skills"/flow "$HOME_DIR/.agents/skills"/flow-*; do
97
+ if [ -L "$old" ]; then
98
+ rm -rf "$old"
99
+ echo " ✓ 移除旧 symlink $old"
100
+ MIGRATED=1
101
+ fi
102
+ done
103
+ fi
104
+
105
+ # Memory directory
106
+ if [ -d "$HOME_DIR/.flow-kit/memory" ] && [ ! -d "$HOME_DIR/.atdc/memory" ]; then
107
+ mkdir -p "$HOME_DIR/.atdc"
108
+ mv "$HOME_DIR/.flow-kit/memory" "$HOME_DIR/.atdc/memory"
109
+ echo " ✓ 迁移 memory: ~/.flow-kit/memory/ → ~/.atdc/memory/"
110
+ MIGRATED=1
111
+ fi
112
+
113
+ [ "$MIGRATED" -eq 1 ] && echo " 检测到旧 flow-kit symlink/memory,已自动迁移到 atdc。" || echo " 无旧 symlink,跳过。"
114
+
115
+ echo ""
116
+
117
+ # ── Step 3:Claude Code symlinks ────────────────────────────────────────────
118
+
119
+ echo "Step 3:Claude Code 命令..."
120
+ CLAUDE_CMD="$HOME_DIR/.claude/commands"
121
+
122
+ if [ ! -d "$CLAUDE_CMD" ]; then
123
+ echo " ⚠️ 未检测到 Claude Code(~/.claude/commands 不存在),跳过。"
124
+ else
125
+ mkdir -p "$CLAUDE_CMD"
126
+
127
+ # atd.md
128
+ if [ -L "$CLAUDE_CMD/atd.md" ] || [ -f "$CLAUDE_CMD/atd.md" ]; then
129
+ rm -f "$CLAUDE_CMD/atd.md"
130
+ fi
131
+ ln -s "$ATDC_DIR/commands/claude/atd.md" "$CLAUDE_CMD/atd.md"
132
+
133
+ # atd/ 子命令目录
134
+ if [ -L "$CLAUDE_CMD/atd" ] || [ -d "$CLAUDE_CMD/atd" ]; then
135
+ rm -rf "$CLAUDE_CMD/atd"
136
+ fi
137
+ ln -s "$ATDC_DIR/commands/claude/atd" "$CLAUDE_CMD/atd"
138
+
139
+ echo " ✓ ~/.claude/commands/atd.md → atdc/commands/claude/atd.md"
140
+ echo " ✓ ~/.claude/commands/atd/ → atdc/commands/claude/atd/"
141
+ fi
142
+
143
+ echo ""
144
+
145
+ # ── Step 4:OpenCode symlinks ───────────────────────────────────────────────
146
+
147
+ echo "Step 4:OpenCode 命令..."
148
+ OPENCODE_CMD="$HOME_DIR/.config/opencode/commands"
149
+
150
+ if [ ! -d "$HOME_DIR/.config/opencode" ]; then
151
+ echo " ⚠️ 未检测到 OpenCode(~/.config/opencode 不存在),跳过。"
152
+ else
153
+ mkdir -p "$OPENCODE_CMD"
154
+
155
+ if [ -L "$OPENCODE_CMD/atd.md" ] || [ -f "$OPENCODE_CMD/atd.md" ]; then
156
+ rm -f "$OPENCODE_CMD/atd.md"
157
+ fi
158
+ ln -s "$ATDC_DIR/commands/opencode/atd.md" "$OPENCODE_CMD/atd.md"
159
+
160
+ if [ -L "$OPENCODE_CMD/atd" ] || [ -d "$OPENCODE_CMD/atd" ]; then
161
+ rm -rf "$OPENCODE_CMD/atd"
162
+ fi
163
+ ln -s "$ATDC_DIR/commands/opencode/atd" "$OPENCODE_CMD/atd"
164
+
165
+ echo " ✓ ~/.config/opencode/commands/atd.md → atdc/commands/opencode/atd.md"
166
+ echo " ✓ ~/.config/opencode/commands/atd/ → atdc/commands/opencode/atd/"
167
+ fi
168
+
169
+ echo ""
170
+
171
+ # ── Step 5:Codex skills symlinks ───────────────────────────────────────────
172
+
173
+ echo "Step 5:Codex skills..."
174
+ AGENTS_SKILLS="$HOME_DIR/.agents/skills"
175
+
176
+ if [ ! -d "$HOME_DIR/.agents" ]; then
177
+ echo " ⚠️ 未检测到 Codex(~/.agents 不存在),跳过。"
178
+ else
179
+ mkdir -p "$AGENTS_SKILLS"
180
+
181
+ for skill in atd atd-1-spec atd-1-update atd-2-qa atd-3-impl atd-3-impl-skip-spec atd-4-verify atd-5-done atd-add-to-hc atd-article atd-compound atd-context atd-health atd-review atd-strategy atd-diagnose atd-grill-with-docs atd-zoom-out atd-handoff atd-git-guardrails atdc-simplifier atd-test-plan atd-table2xlsx atd-xlsx2sql-insert atd-xlsx2sql-update atd-add-command atd-commit atd-travel-planner atd-learn atd-search atd-bugfix atd-analysis-cls-log; do
182
+ if [ -L "$AGENTS_SKILLS/$skill" ] || [ -d "$AGENTS_SKILLS/$skill" ]; then
183
+ rm -rf "$AGENTS_SKILLS/$skill"
184
+ fi
185
+ ln -s "$ATDC_DIR/commands/codex/$skill" "$AGENTS_SKILLS/$skill"
186
+ echo " ✓ ~/.agents/skills/$skill → atdc/commands/codex/$skill"
187
+ done
188
+ fi
189
+
190
+ echo ""
191
+
192
+ # ── Step 6:Cursor skills symlinks ───────────────────────────────────────────
193
+
194
+ echo "Step 6:Cursor skills..."
195
+ CURSOR_PROJECT_DIR="${1:-$PWD}"
196
+ CURSOR_SKILLS="$CURSOR_PROJECT_DIR/.cursor/skills"
197
+
198
+ if [ ! -d "$CURSOR_PROJECT_DIR/.cursor" ]; then
199
+ mkdir -p "$CURSOR_PROJECT_DIR/.cursor"
200
+ fi
201
+
202
+ if [ -L "$CURSOR_SKILLS" ]; then
203
+ echo " ✓ .cursor/skills 已存在"
204
+ elif [ -d "$CURSOR_SKILLS" ]; then
205
+ echo " ⚠️ .cursor/skills 已存在(非symlink),跳过"
206
+ else
207
+ ln -sf "$ATDC_DIR/commands/cursor" "$CURSOR_SKILLS"
208
+ echo " ✓ .cursor/skills → atdc/commands/cursor"
209
+ fi
210
+
211
+ echo ""
212
+
213
+ # ── Step 7:Git Guardrails hook ───────────────────────────────────────────
214
+
215
+ echo "Step 6:Git Guardrails..."
216
+
217
+ if git rev-parse --git-dir > /dev/null 2>&1; then
218
+ HOOK_PATH="$(git rev-parse --git-dir)/hooks/pre-push"
219
+
220
+ if [ -L "$HOOK_PATH" ]; then
221
+ EXISTING_TARGET=$(readlink "$HOOK_PATH")
222
+ if [ "$EXISTING_TARGET" = "$ATDC_DIR/hooks/guardrails.sh" ]; then
223
+ echo " ✓ git-guardrails 已安装"
224
+ else
225
+ echo " ⚠️ 已有其他 pre-push hook ($EXISTING_TARGET),跳过。手动安装:ln -sf $ATDC_DIR/hooks/guardrails.sh $HOOK_PATH"
226
+ fi
227
+ elif [ -f "$HOOK_PATH" ]; then
228
+ echo " ⚠️ 已有自定义 pre-push hook,跳过。手动合并:参考 $ATDC_DIR/hooks/guardrails.sh"
229
+ else
230
+ ln -sf "$ATDC_DIR/hooks/guardrails.sh" "$HOOK_PATH"
231
+ echo " ✓ git-guardrails 已安装 → .git/hooks/pre-push"
232
+ fi
233
+ else
234
+ echo " ⚠️ 当前目录不是 git 仓库,跳过 hook 安装。进入项目后运行:bash ~/atdc/install.sh"
235
+ fi
236
+
237
+ echo ""
238
+
239
+ # ── Step 6:安装 puppeteer(SVG→PNG CJK 渲染) ────────────────────────
240
+
241
+ echo "Step 6:安装 puppeteer(图表 PNG 导出)..."
242
+
243
+ if [ -d "$ATDC_DIR/node_modules/puppeteer" ]; then
244
+ echo " ✓ puppeteer 已安装"
245
+ else
246
+ echo " 正在安装 puppeteer(含 Chromium,约 300MB,首次较慢)..."
247
+ cd "$ATDC_DIR"
248
+ npm install puppeteer --save 2>&1 | tail -1
249
+ echo " ✓ puppeteer 安装完成"
250
+ fi
251
+
252
+ echo ""
253
+ echo "✅ atdc 安装完成!"
254
+ echo ""
255
+ echo "三端触发方式:"
256
+ echo " Claude Code /atd:1-spec <需求>"
257
+ echo " OpenCode /atd:1-spec <需求>"
258
+ echo " Codex atd:1-spec <需求>"
259
+ echo ""
260
+ echo "横向命令:"
261
+ echo " /atd:diagnose 结构化调试(复现→最小化→假设→插桩→修复→回归)"
262
+ echo " /atd:grill-with-docs 深度拷问 + 更新 CONTEXT.md + 生成 ADR"
263
+ echo " /atd:zoom-out 代码全景分析(定位、数据流、影响面)"
264
+ echo " /atd:handoff 会话交接文档生成"
265
+ echo " /atd:git-guardrails Git 安全防护(已自动安装)"
266
+ echo ""
267
+ echo "Token 压缩(推荐):rtk init -g --opencode"
268
+ echo ""
269
+ echo "代码搜索(推荐):"
270
+ if command -v semble &>/dev/null; then
271
+ echo " ✓ Semble 已安装(代码语义搜索引擎,省 98% Token vs grep)"
272
+ else
273
+ echo " 💡 推荐安装 Semble 代码搜索引擎:"
274
+ echo " uv tool install semble && semble install --agent opencode --type mcp --yes"
275
+ echo " 安装后可使用 /atd:search 快速搜索代码"
276
+ fi
package/package.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@kunlv/atdc",
3
+ "version": "1.0.0",
4
+ "description": "AI coding workflow orchestration kit — team edition",
5
+ "bin": {
6
+ "atdc": "bin/atdc.js",
7
+ "cls": "packages/cls/bin/cls.js"
8
+ },
9
+ "files": [
10
+ "bin/", "src/", "hooks/", "prompts/", "templates/",
11
+ "central/", "scripts/", "config/", "packages/cls/",
12
+ "GO.md", "install.sh", "commands/", "AGENTS.md", "reference/"
13
+ ],
14
+ "scripts": {
15
+ "postinstall": "echo '📋 atdc 已安装。运行: atdc install --all'"
16
+ },
17
+ "keywords": ["ai", "workflow", "coding", "spec-driven"],
18
+ "license": "MIT",
19
+ "engines": { "node": ">=16" }
20
+ }
@@ -0,0 +1,146 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const client = require('../src/client');
5
+
6
+ const HELP = `cls — CLS 日志查询 CLI
7
+
8
+ 用法:
9
+ cls --init 初始化配置文件
10
+ cls --list-accounts 列出可用账号
11
+ cls <account> <query> [options] 查询 CLS 日志
12
+
13
+ 选项:
14
+ --limit N 返回条数(默认 200,最大 1000)
15
+ --out DIR 输出目录(默认当前目录)
16
+ --from TIME 开始时间(默认 15m 前,支持 "2026-07-17 10:00")
17
+ --to TIME 结束时间(默认当前)
18
+ --type TYPE topic 类型(默认 error)
19
+ --regions R 地域(默认 gz,bj)
20
+ --format FORMAT 输出格式 json|jsonl(默认 jsonl)
21
+ --fetch 全量落地(调 cls_fetch_bulk.py)
22
+ --max N 全量最大条数(默认 5000)
23
+ --quiet 静默模式(不输出进度)
24
+ --help 显示此帮助
25
+
26
+ 示例:
27
+ cls tcs "callTencentMusicAPI AND done"
28
+ cls tcs "order AND pay*" --limit 500 --out /tmp/logs/
29
+ cls tcs "order AND pay*" --fetch --max 10000`;
30
+
31
+ function usage() {
32
+ console.log(HELP);
33
+ process.exit(0);
34
+ }
35
+
36
+ function fail(msg) {
37
+ console.error(`cls: ${msg}`);
38
+ process.exit(1);
39
+ }
40
+
41
+ const args = process.argv.slice(2);
42
+
43
+ let emptyConfig = false;
44
+ try {
45
+ const cfg = client.loadConfig();
46
+ if (!cfg.skill_dir || Object.keys(cfg.accounts).length === 0) emptyConfig = true;
47
+ } catch (e) {
48
+ emptyConfig = true;
49
+ }
50
+ if (emptyConfig && args[0] !== '--init' && args[0] !== '--help') {
51
+ const msg = '🔧 首次运行,请完成配置:\n\n cls --init\n\n 按提示输入:\n 1. cls-log-query 所在目录\n 2. 账号(别名=凭证名=项目ID)\n 3. SecretId(可选)\n 4. SecretKey(可选)\n';
52
+ require('fs').writeSync(1, msg);
53
+ process.exit(0);
54
+ }
55
+
56
+ if (args.length === 0 || args.includes('--help')) {
57
+ if (args.length === 0) {
58
+ try { client.loadConfig(); } catch { client.initConfig(); console.log('配置已生成: ~/.cls/config.json'); process.exit(0); }
59
+ }
60
+ usage();
61
+ }
62
+
63
+ if (args[0] === '--init') {
64
+ const fs = require('fs'), path = require('path'), os = require('os');
65
+ let tty;
66
+ try { tty = fs.openSync('/dev/tty', 'r'); } catch (e) {
67
+ console.error('❌ 当前终端不支持交互输入。\n 手动创建 ~/.cls/config.json:\n https://www.npmjs.com/package/cls-log-cli');
68
+ process.exit(1);
69
+ }
70
+ const buf = Buffer.alloc(1024);
71
+ function prompt(q) {
72
+ process.stdout.write(q);
73
+ let data = '';
74
+ while (true) {
75
+ const n = fs.readSync(tty, buf, 0, buf.length, null);
76
+ data += buf.toString('utf8', 0, n);
77
+ if (data.includes('\n')) return data.split('\n')[0].trim();
78
+ }
79
+ }
80
+ process.stdout.write('\n📋 cls-log-cli 初始化配置\n\n');
81
+ const skillDir = prompt('cls-log-query 所在目录: ');
82
+ if (!skillDir) { console.error('❌ 必须填写'); process.exit(1); }
83
+ const resolved = skillDir.replace(/^~/, os.homedir());
84
+ if (!fs.existsSync(resolved)) { console.error(`❌ 目录不存在: ${resolved}`); process.exit(1); }
85
+ const entry = prompt('账号(别名=凭证名=项目ID): ');
86
+ const parts = entry.split('=');
87
+ if (parts.length !== 3) { console.error('❌ 格式: 别名=凭证名=项目ID'); process.exit(1); }
88
+ const sid = prompt('SecretId (留空跳过): ');
89
+ const skey = prompt('SecretKey (留空跳过): ');
90
+ fs.closeSync(tty);
91
+
92
+ const dir = path.join(os.homedir(), '.cls');
93
+ fs.mkdirSync(dir, { recursive: true });
94
+ const config = { skill_dir: resolved, python: 'python3', accounts: { [parts[0]]: { account: parts[1], project_id: parts[2] } }, defaults: { limit: 200, out_dir: '~/.cls/logs', topic_type: 'error', regions: 'gz,bj', time_range: '15m' }, output: { format: 'jsonl', filename: '{account}_{query}_{ts}-{suffix}.jsonl' } };
95
+ fs.writeFileSync(path.join(dir, 'config.json'), JSON.stringify(config, null, 2) + '\n');
96
+ if (sid && skey) {
97
+ fs.writeFileSync(path.join(dir, 'credentials.json'), JSON.stringify({ [parts[1]]: { secret_id: sid, secret_key: skey, project_ids: [parts[2]] } }, null, 2) + '\n');
98
+ fs.chmodSync(path.join(dir, 'credentials.json'), 0o600);
99
+ }
100
+ process.stdout.write('\n✅ ~/.cls/ 配置完成\n\n');
101
+ process.exit(0);
102
+ }
103
+
104
+ if (args[0] === '--list-accounts') {
105
+ try {
106
+ const accounts = client.listAccounts();
107
+ console.log('可用账号:');
108
+ Object.entries(accounts).forEach(([alias, name]) => console.log(` ${alias} → ${name}`));
109
+ } catch (e) { fail(e.message); }
110
+ process.exit(0);
111
+ }
112
+
113
+ const [account, query] = args;
114
+ if (!account || !query) fail('用法: cls <account> <query> [options]');
115
+
116
+ const opts = {};
117
+ for (let i = 2; i < args.length; i++) {
118
+ const a = args[i];
119
+ if (a === '--limit') opts.limit = parseInt(args[++i]);
120
+ else if (a === '--out') opts.out_dir = args[++i];
121
+ else if (a === '--from') opts.from = args[++i];
122
+ else if (a === '--to') opts.to = args[++i];
123
+ else if (a === '--type') opts.type = args[++i];
124
+ else if (a === '--regions') opts.regions = args[++i];
125
+ else if (a === '--format') opts.format = args[++i];
126
+ else if (a === '--max') opts.max = parseInt(args[++i]);
127
+ else if (a === '--fetch') opts.fetch = true;
128
+ else if (a === '--quiet') opts.quiet = true;
129
+ }
130
+
131
+ try {
132
+ if (opts.fetch) {
133
+ const result = client.fetchSync(account, query, opts);
134
+ console.log(`→ ${result.output_file} (${result.total} 条)`);
135
+ } else {
136
+ const result = client.searchSync(account, query, opts);
137
+ console.log(`→ ${result.output_file} (${result.count} 条)`);
138
+ }
139
+ } catch (e) {
140
+ if (e.message && e.message.includes('配置文件') && e.message.includes('不存在')) {
141
+ client.initConfig();
142
+ console.log('配置已生成: ~/.cls/config.json,请重试命令');
143
+ } else {
144
+ fail(e.stderr || e.message);
145
+ }
146
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "_comment": "模板文件,安装时 postinstall 脚本会自动生成 ~/.cls/config.json",
3
+ "skill_dir": "",
4
+ "python": "python3",
5
+ "accounts": {},
6
+ "defaults": {
7
+ "limit": 200,
8
+ "out_dir": "~/.cls/logs",
9
+ "topic_type": "error",
10
+ "regions": "gz,bj",
11
+ "time_range": "15m"
12
+ },
13
+ "output": {
14
+ "format": "jsonl",
15
+ "filename": "{account}_{query}_{ts}-{suffix}.jsonl"
16
+ }
17
+ }
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const readline = require('readline');
5
+ const client = require('../src/client');
6
+
7
+ const TOOLS = [
8
+ {
9
+ name: 'cls_search',
10
+ description: '搜索 CLS 日志并落地到文件。返回输出文件路径、结果数量和样本日志。',
11
+ inputSchema: {
12
+ type: 'object',
13
+ properties: {
14
+ account: { type: 'string', description: '账号别名(如 tcs)' },
15
+ query: { type: 'string', description: 'CLS 查询语句' },
16
+ limit: { type: 'number', description: '返回条数(默认 200)' },
17
+ out_dir: { type: 'string', description: '输出目录(默认当前)' },
18
+ from: { type: 'string', description: '开始时间(默认 15m 前)' },
19
+ to: { type: 'string', description: '结束时间(默认 现在)' },
20
+ type: { type: 'string', description: 'topic 类型(默认 error)' },
21
+ regions: { type: 'string', description: '地域(默认 gz,bj)' },
22
+ },
23
+ required: ['account', 'query'],
24
+ },
25
+ },
26
+ {
27
+ name: 'cls_fetch',
28
+ description: '全量落地 CLS 日志到本地 jsonl 文件。',
29
+ inputSchema: {
30
+ type: 'object',
31
+ properties: {
32
+ account: { type: 'string', description: '账号别名' },
33
+ query: { type: 'string', description: 'CLS 查询语句' },
34
+ max: { type: 'number', description: '最大条数(默认 5000)' },
35
+ out_dir: { type: 'string', description: '输出目录' },
36
+ from: { type: 'string', description: '开始时间' },
37
+ to: { type: 'string', description: '结束时间' },
38
+ },
39
+ required: ['account', 'query'],
40
+ },
41
+ },
42
+ {
43
+ name: 'cls_histogram',
44
+ description: '查看 CLS 日志量时间分布(直方图)。',
45
+ inputSchema: {
46
+ type: 'object',
47
+ properties: {
48
+ account: { type: 'string', description: '账号别名' },
49
+ query: { type: 'string', description: 'CLS 查询语句' },
50
+ from: { type: 'string', description: '开始时间(必填)' },
51
+ to: { type: 'string', description: '结束时间(必填)' },
52
+ interval: { type: 'string', description: '时间桶间隔(默认 30m)' },
53
+ },
54
+ required: ['account', 'query', 'from', 'to'],
55
+ },
56
+ },
57
+ {
58
+ name: 'cls_context',
59
+ description: '拉取某条日志的前后上下文。',
60
+ inputSchema: {
61
+ type: 'object',
62
+ properties: {
63
+ account: { type: 'string', description: '账号别名' },
64
+ pkg_id: { type: 'string', description: '日志 PkgId' },
65
+ pkg_log_id: { type: 'number', description: '日志 PkgLogId' },
66
+ time: { type: 'string', description: '日志时间(毫秒时间戳)' },
67
+ prev: { type: 'number', description: '往前 N 条(默认 10)' },
68
+ next: { type: 'number', description: '往后 N 条(默认 10)' },
69
+ },
70
+ required: ['account', 'pkg_id', 'pkg_log_id', 'time'],
71
+ },
72
+ },
73
+ {
74
+ name: 'cls_list_accounts',
75
+ description: '列出可用账号别名及其映射。',
76
+ inputSchema: { type: 'object', properties: {} },
77
+ },
78
+ ];
79
+
80
+ function send(id, result) {
81
+ process.stdout.write(JSON.stringify({ jsonrpc: '2.0', id, result }) + '\n');
82
+ }
83
+
84
+ function sendError(id, code, message) {
85
+ process.stdout.write(JSON.stringify({ jsonrpc: '2.0', id, error: { code, message } }) + '\n');
86
+ }
87
+
88
+ async function handleCall(id, name, args) {
89
+ try {
90
+ switch (name) {
91
+ case 'cls_search': {
92
+ const r = await client.searchAsync(args.account, args.query, { ...args, quiet: true });
93
+ send(id, { content: [{ type: 'text', text: JSON.stringify(r, null, 2) }] });
94
+ break;
95
+ }
96
+ case 'cls_fetch': {
97
+ const r = await client.fetchAsync(args.account, args.query, args);
98
+ send(id, { content: [{ type: 'text', text: JSON.stringify(r, null, 2) }] });
99
+ break;
100
+ }
101
+ case 'cls_histogram':
102
+ case 'cls_context': {
103
+ send(id, { content: [{ type: 'text', text: JSON.stringify({ note: `${name} 模式待实现,请直接用 CLI: cls ${args.account} "${args.query}" --histogram/--context` }) }] });
104
+ break;
105
+ }
106
+ case 'cls_list_accounts': {
107
+ const accounts = client.listAccounts();
108
+ send(id, { content: [{ type: 'text', text: JSON.stringify(accounts, null, 2) }] });
109
+ break;
110
+ }
111
+ default:
112
+ sendError(id, -32601, `Unknown tool: ${name}`);
113
+ }
114
+ } catch (e) {
115
+ sendError(id, -32000, e.message);
116
+ }
117
+ }
118
+
119
+ const rl = readline.createInterface({ input: process.stdin });
120
+ rl.on('line', line => {
121
+ try {
122
+ const msg = JSON.parse(line);
123
+ const { id, method, params } = msg;
124
+ if (method === 'initialize') {
125
+ send(id, {
126
+ protocolVersion: '2024-11-05',
127
+ capabilities: { tools: {} },
128
+ serverInfo: { name: 'cls-mcp-server', version: '1.0.0' },
129
+ });
130
+ } else if (method === 'tools/list') {
131
+ send(id, { tools: TOOLS });
132
+ } else if (method === 'tools/call') {
133
+ handleCall(id, params.name, params.arguments || {});
134
+ } else if (method === 'notifications/initialized') {
135
+ // no response needed
136
+ } else {
137
+ sendError(id, -32601, `Unknown method: ${method}`);
138
+ }
139
+ } catch (e) {
140
+ sendError(null, -32700, `Parse error: ${e.message}`);
141
+ }
142
+ });
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "cls-log-cli",
3
+ "version": "1.2.6",
4
+ "description": "一行命令查腾讯云 CLS 日志 — CLI + MCP Server",
5
+ "bin": {
6
+ "cls": "bin/cls.js"
7
+ },
8
+ "files": [
9
+ "bin/",
10
+ "src/",
11
+ "mcp/",
12
+ "config/",
13
+ "scripts/"
14
+ ],
15
+ "scripts": {
16
+ "postinstall": "node scripts/postinstall.js"
17
+ },
18
+ "keywords": [
19
+ "cls",
20
+ "tencent-cloud",
21
+ "log",
22
+ "cli",
23
+ "mcp"
24
+ ],
25
+ "license": "MIT",
26
+ "engines": {
27
+ "node": ">=16"
28
+ }
29
+ }
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+ const os = require('os');
7
+
8
+ const CONFIG_DIR = path.join(os.homedir(), '.cls');
9
+ const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
10
+
11
+ if (fs.existsSync(CONFIG_FILE)) {
12
+ process.exit(0);
13
+ }
14
+
15
+ const config = { skill_dir: '', python: 'python3', accounts: {}, defaults: { limit: 200, out_dir: '~/.cls/logs', topic_type: 'error', regions: 'gz,bj', time_range: '15m' }, output: { format: 'jsonl', filename: '{account}_{query}_{ts}-{suffix}.jsonl' } };
16
+ fs.mkdirSync(CONFIG_DIR, { recursive: true });
17
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + '\n');
18
+
19
+ console.log('\n📋 cls-log-cli 已安装。输入 cls 自动进入配置向导。\n');