fix(notify): leave headless agent runs alone
Summary
A script driving an agent (claude -p / --print, codex exec) fires the same hooks as a person at a terminal. Its permission prompts can't be answered by anyone, and the held hook stalls the script for up to 550 seconds on the FIFO; every run's Stop also became a "finished" nudge. notify.sh now skips those runs unless STACKNUDGE_HEADLESS_NUDGES=on.
Changes
notify.sh:agent_is_headlessinspects the agent process's args (-p/--print, orexecfor Codex) and exits without a decision, so the agent's own permission setting decides.STACKNUDGE_HEADLESS_NUDGES=onrestores the old behaviour.scripts/test-notify-headless.py: five cases (interactive claude,claude -pprompt,claude --printstop,codex execprompt,claude -pwith the opt-in), reusing the harness intest-notify-subagents.py. Wired intomake test-notify.notify.conf.example: the new key, commented out.- README: a paragraph on headless runs next to the subagent one.
Testing
Automated, on macOS: python3 scripts/test-notify-headless.py (5/5), python3 scripts/test-notify-subagents.py (25/25), python3 scripts/test-hook-wiring.py (42/42), bash -n notify.sh, ./build.sh, make test-without-xcode (1447 tests, 0 failures), make typecheck-tests.
scripts/test-notify-permission-blocking.py crashes with ValueError: flush of closed file in run_reply_case on this machine, both with and without this change (checked against origin/main's notify.sh), so I could not use it as a check.
Manual, after make reload:
- Run
claude -p "run ls"(or any prompt that needs a permission). No banner or panel prompt appears and the run isn't held waiting for a reply. - Run
claudeinteractively and trigger a permission prompt. The banner and panel prompt appear as before. - Add
STACKNUDGE_HEADLESS_NUDGES=onto~/.stack-nudge/configand repeat step 1. The prompt now appears.
Related issues
None.
š¤ Generated with Claude Code
Summary by cubic
Stops nudging headless agent runs (claude -p, --print, codex exec): a script driving an agent fires the same hooks as a person at a terminal, but nobody can answer its permission prompts, and a held hook stalls the script for up to 550 seconds. notify.sh now skips those runs ā prompts and turn-end notifications alike ā and lets the agent's own permission setting decide. STACKNUDGE_HEADLESS_NUDGES=on restores the old behavior.
- Adds
scripts/test-notify-headless.pywith five cases, wired intomake test-notify. - Documents the new setting in the README and
notify.conf.example.