Skip to content

/heartbeat

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.

From plugin
woterclip
597 skills1 agent3 commands

Claude Code

$ npx -y skills add wotai-dev/woterclip --skill heartbeat --agent claude-code

SKILL.md

heartbeat.SKILL.md
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

WoterClip Heartbeat

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:**

  • `--dry-run` — Show what would be picked up without doing work
  • `--persona <name>` — Only pick issues matching a specific persona

**Reference files** (consult as needed during execution):

  • `${CLAUDE_PLUGIN_ROOT}/references/comment-format.md` — Comment templates and rules
  • `${CLAUDE_PLUGIN_ROOT}/references/label-conventions.md` — Label lifecycle and atomic label operations
  • `${CLAUDE_PLUGIN_ROOT}/references/status-mapping.md` — GitHub state model, sort order, inbox filtering
  • `${CLAUDE_PLUGIN_ROOT}/references/sub-issues.md` — Canonical create/attach/verify procedure for sub-issues
  • `${CLAUDE_PLUGIN_ROOT}/references/persona-dispatch.md` — Subagent dispatch, outcome contract, and fallback rules
  • `${CLAUDE_PLUGIN_ROOT}/references/beat-economics.md` — Clock capture, time ceiling, stop reasons, log fields

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).

Step 1: Load Config & Lock

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`.

  • Exists and **less than** `stale_lock_hours` old → stop: "Previous heartbeat still active. Skipping." **This beat never took the lock — do not delete it and do not record a beat line.**
  • Exists and **older than** `stale_lock_hours` → delete it, log: "Cleaned stale lockfile."
  • No lockfile → proceed.

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-lock

Carry 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:

  • `behavior: "skip"` → record a `quiet_hours` beat line, apply the ownership rule, exit: "Quiet hours active. Skipping."
  • `behavior: "triage-only"` → proceed but only load Orchestrator persona (skip worker personas in step 3).

Step 2: Check Inbox

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 100

2. 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).

Step 3: Pick Issue

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."

Step 4: Resolve Persona

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>/`:

  • `SOUL.md` → inject into context as identity instructions
  • `TOOLS.md` → inject into context as tool guidance
  • `config.yaml` → read runtime settings

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`.

Step 5: Validate Tools

Read `required_tools` from persona config. Verify each entry by its kind:

  • `gh` → verify with `gh auth status` (exit 0) — this proves both the CLI and authentication
  • `mcp__*` entries (e.g., `mcp__neon`) → these are MCP tool prefixes, not executables: verify by checking whether any tool starting with that prefix is available in the current session. Never run `command -v` on an `mcp__*` name.
  • Other executables (e.g., `docker`) → verify with `command -v <tool>`

**If `gh` itself is unavailable or unauthenticated:** no GitHub mutation is

Read more
@wotai-dev
Ships withwoterclip

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.

Stars on GitHub

Momentum

stars in total
59
Star history of wotai-dev/woterclip on GitHub, a chart by star-history.com

Other skills on woterclip.

heartbeat-log
Auto-invoked

heartbeat-log

This skill should be used when the user asks to "show heartbeat log", "heartbeat history", "what has woterclip done", "show agent…

@wotai-dev@wotai-devInstall Skill
init
Auto-invoked

init

This skill should be used when the user asks to "initialize woterclip", "set up woterclip", "woterclip init", "configure…

@wotai-dev@wotai-devInstall Skill
persona-create
Auto-invoked

persona-create

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…

@wotai-dev@wotai-devInstall Skill
persona-import
Auto-invoked

persona-import

This skill should be used when the user asks to "import a paperclip agent", "convert paperclip to woterclip", "migrate from…

@wotai-dev@wotai-devInstall Skill
persona-list
Auto-invoked

persona-list

This skill should be used when the user asks to "list personas", "show personas", "what personas are configured", "show woterclip…

@wotai-dev@wotai-devInstall Skill
status
Auto-invoked

status

This skill should be used when the user asks to "check woterclip status", "show agent status", "what is woterclip doing", "show…

@wotai-dev@wotai-devInstall Skill

More skills from other plugins.

agent-builder

agent-builder

Load immediately after an Agent intent, before the first agent_builder_* call. Governs how you create, configure, test, and…

n8n2w209k
@n8n-io@n8n-ioInstall Skill
browser-use

browser-use

Direct browser control via CDP for web interaction: automation, scraping, testing, screenshots, and site/app work. Also covers…

@browser-use@browser-useInstall Skill
add-anydoc

add-anydoc

Add local office-document-to-Markdown conversion to NanoClaw agent containers with the pinned Firecrawl AnyDoc CLI. Use when…

@nanocoai@nanocoaiInstall Skill

Questions about heartbeat.

Which coding agents can use heartbeat?
heartbeat installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.