github / github/copilot-cli

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

オープン
#2,349 コメント 0 件 リアクション 3 件 担当者 0 名 GitHub で見る
area:agents area:plugins
主要言語
Shell
スター
11.2k
フォーク
1.9k
平均マージ
14時間 16分
マージ済み PR(30日)
6

説明

## 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).

コントリビューションガイド

コントリビューションガイドを開く

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。