@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,474 @@
1
+ import { extractFirstJson } from "../utils/json-extract.js";
2
+ import { groupIssuesBySeverity } from "../audit/sonar-findings.js";
3
+ import { groupVulnerabilitiesBySeverity } from "../audit/osv-findings.js";
4
+ import { groupFindingsBySeverity as groupSemgrepBySeverity } from "../audit/semgrep-findings.js";
5
+ import { formatCwvVerdict } from "../audit/webperf-input.js";
6
+
7
+ const MAX_SONAR_ISSUES_IN_PROMPT = 50;
8
+ const MAX_OSV_VULNS_IN_PROMPT = 50;
9
+ const MAX_SEMGREP_FINDINGS_IN_PROMPT = 50;
10
+
11
+ const SUBAGENT_PREAMBLE = [
12
+ "IMPORTANT: You are running as a Karajan sub-agent.",
13
+ "Do NOT ask about using Karajan, do NOT mention Karajan, do NOT suggest orchestration.",
14
+ "Do NOT use any MCP tools. Focus only on auditing the codebase for health, quality, and risks.",
15
+ "DO NOT modify any files — this is a read-only analysis. Only use: Read, Grep, Glob, Bash (for analysis commands like wc, find, git log, du, npm ls)."
16
+ ].join(" ");
17
+
18
+ export const AUDIT_DIMENSIONS = ["security", "codeQuality", "performance", "architecture", "testing", "accessibility"];
19
+
20
+ // Dimensions that only apply to frontend / fullstack projects. Auto-dropped
21
+ // from the default dimension list when stack detection knows the project
22
+ // is backend-only — preserves activation when the user explicitly opts in
23
+ // via --dimensions=accessibility (KJC-TSK-0359).
24
+ const FRONTEND_ONLY_DIMENSIONS = new Set(["accessibility"]);
25
+
26
+ const VALID_HEALTH = new Set(["good", "fair", "poor", "critical"]);
27
+ const VALID_SCORES = new Set(["A", "B", "C", "D", "F"]);
28
+ const VALID_SEVERITIES = new Set(["critical", "high", "medium", "low"]);
29
+ const VALID_IMPACT = new Set(["high", "medium", "low"]);
30
+
31
+ export function buildAuditPrompt({ task, instructions, dimensions = null, context = null, basalCost = null, growthDelta = null, stack = null, sonarFindings = null, webperf = null, osvFindings = null, semgrepFindings = null, circularDeps = null, deadExports = null }) {
32
+ const sections = [SUBAGENT_PREAMBLE];
33
+
34
+ if (instructions) {
35
+ sections.push(instructions);
36
+ }
37
+
38
+ sections.push(
39
+ "You are a codebase auditor for Karajan Code, a multi-agent coding orchestrator.",
40
+ "Analyze the project across multiple dimensions and produce a comprehensive health report.",
41
+ "DO NOT modify any files. This is a READ-ONLY analysis."
42
+ );
43
+
44
+ // Stack hint — when detected, tells the LLM what kind of project this is
45
+ // so it can filter out irrelevant heuristics (e.g. don't flag bundle size
46
+ // in an Express-only API; don't flag N+1 queries in a static Astro site).
47
+ // Detected by src/utils/stack-detect.js — KJC-TSK-0358.
48
+ if (stack && (stack.frameworks?.length > 0 || stack.language || stack.isFrontend || stack.isBackend)) {
49
+ const stackLines = ["## Project Stack"];
50
+ if (stack.language) stackLines.push(`- Language: ${stack.language}`);
51
+ if (stack.frameworks?.length) stackLines.push(`- Frameworks: ${stack.frameworks.join(", ")}`);
52
+ let tier = "unknown";
53
+ if (stack.isFullstack) tier = "fullstack (frontend + backend)";
54
+ else if (stack.isFrontend) tier = "frontend-only";
55
+ else if (stack.isBackend) tier = "backend-only";
56
+ stackLines.push(`- Tier: ${tier}`);
57
+ if (stack.isFullstack) {
58
+ stackLines.push("Apply BOTH backend heuristics (queries, sync I/O, caching) AND frontend heuristics (bundle size, lazy loading, render-blocking) where each layer applies.");
59
+ } else if (stack.isFrontend) {
60
+ stackLines.push("This project is frontend-only. SKIP findings about N+1 queries, sync file I/O in request handlers, missing pagination on list endpoints, and other backend-specific patterns. Focus on bundle size, lazy loading, render-blocking resources, image optimisation, and accessibility hints.");
61
+ } else if (stack.isBackend) {
62
+ stackLines.push("This project is backend-only. SKIP findings about bundle size, lazy loading, render-blocking resources, image optimisation, and frontend accessibility. Focus on queries, sync I/O, pagination, caching, auth/authz, and dependency hygiene.");
63
+ }
64
+ sections.push(stackLines.join("\n"));
65
+ }
66
+
67
+ // When dimensions are explicit, honour them verbatim — even frontend-only
68
+ // dimensions on a backend project (the user knows what they want).
69
+ // When dimensions are absent, default to all but drop frontend-only
70
+ // dimensions if the stack is provably backend-only. Unknown stack falls
71
+ // back to the full list (no false negatives — better an extra section
72
+ // than a missing one).
73
+ let activeDimensions;
74
+ if (dimensions) {
75
+ activeDimensions = dimensions.filter(d => AUDIT_DIMENSIONS.includes(d));
76
+ } else if (stack && stack.isBackend && !stack.isFrontend) {
77
+ activeDimensions = AUDIT_DIMENSIONS.filter(d => !FRONTEND_ONLY_DIMENSIONS.has(d));
78
+ } else {
79
+ activeDimensions = AUDIT_DIMENSIONS;
80
+ }
81
+
82
+ if (activeDimensions.includes("security")) {
83
+ sections.push(
84
+ "## Security Analysis",
85
+ [
86
+ "- Hardcoded secrets, API keys, tokens in source code",
87
+ "- SQL/NoSQL injection vectors",
88
+ "- XSS vulnerabilities (innerHTML, dangerouslySetInnerHTML, eval)",
89
+ "- Command injection (exec, spawn with user input)",
90
+ "- Insecure dependencies (check package.json for known vulnerable packages)",
91
+ "- Missing input validation at system boundaries",
92
+ "- Authentication/authorization gaps"
93
+ ].join("\n")
94
+ );
95
+ }
96
+
97
+ if (activeDimensions.includes("codeQuality")) {
98
+ sections.push(
99
+ "## Code Quality Analysis (SOLID, DRY, KISS, YAGNI)",
100
+ [
101
+ "- Functions/methods longer than 50 lines",
102
+ "- Files longer than 500 lines",
103
+ "- Duplicated code blocks (same logic in multiple places)",
104
+ "- God classes/modules (too many responsibilities)",
105
+ "- Deep nesting (>4 levels)",
106
+ "- Dead code (unused exports, unreachable branches)",
107
+ "- Missing error handling (uncaught promises, empty catches)",
108
+ "- Over-engineering (abstractions for single use)"
109
+ ].join("\n")
110
+ );
111
+ }
112
+
113
+ if (activeDimensions.includes("performance")) {
114
+ sections.push(
115
+ "## Performance Analysis",
116
+ [
117
+ "- N+1 query patterns",
118
+ "- Synchronous file I/O in request handlers",
119
+ "- Missing pagination on list endpoints",
120
+ "- Large bundle imports (importing entire libraries for one function)",
121
+ "- Missing lazy loading",
122
+ "- Expensive operations in loops",
123
+ "- Missing caching opportunities"
124
+ ].join("\n")
125
+ );
126
+ }
127
+
128
+ if (activeDimensions.includes("architecture")) {
129
+ sections.push(
130
+ "## Architecture Analysis",
131
+ [
132
+ "- Circular dependencies",
133
+ "- Layer violations (UI importing from data layer directly)",
134
+ "- Coupling between modules (shared mutable state)",
135
+ "- Missing dependency injection",
136
+ "- Inconsistent patterns across the codebase",
137
+ "- Missing or outdated documentation",
138
+ "- Configuration scattered vs centralized"
139
+ ].join("\n")
140
+ );
141
+ }
142
+
143
+ if (activeDimensions.includes("testing")) {
144
+ sections.push(
145
+ "## Testing Analysis",
146
+ [
147
+ "- Test coverage gaps (source files without corresponding tests)",
148
+ "- Test quality (assertions per test, meaningful test names)",
149
+ "- Missing edge case coverage",
150
+ "- Test isolation (shared state between tests)",
151
+ "- Flaky test indicators (timeouts, sleep, retries)"
152
+ ].join("\n")
153
+ );
154
+ }
155
+
156
+ if (activeDimensions.includes("accessibility")) {
157
+ sections.push(
158
+ "## Accessibility Analysis (WCAG 2.x)",
159
+ [
160
+ "- Missing alt text on <img> tags (decorative images need empty alt=\"\", not absent)",
161
+ "- Form inputs without associated <label> or aria-label",
162
+ "- Heading hierarchy violations (h1 → h3 skipping h2; multiple h1 per page)",
163
+ "- Buttons / links containing only icons without aria-label or visually-hidden text",
164
+ "- Interactive elements built from <div>/<span> without role + keyboard handlers",
165
+ "- ARIA roles misused (presentation on focusable elements, redundant on native semantics)",
166
+ "- Focus management gaps (modals without focus trap, no visible :focus styles, tabindex misuse)",
167
+ "- Colour-only signalling (status indicated by red/green only, no icon or text)",
168
+ "- Static contrast — flag suspicious low-contrast colour pairs in CSS variables / token files",
169
+ "- Missing lang attribute on <html>, missing skip-to-content link, missing landmarks"
170
+ ].join("\n"),
171
+ "Skip findings about colour contrast that require runtime rendering (e.g. computed styles); flag the suspect CSS values and recommend an axe-core/Lighthouse runtime check."
172
+ );
173
+ }
174
+
175
+ // JSON schema — keep the per-dimension entries in sync with AUDIT_DIMENSIONS.
176
+ const schemaDimensions = AUDIT_DIMENSIONS
177
+ .map(d => `"${d}":{"score":"A|B|C|D|F","findings":[]}`)
178
+ .join(",");
179
+ sections.push(
180
+ "Return a single valid JSON object and nothing else.",
181
+ `JSON schema: {"ok":true,"result":{"summary":{"overallHealth":"good|fair|poor|critical","totalFindings":number,"critical":number,"high":number,"medium":number,"low":number},"dimensions":{${schemaDimensions}},"topRecommendations":[{"priority":number,"dimension":string,"action":string,"impact":"high|medium|low","effort":"high|medium|low"}]},"summary":string}`,
182
+ 'Each finding: {"severity":"critical|high|medium|low","file":string,"line":number,"rule":string,"description":string,"recommendation":string}',
183
+ `Only include dimensions you were asked to analyze: ${activeDimensions.join(", ")}`
184
+ );
185
+
186
+ if (basalCost) {
187
+ const lines = [
188
+ "## Basal Cost",
189
+ `- Total source lines: ${basalCost.totalLines}`,
190
+ `- Total source files: ${basalCost.totalFiles}`,
191
+ `- Dependencies: ${basalCost.dependencies?.total ?? 0} (${basalCost.dependencies?.dependencies ?? 0} prod + ${basalCost.dependencies?.devDependencies ?? 0} dev)`
192
+ ];
193
+ if (basalCost.unusedDependencies?.unused?.length > 0) {
194
+ lines.push(`- Unused dependencies: ${basalCost.unusedDependencies.unused.join(", ")}`);
195
+ } else if (basalCost.unusedDependencies?.note) {
196
+ lines.push(`- Unused dependencies: ${basalCost.unusedDependencies.note}`);
197
+ }
198
+ if (basalCost.deadExports?.length > 0) {
199
+ lines.push(`- Dead exports (exported but never imported): ${basalCost.deadExports.length}`);
200
+ for (const de of basalCost.deadExports.slice(0, 20)) {
201
+ lines.push(` - ${de.name} in ${de.file}`);
202
+ }
203
+ if (basalCost.deadExports.length > 20) {
204
+ lines.push(` - ... and ${basalCost.deadExports.length - 20} more`);
205
+ }
206
+ }
207
+ if (growthDelta) {
208
+ lines.push("");
209
+ lines.push("### Growth since last audit");
210
+ lines.push(`- Lines: ${growthDelta.lines >= 0 ? "+" : ""}${growthDelta.lines}`);
211
+ lines.push(`- Files: ${growthDelta.files >= 0 ? "+" : ""}${growthDelta.files}`);
212
+ lines.push(`- Dependencies: ${growthDelta.deps >= 0 ? "+" : ""}${growthDelta.deps}`);
213
+ if (growthDelta.since) lines.push(`- Since: ${growthDelta.since}`);
214
+ }
215
+ lines.push("");
216
+ lines.push("Flag if basal cost is growing faster than feature delivery. Recommend elimination of unused code and dependencies.");
217
+ sections.push(lines.join("\n"));
218
+ }
219
+
220
+ // Sonar findings — KJC-TSK-0361. Deterministic input from a tool the
221
+ // codebase already runs (kj run + SonarStage). The audit reads existing
222
+ // open issues + quality-gate state instead of re-scanning. Capped at
223
+ // MAX_SONAR_ISSUES_IN_PROMPT total entries (50) across all severities to
224
+ // bound prompt size; the LLM is told the truncated count so it can
225
+ // prioritise.
226
+ if (sonarFindings?.available && (sonarFindings.total > 0 || sonarFindings.qualityGate)) {
227
+ const lines = ["## SonarQube Findings"];
228
+ if (sonarFindings.qualityGate?.status) {
229
+ lines.push(`- Quality gate: ${sonarFindings.qualityGate.status}`);
230
+ }
231
+ if (sonarFindings.total > 0) {
232
+ lines.push(`- Total open issues: ${sonarFindings.total}`);
233
+ const groups = groupIssuesBySeverity(sonarFindings.issues);
234
+ let remaining = MAX_SONAR_ISSUES_IN_PROMPT;
235
+ for (const [severity, issues] of Object.entries(groups)) {
236
+ if (issues.length === 0) continue;
237
+ lines.push("");
238
+ lines.push(`### ${severity} (${issues.length})`);
239
+ const slice = issues.slice(0, Math.max(0, remaining));
240
+ for (const issue of slice) {
241
+ const lineSuffix = issue.line ? `:${issue.line}` : "";
242
+ const loc = issue.component ? `${issue.component}${lineSuffix}` : "";
243
+ const rule = issue.rule ? ` [${issue.rule}]` : "";
244
+ lines.push(` - ${loc}${rule} ${issue.message || ""}`.trim());
245
+ }
246
+ if (issues.length > slice.length) {
247
+ lines.push(` - ... and ${issues.length - slice.length} more in ${severity}`);
248
+ }
249
+ remaining -= slice.length;
250
+ }
251
+ }
252
+ lines.push("");
253
+ lines.push("Cross-reference these with your own findings. When your finding overlaps a Sonar rule, mention the rule ID in the `rule` field — that's a high-confidence match. Findings the LLM raises that Sonar can't see (architecture, naming, API design) are still valuable; mark them with rule names like \"AUDIT-ARCH-N\".");
254
+ sections.push(lines.join("\n"));
255
+ }
256
+
257
+ // WebPerf — KJC-TSK-0360. Two modes: a real CWV measurement when one is
258
+ // surfaced via config.webperf.lastResult (future `kj webperf` command)
259
+ // OR static frontend-perf hints for the LLM to look at the source code
260
+ // when no live measurement is available. Backend-only projects skip the
261
+ // section entirely (collectWebPerfInput returns available:false).
262
+ if (webperf?.available) {
263
+ const lines = ["## WebPerf — Frontend Performance"];
264
+ if (webperf.mode === "cwv-result") {
265
+ lines.push("Live Core Web Vitals measurement available — incorporate the verdict below into the performance dimension findings:");
266
+ lines.push("");
267
+ lines.push(formatCwvVerdict(webperf));
268
+ lines.push("");
269
+ lines.push("If a metric is `poor`, recommend a concrete code change (preconnect, lazy-load, image format, critical CSS, defer script). Cite the offending file or pattern when you can find it in the source.");
270
+ } else {
271
+ lines.push("No live CWV measurement was provided. Audit the source for these static frontend-perf patterns and include findings under the `performance` dimension:");
272
+ lines.push("");
273
+ lines.push("- Render-blocking `<link rel=\"stylesheet\">` or `<script>` without `defer`/`async` in `<head>`");
274
+ lines.push("- Large JavaScript bundles imported eagerly that could be `await import(...)` or split by route");
275
+ lines.push("- Non-modern image formats (only .jpg/.png) where webp/avif are widely supported");
276
+ lines.push("- `<img>` without `width`/`height` attributes (causes CLS)");
277
+ lines.push("- `<img>` without `loading=\"lazy\"` for off-screen images, or videos auto-playing without `preload=\"metadata\"`");
278
+ lines.push("- Web fonts loaded without `font-display: swap` or without `<link rel=\"preconnect\">` to the font origin");
279
+ lines.push("- Whole-library imports for one helper (e.g. `import _ from 'lodash'` instead of `lodash/get`)");
280
+ lines.push("- Missing critical CSS extraction or above-the-fold inlining strategy in build config");
281
+ lines.push("- Large third-party scripts (analytics, A/B, chat widgets) without defer + facade pattern");
282
+ lines.push("- Unbounded list rendering without virtualisation for very long collections");
283
+ }
284
+ sections.push(lines.join("\n"));
285
+ }
286
+
287
+ // OSV vulnerabilities — KJC-TSK-0365. Deterministic CVE/GHSA findings
288
+ // from osv-scanner across the dependency manifest. Capped at
289
+ // MAX_OSV_VULNS_IN_PROMPT entries; the LLM is told the truncated count.
290
+ // Findings fold into the `security` dimension with the upstream
291
+ // identifier (CVE-/GHSA-) as the rule.
292
+ if (osvFindings?.available && (osvFindings.total > 0)) {
293
+ const lines = ["## OSV Vulnerabilities"];
294
+ lines.push(`- Total open vulnerabilities in dependencies: ${osvFindings.total}`);
295
+ const groups = groupVulnerabilitiesBySeverity(osvFindings.vulnerabilities);
296
+ let remaining = MAX_OSV_VULNS_IN_PROMPT;
297
+ for (const [severity, vulns] of Object.entries(groups)) {
298
+ if (vulns.length === 0) continue;
299
+ lines.push("");
300
+ lines.push(`### ${severity} (${vulns.length})`);
301
+ const slice = vulns.slice(0, Math.max(0, remaining));
302
+ for (const vuln of slice) {
303
+ const where = vuln.package ? `${vuln.package}@${vuln.version || "?"}` : "(unknown package)";
304
+ const fixed = vuln.fixed ? ` → fixed in ${vuln.fixed}` : "";
305
+ lines.push(` - ${vuln.id} ${where}${fixed}: ${vuln.summary || ""}`.trim());
306
+ }
307
+ if (vulns.length > slice.length) {
308
+ lines.push(` - ... and ${vulns.length - slice.length} more in ${severity}`);
309
+ }
310
+ remaining -= slice.length;
311
+ }
312
+ lines.push("");
313
+ lines.push("These CVE/GHSA findings are GROUND TRUTH — incorporate them into the `security` dimension. Use the OSV id (CVE-XXXX-XXXX or GHSA-xxxx-xxxx-xxxx) as the `rule` field. Recommend the fixed version when available.");
314
+ sections.push(lines.join("\n"));
315
+ }
316
+
317
+ // Semgrep SAST findings — KJC-TSK-0366. Static analysis catches what
318
+ // sonar/CVE-DBs miss: SQL/Cmd injection, XSS, hardcoded secrets,
319
+ // taint flow, language-specific anti-patterns. Capped at
320
+ // MAX_SEMGREP_FINDINGS_IN_PROMPT entries; LLM is told these are
321
+ // deterministic and asked to use rule IDs as-is in findings.
322
+ if (semgrepFindings?.available && semgrepFindings.total > 0) {
323
+ const lines = ["## Semgrep SAST Findings"];
324
+ lines.push(`- Total findings: ${semgrepFindings.total}`);
325
+ const groups = groupSemgrepBySeverity(semgrepFindings.findings);
326
+ let remaining = MAX_SEMGREP_FINDINGS_IN_PROMPT;
327
+ for (const [severity, findings] of Object.entries(groups)) {
328
+ if (findings.length === 0) continue;
329
+ lines.push("");
330
+ lines.push(`### ${severity} (${findings.length})`);
331
+ const slice = findings.slice(0, Math.max(0, remaining));
332
+ for (const f of slice) {
333
+ const lineSuffix = f.line ? `:${f.line}` : "";
334
+ const loc = f.file ? `${f.file}${lineSuffix}` : "";
335
+ const cweText = Array.isArray(f.cwe) ? f.cwe.join(", ") : f.cwe;
336
+ const cwe = f.cwe ? ` (${cweText})` : "";
337
+ lines.push(` - ${loc} [${f.rule}]${cwe}: ${f.message || ""}`.trim());
338
+ }
339
+ if (findings.length > slice.length) {
340
+ lines.push(` - ... and ${findings.length - slice.length} more in ${severity}`);
341
+ }
342
+ remaining -= slice.length;
343
+ }
344
+ lines.push("");
345
+ lines.push("These SAST findings are GROUND TRUTH — fold ERROR-severity ones into the `security` dimension as critical/high findings. Use the semgrep rule id (e.g. javascript.express.security.audit.xss.direct-response-write) verbatim in the `rule` field; that lets the developer look it up in the semgrep registry.");
346
+ sections.push(lines.join("\n"));
347
+ }
348
+
349
+ // Knip dead-exports findings — KJC-TSK v2.17. Stack-aware, JS/TS only.
350
+ // Folds into the `codeQuality` dimension as MINOR for unused exports/types
351
+ // and MAJOR for unused files (likely real dead code).
352
+ if (deadExports?.available && deadExports.total > 0) {
353
+ const lines = ["## Dead Code (knip)"];
354
+ lines.push(`- Unused exports/types: ${(deadExports.exports || []).length}`);
355
+ lines.push(`- Unused files: ${(deadExports.files || []).length}`);
356
+ const allItems = [...(deadExports.exports || []), ...(deadExports.files || [])].slice(0, 40);
357
+ for (const item of allItems) {
358
+ const lineSuffix = item.line ? `:${item.line}` : "";
359
+ const loc = `${item.path}${lineSuffix}`;
360
+ const name = item.name ? ` \`${item.name}\`` : "";
361
+ lines.push(` - [${item.severity}] ${loc} [${item.rule}]${name}`);
362
+ }
363
+ lines.push("");
364
+ lines.push("These dead-code findings are GROUND TRUTH (deterministic, no LLM guessing). Fold them into the `codeQuality` dimension. Use the knip rule id (`knip:unused-exports`, `knip:unused-types`, `knip:unused-files`) verbatim in the `rule` field. Unused files at MAJOR severity are most likely real dead code; unused exports at MINOR may be public API surface kept for downstream consumers — flag but don't insist on deletion.");
365
+ sections.push(lines.join("\n"));
366
+ }
367
+
368
+ // Madge circular-import findings — KJC-TSK v2.17. Stack-aware, JS/TS only.
369
+ if (circularDeps?.available && circularDeps.total > 0) {
370
+ const lines = ["## Circular Import Cycles"];
371
+ lines.push(`- Total cycles: ${circularDeps.total}`);
372
+ const slice = (circularDeps.cycles || []).slice(0, 30);
373
+ for (const c of slice) {
374
+ const chain = (c.cycle || []).join(" → ");
375
+ lines.push(` - [${c.severity}] ${chain} → ${c.cycle?.[0] || ""}`);
376
+ }
377
+ if (circularDeps.cycles?.length > slice.length) {
378
+ lines.push(` - ... ${circularDeps.cycles.length - slice.length} more cycles`);
379
+ }
380
+ lines.push("");
381
+ lines.push("These cycles are GROUND TRUTH (deterministic, no LLM guessing). Fold them into the `architecture` dimension. Use `madge:circular-import` as the rule field. MAJOR severity = chain length ≥ 4 files; MINOR = shorter chains. Recommend the standard fix: extract a third module that both ends depend on, or break the cycle with a typeof/inline import.");
382
+ sections.push(lines.join("\n"));
383
+ }
384
+
385
+ if (context) {
386
+ sections.push(`## Context\n${context}`);
387
+ }
388
+
389
+ sections.push(`## Task\n${task}`);
390
+
391
+ return sections.join("\n\n");
392
+ }
393
+
394
+ function parseFinding(raw) {
395
+ if (!raw || typeof raw !== "object") return null;
396
+ const severity = String(raw.severity || "").toLowerCase();
397
+ if (!VALID_SEVERITIES.has(severity)) return null;
398
+ return {
399
+ severity,
400
+ file: raw.file || "",
401
+ line: typeof raw.line === "number" ? raw.line : 0,
402
+ rule: raw.rule || "",
403
+ description: raw.description || "",
404
+ recommendation: raw.recommendation || ""
405
+ };
406
+ }
407
+
408
+ function parseDimension(raw) {
409
+ if (!raw || typeof raw !== "object") return { score: "F", findings: [] };
410
+ const score = VALID_SCORES.has(raw.score) ? raw.score : "F";
411
+ const findings = (Array.isArray(raw.findings) ? raw.findings : [])
412
+ .map(parseFinding)
413
+ .filter(Boolean);
414
+ return { score, findings };
415
+ }
416
+
417
+ function parseRecommendation(raw) {
418
+ if (!raw || typeof raw !== "object") return null;
419
+ return {
420
+ priority: typeof raw.priority === "number" ? raw.priority : 99,
421
+ dimension: raw.dimension || "",
422
+ action: raw.action || "",
423
+ impact: VALID_IMPACT.has(raw.impact) ? raw.impact : "medium",
424
+ effort: VALID_IMPACT.has(raw.effort) ? raw.effort : "medium"
425
+ };
426
+ }
427
+
428
+ export function parseAuditOutput(raw) {
429
+ const parsed = extractFirstJson(raw);
430
+ if (!parsed) return null;
431
+
432
+ // Handle both wrapped (result.summary) and flat structures
433
+ const resultObj = parsed.result || parsed;
434
+ const summaryObj = resultObj.summary || {};
435
+
436
+ const overallHealth = VALID_HEALTH.has(summaryObj.overallHealth)
437
+ ? summaryObj.overallHealth
438
+ : "poor";
439
+
440
+ const dims = resultObj.dimensions || {};
441
+ const dimensions = {};
442
+ for (const d of AUDIT_DIMENSIONS) {
443
+ dimensions[d] = parseDimension(dims[d]);
444
+ }
445
+
446
+ const totalFindings = Object.values(dimensions)
447
+ .reduce((sum, d) => sum + d.findings.length, 0);
448
+
449
+ const bySeverity = { critical: 0, high: 0, medium: 0, low: 0 };
450
+ for (const d of Object.values(dimensions)) {
451
+ for (const f of d.findings) {
452
+ bySeverity[f.severity] = (bySeverity[f.severity] || 0) + 1;
453
+ }
454
+ }
455
+
456
+ const topRecommendations = (Array.isArray(resultObj.topRecommendations) ? resultObj.topRecommendations : [])
457
+ .map(parseRecommendation)
458
+ .filter(Boolean)
459
+ .sort((a, b) => a.priority - b.priority);
460
+
461
+ return {
462
+ summary: {
463
+ overallHealth,
464
+ totalFindings,
465
+ critical: bySeverity.critical,
466
+ high: bySeverity.high,
467
+ medium: bySeverity.medium,
468
+ low: bySeverity.low
469
+ },
470
+ dimensions,
471
+ topRecommendations,
472
+ textSummary: parsed.summary || resultObj.textSummary || ""
473
+ };
474
+ }