@karajan-family/code 4.21.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 (746) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +98 -0
  3. package/bin/karajan-mcp.js +2 -0
  4. package/bin/kj-rag-mcp.js +75 -0
  5. package/bin/kj-tail +361 -0
  6. package/bin/kj.js +2 -0
  7. package/docs/README.es.md +80 -0
  8. package/docs/karajan-code-logo-small.png +0 -0
  9. package/library/logical-clocks-lamport.md +40 -0
  10. package/package.json +140 -0
  11. package/packages/ai-trash/README.md +37 -0
  12. package/packages/ai-trash/bin/kj-trash.js +10 -0
  13. package/packages/ai-trash/package.json +43 -0
  14. package/packages/ai-trash/src/cli.js +200 -0
  15. package/packages/ai-trash/src/destructive-parser.js +74 -0
  16. package/packages/ai-trash/src/git-snapshot.js +128 -0
  17. package/packages/ai-trash/src/hook.js +137 -0
  18. package/packages/ai-trash/src/index.js +14 -0
  19. package/packages/ai-trash/src/install.js +73 -0
  20. package/packages/ai-trash/src/logger.js +60 -0
  21. package/packages/ai-trash/src/manifest.js +91 -0
  22. package/packages/ai-trash/src/permissions.js +26 -0
  23. package/packages/ai-trash/src/snapshot.js +66 -0
  24. package/packages/ai-trash/src/ulid.js +66 -0
  25. package/packages/hu-board/README.md +69 -0
  26. package/packages/hu-board/package.json +28 -0
  27. package/packages/hu-board/public/app.js +259 -0
  28. package/packages/hu-board/public/index.html +77 -0
  29. package/packages/hu-board/public/pipeline.css +132 -0
  30. package/packages/hu-board/public/pipeline.html +48 -0
  31. package/packages/hu-board/public/pipeline.js +200 -0
  32. package/packages/hu-board/public/rag.html +21 -0
  33. package/packages/hu-board/public/rag.js +39 -0
  34. package/packages/hu-board/public/styles.css +973 -0
  35. package/packages/hu-board/public/utils/api.js +139 -0
  36. package/packages/hu-board/public/utils/board-view.js +473 -0
  37. package/packages/hu-board/public/utils/command-launcher.js +213 -0
  38. package/packages/hu-board/public/utils/config-editor.js +181 -0
  39. package/packages/hu-board/public/utils/dashboard-view.js +103 -0
  40. package/packages/hu-board/public/utils/formatters.js +300 -0
  41. package/packages/hu-board/public/utils/graph-view.js +216 -0
  42. package/packages/hu-board/public/utils/hu-actions.js +224 -0
  43. package/packages/hu-board/public/utils/init-listeners.js +180 -0
  44. package/packages/hu-board/public/utils/log-panel.js +222 -0
  45. package/packages/hu-board/public/utils/modals.js +309 -0
  46. package/packages/hu-board/public/utils/plan-rollup-view.js +53 -0
  47. package/packages/hu-board/public/utils/preflight-view.js +89 -0
  48. package/packages/hu-board/public/utils/project-actions.js +143 -0
  49. package/packages/hu-board/public/utils/project-picker-view.js +139 -0
  50. package/packages/hu-board/public/utils/run-launcher.js +169 -0
  51. package/packages/hu-board/public/utils/server-push.js +252 -0
  52. package/packages/hu-board/public/utils/sessions-view.js +199 -0
  53. package/packages/hu-board/public/utils/story-detail-view.js +324 -0
  54. package/packages/hu-board/public/utils/story-edit-form.js +271 -0
  55. package/packages/hu-board/public/wiki.html +32 -0
  56. package/packages/hu-board/public/wiki.js +53 -0
  57. package/packages/hu-board/src/auth.js +92 -0
  58. package/packages/hu-board/src/boot-info.js +16 -0
  59. package/packages/hu-board/src/cleanup-zombies.js +145 -0
  60. package/packages/hu-board/src/command-runner.js +133 -0
  61. package/packages/hu-board/src/config-yaml.js +531 -0
  62. package/packages/hu-board/src/db.js +963 -0
  63. package/packages/hu-board/src/ephemeral-cleaner.js +196 -0
  64. package/packages/hu-board/src/event-bus.js +58 -0
  65. package/packages/hu-board/src/format.js +207 -0
  66. package/packages/hu-board/src/hu-zombie-reaper.js +103 -0
  67. package/packages/hu-board/src/journal-parser.js +180 -0
  68. package/packages/hu-board/src/plan-mutations.js +424 -0
  69. package/packages/hu-board/src/preflight.js +286 -0
  70. package/packages/hu-board/src/routes/api.js +1374 -0
  71. package/packages/hu-board/src/routes/pipeline.js +45 -0
  72. package/packages/hu-board/src/routes/rag.js +42 -0
  73. package/packages/hu-board/src/routes/wiki.js +43 -0
  74. package/packages/hu-board/src/run-tracker.js +121 -0
  75. package/packages/hu-board/src/server.js +438 -0
  76. package/packages/hu-board/src/sync.js +732 -0
  77. package/packages/hu-board/src/token-store.js +56 -0
  78. package/packages/hu-board/src/zombie-reaper.js +206 -0
  79. package/scripts/ai-attribution-guard.yml +84 -0
  80. package/scripts/audit-test-diet.mjs +151 -0
  81. package/scripts/build-sea.mjs +150 -0
  82. package/scripts/diet-baseline.mjs +170 -0
  83. package/scripts/dual-publish.mjs +67 -0
  84. package/scripts/esbuild-sea.config.mjs +273 -0
  85. package/scripts/git-hooks/post-merge +18 -0
  86. package/scripts/install-binary.ps1 +174 -0
  87. package/scripts/install-binary.sh +159 -0
  88. package/scripts/install-guard-all-repos.sh +85 -0
  89. package/scripts/install-kj.sh +193 -0
  90. package/scripts/install.js +901 -0
  91. package/scripts/install.sh +7 -0
  92. package/scripts/postinstall.js +117 -0
  93. package/scripts/protect-all-repos.sh +88 -0
  94. package/scripts/quickstart-gate.mjs +97 -0
  95. package/scripts/regen-arch-stats.sh +71 -0
  96. package/scripts/setup-multi-instance.sh +150 -0
  97. package/scripts/verify-pack.mjs +278 -0
  98. package/src/activity-log.js +59 -0
  99. package/src/agents/agy-agent.js +62 -0
  100. package/src/agents/aider-agent.js +78 -0
  101. package/src/agents/availability.js +52 -0
  102. package/src/agents/base-agent.js +134 -0
  103. package/src/agents/claude-agent.js +413 -0
  104. package/src/agents/codex-agent.js +112 -0
  105. package/src/agents/copilot-agent.js +65 -0
  106. package/src/agents/gemini-agent.js +85 -0
  107. package/src/agents/host-agent.js +38 -0
  108. package/src/agents/index.js +59 -0
  109. package/src/agents/kimi-agent.js +45 -0
  110. package/src/agents/model-registry.js +137 -0
  111. package/src/agents/opencode-agent.js +72 -0
  112. package/src/agents/qwen-agent.js +20 -0
  113. package/src/agents/resolve-bin.js +73 -0
  114. package/src/audit/agent-readiness.js +259 -0
  115. package/src/audit/ai-slop-findings.js +102 -0
  116. package/src/audit/audit-fallback.js +66 -0
  117. package/src/audit/audit-history-display.js +61 -0
  118. package/src/audit/audit-history.js +102 -0
  119. package/src/audit/basal-cost.js +281 -0
  120. package/src/audit/circular-deps.js +144 -0
  121. package/src/audit/dead-exports.js +186 -0
  122. package/src/audit/deterministic-summary.js +327 -0
  123. package/src/audit/harness-scorecard.js +100 -0
  124. package/src/audit/harness-section.js +81 -0
  125. package/src/audit/infra-findings.js +100 -0
  126. package/src/audit/injection-findings.js +114 -0
  127. package/src/audit/issue-filter.js +133 -0
  128. package/src/audit/osv-findings.js +167 -0
  129. package/src/audit/plan-adherence.js +224 -0
  130. package/src/audit/semgrep-findings.js +129 -0
  131. package/src/audit/sonar-findings.js +93 -0
  132. package/src/audit/webperf-input.js +133 -0
  133. package/src/autonomy/arbiter-role.js +71 -0
  134. package/src/autonomy/arbiter.js +22 -0
  135. package/src/autonomy/decider.js +18 -0
  136. package/src/autonomy/decision-resolver.js +58 -0
  137. package/src/autonomy/outcome-report.js +55 -0
  138. package/src/autonomy/policy.js +41 -0
  139. package/src/autonomy/stage-ask.js +30 -0
  140. package/src/bootstrap.js +276 -0
  141. package/src/brain/agent-error-classifier.js +116 -0
  142. package/src/brain/decision-tracker.js +125 -0
  143. package/src/brain/decisor.js +243 -0
  144. package/src/brain/solomon-consult.js +171 -0
  145. package/src/brain/standby-scheduler.js +8 -0
  146. package/src/brain/standby-store.js +12 -0
  147. package/src/brain/with-brain-recovery.js +235 -0
  148. package/src/budget/comparison.js +96 -0
  149. package/src/canvas/parse-md.js +238 -0
  150. package/src/canvas/schema.js +101 -0
  151. package/src/canvas/to-flat.js +85 -0
  152. package/src/canvas/validate.js +163 -0
  153. package/src/checks/ai-surface.js +79 -0
  154. package/src/checks/ai-trash.js +34 -0
  155. package/src/checks/binaries.js +207 -0
  156. package/src/checks/ci.js +105 -0
  157. package/src/checks/config-files.js +217 -0
  158. package/src/checks/dir-setup.js +103 -0
  159. package/src/checks/guarantee-level.js +38 -0
  160. package/src/checks/hardware.js +150 -0
  161. package/src/checks/harness-scorecard.js +41 -0
  162. package/src/checks/mcp-health.js +169 -0
  163. package/src/checks/method.js +73 -0
  164. package/src/checks/native-build.js +67 -0
  165. package/src/checks/node.js +70 -0
  166. package/src/checks/ollama.js +41 -0
  167. package/src/checks/orphans.js +77 -0
  168. package/src/checks/ports.js +188 -0
  169. package/src/checks/project-checks.js +245 -0
  170. package/src/checks/qmd.js +41 -0
  171. package/src/checks/rag-hooks.js +54 -0
  172. package/src/checks/release-check.js +102 -0
  173. package/src/checks/rtk.js +36 -0
  174. package/src/checks/runner.js +326 -0
  175. package/src/checks/skills.js +53 -0
  176. package/src/checks/sonar.js +67 -0
  177. package/src/checks/squeezr.js +36 -0
  178. package/src/checks/system.js +53 -0
  179. package/src/checks/tokens.js +172 -0
  180. package/src/checks/types.js +103 -0
  181. package/src/ci/dispatch.js +99 -0
  182. package/src/ci/index.js +3 -0
  183. package/src/ci/pr-diff.js +26 -0
  184. package/src/ci/repo.js +45 -0
  185. package/src/cli/_shared.js +30 -0
  186. package/src/cli/advanced-commands.js +61 -0
  187. package/src/cli/register-meta.js +772 -0
  188. package/src/cli/register-pipeline.js +335 -0
  189. package/src/cli/register-plan.js +224 -0
  190. package/src/cli/register-roles-skills.js +54 -0
  191. package/src/cli/register-sonar.js +28 -0
  192. package/src/cli/register-standby.js +26 -0
  193. package/src/cli.js +155 -0
  194. package/src/commands/advanced.js +31 -0
  195. package/src/commands/agent-run.js +63 -0
  196. package/src/commands/agents.js +105 -0
  197. package/src/commands/architect.js +123 -0
  198. package/src/commands/audit.js +430 -0
  199. package/src/commands/autorun.js +49 -0
  200. package/src/commands/board.js +458 -0
  201. package/src/commands/check.js +40 -0
  202. package/src/commands/clean.js +145 -0
  203. package/src/commands/code.js +45 -0
  204. package/src/commands/config.js +74 -0
  205. package/src/commands/discover.js +105 -0
  206. package/src/commands/doctor.js +251 -0
  207. package/src/commands/env.js +207 -0
  208. package/src/commands/harden.js +203 -0
  209. package/src/commands/hu.js +210 -0
  210. package/src/commands/identity.js +60 -0
  211. package/src/commands/init.js +950 -0
  212. package/src/commands/install-tools.js +432 -0
  213. package/src/commands/mutate.js +94 -0
  214. package/src/commands/ollama.js +44 -0
  215. package/src/commands/onboard.js +45 -0
  216. package/src/commands/plan/_shared.js +55 -0
  217. package/src/commands/plan/add-hu.js +23 -0
  218. package/src/commands/plan/delete.js +9 -0
  219. package/src/commands/plan/fix.js +99 -0
  220. package/src/commands/plan/generate.js +532 -0
  221. package/src/commands/plan/index.js +13 -0
  222. package/src/commands/plan/list.js +21 -0
  223. package/src/commands/plan/migrate-result.js +41 -0
  224. package/src/commands/plan/ready.js +46 -0
  225. package/src/commands/plan/remove-hu.js +17 -0
  226. package/src/commands/plan/share.js +85 -0
  227. package/src/commands/plan/show.js +81 -0
  228. package/src/commands/plan/unshare.js +41 -0
  229. package/src/commands/plan/validate.js +20 -0
  230. package/src/commands/plan.js +17 -0
  231. package/src/commands/policy.js +164 -0
  232. package/src/commands/privacy.js +45 -0
  233. package/src/commands/qmd.js +86 -0
  234. package/src/commands/rag-mcp.js +18 -0
  235. package/src/commands/rag.js +173 -0
  236. package/src/commands/report-issue.js +77 -0
  237. package/src/commands/report.js +469 -0
  238. package/src/commands/researcher.js +54 -0
  239. package/src/commands/resume.js +68 -0
  240. package/src/commands/review-gate.js +355 -0
  241. package/src/commands/review.js +89 -0
  242. package/src/commands/roles.js +116 -0
  243. package/src/commands/run.js +185 -0
  244. package/src/commands/scan.js +18 -0
  245. package/src/commands/skills.js +86 -0
  246. package/src/commands/sonar.js +53 -0
  247. package/src/commands/standby.js +117 -0
  248. package/src/commands/start.js +121 -0
  249. package/src/commands/status.js +36 -0
  250. package/src/commands/sync.js +103 -0
  251. package/src/commands/telemetry.js +70 -0
  252. package/src/commands/tournament.js +85 -0
  253. package/src/commands/triage.js +78 -0
  254. package/src/commands/undo.js +62 -0
  255. package/src/commands/watch.js +46 -0
  256. package/src/commands/webperf.js +162 -0
  257. package/src/commands/worktree.js +76 -0
  258. package/src/config/defaults.js +270 -0
  259. package/src/config/loader.js +204 -0
  260. package/src/config/overrides.js +220 -0
  261. package/src/config/role-resolver.js +171 -0
  262. package/src/config/schema.js +299 -0
  263. package/src/config/test-harness.js +78 -0
  264. package/src/config.js +34 -0
  265. package/src/domains/domain-loader.js +245 -0
  266. package/src/domains/domain-registry.js +140 -0
  267. package/src/domains/domain-synthesizer.js +129 -0
  268. package/src/environment/adr.js +45 -0
  269. package/src/environment/board-access.js +97 -0
  270. package/src/environment/board-select.js +59 -0
  271. package/src/environment/briefs.js +129 -0
  272. package/src/environment/issue-report.js +72 -0
  273. package/src/environment/mcp-wiring.js +44 -0
  274. package/src/environment/playbook.js +127 -0
  275. package/src/git/automation.js +334 -0
  276. package/src/git/hu-automation.js +171 -0
  277. package/src/git/hu-snapshot.js +10 -0
  278. package/src/golden/asserter.js +92 -0
  279. package/src/golden/loader.js +52 -0
  280. package/src/golden/runner.js +92 -0
  281. package/src/golden/schema.js +41 -0
  282. package/src/guards/intent-guard.js +161 -0
  283. package/src/guards/output-guard.js +149 -0
  284. package/src/guards/perf-guard.js +126 -0
  285. package/src/guards/policy-guard.js +90 -0
  286. package/src/guards/policy-resolver.js +85 -0
  287. package/src/guards/secret-redactor.js +71 -0
  288. package/src/harden/advisory.js +203 -0
  289. package/src/harden/alternatives.js +50 -0
  290. package/src/harden/check.js +81 -0
  291. package/src/harden/config-engine.js +128 -0
  292. package/src/harden/config-templates.js +122 -0
  293. package/src/harden/guidelines-engine.js +48 -0
  294. package/src/harden/guidelines-templates.js +36 -0
  295. package/src/harden/harden-engine.js +80 -0
  296. package/src/harden/harness-hooks.js +107 -0
  297. package/src/harden/hook-commands.js +25 -0
  298. package/src/harden/hook-templates.js +183 -0
  299. package/src/harden/interactive.js +76 -0
  300. package/src/harden/sentinel-hooks.js +721 -0
  301. package/src/harden/stack-roots.js +105 -0
  302. package/src/harden/test-on-push.js +38 -0
  303. package/src/harden/workflow-engine.js +116 -0
  304. package/src/harden/workflow-templates.js +285 -0
  305. package/src/hu/acceptance-runner.js +138 -0
  306. package/src/hu/auto-generator.js +358 -0
  307. package/src/hu/graph.js +71 -0
  308. package/src/hu/lazy-planner.js +109 -0
  309. package/src/hu/model-router.js +108 -0
  310. package/src/hu/parallel-executor.js +94 -0
  311. package/src/hu/split-validator.js +143 -0
  312. package/src/hu/splitting-detector.js +158 -0
  313. package/src/hu/splitting-generator.js +175 -0
  314. package/src/hu/store.js +392 -0
  315. package/src/hu/worktree-bootstrap.js +59 -0
  316. package/src/identity/bootstrap.js +48 -0
  317. package/src/identity/compare.js +38 -0
  318. package/src/identity/detect.js +51 -0
  319. package/src/identity/store.js +66 -0
  320. package/src/infrastructure/command-runner.js +44 -0
  321. package/src/infrastructure/environment.js +38 -0
  322. package/src/infrastructure/file-system-service.js +63 -0
  323. package/src/infrastructure/mocks.js +182 -0
  324. package/src/lang/chunk-go.js +94 -0
  325. package/src/lang/chunk-java.js +90 -0
  326. package/src/lang/chunk-python.js +88 -0
  327. package/src/lang/chunk-rust.js +102 -0
  328. package/src/lang/go.js +14 -0
  329. package/src/lang/java.js +16 -0
  330. package/src/lang/js.js +8 -0
  331. package/src/lang/python.js +14 -0
  332. package/src/lang/registry.js +79 -0
  333. package/src/lang/rust.js +14 -0
  334. package/src/lang/tree-sitter-loader.js +45 -0
  335. package/src/mcp/direct-role-runner.js +112 -0
  336. package/src/mcp/error-classifiers.js +66 -0
  337. package/src/mcp/handlers/direct-handlers.js +486 -0
  338. package/src/mcp/handlers/hu-handlers.js +93 -0
  339. package/src/mcp/handlers/management-handlers.js +265 -0
  340. package/src/mcp/handlers/rag-handler.js +52 -0
  341. package/src/mcp/handlers/run-handler.js +313 -0
  342. package/src/mcp/orphan-guard.js +131 -0
  343. package/src/mcp/preflight.js +47 -0
  344. package/src/mcp/progress.js +149 -0
  345. package/src/mcp/response-compressor.js +81 -0
  346. package/src/mcp/run-kj.js +135 -0
  347. package/src/mcp/server-handlers.js +79 -0
  348. package/src/mcp/server.js +66 -0
  349. package/src/mcp/shared-helpers.js +297 -0
  350. package/src/mcp/sovereignty-guard.js +112 -0
  351. package/src/mcp/suggest-handler.js +92 -0
  352. package/src/mcp/tool-arg-normalizers.js +16 -0
  353. package/src/mcp/tools.js +432 -0
  354. package/src/mutate/diff-scope.js +105 -0
  355. package/src/mutate/reviewer-signal.js +76 -0
  356. package/src/mutate/runner.js +72 -0
  357. package/src/mutate/tool-registry.js +90 -0
  358. package/src/onboarder/cache.js +24 -0
  359. package/src/onboarder/collectors/framework-multilang.js +64 -0
  360. package/src/onboarder/collectors/index.js +136 -0
  361. package/src/orchestrator/agent-fallback.js +81 -0
  362. package/src/orchestrator/brain-coordinator.js +186 -0
  363. package/src/orchestrator/ci-integration.js +139 -0
  364. package/src/orchestrator/config-init.js +510 -0
  365. package/src/orchestrator/direct-actions.js +217 -0
  366. package/src/orchestrator/drivers/error-recovery.js +287 -0
  367. package/src/orchestrator/drivers/init-context.js +227 -0
  368. package/src/orchestrator/drivers/iteration-loop.js +380 -0
  369. package/src/orchestrator/drivers/iteration-phases/coder-and-refactorer.js +69 -0
  370. package/src/orchestrator/drivers/iteration-phases/guards.js +84 -0
  371. package/src/orchestrator/drivers/iteration-phases/handle-approved.js +29 -0
  372. package/src/orchestrator/drivers/iteration-phases/quality-gates.js +114 -0
  373. package/src/orchestrator/drivers/iteration-phases/reviewer-gate.js +60 -0
  374. package/src/orchestrator/drivers/post-loop.js +383 -0
  375. package/src/orchestrator/drivers/pre-loop-phases/auto-hu-batch.js +136 -0
  376. package/src/orchestrator/drivers/pre-loop-phases/config-deprecations.js +47 -0
  377. package/src/orchestrator/drivers/pre-loop-phases/ensure-addyosmani-skills.js +84 -0
  378. package/src/orchestrator/drivers/pre-loop-phases/inject-loaded-plan.js +391 -0
  379. package/src/orchestrator/drivers/pre-loop.js +507 -0
  380. package/src/orchestrator/drivers/run-hu-batch.js +427 -0
  381. package/src/orchestrator/feedback-enrichment.js +140 -0
  382. package/src/orchestrator/feedback-queue.js +151 -0
  383. package/src/orchestrator/flow-control.js +170 -0
  384. package/src/orchestrator/flow-runner.js +364 -0
  385. package/src/orchestrator/fs-leak-detector.js +210 -0
  386. package/src/orchestrator/hu-scheduler.js +114 -0
  387. package/src/orchestrator/hu-sub-pipeline.js +616 -0
  388. package/src/orchestrator/integrations.js +81 -0
  389. package/src/orchestrator/iteration-gate.js +73 -0
  390. package/src/orchestrator/iteration-stages.js +9 -0
  391. package/src/orchestrator/parallel-limiter.js +74 -0
  392. package/src/orchestrator/pipeline-context.js +72 -0
  393. package/src/orchestrator/post-loop-stages.js +468 -0
  394. package/src/orchestrator/pre-loop-stages.js +11 -0
  395. package/src/orchestrator/preflight-checks.js +462 -0
  396. package/src/orchestrator/repair/repair-detector.js +117 -0
  397. package/src/orchestrator/repair/repair-runner.js +142 -0
  398. package/src/orchestrator/reviewer-fallback.js +45 -0
  399. package/src/orchestrator/role-output-compressor.js +189 -0
  400. package/src/orchestrator/session-journal.js +308 -0
  401. package/src/orchestrator/solomon-escalation.js +305 -0
  402. package/src/orchestrator/solomon-rules.js +212 -0
  403. package/src/orchestrator/stages/architect-stage.js +172 -0
  404. package/src/orchestrator/stages/coder-stage.js +480 -0
  405. package/src/orchestrator/stages/domain-curator-stage.js +82 -0
  406. package/src/orchestrator/stages/hu-reviewer-phases/detect-and-apply-splits.js +127 -0
  407. package/src/orchestrator/stages/hu-reviewer-stage.js +394 -0
  408. package/src/orchestrator/stages/perf-stage.js +140 -0
  409. package/src/orchestrator/stages/planner-stage.js +85 -0
  410. package/src/orchestrator/stages/rag-context-stage.js +77 -0
  411. package/src/orchestrator/stages/rag-preload-decisor.js +58 -0
  412. package/src/orchestrator/stages/research-stage.js +69 -0
  413. package/src/orchestrator/stages/reviewer-stage.js +422 -0
  414. package/src/orchestrator/stages/sonar-stage.js +421 -0
  415. package/src/orchestrator/stages/stage-classes.js +84 -0
  416. package/src/orchestrator/stages/stage-executor.js +155 -0
  417. package/src/orchestrator/stages/tdd-discipline-stage.js +56 -0
  418. package/src/orchestrator/stages/tool-judge-stage.js +53 -0
  419. package/src/orchestrator/stages/triage-stage.js +172 -0
  420. package/src/orchestrator/standby.js +71 -0
  421. package/src/orchestrator/verification-gate.js +183 -0
  422. package/src/orchestrator.js +22 -0
  423. package/src/plan/adr-generator.js +170 -0
  424. package/src/plan/adr-loader.js +60 -0
  425. package/src/plan/plan-executor.js +100 -0
  426. package/src/plan/plan-fixer.js +192 -0
  427. package/src/plan/plan-hu-ops.js +16 -0
  428. package/src/plan/plan-id.js +4 -0
  429. package/src/plan/plan-migrate-result.js +24 -0
  430. package/src/plan/plan-reviewer.js +236 -0
  431. package/src/plan/plan-schema.js +334 -0
  432. package/src/plan/plan-store.js +260 -0
  433. package/src/plan/plan-structural-pass.js +122 -0
  434. package/src/plan/plan-validation.js +4 -0
  435. package/src/plan/preflight-hu.js +105 -0
  436. package/src/plan/spec-detector.js +61 -0
  437. package/src/plan/tests-synthesizer.js +131 -0
  438. package/src/planning-game/adapter.js +108 -0
  439. package/src/planning-game/architect-adrs.js +45 -0
  440. package/src/planning-game/client.js +108 -0
  441. package/src/planning-game/decomposition.js +87 -0
  442. package/src/planning-game/pipeline-adapter.js +251 -0
  443. package/src/plugins/loader.js +67 -0
  444. package/src/policy/add.js +111 -0
  445. package/src/policy/decisions.js +42 -0
  446. package/src/policy/engine.js +82 -0
  447. package/src/policy/exceptions.js +60 -0
  448. package/src/privacy/onboarding.js +35 -0
  449. package/src/privacy/scan.js +120 -0
  450. package/src/prompts/arbiter.js +38 -0
  451. package/src/prompts/architect.js +103 -0
  452. package/src/prompts/audit.js +474 -0
  453. package/src/prompts/coder.js +287 -0
  454. package/src/prompts/diff-clip.js +27 -0
  455. package/src/prompts/discover.js +222 -0
  456. package/src/prompts/hu-reviewer.js +219 -0
  457. package/src/prompts/planner.js +312 -0
  458. package/src/prompts/prompt-layout.js +80 -0
  459. package/src/prompts/prompt-resolver.js +120 -0
  460. package/src/prompts/reviewer.js +75 -0
  461. package/src/prompts/rtk-snippet.js +25 -0
  462. package/src/prompts/spec-reviewer.js +66 -0
  463. package/src/prompts/split-signal.js +82 -0
  464. package/src/prompts/start-decision.js +52 -0
  465. package/src/prompts/tool-correctness-judge.js +31 -0
  466. package/src/prompts/triage.js +57 -0
  467. package/src/rag/auto-update.js +72 -0
  468. package/src/rag/chunker-ast.js +56 -0
  469. package/src/rag/chunker.js +132 -0
  470. package/src/rag/embedder.js +2 -0
  471. package/src/rag/embedders/_cloud-base.js +2 -0
  472. package/src/rag/embedders/cohere.js +2 -0
  473. package/src/rag/embedders/factory.js +2 -0
  474. package/src/rag/embedders/mistral.js +2 -0
  475. package/src/rag/embedders/onnx.js +2 -0
  476. package/src/rag/embedders/openai.js +2 -0
  477. package/src/rag/embedders/voyage.js +2 -0
  478. package/src/rag/eval.js +61 -0
  479. package/src/rag/governed-embedder.js +39 -0
  480. package/src/rag/indexer.js +199 -0
  481. package/src/rag/library.js +62 -0
  482. package/src/rag/ollama-capability.js +59 -0
  483. package/src/rag/ollama-manager.js +98 -0
  484. package/src/rag/onnx-fallback.js +69 -0
  485. package/src/rag/rerank.js +4 -0
  486. package/src/rag/retriever.js +2 -0
  487. package/src/rag/vec-store.js +17 -0
  488. package/src/rag/watcher.js +62 -0
  489. package/src/rag/where-parser.js +4 -0
  490. package/src/repeat-detector.js +88 -0
  491. package/src/review/card-first.js +99 -0
  492. package/src/review/card-verify.js +83 -0
  493. package/src/review/diff-generator.js +112 -0
  494. package/src/review/gate-gitignore.js +77 -0
  495. package/src/review/git-stash-helper.js +104 -0
  496. package/src/review/mutation-pregate.js +48 -0
  497. package/src/review/one-shot-review.js +122 -0
  498. package/src/review/parser.js +80 -0
  499. package/src/review/policy-gate.js +26 -0
  500. package/src/review/profiles.js +66 -0
  501. package/src/review/reviewer-fallback.js +125 -0
  502. package/src/review/schema.js +31 -0
  503. package/src/review/scope-filter.js +152 -0
  504. package/src/review/snapshot-diff.js +122 -0
  505. package/src/review/solomon-arbitration.js +113 -0
  506. package/src/review/sonar-pregate.js +63 -0
  507. package/src/review/tdd-discipline.js +90 -0
  508. package/src/review/tdd-policy.js +69 -0
  509. package/src/review/tests-with-code.js +33 -0
  510. package/src/review/verdict-store.js +87 -0
  511. package/src/review/workspace.js +21 -0
  512. package/src/roles/agent-role.js +194 -0
  513. package/src/roles/architect-role.js +77 -0
  514. package/src/roles/audit-role.js +258 -0
  515. package/src/roles/base-role.js +165 -0
  516. package/src/roles/coder-role.js +107 -0
  517. package/src/roles/commiter-role.js +110 -0
  518. package/src/roles/discover-role.js +81 -0
  519. package/src/roles/domain-curator-role.js +141 -0
  520. package/src/roles/hu-reviewer-role.js +64 -0
  521. package/src/roles/impeccable-role.js +85 -0
  522. package/src/roles/index.js +18 -0
  523. package/src/roles/karajan-brain-role.js +134 -0
  524. package/src/roles/onboarder-role.js +61 -0
  525. package/src/roles/perf-role.js +122 -0
  526. package/src/roles/planner-role.js +151 -0
  527. package/src/roles/refactorer-role.js +30 -0
  528. package/src/roles/repairer-role.js +181 -0
  529. package/src/roles/researcher-role.js +70 -0
  530. package/src/roles/reviewer-role.js +104 -0
  531. package/src/roles/security-role.js +73 -0
  532. package/src/roles/solomon-role.js +265 -0
  533. package/src/roles/sonar-role.js +70 -0
  534. package/src/roles/spec-reviewer-role.js +106 -0
  535. package/src/roles/tester-role.js +235 -0
  536. package/src/roles/tool-correctness-judge-role.js +78 -0
  537. package/src/roles/triage-role.js +99 -0
  538. package/src/session/journal/decisions-writer.js +200 -0
  539. package/src/session/journal/iteration-logger.js +194 -0
  540. package/src/session/journal/summary-writer.js +320 -0
  541. package/src/session/journal/tree-writer.js +164 -0
  542. package/src/session/journal/write-all.js +89 -0
  543. package/src/session/mutators.js +339 -0
  544. package/src/session/runtime-overrides.js +59 -0
  545. package/src/session/store.js +106 -0
  546. package/src/session-cleanup.js +116 -0
  547. package/src/skills/addyosmani-catalog.js +315 -0
  548. package/src/skills/addyosmani-role-map.js +139 -0
  549. package/src/skills/openskills-client.js +157 -0
  550. package/src/skills/semantic-detector.js +167 -0
  551. package/src/skills/skill-detector.js +385 -0
  552. package/src/skills/skill-loader.js +219 -0
  553. package/src/skills/skills-cache.js +128 -0
  554. package/src/sonar/api.js +128 -0
  555. package/src/sonar/cloud-scanner.js +78 -0
  556. package/src/sonar/config-resolver.js +88 -0
  557. package/src/sonar/credentials.js +60 -0
  558. package/src/sonar/discovery.js +124 -0
  559. package/src/sonar/enforcer.js +19 -0
  560. package/src/sonar/issue-filter.js +12 -0
  561. package/src/sonar/manager.js +181 -0
  562. package/src/sonar/project-key.js +120 -0
  563. package/src/sonar/scanner.js +307 -0
  564. package/src/sonar/token-bootstrap.js +205 -0
  565. package/src/sonar/token-recovery.js +67 -0
  566. package/src/spec-review/refine-loop.js +58 -0
  567. package/src/spec-review/run-spec-review.js +119 -0
  568. package/src/start/assessment.js +74 -0
  569. package/src/start/maturity.js +73 -0
  570. package/src/start/start-decider-role.js +79 -0
  571. package/src/start/sweep.js +157 -0
  572. package/src/sync/apply-canvas-patch.js +55 -0
  573. package/src/sync/detect-drift.js +113 -0
  574. package/src/tournament/crown.js +88 -0
  575. package/src/tournament/judge.js +150 -0
  576. package/src/tournament/run.js +142 -0
  577. package/src/tournament/scoreboard.js +124 -0
  578. package/src/tracker-bootstrap.js +44 -0
  579. package/src/types/agent.js +55 -0
  580. package/src/types/config.js +114 -0
  581. package/src/types/hu.js +47 -0
  582. package/src/types/index.js +38 -0
  583. package/src/types/policy.js +43 -0
  584. package/src/types/session.js +75 -0
  585. package/src/types/solomon.js +87 -0
  586. package/src/types/stage.js +68 -0
  587. package/src/utils/agent-detect.js +93 -0
  588. package/src/utils/ai-trash.js +48 -0
  589. package/src/utils/async-lock.js +31 -0
  590. package/src/utils/atomic-write.js +6 -0
  591. package/src/utils/banner.js +66 -0
  592. package/src/utils/binary-sources.js +70 -0
  593. package/src/utils/board-prompt-bridge.js +108 -0
  594. package/src/utils/budget.js +229 -0
  595. package/src/utils/cli-ask-question.js +93 -0
  596. package/src/utils/cli-progress.js +220 -0
  597. package/src/utils/cli-run-log.js +83 -0
  598. package/src/utils/cwd-confirm.js +39 -0
  599. package/src/utils/derive-project-name-from-cwd.js +119 -0
  600. package/src/utils/display/event-handlers.js +403 -0
  601. package/src/utils/display/formatters.js +132 -0
  602. package/src/utils/display/header.js +47 -0
  603. package/src/utils/display/resume-hint.js +41 -0
  604. package/src/utils/display/session-summary.js +118 -0
  605. package/src/utils/display/solomon.js +42 -0
  606. package/src/utils/display/spec-findings.js +44 -0
  607. package/src/utils/doc-links.js +29 -0
  608. package/src/utils/docker-install.js +34 -0
  609. package/src/utils/escape-regexp.js +15 -0
  610. package/src/utils/events.js +35 -0
  611. package/src/utils/fs.js +19 -0
  612. package/src/utils/garbage-collector.js +481 -0
  613. package/src/utils/git.js +279 -0
  614. package/src/utils/home-migration.js +87 -0
  615. package/src/utils/injection-guard.js +186 -0
  616. package/src/utils/install-hints.js +180 -0
  617. package/src/utils/json-extract.js +64 -0
  618. package/src/utils/locale.js +59 -0
  619. package/src/utils/logger.js +96 -0
  620. package/src/utils/managed-markers.js +93 -0
  621. package/src/utils/manifest-sniff.js +82 -0
  622. package/src/utils/messages.js +61 -0
  623. package/src/utils/model-selector.js +107 -0
  624. package/src/utils/os-detect.js +79 -0
  625. package/src/utils/paths.js +13 -0
  626. package/src/utils/pending-user-action.js +95 -0
  627. package/src/utils/port-check.js +6 -0
  628. package/src/utils/port-occupant.js +96 -0
  629. package/src/utils/pricing.js +29 -0
  630. package/src/utils/process.js +4 -0
  631. package/src/utils/project-detect.js +160 -0
  632. package/src/utils/prompt-project-name.js +35 -0
  633. package/src/utils/provider-env.js +116 -0
  634. package/src/utils/qmd-collection.js +72 -0
  635. package/src/utils/qmd-detect.js +18 -0
  636. package/src/utils/qmd-install.js +37 -0
  637. package/src/utils/quota-simulator.js +56 -0
  638. package/src/utils/rate-limit-detector.js +181 -0
  639. package/src/utils/repo-cleaner.js +79 -0
  640. package/src/utils/retry.js +88 -0
  641. package/src/utils/role-assigner.js +137 -0
  642. package/src/utils/role-env.js +58 -0
  643. package/src/utils/rtk-detect.js +18 -0
  644. package/src/utils/rtk-install.js +38 -0
  645. package/src/utils/rtk-wrapper.js +87 -0
  646. package/src/utils/run-context.js +75 -0
  647. package/src/utils/run-log.js +217 -0
  648. package/src/utils/run-registry.js +9 -0
  649. package/src/utils/shared-paths.js +12 -0
  650. package/src/utils/squeezr-detect.js +21 -0
  651. package/src/utils/squeezr-install.js +37 -0
  652. package/src/utils/stack-detect.js +135 -0
  653. package/src/utils/stall-detector.js +159 -0
  654. package/src/utils/status-dashboard.js +254 -0
  655. package/src/utils/task-file.js +109 -0
  656. package/src/utils/telemetry.js +124 -0
  657. package/src/utils/templates-root.js +61 -0
  658. package/src/utils/tool-call-extractor.js +56 -0
  659. package/src/utils/tool-governor.js +116 -0
  660. package/src/utils/tool-installer.js +93 -0
  661. package/src/utils/update-check.js +280 -0
  662. package/src/utils/vector-store-orphans.js +89 -0
  663. package/src/utils/welcome.js +47 -0
  664. package/src/utils/with-timeout.js +42 -0
  665. package/src/utils/wizard.js +47 -0
  666. package/src/webperf/cwv-gate.js +94 -0
  667. package/src/webperf/devtools-detect.js +112 -0
  668. package/src/webperf/scanner.js +209 -0
  669. package/src/webperf/webperf-role-integration.js +66 -0
  670. package/templates/coder-rules.md +45 -0
  671. package/templates/docker-compose.sonar.yml +60 -0
  672. package/templates/domains/example-dental.md +57 -0
  673. package/templates/kj.config.yml +128 -0
  674. package/templates/review-rules.md +17 -0
  675. package/templates/roles/architect/anthropic.md +74 -0
  676. package/templates/roles/architect/default.md +72 -0
  677. package/templates/roles/architect/google.md +61 -0
  678. package/templates/roles/architect/openai.md +60 -0
  679. package/templates/roles/architect/opencode.md +59 -0
  680. package/templates/roles/architect.md +76 -0
  681. package/templates/roles/audit.md +68 -0
  682. package/templates/roles/coder/anthropic.md +81 -0
  683. package/templates/roles/coder/default.md +78 -0
  684. package/templates/roles/coder/google.md +87 -0
  685. package/templates/roles/coder/openai.md +68 -0
  686. package/templates/roles/coder/opencode.md +58 -0
  687. package/templates/roles/coder.md +152 -0
  688. package/templates/roles/commiter.md +44 -0
  689. package/templates/roles/discover.md +167 -0
  690. package/templates/roles/domain-curator.md +52 -0
  691. package/templates/roles/hu-reviewer.md +236 -0
  692. package/templates/roles/impeccable-design.md +87 -0
  693. package/templates/roles/impeccable.md +125 -0
  694. package/templates/roles/karajan-brain.md +95 -0
  695. package/templates/roles/onboarder.md +45 -0
  696. package/templates/roles/planner/anthropic.md +59 -0
  697. package/templates/roles/planner/default.md +57 -0
  698. package/templates/roles/planner/google.md +75 -0
  699. package/templates/roles/planner/openai.md +55 -0
  700. package/templates/roles/planner/opencode.md +62 -0
  701. package/templates/roles/planner.md +61 -0
  702. package/templates/roles/refactorer.md +48 -0
  703. package/templates/roles/repairer.md +103 -0
  704. package/templates/roles/researcher.md +41 -0
  705. package/templates/roles/reviewer/anthropic.md +61 -0
  706. package/templates/roles/reviewer/default.md +62 -0
  707. package/templates/roles/reviewer/google.md +63 -0
  708. package/templates/roles/reviewer/openai.md +57 -0
  709. package/templates/roles/reviewer/opencode.md +42 -0
  710. package/templates/roles/reviewer-paranoid.md +38 -0
  711. package/templates/roles/reviewer-relaxed.md +34 -0
  712. package/templates/roles/reviewer-strict.md +37 -0
  713. package/templates/roles/reviewer.md +62 -0
  714. package/templates/roles/security.md +54 -0
  715. package/templates/roles/solomon/anthropic.md +71 -0
  716. package/templates/roles/solomon/default.md +83 -0
  717. package/templates/roles/solomon/google.md +61 -0
  718. package/templates/roles/solomon/openai.md +53 -0
  719. package/templates/roles/solomon/opencode.md +55 -0
  720. package/templates/roles/solomon.md +83 -0
  721. package/templates/roles/sonar.md +49 -0
  722. package/templates/roles/spec-reviewer.md +47 -0
  723. package/templates/roles/tester.md +50 -0
  724. package/templates/roles/triage.md +69 -0
  725. package/templates/skills/kj-architect.md +45 -0
  726. package/templates/skills/kj-audit.md +63 -0
  727. package/templates/skills/kj-board.md +16 -0
  728. package/templates/skills/kj-code.md +51 -0
  729. package/templates/skills/kj-csv-transform.md +40 -0
  730. package/templates/skills/kj-data-report.md +44 -0
  731. package/templates/skills/kj-discover.md +24 -0
  732. package/templates/skills/kj-rag-query.md +50 -0
  733. package/templates/skills/kj-review.md +47 -0
  734. package/templates/skills/kj-run.md +73 -0
  735. package/templates/skills/kj-security.md +49 -0
  736. package/templates/skills/kj-sonar.md +41 -0
  737. package/templates/skills/kj-sql-analysis.md +40 -0
  738. package/templates/skills/kj-test.md +40 -0
  739. package/templates/workflows/automerge.yml +30 -0
  740. package/templates/workflows/houston-override.yml +46 -0
  741. package/templates/workflows/kj-ci-gateway.yml +58 -0
  742. package/vendor/tree-sitter-grammars/README.md +21 -0
  743. package/vendor/tree-sitter-grammars/go.wasm +0 -0
  744. package/vendor/tree-sitter-grammars/java.wasm +0 -0
  745. package/vendor/tree-sitter-grammars/python.wasm +0 -0
  746. package/vendor/tree-sitter-grammars/rust.wasm +0 -0
@@ -0,0 +1,56 @@
1
+ // TDD discipline stage (KJC-TSK-0398 PR3).
2
+ // Runs the red-then-green check when `development.require_red_then_green`
3
+ // is true. Wraps `verifyTddDiscipline` with the surgical stash helper and
4
+ // the project's detected test framework. Gate is opt-in; an unsupported
5
+ // framework reports a warning and does not block the iteration.
6
+
7
+ import { detectTestFramework } from "../../utils/project-detect.js";
8
+ import { verifyTddDiscipline } from "../../review/tdd-discipline.js";
9
+ import { stashFilesAside, restoreFiles } from "../../review/git-stash-helper.js";
10
+ import { runCommand } from "../../utils/process.js";
11
+ import { emitProgress, makeEvent } from "../../utils/events.js";
12
+
13
+ const TDD_DISCIPLINE_COMMANDS = {
14
+ vitest: ["npx", ["vitest", "run", "--reporter=verbose"]],
15
+ jest: ["npx", ["jest", "--verbose"]],
16
+ pytest: ["pytest", ["--tb=short"]],
17
+ };
18
+
19
+ export async function runTddDisciplineStage({
20
+ config, logger, emitter, eventBase, sourceFiles = [], testFiles = [],
21
+ detectFramework = detectTestFramework,
22
+ runTestsImpl,
23
+ stashImpl = stashFilesAside,
24
+ restoreImpl = restoreFiles,
25
+ } = {}) {
26
+ const projectDir = config?.projectDir || process.cwd();
27
+ const detection = await detectFramework(projectDir);
28
+ const framework = detection?.framework || null;
29
+
30
+ const runTests = runTestsImpl || (async () => {
31
+ const cmd = TDD_DISCIPLINE_COMMANDS[framework];
32
+ if (!cmd) return { exitCode: 0, output: "" };
33
+ const res = await runCommand(cmd[0], cmd[1], { cwd: projectDir, reject: false });
34
+ return { exitCode: res.exitCode ?? 0, output: `${res.stdout || ""}\n${res.stderr || ""}` };
35
+ });
36
+
37
+ const result = await verifyTddDiscipline({
38
+ projectDir, sourceFiles, testFiles, framework,
39
+ runTests,
40
+ stashFiles: (files) => stashImpl(files, { projectDir }),
41
+ restoreFiles: (token) => restoreImpl(token, { projectDir }),
42
+ });
43
+
44
+ emitProgress(emitter, makeEvent("tdd:discipline", { ...eventBase, stage: "tdd" }, {
45
+ status: result.ok ? "ok" : "fail",
46
+ message: result.message || `TDD discipline: ${result.reason}`,
47
+ detail: { reason: result.reason, framework },
48
+ }));
49
+
50
+ if (result.warning) logger?.warn?.(result.warning);
51
+ if (!result.ok) {
52
+ logger?.warn?.(`TDD discipline violation: ${result.reason}`);
53
+ return { action: "continue", result };
54
+ }
55
+ return { action: "ok", result };
56
+ }
@@ -0,0 +1,53 @@
1
+ // KJC-TSK-0375 PR3 — ToolJudgeStage.
2
+ // Opt-in (`pipeline.tool_judge.enabled`). Scores the coder's tool calls
3
+ // extracted from `session.last_coder_transcript`. Non-blocking: a low
4
+ // score emits a warn event and surfaces in summary but never gates the
5
+ // iteration loop. Wiring lives in `quality-gates.js`.
6
+
7
+ import { ToolCorrectnessJudgeRole } from "../../roles/tool-correctness-judge-role.js";
8
+ import { extractToolCalls } from "../../utils/tool-call-extractor.js";
9
+ import { emitProgress, makeEvent } from "../../utils/events.js";
10
+
11
+ export async function runToolJudgeStage({
12
+ config, logger, emitter, eventBase, session, coderRole, trackBudget,
13
+ iteration, task,
14
+ extractFn = extractToolCalls,
15
+ RoleClass = ToolCorrectnessJudgeRole,
16
+ } = {}) {
17
+ logger?.setContext?.({ iteration, stage: "tool-judge" });
18
+ emitProgress(emitter, makeEvent("toolJudge:start", { ...eventBase, stage: "tool-judge" }, {
19
+ message: "Tool-judge scoring coder tool calls",
20
+ }));
21
+
22
+ const transcript = session?.last_coder_transcript || "";
23
+ const provider = coderRole?.provider || "claude";
24
+ const toolCalls = extractFn({ transcript, provider });
25
+
26
+ const role = new RoleClass({ config, logger, emitter });
27
+ const roleResult = await role.execute({ task, toolCalls });
28
+
29
+ try { trackBudget?.("tool-judge", roleResult.usage || { tokens_in: 0, tokens_out: 0, cost_usd: 0 }); } catch { /* best-effort */ }
30
+
31
+ const r = roleResult.result;
32
+ const status = r?.skipped ? "skip" : r?.lowQuality ? "warn" : roleResult.ok ? "ok" : "fail";
33
+
34
+ emitProgress(emitter, makeEvent("toolJudge:end", { ...eventBase, stage: "tool-judge" }, {
35
+ status,
36
+ message: roleResult.summary || "tool-judge done",
37
+ detail: { score: r?.score ?? null, threshold: r?.threshold ?? null, skipped: Boolean(r?.skipped), callCount: toolCalls.length },
38
+ }));
39
+
40
+ return {
41
+ action: "ok",
42
+ stageResult: {
43
+ ok: roleResult.ok !== false,
44
+ score: r?.score ?? null,
45
+ lowQuality: Boolean(r?.lowQuality),
46
+ skipped: Boolean(r?.skipped),
47
+ threshold: r?.threshold ?? null,
48
+ summary: roleResult.summary || "",
49
+ breakdown: r?.breakdown || [],
50
+ callCount: toolCalls.length,
51
+ },
52
+ };
53
+ }
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Triage stage logic.
3
+ * Extracted from pre-loop-stages.js for maintainability.
4
+ */
5
+
6
+ import { TriageRole } from "../../roles/triage-role.js";
7
+ import { addCheckpoint } from "../../session/store.js";
8
+ import { emitProgress, makeEvent, emitAgentOutput } from "../../utils/events.js";
9
+ import { selectModelsForRoles } from "../../utils/model-selector.js";
10
+ import { createStallDetector } from "../../utils/stall-detector.js";
11
+
12
+ const ROLE_NAMES = ["planner", "researcher", "architect", "refactorer", "reviewer", "tester", "security", "impeccable"];
13
+
14
+ // What each role is for. Used to explain — deterministically — why triage would
15
+ // or would not turn a role on. These describe the role's trigger, never a claim
16
+ // about the current task, so the rationale is never invented per run.
17
+ const ROLE_PURPOSE = {
18
+ planner: "planificación multi-fichero",
19
+ researcher: "investigación de contexto externo",
20
+ architect: "decisiones de arquitectura",
21
+ refactorer: "refactor de código existente",
22
+ reviewer: "revisión de cambios",
23
+ tester: "cobertura de tests dedicada",
24
+ security: "auditoría de seguridad",
25
+ impeccable: "auditoría de diseño"
26
+ };
27
+
28
+ function buildRoleOverrides(recommendedRoles, pipelineConfig) {
29
+ const overrides = {};
30
+ for (const role of ROLE_NAMES) {
31
+ overrides[`${role}Enabled`] = recommendedRoles.has(role) || Boolean(pipelineConfig[role]?.enabled);
32
+ }
33
+ return overrides;
34
+ }
35
+
36
+ // Per-role explanation of the activate/skip decision, mirroring buildRoleOverrides.
37
+ // When triage failed, recommendations are unavailable: roles resolve from config
38
+ // alone and skipped ones get a neutral "sin datos de triage" reason.
39
+ function buildRoleRationale(recommendedRoles, pipelineConfig, triageOk) {
40
+ return ROLE_NAMES.map((role) => {
41
+ const forced = Boolean(pipelineConfig[role]?.enabled);
42
+ const recommended = triageOk && recommendedRoles.has(role);
43
+ const purpose = ROLE_PURPOSE[role];
44
+
45
+ if (recommended) {
46
+ return { role, enabled: true, source: "triage", reason: `recomendado por triage — ${purpose}` };
47
+ }
48
+ if (forced) {
49
+ return { role, enabled: true, source: "config", reason: `forzado por configuración — ${purpose}` };
50
+ }
51
+ const reason = triageOk
52
+ ? `no recomendado — ${purpose} sin aplicar`
53
+ : `sin datos de triage — ${purpose} sin evaluar`;
54
+ return { role, enabled: false, source: "none", reason };
55
+ });
56
+ }
57
+
58
+ function applyModelSelection(triageOutput, config, emitter, eventBase) {
59
+ if (!triageOutput.ok || !config?.model_selection?.enabled) return null;
60
+ const level = triageOutput.result?.level;
61
+ if (!level) return null;
62
+
63
+ const { modelOverrides, reasoning } = selectModelsForRoles({ level, config });
64
+ for (const [role, model] of Object.entries(modelOverrides)) {
65
+ if (config.roles?.[role] && !config.roles[role].model) {
66
+ config.roles[role].model = model;
67
+ }
68
+ }
69
+ const modelSelection = { modelOverrides, reasoning };
70
+ emitProgress(
71
+ emitter,
72
+ makeEvent("model-selection:applied", { ...eventBase, stage: "triage" }, {
73
+ message: "Smart model selection applied",
74
+ detail: modelSelection
75
+ })
76
+ );
77
+ return modelSelection;
78
+ }
79
+
80
+ export async function runTriageStage({ config, logger, emitter, eventBase, session, coderRole, trackBudget }) {
81
+ logger.setContext({ iteration: 0, stage: "triage" });
82
+
83
+ const triageProvider = config?.roles?.triage?.provider || coderRole.provider;
84
+ emitProgress(
85
+ emitter,
86
+ makeEvent("triage:start", { ...eventBase, stage: "triage" }, {
87
+ message: "Triage classifying task complexity",
88
+ detail: { provider: triageProvider, executorType: "agent" }
89
+ })
90
+ );
91
+
92
+ const triageOnOutput = (payload) => emitAgentOutput(emitter, eventBase, "triage", triageProvider, payload);
93
+ const triageStall = createStallDetector({
94
+ onOutput: triageOnOutput, emitter, eventBase, stage: "triage", provider: triageProvider
95
+ });
96
+
97
+ const triage = new TriageRole({ config, logger, emitter });
98
+ await triage.init({ task: session.task, sessionId: session.id, iteration: 0 });
99
+ const triageStart = Date.now();
100
+ let triageOutput;
101
+ try {
102
+ triageOutput = await triage.run({ task: session.task, onOutput: triageStall.onOutput });
103
+ } catch (err) {
104
+ logger.warn(`Triage threw: ${err.message}`);
105
+ triageOutput = { ok: false, summary: `Triage error: ${err.message}`, result: { error: err.message } };
106
+ } finally {
107
+ triageStall.stop();
108
+ }
109
+ trackBudget({
110
+ role: "triage",
111
+ provider: config?.roles?.triage?.provider || coderRole.provider,
112
+ model: config?.roles?.triage?.model || coderRole.model,
113
+ result: triageOutput,
114
+ duration_ms: Date.now() - triageStart
115
+ });
116
+
117
+ await addCheckpoint(session, {
118
+ stage: "triage",
119
+ iteration: 0,
120
+ ok: triageOutput.ok,
121
+ provider: config?.roles?.triage?.provider || coderRole.provider,
122
+ model: config?.roles?.triage?.model || coderRole.model || null
123
+ });
124
+
125
+ const recommendedRoles = new Set(triageOutput.result?.roles || []);
126
+ const roleOverrides = triageOutput.ok
127
+ ? buildRoleOverrides(recommendedRoles, config.pipeline || {})
128
+ : {};
129
+
130
+ const shouldDecompose = triageOutput.result?.shouldDecompose || false;
131
+ const subtasks = triageOutput.result?.subtasks || [];
132
+
133
+ const domainHints = triageOutput.result?.domainHints || [];
134
+
135
+ const stageResult = {
136
+ ok: triageOutput.ok,
137
+ level: triageOutput.result?.level || null,
138
+ roles: Array.from(recommendedRoles),
139
+ reasoning: triageOutput.result?.reasoning || null,
140
+ taskType: triageOutput.result?.taskType || "sw",
141
+ shouldDecompose,
142
+ subtasks,
143
+ domainHints,
144
+ roleRationale: buildRoleRationale(recommendedRoles, config.pipeline || {}, triageOutput.ok)
145
+ };
146
+
147
+ const modelSelection = applyModelSelection(triageOutput, config, emitter, eventBase);
148
+ if (modelSelection) {
149
+ stageResult.modelSelection = modelSelection;
150
+ }
151
+
152
+ if (shouldDecompose && subtasks.length > 0) {
153
+ emitProgress(
154
+ emitter,
155
+ makeEvent("triage:decompose", { ...eventBase, stage: "triage" }, {
156
+ message: `Task decomposition recommended: ${subtasks.length} subtask${subtasks.length === 1 ? "" : "s"}`,
157
+ detail: { shouldDecompose, subtasks }
158
+ })
159
+ );
160
+ }
161
+
162
+ emitProgress(
163
+ emitter,
164
+ makeEvent("triage:end", { ...eventBase, stage: "triage" }, {
165
+ status: triageOutput.ok ? "ok" : "fail",
166
+ message: triageOutput.ok ? "Triage completed" : `Triage failed: ${triageOutput.summary}`,
167
+ detail: { ...stageResult, provider: triageProvider, executorType: "agent" }
168
+ })
169
+ );
170
+
171
+ return { roleOverrides, stageResult };
172
+ }
@@ -0,0 +1,71 @@
1
+ import { emitProgress, makeEvent } from "../utils/events.js";
2
+ import { setStatus } from "../session/mutators.js";
3
+
4
+ const DEFAULT_COOLDOWN_MS = 5 * 60 * 1000; // 5 minutes
5
+ const MAX_COOLDOWN_MS = 30 * 60 * 1000; // 30 minutes
6
+ const MAX_STANDBY_RETRIES = 5;
7
+ const HEARTBEAT_INTERVAL_MS = 30 * 1000; // 30 seconds
8
+
9
+ /**
10
+ * Wait for a rate limit cooldown, emitting heartbeat events.
11
+ * Returns when the cooldown expires.
12
+ *
13
+ * @param {object} options
14
+ * @param {number|null} options.cooldownMs - Milliseconds to wait (null = use default)
15
+ * @param {string|null} options.cooldownUntil - ISO timestamp when cooldown expires
16
+ * @param {string} options.agent - Agent that was rate-limited
17
+ * @param {number} options.retryCount - Current retry attempt (for backoff)
18
+ * @param {object} options.emitter - Event emitter
19
+ * @param {object} options.eventBase - Base event fields
20
+ * @param {object} options.logger
21
+ * @param {object} options.session
22
+ */
23
+ export async function waitForCooldown({ cooldownMs, cooldownUntil, agent, retryCount, emitter, eventBase, logger, session }) {
24
+ // Calculate wait time with exponential backoff for retries without known cooldown
25
+ let waitMs = cooldownMs || DEFAULT_COOLDOWN_MS;
26
+ if (!cooldownMs && retryCount > 0) {
27
+ waitMs = Math.min(DEFAULT_COOLDOWN_MS * Math.pow(2, retryCount), MAX_COOLDOWN_MS);
28
+ }
29
+
30
+ const resumeAt = cooldownUntil || new Date(Date.now() + waitMs).toISOString();
31
+
32
+ logger.info(`Standby: waiting ${Math.round(waitMs / 1000)}s for ${agent} rate limit (retry ${retryCount + 1}/${MAX_STANDBY_RETRIES})`);
33
+
34
+ // Emit standby start event
35
+ emitProgress(emitter, makeEvent("coder:standby", { ...eventBase, stage: "standby" }, {
36
+ message: `Rate limited — standby until ${resumeAt} (attempt ${retryCount + 1}/${MAX_STANDBY_RETRIES})`,
37
+ detail: { agent, cooldownUntil: resumeAt, cooldownMs: waitMs, retryCount: retryCount + 1, maxRetries: MAX_STANDBY_RETRIES }
38
+ }));
39
+
40
+ // Update session status
41
+ setStatus(session, "standby");
42
+
43
+ // Wait with periodic heartbeats
44
+ const startTime = Date.now();
45
+ const endTime = startTime + waitMs;
46
+
47
+ while (Date.now() < endTime) {
48
+ const remaining = endTime - Date.now();
49
+ const sleepTime = Math.min(HEARTBEAT_INTERVAL_MS, remaining);
50
+
51
+ await new Promise(resolve => setTimeout(resolve, sleepTime));
52
+
53
+ if (Date.now() < endTime) {
54
+ const remainingSec = Math.round((endTime - Date.now()) / 1000);
55
+ emitProgress(emitter, makeEvent("coder:standby_heartbeat", { ...eventBase, stage: "standby" }, {
56
+ message: `Standby: ${remainingSec}s remaining`,
57
+ detail: { agent, remainingMs: endTime - Date.now(), retryCount: retryCount + 1 }
58
+ }));
59
+ }
60
+ }
61
+
62
+ // Emit resume event
63
+ emitProgress(emitter, makeEvent("coder:standby_resume", { ...eventBase, stage: "standby" }, {
64
+ message: `Cooldown expired — resuming with ${agent}`,
65
+ detail: { agent, retryCount: retryCount + 1 }
66
+ }));
67
+
68
+ setStatus(session, "running");
69
+ }
70
+
71
+ export { DEFAULT_COOLDOWN_MS, MAX_COOLDOWN_MS, MAX_STANDBY_RETRIES, HEARTBEAT_INTERVAL_MS };
@@ -0,0 +1,183 @@
1
+ // Verification gate: checks whether the coder actually produced changes.
2
+ // Prevents advancing the pipeline when coder iterations produce 0 file changes.
3
+
4
+ import { execFileSync } from "node:child_process";
5
+
6
+ /**
7
+ * @typedef {Object} VerificationResult
8
+ * @property {boolean} passed - true if coder produced real changes
9
+ * @property {number} filesChanged - count of modified/added/deleted files
10
+ * @property {number} linesChanged - total lines added/deleted
11
+ * @property {string[]} files - list of changed file paths
12
+ * @property {string} reason - explanation when not passed
13
+ * @property {string} [retryStrategy] - suggested retry approach when not passed
14
+ */
15
+
16
+ /**
17
+ * Count files and lines changed since a base reference.
18
+ * Uses git diff --numstat to get both file and line counts.
19
+ *
20
+ * Audit follow-up: was using execSync with template-string interpolation
21
+ * of `baseRef` and `projectDir`. Both come ultimately from session
22
+ * state / config — not user shell input — but the shape was a known
23
+ * shell-injection vector. Switched to execFileSync with arg arrays so
24
+ * no interpolation reaches /bin/sh.
25
+ */
26
+ export function countChangesSince(baseRef, projectDir = null) {
27
+ try {
28
+ const args = ["diff", "--numstat", String(baseRef)];
29
+ if (projectDir) args.push("--", String(projectDir));
30
+ const output = execFileSync("git", args, {
31
+ encoding: "utf8", stdio: ["pipe", "pipe", "pipe"],
32
+ }).trim();
33
+
34
+ if (!output) return { files: [], filesChanged: 0, linesAdded: 0, linesDeleted: 0 };
35
+
36
+ const lines = output.split("\n");
37
+ const files = [];
38
+ let linesAdded = 0;
39
+ let linesDeleted = 0;
40
+
41
+ for (const line of lines) {
42
+ const [added, deleted, file] = line.split("\t");
43
+ if (!file) continue;
44
+ files.push(file);
45
+ linesAdded += Number(added) || 0;
46
+ linesDeleted += Number(deleted) || 0;
47
+ }
48
+
49
+ return { files, filesChanged: files.length, linesAdded, linesDeleted };
50
+ } catch (err) {
51
+ // Git itself failed (baseRef invalid, repo corrupt, git binary
52
+ // missing). Previously we returned `filesChanged: 0` silently —
53
+ // indistinguishable from "the coder did nothing". Surface the
54
+ // error so verifyCoderOutput stops blaming the agent for an
55
+ // infrastructure failure.
56
+ return {
57
+ files: [], filesChanged: 0, linesAdded: 0, linesDeleted: 0,
58
+ gitError: err?.stderr?.toString?.() || err?.message || String(err),
59
+ };
60
+ }
61
+ }
62
+
63
+ /**
64
+ * Also count untracked files (new files not yet added to git).
65
+ *
66
+ * Audit follow-up: same execSync→execFileSync change as countChangesSince.
67
+ */
68
+ export function countUntrackedFiles(projectDir = null) {
69
+ try {
70
+ const args = ["ls-files", "--others", "--exclude-standard"];
71
+ if (projectDir) args.push(String(projectDir));
72
+ const output = execFileSync("git", args, {
73
+ encoding: "utf8", stdio: ["pipe", "pipe", "pipe"],
74
+ }).trim();
75
+
76
+ if (!output) return { files: [] };
77
+ return { files: output.split("\n").filter(Boolean) };
78
+ } catch (err) {
79
+ return {
80
+ files: [],
81
+ gitError: err?.stderr?.toString?.() || err?.message || String(err),
82
+ };
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Verify that the coder produced real changes.
88
+ * Counts both tracked changes and untracked files.
89
+ *
90
+ * @param {Object} params
91
+ * @param {string} params.baseRef - git reference to compare against
92
+ * @param {string} [params.projectDir] - directory scope
93
+ * @param {number} [params.minFiles=1] - minimum files that must change
94
+ * @param {number} [params.minLines=1] - minimum lines that must change
95
+ * @returns {VerificationResult}
96
+ */
97
+ export function verifyCoderOutput({ baseRef, projectDir = null, minFiles = 1, minLines = 1 }) {
98
+ const tracked = countChangesSince(baseRef, projectDir);
99
+ const untracked = countUntrackedFiles(projectDir);
100
+
101
+ // Git infra failure (bad baseRef, corrupt repo, git missing) — not
102
+ // the coder's fault. Bail out with `gitError` so the caller can log
103
+ // it and skip the "retry with explicit file paths" feedback that
104
+ // would otherwise blame the agent.
105
+ const gitError = tracked.gitError || untracked.gitError;
106
+ if (gitError) {
107
+ return {
108
+ passed: false,
109
+ filesChanged: 0,
110
+ linesChanged: 0,
111
+ files: [],
112
+ reason: `Git verification failed: ${gitError}`,
113
+ retryStrategy: null,
114
+ gitError,
115
+ };
116
+ }
117
+
118
+ const untrackedFiles = untracked.files || [];
119
+ const totalFiles = tracked.filesChanged + untrackedFiles.length;
120
+ const totalLines = tracked.linesAdded + tracked.linesDeleted;
121
+ const allFiles = [...tracked.files, ...untrackedFiles];
122
+
123
+ const passed = totalFiles >= minFiles && (untrackedFiles.length > 0 || totalLines >= minLines);
124
+
125
+ if (passed) {
126
+ return {
127
+ passed: true,
128
+ filesChanged: totalFiles,
129
+ linesChanged: totalLines,
130
+ files: allFiles,
131
+ reason: "",
132
+ retryStrategy: null
133
+ };
134
+ }
135
+
136
+ return {
137
+ passed: false,
138
+ filesChanged: totalFiles,
139
+ linesChanged: totalLines,
140
+ files: allFiles,
141
+ reason: totalFiles === 0
142
+ ? "Coder produced 0 file changes"
143
+ : `Only ${totalFiles} file(s) and ${totalLines} line(s) changed (below minimum)`,
144
+ retryStrategy: buildRetryStrategy(totalFiles, totalLines)
145
+ };
146
+ }
147
+
148
+ /**
149
+ * Build a retry strategy based on the verification failure.
150
+ */
151
+ function buildRetryStrategy(filesChanged, _linesChanged) {
152
+ if (filesChanged === 0) {
153
+ return "Rephrase the feedback with explicit file paths. List specific files to create/modify. Include example code snippets.";
154
+ }
155
+ return "Expand the prompt with more specific instructions. Break the task into smaller concrete steps.";
156
+ }
157
+
158
+ /**
159
+ * Track consecutive verification failures to detect stuck loops.
160
+ */
161
+ export class VerificationTracker {
162
+ constructor() {
163
+ this.consecutiveFailures = 0;
164
+ this.history = [];
165
+ }
166
+
167
+ record(result) {
168
+ this.history.push({ ...result, timestamp: Date.now() });
169
+ if (result.passed) {
170
+ this.consecutiveFailures = 0;
171
+ } else {
172
+ this.consecutiveFailures += 1;
173
+ }
174
+ }
175
+
176
+ isStuck(threshold = 2) {
177
+ return this.consecutiveFailures >= threshold;
178
+ }
179
+
180
+ getLastFailure() {
181
+ return [...this.history].reverse().find(h => !h.passed) || null;
182
+ }
183
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Orchestrator public API — thin barrel over the implementation in
3
+ * src/orchestrator/flow-runner.js.
4
+ *
5
+ * Why this file is tiny: the 2 000-line monolith that used to live here was
6
+ * extracted in KJC-TSK-0315 so that adding a new stage or routing rule no
7
+ * longer requires touching a god-module. Consumers keep importing from
8
+ * `src/orchestrator.js` — only the internal layout changed.
9
+ *
10
+ * See also:
11
+ * - src/orchestrator/flow-runner.js — runFlow + resumeFlow internals
12
+ * - src/orchestrator/stages/stage-executor.js — the StageExecutor contract
13
+ * that individual stages can implement to register themselves with
14
+ * StageRegistry.
15
+ */
16
+
17
+ export { runFlow, resumeFlow } from "./orchestrator/flow-runner.js";
18
+ export { loadProductContext } from "./orchestrator/config-init.js";
19
+ export {
20
+ shouldAutoContinueCheckpoint,
21
+ parseCheckpointAnswer
22
+ } from "./orchestrator/flow-control.js";