@amsterdamdatalabs/enact-factory 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 (644) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +566 -0
  3. package/dist/adapters/agenticLoop.d.ts +90 -0
  4. package/dist/adapters/agenticLoop.d.ts.map +1 -0
  5. package/dist/adapters/agenticLoop.js +219 -0
  6. package/dist/adapters/agenticLoop.js.map +1 -0
  7. package/dist/adapters/base.d.ts +16 -0
  8. package/dist/adapters/base.d.ts.map +1 -0
  9. package/dist/adapters/base.js +135 -0
  10. package/dist/adapters/base.js.map +1 -0
  11. package/dist/adapters/claude.d.ts +13 -0
  12. package/dist/adapters/claude.d.ts.map +1 -0
  13. package/dist/adapters/claude.js +318 -0
  14. package/dist/adapters/claude.js.map +1 -0
  15. package/dist/adapters/codex.d.ts +14 -0
  16. package/dist/adapters/codex.d.ts.map +1 -0
  17. package/dist/adapters/codex.js +366 -0
  18. package/dist/adapters/codex.js.map +1 -0
  19. package/dist/adapters/cryptoQuantAdapter.d.ts +85 -0
  20. package/dist/adapters/cryptoQuantAdapter.d.ts.map +1 -0
  21. package/dist/adapters/cryptoQuantAdapter.js +238 -0
  22. package/dist/adapters/cryptoQuantAdapter.js.map +1 -0
  23. package/dist/adapters/cursor.d.ts +13 -0
  24. package/dist/adapters/cursor.d.ts.map +1 -0
  25. package/dist/adapters/cursor.js +300 -0
  26. package/dist/adapters/cursor.js.map +1 -0
  27. package/dist/adapters/envPath.d.ts +20 -0
  28. package/dist/adapters/envPath.d.ts.map +1 -0
  29. package/dist/adapters/envPath.js +49 -0
  30. package/dist/adapters/envPath.js.map +1 -0
  31. package/dist/adapters/hermes.d.ts +13 -0
  32. package/dist/adapters/hermes.d.ts.map +1 -0
  33. package/dist/adapters/hermes.js +283 -0
  34. package/dist/adapters/hermes.js.map +1 -0
  35. package/dist/adapters/index.d.ts +18 -0
  36. package/dist/adapters/index.d.ts.map +1 -0
  37. package/dist/adapters/index.js +56 -0
  38. package/dist/adapters/index.js.map +1 -0
  39. package/dist/adapters/opencode.d.ts +13 -0
  40. package/dist/adapters/opencode.d.ts.map +1 -0
  41. package/dist/adapters/opencode.js +282 -0
  42. package/dist/adapters/opencode.js.map +1 -0
  43. package/dist/adapters/processRegistry.d.ts +38 -0
  44. package/dist/adapters/processRegistry.d.ts.map +1 -0
  45. package/dist/adapters/processRegistry.js +147 -0
  46. package/dist/adapters/processRegistry.js.map +1 -0
  47. package/dist/adapters/responses.d.ts +16 -0
  48. package/dist/adapters/responses.d.ts.map +1 -0
  49. package/dist/adapters/responses.js +244 -0
  50. package/dist/adapters/responses.js.map +1 -0
  51. package/dist/adapters/streamBuffer.d.ts +59 -0
  52. package/dist/adapters/streamBuffer.d.ts.map +1 -0
  53. package/dist/adapters/streamBuffer.js +123 -0
  54. package/dist/adapters/streamBuffer.js.map +1 -0
  55. package/dist/adapters/tools.d.ts +30 -0
  56. package/dist/adapters/tools.d.ts.map +1 -0
  57. package/dist/adapters/tools.js +219 -0
  58. package/dist/adapters/tools.js.map +1 -0
  59. package/dist/adapters/types.d.ts +82 -0
  60. package/dist/adapters/types.d.ts.map +1 -0
  61. package/dist/adapters/types.js +6 -0
  62. package/dist/adapters/types.js.map +1 -0
  63. package/dist/agents/agentBus.d.ts +160 -0
  64. package/dist/agents/agentBus.d.ts.map +1 -0
  65. package/dist/agents/agentBus.js +350 -0
  66. package/dist/agents/agentBus.js.map +1 -0
  67. package/dist/agents/agentPair.d.ts +215 -0
  68. package/dist/agents/agentPair.d.ts.map +1 -0
  69. package/dist/agents/agentPair.js +456 -0
  70. package/dist/agents/agentPair.js.map +1 -0
  71. package/dist/agents/auditor.d.ts +27 -0
  72. package/dist/agents/auditor.d.ts.map +1 -0
  73. package/dist/agents/auditor.js +238 -0
  74. package/dist/agents/auditor.js.map +1 -0
  75. package/dist/agents/cliStreamParser.d.ts +18 -0
  76. package/dist/agents/cliStreamParser.d.ts.map +1 -0
  77. package/dist/agents/cliStreamParser.js +156 -0
  78. package/dist/agents/cliStreamParser.js.map +1 -0
  79. package/dist/agents/documenter.d.ts +31 -0
  80. package/dist/agents/documenter.d.ts.map +1 -0
  81. package/dist/agents/documenter.js +286 -0
  82. package/dist/agents/documenter.js.map +1 -0
  83. package/dist/agents/draftAnalyzer.d.ts +50 -0
  84. package/dist/agents/draftAnalyzer.d.ts.map +1 -0
  85. package/dist/agents/draftAnalyzer.js +289 -0
  86. package/dist/agents/draftAnalyzer.js.map +1 -0
  87. package/dist/agents/evaluator.d.ts +61 -0
  88. package/dist/agents/evaluator.d.ts.map +1 -0
  89. package/dist/agents/evaluator.js +338 -0
  90. package/dist/agents/evaluator.js.map +1 -0
  91. package/dist/agents/executor.d.ts +33 -0
  92. package/dist/agents/executor.d.ts.map +1 -0
  93. package/dist/agents/executor.js +130 -0
  94. package/dist/agents/executor.js.map +1 -0
  95. package/dist/agents/index.d.ts +10 -0
  96. package/dist/agents/index.d.ts.map +1 -0
  97. package/dist/agents/index.js +10 -0
  98. package/dist/agents/index.js.map +1 -0
  99. package/dist/agents/pairMetrics.d.ts +63 -0
  100. package/dist/agents/pairMetrics.d.ts.map +1 -0
  101. package/dist/agents/pairMetrics.js +232 -0
  102. package/dist/agents/pairMetrics.js.map +1 -0
  103. package/dist/agents/pairPipeline.d.ts +184 -0
  104. package/dist/agents/pairPipeline.d.ts.map +1 -0
  105. package/dist/agents/pairPipeline.js +934 -0
  106. package/dist/agents/pairPipeline.js.map +1 -0
  107. package/dist/agents/pairWebhook.d.ts +59 -0
  108. package/dist/agents/pairWebhook.d.ts.map +1 -0
  109. package/dist/agents/pairWebhook.js +242 -0
  110. package/dist/agents/pairWebhook.js.map +1 -0
  111. package/dist/agents/pipelineFormat.d.ts +8 -0
  112. package/dist/agents/pipelineFormat.d.ts.map +1 -0
  113. package/dist/agents/pipelineFormat.js +65 -0
  114. package/dist/agents/pipelineFormat.js.map +1 -0
  115. package/dist/agents/pipelineGuards.d.ts +23 -0
  116. package/dist/agents/pipelineGuards.d.ts.map +1 -0
  117. package/dist/agents/pipelineGuards.js +257 -0
  118. package/dist/agents/pipelineGuards.js.map +1 -0
  119. package/dist/agents/reviewer.d.ts +37 -0
  120. package/dist/agents/reviewer.d.ts.map +1 -0
  121. package/dist/agents/reviewer.js +214 -0
  122. package/dist/agents/reviewer.js.map +1 -0
  123. package/dist/agents/skillDocumenter.d.ts +23 -0
  124. package/dist/agents/skillDocumenter.d.ts.map +1 -0
  125. package/dist/agents/skillDocumenter.js +219 -0
  126. package/dist/agents/skillDocumenter.js.map +1 -0
  127. package/dist/agents/tester.d.ts +37 -0
  128. package/dist/agents/tester.d.ts.map +1 -0
  129. package/dist/agents/tester.js +309 -0
  130. package/dist/agents/tester.js.map +1 -0
  131. package/dist/automation/autonomousRunner.d.ts +145 -0
  132. package/dist/automation/autonomousRunner.d.ts.map +1 -0
  133. package/dist/automation/autonomousRunner.js +1272 -0
  134. package/dist/automation/autonomousRunner.js.map +1 -0
  135. package/dist/automation/dailyReporter.d.ts +26 -0
  136. package/dist/automation/dailyReporter.d.ts.map +1 -0
  137. package/dist/automation/dailyReporter.js +130 -0
  138. package/dist/automation/dailyReporter.js.map +1 -0
  139. package/dist/automation/index.d.ts +5 -0
  140. package/dist/automation/index.d.ts.map +1 -0
  141. package/dist/automation/index.js +5 -0
  142. package/dist/automation/index.js.map +1 -0
  143. package/dist/automation/longRunningMonitor.d.ts +26 -0
  144. package/dist/automation/longRunningMonitor.d.ts.map +1 -0
  145. package/dist/automation/longRunningMonitor.js +356 -0
  146. package/dist/automation/longRunningMonitor.js.map +1 -0
  147. package/dist/automation/prOwnership.d.ts +18 -0
  148. package/dist/automation/prOwnership.d.ts.map +1 -0
  149. package/dist/automation/prOwnership.js +61 -0
  150. package/dist/automation/prOwnership.js.map +1 -0
  151. package/dist/automation/runnerExecution.d.ts +57 -0
  152. package/dist/automation/runnerExecution.d.ts.map +1 -0
  153. package/dist/automation/runnerExecution.js +701 -0
  154. package/dist/automation/runnerExecution.js.map +1 -0
  155. package/dist/automation/runnerState.d.ts +170 -0
  156. package/dist/automation/runnerState.d.ts.map +1 -0
  157. package/dist/automation/runnerState.js +496 -0
  158. package/dist/automation/runnerState.js.map +1 -0
  159. package/dist/automation/runnerTypes.d.ts +57 -0
  160. package/dist/automation/runnerTypes.d.ts.map +1 -0
  161. package/dist/automation/runnerTypes.js +5 -0
  162. package/dist/automation/runnerTypes.js.map +1 -0
  163. package/dist/automation/scheduler.d.ts +75 -0
  164. package/dist/automation/scheduler.d.ts.map +1 -0
  165. package/dist/automation/scheduler.js +402 -0
  166. package/dist/automation/scheduler.js.map +1 -0
  167. package/dist/azdo/azdo.d.ts +70 -0
  168. package/dist/azdo/azdo.d.ts.map +1 -0
  169. package/dist/azdo/azdo.js +328 -0
  170. package/dist/azdo/azdo.js.map +1 -0
  171. package/dist/azdo/index.d.ts +3 -0
  172. package/dist/azdo/index.d.ts.map +1 -0
  173. package/dist/azdo/index.js +3 -0
  174. package/dist/azdo/index.js.map +1 -0
  175. package/dist/azdo/projectUpdater.d.ts +13 -0
  176. package/dist/azdo/projectUpdater.d.ts.map +1 -0
  177. package/dist/azdo/projectUpdater.js +155 -0
  178. package/dist/azdo/projectUpdater.js.map +1 -0
  179. package/dist/azureDevOps/client.d.ts +75 -0
  180. package/dist/azureDevOps/client.d.ts.map +1 -0
  181. package/dist/azureDevOps/client.js +150 -0
  182. package/dist/azureDevOps/client.js.map +1 -0
  183. package/dist/azureDevOps/hierarchy.d.ts +119 -0
  184. package/dist/azureDevOps/hierarchy.d.ts.map +1 -0
  185. package/dist/azureDevOps/hierarchy.js +470 -0
  186. package/dist/azureDevOps/hierarchy.js.map +1 -0
  187. package/dist/azureDevOps/mapper.d.ts +101 -0
  188. package/dist/azureDevOps/mapper.d.ts.map +1 -0
  189. package/dist/azureDevOps/mapper.js +438 -0
  190. package/dist/azureDevOps/mapper.js.map +1 -0
  191. package/dist/azureDevOps/stateMapping.d.ts +15 -0
  192. package/dist/azureDevOps/stateMapping.d.ts.map +1 -0
  193. package/dist/azureDevOps/stateMapping.js +141 -0
  194. package/dist/azureDevOps/stateMapping.js.map +1 -0
  195. package/dist/cli/authHandler.d.ts +13 -0
  196. package/dist/cli/authHandler.d.ts.map +1 -0
  197. package/dist/cli/authHandler.js +70 -0
  198. package/dist/cli/authHandler.js.map +1 -0
  199. package/dist/cli/checkHandler.d.ts +27 -0
  200. package/dist/cli/checkHandler.d.ts.map +1 -0
  201. package/dist/cli/checkHandler.js +560 -0
  202. package/dist/cli/checkHandler.js.map +1 -0
  203. package/dist/cli/daemon.d.ts +30 -0
  204. package/dist/cli/daemon.d.ts.map +1 -0
  205. package/dist/cli/daemon.js +141 -0
  206. package/dist/cli/daemon.js.map +1 -0
  207. package/dist/cli/factoryCommands.d.ts +3 -0
  208. package/dist/cli/factoryCommands.d.ts.map +1 -0
  209. package/dist/cli/factoryCommands.js +165 -0
  210. package/dist/cli/factoryCommands.js.map +1 -0
  211. package/dist/cli/promptHandler.d.ts +13 -0
  212. package/dist/cli/promptHandler.d.ts.map +1 -0
  213. package/dist/cli/promptHandler.js +193 -0
  214. package/dist/cli/promptHandler.js.map +1 -0
  215. package/dist/cli.d.ts +3 -0
  216. package/dist/cli.d.ts.map +1 -0
  217. package/dist/cli.js +320 -0
  218. package/dist/cli.js.map +1 -0
  219. package/dist/core/agentLifecycle.d.ts +322 -0
  220. package/dist/core/agentLifecycle.d.ts.map +1 -0
  221. package/dist/core/agentLifecycle.js +230 -0
  222. package/dist/core/agentLifecycle.js.map +1 -0
  223. package/dist/core/areaMapping.d.ts +9 -0
  224. package/dist/core/areaMapping.d.ts.map +1 -0
  225. package/dist/core/areaMapping.js +37 -0
  226. package/dist/core/areaMapping.js.map +1 -0
  227. package/dist/core/config.d.ts +469 -0
  228. package/dist/core/config.d.ts.map +1 -0
  229. package/dist/core/config.js +780 -0
  230. package/dist/core/config.js.map +1 -0
  231. package/dist/core/dashboardContract.d.ts +204 -0
  232. package/dist/core/dashboardContract.d.ts.map +1 -0
  233. package/dist/core/dashboardContract.js +205 -0
  234. package/dist/core/dashboardContract.js.map +1 -0
  235. package/dist/core/devopsModel.d.ts +138 -0
  236. package/dist/core/devopsModel.d.ts.map +1 -0
  237. package/dist/core/devopsModel.js +137 -0
  238. package/dist/core/devopsModel.js.map +1 -0
  239. package/dist/core/envFile.d.ts +11 -0
  240. package/dist/core/envFile.d.ts.map +1 -0
  241. package/dist/core/envFile.js +104 -0
  242. package/dist/core/envFile.js.map +1 -0
  243. package/dist/core/eventHub.d.ts +220 -0
  244. package/dist/core/eventHub.d.ts.map +1 -0
  245. package/dist/core/eventHub.js +136 -0
  246. package/dist/core/eventHub.js.map +1 -0
  247. package/dist/core/index.d.ts +8 -0
  248. package/dist/core/index.d.ts.map +1 -0
  249. package/dist/core/index.js +7 -0
  250. package/dist/core/index.js.map +1 -0
  251. package/dist/core/laneExecutionState.d.ts +29 -0
  252. package/dist/core/laneExecutionState.d.ts.map +1 -0
  253. package/dist/core/laneExecutionState.js +18 -0
  254. package/dist/core/laneExecutionState.js.map +1 -0
  255. package/dist/core/laneStatus.d.ts +49 -0
  256. package/dist/core/laneStatus.d.ts.map +1 -0
  257. package/dist/core/laneStatus.js +153 -0
  258. package/dist/core/laneStatus.js.map +1 -0
  259. package/dist/core/prSidecar.d.ts +96 -0
  260. package/dist/core/prSidecar.d.ts.map +1 -0
  261. package/dist/core/prSidecar.js +33 -0
  262. package/dist/core/prSidecar.js.map +1 -0
  263. package/dist/core/runtimeConfig.d.ts +6 -0
  264. package/dist/core/runtimeConfig.d.ts.map +1 -0
  265. package/dist/core/runtimeConfig.js +24 -0
  266. package/dist/core/runtimeConfig.js.map +1 -0
  267. package/dist/core/scmProvider.d.ts +19 -0
  268. package/dist/core/scmProvider.d.ts.map +1 -0
  269. package/dist/core/scmProvider.js +38 -0
  270. package/dist/core/scmProvider.js.map +1 -0
  271. package/dist/core/service.d.ts +10 -0
  272. package/dist/core/service.d.ts.map +1 -0
  273. package/dist/core/service.js +297 -0
  274. package/dist/core/service.js.map +1 -0
  275. package/dist/core/traceCollector.d.ts +105 -0
  276. package/dist/core/traceCollector.d.ts.map +1 -0
  277. package/dist/core/traceCollector.js +141 -0
  278. package/dist/core/traceCollector.js.map +1 -0
  279. package/dist/core/types.d.ts +432 -0
  280. package/dist/core/types.d.ts.map +1 -0
  281. package/dist/core/types.js +2 -0
  282. package/dist/core/types.js.map +1 -0
  283. package/dist/core/workItemMapper.d.ts +39 -0
  284. package/dist/core/workItemMapper.d.ts.map +1 -0
  285. package/dist/core/workItemMapper.js +427 -0
  286. package/dist/core/workItemMapper.js.map +1 -0
  287. package/dist/core/workItemModel.d.ts +120 -0
  288. package/dist/core/workItemModel.d.ts.map +1 -0
  289. package/dist/core/workItemModel.js +104 -0
  290. package/dist/core/workItemModel.js.map +1 -0
  291. package/dist/core/workItemPayload.d.ts +195 -0
  292. package/dist/core/workItemPayload.d.ts.map +1 -0
  293. package/dist/core/workItemPayload.js +24 -0
  294. package/dist/core/workItemPayload.js.map +1 -0
  295. package/dist/core/workspaceConfig.d.ts +57 -0
  296. package/dist/core/workspaceConfig.d.ts.map +1 -0
  297. package/dist/core/workspaceConfig.js +184 -0
  298. package/dist/core/workspaceConfig.js.map +1 -0
  299. package/dist/doctor.d.ts +18 -0
  300. package/dist/doctor.d.ts.map +1 -0
  301. package/dist/doctor.js +34 -0
  302. package/dist/doctor.js.map +1 -0
  303. package/dist/factory/activeSkill.d.ts +11 -0
  304. package/dist/factory/activeSkill.d.ts.map +1 -0
  305. package/dist/factory/activeSkill.js +44 -0
  306. package/dist/factory/activeSkill.js.map +1 -0
  307. package/dist/factory/assignment.d.ts +54 -0
  308. package/dist/factory/assignment.d.ts.map +1 -0
  309. package/dist/factory/assignment.js +94 -0
  310. package/dist/factory/assignment.js.map +1 -0
  311. package/dist/factory/auditLog.d.ts +10 -0
  312. package/dist/factory/auditLog.d.ts.map +1 -0
  313. package/dist/factory/auditLog.js +38 -0
  314. package/dist/factory/auditLog.js.map +1 -0
  315. package/dist/factory/closureRequirements.d.ts +12 -0
  316. package/dist/factory/closureRequirements.d.ts.map +1 -0
  317. package/dist/factory/closureRequirements.js +30 -0
  318. package/dist/factory/closureRequirements.js.map +1 -0
  319. package/dist/factory/delegationPrompt.d.ts +3 -0
  320. package/dist/factory/delegationPrompt.d.ts.map +1 -0
  321. package/dist/factory/delegationPrompt.js +16 -0
  322. package/dist/factory/delegationPrompt.js.map +1 -0
  323. package/dist/factory/http.d.ts +3 -0
  324. package/dist/factory/http.d.ts.map +1 -0
  325. package/dist/factory/http.js +555 -0
  326. package/dist/factory/http.js.map +1 -0
  327. package/dist/factory/lifecyclePushMap.d.ts +4 -0
  328. package/dist/factory/lifecyclePushMap.d.ts.map +1 -0
  329. package/dist/factory/lifecyclePushMap.js +7 -0
  330. package/dist/factory/lifecyclePushMap.js.map +1 -0
  331. package/dist/factory/missions.d.ts +125 -0
  332. package/dist/factory/missions.d.ts.map +1 -0
  333. package/dist/factory/missions.js +304 -0
  334. package/dist/factory/missions.js.map +1 -0
  335. package/dist/factory/mode.d.ts +9 -0
  336. package/dist/factory/mode.d.ts.map +1 -0
  337. package/dist/factory/mode.js +30 -0
  338. package/dist/factory/mode.js.map +1 -0
  339. package/dist/factory/operatorActiveSkill.d.ts +15 -0
  340. package/dist/factory/operatorActiveSkill.d.ts.map +1 -0
  341. package/dist/factory/operatorActiveSkill.js +95 -0
  342. package/dist/factory/operatorActiveSkill.js.map +1 -0
  343. package/dist/factory/paseoDispatcher.d.ts +52 -0
  344. package/dist/factory/paseoDispatcher.d.ts.map +1 -0
  345. package/dist/factory/paseoDispatcher.js +122 -0
  346. package/dist/factory/paseoDispatcher.js.map +1 -0
  347. package/dist/factory/paseoLifecycle.d.ts +32 -0
  348. package/dist/factory/paseoLifecycle.d.ts.map +1 -0
  349. package/dist/factory/paseoLifecycle.js +260 -0
  350. package/dist/factory/paseoLifecycle.js.map +1 -0
  351. package/dist/factory/paths.d.ts +31 -0
  352. package/dist/factory/paths.d.ts.map +1 -0
  353. package/dist/factory/paths.js +139 -0
  354. package/dist/factory/paths.js.map +1 -0
  355. package/dist/factory/progressWatchdog.d.ts +58 -0
  356. package/dist/factory/progressWatchdog.d.ts.map +1 -0
  357. package/dist/factory/progressWatchdog.js +160 -0
  358. package/dist/factory/progressWatchdog.js.map +1 -0
  359. package/dist/factory/roster.d.ts +59 -0
  360. package/dist/factory/roster.d.ts.map +1 -0
  361. package/dist/factory/roster.js +116 -0
  362. package/dist/factory/roster.js.map +1 -0
  363. package/dist/factory/runtime.d.ts +44 -0
  364. package/dist/factory/runtime.d.ts.map +1 -0
  365. package/dist/factory/runtime.js +238 -0
  366. package/dist/factory/runtime.js.map +1 -0
  367. package/dist/factory/sync.d.ts +29 -0
  368. package/dist/factory/sync.d.ts.map +1 -0
  369. package/dist/factory/sync.js +77 -0
  370. package/dist/factory/sync.js.map +1 -0
  371. package/dist/factory/workitemQueues.d.ts +37 -0
  372. package/dist/factory/workitemQueues.d.ts.map +1 -0
  373. package/dist/factory/workitemQueues.js +99 -0
  374. package/dist/factory/workitemQueues.js.map +1 -0
  375. package/dist/factory/workitemTriage.d.ts +9 -0
  376. package/dist/factory/workitemTriage.d.ts.map +1 -0
  377. package/dist/factory/workitemTriage.js +81 -0
  378. package/dist/factory/workitemTriage.js.map +1 -0
  379. package/dist/hooks.d.ts +18 -0
  380. package/dist/hooks.d.ts.map +1 -0
  381. package/dist/hooks.js +96 -0
  382. package/dist/hooks.js.map +1 -0
  383. package/dist/index.d.ts +3 -0
  384. package/dist/index.d.ts.map +1 -0
  385. package/dist/index.js +90 -0
  386. package/dist/index.js.map +1 -0
  387. package/dist/install/agentCatalog.d.ts +7 -0
  388. package/dist/install/agentCatalog.d.ts.map +1 -0
  389. package/dist/install/agentCatalog.js +28 -0
  390. package/dist/install/agentCatalog.js.map +1 -0
  391. package/dist/install/bundlePaths.d.ts +10 -0
  392. package/dist/install/bundlePaths.d.ts.map +1 -0
  393. package/dist/install/bundlePaths.js +30 -0
  394. package/dist/install/bundlePaths.js.map +1 -0
  395. package/dist/install/codex.d.ts +43 -0
  396. package/dist/install/codex.d.ts.map +1 -0
  397. package/dist/install/codex.js +207 -0
  398. package/dist/install/codex.js.map +1 -0
  399. package/dist/install/enactHome.d.ts +37 -0
  400. package/dist/install/enactHome.d.ts.map +1 -0
  401. package/dist/install/enactHome.js +152 -0
  402. package/dist/install/enactHome.js.map +1 -0
  403. package/dist/install/plugins.d.ts +115 -0
  404. package/dist/install/plugins.d.ts.map +1 -0
  405. package/dist/install/plugins.js +259 -0
  406. package/dist/install/plugins.js.map +1 -0
  407. package/dist/install/setup.d.ts +33 -0
  408. package/dist/install/setup.d.ts.map +1 -0
  409. package/dist/install/setup.js +167 -0
  410. package/dist/install/setup.js.map +1 -0
  411. package/dist/locale/en.d.ts +3 -0
  412. package/dist/locale/en.d.ts.map +1 -0
  413. package/dist/locale/en.js +435 -0
  414. package/dist/locale/en.js.map +1 -0
  415. package/dist/locale/index.d.ts +28 -0
  416. package/dist/locale/index.d.ts.map +1 -0
  417. package/dist/locale/index.js +84 -0
  418. package/dist/locale/index.js.map +1 -0
  419. package/dist/locale/prompts/en.d.ts +3 -0
  420. package/dist/locale/prompts/en.d.ts.map +1 -0
  421. package/dist/locale/prompts/en.js +254 -0
  422. package/dist/locale/prompts/en.js.map +1 -0
  423. package/dist/locale/types.d.ts +433 -0
  424. package/dist/locale/types.d.ts.map +1 -0
  425. package/dist/locale/types.js +5 -0
  426. package/dist/locale/types.js.map +1 -0
  427. package/dist/mcp/server.d.ts +489 -0
  428. package/dist/mcp/server.d.ts.map +1 -0
  429. package/dist/mcp/server.js +597 -0
  430. package/dist/mcp/server.js.map +1 -0
  431. package/dist/orchestration/decisionEngine.d.ts +175 -0
  432. package/dist/orchestration/decisionEngine.d.ts.map +1 -0
  433. package/dist/orchestration/decisionEngine.js +471 -0
  434. package/dist/orchestration/decisionEngine.js.map +1 -0
  435. package/dist/orchestration/index.d.ts +5 -0
  436. package/dist/orchestration/index.d.ts.map +1 -0
  437. package/dist/orchestration/index.js +5 -0
  438. package/dist/orchestration/index.js.map +1 -0
  439. package/dist/orchestration/workItemParser.d.ts +67 -0
  440. package/dist/orchestration/workItemParser.d.ts.map +1 -0
  441. package/dist/orchestration/workItemParser.js +560 -0
  442. package/dist/orchestration/workItemParser.js.map +1 -0
  443. package/dist/orchestration/workItemScheduler.d.ts +141 -0
  444. package/dist/orchestration/workItemScheduler.d.ts.map +1 -0
  445. package/dist/orchestration/workItemScheduler.js +317 -0
  446. package/dist/orchestration/workItemScheduler.js.map +1 -0
  447. package/dist/orchestration/workflow.d.ts +145 -0
  448. package/dist/orchestration/workflow.d.ts.map +1 -0
  449. package/dist/orchestration/workflow.js +301 -0
  450. package/dist/orchestration/workflow.js.map +1 -0
  451. package/dist/providers/codexSessions.d.ts +93 -0
  452. package/dist/providers/codexSessions.d.ts.map +1 -0
  453. package/dist/providers/codexSessions.js +366 -0
  454. package/dist/providers/codexSessions.js.map +1 -0
  455. package/dist/registry/bsDetector.d.ts +24 -0
  456. package/dist/registry/bsDetector.d.ts.map +1 -0
  457. package/dist/registry/bsDetector.js +276 -0
  458. package/dist/registry/bsDetector.js.map +1 -0
  459. package/dist/registry/entityScanner.d.ts +36 -0
  460. package/dist/registry/entityScanner.d.ts.map +1 -0
  461. package/dist/registry/entityScanner.js +693 -0
  462. package/dist/registry/entityScanner.js.map +1 -0
  463. package/dist/registry/index.d.ts +9 -0
  464. package/dist/registry/index.d.ts.map +1 -0
  465. package/dist/registry/index.js +13 -0
  466. package/dist/registry/index.js.map +1 -0
  467. package/dist/registry/schema.d.ts +307 -0
  468. package/dist/registry/schema.d.ts.map +1 -0
  469. package/dist/registry/schema.js +139 -0
  470. package/dist/registry/schema.js.map +1 -0
  471. package/dist/registry/sqliteStore.d.ts +101 -0
  472. package/dist/registry/sqliteStore.d.ts.map +1 -0
  473. package/dist/registry/sqliteStore.js +688 -0
  474. package/dist/registry/sqliteStore.js.map +1 -0
  475. package/dist/registry/workItemBridge.d.ts +8 -0
  476. package/dist/registry/workItemBridge.d.ts.map +1 -0
  477. package/dist/registry/workItemBridge.js +30 -0
  478. package/dist/registry/workItemBridge.js.map +1 -0
  479. package/dist/runners/cliRunner.d.ts +11 -0
  480. package/dist/runners/cliRunner.d.ts.map +1 -0
  481. package/dist/runners/cliRunner.js +193 -0
  482. package/dist/runners/cliRunner.js.map +1 -0
  483. package/dist/support/apiCache.d.ts +85 -0
  484. package/dist/support/apiCache.d.ts.map +1 -0
  485. package/dist/support/apiCache.js +163 -0
  486. package/dist/support/apiCache.js.map +1 -0
  487. package/dist/support/chat.d.ts +3 -0
  488. package/dist/support/chat.d.ts.map +1 -0
  489. package/dist/support/chat.js +305 -0
  490. package/dist/support/chat.js.map +1 -0
  491. package/dist/support/chatBackend.d.ts +25 -0
  492. package/dist/support/chatBackend.d.ts.map +1 -0
  493. package/dist/support/chatBackend.js +289 -0
  494. package/dist/support/chatBackend.js.map +1 -0
  495. package/dist/support/chatTui.d.ts +3 -0
  496. package/dist/support/chatTui.d.ts.map +1 -0
  497. package/dist/support/chatTui.js +1082 -0
  498. package/dist/support/chatTui.js.map +1 -0
  499. package/dist/support/costTracker.d.ts +29 -0
  500. package/dist/support/costTracker.d.ts.map +1 -0
  501. package/dist/support/costTracker.js +113 -0
  502. package/dist/support/costTracker.js.map +1 -0
  503. package/dist/support/dashboardHtml.d.ts +5 -0
  504. package/dist/support/dashboardHtml.d.ts.map +1 -0
  505. package/dist/support/dashboardHtml.js +2629 -0
  506. package/dist/support/dashboardHtml.js.map +1 -0
  507. package/dist/support/dev.d.ts +55 -0
  508. package/dist/support/dev.d.ts.map +1 -0
  509. package/dist/support/dev.js +298 -0
  510. package/dist/support/dev.js.map +1 -0
  511. package/dist/support/editParser.d.ts +37 -0
  512. package/dist/support/editParser.d.ts.map +1 -0
  513. package/dist/support/editParser.js +365 -0
  514. package/dist/support/editParser.js.map +1 -0
  515. package/dist/support/ghosttyThemeCatalog.generated.d.ts +2 -0
  516. package/dist/support/ghosttyThemeCatalog.generated.d.ts.map +1 -0
  517. package/dist/support/ghosttyThemeCatalog.generated.js +11116 -0
  518. package/dist/support/ghosttyThemeCatalog.generated.js.map +1 -0
  519. package/dist/support/gitStatus.d.ts +21 -0
  520. package/dist/support/gitStatus.d.ts.map +1 -0
  521. package/dist/support/gitStatus.js +108 -0
  522. package/dist/support/gitStatus.js.map +1 -0
  523. package/dist/support/gitTracker.d.ts +30 -0
  524. package/dist/support/gitTracker.d.ts.map +1 -0
  525. package/dist/support/gitTracker.js +143 -0
  526. package/dist/support/gitTracker.js.map +1 -0
  527. package/dist/support/index.d.ts +12 -0
  528. package/dist/support/index.d.ts.map +1 -0
  529. package/dist/support/index.js +12 -0
  530. package/dist/support/index.js.map +1 -0
  531. package/dist/support/planner.d.ts +64 -0
  532. package/dist/support/planner.d.ts.map +1 -0
  533. package/dist/support/planner.js +396 -0
  534. package/dist/support/planner.js.map +1 -0
  535. package/dist/support/projectMapper.d.ts +46 -0
  536. package/dist/support/projectMapper.d.ts.map +1 -0
  537. package/dist/support/projectMapper.js +273 -0
  538. package/dist/support/projectMapper.js.map +1 -0
  539. package/dist/support/pty-helper.py +117 -0
  540. package/dist/support/quotaTracker.d.ts +29 -0
  541. package/dist/support/quotaTracker.d.ts.map +1 -0
  542. package/dist/support/quotaTracker.js +89 -0
  543. package/dist/support/quotaTracker.js.map +1 -0
  544. package/dist/support/rateLimiter.d.ts +101 -0
  545. package/dist/support/rateLimiter.d.ts.map +1 -0
  546. package/dist/support/rateLimiter.js +219 -0
  547. package/dist/support/rateLimiter.js.map +1 -0
  548. package/dist/support/rollback.d.ts +61 -0
  549. package/dist/support/rollback.d.ts.map +1 -0
  550. package/dist/support/rollback.js +329 -0
  551. package/dist/support/rollback.js.map +1 -0
  552. package/dist/support/sharedShell.d.ts +17 -0
  553. package/dist/support/sharedShell.d.ts.map +1 -0
  554. package/dist/support/sharedShell.js +439 -0
  555. package/dist/support/sharedShell.js.map +1 -0
  556. package/dist/support/stuckDetector.d.ts +68 -0
  557. package/dist/support/stuckDetector.d.ts.map +1 -0
  558. package/dist/support/stuckDetector.js +174 -0
  559. package/dist/support/stuckDetector.js.map +1 -0
  560. package/dist/support/terminalBridge.d.ts +18 -0
  561. package/dist/support/terminalBridge.d.ts.map +1 -0
  562. package/dist/support/terminalBridge.js +553 -0
  563. package/dist/support/terminalBridge.js.map +1 -0
  564. package/dist/support/timeWindow.d.ts +60 -0
  565. package/dist/support/timeWindow.d.ts.map +1 -0
  566. package/dist/support/timeWindow.js +236 -0
  567. package/dist/support/timeWindow.js.map +1 -0
  568. package/dist/support/uiThemes.d.ts +44 -0
  569. package/dist/support/uiThemes.d.ts.map +1 -0
  570. package/dist/support/uiThemes.js +290 -0
  571. package/dist/support/uiThemes.js.map +1 -0
  572. package/dist/support/web.d.ts +29 -0
  573. package/dist/support/web.d.ts.map +1 -0
  574. package/dist/support/web.js +1097 -0
  575. package/dist/support/web.js.map +1 -0
  576. package/dist/support/worktreeManager.d.ts +20 -0
  577. package/dist/support/worktreeManager.d.ts.map +1 -0
  578. package/dist/support/worktreeManager.js +140 -0
  579. package/dist/support/worktreeManager.js.map +1 -0
  580. package/dist/task_state_model.py +55 -0
  581. package/dist/workItemState/store.d.ts +122 -0
  582. package/dist/workItemState/store.d.ts.map +1 -0
  583. package/dist/workItemState/store.js +438 -0
  584. package/dist/workItemState/store.js.map +1 -0
  585. package/dist/workItems/azdoBridge.d.ts +42 -0
  586. package/dist/workItems/azdoBridge.d.ts.map +1 -0
  587. package/dist/workItems/azdoBridge.js +143 -0
  588. package/dist/workItems/azdoBridge.js.map +1 -0
  589. package/dist/workItems/azdoSyncRuntime.d.ts +28 -0
  590. package/dist/workItems/azdoSyncRuntime.d.ts.map +1 -0
  591. package/dist/workItems/azdoSyncRuntime.js +158 -0
  592. package/dist/workItems/azdoSyncRuntime.js.map +1 -0
  593. package/dist/workItems/azureDevOpsSync.d.ts +128 -0
  594. package/dist/workItems/azureDevOpsSync.d.ts.map +1 -0
  595. package/dist/workItems/azureDevOpsSync.js +748 -0
  596. package/dist/workItems/azureDevOpsSync.js.map +1 -0
  597. package/dist/workItems/helpers.d.ts +11 -0
  598. package/dist/workItems/helpers.d.ts.map +1 -0
  599. package/dist/workItems/helpers.js +17 -0
  600. package/dist/workItems/helpers.js.map +1 -0
  601. package/dist/workItems/index.d.ts +21 -0
  602. package/dist/workItems/index.d.ts.map +1 -0
  603. package/dist/workItems/index.js +89 -0
  604. package/dist/workItems/index.js.map +1 -0
  605. package/dist/workItems/localWorkItemFetcher.d.ts +55 -0
  606. package/dist/workItems/localWorkItemFetcher.d.ts.map +1 -0
  607. package/dist/workItems/localWorkItemFetcher.js +209 -0
  608. package/dist/workItems/localWorkItemFetcher.js.map +1 -0
  609. package/dist/workItems/migrations/001_rename_workItem_to_work_item.sql +10 -0
  610. package/dist/workItems/postgresStore.d.ts +78 -0
  611. package/dist/workItems/postgresStore.d.ts.map +1 -0
  612. package/dist/workItems/postgresStore.js +937 -0
  613. package/dist/workItems/postgresStore.js.map +1 -0
  614. package/dist/workItems/schema.d.ts +257 -0
  615. package/dist/workItems/schema.d.ts.map +1 -0
  616. package/dist/workItems/schema.js +176 -0
  617. package/dist/workItems/schema.js.map +1 -0
  618. package/dist/workItems/sqliteStore.d.ts +124 -0
  619. package/dist/workItems/sqliteStore.d.ts.map +1 -0
  620. package/dist/workItems/sqliteStore.js +713 -0
  621. package/dist/workItems/sqliteStore.js.map +1 -0
  622. package/dist/workItems/workItemBoardHtml.d.ts +5 -0
  623. package/dist/workItems/workItemBoardHtml.d.ts.map +1 -0
  624. package/dist/workItems/workItemBoardHtml.js +2192 -0
  625. package/dist/workItems/workItemBoardHtml.js.map +1 -0
  626. package/package.json +99 -0
  627. package/templates/AGENTS.md +432 -0
  628. package/templates/BOOT.md +25 -0
  629. package/templates/BOOTSTRAP.md +50 -0
  630. package/templates/CHANGELOG_AUDIT.md +74 -0
  631. package/templates/HEARTBEAT.md +86 -0
  632. package/templates/IDENTITY.md +27 -0
  633. package/templates/PR_LAND.md +75 -0
  634. package/templates/PR_REVIEW.md +97 -0
  635. package/templates/SOUL.dev.md +52 -0
  636. package/templates/SOUL.md +81 -0
  637. package/templates/TOOLS.md +52 -0
  638. package/templates/USER.md +22 -0
  639. package/templates/WORKITEM_ANALYSIS.md +31 -0
  640. package/templates/agents/executor.md +26 -0
  641. package/templates/agents/plan.md +22 -0
  642. package/templates/agents/ralph.md +37 -0
  643. package/templates/agents/review.md +22 -0
  644. package/templates/agents/team.md +39 -0
@@ -0,0 +1,934 @@
1
+ // ============================================
2
+ // EnactFactory - Pair Pipeline
3
+ // Executor → Reviewer → Tester → Documenter pipeline
4
+ // ============================================
5
+ import { EventEmitter } from 'node:events';
6
+ import { aggregateCosts, formatCost } from '../support/costTracker.js';
7
+ import { broadcastEvent } from '../core/eventHub.js';
8
+ import { getConfidenceAction, getConfidenceProfile, } from '../agents/agentPair.js';
9
+ import * as agentPair from '../agents/agentPair.js';
10
+ import { runGuards } from '../agents/pipelineGuards.js';
11
+ import * as executorAgent from '../agents/executor.js';
12
+ import * as reviewerAgent from '../agents/reviewer.js';
13
+ import * as testerAgent from '../agents/tester.js';
14
+ import { inferProviderFromModel } from '../support/chatBackend.js';
15
+ const ADAPTER_NAMES = new Set(['claude', 'codex', 'responses', 'cursor', 'hermes', 'opencode']);
16
+ function isAdapterName(v) {
17
+ return v !== undefined && ADAPTER_NAMES.has(v);
18
+ }
19
+ import * as documenterAgent from '../agents/documenter.js';
20
+ import * as auditorAgent from '../agents/auditor.js';
21
+ import * as skillDocumenterAgent from '../agents/skillDocumenter.js';
22
+ import { createStuckDetector } from '../support/stuckDetector.js';
23
+ /**
24
+ * Build a consistent workItem prefix for logging across all pipeline stages.
25
+ * Format: "ProjectName | INT-XXX | worktree/abc123" or "ProjectName | INT-XXX"
26
+ */
27
+ export function buildWorkItemPrefix(workItem, projectPath) {
28
+ const parts = [];
29
+ const projectName = workItem.azdoProject?.name || projectPath.split('/').pop() || 'unknown';
30
+ parts.push(projectName);
31
+ if (workItem.workItemIdentifier) {
32
+ parts.push(workItem.workItemIdentifier);
33
+ }
34
+ else if (workItem.workItemId) {
35
+ parts.push(workItem.workItemId.slice(0, 8));
36
+ }
37
+ // Detect worktree path
38
+ const worktreeMatch = projectPath.match(/worktree\/([a-f0-9-]+)/);
39
+ if (worktreeMatch) {
40
+ parts.push(`worktree/${worktreeMatch[1].slice(0, 8)}`);
41
+ }
42
+ return parts.join(' | ');
43
+ }
44
+ // Pair Pipeline
45
+ export class PairPipeline extends EventEmitter {
46
+ config;
47
+ stuckDetector;
48
+ jobProfiles;
49
+ constructor(config) {
50
+ super();
51
+ this.config = {
52
+ continueOnTestFail: false,
53
+ skipDocumenterIfNoChange: true,
54
+ maxIterations: 3,
55
+ ...config,
56
+ };
57
+ // Initialize stuck detector
58
+ this.stuckDetector = createStuckDetector({
59
+ sameErrorRepeat: 2,
60
+ revisionLoop: 4,
61
+ });
62
+ this.jobProfiles = config.jobProfiles ?? [];
63
+ }
64
+ getExecutorConfidenceProfile(context, stageModel) {
65
+ const executorModel = stageModel ?? this.getModelForRole('coder', context.workItem);
66
+ const adapterName = inferProviderFromModel(executorModel);
67
+ return getConfidenceProfile(adapterName ?? 'default');
68
+ }
69
+ matchesProfile(workItem, profile) {
70
+ const estimate = workItem.estimatedMinutes ?? 0;
71
+ if (profile.minMinutes != null && estimate < profile.minMinutes)
72
+ return false;
73
+ if (profile.maxMinutes != null && estimate > profile.maxMinutes)
74
+ return false;
75
+ if (profile.priority != null && workItem.priority !== profile.priority)
76
+ return false;
77
+ return true;
78
+ }
79
+ getProfileForWorkItem(workItem) {
80
+ if (!this.jobProfiles || this.jobProfiles.length === 0)
81
+ return undefined;
82
+ return this.jobProfiles.find((profile) => this.matchesProfile(workItem, profile));
83
+ }
84
+ getModelForRole(stage, workItem) {
85
+ const profile = this.getProfileForWorkItem(workItem);
86
+ return profile?.roles?.[stage] || this.config.stageConfigs?.[stage]?.model;
87
+ }
88
+ // ============================================
89
+ // Main Execution
90
+ // ============================================
91
+ /**
92
+ * Run pipeline
93
+ *
94
+ * 1 iteration = full pass through Executor → Reviewer → Tester
95
+ * On failure at any stage, returns to Executor (up to maxIterations)
96
+ */
97
+ async run(workItem, projectPath) {
98
+ const startTime = Date.now();
99
+ const stages = [];
100
+ const maxIterations = this.config.maxIterations ?? 3;
101
+ // Reset stuck detector (new pipeline run)
102
+ this.stuckDetector.reset();
103
+ // Create session
104
+ const session = agentPair.createPairSession({
105
+ workItemId: workItem.workItemIdentifier || workItem.workItemId || workItem.id,
106
+ workItemTitle: workItem.title,
107
+ workItemDescription: workItem.description || '',
108
+ projectPath,
109
+ maxAttempts: maxIterations,
110
+ models: {
111
+ coder: this.config.stageConfigs?.coder?.model,
112
+ critic: this.config.stageConfigs?.critic?.model,
113
+ },
114
+ });
115
+ const workItemPrefix = buildWorkItemPrefix(workItem, projectPath);
116
+ const context = {
117
+ workItem,
118
+ projectPath,
119
+ session,
120
+ config: this.config,
121
+ currentIteration: 0,
122
+ workItemPrefix,
123
+ };
124
+ try {
125
+ // Full iteration loop: Executor → Reviewer → Tester
126
+ const iterationResult = await this.runFullIterationLoop(context, stages);
127
+ if (!iterationResult.success) {
128
+ return this.buildResult(context, stages, startTime);
129
+ }
130
+ // Run Documenter after all stages pass
131
+ if (this.hasStage('documenter') && context.executorResult?.success) {
132
+ if (this.config.skipDocumenterIfNoChange &&
133
+ (!context.executorResult.filesChanged || context.executorResult.filesChanged.length === 0)) {
134
+ console.log(`[${context.workItemPrefix}] Skipping documenter: no files changed`);
135
+ }
136
+ else {
137
+ const documenterResult = await this.runStage('documenter', context);
138
+ stages.push(documenterResult);
139
+ // Documenter failure does not cause overall failure
140
+ }
141
+ }
142
+ // Auditor (post-success, non-blocking)
143
+ if (this.hasStage('auditor') && context.executorResult?.success) {
144
+ const auditorFileThreshold = this.config.skipAuditorUnderFileCount ?? 3;
145
+ const auditorChangedFiles = context.executorResult.filesChanged || [];
146
+ if (auditorChangedFiles.length < auditorFileThreshold) {
147
+ console.log(`[${context.workItemPrefix}] Skipping auditor: ${auditorChangedFiles.length} files changed (threshold: ${auditorFileThreshold})`);
148
+ }
149
+ else {
150
+ const auditorResult = await this.runStage('auditor', context);
151
+ stages.push(auditorResult);
152
+ // Auditor failure does not affect overall success
153
+ }
154
+ }
155
+ // Skill Documenter (post-success, non-blocking)
156
+ if (this.hasStage('stage-documenter') && context.executorResult?.success) {
157
+ const sdResult = await this.runStage('stage-documenter', context);
158
+ stages.push(sdResult);
159
+ // Skill Documenter failure does not affect overall success
160
+ }
161
+ // Success
162
+ agentPair.updateSessionStatus(session.id, 'approved');
163
+ return this.buildResult(context, stages, startTime);
164
+ }
165
+ catch (error) {
166
+ console.error('[%s] Error:', context.workItemPrefix, error);
167
+ agentPair.updateSessionStatus(session.id, 'failed');
168
+ return {
169
+ success: false,
170
+ sessionId: session.id,
171
+ stages,
172
+ finalStatus: 'failed',
173
+ totalDuration: Date.now() - startTime,
174
+ iterations: context.currentIteration,
175
+ executorResult: context.executorResult,
176
+ reviewResult: context.reviewResult,
177
+ testerResult: context.testerResult,
178
+ documenterResult: context.documenterResult,
179
+ workItemContext: {
180
+ workItemIdentifier: context.workItem.workItemIdentifier || context.workItem.workItemId,
181
+ projectName: context.workItem.azdoProject?.name,
182
+ projectPath: context.projectPath,
183
+ workItemTitle: context.workItem.title,
184
+ },
185
+ };
186
+ }
187
+ }
188
+ // ============================================
189
+ // Stage Execution
190
+ // ============================================
191
+ /**
192
+ * Executor에 주입할 코드 컨텍스트 수집
193
+ * Draft 분석이 있으면 재사용, 없으면 직접 수집
194
+ */
195
+ async collectExecutorContext() {
196
+ try {
197
+ const wc = {};
198
+ const draft = this.config.draftAnalysis;
199
+ // Draft 분석 결과가 있으면 우선 사용 (중복 API 호출 방지)
200
+ if (draft) {
201
+ wc.draftAnalysis = {
202
+ workItemType: draft.workItemType,
203
+ intentSummary: draft.intentSummary,
204
+ relevantFiles: draft.relevantFiles,
205
+ suggestedApproach: draft.suggestedApproach,
206
+ projectStats: draft.projectStats,
207
+ };
208
+ if (draft.registrySnapshot && draft.registrySnapshot.length > 0) {
209
+ wc.registryBriefs = draft.registrySnapshot;
210
+ }
211
+ }
212
+ if (!wc.registryBriefs && !wc.draftAnalysis)
213
+ return undefined;
214
+ return wc;
215
+ }
216
+ catch (err) {
217
+ console.warn('[Pipeline] Executor context collection failed (non-blocking):', err);
218
+ return undefined;
219
+ }
220
+ }
221
+ /**
222
+ * Check if a stage is enabled
223
+ */
224
+ hasStage(stage) {
225
+ return this.config.stages.includes(stage);
226
+ }
227
+ /**
228
+ * Run a single stage
229
+ */
230
+ async runStage(stage, context, overrides) {
231
+ const startTime = Date.now();
232
+ const stageModel = overrides?.model ?? this.getModelForRole(stage, context.workItem);
233
+ // Priority 1: Explicit provider prefix in model (e.g. "codex:gpt-5.4")
234
+ let adapterName = inferProviderFromModel(stageModel);
235
+ // Priority 2: Explicit adapter configured for this role in the root config.toml
236
+ const roleConfig = this.config.stageConfigs?.[stage];
237
+ if (roleConfig?.adapter) {
238
+ adapterName = roleConfig.adapter;
239
+ }
240
+ const prefix = context.workItemPrefix;
241
+ console.log(`[${prefix}] Stage starting: ${stage} (model: ${stageModel || 'default'}, adapter: ${adapterName || 'default'})`);
242
+ this.emit('stage:start', { stage, context });
243
+ broadcastEvent({ type: 'pipeline:stage', data: { workItemId: context.workItem.id, stage, status: 'start', model: stageModel } });
244
+ if (this.config.verbose) {
245
+ this.emit('log', { line: `[verbose] Stage: ${stage} | model: ${stageModel ?? 'default'} | iteration: ${context.currentIteration}` });
246
+ }
247
+ try {
248
+ let result;
249
+ switch (stage) {
250
+ case 'coder': {
251
+ agentPair.updateSessionStatus(context.session.id, 'working');
252
+ const workItemId = context.workItem.id;
253
+ const onLog = (line) => broadcastEvent({ type: 'log', data: { workItemId, stage: 'coder', line: `[${prefix}] ${line}` } });
254
+ // Check if fresh context should be used (after N failures)
255
+ const useFreshContext = agentPair.shouldUseFreshContext(context.session.id);
256
+ if (useFreshContext) {
257
+ console.log(`[${prefix}] Using fresh context for executor (retry with clean slate)`);
258
+ agentPair.consumeFreshContext(context.session.id);
259
+ onLog('🔄 Using fresh context (previous attempts failed)');
260
+ }
261
+ // 코드 컨텍스트 수집 (첫 시도 정확도 향상 목적)
262
+ const executorContext = await this.collectExecutorContext();
263
+ if (executorContext && this.config.verbose) {
264
+ const briefCount = executorContext.registryBriefs?.length ?? 0;
265
+ this.emit('log', { line: `[verbose] Executor context: ${briefCount} file briefs` });
266
+ }
267
+ result = await executorAgent.runExecutor({
268
+ workItemTitle: context.workItem.title,
269
+ workItemDescription: context.workItem.description || '',
270
+ projectPath: context.projectPath,
271
+ previousFeedback: useFreshContext
272
+ ? undefined // Fresh context: no previous feedback
273
+ : (context.reviewResult
274
+ ? reviewerAgent.buildRevisionPrompt(context.reviewResult)
275
+ : undefined),
276
+ timeoutMs: this.config.stageConfigs?.coder?.timeoutMs ?? 0,
277
+ model: stageModel,
278
+ maxTurns: this.config.stageConfigs?.coder?.maxTurns,
279
+ adapterName: adapterName,
280
+ workItemIdentifier: context.workItem.workItemIdentifier || context.workItem.workItemId,
281
+ projectName: context.workItem.azdoProject?.name,
282
+ onLog,
283
+ processContext: { workItemId: context.workItem.id, stage: 'coder' },
284
+ executorContext,
285
+ });
286
+ agentPair.saveExecutorResult(context.session.id, result);
287
+ context.executorResult = result;
288
+ // Verbose: emit detailed executor result info
289
+ if (this.config.verbose) {
290
+ const wr = result;
291
+ if (wr.filesChanged?.length) {
292
+ this.emit('log', { line: `[verbose] Files changed: ${wr.filesChanged.join(', ')}` });
293
+ }
294
+ if (wr.commands?.length) {
295
+ this.emit('log', { line: `[verbose] Commands executed: ${wr.commands.join('; ')}` });
296
+ }
297
+ if (wr.confidencePercent != null) {
298
+ this.emit('log', { line: `[verbose] Executor confidence: ${wr.confidencePercent}%` });
299
+ }
300
+ if (wr.haltReason) {
301
+ this.emit('log', { line: `[verbose] Executor halt reason: ${wr.haltReason}` });
302
+ }
303
+ }
304
+ // Track confidence and check for degradation
305
+ const attempt = context.session.executor.attempts;
306
+ agentPair.updateConfidenceTracker(context.session.id, result, attempt);
307
+ break;
308
+ }
309
+ case 'critic':
310
+ result = await this.runReviewerStage(context, {
311
+ executorResult: context.executorResult,
312
+ stageModel,
313
+ adapterName,
314
+ criticOverrides: overrides,
315
+ });
316
+ context.reviewResult = result;
317
+ agentPair.saveReviewerResult(context.session.id, result);
318
+ break;
319
+ case 'tester':
320
+ if (!context.executorResult) {
321
+ throw new Error('Executor result required for tester');
322
+ }
323
+ result = await testerAgent.runTester({
324
+ workItemTitle: context.workItem.title,
325
+ workItemDescription: context.workItem.description || '',
326
+ executorResult: context.executorResult,
327
+ projectPath: context.projectPath,
328
+ timeoutMs: this.config.stageConfigs?.tester?.timeoutMs ?? 0,
329
+ model: stageModel,
330
+ maxTurns: this.config.stageConfigs?.tester?.maxTurns,
331
+ adapterName: adapterName,
332
+ });
333
+ context.testerResult = result;
334
+ // Verbose: emit tester details
335
+ if (this.config.verbose) {
336
+ const tr = result;
337
+ this.emit('log', { line: `[verbose] Tests passed: ${tr.testsPassed}, failed: ${tr.testsFailed}${tr.coverage != null ? `, coverage: ${tr.coverage}%` : ''}` });
338
+ }
339
+ break;
340
+ case 'documenter':
341
+ if (!context.executorResult) {
342
+ throw new Error('Executor result required for documenter');
343
+ }
344
+ result = await documenterAgent.runDocumenter({
345
+ workItemTitle: context.workItem.title,
346
+ workItemDescription: context.workItem.description || '',
347
+ executorResult: context.executorResult,
348
+ projectPath: context.projectPath,
349
+ timeoutMs: this.config.stageConfigs?.documenter?.timeoutMs ?? 0,
350
+ model: this.config.stageConfigs?.documenter?.model,
351
+ maxTurns: this.config.stageConfigs?.documenter?.maxTurns,
352
+ adapterName: this.config.stageConfigs?.documenter?.adapter,
353
+ });
354
+ context.documenterResult = result;
355
+ break;
356
+ case 'auditor':
357
+ if (!context.executorResult) {
358
+ throw new Error('Executor result required for auditor');
359
+ }
360
+ result = await auditorAgent.runAuditor({
361
+ workItemTitle: context.workItem.title,
362
+ workItemDescription: context.workItem.description || '',
363
+ executorResult: context.executorResult,
364
+ projectPath: context.projectPath,
365
+ timeoutMs: this.config.stageConfigs?.auditor?.timeoutMs ?? 0,
366
+ model: this.config.stageConfigs?.auditor?.model,
367
+ maxTurns: this.config.stageConfigs?.auditor?.maxTurns,
368
+ adapterName: this.config.stageConfigs?.auditor?.adapter,
369
+ });
370
+ context.auditorResult = result;
371
+ break;
372
+ case 'stage-documenter':
373
+ if (!context.executorResult) {
374
+ throw new Error('Executor result required for stage-documenter');
375
+ }
376
+ result = await skillDocumenterAgent.runSkillDocumenter({
377
+ workItemTitle: context.workItem.title,
378
+ workItemDescription: context.workItem.description || '',
379
+ executorResult: context.executorResult,
380
+ projectPath: context.projectPath,
381
+ timeoutMs: this.config.stageConfigs?.['stage-documenter']?.timeoutMs ?? 0,
382
+ model: this.config.stageConfigs?.['stage-documenter']?.model,
383
+ maxTurns: this.config.stageConfigs?.['stage-documenter']?.maxTurns,
384
+ adapterName: this.config.stageConfigs?.['stage-documenter']?.adapter,
385
+ });
386
+ context.skillDocumenterResult = result;
387
+ break;
388
+ default:
389
+ throw new Error(`Unknown stage: ${stage}`);
390
+ }
391
+ const completedAt = Date.now();
392
+ const stageResult = {
393
+ stage,
394
+ success: this.isStageSuccess(stage, result),
395
+ result,
396
+ duration: completedAt - startTime,
397
+ startedAt: startTime,
398
+ completedAt,
399
+ };
400
+ console.log(`[${prefix}] ${stage} completed (${(stageResult.duration / 1000).toFixed(1)}s)`);
401
+ this.emit('stage:complete', { stage, result: stageResult, context });
402
+ const costInfo = result.costInfo;
403
+ if (this.config.verbose) {
404
+ this.emit('log', { line: `[verbose] Stage ${stage} completed in ${(stageResult.duration / 1000).toFixed(1)}s${costInfo ? ` | cost: $${costInfo.costUsd.toFixed(4)} (${costInfo.inputTokens}in/${costInfo.outputTokens}out)` : ''}` });
405
+ }
406
+ broadcastEvent({ type: 'pipeline:stage', data: {
407
+ workItemId: context.workItem.id, stage, status: 'complete',
408
+ model: costInfo?.model,
409
+ inputTokens: costInfo?.inputTokens,
410
+ outputTokens: costInfo?.outputTokens,
411
+ costUsd: costInfo?.costUsd,
412
+ } });
413
+ return stageResult;
414
+ }
415
+ catch (error) {
416
+ const completedAt = Date.now();
417
+ const stageResult = {
418
+ stage,
419
+ success: false,
420
+ result: {
421
+ success: false,
422
+ error: error instanceof Error ? error.message : String(error),
423
+ },
424
+ duration: completedAt - startTime,
425
+ startedAt: startTime,
426
+ completedAt,
427
+ };
428
+ console.log(`[${prefix}] ${stage} failed (${(stageResult.duration / 1000).toFixed(1)}s)`);
429
+ this.emit('stage:fail', { stage, result: stageResult, context, error });
430
+ broadcastEvent({ type: 'pipeline:stage', data: { workItemId: context.workItem.id, stage, status: 'fail' } });
431
+ return stageResult;
432
+ }
433
+ }
434
+ async runReviewerStage(context, options) {
435
+ const reviewerMaxTurns = this.config.stageConfigs?.critic?.maxTurns;
436
+ const effectiveReviewerMaxTurns = context.executorResult?.confidencePercent && context.executorResult.confidencePercent > 90
437
+ ? Math.min(reviewerMaxTurns ?? 10, 5)
438
+ : reviewerMaxTurns;
439
+ const timeoutMs = this.config.stageConfigs?.critic?.timeoutMs ?? 0;
440
+ const consensusConfig = this.config.stageConfigs?.critic?.consensus;
441
+ const consensusEnabled = consensusConfig?.enabled === true;
442
+ agentPair.updateSessionStatus(context.session.id, 'reviewing');
443
+ if (!options.executorResult) {
444
+ throw new Error('Executor result required for reviewer');
445
+ }
446
+ const runSingleReview = async (model, adapter, stageLabel = 'critic') => {
447
+ const resolvedModel = model ?? options.stageModel;
448
+ const resolvedAdapterStr = adapter ?? options.adapterName;
449
+ const resolvedAdapter = isAdapterName(resolvedAdapterStr) ? resolvedAdapterStr : undefined;
450
+ const result = await reviewerAgent.runReviewer({
451
+ workItemTitle: context.workItem.title,
452
+ workItemDescription: context.workItem.description || '',
453
+ executorResult: options.executorResult,
454
+ projectPath: context.projectPath,
455
+ timeoutMs,
456
+ model: resolvedModel,
457
+ maxTurns: effectiveReviewerMaxTurns,
458
+ adapterName: resolvedAdapter,
459
+ processContext: { workItemId: context.workItem.id, stage: stageLabel },
460
+ });
461
+ if (this.config.verbose) {
462
+ this.emit('log', { line: `[verbose] ${stageLabel} decision: ${result.decision}` });
463
+ if (result.feedback) {
464
+ const lines = result.feedback.split('\n').slice(0, 5);
465
+ for (const line of lines) {
466
+ this.emit('log', { line: `[verbose] ${line}` });
467
+ }
468
+ }
469
+ }
470
+ return result;
471
+ };
472
+ const primaryModel = options.criticOverrides?.model ?? options.stageModel;
473
+ const primaryResult = await runSingleReview(primaryModel, options.adapterName, 'critic');
474
+ if (!consensusEnabled) {
475
+ return primaryResult;
476
+ }
477
+ const extraModels = (consensusConfig.models || [])
478
+ .map((m) => m?.trim())
479
+ .filter((m) => !!m && m.length > 0);
480
+ const uniqueExtraModels = Array.from(new Set(extraModels))
481
+ .filter((m) => m !== primaryModel);
482
+ if (uniqueExtraModels.length === 0) {
483
+ return primaryResult;
484
+ }
485
+ const extraResults = [];
486
+ for (let i = 0; i < uniqueExtraModels.length; i++) {
487
+ const model = uniqueExtraModels[i];
488
+ const adapter = inferProviderFromModel(model) ?? options.adapterName;
489
+ const extraResult = await runSingleReview(model, adapter, `reviewer-consensus-${i + 1}`);
490
+ extraResults.push(extraResult);
491
+ }
492
+ const allResults = [primaryResult, ...extraResults];
493
+ const totalReviews = allResults.length;
494
+ const requiredApprovals = Math.min(consensusConfig.requiredApprovals ?? totalReviews, totalReviews);
495
+ const approvalCount = allResults.filter((entry) => entry.decision === 'approve').length;
496
+ const rejectCount = allResults.filter((entry) => entry.decision === 'reject').length;
497
+ const reviseCount = allResults.filter((entry) => entry.decision === 'revise').length;
498
+ if (rejectCount > 0) {
499
+ const mergedWorkItems = allResults.flatMap((entry, idx) => {
500
+ const workItems = entry.workItems || [];
501
+ return workItems.length > 0 ? workItems : [`reviewer-${idx + 1}: ${entry.decision}`];
502
+ });
503
+ return {
504
+ decision: 'reject',
505
+ feedback: this.mergeReviewFeedback('Reviewer consensus decision', allResults),
506
+ workItems: mergedWorkItems.slice(0, 10),
507
+ suggestions: ['Resolve all reviewer blocking feedback before retrying'],
508
+ };
509
+ }
510
+ if (approvalCount < requiredApprovals || reviseCount > 0) {
511
+ const mergedWorkItems = allResults.flatMap((entry, idx) => {
512
+ const workItems = entry.workItems || [];
513
+ return workItems.length > 0 ? workItems : [`reviewer-${idx + 1}: ${entry.decision}`];
514
+ });
515
+ return {
516
+ decision: 'revise',
517
+ feedback: this.mergeReviewFeedback('Reviewer consensus decision', allResults),
518
+ workItems: mergedWorkItems.slice(0, 10),
519
+ suggestions: ['Incorporate the remaining reviewer feedback and re-run executor'],
520
+ };
521
+ }
522
+ return {
523
+ decision: 'approve',
524
+ feedback: this.mergeReviewFeedback('Reviewer consensus decision', allResults),
525
+ workItems: primaryResult.workItems,
526
+ suggestions: primaryResult.suggestions,
527
+ costInfo: primaryResult.costInfo || extraResults.find((entry) => entry.costInfo)?.costInfo,
528
+ };
529
+ }
530
+ mergeReviewFeedback(title, reviewResults) {
531
+ const parts = [title];
532
+ for (let i = 0; i < reviewResults.length; i++) {
533
+ const result = reviewResults[i];
534
+ const label = i === 0 ? `primary-${i + 1}` : `consensus-${i}`;
535
+ parts.push(`- ${label}: ${result.decision.toUpperCase()}`);
536
+ if (result.feedback) {
537
+ parts.push(result.feedback);
538
+ }
539
+ }
540
+ return parts.join('\n');
541
+ }
542
+ /**
543
+ * Determine stage success
544
+ */
545
+ isStageSuccess(stage, result) {
546
+ switch (stage) {
547
+ case 'coder':
548
+ return result.success;
549
+ case 'critic':
550
+ return result.decision === 'approve';
551
+ case 'tester':
552
+ return result.success;
553
+ case 'documenter':
554
+ return result.success;
555
+ case 'auditor':
556
+ return result.success;
557
+ case 'stage-documenter':
558
+ return result.success;
559
+ default:
560
+ return false;
561
+ }
562
+ }
563
+ // ============================================
564
+ // Full Iteration Loop
565
+ // ============================================
566
+ /**
567
+ * Full iteration loop
568
+ *
569
+ * 1 iteration = full pass through Executor → Reviewer → Tester
570
+ * On failure (revise) at any stage, restart from Executor in next iteration
571
+ * reject = immediate termination
572
+ */
573
+ async runFullIterationLoop(context, stages) {
574
+ const maxIterations = this.config.maxIterations ?? 3;
575
+ const hasCoder = this.hasStage('coder');
576
+ const hasCritic = this.hasStage('critic');
577
+ const hasTester = this.hasStage('tester');
578
+ // No point without a executor
579
+ if (!hasCoder) {
580
+ console.log(`[${context.workItemPrefix}] No executor stage configured`);
581
+ return { success: false };
582
+ }
583
+ while (context.currentIteration < maxIterations) {
584
+ context.currentIteration++;
585
+ // Stuck detection check (before iteration starts)
586
+ const stuckCheck = this.stuckDetector.check();
587
+ if (stuckCheck.isStuck) {
588
+ console.error(`[${context.workItemPrefix}] STUCK DETECTED: ${stuckCheck.reason}`);
589
+ console.error(`[${context.workItemPrefix}] Suggestion: ${stuckCheck.suggestion}`);
590
+ this.emit('stuck', {
591
+ reason: stuckCheck.reason,
592
+ suggestion: stuckCheck.suggestion,
593
+ context,
594
+ });
595
+ agentPair.updateSessionStatus(context.session.id, 'failed');
596
+ return { success: false };
597
+ }
598
+ this.emit('iteration:start', {
599
+ iteration: context.currentIteration,
600
+ maxIterations,
601
+ context,
602
+ });
603
+ broadcastEvent({ type: 'pipeline:iteration', data: { workItemId: context.workItem.id, iteration: context.currentIteration } });
604
+ console.log(`[${context.workItemPrefix}] Iteration ${context.currentIteration}/${maxIterations}`);
605
+ // ========== EXECUTOR (with escalation) ==========
606
+ const coderCfg = this.config.stageConfigs?.coder;
607
+ const escalateThreshold = coderCfg?.escalateAfterIteration ?? 3;
608
+ const escalateModel = coderCfg?.escalateModel;
609
+ const shouldEscalate = context.currentIteration >= escalateThreshold && !!escalateModel;
610
+ const baseExecutorModel = this.getModelForRole('coder', context.workItem);
611
+ const executorOverrides = shouldEscalate
612
+ ? { model: escalateModel }
613
+ : (baseExecutorModel ? { model: baseExecutorModel } : undefined);
614
+ if (shouldEscalate && escalateModel) {
615
+ console.log(`[${context.workItemPrefix}] Escalating executor model → ${escalateModel} (iteration ${context.currentIteration})`);
616
+ broadcastEvent({ type: 'pipeline:escalation', data: {
617
+ workItemId: context.workItem.id,
618
+ iteration: context.currentIteration,
619
+ fromModel: coderCfg?.model,
620
+ toModel: escalateModel,
621
+ } });
622
+ }
623
+ agentPair.updateSessionStatus(context.session.id, 'working');
624
+ const executorResult = await this.runStage('coder', context, executorOverrides);
625
+ stages.push(executorResult);
626
+ // Record Executor result in stuck detector
627
+ this.stuckDetector.addEntry({
628
+ stage: 'coder',
629
+ success: executorResult.success,
630
+ output: executorResult.result.summary,
631
+ error: executorResult.result.error,
632
+ timestamp: Date.now(),
633
+ });
634
+ if (!executorResult.success) {
635
+ console.log(`[${context.workItemPrefix}] Executor failed, retrying...`);
636
+ agentPair.trackFailure(context.session.id); // Track for fresh context decision
637
+ this.emit('iteration:fail', {
638
+ iteration: context.currentIteration,
639
+ stage: 'coder',
640
+ context,
641
+ });
642
+ continue; // Next iteration
643
+ }
644
+ // ========== PIPELINE GUARDS (post-executor, pre-reviewer) ==========
645
+ if (this.config.guards && context.executorResult) {
646
+ console.log(`[${context.workItemPrefix}] Running pipeline guards...`);
647
+ const guardsResult = await runGuards(context.executorResult, context.projectPath, this.config.guards);
648
+ context.guardsResult = guardsResult;
649
+ if (!guardsResult.allPassed) {
650
+ // Blocking guard failed → inject revise, skip reviewer
651
+ console.log(`[${context.workItemPrefix}] Blocking guard failed: ${guardsResult.combinedWorkItems.join('; ')}`);
652
+ context.reviewResult = {
653
+ decision: 'revise',
654
+ feedback: `Pipeline guard failed: ${guardsResult.combinedWorkItems.join('; ')}`,
655
+ workItems: guardsResult.combinedWorkItems,
656
+ suggestions: ['Fix the workItems flagged by quality guards'],
657
+ };
658
+ agentPair.trackFailure(context.session.id);
659
+ this.emit('iteration:fail', {
660
+ iteration: context.currentIteration,
661
+ stage: 'coder',
662
+ context,
663
+ });
664
+ agentPair.updateSessionStatus(context.session.id, 'revising');
665
+ continue;
666
+ }
667
+ // Log non-blocking guard warnings
668
+ const warnings = guardsResult.results.filter(r => !r.passed && !r.blocking);
669
+ if (warnings.length > 0) {
670
+ console.log(`[${context.workItemPrefix}] Guard warnings: ${warnings.map(w => w.guard).join(', ')}`);
671
+ this.emit('log', {
672
+ line: `⚠️ Guard warnings: ${warnings.flatMap(w => w.workItems).join('; ')}`,
673
+ });
674
+ }
675
+ }
676
+ // ========== HALT CHECK (confidence too low) ==========
677
+ if (context.executorResult) {
678
+ const confidence = agentPair.calculateConfidence(context.executorResult);
679
+ const stageModel = executorOverrides?.model;
680
+ const confidenceProfile = this.getExecutorConfidenceProfile(context, stageModel);
681
+ const confidenceAction = getConfidenceAction(confidence, confidenceProfile);
682
+ if (confidenceAction === 'halt') {
683
+ const haltReason = context.executorResult.haltReason
684
+ || `Low confidence: ${confidence}%`;
685
+ console.warn(`[${context.workItemPrefix}] HALT triggered: confidence=${confidence}%, reason=${haltReason}`);
686
+ this.emit('halt', {
687
+ confidence,
688
+ haltReason,
689
+ sessionId: context.session.id,
690
+ iteration: context.currentIteration,
691
+ context,
692
+ });
693
+ // Inject revise to retry
694
+ context.reviewResult = {
695
+ decision: 'revise',
696
+ feedback: `[HALT] Confidence too low (${confidence}%). ${haltReason}`,
697
+ workItems: [haltReason],
698
+ suggestions: ['Review workItem requirements', 'Provide additional context', 'Break into sub-workItems'],
699
+ };
700
+ agentPair.trackFailure(context.session.id);
701
+ this.emit('iteration:fail', {
702
+ iteration: context.currentIteration,
703
+ stage: 'coder',
704
+ context,
705
+ });
706
+ agentPair.updateSessionStatus(context.session.id, 'revising');
707
+ continue;
708
+ }
709
+ if (confidenceAction === 'cautious') {
710
+ const summary = `⚠️ Cautious confidence: ${confidence}% — continuing with heightened review awareness`;
711
+ console.warn(`[${context.workItemPrefix}] ${summary}`);
712
+ this.emit('log', { line: summary });
713
+ }
714
+ if (context.config.verbose) {
715
+ this.emit('log', { line: `[verbose] Executor confidence action: ${confidenceAction}` });
716
+ }
717
+ }
718
+ // ========== REVIEWER ==========
719
+ if (hasCritic) {
720
+ agentPair.updateSessionStatus(context.session.id, 'reviewing');
721
+ // Reviewer escalation: 로컬 모델이 N회 이상 REVISE → 상위 모델로 spot check
722
+ const criticCfg = this.config.stageConfigs?.critic;
723
+ const criticEscalateModel = criticCfg?.escalateModel;
724
+ const criticEscalateThreshold = criticCfg?.escalateAfterIteration ?? 3;
725
+ const shouldEscalateCritic = context.currentIteration >= criticEscalateThreshold && !!criticEscalateModel;
726
+ const criticOverrides = shouldEscalateCritic
727
+ ? { model: criticEscalateModel }
728
+ : undefined;
729
+ if (shouldEscalateCritic && criticEscalateModel) {
730
+ console.log(`[${context.workItemPrefix}] Critic escalation → ${criticEscalateModel} (iteration ${context.currentIteration})`);
731
+ this.emit('log', {
732
+ line: `Critic spot check: escalating to ${criticEscalateModel}`,
733
+ });
734
+ }
735
+ const criticResult = await this.runStage('critic', context, criticOverrides);
736
+ stages.push(criticResult);
737
+ const decision = criticResult.result.decision;
738
+ // Record Reviewer result in stuck detector
739
+ this.stuckDetector.addEntry({
740
+ stage: 'critic',
741
+ success: criticResult.success,
742
+ decision: decision,
743
+ output: criticResult.result.feedback,
744
+ timestamp: Date.now(),
745
+ });
746
+ if (decision === 'reject') {
747
+ // reject = terminate immediately
748
+ console.log(`[${context.workItemPrefix}] Reviewer rejected`);
749
+ agentPair.updateSessionStatus(context.session.id, 'rejected');
750
+ return { success: false };
751
+ }
752
+ if (decision === 'revise') {
753
+ // revise = next iteration
754
+ console.log(`[${context.workItemPrefix}] Reviewer requested revision`);
755
+ agentPair.trackFailure(context.session.id); // Track for fresh context decision
756
+ this.emit('iteration:fail', {
757
+ iteration: context.currentIteration,
758
+ stage: 'critic',
759
+ context,
760
+ });
761
+ agentPair.updateSessionStatus(context.session.id, 'revising');
762
+ continue;
763
+ }
764
+ // approve → proceed to Tester
765
+ agentPair.resetFailureStreak(context.session.id); // Reset on approval
766
+ }
767
+ // ========== TESTER ==========
768
+ if (hasTester) {
769
+ // Skip tester if no code files changed (configurable, default true)
770
+ const skipIfNoCode = this.config.skipTesterIfNoCodeChange ?? true;
771
+ const codeExtensions = /\.(ts|tsx|js|jsx|py|rs|go|java|rb|c|cpp|h|hpp)$/;
772
+ const changedFiles = context.executorResult?.filesChanged || [];
773
+ const hasCodeChange = changedFiles.some(f => codeExtensions.test(f));
774
+ if (skipIfNoCode && !hasCodeChange) {
775
+ console.log(`[${context.workItemPrefix}] Skipping tester: no code files changed (${changedFiles.length} files: ${changedFiles.join(', ') || 'none'})`);
776
+ }
777
+ else {
778
+ const testerResult = await this.runStage('tester', context);
779
+ stages.push(testerResult);
780
+ if (!testerResult.success && !this.config.continueOnTestFail) {
781
+ // Test failed → set feedback then next iteration
782
+ console.log(`[${context.workItemPrefix}] Tester failed, retrying...`);
783
+ agentPair.trackFailure(context.session.id); // Track for fresh context decision
784
+ if (context.testerResult) {
785
+ context.reviewResult = {
786
+ decision: 'revise',
787
+ feedback: testerAgent.buildTestFixPrompt(context.testerResult),
788
+ workItems: context.testerResult.failedTests,
789
+ suggestions: context.testerResult.suggestions,
790
+ };
791
+ }
792
+ this.emit('iteration:fail', {
793
+ iteration: context.currentIteration,
794
+ stage: 'tester',
795
+ context,
796
+ });
797
+ agentPair.updateSessionStatus(context.session.id, 'revising');
798
+ continue;
799
+ }
800
+ } // end else (has code change)
801
+ }
802
+ // ========== ALL PASSED ==========
803
+ console.log(`[${context.workItemPrefix}] Iteration ${context.currentIteration} completed successfully`);
804
+ this.emit('iteration:complete', {
805
+ iteration: context.currentIteration,
806
+ context,
807
+ });
808
+ return { success: true };
809
+ }
810
+ // maxIterations exceeded
811
+ console.log(`[${context.workItemPrefix}] Max iterations (${maxIterations}) exceeded`);
812
+ agentPair.updateSessionStatus(context.session.id, 'failed');
813
+ return { success: false };
814
+ }
815
+ // ============================================
816
+ // Result Building
817
+ // ============================================
818
+ /**
819
+ * Build pipeline result
820
+ */
821
+ buildResult(context, stages, startTime) {
822
+ // Use context.session directly — do NOT re-fetch from store.
823
+ // updateSessionStatus('approved') archives the session (deletes from Map),
824
+ // so getPairSession() would return undefined → finalStatus = 'failed'.
825
+ const session = context.session;
826
+ const finalStatus = session.status || 'failed';
827
+ const success = finalStatus === 'approved';
828
+ // Aggregate costs from all stages
829
+ const stageCosts = [];
830
+ if (context.executorResult?.costInfo)
831
+ stageCosts.push(context.executorResult.costInfo);
832
+ if (context.reviewResult?.costInfo)
833
+ stageCosts.push(context.reviewResult.costInfo);
834
+ if (context.testerResult?.costInfo)
835
+ stageCosts.push(context.testerResult.costInfo);
836
+ if (context.documenterResult?.costInfo)
837
+ stageCosts.push(context.documenterResult.costInfo);
838
+ if (context.auditorResult?.costInfo)
839
+ stageCosts.push(context.auditorResult.costInfo);
840
+ if (context.skillDocumenterResult?.costInfo)
841
+ stageCosts.push(context.skillDocumenterResult.costInfo);
842
+ const totalCost = stageCosts.length > 0 ? aggregateCosts(stageCosts) : undefined;
843
+ if (totalCost) {
844
+ console.log(`[${context.workItemPrefix}] Total cost: ${formatCost(totalCost)}`);
845
+ broadcastEvent({ type: 'workItem:cost', data: { workItemId: context.workItem.id, cost: totalCost } });
846
+ }
847
+ const result = {
848
+ success,
849
+ sessionId: context.session.id,
850
+ stages,
851
+ finalStatus,
852
+ totalDuration: Date.now() - startTime,
853
+ iterations: context.currentIteration,
854
+ executorResult: context.executorResult,
855
+ reviewResult: context.reviewResult,
856
+ testerResult: context.testerResult,
857
+ documenterResult: context.documenterResult,
858
+ auditorResult: context.auditorResult,
859
+ skillDocumenterResult: context.skillDocumenterResult,
860
+ workItemContext: {
861
+ workItemIdentifier: context.workItem.workItemIdentifier || context.workItem.workItemId,
862
+ projectName: context.workItem.azdoProject?.name,
863
+ projectPath: context.projectPath,
864
+ workItemTitle: context.workItem.title,
865
+ },
866
+ totalCost,
867
+ };
868
+ if (success) {
869
+ this.emit('pipeline:complete', result);
870
+ }
871
+ else {
872
+ this.emit('pipeline:fail', result);
873
+ }
874
+ return result;
875
+ }
876
+ }
877
+ // Factory Functions
878
+ /**
879
+ * Create default pipeline (Executor + Reviewer)
880
+ */
881
+ export function createDefaultPipeline(maxIterations = 3) {
882
+ return new PairPipeline({
883
+ stages: ['coder', 'critic'],
884
+ maxIterations,
885
+ });
886
+ }
887
+ /**
888
+ * Create full pipeline (Executor + Reviewer + Tester + Documenter)
889
+ */
890
+ export function createFullPipeline(config) {
891
+ return new PairPipeline({
892
+ stages: ['coder', 'critic', 'tester', 'documenter'],
893
+ maxIterations: 3,
894
+ continueOnTestFail: false,
895
+ skipDocumenterIfNoChange: true,
896
+ ...config,
897
+ });
898
+ }
899
+ /**
900
+ * Create pipeline from configuration
901
+ */
902
+ export function createPipelineFromConfig(stageConfigs, maxIterations = 3, guards, jobProfiles, draftAnalysis) {
903
+ const stages = [];
904
+ if (stageConfigs?.coder?.enabled !== false) {
905
+ stages.push('coder');
906
+ }
907
+ if (stageConfigs?.critic?.enabled !== false) {
908
+ stages.push('critic');
909
+ }
910
+ if (stageConfigs?.tester?.enabled) {
911
+ stages.push('tester');
912
+ }
913
+ if (stageConfigs?.documenter?.enabled) {
914
+ stages.push('documenter');
915
+ }
916
+ if (stageConfigs?.auditor?.enabled) {
917
+ stages.push('auditor');
918
+ }
919
+ if (stageConfigs?.['stage-documenter']?.enabled) {
920
+ stages.push('stage-documenter');
921
+ }
922
+ return new PairPipeline({
923
+ stages,
924
+ maxIterations,
925
+ stageConfigs,
926
+ guards,
927
+ jobProfiles,
928
+ draftAnalysis,
929
+ });
930
+ }
931
+ // Helpers
932
+ // Re-export formatting functions (extracted to pipelineFormat.ts)
933
+ export { formatPipelineResult, formatPipelineResultEmbed } from '../agents/pipelineFormat.js';
934
+ //# sourceMappingURL=pairPipeline.js.map