@winspan/claude-forge 0.3.7 → 0.4.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 (111) hide show
  1. package/README.md +12 -7
  2. package/dist/autopilot/intent-engine.d.ts +7 -1
  3. package/dist/autopilot/intent-engine.d.ts.map +1 -1
  4. package/dist/autopilot/intent-engine.js +30 -3
  5. package/dist/autopilot/intent-engine.js.map +1 -1
  6. package/dist/autopilot/quality-gate.d.ts +16 -0
  7. package/dist/autopilot/quality-gate.d.ts.map +1 -1
  8. package/dist/autopilot/quality-gate.js +88 -2
  9. package/dist/autopilot/quality-gate.js.map +1 -1
  10. package/dist/cli/commands/config.d.ts.map +1 -1
  11. package/dist/cli/commands/config.js +4 -1
  12. package/dist/cli/commands/config.js.map +1 -1
  13. package/dist/cli/commands/init/project-doctor.d.ts.map +1 -1
  14. package/dist/cli/commands/init/project-doctor.js +41 -3
  15. package/dist/cli/commands/init/project-doctor.js.map +1 -1
  16. package/dist/cli/commands/pipeline.d.ts.map +1 -1
  17. package/dist/cli/commands/pipeline.js +6 -3
  18. package/dist/cli/commands/pipeline.js.map +1 -1
  19. package/dist/cli/tui.d.ts.map +1 -1
  20. package/dist/cli/tui.js +110 -85
  21. package/dist/cli/tui.js.map +1 -1
  22. package/dist/config/defaults.d.ts.map +1 -1
  23. package/dist/config/defaults.js +5 -0
  24. package/dist/config/defaults.js.map +1 -1
  25. package/dist/config/index.d.ts.map +1 -1
  26. package/dist/config/index.js +1 -0
  27. package/dist/config/index.js.map +1 -1
  28. package/dist/config/schema.d.ts +5 -0
  29. package/dist/config/schema.d.ts.map +1 -1
  30. package/dist/config/schema.js +12 -0
  31. package/dist/config/schema.js.map +1 -1
  32. package/dist/daemon/context-injector.js +1 -1
  33. package/dist/daemon/engine-registry.d.ts.map +1 -1
  34. package/dist/daemon/engine-registry.js +3 -0
  35. package/dist/daemon/engine-registry.js.map +1 -1
  36. package/dist/daemon/handler-context.d.ts +4 -2
  37. package/dist/daemon/handler-context.d.ts.map +1 -1
  38. package/dist/daemon/handlers/post-tool-use-handler.d.ts.map +1 -1
  39. package/dist/daemon/handlers/post-tool-use-handler.js +6 -0
  40. package/dist/daemon/handlers/post-tool-use-handler.js.map +1 -1
  41. package/dist/daemon/handlers/session-cleanup.d.ts +6 -0
  42. package/dist/daemon/handlers/session-cleanup.d.ts.map +1 -1
  43. package/dist/daemon/handlers/session-cleanup.js +107 -0
  44. package/dist/daemon/handlers/session-cleanup.js.map +1 -1
  45. package/dist/daemon/handlers/stop-handler.d.ts.map +1 -1
  46. package/dist/daemon/handlers/stop-handler.js +15 -0
  47. package/dist/daemon/handlers/stop-handler.js.map +1 -1
  48. package/dist/daemon/handlers/user-prompt-handler.d.ts +10 -3
  49. package/dist/daemon/handlers/user-prompt-handler.d.ts.map +1 -1
  50. package/dist/daemon/handlers/user-prompt-handler.js +151 -44
  51. package/dist/daemon/handlers/user-prompt-handler.js.map +1 -1
  52. package/dist/distill/index.js +1 -1
  53. package/dist/distill/index.js.map +1 -1
  54. package/dist/distill/tree-index.d.ts +40 -0
  55. package/dist/distill/tree-index.d.ts.map +1 -0
  56. package/dist/distill/tree-index.js +237 -0
  57. package/dist/distill/tree-index.js.map +1 -0
  58. package/dist/distill/writer.d.ts +3 -0
  59. package/dist/distill/writer.d.ts.map +1 -1
  60. package/dist/distill/writer.js +13 -0
  61. package/dist/distill/writer.js.map +1 -1
  62. package/dist/pipeline/artifact-generator.d.ts +35 -0
  63. package/dist/pipeline/artifact-generator.d.ts.map +1 -0
  64. package/dist/pipeline/artifact-generator.js +269 -0
  65. package/dist/pipeline/artifact-generator.js.map +1 -0
  66. package/dist/pipeline/index.d.ts +15 -0
  67. package/dist/pipeline/index.d.ts.map +1 -1
  68. package/dist/pipeline/index.js +34 -1
  69. package/dist/pipeline/index.js.map +1 -1
  70. package/dist/pipeline/phase-manager.d.ts +9 -1
  71. package/dist/pipeline/phase-manager.d.ts.map +1 -1
  72. package/dist/pipeline/phase-manager.js +91 -48
  73. package/dist/pipeline/phase-manager.js.map +1 -1
  74. package/dist/retrospective/failure-detector.d.ts +17 -0
  75. package/dist/retrospective/failure-detector.d.ts.map +1 -0
  76. package/dist/retrospective/failure-detector.js +67 -0
  77. package/dist/retrospective/failure-detector.js.map +1 -0
  78. package/dist/retrospective/index.d.ts +69 -0
  79. package/dist/retrospective/index.d.ts.map +1 -0
  80. package/dist/retrospective/index.js +189 -0
  81. package/dist/retrospective/index.js.map +1 -0
  82. package/dist/retrospective/metrics-extractor.d.ts +27 -0
  83. package/dist/retrospective/metrics-extractor.d.ts.map +1 -0
  84. package/dist/retrospective/metrics-extractor.js +71 -0
  85. package/dist/retrospective/metrics-extractor.js.map +1 -0
  86. package/dist/retrospective/pattern-learner.d.ts +29 -0
  87. package/dist/retrospective/pattern-learner.d.ts.map +1 -0
  88. package/dist/retrospective/pattern-learner.js +159 -0
  89. package/dist/retrospective/pattern-learner.js.map +1 -0
  90. package/dist/retrospective/report-writer.d.ts +33 -0
  91. package/dist/retrospective/report-writer.d.ts.map +1 -0
  92. package/dist/retrospective/report-writer.js +173 -0
  93. package/dist/retrospective/report-writer.js.map +1 -0
  94. package/dist/retrospective/strategy-advisor.d.ts +21 -0
  95. package/dist/retrospective/strategy-advisor.d.ts.map +1 -0
  96. package/dist/retrospective/strategy-advisor.js +63 -0
  97. package/dist/retrospective/strategy-advisor.js.map +1 -0
  98. package/dist/retrospective/types.d.ts +107 -0
  99. package/dist/retrospective/types.d.ts.map +1 -0
  100. package/dist/retrospective/types.js +7 -0
  101. package/dist/retrospective/types.js.map +1 -0
  102. package/dist/skill-registry/evolver/keyword-evolver.d.ts.map +1 -1
  103. package/dist/skill-registry/evolver/keyword-evolver.js +5 -1
  104. package/dist/skill-registry/evolver/keyword-evolver.js.map +1 -1
  105. package/dist/storage/index.d.ts +12 -0
  106. package/dist/storage/index.d.ts.map +1 -1
  107. package/dist/storage/sqlite.d.ts +57 -0
  108. package/dist/storage/sqlite.d.ts.map +1 -1
  109. package/dist/storage/sqlite.js +126 -1
  110. package/dist/storage/sqlite.js.map +1 -1
  111. package/package.json +1 -1
@@ -0,0 +1,71 @@
1
+ /**
2
+ * 质量指标提取器 — 纯函数,无副作用
3
+ *
4
+ * 从事件流中提取客观的任务执行质量指标
5
+ * 不依赖 AI 自评,基于行为数据计算
6
+ */
7
+ /**
8
+ * 从事件流提取任务质量指标
9
+ *
10
+ * @param events 本次会话的所有事件(按时间排序)
11
+ * @param qualityPassCount 质量门禁通过次数(从 QualityGateEngine 在 reset 前捕获)
12
+ * @param qualityFailCount 质量门禁失败次数
13
+ * @param phases 阶段快照(从 PhaseManager 获取)
14
+ * @param completed 会话是否正常完成
15
+ */
16
+ export function extractMetrics(events, qualityPassCount, qualityFailCount, phases, completed) {
17
+ const userPromptEvents = events.filter(e => e.hook_type === 'UserPromptSubmit');
18
+ const toolUseEvents = events.filter(e => e.hook_type === 'PostToolUse');
19
+ const writeEditEvents = toolUseEvents.filter(e => e.tool_name === 'Write' || e.tool_name === 'Edit');
20
+ // 修复尝试:从阶段快照汇总
21
+ const fixAttemptCount = phases.reduce((sum, p) => sum + p.fix_attempt_count, 0);
22
+ // 持续时长:最后事件时间 - 第一个事件时间
23
+ let durationMs = 0;
24
+ if (events.length >= 2) {
25
+ const first = new Date(events[0].timestamp).getTime();
26
+ const last = new Date(events[events.length - 1].timestamp).getTime();
27
+ if (!isNaN(first) && !isNaN(last) && last > first) {
28
+ durationMs = last - first;
29
+ }
30
+ }
31
+ return {
32
+ total_rounds: userPromptEvents.length,
33
+ total_tool_calls: toolUseEvents.length,
34
+ write_edit_count: writeEditEvents.length,
35
+ fix_attempt_count: fixAttemptCount,
36
+ quality_pass_count: qualityPassCount,
37
+ quality_fail_count: qualityFailCount,
38
+ phase_distribution: phases,
39
+ duration_ms: durationMs,
40
+ completed,
41
+ };
42
+ }
43
+ /**
44
+ * 根据需求文本推断任务类型
45
+ */
46
+ export function classifyTaskType(requirement) {
47
+ const lower = requirement.toLowerCase();
48
+ if (/重构|refactor|优化|cleanup|clean up/.test(lower))
49
+ return 'refactor';
50
+ if (/修复|fix|bug|错误|异常|报错/.test(lower))
51
+ return 'bugfix';
52
+ if (/审查|review|检查|check|评审/.test(lower))
53
+ return 'review';
54
+ if (/设计|design|架构|architecture|方案/.test(lower))
55
+ return 'design';
56
+ if (/新增|添加|实现|feature|功能|开发/.test(lower))
57
+ return 'feature';
58
+ return 'other';
59
+ }
60
+ /**
61
+ * 根据指标评估任务复杂度
62
+ */
63
+ export function assessComplexity(metrics) {
64
+ const { total_tool_calls, write_edit_count, total_rounds } = metrics;
65
+ if (total_tool_calls > 50 || write_edit_count > 15 || total_rounds > 10)
66
+ return 'complex';
67
+ if (total_tool_calls > 15 || write_edit_count > 5 || total_rounds > 4)
68
+ return 'moderate';
69
+ return 'simple';
70
+ }
71
+ //# sourceMappingURL=metrics-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics-extractor.js","sourceRoot":"","sources":["../../src/retrospective/metrics-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * PatternLearner — AI 驱动的失败模式提炼器
3
+ *
4
+ * 从 task_sessions + failure_signals 历史数据中提炼同类任务的共同失败模式,
5
+ * 并将结论写入 task_patterns 表供 StrategyAdvisor 使用。
6
+ *
7
+ * 触发条件:每 10 次 Stop,或同类型任务新增 >= 5 条时
8
+ */
9
+ import type { AIProvider } from '../ai-provider/types.js';
10
+ import type { StorageEngine } from '../storage/index.js';
11
+ import type { TaskType } from './types.js';
12
+ export declare class PatternLearner {
13
+ private storage;
14
+ private api;
15
+ constructor(storage: StorageEngine, api: AIProvider);
16
+ /**
17
+ * 对指定任务类型执行模式提炼。
18
+ * 若历史不足 MIN_SAMPLES 条则跳过。
19
+ */
20
+ learnPatterns(taskType: TaskType): Promise<number>;
21
+ /**
22
+ * 对所有任务类型批量执行模式学习(每 10 次 Stop 触发)。
23
+ * 返回总写入模式数。
24
+ */
25
+ learnAll(): Promise<number>;
26
+ private buildPrompt;
27
+ private parsePatterns;
28
+ }
29
+ //# sourceMappingURL=pattern-learner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern-learner.d.ts","sourceRoot":"","sources":["../../src/retrospective/pattern-learner.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAe,MAAM,YAAY,CAAC;AAYxD,qBAAa,cAAc;IAEvB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,GAAG;gBADH,OAAO,EAAE,aAAa,EACtB,GAAG,EAAE,UAAU;IAGzB;;;OAGG;IACG,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAkExD;;;OAGG;IACG,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IAcjC,OAAO,CAAC,WAAW;IAsCnB,OAAO,CAAC,aAAa;CAmCtB"}
@@ -0,0 +1,159 @@
1
+ /**
2
+ * PatternLearner — AI 驱动的失败模式提炼器
3
+ *
4
+ * 从 task_sessions + failure_signals 历史数据中提炼同类任务的共同失败模式,
5
+ * 并将结论写入 task_patterns 表供 StrategyAdvisor 使用。
6
+ *
7
+ * 触发条件:每 10 次 Stop,或同类型任务新增 >= 5 条时
8
+ */
9
+ import { randomUUID } from 'node:crypto';
10
+ import { logger } from '../utils/logger.js';
11
+ /** 最少需要多少条任务历史才触发模式提炼 */
12
+ const MIN_SAMPLES = 5;
13
+ /** 每种任务类型最多分析的历史条数 */
14
+ const MAX_HISTORY_PER_TYPE = 30;
15
+ /** 模式置信度阈值:低于此值视为噪音,不写入 */
16
+ const MIN_CONFIDENCE = 0.4;
17
+ const ALL_TASK_TYPES = ['refactor', 'feature', 'bugfix', 'review', 'design', 'other'];
18
+ export class PatternLearner {
19
+ storage;
20
+ api;
21
+ constructor(storage, api) {
22
+ this.storage = storage;
23
+ this.api = api;
24
+ }
25
+ /**
26
+ * 对指定任务类型执行模式提炼。
27
+ * 若历史不足 MIN_SAMPLES 条则跳过。
28
+ */
29
+ async learnPatterns(taskType) {
30
+ const sessions = this.storage.getTaskSessionsByType(taskType, MAX_HISTORY_PER_TYPE);
31
+ if (sessions.length < MIN_SAMPLES) {
32
+ logger.info(`[Forge:模式学习] ${taskType} 历史不足 ${MIN_SAMPLES} 条(当前 ${sessions.length}),跳过`);
33
+ return 0;
34
+ }
35
+ logger.info(`[Forge:模式学习] 开始提炼 ${taskType}(${sessions.length} 条历史)`);
36
+ // 收集所有失败信号
37
+ const failureSummaries = [];
38
+ for (const session of sessions) {
39
+ const sessionId = String(session['session_id'] ?? '');
40
+ const projectPath = String(session['project_path'] ?? '');
41
+ const signals = this.storage.getFailureSignals({ session_id: sessionId, project_path: projectPath });
42
+ if (signals.length > 0) {
43
+ const signalTexts = signals.map(s => ` - [${String(s['signal_type'] ?? '')}] "${String(s['raw_prompt'] ?? '')}" (阶段=${String(s['context_phase'] ?? '未知')}, 前置工具调用=${Number(s['preceding_tool_count'] ?? 0)})`).join('\n');
44
+ failureSummaries.push(`会话 ${sessionId.slice(0, 8)}... | 结果=${String(session['outcome'] ?? '')} | 轮次=${Number(session['total_rounds'] ?? 0)} | 工具调用=${Number(session['total_tool_calls'] ?? 0)}\n` +
45
+ `失败信号:\n${signalTexts}`);
46
+ }
47
+ }
48
+ if (failureSummaries.length === 0) {
49
+ logger.info(`[Forge:模式学习] ${taskType} 无失败信号记录,跳过模式提炼`);
50
+ return 0;
51
+ }
52
+ // 构建 AI prompt
53
+ const prompt = this.buildPrompt(taskType, sessions, failureSummaries);
54
+ let response;
55
+ try {
56
+ response = await this.api.complete(prompt, '模式学习', { timeoutMs: 60_000, maxTokens: 1000 });
57
+ }
58
+ catch (err) {
59
+ logger.warn(`[Forge:模式学习] AI 调用失败:${err}`);
60
+ return 0;
61
+ }
62
+ // 解析 AI 返回的模式列表
63
+ const patterns = this.parsePatterns(response, taskType);
64
+ if (patterns.length === 0) {
65
+ logger.info(`[Forge:模式学习] AI 未提炼出有效模式`);
66
+ return 0;
67
+ }
68
+ // 写入 task_patterns 表
69
+ for (const pattern of patterns) {
70
+ this.storage.upsertTaskPattern({
71
+ id: randomUUID(),
72
+ task_type: pattern.task_type,
73
+ failure_pattern: pattern.failure_pattern,
74
+ prevention_strategy: pattern.prevention_strategy,
75
+ confidence_score: pattern.confidence_score,
76
+ sample_count: sessions.length,
77
+ last_updated: new Date().toISOString(),
78
+ });
79
+ }
80
+ logger.info(`[Forge:模式学习] ${taskType} 提炼完成,写入 ${patterns.length} 个模式`);
81
+ return patterns.length;
82
+ }
83
+ /**
84
+ * 对所有任务类型批量执行模式学习(每 10 次 Stop 触发)。
85
+ * 返回总写入模式数。
86
+ */
87
+ async learnAll() {
88
+ let total = 0;
89
+ for (const taskType of ALL_TASK_TYPES) {
90
+ try {
91
+ total += await this.learnPatterns(taskType);
92
+ }
93
+ catch (err) {
94
+ logger.warn(`[Forge:模式学习] ${taskType} 提炼失败:${err}`);
95
+ }
96
+ }
97
+ return total;
98
+ }
99
+ // ── 私有方法 ────────────────────────────────────────────────────────────────
100
+ buildPrompt(taskType, sessions, failureSummaries) {
101
+ const totalSessions = sessions.length;
102
+ const failedCount = sessions.filter(s => {
103
+ const outcome = s['outcome'];
104
+ const failureCount = typeof s['failure_signal_count'] === 'number' ? s['failure_signal_count'] : 0;
105
+ return outcome === 'partial' || failureCount > 0;
106
+ }).length;
107
+ return `你是一位软件工程质量分析师。以下是 ${totalSessions} 条"${taskType}"类型任务的执行历史,其中 ${failedCount} 条含失败信号。
108
+
109
+ 请分析这些失败信号,提炼出 1-3 个最常见的失败模式,以及对应的预防策略。
110
+
111
+ ## 失败信号记录
112
+
113
+ ${failureSummaries.join('\n\n---\n\n')}
114
+
115
+ ## 输出格式
116
+
117
+ 请严格按以下 JSON 数组格式输出,不要包含任何其他文本:
118
+
119
+ [
120
+ {
121
+ "failure_pattern": "简短描述失败模式(20字以内)",
122
+ "prevention_strategy": "具体的预防策略(50字以内)",
123
+ "confidence": 0.7
124
+ }
125
+ ]
126
+
127
+ 要求:
128
+ - confidence 范围 0.0-1.0,表示这个模式在样本中的普遍性
129
+ - confidence < ${MIN_CONFIDENCE} 的模式请直接省略不输出
130
+ - 只输出 JSON 数组,不要 markdown 代码块,不要解释文字`;
131
+ }
132
+ parsePatterns(response, taskType) {
133
+ try {
134
+ // 提取 JSON 数组(兼容 AI 可能包裹了 markdown 代码块的情况)
135
+ const jsonMatch = response.match(/\[[\s\S]*\]/);
136
+ if (!jsonMatch)
137
+ return [];
138
+ const parsed = JSON.parse(jsonMatch[0]);
139
+ if (!Array.isArray(parsed))
140
+ return [];
141
+ return parsed
142
+ .filter(p => typeof p.failure_pattern === 'string' && p.failure_pattern.trim() &&
143
+ typeof p.prevention_strategy === 'string' && p.prevention_strategy.trim() &&
144
+ typeof p.confidence === 'number' && p.confidence >= MIN_CONFIDENCE)
145
+ .slice(0, 3) // 最多保留 3 个
146
+ .map(p => ({
147
+ task_type: taskType,
148
+ failure_pattern: p.failure_pattern.trim(),
149
+ prevention_strategy: p.prevention_strategy.trim(),
150
+ confidence_score: Math.min(1.0, Math.max(0.0, p.confidence)),
151
+ }));
152
+ }
153
+ catch (err) {
154
+ logger.warn(`[Forge:模式学习] 解析 AI 响应失败:${err}`);
155
+ return [];
156
+ }
157
+ }
158
+ }
159
+ //# sourceMappingURL=pattern-learner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern-learner.js","sourceRoot":"","sources":["../../src/retrospective/pattern-learner.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAIzC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,yBAAyB;AACzB,MAAM,WAAW,GAAG,CAAC,CAAC;AACtB,sBAAsB;AACtB,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAChC,2BAA2B;AAC3B,MAAM,cAAc,GAAG,GAAG,CAAC;AAE3B,MAAM,cAAc,GAAe,CAAC,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AAElG,MAAM,OAAO,cAAc;IAEf;IACA;IAFV,YACU,OAAsB,EACtB,GAAe;QADf,YAAO,GAAP,OAAO,CAAe;QACtB,QAAG,GAAH,GAAG,CAAY;IACtB,CAAC;IAEJ;;;OAGG;IACH,KAAK,CAAC,aAAa,CAAC,QAAkB;QACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAAC;QACpF,IAAI,QAAQ,CAAC,MAAM,GAAG,WAAW,EAAE,CAAC;YAClC,MAAM,CAAC,IAAI,CAAC,gBAAgB,QAAQ,SAAS,WAAW,SAAS,QAAQ,CAAC,MAAM,MAAM,CAAC,CAAC;YACxF,OAAO,CAAC,CAAC;QACX,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,qBAAqB,QAAQ,IAAI,QAAQ,CAAC,MAAM,OAAO,CAAC,CAAC;QAErE,WAAW;QACX,MAAM,gBAAgB,GAAa,EAAE,CAAC;QACtC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC;YACtD,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC;YAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC;YACrG,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAClC,QAAQ,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,SAAS,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC,YAAY,MAAM,CAAC,CAAC,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC,GAAG,CAC1K,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACb,gBAAgB,CAAC,IAAI,CACnB,MAAM,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,YAAY,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,SAAS,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,WAAW,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,IAAI;oBAC3K,UAAU,WAAW,EAAE,CACxB,CAAC;YACJ,CAAC;QACH,CAAC;QAED,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClC,MAAM,CAAC,IAAI,CAAC,gBAAgB,QAAQ,iBAAiB,CAAC,CAAC;YACvD,OAAO,CAAC,CAAC;QACX,CAAC;QAED,eAAe;QACf,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC;QAEtE,IAAI,QAAgB,CAAC;QACrB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7F,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,IAAI,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAC;YAC3C,OAAO,CAAC,CAAC;QACX,CAAC;QAED,gBAAgB;QAChB,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACxD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;YACxC,OAAO,CAAC,CAAC;QACX,CAAC;QAED,qBAAqB;QACrB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC;gBAC7B,EAAE,EAAE,UAAU,EAAE;gBAChB,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,eAAe,EAAE,OAAO,CAAC,eAAe;gBACxC,mBAAmB,EAAE,OAAO,CAAC,mBAAmB;gBAChD,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;gBAC1C,YAAY,EAAE,QAAQ,CAAC,MAAM;gBAC7B,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACvC,CAAC,CAAC;QACL,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,gBAAgB,QAAQ,YAAY,QAAQ,CAAC,MAAM,MAAM,CAAC,CAAC;QACvE,OAAO,QAAQ,CAAC,MAAM,CAAC;IACzB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,QAAQ;QACZ,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,QAAQ,IAAI,cAAc,EAAE,CAAC;YACtC,IAAI,CAAC;gBACH,KAAK,IAAI,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YAC9C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,IAAI,CAAC,gBAAgB,QAAQ,SAAS,GAAG,EAAE,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,2EAA2E;IAEnE,WAAW,CACjB,QAAkB,EAClB,QAAmC,EACnC,gBAA0B;QAE1B,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC;QACtC,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;YACtC,MAAM,OAAO,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC;YAC7B,MAAM,YAAY,GAAG,OAAO,CAAC,CAAC,sBAAsB,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACnG,OAAO,OAAO,KAAK,SAAS,IAAI,YAAY,GAAG,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC,MAAM,CAAC;QAEV,OAAO,qBAAqB,aAAa,MAAM,QAAQ,iBAAiB,WAAW;;;;;;EAMrF,gBAAgB,CAAC,IAAI,CAAC,aAAa,CAAC;;;;;;;;;;;;;;;;iBAgBrB,cAAc;qCACM,CAAC;IACpC,CAAC;IAEO,aAAa,CACnB,QAAgB,EAChB,QAAkB;QAElB,IAAI,CAAC;YACH,0CAA0C;YAC1C,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YAChD,IAAI,CAAC,SAAS;gBAAE,OAAO,EAAE,CAAC;YAE1B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAIpC,CAAC;YAEH,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;gBAAE,OAAO,EAAE,CAAC;YAEtC,OAAO,MAAM;iBACV,MAAM,CAAC,CAAC,CAAC,EAAE,CACV,OAAO,CAAC,CAAC,eAAe,KAAK,QAAQ,IAAI,CAAC,CAAC,eAAe,CAAC,IAAI,EAAE;gBACjE,OAAO,CAAC,CAAC,mBAAmB,KAAK,QAAQ,IAAI,CAAC,CAAC,mBAAmB,CAAC,IAAI,EAAE;gBACzE,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,CAAC,UAAU,IAAI,cAAc,CACnE;iBACA,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAE,WAAW;iBACxB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACT,SAAS,EAAE,QAAQ;gBACnB,eAAe,EAAE,CAAC,CAAC,eAAgB,CAAC,IAAI,EAAE;gBAC1C,mBAAmB,EAAE,CAAC,CAAC,mBAAoB,CAAC,IAAI,EAAE;gBAClD,gBAAgB,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,UAAW,CAAC,CAAC;aAC9D,CAAC,CAAC,CAAC;QACR,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,IAAI,CAAC,2BAA2B,GAAG,EAAE,CAAC,CAAC;YAC9C,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * 复盘报告写入器
3
+ *
4
+ * 生成 .claude-forge/retrospective.md,自动轮换归档
5
+ */
6
+ import type { TaskSession } from './types.js';
7
+ export declare class RetrospectiveReportWriter {
8
+ private projectPath;
9
+ private reportPath;
10
+ private archivePath;
11
+ constructor(projectPath: string);
12
+ /**
13
+ * 写入任务复盘条目
14
+ */
15
+ write(session: TaskSession): void;
16
+ /**
17
+ * 格式化单条复盘记录
18
+ */
19
+ private formatEntry;
20
+ /**
21
+ * 归档旧条目
22
+ */
23
+ private rotateArchive;
24
+ /**
25
+ * 从需求文本提取简短标题
26
+ */
27
+ private extractTitle;
28
+ /**
29
+ * 获取结果标签
30
+ */
31
+ private getOutcomeLabel;
32
+ }
33
+ //# sourceMappingURL=report-writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report-writer.d.ts","sourceRoot":"","sources":["../../src/retrospective/report-writer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAiB,MAAM,YAAY,CAAC;AAK7D,qBAAa,yBAAyB;IAIxB,OAAO,CAAC,WAAW;IAH/B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAS;gBAER,WAAW,EAAE,MAAM;IAWvC;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAuCjC;;OAEG;IACH,OAAO,CAAC,WAAW;IAgDnB;;OAEG;IACH,OAAO,CAAC,aAAa;IAsCrB;;OAEG;IACH,OAAO,CAAC,YAAY;IAOpB;;OAEG;IACH,OAAO,CAAC,eAAe;CASxB"}
@@ -0,0 +1,173 @@
1
+ /**
2
+ * 复盘报告写入器
3
+ *
4
+ * 生成 .claude-forge/retrospective.md,自动轮换归档
5
+ */
6
+ import fs from 'node:fs';
7
+ import path from 'node:path';
8
+ const MAX_ENTRIES = 20;
9
+ const ARCHIVE_FILENAME = 'retrospective-archive.md';
10
+ export class RetrospectiveReportWriter {
11
+ projectPath;
12
+ reportPath;
13
+ archivePath;
14
+ constructor(projectPath) {
15
+ this.projectPath = projectPath;
16
+ const forgeDir = path.join(projectPath, '.claude-forge');
17
+ this.reportPath = path.join(forgeDir, 'retrospective.md');
18
+ this.archivePath = path.join(forgeDir, ARCHIVE_FILENAME);
19
+ // 确保目录存在
20
+ if (!fs.existsSync(forgeDir)) {
21
+ fs.mkdirSync(forgeDir, { recursive: true });
22
+ }
23
+ }
24
+ /**
25
+ * 写入任务复盘条目
26
+ */
27
+ write(session) {
28
+ const entry = this.formatEntry(session);
29
+ // 读取现有内容
30
+ let content = '';
31
+ if (fs.existsSync(this.reportPath)) {
32
+ content = fs.readFileSync(this.reportPath, 'utf-8');
33
+ }
34
+ else {
35
+ content = '# 任务复盘日志\n\n';
36
+ }
37
+ // 插入新条目(在标题后的第一个分隔符之后)
38
+ const lines = content.split('\n');
39
+ const headerEndIndex = lines.findIndex((line, i) => i > 0 && line.startsWith('---'));
40
+ if (headerEndIndex > 0) {
41
+ // 在分隔符后插入(即第一条记录之前)
42
+ lines.splice(headerEndIndex + 1, 0, entry);
43
+ }
44
+ else {
45
+ // 若无分隔符,在标题后插入
46
+ const titleIndex = lines.findIndex(l => l.startsWith('# '));
47
+ if (titleIndex >= 0) {
48
+ lines.splice(titleIndex + 2, 0, entry); // 标题后空一行
49
+ }
50
+ else {
51
+ lines.push(entry);
52
+ }
53
+ }
54
+ content = lines.join('\n');
55
+ // 检查条目数量,超过阈值则归档
56
+ const entryCount = (content.match(/^## \d{4}-\d{2}-\d{2}/gm) || []).length;
57
+ if (entryCount > MAX_ENTRIES) {
58
+ this.rotateArchive(content);
59
+ }
60
+ else {
61
+ fs.writeFileSync(this.reportPath, content, 'utf-8');
62
+ }
63
+ }
64
+ /**
65
+ * 格式化单条复盘记录
66
+ */
67
+ formatEntry(session) {
68
+ const { metrics, failure_signals } = session;
69
+ const date = session.started_at.split('T')[0];
70
+ const title = this.extractTitle(session.requirement);
71
+ const outcomeLabel = this.getOutcomeLabel(session.outcome);
72
+ const durationMin = Math.round(metrics.duration_ms / 60000);
73
+ let entry = `---\n## ${date} | ${title} | 类型: ${session.task_type} | 结果: ${outcomeLabel}\n\n`;
74
+ // 执行指标
75
+ entry += '**执行指标**\n';
76
+ entry += `- 总轮次: ${metrics.total_rounds} | 工具调用: ${metrics.total_tool_calls} | 修复尝试: ${metrics.fix_attempt_count} | 耗时: ${durationMin}min\n`;
77
+ entry += `- 质量门禁: 通过 ${metrics.quality_pass_count} 次 / 失败 ${metrics.quality_fail_count} 次\n`;
78
+ // 失败信号
79
+ if (failure_signals.length > 0) {
80
+ const dissatisfied = failure_signals.filter(s => s.signal_type === 'dissatisfied').length;
81
+ const iteration = failure_signals.filter(s => s.signal_type === 'iteration').length;
82
+ entry += `- 失败信号: ${failure_signals.length} 次`;
83
+ if (dissatisfied > 0)
84
+ entry += `(不满意 ${dissatisfied} 次`;
85
+ if (iteration > 0)
86
+ entry += `${dissatisfied > 0 ? ',' : '('}迭代 ${iteration} 次`;
87
+ entry += ')\n';
88
+ // 详细信号列表
89
+ const firstSignal = failure_signals[0];
90
+ if (firstSignal) {
91
+ entry += ` - 首次信号: "${firstSignal.matched_pattern}"`;
92
+ if (firstSignal.context_phase)
93
+ entry += ` 发生在 ${firstSignal.context_phase} 阶段`;
94
+ entry += '\n';
95
+ }
96
+ }
97
+ else {
98
+ entry += '- 失败信号: 无\n';
99
+ }
100
+ // 阶段分布
101
+ if (metrics.phase_distribution.length > 0) {
102
+ entry += '\n**阶段分布**\n';
103
+ for (const phase of metrics.phase_distribution) {
104
+ entry += `- ${phase.phase}: ${phase.tool_call_count} 次工具调用`;
105
+ if (phase.fix_attempt_count > 0)
106
+ entry += `(修复 ${phase.fix_attempt_count} 次)`;
107
+ entry += '\n';
108
+ }
109
+ }
110
+ entry += '\n';
111
+ return entry;
112
+ }
113
+ /**
114
+ * 归档旧条目
115
+ */
116
+ rotateArchive(content) {
117
+ const lines = content.split('\n');
118
+ const entries = [];
119
+ let currentEntry = [];
120
+ for (const line of lines) {
121
+ if (line.startsWith('## ') && currentEntry.length > 0) {
122
+ entries.push(currentEntry.join('\n'));
123
+ currentEntry = [line];
124
+ }
125
+ else {
126
+ currentEntry.push(line);
127
+ }
128
+ }
129
+ if (currentEntry.length > 0) {
130
+ entries.push(currentEntry.join('\n'));
131
+ }
132
+ // 保留最新的 MAX_ENTRIES 条
133
+ const keep = entries.slice(0, MAX_ENTRIES);
134
+ const archive = entries.slice(MAX_ENTRIES);
135
+ // 写入主文件
136
+ const newContent = '# 任务复盘日志\n\n' + keep.join('\n---\n');
137
+ fs.writeFileSync(this.reportPath, newContent, 'utf-8');
138
+ // 追加到归档文件
139
+ if (archive.length > 0) {
140
+ let archiveContent = '';
141
+ if (fs.existsSync(this.archivePath)) {
142
+ archiveContent = fs.readFileSync(this.archivePath, 'utf-8');
143
+ }
144
+ else {
145
+ archiveContent = '# 任务复盘归档\n\n';
146
+ }
147
+ archiveContent += archive.join('\n---\n') + '\n';
148
+ fs.writeFileSync(this.archivePath, archiveContent, 'utf-8');
149
+ }
150
+ }
151
+ /**
152
+ * 从需求文本提取简短标题
153
+ */
154
+ extractTitle(requirement) {
155
+ // 取第一句话或前 30 个字符
156
+ const firstLine = requirement.split('\n')[0];
157
+ const title = firstLine.length > 30 ? firstLine.slice(0, 30) + '...' : firstLine;
158
+ return title.trim();
159
+ }
160
+ /**
161
+ * 获取结果标签
162
+ */
163
+ getOutcomeLabel(outcome) {
164
+ const labels = {
165
+ success: '成功',
166
+ partial: '部分完成',
167
+ abandoned: '中止',
168
+ in_progress: '进行中',
169
+ };
170
+ return labels[outcome] || outcome;
171
+ }
172
+ }
173
+ //# sourceMappingURL=report-writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report-writer.js","sourceRoot":"","sources":["../../src/retrospective/report-writer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * StrategyAdvisor — 预防策略推荐器
3
+ *
4
+ * 读取 task_patterns 表中已学习的失败模式,
5
+ * 在 UserPromptHandler 检测到同类任务时注入预防建议。
6
+ */
7
+ import type { StorageEngine } from '../storage/index.js';
8
+ export declare class StrategyAdvisor {
9
+ private storage;
10
+ constructor(storage: StorageEngine);
11
+ /**
12
+ * 根据用户需求文本,查找相关历史失败模式并返回预防建议。
13
+ * 无相关模式时返回 null。
14
+ */
15
+ getRelevantStrategies(requirement: string): string | null;
16
+ /**
17
+ * 加载指定任务类型的高置信度模式,按置信度降序排列。
18
+ */
19
+ private loadPatterns;
20
+ }
21
+ //# sourceMappingURL=strategy-advisor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategy-advisor.d.ts","sourceRoot":"","sources":["../../src/retrospective/strategy-advisor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAUzD,qBAAa,eAAe;IACd,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,aAAa;IAE1C;;;OAGG;IACH,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAmBzD;;OAEG;IACH,OAAO,CAAC,YAAY;CAqBrB"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * StrategyAdvisor — 预防策略推荐器
3
+ *
4
+ * 读取 task_patterns 表中已学习的失败模式,
5
+ * 在 UserPromptHandler 检测到同类任务时注入预防建议。
6
+ */
7
+ import { classifyTaskType } from './metrics-extractor.js';
8
+ import { logger } from '../utils/logger.js';
9
+ /** 注入建议的最低置信度阈值 */
10
+ const MIN_INJECT_CONFIDENCE = 0.5;
11
+ /** 每次最多注入的建议条数 */
12
+ const MAX_STRATEGIES = 2;
13
+ export class StrategyAdvisor {
14
+ storage;
15
+ constructor(storage) {
16
+ this.storage = storage;
17
+ }
18
+ /**
19
+ * 根据用户需求文本,查找相关历史失败模式并返回预防建议。
20
+ * 无相关模式时返回 null。
21
+ */
22
+ getRelevantStrategies(requirement) {
23
+ const taskType = classifyTaskType(requirement);
24
+ const patterns = this.loadPatterns(taskType);
25
+ if (patterns.length === 0)
26
+ return null;
27
+ const lines = [
28
+ `[Forge 历史经验] 检测到 ${taskType} 类型任务,以下是历史失败模式和预防建议:`,
29
+ ];
30
+ for (const p of patterns) {
31
+ lines.push(`- ⚠️ 常见问题:${p.failure_pattern}`);
32
+ lines.push(` 建议:${p.prevention_strategy}`);
33
+ }
34
+ logger.info(`[Forge:策略建议] 注入 ${patterns.length} 条 ${taskType} 类型预防建议`);
35
+ return lines.join('\n');
36
+ }
37
+ /**
38
+ * 加载指定任务类型的高置信度模式,按置信度降序排列。
39
+ */
40
+ loadPatterns(taskType) {
41
+ try {
42
+ const raw = this.storage.getTaskPatterns(taskType);
43
+ return raw
44
+ .map(r => ({
45
+ id: String(r['id'] ?? ''),
46
+ task_type: String(r['task_type'] ?? ''),
47
+ failure_pattern: String(r['failure_pattern'] ?? ''),
48
+ prevention_strategy: String(r['prevention_strategy'] ?? ''),
49
+ confidence_score: Number(r['confidence_score'] ?? 0),
50
+ sample_count: Number(r['sample_count'] ?? 0),
51
+ last_updated: String(r['last_updated'] ?? ''),
52
+ }))
53
+ .filter(p => p.confidence_score >= MIN_INJECT_CONFIDENCE)
54
+ .sort((a, b) => b.confidence_score - a.confidence_score)
55
+ .slice(0, MAX_STRATEGIES);
56
+ }
57
+ catch (err) {
58
+ logger.warn(`[Forge:策略建议] 加载模式失败:${err}`);
59
+ return [];
60
+ }
61
+ }
62
+ }
63
+ //# sourceMappingURL=strategy-advisor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategy-advisor.js","sourceRoot":"","sources":["../../src/retrospective/strategy-advisor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,mBAAmB;AACnB,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAClC,kBAAkB;AAClB,MAAM,cAAc,GAAG,CAAC,CAAC;AAEzB,MAAM,OAAO,eAAe;IACN;IAApB,YAAoB,OAAsB;QAAtB,YAAO,GAAP,OAAO,CAAe;IAAG,CAAC;IAE9C;;;OAGG;IACH,qBAAqB,CAAC,WAAmB;QACvC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;QAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QAE7C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAEvC,MAAM,KAAK,GAAa;YACtB,oBAAoB,QAAQ,uBAAuB;SACpD,CAAC;QAEF,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC;YAC7C,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,mBAAmB,EAAE,CAAC,CAAC;QAC9C,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,mBAAmB,QAAQ,CAAC,MAAM,MAAM,QAAQ,SAAS,CAAC,CAAC;QACvE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED;;OAEG;IACK,YAAY,CAAC,QAAkB;QACrC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;YACnD,OAAO,GAAG;iBACP,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACT,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACzB,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,CAAa;gBACnD,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC;gBACnD,mBAAmB,EAAE,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAC,IAAI,EAAE,CAAC;gBAC3D,gBAAgB,EAAE,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;gBACpD,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;gBAC5C,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;aAC9C,CAAC,CAAC;iBACF,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB,IAAI,qBAAqB,CAAC;iBACxD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB,GAAG,CAAC,CAAC,gBAAgB,CAAC;iBACvD,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,IAAI,CAAC,uBAAuB,GAAG,EAAE,CAAC,CAAC;YAC1C,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;CACF"}