github / github/copilot-cli

Hook `async` property silently ignored — postToolUse hooks block tool completion

未关闭
#3,063 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
area:plugins area:tools
主要语言
Shell
星标
11.2k
派生
1.9k
平均合并
14 小时 16 分钟
30 天内合并 PR
6

描述

## Describe the bug

The `async` property on command hooks in `hooks.json` is silently ignored. Hooks with `"async": true` still block tool completion because `executeHooks()` unconditionally `await`s every hook in a sequential `for` loop.

Claude Code [documents `async`](https://docs.anthropic.com/en/docs/claude-code/hooks) as a supported hook field:

> **`async`** — If `true`, runs in the background without blocking.

Since plugins share the same `hooks.json` format across both Claude Code and Copilot CLI, authors reasonably expect `"async": true` to work. Instead, it is parsed by the Zod schema (via `.passthrough()`) but never read by the execution path.

## Impact

In a real session, a `postToolUse` hook with `"async": true` blocked for **13.5 seconds** on first invocation because it triggered a package auto-update (resolving 419 packages via `uv`). This added ~14s of latency to the first tool call of the session despite the hook being marked async.

**Timeline from session events:**
```
18:57:09.756 hook.start postToolUse
18:57:22.186 [hook stdout] Resolved 419 packages in 6.91s
18:57:22.803 [hook stdout] Installed 2 packages
18:57:23.216 hook.end ← 13.46s blocked
```

## Root cause

In `sdk/index.js`, the `executeHooks` function (`Yg` in minified source):

```javascript
async function executeHooks(hooks, input, logger, hookType, emitter) {
// ...
for (let hook of hooks) {
let result = await hook(input); // ← always awaits, ignores async flag
// ...
}
}
```

And in `processToolExecutionResult`:
```javascript
await executeHooks(this.getEffectiveHooks()?.postToolUse, ...) // blocks tool completion
```

The `async` property from the hook config is never propagated to the execution layer.

## Expected behavior

When a hook specifies `"async": true`, it should run in the background without blocking tool completion — matching Claude Code's documented behavior. Ideally also support `asyncRewake` for parity.

## Workaround

Plugin authors can append `&` to the shell command to background it manually, but this loses stdout/stderr capture and exit code handling.

## Environment

- Copilot CLI: 1.0.40-2
- OS: macOS (Darwin arm64)

## Related issues

- #2893 — hooks serialized + timeout fail-open (related hook execution model concerns)

贡献指南

打开贡献指南

调研方向

首先跟踪 sdk/index.js 中的 executeHooks 以及它从 processToolExecutionResult 发起的调用,然后检查 hook 配置如何传递到执行层。确认异步 hook 应如何在后台完成,以及输出、错误和工具完成应是什么样;完成的标准是异步 hook 不再阻塞,同时同步 hook 保持当前行为不变。

由索引模型根据 Issue 内容生成。

评估

技术栈
javascript
领域
cli
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
冷清
描述清晰度
基本清楚
新手友好度
48/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。