.claude/skills/heartbeat/SKILL.md
Start and manage the full heartbeat ecosystem for agent-studio. Registers all 7 heartbeat loops plus auto-reschedule task via CronCreate to keep the agent ecosystem healthy, indexed, informed, and connected.
npx skillsauth add oimiragieo/agent-studio heartbeatInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
The Heartbeat Ecosystem keeps agent-studio healthy, indexed, and informed by running 7 background loops via Claude Code's cron scheduler (CronCreate/CronList/CronDelete).
Key constraint — session-scoped: All loops die when the terminal closes. Use Loop 0 (auto-reschedule) to prevent silent 3-day expiry, and re-run Quick-Start commands after each session restart.
Run these /loop commands in your Claude Code session:
/loop 2h Heartbeat tick: Spawn heartbeat-orchestrator subagent via Task({ task_id: 'hb-reflection-' + Date.now(), subagent_type: 'heartbeat-orchestrator' }) to run reflection-check.cjs. Reply HEARTBEAT_OK after spawning.
/loop 4h Heartbeat tick: Spawn heartbeat-orchestrator subagent via Task({ task_id: 'hb-indexing-' + Date.now(), subagent_type: 'heartbeat-orchestrator' }) to check bm25-index.json mtime and reindex if stale. Reply HEARTBEAT_OK after spawning.
/loop 30m Heartbeat tick: Spawn heartbeat-orchestrator subagent via Task({ task_id: 'hb-drain-' + Date.now(), subagent_type: 'heartbeat-orchestrator' }) to run context-drain.cjs and report stdout. Reply HEARTBEAT_OK after spawning.
/loop 24h Heartbeat tick: Spawn heartbeat-orchestrator subagent via Task({ task_id: 'hb-evolution-' + Date.now(), subagent_type: 'heartbeat-orchestrator' }) to run evolution-check.cjs. Reply HEARTBEAT_OK after spawning.
Prevents silent 3-day expiry. CRITICAL ORDER: Always CronCreate new tasks BEFORE CronDelete old ones.
CronCreate({
schedule: '0 0 */2 * *',
task: 'Self-maintenance: CronList() to inventory active tasks. Identify missing heartbeat loops from the expected set (reflection-2h, evolution-24h, briefing-8am, indexing-4h, drain-30m, telegram-5m, research-7am, reschedule-2d). Recreate any missing tasks using schedules in .claude/context/plans/heartbeat-ecosystem-design-2026-03-07.md. Report recreated task IDs.',
});
Extracts patterns from session transcripts before they are lost.
CronCreate({
schedule: '0 */2 * * *',
task: "Heartbeat tick: Spawn heartbeat-orchestrator subagent via Task({ task_id: 'hb-reflection-' + Date.now(), subagent_type: 'heartbeat-orchestrator' }) to execute this tick. The orchestrator must: (1) call TaskUpdate(in_progress), (2) run `node .claude/tools/cli/reflection-check.cjs`, (3) if stdout is HEARTBEAT_OK, call TaskUpdate(completed) and exit. Do NOT run the script directly in the router session. Reply HEARTBEAT_OK immediately after spawning.",
});
Applies accumulated learnings to improve agent definitions.
CronCreate({
schedule: '0 3 * * *',
task: "Heartbeat tick: Spawn heartbeat-orchestrator subagent via Task({ task_id: 'hb-evolution-' + Date.now(), subagent_type: 'heartbeat-orchestrator' }) to execute this tick. The orchestrator must: (1) call TaskUpdate(in_progress), (2) run `node .claude/tools/cli/evolution-check.cjs`, (3) if stdout is HEARTBEAT_OK, call TaskUpdate(completed) and exit. Do NOT run the script directly in the router session. Reply HEARTBEAT_OK immediately after spawning.",
});
Summarizes overnight state and suggests priority work.
CronCreate({
schedule: '0 8 * * 1-5',
task: 'Morning briefing: Spawn researcher via Task() to read issues.md, learnings.md, git log, and generate morning briefing report. Do NOT wait for sub-agent. Reply HEARTBEAT_OK and exit.',
});
Keeps hybrid search index fresh.
CronCreate({
schedule: '0 */4 * * *',
task: "Heartbeat tick: Spawn heartbeat-orchestrator subagent via Task({ task_id: 'hb-indexing-' + Date.now(), subagent_type: 'heartbeat-orchestrator' }) to execute this tick. The orchestrator must: (1) call TaskUpdate(in_progress), (2) check mtime of .claude/context/data/bm25-index.json via Bash; if older than 4 hours or missing, run `pnpm code:index:reindex`, (3) call TaskUpdate(completed) and exit. Do NOT run the script directly in the router session. Reply HEARTBEAT_OK immediately after spawning.",
});
Detects pipeline idle state — warns user, does NOT auto-clear.
CronCreate({
schedule: '*/30 * * * *',
task: "Heartbeat tick: Spawn heartbeat-orchestrator subagent via Task({ task_id: 'hb-drain-' + Date.now(), subagent_type: 'heartbeat-orchestrator' }) to execute this tick. The orchestrator must: (1) call TaskUpdate(in_progress), (2) run `node .claude/tools/cli/context-drain.cjs`, (3) reply with the exact stdout output, then call TaskUpdate(completed) and exit. Do NOT run the script directly in the router session. Reply HEARTBEAT_OK immediately after spawning.",
});
Polls Telegram Bot API for user messages and routes to agents.
Configuration required:
TELEGRAM_BOT_TOKEN=your_token in .env.env is configuredCronCreate({
schedule: '*/5 * * * *',
task: "Heartbeat tick: Spawn heartbeat-orchestrator subagent via Task({ task_id: 'hb-telegram-' + Date.now(), subagent_type: 'heartbeat-orchestrator' }) to execute this tick. The orchestrator must: (1) call TaskUpdate(in_progress), (2) run `node .claude/tools/cli/telegram-poll.cjs`, (3) if stdout is HEARTBEAT_OK, call TaskUpdate(completed) and exit. Do NOT run the script directly in the router session. Reply HEARTBEAT_OK immediately after spawning.",
});
Discord note: Discord uses webhooks (push-based) rather than polling. Send messages via Discord webhook URL, but receiving requires a persistent process — recommend Telegram for bidirectional communication.
Surfaces relevant academic papers and web news. Delegates to the dedicated monitor skills.
CronCreate({
schedule: '0 7 * * *',
task: 'Research digest: Spawn researcher via Task() to invoke arxiv-monitor and exa-monitor skills. Do NOT wait for sub-agent. Reply HEARTBEAT_OK and exit.',
});
Dedicated skills: arxiv-monitor (every 6h standalone) | exa-monitor (every 4h standalone)
Config: ARXIV_KEYWORDS and EXA_MONITOR_TOPICS env vars (see .env.example)
To activate all 8 tasks programmatically:
// Invoke via Skill({ skill: 'heartbeat' }) — this skill registers all loops
// Loop 0: Auto-reschedule (must be first — keeps everything alive)
CronCreate({ schedule: '0 0 */2 * *', task: '...' }); // see Loop 0 above
// Loop 1: Reflection
CronCreate({ schedule: '0 */2 * * *', task: '...' }); // see Loop 1 above
// Loop 2: Evolution
CronCreate({ schedule: '0 3 * * *', task: '...' }); // see Loop 2 above
// Loop 3: Morning Briefing
CronCreate({ schedule: '0 8 * * 1-5', task: '...' }); // see Loop 3 above
// Loop 4: Indexing
CronCreate({ schedule: '0 */4 * * *', task: '...' }); // see Loop 4 above
// Loop 5: Drain Check
CronCreate({ schedule: '*/30 * * * *', task: '...' }); // see Loop 5 above
// Loop 6: Telegram Polling
CronCreate({ schedule: '*/5 * * * *', task: '...' }); // see Loop 6 above
// Loop 7: Research Digest
CronCreate({ schedule: '0 7 * * *', task: '...' }); // see Loop 7 above
// Verify all registered
CronList();
CronList(); // Returns all active tasks with IDs, schedules, next fire time
CronDelete({ id: 'abc12345' }); // Use ID from CronList()
// Get all IDs via CronList(), then delete each
const tasks = await CronList();
for (const task of tasks) {
CronDelete({ id: task.id });
}
minute hour day-of-month month day-of-week
*/5 * * * * = Every 5 minutes
0 */2 * * * = Every 2 hours
0 8 * * 1-5 = Weekdays at 8am
0 */4 * * * = Every 4 hours
*/30 * * * * = Every 30 minutes
0 0 */2 * * = Every 2 days at midnight
Supported: wildcards (*), single values (5), steps (*/15), ranges (1-5), comma lists (1,15,30).
NOT supported: L, W, ?, named aliases (MON, JAN).
| Risk | Mitigation |
| ------------------------------------------------- | ----------------------------------------------------- |
| session-scoped: loops die on terminal close | Re-run Quick-Start commands on each session restart |
| 3-day auto-expiry: tasks silently self-delete | Loop 0 auto-reschedule runs every 2 days |
| 50-task cap: max concurrent scheduled tasks | 8 loops = 16% of cap; leaves 84% for ad-hoc tasks |
| No catch-up: missed fires are NOT replayed | Design loops to be idempotent (safe to skip) |
| Jitter: up to 15min delay on recurring tasks | Expected; design checks to tolerate timing variance |
| Telegram token not configured | Loop 6 gracefully skips if TELEGRAM_BOT_TOKEN unset |
memory-rotator.cjs for automatic file rotationagent-health.json for degradation signals.claude/context/memory/research-digest.mdTaskList() same as the router drain gatescheduled-tasks — low-level cron patterns (this skill builds on it)arxiv-monitor — dedicated ArXiv paper monitor (ARXIV_KEYWORDS, 6h interval)exa-monitor — dedicated Exa web search monitor (EXA_MONITOR_TOPICS, 4h interval)telegram-polling — Telegram Bot API polling (TELEGRAM_BOT_TOKEN required)task-management-protocol — task tracking patternsmemory-search — semantic memory queries used by loop promptstools
Comprehensive biosignal processing toolkit for analyzing physiological data including ECG, EEG, EDA, RSP, PPG, EMG, and EOG signals. Use this skill when processing cardiovascular signals, brain activity, electrodermal responses, respiratory patterns, muscle activity, or eye movements. Applicable for heart rate variability analysis, event-related potentials, complexity measures, autonomic nervous system assessment, psychophysiology research, and multi-modal physiological signal integration.
tools
Comprehensive toolkit for creating, analyzing, and visualizing complex networks and graphs in Python. Use when working with network/graph data structures, analyzing relationships between entities, computing graph algorithms (shortest paths, centrality, clustering), detecting communities, generating synthetic networks, or visualizing network topologies. Applicable to social networks, biological networks, transportation systems, citation networks, and any domain involving pairwise relationships.
data-ai
Molecular featurization for ML (100+ featurizers). ECFP, MACCS, descriptors, pretrained models (ChemBERTa), convert SMILES to features, for QSAR and molecular ML.
development
Run Python code in the cloud with serverless containers, GPUs, and autoscaling. Use when deploying ML models, running batch processing jobs, scheduling compute-intensive tasks, or serving APIs that require GPU acceleration or dynamic scaling.