karajan-code 4.70.4 → 5.0.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 (380) hide show
  1. package/README.md +2 -2
  2. package/package.json +6 -14
  3. package/packages/hu-board/package.json +1 -1
  4. package/packages/hu-board/public/app.js +4 -18
  5. package/packages/hu-board/public/index.html +5 -2
  6. package/packages/hu-board/public/styles.css +26 -0
  7. package/packages/hu-board/public/utils/api.js +0 -74
  8. package/packages/hu-board/public/utils/board-tour.js +62 -0
  9. package/packages/hu-board/public/utils/board-view.js +49 -144
  10. package/packages/hu-board/public/utils/command-launcher.js +8 -70
  11. package/packages/hu-board/public/utils/formatters.js +10 -0
  12. package/packages/hu-board/public/utils/governance-view.js +13 -1
  13. package/packages/hu-board/public/utils/hu-actions.js +17 -68
  14. package/packages/hu-board/public/utils/init-listeners.js +7 -8
  15. package/packages/hu-board/public/utils/log-panel.js +3 -16
  16. package/packages/hu-board/public/utils/maggle-mode.js +2 -12
  17. package/packages/hu-board/public/utils/modals.js +7 -0
  18. package/packages/hu-board/public/utils/project-picker-view.js +1 -1
  19. package/packages/hu-board/public/utils/server-push.js +3 -22
  20. package/packages/hu-board/public/utils/shared-board-notice.js +33 -0
  21. package/packages/hu-board/public/utils/story-detail-view.js +5 -19
  22. package/packages/hu-board/src/cleanup-zombies.js +0 -1
  23. package/packages/hu-board/src/command-runner.js +36 -25
  24. package/packages/hu-board/src/db-connection.js +282 -0
  25. package/packages/hu-board/src/db-paths.js +113 -0
  26. package/packages/hu-board/src/db-queries.js +188 -0
  27. package/packages/hu-board/src/db-tombstones.js +51 -0
  28. package/packages/hu-board/src/db.js +28 -619
  29. package/packages/hu-board/src/ephemeral-cleaner.js +2 -3
  30. package/packages/hu-board/src/hu-zombie-reaper.js +5 -1
  31. package/packages/hu-board/src/plan-mutations.js +3 -153
  32. package/packages/hu-board/src/plans-service.js +55 -0
  33. package/packages/hu-board/src/routes/api/commands.js +122 -0
  34. package/packages/hu-board/src/routes/api/plans.js +55 -0
  35. package/packages/hu-board/src/routes/api/projects.js +267 -0
  36. package/packages/hu-board/src/routes/api/prompts.js +135 -0
  37. package/packages/hu-board/src/routes/api/sessions.js +95 -0
  38. package/packages/hu-board/src/routes/api/stories.js +183 -0
  39. package/packages/hu-board/src/routes/api/system.js +241 -0
  40. package/packages/hu-board/src/routes/api/tombstones.js +38 -0
  41. package/packages/hu-board/src/routes/api.js +24 -1371
  42. package/packages/hu-board/src/routes/governance.js +23 -1
  43. package/packages/hu-board/src/routes/lanes.js +40 -0
  44. package/packages/hu-board/src/routes/rag.js +4 -3
  45. package/packages/hu-board/src/server.js +20 -34
  46. package/packages/hu-board/src/sync-files.js +318 -0
  47. package/packages/hu-board/src/sync-project.js +99 -0
  48. package/packages/hu-board/src/sync.js +22 -566
  49. package/packages/hu-board/src/zombie-reaper.js +1 -1
  50. package/scripts/dual-publish.mjs +19 -3
  51. package/scripts/postinstall.js +15 -2
  52. package/scripts/verify-pack-mcp.mjs +11 -7
  53. package/scripts/verify-pack.mjs +4 -4
  54. package/src/audit/audit-history.js +3 -2
  55. package/src/audit/dead-exports.js +68 -59
  56. package/src/audit/deterministic-summary.js +33 -13
  57. package/src/audit/npm-signatures.js +41 -0
  58. package/src/audit/sbom.js +35 -0
  59. package/src/checks/agent-token.js +112 -0
  60. package/src/checks/dir-setup.js +34 -1
  61. package/src/checks/native-build.js +21 -39
  62. package/src/checks/runner.js +128 -142
  63. package/src/cli/advanced-commands.js +6 -6
  64. package/src/cli/register-meta.js +42 -82
  65. package/src/cli/register-pipeline.js +8 -143
  66. package/src/cli/register-plan.js +9 -100
  67. package/src/cli/retired-commands.js +49 -0
  68. package/src/cli.js +18 -5
  69. package/src/commands/agent-run.js +40 -26
  70. package/src/commands/audit.js +127 -124
  71. package/src/commands/board.js +5 -9
  72. package/src/commands/check.js +29 -16
  73. package/src/commands/doctor.js +2 -0
  74. package/src/commands/env.js +176 -150
  75. package/src/commands/go.js +71 -53
  76. package/src/commands/harden.js +90 -81
  77. package/src/commands/hu-start.js +52 -0
  78. package/src/commands/hu.js +288 -221
  79. package/src/commands/identity.js +111 -78
  80. package/src/commands/init-atril.js +47 -0
  81. package/src/commands/init.js +11 -40
  82. package/src/commands/install-tools.js +70 -85
  83. package/src/commands/main-guard.js +78 -0
  84. package/src/commands/policy.js +226 -184
  85. package/src/commands/qmd.js +27 -21
  86. package/src/commands/rag.js +75 -48
  87. package/src/commands/review-gate.js +421 -341
  88. package/src/commands/start.js +4 -5
  89. package/src/commands/steward.js +96 -47
  90. package/src/commands/tournament.js +46 -37
  91. package/src/commands/worktree.js +94 -25
  92. package/src/config/loader.js +34 -17
  93. package/src/config/secrets.js +36 -0
  94. package/src/config.js +1 -0
  95. package/src/environment/adr.js +16 -2
  96. package/src/git/karajan-label.js +20 -8
  97. package/src/guards/main-guard.js +54 -0
  98. package/src/harden/hook-templates.js +16 -1
  99. package/src/harden/sentinel/posttooluse.mjs +18 -6
  100. package/src/harden/sentinel/pretooluse-sentinel.mjs +64 -36
  101. package/src/harden/sentinel/sentinel-lib.mjs +129 -26
  102. package/src/harden/sentinel/sentinel-shell.mjs +5 -16
  103. package/src/harden/sentinel/sessionstart.mjs +3 -2
  104. package/src/harden/sentinel/stop.mjs +5 -4
  105. package/src/harden/workflow-templates.js +1 -1
  106. package/src/hu/board-lookup.js +29 -0
  107. package/src/hu/gh-identity.js +23 -0
  108. package/src/hu/github-board.js +4 -2
  109. package/src/hu/lane-prune.js +15 -7
  110. package/src/hu/lane-setup.js +65 -0
  111. package/src/hu/lanes.js +66 -0
  112. package/src/hu/team-board-mirror.js +3 -2
  113. package/src/infrastructure/command-runner.js +1 -1
  114. package/src/infrastructure/file-system-service.js +1 -1
  115. package/src/mcp/handlers/direct-handlers.js +2 -292
  116. package/src/mcp/handlers/hu-handlers.js +1 -35
  117. package/src/mcp/handlers/management-handlers.js +2 -42
  118. package/src/mcp/server-handlers.js +16 -22
  119. package/src/mcp/tools.js +1 -196
  120. package/src/plan/lane-plans.js +54 -0
  121. package/src/plan/plan-store.js +7 -4
  122. package/src/policy/add.js +26 -12
  123. package/src/policy/adr-number-check.js +31 -0
  124. package/src/prompts/audit.js +299 -339
  125. package/src/prompts/card-context.js +10 -5
  126. package/src/prompts/reviewer.js +5 -2
  127. package/src/rag/auto-update.js +56 -43
  128. package/src/rag/bootstrap-index.js +28 -54
  129. package/src/rag/migrate.js +1 -1
  130. package/src/rag/onnx-fallback.js +2 -2
  131. package/src/rag/pid-lease.js +70 -0
  132. package/src/rag/project-store.js +2 -12
  133. package/src/review/card-first.js +57 -46
  134. package/src/review/gate-gitignore.js +23 -4
  135. package/src/review/gate-hook.js +12 -4
  136. package/src/review/one-shot-review.js +45 -35
  137. package/src/review/publish-pr.js +14 -2
  138. package/src/review/repo-docs.js +73 -0
  139. package/src/review/repo-stack.js +59 -0
  140. package/src/review/reviewer-fallback.js +19 -4
  141. package/src/review/seal-commit.js +29 -0
  142. package/src/review/sonar-pregate.js +59 -44
  143. package/src/review/third-party-review.js +90 -16
  144. package/src/review/third-party-size.js +43 -0
  145. package/src/review/third-party-skills.js +54 -0
  146. package/src/review/verify-pr.js +1 -24
  147. package/src/roles/audit-role.js +106 -125
  148. package/src/skills/atril-skills.js +5 -4
  149. package/src/sonar/scanner.js +116 -101
  150. package/src/steward/invariants.js +5 -4
  151. package/src/steward/phantom-sweep.js +66 -0
  152. package/src/tournament/judge.js +60 -53
  153. package/src/utils/gh-account.js +37 -0
  154. package/src/utils/git.js +0 -13
  155. package/src/utils/home-migration.js +7 -1
  156. package/src/utils/main-checkout.js +53 -0
  157. package/src/utils/qmd-collection.js +3 -1
  158. package/src/utils/welcome.js +3 -3
  159. package/templates/{skills → atril/commands}/kj-architect.md +5 -0
  160. package/templates/{skills → atril/commands}/kj-audit.md +5 -0
  161. package/templates/{skills → atril/commands}/kj-board.md +5 -0
  162. package/templates/{skills → atril/commands}/kj-code.md +5 -0
  163. package/templates/{skills → atril/commands}/kj-csv-transform.md +5 -0
  164. package/templates/{skills → atril/commands}/kj-data-report.md +5 -0
  165. package/templates/{skills → atril/commands}/kj-discover.md +5 -0
  166. package/templates/{skills → atril/commands}/kj-rag-query.md +5 -0
  167. package/templates/{skills → atril/commands}/kj-review.md +5 -0
  168. package/templates/{skills → atril/commands}/kj-security.md +5 -0
  169. package/templates/{skills → atril/commands}/kj-sonar.md +5 -0
  170. package/templates/{skills → atril/commands}/kj-sql-analysis.md +5 -0
  171. package/templates/{skills → atril/commands}/kj-test.md +5 -0
  172. package/packages/hu-board/public/utils/run-launcher.js +0 -169
  173. package/packages/hu-board/src/run-tracker.js +0 -121
  174. package/src/activity-log.js +0 -59
  175. package/src/agents/host-agent.js +0 -38
  176. package/src/agents/model-registry.js +0 -142
  177. package/src/audit/plan-adherence.js +0 -224
  178. package/src/autonomy/arbiter-role.js +0 -71
  179. package/src/autonomy/arbiter.js +0 -22
  180. package/src/autonomy/decider.js +0 -18
  181. package/src/autonomy/decision-resolver.js +0 -58
  182. package/src/autonomy/outcome-report.js +0 -55
  183. package/src/autonomy/stage-ask.js +0 -30
  184. package/src/brain/decision-tracker.js +0 -125
  185. package/src/brain/decisor.js +0 -243
  186. package/src/brain/solomon-consult.js +0 -171
  187. package/src/brain/standby-scheduler.js +0 -8
  188. package/src/budget/comparison.js +0 -96
  189. package/src/canvas/parse-md.js +0 -238
  190. package/src/canvas/schema.js +0 -101
  191. package/src/canvas/to-flat.js +0 -85
  192. package/src/canvas/validate.js +0 -163
  193. package/src/ci/dispatch.js +0 -99
  194. package/src/ci/index.js +0 -3
  195. package/src/ci/pr-diff.js +0 -26
  196. package/src/cli/register-standby.js +0 -26
  197. package/src/commands/architect.js +0 -111
  198. package/src/commands/autorun.js +0 -49
  199. package/src/commands/researcher.js +0 -54
  200. package/src/commands/resume.js +0 -72
  201. package/src/commands/review.js +0 -89
  202. package/src/commands/run.js +0 -185
  203. package/src/commands/standby.js +0 -117
  204. package/src/commands/status.js +0 -36
  205. package/src/commands/triage.js +0 -78
  206. package/src/commands/undo.js +0 -62
  207. package/src/domains/domain-loader.js +0 -245
  208. package/src/domains/domain-registry.js +0 -140
  209. package/src/domains/domain-synthesizer.js +0 -129
  210. package/src/git/automation.js +0 -433
  211. package/src/git/coder-commit-guard.js +0 -40
  212. package/src/git/hu-automation.js +0 -243
  213. package/src/git/hu-snapshot.js +0 -10
  214. package/src/git/symlink-targets.js +0 -57
  215. package/src/golden/asserter.js +0 -92
  216. package/src/golden/loader.js +0 -52
  217. package/src/golden/runner.js +0 -92
  218. package/src/golden/schema.js +0 -41
  219. package/src/guards/duplicate-members.js +0 -86
  220. package/src/guards/intent-guard.js +0 -161
  221. package/src/guards/perf-guard.js +0 -126
  222. package/src/guards/policy-guard.js +0 -90
  223. package/src/guards/policy-resolver.js +0 -85
  224. package/src/guards/secret-redactor.js +0 -71
  225. package/src/hu/acceptance-runner.js +0 -138
  226. package/src/hu/lazy-planner.js +0 -109
  227. package/src/hu/parallel-executor.js +0 -94
  228. package/src/hu/routing-metrics.js +0 -17
  229. package/src/hu/split-validator.js +0 -143
  230. package/src/hu/splitting-detector.js +0 -158
  231. package/src/hu/splitting-generator.js +0 -175
  232. package/src/hu/store.js +0 -394
  233. package/src/infrastructure/mocks.js +0 -182
  234. package/src/mcp/handlers/run-handler.js +0 -318
  235. package/src/mcp/sovereignty-guard.js +0 -113
  236. package/src/mcp/tool-arg-normalizers.js +0 -16
  237. package/src/mutate/reviewer-signal.js +0 -76
  238. package/src/orchestrator/agent-fallback.js +0 -81
  239. package/src/orchestrator/brain-coordinator.js +0 -186
  240. package/src/orchestrator/ci-integration.js +0 -139
  241. package/src/orchestrator/config-init.js +0 -426
  242. package/src/orchestrator/direct-actions.js +0 -217
  243. package/src/orchestrator/drivers/error-recovery.js +0 -287
  244. package/src/orchestrator/drivers/init-context.js +0 -238
  245. package/src/orchestrator/drivers/iteration-loop.js +0 -382
  246. package/src/orchestrator/drivers/iteration-phases/coder-and-refactorer.js +0 -69
  247. package/src/orchestrator/drivers/iteration-phases/guards.js +0 -91
  248. package/src/orchestrator/drivers/iteration-phases/handle-approved.js +0 -29
  249. package/src/orchestrator/drivers/iteration-phases/quality-gates.js +0 -125
  250. package/src/orchestrator/drivers/iteration-phases/reviewer-gate.js +0 -62
  251. package/src/orchestrator/drivers/post-loop.js +0 -404
  252. package/src/orchestrator/drivers/pre-loop-phases/auto-hu-batch.js +0 -137
  253. package/src/orchestrator/drivers/pre-loop-phases/config-deprecations.js +0 -47
  254. package/src/orchestrator/drivers/pre-loop-phases/ensure-addyosmani-skills.js +0 -84
  255. package/src/orchestrator/drivers/pre-loop-phases/inject-loaded-plan.js +0 -393
  256. package/src/orchestrator/drivers/pre-loop.js +0 -524
  257. package/src/orchestrator/drivers/run-hu-batch.js +0 -468
  258. package/src/orchestrator/feedback-enrichment.js +0 -140
  259. package/src/orchestrator/feedback-queue.js +0 -151
  260. package/src/orchestrator/flow-control.js +0 -170
  261. package/src/orchestrator/flow-runner.js +0 -365
  262. package/src/orchestrator/fs-leak-detector.js +0 -228
  263. package/src/orchestrator/hu-scheduler.js +0 -114
  264. package/src/orchestrator/hu-sub-pipeline.js +0 -642
  265. package/src/orchestrator/iteration-gate.js +0 -73
  266. package/src/orchestrator/iteration-stages.js +0 -9
  267. package/src/orchestrator/parallel-limiter.js +0 -74
  268. package/src/orchestrator/pipeline-context.js +0 -72
  269. package/src/orchestrator/post-loop-stages.js +0 -468
  270. package/src/orchestrator/pre-loop-stages.js +0 -11
  271. package/src/orchestrator/preflight-checks.js +0 -487
  272. package/src/orchestrator/repair/repair-detector.js +0 -117
  273. package/src/orchestrator/repair/repair-runner.js +0 -142
  274. package/src/orchestrator/reviewer-fallback.js +0 -45
  275. package/src/orchestrator/role-output-compressor.js +0 -189
  276. package/src/orchestrator/session-journal.js +0 -308
  277. package/src/orchestrator/solomon-escalation.js +0 -331
  278. package/src/orchestrator/solomon-rules.js +0 -212
  279. package/src/orchestrator/stages/acceptance-coverage-stage.js +0 -47
  280. package/src/orchestrator/stages/architect-stage.js +0 -172
  281. package/src/orchestrator/stages/coder-stage.js +0 -506
  282. package/src/orchestrator/stages/domain-curator-stage.js +0 -82
  283. package/src/orchestrator/stages/format-stage.js +0 -61
  284. package/src/orchestrator/stages/hu-reviewer-phases/detect-and-apply-splits.js +0 -127
  285. package/src/orchestrator/stages/hu-reviewer-stage.js +0 -419
  286. package/src/orchestrator/stages/perf-stage.js +0 -140
  287. package/src/orchestrator/stages/planner-stage.js +0 -85
  288. package/src/orchestrator/stages/rag-context-stage.js +0 -80
  289. package/src/orchestrator/stages/rag-preload-decisor.js +0 -58
  290. package/src/orchestrator/stages/research-stage.js +0 -69
  291. package/src/orchestrator/stages/reviewer-stage.js +0 -431
  292. package/src/orchestrator/stages/sonar-stage.js +0 -439
  293. package/src/orchestrator/stages/stage-classes.js +0 -84
  294. package/src/orchestrator/stages/stage-executor.js +0 -155
  295. package/src/orchestrator/stages/suite-green-stage.js +0 -62
  296. package/src/orchestrator/stages/tdd-discipline-stage.js +0 -56
  297. package/src/orchestrator/stages/tool-judge-stage.js +0 -53
  298. package/src/orchestrator/stages/triage-stage.js +0 -172
  299. package/src/orchestrator/standby.js +0 -71
  300. package/src/orchestrator/verification-gate.js +0 -183
  301. package/src/orchestrator.js +0 -22
  302. package/src/plan/adr-generator.js +0 -170
  303. package/src/plan/adr-loader.js +0 -60
  304. package/src/plan/plan-executor.js +0 -100
  305. package/src/plan/plan-validation.js +0 -4
  306. package/src/prompts/acceptance-coverage.js +0 -32
  307. package/src/prompts/arbiter.js +0 -38
  308. package/src/prompts/architect.js +0 -103
  309. package/src/prompts/hu-reviewer.js +0 -244
  310. package/src/prompts/tool-correctness-judge.js +0 -31
  311. package/src/prompts/triage.js +0 -57
  312. package/src/rag/embedder.js +0 -2
  313. package/src/rag/embedders/_cloud-base.js +0 -2
  314. package/src/rag/embedders/cohere.js +0 -2
  315. package/src/rag/embedders/mistral.js +0 -2
  316. package/src/rag/embedders/onnx.js +0 -2
  317. package/src/rag/embedders/openai.js +0 -2
  318. package/src/rag/embedders/voyage.js +0 -2
  319. package/src/rag/rerank.js +0 -4
  320. package/src/rag/where-parser.js +0 -4
  321. package/src/repeat-detector.js +0 -88
  322. package/src/review/diff-generator.js +0 -112
  323. package/src/review/git-stash-helper.js +0 -104
  324. package/src/review/schema.js +0 -31
  325. package/src/review/scope-filter.js +0 -152
  326. package/src/review/snapshot-diff.js +0 -122
  327. package/src/review/tdd-discipline.js +0 -90
  328. package/src/review/tdd-policy.js +0 -69
  329. package/src/roles/acceptance-coverage-role.js +0 -78
  330. package/src/roles/architect-role.js +0 -77
  331. package/src/roles/coder-role.js +0 -113
  332. package/src/roles/commiter-role.js +0 -113
  333. package/src/roles/domain-curator-role.js +0 -134
  334. package/src/roles/hu-reviewer-role.js +0 -64
  335. package/src/roles/impeccable-role.js +0 -85
  336. package/src/roles/index.js +0 -18
  337. package/src/roles/karajan-brain-role.js +0 -134
  338. package/src/roles/perf-role.js +0 -122
  339. package/src/roles/planner-role.js +0 -151
  340. package/src/roles/refactorer-role.js +0 -30
  341. package/src/roles/repairer-role.js +0 -181
  342. package/src/roles/researcher-role.js +0 -70
  343. package/src/roles/reviewer-role.js +0 -115
  344. package/src/roles/security-role.js +0 -73
  345. package/src/roles/solomon-role.js +0 -271
  346. package/src/roles/sonar-role.js +0 -72
  347. package/src/roles/tester-role.js +0 -235
  348. package/src/roles/tool-correctness-judge-role.js +0 -78
  349. package/src/roles/triage-role.js +0 -99
  350. package/src/session/journal/decisions-writer.js +0 -200
  351. package/src/session/journal/iteration-logger.js +0 -194
  352. package/src/session/journal/summary-writer.js +0 -320
  353. package/src/session/journal/tree-writer.js +0 -164
  354. package/src/session/journal/write-all.js +0 -89
  355. package/src/session-cleanup.js +0 -116
  356. package/src/skills/semantic-detector.js +0 -167
  357. package/src/skills/skill-detector.js +0 -385
  358. package/src/sonar/cloud-scanner.js +0 -78
  359. package/src/tracker-bootstrap.js +0 -44
  360. package/src/types/index.js +0 -38
  361. package/src/types/policy.js +0 -43
  362. package/src/types/solomon.js +0 -87
  363. package/src/utils/async-lock.js +0 -31
  364. package/src/utils/budget.js +0 -229
  365. package/src/utils/cwd-confirm.js +0 -39
  366. package/src/utils/display/event-handlers.js +0 -403
  367. package/src/utils/display/formatters.js +0 -132
  368. package/src/utils/display/header.js +0 -47
  369. package/src/utils/display/session-summary.js +0 -118
  370. package/src/utils/display/solomon.js +0 -42
  371. package/src/utils/pricing.js +0 -29
  372. package/src/utils/quota-simulator.js +0 -56
  373. package/src/utils/role-assigner.js +0 -137
  374. package/src/utils/rtk-wrapper.js +0 -87
  375. package/src/utils/run-registry.js +0 -9
  376. package/src/utils/status-dashboard.js +0 -254
  377. package/src/utils/tool-call-extractor.js +0 -56
  378. package/src/webperf/devtools-detect.js +0 -112
  379. package/src/webperf/webperf-role-integration.js +0 -66
  380. package/templates/skills/kj-run.md +0 -73
package/src/mcp/tools.js CHANGED
@@ -48,91 +48,6 @@ export const tools = [
48
48
  }
49
49
  }
50
50
  },
51
- {
52
- name: "kj_run",
53
- description:
54
- "Run the full Karajan pipeline. IMPORTANT: Pass the user's task description exactly as they wrote it. Do NOT group, split, reorder, or modify tasks yourself. Karajan handles decomposition, role activation, iteration, and quality gates internally. Do NOT override pipeline parameters (enableHuReviewer, mode, methodology) unless the user explicitly requested it. If you have observations about the task, use kj_suggest instead.",
55
- inputSchema: {
56
- type: "object",
57
- properties: {
58
- task: { type: "string", description: "Task description for the coder (can include a Planning Game card ID like KJC-TSK-0042). Either `task` or `taskFile` is required." },
59
- taskFile: { type: "string", description: "Alternative to `task`: path to a .md (or any text file) whose contents become the task description. Relative paths resolve against projectDir." },
60
- plan: { type: "string", description: "Plan ID from kj_plan. Loads persisted plan context and skips researcher/architect/planner stages." },
61
- projectDir: { type: "string", description: "Absolute path to the project directory. Required when KJ MCP server runs from a different directory than the target project." },
62
- pgTask: { type: "string", description: "Planning Game card ID (e.g., KJC-TSK-0042). If provided, fetches full card details as task context and updates card status on completion." },
63
- pgProject: { type: "string", description: "Planning Game project ID (e.g., 'Karajan Code'). Required when pgTask is used." },
64
- planner: { type: "string" },
65
- coder: { type: "string" },
66
- reviewer: { type: "string" },
67
- refactorer: { type: "string" },
68
- plannerModel: { type: "string" },
69
- coderModel: { type: "string" },
70
- reviewerModel: { type: "string" },
71
- refactorerModel: { type: "string" },
72
- enablePlanner: { type: "boolean" },
73
- enableReviewer: { type: "boolean" },
74
- enableRefactorer: { type: "boolean" },
75
- enableResearcher: { type: "boolean" },
76
- enableTester: { type: "boolean" },
77
- enableSecurity: { type: "boolean" },
78
- enableImpeccable: { type: "boolean" },
79
- enablePerf: { type: "boolean" },
80
- enableTriage: { type: "boolean" },
81
- enableDiscover: { type: "boolean" },
82
- enableArchitect: { type: "boolean" },
83
- enableHuReviewer: { type: "boolean" },
84
- architectModel: { type: "string" },
85
- huFile: { type: "string", description: "Path to YAML file with HU stories to certify before coding" },
86
- enableSerena: { type: "boolean" },
87
- enableCi: { type: "boolean", description: "Enable Karajan CI (early PR + dispatch comments/reviews)" },
88
- reviewerFallback: { type: "string" },
89
- reviewerRetries: { type: "number" },
90
- mode: { type: "string" },
91
- maxIterations: { type: "number" },
92
- maxIterationMinutes: { type: "number" },
93
- maxTotalMinutes: { type: "number" },
94
- baseBranch: { type: "string" },
95
- baseRef: { type: "string" },
96
- methodology: { type: "string", enum: ["tdd", "standard"] },
97
- autoCommit: { type: "boolean" },
98
- autoPush: { type: "boolean" },
99
- autoPr: { type: "boolean" },
100
- autoRebase: { type: "boolean" },
101
- branchPrefix: { type: "string" },
102
- autoSimplify: { type: "boolean", description: "Auto-simplify pipeline for simple tasks (level trivial/simple). Disable with false to force full pipeline." },
103
- smartModels: { type: "boolean", description: "Enable/disable smart model selection based on triage complexity" },
104
- checkpointInterval: { type: "number", description: "Minutes between interactive checkpoints (default: 5). Set 0 to disable." },
105
- taskType: { type: "string", enum: ["sw", "infra", "doc", "add-tests", "refactor"], description: "Explicit task type for policy resolution. Overrides triage classification." },
106
- quiet: { type: "boolean", description: "Suppress raw agent output lines, show only stage status (default: true). Set false for verbose output." },
107
- noSonar: { type: "boolean" },
108
- design: { type: "boolean", description: "Activate design refactoring mode. Impeccable role applies design changes instead of just auditing." },
109
- enableSonarcloud: { type: "boolean", description: "Enable SonarCloud scan (complementary to SonarQube)" },
110
- kjHome: { type: "string" },
111
- sonarToken: { type: "string" },
112
- timeoutMs: { type: "number" },
113
- domain: { type: "string", description: "Domain knowledge: inline text describing the project domain, or absolute path to a .md file. Auto-saved to .karajan/domains/ for the curator." },
114
- brain: { type: "string", enum: ["on", "off"], description: "Brain decisor: on|off. Controls whether intent-driven routing overrides pipeline flags." },
115
- forceRole: { type: "array", items: { type: "string" }, description: "Force roles ON regardless of triage (e.g. [\"security\"])" },
116
- skipRole: { type: "array", items: { type: "string" }, description: "Force roles OFF regardless of triage (e.g. [\"tester\"])" },
117
- specReviewMode: { type: "string", enum: ["auto", "skip"], description: "Pre-pipeline spec-reviewer behaviour (KJC-PCS-0048). `auto` (default): the role runs, findings stream to the client via progress events; the pipeline continues regardless. `skip`: bypass the reviewer entirely (mirrors the --skip-spec-review CLI flag)." }
118
- }
119
- }
120
- },
121
- {
122
- name: "kj_resume",
123
- description:
124
- "Resume a paused, stopped, or failed session by ID. For paused sessions, provide an answer. For stopped/failed sessions, re-runs the flow from scratch. Sends real-time progress notifications via MCP logging.",
125
- inputSchema: {
126
- type: "object",
127
- required: ["sessionId"],
128
- properties: {
129
- sessionId: { type: "string", description: "Session ID to resume" },
130
- answer: { type: "string", description: "Answer to the question that caused the pause" },
131
- projectDir: { type: "string", description: "Absolute path to the project directory" },
132
- kjHome: { type: "string" }
133
- }
134
- }
135
- },
136
51
  {
137
52
  name: "kj_report",
138
53
  description: "Read latest or list session reports. Use trace=true for chronological stage-by-stage breakdown with timing and token usage.",
@@ -176,7 +91,7 @@ export const tools = [
176
91
  },
177
92
  {
178
93
  name: "kj_preflight",
179
- description: "Confirm or adjust agent configuration before first kj_run/kj_code. REQUIRED before running any task via MCP. Show the config to the human, get their confirmation or adjustments, then call this tool with their response.",
94
+ description: "Confirm or adjust agent configuration before first kj_code. REQUIRED before running any task via MCP. Show the config to the human, get their confirmation or adjustments, then call this tool with their response.",
180
95
  inputSchema: {
181
96
  type: "object",
182
97
  required: ["humanResponse"],
@@ -207,50 +122,6 @@ export const tools = [
207
122
  }
208
123
  }
209
124
  },
210
- {
211
- name: "kj_review",
212
- description: "Run reviewer-only mode against current diff. Do NOT filter or pre-process the diff before passing it.",
213
- inputSchema: {
214
- type: "object",
215
- properties: {
216
- task: { type: "string", description: "Task description. Either `task` or `taskFile` is required." },
217
- taskFile: { type: "string", description: "Alternative to `task`: path to a .md/text file." },
218
- reviewer: { type: "string" },
219
- reviewerModel: { type: "string" },
220
- baseRef: { type: "string" },
221
- projectDir: { type: "string", description: "Absolute path to the project directory" },
222
- kjHome: { type: "string" }
223
- }
224
- }
225
- },
226
- {
227
- name: "kj_status",
228
- description: "Show real-time status and log of the current or last Karajan run. Returns a parsed status (current stage, agent, iteration, errors) plus recent log lines. Use this to monitor progress while kj_run/kj_plan/kj_code is executing.",
229
- inputSchema: {
230
- type: "object",
231
- properties: {
232
- lines: { type: "number", description: "Number of log lines to show (default 50)" }
233
- }
234
- }
235
- },
236
- {
237
- name: "kj_plan",
238
- description: "Generate implementation plan for a task. Pass the task as the user described it. Karajan's planner decides the approach.",
239
- inputSchema: {
240
- type: "object",
241
- properties: {
242
- task: { type: "string", description: "Task description. Either `task` or `taskFile` is required." },
243
- taskFile: { type: "string", description: "Alternative to `task`: path to a .md/text file." },
244
- planner: { type: "string" },
245
- plannerModel: { type: "string" },
246
- coder: { type: "string", description: "Legacy alias for planner" },
247
- coderModel: { type: "string", description: "Legacy alias for plannerModel" },
248
- projectDir: { type: "string", description: "Absolute path to the project directory" },
249
- kjHome: { type: "string" },
250
- specReviewMode: { type: "string", enum: ["auto", "skip"], description: "Pre-planner spec-reviewer behaviour (KJC-PCS-0048). `auto` (default): runs the reviewer, findings stream as progress, planner continues. `skip`: bypass entirely." }
251
- }
252
- }
253
- },
254
125
  {
255
126
  name: "kj_discover",
256
127
  description: "Analyze a task for gaps, ambiguities, and missing information before execution. Returns a verdict (ready/needs_validation) with structured gap list. Can read task details from Planning Game if pgTask is provided.",
@@ -268,46 +139,6 @@ export const tools = [
268
139
  }
269
140
  }
270
141
  },
271
- {
272
- name: "kj_triage",
273
- description: "Classify task complexity and recommend which pipeline roles to activate. Returns level (trivial/simple/medium/complex), taskType, recommended roles, and optional decomposition.",
274
- inputSchema: {
275
- type: "object",
276
- properties: {
277
- task: { type: "string", description: "Task description to classify. Either `task` or `taskFile` is required." },
278
- taskFile: { type: "string", description: "Alternative to `task`: path to a .md/text file." },
279
- projectDir: { type: "string", description: "Absolute path to the project directory" },
280
- kjHome: { type: "string" }
281
- }
282
- }
283
- },
284
- {
285
- name: "kj_researcher",
286
- description: "Research the codebase for a task. Identifies affected files, patterns, constraints, prior decisions, risks, and test coverage.",
287
- inputSchema: {
288
- type: "object",
289
- properties: {
290
- task: { type: "string", description: "Task description to research. Either `task` or `taskFile` is required." },
291
- taskFile: { type: "string", description: "Alternative to `task`: path to a .md/text file." },
292
- projectDir: { type: "string", description: "Absolute path to the project directory" },
293
- kjHome: { type: "string" }
294
- }
295
- }
296
- },
297
- {
298
- name: "kj_architect",
299
- description: "Design solution architecture for a task. Returns layers, patterns, data model, API contracts, tradeoffs, and a verdict (ready/needs_clarification).",
300
- inputSchema: {
301
- type: "object",
302
- properties: {
303
- task: { type: "string", description: "Task description to architect. Either `task` or `taskFile` is required." },
304
- taskFile: { type: "string", description: "Alternative to `task`: path to a .md/text file." },
305
- context: { type: "string", description: "Additional context (e.g., researcher output)" },
306
- projectDir: { type: "string", description: "Absolute path to the project directory" },
307
- kjHome: { type: "string" }
308
- }
309
- }
310
- },
311
142
  {
312
143
  name: "kj_audit",
313
144
  description: "Analyze codebase health without modifying files. Returns findings across security, code quality, performance, architecture, and testing dimensions.",
@@ -363,32 +194,6 @@ export const tools = [
363
194
  }
364
195
  }
365
196
  },
366
- {
367
- name: "kj_skills",
368
- description: "Manage OpenSkills for domain-specific agent knowledge. Install skills from the marketplace or GitHub repos to give coders domain expertise.",
369
- inputSchema: {
370
- type: "object",
371
- properties: {
372
- action: { type: "string", enum: ["install", "remove", "list", "read"], description: "Action to perform" },
373
- source: { type: "string", description: "Skill source: marketplace name, GitHub URL, or local path (for install)" },
374
- name: { type: "string", description: "Skill name (for remove/read)" },
375
- global: { type: "boolean", description: "Install globally (~/.agent/skills/) instead of project-local" },
376
- projectDir: { type: "string", description: "Project directory" }
377
- },
378
- required: ["action"]
379
- }
380
- },
381
- {
382
- name: "kj_undo",
383
- description: "Revert the last pipeline run by resetting to the pre-pipeline commit. Default: soft reset (keeps changes staged). Use hard=true to discard all changes.",
384
- inputSchema: {
385
- type: "object",
386
- properties: {
387
- hard: { type: "boolean", description: "If true, discard all changes (git reset --hard). Default: false (soft reset, keeps changes staged)." },
388
- projectDir: { type: "string", description: "Absolute path to the project directory" }
389
- }
390
- }
391
- },
392
197
  {
393
198
  name: "kj_clean",
394
199
  description: "Garbage-collect stale Karajan state: orphan plans (project dir no longer exists), finalised plans/sessions past their retention window, and HU story batches. Dry-run by default; pass yes=true to actually delete. Use nuke=true to wipe everything (retention=0 on every bucket + drop the HU board SQLite DB).",
@@ -0,0 +1,54 @@
1
+ /**
2
+ * #2566: a lane (<main>/.kj/worktrees/<x>, <main>/.claude/worktrees/<x>) kept plans under its own
3
+ * slug; `kj hu list` moves them to the main checkout's. A taken name is kept and reported.
4
+ */
5
+ import fs from "node:fs/promises";
6
+ import path from "node:path";
7
+ import { plansDir } from "./plan-store.js";
8
+ import { mainCheckout } from "../utils/main-checkout.js";
9
+ import { MIRROR_PLAN_ID } from "../hu/team-board-mirror.js";
10
+
11
+ const LANE_DIRS = [".kj_worktrees_", ".claude_worktrees_"];
12
+
13
+ // Never overwrites: "wx" and errorOnExist fail with EEXIST if another session wrote dest first.
14
+ async function moveEntry(from, dest, main) {
15
+ const plan = from.endsWith(".json") ? await fs.readFile(from, "utf8").then(JSON.parse, () => null) : null;
16
+ if (plan) {
17
+ // TSK-0341: the stamp must outlive the lane, or the GC sees the plan as orphan.
18
+ await fs.writeFile(dest, JSON.stringify({ ...plan, projectDir: main }, null, 2), { flag: "wx" });
19
+ return fs.unlink(from);
20
+ }
21
+ await fs.cp(from, dest, { recursive: true, force: false, errorOnExist: true });
22
+ return fs.rm(from, { recursive: true });
23
+ }
24
+
25
+ export async function migrateLanePlans(projectDir) {
26
+ const [target, main] = [plansDir(projectDir), mainCheckout(projectDir)];
27
+ const root = path.dirname(target);
28
+ const prefixes = LANE_DIRS.map((d) => `${path.basename(target)}_${d}`); // the main checkout's slug
29
+ const moved = [];
30
+ const kept = [];
31
+ let entries;
32
+ try { entries = await fs.readdir(root, { withFileTypes: true }); } catch (err) {
33
+ if (err.code === "ENOENT") return { moved, kept };
34
+ throw err;
35
+ }
36
+ const isLaneFolder = (e) => e.isDirectory() && prefixes.some((p) => e.name.startsWith(p));
37
+ for (const lane of entries.filter(isLaneFolder)) {
38
+ const from = path.join(root, lane.name);
39
+ await fs.mkdir(target, { recursive: true });
40
+ for (const file of await fs.readdir(from)) {
41
+ // The team board mirror is no plan: `kj hu list` rewrites it from GitHub, a lane's copy is stale.
42
+ if (file === `${MIRROR_PLAN_ID}.json`) { await fs.unlink(path.join(from, file)); continue; }
43
+ try {
44
+ await moveEntry(path.join(from, file), path.join(target, file), main);
45
+ moved.push(file);
46
+ } catch (err) {
47
+ if (err.code !== "EEXIST" && err.code !== "ERR_FS_CP_EEXIST") throw err;
48
+ kept.push(path.join(from, file));
49
+ }
50
+ }
51
+ await fs.rmdir(from).catch((err) => { if (err.code !== "ENOTEMPTY") throw err; }); // a collision stays
52
+ }
53
+ return { moved, kept };
54
+ }
@@ -10,6 +10,7 @@ import { writeJsonAtomic } from "../utils/atomic-write.js";
10
10
  import { resolveHome } from "../utils/paths.js";
11
11
  import { getSharedPlansDir } from "../utils/shared-paths.js";
12
12
  import { generatePlanId, normaliseAlias } from "./plan-id.js";
13
+ import { mainCheckout } from "../utils/main-checkout.js";
13
14
 
14
15
  /**
15
16
  * A plan JSON file failed to parse — typically an interrupted write
@@ -51,7 +52,7 @@ export function getKjHome() {
51
52
  /**
52
53
  * Deterministic slug for a project path — stable across plan-store writes,
53
54
  * HU-board syncs and board URL routing. Keep in lockstep with
54
- * `packages/hu-board/src/sync.js::deriveProjectIdFromDir`.
55
+ * `packages/hu-board/src/sync.js::deriveProjectIdFromDir` (kj slugs the main checkout, #2566).
55
56
  * @param {string} projectDir - absolute project path
56
57
  * @returns {string}
57
58
  */
@@ -64,12 +65,13 @@ export function projectSlug(projectDir) {
64
65
  }
65
66
 
66
67
  // KJC-TSK-1166: the board honours KJ_PLANS_DIR as its plans root; what kj writes must land
67
- // in the same root, or the board shows none of it.
68
+ // in the same root, or the board shows none of it. #2566: one folder per main checkout, lanes included.
68
69
  export function plansDir(projectDir) {
69
70
  const root = process.env.KJ_PLANS_DIR || path.join(getKjHome(), "plans");
70
- return path.join(root, projectSlug(projectDir));
71
+ return path.join(root, projectSlug(mainCheckout(projectDir)));
71
72
  }
72
73
 
74
+
73
75
  /**
74
76
  * Save a plan to disk. Accepts both v1 and v2 schemas.
75
77
  * @param {string} projectDir
@@ -88,7 +90,8 @@ export async function savePlan(projectDir, planResult) {
88
90
  // plan so the GC can check `fs.exists(projectDir)` reliably. Reverse-
89
91
  // engineering it from the slug is lossy (underscores in the original
90
92
  // name collide with underscores introduced by slash-substitution).
91
- if (!planResult.projectDir && projectDir) planResult.projectDir = projectDir;
93
+ // #2566: the main checkout, never a lane that is deleted after merge.
94
+ if (!planResult.projectDir && projectDir) planResult.projectDir = mainCheckout(projectDir);
92
95
  // Humanización IDs: si el plan no tiene alias todavía, derívalo de
93
96
  // plan.name (lo que el planner pidió al usuario). Resuelve
94
97
  // colisiones con sufijo -2, -3… leyendo el dir antes.
package/src/policy/add.js CHANGED
@@ -67,31 +67,29 @@ const naiveDiff = (oldText, newText) => {
67
67
  ].join("\n");
68
68
  };
69
69
 
70
- export async function policyAddCommand({ text, config = {}, flags = {}, logger = console, deps = {} }) {
71
- const projectDir = config?.projectDir || process.cwd();
72
- if (!text?.trim()) {
73
- logger.error?.('policy add: falta la regla — kj policy add "el coder no toca los workflows"');
74
- return 1;
75
- }
76
- const { translateFn = defaultTranslate } = deps;
77
- const raw = await translateFn({ text, config, logger });
70
+ // The agent's answer as a policy fragment, or null (said) when it is not one:
71
+ // untranslatable, not YAML, or keys outside the closed vocabulary.
72
+ function fragmentOf(raw, logger) {
78
73
  if (raw.includes("NO_TRADUCIBLE")) {
79
74
  logger.error?.("policy add: la regla no cabe en el vocabulario cerrado v1 — no se inventa nada; exprésala como write/shell/diff-threshold o queda como instrucción de prompt");
80
- return 1;
75
+ return null;
81
76
  }
82
77
  let frag;
83
78
  try {
84
79
  frag = yaml.load(raw);
85
80
  } catch (err) {
86
81
  logger.error?.(`policy add: el agente no devolvió YAML válido (${err.message}) — nada que aplicar`);
87
- return 1;
82
+ return null;
88
83
  }
89
84
  if (typeof frag !== "object" || frag === null || Object.keys(frag).some((k) => !["roles", "invariants"].includes(k))) {
90
85
  logger.error?.("policy add: el fragmento solo puede declarar roles y/o invariants — rechazado (vocabulario cerrado)");
91
- return 1;
86
+ return null;
92
87
  }
88
+ return frag;
89
+ }
93
90
 
94
- const file = join(projectDir, ".karajan", "policy.yml");
91
+ // The current policy merged with the fragment, or null (said) when the engine rejects it.
92
+ function proposePolicy(file, frag, logger) {
95
93
  let current = "";
96
94
  try {
97
95
  current = readFileSync(file, "utf8");
@@ -102,8 +100,24 @@ export async function policyAddCommand({ text, config = {}, flags = {}, logger =
102
100
  if (errors.length > 0) {
103
101
  for (const e of errors) logger.error?.(`✗ ${e}`);
104
102
  logger.error?.("policy add: la regla traducida no valida contra el vocabulario del motor — rechazada, no se inventa");
103
+ return null;
104
+ }
105
+ return { current, proposed };
106
+ }
107
+
108
+ export async function policyAddCommand({ text, config = {}, flags = {}, logger = console, deps = {} }) {
109
+ const projectDir = config?.projectDir || process.cwd();
110
+ if (!text?.trim()) {
111
+ logger.error?.('policy add: falta la regla — kj policy add "el coder no toca los workflows"');
105
112
  return 1;
106
113
  }
114
+ const { translateFn = defaultTranslate } = deps;
115
+ const frag = fragmentOf(await translateFn({ text, config, logger }), logger);
116
+ if (!frag) return 1;
117
+ const file = join(projectDir, ".karajan", "policy.yml");
118
+ const proposal = proposePolicy(file, frag, logger);
119
+ if (!proposal) return 1;
120
+ const { current, proposed } = proposal;
107
121
 
108
122
  logger.info?.(`policy add — diff propuesto para .karajan/policy.yml:\n${naiveDiff(current, proposed)}`);
109
123
  if (current.includes("#")) {
@@ -0,0 +1,31 @@
1
+ /**
2
+ * HU-2792: two branches can add `.karajan/adrs/0037-a.md` and `0037-b.md` in
3
+ * parallel: the names differ, so git sees no conflict and both land with the
4
+ * same number. CI judges a PR that adds an ADR whose number the base already
5
+ * holds under another name (unless the same diff deletes that one: a rename).
6
+ */
7
+ export const ADR_RULE = "defaults.adr.number";
8
+ const ADR_DIR = ".karajan/adrs/";
9
+ const ADR = /^\.karajan\/adrs\/(\d{4})-[^/]*\.md$/;
10
+ const lines = (text) => text.split("\n").map((s) => s.trim()).filter(Boolean);
11
+ const numberOf = (file) => Number(ADR.exec(file)[1]);
12
+
13
+ /**
14
+ * @param {{files: string[], range: string|null, run: (args: string[]) => Promise<string>}} opts
15
+ * @returns {Promise<object|null>} the violation, or null when no added ADR collides with the base
16
+ */
17
+ export async function adrNumberViolation({ files, range, run }) {
18
+ if (!files.some((f) => ADR.test(f))) return null;
19
+ const baseRef = range ? range.split(/\.{2,3}/)[0] : "HEAD";
20
+ const changes = lines(await run(["diff", "--no-renames", "--name-status", ...(range ? ["--end-of-options", range] : ["--cached"])])).map((l) => l.split("\t"));
21
+ const added = changes.filter(([status, file]) => status === "A" && ADR.test(file)).map(([, file]) => file);
22
+ const deleted = new Set(changes.filter(([status]) => status === "D").map(([, file]) => file));
23
+ const onBase = lines(await run(["ls-tree", "--name-only", "--end-of-options", baseRef, ADR_DIR])).filter((f) => ADR.test(f));
24
+ for (const file of added) {
25
+ const clash = onBase.find((f) => f !== file && numberOf(f) === numberOf(file) && !deleted.has(f));
26
+ if (!clash) continue;
27
+ const next = String(Math.max(...onBase.map(numberOf), ...added.map(numberOf)) + 1).padStart(4, "0");
28
+ return { rule_id: ADR_RULE, enforcement: "deny", file, reason: `${file} reuses the ADR number of ${clash}, which the base already has; the next free number is ${next}` };
29
+ }
30
+ return null;
31
+ }