spec-agent 1.0.3

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 (86) hide show
  1. package/README.md +256 -0
  2. package/bin/spec-agent.js +14 -0
  3. package/dist/commands/analyze.d.ts +16 -0
  4. package/dist/commands/analyze.d.ts.map +1 -0
  5. package/dist/commands/analyze.js +283 -0
  6. package/dist/commands/analyze.js.map +1 -0
  7. package/dist/commands/clean.d.ts +9 -0
  8. package/dist/commands/clean.d.ts.map +1 -0
  9. package/dist/commands/clean.js +109 -0
  10. package/dist/commands/clean.js.map +1 -0
  11. package/dist/commands/dispatch.d.ts +12 -0
  12. package/dist/commands/dispatch.d.ts.map +1 -0
  13. package/dist/commands/dispatch.js +232 -0
  14. package/dist/commands/dispatch.js.map +1 -0
  15. package/dist/commands/doctor.d.ts +9 -0
  16. package/dist/commands/doctor.d.ts.map +1 -0
  17. package/dist/commands/doctor.js +153 -0
  18. package/dist/commands/doctor.js.map +1 -0
  19. package/dist/commands/learn.d.ts +13 -0
  20. package/dist/commands/learn.d.ts.map +1 -0
  21. package/dist/commands/learn.js +234 -0
  22. package/dist/commands/learn.js.map +1 -0
  23. package/dist/commands/merge.d.ts +11 -0
  24. package/dist/commands/merge.d.ts.map +1 -0
  25. package/dist/commands/merge.js +335 -0
  26. package/dist/commands/merge.js.map +1 -0
  27. package/dist/commands/pipeline.d.ts +19 -0
  28. package/dist/commands/pipeline.d.ts.map +1 -0
  29. package/dist/commands/pipeline.js +266 -0
  30. package/dist/commands/pipeline.js.map +1 -0
  31. package/dist/commands/plan.d.ts +13 -0
  32. package/dist/commands/plan.d.ts.map +1 -0
  33. package/dist/commands/plan.js +314 -0
  34. package/dist/commands/plan.js.map +1 -0
  35. package/dist/commands/scan.d.ts +28 -0
  36. package/dist/commands/scan.d.ts.map +1 -0
  37. package/dist/commands/scan.js +488 -0
  38. package/dist/commands/scan.js.map +1 -0
  39. package/dist/commands/status.d.ts +8 -0
  40. package/dist/commands/status.d.ts.map +1 -0
  41. package/dist/commands/status.js +146 -0
  42. package/dist/commands/status.js.map +1 -0
  43. package/dist/index.d.ts +2 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +126 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/services/document-parser.d.ts +49 -0
  48. package/dist/services/document-parser.d.ts.map +1 -0
  49. package/dist/services/document-parser.js +499 -0
  50. package/dist/services/document-parser.js.map +1 -0
  51. package/dist/services/llm.d.ts +61 -0
  52. package/dist/services/llm.d.ts.map +1 -0
  53. package/dist/services/llm.js +716 -0
  54. package/dist/services/llm.js.map +1 -0
  55. package/dist/types.d.ts +159 -0
  56. package/dist/types.d.ts.map +1 -0
  57. package/dist/types.js +4 -0
  58. package/dist/types.js.map +1 -0
  59. package/dist/utils/file.d.ts +10 -0
  60. package/dist/utils/file.d.ts.map +1 -0
  61. package/dist/utils/file.js +96 -0
  62. package/dist/utils/file.js.map +1 -0
  63. package/dist/utils/logger.d.ts +13 -0
  64. package/dist/utils/logger.d.ts.map +1 -0
  65. package/dist/utils/logger.js +55 -0
  66. package/dist/utils/logger.js.map +1 -0
  67. package/package.json +48 -0
  68. package/scripts/publish-npm.js +174 -0
  69. package/spec-agent-implementation.md +750 -0
  70. package/src/commands/analyze.ts +322 -0
  71. package/src/commands/clean.ts +88 -0
  72. package/src/commands/dispatch.ts +250 -0
  73. package/src/commands/doctor.ts +136 -0
  74. package/src/commands/learn.ts +261 -0
  75. package/src/commands/merge.ts +377 -0
  76. package/src/commands/pipeline.ts +306 -0
  77. package/src/commands/plan.ts +331 -0
  78. package/src/commands/scan.ts +568 -0
  79. package/src/commands/status.ts +129 -0
  80. package/src/index.ts +137 -0
  81. package/src/services/document-parser.ts +548 -0
  82. package/src/services/llm.ts +857 -0
  83. package/src/types.ts +161 -0
  84. package/src/utils/file.ts +60 -0
  85. package/src/utils/logger.ts +58 -0
  86. package/tsconfig.json +19 -0
package/README.md ADDED
@@ -0,0 +1,256 @@
1
+ # spec-agent
2
+
3
+ 多 Agent CLI 工具,用于拆解大型需求文档。
4
+
5
+ ## 在 Cursor 中使用
6
+
7
+ ### 1. 配置环境变量
8
+
9
+ 在 Cursor 的终端中设置 API Key:
10
+
11
+ ```bash
12
+ # 使用 OpenAI
13
+ export OPENAI_API_KEY=your_openai_key_here
14
+
15
+ # 或使用其他兼容 OpenAI API 的服务
16
+ export LLM_API_KEY=your_key_here
17
+ export LLM_BASE_URL=https://api.your-provider.com/v1
18
+ export LLM_MODEL=gpt-4o-mini
19
+ export LLM_TIMEOUT_MS=60000
20
+ export LLM_RETRIES=2
21
+ export LLM_RETRY_DELAY_MS=1200
22
+ ```
23
+
24
+ Windows PowerShell:
25
+ ```powershell
26
+ $env:OPENAI_API_KEY="your_openai_key_here"
27
+ ```
28
+
29
+ ### 2. 快速开始
30
+
31
+ ```bash
32
+ # 1. 扫描文档,生成分片清单
33
+ spec-agent scan --input ./docs --output ./output/manifest.json
34
+
35
+ # 2. 并行分析文档(需要配置 API Key)
36
+ spec-agent analyze --manifest ./output/manifest.json --output ./output/summaries
37
+
38
+ # 3. 合并分析结果
39
+ spec-agent merge --summaries ./output/summaries --output ./output/spec_summary.json
40
+
41
+ # 4. 生成任务计划
42
+ spec-agent plan --spec ./output/spec_summary.json --output ./output/task_plan.json
43
+
44
+ # 5. 分配任务给不同 Agent
45
+ spec-agent dispatch --plan ./output/task_plan.json --output ./output/dispatch_plan.json
46
+
47
+ # 或者一键执行全部
48
+ spec-agent pipeline --input ./docs --output ./output
49
+ ```
50
+
51
+ ### 3. 命令详解
52
+
53
+ #### scan - 文档扫描
54
+ ```bash
55
+ spec-agent scan --input <path> --output <manifest.json> [options]
56
+
57
+ Options:
58
+ --chunk-size <size> 分片大小 (默认: 200kb)
59
+ --min-chunk-size <size> 小分片合并阈值 (默认: 10kb)
60
+ --no-llm-chunking 关闭 LLM 智能切分,改为规则切分
61
+ --strict-llm LLM 切分失败时直接报错(不回退)
62
+ --format <type> 文档格式: auto, md, pdf, docx, html
63
+ --dry-run 预览分片计划
64
+ ```
65
+
66
+ 说明:
67
+ - `scan` 默认启用 LLM 结构分析(按语义和行号切分),更适合复杂文档。
68
+ - 当 LLM 调用临时失败时,会自动退回到“按大小强制切分”,避免使用脆弱的标题正则切分。
69
+ - `scan` 现在会提取文档中的嵌入图片(如 docx 内截图)并保留图片引用,不再直接丢弃图片信息。
70
+ - 在已配置 LLM 且模型支持多模态时,`scan` 会为图片生成简要语义摘要并写入 chunk 文本。
71
+
72
+ #### analyze - 并行分析
73
+ ```bash
74
+ spec-agent analyze --manifest <path> --output <dir> [options]
75
+
76
+ Options:
77
+ --agents <count> 并行 Agent 数量 (默认: auto)
78
+ --chunks <indices> 指定分析的 chunk,如: 0,1,2
79
+ --focus <type> 分析重点: full, features, data-model, api, pages
80
+ --retries <count> 单个 chunk 失败后的重试次数 (默认: 1)
81
+ --dry-run 预览分析计划
82
+ ```
83
+
84
+ 说明:
85
+ - 若有失败 chunk,会在输出目录生成 `analyze_failures.json`,便于后续重跑或排查。
86
+
87
+ #### merge - 合并结果
88
+ ```bash
89
+ spec-agent merge --summaries <dir> --output <spec.json> [options]
90
+
91
+ Options:
92
+ --strategy <type> 去重策略: conservative, aggressive
93
+ ```
94
+
95
+ #### plan - 生成任务计划
96
+ ```bash
97
+ spec-agent plan --spec <path> --output <plan.json> [options]
98
+
99
+ Options:
100
+ --framework <name> 目标框架: vue, react, angular
101
+ --type <type> 项目类型: spa, ssr, micro-frontend
102
+ ```
103
+
104
+ #### dispatch - 任务分配
105
+ ```bash
106
+ spec-agent dispatch --plan <path> --output <plan.json> [options]
107
+
108
+ Options:
109
+ --pool <agents> Agent 池配置,如: frontend:2,backend:1
110
+ ```
111
+
112
+ #### pipeline - 一键执行
113
+ ```bash
114
+ spec-agent pipeline --input <path> --output <dir> [options]
115
+
116
+ Options:
117
+ --chunk-size <size> 分片大小 (默认: 200kb)
118
+ --min-chunk-size <size> 小分片合并阈值 (默认: 10kb)
119
+ --analyze-retries <count> analyze 阶段单 chunk 重试次数 (默认: 1)
120
+ --analyze-budget-tokens <count> analyze 阶段 token 预算上限 (默认: 0=不限制)
121
+ --strict-llm LLM 切分失败时直接报错(不回退)
122
+ --from <phase> 从指定阶段恢复: scan, analyze, merge, plan, dispatch
123
+ --stop-at <phase> 执行到指定阶段停止
124
+ ```
125
+
126
+ #### doctor - 环境自检
127
+ ```bash
128
+ spec-agent doctor --workspace <dir> [--check-llm]
129
+ ```
130
+
131
+ ### 退出码约定(用于脚本/CI)
132
+
133
+ - `scan`:
134
+ - `1` 输入错误(路径/参数)
135
+ - `2` 配置错误(LLM API Key 缺失)
136
+ - `3` 严格 LLM 模式失败(`--strict-llm`)
137
+ - `10` 其他运行时错误
138
+ - `analyze`:
139
+ - `1` 输入错误(manifest/chunk 索引)
140
+ - `2` 配置错误(LLM 配置)
141
+ - `3` 部分 chunk 失败(会生成 `analyze_failures.json`)
142
+ - `10` 其他运行时错误
143
+ - `doctor`:
144
+ - `2` 存在失败检查项
145
+ - `1` 命令本身运行失败
146
+ - `pipeline`:
147
+ - `2` 任一阶段失败(同时输出 `pipeline_summary.json` 与 `run_report.json`)
148
+
149
+ #### status - 查看状态
150
+ ```bash
151
+ spec-agent status --workspace <dir>
152
+ ```
153
+
154
+ #### clean - 清理文件
155
+ ```bash
156
+ spec-agent clean --workspace <dir> [--all]
157
+ ```
158
+
159
+ ### 4. 环境变量配置
160
+
161
+ | 变量 | 说明 | 默认值 |
162
+ |------|------|--------|
163
+ | `OPENAI_API_KEY` | OpenAI API Key | - |
164
+ | `LLM_API_KEY` | 通用 LLM API Key | - |
165
+ | `OPENAI_BASE_URL` / `LLM_BASE_URL` | API 基础 URL | https://api.openai.com/v1 |
166
+ | `LLM_MODEL` | 模型名称 | gpt-4o-mini |
167
+ | `LLM_MODEL_SCAN` | scan 阶段模型(可选,未设置则使用 LLM_MODEL) | - |
168
+ | `LLM_MODEL_ANALYZE` | analyze 阶段模型(可选) | - |
169
+ | `LLM_MODEL_VISION` | 图片语义模型(可选) | - |
170
+ | `LLM_MAX_TOKENS` | 最大 token 数 | 4000 |
171
+ | `LLM_TEMPERATURE` | 温度参数 | 0.3 |
172
+ | `LLM_TIMEOUT_MS` | 单次请求超时(毫秒) | 60000 |
173
+ | `LLM_RETRIES` | 请求失败重试次数 | 2 |
174
+ | `LLM_RETRY_DELAY_MS` | 首次重试等待毫秒(指数退避) | 1200 |
175
+ | `LLM_IMAGE_MAX_PER_DOC` | 每个文档最多做语义理解的图片数 | 12 |
176
+ | `LLM_IMAGE_MAX_BYTES` | 单张图片最大请求字节(超出跳过) | 2097152 |
177
+ | `PDF_IMAGE_PAGE_LIMIT` | PDF 最多抽取多少页做图片语义理解 | 8 |
178
+ | `MAX_ANALYZE_TOKENS` | analyze 阶段总 token 预算(0=不限制) | 0 |
179
+
180
+ 说明:
181
+ - PDF 图片页抽取依赖系统命令 `pdftoppm`(Poppler)。若环境中不存在该命令,流程会自动降级为仅文本解析,不会中断。
182
+
183
+ #### 阿里百炼(DashScope)配置示例
184
+
185
+ PowerShell(当前终端生效):
186
+
187
+ ```powershell
188
+ $env:LLM_API_KEY="你的百炼API-KEY"
189
+ $env:LLM_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"
190
+ $env:LLM_MODEL="qwen-plus"
191
+ $env:LLM_MODEL_VISION="qwen-vl-plus"
192
+ $env:LLM_MODEL_ANALYZE="qwen-plus"
193
+ $env:MAX_ANALYZE_TOKENS="250000"
194
+ ```
195
+
196
+ PowerShell(持久化到用户环境变量):
197
+
198
+ ```powershell
199
+ setx LLM_API_KEY "你的百炼API-KEY"
200
+ setx LLM_BASE_URL "https://dashscope.aliyuncs.com/compatible-mode/v1"
201
+ setx LLM_MODEL "qwen-plus"
202
+ setx LLM_MODEL_VISION "qwen-vl-plus"
203
+ setx LLM_MODEL_ANALYZE "qwen-plus"
204
+ setx MAX_ANALYZE_TOKENS "250000"
205
+ ```
206
+
207
+ 可用以下命令验证配置是否生效:
208
+
209
+ ```bash
210
+ node dist/index.js doctor --workspace . --check-llm --format json
211
+ ```
212
+
213
+ ### 5. 工作流程
214
+
215
+ ```
216
+ ┌─────────┐ ┌──────────┐ ┌────────┐ ┌────────┐ ┌──────────┐
217
+ │ Scan │ → │ Analyze │ → │ Merge │ → │ Plan │ → │ Dispatch │
218
+ │ (Scanner)│ │(Analyst×N)│ │(Architect)│ │(Planner)│ │(Dispatcher)│
219
+ └─────────┘ └──────────┘ └────────┘ └────────┘ └──────────┘
220
+ │ │ │ │ │
221
+ ▼ ▼ ▼ ▼ ▼
222
+ manifest.json chunk_*.json spec.json task_plan.json dispatch.json
223
+ ```
224
+
225
+ ### 6. 支持的文档格式
226
+
227
+ - `.md` - Markdown
228
+ - `.txt` - 纯文本
229
+ - `.html` / `.htm` - HTML
230
+ - `.pdf` - PDF (需要安装依赖)
231
+ - `.docx` - Word 文档 (需要安装依赖)
232
+
233
+ ### 7. 断点恢复
234
+
235
+ 如果流程中断,可以从任意阶段恢复:
236
+
237
+ ```bash
238
+ # 查看当前状态
239
+ spec-agent status --workspace ./output
240
+
241
+ # 从指定阶段恢复
242
+ spec-agent pipeline --input ./docs --output ./output --from analyze
243
+ ```
244
+
245
+ ## 开发
246
+
247
+ ```bash
248
+ # 安装依赖
249
+ npm install
250
+
251
+ # 编译
252
+ npm run build
253
+
254
+ # 开发模式
255
+ npm run dev
256
+ ```
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+
3
+ const path = require('path');
4
+ const fs = require('fs');
5
+
6
+ // Check if dist exists, if not show helpful message
7
+ const distPath = path.join(__dirname, '..', 'dist', 'index.js');
8
+ if (!fs.existsSync(distPath)) {
9
+ console.error('Error: spec-agent is not built yet.');
10
+ console.error('Please run: npm install && npm run build');
11
+ process.exit(1);
12
+ }
13
+
14
+ require(distPath);
@@ -0,0 +1,16 @@
1
+ import { Command } from 'commander';
2
+ interface AnalyzeOptions {
3
+ manifest: string;
4
+ output: string;
5
+ agents: string;
6
+ chunks?: string;
7
+ focus: string;
8
+ retries: string;
9
+ budgetTokens?: string;
10
+ applyLearned?: boolean;
11
+ dryRun?: boolean;
12
+ yes?: boolean;
13
+ }
14
+ export declare function analyzeCommand(options: AnalyzeOptions, command: Command): Promise<void>;
15
+ export {};
16
+ //# sourceMappingURL=analyze.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze.d.ts","sourceRoot":"","sources":["../../src/commands/analyze.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC,UAAU,cAAc;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAoBD,wBAAsB,cAAc,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA8Q7F"}
@@ -0,0 +1,283 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.analyzeCommand = analyzeCommand;
37
+ const path = __importStar(require("path"));
38
+ const crypto_1 = require("crypto");
39
+ const logger_1 = require("../utils/logger");
40
+ const file_1 = require("../utils/file");
41
+ const llm_1 = require("../services/llm");
42
+ const document_parser_1 = require("../services/document-parser");
43
+ const ANALYZE_EXIT_CODE = {
44
+ INPUT_ERROR: 1,
45
+ CONFIG_ERROR: 2,
46
+ PARTIAL_FAILED: 3,
47
+ RUNTIME_ERROR: 10,
48
+ };
49
+ async function analyzeCommand(options, command) {
50
+ const logger = new logger_1.Logger();
51
+ try {
52
+ // Check manifest exists
53
+ const manifestPath = path.resolve(options.manifest);
54
+ if (!(await (0, file_1.fileExists)(manifestPath))) {
55
+ logger.error(`[E_ANALYZE_INPUT] Manifest not found: ${options.manifest}`);
56
+ logger.info('Run spec-agent scan first to create a manifest.');
57
+ process.exit(ANALYZE_EXIT_CODE.INPUT_ERROR);
58
+ }
59
+ const manifest = await (0, file_1.readJson)(manifestPath);
60
+ // Determine which chunks to analyze
61
+ let chunkIndices = [];
62
+ if (options.chunks) {
63
+ chunkIndices = options.chunks.split(',').map(s => parseInt(s.trim(), 10));
64
+ }
65
+ else {
66
+ chunkIndices = manifest.chunks.map((_, i) => i);
67
+ }
68
+ // Validate chunk indices
69
+ const invalidIndices = chunkIndices.filter(i => i < 0 || i >= manifest.chunks.length);
70
+ if (invalidIndices.length > 0) {
71
+ logger.error(`[E_ANALYZE_INPUT] Invalid chunk indices: ${invalidIndices.join(', ')}`);
72
+ logger.info(`Valid range: 0-${manifest.chunks.length - 1}`);
73
+ process.exit(ANALYZE_EXIT_CODE.INPUT_ERROR);
74
+ }
75
+ // Get LLM config
76
+ const llmConfig = (0, llm_1.getLLMConfigForPurpose)('analyze');
77
+ if (options.dryRun) {
78
+ logger.info('Dry run mode - analysis plan:');
79
+ logger.info(`LLM Config: ${llmConfig.model} @ ${llmConfig.baseUrl}`);
80
+ for (const idx of chunkIndices) {
81
+ const chunk = manifest.chunks[idx];
82
+ logger.info(` Chunk ${idx}: ${chunk.sourceFiles.length} files, ${(0, file_1.formatSize)(chunk.size)}`);
83
+ }
84
+ return;
85
+ }
86
+ // Validate LLM config (skip if explicitly bypassed)
87
+ try {
88
+ (0, llm_1.validateLLMConfig)(llmConfig);
89
+ }
90
+ catch (error) {
91
+ logger.error(`LLM Configuration Error: ${error instanceof Error ? error.message : String(error)}`);
92
+ logger.info('\nTo use analyze, set one of these environment variables:');
93
+ logger.info(' export OPENAI_API_KEY=your_key_here');
94
+ logger.info(' export LLM_API_KEY=your_key_here');
95
+ logger.info('\nOptional configuration:');
96
+ logger.info(' export OPENAI_BASE_URL=https://api.openai.com/v1 # or your custom endpoint');
97
+ logger.info(' export LLM_MODEL=gpt-4o-mini # or gpt-4o, claude-3-sonnet, etc.');
98
+ process.exit(ANALYZE_EXIT_CODE.CONFIG_ERROR);
99
+ }
100
+ logger.info(`Analyzing ${chunkIndices.length} chunks with focus: ${options.focus}`);
101
+ logger.info(`Using LLM: ${llmConfig.model}`);
102
+ // Ensure output directory
103
+ const outputDir = path.resolve(options.output);
104
+ await (0, file_1.ensureDir)(outputDir);
105
+ const cacheDir = path.join(outputDir, '.cache', 'analyze');
106
+ await (0, file_1.ensureDir)(cacheDir);
107
+ // Analyze chunks
108
+ const results = [];
109
+ const startTime = Date.now();
110
+ logger.info('Starting parallel analysis...');
111
+ // Process chunks in parallel
112
+ const concurrencyRaw = options.agents === 'auto'
113
+ ? Math.min(4, chunkIndices.length)
114
+ : parseInt(options.agents, 10);
115
+ const concurrency = Number.isFinite(concurrencyRaw) && concurrencyRaw > 0
116
+ ? concurrencyRaw
117
+ : 1;
118
+ let totalTokens = 0;
119
+ let cachedChunks = 0;
120
+ let llmInvocations = 0;
121
+ const maxRetries = Math.max(0, parseInt(options.retries || '1', 10) || 0);
122
+ const budgetTokens = Math.max(0, parseInt(options.budgetTokens || process.env.MAX_ANALYZE_TOKENS || '0', 10) || 0);
123
+ const failures = [];
124
+ for (let i = 0; i < chunkIndices.length; i += concurrency) {
125
+ const batch = chunkIndices.slice(i, i + concurrency);
126
+ logger.progress(i, chunkIndices.length, `Analyzing chunks ${batch.join(', ')}...`);
127
+ // Process batch in parallel
128
+ const batchResults = await Promise.all(batch.map(async (idx) => {
129
+ const chunk = manifest.chunks[idx];
130
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
131
+ try {
132
+ // Read chunk content
133
+ logger.debug(`Reading chunk ${idx}: ${chunk.sourceFiles.length} files`);
134
+ let content;
135
+ if (chunk.contentPath && await (0, file_1.fileExists)(chunk.contentPath)) {
136
+ // Read from chunk file
137
+ content = await (0, file_1.readFileContent)(chunk.contentPath);
138
+ }
139
+ else if (chunk.content) {
140
+ // Read from manifest (legacy)
141
+ content = chunk.content;
142
+ }
143
+ else {
144
+ // Fallback: read from source files
145
+ content = await (0, document_parser_1.readChunkContent)(chunk.sourceFiles);
146
+ }
147
+ const cacheKey = (0, crypto_1.createHash)('sha256')
148
+ .update(content)
149
+ .update(`|focus:${options.focus}|model:${llmConfig.model}|v:analyze-2`)
150
+ .digest('hex');
151
+ const cachePath = path.join(cacheDir, `${cacheKey}.json`);
152
+ if (await (0, file_1.fileExists)(cachePath)) {
153
+ const cached = await (0, file_1.readJson)(cachePath);
154
+ cachedChunks++;
155
+ if (cached.llmUsage) {
156
+ totalTokens += cached.llmUsage.totalTokens;
157
+ }
158
+ cached.sourceFiles = chunk.sourceFiles;
159
+ cached.size = (0, file_1.formatSize)(chunk.size);
160
+ return { ok: true, summary: cached };
161
+ }
162
+ if (budgetTokens > 0 && totalTokens >= budgetTokens) {
163
+ return {
164
+ ok: false,
165
+ failure: {
166
+ chunkId: idx,
167
+ sourceFiles: chunk.sourceFiles,
168
+ attempts: attempt + 1,
169
+ error: `Token budget exceeded (${totalTokens}/${budgetTokens})`,
170
+ },
171
+ };
172
+ }
173
+ // Analyze with LLM
174
+ logger.debug(`Sending chunk ${idx} to LLM (${content.length} chars), attempt ${attempt + 1}/${maxRetries + 1}`);
175
+ llmInvocations++;
176
+ const summary = await (0, llm_1.analyzeChunkWithLLM)(content, idx, options.focus, llmConfig, logger);
177
+ // Fill in source info
178
+ summary.sourceFiles = chunk.sourceFiles;
179
+ summary.size = (0, file_1.formatSize)(chunk.size);
180
+ if (summary.llmUsage) {
181
+ totalTokens += summary.llmUsage.totalTokens;
182
+ }
183
+ await (0, file_1.writeJson)(cachePath, summary);
184
+ return { ok: true, summary };
185
+ }
186
+ catch (error) {
187
+ const canRetry = attempt < maxRetries;
188
+ const errorText = error instanceof Error ? error.message : String(error);
189
+ if (canRetry) {
190
+ logger.warn(`Chunk ${idx} 分析失败,准备重试 (${attempt + 1}/${maxRetries}): ${errorText}`);
191
+ continue;
192
+ }
193
+ return {
194
+ ok: false,
195
+ failure: {
196
+ chunkId: idx,
197
+ sourceFiles: chunk.sourceFiles,
198
+ attempts: attempt + 1,
199
+ error: errorText,
200
+ },
201
+ };
202
+ }
203
+ }
204
+ return {
205
+ ok: false,
206
+ failure: {
207
+ chunkId: idx,
208
+ sourceFiles: chunk.sourceFiles,
209
+ attempts: maxRetries + 1,
210
+ error: 'Unknown analysis error',
211
+ },
212
+ };
213
+ }));
214
+ const successResults = batchResults
215
+ .filter((item) => item.ok)
216
+ .map(item => item.summary);
217
+ const failedResults = batchResults
218
+ .filter((item) => !item.ok)
219
+ .map(item => item.failure);
220
+ results.push(...successResults);
221
+ failures.push(...failedResults);
222
+ // Save individual chunk summaries
223
+ for (const summary of successResults) {
224
+ const summaryPath = path.join(outputDir, `chunk_${summary.chunkId}_summary.json`);
225
+ await (0, file_1.writeJson)(summaryPath, summary);
226
+ }
227
+ }
228
+ const duration = ((Date.now() - startTime) / 1000).toFixed(1);
229
+ const failuresPath = path.join(outputDir, 'analyze_failures.json');
230
+ if (failures.length > 0) {
231
+ await (0, file_1.writeJson)(failuresPath, {
232
+ status: 'partial_failed',
233
+ createdAt: new Date().toISOString(),
234
+ chunksRequested: chunkIndices.length,
235
+ chunksSucceeded: results.length,
236
+ chunksFailed: failures.length,
237
+ failures,
238
+ });
239
+ }
240
+ logger.success(`Analysis complete in ${duration}s`);
241
+ if (failures.length > 0) {
242
+ logger.warn(`有 ${failures.length} 个 chunk 失败,详情见: ${failuresPath}`);
243
+ }
244
+ logger.json({
245
+ status: failures.length > 0 ? 'partial_failed' : 'success',
246
+ chunksAnalyzed: results.length,
247
+ chunksFailed: failures.length,
248
+ totalFeatures: results.reduce((sum, r) => sum + r.features.length, 0),
249
+ totalDataModels: results.reduce((sum, r) => sum + r.dataModels.length, 0),
250
+ totalPages: results.reduce((sum, r) => sum + r.pages.length, 0),
251
+ totalApis: results.reduce((sum, r) => sum + r.apis.length, 0),
252
+ totalTokens,
253
+ cachedChunks,
254
+ llmInvocations,
255
+ tokenBudget: budgetTokens > 0 ? budgetTokens : undefined,
256
+ retriesPerChunk: maxRetries,
257
+ failuresPath: failures.length > 0 ? failuresPath : undefined,
258
+ outputDir,
259
+ });
260
+ const analyzeReportPath = path.join(outputDir, 'analyze_report.json');
261
+ await (0, file_1.writeJson)(analyzeReportPath, {
262
+ createdAt: new Date().toISOString(),
263
+ status: failures.length > 0 ? 'partial_failed' : 'success',
264
+ chunksRequested: chunkIndices.length,
265
+ chunksSucceeded: results.length,
266
+ chunksFailed: failures.length,
267
+ retriesPerChunk: maxRetries,
268
+ cachedChunks,
269
+ llmInvocations,
270
+ totalTokens,
271
+ tokenBudget: budgetTokens > 0 ? budgetTokens : undefined,
272
+ cacheDir,
273
+ });
274
+ if (failures.length > 0) {
275
+ process.exit(ANALYZE_EXIT_CODE.PARTIAL_FAILED);
276
+ }
277
+ }
278
+ catch (error) {
279
+ logger.error(`Analysis failed: ${error instanceof Error ? error.message : String(error)}`);
280
+ process.exit(ANALYZE_EXIT_CODE.RUNTIME_ERROR);
281
+ }
282
+ }
283
+ //# sourceMappingURL=analyze.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze.js","sourceRoot":"","sources":["../../src/commands/analyze.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { Command } from 'commander';
2
+ interface CleanOptions {
3
+ workspace: string;
4
+ dryRun?: boolean;
5
+ yes?: boolean;
6
+ }
7
+ export declare function cleanCommand(options: CleanOptions, command: Command): Promise<void>;
8
+ export {};
9
+ //# sourceMappingURL=clean.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clean.d.ts","sourceRoot":"","sources":["../../src/commands/clean.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,UAAU,YAAY;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAgBD,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA6DzF"}