aiwcli 0.15.5 → 0.15.7

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 (299) hide show
  1. package/README.md +6 -3
  2. package/dist/capabilities/branch/adapters.d.ts +2 -0
  3. package/dist/capabilities/branch/adapters.js +21 -0
  4. package/dist/capabilities/branch/contracts.d.ts +57 -0
  5. package/dist/capabilities/branch/contracts.js +1 -0
  6. package/dist/capabilities/branch/control-plane.d.ts +2 -0
  7. package/dist/capabilities/branch/control-plane.js +343 -0
  8. package/dist/capabilities/branch/runtime-core.d.ts +5 -0
  9. package/dist/capabilities/branch/runtime-core.js +36 -0
  10. package/dist/capabilities/installation/control-plane/clean-command.d.ts +41 -0
  11. package/dist/capabilities/installation/control-plane/clean-command.js +196 -0
  12. package/dist/capabilities/installation/control-plane/clear-command.d.ts +160 -0
  13. package/dist/capabilities/installation/control-plane/clear-command.js +1220 -0
  14. package/dist/capabilities/installation/control-plane/init-command.d.ts +81 -0
  15. package/dist/capabilities/installation/control-plane/init-command.js +449 -0
  16. package/dist/capabilities/launch/contracts.d.ts +51 -0
  17. package/dist/capabilities/launch/contracts.js +1 -0
  18. package/dist/capabilities/launch/control-plane/execute-launch.d.ts +2 -0
  19. package/dist/capabilities/launch/control-plane/execute-launch.js +222 -0
  20. package/dist/capabilities/launch/runtime-core/launch-options.d.ts +14 -0
  21. package/dist/capabilities/launch/runtime-core/launch-options.js +69 -0
  22. package/dist/cli/base-command.d.ts +18 -0
  23. package/dist/cli/base-command.js +55 -0
  24. package/dist/commands/branch.d.ts +0 -20
  25. package/dist/commands/branch.js +24 -416
  26. package/dist/commands/clean.d.ts +1 -41
  27. package/dist/commands/clean.js +1 -196
  28. package/dist/commands/clear.d.ts +1 -161
  29. package/dist/commands/clear.js +1 -1121
  30. package/dist/commands/init/index.d.ts +1 -98
  31. package/dist/commands/init/index.js +4 -478
  32. package/dist/commands/launch.d.ts +36 -11
  33. package/dist/commands/launch.js +135 -159
  34. package/dist/lib/base-command.d.ts +1 -114
  35. package/dist/lib/base-command.js +1 -153
  36. package/dist/lib/claude-settings-types.d.ts +31 -19
  37. package/dist/lib/context/context-formatter.d.ts +74 -0
  38. package/dist/lib/context/context-formatter.js +493 -0
  39. package/dist/lib/context/context-selector.d.ts +42 -0
  40. package/dist/lib/context/context-selector.js +451 -0
  41. package/dist/lib/context/context-store.d.ts +100 -0
  42. package/dist/lib/context/context-store.js +618 -0
  43. package/dist/lib/context/plan-manager.d.ts +54 -0
  44. package/dist/lib/context/plan-manager.js +282 -0
  45. package/dist/lib/context/task-tracker.d.ts +44 -0
  46. package/dist/lib/context/task-tracker.js +146 -0
  47. package/dist/lib/core-ide-base.d.ts +4 -0
  48. package/dist/lib/core-ide-base.js +77 -0
  49. package/dist/lib/core-installer.d.ts +5 -0
  50. package/dist/lib/core-installer.js +54 -0
  51. package/dist/lib/git-exclude-manager.d.ts +2 -2
  52. package/dist/lib/git-exclude-manager.js +3 -3
  53. package/dist/lib/hooks/hook-utils.d.ts +143 -0
  54. package/dist/lib/hooks/hook-utils.js +609 -0
  55. package/dist/lib/hooks/session-end-logic.d.ts +5 -0
  56. package/dist/lib/hooks/session-end-logic.js +63 -0
  57. package/dist/lib/hooks-merger.js +25 -19
  58. package/dist/lib/ide-path-resolver.d.ts +19 -7
  59. package/dist/lib/ide-path-resolver.js +25 -9
  60. package/dist/lib/install-state.d.ts +34 -0
  61. package/dist/lib/install-state.js +161 -0
  62. package/dist/lib/launch-options.d.ts +1 -0
  63. package/dist/lib/launch-options.js +1 -0
  64. package/dist/lib/lsp-patch.d.ts +12 -0
  65. package/dist/lib/lsp-patch.js +156 -0
  66. package/dist/lib/multiplexer.d.ts +57 -0
  67. package/dist/lib/multiplexer.js +19 -0
  68. package/dist/lib/multiplexers/psmux.d.ts +75 -0
  69. package/dist/lib/multiplexers/psmux.js +384 -0
  70. package/dist/lib/multiplexers/tmux.d.ts +44 -0
  71. package/dist/lib/multiplexers/tmux.js +262 -0
  72. package/dist/lib/mux-utils.d.ts +5 -0
  73. package/dist/lib/mux-utils.js +42 -0
  74. package/dist/lib/paths.d.ts +2 -2
  75. package/dist/lib/paths.js +2 -2
  76. package/dist/lib/platform-commands.d.ts +27 -0
  77. package/dist/lib/platform-commands.js +49 -0
  78. package/dist/lib/runtime/aiw-cli.d.ts +37 -0
  79. package/dist/lib/runtime/aiw-cli.js +74 -0
  80. package/dist/lib/runtime/atomic-write.d.ts +19 -0
  81. package/dist/lib/runtime/atomic-write.js +121 -0
  82. package/dist/lib/runtime/cli-args.d.ts +55 -0
  83. package/dist/lib/runtime/cli-args.js +185 -0
  84. package/dist/lib/runtime/constants.d.ts +56 -0
  85. package/dist/lib/runtime/constants.js +230 -0
  86. package/dist/lib/runtime/executable-policy.d.ts +16 -0
  87. package/dist/lib/runtime/executable-policy.js +57 -0
  88. package/dist/lib/runtime/git-state.d.ts +9 -0
  89. package/dist/lib/runtime/git-state.js +59 -0
  90. package/dist/lib/runtime/inference.d.ts +37 -0
  91. package/dist/lib/runtime/inference.js +262 -0
  92. package/dist/lib/runtime/lint-dispatch.d.ts +40 -0
  93. package/dist/lib/runtime/lint-dispatch.js +285 -0
  94. package/dist/lib/runtime/logger.d.ts +66 -0
  95. package/dist/lib/runtime/logger.js +201 -0
  96. package/dist/lib/runtime/models.d.ts +14 -0
  97. package/dist/lib/runtime/models.js +14 -0
  98. package/dist/lib/runtime/platform-adapter.d.ts +7 -0
  99. package/dist/lib/runtime/platform-adapter.js +21 -0
  100. package/dist/lib/runtime/preflight.d.ts +24 -0
  101. package/dist/lib/runtime/preflight.js +65 -0
  102. package/dist/lib/runtime/sentinel-ipc.d.ts +14 -0
  103. package/dist/lib/runtime/sentinel-ipc.js +67 -0
  104. package/dist/lib/runtime/state-io.d.ts +30 -0
  105. package/dist/lib/runtime/state-io.js +174 -0
  106. package/dist/lib/runtime/stop-words.d.ts +20 -0
  107. package/dist/lib/runtime/stop-words.js +150 -0
  108. package/dist/lib/runtime/subprocess-utils.d.ts +29 -0
  109. package/dist/lib/runtime/subprocess-utils.js +96 -0
  110. package/dist/lib/runtime/tmux-preflight.d.ts +13 -0
  111. package/dist/lib/runtime/tmux-preflight.js +78 -0
  112. package/dist/lib/runtime/utils.d.ts +54 -0
  113. package/dist/lib/runtime/utils.js +162 -0
  114. package/dist/lib/sentinel-wrapper.d.ts +9 -0
  115. package/dist/lib/sentinel-wrapper.js +20 -0
  116. package/dist/lib/shell-quoting.d.ts +5 -0
  117. package/dist/lib/shell-quoting.js +17 -0
  118. package/dist/lib/spawn-errors.d.ts +6 -0
  119. package/dist/lib/spawn-errors.js +15 -0
  120. package/dist/lib/spawn.js +5 -11
  121. package/dist/lib/template-installer.d.ts +4 -5
  122. package/dist/lib/template-installer.js +36 -34
  123. package/dist/lib/template-resolver.d.ts +6 -7
  124. package/dist/lib/template-resolver.js +26 -21
  125. package/dist/lib/template-settings-reconstructor.d.ts +7 -2
  126. package/dist/lib/template-settings-reconstructor.js +76 -45
  127. package/dist/lib/terminal-strategy.d.ts +11 -0
  128. package/dist/lib/terminal-strategy.js +49 -0
  129. package/dist/lib/terminal.d.ts +28 -0
  130. package/dist/lib/terminal.js +162 -112
  131. package/dist/lib/tmux-pane-placement.d.ts +17 -0
  132. package/dist/lib/tmux-pane-placement.js +58 -0
  133. package/dist/lib/tmux-primitives.d.ts +5 -0
  134. package/dist/lib/tmux-primitives.js +15 -0
  135. package/dist/lib/tmux-session.d.ts +32 -0
  136. package/dist/lib/tmux-session.js +86 -0
  137. package/dist/lib/tty-detection.js +1 -1
  138. package/dist/lib/types.d.ts +168 -0
  139. package/dist/lib/types.js +6 -0
  140. package/dist/lib/version.d.ts +1 -1
  141. package/dist/lib/version.js +1 -1
  142. package/dist/platform/launch.d.ts +10 -0
  143. package/dist/platform/launch.js +10 -0
  144. package/dist/templates/CLAUDE.md +31 -40
  145. package/dist/templates/cc-native/.claude/settings.json +27 -27
  146. package/dist/templates/cc-native/CC-NATIVE-README.md +1 -1
  147. package/dist/templates/cc-native/TEMPLATE-SCHEMA.md +10 -9
  148. package/dist/templates/cc-native/_cc-native/CLAUDE.md +18 -18
  149. package/dist/templates/cc-native/_cc-native/artifacts/CLAUDE.md +3 -3
  150. package/dist/templates/cc-native/_cc-native/artifacts/lib/format.ts +14 -14
  151. package/dist/templates/cc-native/_cc-native/artifacts/lib/tracker.ts +1 -1
  152. package/dist/templates/cc-native/_cc-native/artifacts/lib/write.ts +3 -3
  153. package/dist/templates/cc-native/_cc-native/cc-native.config.json +3 -3
  154. package/dist/templates/cc-native/_cc-native/hooks/CLAUDE.md +16 -15
  155. package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.ts +3 -3
  156. package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_subagent.ts +2 -2
  157. package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_write.ts +2 -2
  158. package/dist/templates/cc-native/_cc-native/hooks/mark_questions_asked.ts +3 -3
  159. package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.ts +2 -2
  160. package/dist/templates/cc-native/_cc-native/hooks/validate_task_prompt.ts +3 -3
  161. package/dist/templates/cc-native/_cc-native/lib-ts/CLAUDE.md +8 -8
  162. package/dist/templates/cc-native/_cc-native/lib-ts/aggregate-agents.ts +1 -1
  163. package/dist/templates/cc-native/_cc-native/lib-ts/cc-native-state.ts +4 -4
  164. package/dist/templates/cc-native/_cc-native/lib-ts/cli-output-parser.ts +1 -1
  165. package/dist/templates/cc-native/_cc-native/lib-ts/config.ts +1 -1
  166. package/dist/templates/cc-native/_cc-native/lib-ts/debug.ts +1 -1
  167. package/dist/templates/cc-native/_cc-native/lib-ts/json-parser.ts +1 -1
  168. package/dist/templates/cc-native/_cc-native/lib-ts/plan-discovery.ts +2 -2
  169. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/logger.ts +1 -1
  170. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/retrieval-pipeline.ts +2 -2
  171. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/types.ts +1 -1
  172. package/dist/templates/cc-native/_cc-native/lib-ts/settings.ts +8 -8
  173. package/dist/templates/cc-native/_cc-native/lib-ts/state.ts +3 -3
  174. package/dist/templates/cc-native/_cc-native/lib-ts/tsconfig.json +2 -2
  175. package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +3 -3
  176. package/dist/templates/cc-native/_cc-native/plan-review/CLAUDE.md +3 -1
  177. package/dist/templates/cc-native/_cc-native/plan-review/lib/__tests__/agent-selection.test.ts +345 -0
  178. package/dist/templates/cc-native/_cc-native/plan-review/lib/__tests__/preflight.test.ts +344 -0
  179. package/dist/templates/cc-native/_cc-native/plan-review/lib/agent-selection.ts +37 -15
  180. package/dist/templates/cc-native/_cc-native/plan-review/lib/corroboration.ts +16 -69
  181. package/dist/templates/cc-native/_cc-native/plan-review/lib/orchestrator.ts +1 -1
  182. package/dist/templates/cc-native/_cc-native/plan-review/lib/output-builder.ts +1 -1
  183. package/dist/templates/cc-native/_cc-native/plan-review/lib/plan-questions.ts +2 -2
  184. package/dist/templates/cc-native/_cc-native/plan-review/lib/preflight.ts +56 -26
  185. package/dist/templates/cc-native/_cc-native/plan-review/lib/review-pipeline.ts +7 -7
  186. package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/agent.ts +4 -4
  187. package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/base/base-agent.ts +3 -3
  188. package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/index.ts +1 -1
  189. package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/providers/claude-agent.ts +2 -2
  190. package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/providers/codex-agent.ts +4 -4
  191. package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/providers/gemini-agent.ts +1 -1
  192. package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/providers/orchestrator-claude-agent.ts +5 -6
  193. package/dist/templates/core/.codex/workflows/codex.md +17 -0
  194. package/dist/templates/core/.codex/workflows/handoff.md +5 -0
  195. package/dist/templates/core/.codex/workflows/meta-plan.md +7 -0
  196. package/dist/templates/core/.cognition/AGENTS.md +5 -0
  197. package/dist/templates/core/.cognition/config.json +12 -0
  198. package/dist/templates/{_shared → core}/.windsurf/workflows/handoff.md +1 -1
  199. package/dist/templates/{_shared → core}/.windsurf/workflows/meta-plan.md +1 -1
  200. package/dist/templates/core/hooks-ts/_utils/git-state.ts +2 -0
  201. package/dist/templates/{_shared → core}/hooks-ts/archive_plan.ts +14 -23
  202. package/dist/templates/core/hooks-ts/codex_explorer.ts +160 -0
  203. package/dist/templates/{_shared → core}/hooks-ts/context_monitor.ts +23 -55
  204. package/dist/templates/{_shared → core}/hooks-ts/file-suggestion.ts +4 -3
  205. package/dist/templates/{_shared → core}/hooks-ts/lint_after_edit.ts +7 -9
  206. package/dist/templates/{_shared → core}/hooks-ts/pre_compact.ts +5 -5
  207. package/dist/templates/{_shared → core}/hooks-ts/session_end.ts +38 -78
  208. package/dist/templates/{_shared → core}/hooks-ts/session_start.ts +5 -5
  209. package/dist/templates/core/hooks-ts/task_create_capture.ts +32 -0
  210. package/dist/templates/{_shared → core}/hooks-ts/task_update_capture.ts +9 -24
  211. package/dist/templates/core/hooks-ts/user_prompt_submit.ts +46 -0
  212. package/dist/templates/{_shared → core}/lib-ts/CLAUDE.md +27 -16
  213. package/dist/templates/{_shared → core}/lib-ts/agent-exec/backends/headless.ts +3 -2
  214. package/dist/templates/{_shared → core}/lib-ts/agent-exec/backends/tmux.ts +44 -15
  215. package/dist/templates/{_shared → core}/lib-ts/agent-exec/base-agent.ts +6 -4
  216. package/dist/templates/{_shared → core}/lib-ts/agent-exec/execution-backend.ts +1 -1
  217. package/dist/templates/{_shared → core}/lib-ts/agent-exec/index.ts +2 -2
  218. package/dist/templates/{_shared → core}/lib-ts/agent-exec/structured-output.ts +4 -5
  219. package/dist/templates/{_shared → core}/lib-ts/context/CLAUDE.md +9 -6
  220. package/dist/templates/{_shared → core}/lib-ts/context/context-formatter.ts +16 -21
  221. package/dist/templates/{_shared → core}/lib-ts/context/context-selector.ts +8 -6
  222. package/dist/templates/{_shared → core}/lib-ts/context/context-store.ts +32 -20
  223. package/dist/templates/{_shared → core}/lib-ts/context/plan-manager.ts +19 -15
  224. package/dist/templates/{_shared → core}/lib-ts/context/task-tracker.ts +3 -3
  225. package/dist/templates/core/lib-ts/hooks/context-monitor-logic.ts +32 -0
  226. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/hooks}/hook-utils.ts +168 -41
  227. package/dist/templates/core/lib-ts/hooks/prompt-binding-logic.ts +80 -0
  228. package/dist/templates/core/lib-ts/hooks/session-end-logic.ts +93 -0
  229. package/dist/templates/core/lib-ts/package.json +19 -0
  230. package/dist/templates/core/lib-ts/runtime/agent-launcher.ts +295 -0
  231. package/dist/templates/core/lib-ts/runtime/aiw-cli.ts +106 -0
  232. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/atomic-write.ts +12 -7
  233. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/cli-args.ts +8 -6
  234. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/constants.ts +326 -324
  235. package/dist/templates/core/lib-ts/runtime/executable-policy.ts +89 -0
  236. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/git-state.ts +6 -4
  237. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/inference.ts +59 -10
  238. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/lint-dispatch.ts +25 -23
  239. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/logger.ts +32 -29
  240. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/models.ts +2 -2
  241. package/dist/templates/core/lib-ts/runtime/platform-adapter.ts +33 -0
  242. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/preflight.ts +4 -3
  243. package/dist/templates/core/lib-ts/runtime/sentinel-ipc.ts +91 -0
  244. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/state-io.ts +11 -7
  245. package/dist/templates/core/lib-ts/runtime/stop-words.ts +185 -0
  246. package/dist/templates/core/lib-ts/runtime/subprocess-utils.ts +147 -0
  247. package/dist/templates/core/lib-ts/runtime/tmux-preflight.ts +93 -0
  248. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/utils.ts +4 -3
  249. package/dist/templates/{_shared → core}/lib-ts/templates/formatters.ts +7 -5
  250. package/dist/templates/{_shared → core}/lib-ts/templates/plan-context.ts +2 -1
  251. package/dist/templates/{_shared → core}/lib-ts/tsconfig.json +3 -1
  252. package/dist/templates/{_shared → core}/lib-ts/types.ts +78 -77
  253. package/dist/templates/core/scripts/resolve-run.ts +61 -0
  254. package/dist/templates/{_shared → core}/scripts/resolve_context.ts +3 -3
  255. package/dist/templates/{_shared → core}/scripts/status_line.ts +25 -20
  256. package/dist/templates/core/skills/codex/CLAUDE.md +78 -0
  257. package/dist/templates/{_shared → core}/skills/codex/SKILL.md +21 -18
  258. package/dist/templates/{_shared → core}/skills/codex/lib/codex-watcher.ts +76 -103
  259. package/dist/templates/{_shared → core}/skills/codex/scripts/launch-codex.ts +119 -133
  260. package/dist/templates/{_shared → core}/skills/codex/scripts/watch-codex.ts +6 -4
  261. package/dist/templates/core/skills/devin/CLAUDE.md +65 -0
  262. package/dist/templates/core/skills/devin/SKILL.md +73 -0
  263. package/dist/templates/core/skills/devin/lib/devin-watcher.ts +280 -0
  264. package/dist/templates/core/skills/devin/scripts/launch-devin.ts +257 -0
  265. package/dist/templates/{_shared → core}/skills/handoff-system/CLAUDE.md +436 -433
  266. package/dist/templates/{_shared → core}/skills/handoff-system/lib/document-generator.ts +9 -7
  267. package/dist/templates/{_shared → core}/skills/handoff-system/lib/handoff-reader.ts +6 -4
  268. package/dist/templates/{_shared → core}/skills/handoff-system/scripts/resume_handoff.ts +10 -8
  269. package/dist/templates/{_shared → core}/skills/handoff-system/scripts/save_handoff.ts +12 -10
  270. package/dist/templates/{_shared → core}/skills/handoff-system/workflows/handoff-resume.md +2 -2
  271. package/dist/templates/{_shared → core}/skills/handoff-system/workflows/handoff.md +6 -5
  272. package/dist/templates/{_shared → core}/skills/meta-plan/CLAUDE.md +2 -1
  273. package/dist/templates/{_shared → core}/skills/meta-plan/workflows/meta-plan.md +8 -7
  274. package/oclif.manifest.json +89 -13
  275. package/package.json +13 -12
  276. package/dist/templates/_shared/.claude/settings.json +0 -120
  277. package/dist/templates/_shared/.claude/skills/codex/SKILL.md +0 -35
  278. package/dist/templates/_shared/.claude/skills/handoff/SKILL.md +0 -13
  279. package/dist/templates/_shared/.claude/skills/handoff-resume/SKILL.md +0 -13
  280. package/dist/templates/_shared/.claude/skills/meta-plan/SKILL.md +0 -43
  281. package/dist/templates/_shared/.codex/workflows/codex.md +0 -11
  282. package/dist/templates/_shared/.codex/workflows/handoff.md +0 -226
  283. package/dist/templates/_shared/.codex/workflows/meta-plan.md +0 -347
  284. package/dist/templates/_shared/hooks-ts/_utils/git-state.ts +0 -2
  285. package/dist/templates/_shared/hooks-ts/task_create_capture.ts +0 -48
  286. package/dist/templates/_shared/hooks-ts/user_prompt_submit.ts +0 -93
  287. package/dist/templates/_shared/lib-ts/base/launchers/tmux-launcher.ts +0 -173
  288. package/dist/templates/_shared/lib-ts/base/launchers/window-launcher.ts +0 -93
  289. package/dist/templates/_shared/lib-ts/base/launchers/wt-launcher.ts +0 -64
  290. package/dist/templates/_shared/lib-ts/base/pane-launcher.ts +0 -55
  291. package/dist/templates/_shared/lib-ts/base/sentinel-ipc.ts +0 -87
  292. package/dist/templates/_shared/lib-ts/base/stop-words.ts +0 -184
  293. package/dist/templates/_shared/lib-ts/base/subprocess-utils.ts +0 -249
  294. package/dist/templates/_shared/lib-ts/base/tmux-driver.ts +0 -341
  295. package/dist/templates/_shared/lib-ts/base/tmux-pane-placement.ts +0 -78
  296. package/dist/templates/_shared/lib-ts/package.json +0 -20
  297. package/dist/templates/_shared/scripts/resolve-run.ts +0 -62
  298. package/dist/templates/_shared/skills/codex/CLAUDE.md +0 -70
  299. /package/dist/templates/{_shared → core}/lib-ts/agent-exec/backends/index.ts +0 -0
@@ -0,0 +1,344 @@
1
+ /**
2
+ * Tests for preflight health checks.
3
+ * Tests pure functions (collectPreflightChecks, buildPreflightReport) directly.
4
+ * Tests classifyError from shared preflight module directly.
5
+ * Slim integration tests for runPreflight mock only checkProviderModel (network boundary).
6
+ */
7
+
8
+ import { describe, it, expect, mock, beforeEach } from "bun:test";
9
+
10
+ import type { ModelsConfig, PreflightCheckResult, PreflightReport } from "../../../lib-ts/types.js";
11
+
12
+ // ---------------------------------------------------------------------------
13
+ // Mock logger for noise suppression only (no assertions on logger calls)
14
+ // ---------------------------------------------------------------------------
15
+
16
+ mock.module("../../../../_core/lib-ts/runtime/logger.js", () => ({
17
+ hookLog() {},
18
+ logDebug() {},
19
+ logInfo() {},
20
+ logWarn() {},
21
+ logError() {},
22
+ logBlocking() {},
23
+ logDiagnostic() {},
24
+ logHookError() {},
25
+ setSessionId() {},
26
+ setContextPath() {},
27
+ getContextPath: () => null,
28
+ }));
29
+
30
+ // ---------------------------------------------------------------------------
31
+ // Import pure functions under test (no mocks needed)
32
+ // ---------------------------------------------------------------------------
33
+
34
+ const { collectPreflightChecks, buildPreflightReport } = await import("../preflight.js");
35
+ const { classifyError } = await import("../../../../_core/lib-ts/runtime/preflight.js");
36
+
37
+ // ---------------------------------------------------------------------------
38
+ // Helpers
39
+ // ---------------------------------------------------------------------------
40
+
41
+ function makeModelsConfig(providers: Record<string, { enabled: boolean; models: string[] }>): ModelsConfig {
42
+ return { providers };
43
+ }
44
+
45
+ // ---------------------------------------------------------------------------
46
+ // collectPreflightChecks — pure, zero mocks
47
+ // ---------------------------------------------------------------------------
48
+
49
+ describe("preflight", () => {
50
+ describe("collectPreflightChecks", () => {
51
+ const knownProviders = new Set(["claude", "codex"]);
52
+
53
+ it("collects enabled providers with known names", () => {
54
+ const config = makeModelsConfig({
55
+ claude: { enabled: true, models: ["sonnet"] },
56
+ codex: { enabled: true, models: ["codex-mini-latest"] },
57
+ });
58
+
59
+ const { checks, skippedProviders } = collectPreflightChecks(config, knownProviders);
60
+
61
+ expect(checks).toEqual([
62
+ { provider: "claude", model: "sonnet" },
63
+ { provider: "codex", model: "codex-mini-latest" },
64
+ ]);
65
+ expect(skippedProviders).toEqual([]);
66
+ });
67
+
68
+ it("skips disabled providers", () => {
69
+ const config = makeModelsConfig({
70
+ claude: { enabled: false, models: ["sonnet"] },
71
+ codex: { enabled: true, models: ["codex-mini-latest"] },
72
+ });
73
+
74
+ const { checks } = collectPreflightChecks(config, knownProviders);
75
+
76
+ expect(checks).toEqual([{ provider: "codex", model: "codex-mini-latest" }]);
77
+ });
78
+
79
+ it("skips providers with empty model lists", () => {
80
+ const config = makeModelsConfig({
81
+ claude: { enabled: true, models: [] },
82
+ });
83
+
84
+ const { checks } = collectPreflightChecks(config, knownProviders);
85
+
86
+ expect(checks).toEqual([]);
87
+ });
88
+
89
+ it("reports unknown providers in skippedProviders", () => {
90
+ const config = makeModelsConfig({
91
+ unknown_provider: { enabled: true, models: ["some-model"] },
92
+ });
93
+
94
+ const { checks, skippedProviders } = collectPreflightChecks(config, knownProviders);
95
+
96
+ expect(checks).toEqual([]);
97
+ expect(skippedProviders).toEqual(["unknown_provider"]);
98
+ });
99
+
100
+ it("deduplicates same provider:model combo", () => {
101
+ const config = makeModelsConfig({
102
+ claude: { enabled: true, models: ["sonnet", "sonnet"] },
103
+ });
104
+
105
+ const { checks } = collectPreflightChecks(config, knownProviders);
106
+
107
+ expect(checks).toEqual([{ provider: "claude", model: "sonnet" }]);
108
+ });
109
+
110
+ it("collects multiple models per provider", () => {
111
+ const config = makeModelsConfig({
112
+ claude: { enabled: true, models: ["sonnet", "opus"] },
113
+ });
114
+
115
+ const { checks } = collectPreflightChecks(config, knownProviders);
116
+
117
+ expect(checks).toEqual([
118
+ { provider: "claude", model: "sonnet" },
119
+ { provider: "claude", model: "opus" },
120
+ ]);
121
+ });
122
+
123
+ it("returns empty checks when no providers are enabled", () => {
124
+ const config = makeModelsConfig({
125
+ claude: { enabled: false, models: ["sonnet"] },
126
+ });
127
+
128
+ const { checks, skippedProviders } = collectPreflightChecks(config, knownProviders);
129
+
130
+ expect(checks).toEqual([]);
131
+ expect(skippedProviders).toEqual([]);
132
+ });
133
+ });
134
+
135
+ // ---------------------------------------------------------------------------
136
+ // buildPreflightReport — pure, zero mocks
137
+ // ---------------------------------------------------------------------------
138
+
139
+ describe("buildPreflightReport", () => {
140
+ it("builds available map from passing results", () => {
141
+ const results = [
142
+ { provider: "claude", model: "sonnet", available: true, latencyMs: 50 },
143
+ { provider: "codex", model: "codex-mini-latest", available: true, latencyMs: 30 },
144
+ ];
145
+
146
+ const report = buildPreflightReport(results, 100);
147
+
148
+ expect(report.allFailed).toBe(false);
149
+ expect(report.available.size).toBe(2);
150
+ expect(report.available.get("claude")?.has("sonnet")).toBe(true);
151
+ expect(report.available.get("codex")?.has("codex-mini-latest")).toBe(true);
152
+ expect(report.totalMs).toBe(100);
153
+ });
154
+
155
+ it("reports allFailed when all results fail", () => {
156
+ const results = [
157
+ { provider: "claude", model: "sonnet", available: false, error: "Auth failed", latencyMs: 10 },
158
+ { provider: "codex", model: "codex-mini", available: false, error: "Timeout", latencyMs: 15_000 },
159
+ ];
160
+
161
+ const report = buildPreflightReport(results, 15_000);
162
+
163
+ expect(report.allFailed).toBe(true);
164
+ expect(report.available.size).toBe(0);
165
+ });
166
+
167
+ it("reports allFailed=true for empty results", () => {
168
+ const report = buildPreflightReport([], 5);
169
+
170
+ expect(report.allFailed).toBe(true);
171
+ expect(report.available.size).toBe(0);
172
+ expect(report.checks).toEqual([]);
173
+ });
174
+
175
+ it("groups multiple models under same provider", () => {
176
+ const results = [
177
+ { provider: "claude", model: "sonnet", available: true, latencyMs: 50 },
178
+ { provider: "claude", model: "opus", available: true, latencyMs: 80 },
179
+ ];
180
+
181
+ const report = buildPreflightReport(results, 80);
182
+
183
+ expect(report.available.get("claude")?.size).toBe(2);
184
+ expect(report.available.get("claude")?.has("sonnet")).toBe(true);
185
+ expect(report.available.get("claude")?.has("opus")).toBe(true);
186
+ });
187
+
188
+ it("excludes failed models from available map", () => {
189
+ const results = [
190
+ { provider: "claude", model: "sonnet", available: true, latencyMs: 50 },
191
+ { provider: "claude", model: "opus", available: false, error: "Rate limited", latencyMs: 10 },
192
+ ];
193
+
194
+ const report = buildPreflightReport(results, 50);
195
+
196
+ expect(report.allFailed).toBe(false);
197
+ expect(report.available.get("claude")?.has("sonnet")).toBe(true);
198
+ expect(report.available.get("claude")?.has("opus")).toBe(false);
199
+ });
200
+
201
+ it("preserves check results in output", () => {
202
+ const results = [
203
+ { provider: "claude", model: "sonnet", available: true, latencyMs: 42 },
204
+ ];
205
+
206
+ const report = buildPreflightReport(results, 42);
207
+
208
+ expect(report.checks.length).toBe(1);
209
+ expect(report.checks[0]!.provider).toBe("claude");
210
+ expect(report.checks[0]!.model).toBe("sonnet");
211
+ expect(report.checks[0]!.available).toBe(true);
212
+ expect(report.checks[0]!.latencyMs).toBe(42);
213
+ });
214
+ });
215
+
216
+ // ---------------------------------------------------------------------------
217
+ // classifyError — pure, zero mocks (from shared _core/lib-ts/runtime/preflight.ts)
218
+ // ---------------------------------------------------------------------------
219
+
220
+ describe("classifyError", () => {
221
+ it("classifies timeout (killed + SIGTERM)", () => {
222
+ expect(classifyError("", null, true, "SIGTERM")).toBe("Preflight timed out");
223
+ });
224
+
225
+ it("classifies timeout (killed without signal)", () => {
226
+ expect(classifyError("", null, true, null)).toBe("Preflight timed out");
227
+ });
228
+
229
+ it("classifies model not found", () => {
230
+ expect(classifyError("model not found", 1, false, null)).toBe("Model not available for this account");
231
+ });
232
+
233
+ it("classifies not available", () => {
234
+ expect(classifyError("not available for your plan", 1, false, null)).toBe("Model not available for this account");
235
+ });
236
+
237
+ it("classifies rate limit by text", () => {
238
+ expect(classifyError("rate limit exceeded", 1, false, null)).toBe("Rate limited");
239
+ });
240
+
241
+ it("classifies rate limit by 429", () => {
242
+ expect(classifyError("error 429", 1, false, null)).toBe("Rate limited");
243
+ });
244
+
245
+ it("classifies auth errors", () => {
246
+ expect(classifyError("invalid api key", 1, false, null)).toBe("Authentication failed");
247
+ });
248
+
249
+ it("classifies 401 as auth", () => {
250
+ expect(classifyError("HTTP 401 Unauthorized", 1, false, null)).toBe("Authentication failed");
251
+ });
252
+
253
+ it("classifies quota errors", () => {
254
+ expect(classifyError("billing quota exceeded", 1, false, null)).toBe("Quota/billing issue");
255
+ });
256
+
257
+ it("falls back to exit code for unknown errors", () => {
258
+ expect(classifyError("something unexpected", 42, false, null)).toBe("Exit code 42");
259
+ });
260
+ });
261
+
262
+ // ---------------------------------------------------------------------------
263
+ // runPreflight — slim integration (mock only checkProviderModel)
264
+ // ---------------------------------------------------------------------------
265
+
266
+ describe("runPreflight", () => {
267
+ // Mock the network boundary: checkProviderModel and subprocess-utils
268
+ const mockCheckProviderModel = mock(
269
+ async (provider: string, model: string) =>
270
+ ({ provider, model, available: true, latencyMs: 10 }) as PreflightCheckResult,
271
+ );
272
+
273
+ const mockFindExecutable = mock(() => "/usr/bin/mock-cli" as string | null);
274
+
275
+ // Re-mock the modules to inject our mock for integration tests
276
+ mock.module("../../../../_core/lib-ts/runtime/preflight.js", () => ({
277
+ checkProviderModel: mockCheckProviderModel,
278
+ classifyError,
279
+ }));
280
+
281
+ mock.module("../../../../_core/lib-ts/runtime/subprocess-utils.js", () => ({
282
+ findExecutable: mockFindExecutable,
283
+ execFileAsync: mock(() => Promise.resolve({ stdout: "ok", stderr: "", exitCode: 0, killed: false, signal: null })),
284
+ isInternalCall: () => false,
285
+ getInternalSubprocessEnv: () => ({}),
286
+ normalizePathForCli: (p: string) => p,
287
+ shellQuoteWin: (arg: string) => arg,
288
+ isExecSyncError: () => false,
289
+ }));
290
+
291
+ // Re-import to pick up the mocked checkProviderModel
292
+ let runPreflight: (config: ModelsConfig, timeoutMs?: number) => Promise<PreflightReport>;
293
+
294
+ beforeEach(async () => {
295
+ mockCheckProviderModel.mockReset();
296
+ mockCheckProviderModel.mockImplementation(
297
+ async (provider: string, model: string) =>
298
+ ({ provider, model, available: true, latencyMs: 10 }) as PreflightCheckResult,
299
+ );
300
+ // Force fresh import to pick up mocks
301
+ const mod = await import("../preflight.js");
302
+ runPreflight = mod.runPreflight;
303
+ });
304
+
305
+ it("returns available report when checks pass", async () => {
306
+ const config = makeModelsConfig({
307
+ claude: { enabled: true, models: ["sonnet"] },
308
+ codex: { enabled: true, models: ["codex-mini-latest"] },
309
+ });
310
+
311
+ const report = await runPreflight(config);
312
+
313
+ expect(report.allFailed).toBe(false);
314
+ expect(report.available.size).toBe(2);
315
+ });
316
+
317
+ it("reports allFailed when all checks fail", async () => {
318
+ mockCheckProviderModel.mockImplementation(
319
+ async (provider: string, model: string) =>
320
+ ({ provider, model, available: false, latencyMs: 10, error: "Auth failed" }) as PreflightCheckResult,
321
+ );
322
+
323
+ const config = makeModelsConfig({
324
+ claude: { enabled: true, models: ["sonnet"] },
325
+ });
326
+
327
+ const report = await runPreflight(config);
328
+
329
+ expect(report.allFailed).toBe(true);
330
+ expect(report.available.size).toBe(0);
331
+ });
332
+
333
+ it("returns empty checks when no providers enabled", async () => {
334
+ const config = makeModelsConfig({
335
+ claude: { enabled: false, models: ["sonnet"] },
336
+ });
337
+
338
+ const report = await runPreflight(config);
339
+
340
+ expect(report.allFailed).toBe(true);
341
+ expect(report.checks.length).toBe(0);
342
+ });
343
+ });
344
+ });
@@ -3,8 +3,8 @@
3
3
  * Extracted from cc-native-plan-review.ts.
4
4
  */
5
5
 
6
- import { logDebug, logInfo, logWarn } from "../../../_shared/lib-ts/base/logger.js";
7
- import { findExecutable } from "../../../_shared/lib-ts/base/subprocess-utils.js";
6
+ import { logDebug, logInfo, logWarn } from "../../../_core/lib-ts/runtime/logger.js";
7
+ import { findExecutable } from "../../../_core/lib-ts/runtime/subprocess-utils.js";
8
8
  import type {
9
9
  AgentConfig,
10
10
  AgentReviewSettings,
@@ -51,22 +51,21 @@ export function resolveMandatoryAgents(
51
51
  /** Provider priority order: codex first (cheaper/faster), claude as fallback */
52
52
  const PROVIDER_PRIORITY = ["codex", "claude"];
53
53
 
54
- /**
55
- * Assign providers and models to agents.
56
- * When preflightAvailable is provided, filters to only models that passed preflight.
57
- * Providers are ordered by PROVIDER_PRIORITY (codex first, claude fallback).
58
- * All agents get the first available provider; random model within that provider.
59
- */
60
- export function assignModelsToAgents(
61
- agents: AgentConfig[],
54
+ // ---------------------------------------------------------------------------
55
+ // Pure Provider Resolution (extracted for direct testing)
56
+ // ---------------------------------------------------------------------------
57
+
58
+ /** @internal */
59
+ export function resolveEnabledProviders(
62
60
  modelsConfig: ModelsConfig,
61
+ isCliAvailable: (cliName: string) => boolean,
63
62
  preflightAvailable?: Map<string, Set<string>>,
64
- ): AgentConfig[] {
65
- let enabledProviders = Object.entries(modelsConfig.providers)
63
+ ): Array<[string, { enabled: boolean; models: string[] }]> {
64
+ const result = Object.entries(modelsConfig.providers)
66
65
  .filter(([name, config]) => {
67
66
  if (!config.enabled || config.models.length === 0) return false;
68
67
  const cliName = name === "claude" ? "claude" : name;
69
- const found = findExecutable(cliName);
68
+ const found = isCliAvailable(cliName);
70
69
  if (!found) {
71
70
  logWarn(HOOK, `Provider '${name}' enabled but CLI '${cliName}' not found on PATH — skipping`);
72
71
  return false;
@@ -93,12 +92,35 @@ export function assignModelsToAgents(
93
92
  .filter((entry): entry is [string, { enabled: boolean; models: string[] }] => entry !== null);
94
93
 
95
94
  // Sort by provider priority (codex first)
96
- enabledProviders.sort((a, b) => {
95
+ result.sort((a, b) => {
97
96
  const aIdx = PROVIDER_PRIORITY.indexOf(a[0]);
98
97
  const bIdx = PROVIDER_PRIORITY.indexOf(b[0]);
99
98
  return (aIdx === -1 ? 999 : aIdx) - (bIdx === -1 ? 999 : bIdx);
100
99
  });
101
100
 
101
+ return result;
102
+ }
103
+
104
+ /**
105
+ * Assign providers and models to agents.
106
+ * When preflightAvailable is provided, filters to only models that passed preflight.
107
+ * Providers are ordered by PROVIDER_PRIORITY (codex first, claude fallback).
108
+ * All agents get the first available provider; random model within that provider.
109
+ */
110
+ export function assignModelsToAgents(
111
+ agents: AgentConfig[],
112
+ modelsConfig: ModelsConfig,
113
+ preflightAvailable?: Map<string, Set<string>>,
114
+ options?: {
115
+ isCliAvailable?: (name: string) => boolean;
116
+ randomFn?: () => number;
117
+ },
118
+ ): AgentConfig[] {
119
+ const isCliAvailable = options?.isCliAvailable ?? ((name: string) => Boolean(findExecutable(name)));
120
+ const randomFn = options?.randomFn ?? Math.random;
121
+
122
+ const enabledProviders = resolveEnabledProviders(modelsConfig, isCliAvailable, preflightAvailable);
123
+
102
124
  if (enabledProviders.length === 0) {
103
125
  logWarn(HOOK, "No providers with available CLI found, falling back to Claude with agent defaults");
104
126
  return agents.map(a => ({ ...a, provider: "claude" }));
@@ -109,7 +131,7 @@ export function assignModelsToAgents(
109
131
  logInfo(HOOK, `Using provider: ${providerName} (models: ${providerConfig.models.join(", ")})`);
110
132
 
111
133
  return agents.map(agent => {
112
- const modelIdx = Math.floor(Math.random() * providerConfig.models.length);
134
+ const modelIdx = Math.floor(randomFn() * providerConfig.models.length);
113
135
  const model = providerConfig.models[modelIdx] ?? providerConfig.models[0] ?? agent.model;
114
136
  return { ...agent, provider: providerName, model };
115
137
  });
@@ -1,35 +1,23 @@
1
1
  /**
2
2
  * Corroboration-based verdict computation for plan review.
3
3
  *
4
- * Uses agent-agreement thresholding: a dimension blocks only when a sufficient
5
- * number of *distinct agents* independently flag it. This measures true
6
- * corroboration (multiple independent reviewers converge) rather than issue
7
- * density (one verbose agent floods a dimension).
4
+ * Replaces the old per-verdict aggregation with proportional thresholding:
5
+ * high-severity issues in a dimension only block when the total count
6
+ * exceeds the number of distinct agents contributing to that dimension.
8
7
  *
9
- * **Algorithm:**
10
- * For each dimension, compute: `effective_threshold = max(minAgreement, ceil(minRatio × totalAgents))`
11
- * Block when `distinct_agents_in_dimension >= effective_threshold`.
12
- *
13
- * **Default config:** `minAgreement=2, minRatio=0.40`
14
- * - At 6 agents: threshold=3 (50% must agree)
15
- * - At 10 agents: threshold=4 (40% must agree)
16
- * - At 20 agents: threshold=8 (40% must agree)
17
- *
18
- * **Why agent-agreement over issue-density:**
19
- * The previous system (issues >= 2×agents_in_dimension) allowed a single agent
20
- * to self-corroborate by raising 2+ issues, and made blocking harder as more
21
- * agents covered a dimension (inverted scaling). Agent-agreement fixes both:
22
- * a single agent can never self-corroborate, and more agents agreeing is a
23
- * stronger signal, not a weaker one.
8
+ * **Why proportional thresholding:**
9
+ * The agent pool has dimensional imbalance (e.g., 10 completeness agents vs
10
+ * 1 maintainability agent). A fixed "2+ agents agree = block" would mean
11
+ * any 2 completeness agents always block. Proportional scaling (issues > 2×agents)
12
+ * sets a fair bar regardless of how many agents focus on each dimension.
24
13
  *
25
14
  * **Convergence problem this solves:**
26
15
  * Agents with opposing philosophies (simplicity-guardian vs completeness-gaps)
27
16
  * produce contradictory high-severity issues. Because the old system treated
28
17
  * every agent's finding as independently authoritative, plans oscillated —
29
- * addressing one agent's feedback triggered the opposing agent. The minAgreement
30
- * floor prevents any single agent's philosophy from blocking alone.
18
+ * addressing one agent's feedback triggered the opposing agent.
31
19
  *
32
- * **Revert path:** Change one line in review-pipeline.ts back to
20
+ * **Revert path:** Change one line in cc-native-plan-review.ts back to
33
21
  * `computeReviewDecision(allVerdicts)`. Old function kept in verdict.ts.
34
22
  */
35
23
 
@@ -42,55 +30,22 @@ import type {
42
30
  SoloFinding,
43
31
  } from "../../lib-ts/types.js";
44
32
 
45
- /** Configuration for corroboration thresholds */
46
- export interface CorroborationConfig {
47
- /** Minimum distinct agents that must agree to trigger blocking (default: 2) */
48
- minAgreement?: number;
49
- /** Minimum fraction of total agent pool that must agree (default: 0.40) */
50
- minRatio?: number;
51
- }
52
-
53
- const DEFAULT_MIN_AGREEMENT = 2;
54
- const DEFAULT_MIN_RATIO = 0.40;
55
-
56
- /**
57
- * Compute the effective blocking threshold for a given agent pool size.
58
- *
59
- * Returns `max(minAgreement, ceil(minRatio × totalAgents))`.
60
- * This ensures a fixed floor (no single-agent self-corroboration) while
61
- * scaling proportionally at larger pool sizes.
62
- */
63
- export function getEffectiveThreshold(
64
- totalAgents: number,
65
- config: CorroborationConfig = {},
66
- ): number {
67
- const minAgreement = config.minAgreement ?? DEFAULT_MIN_AGREEMENT;
68
- const minRatio = config.minRatio ?? DEFAULT_MIN_RATIO;
69
- return Math.max(minAgreement, Math.ceil(totalAgents * minRatio));
70
- }
71
-
72
33
  /**
73
34
  * Compute a corroboration-based review decision from all reviewer results.
74
35
  *
75
36
  * Algorithm:
76
37
  * 1. Collect all high-severity issues with a `dimension` field
77
38
  * 2. Group by dimension, tracking distinct agent names per group
78
- * 3. Compute effective threshold: `max(minAgreement, ceil(minRatio × totalAgents))`
79
- * 4. For each dimension: block if `distinct_agents >= effective_threshold`
80
- * 5. Issues without `dimension` are unclassified (logged as warning, never block)
81
- * 6. Non-high issues are ignored (informational only)
39
+ * 3. For each dimension: block if `issues.length > 2 × agentCount`
40
+ * 4. Issues without `dimension` are unclassified (never block)
41
+ * 5. Non-high issues are ignored (informational only)
82
42
  *
83
43
  * @param allResults - Map of reviewer name → ReviewerResult (CLI + agent)
84
- * @param config - Optional threshold configuration
85
44
  * @returns CorroborationResult with blocking groups, solo findings, and verdict
86
45
  */
87
46
  export function computeCorroboratedDecision(
88
47
  allResults: Record<string, ReviewerResult>,
89
- config: CorroborationConfig = {},
90
48
  ): CorroborationResult {
91
- const totalAgents = Object.keys(allResults).length;
92
- const threshold = getEffectiveThreshold(totalAgents, config);
93
-
94
49
  // Accumulator: dimension → { issues, agentNames }
95
50
  const dimMap = new Map<
96
51
  IssueDimension,
@@ -111,7 +66,7 @@ export function computeCorroboratedDecision(
111
66
  // Only high-severity issues participate in corroboration
112
67
  if (issue.severity !== "high") continue;
113
68
 
114
- // Issues without dimension are unclassified — logged but cannot block
69
+ // Issues without dimension are unclassified — cannot block
115
70
  if (!issue.dimension) {
116
71
  unclassified.push({ agent: agentName, issue });
117
72
  continue;
@@ -127,22 +82,14 @@ export function computeCorroboratedDecision(
127
82
  }
128
83
  }
129
84
 
130
- // Warn about unclassified issues so they don't silently disappear
131
- if (unclassified.length > 0) {
132
- const agents = [...new Set(unclassified.map(u => u.agent))];
133
- process.stderr.write(
134
- `[corroboration] WARNING: ${unclassified.length} high-severity issue(s) from [${agents.join(", ")}] lack dimension classification and cannot participate in corroboration\n`,
135
- );
136
- }
137
-
138
85
  const blocking: CorroboratedGroup[] = [];
139
86
  const solo: SoloFinding[] = [];
140
87
 
141
88
  for (const [dimension, group] of dimMap) {
142
89
  const agentCount = group.agentNames.size;
90
+ const threshold = 2 * agentCount;
143
91
 
144
- // Block when enough distinct agents independently flag this dimension
145
- if (agentCount >= threshold) {
92
+ if (group.issues.length >= threshold) {
146
93
  blocking.push({
147
94
  dimension,
148
95
  issues: group.issues,
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import { OrchestratorClaudeAgent } from "./reviewers/providers/orchestrator-claude-agent.js";
8
- import { logInfo, logWarn } from "../../../_shared/lib-ts/base/logger.js";
8
+ import { logInfo, logWarn } from "../../../_core/lib-ts/runtime/logger.js";
9
9
  import type { AgentConfig, AgentReviewSettings, OrchestratorConfig, OrchestratorResult } from "../../lib-ts/types.js";
10
10
 
11
11
  // Re-export for backward compatibility (moved to reviewers/schemas.ts)
@@ -3,7 +3,7 @@
3
3
  * Extracted from cc-native-plan-review.ts.
4
4
  */
5
5
 
6
- import { logInfo } from "../../../_shared/lib-ts/base/logger.js";
6
+ import { logInfo } from "../../../_core/lib-ts/runtime/logger.js";
7
7
  import {
8
8
  buildInlineReviewSummary,
9
9
  extractTopIssuesText,
@@ -8,8 +8,8 @@ import * as path from "node:path";
8
8
 
9
9
  import { runAgentReview } from "./reviewers/index.js";
10
10
  import { QUESTIONS_SCHEMA } from "./reviewers/schemas.js";
11
- import { logInfo, logWarn, logError } from "../../../_shared/lib-ts/base/logger.js";
12
- import { findExecutable } from "../../../_shared/lib-ts/base/subprocess-utils.js";
11
+ import { logInfo, logWarn, logError } from "../../../_core/lib-ts/runtime/logger.js";
12
+ import { findExecutable } from "../../../_core/lib-ts/runtime/subprocess-utils.js";
13
13
  import { aggregateAgents } from "../../lib-ts/aggregate-agents.js";
14
14
  import type { AgentConfig } from "../../lib-ts/types.js";
15
15