aiwcli 0.15.7 → 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 +106 -1125
- package/bin/run.js +0 -4
- package/dist/capabilities/installation/control-plane/clear-command.d.ts +2 -0
- package/dist/capabilities/installation/control-plane/clear-command.js +32 -3
- package/dist/capabilities/installation/control-plane/init-command.js +2 -2
- package/dist/capabilities/launch/contracts.d.ts +39 -4
- package/dist/capabilities/launch/control-plane/execute-launch.js +158 -119
- 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/commands/branch.d.ts +1 -1
- package/dist/commands/branch.js +1 -1
- package/dist/commands/launch.d.ts +0 -5
- package/dist/commands/launch.js +2 -37
- package/dist/lib/config.js +1 -2
- package/dist/lib/context/context-store.js +28 -2
- package/dist/lib/core-installer.d.ts +1 -1
- package/dist/lib/core-installer.js +6 -27
- 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.js +1 -1
- 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.js +11 -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.js +2 -14
- package/dist/lib/install-state.js +6 -13
- package/dist/lib/json-io.d.ts +12 -0
- package/dist/lib/json-io.js +30 -0
- package/dist/lib/multiplexer.d.ts +43 -35
- package/dist/lib/multiplexer.js +21 -2
- package/dist/lib/multiplexers/psmux.d.ts +14 -34
- package/dist/lib/multiplexers/psmux.js +70 -130
- package/dist/lib/multiplexers/tmux.d.ts +11 -19
- package/dist/lib/multiplexers/tmux.js +79 -120
- package/dist/lib/multiplexers/wezterm.d.ts +38 -0
- package/dist/lib/multiplexers/wezterm.js +225 -0
- package/dist/lib/mux-utils.d.ts +4 -3
- package/dist/lib/mux-utils.js +7 -13
- 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 +2 -0
- package/dist/lib/runtime/aiw-cli.js +3 -1
- package/dist/lib/runtime/cli-args.d.ts +5 -2
- package/dist/lib/runtime/cli-args.js +18 -3
- package/dist/lib/runtime/inference.js +3 -14
- package/dist/lib/runtime/models.d.ts +6 -0
- package/dist/lib/runtime/models.js +6 -0
- package/dist/lib/runtime/state-io.d.ts +2 -1
- package/dist/lib/runtime/state-io.js +9 -4
- package/dist/lib/runtime/utils.d.ts +8 -0
- package/dist/lib/runtime/utils.js +31 -1
- 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 +1 -0
- package/dist/lib/sentinel-wrapper.js +12 -3
- 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/spawn-errors.d.ts +3 -0
- package/dist/lib/spawn-errors.js +15 -1
- package/dist/lib/spinner.d.ts +0 -5
- package/dist/lib/spinner.js +0 -16
- package/dist/lib/template-installer.d.ts +10 -0
- package/dist/lib/template-installer.js +4 -4
- package/dist/lib/terminal-strategy.d.ts +1 -0
- package/dist/lib/terminal-strategy.js +12 -6
- package/dist/lib/terminal.d.ts +7 -5
- package/dist/lib/terminal.js +42 -19
- package/dist/lib/tmux-primitives.d.ts +0 -2
- package/dist/lib/tmux-primitives.js +0 -4
- package/dist/lib/tmux-session.js +2 -1
- package/dist/lib/windsurf-hooks-hierarchy.js +6 -23
- package/dist/platform/launch.d.ts +2 -1
- package/dist/platform/launch.js +1 -0
- package/dist/templates/CLAUDE.md +0 -1
- package/dist/templates/cc-native/.claude/settings.json +0 -10
- package/dist/templates/cc-native/TEMPLATE-SCHEMA.md +11 -4
- package/dist/templates/cc-native/_cc-native/cc-native.config.json +3 -7
- package/dist/templates/cc-native/_cc-native/hooks/CLAUDE.md +26 -47
- package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.ts +7 -9
- package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_write.ts +2 -3
- package/dist/templates/cc-native/_cc-native/hooks/mark_questions_asked.ts +2 -2
- package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.ts +0 -25
- package/dist/templates/cc-native/_cc-native/hooks/validate_task_prompt.ts +4 -4
- 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 +16 -15
- package/dist/templates/cc-native/_cc-native/lib-ts/cli-output-parser.ts +132 -10
- package/dist/templates/cc-native/_cc-native/lib-ts/constants.ts +6 -6
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/corroboration.ts +119 -119
- package/dist/templates/cc-native/_cc-native/lib-ts/debug.ts +1 -2
- 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 +4 -4
- 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/{core/lib-ts/agent-exec → cc-native/_cc-native/lib-ts/reviewers/base}/base-agent.ts +138 -152
- 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 -224
- 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 +6 -7
- 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 +14 -17
- 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 +8 -9
- 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 +19 -21
- package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +13 -88
- 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 +35 -0
- package/dist/templates/cc-native/_cc-native/plan-review/lib/agent-selection.ts +1 -1
- 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/{workflows/meta-plan.md → skills/meta-plan/SKILL.md} +6 -0
- package/dist/templates/core/{.cognition → .devin}/AGENTS.md +2 -2
- 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/core/hooks-ts/archive_plan.ts +1 -21
- package/dist/templates/core/hooks-ts/file-suggestion.ts +1 -19
- package/dist/templates/core/hooks-ts/pre_compact.ts +5 -18
- package/dist/templates/core/lib-ts/context/context-store.ts +29 -2
- package/dist/templates/core/lib-ts/hooks/hook-utils.ts +11 -0
- package/dist/templates/core/lib-ts/hooks/session-end-logic.ts +2 -13
- package/dist/templates/core/lib-ts/runtime/agent-launcher.ts +74 -0
- package/dist/templates/core/lib-ts/runtime/aiw-cli.ts +4 -2
- package/dist/templates/core/lib-ts/runtime/cli-args.ts +18 -4
- package/dist/templates/core/lib-ts/runtime/inference.ts +3 -15
- package/dist/templates/core/lib-ts/runtime/models.ts +7 -0
- package/dist/templates/core/lib-ts/runtime/state-io.ts +9 -4
- package/dist/templates/core/lib-ts/runtime/utils.ts +30 -1
- package/dist/templates/core/lib-ts/schemas.ts +233 -0
- package/dist/templates/core/scripts/resolve-run.ts +34 -2
- package/dist/templates/core/scripts/status_line.ts +1 -1
- package/dist/templates/core/skills/codex/CLAUDE.md +9 -4
- package/dist/templates/core/skills/codex/SKILL.md +6 -0
- package/dist/templates/core/skills/codex/lib/codex-watcher.ts +3 -10
- package/dist/templates/core/skills/codex/scripts/launch-codex.ts +26 -26
- package/dist/templates/core/skills/devin/CLAUDE.md +63 -6
- package/dist/templates/core/skills/devin/lib/devin-watcher.ts +116 -96
- package/dist/templates/core/skills/devin/scripts/launch-devin.ts +22 -21
- package/dist/templates/core/skills/handoff-system/CLAUDE.md +1 -1
- package/oclif.manifest.json +4 -4
- package/package.json +4 -4
- package/dist/lib/base-command.d.ts +0 -1
- package/dist/lib/base-command.js +0 -1
- package/dist/lib/env-compat.d.ts +0 -18
- package/dist/lib/env-compat.js +0 -23
- package/dist/lib/launch-options.d.ts +0 -1
- package/dist/lib/launch-options.js +0 -1
- package/dist/lib/stdin.d.ts +0 -48
- package/dist/lib/stdin.js +0 -60
- 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/reviewers/base/base-agent.ts +0 -7
- package/dist/templates/core/.codex/workflows/codex.md +0 -17
- package/dist/templates/core/.codex/workflows/handoff.md +0 -5
- package/dist/templates/core/lib-ts/agent-exec/backends/headless.ts +0 -34
- package/dist/templates/core/lib-ts/agent-exec/backends/index.ts +0 -6
- package/dist/templates/core/lib-ts/agent-exec/backends/tmux.ts +0 -148
- package/dist/templates/core/lib-ts/agent-exec/execution-backend.ts +0 -50
- package/dist/templates/core/lib-ts/agent-exec/index.ts +0 -6
- package/dist/templates/core/lib-ts/agent-exec/structured-output.ts +0 -165
- /package/dist/templates/core/{.cognition → .devin}/config.json +0 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BashAdapter — ShellAdapter for bash (Unix + MSYS2/Git Bash on Windows).
|
|
3
|
+
* Delegates to low-level primitives in shell-quoting.ts, sentinel-wrapper.ts, etc.
|
|
4
|
+
*/
|
|
5
|
+
import { REPL_NESTING_VARS } from '../env-sanitizer.js';
|
|
6
|
+
import { execFileAsync, findExecutable } from '../runtime/subprocess-utils.js';
|
|
7
|
+
import { wrapSentinelSh } from '../sentinel-wrapper.js';
|
|
8
|
+
import { quoteForSh } from '../shell-quoting.js';
|
|
9
|
+
import { toMsysPosixPath } from '../tmux-primitives.js';
|
|
10
|
+
export class BashAdapter {
|
|
11
|
+
dialect = 'bash';
|
|
12
|
+
quote(value) {
|
|
13
|
+
return quoteForSh(value);
|
|
14
|
+
}
|
|
15
|
+
buildEnvPreamble(env) {
|
|
16
|
+
return Object.entries(env)
|
|
17
|
+
.map(([key, value]) => `${key}=${this.quote(value)}`)
|
|
18
|
+
.join(' ');
|
|
19
|
+
}
|
|
20
|
+
buildToolCommand(params) {
|
|
21
|
+
const { toolPath, args, env, mode, promptPath, promptText } = params;
|
|
22
|
+
const envPrefix = this.buildEnvPreamble(env);
|
|
23
|
+
const commandArgs = this.appendPromptArg(args, mode, promptText);
|
|
24
|
+
const argPart = commandArgs.map((arg) => this.quote(arg)).join(' ');
|
|
25
|
+
const base = [envPrefix, this.quote(toolPath), argPart]
|
|
26
|
+
.filter(Boolean)
|
|
27
|
+
.join(' ');
|
|
28
|
+
if (mode === 'exec' && promptPath) {
|
|
29
|
+
return `${base} < ${this.quote(promptPath)}`;
|
|
30
|
+
}
|
|
31
|
+
return base;
|
|
32
|
+
}
|
|
33
|
+
wrapSentinel(params) {
|
|
34
|
+
return wrapSentinelSh(params);
|
|
35
|
+
}
|
|
36
|
+
async resolveToolPath(toolName, nativePath) {
|
|
37
|
+
if (process.platform !== 'win32')
|
|
38
|
+
return nativePath;
|
|
39
|
+
// On Windows, resolve tool from bash's perspective (MSYS2/Git Bash PATH)
|
|
40
|
+
const bash = findExecutable('bash');
|
|
41
|
+
if (!bash)
|
|
42
|
+
return null;
|
|
43
|
+
const result = await execFileAsync(bash, ['-lc', `command -v ${toolName}`], {
|
|
44
|
+
timeout: 3000,
|
|
45
|
+
env: { ...process.env, MSYS_NO_PATHCONV: '1' },
|
|
46
|
+
});
|
|
47
|
+
return result.exitCode === 0 ? result.stdout.trim() || null : null;
|
|
48
|
+
}
|
|
49
|
+
buildNestingCleanup() {
|
|
50
|
+
const pathFix = 'export PATH="/usr/bin:/usr/local/bin:/mingw64/bin:$PATH";';
|
|
51
|
+
const unset = `unset ${REPL_NESTING_VARS.join(' ')};`;
|
|
52
|
+
return `${pathFix} ${unset}`;
|
|
53
|
+
}
|
|
54
|
+
normalizeCwd(cwd) {
|
|
55
|
+
return toMsysPosixPath(cwd);
|
|
56
|
+
}
|
|
57
|
+
wrapQuickExitRetry(command, toolPath, thresholdSec = 10) {
|
|
58
|
+
const warmup = `${toolPath} --version >/dev/null 2>&1`;
|
|
59
|
+
return `${warmup}; _qr_t0=$SECONDS; ${command}; if [ $((SECONDS - _qr_t0)) -lt ${thresholdSec} ]; then ${command}; fi`;
|
|
60
|
+
}
|
|
61
|
+
encodeForExecution(command) {
|
|
62
|
+
return command;
|
|
63
|
+
}
|
|
64
|
+
appendPromptArg(args, mode, promptText) {
|
|
65
|
+
if (mode !== 'repl' || promptText === undefined)
|
|
66
|
+
return args;
|
|
67
|
+
return [...args, promptText];
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { BashAdapter } from './bash-adapter.js';
|
|
2
|
+
export { PowerShellAdapter } from './powershell-adapter.js';
|
|
3
|
+
export type { SentinelWrapOptions, ShellAdapter, ToolCommandParams } from './shell-adapter.js';
|
|
4
|
+
import type { ShellAdapter } from './shell-adapter.js';
|
|
5
|
+
export declare function shellAdapterForBackend(backend: string): ShellAdapter;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { BashAdapter } from './bash-adapter.js';
|
|
2
|
+
export { PowerShellAdapter } from './powershell-adapter.js';
|
|
3
|
+
import { BashAdapter } from './bash-adapter.js';
|
|
4
|
+
import { PowerShellAdapter } from './powershell-adapter.js';
|
|
5
|
+
export function shellAdapterForBackend(backend) {
|
|
6
|
+
return backend === 'psmux' ? new PowerShellAdapter() : new BashAdapter();
|
|
7
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PowerShellAdapter — ShellAdapter for PowerShell (Windows, psmux backend).
|
|
3
|
+
* Delegates to low-level primitives in shell-quoting.ts, sentinel-wrapper.ts, etc.
|
|
4
|
+
*/
|
|
5
|
+
import type { SentinelWrapOptions, ShellAdapter, ToolCommandParams } from './shell-adapter.js';
|
|
6
|
+
export declare class PowerShellAdapter implements ShellAdapter {
|
|
7
|
+
readonly dialect: "powershell";
|
|
8
|
+
quote(value: string): string;
|
|
9
|
+
buildEnvPreamble(env: Record<string, string>): string;
|
|
10
|
+
buildToolCommand(params: ToolCommandParams): string;
|
|
11
|
+
wrapSentinel(params: SentinelWrapOptions): string;
|
|
12
|
+
resolveToolPath(_toolName: string, nativePath: string): Promise<string | null>;
|
|
13
|
+
buildNestingCleanup(): string;
|
|
14
|
+
normalizeCwd(cwd: string): string;
|
|
15
|
+
wrapQuickExitRetry(command: string, _toolPath: string, _thresholdSec?: number): string;
|
|
16
|
+
encodeForExecution(command: string): string;
|
|
17
|
+
private appendPromptArg;
|
|
18
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PowerShellAdapter — ShellAdapter for PowerShell (Windows, psmux backend).
|
|
3
|
+
* Delegates to low-level primitives in shell-quoting.ts, sentinel-wrapper.ts, etc.
|
|
4
|
+
*/
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { REPL_NESTING_VARS } from '../env-sanitizer.js';
|
|
7
|
+
import { buildBootstrapPrompt } from '../mux-utils.js';
|
|
8
|
+
import { wrapSentinelPowerShell } from '../sentinel-wrapper.js';
|
|
9
|
+
import { quoteForPowerShell, toEncodedPowerShell } from '../shell-quoting.js';
|
|
10
|
+
export class PowerShellAdapter {
|
|
11
|
+
dialect = 'powershell';
|
|
12
|
+
quote(value) {
|
|
13
|
+
return quoteForPowerShell(value);
|
|
14
|
+
}
|
|
15
|
+
buildEnvPreamble(env) {
|
|
16
|
+
return Object.entries(env)
|
|
17
|
+
.map(([key, value]) => `$env:${key}=${this.quote(value)}`)
|
|
18
|
+
.join('; ');
|
|
19
|
+
}
|
|
20
|
+
buildToolCommand(params) {
|
|
21
|
+
const { toolPath, args, env, mode, promptPath } = params;
|
|
22
|
+
const envPrefix = this.buildEnvPreamble(env);
|
|
23
|
+
const commandArgs = this.appendPromptArg(args, mode, promptPath);
|
|
24
|
+
const argArray = commandArgs.map((arg) => this.quote(arg)).join(', ');
|
|
25
|
+
const invocation = `& ${this.quote(toolPath)}${argArray ? ` @(${argArray})` : ''}`;
|
|
26
|
+
const body = mode === 'exec' && promptPath
|
|
27
|
+
? `Get-Content -Raw -Path ${this.quote(promptPath)} | ${invocation}`
|
|
28
|
+
: invocation;
|
|
29
|
+
return [envPrefix, body].filter(Boolean).join('; ');
|
|
30
|
+
}
|
|
31
|
+
wrapSentinel(params) {
|
|
32
|
+
return wrapSentinelPowerShell(params);
|
|
33
|
+
}
|
|
34
|
+
async resolveToolPath(_toolName, nativePath) {
|
|
35
|
+
return nativePath;
|
|
36
|
+
}
|
|
37
|
+
buildNestingCleanup() {
|
|
38
|
+
return REPL_NESTING_VARS
|
|
39
|
+
.map((v) => `Remove-Item Env:\\${v} -ErrorAction SilentlyContinue`)
|
|
40
|
+
.join('; ') + ';';
|
|
41
|
+
}
|
|
42
|
+
normalizeCwd(cwd) {
|
|
43
|
+
return cwd;
|
|
44
|
+
}
|
|
45
|
+
wrapQuickExitRetry(command, _toolPath, _thresholdSec) {
|
|
46
|
+
// Quick-exit retry not implemented for PowerShell — inline retry handles it
|
|
47
|
+
return command;
|
|
48
|
+
}
|
|
49
|
+
encodeForExecution(command) {
|
|
50
|
+
return toEncodedPowerShell(command);
|
|
51
|
+
}
|
|
52
|
+
appendPromptArg(args, mode, promptPath) {
|
|
53
|
+
if (mode !== 'repl' || !promptPath)
|
|
54
|
+
return args;
|
|
55
|
+
const absolutePromptPath = path.resolve(promptPath);
|
|
56
|
+
const formatted = process.platform === 'win32'
|
|
57
|
+
? absolutePromptPath.replaceAll('\\', '/')
|
|
58
|
+
: absolutePromptPath;
|
|
59
|
+
const bootstrap = buildBootstrapPrompt(formatted);
|
|
60
|
+
return [...args, bootstrap];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ShellAdapter interface — abstracts shell-dialect differences for command building.
|
|
3
|
+
* BashAdapter and PowerShellAdapter implement this for their respective shells.
|
|
4
|
+
*/
|
|
5
|
+
export interface ToolCommandParams {
|
|
6
|
+
toolPath: string;
|
|
7
|
+
args: string[];
|
|
8
|
+
env: Record<string, string>;
|
|
9
|
+
mode: 'exec' | 'repl';
|
|
10
|
+
promptPath?: string | undefined;
|
|
11
|
+
promptText?: string | undefined;
|
|
12
|
+
}
|
|
13
|
+
export interface SentinelWrapOptions {
|
|
14
|
+
command: string;
|
|
15
|
+
sentinelPath: string;
|
|
16
|
+
autoClose: boolean;
|
|
17
|
+
autoCloseCommand?: string | undefined;
|
|
18
|
+
holdPane: boolean;
|
|
19
|
+
holdMessage: string;
|
|
20
|
+
}
|
|
21
|
+
export interface ShellAdapter {
|
|
22
|
+
readonly dialect: 'bash' | 'powershell';
|
|
23
|
+
/** Quote a value for safe inclusion in a shell command. */
|
|
24
|
+
quote(value: string): string;
|
|
25
|
+
/** Build env var assignments as a command preamble (KEY=val for bash, $env:KEY=val for PS). */
|
|
26
|
+
buildEnvPreamble(env: Record<string, string>): string;
|
|
27
|
+
/** Build a complete tool invocation command (env + tool + args + prompt handling). */
|
|
28
|
+
buildToolCommand(params: ToolCommandParams): string;
|
|
29
|
+
/** Wrap a command with sentinel exit-code tracking and optional pane hold. */
|
|
30
|
+
wrapSentinel(params: SentinelWrapOptions): string;
|
|
31
|
+
/**
|
|
32
|
+
* Resolve a tool path for the shell dialect.
|
|
33
|
+
* On Windows with bash, resolves via `command -v` in bash.
|
|
34
|
+
* On Unix or PowerShell, returns nativePath as-is.
|
|
35
|
+
*/
|
|
36
|
+
resolveToolPath(toolName: string, nativePath: string): Promise<string | null>;
|
|
37
|
+
/** Build a shell snippet that clears REPL nesting env vars. */
|
|
38
|
+
buildNestingCleanup(): string;
|
|
39
|
+
/** Normalize a cwd path for the shell dialect (e.g. Windows→POSIX for bash). */
|
|
40
|
+
normalizeCwd(cwd: string): string;
|
|
41
|
+
/** Wrap a command with warmup + quick-exit retry logic. */
|
|
42
|
+
wrapQuickExitRetry(command: string, toolPath: string, thresholdSec?: number): string;
|
|
43
|
+
/** Encode a command for safe execution (identity for bash, Base64 for PowerShell). */
|
|
44
|
+
encodeForExecution(command: string): string;
|
|
45
|
+
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { ProcessSpawnError } from './errors.js';
|
|
2
|
+
export declare function getInstallInstruction(command: string): string;
|
|
3
|
+
export declare function formatCommandNotFoundMessage(command: string): string;
|
|
4
|
+
export declare function formatPathWarning(command: string): string;
|
|
2
5
|
export declare function classifySpawnError(command: string, error: NodeJS.ErrnoException): ProcessSpawnError;
|
|
3
6
|
export declare function resolveWindowsSpawnArgs(command: string, args: string[], cmdExists: (commandName: string) => boolean): null | {
|
|
4
7
|
args: string[];
|
package/dist/lib/spawn-errors.js
CHANGED
|
@@ -1,7 +1,21 @@
|
|
|
1
1
|
import { ProcessSpawnError } from './errors.js';
|
|
2
|
+
const INSTALL_INSTRUCTIONS = {
|
|
3
|
+
claude: 'Install Claude Code from https://claude.ai/download.',
|
|
4
|
+
codex: 'Install Codex from npm.',
|
|
5
|
+
devin: 'Install Devin from https://cli.devin.ai.',
|
|
6
|
+
};
|
|
7
|
+
export function getInstallInstruction(command) {
|
|
8
|
+
return INSTALL_INSTRUCTIONS[command] ?? 'Check that the command exists and is executable.';
|
|
9
|
+
}
|
|
10
|
+
export function formatCommandNotFoundMessage(command) {
|
|
11
|
+
return `Command not found: ${command}. ${getInstallInstruction(command)}`;
|
|
12
|
+
}
|
|
13
|
+
export function formatPathWarning(command) {
|
|
14
|
+
return `${command} not found on PATH (${getInstallInstruction(command).replace(/\.$/, '')})`;
|
|
15
|
+
}
|
|
2
16
|
export function classifySpawnError(command, error) {
|
|
3
17
|
if (error.code === 'ENOENT') {
|
|
4
|
-
return new ProcessSpawnError(
|
|
18
|
+
return new ProcessSpawnError(formatCommandNotFoundMessage(command), 'ENOENT');
|
|
5
19
|
}
|
|
6
20
|
if (error.code === 'EACCES') {
|
|
7
21
|
return new ProcessSpawnError(`Permission denied: ${command}. Check file permissions.`, 'EACCES');
|
package/dist/lib/spinner.d.ts
CHANGED
|
@@ -12,8 +12,3 @@ import { type Ora } from 'ora';
|
|
|
12
12
|
export declare function createSpinner(text: string, flags?: {
|
|
13
13
|
quiet?: boolean;
|
|
14
14
|
}): Ora;
|
|
15
|
-
/**
|
|
16
|
-
* Helper for common "loading" operations with spinner.
|
|
17
|
-
* Automatically handles success/failure and cleanup.
|
|
18
|
-
*/
|
|
19
|
-
export declare function withSpinner<T>(text: string, operation: () => Promise<T>): Promise<T>;
|
package/dist/lib/spinner.js
CHANGED
|
@@ -16,19 +16,3 @@ export function createSpinner(text, flags) {
|
|
|
16
16
|
text,
|
|
17
17
|
});
|
|
18
18
|
}
|
|
19
|
-
/**
|
|
20
|
-
* Helper for common "loading" operations with spinner.
|
|
21
|
-
* Automatically handles success/failure and cleanup.
|
|
22
|
-
*/
|
|
23
|
-
export async function withSpinner(text, operation) {
|
|
24
|
-
const spinner = createSpinner(text).start();
|
|
25
|
-
try {
|
|
26
|
-
const result = await operation();
|
|
27
|
-
spinner.succeed();
|
|
28
|
-
return result;
|
|
29
|
-
}
|
|
30
|
-
catch (error) {
|
|
31
|
-
spinner.fail();
|
|
32
|
-
throw error;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
@@ -74,6 +74,16 @@ export declare function shouldExclude(name: string): boolean;
|
|
|
74
74
|
* @param excludeIdeFolders - If true, exclude IDE config folders (.claude, .windsurf, etc.)
|
|
75
75
|
*/
|
|
76
76
|
export declare function copyDir(src: string, dest: string, excludeIdeFolders?: boolean): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Merge source directory into destination, skipping existing files.
|
|
79
|
+
* Unlike copyDir, this preserves existing files in destination.
|
|
80
|
+
*
|
|
81
|
+
* @param src - Source directory path
|
|
82
|
+
* @param dest - Destination directory path
|
|
83
|
+
*/
|
|
84
|
+
export declare function mergeDirectory(src: string, dest: string, options?: {
|
|
85
|
+
exclude?: (name: string) => boolean;
|
|
86
|
+
}): Promise<void>;
|
|
77
87
|
/**
|
|
78
88
|
* Install template with IDE-specific folder selection.
|
|
79
89
|
*
|
|
@@ -128,16 +128,16 @@ export async function copyDir(src, dest, excludeIdeFolders = false) {
|
|
|
128
128
|
* @param src - Source directory path
|
|
129
129
|
* @param dest - Destination directory path
|
|
130
130
|
*/
|
|
131
|
-
async function mergeDirectory(src, dest) {
|
|
131
|
+
export async function mergeDirectory(src, dest, options) {
|
|
132
132
|
await fs.mkdir(dest, { recursive: true });
|
|
133
133
|
const entries = await fs.readdir(src, { withFileTypes: true });
|
|
134
134
|
const ops = entries
|
|
135
|
-
.filter((entry) => !
|
|
135
|
+
.filter((entry) => !(options?.exclude?.(entry.name)))
|
|
136
136
|
.map(async (entry) => {
|
|
137
137
|
const srcPath = join(src, entry.name);
|
|
138
138
|
const destPath = join(dest, entry.name);
|
|
139
139
|
if (entry.isDirectory()) {
|
|
140
|
-
await mergeDirectory(srcPath, destPath);
|
|
140
|
+
await mergeDirectory(srcPath, destPath, options);
|
|
141
141
|
}
|
|
142
142
|
else if (!(await pathExists(destPath))) {
|
|
143
143
|
await fs.copyFile(srcPath, destPath);
|
|
@@ -229,7 +229,7 @@ export async function installTemplate(config) {
|
|
|
229
229
|
}
|
|
230
230
|
else {
|
|
231
231
|
// No method-namespaced child — copy the entire subdirectory, merging with existing
|
|
232
|
-
await mergeDirectory(subdirSrc, subdirDest);
|
|
232
|
+
await mergeDirectory(subdirSrc, subdirDest, { exclude: shouldExclude });
|
|
233
233
|
}
|
|
234
234
|
});
|
|
235
235
|
await Promise.all(subdirOps);
|
|
@@ -4,6 +4,7 @@ export interface TerminalConfig {
|
|
|
4
4
|
}
|
|
5
5
|
export type WindowsShellPreference = 'default' | 'git-bash' | 'mintty';
|
|
6
6
|
export type WindowsTerminalStrategy = 'git-bash-in-wt' | 'mintty' | 'powershell-fallback' | 'windows-terminal';
|
|
7
|
+
export declare function defaultShell(): string;
|
|
7
8
|
export declare const LINUX_TERMINALS: TerminalConfig[];
|
|
8
9
|
export declare function resolveWindowsTerminalStrategy(preference: WindowsShellPreference, gitBashPath: null | string, minttyExists: boolean, powershellCmd: string): WindowsTerminalStrategy[];
|
|
9
10
|
export declare function detectPowerShell(isAvailable: (command: string) => boolean): string;
|
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
export function defaultShell() {
|
|
2
|
+
return process.env.SHELL || 'bash';
|
|
3
|
+
}
|
|
4
|
+
export const LINUX_TERMINALS = (() => {
|
|
5
|
+
const shell = defaultShell();
|
|
6
|
+
return [
|
|
7
|
+
{ cmd: 'x-terminal-emulator', getArgs: (command) => ['-e', `${shell} -c "${command}; exec ${shell}"`] },
|
|
8
|
+
{ cmd: 'gnome-terminal', getArgs: (command) => ['--', shell, '-c', `${command}; exec ${shell}`] },
|
|
9
|
+
{ cmd: 'konsole', getArgs: (command) => ['-e', `${shell} -c "${command}; exec ${shell}"`] },
|
|
10
|
+
{ cmd: 'xterm', getArgs: (command) => ['-e', `${shell} -c "${command}; exec ${shell}"`] },
|
|
11
|
+
];
|
|
12
|
+
})();
|
|
7
13
|
export function resolveWindowsTerminalStrategy(preference, gitBashPath, minttyExists, powershellCmd) {
|
|
8
14
|
const strategies = [];
|
|
9
15
|
if (preference === 'mintty') {
|
package/dist/lib/terminal.d.ts
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
*
|
|
7
7
|
* ## Supported Platforms
|
|
8
8
|
* - **Windows**: Windows Terminal (wt.exe) with PowerShell 7 (pwsh) fallback to PowerShell 5.1
|
|
9
|
-
* - **macOS**: Terminal.app via
|
|
9
|
+
* - **macOS**: Terminal.app via `open` + temporary `.command` script
|
|
10
10
|
* - **WSL**: Windows Terminal (wt.exe) via wsl.exe, falls back to Linux emulators
|
|
11
|
-
* - **Linux**: gnome-terminal, konsole, xterm
|
|
11
|
+
* - **Linux**: x-terminal-emulator, gnome-terminal, konsole, xterm (in order of preference)
|
|
12
12
|
*
|
|
13
13
|
* ## Usage
|
|
14
14
|
* ```typescript
|
|
@@ -36,7 +36,9 @@ export interface SpawnArgs {
|
|
|
36
36
|
/** @internal */
|
|
37
37
|
export declare function resolveTerminalPlatform(platform: NodeJS.Platform, isWSLResult: boolean): 'darwin' | 'linux' | 'windows' | 'wsl';
|
|
38
38
|
/** @internal */
|
|
39
|
-
export declare function
|
|
39
|
+
export declare function buildMacTerminalScriptContent(cwd: string, command: string, shellPath?: string): string;
|
|
40
|
+
/** @internal */
|
|
41
|
+
export declare function buildMacTerminalSpawnArgs(scriptPath: string): SpawnArgs;
|
|
40
42
|
/** @internal */
|
|
41
43
|
export declare function buildWindowsTerminalSpawnArgs(cwd: string, command: string, powershellCmd: string): SpawnArgs;
|
|
42
44
|
/** @internal */
|
|
@@ -92,9 +94,9 @@ interface TerminalLaunchResult {
|
|
|
92
94
|
* This function automatically detects the platform and uses the appropriate
|
|
93
95
|
* terminal emulator:
|
|
94
96
|
* - **Windows**: Windows Terminal (wt.exe) with PowerShell, falls back to PowerShell directly
|
|
95
|
-
* - **macOS**: Terminal.app via
|
|
97
|
+
* - **macOS**: Terminal.app via `open` + temporary `.command` script
|
|
96
98
|
* - **WSL**: Windows Terminal (wt.exe) via wsl.exe, falls back to Linux terminals
|
|
97
|
-
* - **Linux**: Tries gnome-terminal, konsole, xterm
|
|
99
|
+
* - **Linux**: Tries x-terminal-emulator, gnome-terminal, konsole, xterm in order
|
|
98
100
|
*
|
|
99
101
|
* The terminal is launched in detached mode, allowing the parent process to exit
|
|
100
102
|
* without affecting the new terminal.
|
package/dist/lib/terminal.js
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
*
|
|
7
7
|
* ## Supported Platforms
|
|
8
8
|
* - **Windows**: Windows Terminal (wt.exe) with PowerShell 7 (pwsh) fallback to PowerShell 5.1
|
|
9
|
-
* - **macOS**: Terminal.app via
|
|
9
|
+
* - **macOS**: Terminal.app via `open` + temporary `.command` script
|
|
10
10
|
* - **WSL**: Windows Terminal (wt.exe) via wsl.exe, falls back to Linux emulators
|
|
11
|
-
* - **Linux**: gnome-terminal, konsole, xterm
|
|
11
|
+
* - **Linux**: x-terminal-emulator, gnome-terminal, konsole, xterm (in order of preference)
|
|
12
12
|
*
|
|
13
13
|
* ## Usage
|
|
14
14
|
* ```typescript
|
|
@@ -28,14 +28,15 @@
|
|
|
28
28
|
* @module lib/terminal
|
|
29
29
|
*/
|
|
30
30
|
import { spawn } from 'node:child_process';
|
|
31
|
-
import { existsSync } from 'node:fs';
|
|
31
|
+
import { existsSync, writeFileSync } from 'node:fs';
|
|
32
|
+
import { tmpdir } from 'node:os';
|
|
32
33
|
import path from 'node:path';
|
|
33
|
-
import { cleanClaudeEnv } from './
|
|
34
|
+
import { sanitizedProcessEnv as cleanClaudeEnv } from './env-sanitizer.js';
|
|
34
35
|
import { isCommandAvailable } from './runtime/executable-policy.js';
|
|
35
36
|
import { isWindowsPlatform } from './runtime/platform-adapter.js';
|
|
36
37
|
import { findMsysBash } from './runtime/tmux-preflight.js';
|
|
37
38
|
import { escapeSingleQuotedPath } from './shell-quoting.js';
|
|
38
|
-
import { detectPowerShell, findAvailableLinuxTerminal, isWSL, resolveWindowsTerminalStrategy, } from './terminal-strategy.js';
|
|
39
|
+
import { defaultShell, detectPowerShell, findAvailableLinuxTerminal, isWSL, resolveWindowsTerminalStrategy, } from './terminal-strategy.js';
|
|
39
40
|
/** @internal */
|
|
40
41
|
export function resolveTerminalPlatform(platform, isWSLResult) {
|
|
41
42
|
if (isWindowsPlatform(platform))
|
|
@@ -47,13 +48,20 @@ export function resolveTerminalPlatform(platform, isWSLResult) {
|
|
|
47
48
|
return 'linux';
|
|
48
49
|
}
|
|
49
50
|
/** @internal */
|
|
50
|
-
export function
|
|
51
|
+
export function buildMacTerminalScriptContent(cwd, command, shellPath = defaultShell()) {
|
|
51
52
|
const escapedPath = escapeSingleQuotedPath(cwd, 'bash');
|
|
52
|
-
const
|
|
53
|
-
const
|
|
53
|
+
const escapedShell = escapeSingleQuotedPath(shellPath, 'bash');
|
|
54
|
+
const fullCommand = `cd '${escapedPath}' && ${command}; exec '${escapedShell}' -l`;
|
|
55
|
+
const escapedCommand = escapeSingleQuotedPath(fullCommand, 'bash');
|
|
56
|
+
return `#!/bin/sh
|
|
57
|
+
exec '${escapedShell}' -lc '${escapedCommand}'
|
|
58
|
+
`;
|
|
59
|
+
}
|
|
60
|
+
/** @internal */
|
|
61
|
+
export function buildMacTerminalSpawnArgs(scriptPath) {
|
|
54
62
|
return {
|
|
55
|
-
command: '
|
|
56
|
-
args: ['-
|
|
63
|
+
command: 'open',
|
|
64
|
+
args: ['-a', 'Terminal', scriptPath],
|
|
57
65
|
};
|
|
58
66
|
}
|
|
59
67
|
/** @internal */
|
|
@@ -84,10 +92,11 @@ export function buildLinuxTerminalSpawnArgs(cwd, command, terminalInfo) {
|
|
|
84
92
|
/** @internal */
|
|
85
93
|
export function buildWSLTerminalSpawnArgs(cwd, command) {
|
|
86
94
|
const escapedPath = escapeSingleQuotedPath(cwd, 'bash');
|
|
87
|
-
const
|
|
95
|
+
const shell = defaultShell();
|
|
96
|
+
const shellCmd = `cd '${escapedPath}' && ${command}; exec ${shell}`;
|
|
88
97
|
return {
|
|
89
98
|
command: 'wt.exe',
|
|
90
|
-
args: ['wsl.exe', '--',
|
|
99
|
+
args: ['wsl.exe', '--', shell, '-c', shellCmd],
|
|
91
100
|
};
|
|
92
101
|
}
|
|
93
102
|
/**
|
|
@@ -206,16 +215,30 @@ async function launchWindowsTerminal(cwd, command, shellPreference, debugLog) {
|
|
|
206
215
|
return tryStrategies();
|
|
207
216
|
}
|
|
208
217
|
/**
|
|
209
|
-
* Launch macOS Terminal.app with command.
|
|
218
|
+
* Launch macOS Terminal.app with a temporary `.command` script.
|
|
219
|
+
*
|
|
220
|
+
* Avoids AppleScript/Automation prompts by delegating to `open(1)` instead of
|
|
221
|
+
* sending Apple Events to Terminal.app.
|
|
210
222
|
*
|
|
211
223
|
* @param cwd - Working directory
|
|
212
224
|
* @param command - Command to execute
|
|
213
225
|
* @param debugLog - Optional debug logging function
|
|
214
226
|
*/
|
|
215
227
|
async function launchMacTerminal(cwd, command, debugLog) {
|
|
228
|
+
const scriptPath = path.join(tmpdir(), `aiwcli-terminal-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.command`);
|
|
229
|
+
try {
|
|
230
|
+
writeFileSync(scriptPath, buildMacTerminalScriptContent(cwd, command), {
|
|
231
|
+
encoding: 'utf8',
|
|
232
|
+
mode: 0o700,
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
catch (error) {
|
|
236
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
237
|
+
return { success: false, error: `Failed to prepare Terminal launch script: ${message}` };
|
|
238
|
+
}
|
|
216
239
|
return new Promise((resolve) => {
|
|
217
|
-
const spawnArgs = buildMacTerminalSpawnArgs(
|
|
218
|
-
debugLog?.(`Launching macOS Terminal with
|
|
240
|
+
const spawnArgs = buildMacTerminalSpawnArgs(scriptPath);
|
|
241
|
+
debugLog?.(`Launching macOS Terminal with script: ${scriptPath}`);
|
|
219
242
|
const terminal = spawn(spawnArgs.command, spawnArgs.args, {
|
|
220
243
|
detached: true,
|
|
221
244
|
stdio: 'ignore',
|
|
@@ -229,9 +252,9 @@ async function launchMacTerminal(cwd, command, debugLog) {
|
|
|
229
252
|
});
|
|
230
253
|
}
|
|
231
254
|
/**
|
|
232
|
-
* Launch Windows Terminal (wt.exe) from WSL, running the command inside a new
|
|
255
|
+
* Launch Windows Terminal (wt.exe) from WSL, running the command inside a new shell session.
|
|
233
256
|
*
|
|
234
|
-
* Uses wt.exe → wsl.exe →
|
|
257
|
+
* Uses wt.exe → wsl.exe → $SHELL so the new terminal inherits the correct WSL distro.
|
|
235
258
|
* Claude Code nesting-detection vars are stripped via cleanClaudeEnv().
|
|
236
259
|
*
|
|
237
260
|
* @param cwd - Working directory (WSL path)
|
|
@@ -293,9 +316,9 @@ async function launchLinuxTerminal(cwd, command, debugLog) {
|
|
|
293
316
|
* This function automatically detects the platform and uses the appropriate
|
|
294
317
|
* terminal emulator:
|
|
295
318
|
* - **Windows**: Windows Terminal (wt.exe) with PowerShell, falls back to PowerShell directly
|
|
296
|
-
* - **macOS**: Terminal.app via
|
|
319
|
+
* - **macOS**: Terminal.app via `open` + temporary `.command` script
|
|
297
320
|
* - **WSL**: Windows Terminal (wt.exe) via wsl.exe, falls back to Linux terminals
|
|
298
|
-
* - **Linux**: Tries gnome-terminal, konsole, xterm
|
|
321
|
+
* - **Linux**: Tries x-terminal-emulator, gnome-terminal, konsole, xterm in order
|
|
299
322
|
*
|
|
300
323
|
* The terminal is launched in detached mode, allowing the parent process to exit
|
|
301
324
|
* without affecting the new terminal.
|
|
@@ -1,5 +1,3 @@
|
|
|
1
1
|
export { quoteForSh } from './shell-quoting.js';
|
|
2
|
-
/** Fixed tmux server socket. Multiple named sessions share one server. */
|
|
3
|
-
export declare const TMUX_SOCKET_PATH: string;
|
|
4
2
|
/** Convert Windows path to MSYS2 POSIX path for tmux args. C:\foo\bar → /c/foo/bar */
|
|
5
3
|
export declare function toMsysPosixPath(winPath: string): string;
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import * as os from 'node:os';
|
|
2
|
-
import path from 'node:path';
|
|
3
1
|
export { quoteForSh } from './shell-quoting.js';
|
|
4
|
-
/** Fixed tmux server socket. Multiple named sessions share one server. */
|
|
5
|
-
export const TMUX_SOCKET_PATH = path.join(os.tmpdir(), 'aiwcli-tmux.sock');
|
|
6
2
|
/** Convert Windows path to MSYS2 POSIX path for tmux args. C:\foo\bar → /c/foo/bar */
|
|
7
3
|
export function toMsysPosixPath(winPath) {
|
|
8
4
|
if (process.platform !== 'win32')
|
package/dist/lib/tmux-session.js
CHANGED
|
@@ -2,6 +2,7 @@ import { execSync } from 'node:child_process';
|
|
|
2
2
|
import { writeFileSync } from 'node:fs';
|
|
3
3
|
import * as os from 'node:os';
|
|
4
4
|
import path from 'node:path';
|
|
5
|
+
import { buildBootstrapPrompt } from './mux-utils.js';
|
|
5
6
|
import { resolveExecutable } from './runtime/executable-policy.js';
|
|
6
7
|
import { isNonWindowsPlatform, resolveTmuxColorModeForPlatform, } from './runtime/platform-adapter.js';
|
|
7
8
|
import { quoteForSh } from './tmux-primitives.js';
|
|
@@ -46,7 +47,7 @@ export function buildShellCommand(opts) {
|
|
|
46
47
|
if (promptText) {
|
|
47
48
|
const tmpFile = path.join(os.tmpdir(), `aiwcli-prompt-${Date.now()}-${process.pid}.txt`);
|
|
48
49
|
writeFileSync(tmpFile, promptText, { encoding: 'utf8', mode: 0o600 });
|
|
49
|
-
const bootstrap =
|
|
50
|
+
const bootstrap = buildBootstrapPrompt(tmpFile);
|
|
50
51
|
cmdParts.push(quoteForSh(bootstrap));
|
|
51
52
|
}
|
|
52
53
|
// Export COLORTERM only when truecolor is intentionally enabled.
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { pathExists } from './paths.js';
|
|
1
|
+
import { IdePathResolver } from './ide-path-resolver.js';
|
|
2
|
+
import { readJsonFile, writeJsonFile } from './json-io.js';
|
|
4
3
|
/**
|
|
5
4
|
* Read Windsurf hooks from file
|
|
6
5
|
*
|
|
@@ -8,14 +7,7 @@ import { pathExists } from './paths.js';
|
|
|
8
7
|
* @returns Parsed hooks or undefined if file doesn't exist or is invalid
|
|
9
8
|
*/
|
|
10
9
|
export async function readWindsurfHooks(path) {
|
|
11
|
-
|
|
12
|
-
const content = await fs.readFile(path, 'utf8');
|
|
13
|
-
return JSON.parse(content);
|
|
14
|
-
}
|
|
15
|
-
catch {
|
|
16
|
-
// File doesn't exist or invalid JSON
|
|
17
|
-
return undefined;
|
|
18
|
-
}
|
|
10
|
+
return readJsonFile(path);
|
|
19
11
|
}
|
|
20
12
|
/**
|
|
21
13
|
* Write Windsurf hooks to file
|
|
@@ -28,17 +20,7 @@ export async function readWindsurfHooks(path) {
|
|
|
28
20
|
* @throws Error if write fails
|
|
29
21
|
*/
|
|
30
22
|
export async function writeWindsurfHooks(path, hooks) {
|
|
31
|
-
|
|
32
|
-
const dir = join(path, '..');
|
|
33
|
-
await fs.mkdir(dir, { recursive: true });
|
|
34
|
-
// Backup existing file if it exists
|
|
35
|
-
if (await pathExists(path)) {
|
|
36
|
-
const backupPath = `${path}.backup`;
|
|
37
|
-
await fs.copyFile(path, backupPath);
|
|
38
|
-
}
|
|
39
|
-
// Write hooks with pretty formatting
|
|
40
|
-
const content = JSON.stringify(hooks, null, 2);
|
|
41
|
-
await fs.writeFile(path, content, 'utf8');
|
|
23
|
+
return writeJsonFile(path, hooks, { backup: true });
|
|
42
24
|
}
|
|
43
25
|
/**
|
|
44
26
|
* Get the target hooks file for template hook merging
|
|
@@ -51,5 +33,6 @@ export async function writeWindsurfHooks(path, hooks) {
|
|
|
51
33
|
* @returns Path to target hooks file
|
|
52
34
|
*/
|
|
53
35
|
export function getTargetHooksFile(projectDir) {
|
|
54
|
-
|
|
36
|
+
const resolver = new IdePathResolver(projectDir);
|
|
37
|
+
return resolver.getWindsurfHooks();
|
|
55
38
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { ProcessSpawnError } from '../lib/errors.js';
|
|
2
2
|
export { ensureLspPatch } from '../lib/lsp-patch.js';
|
|
3
|
-
export { detectMultiplexer, type
|
|
3
|
+
export { detectMultiplexer, type LaunchResult, type SplitDirection } from '../lib/multiplexer.js';
|
|
4
|
+
export { REPL_NESTING_VARS } from '../lib/env-sanitizer.js';
|
|
4
5
|
export { readSentinelExitCode, waitForSentinelFile } from '../lib/runtime/sentinel-ipc.js';
|
|
5
6
|
export { findExecutable } from '../lib/runtime/subprocess-utils.js';
|
|
6
7
|
export { quoteForSh } from '../lib/shell-quoting.js';
|
package/dist/platform/launch.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { ProcessSpawnError } from '../lib/errors.js';
|
|
2
2
|
export { ensureLspPatch } from '../lib/lsp-patch.js';
|
|
3
3
|
export { detectMultiplexer } from '../lib/multiplexer.js';
|
|
4
|
+
export { REPL_NESTING_VARS } from '../lib/env-sanitizer.js';
|
|
4
5
|
export { readSentinelExitCode, waitForSentinelFile } from '../lib/runtime/sentinel-ipc.js';
|
|
5
6
|
export { findExecutable } from '../lib/runtime/subprocess-utils.js';
|
|
6
7
|
export { quoteForSh } from '../lib/shell-quoting.js';
|
package/dist/templates/CLAUDE.md
CHANGED
|
@@ -27,7 +27,6 @@ packages/cli/src/templates/
|
|
|
27
27
|
│ ├── runtime/ # Core runtime helpers
|
|
28
28
|
│ ├── context/ # Context CRUD, selection, formatting, plans, tasks
|
|
29
29
|
│ ├── hooks/ # Hook utility APIs
|
|
30
|
-
│ ├── agent-exec/ # Agent execution backends
|
|
31
30
|
│ └── templates/ # Output formatters, plan context templates
|
|
32
31
|
│
|
|
33
32
|
├── cc-native/ # CC-Native method template
|