@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,358 @@
1
+ /**
2
+ * HU Auto-Generator — converts triage subtasks (+ researcher/architect context)
3
+ * into a certified HU batch ready for hu-sub-pipeline execution.
4
+ *
5
+ * Input: original task, triage subtasks, detected stack, researcher/architect context.
6
+ * Output: HU batch with setup HU (when needed), task HUs with per-HU task_type,
7
+ * and a dependency graph (setup blocks everything; remaining linear by default).
8
+ */
9
+
10
+ /**
11
+ * Derive a human-readable project name from a task prompt.
12
+ * Strips common action verbs + stopwords, takes up to 6 meaningful words,
13
+ * and title-cases the result. Max 60 chars.
14
+ */
15
+ export function deriveProjectName(originalTask) {
16
+ if (!originalTask || typeof originalTask !== "string") return "Untitled Project";
17
+ const STOPWORDS = new Set([
18
+ "a", "an", "the", "and", "or", "with", "for", "to", "of", "in", "on",
19
+ "is", "it", "its", "this", "that", "these", "those", "be", "been", "being",
20
+ "build", "create", "implement", "make", "develop", "add", "set", "up",
21
+ "setup", "write", "code", "new", "complete", "from", "scratch",
22
+ "application", "app", "tool", "system", "project", "using", "use",
23
+ "full", "full-stack", "fullstack", "stack", "based", "simple", "basic"
24
+ ]);
25
+ const words = originalTask
26
+ .toLowerCase()
27
+ .replaceAll(/[^\p{L}\p{N}\s-]/gu, " ")
28
+ .split(/\s+/)
29
+ .filter(w => w && !STOPWORDS.has(w));
30
+ const meaningful = words.slice(0, 6);
31
+ if (meaningful.length === 0) {
32
+ return originalTask.slice(0, 60).trim() || "Untitled Project";
33
+ }
34
+ const titled = meaningful
35
+ .map(w => w.charAt(0).toUpperCase() + w.slice(1))
36
+ .join(" ");
37
+ return titled.length > 60 ? titled.slice(0, 57) + "..." : titled;
38
+ }
39
+
40
+ /**
41
+ * Classify a subtask into a Karajan task_type.
42
+ * Maps free-text subtask descriptions to {infra|sw|add-tests|doc|refactor|nocode}.
43
+ */
44
+ export function classifyTaskType(text) {
45
+ if (!text || typeof text !== "string") return "sw";
46
+ const t = text.toLowerCase();
47
+ // Order matters: no-code beats infra (Zapier/Notion setups are no-code, not infra)
48
+ if (/\b(no-code|nocode|zapier|make\.com|airtable|notion)\b/.test(t)) return "nocode";
49
+ if (/\b(setup|install|init(?:ialize|iate)?|configure|scaffold|bootstrap)\b/.test(t)) return "infra";
50
+ if (/\b(docker|ci\/cd|pipeline|deploy|workflow\.yml|github actions?)\b/.test(t)) return "infra";
51
+ if (/\b(tests?|coverage|spec|vitest|jest|mocha|playwright)\b/.test(t) && !/\b(component|feature|endpoint)\b/.test(t)) return "add-tests";
52
+ if (/\b(readme|docs?|documentation|guide|tutorial)\b/.test(t)) return "doc";
53
+ if (/\b(refactor|cleanup|reorganiz|restructure|extract)\b/.test(t)) return "refactor";
54
+ return "sw";
55
+ }
56
+
57
+ /**
58
+ * Decide whether a setup HU is needed.
59
+ * Needed when: project is new OR stack hints suggest new dependencies.
60
+ */
61
+ export function needsSetupHu({ isNewProject = false, stackHints = [], subtasks = [] }) {
62
+ if (isNewProject) return true;
63
+ if (stackHints.length > 0) return true;
64
+ // Subtasks mentioning a framework/tool suggest fresh setup
65
+ const setupKeywords = /\b(npm init|package\.json|workspace|monorepo|vite|vitest|express|astro|next\.js|nestjs)\b/i;
66
+ return subtasks.some(s => setupKeywords.test(s));
67
+ }
68
+
69
+ // Stack-hint keyword sets. Used by filterConflictingHints (drop hints
70
+ // from other ecosystems once one is detected) and by
71
+ // resolveLanguageFromHints (pick the canonical language for setup +
72
+ // acceptance_tests templates).
73
+ const HINT_NODE = new Set(["express", "vite", "vitest", "jest", "next", "astro", "react", "vue", "svelte", "nestjs", "monorepo", "workspaces"]);
74
+ const HINT_PYTHON = new Set(["pytest", "flask", "fastapi", "django", "numpy", "pandas"]);
75
+ const HINT_GO = new Set(["gin", "fiber", "go"]);
76
+ const HINT_RUST = new Set(["cargo", "rust"]);
77
+
78
+ /**
79
+ * Drop hints from OTHER ecosystems when one is clearly the project's.
80
+ * Symmetric: previously only node-vs-go was filtered, so a Python
81
+ * project that also had "vitest" in a stale gitignore would still
82
+ * receive vitest in its setup HU.
83
+ */
84
+ function filterConflictingHints(hints) {
85
+ if (!hints || hints.length === 0) return hints;
86
+ const setForEachLang = [
87
+ ["python", HINT_PYTHON],
88
+ ["go", HINT_GO],
89
+ ["rust", HINT_RUST],
90
+ ["node", HINT_NODE],
91
+ ];
92
+ const present = setForEachLang.filter(([, set]) => hints.some((h) => set.has(h)));
93
+ if (present.length <= 1) return hints;
94
+ // First ecosystem found in the original hints order wins. We keep
95
+ // ambiguous keywords (those not in any set) and the winner's own
96
+ // keywords; we drop the explicit losers from competing ecosystems.
97
+ const winnerSet = present[0][1];
98
+ const losers = present.slice(1).flatMap(([, s]) => [...s]);
99
+ return hints.filter((h) => winnerSet.has(h) || !losers.includes(h));
100
+ }
101
+
102
+ /**
103
+ * Pick the canonical language for setup + acceptance_test templates
104
+ * based on the (already filtered) stack hints. Falls back to
105
+ * javascript so existing Node-centric runs keep their previous shape.
106
+ * @param {string[]} hints
107
+ * @returns {"python"|"go"|"rust"|"javascript"}
108
+ */
109
+ function resolveLanguageFromHints(hints) {
110
+ if (!hints || hints.length === 0) return "javascript";
111
+ if (hints.some((h) => HINT_PYTHON.has(h))) return "python";
112
+ if (hints.some((h) => HINT_GO.has(h))) return "go";
113
+ if (hints.some((h) => HINT_RUST.has(h))) return "rust";
114
+ return "javascript";
115
+ }
116
+
117
+ // HU templates per language. The JS template is the legacy default;
118
+ // the others were missing — every autogenerated HU got vitest /
119
+ // npm-install hardcoded acceptance_tests regardless of stack.
120
+ const HU_TEMPLATES = {
121
+ javascript: {
122
+ pkgManager: "npm",
123
+ setupBullets: [
124
+ "- Create package.json (with workspaces if monorepo detected from stack hints)",
125
+ "- Install all runtime + dev dependencies listed in stack hints",
126
+ "- Install test framework WITH coverage reporter (e.g. vitest + @vitest/coverage-v8)",
127
+ "- Configure vitest.config.js with coverage.enabled = true",
128
+ "- Create .env.example with placeholder variables",
129
+ ],
130
+ setupCriteria: [
131
+ "npm install succeeds without errors",
132
+ "npm test runs without error",
133
+ "npm run test:coverage runs without error",
134
+ ".env.example exists",
135
+ ],
136
+ setupTests: [
137
+ "npm install --ignore-scripts 2>&1 && echo PASS || echo FAIL",
138
+ "npx vitest run 2>&1; test $? -eq 0 && echo PASS || echo FAIL",
139
+ "npx vitest run --coverage 2>&1 | grep -q 'All files\\|% Stmts' && echo PASS || echo FAIL",
140
+ "test -f .env.example && echo PASS || echo FAIL",
141
+ ],
142
+ taskTests: [
143
+ "npx vitest run 2>&1; test $? -eq 0 && echo PASS || echo FAIL",
144
+ "npx vitest run --coverage 2>&1 | grep -q 'All files\\|% Stmts' && echo PASS || echo FAIL",
145
+ ],
146
+ },
147
+ python: {
148
+ pkgManager: "pip",
149
+ setupBullets: [
150
+ "- Create pyproject.toml (preferred) or requirements.txt",
151
+ "- Create a virtual env: python -m venv .venv",
152
+ "- Install runtime + dev dependencies (pip install -e . or pip install -r requirements.txt)",
153
+ "- Install pytest with coverage (pip install pytest pytest-cov)",
154
+ "- Create .env.example with placeholder variables",
155
+ ],
156
+ setupCriteria: [
157
+ "Project metadata file exists (pyproject.toml or requirements.txt)",
158
+ "pytest runs without error",
159
+ "pytest --cov reports a total",
160
+ ".env.example exists",
161
+ ],
162
+ setupTests: [
163
+ "(test -f pyproject.toml || test -f requirements.txt) && echo PASS || echo FAIL",
164
+ "python -m pytest 2>&1; test $? -eq 0 && echo PASS || echo FAIL",
165
+ "python -m pytest --cov 2>&1 | grep -q 'TOTAL\\|coverage' && echo PASS || echo FAIL",
166
+ "test -f .env.example && echo PASS || echo FAIL",
167
+ ],
168
+ taskTests: [
169
+ "python -m pytest 2>&1; test $? -eq 0 && echo PASS || echo FAIL",
170
+ "python -m pytest --cov 2>&1 | grep -q 'TOTAL\\|coverage' && echo PASS || echo FAIL",
171
+ ],
172
+ },
173
+ go: {
174
+ pkgManager: "go",
175
+ setupBullets: [
176
+ "- Create go.mod with `go mod init <module>`",
177
+ "- Install dependencies with `go get` per import",
178
+ "- Create .env.example with placeholder variables",
179
+ ],
180
+ setupCriteria: [
181
+ "go.mod exists",
182
+ "go test ./... runs without error",
183
+ "go test -cover reports coverage",
184
+ ".env.example exists",
185
+ ],
186
+ setupTests: [
187
+ "test -f go.mod && echo PASS || echo FAIL",
188
+ "go test ./... 2>&1; test $? -eq 0 && echo PASS || echo FAIL",
189
+ "go test -cover ./... 2>&1 | grep -q 'coverage:' && echo PASS || echo FAIL",
190
+ "test -f .env.example && echo PASS || echo FAIL",
191
+ ],
192
+ taskTests: [
193
+ "go test ./... 2>&1; test $? -eq 0 && echo PASS || echo FAIL",
194
+ ],
195
+ },
196
+ rust: {
197
+ pkgManager: "cargo",
198
+ setupBullets: [
199
+ "- Initialise the crate with `cargo init`",
200
+ "- Add dependencies with `cargo add`",
201
+ "- Create .env.example with placeholder variables",
202
+ ],
203
+ setupCriteria: [
204
+ "Cargo.toml exists",
205
+ "cargo test runs without error",
206
+ ".env.example exists",
207
+ ],
208
+ setupTests: [
209
+ "test -f Cargo.toml && echo PASS || echo FAIL",
210
+ "cargo test 2>&1; test $? -eq 0 && echo PASS || echo FAIL",
211
+ "test -f .env.example && echo PASS || echo FAIL",
212
+ ],
213
+ taskTests: [
214
+ "cargo test 2>&1; test $? -eq 0 && echo PASS || echo FAIL",
215
+ ],
216
+ },
217
+ };
218
+
219
+ function templateFor(language) {
220
+ return HU_TEMPLATES[language] || HU_TEMPLATES.javascript;
221
+ }
222
+
223
+ /**
224
+ * Build a MINIMAL setup HU — project structure + deps only.
225
+ * NEVER includes the full original task. The coder must only do setup.
226
+ */
227
+ function buildSetupHu({ stackHints, language = "javascript" }) {
228
+ const tpl = templateFor(language);
229
+ const deps = stackHints.length > 0
230
+ ? stackHints.map(h => `- ${h}`).join("\n")
231
+ : "- (auto-detect from subsequent HUs)";
232
+ const certifiedText = [
233
+ `**Setup: initialise the ${language} project + install dependencies (package manager: ${tpl.pkgManager}).**`,
234
+ "",
235
+ "SCOPE (do ONLY this, nothing else):",
236
+ ...tpl.setupBullets,
237
+ "- Verify by running each acceptance_test command below",
238
+ "",
239
+ "DO NOT implement any business logic, API routes, components, or features.",
240
+ "This HU is ONLY project scaffolding.",
241
+ "",
242
+ "Stack hints:",
243
+ deps,
244
+ ].join("\n");
245
+ return {
246
+ id: "HU-01",
247
+ title: `Setup: ${language} project structure + dependencies`,
248
+ task_type: "infra",
249
+ status: "certified",
250
+ blocked_by: [],
251
+ certified: { text: certifiedText },
252
+ acceptance_criteria: tpl.setupCriteria,
253
+ acceptance_tests: tpl.setupTests,
254
+ };
255
+ }
256
+
257
+ /**
258
+ * Build a MINIMAL task HU — one specific, focused piece of work.
259
+ * Includes a short goal reference (max 80 chars) NOT the full task.
260
+ */
261
+ function buildTaskHu({ id, subtask, projectName, blockedBy, language = "javascript" }) {
262
+ const taskType = classifyTaskType(subtask);
263
+ const tpl = templateFor(language);
264
+ const certifiedText = [
265
+ `**${subtask}**`,
266
+ "",
267
+ `Project: ${projectName}`,
268
+ "",
269
+ "SCOPE (do ONLY this, nothing else):",
270
+ `- Implement: ${subtask}`,
271
+ "- Add unit tests for the new code",
272
+ "- Run ALL acceptance_tests listed below and ensure they pass",
273
+ "- Do NOT touch code outside this subtask's scope",
274
+ "- Target: <200 lines changed (like an atomic PR)",
275
+ ].join("\n");
276
+ return {
277
+ id,
278
+ title: subtask.length > 80 ? subtask.slice(0, 77) + "..." : subtask,
279
+ task_type: taskType,
280
+ status: "certified",
281
+ blocked_by: blockedBy,
282
+ certified: { text: certifiedText },
283
+ acceptance_criteria: [
284
+ `${subtask} is implemented and working`,
285
+ "Unit tests cover the new code",
286
+ "All acceptance_tests pass",
287
+ ],
288
+ acceptance_tests: tpl.taskTests,
289
+ };
290
+ }
291
+
292
+ /**
293
+ * Main entry point: generate a certified HU batch from triage output.
294
+ *
295
+ * @param {object} input
296
+ * @param {string} input.originalTask - the user's raw task
297
+ * @param {string[]} input.subtasks - triage.subtasks array
298
+ * @param {string[]} [input.stackHints] - detected stack keywords (e.g. ["nodejs", "vitest"])
299
+ * @param {boolean} [input.isNewProject] - true when projectDir is empty/fresh
300
+ * @param {string} [input.researcherContext] - researcher output (optional, used for better HU text)
301
+ * @param {string} [input.architectContext] - architect output (optional, used for dep graph)
302
+ * @returns {{ stories: object[], total: number, certified: number, generated: true }}
303
+ */
304
+ export function generateHuBatch({
305
+ originalTask,
306
+ subtasks = [],
307
+ stackHints = [],
308
+ isNewProject = false,
309
+ researcherContext = null,
310
+ architectContext = null,
311
+ language = null,
312
+ }) {
313
+ if (!originalTask || typeof originalTask !== "string") {
314
+ throw new Error("generateHuBatch: originalTask is required");
315
+ }
316
+ if (!Array.isArray(subtasks) || subtasks.length === 0) {
317
+ throw new Error("generateHuBatch: subtasks array is required");
318
+ }
319
+
320
+ const stories = [];
321
+ const filteredHints = filterConflictingHints(stackHints);
322
+ const needsSetup = needsSetupHu({ isNewProject, stackHints: filteredHints, subtasks });
323
+ // Caller may pass a language explicitly (when it has a real
324
+ // detectProjectStack result from the filesystem); otherwise fall
325
+ // back to inferring from the hint keywords. Default 'javascript'
326
+ // matches the previous behaviour for Node-centric runs.
327
+ const resolvedLanguage = language || resolveLanguageFromHints(filteredHints);
328
+ let nextId = 1;
329
+
330
+ const projectName = deriveProjectName(originalTask);
331
+
332
+ if (needsSetup) {
333
+ stories.push(buildSetupHu({ stackHints: filteredHints, language: resolvedLanguage }));
334
+ nextId = 2;
335
+ }
336
+
337
+ // Task HUs: linear dependency chain after setup (conservative default).
338
+ const setupId = needsSetup ? "HU-01" : null;
339
+ let previousId = setupId;
340
+ for (const subtask of subtasks) {
341
+ const id = `HU-${String(nextId).padStart(2, "0")}`;
342
+ const blockedBy = [];
343
+ if (setupId) blockedBy.push(setupId);
344
+ if (previousId && previousId !== setupId) blockedBy.push(previousId);
345
+ stories.push(buildTaskHu({ id, subtask, projectName, blockedBy, language: resolvedLanguage }));
346
+ previousId = id;
347
+ nextId += 1;
348
+ }
349
+
350
+ return {
351
+ stories,
352
+ total: stories.length,
353
+ certified: stories.length,
354
+ projectName: deriveProjectName(originalTask),
355
+ generated: true,
356
+ source: { triage_subtasks: subtasks.length, researcher: Boolean(researcherContext), architect: Boolean(architectContext) }
357
+ };
358
+ }
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Topological sort of HU stories respecting blocked_by dependencies.
3
+ * Returns ordered array of story IDs (dependencies first).
4
+ * Throws if circular dependency detected.
5
+ * @param {Array<{id: string, blocked_by?: string[]}>} stories
6
+ * @returns {string[]} Sorted story IDs.
7
+ */
8
+ export function topologicalSort(stories) {
9
+ const ids = new Set(stories.map(s => s.id));
10
+ const adj = new Map(); // id -> [dependents]
11
+ const inDegree = new Map();
12
+
13
+ for (const s of stories) {
14
+ adj.set(s.id, []);
15
+ inDegree.set(s.id, 0);
16
+ }
17
+
18
+ for (const s of stories) {
19
+ for (const dep of (s.blocked_by || [])) {
20
+ if (!ids.has(dep)) throw new Error(`Dependency ${dep} not found in batch`);
21
+ adj.get(dep).push(s.id);
22
+ inDegree.set(s.id, (inDegree.get(s.id) || 0) + 1);
23
+ }
24
+ }
25
+
26
+ const queue = [];
27
+ for (const [id, degree] of inDegree) {
28
+ if (degree === 0) queue.push(id);
29
+ }
30
+
31
+ const sorted = [];
32
+ while (queue.length > 0) {
33
+ const id = queue.shift();
34
+ sorted.push(id);
35
+ for (const dependent of adj.get(id)) {
36
+ inDegree.set(dependent, inDegree.get(dependent) - 1);
37
+ if (inDegree.get(dependent) === 0) queue.push(dependent);
38
+ }
39
+ }
40
+
41
+ if (sorted.length !== stories.length) {
42
+ throw new Error("Circular dependency detected in HU batch");
43
+ }
44
+
45
+ return sorted;
46
+ }
47
+
48
+ /**
49
+ * Check if a story is ready to execute (all its dependencies are done).
50
+ * @param {{blocked_by?: string[]}} story
51
+ * @param {{stories: Array<{id: string, status: string}>}} batch
52
+ * @returns {boolean}
53
+ */
54
+ export function isStoryReady(story, batch) {
55
+ if (!story.blocked_by || story.blocked_by.length === 0) return true;
56
+ return story.blocked_by.every(depId => {
57
+ const dep = batch.stories.find(s => s.id === depId);
58
+ return dep && dep.status === "done";
59
+ });
60
+ }
61
+
62
+ /**
63
+ * Get next stories ready for execution (certified + all deps done).
64
+ * @param {{stories: Array<{id: string, status: string, blocked_by?: string[]}>}} batch
65
+ * @returns {Array<object>} Stories that are certified and whose deps are all done.
66
+ */
67
+ export function getNextReadyStories(batch) {
68
+ return batch.stories.filter(s =>
69
+ s.status === "certified" && isStoryReady(s, batch)
70
+ );
71
+ }
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Lazy HU Planner — refines HUs one at a time using context from completed HUs.
3
+ *
4
+ * Instead of fully planning all HUs upfront, only the first HU is decomposed
5
+ * with full acceptance criteria. Subsequent HUs are refined lazily before
6
+ * execution, incorporating learnings from previously completed HUs.
7
+ */
8
+ import { createAgent } from "../agents/index.js";
9
+ import { extractFirstJson } from "../utils/json-extract.js";
10
+ import { withBrainRecovery } from "../brain/with-brain-recovery.js";
11
+
12
+ const SUBAGENT_PREAMBLE = [
13
+ "IMPORTANT: You are running as a Karajan sub-agent.",
14
+ "Do NOT ask about using Karajan, do NOT mention Karajan, do NOT suggest orchestration.",
15
+ "Do NOT use any MCP tools. Focus only on refining the user story."
16
+ ].join(" ");
17
+
18
+ /**
19
+ * Build a prompt asking the AI to refine an HU based on context from completed HUs.
20
+ * @param {object} hu - The HU to refine (with at least id, original.text or certified.text).
21
+ * @param {Array<object>} completedHus - Array of completed HU results with summaries.
22
+ * @returns {string} The assembled refinement prompt.
23
+ */
24
+ export function buildRefinementPrompt(hu, completedHus) {
25
+ const sections = [SUBAGENT_PREAMBLE];
26
+
27
+ sections.push("## HU Refinement");
28
+ sections.push(
29
+ "You are a senior product owner. Refine the following user story by adding or updating its acceptance criteria.",
30
+ "Use the context from previously completed HUs to make the criteria more precise and avoid redundant work."
31
+ );
32
+
33
+ if (completedHus.length > 0) {
34
+ sections.push("## Previously Completed HUs");
35
+ for (const completed of completedHus) {
36
+ const title = completed.certified?.title || completed.id;
37
+ const summary = completed.resultSummary || completed.certified?.text || completed.original?.text || "No summary available";
38
+ sections.push(`### ${completed.id} — ${title}\nResult: ${summary}`);
39
+ }
40
+ }
41
+
42
+ const huText = hu.certified?.text || hu.original?.text || `Implement HU ${hu.id}`;
43
+ sections.push(`## HU to Refine\n### ${hu.id}\n${huText}`);
44
+
45
+ sections.push(
46
+ "Return a single valid JSON object and nothing else.",
47
+ `JSON schema: {"id":string,"title":string,"text":string,"acceptanceCriteria":[string]}`,
48
+ "Rules:",
49
+ "- Keep the same HU id",
50
+ "- Refine the description to be more specific based on what was learned",
51
+ "- Add concrete, testable acceptance criteria",
52
+ "- Avoid repeating work already done in completed HUs",
53
+ "- The text field should be the full story description ready for implementation"
54
+ );
55
+
56
+ return sections.join("\n\n");
57
+ }
58
+
59
+ /**
60
+ * Refine an HU using AI, incorporating context from completed HUs.
61
+ * @param {object} hu - The HU story object to refine.
62
+ * @param {Array<object>} completedHus - Completed HU stories with results.
63
+ * @param {object} config - Pipeline configuration.
64
+ * @param {object} logger - Logger instance.
65
+ * @returns {Promise<object>} Updated HU object with refined description and AC.
66
+ */
67
+ export async function refineHuWithContext(hu, completedHus, config, logger) {
68
+ const provider = config?.roles?.hu_reviewer?.provider || config?.roles?.coder?.provider || "claude";
69
+ const prompt = buildRefinementPrompt(hu, completedHus);
70
+
71
+ logger.info(`Lazy planner: refining HU ${hu.id} with context from ${completedHus.length} completed HU(s)`);
72
+
73
+ const agent = createAgent(provider, config, logger);
74
+ let result;
75
+ try {
76
+ // KJC-TSK-0413 step C
77
+ result = await withBrainRecovery({
78
+ agent, taskArgs: { prompt, role: "hu-reviewer" },
79
+ role: "lazy-planner", provider, logger,
80
+ });
81
+ } catch (err) {
82
+ logger.warn(`Lazy planner: refinement failed for HU ${hu.id}: ${err.message}`);
83
+ return hu;
84
+ }
85
+
86
+ if (!result.ok) {
87
+ logger.warn(`Lazy planner: refinement returned not-ok for HU ${hu.id}`);
88
+ return hu;
89
+ }
90
+
91
+ const parsed = extractFirstJson(result.output);
92
+ if (!parsed || !parsed.text) {
93
+ logger.warn(`Lazy planner: could not parse refinement output for HU ${hu.id}`);
94
+ return hu;
95
+ }
96
+
97
+ // Update the HU with refined content
98
+ const refined = { ...hu };
99
+ refined.certified = {
100
+ ...(hu.certified || {}),
101
+ text: parsed.text,
102
+ title: parsed.title || hu.certified?.title || hu.id,
103
+ acceptanceCriteria: parsed.acceptanceCriteria || []
104
+ };
105
+ refined.needsRefinement = false;
106
+
107
+ logger.info(`Lazy planner: HU ${hu.id} refined successfully`);
108
+ return refined;
109
+ }
@@ -0,0 +1,108 @@
1
+ // KJC-TSK-0405: dado un HU con complexity score, recomienda coder_model y
2
+ // reviewer_model. El reviewer por defecto usa el provider alternativo al
3
+ // coder (cross-provider review) para que dos cabezas distintas miren el
4
+ // código y se detecten más patrones.
5
+
6
+ const LEVELS = ["trivial", "simple", "medium", "complex"];
7
+
8
+ // Mapping complexity score numérico → nivel categórico.
9
+ // 1 → trivial, 2 → simple, 3/4 → medium, 5+ → complex.
10
+ const SCORE_TO_LEVEL = {
11
+ 1: "trivial",
12
+ 2: "simple",
13
+ 3: "medium",
14
+ 4: "medium",
15
+ 5: "complex",
16
+ };
17
+
18
+ // Defaults por provider — alineados con utils/model-selector.js DEFAULTS.
19
+ // opencode: usa "coder" como alias razonable; el usuario suele definir
20
+ // gemma-local/coder, ollama/coder o similar en opencode.json. Override
21
+ // per-tier vía config.model_routing.by_provider.opencode si quieres
22
+ // rutear distinto por complexity (ej. fast para trivial, coder para
23
+ // complex). aider: null porque aider envuelve a otros providers — no
24
+ // tiene "modelos propios". Si el usuario lo elige, debe configurarlo
25
+ // explícito en config.model_routing.by_provider.aider o vía override
26
+ // del modal por HU.
27
+ const DEFAULT_TIERS = {
28
+ claude: { trivial: "haiku", simple: "haiku", medium: "sonnet", complex: "opus" },
29
+ codex: { trivial: "o4-mini", simple: "o4-mini", medium: "o4-mini", complex: "o3" },
30
+ gemini: { trivial: "gemini-2.0-flash", simple: "gemini-2.0-flash", medium: "gemini-2.5-pro", complex: "gemini-2.5-pro" },
31
+ opencode: { trivial: "coder", simple: "coder", medium: "coder", complex: "coder" },
32
+ aider: { trivial: null, simple: null, medium: null, complex: null },
33
+ };
34
+
35
+ // Cross-provider reviewer default: para cada coder provider, qué provider
36
+ // usa el reviewer por defecto. Dos cabezas distintas miran el código.
37
+ // opencode → claude: pattern "local barato escribe + cloud revisa".
38
+ // aider → claude: aider suele correr en un model pequeño, claude verifica.
39
+ const CROSS_PROVIDER_REVIEWER = {
40
+ claude: "codex",
41
+ codex: "claude",
42
+ gemini: "claude",
43
+ opencode: "claude",
44
+ aider: "claude",
45
+ };
46
+
47
+ // KJC-TSK-0405 step 2: heurística para inferir complexity desde
48
+ // task_type cuando el planner no emite un score explícito. Permite
49
+ // que el model-router asigne modelos razonables sin un triage explícito.
50
+ const TASK_TYPE_COMPLEXITY = {
51
+ sw: "medium",
52
+ refactor: "medium",
53
+ "add-tests": "simple",
54
+ infra: "trivial",
55
+ doc: "trivial",
56
+ spike: "complex",
57
+ research: "complex",
58
+ audit: "complex",
59
+ analysis: "medium",
60
+ "no-code": "trivial",
61
+ };
62
+
63
+ export function complexityFromTaskType(taskType) {
64
+ return TASK_TYPE_COMPLEXITY[taskType] || "medium";
65
+ }
66
+
67
+ export function complexityToLevel(complexity) {
68
+ if (typeof complexity === "string" && LEVELS.includes(complexity)) return complexity;
69
+ if (typeof complexity === "number" && SCORE_TO_LEVEL[complexity]) return SCORE_TO_LEVEL[complexity];
70
+ return "medium";
71
+ }
72
+
73
+ /**
74
+ * @param {object} args
75
+ * @param {string|number} args.complexity - "trivial" | "simple" | "medium" | "complex" | score 1-5
76
+ * @param {string} args.coderProvider - "claude" | "codex" | "gemini"
77
+ * @param {object} args.config - karajan config (lee model_routing si existe)
78
+ * @returns {{ coder_model: string|null, coder_provider: string, reviewer_model: string|null, reviewer_provider: string }}
79
+ */
80
+ export function recommendModelsForHu({ complexity, coderProvider, config = {} }) {
81
+ const level = complexityToLevel(complexity);
82
+ const routing = config.model_routing || {};
83
+ const fixed = routing.fixed || {};
84
+
85
+ // Merge tiers: defaults + user overrides per provider.
86
+ const tiers = { ...DEFAULT_TIERS };
87
+ if (routing.by_provider) {
88
+ for (const [prov, levels] of Object.entries(routing.by_provider)) {
89
+ tiers[prov] = { ...(tiers[prov] || {}), ...levels };
90
+ }
91
+ }
92
+
93
+ const coderTier = tiers[coderProvider];
94
+ const coderAuto = coderTier ? (coderTier[level] || null) : null;
95
+ const coder_model = fixed.coder || coderAuto;
96
+
97
+ const reviewer_provider = CROSS_PROVIDER_REVIEWER[coderProvider] || "claude";
98
+ const reviewerTier = tiers[reviewer_provider];
99
+ const reviewerAuto = reviewerTier ? (reviewerTier[level] || null) : null;
100
+ const reviewer_model = fixed.reviewer || reviewerAuto;
101
+
102
+ return {
103
+ coder_model,
104
+ coder_provider: coderProvider,
105
+ reviewer_model,
106
+ reviewer_provider,
107
+ };
108
+ }