How It Works
The three layers, the Ask Loop, and which notification comes from where.
Hwip is three cooperating layers. Hooks fire whether or not the model cooperates; MCP tools give the model a way to reach you on purpose.
hwipit/plugin (Claude Code plugin)
├─ hooks/hwip-setup.js → SessionStart: inject the behavioral rules
├─ hooks/hwip-stop.sh → Stop: auto completion push
├─ hooks/hwip-ask.sh → PreToolUse(AskUserQuestion): question push
├─ hooks/hwip-approve.sh → PreToolUse(Bash): opt-in phone approval for risky commands
├─ hooks/hwip-remote.sh → UserPromptSubmit: phone-sent message → REMOTE mode
├─ hooks/hwip-herdr.sh → agent state → herdr sidebar, for a `hwip cc` pane
├─ .mcp.json → registers the MCP server (`hwip mcp`)
└─ builds on:
├─ @hwip/cli → hooks + notify/list/dismiss + tmux remote control
└─ @hwip/mcp-server → hwip_ask / notify / clipboard / file …| Layer | Package | Role | Reliability |
|---|---|---|---|
| Hooks | @hwip/cli | auto-fire on Claude events | 100%, no AI cooperation needed |
| MCP server | @hwip/mcp-server | AI-callable tools: ask, notify, file, and the rest | depends on the model following rules |
| Plugin | hwipit/plugin | bundles hooks, MCP, and rules | installed once |
Session flow and the Ask Loop
SessionStart hook
├─ read ~/.hwip/config.json and the project's state files
├─ muted → hooks are silent, the tools are not used
├─ HOOK_ID absent → inject notify-only rules
├─ REMOTE live → inject the REMOTE rules
└─ otherwise → inject NORMAL rules, Push Signal matching the project's dial
Working…
├─ NORMAL (at the terminal)
│ ├─ Question → AskUserQuestion picker + Ask hook push
│ └─ Task complete → Stop hook push only (per your dial)
└─ REMOTE (entered by a message from your phone)
├─ Every response → hwip_ask → button or text reply from mobile → continue
├─ Question → hwip_ask (the picker is denied)
└─ tap "Done" / type at the terminal → back to NORMALThere are two states. At the terminal (NORMAL) Claude owes you nothing extra: questions open the local picker, completion is just the Stop-hook push, and a session you are watching never blocks waiting for a phone tap.
Once a session is in REMOTE, Claude uses hwip_ask as its final action on every response. Your
reply is treated as a direct instruction — executed without re-confirming — and then Claude asks
again, until you tap Done.
The loop starts from the phone: send a message via the app's agent chat, and the
hwip listener records exactly what it injected. The plugin's UserPromptSubmit hook verifies the
match, and Claude knows you are remote.
A Hook ID says you can drive from your phone, not that you are. In NORMAL the picker opens exactly as it always did, and you still get the Ask-hook push telling you a question is waiting.
Questions in REMOTE
While a session is in REMOTE, a short, button-friendly AskUserQuestion is denied and handed back
to Claude to re-ask through hwip_ask. The picker is the worse remote channel: it needs tmux, it
makes you read a terminal pane and count arrow presses, and the answer arrives as keystrokes, so
the session would not stay phone-driveable.
Long questions, long option text, and options carrying a preview still open the picker. A repeat
of the same denied question is let through too, so a session cannot get trapped when the MCP server
is unreachable.
Notification matrix
Who fires what, and whether it can double up:
| Event | Source | Reliability | Duplicates |
|---|---|---|---|
| Task completed | Stop hook | 100% | No — skipped if the AI already sent hwip_ask |
| Question asked | Ask hook | 100% | No |
| Decision or input needed | hwip_ask | depends on the model calling it | No |
| Manual push | hwip_notify | on request | No |
Driving a session from your phone
Launch Claude through hwip cc and the phone's Active Agents picker can type directly into the
running session — even after a hwip_ask window has closed. Start a refactor from the couch,
answer follow-ups over lunch, come back to a finished branch.
hwip cc # claude in a named tmux session the phone can reach
hwip codex # same for Codex
hwip gemini # same for GeminiThe one-step setup and the full architecture are under CLI → Remote Control.
Autonomous mode
Hand Claude a time budget and walk away:
/hwip-auto 2h fix the flaky testsClaude loops explore → plan → implement → verify → commit until the budget runs out, committing each verified unit on a work branch.
Questions arrive on your phone as hwip_ask buttons with a stated default — answer to steer,
or ignore and the run proceeds on the safe default after the timeout. Irreversible actions such as
push, deploy, or delete never happen on a timeout; they wait for an explicit tap.
The run ends with a report of what was committed, skipped, and auto-defaulted, plus buttons to extend, review, or finish.
Duration accepts 2h, 90m, 1h30m, or plain minutes, defaulting to 1h. /hwip-mode shows the
remaining budget mid-run.