xcoder-dna 0.0.0-stage → 1.3.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 (390) hide show
  1. package/LICENSE +66 -0
  2. package/README.md +87 -2
  3. package/dist/agents/ai-chat-debate.d.ts +36 -0
  4. package/dist/agents/ai-chat-debate.js +300 -0
  5. package/dist/agents/ai-chat-report-writer.d.ts +7 -0
  6. package/dist/agents/ai-chat-report-writer.js +100 -0
  7. package/dist/agents/duplicate-detector.d.ts +41 -0
  8. package/dist/agents/duplicate-detector.js +65 -0
  9. package/dist/agents/genesis-agent.d.ts +61 -0
  10. package/dist/agents/genesis-agent.js +340 -0
  11. package/dist/agents/samurai-agent.d.ts +53 -0
  12. package/dist/agents/samurai-agent.js +279 -0
  13. package/dist/agents/sub-agent.d.ts +56 -0
  14. package/dist/agents/sub-agent.js +353 -0
  15. package/dist/backlog/backlog-requirement-validator.d.ts +10 -0
  16. package/dist/backlog/backlog-requirement-validator.js +60 -0
  17. package/dist/backlog/backlog-store.d.ts +29 -0
  18. package/dist/backlog/backlog-store.js +148 -0
  19. package/dist/backlog/po-agent.d.ts +16 -0
  20. package/dist/backlog/po-agent.js +121 -0
  21. package/dist/backlog/types.d.ts +25 -0
  22. package/dist/backlog/types.js +4 -0
  23. package/dist/bench/run.d.ts +11 -0
  24. package/dist/bench/run.js +185 -0
  25. package/dist/bench/types.d.ts +50 -0
  26. package/dist/bench/types.js +1 -0
  27. package/dist/cli/swarm.d.ts +10 -0
  28. package/dist/cli/swarm.js +100 -0
  29. package/dist/cli/task.d.ts +14 -0
  30. package/dist/cli/task.js +121 -0
  31. package/dist/cli/wbc-arg.d.ts +6 -0
  32. package/dist/cli/wbc-arg.js +40 -0
  33. package/dist/cli/wbc.d.ts +45 -0
  34. package/dist/cli/wbc.js +98 -0
  35. package/dist/commands/license.d.ts +9 -0
  36. package/dist/commands/license.js +140 -0
  37. package/dist/commands/release.d.ts +44 -0
  38. package/dist/commands/release.js +180 -0
  39. package/dist/commands/test.d.ts +50 -0
  40. package/dist/commands/test.js +385 -0
  41. package/dist/config/loadConfig.d.ts +82 -0
  42. package/dist/config/loadConfig.js +240 -0
  43. package/dist/config/secure-mode.d.ts +29 -0
  44. package/dist/config/secure-mode.js +63 -0
  45. package/dist/config/user-config.d.ts +39 -0
  46. package/dist/config/user-config.js +202 -0
  47. package/dist/engine/reasoning-engine.d.ts +21 -0
  48. package/dist/engine/reasoning-engine.js +59 -0
  49. package/dist/events/bus.d.ts +22 -0
  50. package/dist/events/bus.js +18 -0
  51. package/dist/index.d.ts +79 -0
  52. package/dist/index.js +77 -0
  53. package/dist/indexing/ignoreRules.d.ts +1 -0
  54. package/dist/indexing/ignoreRules.js +53 -0
  55. package/dist/instance-swarm/instance-swarm-orchestrator.d.ts +57 -0
  56. package/dist/instance-swarm/instance-swarm-orchestrator.js +204 -0
  57. package/dist/instance-swarm/protocol-name-resolver.d.ts +23 -0
  58. package/dist/instance-swarm/protocol-name-resolver.js +64 -0
  59. package/dist/license/gate.d.ts +31 -0
  60. package/dist/license/gate.js +188 -0
  61. package/dist/license/http-client.d.ts +43 -0
  62. package/dist/license/http-client.js +195 -0
  63. package/dist/license/manager.d.ts +39 -0
  64. package/dist/license/manager.js +175 -0
  65. package/dist/license/receipt.d.ts +27 -0
  66. package/dist/license/receipt.js +108 -0
  67. package/dist/license/state-codec.d.ts +72 -0
  68. package/dist/license/state-codec.js +218 -0
  69. package/dist/license/state-paths.d.ts +17 -0
  70. package/dist/license/state-paths.js +64 -0
  71. package/dist/license/store.d.ts +44 -0
  72. package/dist/license/store.js +223 -0
  73. package/dist/license/trust-anchor.d.ts +24 -0
  74. package/dist/license/trust-anchor.js +74 -0
  75. package/dist/license/types.d.ts +34 -0
  76. package/dist/license/types.js +19 -0
  77. package/dist/llm/budget.d.ts +23 -0
  78. package/dist/llm/budget.js +58 -0
  79. package/dist/llm/client.d.ts +53 -0
  80. package/dist/llm/client.js +122 -0
  81. package/dist/llm/factory.d.ts +14 -0
  82. package/dist/llm/factory.js +32 -0
  83. package/dist/orchestrator/defect-logger.d.ts +31 -0
  84. package/dist/orchestrator/defect-logger.js +101 -0
  85. package/dist/orchestrator/defect-manager.d.ts +118 -0
  86. package/dist/orchestrator/defect-manager.js +338 -0
  87. package/dist/orchestrator/defect-migration.d.ts +14 -0
  88. package/dist/orchestrator/defect-migration.js +174 -0
  89. package/dist/orchestrator/defect-store.d.ts +48 -0
  90. package/dist/orchestrator/defect-store.js +76 -0
  91. package/dist/orchestrator/healing.d.ts +14 -0
  92. package/dist/orchestrator/healing.js +11 -0
  93. package/dist/orchestrator/interactive-steering.d.ts +64 -0
  94. package/dist/orchestrator/interactive-steering.js +107 -0
  95. package/dist/orchestrator/interrupt-handler.d.ts +30 -0
  96. package/dist/orchestrator/interrupt-handler.js +70 -0
  97. package/dist/orchestrator/lesson-manager.d.ts +25 -0
  98. package/dist/orchestrator/lesson-manager.js +122 -0
  99. package/dist/orchestrator/progress-summary.d.ts +15 -0
  100. package/dist/orchestrator/progress-summary.js +106 -0
  101. package/dist/orchestrator/reasoning-score.d.ts +49 -0
  102. package/dist/orchestrator/reasoning-score.js +117 -0
  103. package/dist/orchestrator/swarm.d.ts +36 -0
  104. package/dist/orchestrator/swarm.js +77 -0
  105. package/dist/orchestrator/task-factory.d.ts +15 -0
  106. package/dist/orchestrator/task-factory.js +176 -0
  107. package/dist/orchestrator/validation-gate.d.ts +23 -0
  108. package/dist/orchestrator/validation-gate.js +155 -0
  109. package/dist/protocol/react-contract.d.ts +136 -0
  110. package/dist/protocol/react-contract.js +698 -0
  111. package/dist/protocol/wks-protocol-manager.d.ts +22 -0
  112. package/dist/protocol/wks-protocol-manager.js +72 -0
  113. package/dist/sdlc-runtime/conversation-runner.d.ts +8 -0
  114. package/dist/sdlc-runtime/conversation-runner.js +64 -0
  115. package/dist/sdlc-runtime/dag-utils.d.ts +15 -0
  116. package/dist/sdlc-runtime/dag-utils.js +67 -0
  117. package/dist/sdlc-runtime/defect-integration.d.ts +7 -0
  118. package/dist/sdlc-runtime/defect-integration.js +99 -0
  119. package/dist/sdlc-runtime/execution-loop.d.ts +38 -0
  120. package/dist/sdlc-runtime/execution-loop.js +274 -0
  121. package/dist/sdlc-runtime/lesson-recorder.d.ts +9 -0
  122. package/dist/sdlc-runtime/lesson-recorder.js +27 -0
  123. package/dist/sdlc-runtime/plan-initializer.d.ts +47 -0
  124. package/dist/sdlc-runtime/plan-initializer.js +135 -0
  125. package/dist/sdlc-runtime/progress-persister.d.ts +10 -0
  126. package/dist/sdlc-runtime/progress-persister.js +34 -0
  127. package/dist/sdlc-runtime/protocol-loader.d.ts +10 -0
  128. package/dist/sdlc-runtime/protocol-loader.js +21 -0
  129. package/dist/sdlc-runtime/reporting.d.ts +24 -0
  130. package/dist/sdlc-runtime/reporting.js +68 -0
  131. package/dist/sdlc-runtime/sdlc-orchestrator.d.ts +59 -0
  132. package/dist/sdlc-runtime/sdlc-orchestrator.js +170 -0
  133. package/dist/sdlc-runtime/sdlc-skill.d.ts +44 -0
  134. package/dist/sdlc-runtime/sdlc-skill.js +148 -0
  135. package/dist/sdlc-runtime/steering-handler.d.ts +14 -0
  136. package/dist/sdlc-runtime/steering-handler.js +51 -0
  137. package/dist/sdlc-runtime/trace-recorder.d.ts +10 -0
  138. package/dist/sdlc-runtime/trace-recorder.js +7 -0
  139. package/dist/security/index.d.ts +16 -0
  140. package/dist/security/index.js +12 -0
  141. package/dist/security/input-screen.d.ts +30 -0
  142. package/dist/security/input-screen.js +75 -0
  143. package/dist/security/tool-call-guard.d.ts +16 -0
  144. package/dist/security/tool-call-guard.js +163 -0
  145. package/dist/security/untrusted-content.d.ts +34 -0
  146. package/dist/security/untrusted-content.js +63 -0
  147. package/dist/skills/advanced-dfir/SKILL.md +85 -0
  148. package/dist/skills/advanced-pentest-lab/SKILL.md +88 -0
  149. package/dist/skills/analyst/SKILL.md +55 -0
  150. package/dist/skills/architect/SKILL.md +54 -0
  151. package/dist/skills/aws/SKILL.md +92 -0
  152. package/dist/skills/azure/SKILL.md +90 -0
  153. package/dist/skills/bylaw-context.d.ts +45 -0
  154. package/dist/skills/bylaw-context.js +61 -0
  155. package/dist/skills/bylaw-review.d.ts +20 -0
  156. package/dist/skills/bylaw-review.js +101 -0
  157. package/dist/skills/conversation/SKILL.md +29 -0
  158. package/dist/skills/design-patterns/SKILL.md +190 -0
  159. package/dist/skills/devops/SKILL.md +55 -0
  160. package/dist/skills/directives.d.ts +20 -0
  161. package/dist/skills/directives.js +313 -0
  162. package/dist/skills/docker/SKILL.md +76 -0
  163. package/dist/skills/docker-expert/SKILL.md +56 -0
  164. package/dist/skills/enterprise-systems-analyst/SKILL.md +83 -0
  165. package/dist/skills/enterprise-systems-analyst/references/crm.md +41 -0
  166. package/dist/skills/enterprise-systems-analyst/references/erp.md +40 -0
  167. package/dist/skills/enterprise-systems-analyst/references/financial-systems.md +35 -0
  168. package/dist/skills/enterprise-systems-analyst/references/hcm.md +38 -0
  169. package/dist/skills/enterprise-systems-analyst/references/mrp.md +37 -0
  170. package/dist/skills/enterprise-systems-analyst/references/scm.md +32 -0
  171. package/dist/skills/ethical-hacking-methodology/SKILL.md +119 -0
  172. package/dist/skills/externalSkillLoader.d.ts +25 -0
  173. package/dist/skills/externalSkillLoader.js +65 -0
  174. package/dist/skills/externalSkillRegistry.d.ts +33 -0
  175. package/dist/skills/externalSkillRegistry.js +94 -0
  176. package/dist/skills/filesystem-management/SKILL.md +61 -0
  177. package/dist/skills/first-run-seed.d.ts +26 -0
  178. package/dist/skills/first-run-seed.js +75 -0
  179. package/dist/skills/git-vcs/SKILL.md +84 -0
  180. package/dist/skills/kafka/SKILL.md +89 -0
  181. package/dist/skills/kubernetes/SKILL.md +93 -0
  182. package/dist/skills/kubernetes-expert/SKILL.md +54 -0
  183. package/dist/skills/openshift/SKILL.md +93 -0
  184. package/dist/skills/pentester/SKILL.md +59 -0
  185. package/dist/skills/performance-tester/SKILL.md +57 -0
  186. package/dist/skills/playwright-ui-tester/SKILL.md +67 -0
  187. package/dist/skills/programmer/SKILL.md +58 -0
  188. package/dist/skills/project-scaffolding/SKILL.md +133 -0
  189. package/dist/skills/qa-engineer/SKILL.md +91 -0
  190. package/dist/skills/rca/SKILL.md +58 -0
  191. package/dist/skills/redhat/SKILL.md +92 -0
  192. package/dist/skills/rosa/SKILL.md +80 -0
  193. package/dist/skills/scrum-framework/SKILL.md +74 -0
  194. package/dist/skills/scrum-framework/references/artifacts_and_quality.md +79 -0
  195. package/dist/skills/scrum-framework/references/roles_and_events.md +105 -0
  196. package/dist/skills/scrum-master-agent/SKILL.md +74 -0
  197. package/dist/skills/scrum-master-agent/references/behaviors.md +56 -0
  198. package/dist/skills/sdlc-skill.d.ts +1 -0
  199. package/dist/skills/sdlc-skill.js +4 -0
  200. package/dist/skills/secops/SKILL.md +52 -0
  201. package/dist/skills/secure-architect.bylaws.d.ts +68 -0
  202. package/dist/skills/secure-architect.bylaws.js +525 -0
  203. package/dist/skills/seed-skills.d.ts +48 -0
  204. package/dist/skills/seed-skills.js +213 -0
  205. package/dist/skills/skill-authoring/SKILL.md +123 -0
  206. package/dist/skills/skill-header.d.ts +51 -0
  207. package/dist/skills/skill-header.js +163 -0
  208. package/dist/skills/skill-path-guard.d.ts +41 -0
  209. package/dist/skills/skill-path-guard.js +95 -0
  210. package/dist/skills/skillRouter.d.ts +51 -0
  211. package/dist/skills/skillRouter.js +90 -0
  212. package/dist/skills/skills-root.d.ts +64 -0
  213. package/dist/skills/skills-root.js +168 -0
  214. package/dist/skills/software-architect/SKILL.md +77 -0
  215. package/dist/skills/software-engineer/SKILL.md +74 -0
  216. package/dist/skills/solid-principles/SKILL.md +94 -0
  217. package/dist/skills/task-planning/SKILL.md +115 -0
  218. package/dist/skills/tester/SKILL.md +54 -0
  219. package/dist/skills/ubuntu/SKILL.md +87 -0
  220. package/dist/skills/ui-ux-design/SKILL.md +114 -0
  221. package/dist/skills/workspace-context/SKILL.md +103 -0
  222. package/dist/sprint/controller.d.ts +37 -0
  223. package/dist/sprint/controller.js +220 -0
  224. package/dist/sprint/dag-builder.d.ts +14 -0
  225. package/dist/sprint/dag-builder.js +105 -0
  226. package/dist/sprint/reporter.d.ts +11 -0
  227. package/dist/sprint/reporter.js +97 -0
  228. package/dist/sprint/state-store.d.ts +10 -0
  229. package/dist/sprint/state-store.js +71 -0
  230. package/dist/sprint/types.d.ts +24 -0
  231. package/dist/sprint/types.js +4 -0
  232. package/dist/store/file-version-store.d.ts +24 -0
  233. package/dist/store/file-version-store.js +73 -0
  234. package/dist/store/task-store.d.ts +90 -0
  235. package/dist/store/task-store.js +166 -0
  236. package/dist/task-ingest/architect-detailer.d.ts +43 -0
  237. package/dist/task-ingest/architect-detailer.js +141 -0
  238. package/dist/task-ingest/detail-schema.d.ts +9 -0
  239. package/dist/task-ingest/detail-schema.js +195 -0
  240. package/dist/task-ingest/detailed-run.d.ts +36 -0
  241. package/dist/task-ingest/detailed-run.js +108 -0
  242. package/dist/task-ingest/extract-id.d.ts +9 -0
  243. package/dist/task-ingest/extract-id.js +24 -0
  244. package/dist/task-ingest/index.d.ts +23 -0
  245. package/dist/task-ingest/index.js +14 -0
  246. package/dist/task-ingest/ingest.d.ts +45 -0
  247. package/dist/task-ingest/ingest.js +163 -0
  248. package/dist/task-ingest/list-ingested.d.ts +13 -0
  249. package/dist/task-ingest/list-ingested.js +30 -0
  250. package/dist/task-ingest/pending-filter.d.ts +30 -0
  251. package/dist/task-ingest/pending-filter.js +59 -0
  252. package/dist/task-ingest/scanner.d.ts +56 -0
  253. package/dist/task-ingest/scanner.js +216 -0
  254. package/dist/task-ingest/source-reader.d.ts +25 -0
  255. package/dist/task-ingest/source-reader.js +93 -0
  256. package/dist/task-ingest/spec-builder.d.ts +34 -0
  257. package/dist/task-ingest/spec-builder.js +89 -0
  258. package/dist/task-ingest/wbs-extract.d.ts +50 -0
  259. package/dist/task-ingest/wbs-extract.js +226 -0
  260. package/dist/task-ingest/wbs-parser.d.ts +36 -0
  261. package/dist/task-ingest/wbs-parser.js +170 -0
  262. package/dist/tools/apiTestTool.d.ts +37 -0
  263. package/dist/tools/apiTestTool.js +128 -0
  264. package/dist/tools/ast-tools.d.ts +183 -0
  265. package/dist/tools/ast-tools.js +853 -0
  266. package/dist/tools/browse-tool.d.ts +105 -0
  267. package/dist/tools/browse-tool.js +394 -0
  268. package/dist/tools/credential.d.ts +17 -0
  269. package/dist/tools/credential.js +32 -0
  270. package/dist/tools/dependency-graph.d.ts +23 -0
  271. package/dist/tools/dependency-graph.js +164 -0
  272. package/dist/tools/edit-tool.d.ts +34 -0
  273. package/dist/tools/edit-tool.js +95 -0
  274. package/dist/tools/file-header-manager.d.ts +27 -0
  275. package/dist/tools/file-header-manager.js +153 -0
  276. package/dist/tools/fs-tools.d.ts +154 -0
  277. package/dist/tools/fs-tools.js +337 -0
  278. package/dist/tools/git-tools.d.ts +79 -0
  279. package/dist/tools/git-tools.js +348 -0
  280. package/dist/tools/github-tool.d.ts +48 -0
  281. package/dist/tools/github-tool.js +147 -0
  282. package/dist/tools/globTool.d.ts +20 -0
  283. package/dist/tools/globTool.js +34 -0
  284. package/dist/tools/grepTool.d.ts +19 -0
  285. package/dist/tools/grepTool.js +44 -0
  286. package/dist/tools/index-freshness.d.ts +58 -0
  287. package/dist/tools/index-freshness.js +190 -0
  288. package/dist/tools/index-glob.d.ts +48 -0
  289. package/dist/tools/index-glob.js +175 -0
  290. package/dist/tools/load-skill-tool.d.ts +15 -0
  291. package/dist/tools/load-skill-tool.js +114 -0
  292. package/dist/tools/patch-tools.d.ts +58 -0
  293. package/dist/tools/patch-tools.js +153 -0
  294. package/dist/tools/playwright-tool.d.ts +66 -0
  295. package/dist/tools/playwright-tool.js +121 -0
  296. package/dist/tools/project-detect.d.ts +20 -0
  297. package/dist/tools/project-detect.js +87 -0
  298. package/dist/tools/prompt-guidance.d.ts +22 -0
  299. package/dist/tools/prompt-guidance.js +23 -0
  300. package/dist/tools/scheduleTool.d.ts +19 -0
  301. package/dist/tools/scheduleTool.js +181 -0
  302. package/dist/tools/search-tools.d.ts +27 -0
  303. package/dist/tools/search-tools.js +78 -0
  304. package/dist/tools/sed-tool.d.ts +66 -0
  305. package/dist/tools/sed-tool.js +402 -0
  306. package/dist/tools/shell-result.d.ts +11 -0
  307. package/dist/tools/shell-result.js +1 -0
  308. package/dist/tools/shell-tool.d.ts +45 -0
  309. package/dist/tools/shell-tool.js +141 -0
  310. package/dist/tools/siteCrawlerTool.d.ts +32 -0
  311. package/dist/tools/siteCrawlerTool.js +205 -0
  312. package/dist/tools/tool-registry.d.ts +67 -0
  313. package/dist/tools/tool-registry.js +596 -0
  314. package/dist/tools/validate-tool.d.ts +23 -0
  315. package/dist/tools/validate-tool.js +201 -0
  316. package/dist/tools/workspace-index.d.ts +46 -0
  317. package/dist/tools/workspace-index.js +173 -0
  318. package/dist/types.d.ts +222 -0
  319. package/dist/types.js +7 -0
  320. package/dist/updater/index.d.ts +14 -0
  321. package/dist/updater/index.js +120 -0
  322. package/dist/util/banner.d.ts +25 -0
  323. package/dist/util/banner.js +140 -0
  324. package/dist/util/command-suggester.d.ts +6 -0
  325. package/dist/util/command-suggester.js +25 -0
  326. package/dist/util/confirm-interrupt.d.ts +10 -0
  327. package/dist/util/confirm-interrupt.js +31 -0
  328. package/dist/util/continue-trigger.d.ts +11 -0
  329. package/dist/util/continue-trigger.js +20 -0
  330. package/dist/util/env-info.d.ts +18 -0
  331. package/dist/util/env-info.js +37 -0
  332. package/dist/util/file-access-log.d.ts +35 -0
  333. package/dist/util/file-access-log.js +140 -0
  334. package/dist/util/footer-manager.d.ts +124 -0
  335. package/dist/util/footer-manager.js +195 -0
  336. package/dist/util/footer-renderer.d.ts +67 -0
  337. package/dist/util/footer-renderer.js +319 -0
  338. package/dist/util/footer-state.d.ts +34 -0
  339. package/dist/util/footer-state.js +18 -0
  340. package/dist/util/footer-text.d.ts +51 -0
  341. package/dist/util/footer-text.js +74 -0
  342. package/dist/util/ids.d.ts +1 -0
  343. package/dist/util/ids.js +4 -0
  344. package/dist/util/levenshtein.d.ts +6 -0
  345. package/dist/util/levenshtein.js +34 -0
  346. package/dist/util/logger.d.ts +10 -0
  347. package/dist/util/logger.js +41 -0
  348. package/dist/util/logs.d.ts +26 -0
  349. package/dist/util/logs.js +88 -0
  350. package/dist/util/output-handler.d.ts +89 -0
  351. package/dist/util/output-handler.js +193 -0
  352. package/dist/util/output-interceptor.d.ts +18 -0
  353. package/dist/util/output-interceptor.js +49 -0
  354. package/dist/util/output-paths.d.ts +43 -0
  355. package/dist/util/output-paths.js +121 -0
  356. package/dist/util/package-json.d.ts +6 -0
  357. package/dist/util/package-json.js +36 -0
  358. package/dist/util/process-kill.d.ts +27 -0
  359. package/dist/util/process-kill.js +148 -0
  360. package/dist/util/protocol-error-logger.d.ts +33 -0
  361. package/dist/util/protocol-error-logger.js +73 -0
  362. package/dist/util/redact.d.ts +25 -0
  363. package/dist/util/redact.js +103 -0
  364. package/dist/util/scroll-region-guard.d.ts +33 -0
  365. package/dist/util/scroll-region-guard.js +63 -0
  366. package/dist/util/spinner.d.ts +15 -0
  367. package/dist/util/spinner.js +49 -0
  368. package/dist/util/terminal-output.d.ts +34 -0
  369. package/dist/util/terminal-output.js +1 -0
  370. package/dist/util/terminal-silent.d.ts +6 -0
  371. package/dist/util/terminal-silent.js +20 -0
  372. package/dist/util/terminal.d.ts +56 -0
  373. package/dist/util/terminal.js +124 -0
  374. package/dist/util/text-sanitize.d.ts +8 -0
  375. package/dist/util/text-sanitize.js +45 -0
  376. package/dist/util/thinking-spinner.d.ts +27 -0
  377. package/dist/util/thinking-spinner.js +189 -0
  378. package/dist/util/tool-error-logger.d.ts +33 -0
  379. package/dist/util/tool-error-logger.js +77 -0
  380. package/dist/util/tty.d.ts +13 -0
  381. package/dist/util/tty.js +16 -0
  382. package/dist/util/xcoder-paths.d.ts +56 -0
  383. package/dist/util/xcoder-paths.js +63 -0
  384. package/dist/version.d.ts +2 -0
  385. package/dist/version.js +4 -0
  386. package/dist/worker-agent/to-subtask-node.d.ts +35 -0
  387. package/dist/worker-agent/to-subtask-node.js +41 -0
  388. package/dist/worker-agent/worker-orchestrator.d.ts +104 -0
  389. package/dist/worker-agent/worker-orchestrator.js +201 -0
  390. package/package.json +39 -4
@@ -0,0 +1,122 @@
1
+ import { promises as fs } from "node:fs";
2
+ import path from "node:path";
3
+ import { randomUUID } from "node:crypto";
4
+ /**
5
+ * Resolve whether lesson-learned is enabled from CLI option + env var.
6
+ * CLI flag "--lesson-learned" → true; "--no-lesson-learned" → false.
7
+ * If neither is passed, check XCODER_LESSON_LEARNED ("true" → true).
8
+ * Default: false.
9
+ */
10
+ export function resolveLessonFlag(cliFlag, env) {
11
+ if (cliFlag === true)
12
+ return true;
13
+ if (cliFlag === false)
14
+ return false;
15
+ const envVal = env.XCODER_LESSON_LEARNED;
16
+ if (envVal !== undefined)
17
+ return envVal.toLowerCase() === "true";
18
+ return false;
19
+ }
20
+ const LESSON_FILE = ".xcoder/lesson.md";
21
+ const MAX_FILE_SIZE = 64 * 1024; // 64 KB
22
+ /**
23
+ * Read the full contents of .xcoder/lesson.md.
24
+ * Returns the raw Markdown string (empty string if the file doesn't exist).
25
+ */
26
+ export async function loadLessons(workspaceRoot) {
27
+ const filePath = path.join(workspaceRoot, LESSON_FILE);
28
+ try {
29
+ return await fs.readFile(filePath, "utf8");
30
+ }
31
+ catch (e) {
32
+ const code = e.code;
33
+ if (code === "ENOENT")
34
+ return "";
35
+ throw e;
36
+ }
37
+ }
38
+ /**
39
+ * Check if the lessons file exceeds 64 KB.
40
+ * Returns a warning string if it does, or null if it's within bounds.
41
+ */
42
+ export async function checkLessonFileSize(workspaceRoot) {
43
+ const filePath = path.join(workspaceRoot, LESSON_FILE);
44
+ try {
45
+ const stat = await fs.stat(filePath);
46
+ if (stat.size > MAX_FILE_SIZE) {
47
+ const kb = Math.round(stat.size / 1024);
48
+ return (`.xcoder/lesson.md is ${kb} KB (limit: 64 KB). ` +
49
+ `Lessons beyond 64 KB are NOT injected into Sub Agent prompts. ` +
50
+ `Consider pruning older entries manually.`);
51
+ }
52
+ }
53
+ catch {
54
+ // File doesn't exist — nothing to warn about.
55
+ }
56
+ return null;
57
+ }
58
+ /**
59
+ * Record a lesson into .xcoder/lesson.md with an atomic write.
60
+ * Uses temp-file + rename for concurrency safety.
61
+ * Creates .xcoder/ dir and lesson.md on first write.
62
+ * Non-fatal: if the write fails, the caller logs a warning and continues.
63
+ */
64
+ export async function recordLesson(workspaceRoot, entry) {
65
+ const dir = path.join(workspaceRoot, ".xcoder");
66
+ await fs.mkdir(dir, { recursive: true });
67
+ const filePath = path.join(workspaceRoot, LESSON_FILE);
68
+ const ts = new Date().toISOString();
69
+ const tagsFormatted = `[${entry.tags.join(", ")}]`;
70
+ const block = [
71
+ `## Lesson — ${ts}`,
72
+ `- **source:** \`${entry.source}\``,
73
+ `- **taskId:** \`${entry.taskId}\``,
74
+ `- **tags:** \`${tagsFormatted}\``,
75
+ `- **context:** ${entry.context}`,
76
+ `- **lesson:** ${entry.lesson}`,
77
+ "",
78
+ ].join("\n");
79
+ let oldContent = "";
80
+ try {
81
+ oldContent = await fs.readFile(filePath, "utf8");
82
+ }
83
+ catch (e) {
84
+ const code = e.code;
85
+ if (code !== "ENOENT")
86
+ throw e;
87
+ }
88
+ const newContent = oldContent ? `${oldContent}${block}` : block;
89
+ const tmpPath = `${filePath}.tmp-${randomUUID()}`;
90
+ try {
91
+ await fs.writeFile(tmpPath, newContent, "utf8");
92
+ await fs.rename(tmpPath, filePath);
93
+ }
94
+ catch (e) {
95
+ // If rename fails (e.g. another process wrote concurrently),
96
+ // retry once: re-read current content and try again.
97
+ try {
98
+ let currentContent = "";
99
+ try {
100
+ currentContent = await fs.readFile(filePath, "utf8");
101
+ }
102
+ catch {
103
+ // file might have been deleted — that's fine
104
+ }
105
+ const retryContent = currentContent ? `${currentContent}${block}` : block;
106
+ const retryTmp = `${filePath}.tmp-${randomUUID()}`;
107
+ await fs.writeFile(retryTmp, retryContent, "utf8");
108
+ await fs.rename(retryTmp, filePath);
109
+ }
110
+ catch {
111
+ // Swallow — never crash the orchestrator on a lesson write failure.
112
+ // The lesson is lost, but the run continues.
113
+ }
114
+ // Clean up the original temp file if it still exists.
115
+ try {
116
+ await fs.unlink(tmpPath);
117
+ }
118
+ catch {
119
+ // Best effort.
120
+ }
121
+ }
122
+ }
@@ -0,0 +1,15 @@
1
+ import type { TaskRun } from "../types.js";
2
+ /**
3
+ * Written to `.xcoder/tasks/<taskId>.md` at every terminal state (done,
4
+ * escalated, or halted) and refreshed again after a resume. Two audiences:
5
+ *
6
+ * 1. A human re-opening this task later — a readable "what happened"
7
+ * without digging through think.log/sys.log/score.log by hand.
8
+ * 2. A resumed Sub Agent — its `healing.log` (persisted per-node) already
9
+ * carries what it needs to continue without re-discovery, but this
10
+ * file is what `--resume` points a human at, and its file-list section
11
+ * is exactly the "don't re-query every file to understand everything"
12
+ * ask: a resumed subtask's healing hint references it directly rather
13
+ * than making the model glob the whole workspace again.
14
+ */
15
+ export declare function buildProgressSummaryMarkdown(run: TaskRun): string;
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Written to `.xcoder/tasks/<taskId>.md` at every terminal state (done,
3
+ * escalated, or halted) and refreshed again after a resume. Two audiences:
4
+ *
5
+ * 1. A human re-opening this task later — a readable "what happened"
6
+ * without digging through think.log/sys.log/score.log by hand.
7
+ * 2. A resumed Sub Agent — its `healing.log` (persisted per-node) already
8
+ * carries what it needs to continue without re-discovery, but this
9
+ * file is what `--resume` points a human at, and its file-list section
10
+ * is exactly the "don't re-query every file to understand everything"
11
+ * ask: a resumed subtask's healing hint references it directly rather
12
+ * than making the model glob the whole workspace again.
13
+ */
14
+ export function buildProgressSummaryMarkdown(run) {
15
+ const { spec, dag, status, escalations, totalTokenUsage } = run;
16
+ const lines = [];
17
+ lines.push(`# Progress Summary — ${spec.taskId}`);
18
+ lines.push("");
19
+ lines.push(`**Goal:** ${spec.goal}`);
20
+ lines.push(`**Status:** ${status}`);
21
+ lines.push(`**Last updated:** ${new Date().toISOString()}`);
22
+ lines.push(`**Tokens spent so far:** ${totalTokenUsage.inputTokens} in / ${totalTokenUsage.outputTokens} out`);
23
+ lines.push("");
24
+ lines.push("## Plan");
25
+ for (const n of dag) {
26
+ const box = n.status === "done" ? "[x]" : "[ ]";
27
+ const healingNote = n.healing.attempts > 0 ? ` (healing ${n.healing.attempts}/${n.healing.maxAttempts})` : "";
28
+ lines.push(`- ${box} \`${n.id}\` (${n.role}) — ${n.status}${healingNote}`);
29
+ }
30
+ lines.push("");
31
+ const done = dag.filter((n) => n.status === "done");
32
+ if (done.length) {
33
+ lines.push("## What's already done");
34
+ for (const n of done) {
35
+ lines.push(`### \`${n.id}\` (${n.role}) — done`);
36
+ lines.push(n.result?.summary ?? "(no summary recorded)");
37
+ lines.push("");
38
+ }
39
+ }
40
+ const allFiles = new Set();
41
+ for (const n of dag) {
42
+ for (const f of n.result?.filesTouched ?? [])
43
+ allFiles.add(f);
44
+ }
45
+ if (allFiles.size) {
46
+ lines.push("## Files created or modified (by subtask)");
47
+ lines.push("A resumed subtask should check these with `read_file`/`glob` before writing anything new — " +
48
+ "most of what's needed to continue is already in this list, not in the original design doc.");
49
+ for (const n of dag) {
50
+ const meta = n.result?._filesTouchedMeta;
51
+ const files = n.result?.filesTouched;
52
+ if ((!meta || meta.length === 0) && (!files || files.length === 0))
53
+ continue;
54
+ lines.push(`### \`${n.id}\` (${n.role})`);
55
+ if (meta && meta.length > 0) {
56
+ for (const entry of meta) {
57
+ const label = entry.operation === "created" ? "[created]" : entry.operation === "modified" ? "[modified]" : "[touched]";
58
+ lines.push(`- \`${entry.path}\` ${label}`);
59
+ }
60
+ }
61
+ else if (files) {
62
+ for (const f of [...files].sort()) {
63
+ lines.push(`- \`${f}\` [touched]`);
64
+ }
65
+ }
66
+ lines.push("");
67
+ }
68
+ lines.push("");
69
+ }
70
+ const blocked = dag.filter((n) => n.status === "escalated" || n.status === "failed");
71
+ if (blocked.length) {
72
+ lines.push("## What's blocking");
73
+ for (const n of blocked) {
74
+ const esc = escalations.find((e) => e.subtaskId === n.id);
75
+ lines.push(`### \`${n.id}\` (${n.role}) — ${n.status}`);
76
+ lines.push(`Reason: ${esc?.reason ?? n.healing.log.at(-1) ?? "(no reason recorded)"}`);
77
+ lines.push(`Healing attempts used: ${n.healing.attempts}/${n.healing.maxAttempts}`);
78
+ lines.push("");
79
+ }
80
+ }
81
+ const remaining = dag.filter((n) => n.status !== "done");
82
+ if (remaining.length && status !== "done") {
83
+ lines.push("## Next steps when resumed");
84
+ for (const n of remaining) {
85
+ lines.push(`- \`${n.id}\` (${n.role}, ${n.status}) — ${nextStepNote(n)}`);
86
+ }
87
+ lines.push("");
88
+ }
89
+ if (status === "done") {
90
+ lines.push("## Result");
91
+ lines.push("This task completed successfully — nothing left to resume.");
92
+ }
93
+ return lines.join("\n");
94
+ }
95
+ function nextStepNote(n) {
96
+ if (n.status === "escalated") {
97
+ return "will be retried with a fresh healing budget on resume; its healing log (what was already tried) carries forward.";
98
+ }
99
+ if (n.status === "pending") {
100
+ return "blocked on an upstream dependency finishing first.";
101
+ }
102
+ if (n.status === "ready" || n.status === "healing") {
103
+ return "will be (re-)dispatched on resume.";
104
+ }
105
+ return "no action needed.";
106
+ }
@@ -0,0 +1,49 @@
1
+ import type { SubtaskNode, SubtaskResult } from "../types.js";
2
+ import type { ValidationOutcome } from "./validation-gate.js";
3
+ export interface ReasoningScore {
4
+ score: number;
5
+ breakdown: string[];
6
+ }
7
+ /**
8
+ * WHAT THIS IS: a transparent, additive rubric over one subtask attempt —
9
+ * acceptance-criteria pass rate, iteration efficiency, error rate, and
10
+ * self-check discipline. Every point gained or lost has a one-line reason
11
+ * in `breakdown`, on purpose: a score nobody can audit is a score nobody
12
+ * should trust enough to act on.
13
+ *
14
+ * WHAT THIS IS NOT: a gate. Validation Gate (`validation-gate.ts`) already
15
+ * decides pass/fail from acceptance criteria alone — that decision is
16
+ * final and this score never overrides it. This is a SEPARATE signal for
17
+ * two specific, bounded uses:
18
+ *
19
+ * 1. Within a single task run: a low-efficiency score on a failed
20
+ * attempt (many iterations, repeated errors) gets folded into the
21
+ * next healing retry's hint — see `sdlc-orchestrator.ts`'s
22
+ * `routeFailure` — so the retry gets a concrete nudge ("you spent 18
23
+ * iterations and repeated the same failed edit_file call 4 times")
24
+ * instead of just "try again." That's a real, bounded improvement
25
+ * inside one run's healing loop.
26
+ *
27
+ * 2. Across benchmark runs over time: `bench/run.ts` reports the average
28
+ * score per fixture per run. A maintainer comparing this week's
29
+ * average against last week's is the actual feedback loop for "does
30
+ * this directive/skill/prompt change help" — a human decision
31
+ * informed by a trend, not an automatic one.
32
+ *
33
+ * What this deliberately does NOT claim to do: make the model itself
34
+ * smarter mid-conversation. Claude isn't fine-tuned by this score, and
35
+ * feeding a bare number back into the model's own context is a Goodhart's-
36
+ * law risk (a model that can see its score can learn to game the score's
37
+ * proxies — fewer tool calls, a confident-sounding self_check — rather
38
+ * than the actual acceptance criteria). That's why the score itself is
39
+ * never shown to the Sub Agent; only the specific, concrete FAILURE REASON
40
+ * (already the existing healing-hint mechanism) is.
41
+ */
42
+ export declare function computeReasoningScore(node: SubtaskNode, result: SubtaskResult, validation: ValidationOutcome): ReasoningScore;
43
+ /**
44
+ * The one place a score's breakdown is allowed to influence the model: a
45
+ * short, concrete efficiency note appended to the NEXT healing attempt's
46
+ * hint — never the raw number, never phrased as "your score was X."
47
+ * Silent no-op if the attempt wasn't actually inefficient.
48
+ */
49
+ export declare function efficiencyHint(result: SubtaskResult): string | null;
@@ -0,0 +1,117 @@
1
+ const SELF_CHECK_EXPECTED_ROLES = new Set(["programmer", "refactorer", "tester", "devops", "ui-api-tester"]);
2
+ /**
3
+ * WHAT THIS IS: a transparent, additive rubric over one subtask attempt —
4
+ * acceptance-criteria pass rate, iteration efficiency, error rate, and
5
+ * self-check discipline. Every point gained or lost has a one-line reason
6
+ * in `breakdown`, on purpose: a score nobody can audit is a score nobody
7
+ * should trust enough to act on.
8
+ *
9
+ * WHAT THIS IS NOT: a gate. Validation Gate (`validation-gate.ts`) already
10
+ * decides pass/fail from acceptance criteria alone — that decision is
11
+ * final and this score never overrides it. This is a SEPARATE signal for
12
+ * two specific, bounded uses:
13
+ *
14
+ * 1. Within a single task run: a low-efficiency score on a failed
15
+ * attempt (many iterations, repeated errors) gets folded into the
16
+ * next healing retry's hint — see `sdlc-orchestrator.ts`'s
17
+ * `routeFailure` — so the retry gets a concrete nudge ("you spent 18
18
+ * iterations and repeated the same failed edit_file call 4 times")
19
+ * instead of just "try again." That's a real, bounded improvement
20
+ * inside one run's healing loop.
21
+ *
22
+ * 2. Across benchmark runs over time: `bench/run.ts` reports the average
23
+ * score per fixture per run. A maintainer comparing this week's
24
+ * average against last week's is the actual feedback loop for "does
25
+ * this directive/skill/prompt change help" — a human decision
26
+ * informed by a trend, not an automatic one.
27
+ *
28
+ * What this deliberately does NOT claim to do: make the model itself
29
+ * smarter mid-conversation. Claude isn't fine-tuned by this score, and
30
+ * feeding a bare number back into the model's own context is a Goodhart's-
31
+ * law risk (a model that can see its score can learn to game the score's
32
+ * proxies — fewer tool calls, a confident-sounding self_check — rather
33
+ * than the actual acceptance criteria). That's why the score itself is
34
+ * never shown to the Sub Agent; only the specific, concrete FAILURE REASON
35
+ * (already the existing healing-hint mechanism) is.
36
+ */
37
+ export function computeReasoningScore(node, result, validation) {
38
+ const breakdown = [];
39
+ let score = 0;
40
+ // --- Acceptance criteria: up to 60 points -------------------------------
41
+ const totalAC = node.acceptanceCriteria.length;
42
+ if (totalAC === 0) {
43
+ score += 60;
44
+ breakdown.push("+60 no acceptance criteria defined for this stage (e.g. conversation) — full credit");
45
+ }
46
+ else {
47
+ const passedAC = validation.perCriterion.filter((c) => c.passed).length;
48
+ const points = Math.round((60 * passedAC) / totalAC);
49
+ score += points;
50
+ breakdown.push(`+${points} acceptance criteria: ${passedAC}/${totalAC} passed`);
51
+ }
52
+ // --- Iteration efficiency: up to 25 points ------------------------------
53
+ const iterations = result.iterations;
54
+ if (iterations <= 8) {
55
+ score += 25;
56
+ breakdown.push(`+25 efficient: reached a result in ${iterations} iteration(s) (≤8 baseline)`);
57
+ }
58
+ else {
59
+ const penalty = Math.min(25, (iterations - 8) * 2);
60
+ const points = 25 - penalty;
61
+ score += points;
62
+ breakdown.push(`+${points} took ${iterations} iterations, ${penalty} points off for exceeding the 8-iteration baseline`);
63
+ }
64
+ // --- Error rate: down to -20 points -------------------------------------
65
+ const errorCount = result.raoTrace.filter((s) => s.observation.startsWith("protocol_error") || s.observation.startsWith("llm_error")).length;
66
+ if (errorCount > 0) {
67
+ const penalty = Math.min(20, errorCount * 4);
68
+ score -= penalty;
69
+ breakdown.push(`-${penalty} ${errorCount} protocol/LLM error(s) during the attempt`);
70
+ }
71
+ else {
72
+ breakdown.push("+0 no protocol/LLM errors");
73
+ }
74
+ // --- Self-check discipline: ±15 points -----------------------------------
75
+ const expectsSelfCheck = SELF_CHECK_EXPECTED_ROLES.has(node.role);
76
+ if (result.selfCheck?.ran && result.selfCheck.passed) {
77
+ score += 15;
78
+ breakdown.push("+15 self_check ran and passed");
79
+ }
80
+ else if (result.selfCheck?.ran && !result.selfCheck.passed) {
81
+ breakdown.push("+0 self_check ran but did not pass (consistent with a failed validation, not double-penalized)");
82
+ }
83
+ else if (expectsSelfCheck) {
84
+ score -= 5;
85
+ breakdown.push(`-5 role "${node.role}" is expected to self-check mechanically-verifiable work, but self_check was never reported`);
86
+ }
87
+ else {
88
+ breakdown.push("+0 self_check not expected for this role");
89
+ }
90
+ // --- Healing cost: -5 per attempt already spent getting here -----------
91
+ if (node.healing.attempts > 0) {
92
+ const penalty = node.healing.attempts * 5;
93
+ score -= penalty;
94
+ breakdown.push(`-${penalty} this is healing attempt ${node.healing.attempts}/${node.healing.maxAttempts} — it took retries to get here`);
95
+ }
96
+ const clamped = Math.max(0, Math.min(100, score));
97
+ if (clamped !== score)
98
+ breakdown.push(`(raw ${score}, clamped to ${clamped})`);
99
+ return { score: clamped, breakdown };
100
+ }
101
+ /**
102
+ * The one place a score's breakdown is allowed to influence the model: a
103
+ * short, concrete efficiency note appended to the NEXT healing attempt's
104
+ * hint — never the raw number, never phrased as "your score was X."
105
+ * Silent no-op if the attempt wasn't actually inefficient.
106
+ */
107
+ export function efficiencyHint(result) {
108
+ const notes = [];
109
+ if (result.iterations > 12) {
110
+ notes.push(`the previous attempt took ${result.iterations} iterations — read each observation fully before deciding the next action, rather than re-checking the same thing repeatedly`);
111
+ }
112
+ const errorCount = result.raoTrace.filter((s) => s.observation.startsWith("protocol_error") || s.observation.startsWith("llm_error")).length;
113
+ if (errorCount >= 2) {
114
+ notes.push(`the previous attempt hit ${errorCount} protocol/tool errors — re-read the response contract and each tool's input shape carefully before calling it again`);
115
+ }
116
+ return notes.length ? notes.join("; ") : null;
117
+ }
@@ -0,0 +1,36 @@
1
+ import type { SubtaskNode, SubtaskResult } from "../types.js";
2
+ import type { WksProtocolMap } from "../protocol/wks-protocol-manager.js";
3
+ import { LlmClient } from "../llm/client.js";
4
+ export interface SwarmDispatchResult {
5
+ subtaskId: string;
6
+ result: SubtaskResult;
7
+ }
8
+ /**
9
+ * The "swarm" the brief asked for: when more than one subtask is `ready`
10
+ * at once, Xcoder SDLC runs a Sub Agent for each concurrently rather than one at
11
+ * a time, bounded by `concurrency`.
12
+ *
13
+ * ISOLATION CONTRACT: this function itself never throws because of
14
+ * anything a single Sub Agent does. `SubAgent.run()` is already designed
15
+ * not to throw (see `agents/sub-agent.ts`), but the `try/catch` below is a
16
+ * deliberate second layer — if a future change to `SubAgent` or a Node-
17
+ * level failure (e.g. an out-of-memory kill translated into a rejected
18
+ * promise) ever does throw, this is where it's caught, logged, and turned
19
+ * into a `crashed: true` result that flows through the SAME validate →
20
+ * heal → escalate pipeline as any other failed subtask, rather than
21
+ * aborting the whole `Promise.all` and taking every other in-flight Sub
22
+ * Agent — and the Master Orchestrator itself — down with it.
23
+ */
24
+ export declare function dispatchSwarm(ready: SubtaskNode[], opts: {
25
+ taskId: string;
26
+ workspaceRoot: string;
27
+ llm: LlmClient;
28
+ subAgentLlm?: LlmClient;
29
+ concurrency: number;
30
+ healingHints?: Record<string, string>;
31
+ protocolOverrides?: WksProtocolMap;
32
+ lessonLearned?: boolean;
33
+ lessonContext?: string;
34
+ signal?: AbortSignal;
35
+ quiet?: boolean;
36
+ }): Promise<SwarmDispatchResult[]>;
@@ -0,0 +1,77 @@
1
+ import { SubAgent } from "../agents/sub-agent.js";
2
+ import { appendSys } from "../util/logs.js";
3
+ import { emitXcoderEvent } from "../events/bus.js";
4
+ import * as term from "../util/terminal.js";
5
+ import { silentTerminal } from "../util/terminal-silent.js";
6
+ /**
7
+ * The "swarm" the brief asked for: when more than one subtask is `ready`
8
+ * at once, Xcoder SDLC runs a Sub Agent for each concurrently rather than one at
9
+ * a time, bounded by `concurrency`.
10
+ *
11
+ * ISOLATION CONTRACT: this function itself never throws because of
12
+ * anything a single Sub Agent does. `SubAgent.run()` is already designed
13
+ * not to throw (see `agents/sub-agent.ts`), but the `try/catch` below is a
14
+ * deliberate second layer — if a future change to `SubAgent` or a Node-
15
+ * level failure (e.g. an out-of-memory kill translated into a rejected
16
+ * promise) ever does throw, this is where it's caught, logged, and turned
17
+ * into a `crashed: true` result that flows through the SAME validate →
18
+ * heal → escalate pipeline as any other failed subtask, rather than
19
+ * aborting the whole `Promise.all` and taking every other in-flight Sub
20
+ * Agent — and the Master Orchestrator itself — down with it.
21
+ */
22
+ export async function dispatchSwarm(ready, opts) {
23
+ const results = [];
24
+ const queue = [...ready];
25
+ const concurrency = Math.max(1, opts.concurrency);
26
+ const resolvedTerm = opts.quiet ? silentTerminal : term;
27
+ async function worker() {
28
+ while (queue.length) {
29
+ // Stop pulling new nodes from the queue when the abort signal fires.
30
+ // In-flight agents complete naturally — no real-time cancellation of
31
+ // in-progress LLM calls (explicit non-goal).
32
+ if (opts.signal?.aborted)
33
+ return;
34
+ const node = queue.shift();
35
+ if (!node)
36
+ return;
37
+ resolvedTerm.orchestratorNote(`dispatching ${node.id} (${node.role} / ${node.engine})`);
38
+ emitXcoderEvent({ type: "orchestrator:note", taskId: opts.taskId, subtaskId: node.id, data: { message: `dispatching ${node.id} (${node.role} / ${node.engine})` } });
39
+ const agent = new SubAgent({
40
+ taskId: opts.taskId,
41
+ workspaceRoot: opts.workspaceRoot,
42
+ llm: opts.subAgentLlm ?? opts.llm,
43
+ healingHint: opts.healingHints?.[node.id],
44
+ protocolOverrides: opts.protocolOverrides,
45
+ lessonLearned: opts.lessonLearned,
46
+ lessonContext: opts.lessonContext,
47
+ quiet: opts.quiet,
48
+ });
49
+ let result;
50
+ try {
51
+ result = await agent.run(node);
52
+ }
53
+ catch (e) {
54
+ // The safety net described above. This branch existing at all means
55
+ // a bug somewhere else — it should never fire in practice — but if
56
+ // it does, the orchestrator keeps running instead of the whole CLI
57
+ // process dying with no report.
58
+ const message = e.stack ?? String(e);
59
+ await appendSys(opts.workspaceRoot, opts.taskId, `[${node.id}] UNCAUGHT crash in swarm worker: ${message}`);
60
+ resolvedTerm.printCrash(node.id, `uncaught exception, isolated at the swarm boundary: ${e.message}`);
61
+ emitXcoderEvent({ type: "agent:crash", taskId: opts.taskId, subtaskId: node.id, data: { message: e.message, recoverable: false } });
62
+ result = {
63
+ summary: `Sub Agent crashed unexpectedly: ${e.message}`,
64
+ deliverable: null,
65
+ filesTouched: [],
66
+ raoTrace: [],
67
+ tokenUsage: { inputTokens: 0, outputTokens: 0 },
68
+ iterations: 0,
69
+ crashed: true,
70
+ };
71
+ }
72
+ results.push({ subtaskId: node.id, result });
73
+ }
74
+ }
75
+ await Promise.all(Array.from({ length: Math.min(concurrency, queue.length) }, () => worker()));
76
+ return results;
77
+ }
@@ -0,0 +1,15 @@
1
+ import type { AcceptanceCriterion, SdlcStage, SubtaskNode, TaskInputs, TaskSpec } from "../types.js";
2
+ export declare function deliverableFor(stage: SdlcStage): string;
3
+ export declare function acceptanceCriteriaFor(stage: SdlcStage): AcceptanceCriterion[];
4
+ /**
5
+ * Builds the initial DAG for a non-conversation task. Deliberately linear
6
+ * for v1 (matching the brief's stage sequences) rather than inventing
7
+ * parallel branches Xcoder SDLC has no evidence justify — the swarm dispatcher
8
+ * (see `orchestrator/swarm.ts`) is what actually gives you fan-out, once a
9
+ * `replan` action splits a stage into independent nodes (e.g. multiple
10
+ * files to implement in parallel). Nodes are fully self-contained: a Sub
11
+ * Agent needs nothing beyond the node it's handed.
12
+ */
13
+ export declare function buildInitialPlan(spec: TaskSpec): SubtaskNode[];
14
+ export declare function isConversation(spec: TaskSpec): boolean;
15
+ export declare function buildTaskSpec(rawTask: string, cliInputs: Partial<TaskInputs>, constraints: TaskSpec["constraints"]): TaskSpec;