Skip to content

feat(watch): add --exec hook to run a command on attention transitions#340

Merged
jongio merged 1 commit into
mainfrom
idea/watch-exec-hook
Jul 20, 2026
Merged

feat(watch): add --exec hook to run a command on attention transitions#340
jongio merged 1 commit into
mainfrom
idea/watch-exec-hook

Conversation

@jongio

@jongio jongio commented Jul 19, 2026

Copy link
Copy Markdown
Owner

Adds dispatch watch --exec <cmd>, an automation hook that runs a command every time a session changes attention state while streaming. This turns watch into a building block for notifiers, webhooks, and desktop alerts without polling the JSON output yourself.

What it does

  • --exec <cmd> runs the command through your shell on each attention transition (waiting, working, thinking, gone, and so on).
  • Session context is passed as environment variables, never interpolated into the command string, so untrusted session metadata cannot change what runs:
    • DISPATCH_SESSION_ID, DISPATCH_SESSION_STATE, DISPATCH_SESSION_PREV_STATE (none for a newly seen session), DISPATCH_SESSION_REPO, DISPATCH_SESSION_BRANCH, DISPATCH_SESSION_FOLDER, DISPATCH_SESSION_SUMMARY.
  • Hook output and non-zero exits are written to stderr; a slow or failing hook never stops the watch loop, keeping stdout clean for --json consumers.
  • --exec requires streaming mode and is rejected when combined with --once. It composes with the existing --repo, --branch, and --folder filters.

Example

dispatch watch --exec '[ "$DISPATCH_SESSION_STATE" = waiting ] && \
  curl -s -X POST "$WEBHOOK_URL" -d "session=$DISPATCH_SESSION_ID needs input"'

Implementation notes

  • New package seam watchExecFn (default runWatchHook) lets tests capture invocations and env payloads without spawning shells.
  • hookShell() picks the shell per OS ($SHELL -c / /bin/sh -c on Unix, %COMSPEC% /c / cmd.exe /c on Windows).
  • hookEnv() builds the DISPATCH_SESSION_* slice and is unit tested directly.

Verification

go build ./..., go vet ./..., go test ./... -count=1, golangci-lint run --timeout 10m (0 issues), and mage deadcode (OK) all pass.

Closes #329

`dispatch watch --exec <cmd>` runs a command each time a session changes
attention state while streaming. Session context is passed only through
DISPATCH_SESSION_* environment variables (ID, STATE, PREV_STATE, REPO,
BRANCH, FOLDER, SUMMARY), never interpolated into the command string, so
untrusted session metadata cannot alter what runs.

The command runs through the platform shell. Hook output and non-zero
exits go to stderr, and a slow or failing hook never stops the watch
loop. `--exec` requires streaming mode and is rejected with `--once`.

Closes #329

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 732fe147-a68b-4784-8e17-ef089fb70ba3
@jongio jongio added the idea Feature idea from the idea pipeline label Jul 19, 2026
@jongio jongio self-assigned this Jul 19, 2026
@jongio
jongio merged commit 541770c into main Jul 20, 2026
2 checks passed
@jongio
jongio deleted the idea/watch-exec-hook branch July 20, 2026 16:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

idea Feature idea from the idea pipeline

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add dispatch watch --exec to run a command on attention transitions

1 participant