heartbeat-log
This skill should be used when the user asks to "show heartbeat log", "heartbeat history", "what has woterclip done", "show agent activity", "summarize…
This skill should be used when the user asks to "run a heartbeat", "run the agent loop", "process GitHub issues", "check for work", or runs the /heartbeat command. Executes the WoterClip heartbeat — picks up GitHub issues, resolves personas, does work, and reports back.
$ npx -y skills add wotai-dev/woterclip --skill heartbeat --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/heartbeatContext preview
The summary Claude sees to decide when to auto-load this skill.
This skill should be used when the user asks to "run a heartbeat", "run the agent loop", "process GitHub issues", "check for work", or runs the /heartbeat command. Executes the WoterClip heartbeat — picks up GitHub issues, resolves personas, does work, and reports back.
name: heartbeat description: This skill should be used when the user asks to "run a heartbeat", "run the agent loop", "process GitHub issues", "check for work", or runs the /heartbeat command. Executes the WoterClip heartbeat — picks up GitHub issues, resolves personas, does work, and reports back. version: 0.1.0
Execute the WoterClip heartbeat cycle: pick up assigned GitHub issues, resolve the right persona, do the work, and report back with structured comments. All GitHub operations go through the `gh` CLI — no MCP server required.
**Arguments:**
**Reference files** (consult as needed during execution):
All `gh issue` / `gh api` calls below target the repo from config `github.repo` (pass `--repo <owner/name>` explicitly — never rely on the working directory's default remote).
1. Read `.woterclip/config.yaml`. If missing, stop and instruct the user to run `/woterclip-init`. Nothing is created yet, so this exit records nothing. 2. Check for lockfile at `.woterclip/.heartbeat-lock`.
3. Take the lock. This one command creates it **and prints it**, so the beat observes its own id and start epoch:
printf '{"beat_id":"%s","started_at":"%s","started_epoch":%s}\n' \
"$(date -u +%s)-$$" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$(date -u +%s)" \
| tee .woterclip/.heartbeat-lockCarry the printed `beat_id` and `started_epoch` forward — they are the beat's identity and its clock. 4. **Ownership rule, applied at every exit from here on.** Re-read `.woterclip/.heartbeat-lock`. Delete it **only if it still carries this beat's `beat_id`**; if it is missing or carries another id, a later beat cleaned and re-took it — leave it alone. Deleting a lock this beat does not own hands two beats the same repo. 5. **Every exit from here on** records one beat line (step 9 format) naming that exit's stop reason, then applies the ownership rule. `--dry-run` and a superseded beat record none. The exit-to-reason map is in `${CLAUDE_PLUGIN_ROOT}/references/beat-economics.md`. Beat elapsed is `$(date -u +%s)` minus `started_epoch`.
Check quiet hours: if `quiet_hours.enabled` and current time is within the quiet window:
1. Fetch open issues assigned to the authenticated user:
gh issue list --repo <owner/name> --assignee @me --state open \
--json number,title,labels,createdAt --limit 1002. Filter and sort client-side per `${CLAUDE_PLUGIN_ROOT}/references/status-mapping.md` § Filter Rules and § Sort Order (labels come from the JSON above). 3. Detect stale `agent-working` labels: if an issue has `agent-working` but no heartbeat comment within `stale_lock_hours`, clean the stale label (`gh issue edit N --remove-label agent-working`, post cleanup comment).
1. If `--persona <name>` flag is set, filter to only issues matching that persona's label. 2. Pick the first issue from the sorted inbox. 3. If `--dry-run`, report what would be picked, then apply the ownership rule and exit. No beat occurred, so record **no** beat line:
Dry run — would pick:
#12 [backend] "Issue title" (in-progress, priority:high)
Queue:
#15 [frontend] "Other issue" (todo)4. If no issues match → record a beat line (`queue_empty` when zero issues were worked this beat, otherwise `complete` with the running count), apply the ownership rule, exit: "No issues in queue. Heartbeat complete."
1. Read the issue's labels. Find the persona label by matching against the `personas` map in config. 2. No persona label found → load the persona with `is_default: true` (typically Orchestrator). 3. Load persona files from `.woterclip/<persona.path>/`:
The persona's `config.yaml` supplies `model`, `thinking_effort`, `max_turns`, and `enable_chrome`; how each feeds the step 8 dispatch is defined in `${CLAUDE_PLUGIN_ROOT}/references/persona-dispatch.md`.
Read `required_tools` from persona config. Verify each entry by its kind:
**If `gh` itself is unavailable or unauthenticated:** no GitHub mutation is
GitHub Issues-backed agent orchestration for Claude Code. A single Claude instance wears different "hats" (personas) based on GitHub issue labels – an Orchestrator routes work, a CEO makes strategic calls, and worker personas execute.
This skill should be used when the user asks to "show heartbeat log", "heartbeat history", "what has woterclip done", "show agent activity", "summarize…
This skill should be used when the user asks to "initialize woterclip", "set up woterclip", "woterclip init", "configure woterclip for this repo", or runs the…
This skill should be used when the user asks to "create a persona", "add a new persona", "set up a new agent role", "add a woterclip persona", or runs the…
This skill should be used when the user asks to "import a paperclip agent", "convert paperclip to woterclip", "migrate from paperclip", "import persona from…
This skill should be used when the user asks to "list personas", "show personas", "what personas are configured", "show woterclip agents", or runs the…
This skill should be used when the user asks to "check woterclip status", "show agent status", "what is woterclip doing", "show heartbeat status", "what's in…