Phase 1b of #422: output went engine→frontend as events; input must go frontend→engine as commands, so a frontend can eventually live across a socket (#420) — and so no frontend imports agent.zig.
Scope:
- Approvals / permission prompts (
approvals.zig, agent_tool_gate.zig call sites): the engine emits a request event (tool, scope, reason) and suspends the gated action; the frontend answers with a respond command. The --json protocol already has this shape live (ask_user events answered by {"type":"answer",...}) — the work is making the interactive TUI use the same mechanism instead of inline prompting.
- Esc / interrupt ownership (
agent_interrupt.zig, agent_ws.zig's tty seams): raw-mode stdin polling moves fully frontend-side; the frontend issues an interrupt command; the engine exposes an interrupt-check seam it already half-has (esc_cancel). This retires the last term.zig imports in engine files.
- Pickers and mid-turn asks (
pickers.zig, picker_auth.zig): same request/respond shape, with the picker UI purely frontend.
- Readline queries (
readline.zig imports agent.zig for completion data): completion catalogs (models, commands, sessions) become explicit query commands with typed replies.
Acceptance: golden harness byte-identity (both modes), plus a scripted PTY approval flow eval added to the harness (the current goldens never exercise a permission prompt — that gap must close before this merges). Frontends end with zero agent.zig imports.
Part of #422; hard prerequisite for #420 milestone 1. Bound by the out-of-the-box invariant issue.
Phase 1b of #422: output went engine→frontend as events; input must go frontend→engine as commands, so a frontend can eventually live across a socket (#420) — and so no frontend imports
agent.zig.Scope:
approvals.zig,agent_tool_gate.zigcall sites): the engine emits a request event (tool, scope, reason) and suspends the gated action; the frontend answers with a respond command. The--jsonprotocol already has this shape live (ask_userevents answered by{"type":"answer",...}) — the work is making the interactive TUI use the same mechanism instead of inline prompting.agent_interrupt.zig,agent_ws.zig's tty seams): raw-mode stdin polling moves fully frontend-side; the frontend issues an interrupt command; the engine exposes an interrupt-check seam it already half-has (esc_cancel). This retires the lastterm.zigimports in engine files.pickers.zig,picker_auth.zig): same request/respond shape, with the picker UI purely frontend.readline.zigimportsagent.zigfor completion data): completion catalogs (models, commands, sessions) become explicit query commands with typed replies.Acceptance: golden harness byte-identity (both modes), plus a scripted PTY approval flow eval added to the harness (the current goldens never exercise a permission prompt — that gap must close before this merges). Frontends end with zero
agent.zigimports.Part of #422; hard prerequisite for #420 milestone 1. Bound by the out-of-the-box invariant issue.