aiwcli 0.15.5 → 0.17.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.
- package/README.md +108 -1124
- package/bin/run.js +0 -4
- package/dist/capabilities/branch/adapters.d.ts +2 -0
- package/dist/capabilities/branch/adapters.js +21 -0
- package/dist/capabilities/branch/contracts.d.ts +57 -0
- package/dist/capabilities/branch/contracts.js +1 -0
- package/dist/capabilities/branch/control-plane.d.ts +2 -0
- package/dist/capabilities/branch/control-plane.js +343 -0
- package/dist/capabilities/branch/runtime-core.d.ts +5 -0
- package/dist/capabilities/branch/runtime-core.js +36 -0
- package/dist/capabilities/installation/control-plane/clean-command.d.ts +41 -0
- package/dist/capabilities/installation/control-plane/clean-command.js +196 -0
- package/dist/capabilities/installation/control-plane/clear-command.d.ts +162 -0
- package/dist/capabilities/installation/control-plane/clear-command.js +1249 -0
- package/dist/capabilities/installation/control-plane/init-command.d.ts +81 -0
- package/dist/capabilities/installation/control-plane/init-command.js +449 -0
- package/dist/capabilities/launch/contracts.d.ts +86 -0
- package/dist/capabilities/launch/contracts.js +1 -0
- package/dist/capabilities/launch/control-plane/execute-launch.d.ts +2 -0
- package/dist/capabilities/launch/control-plane/execute-launch.js +261 -0
- package/dist/capabilities/launch/runtime-core/launch-decisions.d.ts +82 -0
- package/dist/capabilities/launch/runtime-core/launch-decisions.js +202 -0
- package/dist/capabilities/launch/runtime-core/launch-options.d.ts +14 -0
- package/dist/capabilities/launch/runtime-core/launch-options.js +69 -0
- package/dist/cli/base-command.d.ts +18 -0
- package/dist/cli/base-command.js +55 -0
- package/dist/commands/branch.d.ts +1 -21
- package/dist/commands/branch.js +25 -417
- package/dist/commands/clean.d.ts +1 -41
- package/dist/commands/clean.js +1 -196
- package/dist/commands/clear.d.ts +1 -161
- package/dist/commands/clear.js +1 -1121
- package/dist/commands/init/index.d.ts +1 -98
- package/dist/commands/init/index.js +4 -478
- package/dist/commands/launch.d.ts +32 -12
- package/dist/commands/launch.js +107 -166
- package/dist/lib/claude-settings-types.d.ts +31 -19
- package/dist/lib/config.js +1 -2
- package/dist/lib/context/context-formatter.d.ts +74 -0
- package/dist/lib/context/context-formatter.js +493 -0
- package/dist/lib/context/context-selector.d.ts +42 -0
- package/dist/lib/context/context-selector.js +451 -0
- package/dist/lib/context/context-store.d.ts +100 -0
- package/dist/lib/context/context-store.js +644 -0
- package/dist/lib/context/plan-manager.d.ts +54 -0
- package/dist/lib/context/plan-manager.js +282 -0
- package/dist/lib/context/task-tracker.d.ts +44 -0
- package/dist/lib/context/task-tracker.js +146 -0
- package/dist/lib/core-ide-base.d.ts +4 -0
- package/dist/lib/core-ide-base.js +77 -0
- package/dist/lib/core-installer.d.ts +5 -0
- package/dist/lib/core-installer.js +33 -0
- package/dist/lib/debug.d.ts +0 -10
- package/dist/lib/debug.js +0 -10
- package/dist/lib/env-sanitizer.d.ts +25 -0
- package/dist/lib/env-sanitizer.js +46 -0
- package/dist/lib/errors.d.ts +0 -13
- package/dist/lib/errors.js +0 -15
- package/dist/lib/git-exclude-manager.d.ts +2 -2
- package/dist/lib/git-exclude-manager.js +3 -3
- package/dist/lib/hooks/context-monitor-logic.d.ts +6 -0
- package/dist/lib/hooks/context-monitor-logic.js +25 -0
- package/dist/lib/hooks/hook-utils.d.ts +143 -0
- package/dist/lib/hooks/hook-utils.js +620 -0
- package/dist/lib/hooks/prompt-binding-logic.d.ts +7 -0
- package/dist/lib/hooks/prompt-binding-logic.js +50 -0
- package/dist/lib/hooks/session-end-logic.d.ts +5 -0
- package/dist/lib/hooks/session-end-logic.js +51 -0
- package/dist/lib/hooks-merger.js +25 -19
- package/dist/lib/ide-path-resolver.d.ts +19 -7
- package/dist/lib/ide-path-resolver.js +25 -9
- package/dist/lib/install-state.d.ts +34 -0
- package/dist/lib/install-state.js +154 -0
- package/dist/lib/json-io.d.ts +12 -0
- package/dist/lib/json-io.js +30 -0
- package/dist/lib/lsp-patch.d.ts +12 -0
- package/dist/lib/lsp-patch.js +156 -0
- package/dist/lib/multiplexer.d.ts +65 -0
- package/dist/lib/multiplexer.js +38 -0
- package/dist/lib/multiplexers/psmux.d.ts +55 -0
- package/dist/lib/multiplexers/psmux.js +324 -0
- package/dist/lib/multiplexers/tmux.d.ts +36 -0
- package/dist/lib/multiplexers/tmux.js +221 -0
- package/dist/lib/multiplexers/wezterm.d.ts +38 -0
- package/dist/lib/multiplexers/wezterm.js +225 -0
- package/dist/lib/mux-utils.d.ts +6 -0
- package/dist/lib/mux-utils.js +36 -0
- package/dist/lib/paths.d.ts +2 -2
- package/dist/lib/paths.js +2 -2
- package/dist/lib/platform-commands.d.ts +27 -0
- package/dist/lib/platform-commands.js +49 -0
- package/dist/lib/prompt-file-manager.d.ts +23 -0
- package/dist/lib/prompt-file-manager.js +41 -0
- package/dist/lib/runtime/agent-launcher.d.ts +67 -0
- package/dist/lib/runtime/agent-launcher.js +262 -0
- package/dist/lib/runtime/aiw-cli.d.ts +39 -0
- package/dist/lib/runtime/aiw-cli.js +76 -0
- package/dist/lib/runtime/atomic-write.d.ts +19 -0
- package/dist/lib/runtime/atomic-write.js +121 -0
- package/dist/lib/runtime/cli-args.d.ts +58 -0
- package/dist/lib/runtime/cli-args.js +200 -0
- package/dist/lib/runtime/constants.d.ts +56 -0
- package/dist/lib/runtime/constants.js +230 -0
- package/dist/lib/runtime/executable-policy.d.ts +16 -0
- package/dist/lib/runtime/executable-policy.js +57 -0
- package/dist/lib/runtime/git-state.d.ts +9 -0
- package/dist/lib/runtime/git-state.js +59 -0
- package/dist/lib/runtime/inference.d.ts +37 -0
- package/dist/lib/runtime/inference.js +251 -0
- package/dist/lib/runtime/lint-dispatch.d.ts +40 -0
- package/dist/lib/runtime/lint-dispatch.js +285 -0
- package/dist/lib/runtime/logger.d.ts +66 -0
- package/dist/lib/runtime/logger.js +201 -0
- package/dist/lib/runtime/models.d.ts +20 -0
- package/dist/lib/runtime/models.js +20 -0
- package/dist/lib/runtime/platform-adapter.d.ts +7 -0
- package/dist/lib/runtime/platform-adapter.js +21 -0
- package/dist/lib/runtime/preflight.d.ts +24 -0
- package/dist/lib/runtime/preflight.js +65 -0
- package/dist/lib/runtime/sentinel-ipc.d.ts +14 -0
- package/dist/lib/runtime/sentinel-ipc.js +67 -0
- package/dist/lib/runtime/state-io.d.ts +31 -0
- package/dist/lib/runtime/state-io.js +179 -0
- package/dist/lib/runtime/stop-words.d.ts +20 -0
- package/dist/lib/runtime/stop-words.js +150 -0
- package/dist/lib/runtime/subprocess-utils.d.ts +29 -0
- package/dist/lib/runtime/subprocess-utils.js +96 -0
- package/dist/lib/runtime/tmux-preflight.d.ts +13 -0
- package/dist/lib/runtime/tmux-preflight.js +78 -0
- package/dist/lib/runtime/utils.d.ts +62 -0
- package/dist/lib/runtime/utils.js +192 -0
- package/dist/lib/schemas.d.ts +250 -0
- package/dist/lib/schemas.js +216 -0
- package/dist/lib/sentinel-manager.d.ts +32 -0
- package/dist/lib/sentinel-manager.js +62 -0
- package/dist/lib/sentinel-wrapper.d.ts +10 -0
- package/dist/lib/sentinel-wrapper.js +29 -0
- package/dist/lib/settings-hierarchy.js +3 -20
- package/dist/lib/shell-adapters/bash-adapter.d.ts +18 -0
- package/dist/lib/shell-adapters/bash-adapter.js +69 -0
- package/dist/lib/shell-adapters/index.d.ts +5 -0
- package/dist/lib/shell-adapters/index.js +7 -0
- package/dist/lib/shell-adapters/powershell-adapter.d.ts +18 -0
- package/dist/lib/shell-adapters/powershell-adapter.js +62 -0
- package/dist/lib/shell-adapters/shell-adapter.d.ts +45 -0
- package/dist/lib/shell-adapters/shell-adapter.js +5 -0
- package/dist/lib/shell-quoting.d.ts +5 -0
- package/dist/lib/shell-quoting.js +17 -0
- package/dist/lib/spawn-errors.d.ts +9 -0
- package/dist/lib/spawn-errors.js +29 -0
- package/dist/lib/spawn.js +5 -11
- package/dist/lib/spinner.d.ts +0 -5
- package/dist/lib/spinner.js +0 -16
- package/dist/lib/template-installer.d.ts +14 -5
- package/dist/lib/template-installer.js +40 -38
- package/dist/lib/template-resolver.d.ts +6 -7
- package/dist/lib/template-resolver.js +26 -21
- package/dist/lib/template-settings-reconstructor.d.ts +7 -2
- package/dist/lib/template-settings-reconstructor.js +76 -45
- package/dist/lib/terminal-strategy.d.ts +12 -0
- package/dist/lib/terminal-strategy.js +55 -0
- package/dist/lib/terminal.d.ts +34 -4
- package/dist/lib/terminal.js +192 -119
- package/dist/lib/tmux-pane-placement.d.ts +17 -0
- package/dist/lib/tmux-pane-placement.js +58 -0
- package/dist/lib/tmux-primitives.d.ts +3 -0
- package/dist/lib/tmux-primitives.js +11 -0
- package/dist/lib/tmux-session.d.ts +32 -0
- package/dist/lib/tmux-session.js +87 -0
- package/dist/lib/tty-detection.js +1 -1
- package/dist/lib/types.d.ts +168 -0
- package/dist/lib/types.js +6 -0
- package/dist/lib/version.d.ts +1 -1
- package/dist/lib/version.js +1 -1
- package/dist/lib/windsurf-hooks-hierarchy.js +6 -23
- package/dist/platform/launch.d.ts +11 -0
- package/dist/platform/launch.js +11 -0
- package/dist/templates/CLAUDE.md +30 -40
- package/dist/templates/cc-native/.claude/settings.json +26 -36
- package/dist/templates/cc-native/CC-NATIVE-README.md +1 -1
- package/dist/templates/cc-native/TEMPLATE-SCHEMA.md +20 -12
- package/dist/templates/cc-native/_cc-native/cc-native.config.json +2 -6
- package/dist/templates/cc-native/_cc-native/hooks/CLAUDE.md +39 -59
- package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.ts +9 -11
- package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_subagent.ts +2 -2
- package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_write.ts +4 -5
- package/dist/templates/cc-native/_cc-native/hooks/mark_questions_asked.ts +4 -4
- package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.ts +2 -27
- package/dist/templates/cc-native/_cc-native/hooks/validate_task_prompt.ts +7 -7
- package/dist/templates/cc-native/_cc-native/lib-ts/.mocharc.json +9 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/aggregate-agents.test.ts +118 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/artifacts.test.ts +234 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/cc-native-state.test.ts +170 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/cli-output-parser.test.ts +73 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/config.test.ts +64 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/constants.test.ts +40 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/debug.test.ts +42 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/exports.test.ts +58 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/helpers.ts +107 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/hooks/add-plan-context.hook.test.ts +97 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/hooks/plan-questions.hook.test.ts +81 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/hooks/plan-review.hook.test.ts +71 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/json-parser.test.ts +99 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/orchestrator-agent.test.ts +288 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/orchestrator.test.ts +48 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/reviewers.test.ts +32 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/state.test.ts +124 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/verdict.test.ts +93 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/agent-selection.ts +163 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/aggregate-agents.ts +6 -14
- package/dist/templates/cc-native/_cc-native/{artifacts/lib → lib-ts/artifacts}/format.ts +597 -599
- package/dist/templates/cc-native/_cc-native/{artifacts/lib → lib-ts/artifacts}/index.ts +26 -26
- package/dist/templates/cc-native/_cc-native/{artifacts/lib → lib-ts/artifacts}/tracker.ts +106 -107
- package/dist/templates/cc-native/_cc-native/{artifacts/lib → lib-ts/artifacts}/write.ts +118 -119
- package/dist/templates/cc-native/_cc-native/lib-ts/artifacts.ts +21 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/cc-native-state.ts +17 -16
- package/dist/templates/cc-native/_cc-native/lib-ts/cli-output-parser.ts +132 -10
- package/dist/templates/cc-native/_cc-native/lib-ts/config.ts +1 -1
- package/dist/templates/cc-native/_cc-native/lib-ts/constants.ts +6 -6
- package/dist/templates/cc-native/_cc-native/lib-ts/corroboration.ts +119 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/debug.ts +2 -3
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/graduation.ts +132 -132
- package/dist/templates/cc-native/_cc-native/lib-ts/index.ts +88 -86
- package/dist/templates/cc-native/_cc-native/lib-ts/json-parser.ts +5 -6
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/orchestrator.ts +70 -70
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/output-builder.ts +130 -121
- package/dist/templates/cc-native/_cc-native/lib-ts/package-lock.json +1679 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/package.json +24 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/plan-discovery.ts +5 -5
- package/dist/templates/cc-native/_cc-native/lib-ts/plan-enhancement.ts +1 -6
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/plan-questions.ts +101 -101
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/review-pipeline.ts +511 -543
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/__tests__/agent-providers.test.ts +262 -0
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/agent.ts +71 -85
- package/dist/templates/{_shared/lib-ts/agent-exec → cc-native/_cc-native/lib-ts/reviewers/base}/base-agent.ts +138 -150
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/index.ts +12 -12
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/providers/claude-agent.ts +66 -57
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/providers/codex-agent.ts +185 -200
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/providers/gemini-agent.ts +39 -40
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/providers/orchestrator-claude-agent.ts +196 -225
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/schemas.ts +201 -201
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/types.ts +21 -23
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/__tests__/hyde.test.ts +365 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/__tests__/ollama-client.test.ts +223 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/embedding-indexer.ts +12 -16
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/hyde.ts +3 -2
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/index.ts +31 -31
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/logger.ts +7 -8
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/ollama-client.ts +7 -9
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/retrieval-pipeline.ts +16 -19
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-indexer.ts +37 -41
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-loader.ts +33 -43
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-searcher.ts +20 -20
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/types.ts +9 -10
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/vector-store.ts +3 -4
- package/dist/templates/cc-native/_cc-native/lib-ts/settings.ts +50 -126
- package/dist/templates/cc-native/_cc-native/lib-ts/state.ts +20 -22
- package/dist/templates/cc-native/_cc-native/lib-ts/tsconfig.json +2 -2
- package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +14 -89
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/verdict.ts +72 -72
- package/dist/templates/cc-native/_cc-native/plan-review/CLAUDE.md +38 -1
- package/dist/templates/cc-native/_cc-native/plan-review/lib/__tests__/agent-selection.test.ts +345 -0
- package/dist/templates/cc-native/_cc-native/plan-review/lib/__tests__/preflight.test.ts +344 -0
- package/dist/templates/cc-native/_cc-native/plan-review/lib/agent-selection.ts +38 -16
- package/dist/templates/cc-native/_cc-native/plan-review/lib/preflight.ts +56 -26
- package/dist/templates/cc-native/_cc-native/scripts/council_debate.ts +242 -0
- package/dist/templates/cc-native/_cc-native/scripts/council_debate_simple.ts +294 -0
- package/dist/templates/cc-native/_cc-native/{plan-review/workflows → workflows}/specdev.md +9 -9
- package/dist/templates/core/.claude/skills/codex/SKILL.md +25 -0
- package/dist/templates/core/.claude/skills/devin/SKILL.md +25 -0
- package/dist/templates/core/.claude/skills/handoff/SKILL.md +11 -0
- package/dist/templates/core/.claude/skills/handoff-resume/SKILL.md +11 -0
- package/dist/templates/core/.claude/skills/meta-plan/SKILL.md +13 -0
- package/dist/templates/core/.codex/skills/codex/SKILL.md +13 -0
- package/dist/templates/core/.codex/skills/devin/SKILL.md +19 -0
- package/dist/templates/core/.codex/skills/handoff/SKILL.md +11 -0
- package/dist/templates/core/.codex/skills/handoff-resume/SKILL.md +11 -0
- package/dist/templates/core/.codex/skills/meta-plan/SKILL.md +13 -0
- package/dist/templates/core/.devin/AGENTS.md +5 -0
- package/dist/templates/core/.devin/config.json +12 -0
- package/dist/templates/core/.devin/skills/codex/SKILL.md +19 -0
- package/dist/templates/core/.devin/skills/devin/SKILL.md +13 -0
- package/dist/templates/core/.devin/skills/handoff/SKILL.md +11 -0
- package/dist/templates/core/.devin/skills/handoff-resume/SKILL.md +11 -0
- package/dist/templates/core/.devin/skills/meta-plan/SKILL.md +13 -0
- package/dist/templates/core/.windsurf/workflows/handoff-resume.md +9 -0
- package/dist/templates/{_shared → core}/.windsurf/workflows/handoff.md +1 -1
- package/dist/templates/{_shared → core}/.windsurf/workflows/meta-plan.md +1 -1
- package/dist/templates/core/hooks-ts/_utils/git-state.ts +2 -0
- package/dist/templates/{_shared → core}/hooks-ts/archive_plan.ts +15 -44
- package/dist/templates/core/hooks-ts/codex_explorer.ts +160 -0
- package/dist/templates/{_shared → core}/hooks-ts/context_monitor.ts +23 -55
- package/dist/templates/{_shared → core}/hooks-ts/file-suggestion.ts +5 -22
- package/dist/templates/{_shared → core}/hooks-ts/lint_after_edit.ts +7 -9
- package/dist/templates/core/hooks-ts/pre_compact.ts +36 -0
- package/dist/templates/{_shared → core}/hooks-ts/session_end.ts +38 -78
- package/dist/templates/{_shared → core}/hooks-ts/session_start.ts +5 -5
- package/dist/templates/core/hooks-ts/task_create_capture.ts +32 -0
- package/dist/templates/{_shared → core}/hooks-ts/task_update_capture.ts +9 -24
- package/dist/templates/core/hooks-ts/user_prompt_submit.ts +46 -0
- package/dist/templates/{_shared → core}/lib-ts/CLAUDE.md +27 -16
- package/dist/templates/{_shared → core}/lib-ts/context/CLAUDE.md +9 -6
- package/dist/templates/{_shared → core}/lib-ts/context/context-formatter.ts +16 -21
- package/dist/templates/{_shared → core}/lib-ts/context/context-selector.ts +8 -6
- package/dist/templates/{_shared → core}/lib-ts/context/context-store.ts +59 -20
- package/dist/templates/{_shared → core}/lib-ts/context/plan-manager.ts +19 -15
- package/dist/templates/{_shared → core}/lib-ts/context/task-tracker.ts +3 -3
- package/dist/templates/core/lib-ts/hooks/context-monitor-logic.ts +32 -0
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/hooks}/hook-utils.ts +179 -41
- package/dist/templates/core/lib-ts/hooks/prompt-binding-logic.ts +80 -0
- package/dist/templates/core/lib-ts/hooks/session-end-logic.ts +82 -0
- package/dist/templates/core/lib-ts/package.json +19 -0
- package/dist/templates/core/lib-ts/runtime/agent-launcher.ts +369 -0
- package/dist/templates/core/lib-ts/runtime/aiw-cli.ts +108 -0
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/atomic-write.ts +12 -7
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/cli-args.ts +24 -8
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/constants.ts +326 -324
- package/dist/templates/core/lib-ts/runtime/executable-policy.ts +89 -0
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/git-state.ts +6 -4
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/inference.ts +60 -23
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/lint-dispatch.ts +25 -23
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/logger.ts +32 -29
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/models.ts +9 -2
- package/dist/templates/core/lib-ts/runtime/platform-adapter.ts +33 -0
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/preflight.ts +4 -3
- package/dist/templates/core/lib-ts/runtime/sentinel-ipc.ts +91 -0
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/state-io.ts +20 -11
- package/dist/templates/core/lib-ts/runtime/stop-words.ts +185 -0
- package/dist/templates/core/lib-ts/runtime/subprocess-utils.ts +147 -0
- package/dist/templates/core/lib-ts/runtime/tmux-preflight.ts +93 -0
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/utils.ts +34 -4
- package/dist/templates/core/lib-ts/schemas.ts +233 -0
- package/dist/templates/{_shared → core}/lib-ts/templates/formatters.ts +7 -5
- package/dist/templates/{_shared → core}/lib-ts/templates/plan-context.ts +2 -1
- package/dist/templates/{_shared → core}/lib-ts/tsconfig.json +3 -1
- package/dist/templates/{_shared → core}/lib-ts/types.ts +78 -77
- package/dist/templates/core/scripts/resolve-run.ts +93 -0
- package/dist/templates/{_shared → core}/scripts/resolve_context.ts +3 -3
- package/dist/templates/{_shared → core}/scripts/status_line.ts +26 -21
- package/dist/templates/core/skills/codex/CLAUDE.md +83 -0
- package/dist/templates/{_shared → core}/skills/codex/SKILL.md +27 -18
- package/dist/templates/{_shared → core}/skills/codex/lib/codex-watcher.ts +79 -113
- package/dist/templates/{_shared → core}/skills/codex/scripts/launch-codex.ts +134 -148
- package/dist/templates/{_shared → core}/skills/codex/scripts/watch-codex.ts +6 -4
- package/dist/templates/core/skills/devin/CLAUDE.md +122 -0
- package/dist/templates/core/skills/devin/SKILL.md +73 -0
- package/dist/templates/core/skills/devin/lib/devin-watcher.ts +300 -0
- package/dist/templates/core/skills/devin/scripts/launch-devin.ts +258 -0
- package/dist/templates/{_shared → core}/skills/handoff-system/CLAUDE.md +436 -433
- package/dist/templates/{_shared → core}/skills/handoff-system/lib/document-generator.ts +9 -7
- package/dist/templates/{_shared → core}/skills/handoff-system/lib/handoff-reader.ts +6 -4
- package/dist/templates/{_shared → core}/skills/handoff-system/scripts/resume_handoff.ts +10 -8
- package/dist/templates/{_shared → core}/skills/handoff-system/scripts/save_handoff.ts +12 -10
- package/dist/templates/{_shared → core}/skills/handoff-system/workflows/handoff-resume.md +2 -2
- package/dist/templates/{_shared → core}/skills/handoff-system/workflows/handoff.md +6 -5
- package/dist/templates/{_shared → core}/skills/meta-plan/CLAUDE.md +2 -1
- package/dist/templates/{_shared → core}/skills/meta-plan/workflows/meta-plan.md +8 -7
- package/oclif.manifest.json +89 -13
- package/package.json +13 -12
- package/dist/lib/base-command.d.ts +0 -114
- package/dist/lib/base-command.js +0 -153
- package/dist/lib/env-compat.d.ts +0 -18
- package/dist/lib/env-compat.js +0 -23
- package/dist/lib/stdin.d.ts +0 -48
- package/dist/lib/stdin.js +0 -60
- package/dist/templates/_shared/.claude/settings.json +0 -120
- package/dist/templates/_shared/.claude/skills/codex/SKILL.md +0 -35
- package/dist/templates/_shared/.claude/skills/handoff/SKILL.md +0 -13
- package/dist/templates/_shared/.claude/skills/handoff-resume/SKILL.md +0 -13
- package/dist/templates/_shared/.claude/skills/meta-plan/SKILL.md +0 -43
- package/dist/templates/_shared/.codex/workflows/codex.md +0 -11
- package/dist/templates/_shared/.codex/workflows/handoff.md +0 -226
- package/dist/templates/_shared/.codex/workflows/meta-plan.md +0 -347
- package/dist/templates/_shared/hooks-ts/_utils/git-state.ts +0 -2
- package/dist/templates/_shared/hooks-ts/pre_compact.ts +0 -49
- package/dist/templates/_shared/hooks-ts/task_create_capture.ts +0 -48
- package/dist/templates/_shared/hooks-ts/user_prompt_submit.ts +0 -93
- package/dist/templates/_shared/lib-ts/agent-exec/backends/headless.ts +0 -33
- package/dist/templates/_shared/lib-ts/agent-exec/backends/index.ts +0 -6
- package/dist/templates/_shared/lib-ts/agent-exec/backends/tmux.ts +0 -119
- package/dist/templates/_shared/lib-ts/agent-exec/execution-backend.ts +0 -50
- package/dist/templates/_shared/lib-ts/agent-exec/index.ts +0 -6
- package/dist/templates/_shared/lib-ts/agent-exec/structured-output.ts +0 -166
- package/dist/templates/_shared/lib-ts/base/launchers/tmux-launcher.ts +0 -173
- package/dist/templates/_shared/lib-ts/base/launchers/window-launcher.ts +0 -93
- package/dist/templates/_shared/lib-ts/base/launchers/wt-launcher.ts +0 -64
- package/dist/templates/_shared/lib-ts/base/pane-launcher.ts +0 -55
- package/dist/templates/_shared/lib-ts/base/sentinel-ipc.ts +0 -87
- package/dist/templates/_shared/lib-ts/base/stop-words.ts +0 -184
- package/dist/templates/_shared/lib-ts/base/subprocess-utils.ts +0 -249
- package/dist/templates/_shared/lib-ts/base/tmux-driver.ts +0 -341
- package/dist/templates/_shared/lib-ts/base/tmux-pane-placement.ts +0 -78
- package/dist/templates/_shared/lib-ts/package.json +0 -20
- package/dist/templates/_shared/scripts/resolve-run.ts +0 -62
- package/dist/templates/_shared/skills/codex/CLAUDE.md +0 -70
- package/dist/templates/cc-native/_cc-native/CLAUDE.md +0 -73
- package/dist/templates/cc-native/_cc-native/artifacts/CLAUDE.md +0 -64
- package/dist/templates/cc-native/_cc-native/lib-ts/CLAUDE.md +0 -70
- package/dist/templates/cc-native/_cc-native/plan-review/CODING-STANDARDS-CHECKLIST.md +0 -75
- package/dist/templates/cc-native/_cc-native/plan-review/agents/CLAUDE.md +0 -143
- package/dist/templates/cc-native/_cc-native/plan-review/agents/PLAN-ORCHESTRATOR.md +0 -213
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-questions/PLAN-QUESTIONER.md +0 -70
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ARCH-EVOLUTION.md +0 -62
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ARCH-PATTERNS.md +0 -61
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ARCH-STRUCTURE.md +0 -62
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ASSUMPTION-TRACER.md +0 -56
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/CLARITY-AUDITOR.md +0 -53
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/COMPLETENESS-FEASIBILITY.md +0 -66
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/COMPLETENESS-GAPS.md +0 -70
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/COMPLETENESS-ORDERING.md +0 -62
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/CONSTRAINT-VALIDATOR.md +0 -72
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DESIGN-ADR-VALIDATOR.md +0 -61
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DESIGN-SCALE-MATCHER.md +0 -64
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DEVILS-ADVOCATE.md +0 -56
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DOCUMENTATION-PHILOSOPHY.md +0 -86
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/HANDOFF-READINESS.md +0 -59
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/HIDDEN-COMPLEXITY.md +0 -58
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/INCREMENTAL-DELIVERY.md +0 -66
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-DEPENDENCY.md +0 -62
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-FMEA.md +0 -66
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-PREMORTEM.md +0 -71
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-REVERSIBILITY.md +0 -74
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/SCOPE-BOUNDARY.md +0 -77
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/SIMPLICITY-GUARDIAN.md +0 -62
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/SKEPTIC.md +0 -68
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-BEHAVIOR-AUDITOR.md +0 -61
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-CHARACTERIZATION.md +0 -71
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-FIRST-VALIDATOR.md +0 -61
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-PYRAMID-ANALYZER.md +0 -61
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TRADEOFF-COSTS.md +0 -67
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TRADEOFF-STAKEHOLDERS.md +0 -65
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/VERIFY-COVERAGE.md +0 -74
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/VERIFY-STRENGTH.md +0 -69
- package/dist/templates/cc-native/_cc-native/plan-review/lib/corroboration.ts +0 -172
- package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/base/base-agent.ts +0 -7
|
@@ -1,72 +1,72 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure verdict aggregation logic.
|
|
3
|
-
* See cc-native-plan-review-spec.md §4.2
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { ReviewDecisionResult, Verdict } from "
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Return the worst verdict from a list.
|
|
10
|
-
* Order: pass < warn < fail. skip→pass, error→warn.
|
|
11
|
-
*/
|
|
12
|
-
export function worstVerdict(verdicts: Verdict[]): Verdict {
|
|
13
|
-
const order: Record<Verdict, number> = {
|
|
14
|
-
pass: 0,
|
|
15
|
-
warn: 1,
|
|
16
|
-
fail: 2,
|
|
17
|
-
skip: 0,
|
|
18
|
-
error: 1,
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
let worst: Verdict = "pass";
|
|
22
|
-
for (const v of verdicts) {
|
|
23
|
-
if ((order[v] ?? 1) > (order[worst] ?? 0)) {
|
|
24
|
-
worst = v;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Normalize error → warn
|
|
29
|
-
if (worst === "error") return "warn";
|
|
30
|
-
return worst;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Verdict aggregation: fail veto triggers a block.
|
|
35
|
-
*
|
|
36
|
-
* Priority order:
|
|
37
|
-
* 1. Fail Veto: Any fail → deny (ISO 61508 zero-tolerance)
|
|
38
|
-
* 2. Acceptable: warns are informational only
|
|
39
|
-
*
|
|
40
|
-
* Error exclusion: Detectors that produce no signal (error/skip) are excluded
|
|
41
|
-
* from the denominator.
|
|
42
|
-
*
|
|
43
|
-
* @param allVerdicts - List of verdict strings from all reviewers
|
|
44
|
-
* @returns ReviewDecisionResult with should_deny, reason, and score
|
|
45
|
-
*/
|
|
46
|
-
export function computeReviewDecision(
|
|
47
|
-
allVerdicts: Verdict[],
|
|
48
|
-
): ReviewDecisionResult {
|
|
49
|
-
// Exclude non-signal verdicts
|
|
50
|
-
const signalVerdicts = allVerdicts.filter(
|
|
51
|
-
(v) => v === "pass" || v === "warn" || v === "fail",
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
if (signalVerdicts.length === 0) {
|
|
55
|
-
return { should_deny: false, reason: "no_signal", score: 0 };
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Fail blocks unconditionally
|
|
59
|
-
const failCount = signalVerdicts.filter((v) => v === "fail").length;
|
|
60
|
-
if (failCount > 0) {
|
|
61
|
-
return { should_deny: true, reason: "fail_veto", score: 1 };
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Warn also blocks — reviewers flagged concerns worth addressing
|
|
65
|
-
const warnCount = signalVerdicts.filter((v) => v === "warn").length;
|
|
66
|
-
const warnRatio = warnCount / signalVerdicts.length;
|
|
67
|
-
if (warnCount > 0) {
|
|
68
|
-
return { should_deny: true, reason: "warn_block", score: warnRatio };
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return { should_deny: false, reason: "acceptable", score: 0 };
|
|
72
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Pure verdict aggregation logic.
|
|
3
|
+
* See cc-native-plan-review-spec.md §4.2
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { ReviewDecisionResult, Verdict } from "./types.js";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Return the worst verdict from a list.
|
|
10
|
+
* Order: pass < warn < fail. skip→pass, error→warn.
|
|
11
|
+
*/
|
|
12
|
+
export function worstVerdict(verdicts: Verdict[]): Verdict {
|
|
13
|
+
const order: Record<Verdict, number> = {
|
|
14
|
+
pass: 0,
|
|
15
|
+
warn: 1,
|
|
16
|
+
fail: 2,
|
|
17
|
+
skip: 0,
|
|
18
|
+
error: 1,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
let worst: Verdict = "pass";
|
|
22
|
+
for (const v of verdicts) {
|
|
23
|
+
if ((order[v] ?? 1) > (order[worst] ?? 0)) {
|
|
24
|
+
worst = v;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Normalize error → warn
|
|
29
|
+
if (worst === "error") return "warn";
|
|
30
|
+
return worst;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Verdict aggregation: fail veto triggers a block.
|
|
35
|
+
*
|
|
36
|
+
* Priority order:
|
|
37
|
+
* 1. Fail Veto: Any fail → deny (ISO 61508 zero-tolerance)
|
|
38
|
+
* 2. Acceptable: warns are informational only
|
|
39
|
+
*
|
|
40
|
+
* Error exclusion: Detectors that produce no signal (error/skip) are excluded
|
|
41
|
+
* from the denominator.
|
|
42
|
+
*
|
|
43
|
+
* @param allVerdicts - List of verdict strings from all reviewers
|
|
44
|
+
* @returns ReviewDecisionResult with should_deny, reason, and score
|
|
45
|
+
*/
|
|
46
|
+
export function computeReviewDecision(
|
|
47
|
+
allVerdicts: Verdict[],
|
|
48
|
+
): ReviewDecisionResult {
|
|
49
|
+
// Exclude non-signal verdicts
|
|
50
|
+
const signalVerdicts = allVerdicts.filter(
|
|
51
|
+
(v) => v === "pass" || v === "warn" || v === "fail",
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
if (signalVerdicts.length === 0) {
|
|
55
|
+
return { should_deny: false, reason: "no_signal", score: 0.0 };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Fail blocks unconditionally
|
|
59
|
+
const failCount = signalVerdicts.filter((v) => v === "fail").length;
|
|
60
|
+
if (failCount > 0) {
|
|
61
|
+
return { should_deny: true, reason: "fail_veto", score: 1.0 };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Warn also blocks — reviewers flagged concerns worth addressing
|
|
65
|
+
const warnCount = signalVerdicts.filter((v) => v === "warn").length;
|
|
66
|
+
const warnRatio = warnCount / signalVerdicts.length;
|
|
67
|
+
if (warnCount > 0) {
|
|
68
|
+
return { should_deny: true, reason: "warn_block", score: warnRatio };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return { should_deny: false, reason: "acceptable", score: 0.0 };
|
|
72
|
+
}
|
|
@@ -67,8 +67,9 @@ Hooks that invoke this system (all in `../_cc-native/hooks/`):
|
|
|
67
67
|
| Module | Key Exports |
|
|
68
68
|
|--------|-------------|
|
|
69
69
|
| `review-pipeline.ts` | `runReviewPipeline(input)` — main entry point |
|
|
70
|
-
| `agent-selection.ts` | `resolveMandatoryAgents()`, `selectAgents()`, `assignModelsToAgents()` |
|
|
70
|
+
| `agent-selection.ts` | `resolveMandatoryAgents()`, `selectAgents()`, `assignModelsToAgents(agents, config, available?, options?)`, `resolveEnabledProviders()` (@internal). `assignModelsToAgents` accepts optional `{ isCliAvailable, randomFn }` for DI. |
|
|
71
71
|
| `corroboration.ts` | `computeCorroboratedDecision()` |
|
|
72
|
+
| `preflight.ts` | `runPreflight()`, `collectPreflightChecks()` (@internal), `buildPreflightReport()` (@internal), `KNOWN_PROVIDERS` |
|
|
72
73
|
| `graduation.ts` | `computePassEligible()`, `extractTopIssuesForTracker()`, `advanceIterationState()` |
|
|
73
74
|
| `orchestrator.ts` | `runOrchestrator()`, `buildOrchestratorSchema()` (re-exported) |
|
|
74
75
|
| `output-builder.ts` | `buildReviewOutput()`, `truncateAgentIssues()`, `overrideVerdictsByThreshold()` |
|
|
@@ -79,6 +80,7 @@ Hooks that invoke this system (all in `../_cc-native/hooks/`):
|
|
|
79
80
|
## Dependencies
|
|
80
81
|
|
|
81
82
|
**Reads from shared lib-ts (stays in lib-ts, not part of plan-review):**
|
|
83
|
+
- `_core/lib-ts/runtime/cli-args.ts` — centralized CLI arg construction (`buildCliInvocation`, `reviewSpec`, `preflightCommandConfig`). All provider agents and preflight delegate flag construction here.
|
|
82
84
|
- `../../lib-ts/types.ts` — all shared types (AgentConfig, ReviewerResult, etc.)
|
|
83
85
|
- `../../lib-ts/settings.ts` — config loading
|
|
84
86
|
- `../../lib-ts/plan-discovery.ts` — plan file discovery
|
|
@@ -142,9 +144,44 @@ weight: 1.0
|
|
|
142
144
|
|
|
143
145
|
`mandatory: true` agents always run. `mandatory: false` agents are selected by the orchestrator based on plan complexity.
|
|
144
146
|
|
|
147
|
+
## Model & Provider Configuration
|
|
148
|
+
|
|
149
|
+
Model assignment flows through a multi-layer pipeline:
|
|
150
|
+
|
|
151
|
+
1. **Config source:** `cc-native.config.json` → `models.providers` section
|
|
152
|
+
2. **Defaults:** `lib-ts/settings.ts` → `DEFAULT_MODELS_CONFIG`
|
|
153
|
+
3. **Loading:** `loadModelsConfig()` parses config into `ModelsConfig` (including `reasoning_effort`)
|
|
154
|
+
4. **Assignment:** `assignModelsToAgents()` assigns provider, model, and `reasoning_effort` from the selected `ProviderConfig` to each `AgentConfig`
|
|
155
|
+
5. **Invocation:** Provider agents (e.g. `CodexAgent.buildCliArgs()`) emit CLI flags
|
|
156
|
+
|
|
157
|
+
**Current defaults:**
|
|
158
|
+
- Codex: model `gpt-5.4`, `reasoning_effort: "low"` → `codex exec --model gpt-5.4 -c model_reasoning_effort="low"`
|
|
159
|
+
- Claude: model `sonnet` → `claude --model sonnet`
|
|
160
|
+
|
|
161
|
+
**Provider priority:** `["codex", "claude"]` — Codex is preferred (cheaper/faster), Claude is fallback.
|
|
162
|
+
|
|
163
|
+
**`reasoning_effort` field:** Configured per-provider in `ProviderConfig`. Passed through `assignModelsToAgents()` to `AgentConfig.reasoning_effort`. `CodexAgent` emits it as `-c model_reasoning_effort="<value>"`. When absent, the flag is omitted and the CLI default applies.
|
|
164
|
+
|
|
165
|
+
### Verifying model/config changes
|
|
166
|
+
|
|
167
|
+
**Always test model or config changes against the real CLI.** Use `codex exec` directly to confirm the model name and flags are accepted before committing:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
# Verify model + reasoning_effort works
|
|
171
|
+
codex exec --model gpt-5.4 -c 'model_reasoning_effort="low"' --sandbox read-only --ephemeral \
|
|
172
|
+
-o /tmp/test-out.txt "Say hello" 2>&1 | head -20
|
|
173
|
+
|
|
174
|
+
# Check the output header for: model, reasoning effort, provider
|
|
175
|
+
# A 400 error like "model is not supported" means the model name is wrong
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Invalid model names fail at runtime with no compile-time safety net. The CLI header prints the resolved `model:` and `reasoning effort:` — always verify these match expectations.
|
|
179
|
+
|
|
145
180
|
## Design Decisions
|
|
146
181
|
|
|
147
182
|
- **Thin hook, fat pipeline:** The hook is ~70 lines and delegates everything to `review-pipeline.ts`. This enables testing the pipeline without hook machinery.
|
|
148
183
|
- **Parallel reviews:** All selected agents run simultaneously via `Promise.all()`. Review time is bounded by the slowest agent, not total agents.
|
|
149
184
|
- **Questions gate first:** Questions must be asked before review. `wasQuestionsAsked()` prevents skipping the gate via repeated ExitPlanMode attempts.
|
|
150
185
|
- **Co-location:** Moved from scattered `lib-ts/`, `agents/`, and `workflows/` to `plan-review/` to follow the handoff system pattern. See root CLAUDE.md "System Co-location Pattern".
|
|
186
|
+
|
|
187
|
+
<!-- context-layer: last-audited=2026-03-07 | version=2 -->
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for agent-selection module.
|
|
3
|
+
* Tests resolveEnabledProviders directly with simple predicates — zero mocks.
|
|
4
|
+
* Tests assignModelsToAgents with DI options (randomFn, isCliAvailable) — zero mocks.
|
|
5
|
+
* Logger mock is for noise suppression only.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { describe, it, expect, mock } from "bun:test";
|
|
9
|
+
|
|
10
|
+
import type { AgentConfig, ModelsConfig } 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
|
+
logDebug() {},
|
|
18
|
+
logInfo() {},
|
|
19
|
+
logWarn() {},
|
|
20
|
+
logError() {},
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
// Mock subprocess-utils so module load doesn't fail (not used by tests via DI)
|
|
24
|
+
mock.module("../../../../_core/lib-ts/runtime/subprocess-utils.js", () => ({
|
|
25
|
+
findExecutable: () => null,
|
|
26
|
+
}));
|
|
27
|
+
|
|
28
|
+
const { assignModelsToAgents, resolveEnabledProviders } = await import("../agent-selection.js");
|
|
29
|
+
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
// Helpers
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
|
|
34
|
+
function makeAgent(name: string): AgentConfig {
|
|
35
|
+
return {
|
|
36
|
+
name,
|
|
37
|
+
model: "default-model",
|
|
38
|
+
provider: "",
|
|
39
|
+
focus: "test",
|
|
40
|
+
categories: [],
|
|
41
|
+
description: `Test agent ${name}`,
|
|
42
|
+
system_prompt: "",
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function makeModelsConfig(providers: Record<string, { enabled: boolean; models: string[] }>): ModelsConfig {
|
|
47
|
+
return { providers };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** CLI always available */
|
|
51
|
+
const allAvailable = () => true;
|
|
52
|
+
|
|
53
|
+
/** CLI never available */
|
|
54
|
+
const noneAvailable = () => false;
|
|
55
|
+
|
|
56
|
+
/** Only specific CLIs available */
|
|
57
|
+
const onlyAvailable = (...names: string[]) => (name: string) => names.includes(name);
|
|
58
|
+
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
// resolveEnabledProviders — pure, zero mocks
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
|
|
63
|
+
describe("agent-selection", () => {
|
|
64
|
+
describe("resolveEnabledProviders", () => {
|
|
65
|
+
it("returns enabled providers sorted by priority (codex first)", () => {
|
|
66
|
+
const config = makeModelsConfig({
|
|
67
|
+
claude: { enabled: true, models: ["sonnet"] },
|
|
68
|
+
codex: { enabled: true, models: ["codex-mini-latest"] },
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
const result = resolveEnabledProviders(config, allAvailable);
|
|
72
|
+
|
|
73
|
+
expect(result.length).toBe(2);
|
|
74
|
+
expect(result[0]![0]).toBe("codex");
|
|
75
|
+
expect(result[1]![0]).toBe("claude");
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("excludes providers whose CLI is not available", () => {
|
|
79
|
+
const config = makeModelsConfig({
|
|
80
|
+
claude: { enabled: true, models: ["sonnet"] },
|
|
81
|
+
codex: { enabled: true, models: ["codex-mini-latest"] },
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const result = resolveEnabledProviders(config, onlyAvailable("claude"));
|
|
85
|
+
|
|
86
|
+
expect(result.length).toBe(1);
|
|
87
|
+
expect(result[0]![0]).toBe("claude");
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it("excludes disabled providers", () => {
|
|
91
|
+
const config = makeModelsConfig({
|
|
92
|
+
claude: { enabled: false, models: ["sonnet"] },
|
|
93
|
+
codex: { enabled: true, models: ["codex-mini-latest"] },
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const result = resolveEnabledProviders(config, allAvailable);
|
|
97
|
+
|
|
98
|
+
expect(result.length).toBe(1);
|
|
99
|
+
expect(result[0]![0]).toBe("codex");
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it("excludes providers with empty model lists", () => {
|
|
103
|
+
const config = makeModelsConfig({
|
|
104
|
+
claude: { enabled: true, models: [] },
|
|
105
|
+
codex: { enabled: true, models: ["codex-mini-latest"] },
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
const result = resolveEnabledProviders(config, allAvailable);
|
|
109
|
+
|
|
110
|
+
expect(result.length).toBe(1);
|
|
111
|
+
expect(result[0]![0]).toBe("codex");
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it("filters models by preflight results", () => {
|
|
115
|
+
const config = makeModelsConfig({
|
|
116
|
+
claude: { enabled: true, models: ["sonnet", "opus"] },
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const preflightAvailable = new Map([
|
|
120
|
+
["claude", new Set(["sonnet"])],
|
|
121
|
+
]);
|
|
122
|
+
|
|
123
|
+
const result = resolveEnabledProviders(config, allAvailable, preflightAvailable);
|
|
124
|
+
|
|
125
|
+
expect(result.length).toBe(1);
|
|
126
|
+
expect(result[0]![1].models).toEqual(["sonnet"]);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it("skips provider when no models passed preflight", () => {
|
|
130
|
+
const config = makeModelsConfig({
|
|
131
|
+
claude: { enabled: true, models: ["sonnet"] },
|
|
132
|
+
codex: { enabled: true, models: ["codex-mini-latest"] },
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// Only claude passed preflight
|
|
136
|
+
const preflightAvailable = new Map([
|
|
137
|
+
["claude", new Set(["sonnet"])],
|
|
138
|
+
]);
|
|
139
|
+
|
|
140
|
+
const result = resolveEnabledProviders(config, allAvailable, preflightAvailable);
|
|
141
|
+
|
|
142
|
+
expect(result.length).toBe(1);
|
|
143
|
+
expect(result[0]![0]).toBe("claude");
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it("returns empty when no providers are available", () => {
|
|
147
|
+
const config = makeModelsConfig({
|
|
148
|
+
codex: { enabled: true, models: ["codex-mini-latest"] },
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
const result = resolveEnabledProviders(config, noneAvailable);
|
|
152
|
+
|
|
153
|
+
expect(result).toEqual([]);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it("puts unknown providers after known ones in priority", () => {
|
|
157
|
+
const config = makeModelsConfig({
|
|
158
|
+
gemini: { enabled: true, models: ["gemini-pro"] },
|
|
159
|
+
codex: { enabled: true, models: ["codex-mini"] },
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
const result = resolveEnabledProviders(config, allAvailable);
|
|
163
|
+
|
|
164
|
+
expect(result[0]![0]).toBe("codex");
|
|
165
|
+
expect(result[1]![0]).toBe("gemini");
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// ---------------------------------------------------------------------------
|
|
170
|
+
// assignModelsToAgents — uses DI, zero subprocess mocks
|
|
171
|
+
// ---------------------------------------------------------------------------
|
|
172
|
+
|
|
173
|
+
describe("assignModelsToAgents", () => {
|
|
174
|
+
it("assigns provider and model to agents", () => {
|
|
175
|
+
const agents = [makeAgent("a1"), makeAgent("a2")];
|
|
176
|
+
const config = makeModelsConfig({
|
|
177
|
+
claude: { enabled: true, models: ["sonnet"] },
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
const result = assignModelsToAgents(agents, config, undefined, {
|
|
181
|
+
isCliAvailable: allAvailable,
|
|
182
|
+
randomFn: () => 0,
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
expect(result.length).toBe(2);
|
|
186
|
+
expect(result[0]!.provider).toBe("claude");
|
|
187
|
+
expect(result[0]!.model).toBe("sonnet");
|
|
188
|
+
expect(result[1]!.provider).toBe("claude");
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
it("prefers codex over claude when both available", () => {
|
|
192
|
+
const agents = [makeAgent("a1"), makeAgent("a2"), makeAgent("a3")];
|
|
193
|
+
const config = makeModelsConfig({
|
|
194
|
+
claude: { enabled: true, models: ["sonnet"] },
|
|
195
|
+
codex: { enabled: true, models: ["codex-mini-latest"] },
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
const result = assignModelsToAgents(agents, config, undefined, {
|
|
199
|
+
isCliAvailable: allAvailable,
|
|
200
|
+
randomFn: () => 0,
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
expect(result.every(a => a.provider === "codex")).toBe(true);
|
|
204
|
+
expect(result.every(a => a.model === "codex-mini-latest")).toBe(true);
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it("falls back to claude when codex CLI not found", () => {
|
|
208
|
+
const agents = [makeAgent("a1")];
|
|
209
|
+
const config = makeModelsConfig({
|
|
210
|
+
claude: { enabled: true, models: ["sonnet"] },
|
|
211
|
+
codex: { enabled: true, models: ["codex-mini-latest"] },
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
const result = assignModelsToAgents(agents, config, undefined, {
|
|
215
|
+
isCliAvailable: onlyAvailable("claude"),
|
|
216
|
+
randomFn: () => 0,
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
expect(result[0]!.provider).toBe("claude");
|
|
220
|
+
expect(result[0]!.model).toBe("sonnet");
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
it("filters models by preflight results", () => {
|
|
224
|
+
const agents = [makeAgent("a1")];
|
|
225
|
+
const config = makeModelsConfig({
|
|
226
|
+
claude: { enabled: true, models: ["sonnet", "opus"] },
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
const preflightAvailable = new Map([
|
|
230
|
+
["claude", new Set(["sonnet"])],
|
|
231
|
+
]);
|
|
232
|
+
|
|
233
|
+
const result = assignModelsToAgents(agents, config, preflightAvailable, {
|
|
234
|
+
isCliAvailable: allAvailable,
|
|
235
|
+
randomFn: () => 0,
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
expect(result[0]!.provider).toBe("claude");
|
|
239
|
+
expect(result[0]!.model).toBe("sonnet");
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
it("skips provider entirely when no models passed preflight", () => {
|
|
243
|
+
const agents = [makeAgent("a1")];
|
|
244
|
+
const config = makeModelsConfig({
|
|
245
|
+
claude: { enabled: true, models: ["sonnet"] },
|
|
246
|
+
codex: { enabled: true, models: ["codex-mini-latest"] },
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
const preflightAvailable = new Map([
|
|
250
|
+
["claude", new Set(["sonnet"])],
|
|
251
|
+
]);
|
|
252
|
+
|
|
253
|
+
const result = assignModelsToAgents(agents, config, preflightAvailable, {
|
|
254
|
+
isCliAvailable: allAvailable,
|
|
255
|
+
randomFn: () => 0,
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
expect(result[0]!.provider).toBe("claude");
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
it("falls back to claude defaults when all providers fail CLI check", () => {
|
|
262
|
+
const agents = [makeAgent("a1")];
|
|
263
|
+
const config = makeModelsConfig({
|
|
264
|
+
codex: { enabled: true, models: ["codex-mini-latest"] },
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
const result = assignModelsToAgents(agents, config, undefined, {
|
|
268
|
+
isCliAvailable: noneAvailable,
|
|
269
|
+
randomFn: () => 0,
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
expect(result[0]!.provider).toBe("claude");
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
it("skips disabled providers", () => {
|
|
276
|
+
const agents = [makeAgent("a1")];
|
|
277
|
+
const config = makeModelsConfig({
|
|
278
|
+
claude: { enabled: false, models: ["sonnet"] },
|
|
279
|
+
codex: { enabled: true, models: ["codex-mini-latest"] },
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
const result = assignModelsToAgents(agents, config, undefined, {
|
|
283
|
+
isCliAvailable: allAvailable,
|
|
284
|
+
randomFn: () => 0,
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
expect(result[0]!.provider).toBe("codex");
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
it("skips providers with empty model lists", () => {
|
|
291
|
+
const agents = [makeAgent("a1")];
|
|
292
|
+
const config = makeModelsConfig({
|
|
293
|
+
claude: { enabled: true, models: [] },
|
|
294
|
+
codex: { enabled: true, models: ["codex-mini-latest"] },
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
const result = assignModelsToAgents(agents, config, undefined, {
|
|
298
|
+
isCliAvailable: allAvailable,
|
|
299
|
+
randomFn: () => 0,
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
expect(result[0]!.provider).toBe("codex");
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
it("selects deterministic model with randomFn", () => {
|
|
306
|
+
const agents = [makeAgent("a1")];
|
|
307
|
+
const config = makeModelsConfig({
|
|
308
|
+
codex: { enabled: true, models: ["model-a", "model-b"] },
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
// randomFn=0 picks index 0 (model-a)
|
|
312
|
+
const result0 = assignModelsToAgents(agents, config, undefined, {
|
|
313
|
+
isCliAvailable: allAvailable,
|
|
314
|
+
randomFn: () => 0,
|
|
315
|
+
});
|
|
316
|
+
expect(result0[0]!.model).toBe("model-a");
|
|
317
|
+
|
|
318
|
+
// randomFn=0.5 picks index 1 (model-b)
|
|
319
|
+
const result1 = assignModelsToAgents(agents, config, undefined, {
|
|
320
|
+
isCliAvailable: allAvailable,
|
|
321
|
+
randomFn: () => 0.5,
|
|
322
|
+
});
|
|
323
|
+
expect(result1[0]!.model).toBe("model-b");
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
it("preserves agent fields other than provider and model", () => {
|
|
327
|
+
const agent = makeAgent("test-agent");
|
|
328
|
+
agent.focus = "security";
|
|
329
|
+
agent.system_prompt = "Be thorough";
|
|
330
|
+
|
|
331
|
+
const config = makeModelsConfig({
|
|
332
|
+
claude: { enabled: true, models: ["sonnet"] },
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
const result = assignModelsToAgents([agent], config, undefined, {
|
|
336
|
+
isCliAvailable: allAvailable,
|
|
337
|
+
randomFn: () => 0,
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
expect(result[0]!.name).toBe("test-agent");
|
|
341
|
+
expect(result[0]!.focus).toBe("security");
|
|
342
|
+
expect(result[0]!.system_prompt).toBe("Be thorough");
|
|
343
|
+
});
|
|
344
|
+
});
|
|
345
|
+
});
|