Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/copilot/customization/hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -599,12 +599,12 @@ INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
TOOL_INPUT=$(echo "$INPUT" | jq -r '.tool_input')

if [ "$TOOL_NAME" = "runTerminalCommand" ]; then
if [ "$TOOL_NAME" = "run_in_terminal" ]; then
COMMAND=$(echo "$TOOL_INPUT" | jq -r '.command // empty')

if echo "$COMMAND" | grep -qE '(rm\s+-rf|DROP\s+TABLE|DELETE\s+FROM)'; then
echo '{"hookSpecificOutput":{"permissionDecision":"deny","permissionDecisionReason":"Destructive command blocked by security policy"}}'
exit 0
exit 2
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The user would get a generic "unexpected error" with exit code 2. With the exit code 0, the command is denied and the provided reason is shown. Can you revert back to exit code 0?

Copy link
Copy Markdown
Author

@painfulexistence painfulexistence Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @ntrogh, thanks for the review!

I did try exit code 0 and it didn't work. The command did not be blocked when exit code is either 0 or 1.
(I've double checked one minutes ago)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@painfulexistence Ok, let me check if this is a bug. Thanks for looking into this!

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@painfulexistence I can't repro with exit code 0. The hook blocks the command from executing. I do notice that the regex in the sample only blocks rm -rf and not plan rm. Can you check in the agent debug logs (... > Show Agent Debug Logs) which command is being run by the LLM?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I tested it with git add command.
FYI, I ran in autopilot mode. I can still reproduce this issue with exit code 0. Could you try it with autopilot mode?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, this might actually be a side-effect of Autopilot, which auto-approves all tool calls.
I'll create an issue in the vscode repo.

Can you confirm the hook works with exit code 0 when you use default permissions?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I tried Default Approvals mode, but exit code 0 still did not block specified commands. Only exit code 2 works for me.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@painfulexistence This seems to be a product issue. Can you log an issue in the microsoft/vscode repo and provide the repro steps for the scenario that doesn't work with exit code 2?

fi
fi

Expand Down Expand Up @@ -717,7 +717,7 @@ INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')

# Tools that should always require approval
SENSITIVE_TOOLS="runTerminalCommand|deleteFile|pushToGitHub"
SENSITIVE_TOOLS="run_in_terminal|deleteFile|pushToGitHub"

if echo "$TOOL_NAME" | grep -qE "^($SENSITIVE_TOOLS)$"; then
echo '{"hookSpecificOutput":{"permissionDecision":"ask","permissionDecisionReason":"This operation requires manual approval"}}'
Expand Down