speccore 6.82.0 → 6.89.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/dist/commands/analyze.d.ts.map +1 -1
  2. package/dist/commands/analyze.js +178 -34
  3. package/dist/commands/analyze.js.map +1 -1
  4. package/dist/commands/change.d.ts.map +1 -1
  5. package/dist/commands/change.js +39 -1
  6. package/dist/commands/change.js.map +1 -1
  7. package/dist/commands/init.d.ts.map +1 -1
  8. package/dist/commands/init.js +118 -0
  9. package/dist/commands/init.js.map +1 -1
  10. package/dist/commands/pr.d.ts.map +1 -1
  11. package/dist/commands/pr.js +75 -38
  12. package/dist/commands/pr.js.map +1 -1
  13. package/dist/core/agents/defaults/_INDEX.md +68 -0
  14. package/dist/core/agents/defaults/_TEMPLATE.md +34 -0
  15. package/dist/core/agents/defaults/code-reviewer.md +49 -0
  16. package/dist/core/agents/defaults/compiler.md +25 -0
  17. package/dist/core/agents/defaults/compliance-checker.md +38 -0
  18. package/dist/core/agents/defaults/dependency-analyst.md +42 -0
  19. package/dist/core/agents/defaults/doc-sync-agent.md +25 -0
  20. package/dist/core/agents/defaults/impact-analyst.md +37 -0
  21. package/dist/core/agents/defaults/interaction-designer.md +73 -0
  22. package/dist/core/agents/defaults/performance-expert.md +35 -0
  23. package/dist/core/agents/defaults/product-analyst-backend.md +68 -0
  24. package/dist/core/agents/defaults/product-analyst-frontend.md +72 -0
  25. package/dist/core/agents/defaults/product-analyst.md +48 -0
  26. package/dist/core/agents/defaults/regression-tester.md +36 -0
  27. package/dist/core/agents/defaults/risk-assessor.md +38 -0
  28. package/dist/core/agents/defaults/schedule-planner.md +37 -0
  29. package/dist/core/agents/defaults/security-reviewer-finance.md +67 -0
  30. package/dist/core/agents/defaults/security-reviewer.md +43 -0
  31. package/dist/core/agents/defaults/task-decomposer.md +33 -0
  32. package/dist/core/agents/defaults/test-engineer.md +25 -0
  33. package/dist/core/agents/defaults/test-reviewer.md +48 -0
  34. package/dist/core/agents/engine/agent-executor.d.ts +50 -0
  35. package/dist/core/agents/engine/agent-executor.d.ts.map +1 -0
  36. package/dist/core/agents/engine/agent-executor.js +225 -0
  37. package/dist/core/agents/engine/agent-executor.js.map +1 -0
  38. package/dist/core/agents/engine/agent-loader.d.ts +58 -0
  39. package/dist/core/agents/engine/agent-loader.d.ts.map +1 -0
  40. package/dist/core/agents/engine/agent-loader.js +377 -0
  41. package/dist/core/agents/engine/agent-loader.js.map +1 -0
  42. package/dist/core/agents/engine/types.d.ts +71 -0
  43. package/dist/core/agents/engine/types.d.ts.map +1 -0
  44. package/dist/core/agents/engine/types.js +8 -0
  45. package/dist/core/agents/engine/types.js.map +1 -0
  46. package/dist/core/agents/index.d.ts +12 -0
  47. package/dist/core/agents/index.d.ts.map +1 -0
  48. package/dist/core/agents/index.js +31 -0
  49. package/dist/core/agents/index.js.map +1 -0
  50. package/dist/core/agents/product-analyst.d.ts +17 -0
  51. package/dist/core/agents/product-analyst.d.ts.map +1 -0
  52. package/dist/core/agents/product-analyst.js +188 -0
  53. package/dist/core/agents/product-analyst.js.map +1 -0
  54. package/dist/core/command-loader.d.ts +31 -0
  55. package/dist/core/command-loader.d.ts.map +1 -0
  56. package/dist/core/command-loader.js +76 -0
  57. package/dist/core/command-loader.js.map +1 -0
  58. package/dist/core/commands/defaults/change-impact.md +40 -0
  59. package/dist/core/commands/defaults/pr-review.md +42 -0
  60. package/dist/core/commands/defaults/refactor.md +37 -0
  61. package/dist/core/context-injector.d.ts +56 -0
  62. package/dist/core/context-injector.d.ts.map +1 -0
  63. package/dist/core/context-injector.js +122 -0
  64. package/dist/core/context-injector.js.map +1 -0
  65. package/dist/core/hook-runner.d.ts +36 -0
  66. package/dist/core/hook-runner.d.ts.map +1 -0
  67. package/dist/core/hook-runner.js +93 -0
  68. package/dist/core/hook-runner.js.map +1 -0
  69. package/dist/core/hooks/defaults/post-execute.md +22 -0
  70. package/dist/core/hooks/defaults/pre-execute.md +18 -0
  71. package/dist/core/prompt-builder.d.ts +1 -0
  72. package/dist/core/prompt-builder.d.ts.map +1 -1
  73. package/dist/core/prompt-builder.js +60 -1
  74. package/dist/core/prompt-builder.js.map +1 -1
  75. package/dist/core/requirement-clarifier.d.ts +2 -1
  76. package/dist/core/requirement-clarifier.d.ts.map +1 -1
  77. package/dist/core/requirement-clarifier.js +78 -1
  78. package/dist/core/requirement-clarifier.js.map +1 -1
  79. package/dist/core/rule-loader.d.ts +38 -0
  80. package/dist/core/rule-loader.d.ts.map +1 -0
  81. package/dist/core/rule-loader.js +156 -0
  82. package/dist/core/rule-loader.js.map +1 -0
  83. package/dist/core/rules/defaults/_INDEX.md +16 -0
  84. package/dist/core/rules/defaults/api-design.md +44 -0
  85. package/dist/core/rules/defaults/database.md +37 -0
  86. package/dist/core/rules/defaults/frontend-common.md +38 -0
  87. package/dist/core/rules/defaults/nodejs.md +38 -0
  88. package/dist/core/rules/defaults/react.md +34 -0
  89. package/dist/core/rules/defaults/security.md +31 -0
  90. package/dist/core/rules/defaults/testing.md +35 -0
  91. package/dist/core/rules/defaults/typescript.md +36 -0
  92. package/dist/core/skill-loader.d.ts +28 -0
  93. package/dist/core/skill-loader.d.ts.map +1 -0
  94. package/dist/core/skill-loader.js +102 -0
  95. package/dist/core/skill-loader.js.map +1 -0
  96. package/dist/core/skills/defaults/caching.md +33 -0
  97. package/dist/core/skills/defaults/db-migration.md +46 -0
  98. package/dist/core/skills/defaults/deployment.md +50 -0
  99. package/dist/core/skills/defaults/logging.md +38 -0
  100. package/dist/core/verify-engine.d.ts +7 -0
  101. package/dist/core/verify-engine.d.ts.map +1 -1
  102. package/dist/core/verify-engine.js +27 -1
  103. package/dist/core/verify-engine.js.map +1 -1
  104. package/package.json +2 -2
@@ -0,0 +1,225 @@
1
+ "use strict";
2
+ /**
3
+ * AGENTS 引擎 — 执行器
4
+ *
5
+ * 负责:
6
+ * 1. 构建 Agent 专用 Prompt(角色定义 + 检查清单 + 输入上下文)
7
+ * 2. 执行 Agent 分析(生成 prompt 字符串,供外层 AI 调用)
8
+ * 3. 结果解析与聚合
9
+ *
10
+ * v6.84.0+
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.buildAgentPrompt = buildAgentPrompt;
14
+ exports.prepareAgentTask = prepareAgentTask;
15
+ exports.parseAgentResponse = parseAgentResponse;
16
+ exports.mergeAgentResults = mergeAgentResults;
17
+ /**
18
+ * 为指定 Agent 构建完整的分析 Prompt
19
+ *
20
+ * 将 Agent 的角色定义与当前上下文组合,生成可直接发给 AI 的 prompt 字符串
21
+ */
22
+ function buildAgentPrompt(agent, context) {
23
+ const sections = [];
24
+ // 1. 角色注入
25
+ sections.push(agent.rolePrompt);
26
+ sections.push('');
27
+ // 2. 输入上下文
28
+ sections.push('---');
29
+ sections.push('# 输入上下文');
30
+ sections.push('');
31
+ if (context.iteration) {
32
+ sections.push(`- 迭代: ${context.iteration}`);
33
+ }
34
+ if (context.platform) {
35
+ sections.push(`- 端: ${context.platform}`);
36
+ }
37
+ if (context.project?.industry) {
38
+ sections.push(`- 行业: ${context.project.industry}`);
39
+ }
40
+ sections.push('');
41
+ // 3. 任务特定输入
42
+ if (context.docContent) {
43
+ sections.push('## 需求文档内容');
44
+ sections.push('');
45
+ sections.push('```');
46
+ const content = String(context.docContent);
47
+ sections.push(content.slice(0, 8000));
48
+ if (content.length > 8000) {
49
+ sections.push('\n... (文档过长,已截断,请继续读取完整文档)');
50
+ }
51
+ sections.push('```');
52
+ sections.push('');
53
+ }
54
+ if (context.qualityIssues && Array.isArray(context.qualityIssues) && context.qualityIssues.length > 0) {
55
+ sections.push('## 已识别的质量问题');
56
+ sections.push('');
57
+ for (const issue of context.qualityIssues) {
58
+ sections.push(`- ${issue}`);
59
+ }
60
+ sections.push('');
61
+ }
62
+ if (context.codeContent) {
63
+ sections.push('## 代码内容');
64
+ sections.push('');
65
+ sections.push('```');
66
+ const code = String(context.codeContent);
67
+ sections.push(code.slice(0, 6000));
68
+ if (code.length > 6000) {
69
+ sections.push('\n... (代码过长,已截断)');
70
+ }
71
+ sections.push('```');
72
+ sections.push('');
73
+ }
74
+ // 4. 输出格式要求
75
+ if (agent.outputFormat) {
76
+ sections.push('---');
77
+ sections.push('# 输出要求');
78
+ sections.push('');
79
+ sections.push(agent.outputFormat);
80
+ sections.push('');
81
+ }
82
+ // 5. 通用输出格式(结构化)
83
+ sections.push('---');
84
+ sections.push('# 输出格式(必须严格遵守)');
85
+ sections.push('');
86
+ sections.push('请以以下结构输出分析结果:');
87
+ sections.push('');
88
+ sections.push('## 总体评估');
89
+ sections.push('通过 / 不通过');
90
+ sections.push('');
91
+ sections.push('## 发现的问题');
92
+ sections.push('对每个问题,按以下格式:');
93
+ sections.push('- [严重级别] [类别]: [问题描述] → [修改建议]');
94
+ sections.push('');
95
+ sections.push('## 改进建议');
96
+ sections.push('(可选)具体的修改方案');
97
+ sections.push('');
98
+ return sections.join('\n');
99
+ }
100
+ /**
101
+ * 模拟执行 Agent 任务
102
+ *
103
+ * 注意:此函数不直接调用 AI API,而是构建 prompt 并返回给外层调用者。
104
+ * 外层调用者(如 analyze.ts)将 prompt 发送给 AI,然后将 AI 的响应传回给 parseAgentResponse。
105
+ *
106
+ * 返回 { prompt: string, metadata: { agent, context } }
107
+ */
108
+ function prepareAgentTask(agent, context) {
109
+ const prompt = buildAgentPrompt(agent, context);
110
+ return {
111
+ prompt,
112
+ metadata: {
113
+ agentName: agent.name,
114
+ agentDefinition: agent,
115
+ context,
116
+ },
117
+ };
118
+ }
119
+ /**
120
+ * 解析 Agent 的 AI 响应为结构化结果
121
+ *
122
+ * 这是一个启发式解析器,从 AI 返回的 Markdown 文本中提取结构化信息。
123
+ */
124
+ function parseAgentResponse(agentName, response, duration = 0) {
125
+ const findings = [];
126
+ let passed = true;
127
+ // 1. 解析总体评估
128
+ const overallMatch = response.match(/##\s+总体评估\s*\n\s*(通过|不通过|PASS|FAIL|✅|❌)/i);
129
+ if (overallMatch) {
130
+ const verdict = overallMatch[1].toLowerCase();
131
+ passed = !verdict.includes('不') && !verdict.includes('fail') && !verdict.includes('❌');
132
+ }
133
+ // 2. 解析问题列表
134
+ // 格式: - [严重级别] [类别]: [问题描述] → [修改建议]
135
+ const issuePattern = /^\s*[-*]\s*\[?(critical|major|minor|info|严重|重要|一般|提示)\]?\s*\[?([^\]]+)\]?\s*[::]\s*(.+?)(?:→|->|\s-\s)(.+)$/gim;
136
+ let m;
137
+ while ((m = issuePattern.exec(response)) !== null) {
138
+ const severity = mapSeverity(m[1]);
139
+ findings.push({
140
+ severity,
141
+ category: m[2].trim(),
142
+ message: m[3].trim(),
143
+ suggestion: m[4].trim(),
144
+ });
145
+ if (severity === 'critical' || severity === 'major') {
146
+ passed = false;
147
+ }
148
+ }
149
+ // 3. 备用解析:简单列表项
150
+ if (findings.length === 0) {
151
+ const listPattern = /^\s*[-*]\s*(.+)$/gm;
152
+ while ((m = listPattern.exec(response)) !== null) {
153
+ const text = m[1].trim();
154
+ if (text.length < 5)
155
+ continue;
156
+ if (text.startsWith('[') && text.includes(']:'))
157
+ continue; // 跳过已解析的
158
+ // 尝试推断严重级别
159
+ let severity = 'info';
160
+ if (/critical|严重|致命|阻塞/i.test(text))
161
+ severity = 'critical';
162
+ else if (/major|重要|严重/i.test(text))
163
+ severity = 'major';
164
+ else if (/minor|一般|轻微/i.test(text))
165
+ severity = 'minor';
166
+ findings.push({
167
+ severity,
168
+ category: 'general',
169
+ message: text,
170
+ });
171
+ if (severity === 'critical' || severity === 'major') {
172
+ passed = false;
173
+ }
174
+ }
175
+ }
176
+ return {
177
+ agent: agentName,
178
+ passed,
179
+ findings,
180
+ duration,
181
+ output: response,
182
+ };
183
+ }
184
+ function mapSeverity(text) {
185
+ const lower = text.toLowerCase();
186
+ if (lower.includes('critical') || lower.includes('严重') || lower.includes('致命'))
187
+ return 'critical';
188
+ if (lower.includes('major') || lower.includes('重要'))
189
+ return 'major';
190
+ if (lower.includes('minor') || lower.includes('一般') || lower.includes('轻微'))
191
+ return 'minor';
192
+ return 'info';
193
+ }
194
+ /**
195
+ * 将多个 Agent 的结果聚合为统一报告
196
+ */
197
+ function mergeAgentResults(results) {
198
+ const allPassed = results.every(r => r.passed);
199
+ const totalFindings = results.reduce((s, r) => s + r.findings.length, 0);
200
+ const criticalCount = results.reduce((s, r) => s + r.findings.filter(f => f.severity === 'critical').length, 0);
201
+ const majorCount = results.reduce((s, r) => s + r.findings.filter(f => f.severity === 'major').length, 0);
202
+ let report = `# Multi-Agent 审查报告\n\n`;
203
+ report += `| Agent | 结果 | 发现数 | 耗时 |\n`;
204
+ report += `| :--- | :--- | :--- | :--- |\n`;
205
+ for (const r of results) {
206
+ const icon = r.passed ? '✅' : '❌';
207
+ report += `| ${r.agent} | ${icon} ${r.passed ? '通过' : '不通过'} | ${r.findings.length} | ${(r.duration / 1000).toFixed(1)}s |\n`;
208
+ }
209
+ report += '\n';
210
+ for (const r of results) {
211
+ if (r.findings.length === 0)
212
+ continue;
213
+ report += `## ${r.agent}\n\n`;
214
+ for (const f of r.findings) {
215
+ const icon = f.severity === 'critical' ? '🔴' : f.severity === 'major' ? '🟠' : f.severity === 'minor' ? '🟡' : '🔵';
216
+ report += `- ${icon} **[${f.severity.toUpperCase()}]** ${f.category}: ${f.message}\n`;
217
+ if (f.suggestion) {
218
+ report += ` → ${f.suggestion}\n`;
219
+ }
220
+ }
221
+ report += '\n';
222
+ }
223
+ return { allPassed, totalFindings, criticalCount, majorCount, report };
224
+ }
225
+ //# sourceMappingURL=agent-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-executor.js","sourceRoot":"","sources":["../../../../src/core/agents/engine/agent-executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * AGENTS 引擎 — 加载器
3
+ *
4
+ * 负责:
5
+ * 1. 扫描 .speccore/AGENTS/ 目录下的角色定义
6
+ * 2. 解析 Markdown 文件为 AgentDefinition
7
+ * 3. 解析 _INDEX.md 注册表
8
+ * 4. 根据 platform/industry 解析特化版本
9
+ * 5. 条件过滤和优先级排序
10
+ *
11
+ * v6.84.0+
12
+ */
13
+ import { AgentDefinition, AgentRegistry, AgentContext, ResolvedAgent } from './types';
14
+ /**
15
+ * 根据 platform/industry 解析特化版本的 Agent 名称
16
+ *
17
+ * 优先级:platform-specific > industry-specific > generic
18
+ */
19
+ export declare function resolveAgentName(baseAgent: string, context: AgentContext, availableAgents: Set<string>): string;
20
+ /**
21
+ * 加载所有可用的 Agent 定义
22
+ * 优先读取用户自定义,回退到内置默认
23
+ */
24
+ export declare function loadAllAgents(projectRoot: string): Promise<Map<string, AgentDefinition>>;
25
+ /**
26
+ * 加载注册表
27
+ * 优先读取用户自定义,回退到内置默认
28
+ */
29
+ export declare function loadRegistry(projectRoot: string): Promise<AgentRegistry>;
30
+ /**
31
+ * 获取指定命令/阶段下需要激活的 Agent 列表
32
+ * 返回按优先级排序的 ResolvedAgent 数组
33
+ *
34
+ * 混合模式:
35
+ * 1. 注册表中的核心角色(显式配置,优先)
36
+ * 2. 用户自定义角色的自描述激活规则(扩展)
37
+ */
38
+ export declare function resolveAgentsForPhase(command: string, phase: string, context: AgentContext, projectRoot: string): Promise<ResolvedAgent[]>;
39
+ /**
40
+ * 获取单个 Agent 的定义
41
+ */
42
+ export declare function loadAgentDefinition(agentName: string, projectRoot: string): Promise<AgentDefinition | undefined>;
43
+ /**
44
+ * 获取内置 Agent 的原始 Markdown 内容(用于 init 时复制到项目)
45
+ */
46
+ export declare function getBuiltinAgentContents(): Promise<{
47
+ name: string;
48
+ content: string;
49
+ }[]>;
50
+ /**
51
+ * 获取内置注册表内容(用于 init 时复制到项目)
52
+ */
53
+ export declare function getBuiltinRegistryContent(): Promise<string | undefined>;
54
+ /**
55
+ * 获取内置模板内容(用于 init 时复制到项目)
56
+ */
57
+ export declare function getBuiltinTemplateContent(): Promise<string | undefined>;
58
+ //# sourceMappingURL=agent-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-loader.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/engine/agent-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EACL,eAAe,EAEf,aAAa,EAEb,YAAY,EACZ,aAAa,EACd,MAAM,SAAS,CAAC;AAiOjB;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,YAAY,EACrB,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,GAC3B,MAAM,CAkBR;AAMD;;;GAGG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAmB9F;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAa9E;AAED;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,YAAY,EACrB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,aAAa,EAAE,CAAC,CAoD1B;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAGtC;AAED;;GAEG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CAG5F;AAED;;GAEG;AACH,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAM7E;AAED;;GAEG;AACH,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAM7E"}
@@ -0,0 +1,377 @@
1
+ "use strict";
2
+ /**
3
+ * AGENTS 引擎 — 加载器
4
+ *
5
+ * 负责:
6
+ * 1. 扫描 .speccore/AGENTS/ 目录下的角色定义
7
+ * 2. 解析 Markdown 文件为 AgentDefinition
8
+ * 3. 解析 _INDEX.md 注册表
9
+ * 4. 根据 platform/industry 解析特化版本
10
+ * 5. 条件过滤和优先级排序
11
+ *
12
+ * v6.84.0+
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.resolveAgentName = resolveAgentName;
16
+ exports.loadAllAgents = loadAllAgents;
17
+ exports.loadRegistry = loadRegistry;
18
+ exports.resolveAgentsForPhase = resolveAgentsForPhase;
19
+ exports.loadAgentDefinition = loadAgentDefinition;
20
+ exports.getBuiltinAgentContents = getBuiltinAgentContents;
21
+ exports.getBuiltinRegistryContent = getBuiltinRegistryContent;
22
+ exports.getBuiltinTemplateContent = getBuiltinTemplateContent;
23
+ const path_1 = require("path");
24
+ const fs_extra_1 = require("fs-extra");
25
+ const BUILTIN_AGENTS_DIR = (0, path_1.join)(__dirname, '..', 'defaults');
26
+ // ============================================================
27
+ // 1. Markdown 解析
28
+ // ============================================================
29
+ function parseAgentMarkdown(content, source) {
30
+ const name = extractHeading(content) || 'unknown';
31
+ const description = extractSection(content, '职责') || extractSection(content, 'Description') || '';
32
+ const responsibilities = extractListItems(content, '职责') || extractListItems(content, 'Responsibilities') || [];
33
+ const inputSpec = extractSection(content, '输入') || extractSection(content, 'Input') || '';
34
+ const checkList = extractCheckboxItems(content) || [];
35
+ const outputFormat = extractSection(content, '输出格式') || extractSection(content, 'Output Format') || '';
36
+ const activations = parseSelfDescribedActivations(content);
37
+ // rolePrompt = 整个文档内容(作为 AI 的 system prompt 注入)
38
+ const rolePrompt = content;
39
+ return {
40
+ name,
41
+ description,
42
+ responsibilities,
43
+ inputSpec,
44
+ checkList,
45
+ outputFormat,
46
+ rolePrompt,
47
+ source,
48
+ activations,
49
+ };
50
+ }
51
+ /**
52
+ * 解析 Agent 自描述激活规则
53
+ * 从 Markdown 中的 "## 激活规则" 或 "## Activations" 部分提取
54
+ *
55
+ * 支持格式:
56
+ * | 命令 | 阶段 | 优先级 | 条件 |
57
+ * | :--- | :--- | :--- | :--- |
58
+ * | analyze | clarify | 60 | project.industry == 'finance' |
59
+ */
60
+ function parseSelfDescribedActivations(content) {
61
+ const section = extractSection(content, '激活规则') || extractSection(content, 'Activations');
62
+ if (!section)
63
+ return [];
64
+ const activations = [];
65
+ const lines = section.split('\n').filter(l => l.trim().startsWith('|') && !l.trim().match(/^\|[\s-:]+\|/));
66
+ for (const line of lines) {
67
+ const cells = line.split('|').map(c => c.trim()).filter(Boolean);
68
+ if (cells.length >= 3) {
69
+ activations.push({
70
+ command: cells[0],
71
+ phase: cells[1],
72
+ priority: parseInt(cells[2], 10) || 50,
73
+ condition: cells[3] && cells[3] !== '—' && cells[3] !== '-' ? cells[3] : undefined,
74
+ });
75
+ }
76
+ }
77
+ return activations;
78
+ }
79
+ function extractHeading(content) {
80
+ const m = content.match(/^#\s+Agent:\s*(.+)$/m);
81
+ return m?.[1].trim();
82
+ }
83
+ function extractSection(content, sectionName) {
84
+ const regex = new RegExp(`^##\\s+${sectionName}\\s*\\n(.*?)(?=\\n##\\s|$)`, 'ms');
85
+ const m = content.match(regex);
86
+ return m?.[1].trim();
87
+ }
88
+ function extractListItems(content, sectionName) {
89
+ const section = extractSection(content, sectionName);
90
+ if (!section)
91
+ return undefined;
92
+ const items = [];
93
+ for (const line of section.split('\n')) {
94
+ const m = line.match(/^\s*[-*]\s+(.+)$/);
95
+ if (m)
96
+ items.push(m[1].trim());
97
+ }
98
+ return items.length > 0 ? items : undefined;
99
+ }
100
+ function extractCheckboxItems(content) {
101
+ const items = [];
102
+ const matches = content.match(/^\s*-\s*\[[ x]\]\s*(.+)$/gm);
103
+ if (matches) {
104
+ for (const m of matches) {
105
+ const item = m.replace(/^\s*-\s*\[[ x]\]\s*/, '').trim();
106
+ if (item)
107
+ items.push(item);
108
+ }
109
+ }
110
+ return items.length > 0 ? items : undefined;
111
+ }
112
+ // ============================================================
113
+ // 2. 注册表解析
114
+ // ============================================================
115
+ function parseRegistryMarkdown(content) {
116
+ const phases = {};
117
+ const phaseMatches = content.matchAll(/^##\s+(.+?)\s*\/\s*(.+?)\s*\n([\s\S]*?)(?=\n##\s|$)/gm);
118
+ for (const match of phaseMatches) {
119
+ const command = match[1].trim();
120
+ const phase = match[2].trim();
121
+ const phaseKey = `${command}/${phase}`;
122
+ const tableContent = match[3];
123
+ phases[phaseKey] = parseRegistryTable(tableContent);
124
+ }
125
+ return { phases };
126
+ }
127
+ function parseRegistryTable(content) {
128
+ const entries = [];
129
+ const lines = content.split('\n').filter(l => l.trim().startsWith('|') && !l.trim().match(/^\|[\s-:]+\|/));
130
+ for (const line of lines) {
131
+ const cells = line.split('|').map(c => c.trim()).filter(Boolean);
132
+ if (cells.length >= 2) {
133
+ entries.push({
134
+ agent: cells[0],
135
+ priority: parseInt(cells[1], 10) || 50,
136
+ condition: cells[2] && cells[2] !== '—' && cells[2] !== '-' ? cells[2] : undefined,
137
+ description: cells[3],
138
+ });
139
+ }
140
+ }
141
+ return entries;
142
+ }
143
+ // ============================================================
144
+ // 3. 条件表达式求值(简单实现)
145
+ // ============================================================
146
+ function evaluateCondition(condition, context) {
147
+ if (!condition)
148
+ return true;
149
+ try {
150
+ // 支持的格式:
151
+ // project.industry == 'finance'
152
+ // project.securityLevel > 2
153
+ // platform == 'backend'
154
+ const eqMatch = condition.match(/^(.+?)\s*==\s*['"](.+?)['"]$/);
155
+ if (eqMatch) {
156
+ const path = eqMatch[1].trim();
157
+ const expected = eqMatch[2];
158
+ const actual = getContextValue(context, path);
159
+ return String(actual) === expected;
160
+ }
161
+ const gtMatch = condition.match(/^(.+?)\s*>\s*(\d+)$/);
162
+ if (gtMatch) {
163
+ const path = gtMatch[1].trim();
164
+ const expected = parseInt(gtMatch[2], 10);
165
+ const actual = getContextValue(context, path);
166
+ return Number(actual) > expected;
167
+ }
168
+ const gteMatch = condition.match(/^(.+?)\s*>=\s*(\d+)$/);
169
+ if (gteMatch) {
170
+ const path = gteMatch[1].trim();
171
+ const expected = parseInt(gteMatch[2], 10);
172
+ const actual = getContextValue(context, path);
173
+ return Number(actual) >= expected;
174
+ }
175
+ // 简单布尔:存在即真
176
+ const path = condition.trim();
177
+ const actual = getContextValue(context, path);
178
+ return actual !== undefined && actual !== null && actual !== false;
179
+ }
180
+ catch {
181
+ return true; // 条件解析失败,默认通过
182
+ }
183
+ }
184
+ function getContextValue(context, path) {
185
+ const parts = path.split('.');
186
+ let current = context;
187
+ for (const part of parts) {
188
+ if (current === null || current === undefined)
189
+ return undefined;
190
+ current = current[part];
191
+ }
192
+ return current;
193
+ }
194
+ // ============================================================
195
+ // 4. Agent 扫描与加载
196
+ // ============================================================
197
+ /**
198
+ * 扫描指定目录下的所有 Agent 定义文件
199
+ */
200
+ async function scanAgentFiles(dir) {
201
+ if (!(await (0, fs_extra_1.pathExists)(dir)))
202
+ return [];
203
+ const entries = await (0, fs_extra_1.readdir)(dir, { withFileTypes: true });
204
+ const agents = [];
205
+ for (const e of entries) {
206
+ if (!e.isFile() || !e.name.endsWith('.md'))
207
+ continue;
208
+ if (e.name.startsWith('_'))
209
+ continue; // _INDEX.md, _TEMPLATE.md 跳过
210
+ const content = await (0, fs_extra_1.readFile)((0, path_1.join)(dir, e.name), 'utf-8');
211
+ agents.push({
212
+ name: e.name.replace(/\.md$/, ''),
213
+ content,
214
+ source: dir === BUILTIN_AGENTS_DIR ? 'builtin' : 'user-defined',
215
+ });
216
+ }
217
+ return agents;
218
+ }
219
+ // ============================================================
220
+ // 5. 特化版本解析
221
+ // ============================================================
222
+ /**
223
+ * 根据 platform/industry 解析特化版本的 Agent 名称
224
+ *
225
+ * 优先级:platform-specific > industry-specific > generic
226
+ */
227
+ function resolveAgentName(baseAgent, context, availableAgents) {
228
+ const platform = context.platform;
229
+ const industry = context.project?.industry;
230
+ // 1. 尝试 platform-specific: product-analyst-backend
231
+ if (platform) {
232
+ const platformSpecific = `${baseAgent}-${platform}`;
233
+ if (availableAgents.has(platformSpecific))
234
+ return platformSpecific;
235
+ }
236
+ // 2. 尝试 industry-specific: security-reviewer-finance
237
+ if (industry) {
238
+ const industrySpecific = `${baseAgent}-${industry}`;
239
+ if (availableAgents.has(industrySpecific))
240
+ return industrySpecific;
241
+ }
242
+ // 3. 回退到通用版
243
+ return baseAgent;
244
+ }
245
+ // ============================================================
246
+ // 6. 主 API
247
+ // ============================================================
248
+ /**
249
+ * 加载所有可用的 Agent 定义
250
+ * 优先读取用户自定义,回退到内置默认
251
+ */
252
+ async function loadAllAgents(projectRoot) {
253
+ const agents = new Map();
254
+ const userAgentsDir = (0, path_1.join)(projectRoot, '.speccore', 'AGENTS');
255
+ // 1. 先加载内置默认
256
+ const builtinFiles = await scanAgentFiles(BUILTIN_AGENTS_DIR);
257
+ for (const f of builtinFiles) {
258
+ const def = parseAgentMarkdown(f.content, 'builtin');
259
+ agents.set(f.name, def);
260
+ }
261
+ // 2. 用户自定义覆盖(同名覆盖)
262
+ const userFiles = await scanAgentFiles(userAgentsDir);
263
+ for (const f of userFiles) {
264
+ const def = parseAgentMarkdown(f.content, 'user-defined');
265
+ agents.set(f.name, def);
266
+ }
267
+ return agents;
268
+ }
269
+ /**
270
+ * 加载注册表
271
+ * 优先读取用户自定义,回退到内置默认
272
+ */
273
+ async function loadRegistry(projectRoot) {
274
+ const userIndex = (0, path_1.join)(projectRoot, '.speccore', 'AGENTS', '_INDEX.md');
275
+ const builtinIndex = (0, path_1.join)(BUILTIN_AGENTS_DIR, '_INDEX.md');
276
+ let content = '';
277
+ if (await (0, fs_extra_1.pathExists)(userIndex)) {
278
+ content = await (0, fs_extra_1.readFile)(userIndex, 'utf-8');
279
+ }
280
+ else if (await (0, fs_extra_1.pathExists)(builtinIndex)) {
281
+ content = await (0, fs_extra_1.readFile)(builtinIndex, 'utf-8');
282
+ }
283
+ if (!content)
284
+ return { phases: {} };
285
+ return parseRegistryMarkdown(content);
286
+ }
287
+ /**
288
+ * 获取指定命令/阶段下需要激活的 Agent 列表
289
+ * 返回按优先级排序的 ResolvedAgent 数组
290
+ *
291
+ * 混合模式:
292
+ * 1. 注册表中的核心角色(显式配置,优先)
293
+ * 2. 用户自定义角色的自描述激活规则(扩展)
294
+ */
295
+ async function resolveAgentsForPhase(command, phase, context, projectRoot) {
296
+ const phaseKey = `${command}/${phase}`;
297
+ // 1. 加载注册表和 Agent 定义
298
+ const registry = await loadRegistry(projectRoot);
299
+ const allAgents = await loadAllAgents(projectRoot);
300
+ const availableNames = new Set(allAgents.keys());
301
+ // 2. 收集注册表中的角色
302
+ const registryEntries = registry.phases[phaseKey] || [];
303
+ const resolvedMap = new Map();
304
+ for (const entry of registryEntries) {
305
+ if (!evaluateCondition(entry.condition, context))
306
+ continue;
307
+ const resolvedName = resolveAgentName(entry.agent, context, availableNames);
308
+ const def = allAgents.get(resolvedName);
309
+ if (!def)
310
+ continue;
311
+ resolvedMap.set(resolvedName, {
312
+ name: resolvedName,
313
+ definition: def,
314
+ priority: entry.priority,
315
+ });
316
+ }
317
+ // 3. 扫描用户自定义角色的自描述激活规则(扩展角色)
318
+ for (const [agentName, def] of allAgents) {
319
+ // 只扫描用户自定义的角色(内置角色不扫描自描述规则)
320
+ if (def.source !== 'user-defined')
321
+ continue;
322
+ // 已在注册表中的跳过(注册表优先)
323
+ if (resolvedMap.has(agentName))
324
+ continue;
325
+ for (const act of def.activations) {
326
+ if (act.command === command && act.phase === phase) {
327
+ if (evaluateCondition(act.condition, context)) {
328
+ resolvedMap.set(agentName, {
329
+ name: agentName,
330
+ definition: def,
331
+ priority: act.priority,
332
+ });
333
+ }
334
+ break; // 匹配到一个就够了
335
+ }
336
+ }
337
+ }
338
+ // 4. 按优先级排序(高优先级在前)
339
+ const resolved = Array.from(resolvedMap.values());
340
+ resolved.sort((a, b) => b.priority - a.priority);
341
+ return resolved;
342
+ }
343
+ /**
344
+ * 获取单个 Agent 的定义
345
+ */
346
+ async function loadAgentDefinition(agentName, projectRoot) {
347
+ const allAgents = await loadAllAgents(projectRoot);
348
+ return allAgents.get(agentName);
349
+ }
350
+ /**
351
+ * 获取内置 Agent 的原始 Markdown 内容(用于 init 时复制到项目)
352
+ */
353
+ async function getBuiltinAgentContents() {
354
+ const files = await scanAgentFiles(BUILTIN_AGENTS_DIR);
355
+ return files.map(f => ({ name: f.name, content: f.content }));
356
+ }
357
+ /**
358
+ * 获取内置注册表内容(用于 init 时复制到项目)
359
+ */
360
+ async function getBuiltinRegistryContent() {
361
+ const path = (0, path_1.join)(BUILTIN_AGENTS_DIR, '_INDEX.md');
362
+ if (await (0, fs_extra_1.pathExists)(path)) {
363
+ return (0, fs_extra_1.readFile)(path, 'utf-8');
364
+ }
365
+ return undefined;
366
+ }
367
+ /**
368
+ * 获取内置模板内容(用于 init 时复制到项目)
369
+ */
370
+ async function getBuiltinTemplateContent() {
371
+ const path = (0, path_1.join)(BUILTIN_AGENTS_DIR, '_TEMPLATE.md');
372
+ if (await (0, fs_extra_1.pathExists)(path)) {
373
+ return (0, fs_extra_1.readFile)(path, 'utf-8');
374
+ }
375
+ return undefined;
376
+ }
377
+ //# sourceMappingURL=agent-loader.js.map