How /loop Works
Save to .claude/commands/loop.md:
---
description: Schedule a recurring Claude task with a 3-day safety cap
argument-hint: <interval> "<prompt>" [--end <ISO date>]
---
You will register a recurring task. Default cap: 3 days from now.
1. Parse `$ARGUMENTS`:
- First token: interval (`5m`, `1h`, `1d`)
- Second token (quoted): the prompt to fire each tick
- Optional `--end <ISO>` to set a custom end (still capped at +3 days from now)
2. Generate a task-id (short hash from interval + prompt + now).
3. Write `~/.claude/loops/<task-id>/spec.json`:
```json
{
"interval": "<parsed>",
"prompt": "<text>",
"created_at": "<ISO>",
"ends_at": "<ISO + 3d or user-supplied, whichever sooner>",
"ticks": []
}Use
ScheduleWakeup(or platform equivalent: launchd / systemd / cron) to fire the task at the next interval.Each tick:
- Read spec.json. If
now > ends_at, markstatus: completedand stop. - Run the prompt as a fresh Claude session.
- Append result to
ticksarray (truncate to last 100 to avoid disk bloat). - Schedule next tick.
- Read spec.json. If
Output:
Loop registered. ID: <task-id>. Next fire: <ISO>. Cap: <ends_at>.
Companion command
Save to .claude/commands/loop-stop.md:
---
description: Stop a running /loop by id
argument-hint: <task-id>
---
Read `~/.claude/loops/$ARGUMENTS/spec.json`. Set status=cancelled. Cancel the next ScheduleWakeup. Print confirmation.Boundaries
- Hard cap: 3 days. Never extend beyond +3d from now.
- One loop per task-id; do not overwrite existing.
- Never persist secrets in spec.json — the prompt is plaintext.
- /loop-list shows active loops; /loop-stop cancels.
### How it differs from Claude Code's native /loop
Claude Code 1.x has a built-in `/loop` skill that lets you self-pace iterations. Boris's variant adds:
- Hard 3-day cap (native /loop has no cap)
- On-disk spec.json for cross-session persistence
- Companion `/loop-list` and `/loop-stop` for management
- Safety: refuses to overwrite an existing task-id
If both exist, Boris's `.claude/commands/loop.md` overrides the native skill (file-based commands take priority).
---
## Example session
You: "/loop 1h 'Run sentry-errors and DM me if any P0 surfaces'" Claude: -> registered task abc1234 -> Next fire: 2026-04-28T14:00:00Z -> Cap: 2026-05-01T13:00:00Z (3 days) [1h later, automatically] Claude: -> tick 1: sentry-errors found 0 P0 → no DM sent [continues every hour for ≤72 ticks] You: "/loop-stop abc1234" Claude: -> cancelled. 8 ticks fired. Final state archived.
---
## FAQ
**Q: Why a 3-day cap?**
A: Open-ended schedules become forgotten cruft. 3 days covers most real workflows (deploy watch, sprint triage); longer needs deserve a real cron job.
**Q: How is it different from native /loop?**
A: See "How it differs" section. Hard cap + on-disk persistence + companion commands.
**Q: What happens if my machine sleeps?**
A: Missed ticks are skipped (not queued up). Next fire is on next wake. This is intentional — backlog firing causes thundering herds.
**Q: Can I run multiple loops?**
A: Yes — each gets its own task-id. /loop-list to see all active.
**Q: Is this Boris's actual /loop?**
A: No — community-written. Boris's private command file is not open-sourced.
---