@dtt_siye/atool 1.3.1 → 1.5.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 (56) hide show
  1. package/README.md +97 -214
  2. package/README.md.atool-backup.20260410_114701 +299 -0
  3. package/VERSION +1 -1
  4. package/bin/atool.js +55 -9
  5. package/hooks/doc-sync-reminder +4 -4
  6. package/hooks/hooks-cursor.json +20 -0
  7. package/hooks/hooks.json +21 -1
  8. package/hooks/pre-commit +191 -0
  9. package/hooks/prompt-guard +84 -35
  10. package/hooks/session-start +34 -12
  11. package/hooks/task-state-tracker +145 -0
  12. package/install.sh +14 -4
  13. package/lib/common.sh +36 -23
  14. package/lib/compute-importance.sh +73 -0
  15. package/lib/install-cursor.sh +24 -2
  16. package/lib/install-hooks.sh +64 -0
  17. package/lib/install-kiro.sh +26 -2
  18. package/lib/install-skills.sh +5 -2
  19. package/lib/pre-scan.sh +13 -1
  20. package/lib/project-init.sh +28 -9
  21. package/package.json +1 -1
  22. package/skills/agent-audit/SKILL.md +180 -0
  23. package/skills/ai-project-architecture/SKILL.md +33 -534
  24. package/skills/ai-project-architecture/rules/architecture-validation.md +200 -0
  25. package/skills/ai-project-architecture/rules/compliance-check.md +83 -0
  26. package/skills/ai-project-architecture/rules/iron-laws.md +188 -0
  27. package/skills/ai-project-architecture/rules/migration.md +94 -0
  28. package/skills/ai-project-architecture/rules/refactoring.md +91 -0
  29. package/skills/ai-project-architecture/rules/testing.md +249 -0
  30. package/skills/ai-project-architecture/rules/verification.md +111 -0
  31. package/skills/architecture-guard/SKILL.md +164 -0
  32. package/skills/architecture-guard/rules/violation-detection.md +90 -0
  33. package/skills/atool-init/SKILL.md +24 -4
  34. package/skills/ci-feedback/SKILL.md +165 -0
  35. package/skills/project-analyze/SKILL.md +129 -19
  36. package/skills/project-analyze/phases/phase1-setup.md +76 -5
  37. package/skills/project-analyze/phases/phase2-understand.md +137 -26
  38. package/skills/project-analyze/phases/phase2.5-refine.md +32 -23
  39. package/skills/project-analyze/phases/phase3-graph.md +39 -5
  40. package/skills/project-analyze/phases/phase4-synthesize.md +17 -1
  41. package/skills/project-analyze/phases/phase5-export.md +42 -4
  42. package/skills/project-analyze/prompts/understand-agent.md +156 -298
  43. package/skills/project-analyze/rules/java.md +69 -1
  44. package/skills/project-query/SKILL.md +91 -200
  45. package/skills/project-query/rules/aggregate-stats.md +301 -0
  46. package/skills/project-query/rules/data-lineage.md +228 -0
  47. package/skills/project-query/rules/impact-analysis.md +218 -0
  48. package/skills/project-query/rules/neighborhood.md +234 -0
  49. package/skills/project-query/rules/node-lookup.md +97 -0
  50. package/skills/project-query/rules/path-query.md +135 -0
  51. package/skills/software-architecture/SKILL.md +39 -501
  52. package/skills/software-architecture/rules/concurrency-ha.md +346 -0
  53. package/skills/software-architecture/rules/ddd.md +450 -0
  54. package/skills/software-architecture/rules/decision-workflow.md +155 -0
  55. package/skills/software-architecture/rules/deployment.md +508 -0
  56. package/skills/software-architecture/rules/styles.md +232 -0
@@ -1,20 +1,34 @@
1
- # Phase 2: UNDERSTAND(AI Sub-Agents
1
+ # Phase 2: UNDERSTAND(AI Sub-Agents — 两阶段执行)
2
2
 
3
- **目标**:每个模块派发 1 sub-agent,产出三层文档(业务/技术/数据),直接写入 `atool-analysis/modules/`。
3
+ **目标**:每个模块派发 2 个串行 sub-agent(Stage 1 → Stage 2),产出三层文档。
4
4
 
5
- **并发上限:5 个 sub-agent**
5
+ **核心改进**:原设计是 1 个 sub-agent 产出 7 个文件(425 行 prompt,AI 遵循度低)。新设计拆为 2 个 stage:
6
+ - **Stage 1**:产出 `data.json` + `README.md`(~150 行 prompt)
7
+ - **Stage 2**:基于 data.json 产出 `api.md` + `data-model.md` + `dev-guide.md` + `prd.md` + `test-cases.md`(~120 行 prompt)
8
+
9
+ ---
10
+
11
+ ## IDE 适配(执行前检查)
12
+
13
+ - **Claude Code**:使用 Agent 工具批量派发,每批最多 5 个模块并行,每模块内 Stage 1→2 串行
14
+ - **Cursor/其他**:**顺序执行**,按 importance 降序逐模块处理(Stage 1→2 串行),每个模块完成后更新 state.json
15
+ - *原因*:Cursor 不支持并行 sub-agent,自动降级为逐个执行
16
+ - *判断方式*:若 Agent 工具不可用或不响应,自动切换到顺序模式
17
+
18
+ ---
6
19
 
7
20
  ## 前置检查
8
21
 
9
22
  1. 读取 `.atool-docs/analysis-state.json`
10
23
  2. 确认 `phases.phase1_setup == "completed"` — 否则先执行 Phase 1
11
24
  3. 如果 `phases.phase2_understand == "completed"` → 跳过
12
- 4. 加载模块列表 `state.modules[]`
25
+ 4. 加载模块列表 `state.modules[]`(优先使用聚合后的 `aggregated_modules`)
13
26
 
14
27
  ## 输入数据
15
28
 
16
29
  - Pre-Scan 数据:`.atool-docs/pre-scan/{module-slug}.json`(如存在)
17
30
  - 技术栈规则:`rules/{STACK}.md`(优先),fallback `rules/generic.md`
31
+ - Prompt 模板:`prompts/understand-agent.md`(包含 Stage 1 和 Stage 2 两个模板)
18
32
 
19
33
  ### Pre-scan 降级规则
20
34
 
@@ -36,43 +50,112 @@
36
50
  > **执行命令(可选):**
37
51
  > ```bash
38
52
  > DOCS_DIR="$(pwd)/.atool-docs"
39
- > if [ -f "$DOCS_DIR/pre-scan/manifest.json" ]; then
53
+ > # 优先使用聚合后的模块列表
54
+ > if jq -e '.aggregated_modules' "$DOCS_DIR/pre-scan/manifest.json" &>/dev/null; then
55
+ > jq -r '.aggregated_modules | sort_by(-.importance) | .[].slug' "$DOCS_DIR/pre-scan/manifest.json" 2>/dev/null
56
+ > else
40
57
  > jq -r '.modules | sort_by(-.importance) | .[].slug' "$DOCS_DIR/pre-scan/manifest.json" 2>/dev/null
41
58
  > fi
42
59
  > ```
43
60
 
44
61
  否则按 `state.modules[]` 原始顺序。
45
62
 
46
- ### 2.3 批量派发 Sub-Agents
63
+ ### 2.3 两阶段批量派发 Sub-Agents
47
64
 
48
65
  **规则**:
49
- - 每批最多 5 个 sub-agent 并行(使用 Agent 工具)
66
+ - 每批最多 5 个模块并行
67
+ - 每个模块内部严格串行:先 Stage 1,确认 data.json 生成后,再 Stage 2
50
68
  - 等待当前批次**全部完成**后再派发下一批
51
- - 每个 sub-agent 完成后立即更新 `module_status`
52
69
 
53
- **每个 sub-agent 使用 `prompts/understand-agent.md` 模板**
70
+ #### Stage 1 派发
54
71
 
55
- 派发前准备每个 sub-agent 的变量:
72
+ **使用 `prompts/understand-agent.md` 中的「Stage 1 Prompt」模板**
73
+
74
+ 派发前准备变量:
56
75
  1. `{module_name}` — 模块名(slug)
57
76
  2. `{module_path}` — 模块在项目中的路径
58
77
  3. `{prescan_data}` — 读取 `.atool-docs/pre-scan/{module-slug}.json` 的内容(或降级消息)
59
78
  4. `{stack_rules}` — 读取的技术栈规则内容
60
79
  5. `{depth_instructions}` — 当前深度级别的追加指令(L2 留空,L3/L4/L5 内联具体指令)
80
+ 6. `{project_name}` — 项目名
81
+ 7. `{module_list}` — 所有模块名列表
82
+
83
+ #### Stage 1 验证(硬性)
84
+
85
+ **在 Stage 1 sub-agent 完成后立即验证**:
86
+
87
+ ```bash
88
+ DOCS_DIR="$(pwd)/.atool-docs"
89
+ MODULE_SLUG="{module-slug}"
90
+ # 验证 data.json 存在且是合法 JSON
91
+ if [ -f "$DOCS_DIR/modules/$MODULE_SLUG/data.json" ] && jq empty "$DOCS_DIR/modules/$MODULE_SLUG/data.json" 2>/dev/null; then
92
+ # 验证必需字段存在
93
+ HAS_APIS=$(jq 'has("exposed_apis")' "$DOCS_DIR/modules/$MODULE_SLUG/data.json")
94
+ HAS_ENTITIES=$(jq 'has("data_entities")' "$DOCS_DIR/modules/$MODULE_SLUG/data.json")
95
+ HAS_DEPS=$(jq 'has("dependencies")' "$DOCS_DIR/modules/$MODULE_SLUG/data.json")
96
+ if [ "$HAS_APIS" = "true" ] && [ "$HAS_DEPS" = "true" ]; then
97
+ echo "✅ Stage 1 PASS: $MODULE_SLUG data.json valid"
98
+ else
99
+ echo "⚠️ Stage 1 WARNING: $MODULE_SLUG data.json missing fields (apis=$HAS_APIS deps=$HAS_DEPS)"
100
+ fi
101
+ else
102
+ echo "❌ Stage 1 FAIL: $MODULE_SLUG data.json missing or invalid"
103
+ fi
104
+ # 验证 README.md 存在且行数 < 300
105
+ if [ -f "atool-analysis/modules/$MODULE_SLUG/README.md" ]; then
106
+ LINES=$(wc -l < "atool-analysis/modules/$MODULE_SLUG/README.md" | tr -d ' ')
107
+ if [ "$LINES" -gt 300 ]; then
108
+ echo "⚠️ Stage 1 WARNING: $MODULE_SLUG README.md too long ($LINES lines, should be <150)"
109
+ fi
110
+ else
111
+ echo "❌ Stage 1 FAIL: $MODULE_SLUG README.md missing"
112
+ fi
113
+ ```
114
+
115
+ **如果 Stage 1 验证失败**:该模块不进入 Stage 2,标记为 "failed",打印错误信息,其他模块继续。
116
+
117
+ #### Stage 2 派发
118
+
119
+ **使用 `prompts/understand-agent.md` 中的「Stage 2 Prompt」模板**
120
+
121
+ 变量(比 Stage 1 少,因为数据已从 data.json 获取):
122
+ 1. `{module_name}` — 模块名(slug)
123
+ 2. `{module_path}` — 模块路径
124
+ 3. `{stack}` — 技术栈
125
+ 4. `{project_name}` — 项目名
126
+
127
+ #### Stage 2 验证(硬性)
128
+
129
+ ```bash
130
+ MODULE_SLUG="{module-slug}"
131
+ # 验证核心文件存在
132
+ MISSING=""
133
+ for f in api.md dev-guide.md prd.md test-cases.md; do
134
+ [ ! -f "atool-analysis/modules/$MODULE_SLUG/$f" ] && MISSING="$MISSING $f"
135
+ done
136
+ if [ -z "$MISSING" ]; then
137
+ echo "✅ Stage 2 PASS: $MODULE_SLUG all docs generated"
138
+ else
139
+ echo "❌ Stage 2 FAIL: $MODULE_SLUG missing:$MISSING"
140
+ fi
141
+ ```
61
142
 
62
143
  ### 2.4 Sub-Agent 输出路径
63
144
 
64
- 每个 sub-agent 写入以下文件:
145
+ 每个模块最终产出:
65
146
  ```
66
- atool-analysis/modules/{module-name}/README.md # 1: 业务摘要
67
- atool-analysis/modules/{module-name}/api.md # 层2a: 接口文档
68
- atool-analysis/modules/{module-name}/data-model.md # 层2b: 数据模型(如有实体)
69
- atool-analysis/modules/{module-name}/dev-guide.md # 层2c: 开发指引
70
- .atool-docs/modules/{module-name}/data.json # 层3: 机器数据(供 Phase 3)
147
+ atool-analysis/modules/{module-name}/README.md # Stage 1: 业务摘要(<150行)
148
+ atool-analysis/modules/{module-name}/api.md # Stage 2: 接口文档
149
+ atool-analysis/modules/{module-name}/data-model.md # Stage 2: 数据模型(如有实体)
150
+ atool-analysis/modules/{module-name}/dev-guide.md # Stage 2: 开发指引
151
+ atool-analysis/modules/{module-name}/prd.md # Stage 2: 模块 PRD
152
+ atool-analysis/modules/{module-name}/test-cases.md # Stage 2: 测试用例
153
+ .atool-docs/modules/{module-name}/data.json # Stage 1: 机器数据
71
154
  ```
72
155
 
73
156
  ### 2.5 Checkpoint 写入
74
157
 
75
- 每个模块完成后:
158
+ **只有 Stage 1 + Stage 2 都验证通过后**才写入 checkpoint:
76
159
 
77
160
  > **执行命令(必须通过 Bash 工具):**
78
161
  > ```bash
@@ -84,31 +167,59 @@ atool-analysis/modules/{module-name}/dev-guide.md # 层2c: 开发指引
84
167
  > && mv "$DOCS_DIR/analysis-state.json.tmp" "$DOCS_DIR/analysis-state.json"
85
168
  > ```
86
169
 
170
+ **重要**:不再在每个 sub-agent 完成后立即写入 checkpoint。只在两个 stage 都验证通过后才写入。
171
+
87
172
  ### 2.6 断点续传
88
173
 
89
174
  如果从中断恢复:
90
175
  1. 读取 `module_status`,找到 `phase2 != "completed"` 的模块
91
176
  2. 只对未完成模块派发 sub-agent
92
177
  3. 已完成模块跳过
178
+ 4. 对 in_progress 的模块,检查 data.json 是否存在:
179
+ - 存在 → 从 Stage 2 继续
180
+ - 不存在 → 从 Stage 1 重新开始
93
181
 
94
182
  ## 完成条件
95
183
 
96
184
  - 所有模块的 `module_status.{slug}.phase2 == "completed"`
97
- - 每个模块至少 5/6 核心文件存在(data-model.md 可选):
98
- - `atool-analysis/modules/*/README.md` ✓ 必须
99
- - `atool-analysis/modules/*/api.md` ✓ 必须
185
+ - 每个模块至少满足以下(data-model.md 可选):
186
+ - `atool-analysis/modules/*/README.md` ✓ 必须(行数 < 300)
187
+ - `atool-analysis/modules/*/api.md` ✓ 必须(或 README.md 注明无 API)
100
188
  - `atool-analysis/modules/*/dev-guide.md` ✓ 必须
101
189
  - `atool-analysis/modules/*/prd.md` ✓ 必须
102
190
  - `atool-analysis/modules/*/test-cases.md` ✓ 必须
103
191
  - `atool-analysis/modules/*/data-model.md` ○ 可选(无实体时可不存在)
104
- - `.atool-docs/modules/*/data.json` 全部存在
105
- - 更新 state:`phases.phase2_understand = "completed"`
192
+ - `.atool-docs/modules/*/data.json` 全部存在且是合法 JSON
193
+ - **硬验证**(必须通过 Bash 执行):
106
194
 
107
195
  > **执行命令:**
108
196
  > ```bash
109
197
  > DOCS_DIR="$(pwd)/.atool-docs"
110
- > jq --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
111
- > '.phases.phase2_understand = "completed" | .updated_at = $ts' \
112
- > "$DOCS_DIR/analysis-state.json" > "$DOCS_DIR/analysis-state.json.tmp" \
113
- > && mv "$DOCS_DIR/analysis-state.json.tmp" "$DOCS_DIR/analysis-state.json"
198
+ > FAIL_COUNT=0
199
+ > for slug in $(jq -r '.module_status | keys[]' "$DOCS_DIR/analysis-state.json" 2>/dev/null); do
200
+ > DATA_JSON=".atool-docs/modules/$slug/data.json"
201
+ > README="atool-analysis/modules/$slug/README.md"
202
+ > # 检查 data.json
203
+ > if ! jq empty "$DATA_JSON" 2>/dev/null; then
204
+ > echo "❌ FAIL: $slug — data.json missing or invalid"
205
+ > FAIL_COUNT=$((FAIL_COUNT + 1))
206
+ > continue
207
+ > fi
208
+ > # 检查核心文档
209
+ > for f in README.md dev-guide.md prd.md test-cases.md; do
210
+ > if [ ! -f "atool-analysis/modules/$slug/$f" ]; then
211
+ > echo "❌ FAIL: $slug — $f missing"
212
+ > FAIL_COUNT=$((FAIL_COUNT + 1))
213
+ > fi
214
+ > done
215
+ > done
216
+ > if [ "$FAIL_COUNT" -eq 0 ]; then
217
+ > echo "✅ All modules validated"
218
+ > jq --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
219
+ > '.phases.phase2_understand = "completed" | .updated_at = $ts' \
220
+ > "$DOCS_DIR/analysis-state.json" > "$DOCS_DIR/analysis-state.json.tmp" \
221
+ > && mv "$DOCS_DIR/analysis-state.json.tmp" "$DOCS_DIR/analysis-state.json"
222
+ > else
223
+ > echo "❌ $FAIL_COUNT validation failures — Phase 2 NOT completed"
224
+ > fi
114
225
  > ```
@@ -9,7 +9,7 @@
9
9
  ## 前置检查
10
10
 
11
11
  1. `analysis-state.json` 中 `phases.phase2_understand == "completed"`
12
- 2. 读取 `detected_stack` 用于 conventions 加载
12
+ 2. 读取 `stack` 用于 conventions 加载
13
13
  3. 如果 `phases.phase2_5_refine == "completed"` 且非 `--force`,跳过本 Phase
14
14
  4. 如果 `--skip-refine`,跳过本 Phase
15
15
 
@@ -27,7 +27,7 @@
27
27
 
28
28
  ```bash
29
29
  # 从 state.json 读取技术栈
30
- STACK=$(jq -r '.detected_stack // "generic"' .atool-docs/analysis-state.json)
30
+ STACK=$(jq -r '.stack // "generic"' .atool-docs/analysis-state.json)
31
31
  ```
32
32
 
33
33
  从对应 conventions SKILL.md 中提取以下章节内容(不加载全文,控制在 ~200 行):
@@ -94,11 +94,13 @@ MODULES=$(jq -r '.modules | sort_by(-.importance) | .[].name' .atool-docs/pre-sc
94
94
  {conventions_context}
95
95
 
96
96
  ## 精炼规则
97
- 参考 requirements-writer SKILL.md "Refine Mode(精炼模式)" 章节,严格按照其中的精炼逻辑执行:
98
- 1. 保留初稿 §1-§3 和原 §4 非目标(移至 §6)
99
- 2. 补全 §4 数据需求、§5 跨模块依赖、§7 风险与假设、§8 需求追溯矩阵
100
- 3. 增强 §2 加 FR-{MOD}-NNN 编号 + Given-When-Then AC + UI 交互表;§3 NFR-{MOD}-NNN 编号,标注 [待系统级确认]
101
- 4. 输出必须包含完整 8 节结构
97
+ **必须读取并遵循**:`~/.claude/skills/requirements-writer/SKILL.md` 中的 **Refine Mode(精炼模式)** 章节。该章节定义了标准的 PRD 精炼流程和输出格式。按照其中的精炼规则逐条执行。
98
+
99
+ 补充说明(与 Refine Mode 保持一致):
100
+ - 保留初稿 §1-§3 和原 §4 非目标(移至 §6)
101
+ - 补全 §4 数据需求、§5 跨模块依赖、§7 风险与假设、§8 需求追溯矩阵
102
+ - 增强 §2 加 FR-{MOD}-NNN 编号 + Given-When-Then AC + UI 交互表;§3 加 NFR-{MOD}-NNN 编号,标注 [待系统级确认]
103
+ - 输出必须包含完整 8 节结构
102
104
 
103
105
  ## 输出
104
106
  原地覆盖 atool-analysis/modules/{module_name}/prd.md
@@ -109,12 +111,13 @@ MODULES=$(jq -r '.modules | sort_by(-.importance) | .[].name' .atool-docs/pre-sc
109
111
  - 不创建新文件
110
112
  ```
111
113
 
112
- 完成后立即写入 checkpoint
114
+ 完成后立即写入 checkpoint(使用唯一临时文件避免并发竞争):
113
115
 
114
116
  ```bash
117
+ TMP_FILE=".atool-docs/analysis-state.json.tmp.{module_name}"
115
118
  jq --arg mod "{module_name}" \
116
119
  '.refine_status[$mod].prd_refine = "completed"' \
117
- .atool-docs/analysis-state.json > tmp && mv tmp .atool-docs/analysis-state.json
120
+ .atool-docs/analysis-state.json > "$TMP_FILE" && mv "$TMP_FILE" .atool-docs/analysis-state.json
118
121
  ```
119
122
 
120
123
  ---
@@ -151,10 +154,11 @@ jq --arg mod "{module_name}" \
151
154
  选择 C 时:`refine_status.{name}.degraded = true, degraded_reason = "PRD coverage {score}% below threshold"`
152
155
 
153
156
  ```bash
154
- # Gate 2 通过时写入
157
+ # Gate 2 通过时写入(使用唯一临时文件)
158
+ TMP_FILE=".atool-docs/analysis-state.json.tmp.{module_name}.gate2"
155
159
  jq --arg mod "{module_name}" --argjson score {score} \
156
160
  '.refine_status[$mod].prd_coverage = $score | .refine_status[$mod].prd_gate = "passed"' \
157
- .atool-docs/analysis-state.json > tmp && mv tmp .atool-docs/analysis-state.json
161
+ .atool-docs/analysis-state.json > "$TMP_FILE" && mv "$TMP_FILE" .atool-docs/analysis-state.json
158
162
  ```
159
163
 
160
164
  ---
@@ -186,12 +190,14 @@ jq --arg mod "{module_name}" --argjson score {score} \
186
190
  {conventions_context}
187
191
 
188
192
  ## 精炼规则
189
- 参考 software-architecture SKILL.md "Refine Mode(精炼模式)" 章节,严格按照其中的精炼逻辑执行:
190
- 1. 在现有 dev-guide.md 内容末尾追加(不删除原有内容)
191
- 2. 追加 B-subset 组件设计(分层表 + 边界 + 依赖方向)
192
- 3. 追加 C-subset 数据与交互设计(数据所有权 + 同步/异步边界 + API 契约)
193
- 4. 追加至少 1 ADR(使用 7 ADR 模板:Status/Context/Decision/Options/Consequences/NFR Impact/Related)
194
- 5. NFR 对齐:标注 [待系统级确认]
193
+ **必须读取并遵循**:`~/.claude/skills/software-architecture/SKILL.md` 中的 **Refine Mode(精炼模式)** 章节。该章节定义了标准的架构设计精炼流程和输出格式。按照其中的精炼规则逐条执行。
194
+
195
+ 补充说明(与 Refine Mode 保持一致):
196
+ - 在现有 dev-guide.md 内容末尾追加(不删除原有内容)
197
+ - 追加 B-subset 组件设计(分层表 + 边界 + 依赖方向)
198
+ - 追加 C-subset 数据与交互设计(数据所有权 + 同步/异步边界 + API 契约)
199
+ - 追加至少 1 个 ADR(使用 7 节 ADR 模板:Status/Context/Decision/Options/Consequences/NFR Impact/Related)
200
+ - NFR 对齐:标注 [待系统级确认]
195
201
 
196
202
  ## 输出
197
203
  原地覆盖 atool-analysis/modules/{module_name}/dev-guide.md
@@ -203,12 +209,13 @@ jq --arg mod "{module_name}" --argjson score {score} \
203
209
  - 不生成项目级文档(A/D/E/F)
204
210
  ```
205
211
 
206
- 完成后写入 checkpoint
212
+ 完成后写入 checkpoint(使用唯一临时文件):
207
213
 
208
214
  ```bash
215
+ TMP_FILE=".atool-docs/analysis-state.json.tmp.{module_name}.archrefine"
209
216
  jq --arg mod "{module_name}" \
210
217
  '.refine_status[$mod].arch_refine = "completed"' \
211
- .atool-docs/analysis-state.json > tmp && mv tmp .atool-docs/analysis-state.json
218
+ .atool-docs/analysis-state.json > "$TMP_FILE" && mv "$TMP_FILE" .atool-docs/analysis-state.json
212
219
  ```
213
220
 
214
221
  ---
@@ -226,17 +233,19 @@ jq --arg mod "{module_name}" \
226
233
  **失败** → 同 Gate 2 的三选项恢复机制(A 重试 / B 手动 / C 降级)
227
234
 
228
235
  ```bash
229
- # Gate 3 通过时写入
236
+ # Gate 3 通过时写入(使用唯一临时文件)
237
+ TMP_FILE=".atool-docs/analysis-state.json.tmp.{module_name}.gate3"
230
238
  jq --arg mod "{module_name}" \
231
239
  '.refine_status[$mod].arch_gate = "passed"' \
232
- .atool-docs/analysis-state.json > tmp && mv tmp .atool-docs/analysis-state.json
240
+ .atool-docs/analysis-state.json > "$TMP_FILE" && mv "$TMP_FILE" .atool-docs/analysis-state.json
233
241
  ```
234
242
 
235
243
  ### 2.5.5 完成 Checkpoint
236
244
 
237
- 每个模块完成全部精炼(或降级)后,写入完整状态:
245
+ 每个模块完成全部精炼(或降级)后,写入完整状态(使用唯一临时文件):
238
246
 
239
247
  ```bash
248
+ TMP_FILE=".atool-docs/analysis-state.json.tmp.{module_name}.final"
240
249
  jq --arg mod "{module_name}" \
241
250
  --argjson score {prd_score} \
242
251
  --arg conv "{conventions_skill}" \
@@ -249,7 +258,7 @@ jq --arg mod "{module_name}" \
249
258
  "conventions_loaded": $conv,
250
259
  "degraded": false,
251
260
  "degraded_reason": null
252
- }' .atool-docs/analysis-state.json > tmp && mv tmp .atool-docs/analysis-state.json
261
+ }' .atool-docs/analysis-state.json > "$TMP_FILE" && mv "$TMP_FILE" .atool-docs/analysis-state.json
253
262
  ```
254
263
 
255
264
  ### 2.5.6 跨 IDE 降级
@@ -2,14 +2,47 @@
2
2
 
3
3
  **目标**:从 Phase 2 的 data.json 构建知识图谱 + 五维分析。全部通过 bash 库函数执行,禁止 AI 生成。
4
4
 
5
- **执行时间目标**:< 30
5
+ **执行时间目标**:< 30秒(大型项目 < 60秒)
6
+
7
+ **性能特点**:
8
+ - Pure bash + jq(无 AI 开销)
9
+ - 线性时间复杂度:O(M*E),M=模块数,E=边数
10
+ - 内存消耗:~50MB per 100 modules(jq slurp)
11
+ - 中断保护:超过 120 秒自动停止,记录为 "failed"
6
12
 
7
13
  ## 前置检查
8
14
 
9
15
  1. 读取 `.atool-docs/analysis-state.json`
10
16
  2. 确认 `phases.phase2_understand == "completed"` — 否则先完成 Phase 2
11
17
  3. 如果 `phases.phase3_graph == "completed"` → 跳过
12
- 4. 确认 `.atool-docs/modules/*/data.json` 至少有 1 个文件存在
18
+ 4. **data.json 存在性硬验证(必须通过 Bash 执行)**:
19
+
20
+ > **执行命令:**
21
+ > ```bash
22
+ > DOCS_DIR="$(pwd)/.atool-docs"
23
+ > VALID_COUNT=0
24
+ > INVALID_COUNT=0
25
+ > for f in "$DOCS_DIR/modules/"*/data.json; do
26
+ > [ -f "$f" ] || continue
27
+ > if jq empty "$f" 2>/dev/null; then
28
+ > VALID_COUNT=$((VALID_COUNT + 1))
29
+ > else
30
+ > MODULE=$(basename "$(dirname "$f")")
31
+ > echo "⚠️ Invalid JSON: $MODULE/data.json"
32
+ > INVALID_COUNT=$((INVALID_COUNT + 1))
33
+ > fi
34
+ > done
35
+ > echo "Valid data.json: $VALID_COUNT | Invalid: $INVALID_COUNT"
36
+ > if [ "$VALID_COUNT" -eq 0 ]; then
37
+ > echo "❌ BLOCKED: No valid data.json files found. Phase 2 must complete successfully first."
38
+ > echo " Run Phase 2 to generate data.json files before proceeding."
39
+ > else
40
+ > echo "✅ Pre-check passed: $VALID_COUNT modules have valid data"
41
+ > fi
42
+ > ```
43
+ >
44
+ > **如果 VALID_COUNT == 0**:**终止 Phase 3**,将 `phases.phase3_graph` 标记为 `"blocked"`,告知用户需要先完成 Phase 2。
45
+ > **如果 VALID_COUNT > 0 但有 INVALID_COUNT**:记录 warning,仅使用 valid data.json 构建图谱。
13
46
 
14
47
  ## 步骤
15
48
 
@@ -58,7 +91,7 @@
58
91
  > **执行命令(必须通过 Bash 工具):**
59
92
  > ```bash
60
93
  > DOCS_DIR="$(pwd)/.atool-docs"
61
- > if [ -f "$DOCS_DIR/knowledge-graph.json" ]; then
94
+ > if [ -f "$DOCS_DIR/knowledge-graph.json" ] && jq -e '.nodes and .edges' "$DOCS_DIR/knowledge-graph.json" &>/dev/null; then
62
95
  > STATUS="completed"
63
96
  > else
64
97
  > STATUS="failed"
@@ -72,6 +105,7 @@
72
105
 
73
106
  ## 完成条件
74
107
 
75
- - `.atool-docs/knowledge-graph.json` 存在(或 state 标记为 "failed"
108
+ - 前置检查通过(至少 1 个有效 data.json
109
+ - `.atool-docs/knowledge-graph.json` 存在**且**包含 `nodes` 和 `edges` 字段
76
110
  - `.atool-docs/multi-dimensional-analysis.json` 存在(可选,失败不阻断)
77
- - `phases.phase3_graph` 已更新为 `"completed"` 或 `"failed"`
111
+ - `phases.phase3_graph` 已更新为 `"completed"` 或 `"failed"` 或 `"blocked"`
@@ -2,10 +2,26 @@
2
2
 
3
3
  **目标**:以 Phase 2.5 精炼后的模块文档 + 知识图谱为数据源,**聚合**为项目级交付物。Phase 4 不再从零生成模块级内容,而是聚合、补全项目级独有文档、并生成 PROJECT-DELIVERABLE.md 总览入口。
4
4
 
5
+ ---
6
+
7
+ ## IDE 适配(执行前检查)
8
+
9
+ - **Claude Code**:主 Agent 单条线执行 Phase 4 逻辑(无额外并行)
10
+ - **Cursor/其他**:同 Claude Code(Phase 4 本身是单 Agent,无 sub-agent 并行需求)
11
+
12
+ **注**:Phase 4 与 Phase 2/4 不同,本身不使用 sub-agents,仅为单条线聚合逻辑,故无 IDE 差异。
13
+
14
+ ---
15
+
5
16
  ## 前置检查
6
17
 
7
18
  1. 确认 `phases.phase2_understand == "completed"`(必须)
8
- 2. 检查 `phases.phase3_graph`:
19
+ 2. 检查 `phases.phase2_5_refine`(必须):
20
+ - `"completed"` → 使用精炼后的 prd.md、dev-guide.md(含 ADR、架构设计)
21
+ - `"skipped"` 或 `"failed"` → **警告用户并询问是否继续**
22
+ - 若继续:使用 Phase 2 初稿(内容可能不完整)
23
+ - 若中止:建议用户重新执行 Phase 2.5
24
+ 3. 检查 `phases.phase3_graph`:
9
25
  - `"completed"` → 可使用图谱数据生成完整文档
10
26
  - `"failed"` → 跳过图谱相关输出(data-flow.mmd、module-dependencies.mmd),其余正常生成
11
27
 
@@ -79,7 +79,7 @@
79
79
  > "module_count": $MODULE_COUNT,
80
80
  > "file_count": $FILE_COUNT,
81
81
  > "analyzed_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
82
- > "analysis_version": "5.1.0",
82
+ > "analysis_version": "5.2.0",
83
83
  > "atool_analysis_schema": "1.0"
84
84
  > }
85
85
  > EOF
@@ -101,7 +101,44 @@
101
101
  > fi
102
102
  > ```
103
103
 
104
- ### 5.4 生成 EXPORT-FULL.md(可选)
104
+ ### 5.4 生成 Cytoscape.js 可视化(可选)
105
+
106
+ **触发条件**:分析完成时,生成交互式 HTML 可视化
107
+
108
+ > **执行命令(通过 Bash 工具):**
109
+ > ```bash
110
+ > PROJECT_ROOT="$(pwd)"
111
+ > DOCS_DIR="$PROJECT_ROOT/.atool-docs"
112
+ >
113
+ > # 检查 knowledge-graph.json 是否存在
114
+ > if [ -f "$DOCS_DIR/knowledge-graph.json" ]; then
115
+ > # 调用 generate-visualization.sh
116
+ > if [ -f "$PROJECT_ROOT/lib/generate-visualization.sh" ]; then
117
+ > source "$PROJECT_ROOT/lib/generate-visualization.sh"
118
+ > generate_visualization "$DOCS_DIR"
119
+ > if [ -f "$DOCS_DIR/visualization/index.html" ]; then
120
+ > echo "✅ Visualization generated: $DOCS_DIR/visualization/index.html"
121
+ > du -h "$DOCS_DIR/visualization/index.html" | awk '{print "Size: " $1}'
122
+ > fi
123
+ > else
124
+ > echo "⚠️ lib/generate-visualization.sh not found — skipping visualization"
125
+ > fi
126
+ > else
127
+ > echo "⚠️ knowledge-graph.json not found — cannot generate visualization"
128
+ > fi
129
+ > ```
130
+
131
+ **输出**:
132
+ - `.atool-docs/visualization/index.html` — 完整交互式可视化
133
+ - Cytoscape.js + dagre 布局
134
+ - 14 节点类型着色,24 边类型线型
135
+ - G1-G5 缩放控件
136
+ - 搜索、影响分析、邻域查询
137
+ - 离线可打开(JS 库缓存到 `~/.atool/cache/visualization/`)
138
+
139
+ ---
140
+
141
+ ### 5.5 生成 EXPORT-FULL.md(可选)
105
142
 
106
143
  **触发条件**:用户使用 `--export` 参数,或在完成摘要中选择导出。
107
144
 
@@ -111,7 +148,8 @@
111
148
  OUTPUT="atool-analysis/EXPORT-FULL.md"
112
149
 
113
150
  # 1. 标题 + 元信息
114
- echo "# $(jq -r '.project' .atool-docs/analysis-state.json) — 完整项目交付文档" > "$OUTPUT"
151
+ PROJECT_NAME=$(jq -r '.project // (.project_root | split("/") | last)' .atool-docs/analysis-state.json)
152
+ echo "# $PROJECT_NAME — 完整项目交付文档" > "$OUTPUT"
115
153
  echo "" >> "$OUTPUT"
116
154
  echo "> 自动生成于 $(date '+%Y-%m-%d %H:%M') | 单文件导出版" >> "$OUTPUT"
117
155
  echo "" >> "$OUTPUT"
@@ -164,7 +202,7 @@ jq -r '.refine_status | to_entries[] | "| \(.key) | \(.value.prd_coverage // "N/
164
202
  jq '.deliverable_status.export_single_file = "completed"' .atool-docs/analysis-state.json > tmp && mv tmp .atool-docs/analysis-state.json
165
203
  ```
166
204
 
167
- ### 5.5 更新 State + 打印完成摘要
205
+ ### 5.6 更新 State + 打印完成摘要
168
206
 
169
207
  > **执行命令(必须通过 Bash 工具):**
170
208
  > ```bash