Skip to content

feature: unified-shell-resolution (4/4) - #38

Closed
myk1yt wants to merge 35 commits into
pr/b06-terminal-lifecycle-v2from
pr/b07-shell-integration-v2
Closed

feature: unified-shell-resolution (4/4)#38
myk1yt wants to merge 35 commits into
pr/b06-terminal-lifecycle-v2from
pr/b07-shell-integration-v2

Conversation

@myk1yt

@myk1yt myk1yt commented Aug 2, 2026

Copy link
Copy Markdown
Owner

Stack Position

Description

Full Feature Description

  • Feature Branch: feature/unified-shell-resolution
  • Feature Name: Unified Shell Resolution
  • Purpose: Resolves the problem where shell selection, profile interpretation, argument assembly, and terminal reuse differ across command execution paths. Unifies the priority among user-configured shell, VS Code default profile, OS default, and safe fallback into a single typed resolution pipeline. This ensures that the same user settings produce a predictable execution environment across Windows Command Prompt, PowerShell, WSL, and macOS/Linux POSIX shells, reducing cases where the entire task fails in unclear ways due to misconfiguration.
  • Full Change Description: B04 defines the shared shell settings types and the UI using local cached state before saving. B05 resolves settings and platform information into an executable, shell family, source, and argument array, preserving argument boundaries instead of string concatenation. B06 manages command queue, terminal lifecycle, registry, reuse, trace, cancellation, and disposal. B07 connects the resolver and lifecycle to the task, command tool, extension API, and webview message paths.
  • Impact Scope: Affects the shared contracts terminal.ts, global-settings.ts, vscode-extension-host.ts, the settings UI TerminalSettings.tsx and SettingsView.tsx, the backend terminal layer src/integrations/terminal, and the task/tool/API wiring Task.ts, ExecuteCommandTool.ts, api.ts.
  • Errors and Edge Cases: If an explicit user override is invalid, returns a typed rejectable error. If an automatic candidate is invalid, proceeds to the next candidate. Timeout, user cancellation, non-zero exit, and terminal disposal are kept as distinct outcomes. Shell path and command arguments are never combined into a single unescaped string. Inputs in SettingsView.tsx bind to cachedState, not live extension state.
  • Testing Method: Run B04's contract and settings component tests, B05's Windows/POSIX/WSL resolution and invocation tests, B06's queue/reuse/cancellation/disposal tests, B07's task/tool/message tests and terminal-profile.test.ts. Manually run the same command in default, PowerShell, Command Prompt, and where available WSL/POSIX profiles, comparing the selected executable, output, exit code, cancellation, and cleanup.

Why Split Into 17 PRs

Instead of submitting this feature as a single unified PR, it was split into individual PRs because as code size grows, safely reviewing a PR becomes very difficult. The feature was broken into mutually exclusive individual PRs so that each can be reviewed independently.

What This PR Specifically Changes

Connects settings to command environment to lifecycle in Task.ts, ExecuteCommandTool.ts, ClineProvider.ts, and api.ts, and verifies E2E profile behavior. Does not add new primitives.

Included Files

  • src/core/task/Task.ts
  • src/core/webview/ClineProvider.ts
  • src/core/tools/ExecuteCommandTool.ts
  • src/extension/api.ts
  • Direct tests for terminal message/fallback/execute-command
  • apps/vscode-e2e/src/suite/tools/terminal-profile.test.ts

Exclusion Scope

  • New resolver or lifecycle primitives
  • Duplicate B04-B06 implementations
  • Task/provider changes unrelated to shell integration
  • All items in the common removal rules

@myk1yt
myk1yt force-pushed the pr/b06-terminal-lifecycle-v2 branch 2 times, most recently from c085865 to 13fdbae Compare August 2, 2026 10:04
@myk1yt
myk1yt force-pushed the pr/b07-shell-integration-v2 branch from cd98c53 to efcfaec Compare August 2, 2026 10:14
@myk1yt
myk1yt force-pushed the pr/b06-terminal-lifecycle-v2 branch from 13fdbae to b5e9f20 Compare August 2, 2026 14:14
@myk1yt
myk1yt force-pushed the pr/b07-shell-integration-v2 branch from efcfaec to 585ff2d Compare August 2, 2026 14:15
@myk1yt
myk1yt force-pushed the pr/b06-terminal-lifecycle-v2 branch from b5e9f20 to 7c726b2 Compare August 2, 2026 14:24
@myk1yt
myk1yt force-pushed the pr/b07-shell-integration-v2 branch from 585ff2d to 5fb6b61 Compare August 2, 2026 14:25
@myk1yt
myk1yt force-pushed the pr/b06-terminal-lifecycle-v2 branch from 7c726b2 to 151cb30 Compare August 2, 2026 18:25
@myk1yt
myk1yt force-pushed the pr/b07-shell-integration-v2 branch from 5fb6b61 to 9e4d06e Compare August 2, 2026 18:27
@myk1yt
myk1yt force-pushed the pr/b06-terminal-lifecycle-v2 branch from 151cb30 to a3c4f5b Compare August 2, 2026 18:38
@myk1yt
myk1yt force-pushed the pr/b07-shell-integration-v2 branch from 9e4d06e to 0802041 Compare August 2, 2026 18:40
@myk1yt
myk1yt force-pushed the pr/b06-terminal-lifecycle-v2 branch from a3c4f5b to 4534518 Compare August 2, 2026 18:50
@myk1yt
myk1yt force-pushed the pr/b07-shell-integration-v2 branch from 0802041 to 6107801 Compare August 2, 2026 18:50
@myk1yt
myk1yt force-pushed the pr/b06-terminal-lifecycle-v2 branch from 4534518 to fe0ed18 Compare August 2, 2026 19:43
@myk1yt
myk1yt force-pushed the pr/b07-shell-integration-v2 branch from 6107801 to cbaa522 Compare August 2, 2026 19:43
@myk1yt
myk1yt force-pushed the pr/b06-terminal-lifecycle-v2 branch from fe0ed18 to 7bb69de Compare August 2, 2026 20:13
@myk1yt
myk1yt force-pushed the pr/b07-shell-integration-v2 branch from cbaa522 to 88499d2 Compare August 2, 2026 20:13
@myk1yt myk1yt changed the title B07: Shell Integration v2 feature: unified-shell-resolution (4/4) Aug 3, 2026
@myk1yt
myk1yt force-pushed the pr/b07-shell-integration-v2 branch 2 times, most recently from 10f81ce to bffc5e5 Compare August 4, 2026 06:13
@myk1yt
myk1yt force-pushed the pr/b06-terminal-lifecycle-v2 branch from 1e0f087 to 4fe1300 Compare August 4, 2026 11:40
@myk1yt
myk1yt force-pushed the pr/b07-shell-integration-v2 branch from bffc5e5 to 5f48727 Compare August 4, 2026 11:40
@myk1yt
myk1yt force-pushed the pr/b06-terminal-lifecycle-v2 branch from 4fe1300 to 81d56ef Compare August 4, 2026 20:28
Zoo (VP) added 7 commits August 6, 2026 03:11
Merge feature/unified-shell-resolution into pr/b04-shell-contracts-v2.
Combines B04's command_output ask delay with B05's shell resolution
system (ShellResolver, ShellInvocationAdapter, TerminalProfileResolver,
CommandEnvironmentService, CommandScheduler).

Conflict resolution in ExecuteCommandTool.ts:
- Kept B05 ShellFallbackMismatchError + enhanced getTerminalProviderForExecution
- Kept B04 COMMAND_OUTPUT_ASK_DELAY_MS + command_output ask delay logic
- Merged onShellExecutionStarted signature (process param from B04 + traceBuilder from B05)
- Combined commandStartedAt fallback with ExecaTerminal shell invocation plan

Conflict resolution in executeCommandTool.spec.ts:
- Kept both B04 command_output ask policy tests and B05 cwd parameter validation tests

Note: no-explicit-any lint errors are pre-existing in feature/unified-shell-resolution
…s for new test files, update counts for modified files
…onmentService - fixes e2e terminal-profile test where no VS Code terminal was created because provider was hardcoded to execa
Zoo (VP) added 11 commits August 6, 2026 03:16
--noprofile also blocks VS Code's bash shell integration injection
(just like --norc). Use --login instead, which is safe for shell
integration while still proving custom profile args pass-through.
…nterface - optional lifecycle broke TS18048 across TerminalRegistry, ExecuteCommandTool, and ExecaTerminalProcess
…nmentService

The unified shell resolution system ignored the user's terminalShellIntegrationDisabled setting.
- Add terminalShellIntegrationDisabled to CommandEnvironmentSettings
- Use it in resolveEnvironment() to determine primaryProvider
- Pass it from Task.resolveCommandEnvironment() and ClineProvider startup hydration
The shell dropdown's onShellSelectionChange only updated the pending
selection state; the Save button stayed disabled unless the unrelated
onTerminalProfilePickerOpened hook happened to fire. Wrap the handler so
a shell selection change explicitly calls setChangeDetected(true),
enabling Save on shell-only changes. Behavior is otherwise identical.
…ClineProvider.ts

Remove stats/task-organization/tool-call-policy references pulled in by a
bad merge from other feature branches (services/stats, ToolCallRetentionPolicy,
resolveToolCallPolicy, TaskOrganizationStore, usageStatsChanged and
taskOrganizationUpdated messages) which do not exist on this branch and broke
compile, knip, and esbuild on PR 38. Keeps only the shell-related changes:
passing terminalShellIntegrationDisabled into CommandEnvironmentService
hydration and request-scoped environment resolution.
The Terminal settings Browse button posted requestCustomShellPath whose
handler immediately persisted the picked path via
handleSetTerminalShellSelection, so clicking Discard afterwards could not
revert it. The handler now delegates to the new non-persisting
ClineProvider.handleCustomShellPathPicked(), which validates the path via
ShellResolver and returns it to the webview in a customShellPathSelected
message (with a typed error on validation failure). The webview buffers
the path as a pending selection and shows it in the dropdown; persistence
happens only on Save through the existing setTerminalShellSelection path.
@myk1yt
myk1yt force-pushed the pr/b07-shell-integration-v2 branch from e87d7e4 to 38d0829 Compare August 5, 2026 18:25
@myk1yt
myk1yt force-pushed the pr/b06-terminal-lifecycle-v2 branch from 81d56ef to bf2d780 Compare August 6, 2026 04:42
- CommandTrace.spec.ts: 23 tests (builder, collector, finalize)
- CommandEnvironmentService.spec.ts: 18 tests (caching, execa, fallback)
- TerminalProfileResolver.spec.ts: 48 tests (PATH resolution, profiles, env)
- terminal-shell-settings.spec.ts: +13 tests (commandExecutionStatusSchema)
@myk1yt
myk1yt force-pushed the pr/b07-shell-integration-v2 branch from 7f5ecdc to f368426 Compare August 6, 2026 07:37
@myk1yt
myk1yt force-pushed the pr/b07-shell-integration-v2 branch from 2b88304 to e44f18d Compare August 7, 2026 09:19
@myk1yt
myk1yt deleted the branch pr/b06-terminal-lifecycle-v2 August 7, 2026 13:05
@myk1yt myk1yt closed this Aug 7, 2026
@myk1yt
myk1yt deleted the pr/b07-shell-integration-v2 branch August 7, 2026 13:06
@myk1yt
myk1yt restored the pr/b07-shell-integration-v2 branch August 7, 2026 13:32
@myk1yt myk1yt reopened this Aug 8, 2026
Zoo (VP) added 2 commits August 8, 2026 14:56
…-Org#1136)

CI failure: E2E Tests (Mocked) run 31227034941 failed both Shell Integration
tests with AssertionError because the system prompt rendered the legacy
'Default Shell: /bin/bash' fallback instead of the structured block
(Command Execution Provider / Shell Resolution Source / Shell Constraints).
Root cause: Task.getSystemPrompt omitted the final resolvedEnv argument, so
getSystemInfoSection(cwd, resolvedEnv) always received undefined and fell
back to getShell(). Passing this.resolvedCommandEnvironment threads the
resolved shell environment into the prompt.
Run: https://github.com/Zoo-Code-Org/Zoo-Code/actions/runs/31227034941
CommandEnvironmentService caches resolved shell by version counter.
API.setConfiguration persisted terminalShellSelection without
invalidating the cache, causing stale OS Default to appear in system
prompt instead of User Override. Now invalidates when terminalShellSelection,
execaShellPath, or terminalProfile is present.
@myk1yt

myk1yt commented Aug 10, 2026

Copy link
Copy Markdown
Owner Author

Closing to recreate with main as target base branch. This PR had stale base branch references after fork sync.

@myk1yt myk1yt closed this Aug 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant