speccore 8.3.174 → 8.3.176
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.
- package/dist/cli.js +42 -134
- package/dist/cli.js.map +1 -1
- package/dist/commands/analyze.d.ts.map +1 -1
- package/dist/commands/analyze.js +23 -49
- package/dist/commands/analyze.js.map +1 -1
- package/dist/commands/change.js +4 -4
- package/dist/commands/change.js.map +1 -1
- package/dist/commands/context-output.js +1 -1
- package/dist/commands/context-output.js.map +1 -1
- package/dist/commands/doc2spec.d.ts +1 -0
- package/dist/commands/doc2spec.d.ts.map +1 -1
- package/dist/commands/doc2spec.js +128 -4
- package/dist/commands/doc2spec.js.map +1 -1
- package/dist/commands/execute.js +6 -7
- package/dist/commands/execute.js.map +1 -1
- package/dist/commands/help.js +2 -2
- package/dist/commands/help.js.map +1 -1
- package/dist/commands/import.js +3 -3
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/init.d.ts +1 -1
- package/dist/commands/init.js +17 -17
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/iteration/split.d.ts.map +1 -1
- package/dist/commands/iteration/split.js +5 -9
- package/dist/commands/iteration/split.js.map +1 -1
- package/dist/commands/iteration-from-global.js +1 -1
- package/dist/commands/iteration-from-global.js.map +1 -1
- package/dist/commands/lifecycle.js +2 -2
- package/dist/commands/lifecycle.js.map +1 -1
- package/dist/commands/migrate.js +3 -3
- package/dist/commands/migrate.js.map +1 -1
- package/dist/commands/retro.js +3 -3
- package/dist/commands/retro.js.map +1 -1
- package/dist/commands/synthesize.d.ts +2 -2
- package/dist/commands/synthesize.js +11 -11
- package/dist/commands/synthesize.js.map +1 -1
- package/dist/commands/task/new.js +1 -1
- package/dist/commands/task/new.js.map +1 -1
- package/dist/commands/units.d.ts +10 -0
- package/dist/commands/units.d.ts.map +1 -0
- package/dist/commands/units.js +280 -0
- package/dist/commands/units.js.map +1 -0
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +14 -15
- package/dist/commands/update.js.map +1 -1
- package/dist/core/agent-adapter.js +1 -1
- package/dist/core/agent-adapter.js.map +1 -1
- package/dist/core/agents/index.js +1 -1
- package/dist/core/agents/index.js.map +1 -1
- package/dist/core/ai-context-generator.js +1 -1
- package/dist/core/ai-context-generator.js.map +1 -1
- package/dist/core/analyze-engine.js +4 -4
- package/dist/core/analyze-engine.js.map +1 -1
- package/dist/core/ask-config.js +1 -1
- package/dist/core/ask-config.js.map +1 -1
- package/dist/core/code-scanner.js +1 -1
- package/dist/core/code-scanner.js.map +1 -1
- package/dist/core/git-integration.d.ts +1 -1
- package/dist/core/git-integration.js +3 -3
- package/dist/core/git-integration.js.map +1 -1
- package/dist/core/global-artifacts.js +1 -1
- package/dist/core/global-artifacts.js.map +1 -1
- package/dist/core/global-counters.js +2 -2
- package/dist/core/global-counters.js.map +1 -1
- package/dist/core/handoff-generator.d.ts +14 -0
- package/dist/core/handoff-generator.d.ts.map +1 -0
- package/dist/core/handoff-generator.js +218 -0
- package/dist/core/handoff-generator.js.map +1 -0
- package/dist/core/knowledge-graph.js +8 -8
- package/dist/core/knowledge-graph.js.map +1 -1
- package/dist/core/prompt-builder.d.ts.map +1 -1
- package/dist/core/prompt-builder.js +5 -6
- package/dist/core/prompt-builder.js.map +1 -1
- package/dist/core/rag-engine.js +3 -3
- package/dist/core/rag-engine.js.map +1 -1
- package/dist/core/reindex-engine.js +1 -1
- package/dist/core/reindex-engine.js.map +1 -1
- package/dist/core/requirement-clarifier.d.ts +1 -1
- package/dist/core/requirement-clarifier.js +3 -3
- package/dist/core/requirement-clarifier.js.map +1 -1
- package/dist/core/spec-paths.d.ts +4 -4
- package/dist/core/spec-paths.js +10 -10
- package/dist/core/spec-paths.js.map +1 -1
- package/dist/core/spec-skeleton.js +1 -1
- package/dist/core/spec-skeleton.js.map +1 -1
- package/dist/core/state.js +6 -6
- package/dist/core/state.js.map +1 -1
- package/dist/core/streaming-analyzer.js +1 -1
- package/dist/core/task-paths.d.ts +2 -2
- package/dist/core/task-paths.js +3 -3
- package/dist/core/task-paths.js.map +1 -1
- package/dist/core/unified-config.d.ts +2 -2
- package/dist/core/unified-config.d.ts.map +1 -1
- package/dist/core/unified-config.js +2 -2
- package/dist/core/unified-config.js.map +1 -1
- package/dist/core/verify-engine.js +5 -5
- package/dist/core/verify-engine.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateHandoff = generateHandoff;
|
|
4
|
+
exports.getHandoffPath = getHandoffPath;
|
|
5
|
+
exports.handoffExists = handoffExists;
|
|
6
|
+
/**
|
|
7
|
+
* handoff-generator — 阶段传递摘要生成器
|
|
8
|
+
*
|
|
9
|
+
* 每个 Pipeline 阶段完成后,生成精简的传递摘要给下一阶段 AI 使用。
|
|
10
|
+
* 核心原则:完整版存文件,传递版只给下一阶段 AI 看。
|
|
11
|
+
*/
|
|
12
|
+
const fs_extra_1 = require("fs-extra");
|
|
13
|
+
const path_1 = require("path");
|
|
14
|
+
const HANDOFF_LIMITS = {
|
|
15
|
+
'analyze-split': { maxLines: 60, requiredSections: ['modules', 'dependencies', 'constraints'] },
|
|
16
|
+
'split-plan': { maxLines: 60, requiredSections: ['tasks', 'dependencies', 'staffing'] },
|
|
17
|
+
'plan-execute': { maxLines: 150, requiredSections: ['currentTask', 'upstreamContracts', 'globalConstraints'] },
|
|
18
|
+
'execute-review': { maxLines: 80, requiredSections: ['deliverables', 'acceptanceCriteria'] },
|
|
19
|
+
'review-done': { maxLines: 40, requiredSections: ['reviewResults', 'openIssues'] },
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* 生成阶段传递摘要
|
|
23
|
+
*/
|
|
24
|
+
async function generateHandoff(from, to, iteration) {
|
|
25
|
+
const iterDir = `Iteration-${iteration.replace(/^Iteration-/, '')}`;
|
|
26
|
+
const handoffDir = (0, path_1.join)('.speccore', 'local', 'handoffs');
|
|
27
|
+
await (0, fs_extra_1.ensureDir)(handoffDir);
|
|
28
|
+
const handoffKey = `${from}-${to}`;
|
|
29
|
+
const config = HANDOFF_LIMITS[handoffKey];
|
|
30
|
+
if (!config) {
|
|
31
|
+
throw new Error(`未知阶段传递: ${from} → ${to}`);
|
|
32
|
+
}
|
|
33
|
+
const summary = await buildHandoffContent(from, to, iterDir, config);
|
|
34
|
+
const handoffPath = (0, path_1.join)(handoffDir, `handoff-${handoffKey}.md`);
|
|
35
|
+
await (0, fs_extra_1.writeFile)(handoffPath, summary);
|
|
36
|
+
return handoffPath;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* 构建传递摘要内容
|
|
40
|
+
*/
|
|
41
|
+
async function buildHandoffContent(from, to, iterDir, config) {
|
|
42
|
+
const lines = [];
|
|
43
|
+
// 头部信息
|
|
44
|
+
lines.push(`# 阶段传递:${from} → ${to}`);
|
|
45
|
+
lines.push('');
|
|
46
|
+
lines.push('## 1. 核心信息');
|
|
47
|
+
lines.push('');
|
|
48
|
+
lines.push(`| 项目 | 内容 |`);
|
|
49
|
+
lines.push(`| :--- | :--- |`);
|
|
50
|
+
lines.push(`| 迭代 | ${iterDir} |`);
|
|
51
|
+
lines.push(`| 阶段 | ${from} → ${to} |`);
|
|
52
|
+
lines.push(`| 时间 | ${new Date().toISOString().split('T')[0]} |`);
|
|
53
|
+
lines.push('');
|
|
54
|
+
// 根据阶段组合生成不同内容
|
|
55
|
+
switch (`${from}-${to}`) {
|
|
56
|
+
case 'analyze-split':
|
|
57
|
+
await appendAnalyzeToSplit(lines, iterDir);
|
|
58
|
+
break;
|
|
59
|
+
case 'split-plan':
|
|
60
|
+
await appendSplitToPlan(lines, iterDir);
|
|
61
|
+
break;
|
|
62
|
+
case 'plan-execute':
|
|
63
|
+
await appendPlanToExecute(lines, iterDir);
|
|
64
|
+
break;
|
|
65
|
+
case 'execute-review':
|
|
66
|
+
await appendExecuteToReview(lines, iterDir);
|
|
67
|
+
break;
|
|
68
|
+
case 'review-done':
|
|
69
|
+
await appendReviewToDone(lines, iterDir);
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
// 文件引用
|
|
73
|
+
lines.push('');
|
|
74
|
+
lines.push('## 文件引用(需要时自行读取)');
|
|
75
|
+
lines.push('');
|
|
76
|
+
lines.push('| 文件 | 路径 | 用途 |');
|
|
77
|
+
lines.push('| :--- | :--- | :--- |');
|
|
78
|
+
lines.push(`| 完整需求 | ${iterDir}/010-requirements/converted/ | 查看需求细节 |`);
|
|
79
|
+
lines.push(`| 功能单元 | ${iterDir}/010-requirements/features/ | 按模块查看需求 |`);
|
|
80
|
+
lines.push(`| 全局规格 | ${iterDir}/020-specs/overview/ | 查看分析结果 |`);
|
|
81
|
+
lines.push('');
|
|
82
|
+
const result = lines.join('\n');
|
|
83
|
+
// 校验行数上限
|
|
84
|
+
const lineCount = result.split('\n').length;
|
|
85
|
+
if (lineCount > config.maxLines) {
|
|
86
|
+
// 截断到上限
|
|
87
|
+
const truncated = result.split('\n').slice(0, config.maxLines).join('\n');
|
|
88
|
+
return truncated + `\n\n> ⚠️ 摘要已截断(原 ${lineCount} 行 > 上限 ${config.maxLines} 行)\n`;
|
|
89
|
+
}
|
|
90
|
+
return result;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* analyze → split: 功能模块清单 + 依赖关系 + 关键约束
|
|
94
|
+
*/
|
|
95
|
+
async function appendAnalyzeToSplit(lines, iterDir) {
|
|
96
|
+
const featuresDir = (0, path_1.join)(iterDir, '010-requirements', 'features');
|
|
97
|
+
lines.push('## 2. 功能模块清单');
|
|
98
|
+
lines.push('');
|
|
99
|
+
lines.push('| 模块 | 涉及端 | 优先级 | 依赖 | 摘要 |');
|
|
100
|
+
lines.push('| :--- | :--- | :--- | :--- | :--- |');
|
|
101
|
+
if (await (0, fs_extra_1.pathExists)(featuresDir)) {
|
|
102
|
+
const entries = await (0, fs_extra_1.readdir)(featuresDir, { withFileTypes: true });
|
|
103
|
+
const units = entries.filter(e => e.isDirectory() && !e.name.startsWith('.'));
|
|
104
|
+
for (const unit of units.slice(0, 20)) { // 限制行数
|
|
105
|
+
const readmePath = (0, path_1.join)(featuresDir, unit.name, 'README.md');
|
|
106
|
+
let summary = '';
|
|
107
|
+
if (await (0, fs_extra_1.pathExists)(readmePath)) {
|
|
108
|
+
const content = await (0, fs_extra_1.readFile)(readmePath, 'utf-8');
|
|
109
|
+
const firstLine = content.split('\n')[0] || '';
|
|
110
|
+
summary = firstLine.replace(/^#\s*/, '').slice(0, 30);
|
|
111
|
+
}
|
|
112
|
+
lines.push(`| ${unit.name} | 待分析 | 中 | 无 | ${summary} |`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
lines.push('| (未拆分) | 全部 | 中 | 无 | 见 converted/ |');
|
|
117
|
+
}
|
|
118
|
+
lines.push('');
|
|
119
|
+
lines.push('## 3. 依赖关系');
|
|
120
|
+
lines.push('');
|
|
121
|
+
lines.push('```mermaid');
|
|
122
|
+
lines.push('flowchart LR');
|
|
123
|
+
lines.push(' A[需求分析] --> B[任务拆分]');
|
|
124
|
+
lines.push('```');
|
|
125
|
+
lines.push('');
|
|
126
|
+
lines.push('## 4. 关键约束(≤5条)');
|
|
127
|
+
lines.push('');
|
|
128
|
+
lines.push('- 待 analyze 阶段补充');
|
|
129
|
+
lines.push('');
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* split → plan: 任务清单 + 人员配置 + 关键路径
|
|
133
|
+
*/
|
|
134
|
+
async function appendSplitToPlan(lines, iterDir) {
|
|
135
|
+
const tasksDir = (0, path_1.join)(iterDir, '030-tasks');
|
|
136
|
+
lines.push('## 2. 任务清单');
|
|
137
|
+
lines.push('');
|
|
138
|
+
lines.push('| 任务 ID | 名称 | 依赖 | 工时 | 涉及端 |');
|
|
139
|
+
lines.push('| :--- | :--- | :--- | :--- | :--- |');
|
|
140
|
+
if (await (0, fs_extra_1.pathExists)(tasksDir)) {
|
|
141
|
+
const entries = await (0, fs_extra_1.readdir)(tasksDir, { withFileTypes: true });
|
|
142
|
+
const tasks = entries.filter(e => e.isDirectory() && e.name.startsWith('Task-'));
|
|
143
|
+
for (const task of tasks.slice(0, 30)) {
|
|
144
|
+
lines.push(`| ${task.name} | 待填写 | 无 | 待评估 | 待分析 |`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
lines.push('| Task-001 | 示例任务 | 无 | 8h | 全部 |');
|
|
149
|
+
}
|
|
150
|
+
lines.push('');
|
|
151
|
+
lines.push('## 3. 关键路径');
|
|
152
|
+
lines.push('');
|
|
153
|
+
lines.push('- 待 plan 阶段计算');
|
|
154
|
+
lines.push('');
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* plan → execute: 当前任务 Spec + 上游依赖契约
|
|
158
|
+
*/
|
|
159
|
+
async function appendPlanToExecute(lines, iterDir) {
|
|
160
|
+
lines.push('## 2. 当前任务规格');
|
|
161
|
+
lines.push('');
|
|
162
|
+
lines.push('- 执行时由 CLI 动态加载当前任务的 REQ.md + TECH.md');
|
|
163
|
+
lines.push('- 只加载当前任务,不加载其他任务');
|
|
164
|
+
lines.push('');
|
|
165
|
+
lines.push('## 3. 上游依赖契约');
|
|
166
|
+
lines.push('');
|
|
167
|
+
lines.push('- 由 CLI 自动读取上游任务的 `_shared/API_CONTRACT.yaml`');
|
|
168
|
+
lines.push('- 只传契约,不传实现');
|
|
169
|
+
lines.push('');
|
|
170
|
+
lines.push('## 4. 全局约束');
|
|
171
|
+
lines.push('');
|
|
172
|
+
lines.push('- 技术栈见 CONSTITUTION.md');
|
|
173
|
+
lines.push('- 命名规范见 PROJECT.yaml');
|
|
174
|
+
lines.push('');
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* execute → review: 产出物清单 + 验收标准
|
|
178
|
+
*/
|
|
179
|
+
async function appendExecuteToReview(lines, iterDir) {
|
|
180
|
+
lines.push('## 2. 产出物清单');
|
|
181
|
+
lines.push('');
|
|
182
|
+
lines.push('- 代码文件(CONSTITUTION.md 指定的源码路径)');
|
|
183
|
+
lines.push('- 测试用例(TEST.md)');
|
|
184
|
+
lines.push('- API 契约(_shared/API_CONTRACT.yaml)');
|
|
185
|
+
lines.push('');
|
|
186
|
+
lines.push('## 3. 验收标准');
|
|
187
|
+
lines.push('');
|
|
188
|
+
lines.push('- 编译通过');
|
|
189
|
+
lines.push('- 测试通过');
|
|
190
|
+
lines.push('- 无占位符');
|
|
191
|
+
lines.push('');
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* review → done: 审查结果 + 未解决问题
|
|
195
|
+
*/
|
|
196
|
+
async function appendReviewToDone(lines, iterDir) {
|
|
197
|
+
lines.push('## 2. 审查结果');
|
|
198
|
+
lines.push('');
|
|
199
|
+
lines.push('- 待 review 阶段填写');
|
|
200
|
+
lines.push('');
|
|
201
|
+
lines.push('## 3. 未解决问题');
|
|
202
|
+
lines.push('');
|
|
203
|
+
lines.push('- [ ] 待确认');
|
|
204
|
+
lines.push('');
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* 读取 handoff 文件路径
|
|
208
|
+
*/
|
|
209
|
+
function getHandoffPath(from, to) {
|
|
210
|
+
return (0, path_1.join)('.speccore', 'local', 'handoffs', `handoff-${from}-${to}.md`);
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* 检查 handoff 是否存在
|
|
214
|
+
*/
|
|
215
|
+
async function handoffExists(from, to) {
|
|
216
|
+
return (0, fs_extra_1.pathExists)(getHandoffPath(from, to));
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=handoff-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handoff-generator.js","sourceRoot":"","sources":["../../src/core/handoff-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -174,7 +174,7 @@ async function scanSpecs(iterDir) {
|
|
|
174
174
|
mtime,
|
|
175
175
|
});
|
|
176
176
|
}
|
|
177
|
-
//
|
|
177
|
+
// 扫描各端子目录(唯一路径 020-specs/{端}/)
|
|
178
178
|
// v8.3.65+: 加入 requirements(黄金需求目录,由 scanRequirements 单独扫描)
|
|
179
179
|
const knownNonPlatformDirs = new Set(['sources', 'assets', 'prototypes', 'converted', 'features', 'bugs', 'refactors', 'research', 'staging', 'snapshots', 'requirements']);
|
|
180
180
|
const platformDirs = [];
|
|
@@ -300,9 +300,9 @@ async function scanBusinessCodeMappings(iterDir) {
|
|
|
300
300
|
const specsDir = (0, path_1.join)(iterDir, '020-specs');
|
|
301
301
|
if (!(await (0, fs_extra_1.pathExists)(specsDir)))
|
|
302
302
|
return { entities, relations };
|
|
303
|
-
// v8.3.122+:
|
|
303
|
+
// v8.3.122+: 同时扫描多种路径结构
|
|
304
304
|
// 新结构: 020-specs/{feature}/{platform}/TECH.md
|
|
305
|
-
//
|
|
305
|
+
// 结构: 020-specs/{platform}/TECH.md
|
|
306
306
|
const knownNonPlatformDirs = new Set(['sources', 'assets', 'prototypes', 'converted', 'features', 'bugs', 'refactors', 'research', 'staging', 'platforms', 'snapshots', 'global', 'overview', 'requirements']);
|
|
307
307
|
const specsEntries = await (0, fs_extra_1.readdir)(specsDir, { withFileTypes: true });
|
|
308
308
|
for (const featureEntry of specsEntries) {
|
|
@@ -310,10 +310,10 @@ async function scanBusinessCodeMappings(iterDir) {
|
|
|
310
310
|
continue;
|
|
311
311
|
const featureName = featureEntry.name;
|
|
312
312
|
const featureDir = (0, path_1.join)(specsDir, featureName);
|
|
313
|
-
//
|
|
313
|
+
// 检测结构(直接有 TECH.md)还是新结构(有子目录)
|
|
314
314
|
const hasTechMdDirectly = await (0, fs_extra_1.pathExists)((0, path_1.join)(featureDir, 'TECH.md'));
|
|
315
315
|
if (hasTechMdDirectly) {
|
|
316
|
-
//
|
|
316
|
+
// 结构: 020-specs/{platform}/TECH.md — 把 featureName 当成 platformName
|
|
317
317
|
await processTechMdForMappings(featureDir, featureName, '', entities, relations);
|
|
318
318
|
}
|
|
319
319
|
else {
|
|
@@ -440,7 +440,7 @@ async function scanTasks(iterDir) {
|
|
|
440
440
|
const tasksDir = (0, path_1.join)(iterDir, '030-tasks');
|
|
441
441
|
if (!(await (0, fs_extra_1.pathExists)(tasksDir)))
|
|
442
442
|
return { entities, relations };
|
|
443
|
-
// 扫描类型子目录
|
|
443
|
+
// 扫描类型子目录
|
|
444
444
|
const taskDirs = [];
|
|
445
445
|
for (const type of task_paths_1.TASK_TYPES) {
|
|
446
446
|
const typeDir = (0, path_1.join)(tasksDir, type);
|
|
@@ -453,7 +453,7 @@ async function scanTasks(iterDir) {
|
|
|
453
453
|
}
|
|
454
454
|
}
|
|
455
455
|
}
|
|
456
|
-
//
|
|
456
|
+
// 布局: 030-tasks/Task-XXX/
|
|
457
457
|
const rootEntries = await (0, fs_extra_1.readdir)(tasksDir, { withFileTypes: true });
|
|
458
458
|
for (const e of rootEntries) {
|
|
459
459
|
if (e.isDirectory() && e.name.startsWith('Task-')) {
|
|
@@ -599,7 +599,7 @@ async function scanTasks(iterDir) {
|
|
|
599
599
|
}
|
|
600
600
|
}
|
|
601
601
|
else {
|
|
602
|
-
//
|
|
602
|
+
// 端目录下无子任务,端本身作为子任务(单端任务)
|
|
603
603
|
const platformTaskMd = (0, path_1.join)(platformPath, 'TASK.md');
|
|
604
604
|
let subTitle = `${title} — ${de.name}`;
|
|
605
605
|
let subStatus = 'pending';
|