rtk-ai/rtk

`[Bug] rtk hook copilot` does not trigger for VS Code Copilot Chat — `"run_in_terminal"` not recognized in `detect_format()`

Open

#1425 opened on Apr 21, 2026

View on GitHub
 (2 comments) (2 reactions) (0 assignees)Rust (48,085 stars) (2,914 forks)batch import
P1-criticalbugeffort-smallgood first issue

Description

Summary

rtk hook copilot produces no output (PassThrough) when invoked from VS Code Copilot Chat, because detect_format() does not recognize "run_in_terminal" as a valid tool name. As a result, the hook never fires and all commands pass through without rewriting.


Environment

  • RTK version: 0.37.2 (Homebrew)
  • AI tool: VS Code Copilot Chat extension (not Copilot CLI)
  • OS: Ubuntu (WSL2)
  • No copilot-instructions.md was active during hook verification (isolated hook behavior only)

Root Cause

VS Code Copilot Chat sends tool_name: "run_in_terminal" in the PreToolUse hook payload, but detect_format() only matches "runTerminalCommand", "Bash", and "bash":

// src/hooks/hook_cmd.rs
if matches!(tool_name, "runTerminalCommand" | "Bash" | "bash") {

This causes all commands from VS Code Copilot Chat to fall through to HookFormat::PassThrough, and the hook returns no output.


Evidence

Actual JSON received by the hook (captured via debug wrapper script):

{
  "tool_name": "run_in_terminal",
  "tool_input": {
    "command": "git status",
    "explanation": "Check current git status",
    "mode": "sync",
    "timeout": 60000
  }
}

VS Code Output panel (GitHub Copilot Chat Hooks channel):

[PreToolUse] Input: {"tool_name":"run_in_terminal","tool_input":"..."}
[PreToolUse] Completed (Success) in 26ms, no output

Fix

Add "run_in_terminal" to the match arm in detect_format():

if matches!(tool_name, "runTerminalCommand" | "Bash" | "bash" | "run_in_terminal") {

Verified locally with a source build — the hook correctly rewrites commands after this change.


Additional Context: Allow loop after fix (updatedInput not honored)

After applying the fix above, a secondary issue appears in VS Code Copilot Chat:

When the hook returns permissionDecision: "ask" with updatedInput, VS Code Copilot Chat enters an infinite Allow-dialog loop:

  1. Hook fires → returns "ask" + updatedInput: {"command": "rtk git status"}
  2. Copilot Chat shows an Allow dialog
  3. User clicks Allow
  4. updatedInput is ignored — the original command (git status) is retried
  5. Hook fires again → loop repeats

This is consistent with the updatedInput problems reported in Copilot CLI:

  • github/copilot-cli#2013updatedInput was completely ignored in CLI (fixed in v1.0.24)
  • github/copilot-cli#2643 — even after the fix, permissionDecision: "allow"
    • updatedInput still shows a confirmation dialog on every rewrite. The issue notes that deny-with-suggestion was less disruptive because denials are handled gracefully by the agent without surfacing a modal to the user.

The same class of problem appears to affect VS Code Copilot Chat. Resolution is expected on the Copilot side.

Workaround (verified working in VS Code Copilot Chat, 2026-04-21):

Use permissionDecision: "deny" with a suggestion message — the same approach that the Copilot CLI community has recognized as the practical workaround:

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "deny",
    "permissionDecisionReason": "Token savings: use `rtk git status` instead (rtk saves 60-90% tokens)"
  }
}

With this approach, Copilot Chat reads the reason message and automatically retries with rtk git status without surfacing a dialog to the user.

Contributor guide