- types/protocol: ClientMessage approve/reject; ServerMessage status.pending
- server: POST /hook/permission HELD until the client decides; approve/reject
ws messages resolve it with {hookSpecificOutput.decision.behavior allow|deny};
5-min timeout + release-on-disconnect fall back to Claude's own prompt
- manager.handleHookEvent threads pending flag
- setup-hooks: PermissionRequest uses the held curl (writes decision to stdout);
status events stay fire-and-forget
- FE: terminal-session approve()/reject() + pending state; tabs approval banner
(Approve/Reject) for the active tab's held request
- Tests: protocol approve/reject; integration ⑧ held→approve→allow. 207 green.
- Browser-verified: banner 'Claude wants to use Bash' → Approve → resolves allow.