karajan-code 4.70.4 → 5.0.1

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 (390) 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/register-roles-skills.js +1 -1
  68. package/src/cli/retired-commands.js +49 -0
  69. package/src/cli.js +18 -5
  70. package/src/commands/agent-run.js +40 -26
  71. package/src/commands/audit.js +127 -124
  72. package/src/commands/board.js +5 -9
  73. package/src/commands/check.js +29 -16
  74. package/src/commands/doctor.js +2 -0
  75. package/src/commands/env.js +176 -150
  76. package/src/commands/go.js +71 -53
  77. package/src/commands/harden.js +90 -81
  78. package/src/commands/hu-start.js +52 -0
  79. package/src/commands/hu.js +288 -221
  80. package/src/commands/identity.js +111 -78
  81. package/src/commands/init-atril.js +47 -0
  82. package/src/commands/init.js +11 -40
  83. package/src/commands/install-tools.js +70 -85
  84. package/src/commands/main-guard.js +78 -0
  85. package/src/commands/policy.js +226 -184
  86. package/src/commands/qmd.js +27 -21
  87. package/src/commands/rag.js +121 -55
  88. package/src/commands/review-gate.js +421 -341
  89. package/src/commands/skills.js +4 -1
  90. package/src/commands/start.js +4 -5
  91. package/src/commands/steward.js +96 -47
  92. package/src/commands/tournament.js +46 -37
  93. package/src/commands/worktree.js +107 -26
  94. package/src/config/defaults.js +1 -0
  95. package/src/config/loader.js +34 -17
  96. package/src/config/role-resolver.js +1 -0
  97. package/src/config/schema.js +1 -0
  98. package/src/config/secrets.js +36 -0
  99. package/src/config.js +1 -0
  100. package/src/environment/adr.js +16 -2
  101. package/src/git/karajan-label.js +20 -8
  102. package/src/guards/main-guard.js +54 -0
  103. package/src/harden/hook-templates.js +16 -1
  104. package/src/harden/sentinel/posttooluse.mjs +18 -6
  105. package/src/harden/sentinel/pretooluse-sentinel.mjs +64 -36
  106. package/src/harden/sentinel/sentinel-lib.mjs +129 -26
  107. package/src/harden/sentinel/sentinel-shell.mjs +5 -16
  108. package/src/harden/sentinel/sessionstart.mjs +3 -2
  109. package/src/harden/sentinel/stop.mjs +5 -4
  110. package/src/harden/workflow-templates.js +1 -1
  111. package/src/hu/board-lookup.js +29 -0
  112. package/src/hu/gh-identity.js +23 -0
  113. package/src/hu/github-board.js +4 -2
  114. package/src/hu/lane-prune.js +83 -13
  115. package/src/hu/lane-setup.js +65 -0
  116. package/src/hu/lanes.js +66 -0
  117. package/src/hu/team-board-mirror.js +3 -2
  118. package/src/infrastructure/command-runner.js +1 -1
  119. package/src/infrastructure/file-system-service.js +1 -1
  120. package/src/mcp/handlers/direct-handlers.js +2 -292
  121. package/src/mcp/handlers/hu-handlers.js +1 -35
  122. package/src/mcp/handlers/management-handlers.js +2 -42
  123. package/src/mcp/handlers/rag-handler.js +9 -1
  124. package/src/mcp/server-handlers.js +16 -22
  125. package/src/mcp/tools.js +1 -196
  126. package/src/plan/lane-plans.js +54 -0
  127. package/src/plan/plan-store.js +7 -4
  128. package/src/policy/add.js +26 -12
  129. package/src/policy/adr-number-check.js +31 -0
  130. package/src/prompts/audit.js +299 -339
  131. package/src/prompts/card-context.js +10 -5
  132. package/src/prompts/reviewer.js +5 -2
  133. package/src/rag/auto-update.js +71 -44
  134. package/src/rag/bootstrap-index.js +46 -54
  135. package/src/rag/indexer.js +9 -4
  136. package/src/rag/migrate.js +1 -1
  137. package/src/rag/onnx-fallback.js +2 -2
  138. package/src/rag/pid-lease.js +181 -0
  139. package/src/rag/project-store.js +2 -12
  140. package/src/review/card-first.js +57 -46
  141. package/src/review/gate-gitignore.js +23 -4
  142. package/src/review/gate-hook.js +12 -4
  143. package/src/review/one-shot-review.js +45 -35
  144. package/src/review/publish-pr.js +14 -2
  145. package/src/review/repo-docs.js +73 -0
  146. package/src/review/repo-stack.js +59 -0
  147. package/src/review/reviewer-fallback.js +19 -4
  148. package/src/review/seal-commit.js +29 -0
  149. package/src/review/sonar-pregate.js +59 -44
  150. package/src/review/third-party-review.js +90 -16
  151. package/src/review/third-party-size.js +43 -0
  152. package/src/review/third-party-skills.js +54 -0
  153. package/src/review/verify-pr.js +1 -24
  154. package/src/roles/audit-role.js +106 -125
  155. package/src/skills/atril-cli.js +19 -1
  156. package/src/skills/atril-skills.js +5 -4
  157. package/src/skills/skills-search.js +72 -0
  158. package/src/skills/translate.js +62 -0
  159. package/src/sonar/scanner.js +116 -101
  160. package/src/steward/invariants.js +5 -4
  161. package/src/steward/phantom-sweep.js +66 -0
  162. package/src/tournament/judge.js +60 -53
  163. package/src/utils/gh-account.js +37 -0
  164. package/src/utils/git.js +0 -13
  165. package/src/utils/home-migration.js +7 -1
  166. package/src/utils/main-checkout.js +53 -0
  167. package/src/utils/qmd-collection.js +3 -1
  168. package/src/utils/welcome.js +3 -3
  169. package/templates/{skills → atril/commands}/kj-architect.md +5 -0
  170. package/templates/{skills → atril/commands}/kj-audit.md +5 -0
  171. package/templates/{skills → atril/commands}/kj-board.md +5 -0
  172. package/templates/{skills → atril/commands}/kj-code.md +5 -0
  173. package/templates/{skills → atril/commands}/kj-csv-transform.md +5 -0
  174. package/templates/{skills → atril/commands}/kj-data-report.md +5 -0
  175. package/templates/{skills → atril/commands}/kj-discover.md +5 -0
  176. package/templates/{skills → atril/commands}/kj-rag-query.md +5 -0
  177. package/templates/{skills → atril/commands}/kj-review.md +5 -0
  178. package/templates/{skills → atril/commands}/kj-security.md +5 -0
  179. package/templates/{skills → atril/commands}/kj-sonar.md +5 -0
  180. package/templates/{skills → atril/commands}/kj-sql-analysis.md +5 -0
  181. package/templates/{skills → atril/commands}/kj-test.md +5 -0
  182. package/packages/hu-board/public/utils/run-launcher.js +0 -169
  183. package/packages/hu-board/src/run-tracker.js +0 -121
  184. package/src/activity-log.js +0 -59
  185. package/src/agents/host-agent.js +0 -38
  186. package/src/agents/model-registry.js +0 -142
  187. package/src/audit/plan-adherence.js +0 -224
  188. package/src/autonomy/arbiter-role.js +0 -71
  189. package/src/autonomy/arbiter.js +0 -22
  190. package/src/autonomy/decider.js +0 -18
  191. package/src/autonomy/decision-resolver.js +0 -58
  192. package/src/autonomy/outcome-report.js +0 -55
  193. package/src/autonomy/stage-ask.js +0 -30
  194. package/src/brain/decision-tracker.js +0 -125
  195. package/src/brain/decisor.js +0 -243
  196. package/src/brain/solomon-consult.js +0 -171
  197. package/src/brain/standby-scheduler.js +0 -8
  198. package/src/budget/comparison.js +0 -96
  199. package/src/canvas/parse-md.js +0 -238
  200. package/src/canvas/schema.js +0 -101
  201. package/src/canvas/to-flat.js +0 -85
  202. package/src/canvas/validate.js +0 -163
  203. package/src/ci/dispatch.js +0 -99
  204. package/src/ci/index.js +0 -3
  205. package/src/ci/pr-diff.js +0 -26
  206. package/src/cli/register-standby.js +0 -26
  207. package/src/commands/architect.js +0 -111
  208. package/src/commands/autorun.js +0 -49
  209. package/src/commands/researcher.js +0 -54
  210. package/src/commands/resume.js +0 -72
  211. package/src/commands/review.js +0 -89
  212. package/src/commands/run.js +0 -185
  213. package/src/commands/standby.js +0 -117
  214. package/src/commands/status.js +0 -36
  215. package/src/commands/triage.js +0 -78
  216. package/src/commands/undo.js +0 -62
  217. package/src/domains/domain-loader.js +0 -245
  218. package/src/domains/domain-registry.js +0 -140
  219. package/src/domains/domain-synthesizer.js +0 -129
  220. package/src/git/automation.js +0 -433
  221. package/src/git/coder-commit-guard.js +0 -40
  222. package/src/git/hu-automation.js +0 -243
  223. package/src/git/hu-snapshot.js +0 -10
  224. package/src/git/symlink-targets.js +0 -57
  225. package/src/golden/asserter.js +0 -92
  226. package/src/golden/loader.js +0 -52
  227. package/src/golden/runner.js +0 -92
  228. package/src/golden/schema.js +0 -41
  229. package/src/guards/duplicate-members.js +0 -86
  230. package/src/guards/intent-guard.js +0 -161
  231. package/src/guards/perf-guard.js +0 -126
  232. package/src/guards/policy-guard.js +0 -90
  233. package/src/guards/policy-resolver.js +0 -85
  234. package/src/guards/secret-redactor.js +0 -71
  235. package/src/hu/acceptance-runner.js +0 -138
  236. package/src/hu/lazy-planner.js +0 -109
  237. package/src/hu/parallel-executor.js +0 -94
  238. package/src/hu/routing-metrics.js +0 -17
  239. package/src/hu/split-validator.js +0 -143
  240. package/src/hu/splitting-detector.js +0 -158
  241. package/src/hu/splitting-generator.js +0 -175
  242. package/src/hu/store.js +0 -394
  243. package/src/infrastructure/mocks.js +0 -182
  244. package/src/mcp/handlers/run-handler.js +0 -318
  245. package/src/mcp/sovereignty-guard.js +0 -113
  246. package/src/mcp/tool-arg-normalizers.js +0 -16
  247. package/src/mutate/reviewer-signal.js +0 -76
  248. package/src/orchestrator/agent-fallback.js +0 -81
  249. package/src/orchestrator/brain-coordinator.js +0 -186
  250. package/src/orchestrator/ci-integration.js +0 -139
  251. package/src/orchestrator/config-init.js +0 -426
  252. package/src/orchestrator/direct-actions.js +0 -217
  253. package/src/orchestrator/drivers/error-recovery.js +0 -287
  254. package/src/orchestrator/drivers/init-context.js +0 -238
  255. package/src/orchestrator/drivers/iteration-loop.js +0 -382
  256. package/src/orchestrator/drivers/iteration-phases/coder-and-refactorer.js +0 -69
  257. package/src/orchestrator/drivers/iteration-phases/guards.js +0 -91
  258. package/src/orchestrator/drivers/iteration-phases/handle-approved.js +0 -29
  259. package/src/orchestrator/drivers/iteration-phases/quality-gates.js +0 -125
  260. package/src/orchestrator/drivers/iteration-phases/reviewer-gate.js +0 -62
  261. package/src/orchestrator/drivers/post-loop.js +0 -404
  262. package/src/orchestrator/drivers/pre-loop-phases/auto-hu-batch.js +0 -137
  263. package/src/orchestrator/drivers/pre-loop-phases/config-deprecations.js +0 -47
  264. package/src/orchestrator/drivers/pre-loop-phases/ensure-addyosmani-skills.js +0 -84
  265. package/src/orchestrator/drivers/pre-loop-phases/inject-loaded-plan.js +0 -393
  266. package/src/orchestrator/drivers/pre-loop.js +0 -524
  267. package/src/orchestrator/drivers/run-hu-batch.js +0 -468
  268. package/src/orchestrator/feedback-enrichment.js +0 -140
  269. package/src/orchestrator/feedback-queue.js +0 -151
  270. package/src/orchestrator/flow-control.js +0 -170
  271. package/src/orchestrator/flow-runner.js +0 -365
  272. package/src/orchestrator/fs-leak-detector.js +0 -228
  273. package/src/orchestrator/hu-scheduler.js +0 -114
  274. package/src/orchestrator/hu-sub-pipeline.js +0 -642
  275. package/src/orchestrator/iteration-gate.js +0 -73
  276. package/src/orchestrator/iteration-stages.js +0 -9
  277. package/src/orchestrator/parallel-limiter.js +0 -74
  278. package/src/orchestrator/pipeline-context.js +0 -72
  279. package/src/orchestrator/post-loop-stages.js +0 -468
  280. package/src/orchestrator/pre-loop-stages.js +0 -11
  281. package/src/orchestrator/preflight-checks.js +0 -487
  282. package/src/orchestrator/repair/repair-detector.js +0 -117
  283. package/src/orchestrator/repair/repair-runner.js +0 -142
  284. package/src/orchestrator/reviewer-fallback.js +0 -45
  285. package/src/orchestrator/role-output-compressor.js +0 -189
  286. package/src/orchestrator/session-journal.js +0 -308
  287. package/src/orchestrator/solomon-escalation.js +0 -331
  288. package/src/orchestrator/solomon-rules.js +0 -212
  289. package/src/orchestrator/stages/acceptance-coverage-stage.js +0 -47
  290. package/src/orchestrator/stages/architect-stage.js +0 -172
  291. package/src/orchestrator/stages/coder-stage.js +0 -506
  292. package/src/orchestrator/stages/domain-curator-stage.js +0 -82
  293. package/src/orchestrator/stages/format-stage.js +0 -61
  294. package/src/orchestrator/stages/hu-reviewer-phases/detect-and-apply-splits.js +0 -127
  295. package/src/orchestrator/stages/hu-reviewer-stage.js +0 -419
  296. package/src/orchestrator/stages/perf-stage.js +0 -140
  297. package/src/orchestrator/stages/planner-stage.js +0 -85
  298. package/src/orchestrator/stages/rag-context-stage.js +0 -80
  299. package/src/orchestrator/stages/rag-preload-decisor.js +0 -58
  300. package/src/orchestrator/stages/research-stage.js +0 -69
  301. package/src/orchestrator/stages/reviewer-stage.js +0 -431
  302. package/src/orchestrator/stages/sonar-stage.js +0 -439
  303. package/src/orchestrator/stages/stage-classes.js +0 -84
  304. package/src/orchestrator/stages/stage-executor.js +0 -155
  305. package/src/orchestrator/stages/suite-green-stage.js +0 -62
  306. package/src/orchestrator/stages/tdd-discipline-stage.js +0 -56
  307. package/src/orchestrator/stages/tool-judge-stage.js +0 -53
  308. package/src/orchestrator/stages/triage-stage.js +0 -172
  309. package/src/orchestrator/standby.js +0 -71
  310. package/src/orchestrator/verification-gate.js +0 -183
  311. package/src/orchestrator.js +0 -22
  312. package/src/plan/adr-generator.js +0 -170
  313. package/src/plan/adr-loader.js +0 -60
  314. package/src/plan/plan-executor.js +0 -100
  315. package/src/plan/plan-validation.js +0 -4
  316. package/src/prompts/acceptance-coverage.js +0 -32
  317. package/src/prompts/arbiter.js +0 -38
  318. package/src/prompts/architect.js +0 -103
  319. package/src/prompts/hu-reviewer.js +0 -244
  320. package/src/prompts/tool-correctness-judge.js +0 -31
  321. package/src/prompts/triage.js +0 -57
  322. package/src/rag/embedder.js +0 -2
  323. package/src/rag/embedders/_cloud-base.js +0 -2
  324. package/src/rag/embedders/cohere.js +0 -2
  325. package/src/rag/embedders/mistral.js +0 -2
  326. package/src/rag/embedders/onnx.js +0 -2
  327. package/src/rag/embedders/openai.js +0 -2
  328. package/src/rag/embedders/voyage.js +0 -2
  329. package/src/rag/rerank.js +0 -4
  330. package/src/rag/where-parser.js +0 -4
  331. package/src/repeat-detector.js +0 -88
  332. package/src/review/diff-generator.js +0 -112
  333. package/src/review/git-stash-helper.js +0 -104
  334. package/src/review/schema.js +0 -31
  335. package/src/review/scope-filter.js +0 -152
  336. package/src/review/snapshot-diff.js +0 -122
  337. package/src/review/tdd-discipline.js +0 -90
  338. package/src/review/tdd-policy.js +0 -69
  339. package/src/roles/acceptance-coverage-role.js +0 -78
  340. package/src/roles/architect-role.js +0 -77
  341. package/src/roles/coder-role.js +0 -113
  342. package/src/roles/commiter-role.js +0 -113
  343. package/src/roles/domain-curator-role.js +0 -134
  344. package/src/roles/hu-reviewer-role.js +0 -64
  345. package/src/roles/impeccable-role.js +0 -85
  346. package/src/roles/index.js +0 -18
  347. package/src/roles/karajan-brain-role.js +0 -134
  348. package/src/roles/perf-role.js +0 -122
  349. package/src/roles/planner-role.js +0 -151
  350. package/src/roles/refactorer-role.js +0 -30
  351. package/src/roles/repairer-role.js +0 -181
  352. package/src/roles/researcher-role.js +0 -70
  353. package/src/roles/reviewer-role.js +0 -115
  354. package/src/roles/security-role.js +0 -73
  355. package/src/roles/solomon-role.js +0 -271
  356. package/src/roles/sonar-role.js +0 -72
  357. package/src/roles/tester-role.js +0 -235
  358. package/src/roles/tool-correctness-judge-role.js +0 -78
  359. package/src/roles/triage-role.js +0 -99
  360. package/src/session/journal/decisions-writer.js +0 -200
  361. package/src/session/journal/iteration-logger.js +0 -194
  362. package/src/session/journal/summary-writer.js +0 -320
  363. package/src/session/journal/tree-writer.js +0 -164
  364. package/src/session/journal/write-all.js +0 -89
  365. package/src/session-cleanup.js +0 -116
  366. package/src/skills/semantic-detector.js +0 -167
  367. package/src/skills/skill-detector.js +0 -385
  368. package/src/sonar/cloud-scanner.js +0 -78
  369. package/src/tracker-bootstrap.js +0 -44
  370. package/src/types/index.js +0 -38
  371. package/src/types/policy.js +0 -43
  372. package/src/types/solomon.js +0 -87
  373. package/src/utils/async-lock.js +0 -31
  374. package/src/utils/budget.js +0 -229
  375. package/src/utils/cwd-confirm.js +0 -39
  376. package/src/utils/display/event-handlers.js +0 -403
  377. package/src/utils/display/formatters.js +0 -132
  378. package/src/utils/display/header.js +0 -47
  379. package/src/utils/display/session-summary.js +0 -118
  380. package/src/utils/display/solomon.js +0 -42
  381. package/src/utils/pricing.js +0 -29
  382. package/src/utils/quota-simulator.js +0 -56
  383. package/src/utils/role-assigner.js +0 -137
  384. package/src/utils/rtk-wrapper.js +0 -87
  385. package/src/utils/run-registry.js +0 -9
  386. package/src/utils/status-dashboard.js +0 -254
  387. package/src/utils/tool-call-extractor.js +0 -56
  388. package/src/webperf/devtools-detect.js +0 -112
  389. package/src/webperf/webperf-role-integration.js +0 -66
  390. package/templates/skills/kj-run.md +0 -73
package/src/ci/pr-diff.js DELETED
@@ -1,26 +0,0 @@
1
- /**
2
- * Read PR diff via gh CLI for Karajan CI flow.
3
- * The reviewer reads the PR diff instead of local git diff.
4
- */
5
-
6
- import { runCommand } from "../utils/process.js";
7
-
8
- /**
9
- * Get the diff of a PR via `gh pr diff <number>`.
10
- * Returns the diff string or throws on failure.
11
- */
12
- export async function getPrDiff(prNumber) {
13
- if (!prNumber) throw new Error("prNumber is required");
14
-
15
- const res = await runCommand("gh", [
16
- "pr",
17
- "diff",
18
- String(prNumber)
19
- ]);
20
-
21
- if (res.exitCode !== 0) {
22
- throw new Error(`gh pr diff ${prNumber} failed: ${res.stderr || res.stdout}`);
23
- }
24
-
25
- return res.stdout;
26
- }
@@ -1,26 +0,0 @@
1
- // KJC-TSK-0414 PR2: registra `kj standby list` + `kj standby resume <id>`.
2
- // `resume` es subcomando de standby para no colisionar con el `kj resume`
3
- // pre-existente (Solomon pauses con --answer). Modelos mentales distintos:
4
- // - `kj resume <id> --answer X` → Solomon pauseado (existente)
5
- // - `kj standby resume <id>` → run hibernada por quota
6
- import { resumeCommand, standbyListCommand } from "../commands/standby.js";
7
-
8
- export function registerStandby(program) {
9
- const standby = program.command("standby").description("Sesiones hibernadas (QUOTA_EXHAUSTED_DAILY etc.)");
10
- standby
11
- .command("list", { isDefault: true })
12
- .description("Lista sesiones pendientes de reanudar")
13
- .option("--json", "Output JSON")
14
- .action(async (flags) => {
15
- await standbyListCommand({ json: flags.json });
16
- });
17
-
18
- standby
19
- .command("resume")
20
- .description("Reanuda una sesión hibernada (re-spawn comando original)")
21
- .argument("<sessionId>")
22
- .option("--force", "Reanudar aunque cooldownUntil todavía esté en el futuro (no recomendado)")
23
- .action(async (sessionId, flags) => {
24
- await resumeCommand({ sessionId, force: Boolean(flags.force) });
25
- });
26
- }
@@ -1,111 +0,0 @@
1
- import { createAgent } from "../agents/index.js";
2
- import { assertAgentsAvailable } from "../agents/availability.js";
3
- import { resolveRole } from "../config.js";
4
- import { buildArchitectPrompt, parseArchitectOutput } from "../prompts/architect.js";
5
- import { createCliProgressReporter } from "../utils/cli-progress.js";
6
- import { withBrainRecovery } from "../brain/with-brain-recovery.js";
7
-
8
- // KJC-BUG-0313 (#2061): the agent answers each list with plain strings or with
9
- // objects; both render, and a section with neither prints nothing, never "undefined".
10
- function section(title, items, render, lines) {
11
- if (!items?.length) return;
12
- lines.push(`### ${title}`);
13
- for (const item of items) lines.push(...(typeof item === "string" ? [`- ${item}`] : render(item)));
14
- lines.push("");
15
- }
16
-
17
- const named = (o, detail) => [`- **${o.name ?? o.decision ?? JSON.stringify(o)}**${detail ? `: ${detail}` : ""}`];
18
- const contract = (c) => [`- \`${c.method || "GET"} ${c.endpoint ?? c.path ?? ""}\``];
19
- const tradeoff = (t) => [...named(t, t.rationale), ...(t.alternatives?.length ? [` Alternatives: ${t.alternatives.join(", ")}`] : [])];
20
- const entity = (e) => named(e, Array.isArray(e.fields) ? e.fields.join(", ") : e.description);
21
-
22
- function formatArchitecture(arch, lines) {
23
- if (arch.type) lines.push(`**Type:** ${arch.type}`, "");
24
- section("Layers", arch.layers, (l) => named(l, l.responsibility), lines);
25
- section("Patterns", arch.patterns, (p) => [`- ${p.name ?? JSON.stringify(p)}`], lines);
26
- section("Data Model", arch.dataModel?.entities, entity, lines);
27
- // A contract given as a string ("GET /x") is code too: same backticks as an object's.
28
- section("API Contracts", arch.apiContracts?.map((c) => (typeof c === "string" ? { raw: c } : c)), (c) => (c.raw ? [`- \`${c.raw}\``] : contract(c)), lines);
29
- section("Dependencies", arch.dependencies, (d) => named(d, d.reason), lines);
30
- section("Tradeoffs", arch.tradeoffs, tradeoff, lines);
31
- }
32
-
33
- export function formatArchitect(result) {
34
- const lines = [];
35
- lines.push(`## Architecture Design`);
36
- lines.push(`**Verdict:** ${result.verdict || "unknown"}`, "");
37
-
38
- if (result.architecture) formatArchitecture(result.architecture, lines);
39
-
40
- if (result.questions?.length) {
41
- lines.push("### Clarification Questions");
42
- for (const q of result.questions) lines.push(`- ${q.question || q}`);
43
- lines.push("");
44
- }
45
-
46
- if (result.summary) lines.push(`---\n${result.summary}`);
47
- return lines.join("\n");
48
- }
49
-
50
- export async function architectCommand({ task, config, logger, context, json }) {
51
- const { withCliRunLog } = await import("../utils/cli-run-log.js");
52
- return withCliRunLog("architect", { projectDir: config?.projectDir, logger }, async ({ runLog }) => {
53
- const architectRole = resolveRole(config, "architect");
54
- await assertAgentsAvailable([architectRole.provider]);
55
- logger.info(`Architect (${architectRole.provider}) starting...`);
56
- runLog.logText(`[architect] provider=${architectRole.provider}`);
57
-
58
- const agent = createAgent(architectRole.provider, config, logger);
59
- const prompt = await buildArchitectPrompt({ task, researchContext: context });
60
- const progress = createCliProgressReporter({ role: "architect" });
61
- let result;
62
- try {
63
- result = await withBrainRecovery({
64
- agent, taskArgs: { prompt, onOutput: progress.onOutput, role: "architect" },
65
- role: "architect", provider: architectRole.provider, logger,
66
- });
67
- progress.finish(result.ok ? "done" : (result.action || "failed"));
68
- } catch (err) { progress.finish("failed"); throw err; }
69
-
70
- if (!result.ok) {
71
- throw new Error(result.error || result.output || "Architect failed");
72
- }
73
-
74
- const parsed = parseArchitectOutput(result.output);
75
-
76
- if (json) {
77
- console.log(JSON.stringify(parsed || result.output, null, 2));
78
- return { ok: true };
79
- }
80
-
81
- if (parsed?.verdict) {
82
- console.log(formatArchitect(parsed));
83
- } else {
84
- console.log(result.output);
85
- }
86
-
87
- // Persist ADRs from the architect's tradeoffs[] (v2.7.5). One ADR
88
- // per tradeoff in Nygard format under `~/.kj/plans/_loose/adrs/`.
89
- // Coder/reviewer in subsequent runs can pull the active ADRs into
90
- // their prompt for context — done in a follow-up PR.
91
- if (parsed?.architecture && config?.projectDir) {
92
- try {
93
- const { persistAdrsFromArchitecture } = await import("../plan/adr-generator.js");
94
- const { adrs, paths } = await persistAdrsFromArchitecture({
95
- projectDir: config.projectDir,
96
- planId: null, // standalone architect → "_loose" bucket
97
- architecture: parsed.architecture,
98
- });
99
- if (paths.length > 0) {
100
- console.log(`\n${adrs.length} ADR${adrs.length === 1 ? "" : "s"} written:`);
101
- for (const p of paths) console.log(` - ${p}`);
102
- }
103
- } catch (err) {
104
- logger.warn(`ADR write skipped: ${err.message}`);
105
- }
106
- }
107
-
108
- logger.info("Architect completed.");
109
- return { ok: true };
110
- });
111
- }
@@ -1,49 +0,0 @@
1
- /**
2
- * `kj autorun <spec>` — the unattended delivery chain (KJC-TSK-0574, épica
3
- * KJC-PCS-0062, design in docs/specs/autonomous-delivery.md §7).
4
- *
5
- * One command: spec → plan → run all HUs → outcome. It reuses `kj plan` and
6
- * `kj run --plan` rather than reimplementing them, and defaults to the
7
- * `autonomous` level so the Arbiter resolves every gate (no human in the loop).
8
- * The rich outcome report lands in AUTO-F; here we chain + propagate exit code.
9
- */
10
-
11
- import { planGenerateCommand } from "./plan/generate.js";
12
- import { runCommandHandler } from "./run.js";
13
- import { buildOutcome, formatOutcomeReport } from "../autonomy/outcome-report.js";
14
-
15
- export async function autorunCommand({
16
- task,
17
- config,
18
- logger = console,
19
- flags = {},
20
- planFn = planGenerateCommand,
21
- runFn = runCommandHandler,
22
- } = {}) {
23
- // autorun implies unattended: default to autonomous unless the user picked a
24
- // level explicitly (so `kj autorun --autonomy assisted` still works).
25
- const autoFlags = flags.autonomy || flags.autonomous ? flags : { ...flags, autonomous: true };
26
-
27
- logger.info?.("kj autorun — planning…");
28
- const plan = await planFn({ task, config, logger, flags: autoFlags });
29
- if (!plan?.ok || !plan.planId) {
30
- logger.error?.(`kj autorun: planning failed${plan?.reason ? ` (${plan.reason})` : ""}.`);
31
- return { ok: false, stage: "plan", reason: plan?.reason ?? "plan-failed" };
32
- }
33
-
34
- logger.info?.(`kj autorun — running plan ${plan.ref ?? plan.planId} (${plan.huCount ?? "?"} HUs)…`);
35
- const run = await runFn({ config, logger, flags: { ...autoFlags, plan: plan.planId } });
36
-
37
- const ok = run?.ok === true;
38
- // AUTO-F: emit the auditable outcome — delivered/incomplete, HUs that met the
39
- // ask, Arbiter decisions and residual defects (enriched as the run surfaces
40
- // them; baseline today is delivered + plan ref).
41
- const outcome = buildOutcome({
42
- planRef: plan.ref ?? plan.planId,
43
- delivered: ok,
44
- hus: run?.hus ?? [],
45
- decisions: run?.decisions ?? [],
46
- });
47
- for (const line of formatOutcomeReport(outcome)) logger.info?.(line);
48
- return { ok, stage: ok ? "done" : "run", planId: plan.planId, ref: plan.ref ?? plan.planId, outcome };
49
- }
@@ -1,54 +0,0 @@
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 { withBrainRecovery } from "../brain/with-brain-recovery.js";
6
-
7
- const SUBAGENT_PREAMBLE = [
8
- "IMPORTANT: You are running as a Karajan sub-agent.",
9
- "Do NOT ask about using Karajan, do NOT mention Karajan, do NOT suggest orchestration.",
10
- "Do NOT use any MCP tools. Focus only on researching the codebase."
11
- ].join(" ");
12
-
13
- function buildResearchPrompt(task) {
14
- return [
15
- SUBAGENT_PREAMBLE,
16
- "Investigate the codebase for the following task.",
17
- "Identify affected files, patterns, constraints, prior decisions, risks, and test coverage.",
18
- "Return a single valid JSON object with your findings and nothing else.",
19
- '{"affected_files":[string],"patterns":[string],"constraints":[string],"prior_decisions":[string],"risks":[string],"test_coverage":string}',
20
- `## Task\n${task}`
21
- ].join("\n\n");
22
- }
23
-
24
- export async function researcherCommand({ task, config, logger }) {
25
- const { withCliRunLog } = await import("../utils/cli-run-log.js");
26
- return withCliRunLog("researcher", { projectDir: config?.projectDir, logger }, async ({ runLog }) => {
27
- const researcherRole = resolveRole(config, "researcher");
28
- await assertAgentsAvailable([researcherRole.provider]);
29
- logger.info(`Researcher (${researcherRole.provider}) starting...`);
30
- runLog.logText(`[researcher] provider=${researcherRole.provider}`);
31
-
32
- const agent = createAgent(researcherRole.provider, config, logger);
33
- const prompt = buildResearchPrompt(task);
34
- const progress = createCliProgressReporter({ role: "researcher" });
35
- let result;
36
- try {
37
- result = await withBrainRecovery({
38
- agent, taskArgs: { prompt, onOutput: progress.onOutput, role: "researcher" },
39
- role: "researcher", provider: researcherRole.provider, logger,
40
- });
41
- progress.finish(result.ok ? "done" : (result.action || "failed"));
42
- } catch (err) { progress.finish("failed"); throw err; }
43
-
44
- if (!result.ok) {
45
- throw new Error(result.error || result.output || "Researcher failed");
46
- }
47
-
48
- if (result.output) {
49
- console.log(result.output);
50
- }
51
- logger.info("Researcher completed.");
52
- return { ok: true };
53
- });
54
- }
@@ -1,72 +0,0 @@
1
- import { EventEmitter } from "node:events";
2
- import { resumeFlow } from "../orchestrator.js";
3
- import { sweepOnResume } from "./steward.js";
4
- import { createActivityLog } from "../activity-log.js";
5
- import { printEvent } from "../utils/display/event-handlers.js";
6
- import { withCliRunLog } from "../utils/cli-run-log.js";
7
- import { registerRun, unregisterRun } from "../utils/run-registry.js";
8
- import { createCliAskQuestion } from "../utils/cli-ask-question.js";
9
-
10
- export async function resumeCommand({ sessionId, answer, config, logger, flags }) {
11
- const jsonMode = flags?.json;
12
- const quietMode = config.output?.quiet !== false;
13
- // STW-E (KJC-TSK-0793): resuming work is when someone is in front to review
14
- // the state — sweep if the report went stale; adoption stays explicit.
15
- await sweepOnResume({ config, logger });
16
-
17
- // Same wrapper as every other CLI command — without it `.kj/run.log`
18
- // is never opened during the resume and `kj-tail` stays silent
19
- // (every line of the resumed run goes only to the per-session
20
- // activity log + the local console). Also registers the run so the
21
- // HU Board shows it as live and can offer its Stop button.
22
- return withCliRunLog("resume", { projectDir: config?.projectDir, logger }, async ({ forwardProgress }) => {
23
- const runId = registerRun({
24
- pid: process.pid,
25
- planId: flags?.plan || null,
26
- huIds: null,
27
- projectDir: config?.projectDir || process.cwd(),
28
- source: "cli-resume",
29
- });
30
- const cleanupRegistry = () => { if (runId) unregisterRun(runId); };
31
- process.once("exit", cleanupRegistry);
32
- process.once("SIGTERM", () => { cleanupRegistry(); process.exit(143); });
33
- process.once("SIGINT", () => { cleanupRegistry(); process.exit(130); });
34
-
35
- const emitter = new EventEmitter();
36
- let activityLog = null;
37
- forwardProgress(emitter);
38
-
39
- emitter.on("progress", (event) => {
40
- if (!activityLog && event.sessionId) {
41
- activityLog = createActivityLog(event.sessionId);
42
- logger.onLog((entry) => activityLog.write(entry));
43
- }
44
- if (activityLog) {
45
- activityLog.writeEvent(event);
46
- }
47
- if (!jsonMode) {
48
- printEvent(event, { quiet: quietMode });
49
- }
50
- });
51
-
52
- // KJC-BUG-0081 round 2 — propagate `flags` so the helper honours
53
- // `--yes` here too. Before this fix, `kj resume <id> --yes` in
54
- // non-TTY mode still routed every prompt to the HU Board bridge
55
- // and hung, exactly the bug the original PR #995 fixed for `kj run`.
56
- const askQuestion = createCliAskQuestion({ sessionId, flags });
57
- const result = await resumeFlow({
58
- sessionId,
59
- answer: answer || null,
60
- config,
61
- logger,
62
- flags: flags || {},
63
- emitter,
64
- askQuestion
65
- });
66
-
67
- if (jsonMode || !answer) {
68
- console.log(JSON.stringify(result, null, 2));
69
- }
70
- return result;
71
- });
72
- }
@@ -1,89 +0,0 @@
1
- import { createAgent } from "../agents/index.js";
2
- import { assertAgentsAvailable } from "../agents/availability.js";
3
- import { computeBaseRef, generateDiff } from "../review/diff-generator.js";
4
- import { buildReviewerPrompt } from "../prompts/reviewer.js";
5
- import { resolveRole } from "../config.js";
6
- import { resolveReviewProfile } from "../review/profiles.js";
7
- import { withCliRunLog } from "../utils/cli-run-log.js";
8
- import { createCliProgressReporter } from "../utils/cli-progress.js";
9
-
10
- export async function reviewCommand({ task, config, logger, baseRef }) {
11
- return withCliRunLog("review", { projectDir: config?.projectDir, logger }, async ({ runLog }) => {
12
- const reviewerRole = resolveRole(config, "reviewer");
13
- await assertAgentsAvailable([reviewerRole.provider]);
14
- logger.info(`Reviewer (${reviewerRole.provider}) starting...`);
15
- runLog.logText(`[reviewer] provider=${reviewerRole.provider} baseRef=${baseRef || "(auto)"}`);
16
- const reviewer = createAgent(reviewerRole.provider, config, logger);
17
-
18
- let diff;
19
- if (config.ci?.enabled) {
20
- // CI mode: read diff from open PR
21
- const { detectRepo, detectPrNumber } = await import("../ci/repo.js");
22
- const { getPrDiff } = await import("../ci/pr-diff.js");
23
- const repo = await detectRepo();
24
- const prNumber = await detectPrNumber();
25
- if (!prNumber) {
26
- throw new Error("CI enabled but no open PR found for current branch. Create a PR first or disable CI.");
27
- }
28
- logger.info(`CI: reading PR diff #${prNumber}`);
29
- diff = await getPrDiff(prNumber);
30
- // Store for dispatch later
31
- config._ci_pr = { repo, prNumber };
32
- } else {
33
- const resolvedBase = await computeBaseRef({ baseBranch: config.base_branch, baseRef });
34
- diff = await generateDiff({ baseRef: resolvedBase });
35
- }
36
-
37
- const { rules } = await resolveReviewProfile({ mode: config.review_mode, projectDir: process.cwd() });
38
-
39
- const prompt = await buildReviewerPrompt({ task, diff, reviewRules: rules, mode: config.review_mode });
40
- const progress = createCliProgressReporter({ role: "reviewer" });
41
- let result;
42
- try {
43
- result = await reviewer.reviewTask({ prompt, onOutput: progress.onOutput, role: "reviewer" });
44
- progress.finish(result.ok ? "done" : "failed");
45
- } catch (err) { progress.finish("failed"); throw err; }
46
- if (!result.ok) {
47
- if (result.error) logger.error(result.error);
48
- throw new Error(result.error || result.output || `Reviewer failed (exit ${result.exitCode})`);
49
- }
50
- console.log(result.output);
51
- logger.info(`Reviewer completed (exit ${result.exitCode})`);
52
-
53
- // CI: dispatch review result
54
- if (config.ci?.enabled && config._ci_pr) {
55
- try {
56
- const { dispatchReview, dispatchComment } = await import("../ci/dispatch.js");
57
- const { repo, prNumber } = config._ci_pr;
58
- const bc = config.ci;
59
-
60
- // Try to parse structured review from output
61
- let review;
62
- try {
63
- review = JSON.parse(result.output);
64
- } catch { /* output is not JSON */
65
- review = { approved: true, summary: result.output };
66
- }
67
-
68
- const event = review.approved ? "APPROVE" : "REQUEST_CHANGES";
69
- await dispatchReview({
70
- repo, prNumber, event,
71
- body: review.summary || result.output.slice(0, 500),
72
- agent: "Reviewer", ciConfig: bc
73
- });
74
-
75
- await dispatchComment({
76
- repo, prNumber, agent: "Reviewer",
77
- body: `Standalone review: ${event}\n\n${review.summary || result.output.slice(0, 1000)}`,
78
- ciConfig: bc
79
- });
80
-
81
- logger.info(`CI: dispatched review for PR #${prNumber}`);
82
- } catch (err) {
83
- logger.warn(`CI dispatch failed (non-blocking): ${err.message}`);
84
- }
85
- }
86
- runLog.logText(`[reviewer] finished (exit=${result.exitCode})`);
87
- return { ok: true };
88
- });
89
- }
@@ -1,185 +0,0 @@
1
- import { EventEmitter } from "node:events";
2
- import { runFlow } from "../orchestrator.js";
3
- import { assertAgentsAvailable } from "../agents/availability.js";
4
- import { createActivityLog } from "../activity-log.js";
5
- import { withCliRunLog } from "../utils/cli-run-log.js";
6
- import { registerRun, unregisterRun } from "../utils/run-registry.js";
7
- import { printHeader } from "../utils/display/header.js";
8
- import { printEvent } from "../utils/display/event-handlers.js";
9
- import { printResumeHint } from "../utils/display/resume-hint.js";
10
- import { resolveRole } from "../config.js";
11
- import { parseCardId } from "../planning-game/adapter.js";
12
- import { confirmCwd } from "../utils/cwd-confirm.js";
13
- import { runSpecReview } from "../spec-review/run-spec-review.js";
14
- import { maybeAutoUpdate } from "../rag/auto-update.js";
15
-
16
- // Re-export the shared helper so existing imports (tests, MCP wrappers)
17
- // keep working. KJC-BUG-0081 round 2 split the body into utils/ because
18
- // resume.js also needs the same contract.
19
- import { createCliAskQuestion } from "../utils/cli-ask-question.js";
20
- import { buildDecider } from "../autonomy/decider.js";
21
- import { createAutonomyAskQuestion } from "../autonomy/stage-ask.js";
22
- export { createCliAskQuestion };
23
-
24
- export async function runCommandHandler({ task, config, logger, flags }) {
25
- // PR-F (cwd confirmation): when launching from an interactive
26
- // terminal, surface the working directory so the user can abort if
27
- // they typed `kj run` from the wrong place. The user's words:
28
- // "todas las que lo lancé desde terminal te garantizo que estaba
29
- // en la carpeta del proyecto … aún así preguntar por si acaso".
30
- //
31
- // Skip the prompt when:
32
- // - --yes / -y is set (CI / scripted runs),
33
- // - --json mode is on (machine-readable output, no TTY assumed),
34
- // - stdin is not a TTY (piped, board-spawned subprocess, MCP).
35
- const projectDir = config?.projectDir || process.cwd();
36
- const canPrompt = process.stdin.isTTY && process.stdout.isTTY
37
- && !flags?.yes && !flags?.json;
38
- if (canPrompt) {
39
- const ok = await confirmCwd(projectDir);
40
- if (!ok) {
41
- console.log("Aborted by user.");
42
- return { ok: false, aborted: true };
43
- }
44
- }
45
-
46
- // KJC-TSK-0455 — Pre-run drift check. Default ON; opt out with
47
- // --no-rag-update (flag) or config.rag.autoUpdate.onRun=false. If the
48
- // local index is behind HEAD we re-embed the delta before the agents
49
- // start reading from the RAG store; on any failure we log and move on
50
- // so a broken vector store never blocks a run.
51
- await maybeAutoUpdate({ projectDir, config, logger, flags });
52
-
53
- // Best-effort session cleanup before starting
54
- try {
55
- const { cleanupExpiredSessions } = await import("../session-cleanup.js");
56
- await cleanupExpiredSessions({ logger });
57
- } catch { /* non-blocking */ }
58
-
59
- const requiredProviders = [
60
- resolveRole(config, "coder").provider
61
- ];
62
- if (config.pipeline?.reviewer?.enabled !== false) {
63
- requiredProviders.push(resolveRole(config, "reviewer").provider);
64
- }
65
- if (config.pipeline?.triage?.enabled) requiredProviders.push(resolveRole(config, "triage").provider);
66
- if (config.pipeline?.planner?.enabled) requiredProviders.push(resolveRole(config, "planner").provider);
67
- if (config.pipeline?.refactorer?.enabled) requiredProviders.push(resolveRole(config, "refactorer").provider);
68
- if (config.pipeline?.researcher?.enabled) requiredProviders.push(resolveRole(config, "researcher").provider);
69
- if (config.pipeline?.tester?.enabled) requiredProviders.push(resolveRole(config, "tester").provider);
70
- if (config.pipeline?.security?.enabled) requiredProviders.push(resolveRole(config, "security").provider);
71
- await assertAgentsAvailable(requiredProviders);
72
-
73
- // --- Planning Game: resolve card ID ---
74
- const pgCardId = flags?.pgTask || parseCardId(task);
75
- const pgProject = flags?.pgProject || config.planning_game?.project_id || null;
76
-
77
- const jsonMode = flags?.json;
78
- // Quiet mode is the default; --verbose disables it
79
- const quietMode = config.output?.quiet !== false;
80
-
81
- return withCliRunLog("run", { projectDir: config?.projectDir, logger }, async ({ runLog, forwardProgress }) => {
82
- runLog.logText(`[kj_run] task="${String(task).slice(0, 80)}..."`);
83
-
84
- // KJC-TSK-0396 extensión: registrar el PID + planId + huIds en
85
- // ~/.karajan/runs/<runId>.json para que el HU Board pueda mostrar
86
- // el botón ⏹ Stop incluso cuando el run se lanza desde terminal
87
- // externa (no solo desde el botón ▶ Run del board). Best-effort:
88
- // si la escritura falla, el run sigue su curso normal. Limpieza
89
- // garantizada en el finally del withCliRunLog vía registry.unregisterRun.
90
- const huIdsFromFlag = typeof flags?.hu === "string"
91
- ? flags.hu.split(",").map((s) => s.trim()).filter(Boolean)
92
- : null;
93
- const runId = registerRun({
94
- pid: process.pid,
95
- planId: flags?.plan || null,
96
- huIds: huIdsFromFlag,
97
- projectDir: config?.projectDir || process.cwd(),
98
- source: "cli",
99
- });
100
- const cleanupRegistry = () => { if (runId) unregisterRun(runId); };
101
- // Cubrir todos los caminos de salida del proceso.
102
- process.once("exit", cleanupRegistry);
103
- process.once("SIGTERM", () => { cleanupRegistry(); process.exit(143); });
104
- process.once("SIGINT", () => { cleanupRegistry(); process.exit(130); });
105
-
106
- const emitter = new EventEmitter();
107
- let activityLog = null;
108
-
109
- // Mirror every progress event into .kj/run.log so kj-tail works identically
110
- // whether the command came from the MCP server or the CLI (KJC-TSK-0327 follow-up).
111
- forwardProgress(emitter);
112
-
113
- emitter.on("progress", (event) => {
114
- if (!activityLog && event.sessionId) {
115
- activityLog = createActivityLog(event.sessionId);
116
- logger.onLog((entry) => activityLog.write(entry));
117
- }
118
-
119
- if (activityLog) {
120
- activityLog.writeEvent(event);
121
- }
122
-
123
- if (!jsonMode) {
124
- printEvent(event, { quiet: quietMode });
125
- }
126
- });
127
-
128
- if (!jsonMode) {
129
- printHeader({ task: task, config });
130
- }
131
-
132
- const askQuestion = createCliAskQuestion({ flags });
133
-
134
- // Autonomy (KJC-PCS-0062): wire the level to a resolver. In autonomous mode
135
- // every gate is decided by the Arbiter instead of the human; interactive
136
- // keeps the human prompts. The decider is threaded into the gates below.
137
- const { autonomy, resolve: decide } = buildDecider({ config, flags, ask: askQuestion, logger });
138
-
139
- // Spec-reviewer pre-pipeline audit (KJC-PCS-0048). Runs BEFORE
140
- // anything else — surfaces ambiguity / missing scope / missing AC.
141
- // In autonomous mode the Arbiter decides (never aborts); interactive
142
- // lets the user bail. Bypass with --skip-spec-review.
143
- const reviewResult = await runSpecReview({ spec: task, config, logger, askQuestion, flags, resolve: decide, autonomy });
144
- if (!reviewResult.proceed) {
145
- logger.info("Aborted by user after spec review.");
146
- cleanupRegistry();
147
- return { ok: false, aborted: true, reason: "spec-review-cancelled" };
148
- }
149
- // If the user refined the spec via [r]efine, downstream runs the
150
- // REFINED text (not the original) so the pipeline acts on what the
151
- // user actually approved.
152
- const effectiveTask = reviewResult.refined && reviewResult.finalSpec ? reviewResult.finalSpec : task;
153
-
154
- // AUTO-E: in autonomous mode the stages never ask a human or block on the
155
- // board — they auto-continue with the least-bad choice. interactive/assisted
156
- // keep the human prompts.
157
- const stageAsk = createAutonomyAskQuestion({ baseAsk: askQuestion, autonomy, logger });
158
-
159
- let result;
160
- try {
161
- result = await runFlow({ task: effectiveTask, config, logger, flags, emitter, askQuestion: stageAsk, pgTaskId: pgCardId || null, pgProject: pgProject || null });
162
- } finally {
163
- // KJC-TSK-0396: limpia el registro pase lo que pase (éxito,
164
- // throw, o paused). Los handlers de SIGINT/SIGTERM/exit son
165
- // backstop para casos donde el throw no llega aquí (segfault,
166
- // kill -9, etc.).
167
- cleanupRegistry();
168
- }
169
-
170
- if (jsonMode) {
171
- console.log(JSON.stringify(result, null, 2));
172
- } else {
173
- // Last line printed: if the run stopped (hibernated / paused /
174
- // failed), tell the user the exact command to resume it.
175
- printResumeHint(result);
176
- }
177
- // Surface per-HU results so `kj autorun` can build a real outcome report
178
- // (KJC-BUG-0090: it showed "0/0 met the ask" because only { ok } came back).
179
- // The plan run returns them as `huResults` (run-hu-batch finalResult).
180
- const hus = Array.isArray(result?.huResults)
181
- ? result.huResults.map((r) => ({ id: r.huId, met: r.approved === true }))
182
- : [];
183
- return { ok: !result?.paused && result?.approved !== false, hus };
184
- });
185
- }