@intrect/openswarm 0.2.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 (437) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +544 -0
  3. package/config.example.yaml +107 -0
  4. package/dist/adapters/base.d.ts +8 -0
  5. package/dist/adapters/base.d.ts.map +1 -0
  6. package/dist/adapters/base.js +104 -0
  7. package/dist/adapters/base.js.map +1 -0
  8. package/dist/adapters/claude.d.ts +13 -0
  9. package/dist/adapters/claude.d.ts.map +1 -0
  10. package/dist/adapters/claude.js +318 -0
  11. package/dist/adapters/claude.js.map +1 -0
  12. package/dist/adapters/codex.d.ts +14 -0
  13. package/dist/adapters/codex.d.ts.map +1 -0
  14. package/dist/adapters/codex.js +366 -0
  15. package/dist/adapters/codex.js.map +1 -0
  16. package/dist/adapters/cryptoQuantAdapter.d.ts +85 -0
  17. package/dist/adapters/cryptoQuantAdapter.d.ts.map +1 -0
  18. package/dist/adapters/cryptoQuantAdapter.js +238 -0
  19. package/dist/adapters/cryptoQuantAdapter.js.map +1 -0
  20. package/dist/adapters/index.d.ts +17 -0
  21. package/dist/adapters/index.d.ts.map +1 -0
  22. package/dist/adapters/index.js +47 -0
  23. package/dist/adapters/index.js.map +1 -0
  24. package/dist/adapters/processRegistry.d.ts +38 -0
  25. package/dist/adapters/processRegistry.d.ts.map +1 -0
  26. package/dist/adapters/processRegistry.js +147 -0
  27. package/dist/adapters/processRegistry.js.map +1 -0
  28. package/dist/adapters/streamBuffer.d.ts +59 -0
  29. package/dist/adapters/streamBuffer.d.ts.map +1 -0
  30. package/dist/adapters/streamBuffer.js +123 -0
  31. package/dist/adapters/streamBuffer.js.map +1 -0
  32. package/dist/adapters/types.d.ts +65 -0
  33. package/dist/adapters/types.d.ts.map +1 -0
  34. package/dist/adapters/types.js +6 -0
  35. package/dist/adapters/types.js.map +1 -0
  36. package/dist/agents/agentBus.d.ts +160 -0
  37. package/dist/agents/agentBus.d.ts.map +1 -0
  38. package/dist/agents/agentBus.js +350 -0
  39. package/dist/agents/agentBus.js.map +1 -0
  40. package/dist/agents/agentPair.d.ts +210 -0
  41. package/dist/agents/agentPair.d.ts.map +1 -0
  42. package/dist/agents/agentPair.js +420 -0
  43. package/dist/agents/agentPair.js.map +1 -0
  44. package/dist/agents/auditor.d.ts +27 -0
  45. package/dist/agents/auditor.d.ts.map +1 -0
  46. package/dist/agents/auditor.js +237 -0
  47. package/dist/agents/auditor.js.map +1 -0
  48. package/dist/agents/cliStreamParser.d.ts +18 -0
  49. package/dist/agents/cliStreamParser.d.ts.map +1 -0
  50. package/dist/agents/cliStreamParser.js +156 -0
  51. package/dist/agents/cliStreamParser.js.map +1 -0
  52. package/dist/agents/documenter.d.ts +31 -0
  53. package/dist/agents/documenter.d.ts.map +1 -0
  54. package/dist/agents/documenter.js +285 -0
  55. package/dist/agents/documenter.js.map +1 -0
  56. package/dist/agents/index.d.ts +10 -0
  57. package/dist/agents/index.d.ts.map +1 -0
  58. package/dist/agents/index.js +10 -0
  59. package/dist/agents/index.js.map +1 -0
  60. package/dist/agents/pairMetrics.d.ts +63 -0
  61. package/dist/agents/pairMetrics.d.ts.map +1 -0
  62. package/dist/agents/pairMetrics.js +231 -0
  63. package/dist/agents/pairMetrics.js.map +1 -0
  64. package/dist/agents/pairPipeline.d.ts +155 -0
  65. package/dist/agents/pairPipeline.d.ts.map +1 -0
  66. package/dist/agents/pairPipeline.js +793 -0
  67. package/dist/agents/pairPipeline.js.map +1 -0
  68. package/dist/agents/pairWebhook.d.ts +59 -0
  69. package/dist/agents/pairWebhook.d.ts.map +1 -0
  70. package/dist/agents/pairWebhook.js +242 -0
  71. package/dist/agents/pairWebhook.js.map +1 -0
  72. package/dist/agents/pipelineFormat.d.ts +11 -0
  73. package/dist/agents/pipelineFormat.d.ts.map +1 -0
  74. package/dist/agents/pipelineFormat.js +164 -0
  75. package/dist/agents/pipelineFormat.js.map +1 -0
  76. package/dist/agents/pipelineGuards.d.ts +23 -0
  77. package/dist/agents/pipelineGuards.d.ts.map +1 -0
  78. package/dist/agents/pipelineGuards.js +175 -0
  79. package/dist/agents/pipelineGuards.js.map +1 -0
  80. package/dist/agents/reviewer.d.ts +37 -0
  81. package/dist/agents/reviewer.d.ts.map +1 -0
  82. package/dist/agents/reviewer.js +213 -0
  83. package/dist/agents/reviewer.js.map +1 -0
  84. package/dist/agents/skillDocumenter.d.ts +23 -0
  85. package/dist/agents/skillDocumenter.d.ts.map +1 -0
  86. package/dist/agents/skillDocumenter.js +218 -0
  87. package/dist/agents/skillDocumenter.js.map +1 -0
  88. package/dist/agents/tester.d.ts +37 -0
  89. package/dist/agents/tester.d.ts.map +1 -0
  90. package/dist/agents/tester.js +308 -0
  91. package/dist/agents/tester.js.map +1 -0
  92. package/dist/agents/worker.d.ts +30 -0
  93. package/dist/agents/worker.d.ts.map +1 -0
  94. package/dist/agents/worker.js +128 -0
  95. package/dist/agents/worker.js.map +1 -0
  96. package/dist/automation/autonomousRunner.d.ts +123 -0
  97. package/dist/automation/autonomousRunner.d.ts.map +1 -0
  98. package/dist/automation/autonomousRunner.js +1082 -0
  99. package/dist/automation/autonomousRunner.js.map +1 -0
  100. package/dist/automation/ciWorker.d.ts +51 -0
  101. package/dist/automation/ciWorker.d.ts.map +1 -0
  102. package/dist/automation/ciWorker.js +282 -0
  103. package/dist/automation/ciWorker.js.map +1 -0
  104. package/dist/automation/conflictResolver.d.ts +29 -0
  105. package/dist/automation/conflictResolver.d.ts.map +1 -0
  106. package/dist/automation/conflictResolver.js +261 -0
  107. package/dist/automation/conflictResolver.js.map +1 -0
  108. package/dist/automation/dailyReporter.d.ts +26 -0
  109. package/dist/automation/dailyReporter.d.ts.map +1 -0
  110. package/dist/automation/dailyReporter.js +132 -0
  111. package/dist/automation/dailyReporter.js.map +1 -0
  112. package/dist/automation/index.d.ts +7 -0
  113. package/dist/automation/index.d.ts.map +1 -0
  114. package/dist/automation/index.js +7 -0
  115. package/dist/automation/index.js.map +1 -0
  116. package/dist/automation/longRunningMonitor.d.ts +26 -0
  117. package/dist/automation/longRunningMonitor.d.ts.map +1 -0
  118. package/dist/automation/longRunningMonitor.js +231 -0
  119. package/dist/automation/longRunningMonitor.js.map +1 -0
  120. package/dist/automation/prOwnership.d.ts +18 -0
  121. package/dist/automation/prOwnership.d.ts.map +1 -0
  122. package/dist/automation/prOwnership.js +61 -0
  123. package/dist/automation/prOwnership.js.map +1 -0
  124. package/dist/automation/prProcessor.d.ts +62 -0
  125. package/dist/automation/prProcessor.d.ts.map +1 -0
  126. package/dist/automation/prProcessor.js +700 -0
  127. package/dist/automation/prProcessor.js.map +1 -0
  128. package/dist/automation/runnerExecution.d.ts +49 -0
  129. package/dist/automation/runnerExecution.d.ts.map +1 -0
  130. package/dist/automation/runnerExecution.js +663 -0
  131. package/dist/automation/runnerExecution.js.map +1 -0
  132. package/dist/automation/runnerState.d.ts +170 -0
  133. package/dist/automation/runnerState.d.ts.map +1 -0
  134. package/dist/automation/runnerState.js +495 -0
  135. package/dist/automation/runnerState.js.map +1 -0
  136. package/dist/automation/runnerTypes.d.ts +46 -0
  137. package/dist/automation/runnerTypes.d.ts.map +1 -0
  138. package/dist/automation/runnerTypes.js +5 -0
  139. package/dist/automation/runnerTypes.js.map +1 -0
  140. package/dist/automation/scheduler.d.ts +75 -0
  141. package/dist/automation/scheduler.d.ts.map +1 -0
  142. package/dist/automation/scheduler.js +394 -0
  143. package/dist/automation/scheduler.js.map +1 -0
  144. package/dist/cli/promptHandler.d.ts +13 -0
  145. package/dist/cli/promptHandler.d.ts.map +1 -0
  146. package/dist/cli/promptHandler.js +189 -0
  147. package/dist/cli/promptHandler.js.map +1 -0
  148. package/dist/cli.d.ts +3 -0
  149. package/dist/cli.d.ts.map +1 -0
  150. package/dist/cli.js +138 -0
  151. package/dist/cli.js.map +1 -0
  152. package/dist/core/config.d.ts +308 -0
  153. package/dist/core/config.d.ts.map +1 -0
  154. package/dist/core/config.js +529 -0
  155. package/dist/core/config.js.map +1 -0
  156. package/dist/core/eventHub.d.ts +194 -0
  157. package/dist/core/eventHub.d.ts.map +1 -0
  158. package/dist/core/eventHub.js +136 -0
  159. package/dist/core/eventHub.js.map +1 -0
  160. package/dist/core/index.d.ts +6 -0
  161. package/dist/core/index.d.ts.map +1 -0
  162. package/dist/core/index.js +6 -0
  163. package/dist/core/index.js.map +1 -0
  164. package/dist/core/service.d.ts +27 -0
  165. package/dist/core/service.d.ts.map +1 -0
  166. package/dist/core/service.js +438 -0
  167. package/dist/core/service.js.map +1 -0
  168. package/dist/core/traceCollector.d.ts +105 -0
  169. package/dist/core/traceCollector.d.ts.map +1 -0
  170. package/dist/core/traceCollector.js +141 -0
  171. package/dist/core/traceCollector.js.map +1 -0
  172. package/dist/core/types.d.ts +413 -0
  173. package/dist/core/types.d.ts.map +1 -0
  174. package/dist/core/types.js +5 -0
  175. package/dist/core/types.js.map +1 -0
  176. package/dist/discord/discordCore.d.ts +104 -0
  177. package/dist/discord/discordCore.d.ts.map +1 -0
  178. package/dist/discord/discordCore.js +698 -0
  179. package/dist/discord/discordCore.js.map +1 -0
  180. package/dist/discord/discordHandlers.d.ts +86 -0
  181. package/dist/discord/discordHandlers.d.ts.map +1 -0
  182. package/dist/discord/discordHandlers.js +849 -0
  183. package/dist/discord/discordHandlers.js.map +1 -0
  184. package/dist/discord/discordPair.d.ts +6 -0
  185. package/dist/discord/discordPair.d.ts.map +1 -0
  186. package/dist/discord/discordPair.js +567 -0
  187. package/dist/discord/discordPair.js.map +1 -0
  188. package/dist/discord/index.d.ts +4 -0
  189. package/dist/discord/index.d.ts.map +1 -0
  190. package/dist/discord/index.js +11 -0
  191. package/dist/discord/index.js.map +1 -0
  192. package/dist/github/github.d.ts +236 -0
  193. package/dist/github/github.d.ts.map +1 -0
  194. package/dist/github/github.js +535 -0
  195. package/dist/github/github.js.map +1 -0
  196. package/dist/github/index.d.ts +2 -0
  197. package/dist/github/index.d.ts.map +1 -0
  198. package/dist/github/index.js +2 -0
  199. package/dist/github/index.js.map +1 -0
  200. package/dist/index.d.ts +3 -0
  201. package/dist/index.d.ts.map +1 -0
  202. package/dist/index.js +60 -0
  203. package/dist/index.js.map +1 -0
  204. package/dist/knowledge/analyzer.d.ts +36 -0
  205. package/dist/knowledge/analyzer.d.ts.map +1 -0
  206. package/dist/knowledge/analyzer.js +170 -0
  207. package/dist/knowledge/analyzer.js.map +1 -0
  208. package/dist/knowledge/gitInfo.d.ts +10 -0
  209. package/dist/knowledge/gitInfo.d.ts.map +1 -0
  210. package/dist/knowledge/gitInfo.js +134 -0
  211. package/dist/knowledge/gitInfo.js.map +1 -0
  212. package/dist/knowledge/graph.d.ts +45 -0
  213. package/dist/knowledge/graph.d.ts.map +1 -0
  214. package/dist/knowledge/graph.js +262 -0
  215. package/dist/knowledge/graph.js.map +1 -0
  216. package/dist/knowledge/graphqlExporter.d.ts +64 -0
  217. package/dist/knowledge/graphqlExporter.d.ts.map +1 -0
  218. package/dist/knowledge/graphqlExporter.js +333 -0
  219. package/dist/knowledge/graphqlExporter.js.map +1 -0
  220. package/dist/knowledge/index.d.ts +58 -0
  221. package/dist/knowledge/index.d.ts.map +1 -0
  222. package/dist/knowledge/index.js +212 -0
  223. package/dist/knowledge/index.js.map +1 -0
  224. package/dist/knowledge/repository.d.ts +64 -0
  225. package/dist/knowledge/repository.d.ts.map +1 -0
  226. package/dist/knowledge/repository.js +250 -0
  227. package/dist/knowledge/repository.js.map +1 -0
  228. package/dist/knowledge/riskOnAnalyzer.d.ts +79 -0
  229. package/dist/knowledge/riskOnAnalyzer.d.ts.map +1 -0
  230. package/dist/knowledge/riskOnAnalyzer.js +243 -0
  231. package/dist/knowledge/riskOnAnalyzer.js.map +1 -0
  232. package/dist/knowledge/scanner.d.ts +14 -0
  233. package/dist/knowledge/scanner.d.ts.map +1 -0
  234. package/dist/knowledge/scanner.js +350 -0
  235. package/dist/knowledge/scanner.js.map +1 -0
  236. package/dist/knowledge/store.d.ts +23 -0
  237. package/dist/knowledge/store.d.ts.map +1 -0
  238. package/dist/knowledge/store.js +86 -0
  239. package/dist/knowledge/store.js.map +1 -0
  240. package/dist/knowledge/types.d.ts +288 -0
  241. package/dist/knowledge/types.d.ts.map +1 -0
  242. package/dist/knowledge/types.js +111 -0
  243. package/dist/knowledge/types.js.map +1 -0
  244. package/dist/linear/index.d.ts +3 -0
  245. package/dist/linear/index.d.ts.map +1 -0
  246. package/dist/linear/index.js +3 -0
  247. package/dist/linear/index.js.map +1 -0
  248. package/dist/linear/linear.d.ts +160 -0
  249. package/dist/linear/linear.d.ts.map +1 -0
  250. package/dist/linear/linear.js +983 -0
  251. package/dist/linear/linear.js.map +1 -0
  252. package/dist/linear/projectUpdater.d.ts +23 -0
  253. package/dist/linear/projectUpdater.d.ts.map +1 -0
  254. package/dist/linear/projectUpdater.js +347 -0
  255. package/dist/linear/projectUpdater.js.map +1 -0
  256. package/dist/locale/en.d.ts +3 -0
  257. package/dist/locale/en.d.ts.map +1 -0
  258. package/dist/locale/en.js +436 -0
  259. package/dist/locale/en.js.map +1 -0
  260. package/dist/locale/index.d.ts +28 -0
  261. package/dist/locale/index.d.ts.map +1 -0
  262. package/dist/locale/index.js +89 -0
  263. package/dist/locale/index.js.map +1 -0
  264. package/dist/locale/ko.d.ts +3 -0
  265. package/dist/locale/ko.d.ts.map +1 -0
  266. package/dist/locale/ko.js +436 -0
  267. package/dist/locale/ko.js.map +1 -0
  268. package/dist/locale/prompts/en.d.ts +3 -0
  269. package/dist/locale/prompts/en.d.ts.map +1 -0
  270. package/dist/locale/prompts/en.js +278 -0
  271. package/dist/locale/prompts/en.js.map +1 -0
  272. package/dist/locale/prompts/ko.d.ts +3 -0
  273. package/dist/locale/prompts/ko.d.ts.map +1 -0
  274. package/dist/locale/prompts/ko.js +279 -0
  275. package/dist/locale/prompts/ko.js.map +1 -0
  276. package/dist/locale/types.d.ts +407 -0
  277. package/dist/locale/types.d.ts.map +1 -0
  278. package/dist/locale/types.js +5 -0
  279. package/dist/locale/types.js.map +1 -0
  280. package/dist/memory/codex.d.ts +93 -0
  281. package/dist/memory/codex.d.ts.map +1 -0
  282. package/dist/memory/codex.js +366 -0
  283. package/dist/memory/codex.js.map +1 -0
  284. package/dist/memory/compaction.d.ts +21 -0
  285. package/dist/memory/compaction.d.ts.map +1 -0
  286. package/dist/memory/compaction.js +205 -0
  287. package/dist/memory/compaction.js.map +1 -0
  288. package/dist/memory/index.d.ts +13 -0
  289. package/dist/memory/index.d.ts.map +1 -0
  290. package/dist/memory/index.js +13 -0
  291. package/dist/memory/index.js.map +1 -0
  292. package/dist/memory/memoryCore.d.ts +178 -0
  293. package/dist/memory/memoryCore.d.ts.map +1 -0
  294. package/dist/memory/memoryCore.js +623 -0
  295. package/dist/memory/memoryCore.js.map +1 -0
  296. package/dist/memory/memoryOps.d.ts +90 -0
  297. package/dist/memory/memoryOps.d.ts.map +1 -0
  298. package/dist/memory/memoryOps.js +606 -0
  299. package/dist/memory/memoryOps.js.map +1 -0
  300. package/dist/orchestration/conflictDetector.d.ts +15 -0
  301. package/dist/orchestration/conflictDetector.d.ts.map +1 -0
  302. package/dist/orchestration/conflictDetector.js +130 -0
  303. package/dist/orchestration/conflictDetector.js.map +1 -0
  304. package/dist/orchestration/decisionEngine.d.ts +177 -0
  305. package/dist/orchestration/decisionEngine.d.ts.map +1 -0
  306. package/dist/orchestration/decisionEngine.js +496 -0
  307. package/dist/orchestration/decisionEngine.js.map +1 -0
  308. package/dist/orchestration/index.d.ts +5 -0
  309. package/dist/orchestration/index.d.ts.map +1 -0
  310. package/dist/orchestration/index.js +5 -0
  311. package/dist/orchestration/index.js.map +1 -0
  312. package/dist/orchestration/taskParser.d.ts +67 -0
  313. package/dist/orchestration/taskParser.d.ts.map +1 -0
  314. package/dist/orchestration/taskParser.js +542 -0
  315. package/dist/orchestration/taskParser.js.map +1 -0
  316. package/dist/orchestration/taskScheduler.d.ts +141 -0
  317. package/dist/orchestration/taskScheduler.d.ts.map +1 -0
  318. package/dist/orchestration/taskScheduler.js +317 -0
  319. package/dist/orchestration/taskScheduler.js.map +1 -0
  320. package/dist/orchestration/workflow.d.ts +145 -0
  321. package/dist/orchestration/workflow.d.ts.map +1 -0
  322. package/dist/orchestration/workflow.js +301 -0
  323. package/dist/orchestration/workflow.js.map +1 -0
  324. package/dist/runners/cliRunner.d.ts +11 -0
  325. package/dist/runners/cliRunner.d.ts.map +1 -0
  326. package/dist/runners/cliRunner.js +194 -0
  327. package/dist/runners/cliRunner.js.map +1 -0
  328. package/dist/support/apiCache.d.ts +85 -0
  329. package/dist/support/apiCache.d.ts.map +1 -0
  330. package/dist/support/apiCache.js +163 -0
  331. package/dist/support/apiCache.js.map +1 -0
  332. package/dist/support/chat.d.ts +3 -0
  333. package/dist/support/chat.d.ts.map +1 -0
  334. package/dist/support/chat.js +304 -0
  335. package/dist/support/chat.js.map +1 -0
  336. package/dist/support/chatBackend.d.ts +25 -0
  337. package/dist/support/chatBackend.d.ts.map +1 -0
  338. package/dist/support/chatBackend.js +235 -0
  339. package/dist/support/chatBackend.js.map +1 -0
  340. package/dist/support/chatMemory.d.ts +71 -0
  341. package/dist/support/chatMemory.d.ts.map +1 -0
  342. package/dist/support/chatMemory.js +119 -0
  343. package/dist/support/chatMemory.js.map +1 -0
  344. package/dist/support/chatTui.d.ts +3 -0
  345. package/dist/support/chatTui.d.ts.map +1 -0
  346. package/dist/support/chatTui.js +998 -0
  347. package/dist/support/chatTui.js.map +1 -0
  348. package/dist/support/costTracker.d.ts +29 -0
  349. package/dist/support/costTracker.d.ts.map +1 -0
  350. package/dist/support/costTracker.js +113 -0
  351. package/dist/support/costTracker.js.map +1 -0
  352. package/dist/support/dashboardHtml.d.ts +3 -0
  353. package/dist/support/dashboardHtml.d.ts.map +1 -0
  354. package/dist/support/dashboardHtml.js +2070 -0
  355. package/dist/support/dashboardHtml.js.map +1 -0
  356. package/dist/support/delete-beliefs.d.ts +2 -0
  357. package/dist/support/delete-beliefs.d.ts.map +1 -0
  358. package/dist/support/delete-beliefs.js +34 -0
  359. package/dist/support/delete-beliefs.js.map +1 -0
  360. package/dist/support/dev.d.ts +55 -0
  361. package/dist/support/dev.d.ts.map +1 -0
  362. package/dist/support/dev.js +298 -0
  363. package/dist/support/dev.js.map +1 -0
  364. package/dist/support/editParser.d.ts +37 -0
  365. package/dist/support/editParser.d.ts.map +1 -0
  366. package/dist/support/editParser.js +365 -0
  367. package/dist/support/editParser.js.map +1 -0
  368. package/dist/support/gitStatus.d.ts +21 -0
  369. package/dist/support/gitStatus.d.ts.map +1 -0
  370. package/dist/support/gitStatus.js +108 -0
  371. package/dist/support/gitStatus.js.map +1 -0
  372. package/dist/support/gitTracker.d.ts +30 -0
  373. package/dist/support/gitTracker.d.ts.map +1 -0
  374. package/dist/support/gitTracker.js +143 -0
  375. package/dist/support/gitTracker.js.map +1 -0
  376. package/dist/support/index.d.ts +13 -0
  377. package/dist/support/index.d.ts.map +1 -0
  378. package/dist/support/index.js +13 -0
  379. package/dist/support/index.js.map +1 -0
  380. package/dist/support/planner.d.ts +58 -0
  381. package/dist/support/planner.d.ts.map +1 -0
  382. package/dist/support/planner.js +395 -0
  383. package/dist/support/planner.js.map +1 -0
  384. package/dist/support/projectMapper.d.ts +46 -0
  385. package/dist/support/projectMapper.d.ts.map +1 -0
  386. package/dist/support/projectMapper.js +259 -0
  387. package/dist/support/projectMapper.js.map +1 -0
  388. package/dist/support/quotaTracker.d.ts +29 -0
  389. package/dist/support/quotaTracker.d.ts.map +1 -0
  390. package/dist/support/quotaTracker.js +89 -0
  391. package/dist/support/quotaTracker.js.map +1 -0
  392. package/dist/support/rateLimiter.d.ts +101 -0
  393. package/dist/support/rateLimiter.d.ts.map +1 -0
  394. package/dist/support/rateLimiter.js +219 -0
  395. package/dist/support/rateLimiter.js.map +1 -0
  396. package/dist/support/rollback.d.ts +61 -0
  397. package/dist/support/rollback.d.ts.map +1 -0
  398. package/dist/support/rollback.js +328 -0
  399. package/dist/support/rollback.js.map +1 -0
  400. package/dist/support/stuckDetector.d.ts +68 -0
  401. package/dist/support/stuckDetector.d.ts.map +1 -0
  402. package/dist/support/stuckDetector.js +174 -0
  403. package/dist/support/stuckDetector.js.map +1 -0
  404. package/dist/support/timeWindow.d.ts +60 -0
  405. package/dist/support/timeWindow.d.ts.map +1 -0
  406. package/dist/support/timeWindow.js +236 -0
  407. package/dist/support/timeWindow.js.map +1 -0
  408. package/dist/support/web.d.ts +11 -0
  409. package/dist/support/web.d.ts.map +1 -0
  410. package/dist/support/web.js +938 -0
  411. package/dist/support/web.js.map +1 -0
  412. package/dist/support/workflowLinear.d.ts +99 -0
  413. package/dist/support/workflowLinear.d.ts.map +1 -0
  414. package/dist/support/workflowLinear.js +257 -0
  415. package/dist/support/workflowLinear.js.map +1 -0
  416. package/dist/support/worktreeManager.d.ts +20 -0
  417. package/dist/support/worktreeManager.d.ts.map +1 -0
  418. package/dist/support/worktreeManager.js +144 -0
  419. package/dist/support/worktreeManager.js.map +1 -0
  420. package/dist/taskState/store.d.ts +101 -0
  421. package/dist/taskState/store.d.ts.map +1 -0
  422. package/dist/taskState/store.js +346 -0
  423. package/dist/taskState/store.js.map +1 -0
  424. package/package.json +70 -0
  425. package/templates/AGENTS.md +432 -0
  426. package/templates/BOOT.md +25 -0
  427. package/templates/BOOTSTRAP.md +50 -0
  428. package/templates/CHANGELOG_AUDIT.md +74 -0
  429. package/templates/HEARTBEAT.md +86 -0
  430. package/templates/IDENTITY.md +27 -0
  431. package/templates/ISSUE_ANALYSIS.md +31 -0
  432. package/templates/PR_LAND.md +75 -0
  433. package/templates/PR_REVIEW.md +97 -0
  434. package/templates/SOUL.dev.md +52 -0
  435. package/templates/SOUL.md +81 -0
  436. package/templates/TOOLS.md +52 -0
  437. package/templates/USER.md +22 -0
@@ -0,0 +1,793 @@
1
+ // ============================================
2
+ // OpenSwarm - Pair Pipeline
3
+ // Worker → 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 { CONFIDENCE_THRESHOLDS } from './agentPair.js';
9
+ import * as agentPair from './agentPair.js';
10
+ import { runGuards } from './pipelineGuards.js';
11
+ import { hasRepoSnapshot, scanAndCache } from '../knowledge/index.js';
12
+ import * as workerAgent from './worker.js';
13
+ import * as reviewerAgent from './reviewer.js';
14
+ import * as testerAgent from './tester.js';
15
+ import * as documenterAgent from './documenter.js';
16
+ import * as auditorAgent from './auditor.js';
17
+ import * as skillDocumenterAgent from './skillDocumenter.js';
18
+ import { createStuckDetector } from '../support/stuckDetector.js';
19
+ /**
20
+ * Build a consistent task prefix for logging across all pipeline stages.
21
+ * Format: "ProjectName | INT-XXX | worktree/abc123" or "ProjectName | INT-XXX"
22
+ */
23
+ export function buildTaskPrefix(task, projectPath) {
24
+ const parts = [];
25
+ const projectName = task.linearProject?.name || projectPath.split('/').pop() || 'unknown';
26
+ parts.push(projectName);
27
+ if (task.issueIdentifier) {
28
+ parts.push(task.issueIdentifier);
29
+ }
30
+ else if (task.issueId) {
31
+ parts.push(task.issueId.slice(0, 8));
32
+ }
33
+ // Detect worktree path
34
+ const worktreeMatch = projectPath.match(/worktree\/([a-f0-9-]+)/);
35
+ if (worktreeMatch) {
36
+ parts.push(`worktree/${worktreeMatch[1].slice(0, 8)}`);
37
+ }
38
+ return parts.join(' | ');
39
+ }
40
+ // Pair Pipeline
41
+ export class PairPipeline extends EventEmitter {
42
+ config;
43
+ stuckDetector;
44
+ jobProfiles;
45
+ constructor(config) {
46
+ super();
47
+ this.config = {
48
+ continueOnTestFail: false,
49
+ skipDocumenterIfNoChange: true,
50
+ maxIterations: 3,
51
+ ...config,
52
+ };
53
+ // Initialize stuck detector
54
+ this.stuckDetector = createStuckDetector({
55
+ sameErrorRepeat: 2,
56
+ revisionLoop: 4,
57
+ });
58
+ this.jobProfiles = config.jobProfiles ?? [];
59
+ }
60
+ matchesProfile(task, profile) {
61
+ const estimate = task.estimatedMinutes ?? 0;
62
+ if (profile.minMinutes != null && estimate < profile.minMinutes)
63
+ return false;
64
+ if (profile.maxMinutes != null && estimate > profile.maxMinutes)
65
+ return false;
66
+ if (profile.priority != null && task.priority !== profile.priority)
67
+ return false;
68
+ return true;
69
+ }
70
+ getProfileForTask(task) {
71
+ if (!this.jobProfiles || this.jobProfiles.length === 0)
72
+ return undefined;
73
+ return this.jobProfiles.find((profile) => this.matchesProfile(task, profile));
74
+ }
75
+ getModelForRole(stage, task) {
76
+ const profile = this.getProfileForTask(task);
77
+ return profile?.roles?.[stage] || this.config.roles?.[stage]?.model;
78
+ }
79
+ // ============================================
80
+ // Main Execution
81
+ // ============================================
82
+ /**
83
+ * Run pipeline
84
+ *
85
+ * 1 iteration = full pass through Worker → Reviewer → Tester
86
+ * On failure at any stage, returns to Worker (up to maxIterations)
87
+ */
88
+ async run(task, projectPath) {
89
+ const startTime = Date.now();
90
+ const stages = [];
91
+ const maxIterations = this.config.maxIterations ?? 3;
92
+ // Reset stuck detector (new pipeline run)
93
+ this.stuckDetector.reset();
94
+ // Ensure repo graph snapshot exists (first-time scan if needed)
95
+ if (!hasRepoSnapshot(projectPath)) {
96
+ console.log(`[Pipeline] No repo snapshot found, scanning ${projectPath}...`);
97
+ try {
98
+ await scanAndCache(projectPath);
99
+ }
100
+ catch (e) {
101
+ console.warn(`[Pipeline] Repo scan failed (non-blocking):`, e);
102
+ }
103
+ }
104
+ // Create session
105
+ const session = agentPair.createPairSession({
106
+ taskId: task.issueIdentifier || task.issueId || task.id,
107
+ taskTitle: task.title,
108
+ taskDescription: task.description || '',
109
+ projectPath,
110
+ maxAttempts: maxIterations,
111
+ models: {
112
+ worker: this.config.roles?.worker?.model,
113
+ reviewer: this.config.roles?.reviewer?.model,
114
+ },
115
+ });
116
+ const taskPrefix = buildTaskPrefix(task, projectPath);
117
+ const context = {
118
+ task,
119
+ projectPath,
120
+ session,
121
+ config: this.config,
122
+ currentIteration: 0,
123
+ taskPrefix,
124
+ };
125
+ try {
126
+ // Full iteration loop: Worker → Reviewer → Tester
127
+ const iterationResult = await this.runFullIterationLoop(context, stages);
128
+ if (!iterationResult.success) {
129
+ return this.buildResult(context, stages, startTime);
130
+ }
131
+ // Run Documenter after all stages pass
132
+ if (this.hasStage('documenter') && context.workerResult?.success) {
133
+ if (this.config.skipDocumenterIfNoChange &&
134
+ (!context.workerResult.filesChanged || context.workerResult.filesChanged.length === 0)) {
135
+ console.log(`[${context.taskPrefix}] Skipping documenter: no files changed`);
136
+ }
137
+ else {
138
+ const documenterResult = await this.runStage('documenter', context);
139
+ stages.push(documenterResult);
140
+ // Documenter failure does not cause overall failure
141
+ }
142
+ }
143
+ // Auditor (post-success, non-blocking)
144
+ if (this.hasStage('auditor') && context.workerResult?.success) {
145
+ const auditorFileThreshold = this.config.skipAuditorUnderFileCount ?? 3;
146
+ const auditorChangedFiles = context.workerResult.filesChanged || [];
147
+ if (auditorChangedFiles.length < auditorFileThreshold) {
148
+ console.log(`[${context.taskPrefix}] Skipping auditor: ${auditorChangedFiles.length} files changed (threshold: ${auditorFileThreshold})`);
149
+ }
150
+ else {
151
+ const auditorResult = await this.runStage('auditor', context);
152
+ stages.push(auditorResult);
153
+ // Auditor failure does not affect overall success
154
+ }
155
+ }
156
+ // Skill Documenter (post-success, non-blocking)
157
+ if (this.hasStage('skill-documenter') && context.workerResult?.success) {
158
+ const sdResult = await this.runStage('skill-documenter', context);
159
+ stages.push(sdResult);
160
+ // Skill Documenter failure does not affect overall success
161
+ }
162
+ // Success
163
+ agentPair.updateSessionStatus(session.id, 'approved');
164
+ return this.buildResult(context, stages, startTime);
165
+ }
166
+ catch (error) {
167
+ console.error(`[${context.taskPrefix}] Error:`, error);
168
+ agentPair.updateSessionStatus(session.id, 'failed');
169
+ return {
170
+ success: false,
171
+ sessionId: session.id,
172
+ stages,
173
+ finalStatus: 'failed',
174
+ totalDuration: Date.now() - startTime,
175
+ iterations: context.currentIteration,
176
+ workerResult: context.workerResult,
177
+ reviewResult: context.reviewResult,
178
+ testerResult: context.testerResult,
179
+ documenterResult: context.documenterResult,
180
+ taskContext: {
181
+ issueIdentifier: context.task.issueIdentifier || context.task.issueId,
182
+ projectName: context.task.linearProject?.name,
183
+ projectPath: context.projectPath,
184
+ taskTitle: context.task.title,
185
+ },
186
+ };
187
+ }
188
+ }
189
+ // ============================================
190
+ // Stage Execution
191
+ // ============================================
192
+ /**
193
+ * Check if a stage is enabled
194
+ */
195
+ hasStage(stage) {
196
+ return this.config.stages.includes(stage);
197
+ }
198
+ /**
199
+ * Run a single stage
200
+ */
201
+ async runStage(stage, context, overrides) {
202
+ const startTime = Date.now();
203
+ const stageModel = overrides?.model ?? this.getModelForRole(stage, context.task);
204
+ const prefix = context.taskPrefix;
205
+ console.log(`[${prefix}] Stage starting: ${stage}`);
206
+ this.emit('stage:start', { stage, context });
207
+ broadcastEvent({ type: 'pipeline:stage', data: { taskId: context.task.id, stage, status: 'start', model: stageModel } });
208
+ if (this.config.verbose) {
209
+ this.emit('log', { line: `[verbose] Stage: ${stage} | model: ${stageModel ?? 'default'} | iteration: ${context.currentIteration}` });
210
+ }
211
+ try {
212
+ let result;
213
+ switch (stage) {
214
+ case 'worker': {
215
+ agentPair.updateSessionStatus(context.session.id, 'working');
216
+ const taskId = context.task.id;
217
+ const onLog = (line) => broadcastEvent({ type: 'log', data: { taskId, stage: 'worker', line: `[${prefix}] ${line}` } });
218
+ // Check if fresh context should be used (after N failures)
219
+ const useFreshContext = agentPair.shouldUseFreshContext(context.session.id);
220
+ if (useFreshContext) {
221
+ console.log(`[${prefix}] Using fresh context for worker (retry with clean slate)`);
222
+ agentPair.consumeFreshContext(context.session.id);
223
+ onLog('🔄 Using fresh context (previous attempts failed)');
224
+ }
225
+ result = await workerAgent.runWorker({
226
+ taskTitle: context.task.title,
227
+ taskDescription: context.task.description || '',
228
+ projectPath: context.projectPath,
229
+ previousFeedback: useFreshContext
230
+ ? undefined // Fresh context: no previous feedback
231
+ : (context.reviewResult
232
+ ? reviewerAgent.buildRevisionPrompt(context.reviewResult)
233
+ : undefined),
234
+ timeoutMs: this.config.roles?.worker?.timeoutMs ?? 0,
235
+ model: overrides?.model ?? this.config.roles?.worker?.model,
236
+ maxTurns: this.config.roles?.worker?.maxTurns,
237
+ adapterName: this.config.roles?.worker?.adapter,
238
+ issueIdentifier: context.task.issueIdentifier || context.task.issueId,
239
+ projectName: context.task.linearProject?.name,
240
+ onLog,
241
+ processContext: { taskId: context.task.id, stage: 'worker' },
242
+ });
243
+ agentPair.saveWorkerResult(context.session.id, result);
244
+ context.workerResult = result;
245
+ // Verbose: emit detailed worker result info
246
+ if (this.config.verbose) {
247
+ const wr = result;
248
+ if (wr.filesChanged?.length) {
249
+ this.emit('log', { line: `[verbose] Files changed: ${wr.filesChanged.join(', ')}` });
250
+ }
251
+ if (wr.commands?.length) {
252
+ this.emit('log', { line: `[verbose] Commands executed: ${wr.commands.join('; ')}` });
253
+ }
254
+ if (wr.confidencePercent != null) {
255
+ this.emit('log', { line: `[verbose] Worker confidence: ${wr.confidencePercent}%` });
256
+ }
257
+ if (wr.haltReason) {
258
+ this.emit('log', { line: `[verbose] Worker halt reason: ${wr.haltReason}` });
259
+ }
260
+ }
261
+ // Track confidence and check for degradation
262
+ const attempt = context.session.worker.attempts;
263
+ agentPair.updateConfidenceTracker(context.session.id, result, attempt);
264
+ // Check if confidence intervention is needed
265
+ if (agentPair.needsConfidenceIntervention(context.session.id)) {
266
+ console.warn(`[${prefix}] Confidence intervention needed - early review triggered`);
267
+ const summary = agentPair.getConfidenceSummary(context.session.id);
268
+ this.emit('log', { line: `⚠️ Low confidence detected: ${summary}` });
269
+ // Continue to review, but reviewer should be aware of low confidence
270
+ }
271
+ break;
272
+ }
273
+ case 'reviewer':
274
+ agentPair.updateSessionStatus(context.session.id, 'reviewing');
275
+ if (!context.workerResult) {
276
+ throw new Error('Worker result required for reviewer');
277
+ }
278
+ // Pre-check disabled - Haiku format compliance issues causing false rejections
279
+ // Proceed directly to full Sonnet review for reliability
280
+ // Reduce review depth when worker confidence is very high
281
+ let reviewerMaxTurns = this.config.roles?.reviewer?.maxTurns;
282
+ if (context.workerResult?.confidencePercent && context.workerResult.confidencePercent > 90) {
283
+ const cappedTurns = Math.min(reviewerMaxTurns ?? 10, 5);
284
+ console.log(`[${prefix}] High worker confidence (${context.workerResult.confidencePercent}%), limiting reviewer to ${cappedTurns} turns`);
285
+ reviewerMaxTurns = cappedTurns;
286
+ }
287
+ console.log(`[${prefix}] Running full review (Sonnet)...`);
288
+ result = await reviewerAgent.runReviewer({
289
+ taskTitle: context.task.title,
290
+ taskDescription: context.task.description || '',
291
+ workerResult: context.workerResult,
292
+ projectPath: context.projectPath,
293
+ timeoutMs: this.config.roles?.reviewer?.timeoutMs ?? 0,
294
+ model: this.config.roles?.reviewer?.model,
295
+ maxTurns: reviewerMaxTurns,
296
+ adapterName: this.config.roles?.reviewer?.adapter,
297
+ processContext: { taskId: context.task.id, stage: 'reviewer' },
298
+ });
299
+ agentPair.saveReviewerResult(context.session.id, result);
300
+ context.reviewResult = result;
301
+ // Verbose: emit reviewer decision details
302
+ if (this.config.verbose) {
303
+ const rr = result;
304
+ this.emit('log', { line: `[verbose] Reviewer decision: ${rr.decision}` });
305
+ if (rr.feedback) {
306
+ const lines = rr.feedback.split('\n').slice(0, 10);
307
+ for (const line of lines) {
308
+ this.emit('log', { line: `[verbose] ${line}` });
309
+ }
310
+ }
311
+ }
312
+ break;
313
+ case 'tester':
314
+ if (!context.workerResult) {
315
+ throw new Error('Worker result required for tester');
316
+ }
317
+ result = await testerAgent.runTester({
318
+ taskTitle: context.task.title,
319
+ taskDescription: context.task.description || '',
320
+ workerResult: context.workerResult,
321
+ projectPath: context.projectPath,
322
+ timeoutMs: this.config.roles?.tester?.timeoutMs ?? 0,
323
+ model: this.config.roles?.tester?.model,
324
+ maxTurns: this.config.roles?.tester?.maxTurns,
325
+ adapterName: this.config.roles?.tester?.adapter,
326
+ });
327
+ context.testerResult = result;
328
+ // Verbose: emit tester details
329
+ if (this.config.verbose) {
330
+ const tr = result;
331
+ this.emit('log', { line: `[verbose] Tests passed: ${tr.testsPassed}, failed: ${tr.testsFailed}${tr.coverage != null ? `, coverage: ${tr.coverage}%` : ''}` });
332
+ }
333
+ break;
334
+ case 'documenter':
335
+ if (!context.workerResult) {
336
+ throw new Error('Worker result required for documenter');
337
+ }
338
+ result = await documenterAgent.runDocumenter({
339
+ taskTitle: context.task.title,
340
+ taskDescription: context.task.description || '',
341
+ workerResult: context.workerResult,
342
+ projectPath: context.projectPath,
343
+ timeoutMs: this.config.roles?.documenter?.timeoutMs ?? 0,
344
+ model: this.config.roles?.documenter?.model,
345
+ maxTurns: this.config.roles?.documenter?.maxTurns,
346
+ adapterName: this.config.roles?.documenter?.adapter,
347
+ });
348
+ context.documenterResult = result;
349
+ break;
350
+ case 'auditor':
351
+ if (!context.workerResult) {
352
+ throw new Error('Worker result required for auditor');
353
+ }
354
+ result = await auditorAgent.runAuditor({
355
+ taskTitle: context.task.title,
356
+ taskDescription: context.task.description || '',
357
+ workerResult: context.workerResult,
358
+ projectPath: context.projectPath,
359
+ timeoutMs: this.config.roles?.auditor?.timeoutMs ?? 0,
360
+ model: this.config.roles?.auditor?.model,
361
+ maxTurns: this.config.roles?.auditor?.maxTurns,
362
+ adapterName: this.config.roles?.auditor?.adapter,
363
+ });
364
+ context.auditorResult = result;
365
+ break;
366
+ case 'skill-documenter':
367
+ if (!context.workerResult) {
368
+ throw new Error('Worker result required for skill-documenter');
369
+ }
370
+ result = await skillDocumenterAgent.runSkillDocumenter({
371
+ taskTitle: context.task.title,
372
+ taskDescription: context.task.description || '',
373
+ workerResult: context.workerResult,
374
+ projectPath: context.projectPath,
375
+ timeoutMs: this.config.roles?.['skill-documenter']?.timeoutMs ?? 0,
376
+ model: this.config.roles?.['skill-documenter']?.model,
377
+ maxTurns: this.config.roles?.['skill-documenter']?.maxTurns,
378
+ adapterName: this.config.roles?.['skill-documenter']?.adapter,
379
+ });
380
+ context.skillDocumenterResult = result;
381
+ break;
382
+ default:
383
+ throw new Error(`Unknown stage: ${stage}`);
384
+ }
385
+ const completedAt = Date.now();
386
+ const stageResult = {
387
+ stage,
388
+ success: this.isStageSuccess(stage, result),
389
+ result,
390
+ duration: completedAt - startTime,
391
+ startedAt: startTime,
392
+ completedAt,
393
+ };
394
+ console.log(`[${prefix}] ${stage} completed (${(stageResult.duration / 1000).toFixed(1)}s)`);
395
+ this.emit('stage:complete', { stage, result: stageResult, context });
396
+ const costInfo = result.costInfo;
397
+ if (this.config.verbose) {
398
+ 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)` : ''}` });
399
+ }
400
+ broadcastEvent({ type: 'pipeline:stage', data: {
401
+ taskId: context.task.id, stage, status: 'complete',
402
+ model: costInfo?.model,
403
+ inputTokens: costInfo?.inputTokens,
404
+ outputTokens: costInfo?.outputTokens,
405
+ costUsd: costInfo?.costUsd,
406
+ } });
407
+ return stageResult;
408
+ }
409
+ catch (error) {
410
+ const completedAt = Date.now();
411
+ const stageResult = {
412
+ stage,
413
+ success: false,
414
+ result: {
415
+ success: false,
416
+ error: error instanceof Error ? error.message : String(error),
417
+ },
418
+ duration: completedAt - startTime,
419
+ startedAt: startTime,
420
+ completedAt,
421
+ };
422
+ console.log(`[${prefix}] ${stage} failed (${(stageResult.duration / 1000).toFixed(1)}s)`);
423
+ this.emit('stage:fail', { stage, result: stageResult, context, error });
424
+ broadcastEvent({ type: 'pipeline:stage', data: { taskId: context.task.id, stage, status: 'fail' } });
425
+ return stageResult;
426
+ }
427
+ }
428
+ /**
429
+ * Determine stage success
430
+ */
431
+ isStageSuccess(stage, result) {
432
+ switch (stage) {
433
+ case 'worker':
434
+ return result.success;
435
+ case 'reviewer':
436
+ return result.decision === 'approve';
437
+ case 'tester':
438
+ return result.success;
439
+ case 'documenter':
440
+ return result.success;
441
+ case 'auditor':
442
+ return result.success;
443
+ case 'skill-documenter':
444
+ return result.success;
445
+ default:
446
+ return false;
447
+ }
448
+ }
449
+ // ============================================
450
+ // Full Iteration Loop
451
+ // ============================================
452
+ /**
453
+ * Full iteration loop
454
+ *
455
+ * 1 iteration = full pass through Worker → Reviewer → Tester
456
+ * On failure (revise) at any stage, restart from Worker in next iteration
457
+ * reject = immediate termination
458
+ */
459
+ async runFullIterationLoop(context, stages) {
460
+ const maxIterations = this.config.maxIterations ?? 3;
461
+ const hasWorker = this.hasStage('worker');
462
+ const hasReviewer = this.hasStage('reviewer');
463
+ const hasTester = this.hasStage('tester');
464
+ // No point without a worker
465
+ if (!hasWorker) {
466
+ console.log(`[${context.taskPrefix}] No worker stage configured`);
467
+ return { success: false };
468
+ }
469
+ while (context.currentIteration < maxIterations) {
470
+ context.currentIteration++;
471
+ // Stuck detection check (before iteration starts)
472
+ const stuckCheck = this.stuckDetector.check();
473
+ if (stuckCheck.isStuck) {
474
+ console.error(`[${context.taskPrefix}] STUCK DETECTED: ${stuckCheck.reason}`);
475
+ console.error(`[${context.taskPrefix}] Suggestion: ${stuckCheck.suggestion}`);
476
+ this.emit('stuck', {
477
+ reason: stuckCheck.reason,
478
+ suggestion: stuckCheck.suggestion,
479
+ context,
480
+ });
481
+ agentPair.updateSessionStatus(context.session.id, 'failed');
482
+ return { success: false };
483
+ }
484
+ this.emit('iteration:start', {
485
+ iteration: context.currentIteration,
486
+ maxIterations,
487
+ context,
488
+ });
489
+ broadcastEvent({ type: 'pipeline:iteration', data: { taskId: context.task.id, iteration: context.currentIteration } });
490
+ console.log(`[${context.taskPrefix}] Iteration ${context.currentIteration}/${maxIterations}`);
491
+ // ========== WORKER (with escalation) ==========
492
+ const workerCfg = this.config.roles?.worker;
493
+ const escalateThreshold = workerCfg?.escalateAfterIteration ?? 3;
494
+ const shouldEscalate = context.currentIteration >= escalateThreshold && !!workerCfg?.escalateModel;
495
+ const baseWorkerModel = this.getModelForRole('worker', context.task);
496
+ const workerOverrides = shouldEscalate
497
+ ? { model: workerCfg.escalateModel }
498
+ : (baseWorkerModel ? { model: baseWorkerModel } : undefined);
499
+ if (shouldEscalate) {
500
+ console.log(`[${context.taskPrefix}] Escalating worker model → ${workerCfg.escalateModel} (iteration ${context.currentIteration})`);
501
+ broadcastEvent({ type: 'pipeline:escalation', data: {
502
+ taskId: context.task.id,
503
+ iteration: context.currentIteration,
504
+ fromModel: workerCfg?.model,
505
+ toModel: workerCfg.escalateModel,
506
+ } });
507
+ }
508
+ agentPair.updateSessionStatus(context.session.id, 'working');
509
+ const workerResult = await this.runStage('worker', context, workerOverrides);
510
+ stages.push(workerResult);
511
+ // Record Worker result in stuck detector
512
+ this.stuckDetector.addEntry({
513
+ stage: 'worker',
514
+ success: workerResult.success,
515
+ output: workerResult.result.summary,
516
+ error: workerResult.result.error,
517
+ timestamp: Date.now(),
518
+ });
519
+ if (!workerResult.success) {
520
+ console.log(`[${context.taskPrefix}] Worker failed, retrying...`);
521
+ agentPair.trackFailure(context.session.id); // Track for fresh context decision
522
+ this.emit('iteration:fail', {
523
+ iteration: context.currentIteration,
524
+ stage: 'worker',
525
+ context,
526
+ });
527
+ continue; // Next iteration
528
+ }
529
+ // ========== PIPELINE GUARDS (post-worker, pre-reviewer) ==========
530
+ if (this.config.guards && context.workerResult) {
531
+ console.log(`[${context.taskPrefix}] Running pipeline guards...`);
532
+ const guardsResult = await runGuards(context.workerResult, context.projectPath, this.config.guards);
533
+ context.guardsResult = guardsResult;
534
+ if (!guardsResult.allPassed) {
535
+ // Blocking guard failed → inject revise, skip reviewer
536
+ console.log(`[${context.taskPrefix}] Blocking guard failed: ${guardsResult.combinedIssues.join('; ')}`);
537
+ context.reviewResult = {
538
+ decision: 'revise',
539
+ feedback: `Pipeline guard failed: ${guardsResult.combinedIssues.join('; ')}`,
540
+ issues: guardsResult.combinedIssues,
541
+ suggestions: ['Fix the issues flagged by quality guards'],
542
+ };
543
+ agentPair.trackFailure(context.session.id);
544
+ this.emit('iteration:fail', {
545
+ iteration: context.currentIteration,
546
+ stage: 'worker',
547
+ context,
548
+ });
549
+ agentPair.updateSessionStatus(context.session.id, 'revising');
550
+ continue;
551
+ }
552
+ // Log non-blocking guard warnings
553
+ const warnings = guardsResult.results.filter(r => !r.passed && !r.blocking);
554
+ if (warnings.length > 0) {
555
+ console.log(`[${context.taskPrefix}] Guard warnings: ${warnings.map(w => w.guard).join(', ')}`);
556
+ this.emit('log', {
557
+ line: `⚠️ Guard warnings: ${warnings.flatMap(w => w.issues).join('; ')}`,
558
+ });
559
+ }
560
+ }
561
+ // ========== HALT CHECK (confidence too low) ==========
562
+ if (context.workerResult) {
563
+ const confidence = agentPair.calculateConfidence(context.workerResult);
564
+ if (confidence < CONFIDENCE_THRESHOLDS.HALT) {
565
+ const haltReason = context.workerResult.haltReason
566
+ || `Low confidence: ${confidence}%`;
567
+ console.warn(`[${context.taskPrefix}] HALT triggered: confidence=${confidence}%, reason=${haltReason}`);
568
+ this.emit('halt', {
569
+ confidence,
570
+ haltReason,
571
+ sessionId: context.session.id,
572
+ iteration: context.currentIteration,
573
+ context,
574
+ });
575
+ // Inject revise to retry
576
+ context.reviewResult = {
577
+ decision: 'revise',
578
+ feedback: `[HALT] Confidence too low (${confidence}%). ${haltReason}`,
579
+ issues: [haltReason],
580
+ suggestions: ['Review task requirements', 'Provide additional context', 'Break into sub-tasks'],
581
+ };
582
+ agentPair.trackFailure(context.session.id);
583
+ this.emit('iteration:fail', {
584
+ iteration: context.currentIteration,
585
+ stage: 'worker',
586
+ context,
587
+ });
588
+ agentPair.updateSessionStatus(context.session.id, 'revising');
589
+ continue;
590
+ }
591
+ }
592
+ // ========== REVIEWER ==========
593
+ if (hasReviewer) {
594
+ agentPair.updateSessionStatus(context.session.id, 'reviewing');
595
+ const reviewerResult = await this.runStage('reviewer', context);
596
+ stages.push(reviewerResult);
597
+ const decision = reviewerResult.result.decision;
598
+ // Record Reviewer result in stuck detector
599
+ this.stuckDetector.addEntry({
600
+ stage: 'reviewer',
601
+ success: reviewerResult.success,
602
+ decision: decision,
603
+ output: reviewerResult.result.feedback,
604
+ timestamp: Date.now(),
605
+ });
606
+ if (decision === 'reject') {
607
+ // reject = terminate immediately
608
+ console.log(`[${context.taskPrefix}] Reviewer rejected`);
609
+ agentPair.updateSessionStatus(context.session.id, 'rejected');
610
+ return { success: false };
611
+ }
612
+ if (decision === 'revise') {
613
+ // revise = next iteration
614
+ console.log(`[${context.taskPrefix}] Reviewer requested revision`);
615
+ agentPair.trackFailure(context.session.id); // Track for fresh context decision
616
+ this.emit('iteration:fail', {
617
+ iteration: context.currentIteration,
618
+ stage: 'reviewer',
619
+ context,
620
+ });
621
+ agentPair.updateSessionStatus(context.session.id, 'revising');
622
+ continue;
623
+ }
624
+ // approve → proceed to Tester
625
+ agentPair.resetFailureStreak(context.session.id); // Reset on approval
626
+ }
627
+ // ========== TESTER ==========
628
+ if (hasTester) {
629
+ // Skip tester if no code files changed (configurable, default true)
630
+ const skipIfNoCode = this.config.skipTesterIfNoCodeChange ?? true;
631
+ const codeExtensions = /\.(ts|tsx|js|jsx|py|rs|go|java|rb|c|cpp|h|hpp)$/;
632
+ const changedFiles = context.workerResult?.filesChanged || [];
633
+ const hasCodeChange = changedFiles.some(f => codeExtensions.test(f));
634
+ if (skipIfNoCode && !hasCodeChange) {
635
+ console.log(`[${context.taskPrefix}] Skipping tester: no code files changed (${changedFiles.length} files: ${changedFiles.join(', ') || 'none'})`);
636
+ }
637
+ else {
638
+ const testerResult = await this.runStage('tester', context);
639
+ stages.push(testerResult);
640
+ if (!testerResult.success && !this.config.continueOnTestFail) {
641
+ // Test failed → set feedback then next iteration
642
+ console.log(`[${context.taskPrefix}] Tester failed, retrying...`);
643
+ agentPair.trackFailure(context.session.id); // Track for fresh context decision
644
+ if (context.testerResult) {
645
+ context.reviewResult = {
646
+ decision: 'revise',
647
+ feedback: testerAgent.buildTestFixPrompt(context.testerResult),
648
+ issues: context.testerResult.failedTests,
649
+ suggestions: context.testerResult.suggestions,
650
+ };
651
+ }
652
+ this.emit('iteration:fail', {
653
+ iteration: context.currentIteration,
654
+ stage: 'tester',
655
+ context,
656
+ });
657
+ agentPair.updateSessionStatus(context.session.id, 'revising');
658
+ continue;
659
+ }
660
+ } // end else (has code change)
661
+ }
662
+ // ========== ALL PASSED ==========
663
+ console.log(`[${context.taskPrefix}] Iteration ${context.currentIteration} completed successfully`);
664
+ this.emit('iteration:complete', {
665
+ iteration: context.currentIteration,
666
+ context,
667
+ });
668
+ return { success: true };
669
+ }
670
+ // maxIterations exceeded
671
+ console.log(`[${context.taskPrefix}] Max iterations (${maxIterations}) exceeded`);
672
+ agentPair.updateSessionStatus(context.session.id, 'failed');
673
+ return { success: false };
674
+ }
675
+ // ============================================
676
+ // Result Building
677
+ // ============================================
678
+ /**
679
+ * Build pipeline result
680
+ */
681
+ buildResult(context, stages, startTime) {
682
+ // Use context.session directly — do NOT re-fetch from store.
683
+ // updateSessionStatus('approved') archives the session (deletes from Map),
684
+ // so getPairSession() would return undefined → finalStatus = 'failed'.
685
+ const session = context.session;
686
+ const finalStatus = session.status || 'failed';
687
+ const success = finalStatus === 'approved';
688
+ // Aggregate costs from all stages
689
+ const stageCosts = [];
690
+ if (context.workerResult?.costInfo)
691
+ stageCosts.push(context.workerResult.costInfo);
692
+ if (context.reviewResult?.costInfo)
693
+ stageCosts.push(context.reviewResult.costInfo);
694
+ if (context.testerResult?.costInfo)
695
+ stageCosts.push(context.testerResult.costInfo);
696
+ if (context.documenterResult?.costInfo)
697
+ stageCosts.push(context.documenterResult.costInfo);
698
+ if (context.auditorResult?.costInfo)
699
+ stageCosts.push(context.auditorResult.costInfo);
700
+ if (context.skillDocumenterResult?.costInfo)
701
+ stageCosts.push(context.skillDocumenterResult.costInfo);
702
+ const totalCost = stageCosts.length > 0 ? aggregateCosts(stageCosts) : undefined;
703
+ if (totalCost) {
704
+ console.log(`[${context.taskPrefix}] Total cost: ${formatCost(totalCost)}`);
705
+ broadcastEvent({ type: 'task:cost', data: { taskId: context.task.id, cost: totalCost } });
706
+ }
707
+ const result = {
708
+ success,
709
+ sessionId: context.session.id,
710
+ stages,
711
+ finalStatus,
712
+ totalDuration: Date.now() - startTime,
713
+ iterations: context.currentIteration,
714
+ workerResult: context.workerResult,
715
+ reviewResult: context.reviewResult,
716
+ testerResult: context.testerResult,
717
+ documenterResult: context.documenterResult,
718
+ auditorResult: context.auditorResult,
719
+ skillDocumenterResult: context.skillDocumenterResult,
720
+ taskContext: {
721
+ issueIdentifier: context.task.issueIdentifier || context.task.issueId,
722
+ projectName: context.task.linearProject?.name,
723
+ projectPath: context.projectPath,
724
+ taskTitle: context.task.title,
725
+ },
726
+ totalCost,
727
+ };
728
+ if (success) {
729
+ this.emit('pipeline:complete', result);
730
+ }
731
+ else {
732
+ this.emit('pipeline:fail', result);
733
+ }
734
+ return result;
735
+ }
736
+ }
737
+ // Factory Functions
738
+ /**
739
+ * Create default pipeline (Worker + Reviewer)
740
+ */
741
+ export function createDefaultPipeline(maxIterations = 3) {
742
+ return new PairPipeline({
743
+ stages: ['worker', 'reviewer'],
744
+ maxIterations,
745
+ });
746
+ }
747
+ /**
748
+ * Create full pipeline (Worker + Reviewer + Tester + Documenter)
749
+ */
750
+ export function createFullPipeline(config) {
751
+ return new PairPipeline({
752
+ stages: ['worker', 'reviewer', 'tester', 'documenter'],
753
+ maxIterations: 3,
754
+ continueOnTestFail: false,
755
+ skipDocumenterIfNoChange: true,
756
+ ...config,
757
+ });
758
+ }
759
+ /**
760
+ * Create pipeline from configuration
761
+ */
762
+ export function createPipelineFromConfig(roles, maxIterations = 3, guards, jobProfiles) {
763
+ const stages = [];
764
+ if (roles?.worker?.enabled !== false) {
765
+ stages.push('worker');
766
+ }
767
+ if (roles?.reviewer?.enabled !== false) {
768
+ stages.push('reviewer');
769
+ }
770
+ if (roles?.tester?.enabled) {
771
+ stages.push('tester');
772
+ }
773
+ if (roles?.documenter?.enabled) {
774
+ stages.push('documenter');
775
+ }
776
+ if (roles?.auditor?.enabled) {
777
+ stages.push('auditor');
778
+ }
779
+ if (roles?.['skill-documenter']?.enabled) {
780
+ stages.push('skill-documenter');
781
+ }
782
+ return new PairPipeline({
783
+ stages,
784
+ maxIterations,
785
+ roles,
786
+ guards,
787
+ jobProfiles,
788
+ });
789
+ }
790
+ // Helpers
791
+ // Re-export formatting functions (extracted to pipelineFormat.ts)
792
+ export { formatPipelineResult, formatPipelineResultEmbed } from './pipelineFormat.js';
793
+ //# sourceMappingURL=pairPipeline.js.map