@winspan/claude-forge 0.5.3 → 0.6.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 (179) hide show
  1. package/README.md +3 -3
  2. package/dist/ai-gateway/index.d.ts +26 -0
  3. package/dist/ai-gateway/index.d.ts.map +1 -0
  4. package/dist/ai-gateway/index.js +67 -0
  5. package/dist/ai-gateway/index.js.map +1 -0
  6. package/dist/ai-gateway/model-selector.d.ts +6 -0
  7. package/dist/ai-gateway/model-selector.d.ts.map +1 -0
  8. package/dist/ai-gateway/model-selector.js +36 -0
  9. package/dist/ai-gateway/model-selector.js.map +1 -0
  10. package/dist/ai-gateway/rate-limiter.d.ts +20 -0
  11. package/dist/ai-gateway/rate-limiter.d.ts.map +1 -0
  12. package/dist/ai-gateway/rate-limiter.js +45 -0
  13. package/dist/ai-gateway/rate-limiter.js.map +1 -0
  14. package/dist/ai-gateway/response-cache.d.ts +17 -0
  15. package/dist/ai-gateway/response-cache.d.ts.map +1 -0
  16. package/dist/ai-gateway/response-cache.js +44 -0
  17. package/dist/ai-gateway/response-cache.js.map +1 -0
  18. package/dist/ai-provider/types.d.ts +2 -0
  19. package/dist/ai-provider/types.d.ts.map +1 -1
  20. package/dist/ai-provider/types.js.map +1 -1
  21. package/dist/daemon/handlers/context-builder.d.ts +55 -0
  22. package/dist/daemon/handlers/context-builder.d.ts.map +1 -0
  23. package/dist/daemon/handlers/context-builder.js +429 -0
  24. package/dist/daemon/handlers/context-builder.js.map +1 -0
  25. package/dist/daemon/handlers/orchestration-context.d.ts +37 -0
  26. package/dist/daemon/handlers/orchestration-context.d.ts.map +1 -0
  27. package/dist/daemon/handlers/orchestration-context.js +2 -0
  28. package/dist/daemon/handlers/orchestration-context.js.map +1 -0
  29. package/dist/daemon/handlers/session-cleanup.js +5 -5
  30. package/dist/daemon/handlers/session-cleanup.js.map +1 -1
  31. package/dist/daemon/handlers/stages/01-failure-signal.d.ts +8 -0
  32. package/dist/daemon/handlers/stages/01-failure-signal.d.ts.map +1 -0
  33. package/dist/daemon/handlers/stages/01-failure-signal.js +39 -0
  34. package/dist/daemon/handlers/stages/01-failure-signal.js.map +1 -0
  35. package/dist/daemon/handlers/stages/02-active-intervention.d.ts +8 -0
  36. package/dist/daemon/handlers/stages/02-active-intervention.d.ts.map +1 -0
  37. package/dist/daemon/handlers/stages/02-active-intervention.js +27 -0
  38. package/dist/daemon/handlers/stages/02-active-intervention.js.map +1 -0
  39. package/dist/daemon/handlers/stages/03-init-prompt.d.ts +8 -0
  40. package/dist/daemon/handlers/stages/03-init-prompt.d.ts.map +1 -0
  41. package/dist/daemon/handlers/stages/03-init-prompt.js +24 -0
  42. package/dist/daemon/handlers/stages/03-init-prompt.js.map +1 -0
  43. package/dist/daemon/handlers/stages/04-skill-suggestions.d.ts +8 -0
  44. package/dist/daemon/handlers/stages/04-skill-suggestions.d.ts.map +1 -0
  45. package/dist/daemon/handlers/stages/04-skill-suggestions.js +23 -0
  46. package/dist/daemon/handlers/stages/04-skill-suggestions.js.map +1 -0
  47. package/dist/daemon/handlers/stages/05-conv-config.d.ts +10 -0
  48. package/dist/daemon/handlers/stages/05-conv-config.d.ts.map +1 -0
  49. package/dist/daemon/handlers/stages/05-conv-config.js +23 -0
  50. package/dist/daemon/handlers/stages/05-conv-config.js.map +1 -0
  51. package/dist/daemon/handlers/stages/06-engine-check.d.ts +8 -0
  52. package/dist/daemon/handlers/stages/06-engine-check.d.ts.map +1 -0
  53. package/dist/daemon/handlers/stages/06-engine-check.js +13 -0
  54. package/dist/daemon/handlers/stages/06-engine-check.js.map +1 -0
  55. package/dist/daemon/handlers/stages/07-pipeline-reply.d.ts +9 -0
  56. package/dist/daemon/handlers/stages/07-pipeline-reply.d.ts.map +1 -0
  57. package/dist/daemon/handlers/stages/07-pipeline-reply.js +44 -0
  58. package/dist/daemon/handlers/stages/07-pipeline-reply.js.map +1 -0
  59. package/dist/daemon/handlers/stages/08-esc-interrupt.d.ts +9 -0
  60. package/dist/daemon/handlers/stages/08-esc-interrupt.d.ts.map +1 -0
  61. package/dist/daemon/handlers/stages/08-esc-interrupt.js +52 -0
  62. package/dist/daemon/handlers/stages/08-esc-interrupt.js.map +1 -0
  63. package/dist/daemon/handlers/stages/09-pipeline-active.d.ts +8 -0
  64. package/dist/daemon/handlers/stages/09-pipeline-active.d.ts.map +1 -0
  65. package/dist/daemon/handlers/stages/09-pipeline-active.js +20 -0
  66. package/dist/daemon/handlers/stages/09-pipeline-active.js.map +1 -0
  67. package/dist/daemon/handlers/stages/10-cooldown.d.ts +9 -0
  68. package/dist/daemon/handlers/stages/10-cooldown.d.ts.map +1 -0
  69. package/dist/daemon/handlers/stages/10-cooldown.js +44 -0
  70. package/dist/daemon/handlers/stages/10-cooldown.js.map +1 -0
  71. package/dist/daemon/handlers/stages/11-intent-analysis.d.ts +8 -0
  72. package/dist/daemon/handlers/stages/11-intent-analysis.d.ts.map +1 -0
  73. package/dist/daemon/handlers/stages/11-intent-analysis.js +38 -0
  74. package/dist/daemon/handlers/stages/11-intent-analysis.js.map +1 -0
  75. package/dist/daemon/handlers/stages/12-strategy-advice.d.ts +8 -0
  76. package/dist/daemon/handlers/stages/12-strategy-advice.d.ts.map +1 -0
  77. package/dist/daemon/handlers/stages/12-strategy-advice.js +20 -0
  78. package/dist/daemon/handlers/stages/12-strategy-advice.js.map +1 -0
  79. package/dist/daemon/handlers/stages/13-template-route.d.ts +8 -0
  80. package/dist/daemon/handlers/stages/13-template-route.d.ts.map +1 -0
  81. package/dist/daemon/handlers/stages/13-template-route.js +49 -0
  82. package/dist/daemon/handlers/stages/13-template-route.js.map +1 -0
  83. package/dist/daemon/handlers/stages/14-plan-resume.d.ts +8 -0
  84. package/dist/daemon/handlers/stages/14-plan-resume.d.ts.map +1 -0
  85. package/dist/daemon/handlers/stages/14-plan-resume.js +51 -0
  86. package/dist/daemon/handlers/stages/14-plan-resume.js.map +1 -0
  87. package/dist/daemon/handlers/stages/15-plan-enforcement.d.ts +8 -0
  88. package/dist/daemon/handlers/stages/15-plan-enforcement.d.ts.map +1 -0
  89. package/dist/daemon/handlers/stages/15-plan-enforcement.js +41 -0
  90. package/dist/daemon/handlers/stages/15-plan-enforcement.js.map +1 -0
  91. package/dist/daemon/handlers/stages/16-intervention-level.d.ts +8 -0
  92. package/dist/daemon/handlers/stages/16-intervention-level.d.ts.map +1 -0
  93. package/dist/daemon/handlers/stages/16-intervention-level.js +24 -0
  94. package/dist/daemon/handlers/stages/16-intervention-level.js.map +1 -0
  95. package/dist/daemon/handlers/stages/17-simple-task.d.ts +8 -0
  96. package/dist/daemon/handlers/stages/17-simple-task.d.ts.map +1 -0
  97. package/dist/daemon/handlers/stages/17-simple-task.js +47 -0
  98. package/dist/daemon/handlers/stages/17-simple-task.js.map +1 -0
  99. package/dist/daemon/handlers/stages/18-complex-task.d.ts +11 -0
  100. package/dist/daemon/handlers/stages/18-complex-task.d.ts.map +1 -0
  101. package/dist/daemon/handlers/stages/18-complex-task.js +84 -0
  102. package/dist/daemon/handlers/stages/18-complex-task.js.map +1 -0
  103. package/dist/daemon/handlers/stages/19-moderate-task.d.ts +8 -0
  104. package/dist/daemon/handlers/stages/19-moderate-task.d.ts.map +1 -0
  105. package/dist/daemon/handlers/stages/19-moderate-task.js +62 -0
  106. package/dist/daemon/handlers/stages/19-moderate-task.js.map +1 -0
  107. package/dist/daemon/handlers/stages/stage-interface.d.ts +24 -0
  108. package/dist/daemon/handlers/stages/stage-interface.d.ts.map +1 -0
  109. package/dist/daemon/handlers/stages/stage-interface.js +2 -0
  110. package/dist/daemon/handlers/stages/stage-interface.js.map +1 -0
  111. package/dist/daemon/handlers/stop-handler.js +2 -2
  112. package/dist/daemon/handlers/stop-handler.js.map +1 -1
  113. package/dist/daemon/handlers/user-prompt-handler.d.ts +1 -115
  114. package/dist/daemon/handlers/user-prompt-handler.d.ts.map +1 -1
  115. package/dist/daemon/handlers/user-prompt-handler.js +76 -1089
  116. package/dist/daemon/handlers/user-prompt-handler.js.map +1 -1
  117. package/dist/daemon/index.d.ts.map +1 -1
  118. package/dist/daemon/index.js +3 -1
  119. package/dist/daemon/index.js.map +1 -1
  120. package/dist/storage/repositories/api-usage-repository.d.ts +28 -0
  121. package/dist/storage/repositories/api-usage-repository.d.ts.map +1 -0
  122. package/dist/storage/repositories/api-usage-repository.js +59 -0
  123. package/dist/storage/repositories/api-usage-repository.js.map +1 -0
  124. package/dist/storage/repositories/base-repository.d.ts +6 -0
  125. package/dist/storage/repositories/base-repository.d.ts.map +1 -0
  126. package/dist/storage/repositories/base-repository.js +7 -0
  127. package/dist/storage/repositories/base-repository.js.map +1 -0
  128. package/dist/storage/repositories/distill-repository.d.ts +36 -0
  129. package/dist/storage/repositories/distill-repository.d.ts.map +1 -0
  130. package/dist/storage/repositories/distill-repository.js +85 -0
  131. package/dist/storage/repositories/distill-repository.js.map +1 -0
  132. package/dist/storage/repositories/event-repository.d.ts +14 -0
  133. package/dist/storage/repositories/event-repository.d.ts.map +1 -0
  134. package/dist/storage/repositories/event-repository.js +171 -0
  135. package/dist/storage/repositories/event-repository.js.map +1 -0
  136. package/dist/storage/repositories/failure-repository.d.ts +22 -0
  137. package/dist/storage/repositories/failure-repository.d.ts.map +1 -0
  138. package/dist/storage/repositories/failure-repository.js +26 -0
  139. package/dist/storage/repositories/failure-repository.js.map +1 -0
  140. package/dist/storage/repositories/intent-rule-repository.d.ts +20 -0
  141. package/dist/storage/repositories/intent-rule-repository.d.ts.map +1 -0
  142. package/dist/storage/repositories/intent-rule-repository.js +38 -0
  143. package/dist/storage/repositories/intent-rule-repository.js.map +1 -0
  144. package/dist/storage/repositories/knowledge-repository.d.ts +46 -0
  145. package/dist/storage/repositories/knowledge-repository.d.ts.map +1 -0
  146. package/dist/storage/repositories/knowledge-repository.js +84 -0
  147. package/dist/storage/repositories/knowledge-repository.js.map +1 -0
  148. package/dist/storage/repositories/latency-repository.d.ts +21 -0
  149. package/dist/storage/repositories/latency-repository.d.ts.map +1 -0
  150. package/dist/storage/repositories/latency-repository.js +42 -0
  151. package/dist/storage/repositories/latency-repository.js.map +1 -0
  152. package/dist/storage/repositories/maintenance-repository.d.ts +18 -0
  153. package/dist/storage/repositories/maintenance-repository.d.ts.map +1 -0
  154. package/dist/storage/repositories/maintenance-repository.js +61 -0
  155. package/dist/storage/repositories/maintenance-repository.js.map +1 -0
  156. package/dist/storage/repositories/satisfaction-repository.d.ts +21 -0
  157. package/dist/storage/repositories/satisfaction-repository.d.ts.map +1 -0
  158. package/dist/storage/repositories/satisfaction-repository.js +26 -0
  159. package/dist/storage/repositories/satisfaction-repository.js.map +1 -0
  160. package/dist/storage/repositories/session-repository.d.ts +16 -0
  161. package/dist/storage/repositories/session-repository.d.ts.map +1 -0
  162. package/dist/storage/repositories/session-repository.js +69 -0
  163. package/dist/storage/repositories/session-repository.js.map +1 -0
  164. package/dist/storage/repositories/task-repository.d.ts +82 -0
  165. package/dist/storage/repositories/task-repository.d.ts.map +1 -0
  166. package/dist/storage/repositories/task-repository.js +198 -0
  167. package/dist/storage/repositories/task-repository.js.map +1 -0
  168. package/dist/storage/sqlite.d.ts +25 -0
  169. package/dist/storage/sqlite.d.ts.map +1 -1
  170. package/dist/storage/sqlite.js +27 -0
  171. package/dist/storage/sqlite.js.map +1 -1
  172. package/dist/utils/claude-api.d.ts.map +1 -1
  173. package/dist/utils/claude-api.js +3 -1
  174. package/dist/utils/claude-api.js.map +1 -1
  175. package/dist/utils/logger.d.ts +7 -0
  176. package/dist/utils/logger.d.ts.map +1 -1
  177. package/dist/utils/logger.js +22 -0
  178. package/dist/utils/logger.js.map +1 -1
  179. package/package.json +1 -1
@@ -0,0 +1,39 @@
1
+ import { ContextBuilder } from '../context-builder.js';
2
+ import { logger } from '../../../utils/logger.js';
3
+ /** Stage 01: 失败信号检测 + 负向重启回溯修正 */
4
+ export class FailureSignalStage {
5
+ name = '失败信号检测';
6
+ async execute(ctx) {
7
+ const { retrospectiveEngine } = ctx.handlerCtx;
8
+ if (!retrospectiveEngine)
9
+ return { shouldTerminate: false };
10
+ const toolCallCount = ctx.handlerCtx.storage.queryEvents({
11
+ session_id: ctx.event.session_id,
12
+ project_path: ctx.event.project_path,
13
+ hook_type: 'PostToolUse',
14
+ }).length;
15
+ const signal = retrospectiveEngine.detectFailureSignal(ctx.userPrompt, {
16
+ preceding_tool_count: toolCallCount,
17
+ current_phase: ctx.handlerCtx.pipelineEngine?.getCurrentPhase(ctx.event.project_path) ?? undefined,
18
+ timestamp: ctx.event.timestamp ?? new Date().toISOString(),
19
+ });
20
+ if (signal) {
21
+ retrospectiveEngine.recordFailureSignal({
22
+ ...signal,
23
+ session_id: ctx.event.session_id,
24
+ project_path: ctx.event.project_path,
25
+ }).catch(err => logger.debug(`[Forge:任务复盘] 记录失败信号异常:${err}`));
26
+ }
27
+ // 负向重启回溯修正(仅在 session 内首条 UserPromptSubmit 时触发)
28
+ if (!ctx.negativeRestartChecked.has(ctx.event.session_id)) {
29
+ ctx.negativeRestartChecked.add(ctx.event.session_id);
30
+ if (signal?.signal_type === 'dissatisfied') {
31
+ const builder = new ContextBuilder(ctx.handlerCtx);
32
+ builder.applyNegativeRestartPenalty(ctx.event.project_path, ctx.event.session_id)
33
+ .catch(err => logger.debug(`[Forge:满意度] 负向重启回溯失败:${err}`));
34
+ }
35
+ }
36
+ return { shouldTerminate: false };
37
+ }
38
+ }
39
+ //# sourceMappingURL=01-failure-signal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"01-failure-signal.js","sourceRoot":"","sources":["../../../../src/daemon/handlers/stages/01-failure-signal.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAElD,kCAAkC;AAClC,MAAM,OAAO,kBAAkB;IACpB,IAAI,GAAG,QAAQ,CAAC;IAEzB,KAAK,CAAC,OAAO,CAAC,GAAyB;QACrC,MAAM,EAAE,mBAAmB,EAAE,GAAG,GAAG,CAAC,UAAU,CAAC;QAC/C,IAAI,CAAC,mBAAmB;YAAE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;QAE5D,MAAM,aAAa,GAAG,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,WAAW,CAAC;YACvD,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,UAAU;YAChC,YAAY,EAAE,GAAG,CAAC,KAAK,CAAC,YAAY;YACpC,SAAS,EAAE,aAAa;SACzB,CAAC,CAAC,MAAM,CAAC;QAEV,MAAM,MAAM,GAAG,mBAAmB,CAAC,mBAAmB,CAAC,GAAG,CAAC,UAAU,EAAE;YACrE,oBAAoB,EAAE,aAAa;YACnC,aAAa,EAAE,GAAG,CAAC,UAAU,CAAC,cAAc,EAAE,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,SAAS;YAClG,SAAS,EAAE,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SAC3D,CAAC,CAAC;QAEH,IAAI,MAAM,EAAE,CAAC;YACX,mBAAmB,CAAC,mBAAmB,CAAC;gBACtC,GAAG,MAAM;gBACT,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,UAAU;gBAChC,YAAY,EAAE,GAAG,CAAC,KAAK,CAAC,YAAY;aACrC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,GAAG,EAAE,CAAC,CAAC,CAAC;QAChE,CAAC;QAED,gDAAgD;QAChD,IAAI,CAAC,GAAG,CAAC,sBAAsB,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;YAC1D,GAAG,CAAC,sBAAsB,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YACrD,IAAI,MAAM,EAAE,WAAW,KAAK,cAAc,EAAE,CAAC;gBAC3C,MAAM,OAAO,GAAG,IAAI,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBACnD,OAAO,CAAC,2BAA2B,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,EAAE,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC;qBAC9E,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAC,CAAC;YAC/D,CAAC;QACH,CAAC;QAED,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;IACpC,CAAC;CACF"}
@@ -0,0 +1,8 @@
1
+ import type { Stage, StageResult } from './stage-interface.js';
2
+ import type { OrchestrationContext } from '../orchestration-context.js';
3
+ /** Stage 02: 主动干预 — 检测卡死循环(fix_attempt_count >= 3) */
4
+ export declare class ActiveInterventionStage implements Stage {
5
+ readonly name = "\u4E3B\u52A8\u5E72\u9884";
6
+ execute(ctx: OrchestrationContext): Promise<StageResult>;
7
+ }
8
+ //# sourceMappingURL=02-active-intervention.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"02-active-intervention.d.ts","sourceRoot":"","sources":["../../../../src/daemon/handlers/stages/02-active-intervention.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAIxE,sDAAsD;AACtD,qBAAa,uBAAwB,YAAW,KAAK;IACnD,QAAQ,CAAC,IAAI,8BAAU;IAEjB,OAAO,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,CAAC;CAwB/D"}
@@ -0,0 +1,27 @@
1
+ import { ForgeFormatter } from '../../../utils/formatter.js';
2
+ import { logger } from '../../../utils/logger.js';
3
+ /** Stage 02: 主动干预 — 检测卡死循环(fix_attempt_count >= 3) */
4
+ export class ActiveInterventionStage {
5
+ name = '主动干预';
6
+ async execute(ctx) {
7
+ if (!ctx.handlerCtx.retrospectiveEngine)
8
+ return { shouldTerminate: false };
9
+ const sessionMetrics = ctx.handlerCtx.storage.getSessionMetrics(ctx.event.session_id);
10
+ const fixAttempts = Number(sessionMetrics?.['fix_attempt_count'] ?? 0);
11
+ if (fixAttempts >= 3) {
12
+ logger.info(`[Forge:主动干预] 检测到卡死循环(修复尝试次数=${fixAttempts}),注入干预建议`);
13
+ return {
14
+ shouldTerminate: true,
15
+ response: {
16
+ allow: true,
17
+ additionalContext: ForgeFormatter.wrapInQuote(`[Forge 主动干预] 检测到您已进行 ${fixAttempts} 次修复尝试,建议:\n` +
18
+ `1. 回退到上一个稳定状态(git stash 或 git checkout)\n` +
19
+ `2. 重新分析根本原因,而非症状\n` +
20
+ `3. 考虑使用 cf pipeline 启动结构化编排`),
21
+ },
22
+ };
23
+ }
24
+ return { shouldTerminate: false };
25
+ }
26
+ }
27
+ //# sourceMappingURL=02-active-intervention.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"02-active-intervention.js","sourceRoot":"","sources":["../../../../src/daemon/handlers/stages/02-active-intervention.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAElD,sDAAsD;AACtD,MAAM,OAAO,uBAAuB;IACzB,IAAI,GAAG,MAAM,CAAC;IAEvB,KAAK,CAAC,OAAO,CAAC,GAAyB;QACrC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,mBAAmB;YAAE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;QAE3E,MAAM,cAAc,GAAG,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACtF,MAAM,WAAW,GAAG,MAAM,CAAC,cAAc,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC;QAEvE,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC;YACrB,MAAM,CAAC,IAAI,CAAC,+BAA+B,WAAW,UAAU,CAAC,CAAC;YAClE,OAAO;gBACL,eAAe,EAAE,IAAI;gBACrB,QAAQ,EAAE;oBACR,KAAK,EAAE,IAAI;oBACX,iBAAiB,EAAE,cAAc,CAAC,WAAW,CAC3C,wBAAwB,WAAW,cAAc;wBACjD,2CAA2C;wBAC3C,oBAAoB;wBACpB,6BAA6B,CAC9B;iBACF;aACF,CAAC;QACJ,CAAC;QAED,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;IACpC,CAAC;CACF"}
@@ -0,0 +1,8 @@
1
+ import type { Stage, StageResult } from './stage-interface.js';
2
+ import type { OrchestrationContext } from '../orchestration-context.js';
3
+ /** Stage 03: 项目初始化检测 — 未初始化时提示用户(每个 session 只提示一次) */
4
+ export declare class InitPromptStage implements Stage {
5
+ readonly name = "\u521D\u59CB\u5316\u68C0\u6D4B";
6
+ execute(ctx: OrchestrationContext): Promise<StageResult>;
7
+ }
8
+ //# sourceMappingURL=03-init-prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"03-init-prompt.d.ts","sourceRoot":"","sources":["../../../../src/daemon/handlers/stages/03-init-prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAKxE,sDAAsD;AACtD,qBAAa,eAAgB,YAAW,KAAK;IAC3C,QAAQ,CAAC,IAAI,oCAAW;IAElB,OAAO,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,CAAC;CAoB/D"}
@@ -0,0 +1,24 @@
1
+ import { ForgeFormatter } from '../../../utils/formatter.js';
2
+ import { isForgeManaged } from '../../lifecycle.js';
3
+ import { logger } from '../../../utils/logger.js';
4
+ /** Stage 03: 项目初始化检测 — 未初始化时提示用户(每个 session 只提示一次) */
5
+ export class InitPromptStage {
6
+ name = '初始化检测';
7
+ async execute(ctx) {
8
+ const sessionKey = `${ctx.event.session_id}:${ctx.event.project_path}`;
9
+ if (!ctx.initPromptedSessions.has(sessionKey) && !isForgeManaged(ctx.event.project_path)) {
10
+ logger.info(`项目未初始化,已注入配置引导提示`);
11
+ ctx.initPromptedSessions.add(sessionKey);
12
+ ctx.initPromptedAt.set(sessionKey, Date.now());
13
+ return {
14
+ shouldTerminate: true,
15
+ response: {
16
+ allow: true,
17
+ additionalContext: ForgeFormatter.wrapInQuote(`[Claude Forge 提示]\n当前项目(${ctx.event.project_path})尚未加入 Claude Forge 管理。\n请询问用户:"是否将当前项目加入 Claude Forge 管理?(将自动分析技术栈并生成项目规范)(是/否)"\n如果用户确认,请执行:\`\`\`bash\nmkdir -p "${ctx.event.project_path}/.claude-forge" && cd "${ctx.event.project_path}" && cf convention distill\n\`\`\`\n执行完成后告知用户项目已加入管理并生成了自定义规范。`),
18
+ },
19
+ };
20
+ }
21
+ return { shouldTerminate: false };
22
+ }
23
+ }
24
+ //# sourceMappingURL=03-init-prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"03-init-prompt.js","sourceRoot":"","sources":["../../../../src/daemon/handlers/stages/03-init-prompt.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAElD,sDAAsD;AACtD,MAAM,OAAO,eAAe;IACjB,IAAI,GAAG,OAAO,CAAC;IAExB,KAAK,CAAC,OAAO,CAAC,GAAyB;QACrC,MAAM,UAAU,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,UAAU,IAAI,GAAG,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;QAEvE,IAAI,CAAC,GAAG,CAAC,oBAAoB,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC;YACzF,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YAChC,GAAG,CAAC,oBAAoB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACzC,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YAC/C,OAAO;gBACL,eAAe,EAAE,IAAI;gBACrB,QAAQ,EAAE;oBACR,KAAK,EAAE,IAAI;oBACX,iBAAiB,EAAE,cAAc,CAAC,WAAW,CAC3C,2BAA2B,GAAG,CAAC,KAAK,CAAC,YAAY,sHAAsH,GAAG,CAAC,KAAK,CAAC,YAAY,0BAA0B,GAAG,CAAC,KAAK,CAAC,YAAY,gEAAgE,CAC9S;iBACF;aACF,CAAC;QACJ,CAAC;QAED,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;IACpC,CAAC;CACF"}
@@ -0,0 +1,8 @@
1
+ import type { Stage, StageResult } from './stage-interface.js';
2
+ import type { OrchestrationContext } from '../orchestration-context.js';
3
+ /** Stage 04: 技能优化建议注入(每次 session 首条消息,读取后删除文件) */
4
+ export declare class SkillSuggestionsStage implements Stage {
5
+ readonly name = "\u6280\u80FD\u5EFA\u8BAE\u6CE8\u5165";
6
+ execute(ctx: OrchestrationContext): Promise<StageResult>;
7
+ }
8
+ //# sourceMappingURL=04-skill-suggestions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"04-skill-suggestions.d.ts","sourceRoot":"","sources":["../../../../src/daemon/handlers/stages/04-skill-suggestions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAKxE,kDAAkD;AAClD,qBAAa,qBAAsB,YAAW,KAAK;IACjD,QAAQ,CAAC,IAAI,0CAAY;IAEnB,OAAO,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,CAAC;CAmB/D"}
@@ -0,0 +1,23 @@
1
+ import { ContextBuilder } from '../context-builder.js';
2
+ import { ForgeFormatter } from '../../../utils/formatter.js';
3
+ import { logger } from '../../../utils/logger.js';
4
+ /** Stage 04: 技能优化建议注入(每次 session 首条消息,读取后删除文件) */
5
+ export class SkillSuggestionsStage {
6
+ name = '技能建议注入';
7
+ async execute(ctx) {
8
+ const builder = new ContextBuilder(ctx.handlerCtx);
9
+ const skillSuggestions = builder.readAndDeleteSkillSuggestions(ctx.event.project_path, ctx.injectionCache);
10
+ if (skillSuggestions) {
11
+ logger.info('[Forge:技能建议] 注入技能优化建议并删除建议文件');
12
+ return {
13
+ shouldTerminate: true,
14
+ response: {
15
+ allow: true,
16
+ additionalContext: ForgeFormatter.wrapInQuote(`[Forge 技能优化建议]\n以下是上次 Forge 分析生成的技能改进建议,供参考:\n\n${skillSuggestions}`),
17
+ },
18
+ };
19
+ }
20
+ return { shouldTerminate: false };
21
+ }
22
+ }
23
+ //# sourceMappingURL=04-skill-suggestions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"04-skill-suggestions.js","sourceRoot":"","sources":["../../../../src/daemon/handlers/stages/04-skill-suggestions.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAElD,kDAAkD;AAClD,MAAM,OAAO,qBAAqB;IACvB,IAAI,GAAG,QAAQ,CAAC;IAEzB,KAAK,CAAC,OAAO,CAAC,GAAyB;QACrC,MAAM,OAAO,GAAG,IAAI,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACnD,MAAM,gBAAgB,GAAG,OAAO,CAAC,6BAA6B,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;QAE3G,IAAI,gBAAgB,EAAE,CAAC;YACrB,MAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;YAC5C,OAAO;gBACL,eAAe,EAAE,IAAI;gBACrB,QAAQ,EAAE;oBACR,KAAK,EAAE,IAAI;oBACX,iBAAiB,EAAE,cAAc,CAAC,WAAW,CAC3C,mDAAmD,gBAAgB,EAAE,CACtE;iBACF;aACF,CAAC;QACJ,CAAC;QAED,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;IACpC,CAAC;CACF"}
@@ -0,0 +1,10 @@
1
+ import type { Stage, StageResult } from './stage-interface.js';
2
+ import type { OrchestrationContext } from '../orchestration-context.js';
3
+ /** Stage 05: 对话式配置意图检测(pattern-based,不依赖 AI) */
4
+ export declare class ConversationalConfigStage implements Stage {
5
+ readonly name = "\u914D\u7F6E\u610F\u56FE\u68C0\u6D4B";
6
+ private configHandler;
7
+ constructor(ctx: import('../../handler-context.js').HandlerContext);
8
+ execute(ctx: OrchestrationContext): Promise<StageResult>;
9
+ }
10
+ //# sourceMappingURL=05-conv-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"05-conv-config.d.ts","sourceRoot":"","sources":["../../../../src/daemon/handlers/stages/05-conv-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAKxE,gDAAgD;AAChD,qBAAa,yBAA0B,YAAW,KAAK;IACrD,QAAQ,CAAC,IAAI,0CAAY;IACzB,OAAO,CAAC,aAAa,CAA8B;gBAEvC,GAAG,EAAE,OAAO,0BAA0B,EAAE,cAAc;IAI5D,OAAO,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,CAAC;CAW/D"}
@@ -0,0 +1,23 @@
1
+ import { ConversationalConfigHandler } from '../conversational-config-handler.js';
2
+ import { ForgeFormatter } from '../../../utils/formatter.js';
3
+ import { logger } from '../../../utils/logger.js';
4
+ /** Stage 05: 对话式配置意图检测(pattern-based,不依赖 AI) */
5
+ export class ConversationalConfigStage {
6
+ name = '配置意图检测';
7
+ configHandler;
8
+ constructor(ctx) {
9
+ this.configHandler = new ConversationalConfigHandler(ctx);
10
+ }
11
+ async execute(ctx) {
12
+ const configMsg = await this.configHandler.handle(ctx.userPrompt, ctx.event.project_path);
13
+ if (configMsg) {
14
+ logger.info('检测到配置意图,已执行并注入确认消息');
15
+ return {
16
+ shouldTerminate: true,
17
+ response: { allow: true, additionalContext: ForgeFormatter.wrapInQuote(configMsg) },
18
+ };
19
+ }
20
+ return { shouldTerminate: false };
21
+ }
22
+ }
23
+ //# sourceMappingURL=05-conv-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"05-conv-config.js","sourceRoot":"","sources":["../../../../src/daemon/handlers/stages/05-conv-config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAElD,gDAAgD;AAChD,MAAM,OAAO,yBAAyB;IAC3B,IAAI,GAAG,QAAQ,CAAC;IACjB,aAAa,CAA8B;IAEnD,YAAY,GAAsD;QAChE,IAAI,CAAC,aAAa,GAAG,IAAI,2BAA2B,CAAC,GAAG,CAAC,CAAC;IAC5D,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAyB;QACrC,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAC1F,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;YAClC,OAAO;gBACL,eAAe,EAAE,IAAI;gBACrB,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,cAAc,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE;aACpF,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;IACpC,CAAC;CACF"}
@@ -0,0 +1,8 @@
1
+ import type { Stage, StageResult } from './stage-interface.js';
2
+ import type { OrchestrationContext } from '../orchestration-context.js';
3
+ /** Stage 06: 意图引擎可用性检查 */
4
+ export declare class EngineCheckStage implements Stage {
5
+ readonly name = "\u5F15\u64CE\u53EF\u7528\u6027\u68C0\u67E5";
6
+ execute(ctx: OrchestrationContext): Promise<StageResult>;
7
+ }
8
+ //# sourceMappingURL=06-engine-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"06-engine-check.d.ts","sourceRoot":"","sources":["../../../../src/daemon/handlers/stages/06-engine-check.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAGxE,0BAA0B;AAC1B,qBAAa,gBAAiB,YAAW,KAAK;IAC5C,QAAQ,CAAC,IAAI,gDAAa;IAEpB,OAAO,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,CAAC;CAO/D"}
@@ -0,0 +1,13 @@
1
+ import { logger } from '../../../utils/logger.js';
2
+ /** Stage 06: 意图引擎可用性检查 */
3
+ export class EngineCheckStage {
4
+ name = '引擎可用性检查';
5
+ async execute(ctx) {
6
+ if (!ctx.handlerCtx.intentEngine) {
7
+ logger.info('AI 引擎不可用,跳过意图分析');
8
+ return { shouldTerminate: true, response: undefined };
9
+ }
10
+ return { shouldTerminate: false };
11
+ }
12
+ }
13
+ //# sourceMappingURL=06-engine-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"06-engine-check.js","sourceRoot":"","sources":["../../../../src/daemon/handlers/stages/06-engine-check.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAElD,0BAA0B;AAC1B,MAAM,OAAO,gBAAgB;IAClB,IAAI,GAAG,SAAS,CAAC;IAE1B,KAAK,CAAC,OAAO,CAAC,GAAyB;QACrC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC;YACjC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YAC/B,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;QACxD,CAAC;QACD,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;IACpC,CAAC;CACF"}
@@ -0,0 +1,9 @@
1
+ import type { Stage, StageResult } from './stage-interface.js';
2
+ import type { OrchestrationContext } from '../orchestration-context.js';
3
+ /** Stage 07: Pipeline 选择回复处理(A/B/C) */
4
+ export declare class PipelineReplyStage implements Stage {
5
+ readonly name = "Pipeline\u56DE\u590D\u5904\u7406";
6
+ execute(ctx: OrchestrationContext): Promise<StageResult>;
7
+ private startPipelineFromChoice;
8
+ }
9
+ //# sourceMappingURL=07-pipeline-reply.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"07-pipeline-reply.d.ts","sourceRoot":"","sources":["../../../../src/daemon/handlers/stages/07-pipeline-reply.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAKxE,uCAAuC;AACvC,qBAAa,kBAAmB,YAAW,KAAK;IAC9C,QAAQ,CAAC,IAAI,sCAAkB;IAEzB,OAAO,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,CAAC;YAwBhD,uBAAuB;CAwBtC"}
@@ -0,0 +1,44 @@
1
+ import { parsePipelineChoice, PIPELINE_OPTIONS } from '../../../pipeline/pipeline-options.js';
2
+ import { ForgeFormatter } from '../../../utils/formatter.js';
3
+ import { logger } from '../../../utils/logger.js';
4
+ /** Stage 07: Pipeline 选择回复处理(A/B/C) */
5
+ export class PipelineReplyStage {
6
+ name = 'Pipeline回复处理';
7
+ async execute(ctx) {
8
+ const { pipelineEngine, profileManager } = ctx.handlerCtx;
9
+ if (!pipelineEngine || pipelineEngine.hasActivePipeline(ctx.event.project_path)) {
10
+ return { shouldTerminate: false };
11
+ }
12
+ const choice = parsePipelineChoice(ctx.userPrompt);
13
+ if (choice) {
14
+ ctx.suggestionPending.set(ctx.event.project_path, false);
15
+ logger.info(`用户选择了工作流方案:${choice}`);
16
+ profileManager.recordBehavior({ type: 'accept', context: `pipeline:${choice}`, timestamp: new Date().toISOString() });
17
+ const response = await this.startPipelineFromChoice(choice, ctx);
18
+ return { shouldTerminate: true, response };
19
+ }
20
+ if (ctx.suggestionPending.get(ctx.event.project_path)) {
21
+ ctx.suggestionPending.set(ctx.event.project_path, false);
22
+ logger.info('用户忽略了工作流建议');
23
+ profileManager.recordBehavior({ type: 'skip', context: 'pipeline:ignored', timestamp: new Date().toISOString() });
24
+ }
25
+ return { shouldTerminate: false };
26
+ }
27
+ async startPipelineFromChoice(choice, ctx) {
28
+ const option = PIPELINE_OPTIONS[choice];
29
+ const { pipelineEngine, qualityGate } = ctx.handlerCtx;
30
+ if (choice === 'manual') {
31
+ const msg = ForgeFormatter.formatModuleNotification('pipeline', '已切换到手动控制模式,请逐步告诉我你的需求');
32
+ logger.info('用户选择了手动模式');
33
+ return { allow: true, additionalContext: ForgeFormatter.wrapInQuote(msg) };
34
+ }
35
+ const requirement = ctx.event.tool_input?.user_prompt || '用户需求';
36
+ const pipeline = await pipelineEngine.startPipeline(requirement, ctx.event.project_path, ctx.event.session_id);
37
+ if (qualityGate)
38
+ qualityGate.setRequirement(requirement);
39
+ logger.info(`已启动编排(${option.description}):id=${pipeline.id} | 任务数=${pipeline.tasks.length}`);
40
+ const msg = ForgeFormatter.formatModuleNotification('pipeline', `已启动${option.description},共 ${pipeline.tasks.length} 个任务\n阶段:${option.phases.join(' → ')}`);
41
+ return { allow: true, additionalContext: ForgeFormatter.wrapInQuote(msg) };
42
+ }
43
+ }
44
+ //# sourceMappingURL=07-pipeline-reply.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"07-pipeline-reply.js","sourceRoot":"","sources":["../../../../src/daemon/handlers/stages/07-pipeline-reply.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { Stage, StageResult } from './stage-interface.js';
2
+ import type { OrchestrationContext } from '../orchestration-context.js';
3
+ /** Stage 08: ESC 中断状态处理 */
4
+ export declare class EscInterruptStage implements Stage {
5
+ readonly name = "ESC\u4E2D\u65AD\u5904\u7406";
6
+ execute(ctx: OrchestrationContext): Promise<StageResult>;
7
+ private handleInterruptReply;
8
+ }
9
+ //# sourceMappingURL=08-esc-interrupt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"08-esc-interrupt.d.ts","sourceRoot":"","sources":["../../../../src/daemon/handlers/stages/08-esc-interrupt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAQxE,2BAA2B;AAC3B,qBAAa,iBAAkB,YAAW,KAAK;IAC7C,QAAQ,CAAC,IAAI,iCAAa;IAEpB,OAAO,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,CAAC;IAuB9D,OAAO,CAAC,oBAAoB;CA0B7B"}
@@ -0,0 +1,52 @@
1
+ import { ForgeFormatter } from '../../../utils/formatter.js';
2
+ import { logger } from '../../../utils/logger.js';
3
+ const PHASE_LABELS_MAP = {
4
+ analyze: '需求分析', design: '架构设计', code: '编码实现', test: '测试', review: '代码审查',
5
+ };
6
+ /** Stage 08: ESC 中断状态处理 */
7
+ export class EscInterruptStage {
8
+ name = 'ESC中断处理';
9
+ async execute(ctx) {
10
+ const { pipelineEngine } = ctx.handlerCtx;
11
+ const interruptedState = pipelineEngine?.getInterruptedState(ctx.event.project_path);
12
+ if (!interruptedState)
13
+ return { shouldTerminate: false };
14
+ const reply = this.handleInterruptReply(ctx.userPrompt, ctx, interruptedState);
15
+ if (reply !== undefined)
16
+ return { shouldTerminate: true, response: reply };
17
+ // 首次进入中断状态:注入消歧提示
18
+ const { phase, completedCount } = interruptedState;
19
+ const phaseLabel = PHASE_LABELS_MAP[phase] ?? phase;
20
+ logger.info(`[Pipeline] 注入 ESC 中断消歧提示(阶段=${phaseLabel},已完成=${completedCount})`);
21
+ return {
22
+ shouldTerminate: true,
23
+ response: {
24
+ allow: true,
25
+ additionalContext: ForgeFormatter.wrapInQuote(`[Forge Pipeline 中断恢复]\n检测到上次执行被中断(${phaseLabel}阶段,已完成 ${completedCount} 个任务)。\n\n请询问用户:\n"上次执行被中断,请选择处理方式:\nA. 继续 — 从中断处继续执行当前阶段\nB. 重做 — 重新执行当前阶段(清除本阶段进度)\nC. 取消 — 关闭当前 Pipeline,回到普通模式\n\n请输入 A、B 或 C:"`),
26
+ },
27
+ };
28
+ }
29
+ handleInterruptReply(userPrompt, ctx, interruptedState) {
30
+ const choice = userPrompt.trim().toUpperCase();
31
+ const { pipelineEngine } = ctx.handlerCtx;
32
+ if (!pipelineEngine)
33
+ return undefined;
34
+ if (choice === 'A' || /^继续/.test(userPrompt)) {
35
+ pipelineEngine.resumeAfterInterrupt(ctx.event.project_path);
36
+ logger.info(`[Pipeline] 用户选择继续,恢复 ${interruptedState.phase} 阶段`);
37
+ return { allow: true, additionalContext: ForgeFormatter.wrapInQuote(`[Forge Pipeline] 已恢复执行。继续 ${interruptedState.phase} 阶段,请从上次中断处继续工作。`) };
38
+ }
39
+ if (choice === 'B' || /^重做/.test(userPrompt)) {
40
+ pipelineEngine.cancelAfterInterrupt(ctx.event.project_path);
41
+ logger.info(`[Pipeline] 用户选择重做,关闭 Pipeline`);
42
+ return { allow: true, additionalContext: ForgeFormatter.wrapInQuote(`[Forge Pipeline] 已关闭当前 Pipeline。请重新描述需求,系统将重新启动编排流程。`) };
43
+ }
44
+ if (choice === 'C' || /^取消/.test(userPrompt)) {
45
+ pipelineEngine.cancelAfterInterrupt(ctx.event.project_path);
46
+ logger.info(`[Pipeline] 用户选择取消,关闭 Pipeline`);
47
+ return { allow: true, additionalContext: ForgeFormatter.wrapInQuote(`[Forge Pipeline] Pipeline 已取消,回到普通模式。`) };
48
+ }
49
+ return undefined;
50
+ }
51
+ }
52
+ //# sourceMappingURL=08-esc-interrupt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"08-esc-interrupt.js","sourceRoot":"","sources":["../../../../src/daemon/handlers/stages/08-esc-interrupt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { Stage, StageResult } from './stage-interface.js';
2
+ import type { OrchestrationContext } from '../orchestration-context.js';
3
+ /** Stage 09: Pipeline 活跃时短路 — 只注入规范,跳过意图分析 */
4
+ export declare class PipelineActiveStage implements Stage {
5
+ readonly name = "Pipeline\u6D3B\u8DC3\u77ED\u8DEF";
6
+ execute(ctx: OrchestrationContext): Promise<StageResult>;
7
+ }
8
+ //# sourceMappingURL=09-pipeline-active.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"09-pipeline-active.d.ts","sourceRoot":"","sources":["../../../../src/daemon/handlers/stages/09-pipeline-active.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAIxE,8CAA8C;AAC9C,qBAAa,mBAAoB,YAAW,KAAK;IAC/C,QAAQ,CAAC,IAAI,sCAAkB;IAEzB,OAAO,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,CAAC;CAc/D"}
@@ -0,0 +1,20 @@
1
+ import { ForgeFormatter } from '../../../utils/formatter.js';
2
+ import { logger } from '../../../utils/logger.js';
3
+ /** Stage 09: Pipeline 活跃时短路 — 只注入规范,跳过意图分析 */
4
+ export class PipelineActiveStage {
5
+ name = 'Pipeline活跃短路';
6
+ async execute(ctx) {
7
+ if (!ctx.handlerCtx.pipelineEngine?.hasActivePipeline(ctx.event.project_path)) {
8
+ return { shouldTerminate: false };
9
+ }
10
+ const conventionPrompt = ctx.handlerCtx.conventionManager.getActivePrompt(ctx.event.project_path) ?? undefined;
11
+ logger.info('[Forge:Pipeline] Pipeline 活跃,跳过意图分析和低优先级上下文注入');
12
+ if (!conventionPrompt)
13
+ return { shouldTerminate: true, response: undefined };
14
+ return {
15
+ shouldTerminate: true,
16
+ response: { allow: true, additionalContext: ForgeFormatter.wrapInQuote(conventionPrompt) },
17
+ };
18
+ }
19
+ }
20
+ //# sourceMappingURL=09-pipeline-active.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"09-pipeline-active.js","sourceRoot":"","sources":["../../../../src/daemon/handlers/stages/09-pipeline-active.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAElD,8CAA8C;AAC9C,MAAM,OAAO,mBAAmB;IACrB,IAAI,GAAG,cAAc,CAAC;IAE/B,KAAK,CAAC,OAAO,CAAC,GAAyB;QACrC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC;YAC9E,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;QACpC,CAAC;QAED,MAAM,gBAAgB,GAAG,GAAG,CAAC,UAAU,CAAC,iBAAiB,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,SAAS,CAAC;QAC/G,MAAM,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC;QAE7D,IAAI,CAAC,gBAAgB;YAAE,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;QAC7E,OAAO;YACL,eAAe,EAAE,IAAI;YACrB,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,cAAc,CAAC,WAAW,CAAC,gBAAgB,CAAC,EAAE;SAC3F,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,9 @@
1
+ import type { Stage, StageResult } from './stage-interface.js';
2
+ import type { OrchestrationContext } from '../orchestration-context.js';
3
+ /** Stage 10: 分析冷却检查 */
4
+ export declare class CooldownStage implements Stage {
5
+ readonly name = "\u51B7\u5374\u68C0\u67E5";
6
+ execute(ctx: OrchestrationContext): Promise<StageResult>;
7
+ private evictStaleEntries;
8
+ }
9
+ //# sourceMappingURL=10-cooldown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"10-cooldown.d.ts","sourceRoot":"","sources":["../../../../src/daemon/handlers/stages/10-cooldown.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAOxE,uBAAuB;AACvB,qBAAa,aAAc,YAAW,KAAK;IACzC,QAAQ,CAAC,IAAI,8BAAU;IAEjB,OAAO,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,CAAC;IAsB9D,OAAO,CAAC,iBAAiB;CAgB1B"}
@@ -0,0 +1,44 @@
1
+ import { ForgeFormatter } from '../../../utils/formatter.js';
2
+ import { logger, relPath } from '../../../utils/logger.js';
3
+ const ANALYSIS_COOLDOWN_MS = 800;
4
+ const MAX_STATE_AGE_MS = 60 * 60 * 1000;
5
+ /** Stage 10: 分析冷却检查 */
6
+ export class CooldownStage {
7
+ name = '冷却检查';
8
+ async execute(ctx) {
9
+ const now = Date.now();
10
+ this.evictStaleEntries(now, ctx);
11
+ const lastAt = ctx.lastAnalysisAt.get(ctx.event.project_path) ?? 0;
12
+ if (now - lastAt < ANALYSIS_COOLDOWN_MS) {
13
+ logger.info(`分析冷却中,跳过(${relPath(ctx.event.project_path)})`);
14
+ const conventionPrompt = ctx.handlerCtx.conventionManager.getActivePrompt(ctx.event.project_path);
15
+ if (conventionPrompt) {
16
+ logger.info('[Forge:冷却期] 分析冷却中,仅注入规范上下文');
17
+ return {
18
+ shouldTerminate: true,
19
+ response: { allow: true, additionalContext: ForgeFormatter.wrapInQuote(conventionPrompt) },
20
+ };
21
+ }
22
+ return { shouldTerminate: true, response: undefined };
23
+ }
24
+ ctx.lastAnalysisAt.set(ctx.event.project_path, now);
25
+ return { shouldTerminate: false };
26
+ }
27
+ evictStaleEntries(now, ctx) {
28
+ const cutoff = now - MAX_STATE_AGE_MS;
29
+ for (const [key, ts] of ctx.lastAnalysisAt) {
30
+ if (ts < cutoff) {
31
+ ctx.lastAnalysisAt.delete(key);
32
+ ctx.suggestionPending.delete(key);
33
+ ctx.injectionCache.delete(key);
34
+ }
35
+ }
36
+ for (const [key, ts] of ctx.initPromptedAt) {
37
+ if (ts < cutoff) {
38
+ ctx.initPromptedAt.delete(key);
39
+ ctx.initPromptedSessions.delete(key);
40
+ }
41
+ }
42
+ }
43
+ }
44
+ //# sourceMappingURL=10-cooldown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"10-cooldown.js","sourceRoot":"","sources":["../../../../src/daemon/handlers/stages/10-cooldown.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAE3D,MAAM,oBAAoB,GAAG,GAAG,CAAC;AACjC,MAAM,gBAAgB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAExC,uBAAuB;AACvB,MAAM,OAAO,aAAa;IACf,IAAI,GAAG,MAAM,CAAC;IAEvB,KAAK,CAAC,OAAO,CAAC,GAAyB;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAEjC,MAAM,MAAM,GAAG,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QACnE,IAAI,GAAG,GAAG,MAAM,GAAG,oBAAoB,EAAE,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC,YAAY,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;YAC5D,MAAM,gBAAgB,GAAG,GAAG,CAAC,UAAU,CAAC,iBAAiB,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAClG,IAAI,gBAAgB,EAAE,CAAC;gBACrB,MAAM,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;gBAC1C,OAAO;oBACL,eAAe,EAAE,IAAI;oBACrB,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,cAAc,CAAC,WAAW,CAAC,gBAAgB,CAAC,EAAE;iBAC3F,CAAC;YACJ,CAAC;YACD,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;QACxD,CAAC;QAED,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QACpD,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;IACpC,CAAC;IAEO,iBAAiB,CAAC,GAAW,EAAE,GAAyB;QAC9D,MAAM,MAAM,GAAG,GAAG,GAAG,gBAAgB,CAAC;QACtC,KAAK,MAAM,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,cAAc,EAAE,CAAC;YAC3C,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC;gBAChB,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC/B,GAAG,CAAC,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAClC,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjC,CAAC;QACH,CAAC;QACD,KAAK,MAAM,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,cAAc,EAAE,CAAC;YAC3C,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC;gBAChB,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC/B,GAAG,CAAC,oBAAoB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,8 @@
1
+ import type { Stage, StageResult } from './stage-interface.js';
2
+ import type { OrchestrationContext } from '../orchestration-context.js';
3
+ /** Stage 11: 意图分析 — 调用 IntentEngine,设置 ctx.analysis / ctx.activePlan */
4
+ export declare class IntentAnalysisStage implements Stage {
5
+ readonly name = "\u610F\u56FE\u5206\u6790";
6
+ execute(ctx: OrchestrationContext): Promise<StageResult>;
7
+ }
8
+ //# sourceMappingURL=11-intent-analysis.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"11-intent-analysis.d.ts","sourceRoot":"","sources":["../../../../src/daemon/handlers/stages/11-intent-analysis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAKxE,wEAAwE;AACxE,qBAAa,mBAAoB,YAAW,KAAK;IAC/C,QAAQ,CAAC,IAAI,8BAAU;IAEjB,OAAO,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,CAAC;CAkD/D"}
@@ -0,0 +1,38 @@
1
+ import { ContextBuilder } from '../context-builder.js';
2
+ import { isForgeManaged } from '../../lifecycle.js';
3
+ import { logger } from '../../../utils/logger.js';
4
+ /** Stage 11: 意图分析 — 调用 IntentEngine,设置 ctx.analysis / ctx.activePlan */
5
+ export class IntentAnalysisStage {
6
+ name = '意图分析';
7
+ async execute(ctx) {
8
+ const { intentEngine, latencyTracer } = ctx.handlerCtx;
9
+ if (!intentEngine)
10
+ return { shouldTerminate: false };
11
+ const builder = new ContextBuilder(ctx.handlerCtx);
12
+ // 预热:在 await analyze() 之前同步完成不依赖 analysis 的 IO
13
+ ctx.handlerCtx.conventionManager.getActiveConventions(ctx.event.project_path);
14
+ builder.buildPlanStartContext(ctx.event.project_path, ctx.injectionCache);
15
+ builder.buildProfileContext(ctx.event.project_path, ctx.injectionCache);
16
+ builder.readDecisionsFile(ctx.event.project_path, ctx.injectionCache);
17
+ const activePlan = builder.readActivePlanSummary(ctx.event.project_path);
18
+ const userContext = builder.buildUserContext(ctx.event.project_path);
19
+ const history = builder.buildConversationHistory(ctx.event.session_id, ctx.event.project_path);
20
+ const analysis = await latencyTracer.trace({
21
+ session_id: ctx.event.session_id,
22
+ project_path: ctx.event.project_path,
23
+ trace_type: 'intent_analysis',
24
+ engine_name: 'IntentEngine',
25
+ }, () => intentEngine.analyze(ctx.userPrompt, ctx.event.project_path, undefined, history, isForgeManaged(ctx.event.project_path), activePlan, userContext));
26
+ const pipelineStr = analysis.requiresPipeline ? '需要多步骤编排' : '直接执行';
27
+ logger.info(`意图分析:${analysis.complexity} | ${pipelineStr} | ` +
28
+ `预估文件=${analysis.estimatedFiles} | 需求="${analysis.requirement}"`);
29
+ logger.info(`分析理由:${analysis.reasoning}`);
30
+ if (analysis.searchKeywords?.length) {
31
+ ctx.handlerCtx.skillRegistry.setIntentKeywords(analysis.searchKeywords);
32
+ }
33
+ ctx.analysis = analysis;
34
+ ctx.activePlan = activePlan;
35
+ return { shouldTerminate: false };
36
+ }
37
+ }
38
+ //# sourceMappingURL=11-intent-analysis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"11-intent-analysis.js","sourceRoot":"","sources":["../../../../src/daemon/handlers/stages/11-intent-analysis.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAElD,wEAAwE;AACxE,MAAM,OAAO,mBAAmB;IACrB,IAAI,GAAG,MAAM,CAAC;IAEvB,KAAK,CAAC,OAAO,CAAC,GAAyB;QACrC,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,GAAG,GAAG,CAAC,UAAU,CAAC;QACvD,IAAI,CAAC,YAAY;YAAE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;QAErD,MAAM,OAAO,GAAG,IAAI,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAEnD,+CAA+C;QAC/C,GAAG,CAAC,UAAU,CAAC,iBAAiB,CAAC,oBAAoB,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAC9E,OAAO,CAAC,qBAAqB,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;QAC1E,OAAO,CAAC,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;QACxE,OAAO,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;QAEtE,MAAM,UAAU,GAAG,OAAO,CAAC,qBAAqB,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACzE,MAAM,WAAW,GAAG,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACrE,MAAM,OAAO,GAAG,OAAO,CAAC,wBAAwB,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAE/F,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,KAAK,CACxC;YACE,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,UAAU;YAChC,YAAY,EAAE,GAAG,CAAC,KAAK,CAAC,YAAY;YACpC,UAAU,EAAE,iBAAiB;YAC7B,WAAW,EAAE,cAAc;SAC5B,EACD,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,CACxB,GAAG,CAAC,UAAU,EACd,GAAG,CAAC,KAAK,CAAC,YAAY,EACtB,SAAS,EACT,OAAO,EACP,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,EACtC,UAAU,EACV,WAAW,CACZ,CACF,CAAC;QAEF,MAAM,WAAW,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;QACnE,MAAM,CAAC,IAAI,CACT,QAAQ,QAAQ,CAAC,UAAU,MAAM,WAAW,KAAK;YACjD,QAAQ,QAAQ,CAAC,cAAc,UAAU,QAAQ,CAAC,WAAW,GAAG,CACjE,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,QAAQ,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;QAE1C,IAAI,QAAQ,CAAC,cAAc,EAAE,MAAM,EAAE,CAAC;YACpC,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC,iBAAiB,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;QAC1E,CAAC;QAED,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACxB,GAAG,CAAC,UAAU,GAAG,UAAU,CAAC;QAE5B,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;IACpC,CAAC;CACF"}
@@ -0,0 +1,8 @@
1
+ import type { Stage, StageResult } from './stage-interface.js';
2
+ import type { OrchestrationContext } from '../orchestration-context.js';
3
+ /** Stage 12: 历史失败模式预防建议注入 */
4
+ export declare class StrategyAdviceStage implements Stage {
5
+ readonly name = "\u7B56\u7565\u5EFA\u8BAE\u6CE8\u5165";
6
+ execute(ctx: OrchestrationContext): Promise<StageResult>;
7
+ }
8
+ //# sourceMappingURL=12-strategy-advice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"12-strategy-advice.d.ts","sourceRoot":"","sources":["../../../../src/daemon/handlers/stages/12-strategy-advice.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAIxE,6BAA6B;AAC7B,qBAAa,mBAAoB,YAAW,KAAK;IAC/C,QAAQ,CAAC,IAAI,0CAAY;IAEnB,OAAO,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,CAAC;CAiB/D"}
@@ -0,0 +1,20 @@
1
+ import { ForgeFormatter } from '../../../utils/formatter.js';
2
+ import { logger } from '../../../utils/logger.js';
3
+ /** Stage 12: 历史失败模式预防建议注入 */
4
+ export class StrategyAdviceStage {
5
+ name = '策略建议注入';
6
+ async execute(ctx) {
7
+ if (!ctx.handlerCtx.retrospectiveEngine || !ctx.analysis)
8
+ return { shouldTerminate: false };
9
+ const strategies = ctx.handlerCtx.retrospectiveEngine.getStrategies(ctx.analysis.requirement || ctx.userPrompt);
10
+ if (strategies) {
11
+ logger.info('[Forge:策略建议] 注入历史失败模式预防建议');
12
+ return {
13
+ shouldTerminate: true,
14
+ response: { allow: true, additionalContext: ForgeFormatter.wrapInQuote(strategies) },
15
+ };
16
+ }
17
+ return { shouldTerminate: false };
18
+ }
19
+ }
20
+ //# sourceMappingURL=12-strategy-advice.js.map