karajan-code 4.70.3 → 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 (388) 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/ai-surface.js +9 -7
  61. package/src/checks/config-files.js +8 -7
  62. package/src/checks/dir-setup.js +34 -1
  63. package/src/checks/native-build.js +21 -39
  64. package/src/checks/runner.js +128 -142
  65. package/src/cli/advanced-commands.js +6 -6
  66. package/src/cli/register-meta.js +42 -82
  67. package/src/cli/register-pipeline.js +8 -140
  68. package/src/cli/register-plan.js +9 -100
  69. package/src/cli/retired-commands.js +49 -0
  70. package/src/cli.js +18 -5
  71. package/src/commands/agent-run.js +40 -26
  72. package/src/commands/audit.js +127 -124
  73. package/src/commands/board.js +5 -9
  74. package/src/commands/check.js +29 -16
  75. package/src/commands/doctor.js +2 -0
  76. package/src/commands/env.js +176 -148
  77. package/src/commands/go.js +76 -55
  78. package/src/commands/harden.js +105 -86
  79. package/src/commands/hu-start.js +52 -0
  80. package/src/commands/hu.js +288 -221
  81. package/src/commands/identity.js +111 -78
  82. package/src/commands/init-atril.js +47 -0
  83. package/src/commands/init.js +11 -40
  84. package/src/commands/install-tools.js +70 -85
  85. package/src/commands/main-guard.js +78 -0
  86. package/src/commands/policy.js +226 -184
  87. package/src/commands/qmd.js +27 -21
  88. package/src/commands/rag.js +75 -48
  89. package/src/commands/review-gate.js +422 -339
  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 +94 -25
  94. package/src/config/loader.js +34 -17
  95. package/src/config/overrides.js +2 -1
  96. package/src/config/secrets.js +36 -0
  97. package/src/config.js +1 -0
  98. package/src/environment/adr.js +16 -2
  99. package/src/environment/board-access.js +11 -9
  100. package/src/git/karajan-label.js +20 -8
  101. package/src/guards/main-guard.js +54 -0
  102. package/src/harden/branch-protection.js +36 -3
  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 +81 -35
  106. package/src/harden/sentinel/sentinel-lib.mjs +149 -23
  107. package/src/harden/sentinel/sentinel-shell.mjs +64 -0
  108. package/src/harden/sentinel/sessionstart.mjs +3 -2
  109. package/src/harden/sentinel/stop.mjs +5 -4
  110. package/src/harden/workflow-engine.js +12 -1
  111. package/src/harden/workflow-templates.js +1 -1
  112. package/src/hu/board-lookup.js +29 -0
  113. package/src/hu/gh-identity.js +23 -0
  114. package/src/hu/github-board.js +4 -2
  115. package/src/hu/lane-prune.js +15 -7
  116. package/src/hu/lane-setup.js +65 -0
  117. package/src/hu/lanes.js +66 -0
  118. package/src/hu/team-board-mirror.js +3 -2
  119. package/src/infrastructure/command-runner.js +1 -1
  120. package/src/infrastructure/file-system-service.js +1 -1
  121. package/src/mcp/handlers/direct-handlers.js +2 -292
  122. package/src/mcp/handlers/hu-handlers.js +44 -55
  123. package/src/mcp/handlers/management-handlers.js +2 -42
  124. package/src/mcp/server-handlers.js +16 -22
  125. package/src/mcp/tools.js +5 -200
  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 +56 -43
  134. package/src/rag/bootstrap-index.js +28 -54
  135. package/src/rag/migrate.js +1 -1
  136. package/src/rag/onnx-fallback.js +2 -2
  137. package/src/rag/pid-lease.js +70 -0
  138. package/src/rag/project-store.js +2 -12
  139. package/src/review/card-first.js +57 -46
  140. package/src/review/dual-review.js +5 -4
  141. package/src/review/gate-gitignore.js +23 -4
  142. package/src/review/gate-hook.js +47 -0
  143. package/src/review/one-shot-review.js +51 -37
  144. package/src/review/publish-pr.js +18 -3
  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 +34 -3
  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 +2 -26
  154. package/src/roles/audit-role.js +106 -125
  155. package/src/skills/atril-skills.js +5 -4
  156. package/src/sonar/scanner.js +116 -101
  157. package/src/steward/invariants.js +5 -4
  158. package/src/steward/phantom-sweep.js +66 -0
  159. package/src/tournament/judge.js +60 -53
  160. package/src/utils/agent-home.js +33 -0
  161. package/src/utils/gh-account.js +37 -0
  162. package/src/utils/git.js +0 -13
  163. package/src/utils/home-migration.js +7 -1
  164. package/src/utils/main-checkout.js +53 -0
  165. package/src/utils/qmd-collection.js +3 -1
  166. package/src/utils/welcome.js +3 -3
  167. package/templates/{skills → atril/commands}/kj-architect.md +5 -0
  168. package/templates/{skills → atril/commands}/kj-audit.md +5 -0
  169. package/templates/{skills → atril/commands}/kj-board.md +5 -0
  170. package/templates/{skills → atril/commands}/kj-code.md +5 -0
  171. package/templates/{skills → atril/commands}/kj-csv-transform.md +5 -0
  172. package/templates/{skills → atril/commands}/kj-data-report.md +5 -0
  173. package/templates/{skills → atril/commands}/kj-discover.md +5 -0
  174. package/templates/{skills → atril/commands}/kj-rag-query.md +5 -0
  175. package/templates/{skills → atril/commands}/kj-review.md +5 -0
  176. package/templates/{skills → atril/commands}/kj-security.md +5 -0
  177. package/templates/{skills → atril/commands}/kj-sonar.md +5 -0
  178. package/templates/{skills → atril/commands}/kj-sql-analysis.md +5 -0
  179. package/templates/{skills → atril/commands}/kj-test.md +5 -0
  180. package/packages/hu-board/public/utils/run-launcher.js +0 -169
  181. package/packages/hu-board/src/run-tracker.js +0 -121
  182. package/src/activity-log.js +0 -59
  183. package/src/agents/host-agent.js +0 -38
  184. package/src/agents/model-registry.js +0 -142
  185. package/src/audit/plan-adherence.js +0 -224
  186. package/src/autonomy/arbiter-role.js +0 -71
  187. package/src/autonomy/arbiter.js +0 -22
  188. package/src/autonomy/decider.js +0 -18
  189. package/src/autonomy/decision-resolver.js +0 -58
  190. package/src/autonomy/outcome-report.js +0 -55
  191. package/src/autonomy/stage-ask.js +0 -30
  192. package/src/brain/decision-tracker.js +0 -125
  193. package/src/brain/decisor.js +0 -243
  194. package/src/brain/solomon-consult.js +0 -171
  195. package/src/brain/standby-scheduler.js +0 -8
  196. package/src/budget/comparison.js +0 -96
  197. package/src/canvas/parse-md.js +0 -238
  198. package/src/canvas/schema.js +0 -101
  199. package/src/canvas/to-flat.js +0 -85
  200. package/src/canvas/validate.js +0 -163
  201. package/src/ci/dispatch.js +0 -99
  202. package/src/ci/index.js +0 -3
  203. package/src/ci/pr-diff.js +0 -26
  204. package/src/cli/register-standby.js +0 -26
  205. package/src/commands/architect.js +0 -111
  206. package/src/commands/autorun.js +0 -49
  207. package/src/commands/researcher.js +0 -54
  208. package/src/commands/resume.js +0 -72
  209. package/src/commands/review.js +0 -89
  210. package/src/commands/run.js +0 -185
  211. package/src/commands/standby.js +0 -117
  212. package/src/commands/status.js +0 -36
  213. package/src/commands/triage.js +0 -78
  214. package/src/commands/undo.js +0 -62
  215. package/src/domains/domain-loader.js +0 -245
  216. package/src/domains/domain-registry.js +0 -140
  217. package/src/domains/domain-synthesizer.js +0 -129
  218. package/src/git/automation.js +0 -433
  219. package/src/git/coder-commit-guard.js +0 -40
  220. package/src/git/hu-automation.js +0 -243
  221. package/src/git/hu-snapshot.js +0 -10
  222. package/src/git/symlink-targets.js +0 -57
  223. package/src/golden/asserter.js +0 -92
  224. package/src/golden/loader.js +0 -52
  225. package/src/golden/runner.js +0 -92
  226. package/src/golden/schema.js +0 -41
  227. package/src/guards/duplicate-members.js +0 -86
  228. package/src/guards/intent-guard.js +0 -161
  229. package/src/guards/perf-guard.js +0 -126
  230. package/src/guards/policy-guard.js +0 -90
  231. package/src/guards/policy-resolver.js +0 -85
  232. package/src/guards/secret-redactor.js +0 -71
  233. package/src/hu/acceptance-runner.js +0 -138
  234. package/src/hu/lazy-planner.js +0 -109
  235. package/src/hu/parallel-executor.js +0 -94
  236. package/src/hu/routing-metrics.js +0 -17
  237. package/src/hu/split-validator.js +0 -143
  238. package/src/hu/splitting-detector.js +0 -158
  239. package/src/hu/splitting-generator.js +0 -175
  240. package/src/hu/store.js +0 -394
  241. package/src/infrastructure/mocks.js +0 -182
  242. package/src/mcp/handlers/run-handler.js +0 -318
  243. package/src/mcp/sovereignty-guard.js +0 -113
  244. package/src/mcp/tool-arg-normalizers.js +0 -16
  245. package/src/mutate/reviewer-signal.js +0 -76
  246. package/src/orchestrator/agent-fallback.js +0 -81
  247. package/src/orchestrator/brain-coordinator.js +0 -186
  248. package/src/orchestrator/ci-integration.js +0 -139
  249. package/src/orchestrator/config-init.js +0 -426
  250. package/src/orchestrator/direct-actions.js +0 -217
  251. package/src/orchestrator/drivers/error-recovery.js +0 -287
  252. package/src/orchestrator/drivers/init-context.js +0 -238
  253. package/src/orchestrator/drivers/iteration-loop.js +0 -382
  254. package/src/orchestrator/drivers/iteration-phases/coder-and-refactorer.js +0 -69
  255. package/src/orchestrator/drivers/iteration-phases/guards.js +0 -91
  256. package/src/orchestrator/drivers/iteration-phases/handle-approved.js +0 -29
  257. package/src/orchestrator/drivers/iteration-phases/quality-gates.js +0 -125
  258. package/src/orchestrator/drivers/iteration-phases/reviewer-gate.js +0 -62
  259. package/src/orchestrator/drivers/post-loop.js +0 -404
  260. package/src/orchestrator/drivers/pre-loop-phases/auto-hu-batch.js +0 -137
  261. package/src/orchestrator/drivers/pre-loop-phases/config-deprecations.js +0 -47
  262. package/src/orchestrator/drivers/pre-loop-phases/ensure-addyosmani-skills.js +0 -84
  263. package/src/orchestrator/drivers/pre-loop-phases/inject-loaded-plan.js +0 -393
  264. package/src/orchestrator/drivers/pre-loop.js +0 -524
  265. package/src/orchestrator/drivers/run-hu-batch.js +0 -468
  266. package/src/orchestrator/feedback-enrichment.js +0 -140
  267. package/src/orchestrator/feedback-queue.js +0 -151
  268. package/src/orchestrator/flow-control.js +0 -170
  269. package/src/orchestrator/flow-runner.js +0 -365
  270. package/src/orchestrator/fs-leak-detector.js +0 -228
  271. package/src/orchestrator/hu-scheduler.js +0 -114
  272. package/src/orchestrator/hu-sub-pipeline.js +0 -642
  273. package/src/orchestrator/iteration-gate.js +0 -73
  274. package/src/orchestrator/iteration-stages.js +0 -9
  275. package/src/orchestrator/parallel-limiter.js +0 -74
  276. package/src/orchestrator/pipeline-context.js +0 -72
  277. package/src/orchestrator/post-loop-stages.js +0 -468
  278. package/src/orchestrator/pre-loop-stages.js +0 -11
  279. package/src/orchestrator/preflight-checks.js +0 -487
  280. package/src/orchestrator/repair/repair-detector.js +0 -117
  281. package/src/orchestrator/repair/repair-runner.js +0 -142
  282. package/src/orchestrator/reviewer-fallback.js +0 -45
  283. package/src/orchestrator/role-output-compressor.js +0 -189
  284. package/src/orchestrator/session-journal.js +0 -308
  285. package/src/orchestrator/solomon-escalation.js +0 -331
  286. package/src/orchestrator/solomon-rules.js +0 -212
  287. package/src/orchestrator/stages/acceptance-coverage-stage.js +0 -47
  288. package/src/orchestrator/stages/architect-stage.js +0 -172
  289. package/src/orchestrator/stages/coder-stage.js +0 -506
  290. package/src/orchestrator/stages/domain-curator-stage.js +0 -82
  291. package/src/orchestrator/stages/format-stage.js +0 -61
  292. package/src/orchestrator/stages/hu-reviewer-phases/detect-and-apply-splits.js +0 -127
  293. package/src/orchestrator/stages/hu-reviewer-stage.js +0 -419
  294. package/src/orchestrator/stages/perf-stage.js +0 -140
  295. package/src/orchestrator/stages/planner-stage.js +0 -85
  296. package/src/orchestrator/stages/rag-context-stage.js +0 -80
  297. package/src/orchestrator/stages/rag-preload-decisor.js +0 -58
  298. package/src/orchestrator/stages/research-stage.js +0 -69
  299. package/src/orchestrator/stages/reviewer-stage.js +0 -431
  300. package/src/orchestrator/stages/sonar-stage.js +0 -439
  301. package/src/orchestrator/stages/stage-classes.js +0 -84
  302. package/src/orchestrator/stages/stage-executor.js +0 -155
  303. package/src/orchestrator/stages/suite-green-stage.js +0 -62
  304. package/src/orchestrator/stages/tdd-discipline-stage.js +0 -56
  305. package/src/orchestrator/stages/tool-judge-stage.js +0 -53
  306. package/src/orchestrator/stages/triage-stage.js +0 -172
  307. package/src/orchestrator/standby.js +0 -71
  308. package/src/orchestrator/verification-gate.js +0 -183
  309. package/src/orchestrator.js +0 -22
  310. package/src/plan/adr-generator.js +0 -170
  311. package/src/plan/adr-loader.js +0 -60
  312. package/src/plan/plan-executor.js +0 -100
  313. package/src/plan/plan-validation.js +0 -4
  314. package/src/prompts/acceptance-coverage.js +0 -32
  315. package/src/prompts/arbiter.js +0 -38
  316. package/src/prompts/architect.js +0 -103
  317. package/src/prompts/hu-reviewer.js +0 -244
  318. package/src/prompts/tool-correctness-judge.js +0 -31
  319. package/src/prompts/triage.js +0 -57
  320. package/src/rag/embedder.js +0 -2
  321. package/src/rag/embedders/_cloud-base.js +0 -2
  322. package/src/rag/embedders/cohere.js +0 -2
  323. package/src/rag/embedders/mistral.js +0 -2
  324. package/src/rag/embedders/onnx.js +0 -2
  325. package/src/rag/embedders/openai.js +0 -2
  326. package/src/rag/embedders/voyage.js +0 -2
  327. package/src/rag/rerank.js +0 -4
  328. package/src/rag/where-parser.js +0 -4
  329. package/src/repeat-detector.js +0 -88
  330. package/src/review/diff-generator.js +0 -112
  331. package/src/review/git-stash-helper.js +0 -104
  332. package/src/review/schema.js +0 -31
  333. package/src/review/scope-filter.js +0 -152
  334. package/src/review/snapshot-diff.js +0 -122
  335. package/src/review/tdd-discipline.js +0 -90
  336. package/src/review/tdd-policy.js +0 -69
  337. package/src/roles/acceptance-coverage-role.js +0 -78
  338. package/src/roles/architect-role.js +0 -77
  339. package/src/roles/coder-role.js +0 -113
  340. package/src/roles/commiter-role.js +0 -113
  341. package/src/roles/domain-curator-role.js +0 -134
  342. package/src/roles/hu-reviewer-role.js +0 -64
  343. package/src/roles/impeccable-role.js +0 -85
  344. package/src/roles/index.js +0 -18
  345. package/src/roles/karajan-brain-role.js +0 -134
  346. package/src/roles/perf-role.js +0 -122
  347. package/src/roles/planner-role.js +0 -151
  348. package/src/roles/refactorer-role.js +0 -30
  349. package/src/roles/repairer-role.js +0 -181
  350. package/src/roles/researcher-role.js +0 -70
  351. package/src/roles/reviewer-role.js +0 -115
  352. package/src/roles/security-role.js +0 -73
  353. package/src/roles/solomon-role.js +0 -271
  354. package/src/roles/sonar-role.js +0 -72
  355. package/src/roles/tester-role.js +0 -235
  356. package/src/roles/tool-correctness-judge-role.js +0 -78
  357. package/src/roles/triage-role.js +0 -99
  358. package/src/session/journal/decisions-writer.js +0 -200
  359. package/src/session/journal/iteration-logger.js +0 -194
  360. package/src/session/journal/summary-writer.js +0 -320
  361. package/src/session/journal/tree-writer.js +0 -164
  362. package/src/session/journal/write-all.js +0 -89
  363. package/src/session-cleanup.js +0 -116
  364. package/src/skills/semantic-detector.js +0 -167
  365. package/src/skills/skill-detector.js +0 -385
  366. package/src/sonar/cloud-scanner.js +0 -78
  367. package/src/tracker-bootstrap.js +0 -44
  368. package/src/types/index.js +0 -38
  369. package/src/types/policy.js +0 -43
  370. package/src/types/solomon.js +0 -87
  371. package/src/utils/async-lock.js +0 -31
  372. package/src/utils/budget.js +0 -229
  373. package/src/utils/cwd-confirm.js +0 -39
  374. package/src/utils/display/event-handlers.js +0 -403
  375. package/src/utils/display/formatters.js +0 -132
  376. package/src/utils/display/header.js +0 -47
  377. package/src/utils/display/session-summary.js +0 -118
  378. package/src/utils/display/solomon.js +0 -42
  379. package/src/utils/pricing.js +0 -29
  380. package/src/utils/quota-simulator.js +0 -56
  381. package/src/utils/role-assigner.js +0 -137
  382. package/src/utils/rtk-wrapper.js +0 -87
  383. package/src/utils/run-registry.js +0 -9
  384. package/src/utils/status-dashboard.js +0 -254
  385. package/src/utils/tool-call-extractor.js +0 -56
  386. package/src/webperf/devtools-detect.js +0 -112
  387. package/src/webperf/webperf-role-integration.js +0 -66
  388. package/templates/skills/kj-run.md +0 -73
@@ -1,254 +0,0 @@
1
- /**
2
- * Status dashboard formatter.
3
- * Builds a structured terminal dashboard from session data and run-log lines.
4
- */
5
-
6
- import { HU_STATUS } from "../hu/store.js";
7
-
8
- /**
9
- * Status label mapping with visual indicators for terminal output.
10
- * @type {Record<string, string>}
11
- */
12
- const STATUS_LABELS = {
13
- [HU_STATUS.PENDING]: "pending",
14
- [HU_STATUS.CODING]: "coding",
15
- [HU_STATUS.REVIEWING]: "reviewing",
16
- [HU_STATUS.DONE]: "done",
17
- [HU_STATUS.FAILED]: "failed",
18
- [HU_STATUS.BLOCKED]: "blocked",
19
- [HU_STATUS.CERTIFIED]: "certified",
20
- [HU_STATUS.NEEDS_CONTEXT]: "needs_ctx",
21
- };
22
-
23
- /**
24
- * Format a millisecond duration into a human-readable string (e.g. "3m 42s").
25
- * @param {number} ms
26
- * @returns {string}
27
- */
28
- export function formatDuration(ms) {
29
- if (!ms || ms < 0) return "0s";
30
- const totalSec = Math.floor(ms / 1000);
31
- const hours = Math.floor(totalSec / 3600);
32
- const minutes = Math.floor((totalSec % 3600) / 60);
33
- const seconds = totalSec % 60;
34
-
35
- const parts = [];
36
- if (hours > 0) parts.push(`${hours}h`);
37
- if (minutes > 0) parts.push(`${minutes}m`);
38
- if (seconds > 0 || parts.length === 0) parts.push(`${seconds}s`);
39
- return parts.join(" ");
40
- }
41
-
42
- /**
43
- * Parse the current pipeline stage from log lines.
44
- * @param {string[]} lines - Raw log lines.
45
- * @returns {{ currentStage: string|null, lastEvent: string|null }}
46
- */
47
- export function parseStageFromLog(lines) {
48
- let currentStage = null;
49
- let lastEvent = null;
50
-
51
- for (const line of lines) {
52
- const stageStart = /\[(\w+):start\]/.exec(line);
53
- if (stageStart) currentStage = stageStart[1];
54
-
55
- const stageDone = /\[(\w+):done\]|\[(\w+)\] finished/.exec(line);
56
- if (stageDone) {
57
- const doneName = stageDone[1] || stageDone[2];
58
- if (doneName === currentStage) currentStage = "idle";
59
- }
60
-
61
- if (line.includes("[standby]") || line.includes("standby")) {
62
- currentStage = "standby";
63
- }
64
-
65
- if (line.trim()) lastEvent = line.trim();
66
- }
67
-
68
- return { currentStage, lastEvent };
69
- }
70
-
71
- /**
72
- * Format a single HU line for the dashboard.
73
- * @param {object} story - HU story object.
74
- * @param {boolean} isCurrent - Whether this is the currently active HU.
75
- * @returns {string}
76
- */
77
- function formatHuLine(story, isCurrent) {
78
- const id = (story.id || "???").padEnd(12);
79
- const rawStatus = story.status || "pending";
80
- const label = STATUS_LABELS[rawStatus] || rawStatus;
81
- const statusStr = `[${label}]`.padEnd(13);
82
- const title = story.title || story.original?.text || "(untitled)";
83
- const truncTitle = title.length > 40 ? title.slice(0, 37) + "..." : title;
84
-
85
- let timing = "";
86
- if (story.duration_ms) {
87
- timing = formatDuration(story.duration_ms);
88
- }
89
-
90
- const blockedInfo = story.blocked_by?.length
91
- ? ` (needs ${story.blocked_by.join(", ")})`
92
- : "";
93
-
94
- const marker = isCurrent ? " <-- current" : "";
95
- const timingStr = timing ? ` ${timing}` : "";
96
-
97
- return ` ${id} ${statusStr} ${truncTitle}${blockedInfo}${timingStr}${marker}`;
98
- }
99
-
100
- /**
101
- * Build a terminal dashboard string from session data and log lines.
102
- *
103
- * @param {object|null} sessionData - Session JSON (from session-store) or null.
104
- * @param {string[]} logLines - Raw run-log lines.
105
- * @param {object} [options] - Optional overrides.
106
- * @param {object[]|null} [options.stories] - HU stories array (from hu batch).
107
- * @returns {string}
108
- */
109
- export function buildDashboard(sessionData, logLines, options = {}) {
110
- if (!sessionData) {
111
- return "No active pipeline";
112
- }
113
-
114
- const lines = [];
115
- const config = sessionData.config_snapshot || {};
116
- const maxIter = config.max_iterations ?? "?";
117
- const status = sessionData.status || "unknown";
118
-
119
- // Parse log for current stage info
120
- const logInfo = parseStageFromLog(logLines || []);
121
-
122
- // Determine iteration from session or log
123
- const iteration = sessionData.reviewer_retry_count != null
124
- ? sessionData.reviewer_retry_count + 1
125
- : null;
126
- const iterFromLog = parseIterationFromLog(logLines || []);
127
- const displayIter = iterFromLog || iteration || "?";
128
-
129
- // Pipeline header
130
- const statusUpper = status.toUpperCase();
131
- lines.push(`Pipeline: ${statusUpper} (iteration ${displayIter}/${maxIter})`);
132
-
133
- // Duration
134
- const duration = computeDuration(sessionData);
135
- lines.push(`Duration: ${formatDuration(duration)}`);
136
-
137
- // Agent info
138
- const coderProvider = config.coder?.provider || config.roles?.coder?.provider || "?";
139
- const reviewerProvider = config.reviewer?.provider || config.roles?.reviewer?.provider || "?";
140
- lines.push(`Agent: ${coderProvider} (coder) / ${reviewerProvider} (reviewer)`);
141
-
142
- // HU stories section
143
- const stories = options.stories || [];
144
- if (stories.length > 0) {
145
- lines.push("");
146
- lines.push("HUs:");
147
-
148
- // Determine which story is currently being worked on
149
- const currentStory = stories.find(s =>
150
- s.status === HU_STATUS.CODING || s.status === HU_STATUS.REVIEWING
151
- );
152
-
153
- for (const story of stories) {
154
- const isCurrent = currentStory && story.id === currentStory.id;
155
- lines.push(formatHuLine(story, isCurrent));
156
- }
157
- }
158
-
159
- // Current stage and last event
160
- lines.push("");
161
- const stage = logInfo.currentStage || "idle";
162
- const iterSuffix = displayIter !== "?" ? ` (iteration ${displayIter})` : "";
163
- lines.push(`Current stage: ${stage}${iterSuffix}`);
164
-
165
- if (logInfo.lastEvent) {
166
- // Truncate last event for display
167
- const maxLen = 120;
168
- const event = logInfo.lastEvent.length > maxLen
169
- ? logInfo.lastEvent.slice(0, maxLen - 3) + "..."
170
- : logInfo.lastEvent;
171
- lines.push(`Last event: ${event}`);
172
- }
173
-
174
- // Errors
175
- if (sessionData.deferred_issues?.length) {
176
- lines.push("");
177
- lines.push(`Deferred issues: ${sessionData.deferred_issues.length}`);
178
- }
179
-
180
- return lines.join("\n");
181
- }
182
-
183
- /**
184
- * Build a structured JSON response for MCP consumers.
185
- *
186
- * @param {object|null} sessionData - Session JSON or null.
187
- * @param {string[]} logLines - Raw run-log lines.
188
- * @param {object} [options] - Optional overrides.
189
- * @param {object[]|null} [options.stories] - HU stories array.
190
- * @returns {object}
191
- */
192
- export function buildDashboardJson(sessionData, logLines, options = {}) {
193
- if (!sessionData) {
194
- return { ok: false, message: "No active pipeline" };
195
- }
196
-
197
- const config = sessionData.config_snapshot || {};
198
- const logInfo = parseStageFromLog(logLines || []);
199
- const iterFromLog = parseIterationFromLog(logLines || []);
200
- const iteration = iterFromLog
201
- || (sessionData.reviewer_retry_count != null ? sessionData.reviewer_retry_count + 1 : null);
202
-
203
- const stories = (options.stories || []).map(s => ({
204
- id: s.id,
205
- status: s.status || "pending",
206
- title: s.title || s.original?.text || null,
207
- blocked_by: s.blocked_by || [],
208
- duration_ms: s.duration_ms || null,
209
- }));
210
-
211
- return {
212
- ok: true,
213
- pipeline: {
214
- status: sessionData.status || "unknown",
215
- iteration: iteration || null,
216
- maxIterations: config.max_iterations ?? null,
217
- duration_ms: computeDuration(sessionData),
218
- coder: config.coder?.provider || config.roles?.coder?.provider || null,
219
- reviewer: config.reviewer?.provider || config.roles?.reviewer?.provider || null,
220
- },
221
- hus: stories,
222
- currentStage: logInfo.currentStage || "idle",
223
- lastEvent: logInfo.lastEvent || null,
224
- };
225
- }
226
-
227
- /**
228
- * Parse iteration number from log lines.
229
- * @param {string[]} lines
230
- * @returns {number|null}
231
- */
232
- function parseIterationFromLog(lines) {
233
- let iteration = null;
234
- for (const line of lines) {
235
- const m = /[Ii]teration\s+(\d+)/.exec(line);
236
- if (m) iteration = Number.parseInt(m[1], 10);
237
- }
238
- return iteration;
239
- }
240
-
241
- /**
242
- * Compute pipeline duration in milliseconds from session timestamps.
243
- * @param {object} sessionData
244
- * @returns {number}
245
- */
246
- function computeDuration(sessionData) {
247
- const created = sessionData.created_at;
248
- if (!created) return 0;
249
- const start = new Date(created).getTime();
250
- const now = sessionData.updated_at
251
- ? new Date(sessionData.updated_at).getTime()
252
- : Date.now();
253
- return Math.max(0, now - start);
254
- }
@@ -1,56 +0,0 @@
1
- // KJC-TSK-0375 PR2 — Extract structured tool calls from an agent transcript.
2
- //
3
- // The ToolCorrectnessJudgeRole (PR1) consumes a list of `{tool, args}`
4
- // objects. The coder writes a raw transcript (provider-dependent format) to
5
- // disk per iteration. This module bridges the two: parse the transcript,
6
- // return the ordered list of tool invocations.
7
- //
8
- // Provider-agnostic interface; Claude stream-json is the only format
9
- // implemented today. New providers add a branch below — keep parsers
10
- // pure (no I/O), so the role tests can mock transcripts trivially.
11
-
12
- const PROVIDER_PARSERS = {
13
- claude: parseClaudeStreamJson,
14
- };
15
-
16
- /**
17
- * Extract tool calls from a transcript string.
18
- *
19
- * @param {object} args
20
- * @param {string} args.transcript - raw agent output (stdout/stderr buffer).
21
- * @param {string} [args.provider] - "claude" (default). Unknown returns [].
22
- * @returns {Array<{tool:string, args:object}>}
23
- */
24
- export function extractToolCalls({ transcript, provider = "claude" } = {}) {
25
- if (typeof transcript !== "string" || transcript.length === 0) return [];
26
- const parser = PROVIDER_PARSERS[provider];
27
- if (!parser) return [];
28
- return parser(transcript);
29
- }
30
-
31
- // Claude emits one JSON event per line. We care about `assistant` events
32
- // whose `message.content` is an array containing `tool_use` blocks with
33
- // `{type:"tool_use", name, input}`. Lines that fail to parse, that are
34
- // not `assistant`, or whose content is not an array are silently skipped:
35
- // the transcript also carries `system`, `result`, `rate_limit_event`, etc.
36
- function parseClaudeStreamJson(transcript) {
37
- const out = [];
38
- for (const raw of transcript.split("\n")) {
39
- const line = raw.trim();
40
- if (!line || line[0] !== "{") continue;
41
- let obj;
42
- try { obj = JSON.parse(line); } catch { continue; }
43
- if (obj?.type !== "assistant") continue;
44
- const content = obj?.message?.content;
45
- if (!Array.isArray(content)) continue;
46
- for (const block of content) {
47
- if (block?.type === "tool_use" && typeof block.name === "string") {
48
- out.push({
49
- tool: block.name,
50
- args: block.input && typeof block.input === "object" ? block.input : {},
51
- });
52
- }
53
- }
54
- }
55
- return out;
56
- }
@@ -1,112 +0,0 @@
1
- // Chrome DevTools MCP detection and WebPerf skill auto-installation.
2
-
3
- import fs from "node:fs/promises";
4
- import path from "node:path";
5
- import os from "node:os";
6
- import { isOpenSkillsAvailable, listSkills } from "../skills/openskills-client.js";
7
-
8
- /** Skill names relevant for WebPerf analysis. Already installed globally via openskills. */
9
- export const WEBPERF_SKILLS = [
10
- "optimize",
11
- "audit",
12
- "polish"
13
- ];
14
-
15
- /**
16
- * Check whether Chrome DevTools MCP is configured and available.
17
- * Checks: (1) config flag, (2) Claude MCP config (~/.claude.json), (3) VS Code MCP settings.
18
- * @param {object} config - merged Karajan config
19
- * @returns {boolean}
20
- */
21
- export function isDevToolsMcpAvailable(config) {
22
- // Explicit config flag takes priority
23
- if (config?.webperf?.devtools_mcp === true) return true;
24
- if (config?.webperf?.devtools_mcp === false) return false;
25
-
26
- // Check cached detection result
27
- if (_devToolsDetected !== null) return _devToolsDetected;
28
-
29
- // Not yet detected - return false (async detection runs at init)
30
- return false;
31
- }
32
-
33
- let _devToolsDetected = null;
34
-
35
- /**
36
- * Auto-detect Chrome DevTools MCP from system configuration.
37
- * Checks ~/.claude.json and VS Code MCP settings.
38
- * Call once at pipeline init.
39
- */
40
- export async function detectDevToolsMcp(logger) {
41
- // Check Claude MCP config
42
- const claudeConfigPath = path.join(os.homedir(), ".claude.json");
43
- try {
44
- const raw = await fs.readFile(claudeConfigPath, "utf8");
45
- const parsed = JSON.parse(raw);
46
- const mcpServers = parsed?.mcpServers || parsed?.mcp_servers || {};
47
- if (mcpServers["chrome-devtools"] || mcpServers["chrome_devtools"]) {
48
- _devToolsDetected = true;
49
- logger?.info?.("Chrome DevTools MCP detected in ~/.claude.json");
50
- return true;
51
- }
52
- } catch { /* file not found or parse error */ }
53
-
54
- // Check VS Code MCP settings
55
- const vscodePaths = [
56
- path.join(os.homedir(), ".vscode", "settings.json"),
57
- path.join(process.cwd(), ".vscode", "settings.json")
58
- ];
59
- for (const vscPath of vscodePaths) {
60
- try {
61
- const raw = await fs.readFile(vscPath, "utf8");
62
- if (raw.includes("chrome-devtools") || raw.includes("chrome_devtools")) {
63
- _devToolsDetected = true;
64
- logger?.info?.(`Chrome DevTools MCP detected in ${vscPath}`);
65
- return true;
66
- }
67
- } catch { /* not found */ }
68
- }
69
-
70
- _devToolsDetected = false;
71
- return false;
72
- }
73
-
74
- /**
75
- * Ensure WebPerf skills are installed via OpenSkills.
76
- * Installs any missing skills from WEBPERF_SKILLS.
77
- * @param {string} projectDir - absolute path to the project root
78
- * @param {object} [logger] - optional logger ({ info, warn })
79
- * @returns {Promise<{ installed: string[], alreadyInstalled: string[], skipped: string[] }>}
80
- */
81
- export async function ensureWebPerfSkills(projectDir, logger) {
82
- const result = { installed: [], alreadyInstalled: [], skipped: [] };
83
-
84
- const available = await isOpenSkillsAvailable();
85
- if (!available) {
86
- logger?.debug?.("OpenSkills CLI not available - WebPerf skills unavailable");
87
- result.skipped = [...WEBPERF_SKILLS];
88
- return result;
89
- }
90
-
91
- // List skills (includes global installs)
92
- const listResult = await listSkills({ projectDir });
93
- const installedNames = new Set(
94
- (listResult.ok ? listResult.skills : []).map(s => s.name)
95
- );
96
-
97
- for (const skill of WEBPERF_SKILLS) {
98
- if (installedNames.has(skill)) {
99
- result.alreadyInstalled.push(skill);
100
- } else {
101
- // Skills should be installed globally via `openskills install owner/repo`
102
- // Don't attempt auto-install with bare names — just note they're missing
103
- result.skipped.push(skill);
104
- }
105
- }
106
-
107
- if (result.alreadyInstalled.length > 0) {
108
- logger?.info?.(`WebPerf skills available: ${result.alreadyInstalled.join(", ")}`);
109
- }
110
-
111
- return result;
112
- }
@@ -1,66 +0,0 @@
1
- /**
2
- * Integration helpers that format CWV gate results for the
3
- * impeccable prompt and for pipeline progress events.
4
- */
5
-
6
- const RATING_ICONS = { good: "PASS", "needs-improvement": "WARN", poor: "FAIL" };
7
-
8
- /**
9
- * Build a human-readable section for the impeccable prompt.
10
- *
11
- * @param {{ pass: boolean, scores: object, blocking: Array, advisory: Array }} cwvResult
12
- * @returns {string}
13
- */
14
- export function buildWebPerfSection(cwvResult) {
15
- const lines = [];
16
- const verdict = cwvResult.pass ? "PASSED" : "FAILED";
17
- lines.push(`## WebPerf — Core Web Vitals (${verdict})`);
18
- lines.push("");
19
-
20
- for (const [metric, { value, rating }] of Object.entries(cwvResult.scores)) {
21
- const icon = RATING_ICONS[rating] || rating;
22
- const unit = metric === "cls" ? "" : "ms";
23
- lines.push(`- **${metric.toUpperCase()}**: ${value}${unit} [${icon}]`);
24
- }
25
-
26
- if (cwvResult.blocking.length > 0) {
27
- lines.push("");
28
- lines.push("### Blocking issues");
29
- for (const b of cwvResult.blocking) {
30
- const unit = b.metric === "cls" ? "" : "ms";
31
- lines.push(`- ${b.metric.toUpperCase()}: ${b.value}${unit} exceeds poor threshold (${b.threshold}${unit})`);
32
- }
33
- }
34
-
35
- if (cwvResult.advisory.length > 0) {
36
- lines.push("");
37
- lines.push("### Advisory (needs improvement)");
38
- for (const a of cwvResult.advisory) {
39
- const unit = a.metric === "cls" ? "" : "ms";
40
- lines.push(`- ${a.metric.toUpperCase()}: ${a.value}${unit} exceeds good threshold (${a.threshold}${unit})`);
41
- }
42
- }
43
-
44
- return lines.join("\n");
45
- }
46
-
47
- /**
48
- * Format CWV result for a pipeline progress event payload.
49
- *
50
- * @param {{ pass: boolean, scores: object, blocking: Array, advisory: Array }} cwvResult
51
- * @returns {{ type: string, pass: boolean, metrics: object, blockingCount: number, advisoryCount: number }}
52
- */
53
- export function formatCwvForEvent(cwvResult) {
54
- const metrics = {};
55
- for (const [metric, { value, rating }] of Object.entries(cwvResult.scores)) {
56
- metrics[metric] = { value, rating };
57
- }
58
-
59
- return {
60
- type: "webperf-cwv",
61
- pass: cwvResult.pass,
62
- metrics,
63
- blockingCount: cwvResult.blocking.length,
64
- advisoryCount: cwvResult.advisory.length
65
- };
66
- }
@@ -1,73 +0,0 @@
1
- # kj-run — Full Pipeline (Skills Mode)
2
-
3
- Execute the complete Karajan pipeline as sequential skills.
4
-
5
- ## Your task
6
-
7
- $ARGUMENTS
8
-
9
- ## Pipeline steps (execute in order)
10
-
11
- ### Step 1 — Discover (optional but recommended)
12
- Analyze the task for gaps before coding:
13
- - Identify missing requirements, ambiguities, contradictions
14
- - If critical gaps found, STOP and ask the user before proceeding
15
- - If ready, continue
16
-
17
- ### Step 2 — Code (with guardrails)
18
- Implement the task:
19
- 1. **Tests first** (TDD): write/update tests before implementation
20
- 2. **Implement**: minimal, focused code to fulfill the task
21
- 3. **Verify**: run the test suite
22
- 4. **Security check**: no hardcoded secrets, no injection vectors, no destructive ops in the diff
23
- 5. **Diff check**: run `git diff` and verify only intended lines changed
24
- 6. If any guardrail fails, fix before proceeding
25
-
26
- ### Step 3 — Review (self-review)
27
- Review your own changes against quality standards:
28
- 1. Run `git diff main...HEAD` (or base branch)
29
- 2. Check: security, correctness, tests, architecture, style (in that order)
30
- 3. Flag blocking issues:
31
- - Hardcoded credentials or secrets
32
- - Entire files overwritten instead of targeted edits
33
- - Missing tests for new code
34
- - SQL injection, XSS, command injection
35
- - Destructive operations
36
- 4. If blocking issues found, fix them and re-review
37
- 5. If clean, proceed
38
-
39
- ### Step 4 — Test audit
40
- Verify test quality:
41
- 1. Every changed source file has corresponding tests
42
- 2. Run `npm test` (or equivalent) — all must pass
43
- 3. No skipped tests for changed code
44
- 4. If tests fail, fix before proceeding
45
-
46
- ### Step 5 — Security scan
47
- Quick security audit on the diff:
48
- 1. Scan for OWASP top 10 in changed files
49
- 2. Check for leaked secrets, injection vectors, missing auth
50
- 3. If critical/high findings, fix before proceeding
51
-
52
- ### Step 6 — Sonar (if available)
53
- If SonarQube is running (`docker ps | grep sonarqube`):
54
- 1. Run `npx @sonar/scan`
55
- 2. Check quality gate
56
- 3. Fix blockers and critical issues
57
-
58
- ### Step 7 — Commit
59
- If all steps pass:
60
- 1. Stage changed files: `git add <specific files>`
61
- 2. Commit with conventional commit message: `feat:`, `fix:`, `refactor:`, etc.
62
- 3. Do NOT push unless the user explicitly asks
63
-
64
- ## HU Board Integration
65
- If HU Board is enabled (`hu_board.enabled: true` in config), stories and sessions
66
- are automatically tracked and visible at the board URL. Run `kj board` to start it.
67
-
68
- ## Important rules
69
-
70
- - **Never skip steps** — execute all applicable steps in order
71
- - **Fix before proceeding** — if a step finds issues, fix them before moving to the next
72
- - **Report progress** — after each step, briefly state what was done and the result
73
- - **Stop on critical** — if a critical security or correctness issue can't be fixed, stop and report