@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,276 @@
1
+ /**
2
+ * Project bootstrap — mandatory prerequisite gate.
3
+ *
4
+ * Before any KJ tool that executes agents (kj_run, kj_code, kj_review, etc.),
5
+ * this module validates that ALL environment prerequisites are met.
6
+ *
7
+ * Philosophy: NEVER degrade gracefully. If something is missing, STOP and
8
+ * tell the user exactly what to fix. No silent fallbacks, no auto-disabling.
9
+ *
10
+ * Results are cached in `.kj-ready.json` per project (TTL-based) so that
11
+ * slow checks (SonarQube reachability, agent detection) don't repeat on
12
+ * every invocation.
13
+ */
14
+
15
+ import fs from "node:fs/promises";
16
+ import path from "node:path";
17
+ import { readFileSync } from "node:fs";
18
+ import { fileURLToPath } from "node:url";
19
+ import { ensureGitRepo } from "./utils/git.js";
20
+ import { runCommand } from "./utils/process.js";
21
+ import { checkBinary } from "./utils/agent-detect.js";
22
+ import { exists } from "./utils/fs.js";
23
+ import { getConfigPath, resolveRole } from "./config.js";
24
+ import { isSonarReachable, sonarUp } from "./sonar/manager.js";
25
+ import { withDocLink } from "./utils/doc-links.js";
26
+
27
+ const BOOTSTRAP_VERSION = 1;
28
+ const BOOTSTRAP_TTL_HOURS = 24;
29
+ const BOOTSTRAP_FILENAME = ".kj-ready.json";
30
+
31
+ function getPackageVersion() {
32
+ const pkgPath = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../package.json");
33
+ return JSON.parse(readFileSync(pkgPath, "utf8")).version;
34
+ }
35
+
36
+ // ── Individual checks ────────────────────────────────────────────────
37
+
38
+ async function checkGitRepo() {
39
+ let ok;
40
+ try {
41
+ ok = await ensureGitRepo();
42
+ } catch { /* git may not be installed */
43
+ ok = false;
44
+ }
45
+
46
+ if (!ok) {
47
+ // Auto-init: initialize git repo for new projects
48
+ const initResult = await runCommand("git", ["init"]);
49
+ if (initResult.exitCode !== 0) {
50
+ return {
51
+ name: "gitRepo",
52
+ ok: false,
53
+ detail: "Not a git repository and git init failed",
54
+ fix: "Ensure git is installed and you have write permissions to this directory."
55
+ };
56
+ }
57
+ return { name: "gitRepo", ok: true, detail: "Initialized new git repository", fix: null };
58
+ }
59
+
60
+ return { name: "gitRepo", ok: true, detail: "Inside a git repository", fix: null };
61
+ }
62
+
63
+ async function checkGitRemote() {
64
+ try {
65
+ const res = await runCommand("git", ["remote", "get-url", "origin"]);
66
+ if (res.exitCode === 0 && res.stdout.trim()) {
67
+ return { name: "gitRemote", ok: true, detail: res.stdout.trim(), fix: null };
68
+ }
69
+ } catch { /* fall through */ }
70
+ // No remote is acceptable for new projects — non-blocking
71
+ return {
72
+ name: "gitRemote",
73
+ ok: true,
74
+ detail: "No remote configured (new project)",
75
+ fix: null
76
+ };
77
+ }
78
+
79
+ async function checkConfigExists() {
80
+ const configPath = getConfigPath();
81
+ const configOk = await exists(configPath);
82
+ return {
83
+ name: "config",
84
+ ok: configOk,
85
+ detail: configOk ? configPath : "Config file not found",
86
+ fix: configOk ? null : "Run 'kj_init' to create your Karajan config file."
87
+ };
88
+ }
89
+
90
+ async function checkCoreBinaries() {
91
+ const missing = [];
92
+ for (const bin of ["node", "npm", "git"]) {
93
+ const result = await checkBinary(bin);
94
+ if (!result.ok) {
95
+ missing.push(bin);
96
+ }
97
+ }
98
+ if (missing.length > 0) {
99
+ return {
100
+ name: "coreBinaries",
101
+ ok: false,
102
+ detail: `Missing: ${missing.join(", ")}`,
103
+ fix: `Install missing binaries: ${missing.join(", ")}.`
104
+ };
105
+ }
106
+ return { name: "coreBinaries", ok: true, detail: "node, npm, git available", fix: null };
107
+ }
108
+
109
+ async function checkConfiguredAgents(config) {
110
+ const { provider } = resolveRole(config, "coder");
111
+ if (!provider) {
112
+ return {
113
+ name: "agents",
114
+ ok: false,
115
+ detail: "No coder provider configured",
116
+ fix: "Run 'kj_init' or set a coder provider in kj.config.yml."
117
+ };
118
+ }
119
+ const result = await checkBinary(provider);
120
+ if (!result.ok) {
121
+ return {
122
+ name: "agents",
123
+ ok: false,
124
+ detail: `Coder agent "${provider}" not found`,
125
+ fix: `Install "${provider}" CLI. Run 'kj_doctor' for installation instructions.`
126
+ };
127
+ }
128
+ return { name: "agents", ok: true, detail: `coder: ${provider}`, fix: null };
129
+ }
130
+
131
+ async function checkSonarQubeReady(config) {
132
+ if (config.sonarqube?.enabled === false) {
133
+ return { name: "sonarqube", ok: true, detail: "Disabled in config", fix: null };
134
+ }
135
+
136
+ const host = config.sonarqube?.host || "http://localhost:9000";
137
+
138
+ // First attempt
139
+ let reachable = await isSonarReachable(host);
140
+ if (reachable) {
141
+ return { name: "sonarqube", ok: true, detail: `Reachable at ${host}`, fix: null };
142
+ }
143
+
144
+ // Auto-remediation: start and wait up to 60s for SonarQube to be ready
145
+ try {
146
+ await sonarUp(host);
147
+ const deadline = Date.now() + 60000;
148
+ while (Date.now() < deadline) {
149
+ reachable = await isSonarReachable(host);
150
+ if (reachable) {
151
+ return { name: "sonarqube", ok: true, detail: `Started and reachable at ${host}`, fix: null };
152
+ }
153
+ await new Promise(r => setTimeout(r, 5000));
154
+ }
155
+ } catch { /* fall through */ }
156
+
157
+ return {
158
+ name: "sonarqube",
159
+ ok: false,
160
+ detail: `Not reachable at ${host}`,
161
+ fix: `Start SonarQube: 'docker start karajan-sonarqube', or disable it: set sonarqube.enabled: false in kj.config.yml, or pass --no-sonar.`
162
+ };
163
+ }
164
+
165
+ // ── Bootstrap file management ────────────────────────────────────────
166
+
167
+ function bootstrapPath(projectDir) {
168
+ return path.join(projectDir, BOOTSTRAP_FILENAME);
169
+ }
170
+
171
+ async function readBootstrapFile(projectDir) {
172
+ try {
173
+ const raw = await fs.readFile(bootstrapPath(projectDir), "utf8");
174
+ return JSON.parse(raw);
175
+ } catch { /* bootstrap file may not exist or contain invalid JSON */
176
+ return null;
177
+ }
178
+ }
179
+
180
+ function isBootstrapValid(bootstrap, projectDir) {
181
+ if (!bootstrap || bootstrap.version !== BOOTSTRAP_VERSION) return false;
182
+ if (bootstrap.karajanVersion !== getPackageVersion()) return false;
183
+ if (bootstrap.projectDir !== projectDir) return false;
184
+ const age = Date.now() - new Date(bootstrap.createdAt).getTime();
185
+ if (age > BOOTSTRAP_TTL_HOURS * 3600 * 1000) return false;
186
+ return true;
187
+ }
188
+
189
+ async function writeBootstrapFile(projectDir, checks) {
190
+ const data = {
191
+ version: BOOTSTRAP_VERSION,
192
+ karajanVersion: getPackageVersion(),
193
+ createdAt: new Date().toISOString(),
194
+ projectDir,
195
+ checks: Object.fromEntries(checks.map(c => [c.name, { ok: c.ok, detail: c.detail }]))
196
+ };
197
+ await fs.writeFile(bootstrapPath(projectDir), JSON.stringify(data, null, 2) + "\n", "utf8");
198
+ }
199
+
200
+ function formatBootstrapFailure(failures) {
201
+ const lines = failures.map(f =>
202
+ ` FAIL ${f.name}: ${f.detail}\n Fix: ${f.fix}`
203
+ );
204
+ return withDocLink([
205
+ "BOOTSTRAP FAILED — Environment not ready for Karajan Code.\n",
206
+ "The following prerequisite(s) are not met:\n",
207
+ ...lines,
208
+ "",
209
+ "Run 'kj_doctor' for a complete environment diagnostic.",
210
+ "Do NOT work around these issues — fix them properly."
211
+ ].join("\n"), "bootstrap_failed");
212
+ }
213
+
214
+ // ── Public API ───────────────────────────────────────────────────────
215
+
216
+ /**
217
+ * Ensure the project environment is ready for KJ execution.
218
+ * Reads cached `.kj-ready.json` if valid; otherwise runs all checks.
219
+ * Throws Error with actionable message if any prerequisite fails.
220
+ */
221
+ export async function ensureBootstrap(projectDir, config) {
222
+ // Plugin discovery runs unconditionally on every bootstrap, regardless
223
+ // of whether the bootstrap cache says environment is valid. A user
224
+ // dropping a new file into `.karajan/plugins/` expects it to be picked
225
+ // up without running `kj init` again.
226
+ //
227
+ // Pre-v2.7.5 this was never called — `loadPlugins()` was exported but
228
+ // never imported from production code, so any plugin the user added
229
+ // was silently ignored. Fixed in TSK-0329.
230
+ try {
231
+ const { loadPlugins } = await import("./plugins/loader.js");
232
+ await loadPlugins({ projectDir });
233
+ } catch { /* plugin system failed — non-blocking, continue bootstrap */ }
234
+
235
+ // TSK-0339: register the Planning Game adapter in the integrations registry
236
+ // when enabled. The orchestrator no longer imports `src/planning-game/*`
237
+ // directly — it calls `getIntegration("tracker")?.hookName(...)` instead.
238
+ // Other trackers (GitHub Projects, Jira, Linear, …) drop in by writing
239
+ // a sibling adapter that calls `registerIntegration("tracker", …)`.
240
+ if (config?.planning_game?.enabled) {
241
+ try {
242
+ const { registerPgAdapter } = await import("./planning-game/pipeline-adapter.js");
243
+ await registerPgAdapter();
244
+ } catch { /* PG registration failed — non-blocking, continue bootstrap */ }
245
+ }
246
+
247
+ const cached = await readBootstrapFile(projectDir);
248
+ if (isBootstrapValid(cached, projectDir)) {
249
+ return; // Environment already validated
250
+ }
251
+
252
+ const checks = await Promise.all([
253
+ checkGitRepo(),
254
+ checkGitRemote(),
255
+ checkConfigExists(),
256
+ checkCoreBinaries(),
257
+ checkConfiguredAgents(config),
258
+ checkSonarQubeReady(config)
259
+ ]);
260
+
261
+ const failures = checks.filter(c => !c.ok);
262
+ if (failures.length > 0) {
263
+ throw new Error(formatBootstrapFailure(failures));
264
+ }
265
+
266
+ await writeBootstrapFile(projectDir, checks);
267
+ }
268
+
269
+ /**
270
+ * Delete `.kj-ready.json` to force re-validation on next run.
271
+ */
272
+ export async function invalidateBootstrap(projectDir) {
273
+ try {
274
+ await fs.unlink(bootstrapPath(projectDir));
275
+ } catch { /* file may not exist */ }
276
+ }
@@ -0,0 +1,116 @@
1
+ // KJC-TSK-0411: clasificador universal de errores de agente IA.
2
+ //
3
+ // Devuelve clase rica + metadata accionable para que Brain (TSK-0412)
4
+ // decida retry/standby/hibernar/abortar sin tener que repetir lógica
5
+ // de parsing en cada stage.
6
+ //
7
+ // Reutiliza parseCooldown del rate-limit-detector legacy para no
8
+ // duplicar regex. Este módulo extiende la clasificación:
9
+ // - RATE_LIMIT_SHORT vs QUOTA_EXHAUSTED_DAILY se distinguen por
10
+ // cooldownMs (threshold 1h).
11
+ // - SILENCED se detecta por exit 143/null + "killed after Nms".
12
+ // - AUTH_FAILED por 401/403 + "Unauthorized"/"invalid api key".
13
+ // - NETWORK_TIMEOUT por ECONN*/socket hang up sin cooldown.
14
+
15
+ import { parseCooldown } from "../utils/rate-limit-detector.js";
16
+
17
+ export const ERROR_CLASS = Object.freeze({
18
+ RATE_LIMIT_SHORT: "RATE_LIMIT_SHORT",
19
+ QUOTA_EXHAUSTED_DAILY: "QUOTA_EXHAUSTED_DAILY",
20
+ // KJC-TSK-0415: Anthropic Max 20x cambia a $200/mes Agent SDK desde
21
+ // 15-jun-2026. Cuando llegues al cap mensual, el reset es 1-mes —
22
+ // muy distinto del daily de Claude Pro. Esta clase distingue ambos.
23
+ QUOTA_EXHAUSTED_MONTHLY: "QUOTA_EXHAUSTED_MONTHLY",
24
+ API_DOWN: "API_DOWN",
25
+ AUTH_FAILED: "AUTH_FAILED",
26
+ NETWORK_TIMEOUT: "NETWORK_TIMEOUT",
27
+ SILENCED: "SILENCED",
28
+ UNKNOWN_FATAL: "UNKNOWN_FATAL",
29
+ });
30
+
31
+ const ONE_HOUR_MS = 60 * 60 * 1000;
32
+ const ONE_WEEK_MS = 7 * 24 * 60 * 60 * 1000;
33
+
34
+ // `error\s+authenticating` + `IneligibleTierError` (KJC-BUG-0113): the
35
+ // retired Gemini Code Assist CLI fails with "Error authenticating:
36
+ // IneligibleTierError … migrate to Antigravity" — it classified as
37
+ // UNKNOWN_FATAL and left the run without the AUTH escalation message.
38
+ const AUTH_PATTERNS = /\b401\b|\b403\b|unauthorized|invalid\s+api\s+key|authentication\s+failed|expired\s+token|error\s+authenticating|IneligibleTierError/i;
39
+ const SILENCED_PATTERNS = /killed\s+after\s+\d+\s*ms|silence\s*timeout|no\s+output\s+for\s+\d+/i;
40
+ // `session\s+limit` / `weekly\s+limit` cover Claude Code's usage caps
41
+ // ("You've hit your session limit · resets 10:10pm"). Without them the
42
+ // message fell through to UNKNOWN_FATAL and the run aborted instead of
43
+ // hibernating until the reset.
44
+ // Decomposed by family (S5843, complexity 36 → 3 named groups). The
45
+ // union of tokens is identical to the original single alternation.
46
+ const RATE_LIMIT_GROUPS = [
47
+ /rate\s*limit|too\s+many\s+requests|\b429\b|throttl/i,
48
+ /exceeded\s+your\s+current\s+quota|resource\s+exhausted|quota\s+exceeded|token\s+limit\s+reached/i,
49
+ /usage\s+limit|monthly\s+limit|weekly\s+limit|daily\s+limit|session\s+limit/i,
50
+ ];
51
+ const RATE_LIMIT_PATTERNS = { test: (text) => RATE_LIMIT_GROUPS.some((re) => re.test(text)) };
52
+ const API_DOWN_PATTERNS = /\b50[0-4]\b|bad\s+gateway|service\s+unavailable|gateway\s+timeout|overloaded|internal\s+server\s+error/i;
53
+ const NETWORK_PATTERNS = /ECONNREFUSED|ECONNRESET|ETIMEDOUT|socket\s+hang\s+up|fetch\s+failed|network\s+error/i;
54
+
55
+ function pickMessage(combined, pattern) {
56
+ const line = combined.split("\n").find((l) => pattern.test(l));
57
+ return (line || combined).trim().slice(0, 300);
58
+ }
59
+
60
+ /**
61
+ * @param {object} args
62
+ * @param {string} [args.provider] - claude|codex|gemini|opencode|aider
63
+ * @param {string} [args.stdout]
64
+ * @param {string} [args.stderr]
65
+ * @param {number|null} [args.exitCode]
66
+ * @returns {{ class: string, provider: string, message: string, retryAfter: number|null, retryUntil: string|null, recoverable: boolean, exitCode: number|null }}
67
+ */
68
+ export function classifyAgentError({ provider = "unknown", stdout = "", stderr = "", exitCode = null }) {
69
+ const combined = `${stderr}\n${stdout}`;
70
+ const base = { provider, exitCode, retryAfter: null, retryUntil: null };
71
+
72
+ // 1. AUTH_FAILED tiene prioridad absoluta — no es recuperable, escalar al usuario.
73
+ if (AUTH_PATTERNS.test(combined)) {
74
+ return { ...base, class: ERROR_CLASS.AUTH_FAILED, message: pickMessage(combined, AUTH_PATTERNS), recoverable: false };
75
+ }
76
+
77
+ // 2. SILENCED: subprocess killed por silenceTimeout. exit=143 (SIGTERM) o null.
78
+ // También detectamos por mensaje aunque exitCode no encaje (resiliente).
79
+ if (SILENCED_PATTERNS.test(combined) || (exitCode === 143 && !combined.trim())) {
80
+ return { ...base, class: ERROR_CLASS.SILENCED, message: pickMessage(combined, SILENCED_PATTERNS) || "Agent silenciado por timeout", recoverable: true };
81
+ }
82
+
83
+ // 3. RATE_LIMIT con cooldown. Thresholds:
84
+ // cooldown > 7d → MONTHLY (Anthropic Agent SDK $200/mes desde jun-2026)
85
+ // cooldown > 1h → DAILY (Claude Pro daily, OpenAI rate-limit-by-day)
86
+ // cooldown <= 1h → SHORT (rate limit transitorio)
87
+ if (RATE_LIMIT_PATTERNS.test(combined)) {
88
+ const msg = pickMessage(combined, RATE_LIMIT_PATTERNS);
89
+ const { cooldownUntil, cooldownMs } = parseCooldown(msg) ?? {};
90
+ let quotaClass;
91
+ if (cooldownMs != null && cooldownMs > ONE_WEEK_MS) quotaClass = ERROR_CLASS.QUOTA_EXHAUSTED_MONTHLY;
92
+ else if (cooldownMs != null && cooldownMs > ONE_HOUR_MS) quotaClass = ERROR_CLASS.QUOTA_EXHAUSTED_DAILY;
93
+ else quotaClass = ERROR_CLASS.RATE_LIMIT_SHORT;
94
+ return {
95
+ ...base,
96
+ class: quotaClass,
97
+ message: msg,
98
+ retryAfter: cooldownMs ?? null,
99
+ retryUntil: cooldownUntil ?? null,
100
+ recoverable: true,
101
+ };
102
+ }
103
+
104
+ // 4. NETWORK errors antes que API_DOWN — ECONN* es a nivel socket, no respuesta HTTP.
105
+ if (NETWORK_PATTERNS.test(combined)) {
106
+ return { ...base, class: ERROR_CLASS.NETWORK_TIMEOUT, message: pickMessage(combined, NETWORK_PATTERNS), recoverable: true };
107
+ }
108
+
109
+ // 5. API_DOWN: 5xx, overloaded.
110
+ if (API_DOWN_PATTERNS.test(combined)) {
111
+ return { ...base, class: ERROR_CLASS.API_DOWN, message: pickMessage(combined, API_DOWN_PATTERNS), recoverable: true };
112
+ }
113
+
114
+ // 6. UNKNOWN_FATAL: salida no clasificada con exitCode != 0.
115
+ return { ...base, class: ERROR_CLASS.UNKNOWN_FATAL, message: combined.trim().slice(0, 300) || `exit ${exitCode}`, recoverable: false };
116
+ }
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Tracks every routing decision the Brain makes during a session and enforces
3
+ * safety limits (max decisions per session, indecision-loop detection).
4
+ *
5
+ * Decisions are appended to `session.brainDecisions`. Consumers call
6
+ * `recordDecision(tracker, decision, context)` after a buildDecision() call
7
+ * and `checkLimits(tracker)` before making another decision.
8
+ *
9
+ * The limits are soft guards, not hard failures: hitting a limit surfaces
10
+ * a status that the orchestrator can use to escalate to Solomon or pause
11
+ * the session for human input.
12
+ */
13
+
14
+ import { setBrainDecisions } from "../session/mutators.js";
15
+
16
+ export const DEFAULT_MAX_DECISIONS = 20;
17
+ export const INDECISION_REPEAT_THRESHOLD = 3; // 3 identical classifications in a row
18
+
19
+ /**
20
+ * @typedef {Object} RecordedDecision
21
+ * @property {number} seq
22
+ * @property {string} at - ISO timestamp
23
+ * @property {string} intent - e.g. "sw:medium" (taskType:level)
24
+ * @property {string[]} rolesOn
25
+ * @property {"low"|"medium"|"high"} confidence
26
+ * @property {string} rationale
27
+ * @property {string[]} appliedOverrides
28
+ */
29
+
30
+ /**
31
+ * @typedef {Object} TrackerStatus
32
+ * @property {"ok"|"max-reached"|"indecision"} status
33
+ * @property {number} decisionCount
34
+ * @property {string} [detail]
35
+ */
36
+
37
+ /**
38
+ * Initialize a tracker bound to a session. If the session already has a
39
+ * `brainDecisions` array (e.g. from a resumed session), keep it.
40
+ *
41
+ * @param {Object} session
42
+ * @param {{ max?: number }} [options]
43
+ * @returns {{ session: Object, max: number }}
44
+ */
45
+ export function createTracker(session, { max = DEFAULT_MAX_DECISIONS } = {}) {
46
+ if (!Array.isArray(session.brainDecisions)) {
47
+ setBrainDecisions(session, []);
48
+ }
49
+ return { session, max };
50
+ }
51
+
52
+ /**
53
+ * Append a decision to the tracker.
54
+ *
55
+ * @param {{ session: Object, max: number }} tracker
56
+ * @param {Object} decision - output of buildDecision()
57
+ * @param {{ taskType?: string, level?: string }} intent
58
+ * @returns {RecordedDecision}
59
+ */
60
+ export function recordDecision(tracker, decision, intent = {}) {
61
+ const seq = tracker.session.brainDecisions.length + 1;
62
+ const entry = {
63
+ seq,
64
+ at: new Date().toISOString(),
65
+ intent: `${intent.taskType || "?"}:${intent.level || "?"}`,
66
+ rolesOn: Array.isArray(decision.rolesOn) ? [...decision.rolesOn] : [],
67
+ confidence: decision.confidence || "medium",
68
+ rationale: decision.rationale || "",
69
+ appliedOverrides: Array.isArray(decision.appliedOverrides) ? [...decision.appliedOverrides] : [],
70
+ };
71
+ tracker.session.brainDecisions.push(entry);
72
+ return entry;
73
+ }
74
+
75
+ /**
76
+ * Compute status of the tracker. Called BEFORE recording a new decision so
77
+ * the orchestrator can decide to escalate instead of calling the Brain again.
78
+ *
79
+ * @param {{ session: Object, max: number }} tracker
80
+ * @returns {TrackerStatus}
81
+ */
82
+ export function checkLimits(tracker) {
83
+ const decisions = tracker.session.brainDecisions || [];
84
+ const decisionCount = decisions.length;
85
+
86
+ if (decisionCount >= tracker.max) {
87
+ return {
88
+ status: "max-reached",
89
+ decisionCount,
90
+ detail: `Brain made ${decisionCount} decisions (limit ${tracker.max}). Escalate to Solomon or human.`,
91
+ };
92
+ }
93
+
94
+ // Indecision loop: last N decisions share the exact same intent.
95
+ const window = decisions.slice(-INDECISION_REPEAT_THRESHOLD);
96
+ if (window.length >= INDECISION_REPEAT_THRESHOLD && window.every((d) => d.intent === window[0].intent)) {
97
+ return {
98
+ status: "indecision",
99
+ decisionCount,
100
+ detail: `Brain classified the same intent (${window[0].intent}) ${INDECISION_REPEAT_THRESHOLD} times in a row — loop detected.`,
101
+ };
102
+ }
103
+
104
+ return { status: "ok", decisionCount };
105
+ }
106
+
107
+ /**
108
+ * Build a short summary of all decisions made in the session. Useful for the
109
+ * final report and for debugging.
110
+ *
111
+ * @param {{ session: Object }} tracker
112
+ * @returns {{ total: number, byIntent: Record<string,number>, lastRationale: string }}
113
+ */
114
+ export function summarize(tracker) {
115
+ const decisions = tracker.session.brainDecisions || [];
116
+ const byIntent = {};
117
+ for (const d of decisions) {
118
+ byIntent[d.intent] = (byIntent[d.intent] || 0) + 1;
119
+ }
120
+ return {
121
+ total: decisions.length,
122
+ byIntent,
123
+ lastRationale: decisions.at(-1)?.rationale ?? "",
124
+ };
125
+ }