Files
agent-tools/waitfor/README.md
claude 6c8cae885b waitfor: block until a shell condition holds
--cmd exits 0 (+ optional --matches regex) or --timeout; exit 0/3/1,
last output always printed, --then hook composes with notifyr.
Injectable runner for tests + real-shell integration test.
Spec: doc/tool-parity.md 3.2.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011KikHkfCiC3yELbsMN8fT9
2026-08-07 00:39:58 +02:00

45 lines
1.4 KiB
Markdown

# waitfor — block until a condition holds
Replaces the hand-rolled `while ! curl …; do sleep 5; done` loops that
each need a fresh approval in an agent session with **one stable
command prefix**. The agent makes one blocking call instead of burning
turns polling. Closes the `Monitor` gap from
[`doc/tool-parity.md`](../doc/tool-parity.md) §3.2.
## Usage
```
waitfor --cmd "shell command" [--matches regex] [--interval 30s]
[--timeout 20m] [--then "shell command"] [--verbose]
```
The condition holds when `--cmd` exits 0 **and**, if `--matches` is
given, its combined output matches the regex. The first attempt runs
immediately; then every `--interval` until `--timeout`.
| Exit | Meaning |
|------|---------|
| 0 | condition met (`--then` runs afterwards, if given) |
| 3 | timeout — last output still printed so the caller sees the state |
| 1 | usage/config error (empty `--cmd`, bad regex) |
Examples:
```bash
# wait until Gitea answers again
waitfor --cmd "curl -sf https://gitea.brasse-pc.eu/api/healthz" --interval 30s --timeout 20m
# wait until a container is listed (read-only Pi5 wrapper)
waitfor --cmd "ssh pi5-claude sudo claude-docker ps" --matches gitea --timeout 10m
# wait for a file, then notify the phone (composes with notifyr)
waitfor --cmd "test -f /tmp/report.html" --then 'notifyr send --msg "report is ready"'
```
## Build & test
```bash
go test ./...
go build -o build/waitfor .
```