Skip to content

feat(copilot): cross-platform PreToolUse hook via rtk hook (VS Code + Copilot CLI + Windows)#605

Open
jeziellopes wants to merge 6 commits intortk-ai:developfrom
jeziellopes:feat(copilot)/copilot-cli-integration
Open

feat(copilot): cross-platform PreToolUse hook via rtk hook (VS Code + Copilot CLI + Windows)#605
jeziellopes wants to merge 6 commits intortk-ai:developfrom
jeziellopes:feat(copilot)/copilot-cli-integration

Conversation

@jeziellopes
Copy link

@jeziellopes jeziellopes commented Mar 15, 2026

Closes #593

What this adds

Cross-platform PreToolUse hook for GitHub Copilot (VS Code Copilot Chat + Copilot CLI) via rtk hook — a native Rust binary. No bash scripts, no jq, works on Windows natively.

How it works

rtk hook reads PreToolUse JSON from stdin, detects the agent format, responds appropriately:

VS Code Copilot Chat (updatedInput — transparent rewrite):

git status → rtk hook → updatedInput: "rtk git status"  (silent, no denial)

GitHub Copilot CLI (deny-with-suggestion — CLI ignores updatedInput today, copilot-cli#2013):

git status → rtk hook → deny: "Token savings: use `rtk git status` instead"
             Copilot reads reason → re-runs rtk git status

When Copilot CLI adds updatedInput support, only rtk hook needs a one-line change.

Also fixed

The old .github/hooks/rtk-rewrite.json had wrong key names (preToolUsePreToolUse, bash/timeoutSeccommand/timeout) that prevented it from loading in VS Code.

Measured gains (validated Copilot CLI session)

Command Savings Tokens saved
rtk cargo test 99.9% 15.8K
rtk cargo clippy --all-targets 93.3% 5.9K
rtk git diff HEAD~1 81.2% 2.6K
rtk gh pr list 67.0% 0.8K
Session total (24 commands) 83.5% avg ~23.3K

Files

File Role
src/hook_cmd.rs New rtk hook subcommand (13 unit tests)
.github/hooks/rtk-rewrite.json Fixed key casing, points to rtk hook
hooks/copilot-rtk-rewrite.sh Deleted — replaced by rtk hook
hooks/test-copilot-rtk-rewrite.sh Rewritten to test rtk hook
hooks/copilot-rtk-awareness.md Updated: VS Code row, both output paths
src/init.rs Remove bash script checks, update status message
README.md VS Code Copilot Chat support, Windows note
CHANGELOG.md Updated unreleased entry

Testing

# Unit tests (13 tests)
cargo test hook_cmd

# Manual: Copilot CLI deny path
echo '{"toolName":"bash","toolArgs":"{\"command\":\"git status\"}"}' | rtk hook

# Manual: VS Code updatedInput path
echo '{"tool_name":"Bash","tool_input":{"command":"git status"}}' | rtk hook

# Verify rtk init --show
rtk init --show

jeziellopes and others added 3 commits March 15, 2026 13:00
Add .github/copilot-instructions.md so GitHub Copilot CLI sessions
automatically receive rtk usage instructions at startup. Includes:
- Explicit 'always prefix with rtk' directive with before/after examples
- Meta-commands reference (rtk gain, rtk discover, rtk proxy)
- Installation verification step
- Name-collision warning (reachingforthejack/rtk vs rtk-ai/rtk)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: jeziellopes <jeziellopes@gmail.com>
Add GitHub Copilot CLI hook integration using the deny-with-suggestion
pattern (Copilot CLI hooks cannot rewrite commands, only deny them):

- .github/hooks/rtk-rewrite.json: preToolUse hook config
- hooks/copilot-rtk-rewrite.sh: script that calls 'rtk rewrite' and denies
  raw commands with reason 'Token savings: use rtk X instead'
- hooks/copilot-rtk-awareness.md: integration docs (mirrors rtk-awareness.md)
- README.md: GitHub Copilot CLI section under Auto-Rewrite Hook

Copilot CLI reads .github/hooks/*.json automatically — no rtk init needed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: jeziellopes <jeziellopes@gmail.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: jeziellopes <jeziellopes@gmail.com>
jeziellopes and others added 2 commits March 15, 2026 13:24
Show Copilot CLI integration status in `rtk init --show` output,
alongside existing Claude Code and OpenCode checks:

  ✅ Copilot CLI: hook + instructions configured (repo-scoped, automatic)
  ⚠️  Copilot CLI: hook config found but script missing or not executable
  ⚪ Copilot CLI: not configured

Also adds const COPILOT_HOOK_SCRIPT and test_copilot_hook_has_guards
to verify guard ordering mirrors the Claude Code hook convention.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: jeziellopes <jeziellopes@gmail.com>
22 tests covering:
- Intercepted commands (git, cargo, grep, gh) → deny with rtk suggestion
- Pass-through: already-rtk, heredoc, unknown commands, non-bash tools, empty input
- Output format: valid JSON, permissionDecision=deny, backtick-quoted rtk command in reason

Mirrors the structure of hooks/test-rtk-rewrite.sh for the Claude Code hook.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: jeziellopes <jeziellopes@gmail.com>
@vrdons
Copy link

vrdons commented Mar 17, 2026

You should have to do windows support too, also his maybe works on vscode copilot integration. I'm planning to add many extensions to the VS Code chat integration.

@vrdons
Copy link

vrdons commented Mar 17, 2026

Also rewrite script should be automated. Maybe adding rust code should fix that

Replace hooks/copilot-rtk-rewrite.sh with rtk hook — a native Rust binary
that handles PreToolUse hooks for both VS Code Copilot Chat and Copilot CLI.

- VS Code Copilot Chat: returns updatedInput (transparent rewrite, no denial)
- GitHub Copilot CLI: returns permissionDecision: deny with suggestion
  (CLI ignores updatedInput today — tracked in copilot-cli#2013)
- Windows: works natively, no bash or jq dependency

Changes:
- src/hook_cmd.rs: new subcommand, detects format via toolName vs tool_name
- .github/hooks/rtk-rewrite.json: fix key casing (PreToolUse), point to rtk hook
- hooks/copilot-rtk-rewrite.sh: deleted (replaced by rtk hook binary)
- hooks/test-copilot-rtk-rewrite.sh: rewritten to test rtk hook binary
- src/init.rs: remove COPILOT_HOOK_SCRIPT constant and bash script checks
- hooks/copilot-rtk-awareness.md: add VS Code row, document both paths
- README.md: rename section, add VS Code Copilot Chat, Windows note
- CHANGELOG.md: update unreleased entry

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: jeziellopes <jeziellopes@gmail.com>
@jeziellopes
Copy link
Author

@vrdons Great suggestions — this PR has been expanded to implement exactly what you described.

Rust binary instead of bash script
Replaced hooks/copilot-rtk-rewrite.sh with rtk hook, a native Rust subcommand. No bash, no jq, no shell dependency. Works on Windows natively.

VS Code Copilot Chat support
VS Code reads .github/hooks/*.json automatically (same dir, same format). I investigated the VS Code hooks docs and found that VS Code also supports updatedInput — which enables a transparent rewrite instead of a deny. So now rtk hook handles both agents differently:

  • VS Code Copilot Chat → returns updatedInput (silent rewrite, no denial, no retry)
  • GitHub Copilot CLI → returns permissionDecision: deny with suggestion (CLI ignores updatedInput today — tracked in copilot-cli#2013)

When Copilot CLI adds updatedInput support, only rtk hook needs a one-line change.

The old bash hook also had wrong key casing (preToolUse → should be PreToolUse, bash/timeoutSec → should be command/timeout). All fixed now.

@jeziellopes jeziellopes changed the title feat(copilot): GitHub Copilot CLI integration feat(copilot): cross-platform PreToolUse hook via rtk hook (VS Code + Copilot CLI + Windows) Mar 18, 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.

2 participants