Skip to content

Forward agent_needs_input notifications to Warp - #91

Merged
sohumgaitonde merged 2 commits into
mainfrom
sohum/forward-agent-needs-input
Oct 5, 2026
Merged

sohumgaitonde merged 2 commits into
mainfrom
sohum/forward-agent-needs-input

Conversation

@sohumgaitonde

@sohumgaitonde sohumgaitonde commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Subscribes the warp plugin's Notification hook to Claude Code's agent_needs_input notification, in addition to idle_prompt. on-notification.sh already forwards the notification type generically, so no new script is needed. The notification message is forwarded as the event summary, capped at 120 characters.

Why

Claude Code can pause mid-session on a prompt that only a user can answer, for example a confirmation dialog, and emit agent_needs_input. Current plugin version only subscribes to the idle_prompt event. In the case of an agent_needs_input event, then, Warp does not receive notification of this and that the session is stuck, and it keeps reporting the run as in progress. This matters for unattended runs, where a session waiting on input can hang. Warp has no signal to mark the run as blocked, notify, or start any timeout, and the run only ends when an infrastructure timeout eventually fires via reaper job.

This is intentionally generic. It reacts to Claude's own notification type, not to the content of any particular dialog, so it covers prompts we don't know about yet.

Changes

  • hooks/hooks.json: Notification matcher changes from idle_prompt to idle_prompt|agent_needs_input. The hook forwards the notification type unchanged and sends no input to Claude.
  • scripts/on-notification.sh: cap the forwarded summary at 120 characters, the same cap on-permission-request.sh uses for its preview.
  • Bump the plugin to 2.3.0 in plugin.json and marketplace.json
  • Update the README and script header comment.
  • Tests: the matcher includes agent_needs_input, plugin and marketplace versions stay in sync, and the agent_needs_input payload shape is correct.

Follow-up

This PR emits the event. Warp currently ignores unknown event names, so there is no behavior change until the client change (warpdotdev/warp#16232) parses it as a generic needs-input event and maps it to the existing blocked status for unattended runs. Existing installs will need a manual plugin update.

Testing

  • plugins/warp/tests/test-hooks.sh: 62 passed.
  • plugins/oz-harness-support/tests/test-hooks.sh: 34 passed.

Co-Authored-By: Warp agent@warp.dev

Subscribe the existing Notification hook to agent_needs_input in
addition to idle_prompt so Warp is told when Claude Code is blocked
waiting for user input. The hook script already forwards the
notification type generically and does not inspect the message.

Bump the warp plugin to 2.3.0 so the Warp client can require a version
that emits this event, and add tests covering the matcher, version
sync between plugin.json and marketplace.json, and the payload shape.

Co-Authored-By: Warp <agent@warp.dev>
Truncate the notification message to 120 characters before forwarding it
as the event summary, matching the permission request hook.

Co-Authored-By: Warp <agent@warp.dev>
@sohumgaitonde
sohumgaitonde marked this pull request as ready for review October 1, 2026 20:42
@sohumgaitonde
sohumgaitonde merged commit f8c6287 into main Oct 5, 2026
4 checks passed
sohumgaitonde added a commit to warpdotdev/warp that referenced this pull request Oct 6, 2026
## Description
Unattended CLI agent runs (Oz cloud runs and the daemon) can hang
indefinitely when the agent stops on a dialog that only a user can
answer. Claude Code reports this through its `agent_needs_input`
notification, but Warp ignored the event, so the task stayed
`InProgress` and nothing ever ended the run. There is also no safe way
to shut such a run down today. The exit sequence types `/exit` and
Enter, and Enter answers whatever dialog is open, which can be a consent
prompt we should never accept on the user's behalf.

This change makes those runs end predictably, using the existing
blocked-run handling rather than anything specific to a particular
dialog.

- Parse the `agent_needs_input` event (the associated plugin change to
send this is in flight) as a new `CLIAgentEventType::NeedsInput`.
- In autonomous execution modes only (SDK and daemon), map it to
`Blocked`, using the notification text as the status message and falling
back to a generic message when there is none. The plugin caps the text
length. The desktop app and TUI keep ignoring the event, so interactive
behavior is unchanged.
- When shutdown is requested for a session blocked on `NeedsInput`, skip
the typed `/exit` and follow-up Enter and go straight to the existing
safe force-kill. Other statuses keep the graceful exit ladder. The
`Blocked` status now records its source (`BlockedSource`: permission
request, question asked, or needs-input), which lets the driver tell
this case apart from ordinary permission or question blocks.

The final reported state stays `BLOCKED`. The existing
`idle_on_complete` window still applies, so runs the server launches
with it get the usual recovery period.

This depends on `claude-code-warp` forwarding the event
(`idle_prompt|agent_needs_input` Notification matcher, plugin 2.3.0:
warpdotdev/claude-code-warp#91). Until that
plugin version is installed, the event never reaches Warp and this
change has no effect. `MINIMUM_PLUGIN_VERSION` is intentionally not
bumped here.

## Testing
Unit tests added for:
- parsing `agent_needs_input` into `NeedsInput`
- the `Blocked` mapping with the event summary, the generic fallback,
and the `NeedsInput` blocked source
- other blocked events recording their own source
- the autonomous-only gate (SDK applies the event, App mode ignores it)
- the exit state machine skipping the typed exit and force-killing when
blocked on needs-input

Ran targeted checks per `AGENTS.md`:
- `cargo nextest run -p warp --lib -E 'test(cli_agent_sessions) |
test(exit_escalation) | test(plugin_manager) |
test(local_agent_task_sync_model)'` (231 passed)
- `cargo clippy -p warp --all-targets --tests -- -D warnings`
- `cargo fmt --all -- --check`

- [ ] I have manually tested my changes locally with `./script/run`

## Agent Mode
- [X] Warp Agent Mode - This PR was created via Warp's AI Agent Mode

Co-Authored-By: Warp <agent@warp.dev>

---------

Co-authored-by: Warp <agent@warp.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants