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
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TmuxMultiplexer — unified tmux backend.
|
|
3
|
+
* Composes with BashAdapter for command building.
|
|
4
|
+
* Owns: split direction resolution, tmux session config, Windows bootstrap.
|
|
5
|
+
*/
|
|
6
|
+
import { execSync } from 'node:child_process';
|
|
7
|
+
import * as fs from 'node:fs';
|
|
8
|
+
import { sanitizedProcessEnv } from '../env-sanitizer.js';
|
|
9
|
+
import { PANE_HOLD_MESSAGE, getLastLine, spawnAttached, splitFlagFromDimensions } from '../mux-utils.js';
|
|
10
|
+
import { isNonWindowsPlatform, isWindowsPlatform } from '../runtime/platform-adapter.js';
|
|
11
|
+
import { execFileAsync, findExecutable } from '../runtime/subprocess-utils.js';
|
|
12
|
+
import { BashAdapter } from '../shell-adapters/bash-adapter.js';
|
|
13
|
+
import { findBestSplit, listPanes } from '../tmux-pane-placement.js';
|
|
14
|
+
import { toMsysPosixPath } from '../tmux-primitives.js';
|
|
15
|
+
import { buildShellCommand, buildTmuxRuntimeBootstrapCommands, configureTmuxSession } from '../tmux-session.js';
|
|
16
|
+
/** @internal — translate unified SplitDirection to tmux flag. */
|
|
17
|
+
export function toTmuxSplitFlag(direction) {
|
|
18
|
+
return direction === 'horizontal' ? '-h' : '-v';
|
|
19
|
+
}
|
|
20
|
+
/** @internal */
|
|
21
|
+
export function withWindowsTmuxBootstrap(command, platform = process.platform) {
|
|
22
|
+
if (platform !== 'win32')
|
|
23
|
+
return command;
|
|
24
|
+
const bootstrap = buildTmuxRuntimeBootstrapCommands(platform).join('; ');
|
|
25
|
+
return `${bootstrap}; ${command}`;
|
|
26
|
+
}
|
|
27
|
+
/** @internal */
|
|
28
|
+
export function buildTmuxSplitWindowArgs(params) {
|
|
29
|
+
const args = ['split-window', params.splitFlag, '-P', '-F', '#{pane_id}'];
|
|
30
|
+
if (params.cwd) {
|
|
31
|
+
args.push('-c', params.cwd);
|
|
32
|
+
}
|
|
33
|
+
if (params.splitTarget) {
|
|
34
|
+
args.push('-t', params.splitTarget);
|
|
35
|
+
}
|
|
36
|
+
args.push(params.command);
|
|
37
|
+
return args;
|
|
38
|
+
}
|
|
39
|
+
/** @internal */
|
|
40
|
+
export function buildTmuxCreateSessionArgs(params) {
|
|
41
|
+
const args = ['new-session'];
|
|
42
|
+
if (params.reattach)
|
|
43
|
+
args.push('-A');
|
|
44
|
+
args.push('-c', params.cwd, '-s', params.sessionName, params.shellCommand);
|
|
45
|
+
return args;
|
|
46
|
+
}
|
|
47
|
+
async function resolveAutoSplit(tmuxPath, splitTarget) {
|
|
48
|
+
const explicitTarget = splitTarget?.trim();
|
|
49
|
+
if (explicitTarget) {
|
|
50
|
+
const size = await execFileAsync(tmuxPath, ['display-message', '-p', '-t', explicitTarget, '#{pane_width} #{pane_height}'], { timeout: 3000 });
|
|
51
|
+
if (size.exitCode === 0) {
|
|
52
|
+
const parts = size.stdout.trim().split(/\s+/);
|
|
53
|
+
if (parts.length >= 2) {
|
|
54
|
+
const width = Number.parseInt(parts[0] ?? '', 10);
|
|
55
|
+
const height = Number.parseInt(parts[1] ?? '', 10);
|
|
56
|
+
if (Number.isFinite(width) && Number.isFinite(height)) {
|
|
57
|
+
return {
|
|
58
|
+
splitFlag: splitFlagFromDimensions(width, height),
|
|
59
|
+
splitTarget: explicitTarget,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return { splitFlag: '-h', splitTarget: explicitTarget };
|
|
65
|
+
}
|
|
66
|
+
const panes = await listPanes(tmuxPath);
|
|
67
|
+
const placement = findBestSplit(panes);
|
|
68
|
+
if (!placement)
|
|
69
|
+
return { splitFlag: '-h' };
|
|
70
|
+
return {
|
|
71
|
+
splitFlag: placement.splitFlag,
|
|
72
|
+
splitTarget: placement.targetPane,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export class TmuxMultiplexer {
|
|
76
|
+
backend = 'tmux';
|
|
77
|
+
tmuxPath;
|
|
78
|
+
shell;
|
|
79
|
+
constructor(tmuxPath) {
|
|
80
|
+
this.tmuxPath = tmuxPath;
|
|
81
|
+
this.shell = new BashAdapter();
|
|
82
|
+
}
|
|
83
|
+
static create() {
|
|
84
|
+
const tmuxPath = findExecutable('tmux');
|
|
85
|
+
if (!tmuxPath)
|
|
86
|
+
return null;
|
|
87
|
+
return new TmuxMultiplexer(tmuxPath);
|
|
88
|
+
}
|
|
89
|
+
resolveStrategy(ctx) {
|
|
90
|
+
if (ctx.disableMux) {
|
|
91
|
+
return { strategy: 'inline', reason: 'Multiplexer disabled via --no-tmux' };
|
|
92
|
+
}
|
|
93
|
+
if (Boolean(process.env.TMUX)) {
|
|
94
|
+
return { strategy: 'split', reason: 'Inside tmux session' };
|
|
95
|
+
}
|
|
96
|
+
return { strategy: 'create-session', reason: 'Outside tmux — will create new session' };
|
|
97
|
+
}
|
|
98
|
+
async createSession(options) {
|
|
99
|
+
const { sessionName, reattach, cwd } = options;
|
|
100
|
+
if (!isNonWindowsPlatform()) {
|
|
101
|
+
return { launched: false, exitCode: -1, backend: this.backend, reason: 'tmux not available on this platform' };
|
|
102
|
+
}
|
|
103
|
+
// Set default-terminal BEFORE session creation
|
|
104
|
+
try {
|
|
105
|
+
execSync(String.raw `tmux start-server \; set -g default-terminal "tmux-256color"`, { stdio: 'ignore', timeout: 3000 });
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
try {
|
|
109
|
+
execSync(String.raw `tmux start-server \; set -g default-terminal "screen-256color"`, { stdio: 'ignore', timeout: 3000 });
|
|
110
|
+
}
|
|
111
|
+
catch { /* best-effort */ }
|
|
112
|
+
}
|
|
113
|
+
const shellCommand = buildShellCommand({
|
|
114
|
+
sessionName,
|
|
115
|
+
toolPath: options.toolPath,
|
|
116
|
+
toolArgs: options.toolArgs,
|
|
117
|
+
promptText: options.promptText,
|
|
118
|
+
enableMouse: options.enableMouse ?? true,
|
|
119
|
+
});
|
|
120
|
+
const args = buildTmuxCreateSessionArgs({
|
|
121
|
+
sessionName,
|
|
122
|
+
cwd,
|
|
123
|
+
shellCommand,
|
|
124
|
+
reattach,
|
|
125
|
+
});
|
|
126
|
+
return spawnAttached('tmux', args, sanitizedProcessEnv(), this.backend);
|
|
127
|
+
}
|
|
128
|
+
async kill(handle) {
|
|
129
|
+
if (!handle)
|
|
130
|
+
return;
|
|
131
|
+
await execFileAsync(this.tmuxPath, ['kill-pane', '-t', handle], { timeout: 3000 });
|
|
132
|
+
}
|
|
133
|
+
async split(options) {
|
|
134
|
+
const { toolName, args, env, cwd, mode, sentinelPath } = options;
|
|
135
|
+
// Configure tmux session defaults (mouse, scrollback, color)
|
|
136
|
+
configureTmuxSession();
|
|
137
|
+
// Resolve tool path
|
|
138
|
+
const nativePath = findExecutable(toolName);
|
|
139
|
+
if (!nativePath) {
|
|
140
|
+
return { launched: false, backend: this.backend, reason: `${toolName} not found on PATH` };
|
|
141
|
+
}
|
|
142
|
+
const effectiveToolPath = await this.shell.resolveToolPath(toolName, nativePath);
|
|
143
|
+
if (!effectiveToolPath) {
|
|
144
|
+
return { launched: false, backend: this.backend, reason: `${toolName} not found in bash PATH (required for tmux pane)` };
|
|
145
|
+
}
|
|
146
|
+
// Inject COLORTERM=truecolor for tmux
|
|
147
|
+
const effectiveEnv = { COLORTERM: 'truecolor', ...env };
|
|
148
|
+
try {
|
|
149
|
+
const promptText = mode === 'repl' && options.promptPath
|
|
150
|
+
? fs.readFileSync(options.promptPath, 'utf8')
|
|
151
|
+
: undefined;
|
|
152
|
+
let baseCommand = this.shell.buildToolCommand({
|
|
153
|
+
toolPath: effectiveToolPath,
|
|
154
|
+
args,
|
|
155
|
+
env: effectiveEnv,
|
|
156
|
+
mode,
|
|
157
|
+
promptText,
|
|
158
|
+
...(options.promptPath ? { promptPath: options.promptPath } : {}),
|
|
159
|
+
});
|
|
160
|
+
if (options.retryOnQuickExit) {
|
|
161
|
+
baseCommand = this.shell.wrapQuickExitRetry(baseCommand, this.shell.quote(effectiveToolPath));
|
|
162
|
+
}
|
|
163
|
+
const holdMessage = PANE_HOLD_MESSAGE;
|
|
164
|
+
const paneCommand = this.shell.wrapSentinel({
|
|
165
|
+
command: baseCommand,
|
|
166
|
+
sentinelPath,
|
|
167
|
+
autoClose: false,
|
|
168
|
+
holdPane: false,
|
|
169
|
+
holdMessage,
|
|
170
|
+
});
|
|
171
|
+
// Resolve split direction
|
|
172
|
+
const splitDirection = options.split;
|
|
173
|
+
let splitFlag;
|
|
174
|
+
let splitTarget;
|
|
175
|
+
if (splitDirection === 'auto') {
|
|
176
|
+
try {
|
|
177
|
+
const resolved = await resolveAutoSplit(this.tmuxPath);
|
|
178
|
+
splitFlag = resolved.splitFlag;
|
|
179
|
+
splitTarget = resolved.splitTarget;
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
splitFlag = '-h';
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
splitFlag = toTmuxSplitFlag(splitDirection);
|
|
187
|
+
}
|
|
188
|
+
// Build tmux split-window command
|
|
189
|
+
const cwdPath = isWindowsPlatform() ? toMsysPosixPath(cwd) : cwd;
|
|
190
|
+
const bootstrappedCommand = withWindowsTmuxBootstrap(paneCommand);
|
|
191
|
+
const tmuxArgs = buildTmuxSplitWindowArgs({
|
|
192
|
+
splitFlag,
|
|
193
|
+
command: `bash -lc ${this.shell.quote(bootstrappedCommand)}`,
|
|
194
|
+
cwd: cwdPath,
|
|
195
|
+
splitTarget,
|
|
196
|
+
});
|
|
197
|
+
const split = await execFileAsync(this.tmuxPath, tmuxArgs, { timeout: 5000 });
|
|
198
|
+
if (split.exitCode !== 0) {
|
|
199
|
+
return {
|
|
200
|
+
launched: false,
|
|
201
|
+
backend: this.backend,
|
|
202
|
+
reason: 'tmux split-window failed',
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
const handle = getLastLine(split.stdout) || undefined;
|
|
206
|
+
return {
|
|
207
|
+
launched: true,
|
|
208
|
+
backend: this.backend,
|
|
209
|
+
handle,
|
|
210
|
+
sentinelPath,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
return {
|
|
215
|
+
launched: false,
|
|
216
|
+
backend: this.backend,
|
|
217
|
+
reason: `pane launch failed: ${String(error)}`,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WeztermMultiplexer — WezTerm backend for Windows.
|
|
3
|
+
* Composes with BashAdapter for command building.
|
|
4
|
+
* Owns: REPL-context gating (resolveStrategy), WezTerm pane management,
|
|
5
|
+
* holdPane behavior, auto-close command.
|
|
6
|
+
*/
|
|
7
|
+
import type { CreateSessionOptions, LaunchResult, Multiplexer, ResolvedStrategy, SplitOptions, StrategyContext } from '../multiplexer.js';
|
|
8
|
+
type WeztermSplitFlag = '--bottom' | '--right';
|
|
9
|
+
/** @internal — translate unified SplitDirection to wezterm flag. */
|
|
10
|
+
export declare function toWeztermSplitFlag(direction: 'horizontal' | 'vertical'): WeztermSplitFlag;
|
|
11
|
+
/** @internal */
|
|
12
|
+
export declare function buildWeztermSplitArgs(params: {
|
|
13
|
+
bashPath?: string | undefined;
|
|
14
|
+
command: string;
|
|
15
|
+
cwd?: string | undefined;
|
|
16
|
+
paneId?: string | undefined;
|
|
17
|
+
splitFlag: WeztermSplitFlag;
|
|
18
|
+
}): string[];
|
|
19
|
+
/** @internal */
|
|
20
|
+
export declare function buildWeztermSpawnArgs(params: {
|
|
21
|
+
bashPath?: string | undefined;
|
|
22
|
+
command: string;
|
|
23
|
+
cwd?: string | undefined;
|
|
24
|
+
}): string[];
|
|
25
|
+
/** @internal */
|
|
26
|
+
export declare function buildWeztermKillArgs(paneId: string): string[];
|
|
27
|
+
export declare class WeztermMultiplexer implements Multiplexer {
|
|
28
|
+
readonly backend: "wezterm";
|
|
29
|
+
private readonly weztermPath;
|
|
30
|
+
private readonly shell;
|
|
31
|
+
private constructor();
|
|
32
|
+
static create(): null | WeztermMultiplexer;
|
|
33
|
+
resolveStrategy(ctx: StrategyContext): ResolvedStrategy;
|
|
34
|
+
kill(handle: string): Promise<void>;
|
|
35
|
+
split(options: SplitOptions): Promise<LaunchResult>;
|
|
36
|
+
createSession(options: CreateSessionOptions): Promise<LaunchResult>;
|
|
37
|
+
}
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WeztermMultiplexer — WezTerm backend for Windows.
|
|
3
|
+
* Composes with BashAdapter for command building.
|
|
4
|
+
* Owns: REPL-context gating (resolveStrategy), WezTerm pane management,
|
|
5
|
+
* holdPane behavior, auto-close command.
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from 'node:fs';
|
|
8
|
+
import { PANE_HOLD_MESSAGE, getLastLine, splitFlagFromDimensions } from '../mux-utils.js';
|
|
9
|
+
import { execFileAsync, findExecutable } from '../runtime/subprocess-utils.js';
|
|
10
|
+
import { BashAdapter } from '../shell-adapters/bash-adapter.js';
|
|
11
|
+
/** @internal — translate unified SplitDirection to wezterm flag. */
|
|
12
|
+
export function toWeztermSplitFlag(direction) {
|
|
13
|
+
return direction === 'horizontal' ? '--right' : '--bottom';
|
|
14
|
+
}
|
|
15
|
+
/** @internal */
|
|
16
|
+
export function buildWeztermSplitArgs(params) {
|
|
17
|
+
const args = ['cli', 'split-pane', params.splitFlag];
|
|
18
|
+
if (params.cwd) {
|
|
19
|
+
args.push('--cwd', params.cwd);
|
|
20
|
+
}
|
|
21
|
+
if (params.paneId) {
|
|
22
|
+
args.push('--pane-id', params.paneId);
|
|
23
|
+
}
|
|
24
|
+
// Use -c (not -lc): login shell profiles may exec another shell (e.g. zsh),
|
|
25
|
+
// preventing the command from running. Tool paths are already absolute.
|
|
26
|
+
args.push('--', params.bashPath ?? 'bash', '-c', params.command);
|
|
27
|
+
return args;
|
|
28
|
+
}
|
|
29
|
+
/** @internal */
|
|
30
|
+
export function buildWeztermSpawnArgs(params) {
|
|
31
|
+
const args = ['cli', 'spawn', '--new-window'];
|
|
32
|
+
if (params.cwd) {
|
|
33
|
+
args.push('--cwd', params.cwd);
|
|
34
|
+
}
|
|
35
|
+
args.push('--', params.bashPath ?? 'bash', '-c', params.command);
|
|
36
|
+
return args;
|
|
37
|
+
}
|
|
38
|
+
/** @internal */
|
|
39
|
+
export function buildWeztermKillArgs(paneId) {
|
|
40
|
+
return ['cli', 'kill-pane', '--pane-id', paneId];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Resolve Git Bash path on Windows. WezTerm may resolve bare `bash` to
|
|
44
|
+
* WSL's bash.exe instead of Git Bash.
|
|
45
|
+
*/
|
|
46
|
+
function resolveGitBash() {
|
|
47
|
+
return findExecutable('bash');
|
|
48
|
+
}
|
|
49
|
+
async function resolveAutoSplit(weztermPath, currentPaneId) {
|
|
50
|
+
try {
|
|
51
|
+
const result = await execFileAsync(weztermPath, ['cli', 'list', '--format', 'json'], { timeout: 3000 });
|
|
52
|
+
if (result.exitCode !== 0)
|
|
53
|
+
return '--right';
|
|
54
|
+
const panes = JSON.parse(result.stdout);
|
|
55
|
+
const targetId = currentPaneId ?? process.env.WEZTERM_PANE;
|
|
56
|
+
if (!targetId)
|
|
57
|
+
return '--right';
|
|
58
|
+
const pane = panes.find((p) => String(p.pane_id) === targetId);
|
|
59
|
+
if (!pane?.size)
|
|
60
|
+
return '--right';
|
|
61
|
+
const muxFlag = splitFlagFromDimensions(pane.size.cols, pane.size.rows);
|
|
62
|
+
return muxFlag === '-h' ? '--right' : '--bottom';
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return '--right';
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export class WeztermMultiplexer {
|
|
69
|
+
backend = 'wezterm';
|
|
70
|
+
weztermPath;
|
|
71
|
+
shell;
|
|
72
|
+
constructor(weztermPath) {
|
|
73
|
+
this.weztermPath = weztermPath;
|
|
74
|
+
this.shell = new BashAdapter();
|
|
75
|
+
}
|
|
76
|
+
static create() {
|
|
77
|
+
if (!process.env.WEZTERM_PANE && process.env.TERM_PROGRAM !== 'WezTerm')
|
|
78
|
+
return null;
|
|
79
|
+
const weztermPath = findExecutable('wezterm');
|
|
80
|
+
if (!weztermPath)
|
|
81
|
+
return null;
|
|
82
|
+
return new WeztermMultiplexer(weztermPath);
|
|
83
|
+
}
|
|
84
|
+
resolveStrategy(ctx) {
|
|
85
|
+
if (ctx.disableMux) {
|
|
86
|
+
return { strategy: 'inline', reason: 'Multiplexer disabled via --no-tmux' };
|
|
87
|
+
}
|
|
88
|
+
// REPL-context gating: only split when called from a REPL session.
|
|
89
|
+
// From a shell (no REPL vars), launch inline.
|
|
90
|
+
if (!ctx.calledFromRepl) {
|
|
91
|
+
return { strategy: 'inline', reason: 'WezTerm shell — no REPL context, launching inline' };
|
|
92
|
+
}
|
|
93
|
+
return { strategy: 'split', reason: 'Inside WezTerm REPL — splitting pane' };
|
|
94
|
+
}
|
|
95
|
+
async kill(handle) {
|
|
96
|
+
if (!handle)
|
|
97
|
+
return;
|
|
98
|
+
await execFileAsync(this.weztermPath, buildWeztermKillArgs(handle), { timeout: 3000 });
|
|
99
|
+
}
|
|
100
|
+
async split(options) {
|
|
101
|
+
const { toolName, args, env, cwd, mode, sentinelPath } = options;
|
|
102
|
+
// Resolve tool path
|
|
103
|
+
const nativePath = findExecutable(toolName);
|
|
104
|
+
if (!nativePath) {
|
|
105
|
+
return { launched: false, backend: this.backend, reason: `${toolName} not found on PATH` };
|
|
106
|
+
}
|
|
107
|
+
const effectiveToolPath = await this.shell.resolveToolPath(toolName, nativePath);
|
|
108
|
+
if (!effectiveToolPath) {
|
|
109
|
+
return { launched: false, backend: this.backend, reason: `${toolName} not found in bash PATH (required for wezterm pane)` };
|
|
110
|
+
}
|
|
111
|
+
try {
|
|
112
|
+
const promptText = mode === 'repl' && options.promptPath
|
|
113
|
+
? fs.readFileSync(options.promptPath, 'utf8')
|
|
114
|
+
: undefined;
|
|
115
|
+
let baseCommand = this.shell.buildToolCommand({
|
|
116
|
+
toolPath: effectiveToolPath,
|
|
117
|
+
args,
|
|
118
|
+
env,
|
|
119
|
+
mode,
|
|
120
|
+
promptText,
|
|
121
|
+
...(options.promptPath ? { promptPath: options.promptPath } : {}),
|
|
122
|
+
});
|
|
123
|
+
if (options.retryOnQuickExit) {
|
|
124
|
+
baseCommand = this.shell.wrapQuickExitRetry(baseCommand, this.shell.quote(effectiveToolPath));
|
|
125
|
+
}
|
|
126
|
+
const gitBash = process.platform === 'win32' ? resolveGitBash() ?? undefined : undefined;
|
|
127
|
+
// WezTerm always holds pane and uses auto-close via wezterm kill-pane
|
|
128
|
+
const holdMessage = PANE_HOLD_MESSAGE;
|
|
129
|
+
let paneCommand = this.shell.wrapSentinel({
|
|
130
|
+
command: baseCommand,
|
|
131
|
+
sentinelPath,
|
|
132
|
+
autoClose: false,
|
|
133
|
+
autoCloseCommand: `wezterm cli kill-pane --pane-id $WEZTERM_PANE >/dev/null 2>&1 || true`,
|
|
134
|
+
holdPane: true,
|
|
135
|
+
holdMessage,
|
|
136
|
+
});
|
|
137
|
+
// Prepend nesting cleanup (PATH fix + unset REPL vars)
|
|
138
|
+
paneCommand = `${this.shell.buildNestingCleanup()} ${paneCommand}`;
|
|
139
|
+
// Resolve split direction
|
|
140
|
+
const splitDirection = options.split;
|
|
141
|
+
let splitFlag;
|
|
142
|
+
if (splitDirection === 'auto') {
|
|
143
|
+
splitFlag = await resolveAutoSplit(this.weztermPath);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
splitFlag = toWeztermSplitFlag(splitDirection);
|
|
147
|
+
}
|
|
148
|
+
const weztermArgs = buildWeztermSplitArgs({
|
|
149
|
+
splitFlag,
|
|
150
|
+
command: paneCommand,
|
|
151
|
+
cwd,
|
|
152
|
+
paneId: process.env.WEZTERM_PANE,
|
|
153
|
+
bashPath: gitBash,
|
|
154
|
+
});
|
|
155
|
+
const split = await execFileAsync(this.weztermPath, weztermArgs, { timeout: 5000 });
|
|
156
|
+
if (split.exitCode !== 0) {
|
|
157
|
+
return {
|
|
158
|
+
launched: false,
|
|
159
|
+
backend: this.backend,
|
|
160
|
+
reason: 'wezterm split-pane failed',
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
const handle = getLastLine(split.stdout) || undefined;
|
|
164
|
+
return {
|
|
165
|
+
launched: true,
|
|
166
|
+
backend: this.backend,
|
|
167
|
+
handle,
|
|
168
|
+
sentinelPath,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
return {
|
|
173
|
+
launched: false,
|
|
174
|
+
backend: this.backend,
|
|
175
|
+
reason: `pane launch failed: ${String(error)}`,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
async createSession(options) {
|
|
180
|
+
const { toolPath, toolArgs, cwd } = options;
|
|
181
|
+
// On Windows, resolve tool path from bash's perspective
|
|
182
|
+
let effectiveToolPath = toolPath;
|
|
183
|
+
if (process.platform === 'win32') {
|
|
184
|
+
const toolName = toolPath.split(/[\\/]/).pop()?.replace(/\.exe$/i, '') ?? toolPath;
|
|
185
|
+
const bashPath = await this.shell.resolveToolPath(toolName, toolPath);
|
|
186
|
+
if (bashPath) {
|
|
187
|
+
effectiveToolPath = bashPath;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
const baseCommand = this.shell.buildToolCommand({
|
|
191
|
+
toolPath: effectiveToolPath,
|
|
192
|
+
args: toolArgs,
|
|
193
|
+
env: {},
|
|
194
|
+
mode: 'repl',
|
|
195
|
+
promptText: options.promptText,
|
|
196
|
+
});
|
|
197
|
+
// Prepend nesting cleanup
|
|
198
|
+
const spawnCommand = `${this.shell.buildNestingCleanup()} ${baseCommand}`;
|
|
199
|
+
const weztermArgs = buildWeztermSpawnArgs({
|
|
200
|
+
command: spawnCommand,
|
|
201
|
+
cwd,
|
|
202
|
+
bashPath: process.platform === 'win32' ? resolveGitBash() ?? undefined : undefined,
|
|
203
|
+
});
|
|
204
|
+
try {
|
|
205
|
+
const result = await execFileAsync(this.weztermPath, weztermArgs, { timeout: 5000 });
|
|
206
|
+
if (result.exitCode !== 0) {
|
|
207
|
+
return {
|
|
208
|
+
launched: false,
|
|
209
|
+
exitCode: result.exitCode,
|
|
210
|
+
backend: this.backend,
|
|
211
|
+
reason: `wezterm spawn failed: ${result.stderr.trim() || 'unknown error'}`,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
return { launched: true, exitCode: 0, backend: this.backend };
|
|
215
|
+
}
|
|
216
|
+
catch (error) {
|
|
217
|
+
return {
|
|
218
|
+
launched: false,
|
|
219
|
+
exitCode: -1,
|
|
220
|
+
backend: this.backend,
|
|
221
|
+
reason: `wezterm spawn failed: ${String(error)}`,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { LaunchResult } from './multiplexer.js';
|
|
2
|
+
export declare function getLastLine(text: string): string;
|
|
3
|
+
export declare function spawnAttached(command: string, args: string[], env: NodeJS.ProcessEnv | undefined, backendLabel: string): Promise<LaunchResult>;
|
|
4
|
+
export declare function splitFlagFromDimensions(width: number, height: number): '-h' | '-v';
|
|
5
|
+
export declare const PANE_HOLD_MESSAGE = "[aiwcli] Driver exited. Pane held open.";
|
|
6
|
+
export declare function buildBootstrapPrompt(filePath: string): string;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
const CELL_ASPECT_RATIO = 2;
|
|
3
|
+
export function getLastLine(text) {
|
|
4
|
+
const lines = text.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
5
|
+
return lines.at(-1) ?? '';
|
|
6
|
+
}
|
|
7
|
+
export function spawnAttached(command, args, env, backendLabel) {
|
|
8
|
+
return new Promise((resolve) => {
|
|
9
|
+
let child;
|
|
10
|
+
try {
|
|
11
|
+
child = spawn(command, args, { stdio: 'inherit', env: env ?? process.env });
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
resolve({ launched: false, exitCode: -1, backend: backendLabel, reason: error instanceof Error ? error.message : String(error) });
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
child.on('error', (error) => {
|
|
18
|
+
resolve({ launched: false, exitCode: -1, backend: backendLabel, reason: error.message });
|
|
19
|
+
});
|
|
20
|
+
child.on('close', (code) => {
|
|
21
|
+
if (code === 0) {
|
|
22
|
+
resolve({ launched: true, exitCode: 0, backend: backendLabel });
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
resolve({ launched: false, exitCode: code ?? 1, backend: backendLabel, reason: `${backendLabel} exited with code ${code ?? 1}` });
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
export function splitFlagFromDimensions(width, height) {
|
|
31
|
+
return width >= height * CELL_ASPECT_RATIO ? '-h' : '-v';
|
|
32
|
+
}
|
|
33
|
+
export const PANE_HOLD_MESSAGE = '[aiwcli] Driver exited. Pane held open.';
|
|
34
|
+
export function buildBootstrapPrompt(filePath) {
|
|
35
|
+
return `Read startup instructions from this file path before taking action: ${filePath}. Use that file as the initial context.`;
|
|
36
|
+
}
|
package/dist/lib/paths.d.ts
CHANGED
|
@@ -13,14 +13,14 @@ export declare function expandPath(inputPath: string): string;
|
|
|
13
13
|
/**
|
|
14
14
|
* Convert a path to Unix-style forward slashes.
|
|
15
15
|
* Useful for cross-platform logging or display.
|
|
16
|
-
* @param inputPath - Path with
|
|
16
|
+
* @param inputPath - Path with unknown separator style
|
|
17
17
|
* @returns Path with forward slashes only
|
|
18
18
|
*/
|
|
19
19
|
export declare function toUnixPath(inputPath: string): string;
|
|
20
20
|
/**
|
|
21
21
|
* Convert a path to Windows-style backslashes.
|
|
22
22
|
* Useful for cross-platform logging or display.
|
|
23
|
-
* @param inputPath - Path with
|
|
23
|
+
* @param inputPath - Path with unknown separator style
|
|
24
24
|
* @returns Path with backslashes only
|
|
25
25
|
*/
|
|
26
26
|
export declare function toWindowsPath(inputPath: string): string;
|
package/dist/lib/paths.js
CHANGED
|
@@ -31,7 +31,7 @@ export function expandPath(inputPath) {
|
|
|
31
31
|
/**
|
|
32
32
|
* Convert a path to Unix-style forward slashes.
|
|
33
33
|
* Useful for cross-platform logging or display.
|
|
34
|
-
* @param inputPath - Path with
|
|
34
|
+
* @param inputPath - Path with unknown separator style
|
|
35
35
|
* @returns Path with forward slashes only
|
|
36
36
|
*/
|
|
37
37
|
export function toUnixPath(inputPath) {
|
|
@@ -40,7 +40,7 @@ export function toUnixPath(inputPath) {
|
|
|
40
40
|
/**
|
|
41
41
|
* Convert a path to Windows-style backslashes.
|
|
42
42
|
* Useful for cross-platform logging or display.
|
|
43
|
-
* @param inputPath - Path with
|
|
43
|
+
* @param inputPath - Path with unknown separator style
|
|
44
44
|
* @returns Path with backslashes only
|
|
45
45
|
*/
|
|
46
46
|
export function toWindowsPath(inputPath) {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform-specific hook command adaptation.
|
|
3
|
+
*
|
|
4
|
+
* Claude Code on Windows uses cmd.exe to execute hook commands (Node.js
|
|
5
|
+
* child_process.exec defaults to process.env.ComSpec). Template commands use
|
|
6
|
+
* bash syntax (~/ expansion, env-var prefixes) that cmd.exe can't parse.
|
|
7
|
+
*
|
|
8
|
+
* This module rewrites commands at settings-reconstruction time so they work
|
|
9
|
+
* in cmd.exe while remaining valid in bash on Unix (where it's a no-op).
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Resolver path token that appears in all template hook commands.
|
|
13
|
+
* Shared between templates and adapter — changing this requires updating
|
|
14
|
+
* all template settings.json files AND tests.
|
|
15
|
+
*/
|
|
16
|
+
export declare const RESOLVER_TOKEN = ".aiwcli/_core/scripts/resolve-run.ts";
|
|
17
|
+
/**
|
|
18
|
+
* Adapt a hook command for the current platform.
|
|
19
|
+
* On Windows: strips bash env prefixes, quotes the resolver path.
|
|
20
|
+
* On Unix: no-op (returns input unchanged).
|
|
21
|
+
*/
|
|
22
|
+
export declare function adaptHookCommand(command: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* Post-reconstruction validation. On Windows, asserts no command contains
|
|
25
|
+
* bash-only syntax. Throws with actionable message if validation fails.
|
|
26
|
+
*/
|
|
27
|
+
export declare function validateCommandsForPlatform(commands: string[]): void;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform-specific hook command adaptation.
|
|
3
|
+
*
|
|
4
|
+
* Claude Code on Windows uses cmd.exe to execute hook commands (Node.js
|
|
5
|
+
* child_process.exec defaults to process.env.ComSpec). Template commands use
|
|
6
|
+
* bash syntax (~/ expansion, env-var prefixes) that cmd.exe can't parse.
|
|
7
|
+
*
|
|
8
|
+
* This module rewrites commands at settings-reconstruction time so they work
|
|
9
|
+
* in cmd.exe while remaining valid in bash on Unix (where it's a no-op).
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Resolver path token that appears in all template hook commands.
|
|
13
|
+
* Shared between templates and adapter — changing this requires updating
|
|
14
|
+
* all template settings.json files AND tests.
|
|
15
|
+
*/
|
|
16
|
+
export const RESOLVER_TOKEN = '.aiwcli/_core/scripts/resolve-run.ts';
|
|
17
|
+
/** Matches leading bash-style env-var prefixes: KEY=VALUE KEY2= ... */
|
|
18
|
+
const BASH_ENV_PREFIX_RE = /^(?:[A-Z_]+=\S*\s+)+/;
|
|
19
|
+
/**
|
|
20
|
+
* Adapt a hook command for the current platform.
|
|
21
|
+
* On Windows: strips bash env prefixes, quotes the resolver path.
|
|
22
|
+
* On Unix: no-op (returns input unchanged).
|
|
23
|
+
*/
|
|
24
|
+
export function adaptHookCommand(command) {
|
|
25
|
+
if (process.platform !== 'win32')
|
|
26
|
+
return command;
|
|
27
|
+
const quotedResolver = `"${RESOLVER_TOKEN}"`;
|
|
28
|
+
let result = command.replace(BASH_ENV_PREFIX_RE, '');
|
|
29
|
+
result = result.replace(RESOLVER_TOKEN, quotedResolver);
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Post-reconstruction validation. On Windows, asserts no command contains
|
|
34
|
+
* bash-only syntax. Throws with actionable message if validation fails.
|
|
35
|
+
*/
|
|
36
|
+
export function validateCommandsForPlatform(commands) {
|
|
37
|
+
if (process.platform !== 'win32')
|
|
38
|
+
return;
|
|
39
|
+
for (const cmd of commands) {
|
|
40
|
+
if (cmd.includes('~/')) {
|
|
41
|
+
throw new Error(`Hook command contains unexpanded ~/: "${cmd}". ` +
|
|
42
|
+
'All hook commands must use RESOLVER_TOKEN from platform-commands.ts.');
|
|
43
|
+
}
|
|
44
|
+
if (BASH_ENV_PREFIX_RE.test(cmd)) {
|
|
45
|
+
throw new Error(`Hook command contains bash env prefix: "${cmd}". ` +
|
|
46
|
+
'Move env vars into resolve-run.ts spawn env instead.');
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PromptFileManager — owns prompt file lifecycle (creation, cleanup).
|
|
3
|
+
* Replaces scattered writeFileSync calls for prompt temp files.
|
|
4
|
+
*/
|
|
5
|
+
export declare class PromptFileManager {
|
|
6
|
+
private readonly files;
|
|
7
|
+
private readonly tempDir;
|
|
8
|
+
private readonly now;
|
|
9
|
+
private readonly pid;
|
|
10
|
+
constructor(options: {
|
|
11
|
+
tempDir: string;
|
|
12
|
+
now: () => number;
|
|
13
|
+
pid: number;
|
|
14
|
+
});
|
|
15
|
+
/**
|
|
16
|
+
* Write prompt text to a temp file and return the path.
|
|
17
|
+
*/
|
|
18
|
+
materialize(promptText: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Clean up all created prompt files. Call in finally block.
|
|
21
|
+
*/
|
|
22
|
+
cleanup(): void;
|
|
23
|
+
}
|