@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,44 @@
1
+ /**
2
+ * CommandRunner — DI-friendly adapter over execa / runCommand.
3
+ *
4
+ * Why: agent adapters (claude, codex, gemini, ...) all end up invoking
5
+ * src/utils/process.js -> runCommand. That makes unit-testing the agent layer
6
+ * slow and flaky — every test either spins up a real child process or stubs
7
+ * execa deep inside Vitest's module graph.
8
+ *
9
+ * This adapter preserves the runCommand API exactly, so current consumers
10
+ * can opt-in to DI without behavioural changes. A matching MockCommandRunner
11
+ * lives in src/infrastructure/mocks.js and lets tests script outputs per
12
+ * invocation.
13
+ *
14
+ * @typedef {Object} CommandRunResult
15
+ * @property {number} exitCode
16
+ * @property {string} stdout
17
+ * @property {string} stderr
18
+ * @property {boolean} [timedOut]
19
+ * @property {string|null} [signal]
20
+ *
21
+ * @typedef {Object} CommandRunOptions
22
+ * @property {number} [timeout]
23
+ * @property {(evt: {stream: string, line: string}) => void} [onOutput]
24
+ * @property {number} [silenceTimeoutMs]
25
+ * @property {number} [partialOutputFlushMs]
26
+ * @property {string|Buffer} [input]
27
+ * @property {string} [cwd]
28
+ * @property {Record<string,string>} [env]
29
+ *
30
+ * @typedef {Object} CommandRunner
31
+ * @property {(command: string, args?: string[], options?: CommandRunOptions) => Promise<CommandRunResult>} run
32
+ */
33
+
34
+ import { runCommand } from "../utils/process.js";
35
+
36
+ /**
37
+ * Default implementation — delegates to runCommand.
38
+ * @type {CommandRunner}
39
+ */
40
+ export const defaultCommandRunner = {
41
+ async run(command, args = [], options = {}) {
42
+ return runCommand(command, args, options);
43
+ }
44
+ };
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Environment — the DI bundle passed to services that need filesystem + command
3
+ * execution. Grouping them keeps call sites small: `new BaseAgent(..., env)`
4
+ * instead of `new BaseAgent(..., fs, runner)`.
5
+ *
6
+ * @typedef {import("./file-system-service.js").FileSystemService} FileSystemService
7
+ * @typedef {import("./command-runner.js").CommandRunner} CommandRunner
8
+ *
9
+ * @typedef {Object} Environment
10
+ * @property {FileSystemService} fs
11
+ * @property {CommandRunner} runner
12
+ */
13
+
14
+ import { defaultFileSystem } from "./file-system-service.js";
15
+ import { defaultCommandRunner } from "./command-runner.js";
16
+
17
+ /**
18
+ * Default environment uses native fs + real execa-based runner.
19
+ * Tests should inject a custom environment via buildEnvironment() below.
20
+ * @type {Environment}
21
+ */
22
+ export const defaultEnvironment = Object.freeze({
23
+ fs: defaultFileSystem,
24
+ runner: defaultCommandRunner
25
+ });
26
+
27
+ /**
28
+ * Merge overrides on top of the default environment. Missing properties fall
29
+ * back to defaults, so callers can replace only the pieces they care about.
30
+ * @param {Partial<Environment>} [overrides]
31
+ * @returns {Environment}
32
+ */
33
+ export function buildEnvironment(overrides = {}) {
34
+ return Object.freeze({
35
+ fs: overrides.fs ?? defaultFileSystem,
36
+ runner: overrides.runner ?? defaultCommandRunner
37
+ });
38
+ }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * FileSystemService — thin DI-friendly adapter over node:fs/promises.
3
+ *
4
+ * Why: existing code uses node:fs directly (see src/utils/fs.js and consumers),
5
+ * which makes unit-testing orchestrator/agent paths slow and flaky — every test
6
+ * that exercises a code path touching fs has to stage real files on disk.
7
+ *
8
+ * This adapter preserves the exact native API shapes for the handful of
9
+ * operations actually used in the codebase, so consumers can opt-in to DI
10
+ * without rewriting call sites. A matching MockFileSystem lives in
11
+ * src/infrastructure/mocks.js.
12
+ *
13
+ * Scope for TSK-0316: intentionally minimal. Only the operations already used
14
+ * by orchestrator + agents. Additional methods added on demand.
15
+ *
16
+ * @typedef {Object} FileSystemService
17
+ * @property {(path: string, encoding?: string) => Promise<string|Buffer>} readFile
18
+ * @property {(path: string, data: string|Buffer, encoding?: string) => Promise<void>} writeFile
19
+ * @property {(path: string, data: string|Buffer, encoding?: string) => Promise<void>} appendFile
20
+ * @property {(path: string) => Promise<boolean>} exists
21
+ * @property {(path: string) => Promise<void>} ensureDir
22
+ * @property {(path: string) => Promise<string[]>} readdir
23
+ * @property {(src: string, dest: string) => Promise<void>} copyFile
24
+ * @property {(path: string) => Promise<{size: number, isDirectory: () => boolean, isFile: () => boolean}>} stat
25
+ */
26
+
27
+ import fs from "node:fs/promises";
28
+
29
+ /**
30
+ * Default implementation backed by node:fs/promises.
31
+ * @type {FileSystemService}
32
+ */
33
+ export const defaultFileSystem = {
34
+ async readFile(path, encoding = "utf8") {
35
+ return fs.readFile(path, encoding);
36
+ },
37
+ async writeFile(path, data, encoding = "utf8") {
38
+ await fs.writeFile(path, data, encoding);
39
+ },
40
+ async appendFile(path, data, encoding = "utf8") {
41
+ await fs.appendFile(path, data, encoding);
42
+ },
43
+ async exists(path) {
44
+ try {
45
+ await fs.access(path);
46
+ return true;
47
+ } catch {
48
+ return false;
49
+ }
50
+ },
51
+ async ensureDir(path) {
52
+ await fs.mkdir(path, { recursive: true });
53
+ },
54
+ async readdir(path) {
55
+ return fs.readdir(path);
56
+ },
57
+ async copyFile(src, dest) {
58
+ await fs.copyFile(src, dest);
59
+ },
60
+ async stat(path) {
61
+ return fs.stat(path);
62
+ }
63
+ };
@@ -0,0 +1,182 @@
1
+ /**
2
+ * Test doubles for the DI surfaces. Intentionally dumb — tests stage inputs
3
+ * through simple setters and assert on recorded calls.
4
+ *
5
+ * @typedef {import("./file-system-service.js").FileSystemService} FileSystemService
6
+ * @typedef {import("./command-runner.js").CommandRunner} CommandRunner
7
+ * @typedef {import("./command-runner.js").CommandRunResult} CommandRunResult
8
+ * @typedef {import("./command-runner.js").CommandRunOptions} CommandRunOptions
9
+ */
10
+
11
+ /**
12
+ * In-memory file system. Paths are stored as-is (no normalization) to keep
13
+ * behaviour predictable in tests.
14
+ */
15
+ export class MockFileSystem {
16
+ constructor(initial = {}) {
17
+ /** @type {Map<string, string|Buffer>} */
18
+ this.files = new Map(Object.entries(initial));
19
+ /** @type {Set<string>} */
20
+ this.directories = new Set();
21
+ /** @type {Array<{op: string, path: string, args?: unknown}>} */
22
+ this.calls = [];
23
+ }
24
+
25
+ _record(op, path, args) {
26
+ this.calls.push({ op, path, args });
27
+ }
28
+
29
+ async readFile(path, encoding = "utf8") {
30
+ this._record("readFile", path, { encoding });
31
+ if (!this.files.has(path)) {
32
+ const err = new Error(`ENOENT: no such file or directory, open '${path}'`);
33
+ err.code = "ENOENT";
34
+ throw err;
35
+ }
36
+ const data = this.files.get(path);
37
+ if (Buffer.isBuffer(data) && encoding) return data.toString(encoding);
38
+ return data;
39
+ }
40
+
41
+ async writeFile(path, data, encoding = "utf8") {
42
+ this._record("writeFile", path, { encoding });
43
+ this.files.set(path, data);
44
+ }
45
+
46
+ async appendFile(path, data, encoding = "utf8") {
47
+ this._record("appendFile", path, { encoding });
48
+ const prev = this.files.get(path) ?? "";
49
+ this.files.set(path, String(prev) + String(data));
50
+ }
51
+
52
+ async exists(path) {
53
+ this._record("exists", path);
54
+ return this.files.has(path) || this.directories.has(path);
55
+ }
56
+
57
+ async ensureDir(path) {
58
+ this._record("ensureDir", path);
59
+ this.directories.add(path);
60
+ }
61
+
62
+ async readdir(path) {
63
+ this._record("readdir", path);
64
+ const prefix = path.endsWith("/") ? path : path + "/";
65
+ const entries = new Set();
66
+ for (const p of this.files.keys()) {
67
+ if (p.startsWith(prefix)) {
68
+ const tail = p.slice(prefix.length).split("/")[0];
69
+ if (tail) entries.add(tail);
70
+ }
71
+ }
72
+ if (!entries.size && !this.directories.has(path)) {
73
+ const err = new Error(`ENOENT: no such file or directory, scandir '${path}'`);
74
+ err.code = "ENOENT";
75
+ throw err;
76
+ }
77
+ return [...entries];
78
+ }
79
+
80
+ async copyFile(src, dest) {
81
+ this._record("copyFile", src, { dest });
82
+ if (!this.files.has(src)) {
83
+ const err = new Error(`ENOENT: no such file or directory, copyfile '${src}' -> '${dest}'`);
84
+ err.code = "ENOENT";
85
+ throw err;
86
+ }
87
+ this.files.set(dest, this.files.get(src));
88
+ }
89
+
90
+ async stat(path) {
91
+ this._record("stat", path);
92
+ if (this.files.has(path)) {
93
+ const data = this.files.get(path);
94
+ const size = Buffer.isBuffer(data) ? data.length : Buffer.byteLength(String(data));
95
+ return {
96
+ size,
97
+ isDirectory: () => false,
98
+ isFile: () => true
99
+ };
100
+ }
101
+ if (this.directories.has(path)) {
102
+ return {
103
+ size: 0,
104
+ isDirectory: () => true,
105
+ isFile: () => false
106
+ };
107
+ }
108
+ const err = new Error(`ENOENT: no such file or directory, stat '${path}'`);
109
+ err.code = "ENOENT";
110
+ throw err;
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Scripted command runner. Tests call enqueue() to stage responses in order,
116
+ * or setResponder() for a per-invocation decision. Every run() is recorded.
117
+ */
118
+ export class MockCommandRunner {
119
+ constructor() {
120
+ /** @type {Array<CommandRunResult>} */
121
+ this.queue = [];
122
+ /** @type {Array<{command: string, args: string[], options: CommandRunOptions}>} */
123
+ this.calls = [];
124
+ /** @type {null | ((args: {command: string, args: string[], options: CommandRunOptions}) => CommandRunResult|Promise<CommandRunResult>)} */
125
+ this.responder = null;
126
+ /** @type {CommandRunResult} */
127
+ this.defaultResponse = { exitCode: 0, stdout: "", stderr: "" };
128
+ }
129
+
130
+ /**
131
+ * Queue a response. FIFO — first enqueued is returned on the first run().
132
+ * @param {Partial<CommandRunResult>} response
133
+ */
134
+ enqueue(response) {
135
+ this.queue.push({ exitCode: 0, stdout: "", stderr: "", ...response });
136
+ return this;
137
+ }
138
+
139
+ /**
140
+ * Replace FIFO queue with a function that decides per-call.
141
+ * @param {(args: {command: string, args: string[], options: CommandRunOptions}) => CommandRunResult|Promise<CommandRunResult>} fn
142
+ */
143
+ setResponder(fn) {
144
+ this.responder = fn;
145
+ return this;
146
+ }
147
+
148
+ /**
149
+ * @param {string} command
150
+ * @param {string[]} args
151
+ * @param {CommandRunOptions} options
152
+ * @returns {Promise<CommandRunResult>}
153
+ */
154
+ async run(command, args = [], options = {}) {
155
+ this.calls.push({ command, args: [...args], options: { ...options } });
156
+ if (this.responder) return this.responder({ command, args, options });
157
+ if (this.queue.length > 0) return this.queue.shift();
158
+ return { ...this.defaultResponse };
159
+ }
160
+
161
+ /**
162
+ * Convenience: last recorded invocation, or null.
163
+ */
164
+ get lastCall() {
165
+ return this.calls.at(-1) ?? null;
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Build an Environment backed by the mocks above. Useful shorthand in tests:
171
+ *
172
+ * const { env, fs, runner } = buildMockEnvironment();
173
+ * const agent = new BaseAgent(..., env);
174
+ *
175
+ * @param {{files?: Record<string, string|Buffer>}} [opts]
176
+ */
177
+ export function buildMockEnvironment({ files } = {}) {
178
+ const fs = new MockFileSystem(files);
179
+ const runner = new MockCommandRunner();
180
+ const env = Object.freeze({ fs, runner });
181
+ return { env, fs, runner };
182
+ }
@@ -0,0 +1,94 @@
1
+ // KJC-PCS-0052 PR-B.2.3 — Go source chunker (tree-sitter + regex fallback).
2
+ // Mismo contrato síncrono que chunk-rust: AST si el caller awaited
3
+ // `prepareGo()` antes, regex si no. Top-level: func / method / type.
4
+ //
5
+ // `method_declaration` (con receiver) y `function_declaration` se tratan
6
+ // igual — symbol es el nombre, sin componer "Recv.Method" (coherente con
7
+ // Python: del scope se ocupa la búsqueda semántica, no el chunk).
8
+ // `type_declaration` contiene type_spec(s); usamos el primero como symbol.
9
+
10
+ import { getLoaded, loadLanguage } from "./tree-sitter-loader.js";
11
+
12
+ const DEFAULT_LIMIT = 800;
13
+ const DEFAULT_OVERLAP = 100;
14
+ const NAMED_KINDS = new Set([
15
+ "function_declaration",
16
+ "method_declaration",
17
+ ]);
18
+ const TOP_RE = /^(?:func(?:\s+\([^)]+\))?|type)\s+([A-Za-z_]\w*)/gm;
19
+
20
+ export async function prepareGo() {
21
+ return loadLanguage("go");
22
+ }
23
+
24
+ function windowText(text, limit, overlap) {
25
+ if (text.length <= limit) return [text];
26
+ const step = Math.max(1, limit - overlap);
27
+ const out = [];
28
+ for (let i = 0; i < text.length; i += step) {
29
+ out.push(text.slice(i, i + limit));
30
+ if (i + limit >= text.length) break;
31
+ }
32
+ return out;
33
+ }
34
+
35
+ function symbolForType(node) {
36
+ for (const spec of node.namedChildren) {
37
+ if (spec.type === "type_spec" || spec.type === "type_alias") {
38
+ const nameNode = spec.childForFieldName("name");
39
+ if (nameNode) return nameNode.text;
40
+ }
41
+ }
42
+ return null;
43
+ }
44
+
45
+ function marksViaAST(text) {
46
+ const entry = getLoaded("go");
47
+ if (!entry) return null;
48
+ let tree;
49
+ try {
50
+ tree = entry.parser.parse(text);
51
+ } catch {
52
+ return null;
53
+ }
54
+ const marks = [];
55
+ for (const child of tree.rootNode.namedChildren) {
56
+ let symbol = null;
57
+ if (NAMED_KINDS.has(child.type)) {
58
+ const nameNode = child.childForFieldName("name");
59
+ if (nameNode) symbol = nameNode.text;
60
+ } else if (child.type === "type_declaration") {
61
+ symbol = symbolForType(child);
62
+ }
63
+ if (symbol) marks.push({ idx: child.startIndex, symbol });
64
+ }
65
+ return marks;
66
+ }
67
+
68
+ function marksViaRegex(text) {
69
+ const marks = [];
70
+ TOP_RE.lastIndex = 0;
71
+ let m;
72
+ while ((m = TOP_RE.exec(text)) !== null) marks.push({ idx: m.index, symbol: m[1] });
73
+ return marks;
74
+ }
75
+
76
+ export function chunkGo(text, { path = "<src>", limit = DEFAULT_LIMIT, overlap = DEFAULT_OVERLAP } = {}) {
77
+ const marks = marksViaAST(text) ?? marksViaRegex(text);
78
+ if (marks.length === 0) {
79
+ return windowText(text, limit, overlap).map((piece) => ({
80
+ text: piece,
81
+ metadata: { source: path, kind: "code", symbol: null, language: "go" },
82
+ }));
83
+ }
84
+ const out = [];
85
+ for (let i = 0; i < marks.length; i += 1) {
86
+ const start = marks[i].idx;
87
+ const end = i + 1 < marks.length ? marks[i + 1].idx : text.length;
88
+ const body = text.slice(start, end);
89
+ for (const piece of windowText(body, limit, overlap)) {
90
+ out.push({ text: piece, metadata: { source: path, kind: "code", symbol: marks[i].symbol, language: "go" } });
91
+ }
92
+ }
93
+ return out;
94
+ }
@@ -0,0 +1,90 @@
1
+ // KJC-PCS-0052 PR-B.2.5 — Java chunker (tree-sitter + regex fallback).
2
+ // Walker 2 niveles: top-level emite class/interface/enum/record; segundo pase
3
+ // desciende al body por method_declaration / constructor_declaration. Symbol
4
+ // sin prefijar (coherente con chunk-go), el RAG ya lleva contexto del fichero.
5
+
6
+ import { getLoaded, loadLanguage } from "./tree-sitter-loader.js";
7
+
8
+ const DEFAULT_LIMIT = 800;
9
+ const DEFAULT_OVERLAP = 100;
10
+ const CONTAINER_KINDS = new Set([
11
+ "class_declaration",
12
+ "interface_declaration",
13
+ "enum_declaration",
14
+ "record_declaration",
15
+ ]);
16
+ const MEMBER_KINDS = new Set([
17
+ "method_declaration",
18
+ "constructor_declaration",
19
+ ]);
20
+ const TOP_RE = /^[ \t]*(?:public\s+|private\s+|protected\s+|static\s+|final\s+|abstract\s+|sealed\s+|non-sealed\s+)*(class|interface|enum|record)\s+([A-Za-z_]\w*)/gm;
21
+
22
+ export async function prepareJava() {
23
+ return loadLanguage("java");
24
+ }
25
+
26
+ function windowText(text, limit, overlap) {
27
+ if (text.length <= limit) return [text];
28
+ const step = Math.max(1, limit - overlap);
29
+ const out = [];
30
+ for (let i = 0; i < text.length; i += step) {
31
+ out.push(text.slice(i, i + limit));
32
+ if (i + limit >= text.length) break;
33
+ }
34
+ return out;
35
+ }
36
+
37
+ function nameOf(node) {
38
+ const n = node.childForFieldName("name");
39
+ return n ? n.text : null;
40
+ }
41
+
42
+ function marksViaAST(text) {
43
+ const entry = getLoaded("java");
44
+ if (!entry) return null;
45
+ let tree;
46
+ try { tree = entry.parser.parse(text); } catch { return null; }
47
+ const marks = [];
48
+ for (const child of tree.rootNode.namedChildren) {
49
+ if (!CONTAINER_KINDS.has(child.type)) continue;
50
+ const s = nameOf(child);
51
+ if (s) marks.push({ idx: child.startIndex, symbol: s });
52
+ const body = child.childForFieldName("body");
53
+ if (!body) continue;
54
+ for (const m of body.namedChildren) {
55
+ if (!MEMBER_KINDS.has(m.type)) continue;
56
+ const ms = nameOf(m);
57
+ if (ms) marks.push({ idx: m.startIndex, symbol: ms });
58
+ }
59
+ }
60
+ marks.sort((a, b) => a.idx - b.idx);
61
+ return marks;
62
+ }
63
+
64
+ function marksViaRegex(text) {
65
+ const marks = [];
66
+ TOP_RE.lastIndex = 0;
67
+ let m;
68
+ while ((m = TOP_RE.exec(text)) !== null) marks.push({ idx: m.index, symbol: m[2] });
69
+ return marks;
70
+ }
71
+
72
+ export function chunkJava(text, { path = "<src>", limit = DEFAULT_LIMIT, overlap = DEFAULT_OVERLAP } = {}) {
73
+ const marks = marksViaAST(text) ?? marksViaRegex(text);
74
+ if (marks.length === 0) {
75
+ return windowText(text, limit, overlap).map((piece) => ({
76
+ text: piece,
77
+ metadata: { source: path, kind: "code", symbol: null, language: "java" },
78
+ }));
79
+ }
80
+ const out = [];
81
+ for (let i = 0; i < marks.length; i += 1) {
82
+ const start = marks[i].idx;
83
+ const end = i + 1 < marks.length ? marks[i + 1].idx : text.length;
84
+ const body = text.slice(start, end);
85
+ for (const piece of windowText(body, limit, overlap)) {
86
+ out.push({ text: piece, metadata: { source: path, kind: "code", symbol: marks[i].symbol, language: "java" } });
87
+ }
88
+ }
89
+ return out;
90
+ }
@@ -0,0 +1,88 @@
1
+ // KJC-PCS-0052 PR-B.2.1 — Python source chunker (tree-sitter + regex fallback).
2
+ // Top-level `def`/`async def`/`class` siguen siendo la frontera de chunk, pero
3
+ // ahora con dos caminos:
4
+ // 1. AST (web-tree-sitter): si el caller hizo `await preparePython()` antes
5
+ // del indexado, leemos el árbol y capturamos solo nodos cuyo `parent.type`
6
+ // es `module` — eso excluye métodos anidados sin depender de la
7
+ // indentación visual y captura decoradores (`decorated_definition`)
8
+ // apuntando al def/class real subyacente.
9
+ // 2. Regex: fallback síncrono para entornos sin tree-sitter listo (tests
10
+ // legacy, primera invocación antes de `preparePython`). Misma semántica
11
+ // que PR-B.
12
+ //
13
+ // El contrato externo no cambia: `chunkPython(text, opts)` es síncrono y
14
+ // devuelve `[{ text, metadata: { source, kind, symbol, language } }]`.
15
+
16
+ import { getLoaded, loadLanguage } from "./tree-sitter-loader.js";
17
+
18
+ const DEFAULT_LIMIT = 800;
19
+ const DEFAULT_OVERLAP = 100;
20
+ const TOP_RE = /^(?:async\s+)?(?:def|class)\s+([A-Za-z_]\w*)/gm;
21
+
22
+ export async function preparePython() {
23
+ return loadLanguage("python");
24
+ }
25
+
26
+ function windowText(text, limit, overlap) {
27
+ if (text.length <= limit) return [text];
28
+ const step = Math.max(1, limit - overlap);
29
+ const out = [];
30
+ for (let i = 0; i < text.length; i += step) {
31
+ out.push(text.slice(i, i + limit));
32
+ if (i + limit >= text.length) break;
33
+ }
34
+ return out;
35
+ }
36
+
37
+ function marksViaAST(text) {
38
+ const entry = getLoaded("python");
39
+ if (!entry) return null;
40
+ let tree;
41
+ try {
42
+ tree = entry.parser.parse(text);
43
+ } catch {
44
+ return null;
45
+ }
46
+ const marks = [];
47
+ for (const child of tree.rootNode.namedChildren) {
48
+ let defNode = null;
49
+ if (child.type === "function_definition" || child.type === "class_definition") {
50
+ defNode = child;
51
+ } else if (child.type === "decorated_definition") {
52
+ defNode = child.childForFieldName("definition");
53
+ }
54
+ if (!defNode) continue;
55
+ const nameNode = defNode.childForFieldName("name");
56
+ if (!nameNode) continue;
57
+ marks.push({ idx: child.startIndex, symbol: nameNode.text });
58
+ }
59
+ return marks;
60
+ }
61
+
62
+ function marksViaRegex(text) {
63
+ const marks = [];
64
+ TOP_RE.lastIndex = 0;
65
+ let m;
66
+ while ((m = TOP_RE.exec(text)) !== null) marks.push({ idx: m.index, symbol: m[1] });
67
+ return marks;
68
+ }
69
+
70
+ export function chunkPython(text, { path = "<src>", limit = DEFAULT_LIMIT, overlap = DEFAULT_OVERLAP } = {}) {
71
+ const marks = marksViaAST(text) ?? marksViaRegex(text);
72
+ if (marks.length === 0) {
73
+ return windowText(text, limit, overlap).map((piece) => ({
74
+ text: piece,
75
+ metadata: { source: path, kind: "code", symbol: null, language: "python" },
76
+ }));
77
+ }
78
+ const out = [];
79
+ for (let i = 0; i < marks.length; i += 1) {
80
+ const start = marks[i].idx;
81
+ const end = i + 1 < marks.length ? marks[i + 1].idx : text.length;
82
+ const body = text.slice(start, end);
83
+ for (const piece of windowText(body, limit, overlap)) {
84
+ out.push({ text: piece, metadata: { source: path, kind: "code", symbol: marks[i].symbol, language: "python" } });
85
+ }
86
+ }
87
+ return out;
88
+ }