Watch

Watch#

The watch tool arms an event source and returns immediately; gptme keeps working and delivers one system message when the event fires. Use it instead of polling with sleep N; check — for example, to wait for CI without blocking:

watch
until gh pr checks 42 --repo gptme/gptme --every 60s --timeout 30m

Sources include run, until, stream, timer and tmux, with list, cancel and wait to manage them. The tool is opt-in (disabled_by_default); enable it with -t +watch.

Watch tool — arm event sources and get woken when they fire.

Claude Code Monitor + ScheduleWakeup parity: arm a probe/timer/stream/tmux source, keep working, and receive one system message when it fires. Events are delivered through the server wake path (SessionManager) when a server session exists, else queued and drained at STEP_PRE.

Design: knowledge/design/2026-09-10-gptme-monitors-and-completion-events.md

Instructions

Use watch whenever you would otherwise poll (`sleep N; check`) or block on a slow command: arm it, keep working, and get woken by a system message when the event fires. Prefer keep-working; never poll with `sleep N; check`.
Arming a source:
- `watch until <cmd> --every 30s`: fire once when cmd exits 0 (e.g. `gh pr checks`)
- `watch run <cmd>`: fire when the process exits, with rc + output tail
- `watch stream <cmd>`: each stdout line is an event (Monitor)
- `watch timer 10m [desc]`: fire once after a duration (ScheduleWakeup)
- `watch tmux <session> --pattern <re> --stable 5s`: fire on pane match/stability
- `watch list`
- `watch cancel <id>`: disarm. For `run`/`stream`, also stop the child we spawned (otherwise the worker and pipes leak). `until`/`timer`/`tmux` have no long-lived child to kill.
- `watch wait <id> [timeout]`: blocking observation-only wait; never kills.
Verb options: --timeout on run/until/stream/timer/tmux (unit required: 30s, 5m — a bare `--timeout 30` stays on the command, so `watch run pytest --timeout 30` runs pytest's flag); --every on until; --pattern/--stable on tmux. Other `--flags` belong to the watched command (so `watch run pytest --pattern smoke` keeps --pattern). Set `--timeout` on `until` so a never-met condition still wakes you. Runaway sources are auto-cancelled by storm guards. `run`/`until`/`stream` use the same confirmation and denylist as the shell tool (allowlisted probes auto-confirm; others prompt). `list`/`cancel`/`wait`/`timer`/`tmux` do not execute a user command, so they skip it.

Examples

User
Wait for CI on PR 42 without blocking
watch
until gh pr checks 42 --repo gptme/gptme --every 60s --timeout 30m
System
Watch w1 (until) fired: condition met: All checks passed
class gptme.tools.watch.Watch

An armed event source. Fired events are batched and delivered.

__init__(id: str, kind: str, description: str, created: float, deadline: float | None = None, events: ~collections.deque[str] = <factory>, event_times: ~collections.deque[float] = <factory>, cancel_times: ~collections.deque[float] = <factory>, delivered: int = 0, seen: int = 0, cancelled: bool = False, fired: bool = False, logdir: ~pathlib.Path | None = None, proc: ~subprocess.Popen | None = None, lock: ~_thread.allocate_lock = <factory>, cancel_event: ~threading.Event = <factory>, thread: ~threading.Thread | None = None) → None