@mycodemap/mycodemap 0.1.0 → 0.1.1

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 (64) hide show
  1. package/CHANGELOG.md +86 -6
  2. package/README.md +172 -80
  3. package/dist/cli/commands/cycles.d.ts.map +1 -1
  4. package/dist/cli/commands/cycles.js +2 -0
  5. package/dist/cli/commands/cycles.js.map +1 -1
  6. package/dist/cli/commands/init.d.ts.map +1 -1
  7. package/dist/cli/commands/init.js +3 -1
  8. package/dist/cli/commands/init.js.map +1 -1
  9. package/dist/cli/commands/logs.d.ts +5 -0
  10. package/dist/cli/commands/logs.d.ts.map +1 -0
  11. package/dist/cli/commands/logs.js +189 -0
  12. package/dist/cli/commands/logs.js.map +1 -0
  13. package/dist/cli/commands/report.d.ts +12 -0
  14. package/dist/cli/commands/report.d.ts.map +1 -0
  15. package/dist/cli/commands/report.js +158 -0
  16. package/dist/cli/commands/report.js.map +1 -0
  17. package/dist/cli/commands/watch-foreground.d.ts.map +1 -1
  18. package/dist/cli/commands/watch-foreground.js +2 -0
  19. package/dist/cli/commands/watch-foreground.js.map +1 -1
  20. package/dist/cli/commands/watch.d.ts.map +1 -1
  21. package/dist/cli/commands/watch.js +2 -0
  22. package/dist/cli/commands/watch.js.map +1 -1
  23. package/dist/cli/first-run-guide.d.ts +23 -0
  24. package/dist/cli/first-run-guide.d.ts.map +1 -0
  25. package/dist/cli/first-run-guide.js +83 -0
  26. package/dist/cli/first-run-guide.js.map +1 -0
  27. package/dist/cli/index.js +63 -0
  28. package/dist/cli/index.js.map +1 -1
  29. package/dist/cli/platform-check.d.ts +21 -0
  30. package/dist/cli/platform-check.d.ts.map +1 -0
  31. package/dist/cli/platform-check.js +94 -0
  32. package/dist/cli/platform-check.js.map +1 -0
  33. package/dist/cli/tree-sitter-check.d.ts +35 -0
  34. package/dist/cli/tree-sitter-check.d.ts.map +1 -0
  35. package/dist/cli/tree-sitter-check.js +133 -0
  36. package/dist/cli/tree-sitter-check.js.map +1 -0
  37. package/dist/cli/utils/sanitize.d.ts +54 -0
  38. package/dist/cli/utils/sanitize.d.ts.map +1 -0
  39. package/dist/cli/utils/sanitize.js +131 -0
  40. package/dist/cli/utils/sanitize.js.map +1 -0
  41. package/docs/AI_ASSISTANT_SETUP.md +743 -0
  42. package/docs/CI_GATEWAY_DESIGN.md +784 -0
  43. package/docs/OMC_TEAM_DEBUG_REPORT.md +285 -0
  44. package/docs/PUBLISH_NPM_DESIGN_FINAL.md +485 -0
  45. package/docs/REFACTOR_ARCHITECTURE_OVERVIEW.md +552 -0
  46. package/docs/REFACTOR_CONFIDENCE_DESIGN.md +244 -0
  47. package/docs/REFACTOR_GIT_ANALYZER_DESIGN.md +785 -0
  48. package/docs/REFACTOR_ORCHESTRATOR_DESIGN.md +1065 -0
  49. package/docs/REFACTOR_REQUIREMENTS.md +970 -0
  50. package/docs/REFACTOR_RESULT_FUSION_DESIGN.md +315 -0
  51. package/docs/REFACTOR_TEST_LINKER_DESIGN.md +311 -0
  52. package/docs/SETUP_GUIDE.md +407 -0
  53. package/docs/archive/AI_INTEGRATION_GUIDE_ARCHIVED.md +385 -0
  54. package/docs/archive/PUBLISH_NPM_DESIGN_V1.md +1693 -0
  55. package/docs/archive/PUBLISH_NPM_DESIGN_V2.md +390 -0
  56. package/docs/archive/TASK_DESIGN_COVERAGE_REPORT.md +314 -0
  57. package/docs/plans/POST_TASK_PLAN.md +129 -0
  58. package/docs/plans/archive/2026-03-03-deps-path-extension-fix.md +186 -0
  59. package/examples/README.md +61 -0
  60. package/examples/claude/codemap-skill.md +94 -0
  61. package/examples/codex/codemap-agent.md +66 -0
  62. package/examples/copilot/copilot-instructions.md +24 -0
  63. package/examples/kimi/codemap-skill.md +92 -0
  64. package/package.json +5 -3
@@ -0,0 +1,315 @@
1
+ # 多工具结果融合详细设计
2
+
3
+ > 版本: 2.6
4
+ > 所属模块: 编排层 - 结果融合
5
+ > 更新日期: 2026-03-03
6
+
7
+ ---
8
+
9
+ ## 1. 设计目标
10
+
11
+ 所有工具的结果都转换为统一的中间格式,然后按统一规则处理(加权合并、去重、排序)。
12
+
13
+ ---
14
+
15
+ ## 2. 数据结构设计
16
+
17
+ ### 2.1 统一结果格式
18
+
19
+ ```typescript
20
+ // src/orchestrator/types.ts
21
+
22
+ interface UnifiedResult {
23
+ // 唯一标识
24
+ id: string;
25
+
26
+ // 来源信息
27
+ source: 'codemap' | 'ast-grep' | 'rg-internal';
28
+ toolScore: number; // 工具返回的原始分数
29
+
30
+ // 内容信息
31
+ type: 'file' | 'symbol' | 'code' | 'documentation';
32
+ file: string;
33
+ line?: number;
34
+ content: string; // 截断后的内容
35
+ preview?: string; // 上下文预览
36
+
37
+ // 语义信息
38
+ relevance: number; // 0-1 归一化相关度
39
+ keywords: string[]; // 匹配的关键词
40
+
41
+ // 元数据
42
+ metadata?: {
43
+ symbolType?: 'class' | 'function' | 'interface' | 'variable';
44
+ dependencies?: string[];
45
+ testFile?: string;
46
+ commitCount?: number;
47
+ };
48
+ }
49
+ ```
50
+
51
+ ---
52
+
53
+ ## 3. 接口设计
54
+
55
+ ### 3.1 结果融合类
56
+
57
+ ```typescript
58
+ // src/orchestrator/result-fusion.ts
59
+
60
+ class ResultFusion {
61
+ /**
62
+ * 多工具结果融合
63
+ * 策略:加权合并 → 去重 → 排序
64
+ */
65
+ fuse(
66
+ resultsByTool: Map<string, UnifiedResult[]>,
67
+ options: { topK: number; keywordWeights: Record<string, number> }
68
+ ): UnifiedResult[] {
69
+ // 1. 加权合并
70
+ let allResults: UnifiedResult[] = [];
71
+ for (const [tool, results] of resultsByTool) {
72
+ const toolWeight = this.getToolWeight(tool);
73
+ const weighted = results.map(r => ({
74
+ ...r,
75
+ relevance: r.relevance * toolWeight
76
+ }));
77
+ allResults = allResults.concat(weighted);
78
+ }
79
+
80
+ // 2. 去重(基于文件+行号)
81
+ const seen = new Map<string, UnifiedResult>();
82
+ for (const result of allResults) {
83
+ const key = `${result.file}:${result.line || ''}`;
84
+ if (!seen.has(key)) {
85
+ seen.set(key, result);
86
+ } else {
87
+ // 保留分数更高的
88
+ const existing = seen.get(key)!;
89
+ if (result.relevance > existing.relevance) {
90
+ seen.set(key, result);
91
+ }
92
+ }
93
+ }
94
+
95
+ // 3. 按相关度排序
96
+ const sorted = Array.from(seen.values())
97
+ .sort((a, b) => b.relevance - a.relevance);
98
+
99
+ // 4. 关键词加权
100
+ const keywordBoosted = this.applyKeywordBoost(sorted, options.keywordWeights);
101
+
102
+ return keywordBoosted.slice(0, options.topK);
103
+ }
104
+
105
+ private getToolWeight(tool: string): number {
106
+ const weights: Record<string, number> = {
107
+ 'ast-grep': 1.0, // AST 分析最准确
108
+ 'codemap': 0.9, // 结构分析次之
109
+ 'rg-internal': 0.7 // 文本搜索兜底(仅内部调试用)
110
+ };
111
+ return weights[tool] || 0.5;
112
+ }
113
+
114
+ /**
115
+ * 应用关键词加权
116
+ */
117
+ private applyKeywordBoost(
118
+ results: UnifiedResult[],
119
+ keywordWeights: Record<string, number>
120
+ ): UnifiedResult[] {
121
+ if (Object.keys(keywordWeights).length === 0) {
122
+ return results;
123
+ }
124
+
125
+ return results.map(r => {
126
+ let boost = 0;
127
+ for (const keyword of r.keywords) {
128
+ boost += keywordWeights[keyword] || 0;
129
+ }
130
+ return {
131
+ ...r,
132
+ relevance: r.relevance + boost
133
+ };
134
+ }).sort((a, b) => b.relevance - a.relevance);
135
+ }
136
+ }
137
+ ```
138
+
139
+ ---
140
+
141
+ ## 4. Token 截断
142
+
143
+ ### 4.1 按 token 数量截断内容
144
+
145
+ ```typescript
146
+ /**
147
+ * 按 token 数量截断内容(而非字符数)
148
+ * 简单估算:英文约 4 字符 = 1 token,中文约 1 字符 = 1-2 token
149
+ */
150
+ function truncateByToken(content: string, maxTokens: number): string {
151
+ const tokens = content.split(/[\s\u4e00-\u9fa5]/).filter(Boolean);
152
+ if (tokens.length <= maxTokens) return content;
153
+ return tokens.slice(0, maxTokens).join(' ') + '...';
154
+ }
155
+ ```
156
+
157
+ ---
158
+
159
+ ## 5. 模块依赖
160
+
161
+ ```
162
+ 结果融合模块 (result-fusion.ts)
163
+
164
+ ├── 依赖类型: UnifiedResult (输入/输出)
165
+
166
+ └── 被以下模块使用:
167
+ └── ToolOrchestrator (tool-orchestrator.ts)
168
+ └── AnalyzeCommand (analyze.ts)
169
+ └── CIGateway (ci-gateway.ts)
170
+ └── WorkflowOrchestrator (workflow-orchestrator.ts) (v2.5)
171
+ ```
172
+
173
+ ---
174
+
175
+ ## 6. 工作流上下文融合 (v2.5)
176
+
177
+ ### 6.1 跨阶段结果传递
178
+
179
+ 在工作流中,每个阶段的分析结果需要传递给下一阶段:
180
+
181
+ ```typescript
182
+ // 工作流上下文中的结果缓存
183
+
184
+ interface WorkflowFusionContext {
185
+ phaseResults: Map<WorkflowPhase, UnifiedResult[]>;
186
+ accumulatedContext: Map<string, UnifiedResult>;
187
+ }
188
+
189
+ // 跨阶段结果合并策略
190
+ class WorkflowResultFusion {
191
+ /**
192
+ * 将新阶段结果与已有上下文合并
193
+ */
194
+ mergeWithContext(
195
+ newResults: UnifiedResult[],
196
+ context: WorkflowFusionContext
197
+ ): UnifiedResult[] {
198
+ // 1. 合并所有历史结果
199
+ const allResults = [
200
+ ...Array.from(context.phaseResults.values()).flat(),
201
+ ...newResults
202
+ ];
203
+
204
+ // 2. 应用工作流特定的加权
205
+ const workflowWeighted = this.applyWorkflowWeights(allResults, context);
206
+
207
+ // 3. 按工作流阶段优先级排序
208
+ return this.sortByWorkflowPriority(workflowWeighted);
209
+ }
210
+
211
+ /**
212
+ * 工作流阶段权重
213
+ * 越近期的阶段权重越高
214
+ */
215
+ private applyWorkflowWeights(
216
+ results: UnifiedResult[],
217
+ context: WorkflowFusionContext
218
+ ): UnifiedResult[] {
219
+ const phaseWeights: Record<WorkflowPhase, number> = {
220
+ 'reference': 0.8,
221
+ 'impact': 0.9,
222
+ 'risk': 1.0,
223
+ 'implementation': 0.7,
224
+ 'commit': 0.6,
225
+ 'ci': 0.5
226
+ };
227
+
228
+ return results.map(r => {
229
+ // 根据结果来源确定阶段权重
230
+ const sourcePhase = this.inferPhase(r.source);
231
+ const weight = phaseWeights[sourcePhase] || 0.5;
232
+
233
+ return {
234
+ ...r,
235
+ relevance: r.relevance * weight
236
+ };
237
+ });
238
+ }
239
+ }
240
+ ```
241
+
242
+ ### 6.2 阶段间结果继承
243
+
244
+ ```typescript
245
+ // 阶段间的结果继承逻辑
246
+
247
+ class PhaseInheritance {
248
+ /**
249
+ * 获取下一阶段应该继承的结果
250
+ */
251
+ getInheritedResults(
252
+ currentPhase: WorkflowPhase,
253
+ allResults: UnifiedResult[]
254
+ ): UnifiedResult[] {
255
+ switch (currentPhase) {
256
+ case 'reference':
257
+ // 影响分析继承参考搜索的结果
258
+ return allResults.filter(r =>
259
+ r.source === 'ast-grep' || r.source === 'codemap'
260
+ );
261
+
262
+ case 'impact':
263
+ // 风险评估继承影响分析 + 参考搜索
264
+ return allResults;
265
+
266
+ case 'risk':
267
+ // 代码实现继承所有分析结果
268
+ return allResults;
269
+
270
+ default:
271
+ return allResults;
272
+ }
273
+ }
274
+ }
275
+ ```
276
+
277
+ ---
278
+
279
+ ## 7. 融合策略总结
280
+
281
+ | 阶段 | 策略 | 说明 |
282
+ |------|------|------|
283
+ | 1 | 加权合并 | 按工具权重调整 relevance |
284
+ | 2 | 去重 | 基于 file:line 作为 key |
285
+ | 3 | 排序 | 按 relevance 降序 |
286
+ | 4 | 关键词加权 | 提升匹配关键词的结果 |
287
+ | 5 | 截断 | Top-K + Token 限制 |
288
+
289
+ **示例输出**:
290
+ ```
291
+ [SEARCH RESULTS] - Sorted by Relevance
292
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
293
+
294
+ 1. src/auth/jwt.ts (relevance: 92%)
295
+ Type: function | Line: 45
296
+ Content: export function verifyToken(token: string): Payload {...}
297
+
298
+ 2. src/cache/lru-cache.ts (relevance: 85%)
299
+ Type: class | Line: 12
300
+ Content: export class LRUCache<K, V> {...}
301
+
302
+ 3. src/utils/date.ts (relevance: 45%)
303
+ Type: function | Line: 8
304
+ Content: export function formatDate(d: Date): string {...}
305
+ ```
306
+
307
+ ---
308
+
309
+ ## 附录:版本历史
310
+
311
+ | 版本 | 日期 | 变更 |
312
+ |------|------|------|
313
+ | 2.4 | 2026-02-28 | 添加 AI 饲料融合、风险加权 |
314
+ | 2.5 | 2026-03-01 | 添加工作流上下文融合 |
315
+ | 2.6 | 2026-03-03 | 移除 AI 饲料相关功能,简化融合策略 |
@@ -0,0 +1,311 @@
1
+ # 测试关联器详细设计
2
+
3
+ > 版本: 2.4
4
+ > 所属模块: 编排层 - 测试关联器
5
+
6
+ ---
7
+
8
+ ## 1. 功能定位
9
+
10
+ 在影响分析场景中,根据源代码文件自动关联相关的测试文件。
11
+
12
+ ---
13
+
14
+ ## 2. 数据结构设计
15
+
16
+ ### 2.1 测试配置
17
+
18
+ ```typescript
19
+ // src/orchestrator/test-linker.ts
20
+
21
+ interface TestConfig {
22
+ framework: 'jest' | 'vitest' | 'none';
23
+ patterns: {
24
+ testFile: string[]; // 测试文件匹配模式
25
+ testDir: string[]; // 测试目录
26
+ };
27
+ sourceToTestMap: Map<string, string[]>; // 源文件 → 测试文件映射
28
+ }
29
+ ```
30
+
31
+ ---
32
+
33
+ ## 3. 接口设计
34
+
35
+ ### 3.1 测试关联器类
36
+
37
+ ```typescript
38
+ class TestLinker {
39
+ private config: TestConfig | null = null;
40
+
41
+ /**
42
+ * 加载测试配置
43
+ * 读取 jest.config.js / vitest.config.ts
44
+ */
45
+ async loadConfig(projectRoot: string): Promise<TestConfig> {
46
+ const fsPromises = require('fs').promises;
47
+
48
+ // 1. 尝试读取 vitest.config.ts
49
+ const vitestPath = path.join(projectRoot, 'vitest.config.ts');
50
+ if (await this.pathExists(vitestPath)) {
51
+ return this.parseVitestConfig(vitestPath);
52
+ }
53
+
54
+ // 2. 尝试读取 jest.config.js
55
+ const jestPath = path.join(projectRoot, 'jest.config.js');
56
+ if (await this.pathExists(jestPath)) {
57
+ return this.parseJestConfig(jestPath);
58
+ }
59
+
60
+ // 3. 使用默认模式
61
+ const defaultConfig: TestConfig = {
62
+ framework: 'vitest',
63
+ patterns: {
64
+ testFile: ['**/*.test.ts', '**/*.spec.ts'],
65
+ testDir: ['__tests__', 'test', 'tests']
66
+ },
67
+ sourceToTestMap: new Map()
68
+ };
69
+
70
+ // 赋值到实例变量
71
+ this.config = defaultConfig;
72
+ return this.config;
73
+ }
74
+
75
+ /**
76
+ * 检查文件是否存在
77
+ * 使用 fsPromises.access 替代已废弃的 fs.exists
78
+ */
79
+ private async pathExists(filePath: string): Promise<boolean> {
80
+ try {
81
+ await require('fs').promises.access(filePath);
82
+ return true;
83
+ } catch {
84
+ return false;
85
+ }
86
+ }
87
+
88
+ /**
89
+ * 确保配置已加载
90
+ * 在使用 this.config 前调用
91
+ */
92
+ private assertConfig(): void {
93
+ if (!this.config) {
94
+ throw new Error('TestLinker 配置未初始化,请先调用 loadConfig');
95
+ }
96
+ }
97
+ }
98
+ ```
99
+
100
+ ### 3.2 构建映射
101
+
102
+ ```typescript
103
+ /**
104
+ * 构建源文件 → 测试文件 映射
105
+ * 基于测试框架的匹配规则
106
+ */
107
+ async buildMapping(projectRoot: string, codemap: CodemapData): Promise<void> {
108
+ // 确保配置已加载
109
+ if (!this.config) {
110
+ throw new Error('请先调用 loadConfig 加载测试配置');
111
+ }
112
+
113
+ const testFiles = await this.findTestFiles(projectRoot);
114
+
115
+ for (const testFile of testFiles) {
116
+ // 从测试文件名推断源文件
117
+ // 例如: lru-cache.test.ts → lru-cache.ts
118
+ const sourceFile = this.inferSourceFile(testFile);
119
+
120
+ if (sourceFile) {
121
+ const existing = this.config.sourceToTestMap.get(sourceFile) || [];
122
+ existing.push(testFile);
123
+ this.config.sourceToTestMap.set(sourceFile, existing);
124
+ }
125
+
126
+ // 扫描测试文件内容,找出 import 的源文件
127
+ const imports = await this.scanTestImports(testFile);
128
+ for (const imported of imports) {
129
+ const existing = this.config.sourceToTestMap.get(imported) || [];
130
+ if (!existing.includes(testFile)) {
131
+ existing.push(testFile);
132
+ this.config.sourceToTestMap.set(imported, existing);
133
+ }
134
+ }
135
+ }
136
+ }
137
+ ```
138
+
139
+ ### 3.3 查找相关测试
140
+
141
+ ```typescript
142
+ /**
143
+ * 查找相关测试文件
144
+ */
145
+ findRelatedTests(sourceFiles: string[]): string[] {
146
+ // 确保配置已加载
147
+ if (!this.config) {
148
+ throw new Error('请先调用 loadConfig 加载测试配置');
149
+ }
150
+
151
+ const relatedTests = new Set<string>();
152
+
153
+ for (const sourceFile of sourceFiles) {
154
+ // 直接映射
155
+ const direct = this.config.sourceToTestMap.get(sourceFile) || [];
156
+ direct.forEach(t => relatedTests.add(t));
157
+
158
+ // 目录级别匹配
159
+ // src/cache/lru-cache.ts → src/cache/__tests__/
160
+ const dirTests = this.findDirLevelTests(sourceFile);
161
+ dirTests.forEach(t => relatedTests.add(t));
162
+ }
163
+
164
+ return Array.from(relatedTests);
165
+ }
166
+ ```
167
+
168
+ ### 3.4 源文件推断
169
+
170
+ ```typescript
171
+ private inferSourceFile(testFile: string): string | null {
172
+ // lru-cache.test.ts → lru-cache.ts
173
+ // src/cache/__tests__/lru-cache.test.ts → src/cache/lru-cache.ts
174
+ const normalized = testFile.replace(/\\/g, '/');
175
+ const baseMatch = normalized.match(/^(.+?)\.(test|spec)\.ts$/);
176
+ if (!baseMatch) return null;
177
+
178
+ const base = baseMatch[1];
179
+ // 处理任意层级的 __tests__ 目录
180
+ if (base.includes('/__tests__/')) {
181
+ return base.replace('/__tests__/', '/') + '.ts';
182
+ }
183
+ return base + '.ts';
184
+ }
185
+ ```
186
+
187
+ ---
188
+
189
+ ## 4. 测试关联策略
190
+
191
+ | 策略 | 示例 | 优先级 |
192
+ |------|------|--------|
193
+ | **文件名匹配** | `lru-cache.ts` → `lru-cache.test.ts` | 高 |
194
+ | **目录匹配** | `src/cache/file.ts` → `src/cache/__tests__/*.test.ts` | 高 |
195
+ | **import 扫描** | 测试 import 了源文件 | 中 |
196
+ | **反向覆盖** | 哪些测试覆盖了目标代码 | 低(可选) |
197
+
198
+ ---
199
+
200
+ ## 5. 模块依赖
201
+
202
+ ```
203
+ 测试关联器 (test-linker.ts)
204
+
205
+ ├── 依赖: fs.promises (文件系统)
206
+
207
+ └── 被以下模块使用:
208
+ └── AnalyzeCommand (analyze.ts)
209
+ └── WorkflowOrchestrator (workflow-orchestrator.ts) (v2.5 新增)
210
+ ```
211
+
212
+ ---
213
+
214
+ ## 7. 工作流阶段的测试关联 (v2.5 规划)
215
+
216
+ ### 7.1 阶段特定的测试策略
217
+
218
+ ```typescript
219
+ // 工作流阶段与测试关联的映射
220
+
221
+ const PHASE_TEST_STRATEGY: Record<WorkflowPhase, TestStrategy> = {
222
+ reference: {
223
+ // 参考搜索阶段:查找相关测试作为参考
224
+ mode: 'find-similar',
225
+ includePatterns: ['**/*.test.ts', '**/*.spec.ts'],
226
+ excludePatterns: []
227
+ },
228
+ impact: {
229
+ // 影响分析阶段:查找所有可能受影响的测试
230
+ mode: 'find-affected',
231
+ includePatterns: ['**/*.test.ts', '**/*.spec.ts'],
232
+ excludePatterns: []
233
+ },
234
+ risk: {
235
+ // 风险评估阶段:关注高风险模块的测试
236
+ mode: 'focus-high-risk',
237
+ includePatterns: ['**/*.test.ts'],
238
+ excludePatterns: [],
239
+ priority: 'high-risk-first'
240
+ },
241
+ implementation: {
242
+ // 代码实现阶段:需要通过的测试
243
+ mode: 'required-tests',
244
+ includePatterns: ['**/*.test.ts', '**/*.spec.ts'],
245
+ excludePatterns: []
246
+ },
247
+ commit: {
248
+ // 提交阶段:验证测试通过
249
+ mode: 'verify',
250
+ includePatterns: ['**/*.test.ts', '**/*.spec.ts'],
251
+ excludePatterns: []
252
+ },
253
+ ci: {
254
+ // CI 阶段:完整测试套件
255
+ mode: 'full-suite',
256
+ includePatterns: ['**/*.test.ts', '**/*.spec.ts', '**/*.test.js'],
257
+ excludePatterns: []
258
+ }
259
+ };
260
+ ```
261
+
262
+ ### 7.2 工作流测试建议生成
263
+
264
+ ```typescript
265
+ class WorkflowTestLinker {
266
+ /**
267
+ * 根据当前工作流阶段生成测试建议
268
+ */
269
+ getTestSuggestions(
270
+ phase: WorkflowPhase,
271
+ sourceFiles: string[],
272
+ context: WorkflowContext
273
+ ): TestSuggestion[] {
274
+ const strategy = PHASE_TEST_STRATEGY[phase];
275
+ const testFiles = this.findRelatedTests(sourceFiles, strategy);
276
+
277
+ return testFiles.map(testFile => ({
278
+ file: testFile,
279
+ relevance: this.calculateRelevance(testFile, sourceFiles),
280
+ action: this.getSuggestedAction(phase, testFile),
281
+ priority: this.getPriority(phase, testFile, context)
282
+ }));
283
+ }
284
+
285
+ private getSuggestedAction(phase: WorkflowPhase, testFile: string): string {
286
+ switch (phase) {
287
+ case 'reference':
288
+ return '参考此测试的实现模式';
289
+ case 'impact':
290
+ return '修改后需运行此测试';
291
+ case 'risk':
292
+ return '重点关注此测试,确保通过';
293
+ case 'implementation':
294
+ return '实现完成后运行此测试';
295
+ case 'commit':
296
+ return '提交前确保此测试通过';
297
+ case 'ci':
298
+ return 'CI 会自动运行此测试';
299
+ }
300
+ }
301
+ }
302
+ ```
303
+
304
+ ---
305
+
306
+ ## 6. 风险与缓解
307
+
308
+ | 风险 | 影响 | 缓解措施 |
309
+ |------|------|----------|
310
+ | 测试框架配置解析失败 | 无法关联测试 | 使用默认模式 |
311
+ | 复杂 import 关系 | 关联不准确 | 多种策略组合 |