| name | watch-pr |
| description | Manage the v7 PR-watch daemon for the user — start/stop watching specific PRs, list current dashboard, force-resume an ignored PR. The PostToolUse hook auto-registers any PR after `git push` / `gh pr create`, so this skill is for on-demand operations, not for starting the auto chain. Use when builder says /watch-pr / 盯一下 |
/watch-pr — operate the v7 watch daemon
The v7 architecture has a single long-running pr-watch-daemon polling
every active PR. The PostToolUse hook auto-registers PRs after push, so
the day-to-day flow needs zero AI involvement. This skill exposes the
manual control surface for cases the hook does not cover.
v7 automatic chain (you do not participate)
git push / gh pr create
↓
PostToolUse hook (auto-watch-on-push.sh)
→ bash pr-watch-register.sh <repo> <pr> "<trigger>"
↓
state-dir/active/<slug>-<pr>.meta written
ensure-daemon spawns pr-watch-daemon if not already running
↓
daemon polls every 30s (gh pr view + GraphQL reviewThreads)
state change → emit baseline / state_change / merged / etc.
→ ${BDC_HOME:-$HOME/.bdc}/pr-events.jsonl
↓
[next user prompt, any session]
↓
UserPromptSubmit hook (pr-events-flush.sh)
→ renders 📊 dashboard with [action_tag] per row
→ AI sees the dashboard at the top of the next prompt
Manual operations (the skill's job)
/watch-pr <N> — start watching PR #N in the current repo
unset GITHUB_TOKEN
repo=$(gh repo view --json nameWithOwner -q .nameWithOwner)
bash ${BDC_HOME:-$HOME/.bdc}/scripts/pr-watch-register.sh "$repo" <N> "manual /watch-pr"
pr-watch-register.sh writes the meta file and ensures the daemon is
running. The daemon will pick the PR up on its next tick (≤ 30s).
Idempotent — safe to call when the PR is already being watched.
/watch-pr <repo> <N> — start watching a PR in any repo
bash ${BDC_HOME:-$HOME/.bdc}/scripts/pr-watch-register.sh example/repo 187 "manual /watch-pr"
/watch-pr stop <N> (or <repo> <N>) — permanently stop watching this PR
unset GITHUB_TOKEN
repo=$(gh repo view --json nameWithOwner -q .nameWithOwner)
bash ${BDC_HOME:-$HOME/.bdc}/scripts/pr-watch-stop.sh "$repo" <N> "<reason>"
Writes state-dir/ignored/<slug>-<pr>.json, cleans every stale state
file (active meta / fingerprint / post-merge / cooldown / last_change /
per-PR lock), emits a watch_ignored event. The daemon will not
re-discover this PR until you run unignore. Use this when the user
says "别盯了 / 停掉 / 转人工 / 这个 PR 我自己来".
/watch-pr unignore <N> (or <repo> <N>) — resume watching after stop
unset GITHUB_TOKEN
repo=$(gh repo view --json nameWithOwner -q .nameWithOwner)
bash ${BDC_HOME:-$HOME/.bdc}/scripts/pr-watch-unignore.sh "$repo" <N>
Removes the ignored marker, emits watch_unignored, force-registers
the PR so the daemon picks it up immediately on the next tick.
Symmetric to stop. Idempotent — silent no-op if the PR was not ignored.
/watch-pr — list all open PRs in the current repo (no state change)
unset GITHUB_TOKEN
gh pr list --state open --json number,title,headRefName,reviewDecision,mergeable,statusCheckRollup \
| jq -r '.[] | "PR #\(.number) [\(.headRefName)] \(.title)\n reviewDecision: \(.reviewDecision // "none") | mergeable: \(.mergeable)"'
/watch-pr all — overview across configured active repos
unset GITHUB_TOKEN
for repo in example/search-app example/project example/repo example/app; do
echo "=== $repo ==="
gh pr list --repo "$repo" --state open --json number,title,reviewDecision,mergeable \
| jq -r '.[] | " #\(.number) \(.title) [review:\(.reviewDecision // "n/a") merge:\(.mergeable)]"' || echo " (no open PRs)"
done
Daemon lifecycle (reference, not for routine use)
| Operation | Command |
|---|
| Spawn daemon if not running | bash ${BDC_HOME:-$HOME/.bdc}/scripts/pr-watch-ensure-daemon.sh |
| Check daemon alive | cat /tmp/bdc-pr-watch-daemon.lock; ps -p $(cat /tmp/bdc-pr-watch-daemon.lock) |
| Stop daemon | kill $(cat /tmp/bdc-pr-watch-daemon.lock) |
| Daemon log | tail -f /tmp/pr-watch-daemon.log |
ensure-daemon auto-detects daemon-script mtime drift and respawns,
so a code update is picked up the next time any hook calls into it.
v7 event files
| File | Purpose |
|---|
${BDC_HOME:-$HOME/.bdc}/pr-events.jsonl | Append-only event log (baseline / state_change / merged / watch_ignored / watch_unignored / etc.) |
${BDC_HOME:-$HOME/.bdc}/pr-events.cursor | flush-hook read offset |
${BDC_HOME:-$HOME/.bdc}/watch-pr-state/active/<slug>-<pr>.meta | Registered PRs |
${BDC_HOME:-$HOME/.bdc}/watch-pr-state/ignored/<slug>-<pr>.json | User-stopped PRs (persistent across daemon restarts) |
/tmp/bdc-pr-watch-daemon.lock | Daemon single-instance lock |
/tmp/watch-pr-<slug>-<pr>.lock | Per-PR lock (pid = daemon pid) |
To view all historical events for a PR:
cat ${BDC_HOME:-$HOME/.bdc}/pr-events.jsonl | jq 'select(.repo == "example/repo" and .pr == 187)'
Legacy / fallback
pr-watch-loop.sh is the v5 per-PR fan-out script. v7 keeps it on
disk only as a rollback path: if pr-watch-register.sh is removed
(e.g. the user reverts the v7 commits), auto-watch-on-push.sh falls
back to spawning pr-watch-loop.sh directly. Do not call it manually —
use pr-watch-register.sh instead so the daemon owns the lifecycle.