@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,54 @@
1
+ /**
2
+ * RAG post-merge hook wiring check (KJC-BUG-0100).
3
+ *
4
+ * `kj rag install-hooks` used to write the hook into `.git/hooks/post-merge`,
5
+ * but when a repo is hardened `git config core.hooksPath` points at
6
+ * `.karajan/hooks` and git ignores `.git/hooks/` entirely — so the RAG index
7
+ * silently never refreshes after a merge. This check resolves the *effective*
8
+ * hooks dir and reports whether the post-merge hook there reindexes the RAG.
9
+ * The pre-run drift check in `kj run` already covers the gap, so a missing
10
+ * hook is advisory (info), not a failure — it surfaces the state without
11
+ * nagging every repo that never ran `kj rag install-hooks`.
12
+ */
13
+
14
+ import { existsSync, readFileSync } from "node:fs";
15
+ import { join } from "node:path";
16
+ import { STRATEGY } from "./types.js";
17
+ import { resolveHooksDir } from "../rag/auto-update.js";
18
+
19
+ export function createRagHooksCheck({ projectDir } = {}) {
20
+ return {
21
+ name: "rag-hooks",
22
+ label: "RAG post-merge refresh",
23
+ strategy: STRATEGY.MANUAL,
24
+ async detect() {
25
+ const dir = projectDir || process.cwd();
26
+ let hooks;
27
+ try {
28
+ hooks = await resolveHooksDir(dir);
29
+ } catch {
30
+ return { ok: true, severity: "info", detail: "not a git repository — no post-merge hook to wire" };
31
+ }
32
+ const target = join(hooks.dir, "post-merge");
33
+ const wired = existsSync(target) && /kj\s+rag\s+index/.test(readFileSync(target, "utf8"));
34
+ if (wired) {
35
+ return {
36
+ ok: true,
37
+ severity: "info",
38
+ detail: `post-merge reindexes the RAG (${hooks.hooksPath || ".git/hooks"})`,
39
+ };
40
+ }
41
+ const where = hooks.hooksPath ? ` — core.hooksPath=${hooks.hooksPath}` : "";
42
+ return {
43
+ ok: false,
44
+ severity: "info",
45
+ detail: `RAG index won't auto-refresh after merges${where}; pre-run drift check still covers \`kj run\``,
46
+ fix: "Wire the post-merge hook: `kj rag install-hooks`",
47
+ };
48
+ },
49
+ };
50
+ }
51
+
52
+ export function getRagHooksChecks({ projectDir } = {}) {
53
+ return [createRagHooksCheck({ projectDir })];
54
+ }
@@ -0,0 +1,102 @@
1
+ /**
2
+ * release-check (KJC-TSK-0712) — the release checklist made verifiable:
3
+ * a note loses salience; a check fails RED with the exact list. Generics
4
+ * fit any karajan project; each project extends via `release_check.items`
5
+ * (file_contains with {version}, or command with exit-0 semantics).
6
+ */
7
+
8
+ import { existsSync, readFileSync } from "node:fs";
9
+ import { isAbsolute, join } from "node:path";
10
+ import { runCommand } from "../utils/process.js";
11
+ import { loadPrivacyList, scanPaths } from "../privacy/scan.js";
12
+
13
+ const semverCmp = (a, b) => {
14
+ const pa = a.split(".").map(Number), pb = b.split(".").map(Number);
15
+ for (let i = 0; i < 3; i++) if ((pa[i] || 0) !== (pb[i] || 0)) return (pa[i] || 0) - (pb[i] || 0);
16
+ return 0;
17
+ };
18
+
19
+ async function genericChecks(projectDir) {
20
+ const checks = [];
21
+ const pkgPath = join(projectDir, "package.json");
22
+ if (!existsSync(pkgPath)) {
23
+ checks.push({ name: "manifest", ok: true, detail: "no package.json — generic version checks skipped (declared items still run)" });
24
+ return { checks, version: null, pkg: null };
25
+ }
26
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
27
+ const version = pkg.version;
28
+ checks.push({ name: "manifest", ok: Boolean(version), detail: version ? `version ${version}` : "package.json has no version" });
29
+
30
+ const clPath = join(projectDir, "CHANGELOG.md");
31
+ if (existsSync(clPath)) {
32
+ const cl = readFileSync(clPath, "utf8");
33
+ const topVersioned = (cl.match(/^## \[(\d+\.\d+\.\d+)\]/m) || [])[1] || null;
34
+ // Content still sitting under [Unreleased] means unpromoted entries —
35
+ // the tarball would ship changes its release notes do not tell.
36
+ const afterUnreleased = cl.split(/^## \[Unreleased\]\s*$/m)[1] ?? "";
37
+ const unreleasedBody = afterUnreleased.split(/^## \[/m)[0] ?? "";
38
+ const pending = /\S/.test(unreleasedBody);
39
+ const ok = topVersioned === version && !pending;
40
+ let detail = `top section is [${version}], Unreleased empty`;
41
+ if (pending) detail = `[Unreleased] still carries content — promote it into [${version}] before releasing`;
42
+ else if (!ok) detail = `top CHANGELOG section is [${topVersioned ?? "none"}] but the manifest says ${version} — promote Unreleased before releasing`;
43
+ checks.push({ name: "changelog-current", ok, detail });
44
+ } else {
45
+ checks.push({ name: "changelog-current", ok: false, detail: "no CHANGELOG.md — the release story must exist before the release" });
46
+ }
47
+
48
+ const tagsOut = await runCommand("git", ["-C", projectDir, "tag", "--list", "v[0-9]*"]);
49
+ const tags = (tagsOut.stdout || "").split("\n").map((t) => t.trim().replace(/^v/, "")).filter((t) => /^\d+\.\d+\.\d+$/.test(t));
50
+ const ahead = version ? tags.filter((t) => semverCmp(t, version) > 0) : [];
51
+ let tagDetail = tags.includes(version) ? `v${version} already tagged` : `tag v${version} pending (created after publish)`;
52
+ if (ahead.length > 0) tagDetail = `tag(s) ahead of the manifest exist: v${ahead.join(", v")}`;
53
+ checks.push({ name: "tags", ok: ahead.length === 0, detail: tagDetail });
54
+ return { checks, version, pkg };
55
+ }
56
+
57
+ async function packPrivacyCheck(projectDir, pkg) {
58
+ // Every non-private named package is publishable (exports/files-based
59
+ // packages carry no main/bin) — they all get the scan.
60
+ if (!pkg || pkg.private === true || !pkg.name || !pkg.version) return null;
61
+ try {
62
+ const out = await runCommand("npm", ["pack", "--dry-run", "--json", "--silent"], { cwd: projectDir });
63
+ const files = (JSON.parse(out.stdout || "[]")[0]?.files || []).map((f) => join(projectDir, f.path));
64
+ const blocks = scanPaths(files, { list: loadPrivacyList() }).filter((f) => f.severity === "block");
65
+ return { name: "pack-privacy", ok: blocks.length === 0, detail: blocks.length ? `${blocks.length} personal-data/secret hit(s) in the publishable files` : `${files.length} publishable file(s) clean` };
66
+ } catch (err) {
67
+ return { name: "pack-privacy", ok: false, detail: `npm pack --dry-run failed: ${err.message}` };
68
+ }
69
+ }
70
+
71
+ async function declaredItems(projectDir, config, version) {
72
+ const items = config?.release_check?.items;
73
+ if (!Array.isArray(items)) return [];
74
+ const checks = [];
75
+ for (const item of items) {
76
+ const name = item?.name || "unnamed item";
77
+ if (item?.file_contains?.path && item.file_contains.pattern != null) {
78
+ const p = isAbsolute(item.file_contains.path) ? item.file_contains.path : join(projectDir, item.file_contains.path);
79
+ const needle = String(item.file_contains.pattern).replaceAll("{version}", version ?? "");
80
+ const ok = existsSync(p) && readFileSync(p, "utf8").includes(needle);
81
+ checks.push({ name, ok, detail: ok ? `"${needle}" found in ${item.file_contains.path}` : `"${needle}" NOT found in ${item.file_contains.path}` });
82
+ } else if (item?.command) {
83
+ try {
84
+ const res = await runCommand("sh", ["-c", String(item.command).replaceAll("{version}", version ?? "")], { cwd: projectDir });
85
+ checks.push({ name, ok: res.exitCode === 0, detail: res.exitCode === 0 ? "command exited 0" : `command exited ${res.exitCode}` });
86
+ } catch (err) {
87
+ checks.push({ name, ok: false, detail: `command failed to run: ${err.message}` });
88
+ }
89
+ } else {
90
+ checks.push({ name, ok: false, detail: "unknown item shape — use file_contains {path, pattern} or command" });
91
+ }
92
+ }
93
+ return checks;
94
+ }
95
+
96
+ export async function runReleaseCheck({ projectDir = process.cwd(), config = {} } = {}) {
97
+ const { checks, version, pkg } = await genericChecks(projectDir);
98
+ const pack = await packPrivacyCheck(projectDir, pkg);
99
+ if (pack) checks.push(pack);
100
+ checks.push(...await declaredItems(projectDir, config, version));
101
+ return { ok: checks.every((c) => c.ok), version, checks };
102
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * RTK (Rust Token Killer) availability check. Manual strategy — installation
3
+ * depends on the host platform and is handled by getInstallCommand().
4
+ */
5
+
6
+ import { runCommand } from "../utils/process.js";
7
+ import { getInstallCommand } from "../utils/os-detect.js";
8
+ import { withDocLink } from "../utils/doc-links.js";
9
+ import { STRATEGY } from "./types.js";
10
+
11
+ function createRtkCheck() {
12
+ return {
13
+ name: "rtk",
14
+ label: "RTK (Rust Token Killer)",
15
+ strategy: STRATEGY.MANUAL,
16
+ async detect() {
17
+ try {
18
+ const res = await runCommand("rtk", ["--version"]);
19
+ if (res.exitCode === 0) {
20
+ return { ok: true, severity: "info", detail: `${res.stdout.trim()} — token savings active` };
21
+ }
22
+ } catch { /* not installed */ }
23
+ const installCmd = getInstallCommand("rtk");
24
+ return {
25
+ ok: false,
26
+ severity: "warn",
27
+ detail: "Not found — 60-90% token savings available",
28
+ fix: withDocLink(`Install: ${installCmd}`, "rtk_install"),
29
+ };
30
+ },
31
+ };
32
+ }
33
+
34
+ export function getRtkChecks() {
35
+ return [createRtkCheck()];
36
+ }
@@ -0,0 +1,326 @@
1
+ /**
2
+ * Check runner. Orchestrates the detect → remediate → re-verify phases for
3
+ * a list of Check objects.
4
+ *
5
+ * Phase 1 (detect): executed in parallel with per-check timeout. Timeouts
6
+ * are reported as TIMEOUT status (WARN-level), never throw.
7
+ *
8
+ * Phase 2 (remediate): sequential, only for failures with strategy auto or
9
+ * prompt (and user consent for prompt). Skipped entirely when mode is
10
+ * "check-only". Each remediation has its own timeout (5s default, 60s for
11
+ * prompted actions like npm install).
12
+ *
13
+ * Phase 3 (re-verify): re-runs `detect` once for each check that was
14
+ * remediated, to confirm the fix actually worked. If re-verify fails, the
15
+ * status is FAIL (remediation lied).
16
+ *
17
+ * Runtime overrides returned by remediations are merged into `runReport.overrides`
18
+ * for consumers (e.g. preflight → orchestrator) to apply to the active session.
19
+ */
20
+
21
+ import { STATUS, STRATEGY } from "./types.js";
22
+ import { withTimeout, TimeoutError } from "../utils/with-timeout.js";
23
+
24
+ const DEFAULT_DETECT_TIMEOUT_MS = 5000;
25
+ const DEFAULT_REMEDIATE_TIMEOUT_MS = 60000;
26
+
27
+ /**
28
+ * @param {import("./types.js").Check[]} checks
29
+ * @param {{ config: Object }} ctx
30
+ * @param {{
31
+ * mode?: "fix"|"check-only",
32
+ * yes?: boolean,
33
+ * onConfirm?: (describe: string) => Promise<boolean>,
34
+ * timeoutMs?: number,
35
+ * remediateTimeoutMs?: number,
36
+ * signal?: AbortSignal,
37
+ * logger?: { info: Function, warn: Function, error: Function }
38
+ * }} [options]
39
+ * @returns {Promise<import("./types.js").RunReport>}
40
+ */
41
+ export async function runChecks(checks, ctx, options = {}) {
42
+ const {
43
+ mode = "fix",
44
+ yes = false,
45
+ onConfirm = defaultOnConfirm,
46
+ timeoutMs = DEFAULT_DETECT_TIMEOUT_MS,
47
+ remediateTimeoutMs = DEFAULT_REMEDIATE_TIMEOUT_MS,
48
+ signal,
49
+ logger = silentLogger(),
50
+ } = options;
51
+
52
+ const { config } = ctx;
53
+ const startTotal = Date.now();
54
+ const entries = [];
55
+ const overrides = {};
56
+
57
+ // Build applicable entries (skipped checks noted up front).
58
+ // A check.applies(config) may return:
59
+ // - true / false — boolean form (back-compat).
60
+ // - an object { applies: boolean, reason?: string } — when false, `reason`
61
+ // is shown verbatim so users see WHY (e.g. "sonarqube.enabled is false
62
+ // in kj.config.yml") instead of the opaque "Not applicable" message
63
+ // that confused users debugging their config.
64
+ for (const check of checks) {
65
+ if (typeof check.applies !== "function") {
66
+ entries.push({ check, status: null, detail: null, runMs: 0, detectResult: null, remediated: false });
67
+ continue;
68
+ }
69
+ const verdict = check.applies(config);
70
+ const isObj = verdict && typeof verdict === "object" && "applies" in verdict;
71
+ const applies = isObj ? Boolean(verdict.applies) : Boolean(verdict);
72
+ if (applies) {
73
+ entries.push({ check, status: null, detail: null, runMs: 0, detectResult: null, remediated: false });
74
+ continue;
75
+ }
76
+ const reason = (isObj && typeof verdict.reason === "string" && verdict.reason.trim())
77
+ ? verdict.reason.trim()
78
+ : "Not applicable for current configuration";
79
+ entries.push({
80
+ check,
81
+ status: STATUS.SKIPPED,
82
+ detail: reason,
83
+ runMs: 0,
84
+ detectResult: null,
85
+ remediated: false,
86
+ });
87
+ }
88
+
89
+ // Phase 1: detect in parallel with timeout.
90
+ const detectBase = Date.now();
91
+ await Promise.all(
92
+ entries.map(async (entry) => {
93
+ if (entry.status === STATUS.SKIPPED) return;
94
+ const start = Date.now();
95
+ try {
96
+ const result = await withTimeout(entry.check.detect({ config, signal }), timeoutMs, entry.check.name);
97
+ entry.detectResult = result;
98
+ entry.runMs = Date.now() - start;
99
+ entry.status = resolveStatusFromDetect(entry.check, result);
100
+ entry.detail = result.detail;
101
+ // KJC-BUG-0049: si el check es degradable y falló (status FAIL/WARN tras
102
+ // resolveStatusFromDetect), aplicar disables al overrides y degradar a WARN.
103
+ // Así el preflight no aborta — la feature opcional se desactiva con aviso.
104
+ if (!result.ok && entry.check.degradable && (entry.status === STATUS.FAIL || entry.status === STATUS.WARN)) {
105
+ for (const dotPath of entry.check.degradable.disables || []) {
106
+ setDotPath(overrides, dotPath, false);
107
+ }
108
+ entry.status = STATUS.WARN;
109
+ entry.detail = `${result.detail} → ${entry.check.degradable.warn}`;
110
+ entry.degraded = true;
111
+ }
112
+ } catch (err) {
113
+ entry.runMs = Date.now() - start;
114
+ if (err instanceof TimeoutError) {
115
+ entry.detectResult = { ok: false, severity: "warn", detail: `Timeout after ${timeoutMs}ms` };
116
+ entry.status = STATUS.TIMEOUT;
117
+ entry.detail = entry.detectResult.detail;
118
+ } else {
119
+ entry.detectResult = { ok: false, severity: "fail", detail: `Detection error: ${err.message}` };
120
+ entry.status = STATUS.FAIL;
121
+ entry.detail = entry.detectResult.detail;
122
+ }
123
+ }
124
+ })
125
+ );
126
+ logger.info?.(`Detect phase done in ${Date.now() - detectBase}ms`);
127
+
128
+ // Phase 2: remediate sequentially (only in "fix" mode, only failing checks).
129
+ if (mode !== "check-only") {
130
+ for (const entry of entries) {
131
+ if (!shouldAttemptRemediation(entry)) continue;
132
+ const { check, detectResult } = entry;
133
+ if (check.strategy === STRATEGY.PROMPT && !yes) {
134
+ const approved = await onConfirm(check.describe || `Fix: ${check.name}`);
135
+ if (!approved) {
136
+ logger.info?.(`User declined remediation for ${check.name}`);
137
+ continue;
138
+ }
139
+ }
140
+ const start = Date.now();
141
+ try {
142
+ const rem = await withTimeout(
143
+ check.remediate({ config, extra: detectResult.extra, signal, logger }),
144
+ remediateTimeoutMs,
145
+ `${check.name}:remediate`
146
+ );
147
+ entry.remediated = rem.fixed === true;
148
+ entry.runMs += Date.now() - start;
149
+ if (rem.fixed) {
150
+ if (rem.changes) mergeOverrides(overrides, rem.changes);
151
+ entry.detail = rem.detail;
152
+ entry.status = STATUS.FIXED;
153
+ } else {
154
+ entry.detail = rem.detail || entry.detail;
155
+ entry.status = STATUS.FAIL;
156
+ }
157
+ } catch (err) {
158
+ entry.runMs += Date.now() - start;
159
+ const msg = err instanceof TimeoutError ? `Remediation timeout after ${remediateTimeoutMs}ms` : `Remediation error: ${err.message}`;
160
+ entry.detail = msg;
161
+ entry.status = STATUS.FAIL;
162
+ logger.warn?.(`Remediation failed for ${check.name}: ${msg}`);
163
+ }
164
+ }
165
+
166
+ // Phase 3: re-verify fixed checks using the config merged with any
167
+ // runtime overrides applied by remediations. Without this merge, a check
168
+ // that rebinds to a new port (override) would re-verify against the old
169
+ // config and wrongly report failure.
170
+ const verifyConfig = mergeConfigAndOverrides(config, overrides);
171
+ await Promise.all(
172
+ entries.filter((e) => e.remediated).map(async (entry) => {
173
+ const start = Date.now();
174
+ try {
175
+ const result = await withTimeout(entry.check.detect({ config: verifyConfig, signal }), timeoutMs, `${entry.check.name}:reverify`);
176
+ entry.runMs += Date.now() - start;
177
+ if (!result.ok) {
178
+ entry.status = STATUS.FAIL;
179
+ entry.detail = `${entry.detail} (but re-verify failed: ${result.detail})`;
180
+ }
181
+ } catch (err) {
182
+ entry.runMs += Date.now() - start;
183
+ entry.status = STATUS.FAIL;
184
+ entry.detail = `${entry.detail} (re-verify error: ${err.message})`;
185
+ }
186
+ })
187
+ );
188
+ }
189
+
190
+ // Flatten into reports.
191
+ const reports = entries.map((e) => ({
192
+ name: e.check.name,
193
+ label: e.check.label,
194
+ status: e.status,
195
+ strategy: e.check.strategy,
196
+ detail: e.detail ?? "",
197
+ fix: e.detectResult?.fix,
198
+ runMs: e.runMs,
199
+ // Forward optional structured metadata so the doctor printer can
200
+ // surface per-tool remediation tips (KJC-TSK v2.18). Undefined when
201
+ // the check didn't set one — kept minimal so JSON output stays tight.
202
+ extra: e.detectResult?.extra,
203
+ }));
204
+
205
+ const summary = summarize(reports);
206
+
207
+ return {
208
+ checks: reports,
209
+ overrides,
210
+ totalMs: Date.now() - startTotal,
211
+ summary,
212
+ };
213
+ }
214
+
215
+ function shouldAttemptRemediation(entry) {
216
+ if (entry.status === STATUS.SKIPPED) return false;
217
+ if (entry.status === STATUS.OK) return false;
218
+ if (entry.status === STATUS.TIMEOUT) return false; // don't remediate when detect itself timed out
219
+ const { check, detectResult } = entry;
220
+ if (!check.remediate || !detectResult) return false;
221
+ if (check.strategy === STRATEGY.MANUAL || check.strategy === STRATEGY.NONE) return false;
222
+ // Soft failures (WARN) with PROMPT strategy: don't nag the user for optional issues.
223
+ if (entry.status === STATUS.WARN && check.strategy === STRATEGY.PROMPT) return false;
224
+ return true;
225
+ }
226
+
227
+ function resolveStatusFromDetect(check, result) {
228
+ if (result.ok) return STATUS.OK;
229
+ const severity = result.severity || "fail";
230
+ if (severity === "warn") return STATUS.WARN;
231
+ if (severity === "info") return STATUS.OK; // info is always non-failing
232
+ if (check.strategy === STRATEGY.NONE) return STATUS.WARN;
233
+ return STATUS.FAIL;
234
+ }
235
+
236
+ function summarize(reports) {
237
+ const summary = { ok: 0, fixed: 0, warn: 0, fail: 0, skipped: 0, timeout: 0 };
238
+ for (const r of reports) {
239
+ const k = r.status.toLowerCase();
240
+ if (k in summary) summary[k]++;
241
+ }
242
+ return summary;
243
+ }
244
+
245
+ /**
246
+ * Set a dot-path on a target object, creating intermediate objects as needed.
247
+ * Used by the `degradable` check support (KJC-BUG-0049) to disable feature
248
+ * flags like `git.auto_pr` when their preflight check fails.
249
+ *
250
+ * @example setDotPath({}, "git.auto_pr", false) // → { git: { auto_pr: false } }
251
+ */
252
+ // KJC-BUG-0076: prototype-pollution guard. dot-paths come from check
253
+ // remediation outputs (internal but LLM-generated), so a malformed
254
+ // `__proto__.x` would mutate Object.prototype. Skip the whole write
255
+ // when any segment matches a forbidden key.
256
+ const UNSAFE_DOT_KEY_RE = /^(?:__proto__|constructor|prototype)$/;
257
+
258
+ function setDotPath(target, dotPath, value) {
259
+ const parts = String(dotPath).split(".");
260
+ if (parts.some((p) => UNSAFE_DOT_KEY_RE.test(p))) return;
261
+ let cursor = target;
262
+ for (let i = 0; i < parts.length - 1; i++) {
263
+ const k = parts[i];
264
+ if (cursor[k] == null || typeof cursor[k] !== "object") cursor[k] = {};
265
+ cursor = cursor[k];
266
+ }
267
+ cursor[parts.at(-1)] = value;
268
+ }
269
+
270
+ /**
271
+ * Deep-merge (shallow for now, one level deep) remediation changes into overrides.
272
+ * Remediation outputs like { hu_board: { port: 4007 } } should not overwrite a
273
+ * sibling key { hu_board: { enabled: true } } that a prior check set.
274
+ */
275
+ function mergeOverrides(target, source) {
276
+ for (const [key, value] of Object.entries(source)) {
277
+ if (value && typeof value === "object" && !Array.isArray(value) && typeof target[key] === "object") {
278
+ Object.assign(target[key], value);
279
+ } else {
280
+ target[key] = value;
281
+ }
282
+ }
283
+ }
284
+
285
+ /**
286
+ * Produce a shallow-merged copy of config + overrides used during re-verify.
287
+ * Does not mutate the original config.
288
+ */
289
+ function mergeConfigAndOverrides(config, overrides) {
290
+ if (!overrides || Object.keys(overrides).length === 0) return config;
291
+ const merged = { ...config };
292
+ for (const [key, value] of Object.entries(overrides)) {
293
+ if (value && typeof value === "object" && !Array.isArray(value) && typeof config[key] === "object") {
294
+ merged[key] = { ...config[key], ...value };
295
+ } else {
296
+ merged[key] = value;
297
+ }
298
+ }
299
+ return merged;
300
+ }
301
+
302
+ function defaultOnConfirm() {
303
+ // Non-interactive by default: refuse prompts unless the caller supplies a real handler.
304
+ return Promise.resolve(false);
305
+ }
306
+
307
+ function silentLogger() {
308
+ return { info() {}, warn() {}, error() {} };
309
+ }
310
+
311
+ /**
312
+ * Flatten a RunReport into the legacy doctor.js shape.
313
+ * OK/FIXED/SKIPPED → ok:true. WARN/FAIL/TIMEOUT → ok:false.
314
+ */
315
+ export function toLegacyShape(runReport) {
316
+ return runReport.checks.map((c) => ({
317
+ name: c.name,
318
+ label: c.label,
319
+ ok: c.status === STATUS.OK || c.status === STATUS.FIXED || c.status === STATUS.SKIPPED,
320
+ detail: c.detail,
321
+ fix: c.fix ?? null,
322
+ }));
323
+ }
324
+
325
+ // Exposed for prototype-pollution regression tests (KJC-BUG-0076).
326
+ export const __pollutionInternals = { setDotPath };
@@ -0,0 +1,53 @@
1
+ /**
2
+ * OpenSkills CLI availability check. Only runs when skills are enabled.
3
+ * Strategy: prompt — we can offer to run `npm install -g openskills`,
4
+ * but global installs are invasive enough that they need user consent.
5
+ */
6
+
7
+ import { isOpenSkillsAvailable } from "../skills/openskills-client.js";
8
+ import { runCommand } from "../utils/process.js";
9
+ import { STRATEGY } from "./types.js";
10
+
11
+ function skillsEnabled(config) {
12
+ return config?.skills?.enabled !== false;
13
+ }
14
+
15
+ /**
16
+ * @internal Exported for dynamic import from tests/checks/skills.test.js
17
+ * and tests/checks/auto-remediation-e2e.test.js. Knip false positive.
18
+ */
19
+ export function createOpenSkillsCheck() {
20
+ return {
21
+ name: "openskills",
22
+ label: "OpenSkills CLI",
23
+ strategy: STRATEGY.PROMPT,
24
+ applies: skillsEnabled,
25
+ describe: "Install OpenSkills globally: npm install -g openskills",
26
+ async detect() {
27
+ const available = await isOpenSkillsAvailable();
28
+ if (available) {
29
+ return { ok: true, severity: "info", detail: "Available via `npx openskills`" };
30
+ }
31
+ return {
32
+ ok: false,
33
+ severity: "warn", // skills enabled but missing → degrade gracefully
34
+ detail: "`npx openskills` not available — skill injection will be skipped",
35
+ fix: "Install OpenSkills: npm install -g openskills",
36
+ };
37
+ },
38
+ async remediate() {
39
+ const res = await runCommand("npm", ["install", "-g", "openskills"], { timeout: 60000 });
40
+ if (res.exitCode === 0) {
41
+ return { fixed: true, detail: "Installed openskills globally via npm" };
42
+ }
43
+ return {
44
+ fixed: false,
45
+ detail: `npm install -g openskills failed (exit ${res.exitCode}): ${res.stderr.split("\n")[0]}`,
46
+ };
47
+ },
48
+ };
49
+ }
50
+
51
+ export function getSkillsChecks() {
52
+ return [createOpenSkillsCheck()];
53
+ }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * SonarQube reachability + auth checks.
3
+ *
4
+ * Auto-remediation strategy (preserving existing behavior from
5
+ * preflight-checks.js): if Sonar is not reachable, try `sonarUp()` which
6
+ * starts the Docker container, then poll for readiness. If auth fails but
7
+ * admin credentials exist, generate a fresh token and persist it.
8
+ */
9
+
10
+ import { isSonarReachable } from "../sonar/manager.js";
11
+ import { STRATEGY } from "./types.js";
12
+ import { withDocLink } from "../utils/doc-links.js";
13
+
14
+ /**
15
+ * Whether Sonar is enabled in the active config.
16
+ */
17
+ function sonarEnabled(config) {
18
+ return config.sonarqube?.enabled !== false;
19
+ }
20
+
21
+ function sonarHost(config) {
22
+ return config.sonarqube?.host || "http://localhost:9000";
23
+ }
24
+
25
+ /**
26
+ * Informative check: Sonar enabled/disabled status.
27
+ * Produces an OK result with disabled description when Sonar is off.
28
+ */
29
+ function createSonarStatusCheck() {
30
+ return {
31
+ name: "sonarqube",
32
+ label: "SonarQube",
33
+ strategy: STRATEGY.NONE,
34
+ async detect({ config }) {
35
+ const host = sonarHost(config);
36
+ if (!sonarEnabled(config)) {
37
+ return { ok: true, severity: "info", detail: "Disabled in config" };
38
+ }
39
+ let reachable;
40
+ try {
41
+ reachable = await isSonarReachable(host);
42
+ } catch {
43
+ reachable = false;
44
+ }
45
+ return {
46
+ ok: reachable,
47
+ severity: "fail",
48
+ detail: reachable ? `Reachable at ${host}` : `Not reachable at ${host}`,
49
+ fix: reachable
50
+ ? undefined
51
+ : withDocLink(
52
+ "Run 'kj sonar start' or 'docker start karajan-sonarqube'. Use --no-sonar to skip.",
53
+ "sonar_docker"
54
+ ),
55
+ extra: { host, reachable },
56
+ };
57
+ },
58
+ };
59
+ }
60
+
61
+ /**
62
+ * All Sonar-related checks. Keeps just the status check for commit 1;
63
+ * auth + auto-remediation are layered in commit 3.
64
+ */
65
+ export function getSonarChecks() {
66
+ return [createSonarStatusCheck()];
67
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Squeezr availability check. Manual strategy — installation
3
+ * depends on the host platform and is handled by getInstallCommand().
4
+ */
5
+
6
+ import { runCommand } from "../utils/process.js";
7
+ import { getInstallCommand } from "../utils/os-detect.js";
8
+ import { withDocLink } from "../utils/doc-links.js";
9
+ import { STRATEGY } from "./types.js";
10
+
11
+ function createSqueezrCheck() {
12
+ return {
13
+ name: "squeezr",
14
+ label: "Squeezr",
15
+ strategy: STRATEGY.MANUAL,
16
+ async detect() {
17
+ try {
18
+ const res = await runCommand("squeezr", ["--version"]);
19
+ if (res.exitCode === 0) {
20
+ return { ok: true, severity: "info", detail: `${res.stdout.trim()} — context compression active` };
21
+ }
22
+ } catch { /* not installed */ }
23
+ const installCmd = getInstallCommand("squeezr");
24
+ return {
25
+ ok: false,
26
+ severity: "warn",
27
+ detail: "Not found — context compression via Squeezr available",
28
+ fix: withDocLink(`Install: ${installCmd}`, "squeezr_install"),
29
+ };
30
+ },
31
+ };
32
+ }
33
+
34
+ export function getSqueezrChecks() {
35
+ return [createSqueezrCheck()];
36
+ }