Add permission mode tracking across the local→remote switch so mode changes
made inside the interactive Claude TUI (shift+tab) are inherited when
launching remote. Previously, a mode picked in local TUI was invisible to
remote sessions.
Implementation:
- generateHookSettings: add trackPermissionMode option to register UserPromptSubmit
and PreToolUse hooks (their payloads carry permission_mode; SessionStart's does
not). Export buildHookSettings for testing and make matcher optional.
- New hookPermissionMode.ts: normalizer for hook permission_mode → HAPI mode
('manual' → 'default'; unknown modes like 'dontAsk' → null/ignored).
- runClaude.ts: generate a second, local-TUI-only hook settings file with
trackPermissionMode enabled (remote SDK process keeps the SessionStart-only
file — these hooks block Claude per prompt/tool, and remote state is owned
by hub/RPC). Hook callback inherits mode when session.mode === 'local': updates
currentPermissionMode, syncs session, pushes keepalive, emits permission-mode-
changed event.
- session.ts, loop.ts, claudeLocalLauncher.ts: plumb localHookSettingsPath
(defaults to hookSettingsPath when not provided).
`PermissionHandler` stored its own `permissionMode` field and only updated
it inside `handleModeChange`, which is called when a new batch is pulled
from the queue. The `SetSessionConfig` RPC (web dropdown changes) updates
`runClaude.ts`'s `currentPermissionMode` and the session keepalive
metadata, but never reaches the handler — so switching to Yolo mid-turn
left `canCallTool` checking the stale mode and still prompting for
approval. Closes#735.
Drop the stored field and read live from `session.getPermissionMode()`,
mirroring how the OpenCode permission handler already works. Override
`Session.getPermissionMode()` in `claude/session.ts` to return the
Claude-narrow `PermissionMode`, sound because the matching
`setPermissionMode` setter only accepts that subset.
via [HAPI](https://hapi.run)
Co-authored-by: HAPI <noreply@hapi.run>
Implements bidirectional sync of permission/model modes between CLI sessions and web app. Adds Codex-specific permission modes (read-only, safe-yolo, yolo) alongside Claude's modes. Web can now control CLI session state via RPC set-session-config handler, while CLI broadcasts state changes through keep-alive payloads. UI controls are flavor-aware, showing appropriate modes for Claude vs Codex vs Gemini. Type centralization in api/types eliminates circular dependencies.
Adds a dedicated hook server infrastructure to receive Claude SessionStart
notifications. This allows the CLI to track session ID changes (new sessions,
resume, compact, fork, etc.) without relying on file watchers.
Changes:
- Add SessionFound callback system to AgentSessionBase for session tracking
- Create hook server that listens for POST requests from Claude's hooks
- Generate temporary settings files with hook command configuration
- Implement session hook forwarder CLI command to relay hook data
- Integrate hook server into runClaude with proper cleanup
- Pass hookSettingsPath through local and remote execution paths
- Update SDK query builder to support --settings flag