toolflow 3.1.4

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 (49) hide show
  1. package/.github/workflows/ci.yml +31 -0
  2. package/README.md +106 -0
  3. package/README_zh.md +109 -0
  4. package/docs/reports/ADVANCED_EVOLUTION_REPORT.md +44 -0
  5. package/docs/reports/AUDIT_AND_OPTIMIZATION_REPORT.md +645 -0
  6. package/docs/reports/COLD_START_REVIEW_EVOLUTION.md +51 -0
  7. package/docs/reports/DEEP_ECOSYSTEM_EVOLUTION.md +43 -0
  8. package/docs/reports/MEMORY.md +18 -0
  9. package/docs/reports/MICHAEL_DISPATCH_RESULT.md +36 -0
  10. package/docs/reports/OPENSOURCE_INTEGRATION_REPORT.md +43 -0
  11. package/docs/reports/PHASE_1_OPTIMIZATION_REPORT.md +87 -0
  12. package/docs/reports/PHASE_2_OPTIMIZATION_REPORT.md +50 -0
  13. package/docs/reports/PHASE_3_OPTIMIZATION_REPORT.md +24 -0
  14. package/docs/reports/PHASE_4_OPTIMIZATION_REPORT.md +28 -0
  15. package/docs/reports/REPORT_TO_MICHAEL.md +101 -0
  16. package/docs/reports/SIGNOFF_AND_RELEASE_REPORT.md +85 -0
  17. package/docs/reports/STAFF_ASSIGNMENTS.md +26 -0
  18. package/docs/reports/TASK_ASSIGNMENTS.md +59 -0
  19. package/docs/reports/V1_6_0_EVOLUTION_REPORT.md +48 -0
  20. package/docs/reports/V1_9_0_HOTFIX_REPORT.md +30 -0
  21. package/docs/reports/V2_0_0_RELEASE_REPORT.md +18 -0
  22. package/docs/reports/V2_2_0_ZERO_SPECIALIZATION_REPORT.md +24 -0
  23. package/docs/reports/V2_3_0_EVOLUTION_REPORT.md +12 -0
  24. package/ecosystem_taxonomy.json +798 -0
  25. package/package.json +46 -0
  26. package/src/blast_radius.ts +302 -0
  27. package/src/deep_ecosystem.ts +523 -0
  28. package/src/degradation_matrix.ts +180 -0
  29. package/src/dehydrator.ts +532 -0
  30. package/src/ecosystem_taxonomy.json +803 -0
  31. package/src/engine.ts +1510 -0
  32. package/src/i18n.ts +89 -0
  33. package/src/index.ts +983 -0
  34. package/src/json_extractor.ts +57 -0
  35. package/src/memory.ts +151 -0
  36. package/src/prompts_manager.ts +262 -0
  37. package/src/review_isolation.ts +188 -0
  38. package/src/state.ts +810 -0
  39. package/src/taxonomy.ts +580 -0
  40. package/src/types.ts +341 -0
  41. package/src/ui.ts +1036 -0
  42. package/src/worker_orchestrator.ts +60 -0
  43. package/tests/challenger_stress_harness.ts +265 -0
  44. package/tests/monorepo_multilang_stress.ts +404 -0
  45. package/tests/sandbox_e2e.ts +167 -0
  46. package/tests/test_json_extractor.ts +44 -0
  47. package/tests/test_modules_1_to_4.ts +106 -0
  48. package/tests/test_suite.ts +1689 -0
  49. package/tsconfig.json +17 -0
package/src/engine.ts ADDED
@@ -0,0 +1,1510 @@
1
+ import type { ExtensionContext, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
2
+ import {
3
+ EcosystemTaxonomy,
4
+ CapabilityItem,
5
+ TaskDiagnosis,
6
+ TaskRequirementSlot,
7
+ Blueprint,
8
+ BlueprintStage,
9
+ ProjectFingerprint,
10
+ TradeOffPlan,
11
+ ABMatrix,
12
+ DAGPlanResult,
13
+ DAGWave
14
+ } from "./types.js";
15
+ import { sniffProjectFingerprint, cleanName } from "./taxonomy.js";
16
+ import { bindDeepEcosystemToStage, EcosystemRadar } from "./deep_ecosystem.js";
17
+ import { extractValidJsonObject } from "./json_extractor.js";
18
+ import crypto from "crypto";
19
+ import path from "path";
20
+ import fs from "fs";
21
+
22
+ export interface TaskRouteDecision {
23
+ mode: "FAST_TRACK" | "BLUEPRINT";
24
+ reason: string;
25
+ suggestedTools: string[];
26
+ }
27
+
28
+ /**
29
+ * 任务轻重双模路由器 (Fast-Track 极速直达 vs Blueprint 渐进编排)
30
+ */
31
+ export function diagnoseTaskExecutionMode(
32
+ task: string,
33
+ userExplicitMode?: "fast" | "blueprint"
34
+ ): TaskRouteDecision {
35
+ if (userExplicitMode === "fast") {
36
+ return {
37
+ mode: "FAST_TRACK",
38
+ reason: "用户显式指定极速通道",
39
+ suggestedTools: ["read", "edit", "write", "bash", "powershell", "grep", "find"]
40
+ };
41
+ }
42
+ if (userExplicitMode === "blueprint") {
43
+ return {
44
+ mode: "BLUEPRINT",
45
+ reason: "用户显式要求工程蓝图编排",
46
+ suggestedTools: []
47
+ };
48
+ }
49
+
50
+ const trimmed = (task || "").trim();
51
+ const lower = trimmed.toLowerCase();
52
+
53
+ // 1. 系统级架构词汇强制走完整蓝图
54
+ const hasHeavyScope = /(重构系统|架构设计|全新系统|端到端开发|从头开发|设计整个|全栈系统|从零构建|新建工程|大型系统|全量迁移|architect|refactor\s+all|from\s+scratch)/i.test(lower);
55
+ if (hasHeavyScope) {
56
+ return { mode: "BLUEPRINT", reason: "检测到系统级重构或全局架构诉求", suggestedTools: [] };
57
+ }
58
+
59
+ // 2. 判定极速通道特征:具体文件、行号符号、微操作动词
60
+ const hasSingleFileTarget = /\b[\w-]+\.(ts|tsx|js|jsx|py|rs|go|json|css|scss|html|vue|md)\b/i.test(lower);
61
+ const hasSpecificLineOrSymbol = /(第\s*\d+\s*行|line\s*\d+|函数|function\s+\w+|class\s+\w+|方法|变量)/i.test(lower);
62
+ const hasMicroActionVerb = /(修复|fix|修改|改一下|微调|format|加个注释|添加注释|加注释|补充类型|类型修复|换个颜色|改个文案|改文案|加个字段|加字段|增加字段|输出日志|加log|加打印|优化排版)/i.test(lower);
63
+
64
+ if (trimmed.length <= 80 && (hasMicroActionVerb || hasSingleFileTarget || hasSpecificLineOrSymbol)) {
65
+ return {
66
+ mode: "FAST_TRACK",
67
+ reason: `单点日常微任务 (${trimmed.length} 字, 具备局部修改意图)`,
68
+ suggestedTools: ["read", "edit", "write", "bash", "powershell", "grep", "find"]
69
+ };
70
+ }
71
+
72
+ return { mode: "BLUEPRINT", reason: "常规多阶段复合任务", suggestedTools: [] };
73
+ }
74
+
75
+ export interface ProjectArtifactProfile {
76
+ srcPath: string;
77
+ testPath: string;
78
+ docPath: string;
79
+ previewPath: string;
80
+ reportPath: string;
81
+ testCommands: string[];
82
+ buildCommands?: string[];
83
+ previewCommands?: string[];
84
+ }
85
+
86
+ /**
87
+ * 根据工程指纹与项目真实目录结构动态推导物理产物路径,杜绝虚构目录
88
+ */
89
+ export function inferArtifactProfile(fp?: ProjectFingerprint, cwd: string = process.cwd()): ProjectArtifactProfile {
90
+ const pType = fp?.projectType || "node";
91
+ const pkgMgr = fp?.packageManager || "npm";
92
+ const topDirs = new Set(fp?.topLevelDirs || []);
93
+
94
+ // 动态决策目录:如果项目没有对应目录,则优先使用现有结构,无目录则按语言规范放置
95
+ const docDir = topDirs.has("docs") ? "docs" : topDirs.has("doc") ? "doc" : (topDirs.size > 0 ? "docs" : "");
96
+ const reportDir = topDirs.has("reports") ? "reports" : (docDir || "");
97
+ const testDir = topDirs.has("tests") ? "tests" : topDirs.has("test") ? "test" : topDirs.has("spec") ? "spec" : (pType === "rust" ? "tests" : (topDirs.size > 0 ? "tests" : ""));
98
+ const srcDir = topDirs.has("src") ? "src" : topDirs.has("lib") ? "lib" : topDirs.has("app") ? "app" : (pType === "rust" ? "src" : (topDirs.size > 0 ? "src" : ""));
99
+
100
+ switch (pType) {
101
+ case "rust":
102
+ return {
103
+ srcPath: path.join(srcDir, "main.rs").replace(/\\/g, "/"),
104
+ testPath: path.join(testDir, "integration_test.rs").replace(/\\/g, "/"),
105
+ docPath: path.join(docDir, "design.md").replace(/\\/g, "/"),
106
+ previewPath: path.join(reportDir, "preview_summary.md").replace(/\\/g, "/"),
107
+ reportPath: path.join(reportDir, "verification_summary.json").replace(/\\/g, "/"),
108
+ testCommands: ["cargo check", "cargo test"],
109
+ buildCommands: ["cargo build"],
110
+ previewCommands: ["cargo run -- --help"]
111
+ };
112
+ case "python": {
113
+ const runner = pkgMgr === "uv" ? "uv run pytest" : pkgMgr === "poetry" ? "poetry run pytest" : "pytest";
114
+ const mainPath = path.join(srcDir, "main.py").replace(/\\/g, "/");
115
+ return {
116
+ srcPath: mainPath,
117
+ testPath: path.join(testDir, "test_main.py").replace(/\\/g, "/"),
118
+ docPath: path.join(docDir, "design.md").replace(/\\/g, "/"),
119
+ previewPath: path.join(reportDir, "preview_summary.md").replace(/\\/g, "/"),
120
+ reportPath: path.join(reportDir, "verification_summary.json").replace(/\\/g, "/"),
121
+ testCommands: [runner],
122
+ buildCommands: [],
123
+ previewCommands: [pkgMgr === "uv" ? `uv run python ${mainPath}` : `python ${mainPath}`]
124
+ };
125
+ }
126
+ case "go":
127
+ return {
128
+ srcPath: "main.go",
129
+ testPath: "main_test.go",
130
+ docPath: path.join(docDir, "design.md").replace(/\\/g, "/"),
131
+ previewPath: path.join(reportDir, "preview_summary.md").replace(/\\/g, "/"),
132
+ reportPath: path.join(reportDir, "verification_summary.json").replace(/\\/g, "/"),
133
+ testCommands: ["go vet ./...", "go test -v ./..."],
134
+ buildCommands: ["go build -v ."],
135
+ previewCommands: ["go run main.go"]
136
+ };
137
+ case "cpp":
138
+ return {
139
+ srcPath: path.join(srcDir, "main.cpp").replace(/\\/g, "/"),
140
+ testPath: path.join(testDir, "test_main.cpp").replace(/\\/g, "/"),
141
+ docPath: path.join(docDir, "design.md").replace(/\\/g, "/"),
142
+ previewPath: path.join(reportDir, "preview_summary.md").replace(/\\/g, "/"),
143
+ reportPath: path.join(reportDir, "verification_summary.json").replace(/\\/g, "/"),
144
+ testCommands: ["ctest --output-on-failure"],
145
+ buildCommands: ["cmake -B build", "cmake --build build"],
146
+ previewCommands: []
147
+ };
148
+ case "node":
149
+ default: {
150
+ const isUnknown = fp?.projectType === "unknown" || !fp?.projectType;
151
+ const isGenericDoc = fp?.projectType === "generic_doc";
152
+ const isTs = fp?.mainFramework === "TypeScript" || fp?.coreDependencies?.some(d => d.includes("typescript"));
153
+
154
+ let testCmds: string[] = [];
155
+ let buildCmds: string[] = [];
156
+ let previewCmds: string[] = [];
157
+ let srcPath = path.join(srcDir, isTs ? "main.ts" : "main.js").replace(/\\/g, "/");
158
+
159
+ if (isGenericDoc) {
160
+ srcPath = path.join(docDir, "index.md").replace(/\\/g, "/");
161
+ testCmds = [];
162
+ buildCmds = [];
163
+ previewCmds = [];
164
+ } else if (isUnknown) {
165
+ // 未知工程指纹:严格根据目录已有真实文件嗅探,严禁无脑默认 index.html!
166
+ const hasPy = fs.existsSync(path.join(cwd, "requirements.txt")) || fs.existsSync(path.join(cwd, "main.py"));
167
+ const hasTs = fs.existsSync(path.join(cwd, "tsconfig.json"));
168
+ const hasPs = fs.existsSync(path.join(cwd, "scripts")) && fs.readdirSync(path.join(cwd, "scripts")).some(f => f.endsWith(".ps1"));
169
+
170
+ if (hasPy) {
171
+ srcPath = "main.py";
172
+ } else if (hasTs) {
173
+ srcPath = "src/index.ts";
174
+ } else if (hasPs) {
175
+ srcPath = "scripts/main.ps1";
176
+ } else {
177
+ srcPath = "src/index.js";
178
+ }
179
+ testCmds = [];
180
+ buildCmds = [];
181
+ previewCmds = [];
182
+ } else {
183
+ // 标准 Node 项目
184
+ const hasTestScript = fp?.packageManager && fp.packageManager !== "unknown";
185
+ // 仅在明确检测到测试脚本或已知单测框架时添加 test 命令,防止空跑失败
186
+ testCmds = [];
187
+ buildCmds = isTs ? [`${pkgMgr} run build`] : [];
188
+ previewCmds = [];
189
+ }
190
+
191
+ return {
192
+ srcPath,
193
+ testPath: path.join(testDir, isTs ? "index.test.ts" : "index.test.js").replace(/\\/g, "/"),
194
+ docPath: path.join(docDir, "design.md").replace(/\\/g, "/"),
195
+ previewPath: path.join(reportDir, "preview_summary.md").replace(/\\/g, "/"),
196
+ reportPath: path.join(reportDir, "verification_summary.json").replace(/\\/g, "/"),
197
+ testCommands: testCmds,
198
+ buildCommands: buildCmds,
199
+ previewCommands: previewCmds
200
+ };
201
+ }
202
+ }
203
+ }
204
+
205
+ /**
206
+ * 确定性 Kahn 算法 DAG 拓扑排序与分波调度器 (Kahn's Algorithm & Wave Decomposition)
207
+ * Ponytail 优化:若 stages 只有 1 个阶段或无任何依赖关系,直接零计算走极简流水线,杜绝虚胖开销。
208
+ */
209
+ export function planDAGWaves(stages: BlueprintStage[]): DAGPlanResult {
210
+ const uniqueStages: BlueprintStage[] = [];
211
+ const seenIds = new Set<string>();
212
+ for (const s of stages) {
213
+ if (!seenIds.has(s.stageId)) {
214
+ seenIds.add(s.stageId);
215
+ uniqueStages.push(s);
216
+ }
217
+ }
218
+
219
+ // 极简流水线快路径:单阶段或完全线性任务零 DAG 开销
220
+ if (uniqueStages.length <= 1) {
221
+ return {
222
+ sortedStages: uniqueStages,
223
+ waves: [{ waveIndex: 0, stages: uniqueStages, isParallel: false }],
224
+ hasCycles: false
225
+ };
226
+ }
227
+
228
+ const hasAnyExplicitDeps = uniqueStages.some(s => s.dependsOn && s.dependsOn.length > 0);
229
+ if (!hasAnyExplicitDeps) {
230
+ // 阶段间无任何强制先后依赖:判定为天然可并发波次
231
+ return {
232
+ sortedStages: uniqueStages,
233
+ waves: [{ waveIndex: 0, stages: uniqueStages, isParallel: uniqueStages.length > 1 }],
234
+ hasCycles: false
235
+ };
236
+ }
237
+
238
+ const stageMap = new Map<string, BlueprintStage>();
239
+ const inDegree = new Map<string, number>();
240
+ const adjList = new Map<string, string[]>();
241
+
242
+ for (const s of uniqueStages) {
243
+ stageMap.set(s.stageId, s);
244
+ inDegree.set(s.stageId, 0);
245
+ adjList.set(s.stageId, []);
246
+ }
247
+
248
+ for (const s of uniqueStages) {
249
+ const rawDeps = s.dependsOn || [];
250
+ const uniqueDeps = Array.from(new Set(rawDeps));
251
+ for (const dep of uniqueDeps) {
252
+ if (!stageMap.has(dep)) {
253
+ console.warn(`[ToolFlow DAG Warning] Stage '${s.stageId}' depends on unknown stage '${dep}' - dependency skipped.`);
254
+ continue;
255
+ }
256
+ adjList.get(dep)!.push(s.stageId);
257
+ inDegree.set(s.stageId, (inDegree.get(s.stageId) || 0) + 1);
258
+ }
259
+ }
260
+
261
+ const waves: DAGWave[] = [];
262
+ const sortedStages: BlueprintStage[] = [];
263
+ let readyQueue = Array.from(inDegree.entries())
264
+ .filter(([_, degree]) => degree === 0)
265
+ .map(([id]) => id);
266
+
267
+ let processedCount = 0;
268
+ let waveIdx = 0;
269
+
270
+ while (readyQueue.length > 0) {
271
+ const currentWaveStages = readyQueue.map(id => stageMap.get(id)!);
272
+ waves.push({
273
+ waveIndex: waveIdx++,
274
+ stages: currentWaveStages,
275
+ isParallel: currentWaveStages.length > 1
276
+ });
277
+ sortedStages.push(...currentWaveStages);
278
+ processedCount += readyQueue.length;
279
+
280
+ const nextQueue: string[] = [];
281
+ for (const id of readyQueue) {
282
+ const neighbors = adjList.get(id) || [];
283
+ for (const n of neighbors) {
284
+ const d = (inDegree.get(n) || 1) - 1;
285
+ inDegree.set(n, d);
286
+ if (d === 0) {
287
+ nextQueue.push(n);
288
+ }
289
+ }
290
+ }
291
+ readyQueue = nextQueue;
292
+ }
293
+
294
+ const hasCycles = processedCount < uniqueStages.length;
295
+ const cycleNodes = hasCycles
296
+ ? Array.from(inDegree.entries()).filter(([_, d]) => d > 0).map(([id]) => id)
297
+ : undefined;
298
+
299
+ // 如果检测到环路,按原始顺序兜底返回并标记环路节点
300
+ return {
301
+ sortedStages: hasCycles ? uniqueStages : sortedStages,
302
+ waves: hasCycles ? [{ waveIndex: 0, stages: uniqueStages, isParallel: false }] : waves,
303
+ hasCycles,
304
+ cycleNodes
305
+ };
306
+ }
307
+
308
+ /**
309
+ * 构造 A/B 架构权衡矩阵 (Option A 敏捷轻量直出 vs Option B 工业工程)
310
+ */
311
+ export function generateABTradeOffMatrix(task: string, fp?: ProjectFingerprint): TradeOffPlan {
312
+ const profile = inferArtifactProfile(fp);
313
+ const isComplex = task.length > 30 || /系统|框架|重构|架构|全套|引擎|platform|workflow/i.test(task);
314
+
315
+ const matrix: ABMatrix = {
316
+ planA: {
317
+ name: "Option A: 敏捷轻量型 (Lean & Agile)",
318
+ description: `精简流水线,直接交付核心实现 (${profile.srcPath}) 并完成效果走查。`,
319
+ pros: ["极速闭环交付", "Token 开销降低 50-70%", "零冗余设计文件"],
320
+ cons: ["缺乏分层设计文档", "单测与门禁较为简略"],
321
+ tokenOverhead: "minimal"
322
+ },
323
+ planB: {
324
+ name: "Option B: 工业级工程型 (Industrial & Robust)",
325
+ description: `5 阶段严谨工程:方案契约 (${profile.docPath})、模块实现、效果走查 (${profile.previewPath})、全量测试 (${profile.testPath}) 与高保真审计。`,
326
+ pros: ["分层严谨、可维护性高", "包含【效果展示与客户共创层】", "全链路物理校验与测试覆盖"],
327
+ cons: ["多阶段上下文交互", "Token 消耗相对中高"],
328
+ tokenOverhead: "medium"
329
+ },
330
+ dimensions: [
331
+ {
332
+ name: "交付速度 (Velocity)",
333
+ scoreA: 5,
334
+ scoreB: 3,
335
+ commentary: "Plan A 免去繁复设计文档,快速跑通核心原型"
336
+ },
337
+ {
338
+ name: "客户共创深度 (Co-Creation)",
339
+ scoreA: 4,
340
+ scoreB: 5,
341
+ commentary: "Plan B 具备专门的效果走查与意见征询阶段,体验掌控力更强"
342
+ },
343
+ {
344
+ name: "架构健壮性 (Robustness)",
345
+ scoreA: 3,
346
+ scoreB: 5,
347
+ commentary: "Plan B 具备契约文档、多 Agent 审计与 64 位 SHA 门禁"
348
+ },
349
+ {
350
+ name: "长期可维护度 (Maintainability)",
351
+ scoreA: 3,
352
+ scoreB: 5,
353
+ commentary: "Plan B 具备自动化测试套件与清晰设计边界"
354
+ }
355
+ ],
356
+ recommendation: isComplex ? "B" : "A",
357
+ rationale: isComplex
358
+ ? "任务涉及多模块或系统级设计,推荐工业级工程方案保障质量与客户共创。"
359
+ : "任务目标明确且边界清晰,推荐敏捷轻量型以兼顾速度与效果。"
360
+ };
361
+
362
+ return {
363
+ id: `tradeoff_${crypto.randomBytes(3).toString("hex")}`,
364
+ title: "A/B 架构与交付模式权衡 (A/B Trade-Off)",
365
+ summary: matrix.rationale,
366
+ matrix
367
+ };
368
+ }
369
+
370
+ /**
371
+ * 根据具体任务类型推导自适应元决策模型(大白话、场景契合、无生硬黑话、无死板假插件硬绑)
372
+ */
373
+ export function generateUniversalMetaSlots(
374
+ task: string,
375
+ _tax: EcosystemTaxonomy,
376
+ fp: ProjectFingerprint,
377
+ tradeOff: TradeOffPlan
378
+ ): TaskDiagnosis {
379
+ const slots: TaskRequirementSlot[] = [];
380
+ const lowerTask = task.toLowerCase();
381
+ const isWeb = /网页|网站|web|ui|前端|页面|组件|vue|react|html|css|界面|dashboard|app|展示/i.test(lowerTask);
382
+ const isCli = /cli|命令行|脚本|工具|tool|command|cmd|terminal/i.test(lowerTask);
383
+ const isServiceOrBackend = /后端|api|server|服务|中间件|database|db|数据库|微服务|daemon|守护/i.test(lowerTask);
384
+
385
+ // 通用 Ponytail 生态感知:基于任务关键词与所有已安装生态组件的语义碰撞
386
+ const allInstalled = [
387
+ ...((_tax && _tax.extensions) || []),
388
+ ...((_tax && _tax.skills) || []),
389
+ ...((_tax && _tax.prompts) || [])
390
+ ];
391
+
392
+ // 通用多颗粒度分词(支持单字、双字、三字与英文子串提取)
393
+ const taskKeywords: string[] = [];
394
+ const cleanedTask = task.replace(/[,。!?、,\.!?]/g, " ");
395
+ for (let len = 4; len >= 2; len--) {
396
+ for (let i = 0; i <= cleanedTask.length - len; i++) {
397
+ const sub = cleanedTask.substring(i, i + len).trim().toLowerCase();
398
+ if (sub && !["完成", "我想", "开发", "制作", "实现", "一个", "需要", "如何", "怎么", "通知", "提醒"].includes(sub)) {
399
+ taskKeywords.push(sub);
400
+ }
401
+ }
402
+ }
403
+ (task.match(/[a-zA-Z0-9_-]{2,}/g) || []).forEach(w => taskKeywords.push(w.toLowerCase()));
404
+
405
+ const matchKw = (kw: string, text: string) => {
406
+ if (kw.length <= 1) return false; // 忽略单字避免泛误匹配
407
+ // 对于短单词(2-3字符),必须全字匹配或作为独立分词,避免 "pi" 命中 "pi-btw"
408
+ if (kw === "pi" || kw === "agent" || kw === "tool") return false;
409
+ return text.includes(kw);
410
+ };
411
+
412
+ let topEcosystemMatch: CapabilityItem | null = null;
413
+ if (taskKeywords.length > 0) {
414
+ for (const item of allInstalled) {
415
+ // 忽略基础框架、通用运维、侧边栏等通用工具,只对具备专用领域业务能力的生态进行协同
416
+ const ignoredTools = ["toolflow", "pi-tui-status-beautifier", "pi-btw", "input-history", "pi-rewind"];
417
+ if (ignoredTools.includes(item.name.toLowerCase()) || ignoredTools.some(ig => item.name.toLowerCase().includes(ig))) {
418
+ continue;
419
+ }
420
+ const targetText = `${item.name} ${item.description || ""} ${(item.tags || []).join(" ")}`.toLowerCase();
421
+ const matchCount = taskKeywords.filter(kw => matchKw(kw, targetText)).length;
422
+ if (matchCount > 0) {
423
+ topEcosystemMatch = item;
424
+ break;
425
+ }
426
+ }
427
+ }
428
+
429
+ // 1. 核心方案路径与工具流协同 (标准技术方案槽位)
430
+ slots.push({
431
+ slotId: "domain_feature_preference",
432
+ title: "1. 核心功能与技术实现策略 (技术方案)",
433
+ category: "scope",
434
+ question: `针对「${task}」,请选择期望的技术实现路径:`,
435
+ options: [
436
+ {
437
+ id: "opt_feature_comprehensive",
438
+ label: "[标准工程方案] 完整业务实现 (推荐)",
439
+ description: "按照现代软件工程化标准组织代码与接口契约,结构清晰且易于维护",
440
+ isRecommended: true,
441
+ recommendedEcosystem: {
442
+ extensions: [],
443
+ reason: "标准工程化架构落地"
444
+ }
445
+ },
446
+ {
447
+ id: "opt_feature_minimal",
448
+ label: "[极简方案] 核心主干功能",
449
+ description: "聚焦最核心的单点业务链路快速验证可行性,保持轻量纯粹",
450
+ isRecommended: false,
451
+ recommendedEcosystem: {
452
+ extensions: [],
453
+ reason: "轻量原型快速落地"
454
+ }
455
+ }
456
+ ]
457
+ });
458
+
459
+ // 2. 视觉基调 / 交互形态 (自适应 Web / CLI / Backend / 通用)
460
+ if (isWeb) {
461
+ slots.push({
462
+ slotId: "visual_style_preference",
463
+ title: "2. 视觉设计系统与呈现质感 (UI/视觉)",
464
+ category: "design",
465
+ question: "请选择偏好的视觉设计系统与呈现质感:",
466
+ options: [
467
+ {
468
+ id: "opt_style_modern",
469
+ label: "[高质感现代设计] 专业调色盘/精细矢量图标/平滑微动效 (推荐)",
470
+ description: "专业级现代 UI:精选调色盘、精细矢量 SVG 图标资产、8px 网格与优雅微动效",
471
+ isRecommended: true,
472
+ recommendedEcosystem: {
473
+ extensions: ["pi-web-access", "@plannotator/pi-extension"],
474
+ reason: "检索精美UI规范并在浏览器中实时走查体验"
475
+ }
476
+ },
477
+ {
478
+ id: "opt_style_dark",
479
+ label: "[深邃极客/暗黑] 霓虹点缀/高对比度/精致光影质感",
480
+ description: "科技暗黑基调、精致阴影/发光渐变与高对比度重点强调,视觉冲击强烈",
481
+ isRecommended: false,
482
+ recommendedEcosystem: {
483
+ extensions: ["@plannotator/pi-extension"],
484
+ reason: "走查暗黑主题对比度与细节"
485
+ }
486
+ },
487
+ {
488
+ id: "opt_style_minimal",
489
+ label: "[典雅极简/大厂排版] 留白呼吸感/精美字体层次/克制衬色",
490
+ description: "拒绝粗陋简陋,基于瑞士平面设计法则,以高级克制排版与严谨间距呈现",
491
+ isRecommended: false,
492
+ recommendedEcosystem: {
493
+ extensions: ["@plannotator/pi-extension"],
494
+ reason: "快速走查基础排版"
495
+ }
496
+ }
497
+ ]
498
+ });
499
+ } else if (isCli) {
500
+ slots.push({
501
+ slotId: "execution_runtime_preference",
502
+ title: "2. 交互体验与输出形态 (终端交互)",
503
+ category: "design",
504
+ question: "请选择命令行工具的交互与输出体验:",
505
+ options: [
506
+ {
507
+ id: "opt_cli_rich",
508
+ label: "[高质感终端] 交互式提示、彩色高亮与进度条 (推荐)",
509
+ description: "带友好的交互式引导、彩色语法高亮和动态进度条,直观易用",
510
+ isRecommended: true,
511
+ recommendedEcosystem: {
512
+ extensions: ["pi-tui-status-beautifier"],
513
+ reason: "美化终端输出与状态展示"
514
+ }
515
+ },
516
+ {
517
+ id: "opt_cli_standard",
518
+ label: "[标准无废话] 简洁参数输入与纯净输出",
519
+ description: "支持标准标准输入输出与管道重定向,适合脚本管道集成",
520
+ isRecommended: false,
521
+ recommendedEcosystem: {
522
+ extensions: [],
523
+ reason: "极简纯粹 CLI 交付"
524
+ }
525
+ },
526
+ {
527
+ id: "opt_cli_json",
528
+ label: "[结构化集成] 支持 JSON/YAML 多格式输出",
529
+ description: "提供机器友好的结构化输出开关,方便与其他工具链互通",
530
+ isRecommended: false,
531
+ recommendedEcosystem: {
532
+ extensions: [],
533
+ reason: "自动化工具链标准集成"
534
+ }
535
+ }
536
+ ]
537
+ });
538
+ } else if (isServiceOrBackend) {
539
+ slots.push({
540
+ slotId: "execution_runtime_preference",
541
+ title: "2. 架构模式与通信协议 (后端服务)",
542
+ category: "design",
543
+ question: "请选择服务架构与接口协议规范:",
544
+ options: [
545
+ {
546
+ id: "opt_backend_rest",
547
+ label: "[标准 RESTful/JSON API] 开箱即用且规范完整 (推荐)",
548
+ description: "提供规范的 RESTful 端点定义、统一错误处理与请求校验",
549
+ isRecommended: true,
550
+ recommendedEcosystem: {
551
+ extensions: ["pi-web-access"],
552
+ reason: "遵循行业最新 API 设计标准规范"
553
+ }
554
+ },
555
+ {
556
+ id: "opt_backend_fast",
557
+ label: "[极简轻量服务] 最小依赖、秒级冷启动",
558
+ description: "精简中间件,依赖最少化,专注于高并发与极速响应",
559
+ isRecommended: false,
560
+ recommendedEcosystem: {
561
+ extensions: [],
562
+ reason: "轻量极速后端交付"
563
+ }
564
+ },
565
+ {
566
+ id: "opt_backend_modular",
567
+ label: "[领域驱动分层] 控制器/服务/数据模型解耦",
568
+ description: "标准三层或 DDD 分层架构,便于团队协作与长期扩展",
569
+ isRecommended: false,
570
+ recommendedEcosystem: {
571
+ extensions: ["pi-subagents", "@quintinshaw/pi-dynamic-workflows"],
572
+ reason: "多智能体协作划分服务各分层模块"
573
+ }
574
+ }
575
+ ]
576
+ });
577
+ } else {
578
+ slots.push({
579
+ slotId: "execution_runtime_preference",
580
+ title: "2. 交互形态与运行模式 (交互模式)",
581
+ category: "design",
582
+ question: "请选择您偏好的交互形态与部署运行方式:",
583
+ options: [
584
+ {
585
+ id: "opt_runtime_direct",
586
+ label: "[直接运行] 本地开箱即用 (推荐)",
587
+ description: "无需繁琐配置,直接在当前环境一键运行并验证",
588
+ isRecommended: true,
589
+ recommendedEcosystem: {
590
+ extensions: ["pi-web-access"],
591
+ reason: "获取最新环境配置与开箱范式"
592
+ }
593
+ },
594
+ {
595
+ id: "opt_runtime_cli",
596
+ label: "[极简命令行] 终端单次按需调用",
597
+ description: "即敲即用,执行完立即退出,适合自动化脚本或轻量测试",
598
+ isRecommended: false,
599
+ recommendedEcosystem: {
600
+ extensions: [],
601
+ reason: "轻量 CLI 模式"
602
+ }
603
+ },
604
+ {
605
+ id: "opt_runtime_web",
606
+ label: "[可视化界面] 包含走查界面或控制面板",
607
+ description: "提供直观的网页走查或控制台,方便实时监控与交互",
608
+ isRecommended: false,
609
+ recommendedEcosystem: {
610
+ extensions: ["@plannotator/pi-extension"],
611
+ reason: "提供直观走查与状态验证"
612
+ }
613
+ }
614
+ ]
615
+ });
616
+ }
617
+
618
+ // 3. 构建方式与代码结构 (工程架构)
619
+ slots.push({
620
+ slotId: "delivery_strategy",
621
+ title: "3. 构建方式与代码结构 (构建结构)",
622
+ category: "scope",
623
+ question: "请选择代码构建方式:",
624
+ options: [
625
+ {
626
+ id: "opt_delivery_agile",
627
+ label: isWeb
628
+ ? "[组件化构建] 开箱即用 (推荐)"
629
+ : "[极简轻量] 单文件或轻量模块 (推荐)",
630
+ description: isWeb
631
+ ? "HTML/CSS/JS 解耦,开箱即可在浏览器直接运行"
632
+ : "聚焦核心逻辑,开箱即用",
633
+ isRecommended: true,
634
+ recommendedEcosystem: {
635
+ extensions: ["pi-web-access"],
636
+ reason: "获取现代标准规范"
637
+ }
638
+ },
639
+ {
640
+ id: "opt_delivery_modular",
641
+ label: "[标准分层] 模块解耦与分层架构",
642
+ description: "业务逻辑与接口分层,便于维护",
643
+ isRecommended: false,
644
+ recommendedEcosystem: {
645
+ extensions: ["pi-subagents", "@quintinshaw/pi-dynamic-workflows"],
646
+ reason: "多模块解耦落地"
647
+ }
648
+ },
649
+ {
650
+ id: "opt_delivery_enterprise",
651
+ label: "[完整工程] 包含文档与自动化验证",
652
+ description: "配备完整设计文档、单测与质量门禁",
653
+ isRecommended: false,
654
+ recommendedEcosystem: {
655
+ extensions: ["pi-subagents", "pi-rewind", "@plannotator/pi-extension"],
656
+ reason: "全自动化质量保障"
657
+ }
658
+ }
659
+ ]
660
+ });
661
+
662
+ // 4. 特色亮点与扩展考量 (特色亮点)
663
+ slots.push({
664
+ slotId: "ai_spark_highlights",
665
+ title: "4. 特色亮点与扩展考量 (附加能力)",
666
+ category: "general",
667
+ question: "请选择附加功能偏好:",
668
+ options: [
669
+ {
670
+ id: "opt_spark_smart_assistant",
671
+ label: "[容错与反馈] 清晰运行提示 (推荐)",
672
+ description: "增加输入校验与友好错误提示,避免异常崩溃",
673
+ isRecommended: true,
674
+ recommendedEcosystem: {
675
+ extensions: [],
676
+ reason: "高可用体验保障"
677
+ }
678
+ },
679
+ {
680
+ id: "opt_spark_responsive_export",
681
+ label: "[接口扩展] 预留配置化接口",
682
+ description: "预留入参配置,方便未来二次开发",
683
+ isRecommended: false,
684
+ recommendedEcosystem: {
685
+ extensions: [],
686
+ reason: "扩展能力支持"
687
+ }
688
+ },
689
+ {
690
+ id: "opt_spark_none",
691
+ label: "[纯净精简] 仅保留核心主功能",
692
+ description: "不添加额外代码,保持最小交付体积",
693
+ isRecommended: false,
694
+ recommendedEcosystem: {
695
+ extensions: [],
696
+ reason: "极简纯粹交付"
697
+ }
698
+ }
699
+ ]
700
+ });
701
+
702
+ // 动态构建通用目标与架构师灵感推荐 (Architect Sparks: 基础通用能力 + 场景特化能力融合)
703
+ const dynamicGoals = [
704
+ `实现「${task}」核心功能与关键业务链路`,
705
+ `确保代码结构整洁并提供实机走查与验收验证`
706
+ ];
707
+
708
+ // 1. 软件工程通用能力增益 (Universal Capabilities)
709
+ const architectSparks = [
710
+ {
711
+ id: "spark_graceful_error_handling",
712
+ title: "健壮容错与友好提示",
713
+ description: "增强边界条件与输入校验保护,避免异常直接中断流程",
714
+ impact: "健壮性与稳定性",
715
+ isAcceptedByDefault: true
716
+ },
717
+ {
718
+ id: "spark_inspect_and_verify",
719
+ title: "零依赖自省与快速自测",
720
+ description: "内置轻量快速自测与健康检查逻辑,便于验证产物完备性",
721
+ impact: "可测试性与交付质量",
722
+ isAcceptedByDefault: false
723
+ }
724
+ ];
725
+
726
+ // 2. 领域场景特化能力增益 (Domain-Specific Capabilities)
727
+ if (isWeb) {
728
+ architectSparks.push({
729
+ id: "spark_responsive_modern_ui",
730
+ title: "响应式适配与交互美化",
731
+ description: "自适应移动端与桌面端视口,增加微动效与优雅无障碍支持",
732
+ impact: "UI/UX 体验提升",
733
+ isAcceptedByDefault: true
734
+ });
735
+ } else if (isCli) {
736
+ architectSparks.push({
737
+ id: "spark_cli_pipe_friendly",
738
+ title: "管道流支持与丰富退出码",
739
+ description: "支持标准输入输出流管道传输 (stdin/stdout) 并提供标准 Exit Code",
740
+ impact: "脚本与自动化集成友好",
741
+ isAcceptedByDefault: true
742
+ });
743
+ } else if (isServiceOrBackend) {
744
+ architectSparks.push({
745
+ id: "spark_security_structured_log",
746
+ title: "结构化日志与安全鉴权防御",
747
+ description: "集成 JSON 格式结构化请求追踪与基础防刷限流守卫",
748
+ impact: "可观测性与安全防御",
749
+ isAcceptedByDefault: true
750
+ });
751
+ }
752
+
753
+ return {
754
+ taskDescription: task,
755
+ researchSummary: `针对 ${fp.projectType} 工程体系与任务目标,已自动推导场景化元决策模型与动态交付目标。`,
756
+ requirementSlots: slots,
757
+ dynamicGoals,
758
+ tradeOff,
759
+ architectSparks
760
+ };
761
+ }
762
+
763
+ /**
764
+ * 需求深度解构与多维共创推导
765
+ */
766
+ export async function diagnoseTaskRequirements(
767
+ task: string,
768
+ taxonomy: EcosystemTaxonomy,
769
+ ctx?: ExtensionContext,
770
+ providedFp?: ProjectFingerprint
771
+ ): Promise<TaskDiagnosis> {
772
+ const fp = providedFp || taxonomy.projectFingerprint || sniffProjectFingerprint();
773
+ const tradeOff = generateABTradeOffMatrix(task, fp);
774
+
775
+ const availableExtList = (taxonomy.extensions || []).map(e => e.name).join(", ");
776
+ const availableSkillList = (taxonomy.skills || []).map(s => s.name).join(", ");
777
+ const availableMcpList = (taxonomy.mcps || []).map(m => `mcp:${m.name}`).join(", ");
778
+ const availablePromptList = (taxonomy.prompts || []).map(p => `prompt:${p.name}`).join(", ");
779
+ const registeredToolList = (taxonomy.availableToolNames || []).join(", ");
780
+
781
+ const prompt = `[ROLE: Senior Architect & Product Lead]
782
+ Task: "${task}"
783
+ Local Environment: Project Type=${fp.projectType}, Framework=${fp.mainFramework || "none"}, PackageManager=${fp.packageManager}
784
+ Available Tools: Extensions=[${availableExtList}], Skills=[${availableSkillList}], MCP=[${availableMcpList}], Prompts=[${availablePromptList}], RegisteredTools=[${registeredToolList}]
785
+
786
+ [MISSION: TAILORED DECISION MATRIX FOR THIS SPECIFIC TASK]
787
+ You must dynamically generate a tailored, plain-language 4-dimension decision matrix and 2-4 concrete dynamic goals for "${task}".
788
+ No rigid templates, no tech jargon, no generic robotic wording. Everything must be 100% relevant to the user's specific task.
789
+
790
+ [CORE PHILOSOPHY: ECOSYSTEM & TOOL MANAGEMENT FIRST (PONYTAIL PRINCIPLE)]
791
+ You are a TOOL-FLOW ORCHESTRATOR & ECOSYSTEM MANAGER.
792
+ Your mission is to understand the true essence of "${task}".
793
+ - ECOSYSTEM MATCHING: ONLY recommend an installed extension/tool/skill IF it has strong, direct, real-world semantic relevance to the task domain! DO NOT force or hallucinate unrelated tools (e.g. NEVER recommend auxiliary note/query tools like 'pi-btw' or rollback tools like 'pi-rewind' as core architecture for WeChat/Backend/Network tasks). If no installed tool is directly relevant, recommend clean custom development or standard library implementation.
794
+ - ARTIFACT REASONING: Analyze what kind of software "${task}" truly is! If it is a backend integration, message hook, daemon, bot, or CLI, the primary deliverable should be 'src/index.ts', 'src/main.ts', or 'src/bot.ts'—NEVER output 'index.html' unless the task explicitly asks for a web frontend or browser game!
795
+
796
+ [4 DIMENSIONS TO GENERATE]:
797
+ 1. domain_feature_preference: "1. 方案路径与工具流协同 (推荐路径)"
798
+ - If installed tools match the task: First option MUST be "[推荐] 现成工具流协同方案" (explaining how to directly use installed extensions/skills with zero or minimal boilerplate code).
799
+ - Other options: "[自研] 从零定制开发" (custom implementation in workspace) or "[轻量] 极简核心原型".
800
+ 2. visual_style_preference OR execution_runtime_preference:
801
+ - For UI/Web/Frontend tasks: "2. 视觉基调与交互质感 (交互与样式)" with 3 distinct aesthetic/UX choices tailored to "${task}".
802
+ - For CLI/Backend/Script tasks: "2. 交互体验与运行模式 (交互模式)" with 3 distinct runtime/interaction styles tailored to "${task}".
803
+ 3. delivery_strategy: "3. 构建方式与代码结构 (工程架构)"
804
+ - Question: Ask how the code and project structure should be organized for "${task}".
805
+ - Provide 3 distinct options (e.g. Clean zero-config standalone, Modular decoupled, Full-spec industrial).
806
+ 4. ai_spark_highlights: "4. 特色亮点与体验加分项 (特色亮点)"
807
+ - Question: Suggest 2-3 unexpected, delightful spark features specifically tailored to "${task}".
808
+ - Provide 3 options (Rich delightful spark feature, Practical utility feature, Keep minimal & pure).
809
+
810
+ [ECOSYSTEM ATTACHMENT RULES]:
811
+ - Bind recommended extensions/skills ONLY from the Available Tools list if they genuinely assist the choice.
812
+ - For options that leverage installed tools, explicitly list them in recommendedEcosystem.extensions and explain the direct benefit.
813
+ - Every option MUST have: id, label (starting with tag e.g. "[完整方案]"), description (plain-language explanation of what the user gets), isRecommended (true for the best choice in the slot), recommendedEcosystem: { extensions: [...], reason: "plain-language value to user" }.
814
+
815
+ [DYNAMIC GOALS]:
816
+ - Formulate 2-4 specific, actionable milestone goals tailored to "${task}" (e.g. "构建可交互的宠物卡片与领养表单", "提供浏览器即开即用的实机走查体验").
817
+
818
+ [OUTPUT FORMAT]:
819
+ Return ONLY valid raw JSON matching this structure (no markdown fences, or wrapped in \`\`\`json):
820
+ {
821
+ "researchSummary": "针对「${task}」已结合当前工程环境与业务特征完成场景化推导。",
822
+ "requirementSlots": [
823
+ {
824
+ "slotId": "domain_feature_preference",
825
+ "title": "1. 核心功能与业务范围 (功能范围)",
826
+ "category": "scope",
827
+ "question": "...",
828
+ "options": [
829
+ {
830
+ "id": "opt_feature_comprehensive",
831
+ "label": "[完整方案] ... (推荐)",
832
+ "description": "...",
833
+ "isRecommended": true,
834
+ "recommendedEcosystem": { "extensions": ["pi-web-access"], "reason": "..." }
835
+ },
836
+ ...
837
+ ]
838
+ },
839
+ ...
840
+ ],
841
+ "dynamicGoals": [
842
+ "...",
843
+ "..."
844
+ ]
845
+ }`;
846
+
847
+ // 先检查全网公认生态插件(Ecosystem Radar)是否存在最优套餐方案
848
+ const installedNames = [
849
+ ...(taxonomy.extensions || []).map(e => e.name),
850
+ ...(taxonomy.skills || []).map(s => s.name),
851
+ ...(taxonomy.mcps || []).map(m => m.name)
852
+ ];
853
+ const ecosystemBundles = await EcosystemRadar.searchEcosystemCatalog(task, installedNames);
854
+
855
+ let ecosystemExtensionSlot: TaskRequirementSlot | null = null;
856
+ if (ecosystemBundles && ecosystemBundles.length > 0) {
857
+ ecosystemExtensionSlot = {
858
+ slotId: "slot_ecosystem_expansion",
859
+ title: "0. 生态扩展提议 (公认最优解套件推荐)",
860
+ category: "ecosystem",
861
+ question: "针对当前任务,社区/官方已存在公认极佳的专用扩展与 MCP 方案。是否一键装配?",
862
+ options: ecosystemBundles.map(b => ({
863
+ id: b.id,
864
+ label: b.title,
865
+ description: b.description,
866
+ isRecommended: b.isRecommended,
867
+ recommendedEcosystem: {
868
+ extensions: b.packages.map(p => p.name),
869
+ reason: b.isRecommended ? "引入社区公认神装,避免重复造轮子" : "纯净开发"
870
+ }
871
+ }))
872
+ };
873
+ }
874
+
875
+ // ⚡ 极速优先:默认直接采用本地毫秒级工程指纹与槽位推导,零延迟、零 Token 开销秒出决策舱!
876
+ // 仅在明确传入 { forceLLM: true } 且任务极为模糊时才降级为后台推理
877
+ const forceLLM = Boolean((ctx as any)?.forceLLM);
878
+ if (!forceLLM) {
879
+ const fallback = generateUniversalMetaSlots(task, taxonomy, fp, tradeOff);
880
+ const finalFallbackSlots = ecosystemExtensionSlot
881
+ ? [ecosystemExtensionSlot, ...fallback.requirementSlots]
882
+ : fallback.requirementSlots;
883
+
884
+ return {
885
+ ...fallback,
886
+ requirementSlots: finalFallbackSlots,
887
+ decisionSlots: finalFallbackSlots,
888
+ tradeOff
889
+ };
890
+ }
891
+
892
+ // 优先通过 pi 官方 modelRegistry 调用当前会话活跃大模型进行 100% 动态实时推理
893
+ if (ctx && (ctx as any).modelRegistry && (ctx as any).model) {
894
+ try {
895
+ const mr = (ctx as any).modelRegistry;
896
+ const model = (ctx as any).model;
897
+ const res = await mr.complete(
898
+ model,
899
+ {
900
+ messages: [
901
+ {
902
+ role: "user",
903
+ content: [{ type: "text", text: prompt }],
904
+ timestamp: Date.now()
905
+ }
906
+ ]
907
+ },
908
+ {
909
+ maxTokens: 2500,
910
+ temperature: 0.3
911
+ }
912
+ );
913
+
914
+ const textBlocks = (res.content || [])
915
+ .filter((c: any) => c.type === "text")
916
+ .map((c: any) => c.text)
917
+ .join("\n");
918
+
919
+ if (textBlocks) {
920
+ // 健壮提取 JSON 内容(优先 Markdown 围栏代码块,回退平衡大括号,避开贪婪匹配跨块崩溃)
921
+ const parsed = extractValidJsonObject(textBlocks);
922
+ if (parsed.requirementSlots && Array.isArray(parsed.requirementSlots) && parsed.requirementSlots.length >= 3) {
923
+ const isWeb = /网页|网站|单页|web|ui|前端|页面|组件|vue|react|html|css|界面|dashboard|app/i.test(task);
924
+ const fallbackSparks = isWeb
925
+ ? [
926
+ {
927
+ id: "spark_micro_animations",
928
+ title: "微交互反馈与流畅过渡",
929
+ description: "为核心操作增添平滑的触觉反馈与状态过渡,大幅提升界面呼吸感",
930
+ impact: "交互体验跃升",
931
+ isAcceptedByDefault: true
932
+ }
933
+ ]
934
+ : [
935
+ {
936
+ id: "spark_graceful_error_healing",
937
+ title: "优雅容错与输入校验",
938
+ description: "内置完善的入参自愈与异常友好提示,避免底层错误直接倾泻",
939
+ impact: "健壮性倍增",
940
+ isAcceptedByDefault: true
941
+ }
942
+ ];
943
+
944
+ const finalSlots = ecosystemExtensionSlot
945
+ ? [ecosystemExtensionSlot, ...parsed.requirementSlots]
946
+ : parsed.requirementSlots;
947
+
948
+ return {
949
+ taskDescription: task,
950
+ researchSummary: parsed.researchSummary || `已针对「${task}」由 AI 架构师结合本地环境实时动态推导。`,
951
+ requirementSlots: finalSlots,
952
+ decisionSlots: finalSlots,
953
+ dynamicGoals: Array.isArray(parsed.dynamicGoals) && parsed.dynamicGoals.length > 0
954
+ ? parsed.dynamicGoals
955
+ : [`实现「${task}」核心业务功能与关键流程`, `确保工程代码结构规范并完成实机走查验证`],
956
+ tradeOff,
957
+ architectSparks: Array.isArray(parsed.architectSparks) && parsed.architectSparks.length > 0
958
+ ? parsed.architectSparks
959
+ : fallbackSparks
960
+ };
961
+ }
962
+ }
963
+ } catch (_err) {
964
+ // 容错降级至本地智能自适应推导
965
+ }
966
+ }
967
+
968
+ // 本地智能自适应元决策推导(依据任务类型:Web / CLI / Backend / 通用动态适配)
969
+ const fallback = generateUniversalMetaSlots(task, taxonomy, fp, tradeOff);
970
+ const finalFallbackSlots = ecosystemExtensionSlot
971
+ ? [ecosystemExtensionSlot, ...fallback.requirementSlots]
972
+ : fallback.requirementSlots;
973
+
974
+ return {
975
+ ...fallback,
976
+ requirementSlots: finalFallbackSlots,
977
+ decisionSlots: finalFallbackSlots,
978
+ tradeOff
979
+ };
980
+ }
981
+
982
+ export async function synthesizeBlueprintPlanWithLLM(
983
+ task: string,
984
+ diagnosis: TaskDiagnosis,
985
+ userDecisions: Record<string, string>,
986
+ taxonomy: EcosystemTaxonomy,
987
+ ctx?: any
988
+ ): Promise<{ primaryArtifact: string; targetLanguage: string; isFrontend: boolean; stageHeavyTools?: { stage1?: string[]; stage2?: string[]; stage3?: string[] } }> {
989
+ // 默认由工程拓扑保底
990
+ const fp = taxonomy.projectFingerprint || sniffProjectFingerprint();
991
+ const profile = inferArtifactProfile(fp);
992
+
993
+ // 极速路径:从用户任务中尝试提取明确的文件路径(例如 src/auth.ts、tests/login.test.ts 等)
994
+ const pathMatch = task.match(/(?:[a-zA-Z0-9_\-\.\/]+\.(?:ts|js|py|rs|go|cpp|c|h|java|vue|tsx|jsx|json|md))/i);
995
+ const detectedPath = pathMatch ? pathMatch[0].replace(/\\/g, "/") : "";
996
+
997
+ const fallback = {
998
+ primaryArtifact: detectedPath || profile.srcPath,
999
+ targetLanguage: fp.language || "typescript",
1000
+ isFrontend: false
1001
+ };
1002
+
1003
+ // ⚡ 极速优先:默认跳过二次串行 LLM 往返,零延迟开工!仅在明确 forceLLM 时才触发后台请求
1004
+ const forceLLM = Boolean((ctx as any)?.forceLLM);
1005
+ if (!forceLLM) {
1006
+ return fallback;
1007
+ }
1008
+
1009
+ if (!ctx || !(ctx as any).modelRegistry || !(ctx as any).model) {
1010
+ return fallback;
1011
+ }
1012
+
1013
+ try {
1014
+ const mr = (ctx as any).modelRegistry;
1015
+ const model = (ctx as any).model;
1016
+
1017
+ const extraHeavyTools = (taxonomy.tools || [])
1018
+ .map(t => t.name)
1019
+ .filter(name => !["read", "write", "edit", "bash", "powershell", "grep", "find"].includes(name));
1020
+
1021
+ const prompt = `[ROLE: Senior Architect & Heavy Tool Allocator]
1022
+ Analyze the user task, project architecture, and available heavy tools/MCPs for medium-large execution.
1023
+ User Task: "${task}"
1024
+ Selected Decisions: ${JSON.stringify(userDecisions)}
1025
+ Workspace: ${fp.language} (${fp.projectType})
1026
+ Available Heavy Tools & MCPs: ${extraHeavyTools.join(", ") || "none"}
1027
+
1028
+ RULES:
1029
+ 1. primaryArtifact: src/index.ts, main.py for backend/CLI/daemon/bot. Only use index.html for web/UI.
1030
+ 2. Dynamic Heavy Tool Allocation (Token Optimization):
1031
+ - ONLY allocate heavy tools/MCPs to the stage where they are genuinely required.
1032
+ - stage1: Research/perception (e.g. web_search, fetch_content, documentation MCP).
1033
+ - stage2: Implementation/orchestration (e.g. workflow, subagent, database/api MCP).
1034
+ - stage3: Review/verification (e.g. browser/playwright MCP, test/lint MCP).
1035
+ - Omit unused heavy tools to save massive context token overhead.
1036
+
1037
+ Output ONLY a single JSON object:
1038
+ {
1039
+ "primaryArtifact": "src/index.ts",
1040
+ "targetLanguage": "typescript",
1041
+ "isFrontend": false,
1042
+ "stageHeavyTools": { "stage1": [], "stage2": [], "stage3": [] }
1043
+ }`;
1044
+
1045
+ const res = await mr.complete(
1046
+ model,
1047
+ {
1048
+ messages: [
1049
+ {
1050
+ role: "user",
1051
+ content: [{ type: "text", text: prompt }],
1052
+ timestamp: Date.now()
1053
+ }
1054
+ ]
1055
+ },
1056
+ { temperature: 0.1, maxTokens: 400 }
1057
+ );
1058
+
1059
+ const textBlocks = (res.content || [])
1060
+ .filter((c: any) => c.type === "text")
1061
+ .map((c: any) => c.text)
1062
+ .join("\n");
1063
+
1064
+ const parsed = extractValidJsonObject(textBlocks);
1065
+ if (parsed && typeof parsed.primaryArtifact === "string") {
1066
+ return {
1067
+ primaryArtifact: parsed.primaryArtifact,
1068
+ targetLanguage: parsed.targetLanguage || fp.language,
1069
+ isFrontend: Boolean(parsed.isFrontend),
1070
+ stageHeavyTools: parsed.stageHeavyTools
1071
+ };
1072
+ }
1073
+ } catch (_) {}
1074
+
1075
+ return fallback;
1076
+ }
1077
+ export function synthesizeBlueprint(
1078
+ task: string,
1079
+ diagnosis: TaskDiagnosis,
1080
+ userDecisions: Record<string, string>,
1081
+ taxonomy: EcosystemTaxonomy,
1082
+ selectedPlan?: "A" | "B",
1083
+ customRequirements?: string[],
1084
+ llmArtifactPlan?: { primaryArtifact: string; targetLanguage?: string; isFrontend?: boolean; stageHeavyTools?: { stage1?: string[]; stage2?: string[]; stage3?: string[] } }
1085
+ ): Blueprint {
1086
+ const blueprintId = `bp_${crypto.randomBytes(4).toString("hex")}`;
1087
+ const fp = taxonomy.projectFingerprint || sniffProjectFingerprint();
1088
+ const profile = inferArtifactProfile(fp);
1089
+ const isWebOrUI = llmArtifactPlan !== undefined
1090
+ ? llmArtifactPlan.isFrontend
1091
+ : (/(网页|网站|前端|页面|组件|vue|react|html|css|界面|dashboard|ui(?![a-z])|canvas|frontend)/i.test(task) &&
1092
+ !/(backend|后端|通信|hook|服务|daemon|http\s*api|server|api|cli|terminal)/i.test(task));
1093
+
1094
+ const activatedExts = new Set<string>();
1095
+ const activatedSkills = new Set<string>();
1096
+ const activatedPrompts = new Set<string>();
1097
+ const reasons: string[] = [];
1098
+
1099
+ for (const slot of diagnosis.requirementSlots) {
1100
+ const chosenOptId = userDecisions[slot.slotId];
1101
+ const opt = slot.options.find(o => o.id === chosenOptId) || slot.options.find(o => o.isRecommended) || slot.options[0];
1102
+ if (opt?.recommendedEcosystem) {
1103
+ opt.recommendedEcosystem.extensions?.forEach(e => activatedExts.add(e));
1104
+ opt.recommendedEcosystem.skills?.forEach(s => activatedSkills.add(s));
1105
+ opt.recommendedEcosystem.prompts?.forEach(p => activatedPrompts.add(p));
1106
+ reasons.push(`【${slot.title}】选择「${opt.label}」➔ 赋能: ${opt.recommendedEcosystem.reason}`);
1107
+ }
1108
+ }
1109
+
1110
+ const customReqs = customRequirements || (userDecisions.custom_requirements
1111
+ ? [userDecisions.custom_requirements]
1112
+ : userDecisions.customRequirements
1113
+ ? (Array.isArray(userDecisions.customRequirements) ? userDecisions.customRequirements : [userDecisions.customRequirements])
1114
+ : undefined);
1115
+
1116
+ const customReqNotice = customReqs && customReqs.length > 0
1117
+ ? `\n[用户个性化补充需求 (最高优先级)]: ${customReqs.join("; ")}`
1118
+ : "";
1119
+
1120
+ const isOrchestrationActive = activatedExts.has("pi-subagents") || activatedExts.has("@quintinshaw/pi-dynamic-workflows");
1121
+
1122
+ // 推导实机预览入口
1123
+ const livePreviewUrl = isWebOrUI
1124
+ ? `file:///${path.resolve(process.cwd(), "index.html").replace(/\\/g, "/")}`
1125
+ : undefined;
1126
+ const livePreviewCmd = profile.previewCommands && profile.previewCommands.length > 0
1127
+ ? profile.previewCommands[0]
1128
+ : isWebOrUI
1129
+ ? "start index.html"
1130
+ : undefined;
1131
+
1132
+ const explicitPlan = selectedPlan || (userDecisions.__plan as "A" | "B" | undefined) || (userDecisions.plan as "A" | "B" | undefined);
1133
+ const isPlanB = explicitPlan === "B" || (!explicitPlan && (userDecisions.delivery_strategy?.includes("modular") || userDecisions.delivery_strategy?.includes("enterprise")));
1134
+ const isAgile = !isPlanB;
1135
+
1136
+ // 动态提取环境中四层能力集合(完全基于 L1~L4 语义分类,彻底移除固定包名特判)
1137
+ const allExts = taxonomy.extensions || [];
1138
+ const allSkills = taxonomy.skills || [];
1139
+ const allPrompts = taxonomy.prompts || [];
1140
+
1141
+ const l2PerceptionExts = allExts.filter(e => e.layer === "L2_PERCEPTION").map(e => e.name);
1142
+ const l3OrchestrationExts = allExts.filter(e => e.layer === "L3_ORCHESTRATION").map(e => e.name);
1143
+ const l4ReviewExts = allExts.filter(e => e.layer === "L4_REVIEW_GUARD").map(e => e.name);
1144
+
1145
+ // 动态提取环境中实际注册与发现的工具名清单(绝不假设任何未安装的第三方插件)
1146
+ const realTools = new Set(taxonomy.availableToolNames || []);
1147
+ const hasTool = (name: string) => realTools.has(name) || (taxonomy.tools || []).some(t => t.name === name);
1148
+
1149
+ // 动态感知与自动收集已安装的额外工具(如用户自定义 MCP、自定义扩展工具)
1150
+ const extraTools = (taxonomy.tools || [])
1151
+ .map(t => t.name)
1152
+ .filter(name => !["read", "write", "edit", "bash", "powershell", "grep", "find"].includes(name));
1153
+
1154
+ // 🧠 核心架构:若大模型推导给出了精细的阶段重型工具编排 (stageHeavyTools),优先采用 LLM 深度推理分配!
1155
+ const llmAlloc = llmArtifactPlan?.stageHeavyTools;
1156
+ const stage1Tools = ["read", "bash", "powershell", "grep", "find"];
1157
+ const stage2Tools = ["read", "edit", "write", "bash", "powershell", "grep", "find"];
1158
+ const stage3Tools = ["read", "bash", "powershell", "grep", "find"];
1159
+
1160
+ if (isAgile) {
1161
+ stage1Tools.push("edit", "write");
1162
+ }
1163
+ ["goal_complete", "goal_blocked", "goal_wait"].forEach(t => { if (hasTool(t)) stage3Tools.push(t); });
1164
+
1165
+ if (llmAlloc && typeof llmAlloc === "object") {
1166
+ // 🎯 方案 A:大模型精准推理分配,严格按需下发重型工具,彻底消灭不相关 MCP 的 Token 暴利税
1167
+ if (Array.isArray(llmAlloc.stage1)) {
1168
+ llmAlloc.stage1.forEach(t => { if (hasTool(t) && !stage1Tools.includes(t)) stage1Tools.push(t); });
1169
+ }
1170
+ if (Array.isArray(llmAlloc.stage2)) {
1171
+ llmAlloc.stage2.forEach(t => { if (hasTool(t) && !stage2Tools.includes(t)) stage2Tools.push(t); });
1172
+ }
1173
+ if (Array.isArray(llmAlloc.stage3)) {
1174
+ llmAlloc.stage3.forEach(t => { if (hasTool(t) && !stage3Tools.includes(t)) stage3Tools.push(t); });
1175
+ }
1176
+ } else {
1177
+ // 🛡️ 方案 B:无大模型分配时的启发式通用降级
1178
+ if (l2PerceptionExts.length > 0 || hasTool("web_search") || hasTool("fetch_content") || hasTool("source_check")) {
1179
+ ["web_search", "fetch_content", "source_check"].forEach(t => { if (hasTool(t)) stage1Tools.push(t); });
1180
+ }
1181
+ if (hasTool("mcp")) stage1Tools.push("mcp");
1182
+ if (hasTool("mcpScript")) stage1Tools.push("mcpScript");
1183
+ if (hasTool("workflow")) stage1Tools.push("workflow");
1184
+ extraTools.forEach(toolName => {
1185
+ const item = (taxonomy.tools || []).find(t => t.name === toolName);
1186
+ if (item && item.layer === "L2_PERCEPTION" && !stage1Tools.includes(toolName)) stage1Tools.push(toolName);
1187
+ if (!stage2Tools.includes(toolName)) stage2Tools.push(toolName);
1188
+ if (item && item.layer === "L4_REVIEW_GUARD" && !stage3Tools.includes(toolName)) stage3Tools.push(toolName);
1189
+ });
1190
+ if (hasTool("workflow")) stage2Tools.push("workflow");
1191
+ if (hasTool("subagent")) stage2Tools.push("subagent");
1192
+ if (hasTool("mcp")) stage2Tools.push("mcp");
1193
+ if (hasTool("mcpScript")) stage2Tools.push("mcpScript");
1194
+ if (hasTool("workflow")) stage3Tools.push("workflow");
1195
+ if (hasTool("mcp")) stage3Tools.push("mcp");
1196
+ if (hasTool("mcpScript")) stage3Tools.push("mcpScript");
1197
+ }
1198
+ // 交付物产物:若 LLM 推导给出了明确产物则 100% 采纳,否则由工程拓扑保底
1199
+ const defaultSrcPath = (llmArtifactPlan && llmArtifactPlan.primaryArtifact)
1200
+ ? llmArtifactPlan.primaryArtifact
1201
+ : (isWebOrUI ? "index.html" : profile.srcPath);
1202
+ const stage2VerificationCommands = (!isWebOrUI && (profile.buildCommands?.length || profile.testCommands?.length))
1203
+ ? [...(profile.buildCommands || []), ...(profile.testCommands || [])]
1204
+ : undefined;
1205
+
1206
+ // 任务轻重自适应探测 (Adaptive Task Complexity Router)
1207
+ // 识别是否属于日常单点改动/局部修补/微任务,打破僵化的字符数硬限制
1208
+ const taskLower = (task || "").toLowerCase();
1209
+ const explicitMicro = userDecisions.__microTask === "true" || userDecisions.__microTask === ("true" as any);
1210
+
1211
+ // 智能微任务判别:
1212
+ // 1. 包含明确的单点修改、修补、微调、日志、类型补充等意图动词
1213
+ const hasMicroActionVerb = /(修复|fix|修改|改一下|微调|format|加个注释|添加注释|加注释|补充类型|类型修复|换个颜色|改个文案|改文案|加个字段|加字段|增加字段|输出日志|加log|加打印)/i.test(taskLower);
1214
+ // 2. 没有强烈的全局多模块架构、系统级新建或全流程生命周期诉求
1215
+ const hasHeavyArchitecturalScope = /(重构系统|架构设计|全新系统|端到端开发|从头开发|设计整个|全栈系统|从零构建|新建工程|大型系统|全量迁移)/i.test(taskLower);
1216
+ // 3. 长度在适度范围内(80字以内单句指令),或者指名了具体的单个文件名/函数名
1217
+ const isTargetedOrConcise = taskLower.length <= 80 || /\.(ts|js|py|rs|go|json|css|html|md)\b/i.test(taskLower);
1218
+
1219
+ const isLightweightIntent = hasMicroActionVerb && !hasHeavyArchitecturalScope && isTargetedOrConcise;
1220
+
1221
+ const isMicroTask = !isPlanB && (explicitMicro || isLightweightIntent);
1222
+
1223
+ let rawStages: BlueprintStage[];
1224
+ if (isMicroTask) {
1225
+ rawStages = [
1226
+ {
1227
+ stageId: "stage_1_direct_execution",
1228
+ title: "极速响应与验证 (单阶段极简通道)",
1229
+ roleProfile: "quick_specialist",
1230
+ coreObjective: `针对目标任务快速实施变更并执行必要验证,完成后直接交付。${customReqNotice}`,
1231
+ boundCapabilities: {
1232
+ extensions: [],
1233
+ skills: []
1234
+ },
1235
+ expectedArtifact: defaultSrcPath,
1236
+ expectedArtifacts: [defaultSrcPath],
1237
+ targetPatterns: ["src/**", "lib/**", "tests/**", "*"],
1238
+ artifactContract: `直接产出修改代码并确保无语法错误。`,
1239
+ verificationCommands: stage2VerificationCommands,
1240
+ allowedTools: ["read", "edit", "write", "bash", "powershell", "grep", "find"],
1241
+ tokenCostNotice: "极简直接执行,0 前置冗余"
1242
+ }
1243
+ ];
1244
+ } else {
1245
+ rawStages = isAgile
1246
+ ? [
1247
+ {
1248
+ stageId: "stage_1_design",
1249
+ title: "方案设计与契约 (设计阶段)",
1250
+ roleProfile: "system_architect",
1251
+ coreObjective: `依据任务目标快速确立 ${fp.projectType} 架构设计与契约 (${profile.docPath})。优先调用最新检索规范。${customReqNotice}`,
1252
+ boundCapabilities: {
1253
+ extensions: l2PerceptionExts.slice(0, 2),
1254
+ prompts: Array.from(activatedPrompts).filter(p => p.includes("research") || p.includes("clarify"))
1255
+ },
1256
+ expectedArtifact: profile.docPath,
1257
+ expectedArtifacts: [profile.docPath],
1258
+ targetPatterns: ["docs/**", "*.md"],
1259
+ artifactContract: `包含模块架构与接口契约,落盘于 ${profile.docPath}。${customReqNotice ? " 约束说明: " + customReqNotice : ""}`,
1260
+ allowedTools: stage1Tools,
1261
+ tokenCostNotice: "快速确立设计契约,杜绝架构跑偏"
1262
+ },
1263
+ {
1264
+ stageId: "stage_2_implementation_preview",
1265
+ title: "[核心制作] 敏捷编码与实机走查",
1266
+ roleProfile: isOrchestrationActive ? "subagent_orchestrator" : "principal_engineer",
1267
+ dependsOn: ["stage_1_design"],
1268
+ coreObjective: `遵循契约完成核心源码编写 (${defaultSrcPath}),拉起实机走查并向用户展示核心亮点。进入前自动建立安全快照。`,
1269
+ isInteractiveCoCreation: true,
1270
+ previewUrl: livePreviewUrl,
1271
+ previewCommand: livePreviewCmd,
1272
+ boundCapabilities: {
1273
+ extensions: Array.from(activatedExts),
1274
+ skills: Array.from(activatedSkills)
1275
+ },
1276
+ expectedArtifact: defaultSrcPath,
1277
+ expectedArtifacts: [defaultSrcPath],
1278
+ targetPatterns: ["src/**", "lib/**", "*.ts", "*.js", "*.rs", "*.py", "*.go", "*.html"],
1279
+ artifactContract: `完成 ${defaultSrcPath} 编写与运行走查,语法无误。`,
1280
+ verificationCommands: stage2VerificationCommands,
1281
+ allowedTools: stage2Tools,
1282
+ tokenCostNotice: "敏捷合并编码与实机走查,秒级交付"
1283
+ },
1284
+ {
1285
+ stageId: "stage_3_verification_delivery",
1286
+ title: "[门禁终审] 自动化验收与成果交付",
1287
+ roleProfile: "quality_auditor",
1288
+ dependsOn: ["stage_2_implementation_preview"],
1289
+ coreObjective: `执行自动化测试与 64 位 SHA 门禁,生成交付凭证与价值结算单。`,
1290
+ boundCapabilities: {
1291
+ extensions: Array.from(activatedExts).filter(e => e.includes("goal") || e.includes("tui")),
1292
+ skills: Array.from(activatedSkills)
1293
+ },
1294
+ expectedArtifact: profile.reportPath,
1295
+ expectedArtifacts: [profile.reportPath, ...(isWebOrUI || !profile.testPath ? [] : [profile.testPath])],
1296
+ targetPatterns: ["reports/**", "tests/**", "docs/**", "*.test.*", "*.spec.*"],
1297
+ artifactContract: `包含 SHA-256 校验和与测试结果,落盘于 ${profile.reportPath}。`,
1298
+ verificationCommands: !isWebOrUI && profile.testCommands && profile.testCommands.length > 0 ? profile.testCommands : undefined,
1299
+ allowedTools: stage3Tools,
1300
+ isReviewStage: true,
1301
+ reviewIsolation: {
1302
+ enabled: true,
1303
+ requireColdStart: true,
1304
+ diffOnlyContext: true
1305
+ },
1306
+ tokenCostNotice: "自动化测试闭环,生成价值交付收据"
1307
+ }
1308
+ ]
1309
+ : [
1310
+ {
1311
+ stageId: "stage_1_design",
1312
+ title: "[架构设计] 方案设计与意图契约",
1313
+ roleProfile: "system_architect",
1314
+ coreObjective: `依据任务目标与用户共创选型,完成 ${fp.projectType} 架构契约与设计文档编写。优先调用检索工具获取最新官方规范,杜绝过时盲猜。${customReqNotice}`,
1315
+ boundCapabilities: {
1316
+ extensions: l2PerceptionExts.slice(0, 2),
1317
+ prompts: Array.from(activatedPrompts).filter(p => p.includes("research") || p.includes("clarify"))
1318
+ },
1319
+ expectedArtifact: profile.docPath,
1320
+ expectedArtifacts: [profile.docPath],
1321
+ targetPatterns: ["docs/**", "*.md"],
1322
+ artifactContract: `包含业务范围、模块架构、接口契约与依赖规范,落盘于 ${profile.docPath}。${customReqNotice ? " 约束说明: " + customReqNotice : ""}`,
1323
+ allowedTools: stage1Tools,
1324
+ tokenCostNotice: "主动检索官方最新规范,确保设计 100% 准确"
1325
+ },
1326
+ {
1327
+ stageId: "stage_2_implementation",
1328
+ title: "[核心制作] 功能编写与模块构建",
1329
+ roleProfile: isOrchestrationActive ? "subagent_orchestrator" : "principal_engineer",
1330
+ dependsOn: ["stage_1_design"],
1331
+ coreObjective: `遵循阶段 1 设计契约完成核心代码编写 (${defaultSrcPath})。按需自主决策使用 workflow / subagent 派发并行子任务,或直接编码实现。进入前系统自动建立安全快照点。`,
1332
+ boundCapabilities: {
1333
+ extensions: Array.from(activatedExts).filter(e => e.includes("subagents") || e.includes("workflows") || e.includes("rewind")),
1334
+ skills: Array.from(activatedSkills)
1335
+ },
1336
+ expectedArtifact: defaultSrcPath,
1337
+ expectedArtifacts: [defaultSrcPath],
1338
+ targetPatterns: ["src/**", "lib/**", "*.ts", "*.js", "*.rs", "*.py", "*.go", "*.html"],
1339
+ artifactContract: `完成 ${defaultSrcPath} 核心业务逻辑编写,语法无误且符合设计契约。`,
1340
+ verificationCommands: stage2VerificationCommands,
1341
+ allowedTools: stage2Tools,
1342
+ tokenCostNotice: "专注核心源码编写,严格落实设计契约"
1343
+ },
1344
+ {
1345
+ stageId: "stage_3_preview_cocreation",
1346
+ title: "[效果走查] 实机运行与共创调优",
1347
+ roleProfile: "experience_consultant",
1348
+ dependsOn: ["stage_2_implementation"],
1349
+ coreObjective: "运行演示命令或调起实机预览,向用户直观展示当前成果亮点,并主动征询 2~3 个具体优化建议。可按需借助 plannotator / 浏览器走查工具辅助审查。",
1350
+ isInteractiveCoCreation: true,
1351
+ proactiveInquiryPrompt: "我已完成核心功能编写,以下是实际运行效果与亮点。针对交互手感/文案/样式,您是否有特定微调偏好?",
1352
+ previewUrl: livePreviewUrl,
1353
+ previewCommand: livePreviewCmd,
1354
+ boundCapabilities: {
1355
+ extensions: Array.from(activatedExts).filter(e => e.includes("plannotator") || e.includes("web")),
1356
+ skills: Array.from(activatedSkills).filter(s => s.includes("plannotator"))
1357
+ },
1358
+ expectedArtifact: profile.previewPath,
1359
+ expectedArtifacts: [profile.previewPath],
1360
+ targetPatterns: ["reports/**", "docs/**", "*.md"],
1361
+ artifactContract: `输出包含运行效果走查、功能完成对照与用户征询问题的记录,落盘于 ${profile.previewPath}。`,
1362
+ verificationCommands: profile.previewCommands && profile.previewCommands.length > 0 ? profile.previewCommands : undefined,
1363
+ allowedTools: hasTool("mcp") ? ["read", "write", "bash", "powershell", "grep", "find", "mcp"] : ["read", "write", "bash", "powershell", "grep", "find"],
1364
+ tokenCostNotice: "拉起实机走查,人机深度共创把关"
1365
+ },
1366
+ {
1367
+ stageId: "stage_4_testing",
1368
+ title: "自动化单测与物理门禁 (单测验证)",
1369
+ roleProfile: "test_engineer",
1370
+ dependsOn: ["stage_3_preview_cocreation"],
1371
+ coreObjective: `根据共创定稿成果编写单测 (${profile.testPath}),执行验证命令,确保全部绿灯并通过 64 位 SHA 物理校验。可自主使用 goal / workflow(adversarial-review) 强化门禁质量。`,
1372
+ boundCapabilities: {
1373
+ extensions: Array.from(activatedExts).filter(e => e.includes("goal")),
1374
+ skills: Array.from(activatedSkills)
1375
+ },
1376
+ expectedArtifact: profile.testPath,
1377
+ expectedArtifacts: [profile.testPath],
1378
+ targetPatterns: ["tests/**", "*.test.*", "*.spec.*"],
1379
+ artifactContract: `包含测试用例,运行 ${profile.testCommands.join(" / ") || "单测命令"} 必须通过。`,
1380
+ verificationCommands: profile.testCommands,
1381
+ allowedTools: stage2Tools.concat(stage3Tools.filter(t => !stage2Tools.includes(t))),
1382
+ tokenCostNotice: "自动化单测验证,拦截 0-Byte 伪交付"
1383
+ },
1384
+ {
1385
+ stageId: "stage_5_audit_delivery",
1386
+ title: "终审归档与高保真通知 (终审交付)",
1387
+ roleProfile: "quality_auditor",
1388
+ dependsOn: ["stage_4_testing"],
1389
+ coreObjective: `生成交付成果清单与文件校验和,并通过终端 TUI 输出交付卡片。`,
1390
+ boundCapabilities: {
1391
+ extensions: Array.from(activatedExts).filter(e => e.includes("goal") || e.includes("tui")),
1392
+ skills: []
1393
+ },
1394
+ expectedArtifact: profile.reportPath,
1395
+ expectedArtifacts: [profile.reportPath],
1396
+ targetPatterns: ["reports/**", "docs/**"],
1397
+ artifactContract: `包含测试覆盖数据、物理产物 64 位 SHA-256 指纹与竣工报告,落盘于 ${profile.reportPath}。`,
1398
+ allowedTools: ["read", "write", "bash", "powershell", "grep", "find", "mcp"],
1399
+ isReviewStage: true,
1400
+ reviewIsolation: {
1401
+ enabled: true,
1402
+ requireColdStart: true,
1403
+ diffOnlyContext: true
1404
+ },
1405
+ tokenCostNotice: "生成最终交付凭证,触发高保真多端通知"
1406
+ }
1407
+ ];
1408
+ }
1409
+
1410
+ // 执行 Kahn DAG 拓扑排序与分波解算
1411
+ const dagResult = planDAGWaves(rawStages);
1412
+
1413
+ // 深度生态方法级与 SOP 规则物理灌注 (Deep MCP & Deep Skills)
1414
+ const availableMcpServers = (taxonomy?.mcps || []).map(m => m.name.replace("mcp__", ""));
1415
+ const discoveredSkills = (taxonomy?.skills || []).map(s => ({ name: s.name, filePath: s.filePath }));
1416
+ const enrichedStages = dagResult.sortedStages.map(s => {
1417
+ bindDeepEcosystemToStage(s, availableMcpServers, discoveredSkills);
1418
+ return s;
1419
+ });
1420
+
1421
+ return {
1422
+ blueprintId,
1423
+ task,
1424
+ createdAt: Date.now(),
1425
+ projectFingerprint: fp,
1426
+ userChoices: userDecisions,
1427
+ customRequirements: customReqs,
1428
+ activatedCapabilities: {
1429
+ extensions: Array.from(activatedExts),
1430
+ skills: Array.from(activatedSkills),
1431
+ prompts: Array.from(activatedPrompts)
1432
+ },
1433
+ tokenEfficiencySummary: reasons.join("\n"),
1434
+ stages: enrichedStages,
1435
+ dagWaves: dagResult.waves,
1436
+ dynamicGoals: diagnosis.dynamicGoals || [
1437
+ `实现「${task}」核心功能与关键业务链路`,
1438
+ `确保代码结构整洁并提供实机走查与验收验证`
1439
+ ]
1440
+ };
1441
+ }
1442
+
1443
+ /**
1444
+ * 动作指令诱导合成器:根据阶段属性精准注入高阶工具(workflow/goal/subagent)使用诉求,防止退化到低效裸写
1445
+ */
1446
+ export function generateStageActionPrompt(
1447
+ stage: BlueprintStage,
1448
+ stageIndex: number,
1449
+ totalStages: number,
1450
+ isReview: boolean = false
1451
+ ): string {
1452
+ const allowed = stage.allowedTools || [];
1453
+ const hasWorkflow = allowed.includes("workflow");
1454
+ const hasGoal = allowed.includes("goal") || allowed.includes("goal_complete");
1455
+ const hasSubagent = allowed.includes("subagent");
1456
+ const hasMcp = allowed.includes("mcp");
1457
+
1458
+ // 如果阶段绑定了特定 Skills,生成紧凑 SOP 指令建议
1459
+ const boundSkills = stage.boundCapabilities?.skills || [];
1460
+ const skillAdvice = stage.skillContract
1461
+ ? ` (Enforced Skill: '${stage.skillContract.skillName}' [${stage.skillContract.rules[0] || "遵循SOP"}])`
1462
+ : boundSkills.length > 0 ? ` (Tip: Leverage skill '${boundSkills[0]}')` : "";
1463
+
1464
+ // 如果阶段绑定了具体的 MCP 方法,直接打出无幻觉的精准调用模版
1465
+ const mcpTemplateAdvice = (stage.mcpToolBindings && stage.mcpToolBindings.length > 0)
1466
+ ? `\nRecommended MCP Call: ${stage.mcpToolBindings[0].template}`
1467
+ : "";
1468
+
1469
+ if (isReview) {
1470
+ if (hasGoal) {
1471
+ return `执行测试套件与走查验证,全部通过后确认交付。${skillAdvice}${mcpTemplateAdvice}`;
1472
+ }
1473
+ if (hasWorkflow) {
1474
+ return `可通过 'workflow({ name: "code-review" })' 走查或直接运行测试门禁。${skillAdvice}${mcpTemplateAdvice}`;
1475
+ }
1476
+ return `执行测试验证并客观走查关键变更。${skillAdvice}${mcpTemplateAdvice}`;
1477
+ }
1478
+
1479
+ // 架构/设计/调研阶段
1480
+ if (stage.stageId.includes("design") || stage.title.includes("设计") || stage.title.includes("调研")) {
1481
+ if (hasWorkflow) {
1482
+ return `CRITICAL ACTION: You MUST invoke the 'write' tool to output the architectural specification into '${stage.expectedArtifact}' now. (For deep exploration, you may leverage 'workflow({ name: "deep-research" })'). Do NOT merely discuss or think.${skillAdvice}${mcpTemplateAdvice}`;
1483
+ }
1484
+ return `CRITICAL ACTION: You MUST invoke the 'write' tool to create the design specification file '${stage.expectedArtifact}' immediately. Do NOT merely discuss or think without writing.${skillAdvice}${mcpTemplateAdvice}`;
1485
+ }
1486
+
1487
+ // 编码/实现阶段
1488
+ if (stage.stageId.includes("implementation") || stage.title.includes("编码") || stage.title.includes("制作")) {
1489
+ const qualityWarning = "【交付质量硬指标】严防粗制滥造:设计与视觉重灾区必须严谨打造!UI/图案绝不可用单调色块/方块敷衍,必须配备专业调色盘、精细矢量 SVG 图案/图标、一致网格间距与过渡动效;逻辑严密模块化,绝不输出玩具级半成品。";
1490
+ if (hasWorkflow || hasSubagent) {
1491
+ return `实现核心功能逻辑,可按需调用 workflow/subagent 进行并行分发或直接编写落地。${qualityWarning}${skillAdvice}${mcpTemplateAdvice}`;
1492
+ }
1493
+ return `编写实现代码并交付落盘 (${stage.expectedArtifact})。${qualityWarning}${skillAdvice}${mcpTemplateAdvice}`;
1494
+ }
1495
+
1496
+ // 走查/调优阶段
1497
+ if (stage.stageId.includes("preview") || stage.title.includes("走查")) {
1498
+ return `启动本地预览/走查,切实验证实际交互效果、视觉设计与图案质感(重点走查设计是否粗糙、图案是否简陋、间距动效是否自然),查漏补缺,拒绝形式主义。${skillAdvice}${mcpTemplateAdvice}`;
1499
+ }
1500
+
1501
+ // 单测/验收/门禁阶段
1502
+ if (hasGoal || stage.stageId.includes("gate") || stage.title.includes("验收") || stage.title.includes("门禁")) {
1503
+ if (hasGoal) {
1504
+ return `运行测试验证并通过 goal_complete 门禁确认交付。${skillAdvice}${mcpTemplateAdvice}`;
1505
+ }
1506
+ return `运行测试套件验证功能完备性。${skillAdvice}${mcpTemplateAdvice}`;
1507
+ }
1508
+
1509
+ return `编写并落实交付成果 (${stage.expectedArtifact || "目标产物"})。${skillAdvice}${mcpTemplateAdvice}`;
1510
+ }