@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,430 @@
1
+ import path from "node:path";
2
+ import fs from "node:fs/promises";
3
+ import readline from "node:readline";
4
+ import { execFile } from "node:child_process";
5
+ import { promisify } from "node:util";
6
+ import { assertAgentsAvailable, filterAvailableAgents } from "../agents/availability.js";
7
+ import { resolveRole } from "../config.js";
8
+ import { AUDIT_DIMENSIONS } from "../prompts/audit.js";
9
+ import { AuditRole } from "../roles/audit-role.js";
10
+ import { buildAuditFallbackCandidates, runAuditWithFallback } from "../audit/audit-fallback.js";
11
+ import { withCliRunLog } from "../utils/cli-run-log.js";
12
+ import { createCliProgressReporter } from "../utils/cli-progress.js";
13
+ import { runAgentReadiness, formatAgentReadinessReport } from "../audit/agent-readiness.js";
14
+ import { formatDeterministicSummary } from "../audit/deterministic-summary.js";
15
+ import { runHarnessSection, formatHarnessSection, harnessSummaryForJson } from "../audit/harness-section.js";
16
+ import { persistAuditRun, openAuditHistoryDb, getLatestPreviousRun, getRecentScores } from "../audit/audit-history.js";
17
+ import { computeHistoryDiff, formatHistoryDiff, formatTrendSparkline } from "../audit/audit-history-display.js";
18
+
19
+ const execFileAsync = promisify(execFile);
20
+
21
+ /**
22
+ * Prompt the user (TTY only) to decide whether to continue with the LLM
23
+ * phase after deterministic findings have been printed. KJC-TSK-0364.
24
+ *
25
+ * @returns {Promise<boolean>} true to continue with LLM, false to skip
26
+ */
27
+ function promptContinueWithLlm({ promptFn = null } = {}) {
28
+ if (typeof promptFn === "function") return promptFn();
29
+ return new Promise((resolve) => {
30
+ if (!process.stdin.isTTY) { resolve(true); return; } // CI / piped input → continue
31
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
32
+ rl.question("Continue with LLM analysis? [y/N] ", (answer) => {
33
+ rl.close();
34
+ resolve(/^y(es)?$/i.test((answer || "").trim()));
35
+ });
36
+ });
37
+ }
38
+
39
+ function formatFindings(findings) {
40
+ const lines = [];
41
+ for (const f of findings) {
42
+ const lineSuffix = f.line ? `:${f.line}` : "";
43
+ const loc = f.file ? `${f.file}${lineSuffix}` : "";
44
+ const rule = f.rule ? ` [${f.rule}]` : "";
45
+ lines.push(` - [${f.severity.toUpperCase()}] ${loc}${rule}`);
46
+ lines.push(` ${f.description}`);
47
+ if (f.recommendation) lines.push(` Fix: ${f.recommendation}`);
48
+ }
49
+ return lines;
50
+ }
51
+
52
+ function formatDimension(name, dim) {
53
+ const lines = [];
54
+ lines.push(`### ${name} — Score: ${dim.score}`);
55
+ if (dim.findings.length === 0) {
56
+ lines.push(" No issues found.");
57
+ } else {
58
+ lines.push(...formatFindings(dim.findings));
59
+ }
60
+ lines.push("");
61
+ return lines;
62
+ }
63
+
64
+ function formatRecommendations(recs) {
65
+ const lines = ["## Top Recommendations", ""];
66
+ for (const r of recs) {
67
+ lines.push(`${r.priority}. [${r.dimension}] ${r.action} (impact: ${r.impact}, effort: ${r.effort})`);
68
+ }
69
+ lines.push("");
70
+ return lines;
71
+ }
72
+
73
+ const DIMENSION_LABELS = {
74
+ security: "Security",
75
+ codeQuality: "Code Quality",
76
+ performance: "Performance",
77
+ architecture: "Architecture",
78
+ testing: "Testing",
79
+ accessibility: "Accessibility (WCAG 2.x)"
80
+ };
81
+
82
+ function formatAudit(parsed, usage = null) {
83
+ const lines = [];
84
+ lines.push("## Codebase Health Report");
85
+ lines.push(`**Overall Health:** ${parsed.summary.overallHealth}`);
86
+ lines.push(`**Total Findings:** ${parsed.summary.totalFindings} (${parsed.summary.critical} critical, ${parsed.summary.high} high, ${parsed.summary.medium} medium, ${parsed.summary.low} low)`);
87
+ lines.push("");
88
+
89
+ for (const dim of AUDIT_DIMENSIONS) {
90
+ if (parsed.dimensions[dim]) {
91
+ lines.push(...formatDimension(DIMENSION_LABELS[dim] || dim, parsed.dimensions[dim]));
92
+ }
93
+ }
94
+
95
+ if (parsed.topRecommendations?.length) {
96
+ lines.push(...formatRecommendations(parsed.topRecommendations));
97
+ }
98
+
99
+ if (parsed.textSummary) lines.push(`---\n${parsed.textSummary}`);
100
+
101
+ const usageBlock = formatUsageSummary(usage);
102
+ if (usageBlock) {
103
+ lines.push("");
104
+ lines.push(usageBlock);
105
+ }
106
+
107
+ return lines.join("\n");
108
+ }
109
+
110
+ /**
111
+ * Format the LLM token + cost summary that closes every audit report.
112
+ * KJC-TSK-0363: makes the LLM cost visible (was silently discarded
113
+ * pre-patch — auditCommand never read roleResult.usage).
114
+ *
115
+ * @param {object|null} usage - shape produced by AuditRole's extractUsage
116
+ * @returns {string|null} markdown block, or null when there's nothing useful to show
117
+ */
118
+ function formatUsageSummary(usage) {
119
+ if (!usage) return null;
120
+ const lines = ["## LLM Usage"];
121
+ const modelSuffix = usage.model ? ` (${usage.model})` : "";
122
+ lines.push(`- Provider: ${usage.provider}${modelSuffix}`);
123
+ if (typeof usage.durationMs === "number") {
124
+ lines.push(`- Duration: ${(usage.durationMs / 1000).toFixed(1)}s`);
125
+ }
126
+ if (!usage.available) {
127
+ lines.push(`- Tokens: usage data not available — ${usage.reason || "provider does not report it"}`);
128
+ return lines.join("\n");
129
+ }
130
+ // Force en-US locale so the comma grouping is deterministic across CI
131
+ // machines (Node's default Intl.NumberFormat depends on the runtime
132
+ // locale; without this the rendering would look like "1234" on
133
+ // locale-less Node and "1,234" on a US-locale workstation).
134
+ const fmt = (n) => n.toLocaleString("en-US");
135
+ lines.push(`- Tokens: ${fmt(usage.total_tokens)} total (${fmt(usage.tokens_in)} in, ${fmt(usage.tokens_out)} out)`);
136
+ if (typeof usage.cached_tokens === "number" && usage.cached_tokens > 0) {
137
+ lines.push(`- Cached tokens: ${fmt(usage.cached_tokens)} (prompt-cache hits)`);
138
+ }
139
+ if (typeof usage.cost_usd === "number") {
140
+ lines.push(`- Estimated cost: $${usage.cost_usd.toFixed(4)} USD`);
141
+ }
142
+ return lines.join("\n");
143
+ }
144
+
145
+ /**
146
+ * Resolve where to write the audit report on disk, given a flag value, an
147
+ * env override, and the desired format. Returns null if no write target
148
+ * was requested. Creates parent directories on demand.
149
+ *
150
+ * Resolution rules (KJC-TSK-0362):
151
+ * - flag undefined + no env → null (legacy behaviour, stdout only)
152
+ * - flag is a directory → write `audit-<ISO>.{md,json}` inside it
153
+ * - flag is a non-directory path → use it verbatim (extension drives format
154
+ * when --json/--md not explicit)
155
+ * - flag is undefined but env $KJ_AUDIT_REPORT_DIR is set → treat env as dir
156
+ */
157
+ async function resolveReportFilePath(flagValue, isJson) {
158
+ const envDir = process.env.KJ_AUDIT_REPORT_DIR;
159
+ const target = flagValue || (envDir ? envDir : null);
160
+ if (!target) return null;
161
+
162
+ const ext = isJson ? "json" : "md";
163
+ let stats = null;
164
+ try { stats = await fs.stat(target); } catch { /* not a directory yet */ }
165
+ const isDir = stats?.isDirectory() || target.endsWith(path.sep) || target === envDir;
166
+
167
+ let resolved;
168
+ if (isDir) {
169
+ const stamp = new Date().toISOString().replaceAll(/[:.]/g, "-");
170
+ resolved = path.resolve(target, `audit-${stamp}.${ext}`);
171
+ } else {
172
+ resolved = path.resolve(target);
173
+ }
174
+
175
+ await fs.mkdir(path.dirname(resolved), { recursive: true });
176
+ return resolved;
177
+ }
178
+
179
+ /**
180
+ * Build the markdown header that prefixes a persisted report — captures
181
+ * timestamp + repo state + invocation flags so the file is reproducible.
182
+ */
183
+ async function buildReportHeader(projectDir, invocation) {
184
+ const lines = ["# Karajan Audit Report", ""];
185
+ lines.push(`- **Generated:** ${new Date().toISOString()}`);
186
+ lines.push(`- **Project:** ${projectDir || process.cwd()}`);
187
+
188
+ // Best-effort git info — silent if outside a repo.
189
+ try {
190
+ const branch = (await execFileAsync("git", ["rev-parse", "--abbrev-ref", "HEAD"], { cwd: projectDir, timeout: 2000 })).stdout.trim();
191
+ const commit = (await execFileAsync("git", ["rev-parse", "--short", "HEAD"], { cwd: projectDir, timeout: 2000 })).stdout.trim();
192
+ lines.push(`- **Branch:** ${branch}`);
193
+ lines.push(`- **Commit:** ${commit}`);
194
+ } catch { /* not a git repo or git missing */ }
195
+
196
+ if (invocation) lines.push(`- **Invocation:** \`${invocation}\``);
197
+ lines.push("");
198
+ lines.push("---");
199
+ lines.push("");
200
+ return lines.join("\n");
201
+ }
202
+
203
+ function composeHistoryBlock({ diffMd, trendMd }) {
204
+ const parts = [];
205
+ if (diffMd) parts.push(diffMd);
206
+ if (trendMd) parts.push(trendMd);
207
+ return parts.length ? `\n\n## Harness Score History\n${parts.join("\n\n")}` : "";
208
+ }
209
+
210
+ // KJC-TSK-0473 — Resolve diff vs previous run + optional trend sparkline.
211
+ // Errors silenced: history is a nice-to-have; a broken db must not break audit.
212
+ function loadAuditHistoryContext(projectDir, currentHarness, { showTrend = false } = {}) {
213
+ let db;
214
+ try {
215
+ db = openAuditHistoryDb(projectDir);
216
+ if (!db) return { diff: null, diffMd: "", trendMd: "" };
217
+ const previous = currentHarness?.score != null ? getLatestPreviousRun(db, new Date().toISOString()) : null;
218
+ const diff = currentHarness?.score != null ? computeHistoryDiff(currentHarness, previous) : null;
219
+ const trendMd = showTrend ? formatTrendSparkline(getRecentScores(db, 10)) : "";
220
+ return { diff, diffMd: formatHistoryDiff(diff), trendMd };
221
+ } catch { return { diff: null, diffMd: "", trendMd: "" }; }
222
+ finally { try { db?.close(); } catch { /* noop */ } }
223
+ }
224
+
225
+ function describeInvocation({ task, dimensions, noSonar, noOsv, noSemgrep, noHarness, noAiSlop, json, deterministicOnly, yes }) {
226
+ const parts = ["kj audit"];
227
+ if (task && task !== "Analyze the full codebase") parts.push(JSON.stringify(task));
228
+ if (dimensions && dimensions !== "all") parts.push(`--dimensions=${dimensions}`);
229
+ if (noSonar) parts.push("--no-sonar");
230
+ if (noOsv) parts.push("--no-osv");
231
+ if (noSemgrep) parts.push("--no-semgrep");
232
+ if (noHarness) parts.push("--no-harness");
233
+ if (noAiSlop) parts.push("--no-ai-slop");
234
+ if (deterministicOnly) parts.push("--deterministic-only");
235
+ if (yes) parts.push("--yes");
236
+ if (json) parts.push("--json");
237
+ return parts.join(" ");
238
+ }
239
+
240
+ export async function auditCommand({ task, config, logger, dimensions, json, agentReadiness, path: pathArg, noSonar = false, noOsv = false, noSemgrep = false, noHarness = false, noAiSlop = false, reportFile = null, deterministicOnly = false, yes = false, trend = false, promptFn = null, security = false }) {
241
+ // KJC-TSK-0695: --security = the focused pass an agent self-invokes.
242
+ // Deterministic by definition (zero tokens) and skips non-security stages.
243
+ if (security) { deterministicOnly = true; noHarness = true; noAiSlop = true; }
244
+ // --agent-readiness is a STANDALONE, deterministic, LLM-free audit
245
+ // dimension. It scores any third-party repo for AI-agent readability
246
+ // (llms.txt presence, page token budgets, robots allowlist, etc.).
247
+ // Per addyosmani/agentic-seo. Issue #542.
248
+ if (agentReadiness) {
249
+ const rootDir = path.resolve(pathArg || config?.projectDir || process.cwd());
250
+ // Suppress the info banner in --json mode so stdout stays a single
251
+ // valid JSON document. Without this guard, `kj audit --agent-readiness
252
+ // --json | jq` fails with a parse error because the logger writes
253
+ // "Auditing agent-readiness of ..." to stdout BEFORE the JSON blob.
254
+ if (!json) logger.info(`Auditing agent-readiness of ${rootDir}`);
255
+ const report = runAgentReadiness(rootDir);
256
+ if (json) {
257
+ console.log(JSON.stringify(report, null, 2));
258
+ } else {
259
+ console.log(formatAgentReadinessReport(report, rootDir));
260
+ }
261
+ // Exit code: 0 always (audit succeeded). The score is the signal.
262
+ return;
263
+ }
264
+
265
+ return withCliRunLog("audit", { projectDir: config?.projectDir, logger }, async ({ runLog }) => {
266
+ const auditRoleConfig = resolveRole(config, "audit");
267
+ // KJC-BUG-0094: proceed if any fallback candidate is installed; throw only when NONE are.
268
+ const fallbackCandidates = buildAuditFallbackCandidates(config);
269
+ const candidateProviders = [...new Set(fallbackCandidates.map((c) => c.provider))];
270
+ const available = await filterAvailableAgents(candidateProviders);
271
+ if (available.length === 0) await assertAgentsAvailable([auditRoleConfig.provider]);
272
+ logger.info(`Audit (${auditRoleConfig.provider}) starting...`);
273
+ runLog.logText(`[audit] provider=${auditRoleConfig.provider} dimensions=${dimensions || "all"} deterministicOnly=${deterministicOnly}`);
274
+
275
+ // Two-phase audit (KJC-TSK-0364) — collect deterministic findings
276
+ // first; show them; ask the user (when TTY + not --yes + not
277
+ // --deterministic-only) whether to spend tokens on the LLM analysis.
278
+ // CI / piped input / --yes / --deterministic-only never prompts.
279
+ const role = new AuditRole({ config, logger });
280
+ const roleInput = {
281
+ task: task || "Analyze the full codebase",
282
+ dimensions: dimensions || null,
283
+ noSonar,
284
+ noOsv,
285
+ noSemgrep,
286
+ noAiSlop,
287
+ ...(security ? { securityOnly: true } : {}),
288
+ };
289
+ const deterministicCtx = await role.collectDeterministic(roleInput);
290
+ const deterministicMd = formatDeterministicSummary(deterministicCtx);
291
+
292
+ // KJC-TSK-0471 — Harness Scorecard (Docker one-shot, golden metric).
293
+ // Runs after the deterministic phase, before the LLM. Auto-skipped on
294
+ // --no-harness or if `runHarnessSection` surfaces an error (graceful
295
+ // degradation: a missing Docker daemon must not break `kj audit`).
296
+ let harnessSummary = null;
297
+ if (!noHarness) {
298
+ try {
299
+ harnessSummary = await runHarnessSection({
300
+ projectDir: config?.projectDir || process.cwd(),
301
+ harnessConfig: config?.audit?.harness || null,
302
+ });
303
+ if (harnessSummary?.ok && !harnessSummary.skipped) {
304
+ runLog.logText(`[audit] harness score=${harnessSummary.score}/100 grade=${harnessSummary.grade}`);
305
+ }
306
+ } catch (e) {
307
+ harnessSummary = { ok: false, error: e?.message || String(e) };
308
+ runLog.logText(`[audit] harness skipped: ${harnessSummary.error}`);
309
+ }
310
+ }
311
+ const harnessMd = formatHarnessSection(harnessSummary);
312
+
313
+ // --json suppresses the interactive flow regardless: it would mangle
314
+ // a script's stdout. JSON consumers always get the full audit unless
315
+ // they explicitly pass deterministicOnly.
316
+ const reportPath = await resolveReportFilePath(reportFile, json);
317
+ let runLlm = !deterministicOnly;
318
+ if (runLlm && !json && !yes) {
319
+ console.log(deterministicMd);
320
+ console.log("");
321
+ const ok = await promptContinueWithLlm({ promptFn });
322
+ runLlm = ok;
323
+ if (!ok) logger.info("LLM analysis skipped (deterministic-only mode).");
324
+ }
325
+
326
+ if (!runLlm) {
327
+ // Deterministic-only path. Produce the report from what we already
328
+ // have, persist it (md or json), and exit. Zero tokens spent.
329
+ const harnessJson = harnessSummaryForJson(harnessSummary);
330
+ const currentHarness = harnessSummary?.ok && !harnessSummary.skipped ? harnessSummary : null;
331
+ const history = loadAuditHistoryContext(config?.projectDir || process.cwd(), currentHarness, { showTrend: trend });
332
+ const historyMd = composeHistoryBlock(history);
333
+ const stdoutContent = json
334
+ ? JSON.stringify({ deterministic: deterministicCtx, harnessScore: harnessJson, harnessScoreDiff: history.diff, mode: "deterministic-only" }, null, 2)
335
+ : (deterministicOnly ? `${deterministicMd}\n${harnessMd}${historyMd}` : `${harnessMd}${historyMd}`);
336
+ if (json || deterministicOnly || harnessMd) console.log(stdoutContent);
337
+
338
+ if (reportPath) {
339
+ let payload;
340
+ if (reportPath.endsWith(".json")) {
341
+ payload = JSON.stringify({ deterministic: deterministicCtx, harnessScore: harnessJson, harnessScoreDiff: history.diff, mode: "deterministic-only" }, null, 2);
342
+ } else {
343
+ const header = await buildReportHeader(config?.projectDir, describeInvocation({ task, dimensions, noSonar, noOsv, noSemgrep, noHarness, noAiSlop, json, deterministicOnly, yes }));
344
+ payload = `${header}${deterministicMd}\n${harnessMd}${historyMd}`;
345
+ }
346
+ await fs.writeFile(reportPath, payload, "utf8");
347
+ runLog.logText(`[audit] report written (deterministic-only) → ${reportPath}`);
348
+ logger.info(`Audit report written: ${reportPath}`);
349
+ }
350
+ persistAuditRun(config?.projectDir || process.cwd(), { runId: new Date().toISOString(), timestamp: new Date().toISOString(), gitSha: null, harness: harnessSummary?.ok && !harnessSummary.skipped ? harnessSummary : null, rawReportPath: reportPath });
351
+ logger.info("Audit completed (deterministic-only).");
352
+ return { ok: true, mode: "deterministic-only", reportPath: reportPath || undefined };
353
+ }
354
+
355
+ // Continue with the LLM phase using the already-collected context.
356
+ const progress = createCliProgressReporter({ role: "auditor" });
357
+ let roleResult;
358
+ try {
359
+ // KJC-BUG-0094: resilient fallback — if the configured provider/model
360
+ // is down (e.g. an inherited model like "claude-fable-5" is offline),
361
+ // degrade to the provider default, then to the next installed provider,
362
+ // reusing the deterministic context so no static analysis is re-run.
363
+ roleResult = await runAuditWithFallback({
364
+ config, logger,
365
+ roleInput: { ...roleInput, onOutput: progress.onOutput },
366
+ deterministicCtx,
367
+ available,
368
+ candidates: fallbackCandidates,
369
+ onFallback: (cand) => logger.warn(`Audit provider fallback → ${cand.provider}${cand.model ? ` (${cand.model})` : " (default model)"}`),
370
+ });
371
+ progress.finish(roleResult.ok ? "done" : "failed");
372
+ } catch (err) { progress.finish("failed"); throw err; }
373
+
374
+ if (!roleResult.ok) {
375
+ const err = roleResult.result?.error || "Audit failed";
376
+ throw new Error(err);
377
+ }
378
+
379
+ const parsed = roleResult.result;
380
+ const usage = roleResult.usage;
381
+ if (parsed?.summary?.overallHealth) {
382
+ runLog.logText(`[audit] findings=${parsed.summary.totalFindings} (critical=${parsed.summary.critical}, high=${parsed.summary.high})`);
383
+ }
384
+ if (usage?.available) {
385
+ runLog.logText(`[audit] usage tokens=${usage.total_tokens} cost=$${(usage.cost_usd ?? 0).toFixed(4)} duration=${(usage.durationMs / 1000).toFixed(1)}s`);
386
+ }
387
+
388
+ const harnessJson = harnessSummaryForJson(harnessSummary);
389
+ const currentHarness = harnessSummary?.ok && !harnessSummary.skipped ? harnessSummary : null;
390
+ const history = loadAuditHistoryContext(config?.projectDir || process.cwd(), currentHarness, { showTrend: trend });
391
+ const historyMd = composeHistoryBlock(history);
392
+ let stdoutContent;
393
+ if (json) {
394
+ const jsonPayload = parsed
395
+ ? { ...parsed, harnessScore: harnessJson, harnessScoreDiff: history.diff, usage: usage || undefined }
396
+ : { ...roleResult, harnessScore: harnessJson, harnessScoreDiff: history.diff, usage: usage || undefined };
397
+ stdoutContent = JSON.stringify(jsonPayload, null, 2);
398
+ } else if (parsed?.summary?.overallHealth) {
399
+ stdoutContent = `${formatAudit(parsed, usage)}\n${harnessMd}${historyMd}`;
400
+ } else if (parsed?.raw) {
401
+ stdoutContent = parsed.raw + (usage ? `\n\n${formatUsageSummary(usage) || ""}` : "") + `\n${harnessMd}${historyMd}`;
402
+ } else {
403
+ stdoutContent = `${roleResult.summary || "Audit complete."}\n${harnessMd}${historyMd}`;
404
+ }
405
+ console.log(stdoutContent);
406
+
407
+ if (reportPath) {
408
+ let payload;
409
+ if (reportPath.endsWith(".json")) {
410
+ const jsonPayload = parsed
411
+ ? { ...parsed, harnessScore: harnessJson, harnessScoreDiff: history.diff, usage: usage || undefined }
412
+ : { ...roleResult, harnessScore: harnessJson, harnessScoreDiff: history.diff, usage: usage || undefined };
413
+ payload = JSON.stringify(jsonPayload, null, 2);
414
+ } else {
415
+ const header = await buildReportHeader(config?.projectDir, describeInvocation({ task, dimensions, noSonar, noOsv, noSemgrep, noHarness, noAiSlop, json, deterministicOnly, yes }));
416
+ payload = header + stdoutContent + "\n";
417
+ }
418
+ await fs.writeFile(reportPath, payload, "utf8");
419
+ runLog.logText(`[audit] report written → ${reportPath}`);
420
+ logger.info(`Audit report written: ${reportPath}`);
421
+ }
422
+
423
+ persistAuditRun(config?.projectDir || process.cwd(), { runId: new Date().toISOString(), timestamp: new Date().toISOString(), gitSha: null, harness: harnessSummary?.ok && !harnessSummary.skipped ? harnessSummary : null, rawReportPath: reportPath });
424
+ logger.info("Audit completed.");
425
+ return { ok: true, reportPath: reportPath || undefined };
426
+ });
427
+ }
428
+
429
+ // Exposed for tests — kept module-private otherwise.
430
+ export { formatAudit, formatUsageSummary };
@@ -0,0 +1,49 @@
1
+ /**
2
+ * `kj autorun <spec>` — the unattended delivery chain (KJC-TSK-0574, épica
3
+ * KJC-PCS-0062, design in docs/specs/autonomous-delivery.md §7).
4
+ *
5
+ * One command: spec → plan → run all HUs → outcome. It reuses `kj plan` and
6
+ * `kj run --plan` rather than reimplementing them, and defaults to the
7
+ * `autonomous` level so the Arbiter resolves every gate (no human in the loop).
8
+ * The rich outcome report lands in AUTO-F; here we chain + propagate exit code.
9
+ */
10
+
11
+ import { planGenerateCommand } from "./plan/generate.js";
12
+ import { runCommandHandler } from "./run.js";
13
+ import { buildOutcome, formatOutcomeReport } from "../autonomy/outcome-report.js";
14
+
15
+ export async function autorunCommand({
16
+ task,
17
+ config,
18
+ logger = console,
19
+ flags = {},
20
+ planFn = planGenerateCommand,
21
+ runFn = runCommandHandler,
22
+ } = {}) {
23
+ // autorun implies unattended: default to autonomous unless the user picked a
24
+ // level explicitly (so `kj autorun --autonomy assisted` still works).
25
+ const autoFlags = flags.autonomy || flags.autonomous ? flags : { ...flags, autonomous: true };
26
+
27
+ logger.info?.("kj autorun — planning…");
28
+ const plan = await planFn({ task, config, logger, flags: autoFlags });
29
+ if (!plan?.ok || !plan.planId) {
30
+ logger.error?.(`kj autorun: planning failed${plan?.reason ? ` (${plan.reason})` : ""}.`);
31
+ return { ok: false, stage: "plan", reason: plan?.reason ?? "plan-failed" };
32
+ }
33
+
34
+ logger.info?.(`kj autorun — running plan ${plan.ref ?? plan.planId} (${plan.huCount ?? "?"} HUs)…`);
35
+ const run = await runFn({ config, logger, flags: { ...autoFlags, plan: plan.planId } });
36
+
37
+ const ok = run?.ok === true;
38
+ // AUTO-F: emit the auditable outcome — delivered/incomplete, HUs that met the
39
+ // ask, Arbiter decisions and residual defects (enriched as the run surfaces
40
+ // them; baseline today is delivered + plan ref).
41
+ const outcome = buildOutcome({
42
+ planRef: plan.ref ?? plan.planId,
43
+ delivered: ok,
44
+ hus: run?.hus ?? [],
45
+ decisions: run?.decisions ?? [],
46
+ });
47
+ for (const line of formatOutcomeReport(outcome)) logger.info?.(line);
48
+ return { ok, stage: ok ? "done" : "run", planId: plan.planId, ref: plan.ref ?? plan.planId, outcome };
49
+ }