speccore 8.3.219 → 8.3.221
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/commands/iteration/split.d.ts.map +1 -1
- package/dist/commands/iteration/split.js +51 -14
- package/dist/commands/iteration/split.js.map +1 -1
- package/dist/commands/run.js +16 -0
- package/dist/commands/run.js.map +1 -1
- package/dist/core/spec-skeleton.d.ts.map +1 -1
- package/dist/core/spec-skeleton.js +2 -1
- package/dist/core/spec-skeleton.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"split.d.ts","sourceRoot":"","sources":["../../../src/commands/iteration/split.ts"],"names":[],"mappings":"AAwKA,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;
|
|
1
|
+
{"version":3,"file":"split.d.ts","sourceRoot":"","sources":["../../../src/commands/iteration/split.ts"],"names":[],"mappings":"AAwKA,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAmKD,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2pCzF"}
|
|
@@ -198,7 +198,9 @@ async function detectPlatforms(iterationDir, specified) {
|
|
|
198
198
|
async function preSplitGate(iterationDir) {
|
|
199
199
|
const items = [];
|
|
200
200
|
const specDir = (0, path_1.join)(iterationDir, '020-specs');
|
|
201
|
-
// 检查全局 FUNCTION_MAP.md
|
|
201
|
+
// 检查全局 FUNCTION_MAP.md(警告级)
|
|
202
|
+
// v8.3.220+: 降级为 warn——功能单元的权威来源是 010-requirements/features/ 目录(doc2spec --split 产出),
|
|
203
|
+
// FUNCTION_MAP 仅作「功能×端映射」参考。split 的 prompt 构建已有多级回退(FUNCTION_MAP → ANALYSIS.md → features/)。
|
|
202
204
|
const funcMapPath = (0, path_1.join)(specDir, spec_paths_1.GLOBAL_SPECS_DIR, 'FUNCTION_MAP.md');
|
|
203
205
|
const funcMapExists = await (0, fs_extra_1.pathExists)(funcMapPath);
|
|
204
206
|
let funcMapIsSkeleton = false;
|
|
@@ -209,13 +211,13 @@ async function preSplitGate(iterationDir) {
|
|
|
209
211
|
items.push({
|
|
210
212
|
path: funcMapPath,
|
|
211
213
|
name: 'FUNCTION_MAP.md',
|
|
212
|
-
purpose: '
|
|
213
|
-
impact: '
|
|
214
|
+
purpose: '功能单元×端映射参考(权威来源为 010-requirements/features/ 目录)',
|
|
215
|
+
impact: '缺失或不完整时仅作提示,split 以 features/ 目录为准拆分,不影响任务生成',
|
|
214
216
|
exists: funcMapExists,
|
|
215
217
|
isSkeleton: funcMapIsSkeleton,
|
|
216
|
-
level: '
|
|
218
|
+
level: 'warn',
|
|
217
219
|
});
|
|
218
|
-
// 检查全局 REQUIREMENT.md
|
|
220
|
+
// 检查全局 REQUIREMENT.md(阻塞级——taskify 的核心需求上下文,骨架则无法拆分)
|
|
219
221
|
const reqPath = (0, path_1.join)(specDir, spec_paths_1.GLOBAL_SPECS_DIR, 'REQUIREMENT.md');
|
|
220
222
|
const reqExists = await (0, fs_extra_1.pathExists)(reqPath);
|
|
221
223
|
let reqIsSkeleton = false;
|
|
@@ -226,11 +228,28 @@ async function preSplitGate(iterationDir) {
|
|
|
226
228
|
items.push({
|
|
227
229
|
path: reqPath,
|
|
228
230
|
name: 'REQUIREMENT.md',
|
|
229
|
-
purpose: '
|
|
230
|
-
impact: '
|
|
231
|
+
purpose: '本迭代的完整需求规格,包含功能模块清单和验收标准(taskify 拆分任务的核心依据)',
|
|
232
|
+
impact: '缺失或仍为骨架时,AI 拆分缺少需求上下文,会拆出无意义任务(如把「写作要求」当功能模块)',
|
|
231
233
|
exists: reqExists,
|
|
232
234
|
isSkeleton: reqIsSkeleton,
|
|
233
|
-
level: '
|
|
235
|
+
level: 'block',
|
|
236
|
+
});
|
|
237
|
+
// v8.3.221+: 检查全局 ANALYSIS.md(阻塞级——功能分析,骨架说明 analyze 未落盘)
|
|
238
|
+
const analysisGatePath = (0, path_1.join)(specDir, spec_paths_1.GLOBAL_SPECS_DIR, 'ANALYSIS.md');
|
|
239
|
+
const analysisGateExists = await (0, fs_extra_1.pathExists)(analysisGatePath);
|
|
240
|
+
let analysisGateIsSkeleton = false;
|
|
241
|
+
if (analysisGateExists) {
|
|
242
|
+
const ac = await (0, fs_extra_1.readFile)(analysisGatePath, 'utf-8');
|
|
243
|
+
analysisGateIsSkeleton = ac.includes('<!-- SPEC-SKELETON -->') || ac.trim().length < 100;
|
|
244
|
+
}
|
|
245
|
+
items.push({
|
|
246
|
+
path: analysisGatePath,
|
|
247
|
+
name: 'ANALYSIS.md',
|
|
248
|
+
purpose: '需求功能分析(功能点清单 F-xx),taskify 拆分任务的输入之一',
|
|
249
|
+
impact: '仍为骨架说明 analyze 阶段未落盘,拆分会遗漏功能点',
|
|
250
|
+
exists: analysisGateExists,
|
|
251
|
+
isSkeleton: analysisGateIsSkeleton,
|
|
252
|
+
level: 'block',
|
|
234
253
|
});
|
|
235
254
|
// 检查功能模块级文档(警告级)
|
|
236
255
|
const features = await (0, spec_paths_1.parseFeatureList)(iterationDir);
|
|
@@ -2242,7 +2261,7 @@ ${relatedTasks.length > 0 ? relatedTasks.join('\n') : '> 暂无关联任务(sp
|
|
|
2242
2261
|
|
|
2243
2262
|
## 跨端关联
|
|
2244
2263
|
|
|
2245
|
-
> 来自 FUNCTION_MAP.md
|
|
2264
|
+
> 来自 FUNCTION_MAP.md(功能×端映射参考)
|
|
2246
2265
|
|
|
2247
2266
|
| 属性 | 值 |
|
|
2248
2267
|
|:---|:---|
|
|
@@ -3256,7 +3275,7 @@ subagent, contextType) {
|
|
|
3256
3275
|
p += `4. \`020-specs/overview/REQUIREMENT.md\` — 黄金需求文档\n`;
|
|
3257
3276
|
p += `5. \`020-specs/overview/TECH.md\` — 全局技术方案\n`;
|
|
3258
3277
|
p += `6. \`020-specs/overview/ANALYSIS.md\` — 功能分析\n`;
|
|
3259
|
-
p += `7. \`020-specs/overview/FUNCTION_MAP.md\` —
|
|
3278
|
+
p += `7. \`020-specs/overview/FUNCTION_MAP.md\` — 功能单元与端的映射(参考,权威来源为 010-requirements/features/ 目录)\n`;
|
|
3260
3279
|
if (await (0, fs_extra_1.pathExists)((0, path_1.join)(iterationDir || '', '020-specs', 'overview', 'INTERACTION_MAP.md'))) {
|
|
3261
3280
|
p += `8. \`020-specs/overview/INTERACTION_MAP.md\` — 跨端交互时序\n`;
|
|
3262
3281
|
}
|
|
@@ -3271,7 +3290,7 @@ subagent, contextType) {
|
|
|
3271
3290
|
}
|
|
3272
3291
|
p += `\n`;
|
|
3273
3292
|
p += `> 📖 **读取策略**:\n`;
|
|
3274
|
-
p += `> - 先 Read FUNCTION_MAP.md
|
|
3293
|
+
p += `> - 先 Read 010-requirements/features/ 目录了解功能单元划分(权威来源),FUNCTION_MAP.md 作功能×端映射参考\n`;
|
|
3275
3294
|
p += `> - 按功能单元逐个处理,每次只 Read 当前单元相关的文档\n`;
|
|
3276
3295
|
p += `> - reqContent 从 REQUIREMENT.md 和对应功能模块的需求文档提取\n`;
|
|
3277
3296
|
p += `> - techContent 从 TECH.md 和对应功能模块的技术规格提取\n`;
|
|
@@ -3313,9 +3332,9 @@ subagent, contextType) {
|
|
|
3313
3332
|
funcUnitsInjected = true;
|
|
3314
3333
|
}
|
|
3315
3334
|
}
|
|
3316
|
-
// v7.5.0+: FUNCTION_MAP.md
|
|
3335
|
+
// v7.5.0+: FUNCTION_MAP.md 不存在或为空时,从 ANALYSIS.md 提取功能单元清单
|
|
3317
3336
|
if (!funcUnitsInjected) {
|
|
3318
|
-
const analysisPath = (0, path_1.join)(iterationDir, '020-specs', 'ANALYSIS.md');
|
|
3337
|
+
const analysisPath = (0, path_1.join)(iterationDir, '020-specs', spec_paths_1.GLOBAL_SPECS_DIR, 'ANALYSIS.md');
|
|
3319
3338
|
if (await (0, fs_extra_1.pathExists)(analysisPath)) {
|
|
3320
3339
|
const analysisContent = await (0, fs_extra_1.readFile)(analysisPath, 'utf-8');
|
|
3321
3340
|
const analysisUnits = parseAnalysisFunctionalUnits(analysisContent, standardPlatforms);
|
|
@@ -3335,6 +3354,24 @@ subagent, contextType) {
|
|
|
3335
3354
|
p += `- 不允许将不同端的功能单元合并到同一个任务\n\n`;
|
|
3336
3355
|
}
|
|
3337
3356
|
}
|
|
3357
|
+
// v8.3.220+: FUNCTION_MAP 和 ANALYSIS 都为空/骨架时,回退到 features/ 目录(功能单元权威来源)
|
|
3358
|
+
if (!funcUnitsInjected) {
|
|
3359
|
+
const featureDirs = await (0, spec_paths_1.parseFeatureList)(iterationDir);
|
|
3360
|
+
if (featureDirs.length > 0) {
|
|
3361
|
+
p += `## 🧩 功能单元清单(CLI 从 010-requirements/features/ 目录提取,v8.3.220+)\n\n`;
|
|
3362
|
+
p += `> 以下是从 features/ 目录读取的 **全部功能单元**(权威来源)。\n`;
|
|
3363
|
+
p += `> ⚠️ **你必须为每个功能单元创建至少 1 个任务,不允许遗漏任何功能单元。**\n\n`;
|
|
3364
|
+
p += `| 功能单元 |\n`;
|
|
3365
|
+
p += `|:---|\n`;
|
|
3366
|
+
for (const fn of featureDirs) {
|
|
3367
|
+
p += `| ${fn} |\n`;
|
|
3368
|
+
}
|
|
3369
|
+
p += `\n**拆分要求**:\n`;
|
|
3370
|
+
p += `- 每个功能单元必须在某个任务的 \`functionalUnit\` 字段中被引用\n`;
|
|
3371
|
+
p += `- 涉及端从 CONSTITUTION.md 端列表判断,或从 features/{单元}/.meta/source 读取\n\n`;
|
|
3372
|
+
funcUnitsInjected = true;
|
|
3373
|
+
}
|
|
3374
|
+
}
|
|
3338
3375
|
}
|
|
3339
3376
|
}
|
|
3340
3377
|
catch { }
|
|
@@ -4249,7 +4286,7 @@ async function tryModuleDrivenSplit(iteration, iterationDir, options) {
|
|
|
4249
4286
|
}
|
|
4250
4287
|
// 2.5 v7.5.0+: 回退:从 ANALYSIS.md 提取功能单元清单(按端分节的 F-xx 表格)
|
|
4251
4288
|
if (!modulePlatformsParsed) {
|
|
4252
|
-
const analysisPath = (0, path_1.join)(iterationDir, '020-specs', 'ANALYSIS.md');
|
|
4289
|
+
const analysisPath = (0, path_1.join)(iterationDir, '020-specs', spec_paths_1.GLOBAL_SPECS_DIR, 'ANALYSIS.md');
|
|
4253
4290
|
if (await (0, fs_extra_1.pathExists)(analysisPath)) {
|
|
4254
4291
|
try {
|
|
4255
4292
|
const content = await (0, fs_extra_1.readFile)(analysisPath, 'utf-8');
|