@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,72 @@
1
+ /**
2
+ * Mutation runner + report normalizer. Executes a mutation tool and parses its
3
+ * report (the shared mutation-testing-report-schema, `files[].mutants[]`) into a
4
+ * tool-agnostic result the CLI, reviewer and CI can all consume the same way.
5
+ * `exec` and `readReport` are injectable so the logic is testable without a
6
+ * real mutation tool installed.
7
+ */
8
+
9
+ import { runCommand } from "../utils/process.js";
10
+
11
+ // A mutant the test suite detected (killed or forced to time out).
12
+ const KILLED = new Set(["Killed", "Timeout"]);
13
+ // A real survivor: the mutation went undetected (or no test covered it).
14
+ const SURVIVED = new Set(["Survived", "NoCoverage"]);
15
+ // Not a real result: equivalent, config-ignored, or uncompilable mutants.
16
+ const EXCLUDED = new Set(["Ignored", "CompileError", "RuntimeError"]);
17
+
18
+ /**
19
+ * Normalize a standard-schema report into `{score, killed, survived, total, excluded}`.
20
+ * `score` is the covered mutation score `killed / (killed + survived) * 100`, or
21
+ * null when there is nothing to mutate. Excluded mutants never count as survivors.
22
+ * @param {{files?: Record<string, {mutants?: Array<object>}>}} report
23
+ */
24
+ export function parseStandardReport(report) {
25
+ const files = report?.files ?? {};
26
+ let killed = 0;
27
+ let excluded = 0;
28
+ const survived = [];
29
+ for (const [file, entry] of Object.entries(files)) {
30
+ for (const mutant of entry?.mutants ?? []) {
31
+ const { status } = mutant;
32
+ if (EXCLUDED.has(status)) {
33
+ excluded += 1;
34
+ } else if (KILLED.has(status)) {
35
+ killed += 1;
36
+ } else if (SURVIVED.has(status)) {
37
+ survived.push({
38
+ file,
39
+ line: mutant.location?.start?.line ?? null,
40
+ mutator: mutant.mutatorName ?? null,
41
+ status,
42
+ });
43
+ }
44
+ }
45
+ }
46
+ const total = killed + survived.length;
47
+ const score = total === 0 ? null : Number(((killed / total) * 100).toFixed(2));
48
+ return { score, killed, survived, total, excluded };
49
+ }
50
+
51
+ /**
52
+ * Run a mutation tool and normalize the report it produced.
53
+ * @param {object} params
54
+ * @param {string} params.binary
55
+ * @param {string[]} [params.args]
56
+ * @param {string} [params.cwd]
57
+ * @param {Function} [params.exec] - injectable command runner (default runCommand)
58
+ * @param {() => Promise<object>} [params.readReport] - reads/parses the tool's report file
59
+ */
60
+ export async function runMutation({ binary, args = [], cwd, exec = runCommand, readReport }) {
61
+ const run = await exec(binary, args, { cwd }).catch((err) => ({
62
+ exitCode: 1,
63
+ stdout: "",
64
+ stderr: String(err?.message ?? err),
65
+ }));
66
+ let result = null;
67
+ if (readReport) {
68
+ const report = await readReport().catch(() => null);
69
+ if (report) result = parseStandardReport(report);
70
+ }
71
+ return { exitCode: run.exitCode, result, stdout: run.stdout, stderr: run.stderr };
72
+ }
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Mutation-tool registry.
3
+ *
4
+ * Maps a detected stack language (see `src/harden/stack-roots.js`) to the
5
+ * mutation-testing runner Karajan drives for it. Unknown or native-mobile
6
+ * languages resolve to an explicit `{ supported: false, reason }` object —
7
+ * never a silent fallback to another tool.
8
+ *
9
+ * `scope` describes how the runner limits mutation to a subset of files, so
10
+ * diff-scoped runs (`kj mutate --since <ref>`) can pass only the changed paths:
11
+ * - flag: the CLI flag that accepts the file list
12
+ * - separator: how multiple paths are joined for that flag
13
+ */
14
+
15
+ const TOOLS_BY_LANGUAGE = {
16
+ javascript: {
17
+ id: "stryker",
18
+ binary: "stryker",
19
+ installHint: "npm install --save-dev @stryker-mutator/core",
20
+ scope: { flag: "--mutate", separator: "," },
21
+ reportFormat: "json",
22
+ },
23
+ typescript: {
24
+ id: "stryker",
25
+ binary: "stryker",
26
+ installHint: "npm install --save-dev @stryker-mutator/core",
27
+ scope: { flag: "--mutate", separator: "," },
28
+ reportFormat: "json",
29
+ },
30
+ python: {
31
+ id: "mutmut",
32
+ binary: "mutmut",
33
+ installHint: "pip install mutmut",
34
+ scope: { flag: "--paths-to-mutate", separator: "," },
35
+ reportFormat: "json",
36
+ },
37
+ php: {
38
+ id: "infection",
39
+ binary: "infection",
40
+ installHint: "composer require --dev infection/infection",
41
+ scope: { flag: "--filter", separator: "," },
42
+ reportFormat: "json",
43
+ },
44
+ go: {
45
+ id: "go-mutesting",
46
+ binary: "go-mutesting",
47
+ installHint: "go install github.com/avito-tech/go-mutesting/cmd/go-mutesting@latest",
48
+ scope: { flag: "", separator: " " },
49
+ reportFormat: "json",
50
+ },
51
+ java: {
52
+ id: "pitest",
53
+ binary: "pitest",
54
+ installHint: "add org.pitest:pitest-maven (Maven) or gradle-pitest-plugin",
55
+ scope: { flag: "targetClasses", separator: "," },
56
+ reportFormat: "json",
57
+ },
58
+ };
59
+
60
+ const UNSUPPORTED_REASONS = {
61
+ swift: "Swift (iOS) has no mutation runner wired into Karajan",
62
+ kotlin: "Kotlin (Android) has no mutation runner wired into Karajan",
63
+ };
64
+
65
+ function normalize(language) {
66
+ if (typeof language !== "string") return "";
67
+ return language.trim().toLowerCase();
68
+ }
69
+
70
+ /**
71
+ * @param {string} language - language id from `detectStackRoots`
72
+ * @returns {{supported: true, id, binary, language, installHint, scope, reportFormat}
73
+ * | {supported: false, language, reason: string}}
74
+ */
75
+ export function getMutationTool(language) {
76
+ const key = normalize(language);
77
+ const tool = TOOLS_BY_LANGUAGE[key];
78
+ if (tool) {
79
+ return { supported: true, language: key, ...tool };
80
+ }
81
+ const reason =
82
+ UNSUPPORTED_REASONS[key] ??
83
+ `no mutation-testing tool is registered for language "${key || "(none)"}"`;
84
+ return { supported: false, language: key, reason };
85
+ }
86
+
87
+ /** @returns {string[]} languages with a registered mutation tool */
88
+ export function listSupportedLanguages() {
89
+ return Object.keys(TOOLS_BY_LANGUAGE);
90
+ }
@@ -0,0 +1,24 @@
1
+ // KJC-TSK-0384 PR 3 — read the cached Architecture Brief deterministically.
2
+ // briefPath() is exported by src/commands/onboard.js so the writer and
3
+ // reader share the same slug rule.
4
+ import { existsSync } from "node:fs";
5
+ import { readFile } from "node:fs/promises";
6
+
7
+ import { briefPath } from "../commands/onboard.js";
8
+
9
+ /**
10
+ * Read the cached Architecture Brief for `projectDir`. Returns:
11
+ * { found: true, path, content } — when the file exists
12
+ * { found: false, path } — when it does not
13
+ * Never throws.
14
+ */
15
+ export async function readCachedBrief(projectDir) {
16
+ const p = briefPath(projectDir);
17
+ if (!existsSync(p)) return { found: false, path: p };
18
+ try {
19
+ const content = await readFile(p, "utf8");
20
+ return { found: true, path: p, content };
21
+ } catch {
22
+ return { found: false, path: p };
23
+ }
24
+ }
@@ -0,0 +1,64 @@
1
+ // KJC-TSK-0477 — Detectores mínimos de framework por stack (Python/Rust/Go).
2
+ // Consume el sniff de manifests (PR-C) para conocer deps + presencia de
3
+ // archivos canónicos. Cero deps externas, fail-soft (devuelve null o lista
4
+ // vacía). El brief markdown se sintetiza río abajo desde estos campos.
5
+ import { existsSync } from "node:fs";
6
+ import path from "node:path";
7
+
8
+ const PY_FW = [
9
+ { name: "django", deps: ["django"], file: "manage.py" },
10
+ { name: "flask", deps: ["flask"], file: "app.py" },
11
+ { name: "fastapi", deps: ["fastapi"], file: "main.py" },
12
+ ];
13
+ const RUST_FW = [
14
+ { name: "axum", deps: ["axum"] },
15
+ { name: "actix-web", deps: ["actix-web"] },
16
+ { name: "rocket", deps: ["rocket"] },
17
+ ];
18
+ const GO_FW = [
19
+ { name: "gin", deps: ["github.com/gin-gonic/gin"] },
20
+ { name: "echo", deps: ["github.com/labstack/echo"] },
21
+ { name: "fiber", deps: ["github.com/gofiber/fiber"] },
22
+ ];
23
+
24
+ function matchFw(manifestRaw, projectDir, table) {
25
+ const found = [];
26
+ for (const fw of table) {
27
+ const hasDep = fw.deps.some((d) => manifestRaw?.includes(d));
28
+ const hasFile = fw.file ? existsSync(path.join(projectDir, fw.file)) : false;
29
+ if (hasDep || hasFile) found.push({ name: fw.name, viaDep: hasDep, viaFile: hasFile });
30
+ }
31
+ return found;
32
+ }
33
+
34
+ function detectLayout(projectDir, expected) {
35
+ return expected.filter((d) => existsSync(path.join(projectDir, d)));
36
+ }
37
+
38
+ // Detect frameworks + canonical layout per stack. Returns one entry per
39
+ // detected manifest stack (skips Node — the existing JS path already covers
40
+ // that with detectProjectStack).
41
+ export function detectFrameworksMultiLang(projectDir, manifests = [], { readManifest } = {}) {
42
+ const out = [];
43
+ for (const m of manifests) {
44
+ if (m.stack === "node") continue;
45
+ const raw = readManifest ? readManifest(m) : "";
46
+ if (m.stack === "python") {
47
+ out.push({ stack: "python", manifest: m.manifest,
48
+ frameworks: matchFw(raw, projectDir, PY_FW),
49
+ layout: detectLayout(projectDir, ["apps", "src", "tests"]) });
50
+ } else if (m.stack === "rust") {
51
+ const isBin = existsSync(path.join(projectDir, "src", "main.rs"));
52
+ const isLib = existsSync(path.join(projectDir, "src", "lib.rs"));
53
+ out.push({ stack: "rust", manifest: m.manifest,
54
+ crateType: isBin && isLib ? "mixed" : isBin ? "binary" : isLib ? "library" : null,
55
+ frameworks: matchFw(raw, projectDir, RUST_FW),
56
+ layout: detectLayout(projectDir, ["src", "tests", "examples", "benches"]) });
57
+ } else if (m.stack === "go") {
58
+ out.push({ stack: "go", manifest: m.manifest, modulePath: m.name || null,
59
+ frameworks: matchFw(raw, projectDir, GO_FW),
60
+ layout: detectLayout(projectDir, ["cmd", "internal", "pkg"]) });
61
+ }
62
+ }
63
+ return out;
64
+ }
@@ -0,0 +1,136 @@
1
+ // Onboarder collectors — deterministic, zero-LLM extractors. Each pure,
2
+ // JSON-serialisable, fail-soft (returns null on the slot, never throws).
3
+ // Output bundle is consumed by PR 2 synthesis or dumped via `--no-synth`.
4
+ import { execFileSync } from "node:child_process";
5
+ import { existsSync, readFileSync, statSync } from "node:fs";
6
+ import { readdir } from "node:fs/promises";
7
+ import { join, relative } from "node:path";
8
+
9
+ import { detectProjectStack } from "../../utils/stack-detect.js";
10
+ import { sniffManifests } from "../../utils/manifest-sniff.js";
11
+ import { detectFrameworksMultiLang } from "./framework-multilang.js";
12
+
13
+ const IGNORED_DIRS = new Set(["node_modules", ".git", "dist", "build", "coverage", ".karajan", ".next", "__pycache__"]);
14
+
15
+ function safeRun(cmd, args, opts = {}) {
16
+ try { return execFileSync(cmd, args, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], ...opts }).trim(); }
17
+ catch { return null; }
18
+ }
19
+
20
+ // Tree summary: immediate dirs with rough byte count. Ignores noise dirs.
21
+ export async function collectTree(projectDir, { maxDepth = 2 } = {}) {
22
+ async function walk(dir, depth) {
23
+ if (depth > maxDepth) return [];
24
+ let entries;
25
+ try { entries = await readdir(dir, { withFileTypes: true }); } catch { return []; }
26
+ const out = [];
27
+ for (const ent of entries) {
28
+ if (ent.name.startsWith(".") && ent.name !== ".github") continue;
29
+ if (IGNORED_DIRS.has(ent.name)) continue;
30
+ const sub = join(dir, ent.name);
31
+ if (ent.isDirectory()) {
32
+ const children = await walk(sub, depth + 1);
33
+ let bytes = 0;
34
+ for (const c of children) bytes += c.bytes || 0;
35
+ out.push({ path: relative(projectDir, sub), kind: "dir", bytes, children });
36
+ } else if (ent.isFile()) {
37
+ try { out.push({ path: relative(projectDir, sub), kind: "file", bytes: statSync(sub).size }); } catch { /* race */ }
38
+ }
39
+ }
40
+ return out;
41
+ }
42
+ return walk(projectDir, 0);
43
+ }
44
+
45
+ // Git log + branches + hot files. Returns null on non-git (greenfield).
46
+ export function collectGitHistory(projectDir, { maxHotFiles = 10 } = {}) {
47
+ const inside = safeRun("git", ["rev-parse", "--is-inside-work-tree"], { cwd: projectDir });
48
+ if (inside !== "true") return null;
49
+ const commitsRaw = safeRun("git", ["log", "--oneline", "-n", "100"], { cwd: projectDir }) || "";
50
+ const branchesRaw = safeRun("git", ["branch", "--list", "--all", "--format=%(refname:short)"], { cwd: projectDir }) || "";
51
+ const hotRaw = safeRun("git", ["log", "--name-only", "--pretty=format:", "-n", "200"], { cwd: projectDir }) || "";
52
+ const counts = {};
53
+ for (const line of hotRaw.split("\n").map((s) => s.trim()).filter(Boolean)) {
54
+ counts[line] = (counts[line] || 0) + 1;
55
+ }
56
+ const hotFiles = Object.entries(counts)
57
+ .sort((a, b) => b[1] - a[1]).slice(0, maxHotFiles)
58
+ .map(([file, touches]) => ({ file, touches }));
59
+ return {
60
+ commitCount: commitsRaw ? commitsRaw.split("\n").length : 0,
61
+ branches: branchesRaw.split("\n").filter(Boolean),
62
+ hotFiles,
63
+ headSha: safeRun("git", ["rev-parse", "HEAD"], { cwd: projectDir }) || null,
64
+ };
65
+ }
66
+
67
+ // Presence-check of known config files + package.json scripts.
68
+ export function collectConfigs(projectDir) {
69
+ const configFiles = [
70
+ "package.json", "pyproject.toml", "Cargo.toml", "go.mod",
71
+ "tsconfig.json", "jsconfig.json",
72
+ ".eslintrc.js", ".eslintrc.json", "eslint.config.js",
73
+ "vitest.config.js", "vitest.config.ts", "jest.config.js", "jest.config.ts",
74
+ "firebase.json", ".gcloudignore", "Dockerfile", "docker-compose.yml",
75
+ ".github/workflows", ".gitlab-ci.yml", "Makefile",
76
+ ];
77
+ const present = configFiles.filter((f) => existsSync(join(projectDir, f)));
78
+ let scripts = null;
79
+ try {
80
+ const pkg = JSON.parse(readFileSync(join(projectDir, "package.json"), "utf8"));
81
+ scripts = pkg.scripts || null;
82
+ } catch { /* not a node project */ }
83
+ return { present, scripts };
84
+ }
85
+
86
+ // Discover ADR files under docs/adr/, docs/adrs/, docs/architecture/, root.
87
+ export async function collectAdrs(projectDir) {
88
+ const dirs = ["docs/adr", "docs/adrs", "docs/architecture", "."];
89
+ const found = [];
90
+ for (const d of dirs) {
91
+ const abs = join(projectDir, d);
92
+ if (!existsSync(abs)) continue;
93
+ try {
94
+ const entries = await readdir(abs);
95
+ for (const f of entries) {
96
+ if (/^adr-?\d|^\d{4}-.+\.md$/i.test(f) || /architecture.*\.md$/i.test(f)) {
97
+ found.push(relative(projectDir, join(abs, f)));
98
+ }
99
+ }
100
+ } catch { /* unreadable */ }
101
+ }
102
+ return found;
103
+ }
104
+
105
+ // Read a manifest file as raw text (best-effort) for framework dep matching.
106
+ function readManifestRaw(projectDir) {
107
+ return (m) => {
108
+ try { return readFileSync(join(projectDir, m.manifest), "utf8"); }
109
+ catch { return ""; }
110
+ };
111
+ }
112
+
113
+ // One-shot bundle: every slot is independent; missing slots → null/[].
114
+ // KJC-TSK-0477: manifests (multi-stack) + frameworksMultiLang (Python/Rust/Go)
115
+ // se añaden de forma aditiva para que el brief pueda incluir secciones
116
+ // condicionales sin romper consumidores existentes.
117
+ export async function collectAll(projectDir) {
118
+ const [stack, tree, adrs, manifests] = await Promise.all([
119
+ detectProjectStack(projectDir).catch(() => null),
120
+ collectTree(projectDir).catch(() => []),
121
+ collectAdrs(projectDir).catch(() => []),
122
+ sniffManifests(projectDir).catch(() => []),
123
+ ]);
124
+ const frameworksMultiLang = detectFrameworksMultiLang(projectDir, manifests, { readManifest: readManifestRaw(projectDir) });
125
+ return {
126
+ projectDir,
127
+ stack,
128
+ manifests,
129
+ frameworksMultiLang,
130
+ tree,
131
+ git: collectGitHistory(projectDir),
132
+ configs: collectConfigs(projectDir),
133
+ adrs,
134
+ collectedAt: new Date().toISOString(),
135
+ };
136
+ }
@@ -0,0 +1,81 @@
1
+ import { createAgent } from "../agents/index.js";
2
+ import { addCheckpoint } from "../session/store.js";
3
+ import { detectRateLimit } from "../utils/rate-limit-detector.js";
4
+
5
+ /**
6
+ * Run a coder-like role with fallback on rate limit.
7
+ * Tries the primary agent first. If it fails with a rate limit,
8
+ * switches to the fallback agent (if configured).
9
+ * Non-rate-limit failures stop immediately (no fallback).
10
+ *
11
+ * Returns { execResult, attempts, allRateLimited }
12
+ */
13
+ export async function runCoderWithFallback({
14
+ coderName,
15
+ fallbackCoder,
16
+ config,
17
+ logger,
18
+ emitter,
19
+ RoleClass,
20
+ roleInput,
21
+ session,
22
+ iteration,
23
+ onAttemptResult
24
+ }) {
25
+ const candidates = [coderName];
26
+ if (fallbackCoder && fallbackCoder !== coderName) {
27
+ candidates.push(fallbackCoder);
28
+ }
29
+
30
+ const attempts = [];
31
+
32
+ for (const name of candidates) {
33
+ const agentConfig = {
34
+ ...config,
35
+ roles: { ...config.roles, coder: { ...config.roles?.coder, provider: name } }
36
+ };
37
+
38
+ const role = new RoleClass({ config: agentConfig, logger, emitter, createAgentFn: createAgent });
39
+ await role.init();
40
+
41
+ const execResult = await role.execute(roleInput);
42
+
43
+ if (onAttemptResult) {
44
+ await onAttemptResult({ coder: name, result: execResult.result });
45
+ }
46
+
47
+ const rateLimited = !execResult.ok && detectRateLimit({
48
+ stderr: execResult.result?.error || "",
49
+ stdout: execResult.result?.output || ""
50
+ }).isRateLimit;
51
+
52
+ attempts.push({
53
+ coder: name,
54
+ ok: execResult.ok,
55
+ rateLimited,
56
+ result: execResult.result,
57
+ execResult
58
+ });
59
+
60
+ await addCheckpoint(session, {
61
+ stage: "coder-attempt",
62
+ iteration,
63
+ coder: name,
64
+ ok: execResult.ok,
65
+ rateLimited
66
+ });
67
+
68
+ if (execResult.ok) {
69
+ return { execResult, attempts, allRateLimited: false };
70
+ }
71
+
72
+ // Only fallback on rate limit errors
73
+ if (!rateLimited) {
74
+ return { execResult: null, attempts, allRateLimited: false };
75
+ }
76
+
77
+ logger.warn(`Agent ${name} hit rate limit, trying fallback...`);
78
+ }
79
+
80
+ return { execResult: null, attempts, allRateLimited: true };
81
+ }
@@ -0,0 +1,186 @@
1
+ // Brain Coordinator: integrates Karajan Brain + 5 support modules into the pipeline.
2
+ // Replaces ad-hoc role-to-role communication with a central intelligence.
3
+
4
+ import * as queue from "./feedback-queue.js";
5
+ import * as enrich from "./feedback-enrichment.js";
6
+ import { verifyCoderOutput, VerificationTracker } from "./verification-gate.js";
7
+ import { executeActions } from "./direct-actions.js";
8
+ import { compressRoleOutput, measureCompression } from "./role-output-compressor.js";
9
+
10
+ /**
11
+ * @typedef {Object} BrainContext
12
+ * @property {Object} feedbackQueue - structured feedback queue
13
+ * @property {VerificationTracker} verificationTracker - tracks coder changes
14
+ * @property {Object} compressionStats - token savings per role
15
+ * @property {boolean} enabled - whether brain coordination is active
16
+ */
17
+
18
+ /**
19
+ * Create a new brain context for a pipeline session.
20
+ */
21
+ export function createBrainContext({ enabled = false } = {}) {
22
+ return {
23
+ feedbackQueue: queue.createQueue(),
24
+ verificationTracker: new VerificationTracker(),
25
+ compressionStats: { totalSaved: 0, perRole: {} },
26
+ extensionCount: 0,
27
+ enabled
28
+ };
29
+ }
30
+
31
+ /**
32
+ * Check if brain coordination is enabled for this config.
33
+ */
34
+ export function isBrainEnabled(config) {
35
+ return Boolean(config?.brain?.enabled) || Boolean(config?.pipeline?.brain?.enabled);
36
+ }
37
+
38
+ /**
39
+ * After a role completes, push its feedback to the queue and compress.
40
+ * Returns the compressed output for passing to next role.
41
+ */
42
+ export function processRoleOutput(ctx, { roleName, output, iteration }) {
43
+ if (!ctx.enabled) return output;
44
+
45
+ // Compress for next-role context
46
+ const compressed = compressRoleOutput(roleName, output);
47
+ const stats = measureCompression(output, compressed);
48
+ ctx.compressionStats.totalSaved += stats.savedTokens;
49
+ ctx.compressionStats.perRole[roleName] = stats;
50
+
51
+ // Extract feedback entries from specific role outputs
52
+ const entries = extractFeedbackEntries(roleName, output, iteration);
53
+ if (entries.length > 0) {
54
+ queue.addEntries(ctx.feedbackQueue, entries);
55
+ enrich.enrichQueue(ctx.feedbackQueue);
56
+ queue.deduplicate(ctx.feedbackQueue);
57
+ queue.prioritize(ctx.feedbackQueue);
58
+ }
59
+
60
+ return compressed;
61
+ }
62
+
63
+ /**
64
+ * Extract structured feedback entries from a role's output.
65
+ */
66
+ function extractFeedbackEntries(roleName, output, iteration) {
67
+ if (!output || typeof output !== "object") return [];
68
+
69
+ const entries = [];
70
+ if (roleName === "reviewer" && output.blocking_issues) {
71
+ for (const issue of output.blocking_issues) {
72
+ entries.push({
73
+ source: "reviewer",
74
+ severity: issue.severity || "medium",
75
+ description: issue.description || "",
76
+ file: issue.file || null,
77
+ line: issue.line || null,
78
+ suggestedFix: issue.suggested_fix || null,
79
+ id: issue.id || null,
80
+ iteration
81
+ });
82
+ }
83
+ } else if (roleName === "tester" && output.verdict === "fail") {
84
+ const missing = output.missing_scenarios || [];
85
+ for (const scenario of missing) {
86
+ entries.push({
87
+ source: "tester",
88
+ severity: "high",
89
+ category: "tests",
90
+ description: `Missing scenario: ${scenario}`,
91
+ iteration
92
+ });
93
+ }
94
+ if (output.coverage?.overall != null && output.coverage.overall < 80) {
95
+ entries.push({
96
+ source: "tester",
97
+ severity: "high",
98
+ category: "tests",
99
+ description: `Coverage below 80% (${output.coverage.overall}%)`,
100
+ iteration
101
+ });
102
+ }
103
+ // Catch-all: tester failed but no structured detail → still record the failure
104
+ if (entries.length === 0) {
105
+ entries.push({
106
+ source: "tester",
107
+ severity: "high",
108
+ category: "tests",
109
+ description: output.summary || "Tester failed (no structured detail available)",
110
+ iteration
111
+ });
112
+ }
113
+ } else if (roleName === "security" && output.verdict === "fail") {
114
+ for (const vuln of output.vulnerabilities || []) {
115
+ entries.push({
116
+ source: "security",
117
+ severity: vuln.severity || "high",
118
+ category: "security",
119
+ description: vuln.description || "",
120
+ file: vuln.file || null,
121
+ line: vuln.line || null,
122
+ suggestedFix: vuln.fix_suggestion || null,
123
+ iteration
124
+ });
125
+ }
126
+ // Catch-all: security failed but no structured vulnerabilities → still record
127
+ if (entries.length === 0) {
128
+ entries.push({
129
+ source: "security",
130
+ severity: "high",
131
+ category: "security",
132
+ description: output.summary || "Security gate failed (no structured detail available)",
133
+ iteration
134
+ });
135
+ }
136
+ }
137
+ return entries;
138
+ }
139
+
140
+ /**
141
+ * Before coder runs, format the feedback queue as an actionable prompt.
142
+ */
143
+ export function buildCoderFeedbackPrompt(ctx) {
144
+ if (!ctx.enabled || ctx.feedbackQueue.entries.length === 0) return null;
145
+ return enrich.formatEnrichedForCoder(ctx.feedbackQueue.entries);
146
+ }
147
+
148
+ /**
149
+ * After coder runs, verify changes were made. Returns verification result.
150
+ */
151
+ export function verifyCoderRan(ctx, { baseRef, projectDir }) {
152
+ if (!ctx.enabled) return { passed: true, filesChanged: 0, reason: "brain disabled" };
153
+ const result = verifyCoderOutput({ baseRef, projectDir });
154
+ ctx.verificationTracker.record(result);
155
+ return result;
156
+ }
157
+
158
+ /**
159
+ * Execute direct actions (npm install, gitignore updates, etc.).
160
+ */
161
+ export async function runDirectActions(ctx, actions, { cwd } = {}) {
162
+ if (!ctx.enabled || !actions?.length) return [];
163
+ return executeActions(actions, { cwd });
164
+ }
165
+
166
+ /**
167
+ * Clear feedback queue after coder addresses it.
168
+ */
169
+ export function clearFeedback(ctx) {
170
+ if (!ctx.enabled) return;
171
+ queue.clear(ctx.feedbackQueue);
172
+ }
173
+
174
+ /**
175
+ * Get a summary of brain activity for the session.
176
+ */
177
+ export function summarize(ctx) {
178
+ if (!ctx.enabled) return null;
179
+ return {
180
+ feedbackQueueSize: ctx.feedbackQueue.entries.length,
181
+ queueCategories: queue.countByCategory(ctx.feedbackQueue),
182
+ consecutiveVerificationFailures: ctx.verificationTracker.consecutiveFailures,
183
+ compressionSaved: ctx.compressionStats.totalSaved,
184
+ compressionPerRole: ctx.compressionStats.perRole
185
+ };
186
+ }