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,261 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { checkVersionCompatibility, detectMultiplexer, ensureLspPatch, findExecutable, findToolPath, getClaudeCodeVersion, launchTerminal, ProcessSpawnError, quoteForSh, spawnProcess, } from '../../../platform/launch.js';
|
|
3
|
+
import { EXIT_CODES } from '../../../types/index.js';
|
|
4
|
+
import { clearProcessNestingVars, isCalledFromRepl } from '../../../lib/env-sanitizer.js';
|
|
5
|
+
import { PromptFileManager } from '../../../lib/prompt-file-manager.js';
|
|
6
|
+
import { SentinelManager } from '../../../lib/sentinel-manager.js';
|
|
7
|
+
import { formatPathWarning } from '../../../lib/spawn-errors.js';
|
|
8
|
+
import { buildSpawnedWindowArgs, parseExtraEnv, resolvePromptText, } from '../runtime-core/launch-options.js';
|
|
9
|
+
import { buildInlineArgs, buildSessionRequest, buildSplitRequest, formatSessionLaunchMessage, formatSplitSuccessMessage, formatVersionCheckMessages, QUICK_EXIT_THRESHOLD_MS, resolveInlineFallbackMessage, resolveSessionFallbackWarning, resolveToolConfig, resolveToolModeDebugMessage, shouldRetry, toJsonLaunchResult, } from '../runtime-core/launch-decisions.js';
|
|
10
|
+
async function runPreflightWarmup(command, host) {
|
|
11
|
+
try {
|
|
12
|
+
const result = await spawnProcess(command, ['--version'], { stdio: 'pipe' });
|
|
13
|
+
host.debug(`${command} preflight: exit=${result}`);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
host.debug(`${command} preflight failed (non-fatal)`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
async function spawnInlineWithRetry(command, args, retryOnQuickExit, host) {
|
|
20
|
+
if (retryOnQuickExit) {
|
|
21
|
+
await runPreflightWarmup(command, host);
|
|
22
|
+
}
|
|
23
|
+
const start = Date.now();
|
|
24
|
+
let exitCode = await spawnProcess(command, args);
|
|
25
|
+
if (retryOnQuickExit && shouldRetry(Date.now() - start)) {
|
|
26
|
+
host.debug(`${command} exited in <${QUICK_EXIT_THRESHOLD_MS}ms — retrying (first-run init behavior)`);
|
|
27
|
+
exitCode = await spawnProcess(command, args);
|
|
28
|
+
}
|
|
29
|
+
return exitCode;
|
|
30
|
+
}
|
|
31
|
+
export async function executeLaunch(request, dependencies) {
|
|
32
|
+
const { cwd, flags, interactiveTty, platform, readPromptFile } = request;
|
|
33
|
+
const { host, now, pid, tempDir, writePromptFile } = dependencies;
|
|
34
|
+
// 1. Capture REPL context BEFORE clearing env vars (injectable for testing)
|
|
35
|
+
const calledFromRepl = (dependencies.isCalledFromRepl ?? isCalledFromRepl)();
|
|
36
|
+
(dependencies.clearNestingVars ?? clearProcessNestingVars)();
|
|
37
|
+
// Pure decision: resolve tool config
|
|
38
|
+
const toolConfig = resolveToolConfig(flags, platform);
|
|
39
|
+
const { cliCommand, cliArgs, launchFlag, toolMode } = toolConfig;
|
|
40
|
+
const disableMux = flags['no-tmux'];
|
|
41
|
+
const wantJson = flags.json;
|
|
42
|
+
const wantWait = flags.wait;
|
|
43
|
+
if (toolConfig.needsLspPatch) {
|
|
44
|
+
await ensureLspPatch({
|
|
45
|
+
debugLog: (message) => host.debug(message),
|
|
46
|
+
warn(message) {
|
|
47
|
+
host.warn(message);
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
let extraEnv = {};
|
|
52
|
+
try {
|
|
53
|
+
extraEnv = parseExtraEnv(flags.env);
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
host.error(error instanceof Error ? error.message : '--env must be a valid JSON object string', {
|
|
57
|
+
exit: EXIT_CODES.INVALID_USAGE,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
const promptPath = flags['prompt-path']?.trim() || undefined;
|
|
61
|
+
const promptText = resolvePromptText(flags.prompt, flags['prompt-file'], readPromptFile);
|
|
62
|
+
// 2. Handle --new (terminal window)
|
|
63
|
+
if (flags.new) {
|
|
64
|
+
host.debug(`Launching new terminal in: ${cwd}`);
|
|
65
|
+
let promptFilePath;
|
|
66
|
+
if (!promptPath && promptText) {
|
|
67
|
+
promptFilePath = path.join(tempDir, `aiwcli-prompt-${now()}-${pid}.txt`);
|
|
68
|
+
writePromptFile(promptFilePath, promptText);
|
|
69
|
+
}
|
|
70
|
+
const launchArgs = buildSpawnedWindowArgs({
|
|
71
|
+
useCodex: flags.codex,
|
|
72
|
+
useDevin: flags.devin,
|
|
73
|
+
disableTmux: disableMux,
|
|
74
|
+
...(promptPath ? { promptPath } : {}),
|
|
75
|
+
...(promptFilePath ? { promptFilePath } : {}),
|
|
76
|
+
...(flags.env ? { rawEnvJson: flags.env } : {}),
|
|
77
|
+
...(flags['tmux-session'] ? { tmuxSessionFlag: flags['tmux-session'] } : {}),
|
|
78
|
+
});
|
|
79
|
+
const launchCmd = launchArgs.map((arg) => quoteForSh(arg)).join(' ');
|
|
80
|
+
const result = await launchTerminal({
|
|
81
|
+
cwd,
|
|
82
|
+
command: launchCmd,
|
|
83
|
+
windowsShellPreference: platform === 'win32' ? 'mintty' : 'default',
|
|
84
|
+
debugLog: (message) => host.debug(message),
|
|
85
|
+
});
|
|
86
|
+
if (!result.success) {
|
|
87
|
+
host.error(`Failed to launch new terminal: ${result.error}`, { exit: EXIT_CODES.GENERAL_ERROR });
|
|
88
|
+
}
|
|
89
|
+
host.log(`New terminal launched with aiw launch${launchFlag ? ` ${launchFlag}` : ''}`);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const toolDebugMsg = resolveToolModeDebugMessage(toolMode);
|
|
93
|
+
if (toolDebugMsg)
|
|
94
|
+
host.debug(toolDebugMsg);
|
|
95
|
+
// 3. Detect multiplexer + version check
|
|
96
|
+
const [versionCheck, mux] = await Promise.all([
|
|
97
|
+
toolConfig.skipVersionCheck
|
|
98
|
+
? null
|
|
99
|
+
: getClaudeCodeVersion().then((v) => checkVersionCompatibility(v)),
|
|
100
|
+
disableMux ? null : detectMultiplexer(platform),
|
|
101
|
+
]);
|
|
102
|
+
if (versionCheck) {
|
|
103
|
+
const msgs = formatVersionCheckMessages(versionCheck);
|
|
104
|
+
for (const line of msgs.debugLines)
|
|
105
|
+
host.debug(line);
|
|
106
|
+
if (msgs.warning)
|
|
107
|
+
host.warn(msgs.warning);
|
|
108
|
+
}
|
|
109
|
+
// 4. Resolve strategy — backend decides
|
|
110
|
+
const resolved = mux?.resolveStrategy({ calledFromRepl, platform, disableMux })
|
|
111
|
+
?? { strategy: 'inline', reason: 'No multiplexer available' };
|
|
112
|
+
if (!mux || resolved.strategy === 'inline' || resolved.strategy === 'unavailable') {
|
|
113
|
+
// Pure decision: resolve fallback message
|
|
114
|
+
host.logInfo(resolveInlineFallbackMessage({
|
|
115
|
+
disableMux,
|
|
116
|
+
hasMux: Boolean(mux),
|
|
117
|
+
interactiveTty,
|
|
118
|
+
platform,
|
|
119
|
+
resolvedReason: resolved.reason,
|
|
120
|
+
}));
|
|
121
|
+
try {
|
|
122
|
+
// Pure decision: build inline args
|
|
123
|
+
const inlineArgs = buildInlineArgs(cliArgs, toolMode, promptText, promptPath);
|
|
124
|
+
const exitCode = await spawnInlineWithRetry(cliCommand, inlineArgs, toolConfig.retryOnQuickExit, host);
|
|
125
|
+
host.exit(exitCode);
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
if (error instanceof ProcessSpawnError) {
|
|
129
|
+
host.error(error.message, { exit: EXIT_CODES.ENVIRONMENT_ERROR });
|
|
130
|
+
}
|
|
131
|
+
host.error('Unexpected launch failure.', { exit: EXIT_CODES.GENERAL_ERROR });
|
|
132
|
+
}
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
// Lifecycle managers
|
|
136
|
+
const sentinelMgr = new SentinelManager();
|
|
137
|
+
const promptMgr = new PromptFileManager({ tempDir, now, pid });
|
|
138
|
+
// When --json is used without --wait, sentinel ownership transfers to the
|
|
139
|
+
// JSON caller (e.g. skill scripts). The CLI must NOT clean up the sentinel
|
|
140
|
+
// directory because the caller polls for sentinel.txt to detect pane close.
|
|
141
|
+
let sentinelOwnershipTransferred = false;
|
|
142
|
+
let exitCode = 0;
|
|
143
|
+
try {
|
|
144
|
+
const strategy = resolved.strategy;
|
|
145
|
+
if (strategy === 'split') {
|
|
146
|
+
// 5a. Split pane
|
|
147
|
+
host.logInfo(`Inside ${mux.backend} session — splitting new pane`);
|
|
148
|
+
const sentinelPath = sentinelMgr.create(cliCommand);
|
|
149
|
+
let effectivePromptPath = promptPath;
|
|
150
|
+
if (!effectivePromptPath && promptText) {
|
|
151
|
+
effectivePromptPath = promptMgr.materialize(promptText);
|
|
152
|
+
}
|
|
153
|
+
// Pure decision: build split request (fixes cliArgs mutation bug)
|
|
154
|
+
const splitParams = buildSplitRequest({
|
|
155
|
+
cliArgs,
|
|
156
|
+
toolMode,
|
|
157
|
+
effectivePromptPath,
|
|
158
|
+
extraEnv,
|
|
159
|
+
cwd,
|
|
160
|
+
split: flags.split ?? 'auto',
|
|
161
|
+
sentinelPath,
|
|
162
|
+
retryOnQuickExit: toolConfig.retryOnQuickExit,
|
|
163
|
+
});
|
|
164
|
+
const splitResult = await mux.split({
|
|
165
|
+
toolName: cliCommand,
|
|
166
|
+
args: splitParams.toolArgs,
|
|
167
|
+
env: splitParams.env,
|
|
168
|
+
cwd: splitParams.cwd,
|
|
169
|
+
mode: splitParams.mode,
|
|
170
|
+
split: splitParams.split,
|
|
171
|
+
promptPath: splitParams.splitPromptPath,
|
|
172
|
+
sentinelPath: splitParams.sentinelPath,
|
|
173
|
+
holdPane: splitParams.holdPane,
|
|
174
|
+
retryOnQuickExit: splitParams.retryOnQuickExit,
|
|
175
|
+
});
|
|
176
|
+
if (wantJson) {
|
|
177
|
+
const jsonExitCode = wantWait && splitResult.launched && splitResult.sentinelPath
|
|
178
|
+
? await sentinelMgr.waitForExit(splitResult.sentinelPath)
|
|
179
|
+
: splitResult.exitCode ?? null;
|
|
180
|
+
// When returning sentinel path to caller without waiting, transfer
|
|
181
|
+
// ownership so the finally block does not delete the directory.
|
|
182
|
+
if (!wantWait && splitResult.launched && splitResult.sentinelPath) {
|
|
183
|
+
sentinelOwnershipTransferred = true;
|
|
184
|
+
}
|
|
185
|
+
host.log(JSON.stringify(toJsonLaunchResult(splitResult, jsonExitCode)));
|
|
186
|
+
host.exit(jsonExitCode ?? 0);
|
|
187
|
+
}
|
|
188
|
+
if (splitResult.launched) {
|
|
189
|
+
host.logInfo(formatSplitSuccessMessage(mux.backend, splitResult.handle));
|
|
190
|
+
if (wantWait && splitResult.sentinelPath) {
|
|
191
|
+
const waitedExitCode = await sentinelMgr.waitForExit(splitResult.sentinelPath);
|
|
192
|
+
host.exit(waitedExitCode ?? 1);
|
|
193
|
+
}
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
host.logWarning(`Pane split failed (${splitResult.reason}), launching directly`);
|
|
197
|
+
// Pure decision: build inline args for fallback
|
|
198
|
+
const fallbackArgs = buildInlineArgs(cliArgs, toolMode, promptText, promptPath);
|
|
199
|
+
exitCode = await spawnInlineWithRetry(cliCommand, fallbackArgs, toolConfig.retryOnQuickExit, host);
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
// 5b. Create session
|
|
203
|
+
const resolvedPath = findToolPath(cliCommand) ?? findExecutable(cliCommand);
|
|
204
|
+
if (resolvedPath) {
|
|
205
|
+
// Pure decision: build session request
|
|
206
|
+
const sessionParams = buildSessionRequest({
|
|
207
|
+
cliArgs,
|
|
208
|
+
toolMode,
|
|
209
|
+
promptPath,
|
|
210
|
+
promptText,
|
|
211
|
+
tmuxSessionFlag: flags['tmux-session'],
|
|
212
|
+
cwd,
|
|
213
|
+
now: now(),
|
|
214
|
+
pid,
|
|
215
|
+
});
|
|
216
|
+
host.logInfo(formatSessionLaunchMessage(mux.backend, sessionParams.sessionName, sessionParams.reattach));
|
|
217
|
+
const result = await mux.createSession({
|
|
218
|
+
sessionName: sessionParams.sessionName,
|
|
219
|
+
reattach: sessionParams.reattach,
|
|
220
|
+
toolPath: resolvedPath,
|
|
221
|
+
toolArgs: sessionParams.toolArgs,
|
|
222
|
+
cwd,
|
|
223
|
+
promptText: sessionParams.promptText,
|
|
224
|
+
});
|
|
225
|
+
if (result.launched) {
|
|
226
|
+
exitCode = result.exitCode ?? 0;
|
|
227
|
+
if (wantJson) {
|
|
228
|
+
host.log(JSON.stringify(toJsonLaunchResult(result, exitCode)));
|
|
229
|
+
host.exit(exitCode);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
// Pure decision: resolve fallback warning
|
|
234
|
+
if (result.reason) {
|
|
235
|
+
host.logWarning(resolveSessionFallbackWarning(mux.backend, result.reason));
|
|
236
|
+
}
|
|
237
|
+
const fallbackArgs = buildInlineArgs(cliArgs, toolMode, promptText, promptPath);
|
|
238
|
+
exitCode = await spawnInlineWithRetry(cliCommand, fallbackArgs, toolConfig.retryOnQuickExit, host);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
host.logWarning(formatPathWarning(cliCommand));
|
|
243
|
+
const fallbackArgs = buildInlineArgs(cliArgs, toolMode, promptText, promptPath);
|
|
244
|
+
exitCode = await spawnInlineWithRetry(cliCommand, fallbackArgs, toolConfig.retryOnQuickExit, host);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
if (error instanceof ProcessSpawnError) {
|
|
250
|
+
host.error(error.message, { exit: EXIT_CODES.ENVIRONMENT_ERROR });
|
|
251
|
+
}
|
|
252
|
+
host.error('Unexpected launch failure.', { exit: EXIT_CODES.GENERAL_ERROR });
|
|
253
|
+
}
|
|
254
|
+
finally {
|
|
255
|
+
if (!sentinelOwnershipTransferred) {
|
|
256
|
+
sentinelMgr.cleanupAll();
|
|
257
|
+
}
|
|
258
|
+
promptMgr.cleanup();
|
|
259
|
+
}
|
|
260
|
+
host.exit(exitCode);
|
|
261
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure decision functions extracted from execute-launch.ts.
|
|
3
|
+
* No side effects — all functions are deterministic string/config transforms.
|
|
4
|
+
*/
|
|
5
|
+
import type { LaunchResult } from '../../../platform/launch.js';
|
|
6
|
+
import type { InlineFallbackContext, JsonLaunchResult, LaunchFlags, SessionRequestParams, SplitRequestParams, ToolConfig, ToolMode } from '../contracts.js';
|
|
7
|
+
export declare const QUICK_EXIT_THRESHOLD_MS = 10000;
|
|
8
|
+
/**
|
|
9
|
+
* Return the debug message for tool mode, or undefined if none (claude has no special message).
|
|
10
|
+
*/
|
|
11
|
+
export declare function resolveToolModeDebugMessage(toolMode: ToolMode): string | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Format version check results into debug lines and an optional warning.
|
|
14
|
+
*/
|
|
15
|
+
export declare function formatVersionCheckMessages(versionCheck: {
|
|
16
|
+
compatible: boolean;
|
|
17
|
+
version?: null | string;
|
|
18
|
+
warning?: string;
|
|
19
|
+
}): {
|
|
20
|
+
debugLines: string[];
|
|
21
|
+
warning?: string | undefined;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Format the success message after a split pane launch.
|
|
25
|
+
*/
|
|
26
|
+
export declare function formatSplitSuccessMessage(backend: string, handle?: string): string;
|
|
27
|
+
/**
|
|
28
|
+
* Format the info message when launching in a session.
|
|
29
|
+
*/
|
|
30
|
+
export declare function formatSessionLaunchMessage(backend: string, sessionName: string, reattach: boolean): string;
|
|
31
|
+
/**
|
|
32
|
+
* Determine which CLI tool to launch and its configuration.
|
|
33
|
+
*/
|
|
34
|
+
export declare function resolveToolConfig(flags: Pick<LaunchFlags, 'codex' | 'devin'>, platform: NodeJS.Platform): ToolConfig;
|
|
35
|
+
/**
|
|
36
|
+
* Decide the informational message to log when falling back to inline mode.
|
|
37
|
+
*/
|
|
38
|
+
export declare function resolveInlineFallbackMessage(ctx: InlineFallbackContext): string;
|
|
39
|
+
/**
|
|
40
|
+
* Build the args array for an inline process spawn.
|
|
41
|
+
* Always returns a new array — never mutates input.
|
|
42
|
+
*/
|
|
43
|
+
export declare function buildInlineArgs(cliArgs: readonly string[], toolMode: ToolMode, promptText: string | undefined, promptPath: string | undefined): string[];
|
|
44
|
+
/**
|
|
45
|
+
* Build split pane parameters.
|
|
46
|
+
* Returns a new toolArgs array — fixes the cliArgs mutation bug.
|
|
47
|
+
*/
|
|
48
|
+
export declare function buildSplitRequest(params: {
|
|
49
|
+
cliArgs: readonly string[];
|
|
50
|
+
cwd: string;
|
|
51
|
+
effectivePromptPath: string | undefined;
|
|
52
|
+
extraEnv: Record<string, string>;
|
|
53
|
+
retryOnQuickExit: boolean;
|
|
54
|
+
sentinelPath: string;
|
|
55
|
+
split: 'auto' | 'horizontal' | 'vertical';
|
|
56
|
+
toolMode: ToolMode;
|
|
57
|
+
}): SplitRequestParams;
|
|
58
|
+
/**
|
|
59
|
+
* Build session creation parameters.
|
|
60
|
+
*/
|
|
61
|
+
export declare function buildSessionRequest(params: {
|
|
62
|
+
cliArgs: readonly string[];
|
|
63
|
+
cwd: string;
|
|
64
|
+
now: number;
|
|
65
|
+
pid: number;
|
|
66
|
+
promptPath: string | undefined;
|
|
67
|
+
promptText: string | undefined;
|
|
68
|
+
tmuxSessionFlag: string | undefined;
|
|
69
|
+
toolMode: ToolMode;
|
|
70
|
+
}): SessionRequestParams;
|
|
71
|
+
/**
|
|
72
|
+
* Decide warning message when session creation fails and we fall back inline.
|
|
73
|
+
*/
|
|
74
|
+
export declare function resolveSessionFallbackWarning(backend: string, reason: string | undefined): string;
|
|
75
|
+
/**
|
|
76
|
+
* Pure timing decision for retry logic.
|
|
77
|
+
*/
|
|
78
|
+
export declare function shouldRetry(elapsedMs: number, threshold?: number): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Convert a LaunchResult to JSON-serializable form.
|
|
81
|
+
*/
|
|
82
|
+
export declare function toJsonLaunchResult(result: LaunchResult, exitCode: null | number): JsonLaunchResult;
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure decision functions extracted from execute-launch.ts.
|
|
3
|
+
* No side effects — all functions are deterministic string/config transforms.
|
|
4
|
+
*/
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { buildUniqueSessionName, sanitizeSessionName } from './launch-options.js';
|
|
7
|
+
export const QUICK_EXIT_THRESHOLD_MS = 10_000;
|
|
8
|
+
/**
|
|
9
|
+
* Return the debug message for tool mode, or undefined if none (claude has no special message).
|
|
10
|
+
*/
|
|
11
|
+
export function resolveToolModeDebugMessage(toolMode) {
|
|
12
|
+
if (toolMode === 'codex')
|
|
13
|
+
return 'Launching Codex with --yolo flag';
|
|
14
|
+
if (toolMode === 'devin')
|
|
15
|
+
return 'Launching Devin with --permission-mode dangerous';
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Format version check results into debug lines and an optional warning.
|
|
20
|
+
*/
|
|
21
|
+
export function formatVersionCheckMessages(versionCheck) {
|
|
22
|
+
return {
|
|
23
|
+
debugLines: [
|
|
24
|
+
`Claude Code version: ${versionCheck.version ?? 'unknown'}`,
|
|
25
|
+
`Compatibility status: ${versionCheck.compatible ? 'compatible' : 'incompatible'}`,
|
|
26
|
+
],
|
|
27
|
+
...(versionCheck.warning ? { warning: versionCheck.warning } : {}),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Format the success message after a split pane launch.
|
|
32
|
+
*/
|
|
33
|
+
export function formatSplitSuccessMessage(backend, handle) {
|
|
34
|
+
if (handle) {
|
|
35
|
+
return `Launched in ${backend} pane: ${handle}`;
|
|
36
|
+
}
|
|
37
|
+
return `Launched in ${backend}`;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Format the info message when launching in a session.
|
|
41
|
+
*/
|
|
42
|
+
export function formatSessionLaunchMessage(backend, sessionName, reattach) {
|
|
43
|
+
if (reattach) {
|
|
44
|
+
return `Launching in ${backend} session: ${sessionName} (reuse/attach)`;
|
|
45
|
+
}
|
|
46
|
+
return `Launching in new ${backend} session: ${sessionName}`;
|
|
47
|
+
}
|
|
48
|
+
function buildCodexArgs(platform) {
|
|
49
|
+
if (platform !== 'win32')
|
|
50
|
+
return ['--yolo'];
|
|
51
|
+
return ['-c', 'shell_type="bash"', '--yolo'];
|
|
52
|
+
}
|
|
53
|
+
function buildDevinArgs() {
|
|
54
|
+
return ['--permission-mode', 'dangerous'];
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Determine which CLI tool to launch and its configuration.
|
|
58
|
+
*/
|
|
59
|
+
export function resolveToolConfig(flags, platform) {
|
|
60
|
+
if (flags.devin) {
|
|
61
|
+
return {
|
|
62
|
+
cliCommand: 'devin',
|
|
63
|
+
cliArgs: buildDevinArgs(),
|
|
64
|
+
launchFlag: '--devin',
|
|
65
|
+
toolMode: 'devin',
|
|
66
|
+
retryOnQuickExit: true,
|
|
67
|
+
needsLspPatch: false,
|
|
68
|
+
skipVersionCheck: true,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
if (flags.codex) {
|
|
72
|
+
return {
|
|
73
|
+
cliCommand: 'codex',
|
|
74
|
+
cliArgs: buildCodexArgs(platform),
|
|
75
|
+
launchFlag: '--codex',
|
|
76
|
+
toolMode: 'codex',
|
|
77
|
+
retryOnQuickExit: false,
|
|
78
|
+
needsLspPatch: false,
|
|
79
|
+
skipVersionCheck: true,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
cliCommand: 'claude',
|
|
84
|
+
cliArgs: ['--dangerously-skip-permissions'],
|
|
85
|
+
launchFlag: '',
|
|
86
|
+
toolMode: 'claude',
|
|
87
|
+
retryOnQuickExit: false,
|
|
88
|
+
needsLspPatch: platform === 'win32',
|
|
89
|
+
skipVersionCheck: false,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Decide the informational message to log when falling back to inline mode.
|
|
94
|
+
*/
|
|
95
|
+
export function resolveInlineFallbackMessage(ctx) {
|
|
96
|
+
if (!ctx.hasMux) {
|
|
97
|
+
if (ctx.disableMux) {
|
|
98
|
+
return 'Multiplexer disabled via --no-tmux — launching inline';
|
|
99
|
+
}
|
|
100
|
+
if (!ctx.interactiveTty) {
|
|
101
|
+
return 'Non-interactive terminal — launching inline';
|
|
102
|
+
}
|
|
103
|
+
if (ctx.platform === 'win32') {
|
|
104
|
+
return 'No multiplexer found — launching inline. Run inside WezTerm or install psmux for session management.';
|
|
105
|
+
}
|
|
106
|
+
return 'No multiplexer found — launching inline. Install tmux for session management.';
|
|
107
|
+
}
|
|
108
|
+
return ctx.resolvedReason ?? 'Launching inline';
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Build the args array for an inline process spawn.
|
|
112
|
+
* Always returns a new array — never mutates input.
|
|
113
|
+
*/
|
|
114
|
+
export function buildInlineArgs(cliArgs, toolMode, promptText, promptPath) {
|
|
115
|
+
if (toolMode === 'devin' && promptPath) {
|
|
116
|
+
return [...cliArgs, '--prompt-file', promptPath];
|
|
117
|
+
}
|
|
118
|
+
if (promptText) {
|
|
119
|
+
return [...cliArgs, promptText];
|
|
120
|
+
}
|
|
121
|
+
return [...cliArgs];
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Build split pane parameters.
|
|
125
|
+
* Returns a new toolArgs array — fixes the cliArgs mutation bug.
|
|
126
|
+
*/
|
|
127
|
+
export function buildSplitRequest(params) {
|
|
128
|
+
let toolArgs;
|
|
129
|
+
let splitPromptPath;
|
|
130
|
+
if (params.toolMode === 'devin' && params.effectivePromptPath) {
|
|
131
|
+
toolArgs = [...params.cliArgs, '--prompt-file', params.effectivePromptPath];
|
|
132
|
+
splitPromptPath = undefined;
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
toolArgs = [...params.cliArgs];
|
|
136
|
+
splitPromptPath = params.effectivePromptPath;
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
toolArgs,
|
|
140
|
+
splitPromptPath,
|
|
141
|
+
env: params.extraEnv,
|
|
142
|
+
cwd: params.cwd,
|
|
143
|
+
mode: 'repl',
|
|
144
|
+
split: params.split,
|
|
145
|
+
sentinelPath: params.sentinelPath,
|
|
146
|
+
holdPane: false,
|
|
147
|
+
retryOnQuickExit: params.retryOnQuickExit,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Build session creation parameters.
|
|
152
|
+
*/
|
|
153
|
+
export function buildSessionRequest(params) {
|
|
154
|
+
const sessionFromFlag = params.tmuxSessionFlag?.trim();
|
|
155
|
+
const reattach = Boolean(sessionFromFlag && sessionFromFlag.length > 0);
|
|
156
|
+
const sessionName = reattach
|
|
157
|
+
? sanitizeSessionName(sessionFromFlag)
|
|
158
|
+
: buildUniqueSessionName(`aiw-${path.basename(params.cwd)}`, params.now, params.pid);
|
|
159
|
+
const toolArgs = params.toolMode === 'devin' && params.promptPath
|
|
160
|
+
? [...params.cliArgs, '--prompt-file', params.promptPath]
|
|
161
|
+
: [...params.cliArgs];
|
|
162
|
+
const promptText = params.toolMode === 'devin' ? undefined : params.promptText;
|
|
163
|
+
return { sessionName, reattach, toolArgs, promptText };
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Decide warning message when session creation fails and we fall back inline.
|
|
167
|
+
*/
|
|
168
|
+
export function resolveSessionFallbackWarning(backend, reason) {
|
|
169
|
+
if (!reason)
|
|
170
|
+
return 'Session creation failed — launching inline';
|
|
171
|
+
if (reason.includes('not found') || reason.includes('unavailable')) {
|
|
172
|
+
const hint = backend === 'psmux' ? ' Install with: winget install psmux' : '';
|
|
173
|
+
return `${backend} unavailable — launching inline.${hint}`;
|
|
174
|
+
}
|
|
175
|
+
if (reason.includes('too old')) {
|
|
176
|
+
const hint = backend === 'psmux' ? ' Update with: winget upgrade psmux' : '';
|
|
177
|
+
return `${reason} — launching inline.${hint}`;
|
|
178
|
+
}
|
|
179
|
+
if (backend === 'psmux' && reason.includes('attach failed')) {
|
|
180
|
+
return `${reason} — launching inline. Recovery: run "psmux kill-server" and relaunch if this persists.`;
|
|
181
|
+
}
|
|
182
|
+
return `${reason} — launching inline`;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Pure timing decision for retry logic.
|
|
186
|
+
*/
|
|
187
|
+
export function shouldRetry(elapsedMs, threshold = QUICK_EXIT_THRESHOLD_MS) {
|
|
188
|
+
return elapsedMs < threshold;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Convert a LaunchResult to JSON-serializable form.
|
|
192
|
+
*/
|
|
193
|
+
export function toJsonLaunchResult(result, exitCode) {
|
|
194
|
+
return {
|
|
195
|
+
launched: result.launched,
|
|
196
|
+
backend: result.backend,
|
|
197
|
+
handle: result.handle ?? null,
|
|
198
|
+
sentinelPath: result.sentinelPath ?? null,
|
|
199
|
+
exitCode,
|
|
200
|
+
reason: result.reason ?? null,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface BuildSpawnedWindowArgsParams {
|
|
2
|
+
disableTmux: boolean;
|
|
3
|
+
promptFilePath?: string | undefined;
|
|
4
|
+
promptPath?: string | undefined;
|
|
5
|
+
rawEnvJson?: string | undefined;
|
|
6
|
+
tmuxSessionFlag?: string | undefined;
|
|
7
|
+
useCodex: boolean;
|
|
8
|
+
useDevin?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function parseExtraEnv(raw: string | undefined): Record<string, string>;
|
|
11
|
+
export declare function resolvePromptText(promptFlag: string | undefined, promptFileFlag: string | undefined, readFile: (filePath: string) => string | undefined): string | undefined;
|
|
12
|
+
export declare function buildSpawnedWindowArgs(params: BuildSpawnedWindowArgsParams): string[];
|
|
13
|
+
export declare function sanitizeSessionName(input: string): string;
|
|
14
|
+
export declare function buildUniqueSessionName(base: string, now?: number, pid?: number): string;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export function parseExtraEnv(raw) {
|
|
2
|
+
if (!raw)
|
|
3
|
+
return {};
|
|
4
|
+
let parsed;
|
|
5
|
+
try {
|
|
6
|
+
parsed = JSON.parse(raw);
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
throw new Error('--env must be a valid JSON object string');
|
|
10
|
+
}
|
|
11
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
12
|
+
throw new Error('--env must be a valid JSON object string');
|
|
13
|
+
}
|
|
14
|
+
return parsed;
|
|
15
|
+
}
|
|
16
|
+
export function resolvePromptText(promptFlag, promptFileFlag, readFile) {
|
|
17
|
+
const promptText = promptFlag?.trim();
|
|
18
|
+
if (promptText)
|
|
19
|
+
return promptText;
|
|
20
|
+
const promptFilePath = promptFileFlag?.trim();
|
|
21
|
+
if (!promptFilePath)
|
|
22
|
+
return undefined;
|
|
23
|
+
try {
|
|
24
|
+
const fromFile = readFile(promptFilePath)?.trim();
|
|
25
|
+
return fromFile || undefined;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export function buildSpawnedWindowArgs(params) {
|
|
32
|
+
const { useCodex, useDevin, disableTmux, promptFilePath, promptPath, rawEnvJson, tmuxSessionFlag } = params;
|
|
33
|
+
const parts = ['aiw', 'launch', '--spawned-window'];
|
|
34
|
+
if (useDevin)
|
|
35
|
+
parts.push('--devin');
|
|
36
|
+
else if (useCodex)
|
|
37
|
+
parts.push('--codex');
|
|
38
|
+
if (disableTmux)
|
|
39
|
+
parts.push('--no-tmux');
|
|
40
|
+
const tmuxSession = tmuxSessionFlag?.trim();
|
|
41
|
+
if (tmuxSession) {
|
|
42
|
+
parts.push('--tmux-session', tmuxSession);
|
|
43
|
+
}
|
|
44
|
+
const envJson = rawEnvJson?.trim();
|
|
45
|
+
if (envJson) {
|
|
46
|
+
parts.push('--env', envJson);
|
|
47
|
+
}
|
|
48
|
+
if (promptPath) {
|
|
49
|
+
parts.push('--prompt-path', promptPath);
|
|
50
|
+
}
|
|
51
|
+
else if (promptFilePath) {
|
|
52
|
+
parts.push('--prompt-file', promptFilePath);
|
|
53
|
+
}
|
|
54
|
+
return parts;
|
|
55
|
+
}
|
|
56
|
+
export function sanitizeSessionName(input) {
|
|
57
|
+
const trimmed = input.trim().toLowerCase();
|
|
58
|
+
const safe = trimmed
|
|
59
|
+
.replaceAll(/[^a-z0-9_-]/g, '-')
|
|
60
|
+
.replaceAll(/-+/g, '-')
|
|
61
|
+
.replaceAll(/^[-_]+|[-_]+$/g, '');
|
|
62
|
+
return safe || 'aiw';
|
|
63
|
+
}
|
|
64
|
+
export function buildUniqueSessionName(base, now = Date.now(), pid = process.pid) {
|
|
65
|
+
const safeBase = sanitizeSessionName(base);
|
|
66
|
+
const timestamp = now.toString(36);
|
|
67
|
+
const pidPart = pid.toString(36);
|
|
68
|
+
return sanitizeSessionName(`${safeBase}-${timestamp}-${pidPart}`);
|
|
69
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
import { type Ora } from 'ora';
|
|
3
|
+
export default abstract class BaseCommand extends Command {
|
|
4
|
+
static baseFlags: {
|
|
5
|
+
debug: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
6
|
+
help: import("@oclif/core/interfaces").BooleanFlag<void>;
|
|
7
|
+
quiet: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
|
+
};
|
|
9
|
+
init(): Promise<void>;
|
|
10
|
+
protected isQuiet(): boolean;
|
|
11
|
+
protected logDebug(message: string): void;
|
|
12
|
+
protected logError(message: string): void;
|
|
13
|
+
protected logInfo(message: string): void;
|
|
14
|
+
protected logSuccess(message: string): void;
|
|
15
|
+
protected logWarning(message: string): void;
|
|
16
|
+
abstract run(): Promise<void>;
|
|
17
|
+
protected spinner(text: string): Ora;
|
|
18
|
+
}
|