github / github/copilot-cli

preToolUse hook returning 'allow' should short-circuit built-in tool dialogs like exit_plan_mode

Đang mở
#2,349 0 bình luận 3 reaction 0 người được giao Xem trên GitHub
area:agents area:plugins
Ngôn ngữ chính
Shell
Star
11.2k
Fork
1.9k
Merge trung bình
14 giờ 16 phút
Pull request đã merge (30 ngày)
6

Mô tả

## Summary

When a `preToolUse` hook returns `permissionDecision: "allow"` for the `exit_plan_mode` tool, the built-in plan approval dialog still appears, requiring the user to manually click through it. This makes it impossible for hooks to fully automate plan approval, even though `"deny"` already fully short-circuits tool execution.

## Current behavior

1. `preToolUse` hook fires for `exit_plan_mode`
2. Hook returns `{ "permissionDecision": "allow" }` -- this only answers "yes, this tool may run"
3. The tool executes and calls `requestExitPlanMode()` internally
4. The plan approval dialog (`exit_plan_mode.requested`) appears anyway
5. User must manually approve a second time

`"deny"` works perfectly -- the tool never executes, no dialog appears. But `"allow"` is effectively a no-op for tools that have their own built-in interaction dialogs.

## Use case

I build [Plannotator](https://github.com/ramos/plannotator), a visual plan review UI for agentic coding tools. My `preToolUse` hook intercepts `exit_plan_mode`, opens a rich review interface, collects the user's decision, and returns `"allow"` or `"deny"` with feedback. The deny path works great. But on approval, users still have to click through the CLI's plan dialog -- making the approval flow feel redundant.

Hook config:
```json
{
"hooks": {
"preToolUse": [
{
"type": "command",
"bash": "$HOME/.local/bin/plannotator copilot-plan",
"timeoutSec": 345600
}
]
}
}
```

## Proposed solution

Allow `preToolUse` hooks returning `"allow"` for tools with built-in dialogs (like `exit_plan_mode`) to supply the dialog response, skipping the dialog entirely. For example:

```json
{
"permissionDecision": "allow",
"exitPlanModeResponse": {
"approved": true,
"selectedAction": "interactive",
"autoApproveEdits": false
}
}
```

Alternatively, any of these would also work:

- A dedicated `preExitPlanMode` hook type in `QueryHooks` with `ExitPlanModeResponse` as its output type
- A general `preInteraction` hook that fires before any blocking dialog on the `InteractionManager`
- Treating `preToolUse` `"allow"` on `exit_plan_mode` as implicit plan approval (using defaults for `selectedAction`, etc.)

## Why this matters

The current behavior is asymmetric: `"deny"` gives hooks full control, but `"allow"` still forces a manual step. Extensions that implement their own review UI (with richer context, annotations, sharing, etc.) cannot fully replace the built-in dialog on the approval path. This limits the extensibility that the hook system otherwise enables well.

For provenance purposes, this issue was AI assisted.
- not spam though, also the person who authored [this issue](https://github.com/anthropics/claude-code/issues/712).

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.