@karajan-family/code 4.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (746) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +98 -0
  3. package/bin/karajan-mcp.js +2 -0
  4. package/bin/kj-rag-mcp.js +75 -0
  5. package/bin/kj-tail +361 -0
  6. package/bin/kj.js +2 -0
  7. package/docs/README.es.md +80 -0
  8. package/docs/karajan-code-logo-small.png +0 -0
  9. package/library/logical-clocks-lamport.md +40 -0
  10. package/package.json +140 -0
  11. package/packages/ai-trash/README.md +37 -0
  12. package/packages/ai-trash/bin/kj-trash.js +10 -0
  13. package/packages/ai-trash/package.json +43 -0
  14. package/packages/ai-trash/src/cli.js +200 -0
  15. package/packages/ai-trash/src/destructive-parser.js +74 -0
  16. package/packages/ai-trash/src/git-snapshot.js +128 -0
  17. package/packages/ai-trash/src/hook.js +137 -0
  18. package/packages/ai-trash/src/index.js +14 -0
  19. package/packages/ai-trash/src/install.js +73 -0
  20. package/packages/ai-trash/src/logger.js +60 -0
  21. package/packages/ai-trash/src/manifest.js +91 -0
  22. package/packages/ai-trash/src/permissions.js +26 -0
  23. package/packages/ai-trash/src/snapshot.js +66 -0
  24. package/packages/ai-trash/src/ulid.js +66 -0
  25. package/packages/hu-board/README.md +69 -0
  26. package/packages/hu-board/package.json +28 -0
  27. package/packages/hu-board/public/app.js +259 -0
  28. package/packages/hu-board/public/index.html +77 -0
  29. package/packages/hu-board/public/pipeline.css +132 -0
  30. package/packages/hu-board/public/pipeline.html +48 -0
  31. package/packages/hu-board/public/pipeline.js +200 -0
  32. package/packages/hu-board/public/rag.html +21 -0
  33. package/packages/hu-board/public/rag.js +39 -0
  34. package/packages/hu-board/public/styles.css +973 -0
  35. package/packages/hu-board/public/utils/api.js +139 -0
  36. package/packages/hu-board/public/utils/board-view.js +473 -0
  37. package/packages/hu-board/public/utils/command-launcher.js +213 -0
  38. package/packages/hu-board/public/utils/config-editor.js +181 -0
  39. package/packages/hu-board/public/utils/dashboard-view.js +103 -0
  40. package/packages/hu-board/public/utils/formatters.js +300 -0
  41. package/packages/hu-board/public/utils/graph-view.js +216 -0
  42. package/packages/hu-board/public/utils/hu-actions.js +224 -0
  43. package/packages/hu-board/public/utils/init-listeners.js +180 -0
  44. package/packages/hu-board/public/utils/log-panel.js +222 -0
  45. package/packages/hu-board/public/utils/modals.js +309 -0
  46. package/packages/hu-board/public/utils/plan-rollup-view.js +53 -0
  47. package/packages/hu-board/public/utils/preflight-view.js +89 -0
  48. package/packages/hu-board/public/utils/project-actions.js +143 -0
  49. package/packages/hu-board/public/utils/project-picker-view.js +139 -0
  50. package/packages/hu-board/public/utils/run-launcher.js +169 -0
  51. package/packages/hu-board/public/utils/server-push.js +252 -0
  52. package/packages/hu-board/public/utils/sessions-view.js +199 -0
  53. package/packages/hu-board/public/utils/story-detail-view.js +324 -0
  54. package/packages/hu-board/public/utils/story-edit-form.js +271 -0
  55. package/packages/hu-board/public/wiki.html +32 -0
  56. package/packages/hu-board/public/wiki.js +53 -0
  57. package/packages/hu-board/src/auth.js +92 -0
  58. package/packages/hu-board/src/boot-info.js +16 -0
  59. package/packages/hu-board/src/cleanup-zombies.js +145 -0
  60. package/packages/hu-board/src/command-runner.js +133 -0
  61. package/packages/hu-board/src/config-yaml.js +531 -0
  62. package/packages/hu-board/src/db.js +963 -0
  63. package/packages/hu-board/src/ephemeral-cleaner.js +196 -0
  64. package/packages/hu-board/src/event-bus.js +58 -0
  65. package/packages/hu-board/src/format.js +207 -0
  66. package/packages/hu-board/src/hu-zombie-reaper.js +103 -0
  67. package/packages/hu-board/src/journal-parser.js +180 -0
  68. package/packages/hu-board/src/plan-mutations.js +424 -0
  69. package/packages/hu-board/src/preflight.js +286 -0
  70. package/packages/hu-board/src/routes/api.js +1374 -0
  71. package/packages/hu-board/src/routes/pipeline.js +45 -0
  72. package/packages/hu-board/src/routes/rag.js +42 -0
  73. package/packages/hu-board/src/routes/wiki.js +43 -0
  74. package/packages/hu-board/src/run-tracker.js +121 -0
  75. package/packages/hu-board/src/server.js +438 -0
  76. package/packages/hu-board/src/sync.js +732 -0
  77. package/packages/hu-board/src/token-store.js +56 -0
  78. package/packages/hu-board/src/zombie-reaper.js +206 -0
  79. package/scripts/ai-attribution-guard.yml +84 -0
  80. package/scripts/audit-test-diet.mjs +151 -0
  81. package/scripts/build-sea.mjs +150 -0
  82. package/scripts/diet-baseline.mjs +170 -0
  83. package/scripts/dual-publish.mjs +67 -0
  84. package/scripts/esbuild-sea.config.mjs +273 -0
  85. package/scripts/git-hooks/post-merge +18 -0
  86. package/scripts/install-binary.ps1 +174 -0
  87. package/scripts/install-binary.sh +159 -0
  88. package/scripts/install-guard-all-repos.sh +85 -0
  89. package/scripts/install-kj.sh +193 -0
  90. package/scripts/install.js +901 -0
  91. package/scripts/install.sh +7 -0
  92. package/scripts/postinstall.js +117 -0
  93. package/scripts/protect-all-repos.sh +88 -0
  94. package/scripts/quickstart-gate.mjs +97 -0
  95. package/scripts/regen-arch-stats.sh +71 -0
  96. package/scripts/setup-multi-instance.sh +150 -0
  97. package/scripts/verify-pack.mjs +278 -0
  98. package/src/activity-log.js +59 -0
  99. package/src/agents/agy-agent.js +62 -0
  100. package/src/agents/aider-agent.js +78 -0
  101. package/src/agents/availability.js +52 -0
  102. package/src/agents/base-agent.js +134 -0
  103. package/src/agents/claude-agent.js +413 -0
  104. package/src/agents/codex-agent.js +112 -0
  105. package/src/agents/copilot-agent.js +65 -0
  106. package/src/agents/gemini-agent.js +85 -0
  107. package/src/agents/host-agent.js +38 -0
  108. package/src/agents/index.js +59 -0
  109. package/src/agents/kimi-agent.js +45 -0
  110. package/src/agents/model-registry.js +137 -0
  111. package/src/agents/opencode-agent.js +72 -0
  112. package/src/agents/qwen-agent.js +20 -0
  113. package/src/agents/resolve-bin.js +73 -0
  114. package/src/audit/agent-readiness.js +259 -0
  115. package/src/audit/ai-slop-findings.js +102 -0
  116. package/src/audit/audit-fallback.js +66 -0
  117. package/src/audit/audit-history-display.js +61 -0
  118. package/src/audit/audit-history.js +102 -0
  119. package/src/audit/basal-cost.js +281 -0
  120. package/src/audit/circular-deps.js +144 -0
  121. package/src/audit/dead-exports.js +186 -0
  122. package/src/audit/deterministic-summary.js +327 -0
  123. package/src/audit/harness-scorecard.js +100 -0
  124. package/src/audit/harness-section.js +81 -0
  125. package/src/audit/infra-findings.js +100 -0
  126. package/src/audit/injection-findings.js +114 -0
  127. package/src/audit/issue-filter.js +133 -0
  128. package/src/audit/osv-findings.js +167 -0
  129. package/src/audit/plan-adherence.js +224 -0
  130. package/src/audit/semgrep-findings.js +129 -0
  131. package/src/audit/sonar-findings.js +93 -0
  132. package/src/audit/webperf-input.js +133 -0
  133. package/src/autonomy/arbiter-role.js +71 -0
  134. package/src/autonomy/arbiter.js +22 -0
  135. package/src/autonomy/decider.js +18 -0
  136. package/src/autonomy/decision-resolver.js +58 -0
  137. package/src/autonomy/outcome-report.js +55 -0
  138. package/src/autonomy/policy.js +41 -0
  139. package/src/autonomy/stage-ask.js +30 -0
  140. package/src/bootstrap.js +276 -0
  141. package/src/brain/agent-error-classifier.js +116 -0
  142. package/src/brain/decision-tracker.js +125 -0
  143. package/src/brain/decisor.js +243 -0
  144. package/src/brain/solomon-consult.js +171 -0
  145. package/src/brain/standby-scheduler.js +8 -0
  146. package/src/brain/standby-store.js +12 -0
  147. package/src/brain/with-brain-recovery.js +235 -0
  148. package/src/budget/comparison.js +96 -0
  149. package/src/canvas/parse-md.js +238 -0
  150. package/src/canvas/schema.js +101 -0
  151. package/src/canvas/to-flat.js +85 -0
  152. package/src/canvas/validate.js +163 -0
  153. package/src/checks/ai-surface.js +79 -0
  154. package/src/checks/ai-trash.js +34 -0
  155. package/src/checks/binaries.js +207 -0
  156. package/src/checks/ci.js +105 -0
  157. package/src/checks/config-files.js +217 -0
  158. package/src/checks/dir-setup.js +103 -0
  159. package/src/checks/guarantee-level.js +38 -0
  160. package/src/checks/hardware.js +150 -0
  161. package/src/checks/harness-scorecard.js +41 -0
  162. package/src/checks/mcp-health.js +169 -0
  163. package/src/checks/method.js +73 -0
  164. package/src/checks/native-build.js +67 -0
  165. package/src/checks/node.js +70 -0
  166. package/src/checks/ollama.js +41 -0
  167. package/src/checks/orphans.js +77 -0
  168. package/src/checks/ports.js +188 -0
  169. package/src/checks/project-checks.js +245 -0
  170. package/src/checks/qmd.js +41 -0
  171. package/src/checks/rag-hooks.js +54 -0
  172. package/src/checks/release-check.js +102 -0
  173. package/src/checks/rtk.js +36 -0
  174. package/src/checks/runner.js +326 -0
  175. package/src/checks/skills.js +53 -0
  176. package/src/checks/sonar.js +67 -0
  177. package/src/checks/squeezr.js +36 -0
  178. package/src/checks/system.js +53 -0
  179. package/src/checks/tokens.js +172 -0
  180. package/src/checks/types.js +103 -0
  181. package/src/ci/dispatch.js +99 -0
  182. package/src/ci/index.js +3 -0
  183. package/src/ci/pr-diff.js +26 -0
  184. package/src/ci/repo.js +45 -0
  185. package/src/cli/_shared.js +30 -0
  186. package/src/cli/advanced-commands.js +61 -0
  187. package/src/cli/register-meta.js +772 -0
  188. package/src/cli/register-pipeline.js +335 -0
  189. package/src/cli/register-plan.js +224 -0
  190. package/src/cli/register-roles-skills.js +54 -0
  191. package/src/cli/register-sonar.js +28 -0
  192. package/src/cli/register-standby.js +26 -0
  193. package/src/cli.js +155 -0
  194. package/src/commands/advanced.js +31 -0
  195. package/src/commands/agent-run.js +63 -0
  196. package/src/commands/agents.js +105 -0
  197. package/src/commands/architect.js +123 -0
  198. package/src/commands/audit.js +430 -0
  199. package/src/commands/autorun.js +49 -0
  200. package/src/commands/board.js +458 -0
  201. package/src/commands/check.js +40 -0
  202. package/src/commands/clean.js +145 -0
  203. package/src/commands/code.js +45 -0
  204. package/src/commands/config.js +74 -0
  205. package/src/commands/discover.js +105 -0
  206. package/src/commands/doctor.js +251 -0
  207. package/src/commands/env.js +207 -0
  208. package/src/commands/harden.js +203 -0
  209. package/src/commands/hu.js +210 -0
  210. package/src/commands/identity.js +60 -0
  211. package/src/commands/init.js +950 -0
  212. package/src/commands/install-tools.js +432 -0
  213. package/src/commands/mutate.js +94 -0
  214. package/src/commands/ollama.js +44 -0
  215. package/src/commands/onboard.js +45 -0
  216. package/src/commands/plan/_shared.js +55 -0
  217. package/src/commands/plan/add-hu.js +23 -0
  218. package/src/commands/plan/delete.js +9 -0
  219. package/src/commands/plan/fix.js +99 -0
  220. package/src/commands/plan/generate.js +532 -0
  221. package/src/commands/plan/index.js +13 -0
  222. package/src/commands/plan/list.js +21 -0
  223. package/src/commands/plan/migrate-result.js +41 -0
  224. package/src/commands/plan/ready.js +46 -0
  225. package/src/commands/plan/remove-hu.js +17 -0
  226. package/src/commands/plan/share.js +85 -0
  227. package/src/commands/plan/show.js +81 -0
  228. package/src/commands/plan/unshare.js +41 -0
  229. package/src/commands/plan/validate.js +20 -0
  230. package/src/commands/plan.js +17 -0
  231. package/src/commands/policy.js +164 -0
  232. package/src/commands/privacy.js +45 -0
  233. package/src/commands/qmd.js +86 -0
  234. package/src/commands/rag-mcp.js +18 -0
  235. package/src/commands/rag.js +173 -0
  236. package/src/commands/report-issue.js +77 -0
  237. package/src/commands/report.js +469 -0
  238. package/src/commands/researcher.js +54 -0
  239. package/src/commands/resume.js +68 -0
  240. package/src/commands/review-gate.js +355 -0
  241. package/src/commands/review.js +89 -0
  242. package/src/commands/roles.js +116 -0
  243. package/src/commands/run.js +185 -0
  244. package/src/commands/scan.js +18 -0
  245. package/src/commands/skills.js +86 -0
  246. package/src/commands/sonar.js +53 -0
  247. package/src/commands/standby.js +117 -0
  248. package/src/commands/start.js +121 -0
  249. package/src/commands/status.js +36 -0
  250. package/src/commands/sync.js +103 -0
  251. package/src/commands/telemetry.js +70 -0
  252. package/src/commands/tournament.js +85 -0
  253. package/src/commands/triage.js +78 -0
  254. package/src/commands/undo.js +62 -0
  255. package/src/commands/watch.js +46 -0
  256. package/src/commands/webperf.js +162 -0
  257. package/src/commands/worktree.js +76 -0
  258. package/src/config/defaults.js +270 -0
  259. package/src/config/loader.js +204 -0
  260. package/src/config/overrides.js +220 -0
  261. package/src/config/role-resolver.js +171 -0
  262. package/src/config/schema.js +299 -0
  263. package/src/config/test-harness.js +78 -0
  264. package/src/config.js +34 -0
  265. package/src/domains/domain-loader.js +245 -0
  266. package/src/domains/domain-registry.js +140 -0
  267. package/src/domains/domain-synthesizer.js +129 -0
  268. package/src/environment/adr.js +45 -0
  269. package/src/environment/board-access.js +97 -0
  270. package/src/environment/board-select.js +59 -0
  271. package/src/environment/briefs.js +129 -0
  272. package/src/environment/issue-report.js +72 -0
  273. package/src/environment/mcp-wiring.js +44 -0
  274. package/src/environment/playbook.js +127 -0
  275. package/src/git/automation.js +334 -0
  276. package/src/git/hu-automation.js +171 -0
  277. package/src/git/hu-snapshot.js +10 -0
  278. package/src/golden/asserter.js +92 -0
  279. package/src/golden/loader.js +52 -0
  280. package/src/golden/runner.js +92 -0
  281. package/src/golden/schema.js +41 -0
  282. package/src/guards/intent-guard.js +161 -0
  283. package/src/guards/output-guard.js +149 -0
  284. package/src/guards/perf-guard.js +126 -0
  285. package/src/guards/policy-guard.js +90 -0
  286. package/src/guards/policy-resolver.js +85 -0
  287. package/src/guards/secret-redactor.js +71 -0
  288. package/src/harden/advisory.js +203 -0
  289. package/src/harden/alternatives.js +50 -0
  290. package/src/harden/check.js +81 -0
  291. package/src/harden/config-engine.js +128 -0
  292. package/src/harden/config-templates.js +122 -0
  293. package/src/harden/guidelines-engine.js +48 -0
  294. package/src/harden/guidelines-templates.js +36 -0
  295. package/src/harden/harden-engine.js +80 -0
  296. package/src/harden/harness-hooks.js +107 -0
  297. package/src/harden/hook-commands.js +25 -0
  298. package/src/harden/hook-templates.js +183 -0
  299. package/src/harden/interactive.js +76 -0
  300. package/src/harden/sentinel-hooks.js +721 -0
  301. package/src/harden/stack-roots.js +105 -0
  302. package/src/harden/test-on-push.js +38 -0
  303. package/src/harden/workflow-engine.js +116 -0
  304. package/src/harden/workflow-templates.js +285 -0
  305. package/src/hu/acceptance-runner.js +138 -0
  306. package/src/hu/auto-generator.js +358 -0
  307. package/src/hu/graph.js +71 -0
  308. package/src/hu/lazy-planner.js +109 -0
  309. package/src/hu/model-router.js +108 -0
  310. package/src/hu/parallel-executor.js +94 -0
  311. package/src/hu/split-validator.js +143 -0
  312. package/src/hu/splitting-detector.js +158 -0
  313. package/src/hu/splitting-generator.js +175 -0
  314. package/src/hu/store.js +392 -0
  315. package/src/hu/worktree-bootstrap.js +59 -0
  316. package/src/identity/bootstrap.js +48 -0
  317. package/src/identity/compare.js +38 -0
  318. package/src/identity/detect.js +51 -0
  319. package/src/identity/store.js +66 -0
  320. package/src/infrastructure/command-runner.js +44 -0
  321. package/src/infrastructure/environment.js +38 -0
  322. package/src/infrastructure/file-system-service.js +63 -0
  323. package/src/infrastructure/mocks.js +182 -0
  324. package/src/lang/chunk-go.js +94 -0
  325. package/src/lang/chunk-java.js +90 -0
  326. package/src/lang/chunk-python.js +88 -0
  327. package/src/lang/chunk-rust.js +102 -0
  328. package/src/lang/go.js +14 -0
  329. package/src/lang/java.js +16 -0
  330. package/src/lang/js.js +8 -0
  331. package/src/lang/python.js +14 -0
  332. package/src/lang/registry.js +79 -0
  333. package/src/lang/rust.js +14 -0
  334. package/src/lang/tree-sitter-loader.js +45 -0
  335. package/src/mcp/direct-role-runner.js +112 -0
  336. package/src/mcp/error-classifiers.js +66 -0
  337. package/src/mcp/handlers/direct-handlers.js +486 -0
  338. package/src/mcp/handlers/hu-handlers.js +93 -0
  339. package/src/mcp/handlers/management-handlers.js +265 -0
  340. package/src/mcp/handlers/rag-handler.js +52 -0
  341. package/src/mcp/handlers/run-handler.js +313 -0
  342. package/src/mcp/orphan-guard.js +131 -0
  343. package/src/mcp/preflight.js +47 -0
  344. package/src/mcp/progress.js +149 -0
  345. package/src/mcp/response-compressor.js +81 -0
  346. package/src/mcp/run-kj.js +135 -0
  347. package/src/mcp/server-handlers.js +79 -0
  348. package/src/mcp/server.js +66 -0
  349. package/src/mcp/shared-helpers.js +297 -0
  350. package/src/mcp/sovereignty-guard.js +112 -0
  351. package/src/mcp/suggest-handler.js +92 -0
  352. package/src/mcp/tool-arg-normalizers.js +16 -0
  353. package/src/mcp/tools.js +432 -0
  354. package/src/mutate/diff-scope.js +105 -0
  355. package/src/mutate/reviewer-signal.js +76 -0
  356. package/src/mutate/runner.js +72 -0
  357. package/src/mutate/tool-registry.js +90 -0
  358. package/src/onboarder/cache.js +24 -0
  359. package/src/onboarder/collectors/framework-multilang.js +64 -0
  360. package/src/onboarder/collectors/index.js +136 -0
  361. package/src/orchestrator/agent-fallback.js +81 -0
  362. package/src/orchestrator/brain-coordinator.js +186 -0
  363. package/src/orchestrator/ci-integration.js +139 -0
  364. package/src/orchestrator/config-init.js +510 -0
  365. package/src/orchestrator/direct-actions.js +217 -0
  366. package/src/orchestrator/drivers/error-recovery.js +287 -0
  367. package/src/orchestrator/drivers/init-context.js +227 -0
  368. package/src/orchestrator/drivers/iteration-loop.js +380 -0
  369. package/src/orchestrator/drivers/iteration-phases/coder-and-refactorer.js +69 -0
  370. package/src/orchestrator/drivers/iteration-phases/guards.js +84 -0
  371. package/src/orchestrator/drivers/iteration-phases/handle-approved.js +29 -0
  372. package/src/orchestrator/drivers/iteration-phases/quality-gates.js +114 -0
  373. package/src/orchestrator/drivers/iteration-phases/reviewer-gate.js +60 -0
  374. package/src/orchestrator/drivers/post-loop.js +383 -0
  375. package/src/orchestrator/drivers/pre-loop-phases/auto-hu-batch.js +136 -0
  376. package/src/orchestrator/drivers/pre-loop-phases/config-deprecations.js +47 -0
  377. package/src/orchestrator/drivers/pre-loop-phases/ensure-addyosmani-skills.js +84 -0
  378. package/src/orchestrator/drivers/pre-loop-phases/inject-loaded-plan.js +391 -0
  379. package/src/orchestrator/drivers/pre-loop.js +507 -0
  380. package/src/orchestrator/drivers/run-hu-batch.js +427 -0
  381. package/src/orchestrator/feedback-enrichment.js +140 -0
  382. package/src/orchestrator/feedback-queue.js +151 -0
  383. package/src/orchestrator/flow-control.js +170 -0
  384. package/src/orchestrator/flow-runner.js +364 -0
  385. package/src/orchestrator/fs-leak-detector.js +210 -0
  386. package/src/orchestrator/hu-scheduler.js +114 -0
  387. package/src/orchestrator/hu-sub-pipeline.js +616 -0
  388. package/src/orchestrator/integrations.js +81 -0
  389. package/src/orchestrator/iteration-gate.js +73 -0
  390. package/src/orchestrator/iteration-stages.js +9 -0
  391. package/src/orchestrator/parallel-limiter.js +74 -0
  392. package/src/orchestrator/pipeline-context.js +72 -0
  393. package/src/orchestrator/post-loop-stages.js +468 -0
  394. package/src/orchestrator/pre-loop-stages.js +11 -0
  395. package/src/orchestrator/preflight-checks.js +462 -0
  396. package/src/orchestrator/repair/repair-detector.js +117 -0
  397. package/src/orchestrator/repair/repair-runner.js +142 -0
  398. package/src/orchestrator/reviewer-fallback.js +45 -0
  399. package/src/orchestrator/role-output-compressor.js +189 -0
  400. package/src/orchestrator/session-journal.js +308 -0
  401. package/src/orchestrator/solomon-escalation.js +305 -0
  402. package/src/orchestrator/solomon-rules.js +212 -0
  403. package/src/orchestrator/stages/architect-stage.js +172 -0
  404. package/src/orchestrator/stages/coder-stage.js +480 -0
  405. package/src/orchestrator/stages/domain-curator-stage.js +82 -0
  406. package/src/orchestrator/stages/hu-reviewer-phases/detect-and-apply-splits.js +127 -0
  407. package/src/orchestrator/stages/hu-reviewer-stage.js +394 -0
  408. package/src/orchestrator/stages/perf-stage.js +140 -0
  409. package/src/orchestrator/stages/planner-stage.js +85 -0
  410. package/src/orchestrator/stages/rag-context-stage.js +77 -0
  411. package/src/orchestrator/stages/rag-preload-decisor.js +58 -0
  412. package/src/orchestrator/stages/research-stage.js +69 -0
  413. package/src/orchestrator/stages/reviewer-stage.js +422 -0
  414. package/src/orchestrator/stages/sonar-stage.js +421 -0
  415. package/src/orchestrator/stages/stage-classes.js +84 -0
  416. package/src/orchestrator/stages/stage-executor.js +155 -0
  417. package/src/orchestrator/stages/tdd-discipline-stage.js +56 -0
  418. package/src/orchestrator/stages/tool-judge-stage.js +53 -0
  419. package/src/orchestrator/stages/triage-stage.js +172 -0
  420. package/src/orchestrator/standby.js +71 -0
  421. package/src/orchestrator/verification-gate.js +183 -0
  422. package/src/orchestrator.js +22 -0
  423. package/src/plan/adr-generator.js +170 -0
  424. package/src/plan/adr-loader.js +60 -0
  425. package/src/plan/plan-executor.js +100 -0
  426. package/src/plan/plan-fixer.js +192 -0
  427. package/src/plan/plan-hu-ops.js +16 -0
  428. package/src/plan/plan-id.js +4 -0
  429. package/src/plan/plan-migrate-result.js +24 -0
  430. package/src/plan/plan-reviewer.js +236 -0
  431. package/src/plan/plan-schema.js +334 -0
  432. package/src/plan/plan-store.js +260 -0
  433. package/src/plan/plan-structural-pass.js +122 -0
  434. package/src/plan/plan-validation.js +4 -0
  435. package/src/plan/preflight-hu.js +105 -0
  436. package/src/plan/spec-detector.js +61 -0
  437. package/src/plan/tests-synthesizer.js +131 -0
  438. package/src/planning-game/adapter.js +108 -0
  439. package/src/planning-game/architect-adrs.js +45 -0
  440. package/src/planning-game/client.js +108 -0
  441. package/src/planning-game/decomposition.js +87 -0
  442. package/src/planning-game/pipeline-adapter.js +251 -0
  443. package/src/plugins/loader.js +67 -0
  444. package/src/policy/add.js +111 -0
  445. package/src/policy/decisions.js +42 -0
  446. package/src/policy/engine.js +82 -0
  447. package/src/policy/exceptions.js +60 -0
  448. package/src/privacy/onboarding.js +35 -0
  449. package/src/privacy/scan.js +120 -0
  450. package/src/prompts/arbiter.js +38 -0
  451. package/src/prompts/architect.js +103 -0
  452. package/src/prompts/audit.js +474 -0
  453. package/src/prompts/coder.js +287 -0
  454. package/src/prompts/diff-clip.js +27 -0
  455. package/src/prompts/discover.js +222 -0
  456. package/src/prompts/hu-reviewer.js +219 -0
  457. package/src/prompts/planner.js +312 -0
  458. package/src/prompts/prompt-layout.js +80 -0
  459. package/src/prompts/prompt-resolver.js +120 -0
  460. package/src/prompts/reviewer.js +75 -0
  461. package/src/prompts/rtk-snippet.js +25 -0
  462. package/src/prompts/spec-reviewer.js +66 -0
  463. package/src/prompts/split-signal.js +82 -0
  464. package/src/prompts/start-decision.js +52 -0
  465. package/src/prompts/tool-correctness-judge.js +31 -0
  466. package/src/prompts/triage.js +57 -0
  467. package/src/rag/auto-update.js +72 -0
  468. package/src/rag/chunker-ast.js +56 -0
  469. package/src/rag/chunker.js +132 -0
  470. package/src/rag/embedder.js +2 -0
  471. package/src/rag/embedders/_cloud-base.js +2 -0
  472. package/src/rag/embedders/cohere.js +2 -0
  473. package/src/rag/embedders/factory.js +2 -0
  474. package/src/rag/embedders/mistral.js +2 -0
  475. package/src/rag/embedders/onnx.js +2 -0
  476. package/src/rag/embedders/openai.js +2 -0
  477. package/src/rag/embedders/voyage.js +2 -0
  478. package/src/rag/eval.js +61 -0
  479. package/src/rag/governed-embedder.js +39 -0
  480. package/src/rag/indexer.js +199 -0
  481. package/src/rag/library.js +62 -0
  482. package/src/rag/ollama-capability.js +59 -0
  483. package/src/rag/ollama-manager.js +98 -0
  484. package/src/rag/onnx-fallback.js +69 -0
  485. package/src/rag/rerank.js +4 -0
  486. package/src/rag/retriever.js +2 -0
  487. package/src/rag/vec-store.js +17 -0
  488. package/src/rag/watcher.js +62 -0
  489. package/src/rag/where-parser.js +4 -0
  490. package/src/repeat-detector.js +88 -0
  491. package/src/review/card-first.js +99 -0
  492. package/src/review/card-verify.js +83 -0
  493. package/src/review/diff-generator.js +112 -0
  494. package/src/review/gate-gitignore.js +77 -0
  495. package/src/review/git-stash-helper.js +104 -0
  496. package/src/review/mutation-pregate.js +48 -0
  497. package/src/review/one-shot-review.js +122 -0
  498. package/src/review/parser.js +80 -0
  499. package/src/review/policy-gate.js +26 -0
  500. package/src/review/profiles.js +66 -0
  501. package/src/review/reviewer-fallback.js +125 -0
  502. package/src/review/schema.js +31 -0
  503. package/src/review/scope-filter.js +152 -0
  504. package/src/review/snapshot-diff.js +122 -0
  505. package/src/review/solomon-arbitration.js +113 -0
  506. package/src/review/sonar-pregate.js +63 -0
  507. package/src/review/tdd-discipline.js +90 -0
  508. package/src/review/tdd-policy.js +69 -0
  509. package/src/review/tests-with-code.js +33 -0
  510. package/src/review/verdict-store.js +87 -0
  511. package/src/review/workspace.js +21 -0
  512. package/src/roles/agent-role.js +194 -0
  513. package/src/roles/architect-role.js +77 -0
  514. package/src/roles/audit-role.js +258 -0
  515. package/src/roles/base-role.js +165 -0
  516. package/src/roles/coder-role.js +107 -0
  517. package/src/roles/commiter-role.js +110 -0
  518. package/src/roles/discover-role.js +81 -0
  519. package/src/roles/domain-curator-role.js +141 -0
  520. package/src/roles/hu-reviewer-role.js +64 -0
  521. package/src/roles/impeccable-role.js +85 -0
  522. package/src/roles/index.js +18 -0
  523. package/src/roles/karajan-brain-role.js +134 -0
  524. package/src/roles/onboarder-role.js +61 -0
  525. package/src/roles/perf-role.js +122 -0
  526. package/src/roles/planner-role.js +151 -0
  527. package/src/roles/refactorer-role.js +30 -0
  528. package/src/roles/repairer-role.js +181 -0
  529. package/src/roles/researcher-role.js +70 -0
  530. package/src/roles/reviewer-role.js +104 -0
  531. package/src/roles/security-role.js +73 -0
  532. package/src/roles/solomon-role.js +265 -0
  533. package/src/roles/sonar-role.js +70 -0
  534. package/src/roles/spec-reviewer-role.js +106 -0
  535. package/src/roles/tester-role.js +235 -0
  536. package/src/roles/tool-correctness-judge-role.js +78 -0
  537. package/src/roles/triage-role.js +99 -0
  538. package/src/session/journal/decisions-writer.js +200 -0
  539. package/src/session/journal/iteration-logger.js +194 -0
  540. package/src/session/journal/summary-writer.js +320 -0
  541. package/src/session/journal/tree-writer.js +164 -0
  542. package/src/session/journal/write-all.js +89 -0
  543. package/src/session/mutators.js +339 -0
  544. package/src/session/runtime-overrides.js +59 -0
  545. package/src/session/store.js +106 -0
  546. package/src/session-cleanup.js +116 -0
  547. package/src/skills/addyosmani-catalog.js +315 -0
  548. package/src/skills/addyosmani-role-map.js +139 -0
  549. package/src/skills/openskills-client.js +157 -0
  550. package/src/skills/semantic-detector.js +167 -0
  551. package/src/skills/skill-detector.js +385 -0
  552. package/src/skills/skill-loader.js +219 -0
  553. package/src/skills/skills-cache.js +128 -0
  554. package/src/sonar/api.js +128 -0
  555. package/src/sonar/cloud-scanner.js +78 -0
  556. package/src/sonar/config-resolver.js +88 -0
  557. package/src/sonar/credentials.js +60 -0
  558. package/src/sonar/discovery.js +124 -0
  559. package/src/sonar/enforcer.js +19 -0
  560. package/src/sonar/issue-filter.js +12 -0
  561. package/src/sonar/manager.js +181 -0
  562. package/src/sonar/project-key.js +120 -0
  563. package/src/sonar/scanner.js +307 -0
  564. package/src/sonar/token-bootstrap.js +205 -0
  565. package/src/sonar/token-recovery.js +67 -0
  566. package/src/spec-review/refine-loop.js +58 -0
  567. package/src/spec-review/run-spec-review.js +119 -0
  568. package/src/start/assessment.js +74 -0
  569. package/src/start/maturity.js +73 -0
  570. package/src/start/start-decider-role.js +79 -0
  571. package/src/start/sweep.js +157 -0
  572. package/src/sync/apply-canvas-patch.js +55 -0
  573. package/src/sync/detect-drift.js +113 -0
  574. package/src/tournament/crown.js +88 -0
  575. package/src/tournament/judge.js +150 -0
  576. package/src/tournament/run.js +142 -0
  577. package/src/tournament/scoreboard.js +124 -0
  578. package/src/tracker-bootstrap.js +44 -0
  579. package/src/types/agent.js +55 -0
  580. package/src/types/config.js +114 -0
  581. package/src/types/hu.js +47 -0
  582. package/src/types/index.js +38 -0
  583. package/src/types/policy.js +43 -0
  584. package/src/types/session.js +75 -0
  585. package/src/types/solomon.js +87 -0
  586. package/src/types/stage.js +68 -0
  587. package/src/utils/agent-detect.js +93 -0
  588. package/src/utils/ai-trash.js +48 -0
  589. package/src/utils/async-lock.js +31 -0
  590. package/src/utils/atomic-write.js +6 -0
  591. package/src/utils/banner.js +66 -0
  592. package/src/utils/binary-sources.js +70 -0
  593. package/src/utils/board-prompt-bridge.js +108 -0
  594. package/src/utils/budget.js +229 -0
  595. package/src/utils/cli-ask-question.js +93 -0
  596. package/src/utils/cli-progress.js +220 -0
  597. package/src/utils/cli-run-log.js +83 -0
  598. package/src/utils/cwd-confirm.js +39 -0
  599. package/src/utils/derive-project-name-from-cwd.js +119 -0
  600. package/src/utils/display/event-handlers.js +403 -0
  601. package/src/utils/display/formatters.js +132 -0
  602. package/src/utils/display/header.js +47 -0
  603. package/src/utils/display/resume-hint.js +41 -0
  604. package/src/utils/display/session-summary.js +118 -0
  605. package/src/utils/display/solomon.js +42 -0
  606. package/src/utils/display/spec-findings.js +44 -0
  607. package/src/utils/doc-links.js +29 -0
  608. package/src/utils/docker-install.js +34 -0
  609. package/src/utils/escape-regexp.js +15 -0
  610. package/src/utils/events.js +35 -0
  611. package/src/utils/fs.js +19 -0
  612. package/src/utils/garbage-collector.js +481 -0
  613. package/src/utils/git.js +279 -0
  614. package/src/utils/home-migration.js +87 -0
  615. package/src/utils/injection-guard.js +186 -0
  616. package/src/utils/install-hints.js +180 -0
  617. package/src/utils/json-extract.js +64 -0
  618. package/src/utils/locale.js +59 -0
  619. package/src/utils/logger.js +96 -0
  620. package/src/utils/managed-markers.js +93 -0
  621. package/src/utils/manifest-sniff.js +82 -0
  622. package/src/utils/messages.js +61 -0
  623. package/src/utils/model-selector.js +107 -0
  624. package/src/utils/os-detect.js +79 -0
  625. package/src/utils/paths.js +13 -0
  626. package/src/utils/pending-user-action.js +95 -0
  627. package/src/utils/port-check.js +6 -0
  628. package/src/utils/port-occupant.js +96 -0
  629. package/src/utils/pricing.js +29 -0
  630. package/src/utils/process.js +4 -0
  631. package/src/utils/project-detect.js +160 -0
  632. package/src/utils/prompt-project-name.js +35 -0
  633. package/src/utils/provider-env.js +116 -0
  634. package/src/utils/qmd-collection.js +72 -0
  635. package/src/utils/qmd-detect.js +18 -0
  636. package/src/utils/qmd-install.js +37 -0
  637. package/src/utils/quota-simulator.js +56 -0
  638. package/src/utils/rate-limit-detector.js +181 -0
  639. package/src/utils/repo-cleaner.js +79 -0
  640. package/src/utils/retry.js +88 -0
  641. package/src/utils/role-assigner.js +137 -0
  642. package/src/utils/role-env.js +58 -0
  643. package/src/utils/rtk-detect.js +18 -0
  644. package/src/utils/rtk-install.js +38 -0
  645. package/src/utils/rtk-wrapper.js +87 -0
  646. package/src/utils/run-context.js +75 -0
  647. package/src/utils/run-log.js +217 -0
  648. package/src/utils/run-registry.js +9 -0
  649. package/src/utils/shared-paths.js +12 -0
  650. package/src/utils/squeezr-detect.js +21 -0
  651. package/src/utils/squeezr-install.js +37 -0
  652. package/src/utils/stack-detect.js +135 -0
  653. package/src/utils/stall-detector.js +159 -0
  654. package/src/utils/status-dashboard.js +254 -0
  655. package/src/utils/task-file.js +109 -0
  656. package/src/utils/telemetry.js +124 -0
  657. package/src/utils/templates-root.js +61 -0
  658. package/src/utils/tool-call-extractor.js +56 -0
  659. package/src/utils/tool-governor.js +116 -0
  660. package/src/utils/tool-installer.js +93 -0
  661. package/src/utils/update-check.js +280 -0
  662. package/src/utils/vector-store-orphans.js +89 -0
  663. package/src/utils/welcome.js +47 -0
  664. package/src/utils/with-timeout.js +42 -0
  665. package/src/utils/wizard.js +47 -0
  666. package/src/webperf/cwv-gate.js +94 -0
  667. package/src/webperf/devtools-detect.js +112 -0
  668. package/src/webperf/scanner.js +209 -0
  669. package/src/webperf/webperf-role-integration.js +66 -0
  670. package/templates/coder-rules.md +45 -0
  671. package/templates/docker-compose.sonar.yml +60 -0
  672. package/templates/domains/example-dental.md +57 -0
  673. package/templates/kj.config.yml +128 -0
  674. package/templates/review-rules.md +17 -0
  675. package/templates/roles/architect/anthropic.md +74 -0
  676. package/templates/roles/architect/default.md +72 -0
  677. package/templates/roles/architect/google.md +61 -0
  678. package/templates/roles/architect/openai.md +60 -0
  679. package/templates/roles/architect/opencode.md +59 -0
  680. package/templates/roles/architect.md +76 -0
  681. package/templates/roles/audit.md +68 -0
  682. package/templates/roles/coder/anthropic.md +81 -0
  683. package/templates/roles/coder/default.md +78 -0
  684. package/templates/roles/coder/google.md +87 -0
  685. package/templates/roles/coder/openai.md +68 -0
  686. package/templates/roles/coder/opencode.md +58 -0
  687. package/templates/roles/coder.md +152 -0
  688. package/templates/roles/commiter.md +44 -0
  689. package/templates/roles/discover.md +167 -0
  690. package/templates/roles/domain-curator.md +52 -0
  691. package/templates/roles/hu-reviewer.md +236 -0
  692. package/templates/roles/impeccable-design.md +87 -0
  693. package/templates/roles/impeccable.md +125 -0
  694. package/templates/roles/karajan-brain.md +95 -0
  695. package/templates/roles/onboarder.md +45 -0
  696. package/templates/roles/planner/anthropic.md +59 -0
  697. package/templates/roles/planner/default.md +57 -0
  698. package/templates/roles/planner/google.md +75 -0
  699. package/templates/roles/planner/openai.md +55 -0
  700. package/templates/roles/planner/opencode.md +62 -0
  701. package/templates/roles/planner.md +61 -0
  702. package/templates/roles/refactorer.md +48 -0
  703. package/templates/roles/repairer.md +103 -0
  704. package/templates/roles/researcher.md +41 -0
  705. package/templates/roles/reviewer/anthropic.md +61 -0
  706. package/templates/roles/reviewer/default.md +62 -0
  707. package/templates/roles/reviewer/google.md +63 -0
  708. package/templates/roles/reviewer/openai.md +57 -0
  709. package/templates/roles/reviewer/opencode.md +42 -0
  710. package/templates/roles/reviewer-paranoid.md +38 -0
  711. package/templates/roles/reviewer-relaxed.md +34 -0
  712. package/templates/roles/reviewer-strict.md +37 -0
  713. package/templates/roles/reviewer.md +62 -0
  714. package/templates/roles/security.md +54 -0
  715. package/templates/roles/solomon/anthropic.md +71 -0
  716. package/templates/roles/solomon/default.md +83 -0
  717. package/templates/roles/solomon/google.md +61 -0
  718. package/templates/roles/solomon/openai.md +53 -0
  719. package/templates/roles/solomon/opencode.md +55 -0
  720. package/templates/roles/solomon.md +83 -0
  721. package/templates/roles/sonar.md +49 -0
  722. package/templates/roles/spec-reviewer.md +47 -0
  723. package/templates/roles/tester.md +50 -0
  724. package/templates/roles/triage.md +69 -0
  725. package/templates/skills/kj-architect.md +45 -0
  726. package/templates/skills/kj-audit.md +63 -0
  727. package/templates/skills/kj-board.md +16 -0
  728. package/templates/skills/kj-code.md +51 -0
  729. package/templates/skills/kj-csv-transform.md +40 -0
  730. package/templates/skills/kj-data-report.md +44 -0
  731. package/templates/skills/kj-discover.md +24 -0
  732. package/templates/skills/kj-rag-query.md +50 -0
  733. package/templates/skills/kj-review.md +47 -0
  734. package/templates/skills/kj-run.md +73 -0
  735. package/templates/skills/kj-security.md +49 -0
  736. package/templates/skills/kj-sonar.md +41 -0
  737. package/templates/skills/kj-sql-analysis.md +40 -0
  738. package/templates/skills/kj-test.md +40 -0
  739. package/templates/workflows/automerge.yml +30 -0
  740. package/templates/workflows/houston-override.yml +46 -0
  741. package/templates/workflows/kj-ci-gateway.yml +58 -0
  742. package/vendor/tree-sitter-grammars/README.md +21 -0
  743. package/vendor/tree-sitter-grammars/go.wasm +0 -0
  744. package/vendor/tree-sitter-grammars/java.wasm +0 -0
  745. package/vendor/tree-sitter-grammars/python.wasm +0 -0
  746. package/vendor/tree-sitter-grammars/rust.wasm +0 -0
@@ -0,0 +1,139 @@
1
+ /**
2
+ * CI/CD integration — early PR creation, incremental push, review dispatch.
3
+ * Extracted from orchestrator.js — self-contained feature, only active when ci.enabled.
4
+ */
5
+ import { saveSession } from "../session/store.js";
6
+ import { setCiEarlyPr, appendCiCommits } from "../session/mutators.js";
7
+ import { earlyPrCreation, incrementalPush } from "../git/automation.js";
8
+ import { emitProgress, makeEvent } from "../utils/events.js";
9
+ import { getIntegration } from "./integrations.js";
10
+
11
+ export async function tryCiComment({ config, session, logger: _logger, agent, body }) {
12
+ if (!config.ci?.enabled || !session.ci_pr_number) return;
13
+ try {
14
+ const { dispatchComment } = await import("../ci/dispatch.js");
15
+ const { detectRepo } = await import("../ci/repo.js");
16
+ const repo = await detectRepo();
17
+ if (repo) {
18
+ await dispatchComment({
19
+ repo, prNumber: session.ci_pr_number, agent,
20
+ body, ciConfig: config.ci
21
+ });
22
+ }
23
+ } catch { /* non-blocking */ }
24
+ }
25
+
26
+ function formatCommitList(commits) {
27
+ return commits.map((c) => `- \`${c.hash.slice(0, 7)}\` ${c.message}`).join("\n");
28
+ }
29
+
30
+ async function ciIncrementalPush({ config, session, gitCtx, task, logger, repo, dispatchComment }) {
31
+ const pushResult = await incrementalPush({ gitCtx, task, logger, session });
32
+ if (!pushResult) return;
33
+
34
+ const tracker = getIntegration("tracker");
35
+ for (const c of pushResult.commits) tracker?.onCommit?.(session, c);
36
+
37
+ appendCiCommits(session, pushResult.commits);
38
+ await saveSession(session);
39
+
40
+ if (!repo) return;
41
+ const feedback = session.last_reviewer_feedback || "N/A";
42
+ await dispatchComment({
43
+ repo, prNumber: session.ci_pr_number, agent: "Coder",
44
+ body: `Issues fixed:\n${feedback}\n\nCommits:\n${formatCommitList(pushResult.commits)}`,
45
+ ciConfig: config.ci
46
+ });
47
+ }
48
+
49
+ async function ciCreateEarlyPr({ config, session, emitter, eventBase, gitCtx, task, logger, stageResults, i, repo, dispatchComment }) {
50
+ const earlyPr = await earlyPrCreation({ gitCtx, task, logger, session, stageResults });
51
+ if (!earlyPr) return;
52
+
53
+ const tracker = getIntegration("tracker");
54
+ for (const c of earlyPr.commits) tracker?.onCommit?.(session, c);
55
+
56
+ setCiEarlyPr(session, { prNumber: earlyPr.prNumber, prUrl: earlyPr.prUrl, commits: earlyPr.commits });
57
+ await saveSession(session);
58
+ emitProgress(emitter, makeEvent("ci:pr-created", { ...eventBase, stage: "ci" }, {
59
+ message: `Early PR created: #${earlyPr.prNumber}`,
60
+ detail: { prNumber: earlyPr.prNumber, prUrl: earlyPr.prUrl }
61
+ }));
62
+
63
+ if (!repo) return;
64
+ await dispatchComment({
65
+ repo, prNumber: earlyPr.prNumber, agent: "Coder",
66
+ body: `Iteration ${i} completed.\n\nCommits:\n${formatCommitList(earlyPr.commits)}`,
67
+ ciConfig: config.ci
68
+ });
69
+ }
70
+
71
+ export async function handleCiEarlyPrOrPush({ ciEnabled, config, session, emitter, eventBase, gitCtx, task, logger, stageResults, i }) {
72
+ if (!ciEnabled) return;
73
+
74
+ try {
75
+ const { dispatchComment } = await import("../ci/dispatch.js");
76
+ const { detectRepo } = await import("../ci/repo.js");
77
+ const repo = await detectRepo();
78
+
79
+ if (session.ci_pr_number) {
80
+ await ciIncrementalPush({ config, session, gitCtx, task, logger, repo, dispatchComment });
81
+ } else {
82
+ await ciCreateEarlyPr({ config, session, emitter, eventBase, gitCtx, task, logger, stageResults, i, repo, dispatchComment });
83
+ }
84
+ } catch (err) {
85
+ logger.warn(`CI early PR/push failed (non-blocking): ${err.message}`);
86
+ }
87
+ }
88
+
89
+ function formatBlockingIssues(issues) {
90
+ return issues?.map((x) => `- ${x.id || "ISSUE"} [${x.severity || ""}] ${x.description}`).join("\n") || "";
91
+ }
92
+
93
+ function formatSuggestions(suggestions) {
94
+ return suggestions?.map((s) => {
95
+ const detail = typeof s === "string" ? s : `${s.id || ""} ${s.description || s}`;
96
+ return `- ${detail}`;
97
+ }).join("\n") || "";
98
+ }
99
+
100
+ function buildReviewCommentBody(review, i) {
101
+ const status = review.approved ? "APPROVED" : "REQUEST_CHANGES";
102
+ const blocking = formatBlockingIssues(review.blocking_issues);
103
+ const suggestions = formatSuggestions(review.non_blocking_suggestions);
104
+ let body = `Review iteration ${i}: ${status}`;
105
+ if (blocking) body += `\n\n**Blocking:**\n${blocking}`;
106
+ if (suggestions) body += `\n\n**Suggestions:**\n${suggestions}`;
107
+ return body;
108
+ }
109
+
110
+ export async function handleCiReviewDispatch({ ciEnabled, config, session, review, i, logger }) {
111
+ if (!ciEnabled || !session.ci_pr_number) return;
112
+
113
+ try {
114
+ const { dispatchReview, dispatchComment } = await import("../ci/dispatch.js");
115
+ const { detectRepo } = await import("../ci/repo.js");
116
+ const repo = await detectRepo();
117
+ if (!repo) return;
118
+
119
+ const bc = config.ci;
120
+ const reviewEvent = review.approved ? "APPROVE" : "REQUEST_CHANGES";
121
+ const reviewBody = review.approved
122
+ ? (review.summary || "Approved")
123
+ : (formatBlockingIssues(review.blocking_issues) || review.summary || "Changes requested");
124
+
125
+ await dispatchReview({
126
+ repo, prNumber: session.ci_pr_number,
127
+ event: reviewEvent, body: reviewBody, agent: "Reviewer", ciConfig: bc
128
+ });
129
+
130
+ await dispatchComment({
131
+ repo, prNumber: session.ci_pr_number, agent: "Reviewer",
132
+ body: buildReviewCommentBody(review, i), ciConfig: bc
133
+ });
134
+
135
+ logger.info(`CI: dispatched review for PR #${session.ci_pr_number}`);
136
+ } catch (err) {
137
+ logger.warn(`CI dispatch failed (non-blocking): ${err.message}`);
138
+ }
139
+ }
@@ -0,0 +1,510 @@
1
+ /**
2
+ * Configuration initialization and pipeline setup helpers.
3
+ * Extracted from orchestrator.js — pure functions, no orchestration state.
4
+ */
5
+ import fs from "node:fs/promises";
6
+ import path from "node:path";
7
+ import { computeBaseRef, setSnapshot } from "../review/diff-generator.js";
8
+ import { ensureContractBlockPresent } from "../review/gate-gitignore.js";
9
+ import { revParse } from "../utils/git.js";
10
+ import { buildCoderPrompt } from "../prompts/coder.js";
11
+ import { buildReviewerPrompt } from "../prompts/reviewer.js";
12
+ import { resolveRole } from "../config.js";
13
+ import { emitProgress, makeEvent } from "../utils/events.js";
14
+ import { getTemplatesRoot } from "../utils/templates-root.js";
15
+ import { BudgetTracker, extractUsageMetrics } from "../utils/budget.js";
16
+ import { DEFAULTS } from "../config/defaults.js";
17
+ import { computeKjComparison } from "../budget/comparison.js";
18
+ import { resolveRoleMdPath, loadFirstExisting } from "../roles/base-role.js";
19
+ import { projectSlug } from "../plan/plan-store.js";
20
+ import { applyPolicies } from "../guards/policy-resolver.js";
21
+ import { resolveReviewProfile } from "../review/profiles.js";
22
+ import { createSession } from "../session/store.js";
23
+ import { setResolvedPolicies } from "../session/mutators.js";
24
+ import { exists, ensureDir } from "../utils/fs.js";
25
+
26
+ /**
27
+ * Auto-initialize .karajan/ in projectDir if missing.
28
+ * Copies essential templates (coder-rules, review-rules) without running the full wizard.
29
+ * Called by the orchestrator before the pipeline starts.
30
+ */
31
+ export async function autoInit(projectDir, logger) {
32
+ // Ensure git repo exists — without git, diff/reviewer/commit won't work.
33
+ //
34
+ // KJC-BUG-0060: the previous guard `!exists(projectDir/.git)` was insufficient
35
+ // when projectDir is a subdirectory inside an existing repo (common in dogfooding
36
+ // scenarios where kj-linked runs from the karajan-code source tree). In that case
37
+ // `git commit --allow-empty` would resolve upward to the parent repo and land an
38
+ // empty "initial commit" on the user's main branch. Use `git rev-parse
39
+ // --is-inside-work-tree` instead — it follows the same upward traversal that git
40
+ // does naturally, so a subdir inside a repo correctly reports `true` and we don't
41
+ // touch anything. We also drop the `git commit --allow-empty -m "initial commit"`
42
+ // step: a root commit is not required for any downstream stage (diff, review,
43
+ // coder, sonar) and the empty-commit zombie history was the user-visible symptom.
44
+ const { execFileSync } = await import("node:child_process");
45
+ try {
46
+ execFileSync("git", ["rev-parse", "--is-inside-work-tree"], { cwd: projectDir, stdio: "pipe" });
47
+ // Already inside a git work tree (own .git or parent's). Nothing to do.
48
+ } catch {
49
+ // Not inside any repo — create a fresh one. No empty seed commit.
50
+ try {
51
+ execFileSync("git", ["init"], { cwd: projectDir, stdio: "pipe" });
52
+ logger.info("Initialized git repository (no seed commit)");
53
+ } catch (err) {
54
+ logger.warn(`Failed to init git repo: ${err.message}`);
55
+ }
56
+ }
57
+
58
+ // Ensure .gitignore exists with universal entries only (stack-specific added after planner)
59
+ // KJC-BUG-0123: `.karajan/` is NOT in this list on purpose — a bare
60
+ // dir-exclude breaks the gate contract (git cannot re-include children);
61
+ // the canonical block is appended below from its single source.
62
+ const gitignorePath = path.join(projectDir, ".gitignore");
63
+ const universalIgnores = [".env", "*.log", ".DS_Store", ".reviews/"];
64
+ try {
65
+ let content = "";
66
+ if (await exists(gitignorePath)) {
67
+ content = await fs.readFile(gitignorePath, "utf8");
68
+ }
69
+ const missing = universalIgnores.filter(entry => !content.includes(entry));
70
+ if (missing.length > 0) {
71
+ const append = (content && !content.endsWith("\n") ? "\n" : "") + missing.join("\n") + "\n";
72
+ await fs.appendFile(gitignorePath, append, "utf8");
73
+ logger.info(`Created .gitignore with universal entries`);
74
+ }
75
+ await ensureContractBlockPresent(projectDir);
76
+ } catch (err) {
77
+ logger.warn(`Failed to create .gitignore: ${err.message}`);
78
+ }
79
+
80
+ const karajanDir = path.join(projectDir, ".karajan");
81
+ if (await exists(karajanDir)) return;
82
+
83
+ logger.info("No .karajan/ found — auto-initializing project scaffolding");
84
+ await ensureDir(karajanDir);
85
+
86
+ const templatesDir = getTemplatesRoot();
87
+
88
+ const filesToCopy = [
89
+ { src: "coder-rules.md", dest: "coder-rules.md" },
90
+ { src: "review-rules.md", dest: "review-rules.md" }
91
+ ];
92
+
93
+ for (const { src, dest } of filesToCopy) {
94
+ const srcPath = path.join(templatesDir, src);
95
+ const destPath = path.join(karajanDir, dest);
96
+ try {
97
+ if (!(await exists(destPath))) {
98
+ const content = await fs.readFile(srcPath, "utf8");
99
+ await fs.writeFile(destPath, content, "utf8");
100
+ logger.info(` Created .karajan/${dest}`);
101
+ }
102
+ } catch (err) {
103
+ logger.warn(` Failed to copy ${src}: ${err.message}`);
104
+ }
105
+ }
106
+
107
+ // Copy role templates directory
108
+ const rolesTemplateDir = path.join(templatesDir, "roles");
109
+ const rolesDestDir = path.join(karajanDir, "roles");
110
+ try {
111
+ if (await exists(rolesTemplateDir)) {
112
+ await ensureDir(rolesDestDir);
113
+ const roleFiles = await fs.readdir(rolesTemplateDir);
114
+ for (const rf of roleFiles) {
115
+ if (!rf.endsWith(".md")) continue;
116
+ const destFile = path.join(rolesDestDir, rf);
117
+ if (!(await exists(destFile))) {
118
+ await fs.copyFile(path.join(rolesTemplateDir, rf), destFile);
119
+ }
120
+ }
121
+ logger.info(` Copied ${roleFiles.filter(f => f.endsWith(".md")).length} role templates to .karajan/roles/`);
122
+ }
123
+ } catch (err) {
124
+ logger.warn(` Failed to copy role templates: ${err.message}`);
125
+ }
126
+ }
127
+
128
+ // Stack-specific .gitignore patterns keyed by language/framework
129
+ const STACK_GITIGNORE = {
130
+ javascript: ["node_modules/", "dist/", "build/", "coverage/", ".cache/", "*.tsbuildinfo"],
131
+ typescript: ["node_modules/", "dist/", "build/", "coverage/", ".cache/", "*.tsbuildinfo"],
132
+ python: ["__pycache__/", "*.pyc", ".venv/", "venv/", "*.egg-info/", ".pytest_cache/", "htmlcov/", ".mypy_cache/"],
133
+ java: ["target/", "*.class", "*.jar", "*.war", ".gradle/", "build/", ".settings/", ".classpath", ".project"],
134
+ kotlin: ["target/", "*.class", "build/", ".gradle/", ".kotlin/"],
135
+ go: ["bin/", "*.exe", "vendor/"],
136
+ rust: ["target/", "Cargo.lock"],
137
+ ruby: ["vendor/bundle/", ".bundle/", "coverage/", "tmp/"],
138
+ php: ["vendor/", ".phpunit.result.cache", "storage/logs/"],
139
+ csharp: ["bin/", "obj/", "*.suo", "*.user", "packages/", ".vs/"],
140
+ swift: [".build/", "Packages/", "*.xcodeproj/", "DerivedData/"],
141
+ dart: [".dart_tool/", "build/", ".packages"],
142
+ };
143
+
144
+ /**
145
+ * Update .gitignore with stack-specific entries after planner/architect decides the stack.
146
+ * Detects stack from: triage taskType, architect output, planner output, or task keywords.
147
+ */
148
+ export async function updateGitignoreForStack(projectDir, { stageResults, task, logger }) {
149
+ const gitignorePath = path.join(projectDir, ".gitignore");
150
+ const detected = new Set();
151
+
152
+ // From architect — if it chose layers/patterns, it may hint at the language
153
+ const arch = stageResults?.architect?.architecture;
154
+ if (arch) {
155
+ const archText = JSON.stringify(arch).toLowerCase();
156
+ for (const lang of Object.keys(STACK_GITIGNORE)) {
157
+ if (archText.includes(lang)) detected.add(lang);
158
+ }
159
+ }
160
+
161
+ // From planner — scan plan text for language keywords
162
+ const planText = (stageResults?.planner?.plan || "").toLowerCase();
163
+ // From task description
164
+ const taskText = (task || "").toLowerCase();
165
+ const combined = `${planText} ${taskText}`;
166
+
167
+ const langKeywords = {
168
+ javascript: ["node", "npm", "express", "react", "vue", "next", "vite", "vitest", "jest", "pnpm", "yarn", "javascript", "js"],
169
+ typescript: ["typescript", "tsx", "tsc"],
170
+ python: ["python", "django", "flask", "fastapi", "pip", "pytest", "poetry"],
171
+ java: ["java", "spring", "maven", "gradle", "junit"],
172
+ kotlin: ["kotlin", "ktor"],
173
+ go: ["golang", "go mod", "gin", "fiber"],
174
+ rust: ["rust", "cargo", "tokio"],
175
+ ruby: ["ruby", "rails", "gem", "bundler", "rspec"],
176
+ php: ["php", "laravel", "composer", "symfony"],
177
+ csharp: ["c#", "csharp", "dotnet", ".net", "aspnet"],
178
+ swift: ["swift", "swiftui", "vapor"],
179
+ dart: ["dart", "flutter"],
180
+ };
181
+
182
+ for (const [lang, keywords] of Object.entries(langKeywords)) {
183
+ if (keywords.some(kw => combined.includes(kw))) detected.add(lang);
184
+ }
185
+
186
+ if (detected.size === 0) return;
187
+
188
+ // Collect all entries for detected stacks
189
+ const entries = [];
190
+ for (const lang of detected) {
191
+ entries.push(...(STACK_GITIGNORE[lang] || []));
192
+ }
193
+ const unique = [...new Set(entries)];
194
+
195
+ try {
196
+ let content = "";
197
+ if (await exists(gitignorePath)) {
198
+ content = await fs.readFile(gitignorePath, "utf8");
199
+ }
200
+ const missing = unique.filter(entry => !content.includes(entry));
201
+ if (missing.length > 0) {
202
+ const header = `\n# ${[...detected].join(" + ")} project\n`;
203
+ const append = header + missing.join("\n") + "\n";
204
+ await fs.appendFile(gitignorePath, append, "utf8");
205
+ logger.info(`Updated .gitignore for ${[...detected].join(" + ")}: ${missing.join(", ")}`);
206
+ }
207
+ } catch (err) {
208
+ logger.warn(`Failed to update .gitignore for stack: ${err.message}`);
209
+ }
210
+ }
211
+
212
+ /**
213
+ * Load product context from well-known file locations.
214
+ */
215
+ export async function loadProductContext(projectDir) {
216
+ const base = projectDir || process.cwd();
217
+ const candidates = [
218
+ path.join(base, ".karajan", "context.md"),
219
+ path.join(base, "product-vision.md")
220
+ ];
221
+ for (const file of candidates) {
222
+ try {
223
+ const content = await fs.readFile(file, "utf8");
224
+ return { content, source: file };
225
+ } catch { /* not found, try next */ }
226
+ }
227
+ return { content: null, source: null };
228
+ }
229
+
230
+ export function resolvePipelineFlags(config) {
231
+ return {
232
+ plannerEnabled: Boolean(config.pipeline?.planner?.enabled),
233
+ refactorerEnabled: Boolean(config.pipeline?.refactorer?.enabled),
234
+ researcherEnabled: Boolean(config.pipeline?.researcher?.enabled),
235
+ testerEnabled: Boolean(config.pipeline?.tester?.enabled),
236
+ securityEnabled: Boolean(config.pipeline?.security?.enabled),
237
+ impeccableEnabled: Boolean(config.pipeline?.impeccable?.enabled),
238
+ perfEnabled: Boolean(config.pipeline?.perf?.enabled),
239
+ toolJudgeEnabled: Boolean(config.pipeline?.tool_judge?.enabled),
240
+ reviewerEnabled: config.pipeline?.reviewer?.enabled !== false,
241
+ discoverEnabled: Boolean(config.pipeline?.discover?.enabled),
242
+ architectEnabled: Boolean(config.pipeline?.architect?.enabled),
243
+ huReviewerEnabled: Boolean(config.pipeline?.hu_reviewer?.enabled),
244
+ };
245
+ }
246
+
247
+ export async function handleDryRun({ task, config, flags, emitter, pipelineFlags }) {
248
+ const { plannerEnabled, refactorerEnabled, researcherEnabled, testerEnabled, securityEnabled, impeccableEnabled, perfEnabled, reviewerEnabled, discoverEnabled, architectEnabled, huReviewerEnabled } = pipelineFlags;
249
+ const plannerRole = resolveRole(config, "planner");
250
+ const coderRole = resolveRole(config, "coder");
251
+ const reviewerRole = resolveRole(config, "reviewer");
252
+ const refactorerRole = resolveRole(config, "refactorer");
253
+ const triageEnabled = true;
254
+
255
+ const dryRunPolicies = applyPolicies({
256
+ taskType: flags.taskType || config.taskType || null,
257
+ policies: config.policies,
258
+ });
259
+ const projectDir = config.projectDir || process.cwd();
260
+ const { rules: reviewRules } = await resolveReviewProfile({ mode: config.review_mode, projectDir });
261
+ const coderRules = await loadFirstExisting(resolveRoleMdPath("coder", projectDir));
262
+ const coderPrompt = await buildCoderPrompt({ task, coderRules, methodology: config.development?.methodology, serenaEnabled: Boolean(config.serena?.enabled), rtkAvailable: Boolean(config.rtk?.available), productContext: config.productContext || null });
263
+ const reviewerPrompt = await buildReviewerPrompt({ task, diff: "(dry-run: no diff)", reviewRules, mode: config.review_mode, serenaEnabled: Boolean(config.serena?.enabled), rtkAvailable: Boolean(config.rtk?.available), productContext: config.productContext || null });
264
+
265
+ const summary = {
266
+ dry_run: true,
267
+ task,
268
+ policies: dryRunPolicies,
269
+ roles: { planner: plannerRole, coder: coderRole, reviewer: reviewerRole, refactorer: refactorerRole },
270
+ pipeline: {
271
+ discover_enabled: discoverEnabled,
272
+ architect_enabled: architectEnabled,
273
+ triage_enabled: triageEnabled,
274
+ planner_enabled: plannerEnabled,
275
+ refactorer_enabled: refactorerEnabled,
276
+ sonar_enabled: Boolean(config.sonarqube?.enabled),
277
+ reviewer_enabled: reviewerEnabled,
278
+ researcher_enabled: researcherEnabled,
279
+ tester_enabled: testerEnabled,
280
+ security_enabled: securityEnabled,
281
+ impeccable_enabled: impeccableEnabled,
282
+ perf_enabled: perfEnabled,
283
+ solomon_enabled: Boolean(config.pipeline?.solomon?.enabled),
284
+ hu_reviewer_enabled: huReviewerEnabled
285
+ },
286
+ limits: {
287
+ max_iterations: config.max_iterations,
288
+ max_iteration_minutes: config.session?.max_iteration_minutes,
289
+ max_total_minutes: config.session?.max_total_minutes,
290
+ max_sonar_retries: config.session?.max_sonar_retries,
291
+ max_reviewer_retries: config.session?.max_reviewer_retries,
292
+ max_tester_retries: config.session?.max_tester_retries,
293
+ max_security_retries: config.session?.max_security_retries
294
+ },
295
+ prompts: { coder: coderPrompt, reviewer: reviewerPrompt },
296
+ git: config.git
297
+ };
298
+
299
+ emitProgress(
300
+ emitter,
301
+ makeEvent("dry-run:summary", { sessionId: null, iteration: 0, stage: "dry-run", startedAt: Date.now() }, {
302
+ message: "Dry-run complete — no changes made",
303
+ detail: summary
304
+ })
305
+ );
306
+
307
+ return summary;
308
+ }
309
+
310
+ export function createBudgetManager({ config, emitter, eventBase, getCompressionStats = null }) {
311
+ const budgetTracker = new BudgetTracker({ pricing: config?.budget?.pricing });
312
+ // KJC-BUG-0114: Number(null) === 0, so a config that reached us with
313
+ // max_budget_usd: null produced a phantom "$X / $0.00" ceiling (and a
314
+ // permanent warn state). null/undefined fall back to the shipped
315
+ // default ceiling; an explicit 0 means "no ceiling".
316
+ const rawBudget = config?.max_budget_usd;
317
+ const budgetLimit = rawBudget == null ? DEFAULTS.max_budget_usd : Number(rawBudget);
318
+ const hasBudgetLimit = Number.isFinite(budgetLimit) && budgetLimit > 0;
319
+ const warnThresholdPct = Number(config?.budget?.warn_threshold_pct ?? 80);
320
+ let stageCounter = 0;
321
+
322
+ function budgetSummary() {
323
+ const s = budgetTracker.summary();
324
+ s.trace = budgetTracker.trace();
325
+ // Attach the "With KJ vs Without KJ" comparison when compression data
326
+ // is available (TSK-0274). hasCompression: false means no savings to
327
+ // report; the display falls back to the plain cost line.
328
+ if (typeof getCompressionStats === "function") {
329
+ try {
330
+ const stats = getCompressionStats() || {};
331
+ s.kj_comparison = computeKjComparison({
332
+ realTokens: s.total_tokens,
333
+ realCost: s.total_cost_usd,
334
+ rtkSavings: stats.rtkSavings,
335
+ brainCtx: stats.brainCtx,
336
+ });
337
+ } catch { /* best-effort — omit comparison on failure */ }
338
+ }
339
+ return s;
340
+ }
341
+
342
+ function trackBudget({ role, provider, model, result, duration_ms, promptSize }) {
343
+ const enrichedResult = promptSize && result ? { ...result, promptSize } : result;
344
+ const metrics = extractUsageMetrics(enrichedResult, model);
345
+ budgetTracker.record({ role, provider, ...metrics, duration_ms, stage_index: stageCounter++ });
346
+
347
+ if (!hasBudgetLimit) return;
348
+ const totalCost = budgetTracker.total().cost_usd;
349
+ const pctUsed = budgetLimit === 0 ? 100 : (totalCost / budgetLimit) * 100;
350
+ const warnOrOk = pctUsed >= warnThresholdPct ? "paused" : "ok";
351
+ const status = totalCost > budgetLimit ? "fail" : warnOrOk;
352
+ emitProgress(
353
+ emitter,
354
+ makeEvent("budget:update", { ...eventBase, stage: role }, {
355
+ status,
356
+ message: `Budget: $${totalCost.toFixed(2)} / $${budgetLimit.toFixed(2)}`,
357
+ detail: {
358
+ ...budgetSummary(),
359
+ max_budget_usd: budgetLimit,
360
+ warn_threshold_pct: warnThresholdPct,
361
+ pct_used: Number(pctUsed.toFixed(2)),
362
+ remaining_usd: budgetTracker.remaining(budgetLimit),
363
+ executorType: "system"
364
+ }
365
+ })
366
+ );
367
+ }
368
+
369
+ return { budgetTracker, budgetLimit, budgetSummary, trackBudget };
370
+ }
371
+
372
+ export async function initializeSession({ task, config, flags, pgTaskId, pgProject }) {
373
+ const baseRef = await computeBaseRef({ baseBranch: config.base_branch, baseRef: flags.baseRef || null });
374
+
375
+ if (baseRef === "__snapshot__") {
376
+ // TSK-0340: `setSnapshot` now static; `takeSnapshot` kept dynamic because
377
+ // snapshot-diff is ~600 LOC of dependency-free fs walking that most
378
+ // runs don't need (only the greenfield/no-git path reaches here).
379
+ const { takeSnapshot } = await import("../review/snapshot-diff.js");
380
+ const snapshot = await takeSnapshot(config.projectDir || process.cwd());
381
+ setSnapshot(snapshot);
382
+ }
383
+
384
+ // PR-F: stamp project_id on every session derived from the project
385
+ // directory (slug = same algorithm the board uses to bucket plans).
386
+ // Without this, sessions created by `kj run` from a terminal land
387
+ // on disk with `project_id: null`. The board sync sees an orphan
388
+ // and (used to) promote it to a phantom "Orphan sessions" project.
389
+ // Now that PR-B blocks orphans on the board side, we must also fix
390
+ // the source so the session can attach to a real project.
391
+ const projectDir = config.projectDir || process.cwd();
392
+ const project_id = projectSlug(projectDir);
393
+
394
+ // Capture HEAD at the very start of the run, separately from base_ref.
395
+ // session_start_sha was being conflated with base_ref (used for `git diff`)
396
+ // — when the user's repo had a single commit and no remote main, base_ref
397
+ // fell through to git's empty-tree SHA. The post-loop journal then read
398
+ // session_start_sha to enumerate "commits made by this run" and got back
399
+ // the entire history, including pre-existing commits. Capturing actual
400
+ // HEAD here makes "what did the run produce?" deterministic and correct.
401
+ // Falls back to baseRef when HEAD doesn't exist (zero-commits repo); in
402
+ // that case "everything since baseRef" still equals "everything the run
403
+ // produced" because there was no prior history.
404
+ let headAtStart;
405
+ try {
406
+ headAtStart = (await revParse("HEAD")) || baseRef;
407
+ } catch { headAtStart = baseRef; }
408
+
409
+ const sessionInit = {
410
+ task,
411
+ project_id,
412
+ config_snapshot: config,
413
+ base_ref: baseRef,
414
+ session_start_sha: baseRef,
415
+ head_at_start: headAtStart,
416
+ last_reviewer_feedback: null,
417
+ repeated_issue_count: 0,
418
+ sonar_retry_count: 0,
419
+ reviewer_retry_count: 0,
420
+ standby_retry_count: 0,
421
+ last_sonar_issue_signature: null,
422
+ sonar_repeat_count: 0,
423
+ last_reviewer_issue_signature: null,
424
+ reviewer_repeat_count: 0,
425
+ deferred_issues: []
426
+ };
427
+ if (pgTaskId) sessionInit.pg_task_id = pgTaskId;
428
+ if (pgProject) sessionInit.pg_project_id = pgProject;
429
+ return createSession(sessionInit);
430
+ }
431
+
432
+ export function applyTriageOverrides(pipelineFlags, roleOverrides) {
433
+ const keys = ["plannerEnabled", "researcherEnabled", "architectEnabled", "refactorerEnabled", "reviewerEnabled", "testerEnabled", "securityEnabled", "impeccableEnabled"];
434
+ for (const key of keys) {
435
+ if (roleOverrides[key] !== undefined) {
436
+ pipelineFlags[key] = roleOverrides[key];
437
+ }
438
+ }
439
+ }
440
+
441
+ const SIMPLE_LEVELS = new Set(["trivial", "simple"]);
442
+
443
+ export function applyAutoSimplify({ pipelineFlags, triageLevel, config, flags, logger, emitter, eventBase }) {
444
+ if (!config.pipeline?.auto_simplify) return false;
445
+ if (!triageLevel || !SIMPLE_LEVELS.has(triageLevel)) return false;
446
+ if (flags.mode) return false;
447
+ if (flags.enableReviewer !== undefined || flags.enableTester !== undefined) return false;
448
+
449
+ pipelineFlags.reviewerEnabled = false;
450
+ pipelineFlags.testerEnabled = false;
451
+
452
+ const disabledRoles = ["reviewer", "tester"];
453
+ logger.info(`Simple task (${triageLevel}) — lightweight pipeline (disabled: ${disabledRoles.join(", ")})`);
454
+ emitProgress(
455
+ emitter,
456
+ makeEvent("pipeline:simplify", { ...eventBase, stage: "triage" }, {
457
+ message: `Simple task (${triageLevel}) — lightweight pipeline`,
458
+ detail: { level: triageLevel, disabledRoles }
459
+ })
460
+ );
461
+ return true;
462
+ }
463
+
464
+ export function applyFlagOverrides(pipelineFlags, flags) {
465
+ if (flags.enablePlanner !== undefined) pipelineFlags.plannerEnabled = Boolean(flags.enablePlanner);
466
+ if (flags.enableResearcher !== undefined) pipelineFlags.researcherEnabled = Boolean(flags.enableResearcher);
467
+ if (flags.enableArchitect !== undefined) pipelineFlags.architectEnabled = Boolean(flags.enableArchitect);
468
+ if (flags.enableRefactorer !== undefined) pipelineFlags.refactorerEnabled = Boolean(flags.enableRefactorer);
469
+ if (flags.enableReviewer !== undefined) pipelineFlags.reviewerEnabled = Boolean(flags.enableReviewer);
470
+ if (flags.enableTester !== undefined) pipelineFlags.testerEnabled = Boolean(flags.enableTester);
471
+ if (flags.enableSecurity !== undefined) pipelineFlags.securityEnabled = Boolean(flags.enableSecurity);
472
+ if (flags.enableImpeccable !== undefined) pipelineFlags.impeccableEnabled = Boolean(flags.enableImpeccable);
473
+
474
+ if (flags.design) {
475
+ pipelineFlags.impeccableEnabled = true;
476
+ pipelineFlags.impeccableMode = "refactoring";
477
+ }
478
+ }
479
+
480
+ export function resolvePipelinePolicies({ flags, config, stageResults, emitter, eventBase, session, pipelineFlags }) {
481
+ const resolvedPolicies = applyPolicies({
482
+ taskType: flags.taskType || config.taskType || stageResults.triage?.taskType || stageResults.intent?.taskType || null,
483
+ policies: config.policies,
484
+ });
485
+ setResolvedPolicies(session, resolvedPolicies);
486
+
487
+ let updatedConfig = config;
488
+ if (!resolvedPolicies.tdd) {
489
+ updatedConfig = { ...updatedConfig, development: { ...updatedConfig.development, methodology: "standard", require_test_changes: false } };
490
+ }
491
+ if (!resolvedPolicies.sonar) {
492
+ updatedConfig = { ...updatedConfig, sonarqube: { ...updatedConfig.sonarqube, enabled: false } };
493
+ }
494
+ if (!resolvedPolicies.reviewer) {
495
+ pipelineFlags.reviewerEnabled = false;
496
+ }
497
+ if (resolvedPolicies.coderRequired === false) {
498
+ pipelineFlags.coderRequired = false;
499
+ }
500
+
501
+ emitProgress(
502
+ emitter,
503
+ makeEvent("policies:resolved", eventBase, {
504
+ message: `Policies resolved for taskType="${resolvedPolicies.taskType}"`,
505
+ detail: resolvedPolicies
506
+ })
507
+ );
508
+
509
+ return updatedConfig;
510
+ }