@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,185 @@
1
+ import { EventEmitter } from "node:events";
2
+ import { runFlow } from "../orchestrator.js";
3
+ import { assertAgentsAvailable } from "../agents/availability.js";
4
+ import { createActivityLog } from "../activity-log.js";
5
+ import { withCliRunLog } from "../utils/cli-run-log.js";
6
+ import { registerRun, unregisterRun } from "../utils/run-registry.js";
7
+ import { printHeader } from "../utils/display/header.js";
8
+ import { printEvent } from "../utils/display/event-handlers.js";
9
+ import { printResumeHint } from "../utils/display/resume-hint.js";
10
+ import { resolveRole } from "../config.js";
11
+ import { parseCardId } from "../planning-game/adapter.js";
12
+ import { confirmCwd } from "../utils/cwd-confirm.js";
13
+ import { runSpecReview } from "../spec-review/run-spec-review.js";
14
+ import { maybeAutoUpdate } from "../rag/auto-update.js";
15
+
16
+ // Re-export the shared helper so existing imports (tests, MCP wrappers)
17
+ // keep working. KJC-BUG-0081 round 2 split the body into utils/ because
18
+ // resume.js also needs the same contract.
19
+ import { createCliAskQuestion } from "../utils/cli-ask-question.js";
20
+ import { buildDecider } from "../autonomy/decider.js";
21
+ import { createAutonomyAskQuestion } from "../autonomy/stage-ask.js";
22
+ export { createCliAskQuestion };
23
+
24
+ export async function runCommandHandler({ task, config, logger, flags }) {
25
+ // PR-F (cwd confirmation): when launching from an interactive
26
+ // terminal, surface the working directory so the user can abort if
27
+ // they typed `kj run` from the wrong place. The user's words:
28
+ // "todas las que lo lancé desde terminal te garantizo que estaba
29
+ // en la carpeta del proyecto … aún así preguntar por si acaso".
30
+ //
31
+ // Skip the prompt when:
32
+ // - --yes / -y is set (CI / scripted runs),
33
+ // - --json mode is on (machine-readable output, no TTY assumed),
34
+ // - stdin is not a TTY (piped, board-spawned subprocess, MCP).
35
+ const projectDir = config?.projectDir || process.cwd();
36
+ const canPrompt = process.stdin.isTTY && process.stdout.isTTY
37
+ && !flags?.yes && !flags?.json;
38
+ if (canPrompt) {
39
+ const ok = await confirmCwd(projectDir);
40
+ if (!ok) {
41
+ console.log("Aborted by user.");
42
+ return { ok: false, aborted: true };
43
+ }
44
+ }
45
+
46
+ // KJC-TSK-0455 — Pre-run drift check. Default ON; opt out with
47
+ // --no-rag-update (flag) or config.rag.autoUpdate.onRun=false. If the
48
+ // local index is behind HEAD we re-embed the delta before the agents
49
+ // start reading from the RAG store; on any failure we log and move on
50
+ // so a broken vector store never blocks a run.
51
+ await maybeAutoUpdate({ projectDir, config, logger, flags });
52
+
53
+ // Best-effort session cleanup before starting
54
+ try {
55
+ const { cleanupExpiredSessions } = await import("../session-cleanup.js");
56
+ await cleanupExpiredSessions({ logger });
57
+ } catch { /* non-blocking */ }
58
+
59
+ const requiredProviders = [
60
+ resolveRole(config, "coder").provider
61
+ ];
62
+ if (config.pipeline?.reviewer?.enabled !== false) {
63
+ requiredProviders.push(resolveRole(config, "reviewer").provider);
64
+ }
65
+ if (config.pipeline?.triage?.enabled) requiredProviders.push(resolveRole(config, "triage").provider);
66
+ if (config.pipeline?.planner?.enabled) requiredProviders.push(resolveRole(config, "planner").provider);
67
+ if (config.pipeline?.refactorer?.enabled) requiredProviders.push(resolveRole(config, "refactorer").provider);
68
+ if (config.pipeline?.researcher?.enabled) requiredProviders.push(resolveRole(config, "researcher").provider);
69
+ if (config.pipeline?.tester?.enabled) requiredProviders.push(resolveRole(config, "tester").provider);
70
+ if (config.pipeline?.security?.enabled) requiredProviders.push(resolveRole(config, "security").provider);
71
+ await assertAgentsAvailable(requiredProviders);
72
+
73
+ // --- Planning Game: resolve card ID ---
74
+ const pgCardId = flags?.pgTask || parseCardId(task);
75
+ const pgProject = flags?.pgProject || config.planning_game?.project_id || null;
76
+
77
+ const jsonMode = flags?.json;
78
+ // Quiet mode is the default; --verbose disables it
79
+ const quietMode = config.output?.quiet !== false;
80
+
81
+ return withCliRunLog("run", { projectDir: config?.projectDir, logger }, async ({ runLog, forwardProgress }) => {
82
+ runLog.logText(`[kj_run] task="${String(task).slice(0, 80)}..."`);
83
+
84
+ // KJC-TSK-0396 extensión: registrar el PID + planId + huIds en
85
+ // ~/.karajan/runs/<runId>.json para que el HU Board pueda mostrar
86
+ // el botón ⏹ Stop incluso cuando el run se lanza desde terminal
87
+ // externa (no solo desde el botón ▶ Run del board). Best-effort:
88
+ // si la escritura falla, el run sigue su curso normal. Limpieza
89
+ // garantizada en el finally del withCliRunLog vía registry.unregisterRun.
90
+ const huIdsFromFlag = typeof flags?.hu === "string"
91
+ ? flags.hu.split(",").map((s) => s.trim()).filter(Boolean)
92
+ : null;
93
+ const runId = registerRun({
94
+ pid: process.pid,
95
+ planId: flags?.plan || null,
96
+ huIds: huIdsFromFlag,
97
+ projectDir: config?.projectDir || process.cwd(),
98
+ source: "cli",
99
+ });
100
+ const cleanupRegistry = () => { if (runId) unregisterRun(runId); };
101
+ // Cubrir todos los caminos de salida del proceso.
102
+ process.once("exit", cleanupRegistry);
103
+ process.once("SIGTERM", () => { cleanupRegistry(); process.exit(143); });
104
+ process.once("SIGINT", () => { cleanupRegistry(); process.exit(130); });
105
+
106
+ const emitter = new EventEmitter();
107
+ let activityLog = null;
108
+
109
+ // Mirror every progress event into .kj/run.log so kj-tail works identically
110
+ // whether the command came from the MCP server or the CLI (KJC-TSK-0327 follow-up).
111
+ forwardProgress(emitter);
112
+
113
+ emitter.on("progress", (event) => {
114
+ if (!activityLog && event.sessionId) {
115
+ activityLog = createActivityLog(event.sessionId);
116
+ logger.onLog((entry) => activityLog.write(entry));
117
+ }
118
+
119
+ if (activityLog) {
120
+ activityLog.writeEvent(event);
121
+ }
122
+
123
+ if (!jsonMode) {
124
+ printEvent(event, { quiet: quietMode });
125
+ }
126
+ });
127
+
128
+ if (!jsonMode) {
129
+ printHeader({ task: task, config });
130
+ }
131
+
132
+ const askQuestion = createCliAskQuestion({ flags });
133
+
134
+ // Autonomy (KJC-PCS-0062): wire the level to a resolver. In autonomous mode
135
+ // every gate is decided by the Arbiter instead of the human; interactive
136
+ // keeps the human prompts. The decider is threaded into the gates below.
137
+ const { autonomy, resolve: decide } = buildDecider({ config, flags, ask: askQuestion, logger });
138
+
139
+ // Spec-reviewer pre-pipeline audit (KJC-PCS-0048). Runs BEFORE
140
+ // anything else — surfaces ambiguity / missing scope / missing AC.
141
+ // In autonomous mode the Arbiter decides (never aborts); interactive
142
+ // lets the user bail. Bypass with --skip-spec-review.
143
+ const reviewResult = await runSpecReview({ spec: task, config, logger, askQuestion, flags, resolve: decide, autonomy });
144
+ if (!reviewResult.proceed) {
145
+ logger.info("Aborted by user after spec review.");
146
+ cleanupRegistry();
147
+ return { ok: false, aborted: true, reason: "spec-review-cancelled" };
148
+ }
149
+ // If the user refined the spec via [r]efine, downstream runs the
150
+ // REFINED text (not the original) so the pipeline acts on what the
151
+ // user actually approved.
152
+ const effectiveTask = reviewResult.refined && reviewResult.finalSpec ? reviewResult.finalSpec : task;
153
+
154
+ // AUTO-E: in autonomous mode the stages never ask a human or block on the
155
+ // board — they auto-continue with the least-bad choice. interactive/assisted
156
+ // keep the human prompts.
157
+ const stageAsk = createAutonomyAskQuestion({ baseAsk: askQuestion, autonomy, logger });
158
+
159
+ let result;
160
+ try {
161
+ result = await runFlow({ task: effectiveTask, config, logger, flags, emitter, askQuestion: stageAsk, pgTaskId: pgCardId || null, pgProject: pgProject || null });
162
+ } finally {
163
+ // KJC-TSK-0396: limpia el registro pase lo que pase (éxito,
164
+ // throw, o paused). Los handlers de SIGINT/SIGTERM/exit son
165
+ // backstop para casos donde el throw no llega aquí (segfault,
166
+ // kill -9, etc.).
167
+ cleanupRegistry();
168
+ }
169
+
170
+ if (jsonMode) {
171
+ console.log(JSON.stringify(result, null, 2));
172
+ } else {
173
+ // Last line printed: if the run stopped (hibernated / paused /
174
+ // failed), tell the user the exact command to resume it.
175
+ printResumeHint(result);
176
+ }
177
+ // Surface per-HU results so `kj autorun` can build a real outcome report
178
+ // (KJC-BUG-0090: it showed "0/0 met the ask" because only { ok } came back).
179
+ // The plan run returns them as `huResults` (run-hu-batch finalResult).
180
+ const hus = Array.isArray(result?.huResults)
181
+ ? result.huResults.map((r) => ({ id: r.huId, met: r.approved === true }))
182
+ : [];
183
+ return { ok: !result?.paused && result?.approved !== false, hus };
184
+ });
185
+ }
@@ -0,0 +1,18 @@
1
+ import { getOpenIssues, getQualityGateStatus } from "../sonar/api.js";
2
+ import { runSonarScan } from "../sonar/scanner.js";
3
+ import { summarizeIssues } from "../sonar/enforcer.js";
4
+
5
+ export async function scanCommand({ config }) {
6
+ const scan = await runSonarScan(config);
7
+ if (!scan.ok) {
8
+ throw new Error(`Sonar scan failed: ${scan.stderr || scan.stdout}`);
9
+ }
10
+
11
+ const gate = await getQualityGateStatus(config, scan.projectKey);
12
+ const issues = await getOpenIssues(config, scan.projectKey);
13
+
14
+ console.log(`Project key: ${scan.projectKey}`);
15
+ console.log(`Quality Gate: ${gate.status}`);
16
+ console.log(`Open issues: ${issues.total}`);
17
+ console.log(`By severity: ${summarizeIssues(issues.issues) || "none"}`);
18
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * `kj skills` — manage the local OpenSkills cache and the addyosmani catalog.
3
+ *
4
+ * Subcommands:
5
+ * - list : print cached OpenSkills with their age and freshness.
6
+ * - clear-cache : delete all cached metadata (forces re-install on next session).
7
+ * - sync-addyosmani : force a git pull of addyosmani/agent-skills.
8
+ * - list-addyosmani : enumerate slugs available in the cached catalog.
9
+ */
10
+
11
+ import { listCached, clearCache, getCacheRoot, DEFAULT_TTL_MS } from "../skills/skills-cache.js";
12
+ import { refreshIfStale, listAvailableSlugs, getCatalogRoot, loadSkillBySlug } from "../skills/addyosmani-catalog.js";
13
+
14
+ function humanAge(cachedAt) {
15
+ const ms = Date.now() - Date.parse(cachedAt);
16
+ if (!Number.isFinite(ms) || ms < 0) return "unknown";
17
+ const days = ms / (24 * 60 * 60 * 1000);
18
+ if (days < 1) return `${Math.max(1, Math.round(ms / (60 * 60 * 1000)))}h ago`;
19
+ return `${days.toFixed(1)}d ago`;
20
+ }
21
+
22
+ export async function skillsCommand({ action = "list" } = {}) {
23
+ switch (action) {
24
+ case "list":
25
+ return listAction();
26
+ case "clear-cache":
27
+ return clearAction();
28
+ case "sync-addyosmani":
29
+ return syncAddyosmaniAction();
30
+ case "list-addyosmani":
31
+ return listAddyosmaniAction();
32
+ default:
33
+ console.error(`Unknown action: ${action}. Use: list | clear-cache | sync-addyosmani | list-addyosmani`);
34
+ return 1;
35
+ }
36
+ }
37
+
38
+ async function listAction() {
39
+ const cache = await listCached();
40
+ if (cache.length === 0) {
41
+ console.log(`No cached skills at ${getCacheRoot()}`);
42
+ return 0;
43
+ }
44
+ console.log(`Cached skills (TTL ${Math.round(DEFAULT_TTL_MS / 86400000)}d) at ${getCacheRoot()}:\n`);
45
+ for (const entry of cache) {
46
+ const flag = entry.fresh ? "FRESH" : "STALE";
47
+ console.log(` ${flag} ${entry.name} (${humanAge(entry.cachedAt)})`);
48
+ }
49
+ return 0;
50
+ }
51
+
52
+ async function clearAction() {
53
+ const { removed } = await clearCache();
54
+ console.log(`Cleared ${removed} cached skill${removed === 1 ? "" : "s"} from ${getCacheRoot()}`);
55
+ return 0;
56
+ }
57
+
58
+ async function syncAddyosmaniAction() {
59
+ console.log("Syncing addyosmani/agent-skills catalog...");
60
+ const logger = { warn: (m) => console.warn(` warn: ${m}`), info: (m) => console.log(` ${m}`) };
61
+ const result = await refreshIfStale({ force: true, logger });
62
+ if (!result.ok) {
63
+ console.error(`Sync failed: ${result.error || result.action}`);
64
+ return 1;
65
+ }
66
+ const slugs = await listAvailableSlugs();
67
+ console.log(`${result.action === "cloned" ? "Cloned" : "Pulled"} at ${getCatalogRoot()}`);
68
+ console.log(`Available slugs: ${slugs.length}`);
69
+ return 0;
70
+ }
71
+
72
+ async function listAddyosmaniAction() {
73
+ const slugs = await listAvailableSlugs();
74
+ if (slugs.length === 0) {
75
+ console.log(`No addyosmani catalog found at ${getCatalogRoot()}`);
76
+ console.log("Run `kj skills sync-addyosmani` to bootstrap it.");
77
+ return 0;
78
+ }
79
+ console.log(`addyosmani/agent-skills catalog at ${getCatalogRoot()}\n${slugs.length} slug(s):\n`);
80
+ for (const slug of slugs) {
81
+ const skill = await loadSkillBySlug(slug);
82
+ const desc = skill?.description ? ` — ${skill.description.slice(0, 100)}${skill.description.length > 100 ? "..." : ""}` : "";
83
+ console.log(` ${slug}${desc}`);
84
+ }
85
+ return 0;
86
+ }
@@ -0,0 +1,53 @@
1
+ import os from "node:os";
2
+ import { sonarDown, sonarLogs, sonarStatus, sonarUp, isSonarReachable } from "../sonar/manager.js";
3
+ import { resolveSonarProjectKey } from "../sonar/project-key.js";
4
+ import { runCommand } from "../utils/process.js";
5
+
6
+ function openBrowserCmd() {
7
+ const platform = os.platform();
8
+ if (platform === "darwin") return "open";
9
+ if (platform === "win32") return "start";
10
+ return "xdg-open";
11
+ }
12
+
13
+ export async function sonarOpenCommand({ config }) {
14
+ const host = config?.sonarqube?.host || "http://localhost:9000";
15
+
16
+ if (!(await isSonarReachable(host))) {
17
+ return { ok: false, error: `SonarQube is not reachable at ${host}. Run 'kj sonar start' first.` };
18
+ }
19
+
20
+ let projectKey;
21
+ try {
22
+ projectKey = await resolveSonarProjectKey(config);
23
+ } catch (err) {
24
+ return { ok: false, error: err.message };
25
+ }
26
+
27
+ const url = `${host}/dashboard?id=${projectKey}`;
28
+ await runCommand(openBrowserCmd(), [url]);
29
+ return { ok: true, url };
30
+ }
31
+
32
+ export async function sonarCommand({ action }) {
33
+ if (action === "start") {
34
+ const res = await sonarUp();
35
+ console.log(res.stdout || res.stderr);
36
+ return;
37
+ }
38
+
39
+ if (action === "stop") {
40
+ const res = await sonarDown();
41
+ console.log(res.stdout || res.stderr);
42
+ return;
43
+ }
44
+
45
+ if (action === "logs") {
46
+ const res = await sonarLogs();
47
+ console.log(res.stdout || res.stderr);
48
+ return;
49
+ }
50
+
51
+ const res = await sonarStatus();
52
+ console.log(res.stdout || "stopped");
53
+ }
@@ -0,0 +1,117 @@
1
+ // KJC-TSK-0414 PR2: comandos kj standby list / kj resume.
2
+ //
3
+ // `kj resume <sessionId>` valida cooldownUntil y, si llegó la hora, re-spawn
4
+ // el comando original capturado en argv. Si cooldown todavía está en el
5
+ // futuro, muestra countdown y aborta. `kj standby list` solo enumera.
6
+ //
7
+ // Estrategia de resume: cada sessionState persiste su argv original (los
8
+ // argumentos con los que se lanzó el `kj` que hibernó). El resume re-spawn
9
+ // EXACTAMENTE ese mismo comando con env preservado. El run reanuda como si
10
+ // fuera un retry — el state interno (HU pendiente, snapshot_sha, etc.) está
11
+ // en el JSON persistido en disco por TSK-0408 + TSK-0414 PR1.
12
+
13
+ import { spawn } from "node:child_process";
14
+ import path from "node:path";
15
+ import { fileURLToPath } from "node:url";
16
+ import { loadStandby, listPendingStandby, markStandbyDone, acquireStandbyLock } from "../brain/standby-store.js";
17
+
18
+ const REPO_KJ_CLI = (() => {
19
+ try {
20
+ const here = path.dirname(fileURLToPath(import.meta.url));
21
+ return path.join(here, "..", "cli.js");
22
+ } catch {
23
+ return null;
24
+ }
25
+ })();
26
+
27
+ function formatCountdown(ms) {
28
+ if (ms <= 0) return "ahora";
29
+ const s = Math.round(ms / 1000);
30
+ const h = Math.floor(s / 3600);
31
+ const m = Math.floor((s % 3600) / 60);
32
+ const sec = s % 60;
33
+ return `${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")}:${String(sec).padStart(2, "0")}`;
34
+ }
35
+
36
+ export async function standbyListCommand({ json } = {}) {
37
+ const sessions = listPendingStandby();
38
+ if (json) {
39
+ console.log(JSON.stringify(sessions, null, 2));
40
+ return;
41
+ }
42
+ if (sessions.length === 0) {
43
+ console.log("No hay sesiones hibernadas.");
44
+ return;
45
+ }
46
+ console.log(`Sesiones hibernadas (${sessions.length}):`);
47
+ const now = Date.now();
48
+ for (const s of sessions) {
49
+ const ms = new Date(s.cooldownUntil).getTime() - now;
50
+ const status = ms <= 0 ? "✓ lista para resume" : `⏳ resume en ${formatCountdown(ms)}`;
51
+ console.log(` ${s.sessionId} · ${s.reason || "?"} · ${status}`);
52
+ if (s.planId) {
53
+ const huSuffix = s.huId ? `, HU: ${s.huId}` : "";
54
+ console.log(` plan: ${s.planId}${huSuffix}`);
55
+ }
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Re-spawn el comando original capturado en sessionState.argv.
61
+ * Si cooldownUntil > now y force=false → aborta con mensaje.
62
+ */
63
+ export async function resumeCommand({ sessionId, force } = {}) {
64
+ if (!sessionId) {
65
+ console.error("kj resume requiere <sessionId>. Usa `kj standby list` para ver pendientes.");
66
+ process.exitCode = 1;
67
+ return;
68
+ }
69
+ const state = loadStandby(sessionId);
70
+ if (!state) {
71
+ console.error(`Sesión no encontrada: ${sessionId}`);
72
+ process.exitCode = 1;
73
+ return;
74
+ }
75
+ const cooldownMs = new Date(state.cooldownUntil).getTime() - Date.now();
76
+ if (cooldownMs > 0 && !force) {
77
+ console.log(`Sesión ${sessionId} todavía en cooldown ${formatCountdown(cooldownMs)} (hasta ${state.cooldownUntil}).`);
78
+ console.log("Espera o usa `kj resume <sessionId> --force` (no recomendado — la API seguramente seguirá rechazando).");
79
+ process.exitCode = 0;
80
+ return;
81
+ }
82
+
83
+ const lock = acquireStandbyLock(sessionId);
84
+ if (!lock.acquired) {
85
+ console.log(`Sesión ${sessionId} ya está siendo reanudada por otro proceso.`);
86
+ process.exitCode = 0;
87
+ return;
88
+ }
89
+
90
+ try {
91
+ if (!Array.isArray(state.argv) || state.argv.length === 0) {
92
+ console.error(`Sesión ${sessionId} sin argv — no se puede re-spawn. Borra manual y relanza.`);
93
+ process.exitCode = 1;
94
+ return;
95
+ }
96
+ if (!REPO_KJ_CLI) {
97
+ console.error("No se pudo localizar cli.js. ¿Karajan instalado correctamente?");
98
+ process.exitCode = 1;
99
+ return;
100
+ }
101
+ console.log(`Reanudando ${sessionId}: kj ${state.argv.join(" ")}`);
102
+ const child = spawn(process.execPath, [REPO_KJ_CLI, ...state.argv], {
103
+ cwd: state.cwd || process.cwd(),
104
+ env: { ...process.env, ...(state.env || {}), KJ_RESUME_FROM: sessionId },
105
+ stdio: "inherit",
106
+ });
107
+ await new Promise((resolve) => {
108
+ child.on("exit", (code) => {
109
+ if (code === 0) markStandbyDone(sessionId);
110
+ process.exitCode = code ?? 0;
111
+ resolve();
112
+ });
113
+ });
114
+ } finally {
115
+ lock.release?.();
116
+ }
117
+ }
@@ -0,0 +1,121 @@
1
+ // KJC-TSK-0570 (Onboard C) — `kj start`: the single entry point to the Brain.
2
+ // Wires the read-only sweep (0568) → deterministic assessment (0569) → haiku
3
+ // decider (0569), reports the recommended next step, and — interactively only —
4
+ // confirms and dispatches the chosen intent to its saved command
5
+ // (harden/rag/run/plan). --json / --yes / no-TTY stay read-only: emit the
6
+ // assessment + intent and apply nothing. Collaborators are injected for testing.
7
+ import path from "node:path";
8
+ import { fileURLToPath } from "node:url";
9
+ import { execa } from "execa";
10
+ import { runReadOnlySweep } from "../start/sweep.js";
11
+ import { buildAssessment } from "../start/assessment.js";
12
+ import { StartDecidorRole } from "../start/start-decider-role.js";
13
+ import { createWizard, isTTY } from "../utils/wizard.js";
14
+
15
+ // The recommended next step shown for each intent.
16
+ const NEXT_STEP = {
17
+ ASSESS_ONLY: "Everything looks healthy — nothing to do.",
18
+ RECOMMEND_HARDEN: "Suggested: `kj harden --interactive`",
19
+ RECOMMEND_INDEX: "Suggested: `kj rag index`",
20
+ START_TASK: 'Suggested: `kj run "<task>"`',
21
+ PROPOSE_PLAN: 'Suggested: `kj plan "<goal>"`',
22
+ };
23
+
24
+ // Each writing intent maps to the saved command + args `kj start` dispatches.
25
+ const DISPATCH = {
26
+ RECOMMEND_HARDEN: () => ["harden", "--interactive"],
27
+ RECOMMEND_INDEX: () => ["rag", "index"],
28
+ START_TASK: (task) => ["run", task],
29
+ PROPOSE_PLAN: (task) => ["plan", task],
30
+ };
31
+
32
+ const ASK_FALLBACK = "What would you like to do with this project?";
33
+ const CLI_PATH = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "cli.js");
34
+
35
+ // Run a saved `kj` subcommand as a child, inheriting stdio so its own prompts
36
+ // (e.g. `harden --interactive`) drive the real terminal. Never throws here.
37
+ async function spawnKj(args, { cwd }) {
38
+ await execa("node", [CLI_PATH, ...args.filter(Boolean)], { cwd, stdio: "inherit", reject: false });
39
+ }
40
+
41
+ // The decider has its own quota/parse recovery; a spawn-level failure (CLI not
42
+ // installed) still throws, so we degrade here too — `kj start` never crashes.
43
+ async function decide({ task, text, config, logger, makeDecider }) {
44
+ const decider = makeDecider({ config, logger });
45
+ try {
46
+ const decision = await decider.execute({ userMessage: task, assessment: text });
47
+ return decision.result || {};
48
+ } catch (err) {
49
+ logger?.warn?.(`[start] decider unavailable (${err?.message || err}) — asking the user.`);
50
+ return { intent: "ASK_USER", rationale: "Decider unavailable.", questionToAsk: ASK_FALLBACK, degraded: true };
51
+ }
52
+ }
53
+
54
+ // Ask one yes/no, always closing the readline interface afterwards.
55
+ async function confirmApply(makeWizard) {
56
+ const wizard = makeWizard();
57
+ try {
58
+ return await wizard.confirm("Apply this?", true);
59
+ } finally {
60
+ wizard.close();
61
+ }
62
+ }
63
+
64
+ // Print the rationale + recommended step, or the open question for ASK_USER.
65
+ function render(result) {
66
+ if (result.intent === "ASK_USER") {
67
+ console.log(`❓ ${result.questionToAsk || ASK_FALLBACK}`);
68
+ return;
69
+ }
70
+ if (result.rationale) console.log(`→ ${result.rationale}`);
71
+ const step = NEXT_STEP[result.intent];
72
+ if (step) console.log(` ${step}`);
73
+ }
74
+
75
+ export async function startCommand({ task = "", config, logger, flags = {}, deps = {} }) {
76
+ const sweep = deps.runReadOnlySweep || runReadOnlySweep;
77
+ const assess = deps.buildAssessment || buildAssessment;
78
+ const makeDecider = deps.makeDecider || ((opts) => new StartDecidorRole(opts));
79
+ const tty = deps.isTTY || isTTY;
80
+ const spawn = deps.spawnKj || spawnKj;
81
+ const makeWizard = deps.makeWizard || (() => createWizard());
82
+
83
+ // KJC-BUG-0145 (campo, #1471): loadConfig never sets projectDir — passing
84
+ // config.projectDir straight through handed `undefined` to the sweep, every
85
+ // collector failed silently and the project read as "new, no source code".
86
+ const projectDir = config.projectDir || process.cwd();
87
+ const bundle = await sweep(projectDir, { declared: flags.maturity || null });
88
+ const { text, summary } = assess(bundle);
89
+ let result = await decide({ task, text, config, logger, makeDecider });
90
+
91
+ if (flags.json) {
92
+ console.log(JSON.stringify({ maturity: summary.maturity, assessment: text, ...result }, null, 2));
93
+ return { ok: true, intent: result.intent };
94
+ }
95
+
96
+ console.log(`${text}\n`);
97
+ const interactive = tty() && !flags.yes;
98
+ let goal = task;
99
+
100
+ // ASK_USER: one interactive re-route — the open answer becomes the goal.
101
+ if (result.intent === "ASK_USER" && interactive) {
102
+ const wizard = makeWizard();
103
+ try {
104
+ const answer = await wizard.input(`❓ ${result.questionToAsk || ASK_FALLBACK}`);
105
+ if (answer) {
106
+ goal = answer;
107
+ result = await decide({ task: answer, text, config, logger, makeDecider });
108
+ }
109
+ } finally {
110
+ wizard.close();
111
+ }
112
+ }
113
+ render(result);
114
+
115
+ // Dispatch the chosen intent to its saved command, confirming first (it writes).
116
+ const toArgs = DISPATCH[result.intent];
117
+ if (interactive && toArgs && (await confirmApply(makeWizard))) {
118
+ await spawn(toArgs(goal), { cwd: projectDir });
119
+ }
120
+ return { ok: true, intent: result.intent };
121
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * CLI status command — shows a terminal dashboard of the current pipeline state.
3
+ */
4
+
5
+ import { readRunLog } from "../utils/run-log.js";
6
+ import { loadMostRecentSession } from "../session/store.js";
7
+ import { buildDashboard } from "../utils/status-dashboard.js";
8
+
9
+
10
+ /**
11
+ * Run the `kj status` command: print a human-readable dashboard to stdout.
12
+ * @param {object} options
13
+ * @param {number} [options.lines=50] - Max log lines to read.
14
+ * @param {string} [options.projectDir] - Project directory override.
15
+ */
16
+ export async function statusCommand({ lines = 50, projectDir } = {}) {
17
+ const dir = projectDir || process.cwd();
18
+ const logResult = readRunLog(dir, lines);
19
+
20
+ let session = null;
21
+ try {
22
+ session = await loadMostRecentSession();
23
+ } catch { /* no session available */ }
24
+
25
+ let stories = [];
26
+ if (session) {
27
+ try {
28
+ const { loadHuBatch } = await import("../hu/store.js");
29
+ const batch = await loadHuBatch(session.id);
30
+ if (batch?.stories) stories = batch.stories;
31
+ } catch { /* no HU batch */ }
32
+ }
33
+
34
+ const dashboard = buildDashboard(session, logResult.lines || [], { stories });
35
+ console.log(dashboard);
36
+ }