@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,103 @@
1
+ /**
2
+ * `kj sync` — closed-loop drift detection between code and Canvas/plan.
3
+ * Issue #540 MVP: detection + report.
4
+ * KJC-TSK-0348: `--apply` writes drift notes back into the source Canvas
5
+ * markdown (with `.bak` backup) so the user can review + commit.
6
+ */
7
+
8
+ import fs from "node:fs";
9
+ import path from "node:path";
10
+ import { listPlans, loadPlan } from "../plan/plan-store.js";
11
+ import { classifyDrift, formatDriftReport } from "../sync/detect-drift.js";
12
+ import { applyCanvasPatch } from "../sync/apply-canvas-patch.js";
13
+
14
+ const SKIP_DIRS = new Set(["node_modules", ".git", "dist", "build", "coverage", ".karajan", ".kj", "tmp", ".cache", ".astro", ".next"]);
15
+
16
+ function listSourceFiles(rootDir, out = []) {
17
+ for (const e of fs.readdirSync(rootDir, { withFileTypes: true })) {
18
+ if (e.name.startsWith(".") && !["src", "tests"].includes(e.name)) continue;
19
+ if (SKIP_DIRS.has(e.name)) continue;
20
+ const p = path.join(rootDir, e.name);
21
+ if (e.isDirectory()) {
22
+ listSourceFiles(p, out);
23
+ } else if (e.isFile()) {
24
+ try {
25
+ const s = fs.statSync(p);
26
+ out.push({
27
+ path: path.relative(rootDir, p),
28
+ mtime: s.mtime,
29
+ });
30
+ } catch { /* ignore stat errors */ }
31
+ }
32
+ }
33
+ return out;
34
+ }
35
+
36
+ /**
37
+ * @param {object} args
38
+ * @param {object} args.config
39
+ * @param {object} args.logger
40
+ * @param {string} [args.planId] — when set, sync against this plan; else use the latest
41
+ * @param {boolean} [args.json]
42
+ * @param {boolean} [args.apply] — when true, write a drift patch back into
43
+ * the Canvas markdown the plan came from
44
+ * (with `.bak` backup).
45
+ */
46
+ export async function syncCommand({ config, logger, planId, json, apply }) {
47
+ const projectDir = config?.projectDir || process.cwd();
48
+
49
+ // Resolve which plan to sync against.
50
+ let plan;
51
+ if (planId) {
52
+ plan = await loadPlan(projectDir, planId);
53
+ if (!plan) throw new Error(`kj sync: plan not found: ${planId}`);
54
+ } else {
55
+ const all = await listPlans(projectDir);
56
+ if (!all || all.length === 0) {
57
+ throw new Error("kj sync: no plans found for this project. Generate one with `kj plan generate --task-file SPEC.md` (or `--canvas SPEC.canvas.md` for the structured form).");
58
+ }
59
+ // Pick the most recent plan by createdAt.
60
+ plan = await loadPlan(projectDir, all.sort((a, b) =>
61
+ new Date(b.createdAt || 0) - new Date(a.createdAt || 0))[0].planId);
62
+ }
63
+
64
+ logger.info(`kj sync: comparing ${projectDir} against plan ${plan.planId}`);
65
+
66
+ const files = listSourceFiles(projectDir);
67
+ const report = classifyDrift(plan, files);
68
+
69
+ let applyResult = null;
70
+ if (apply) {
71
+ if (!plan.sourceCanvasPath) {
72
+ throw new Error(
73
+ "kj sync --apply: this plan has no sourceCanvasPath — it was not generated from a SPEC.canvas.md. "
74
+ + "Re-run `kj plan generate --task-file SPEC.canvas.md` so the plan remembers the Canvas it came from."
75
+ );
76
+ }
77
+ applyResult = await applyCanvasPatch({ canvasPath: plan.sourceCanvasPath, report });
78
+ }
79
+
80
+ if (json) {
81
+ console.log(JSON.stringify({
82
+ planId: plan.planId,
83
+ projectDir,
84
+ ...report,
85
+ apply: applyResult,
86
+ }, null, 2));
87
+ } else {
88
+ console.log(formatDriftReport(report, plan));
89
+ if (applyResult) {
90
+ if (applyResult.skipped) {
91
+ console.log("\nkj sync --apply: no actionable drift, Canvas left untouched.");
92
+ } else {
93
+ console.log(
94
+ `\nkj sync --apply: wrote ${applyResult.mutations} drift note(s) to ${applyResult.patchedPath} `
95
+ + `(backup at ${applyResult.backupPath}).`
96
+ );
97
+ }
98
+ }
99
+ }
100
+
101
+ // Exit 0 always — drift is informational, not an error. CI users
102
+ // can opt-in to "exit non-zero on drift" later via a flag.
103
+ }
@@ -0,0 +1,70 @@
1
+ import { TELEMETRY_ENDPOINT, buildTelemetryPayload, isTelemetryEnabled } from "../utils/telemetry.js";
2
+
3
+ /**
4
+ * Render the exact payload that would be POSTed for every event type.
5
+ *
6
+ * Read-only by design: this never opens a socket. It exists so users
7
+ * can inspect what telemetry sends before (or after) opting in,
8
+ * without grepping the source. The contract here MUST stay in sync
9
+ * with the producers in src/cli/_shared.js and the pipeline emitter
10
+ * in src/orchestrator/flow-runner.js — if a new field appears there,
11
+ * mirror it in the example below.
12
+ */
13
+ function buildPreview(version) {
14
+ const v = version || "x.y.z";
15
+ return {
16
+ endpoint: TELEMETRY_ENDPOINT,
17
+ events: [
18
+ buildTelemetryPayload("install", { version: v }),
19
+ buildTelemetryPayload("cli_command", { version: v, command: "run" }),
20
+ buildTelemetryPayload("pipeline_complete", {
21
+ version: v,
22
+ mode: "standard",
23
+ agent: "claude",
24
+ duration_s: 42,
25
+ success: true,
26
+ taskType: "feature"
27
+ })
28
+ ]
29
+ };
30
+ }
31
+
32
+ export async function telemetryPreviewCommand({ config, logger, version, json }) {
33
+ const preview = buildPreview(version);
34
+ if (json) {
35
+ logger.info(JSON.stringify(preview, null, 2));
36
+ return preview;
37
+ }
38
+ const enabled = isTelemetryEnabled(config);
39
+ logger.info(`Telemetry endpoint: ${preview.endpoint}`);
40
+ logger.info(`Telemetry enabled: ${enabled ? "yes" : "no"}`);
41
+ logger.info("");
42
+ logger.info("Exact payloads that would be POSTed (one per event type):");
43
+ logger.info("");
44
+ for (const payload of preview.events) {
45
+ logger.info(` [${payload.event}]`);
46
+ logger.info(` ${JSON.stringify(payload)}`);
47
+ logger.info("");
48
+ }
49
+ logger.info("No data was sent — `kj telemetry preview` never opens a socket.");
50
+ return preview;
51
+ }
52
+
53
+ export async function telemetryStatusCommand({ config, logger, json }) {
54
+ const enabled = isTelemetryEnabled(config);
55
+ const report = {
56
+ enabled,
57
+ endpoint: TELEMETRY_ENDPOINT,
58
+ flipHint: enabled
59
+ ? "Set `telemetry: false` in ~/.karajan/kj.config.yml (or re-run `kj init`) to turn it off."
60
+ : "Set `telemetry: true` in ~/.karajan/kj.config.yml (or re-run `kj init`) to turn it on."
61
+ };
62
+ if (json) {
63
+ logger.info(JSON.stringify(report, null, 2));
64
+ return report;
65
+ }
66
+ logger.info(`Telemetry: ${enabled ? "enabled" : "disabled"}`);
67
+ logger.info(`Endpoint: ${report.endpoint}`);
68
+ logger.info(report.flipHint);
69
+ return report;
70
+ }
@@ -0,0 +1,85 @@
1
+ /**
2
+ * `kj tournament` (KJC-TSK-0723, TOR-A) — fan the SAME task out to N coders
3
+ * in N isolated worktree lanes and collect the evidence. The deterministic
4
+ * scoreboard (TOR-B) and the governed judgement/merge (TOR-C) build on the
5
+ * artifacts this command leaves under .kj/tournaments/<id>/.
6
+ */
7
+ import path from "node:path";
8
+ import { runTournament } from "../tournament/run.js";
9
+ import { scoreTournament } from "../tournament/scoreboard.js";
10
+ import { judgeTournament } from "../tournament/judge.js";
11
+ import { crownWinner } from "../tournament/crown.js";
12
+
13
+ // The id feeds a path — same traversal class codex caught in TOR-A's coder
14
+ // names: strict slug, no separators, before any filesystem use.
15
+ function tournamentDirFor(config, rawId) {
16
+ const id = String(rawId);
17
+ if (!/^[a-z0-9][a-z0-9-]{0,63}$/i.test(id)) {
18
+ throw new Error(`tournament: id inválido "${id}" — usa el id que imprimió el torneo (p. ej. tor-abc123)`);
19
+ }
20
+ return path.join(config?.projectDir || process.cwd(), ".kj", "tournaments", id);
21
+ }
22
+
23
+ export async function tournamentCommand({
24
+ task, config, logger = console, flags = {},
25
+ runTournamentFn = runTournament, scoreTournamentFn = scoreTournament,
26
+ judgeTournamentFn = judgeTournament, crownWinnerFn = crownWinner,
27
+ }) {
28
+ // TOR-C: `--judge <id>` ranks the finalists; `--crown <id>` commits the
29
+ // winner through the real gate in its lane.
30
+ if (flags.judge) {
31
+ const judgement = await judgeTournamentFn({ tournamentDir: tournamentDirFor(config, flags.judge), config, logger });
32
+ if (flags.json) logger?.info?.(JSON.stringify(judgement));
33
+ else logger?.info?.(` siguiente: kj tournament --crown ${flags.judge}${judgement.escalated ? " (ganador vía solomon)" : ""}`);
34
+ return judgement;
35
+ }
36
+ if (flags.crown) {
37
+ const crown = await crownWinnerFn({
38
+ tournamentDir: tournamentDirFor(config, flags.crown), config, logger, cardRef: flags.card || null,
39
+ });
40
+ if (flags.json) logger?.info?.(JSON.stringify(crown));
41
+ return crown;
42
+ }
43
+
44
+ // TOR-B: `--score <id>` scores an EXISTING tournament from its artifacts.
45
+ if (flags.score) {
46
+ const tournamentDir = tournamentDirFor(config, flags.score);
47
+ const board = await scoreTournamentFn({ tournamentDir });
48
+ if (flags.json) {
49
+ logger?.info?.(JSON.stringify(board));
50
+ return board;
51
+ }
52
+ logger?.info?.(`scoreboard ${board.id} — regla: ${board.rule}`);
53
+ for (const r of board.rows) {
54
+ if (!r.finalist) {
55
+ logger?.info?.(` ${r.coder.padEnd(10)} eliminado (${r.eliminated_by})`);
56
+ continue;
57
+ }
58
+ const mut = typeof r.mutation?.score === "number" ? `${r.mutation.score}%` : "n/a";
59
+ logger?.info?.(` ${r.coder.padEnd(10)} FINALISTA loc:${String(r.loc.net).padStart(5)} tests:${r.loc.testsTouched} mutation:${mut}`);
60
+ }
61
+ logger?.info?.(` ranking: ${board.ranking.join(" > ") || "(sin finalistas)"}`);
62
+ return board;
63
+ }
64
+
65
+ if (!task || !String(task).trim()) {
66
+ throw new Error("tournament: falta la tarea — kj tournament \"<tarea>\" --coders claude,codex");
67
+ }
68
+ const coders = String(flags.coders || "")
69
+ .split(",")
70
+ .map((c) => c.trim())
71
+ .filter(Boolean);
72
+ if (coders.length < 2) {
73
+ throw new Error("tournament: hacen falta al menos 2 en --coders — p. ej. --coders claude,codex,agy (con uno no hay torneo)");
74
+ }
75
+
76
+ const res = await runTournamentFn({ task, coders, config, logger });
77
+
78
+ const completed = res.lanes.filter((l) => l.status === "completed");
79
+ const green = completed.filter((l) => l.suite?.ok);
80
+ logger?.info?.("");
81
+ logger?.info?.(`torneo ${res.id}: ${completed.length}/${res.lanes.length} carriles completados, ${green.length} con suite verde`);
82
+ logger?.info?.(` evidencia: ${res.dir}`);
83
+ logger?.info?.(" siguiente: el scoreboard determinista (TOR-B) puntuará los carriles; de momento compara los diff.patch a mano.");
84
+ return res;
85
+ }
@@ -0,0 +1,78 @@
1
+ import { createAgent } from "../agents/index.js";
2
+ import { assertAgentsAvailable } from "../agents/availability.js";
3
+ import { resolveRole } from "../config.js";
4
+ import { createCliProgressReporter } from "../utils/cli-progress.js";
5
+ import { buildTriagePrompt } from "../prompts/triage.js";
6
+ import { parseMaybeJsonString } from "../review/parser.js";
7
+ import { withBrainRecovery } from "../brain/with-brain-recovery.js";
8
+
9
+ function formatTriage(result) {
10
+ const lines = [];
11
+ lines.push(`## Triage Result`);
12
+ lines.push(`- **Level:** ${result.level || "unknown"}`);
13
+ if (result.taskType) lines.push(`- **Task type:** ${result.taskType}`);
14
+ if (result.reasoning) lines.push(`- **Reasoning:** ${result.reasoning}`);
15
+ lines.push("");
16
+
17
+ if (result.roles?.length) {
18
+ lines.push("### Recommended Roles");
19
+ for (const r of result.roles) {
20
+ lines.push(`- ${r}`);
21
+ }
22
+ lines.push("");
23
+ }
24
+
25
+ if (result.shouldDecompose) {
26
+ lines.push("### Decomposition Suggested");
27
+ if (result.subtasks?.length) {
28
+ for (const s of result.subtasks) {
29
+ lines.push(`- ${typeof s === "string" ? s : s.title || s}`);
30
+ }
31
+ }
32
+ lines.push("");
33
+ }
34
+
35
+ return lines.join("\n");
36
+ }
37
+
38
+ export async function triageCommand({ task, config, logger, json }) {
39
+ const { withCliRunLog } = await import("../utils/cli-run-log.js");
40
+ return withCliRunLog("triage", { projectDir: config?.projectDir, logger }, async ({ runLog }) => {
41
+ const triageRole = resolveRole(config, "triage");
42
+ await assertAgentsAvailable([triageRole.provider]);
43
+ logger.info(`Triage (${triageRole.provider}) starting...`);
44
+ runLog.logText(`[triage] provider=${triageRole.provider}`);
45
+
46
+ const agent = createAgent(triageRole.provider, config, logger);
47
+ const prompt = buildTriagePrompt({ task });
48
+ const progress = createCliProgressReporter({ role: "triage" });
49
+ let result;
50
+ try {
51
+ result = await withBrainRecovery({
52
+ agent, taskArgs: { prompt, onOutput: progress.onOutput, role: "triage" },
53
+ role: "triage", provider: triageRole.provider, logger,
54
+ });
55
+ progress.finish(result.ok ? "done" : (result.action || "failed"));
56
+ } catch (err) { progress.finish("failed"); throw err; }
57
+
58
+ if (!result.ok) {
59
+ throw new Error(result.error || result.output || "Triage failed");
60
+ }
61
+
62
+ const parsed = parseMaybeJsonString(result.output);
63
+ if (parsed?.level) runLog.logText(`[triage] level=${parsed.level} roles=${(parsed.roles || []).join(",")}`);
64
+
65
+ if (json) {
66
+ console.log(JSON.stringify(parsed || result.output, null, 2));
67
+ return { ok: true };
68
+ }
69
+
70
+ if (parsed?.level) {
71
+ console.log(formatTriage(parsed));
72
+ } else {
73
+ console.log(result.output);
74
+ }
75
+ logger.info("Triage completed.");
76
+ return { ok: true };
77
+ });
78
+ }
@@ -0,0 +1,62 @@
1
+ import { loadMostRecentSession } from "../session/store.js";
2
+ import { runCommand } from "../utils/process.js";
3
+
4
+ /**
5
+ * Revert the last pipeline run by resetting to the pre-pipeline commit.
6
+ * Default: soft reset (keeps changes staged). With --hard: discards all changes.
7
+ */
8
+ export async function undoCommand({ hard = false, logger } = {}) {
9
+ const session = await loadMostRecentSession();
10
+ if (!session) {
11
+ const msg = "No session to undo. No sessions found in the sessions directory.";
12
+ if (logger) logger.error(msg);
13
+ return { ok: false, error: msg };
14
+ }
15
+
16
+ const sha = session.session_start_sha;
17
+ if (!sha) {
18
+ const msg = `Session ${session.id} has no session_start_sha. Cannot determine the pre-pipeline commit.`;
19
+ if (logger) logger.error(msg);
20
+ return { ok: false, error: msg };
21
+ }
22
+
23
+ // Verify the SHA exists in git history
24
+ const verifyRes = await runCommand("git", ["cat-file", "-t", sha]);
25
+ if (verifyRes.exitCode !== 0 || verifyRes.stdout.trim() !== "commit") {
26
+ const msg = `Commit ${sha} not found in git history. It may have been garbage-collected or belong to a different repository.`;
27
+ if (logger) logger.error(msg);
28
+ return { ok: false, error: msg };
29
+ }
30
+
31
+ // Check there are commits after the SHA (HEAD is ahead)
32
+ const logRes = await runCommand("git", ["log", "--oneline", `${sha}..HEAD`]);
33
+ if (logRes.exitCode !== 0 || !logRes.stdout.trim()) {
34
+ const msg = `No commits to undo. HEAD is already at or before ${sha.slice(0, 8)}.`;
35
+ if (logger) logger.warn(msg);
36
+ return { ok: false, error: msg };
37
+ }
38
+
39
+ const mode = hard ? "--hard" : "--soft";
40
+ const resetRes = await runCommand("git", ["reset", mode, sha]);
41
+ if (resetRes.exitCode !== 0) {
42
+ const msg = `git reset ${mode} ${sha} failed: ${resetRes.stderr || resetRes.stdout}`;
43
+ if (logger) logger.error(msg);
44
+ return { ok: false, error: msg };
45
+ }
46
+
47
+ const shortSha = sha.slice(0, 8);
48
+ const message = hard
49
+ ? `Reverted to pre-pipeline state (commit ${shortSha}). All changes discarded.`
50
+ : `Reverted to pre-pipeline state (commit ${shortSha}). Changes are staged. Use \`git diff --cached\` to review.`;
51
+
52
+ if (logger) logger.info(message);
53
+ console.log(message);
54
+
55
+ return {
56
+ ok: true,
57
+ message,
58
+ sessionId: session.id,
59
+ sha,
60
+ mode: hard ? "hard" : "soft"
61
+ };
62
+ }
@@ -0,0 +1,46 @@
1
+ // KJC-TSK-0441 — `kj watch [start|stop|status]`. Thin wrappers.
2
+ import { spawn } from "node:child_process";
3
+ import { fileURLToPath } from "node:url";
4
+ import { dirname, join } from "node:path";
5
+ import { startWatcher, readPidFile, clearPidFile, isPidAlive, writePidFile } from "../rag/watcher.js";
6
+
7
+ const HERE = dirname(fileURLToPath(import.meta.url));
8
+
9
+ export async function watchStartCommand({ config, logger, flags = {} }) {
10
+ const projectDir = config?.projectDir || process.cwd();
11
+ const existing = readPidFile();
12
+ if (existing && isPidAlive(existing)) { logger.info(`Watcher already running (pid ${existing}).`); return { pid: existing, started: false }; }
13
+ if (existing) clearPidFile();
14
+ if (flags.foreground) {
15
+ writePidFile();
16
+ const stop = startWatcher({ projectDir, config, logger, withSources: !!flags.withSources });
17
+ const shutdown = async () => { await stop(); clearPidFile(); process.exit(0); };
18
+ process.on("SIGINT", shutdown).on("SIGTERM", shutdown);
19
+ logger.info(`Watcher started in foreground (pid ${process.pid}). Ctrl+C to stop.`);
20
+ return { pid: process.pid, started: true };
21
+ }
22
+ const args = [join(HERE, "..", "cli.js"), "watch", "start", "--foreground", ...(flags.withSources ? ["--with-sources"] : [])];
23
+ const child = spawn(process.execPath, args, { detached: true, stdio: "ignore", env: { ...process.env, KJ_WATCHER_DAEMON: "1" } });
24
+ child.unref();
25
+ logger.info(`Watcher started in background (pid ${child.pid}).`);
26
+ return { pid: child.pid, started: true };
27
+ }
28
+
29
+ export async function watchStopCommand({ logger }) {
30
+ const pid = readPidFile();
31
+ if (!pid) { logger.info("No watcher running."); return { stopped: false }; }
32
+ if (!isPidAlive(pid)) { clearPidFile(); logger.info(`Stale PID file removed (process ${pid} was not alive).`); return { stopped: false, stale: true }; }
33
+ try { process.kill(pid, "SIGTERM"); } catch (err) { logger.warn(`Could not signal pid ${pid}: ${err.message}`); }
34
+ clearPidFile();
35
+ logger.info(`Watcher (pid ${pid}) stopped.`);
36
+ return { stopped: true, pid };
37
+ }
38
+
39
+ export async function watchStatusCommand({ logger }) {
40
+ const pid = readPidFile();
41
+ const alive = pid && isPidAlive(pid);
42
+ if (alive) logger.info(`Watcher running (pid ${pid}).`);
43
+ else if (pid) logger.warn(`Stale PID file (process ${pid} not alive). Run \`kj watch stop\` to clean up.`);
44
+ else logger.info("Watcher is NOT running.");
45
+ return { pid, alive };
46
+ }
@@ -0,0 +1,162 @@
1
+ /**
2
+ * `kj webperf <url>` — KJC-TSK-0149.
3
+ *
4
+ * Headless Lighthouse wrapper. Produces structured CWV + opportunities
5
+ * JSON. Writes the result into `~/.karajan/webperf/<projectSlug>/last.json`
6
+ * so future `kj audit` runs can surface the verdict via the existing
7
+ * WebPerf section (KJC-TSK-0360 cwv-result mode).
8
+ */
9
+
10
+ import fs from "node:fs/promises";
11
+ import path from "node:path";
12
+ import yaml from "js-yaml";
13
+ import { runWebperfScan } from "../webperf/scanner.js";
14
+ import { withCliRunLog } from "../utils/cli-run-log.js";
15
+
16
+ // Delegated to src/utils/paths.js (KJC-TSK-0420) — respects
17
+ // KARAJAN_HOME / KJ_HOME / VITEST tmp / default.
18
+ import { getWebperfDir } from "../utils/paths.js";
19
+ function defaultReportDir() { return getWebperfDir(); }
20
+
21
+ /**
22
+ * Slug a project directory the same way audit/basal-cost.js and
23
+ * plan/plan-store.js do, so the per-project webperf history aligns
24
+ * with audit history under ~/.karajan/.
25
+ */
26
+ function projectSlug(projectDir) {
27
+ return path.basename(projectDir || process.cwd()).replaceAll(/[^a-zA-Z0-9_-]/g, "_");
28
+ }
29
+
30
+ function formatHumanReport(result) {
31
+ if (!result.ok) {
32
+ return `WebPerf scan FAILED — ${result.reason}`;
33
+ }
34
+ const lines = ["## WebPerf Scan", ""];
35
+ lines.push(`- URL: ${result.url}`);
36
+ lines.push(`- Preset: ${result.preset}`);
37
+ lines.push(`- Captured: ${result.capturedAt}`);
38
+ if (result.lighthouseVersion) lines.push(`- Lighthouse: v${result.lighthouseVersion}`);
39
+ if (typeof result.performanceScore === "number") {
40
+ lines.push(`- Performance score: ${result.performanceScore}/100`);
41
+ }
42
+ lines.push("");
43
+ lines.push(`### Verdict: ${result.cwv.pass ? "PASS" : "FAIL"}`);
44
+ lines.push("");
45
+ lines.push("### Core Web Vitals");
46
+ for (const [metric, score] of Object.entries(result.cwv.scores || {})) {
47
+ const value = formatMetricValue(metric, score.value);
48
+ lines.push(`- ${metric.toUpperCase()}: ${value} (${score.rating})`);
49
+ }
50
+ if (result.cwv.blocking?.length) {
51
+ lines.push("");
52
+ lines.push("### Blocking metrics (above poor threshold)");
53
+ for (const b of result.cwv.blocking) {
54
+ lines.push(`- ${b.metric.toUpperCase()}: ${formatMetricValue(b.metric, b.value)} > ${formatMetricValue(b.metric, b.threshold)}`);
55
+ }
56
+ }
57
+ if (result.issues?.length) {
58
+ lines.push("");
59
+ lines.push(`### Top opportunities (${result.issues.length})`);
60
+ for (const issue of result.issues.slice(0, 10)) {
61
+ const savings = issue.savingsMs ? ` (saves ~${Math.round(issue.savingsMs)}ms)` : "";
62
+ lines.push(`- [${issue.severity.toUpperCase()}] ${issue.id}${savings}: ${issue.title}`);
63
+ }
64
+ if (result.issues.length > 10) {
65
+ lines.push(`- ... and ${result.issues.length - 10} more`);
66
+ }
67
+ }
68
+ return lines.join("\n");
69
+ }
70
+
71
+ function formatMetricValue(metric, value) {
72
+ if (typeof value !== "number") return "n/a";
73
+ if (metric === "cls") return value.toFixed(3);
74
+ return `${Math.round(value)}ms`;
75
+ }
76
+
77
+ /**
78
+ * Persist the scan result into ~/.karajan/webperf/<slug>/last.json so
79
+ * `kj audit` can read it via collectWebPerfInput (KJC-TSK-0360).
80
+ */
81
+ async function persistResult(result, projectDir) {
82
+ if (!result.ok) return null;
83
+ const dir = path.join(defaultReportDir(), projectSlug(projectDir));
84
+ await fs.mkdir(dir, { recursive: true });
85
+ const filePath = path.join(dir, "last.json");
86
+ await fs.writeFile(filePath, JSON.stringify(result, null, 2), "utf8");
87
+ return filePath;
88
+ }
89
+
90
+ /**
91
+ * Optionally update kj.config.yml so `kj audit` finds the result by
92
+ * default (mirrors how sonar config is wired). Best-effort: never
93
+ * fails the command; absence of config file or write error is logged.
94
+ */
95
+ async function patchConfigLastResult(configPath, lastResultPath, logger) {
96
+ if (!configPath || !lastResultPath) return false;
97
+ let raw;
98
+ try { raw = await fs.readFile(configPath, "utf8"); } catch { return false; }
99
+ let parsed;
100
+ try { parsed = yaml.load(raw) || {}; } catch (err) {
101
+ if (logger?.warn) logger.warn(`webperf: cannot parse ${configPath}: ${err.message}`);
102
+ return false;
103
+ }
104
+ parsed.webperf = parsed.webperf || {};
105
+ parsed.webperf.lastResultPath = lastResultPath;
106
+ try {
107
+ await fs.writeFile(configPath, yaml.dump(parsed), "utf8");
108
+ return true;
109
+ } catch (err) {
110
+ if (logger?.warn) logger.warn(`webperf: cannot write ${configPath}: ${err.message}`);
111
+ return false;
112
+ }
113
+ }
114
+
115
+ export async function webperfCommand({ url, config, logger, json = false, mobile = false, persist = true, thresholds = null }) {
116
+ if (!url) {
117
+ throw new Error("kj webperf: <url> is required (e.g. http://localhost:3000)");
118
+ }
119
+ return withCliRunLog("webperf", { projectDir: config?.projectDir, logger }, async ({ runLog }) => {
120
+ logger.info(`Running webperf scan against ${url} (preset: ${mobile ? "mobile" : "desktop"})`);
121
+ runLog.logText(`[webperf] scan url=${url} preset=${mobile ? "mobile" : "desktop"}`);
122
+
123
+ const scanThresholds = thresholds || config?.webperf?.thresholds || null;
124
+ const result = await runWebperfScan(url, {
125
+ preset: mobile ? "mobile" : "desktop",
126
+ thresholds: scanThresholds,
127
+ logger,
128
+ });
129
+
130
+ if (json) {
131
+ console.log(JSON.stringify(result, null, 2));
132
+ } else {
133
+ console.log(formatHumanReport(result));
134
+ }
135
+
136
+ if (!result.ok) {
137
+ runLog.logText(`[webperf] failed reason=${result.reason}`);
138
+ return { ok: false, reason: result.reason };
139
+ }
140
+
141
+ runLog.logText(`[webperf] verdict=${result.cwv.pass ? "PASS" : "FAIL"} score=${result.performanceScore}`);
142
+
143
+ let savedPath = null;
144
+ if (persist) {
145
+ try {
146
+ savedPath = await persistResult(result, config?.projectDir);
147
+ if (savedPath) {
148
+ logger.info(`WebPerf result saved: ${savedPath}`);
149
+ // Wire into kj.config.yml so `kj audit` picks it up automatically.
150
+ const configPath = config?.configFilePath
151
+ || path.join(config?.projectDir || process.cwd(), ".karajan", "kj.config.yml");
152
+ await patchConfigLastResult(configPath, savedPath, logger);
153
+ }
154
+ } catch (err) {
155
+ logger.warn(`webperf: persist failed (non-blocking): ${err.message}`);
156
+ }
157
+ }
158
+
159
+ // Exit code: 0 for PASS, 1 for FAIL. Lets CI gate on it.
160
+ return { ok: result.cwv.pass, result, savedPath };
161
+ });
162
+ }