chat.tools.terminal.autoApprove (and related terminal tool auto-approval) does not match inner commands when the command line uses common wrappers (timeout, bash -c, env, sudo time, etc.)

Open
#318,347 1 comment 1 reaction 1 assignee View on GitHub

@anthonykim1 is already working on this.

Since May 26, 2026.

Assessment

This issue has not been assessed yet.

Description

bug terminal-auto-approve
Problem

The chat.tools.terminal.autoApprove setting (and the underlying auto-approval logic used by the Run in Terminal tool) only matches against the outermost command(s) returned by TreeSitterCommandParser.extractSubCommands.

Common wrapper patterns used in agent workflows (timeouts, explicit shells for cd + command, environment setup, etc.) cause the inner "real" command (git, npm run build, etc.) to be invisible to the rule matcher. As a result, granular allow/deny rules for those inner commands never fire, and users are forced to either:

  • Approve every invocation manually, or
  • Use very broad rules (e.g. bash or the full timeout ... line), which is both less safe and less convenient.
Steps to Reproduce
  1. Add a rule such as:
    "chat.tools.terminal.autoApprove": {
      "git": true,
      "npm": true
    }
    
  2. Ask the agent to run something that produces a wrapped command, for example the pattern commonly generated from copilot-instructions.md:
    timeout 30 bash -c 'cd /home/src/code && git status --porcelain'
    
    (or env ..., sudo time git ..., bash -c "...", etc.)
  3. Observe that the command requires explicit confirmation even though git (or npm) would have been auto-approved without the wrapper.
Expected behavior

The auto-approval logic should "see through" well-known wrappers (the same way other parts of the terminal chat agent tools already do for sandboxing/display) and evaluate the effective inner command(s) against the user's rules. A git rule should still apply when the command is wrapped in timeout 30 bash -c '...'.

Actual behavior

Only the outer command (timeout, bash, env, etc.) is considered. Inner commands are never extracted for rule matching.

Additional context / motivation
  • This pattern is actively used in real agent instructions (see the user's copilot-instructions.md for the exact timeout 30 bash -c 'cd ... && ...' idiom).
  • The terminal chat agent tools already contain richer command parsing that identifies wrappers and inner tokens (src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/terminalCommandParser.tsparseCommand, wrappers, segmentHead, etc.).
  • Recent work (#315881 and related compression-parsing improvements) enhanced wrapper handling for other purposes; the auto-approve path was not updated at the same time.
  • Security note: the existing neverAutoApproveCommands set in runInTerminalHelpers.ts (shells, interpreters, sudo, eval, etc.) should continue to be respected when deciding what to surface for approval suggestions.
References to current implementation
  • Primary parser used for auto-approval:
    src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/treeSitterCommandParser.ts
    extractSubCommands (the query (command) @command) and extractCommands.
  • Auto-approval decision logic:
    src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/autoApprove/commandLineAutoApprover.ts
    CommandLineAutoApproveAnalyzer (in commandLineAutoApproveAnalyzer.ts).
  • Richer wrapper-aware parser (already used for sandboxing):
    src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/terminalCommandParser.ts.
  • neverAutoApproveCommands guard:
    src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/runInTerminalHelpers.ts.
  • Platform-level auto-approver (similar tree-sitter usage):
    src/vs/platform/agentHost/node/commandAutoApprover.ts.
Possible implementation direction
  • Extend CommandLineAutoApproveAnalyzer (or the approver) to also call the existing wrapper-stripping logic from terminalCommandParser.ts (or a shared helper) and feed the effective inner commands to the rule matcher.
  • Alternatively, enhance TreeSitterCommandParser (or add a post-processing step) to optionally return "unwrapped" commands for the auto-approve use case.
  • Ensure the change does not affect the security-sensitive neverAutoApproveCommands list or the exact-command-line matching path.

This would make the auto-approve experience consistent with the rest of the terminal agent tooling and dramatically improve usability for realistic long-running or multi-step agent commands.

Dominant language
TypeScript
Stars
193k
Forks
42.9k
PR merge metrics
PR metrics pending

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from microsoft/vscode

All issues in microsoft/vscode

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.