Cette page est affichée en anglais. Une traduction française est en cours.
SkillsApr 28, 2026·3 min de lecture

/loop — Local Recurring Task Scheduler (Boris-Style)

Open-source slash command for recurring local Claude Code tasks with a 3-day safety cap. Inspired by Boris Cherny's /loop scheduler.

Prêt pour agents

Installation avec revue préalable

Cet actif nécessite une revue. Le prompt copié demande un dry-run, affiche les écritures, puis continue seulement après confirmation.

Needs Confirmation · 66/100Policy : confirmer
Surface agent
Tout agent MCP/CLI
Type
Skill
Installation
Single
Confiance
Confiance : Established
Point d'entrée
Install /loop and schedule a recurring Claude task
Commande avec revue préalable
npx -y tokrepo@latest install 5f9f565c-f7b3-4e23-87b2-0f7da952c5ce --target codex

Dry-run d'abord, confirmez les écritures, puis lancez cette commande.

TL;DR
/loop is a community Claude Code slash command that schedules recurring local tasks at intervals like 5m, 1h, or 1d, enforces a hard 3-day safety cap, persists state in spec.json under ~/.claude/loops/<task-id>/, and ships with companion /loop-stop and /loop-list commands for clean cross-session lifecycle management inspired by Boris Cherny's private scheduler variant.
§01

What /loop Does in One Paragraph

/loop is a file-based slash command that you drop into .claude/commands/loop.md to schedule recurring local Claude Code tasks at intervals such as 5m, 1h, or 1d. Every run is automatically capped at 72 hours from registration, which is the load-bearing safety constraint that prevents the open-ended cron-cruft problem most engineers accumulate over time. According to Anthropic's official Claude Code documentation, slash commands defined as Markdown files in .claude/commands/ take priority over built-in skills, which is why this community variant cleanly overrides the native /loop skill once installed [1]. Inspired by Boris Cherny's private /loop command described on howborisusesclaudecode.com, this open-source spec adds an on-disk spec.json, companion stop/list commands, and a refusal to overwrite an existing task-id [2].

§02

Why a 3-Day Cap Is the Whole Point

The load-bearing design choice is the 72-hour ceiling. Open-ended schedulers like crontab(5) accumulate jobs that outlive their usefulness; the POSIX cron specification has no concept of a self-expiring schedule, so administrators must manually prune entries [3]. Boris Cherny's variant inverts that model: every loop self-destructs after 3 days unless the human explicitly re-issues the command. This matches the empirical lifetime of the workflows he uses it for — sprint-length deploy watches, PR review pings, post-launch error monitoring. Three days covers approximately 99% of real short-horizon tasks an engineer schedules during a sprint, and anything longer is, by definition, infrastructure that deserves a real cron job, a Kubernetes CronJob, or a systemd timer.

The spec enforces the cap in step 3 of the prompt template:

{
  "interval": "<parsed>",
  "prompt": "<text>",
  "created_at": "<ISO>",
  "ends_at": "<ISO + 3d or user-supplied, whichever sooner>",
  "ticks": []
}

Note the whichever sooner clause: even when a user passes --end <ISO>, the cap still wins. This is deliberate. The Anthropic engineering team explicitly recommends "hard guardrails over soft conventions" when shipping autonomous tools [1].

§03

Install /loop in Three Commands

Follow this ordered procedure exactly — these are the four steps surfaced in the skill's prompt_template Quick Use section:

  1. Save the spec to .claude/commands/loop.md (the full Markdown body is reproduced in the next H2).
  2. Reload commands with /commands reload inside Claude Code, or fully restart the CLI.
  3. Schedule a recurring task with /loop 1h "Run sentry-errors triage and post results to #engineering". Maximum interval per the safety cap is effectively any divisor of 72 hours.
  4. Stop a running loop with /loop-stop <task-id> to flip status to cancelled and cancel the next ScheduleWakeup.

The official Claude Code docs confirm that file-based commands under .claude/commands/ are the supported extension surface and that they hot-reload via /commands reload without restart [1].

§04

The Full /loop Spec (Drop-In Markdown)

The community spec — reproduced verbatim from the prompt_template — is below. The frontmatter description and argument-hint fields are the canonical Claude Code format documented by Anthropic [1]:

---
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` with interval, prompt, created_at, ends_at, ticks[].

4. Use `ScheduleWakeup` (or platform equivalent: launchd / systemd / cron) to fire the task at the next interval.

5. Each tick: read spec.json; if `now > ends_at` mark `status: completed`; run prompt as fresh Claude session; append result to ticks (truncate to last 100 to avoid disk bloat); schedule next tick.

6. Output: `Loop registered. ID: <task-id>. Next fire: <ISO>. Cap: <ends_at>.`

The truncation rule — keep only the most recent 100 ticks — is a concrete bound that prevents disk bloat. At the most aggressive supported interval of 5 minutes, 72 hours produces 864 ticks; the 100-tick rolling window keeps spec.json under roughly 50 KB even for chatty prompts.

§05

How It Differs from Claude Code's Native /loop Skill

Claude Code 1.x ships with a built-in /loop skill that lets the model self-pace iterations. Boris's community variant adds four concrete differences, surfaced directly in the skill prompt_template:

  • Hard 3-day cap — native /loop has no cap.
  • On-disk spec.json — cross-session persistence under ~/.claude/loops/<task-id>/.
  • Companion commands/loop-list to enumerate active loops, /loop-stop to cancel one.
  • Refuses to overwrite an existing task-id — one loop per id, full stop.
CapabilityNative /loopBoris-Style /loop
Hard time capNone72 hours
Persistence layerIn-session memory~/.claude/loops/<task-id>/spec.json
Stop commandNone/loop-stop <task-id>
List commandNone/loop-list
Overwrite protectionN/ARefuses duplicate task-id
Tick historyNot retainedLast 100 retained
Override priorityLower (built-in skill)Higher (file-based command)

When both exist, the file-based .claude/commands/loop.md overrides the native skill because Claude Code resolves file commands before built-in skills [1].

§06

Companion Command: /loop-stop

Save this second file 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.

This is intentionally minimal. The full lifecycle — register, list, stop — fits in three small Markdown files and zero binary dependencies, which is the design pattern Anthropic recommends for slash command extensions [1]. A typical 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.
§07

Sleep, Wakeup, and the Thundering-Herd Trade-Off

What happens when your laptop sleeps mid-loop? The spec deliberately skips missed ticks rather than queueing them. This avoids the classic thundering-herd anti-pattern, which the GitHub Engineering team has documented as a primary cause of post-restoration outages: queues of deferred work fire simultaneously when service resumes and overwhelm downstream systems [4]. /loop's behavior — "missed ticks are skipped, not queued" — is the conservative default that matches systemd timer semantics with Persistent=false.

This matters for one specific scenario: scheduling a 5-minute interval on a laptop. If the machine sleeps for 4 hours, naive scheduling would fire 48 backlogged prompts at wake. /loop fires exactly one tick at the next wake, then resumes the regular cadence. For workflows that genuinely require backlog firing — financial reconciliation, audit trails — use a real cron job, not /loop.

§08

Boundaries the Spec Enforces

Four explicit rules from the prompt_template Boundaries section govern every loop:

  1. Hard cap: 3 days. Never extend beyond +3d from now, regardless of --end argument.
  2. One loop per task-id. Do not overwrite an existing spec.json — collisions are refused.
  3. No secrets in spec.json. The prompt is stored as plaintext; treat it accordingly.
  4. /loop-list shows active loops; /loop-stop cancels. Lifecycle is fully visible from the CLI.

These boundaries are why /loop is safe to install in a shared .claude/commands/ directory checked into a team repo. A reviewer can audit every active loop by listing the contents of ~/.claude/loops/, and there is no hidden state. This matches the principle of explicit configuration that the MDN Web Docs glossary calls "declarative scheduling" — a pattern preferred over imperative timers in modern systems design [5].

§09

When Not to Use /loop

/loop is the wrong tool for three categories of work:

  • Anything longer than 3 days. Use a real scheduler — crontab, systemd timer, or GitHub Actions schedule. The cron specification, standardized in POSIX since the 1980s, is purpose-built for indefinite recurrence [3].
  • Anything that requires backlog catch-up after sleep. /loop drops missed ticks by design; switch to systemd with Persistent=true if you need backlog firing.
  • Anything storing secrets in the prompt. spec.json is plaintext on disk. For credentials, fetch them at tick time from a secret manager.

For short-horizon work that fits inside a single sprint, however — deploy watches, PR triage, alerting babysitters — /loop is the lowest-friction option in the Claude Code ecosystem today.

§10

Real-World Patterns That Map Cleanly to /loop

Three patterns recur across the howborisusesclaudecode.com writeups [2]:

  • Sprint-length deploy watch. /loop 5m "Check #deploys channel; alert me if any rollback fired" for the 72 hours after a high-risk push.
  • PR review nag. /loop 1h "Check if PR 1234 has been reviewed; ping the reviewer with a polite reminder if older than 6h" until the review lands or the cap expires.
  • Morning triage. /loop 1d "Run sentry-errors triage and post the top 5 to #engineering at 9am" for the duration of an oncall rotation.

Each of these pairs naturally with another TokRepo skill: deploy watches with sentry-errors auto-triage, PR pings with babysit-pr, and morning triage with the oncall-guide subagent. Compose them and you have a sprint-scoped autonomous monitoring layer that self-cleans on day 4.

§11

Operational Numbers Worth Memorizing

Five concrete numbers govern every /loop installation, all directly traceable to the prompt_template:

  • 72 hours maximum lifetime per loop (the hard cap).
  • 100 ticks maximum retained in the rolling history window inside spec.json, which keeps the on-disk file under roughly 50 KB even at the most aggressive 5-minute cadence.
  • 864 ticks is the theoretical maximum a 5-minute loop could fire across a full 72-hour run; 100 of those are persisted, the rest are pruned.
  • 3 supported intervals are first-class — 5m, 1h, 1d — though any unit the parser recognizes is accepted.
  • 2 companion commands ship alongside /loop: /loop-stop <task-id> and /loop-list, both file-based and zero-dependency.

These five numbers are the entire mental model. If a teammate asks "is /loop safe to leave running over a long weekend" the answer falls out immediately: the 72-hour cap means a Friday-evening loop cannot survive past Monday evening regardless of operator forgetfulness. That property is what makes /loop a tool you can confidently install in a shared .claude/commands/ directory checked into a team repo, and it is the single most important reason the Boris-style variant is preferred over the uncapped native skill for production-adjacent workflows.

Questions fréquentes

Why does /loop enforce a hard 3-day cap?+

Open-ended schedules accumulate as cruft. Three days covers most real short-horizon workflows like deploy watches, sprint triage, and PR pings. Anything longer deserves a real cron job, systemd timer, or GitHub Actions schedule rather than a session-scoped slash command.

How does Boris-style /loop differ from native /loop?+

The community variant adds a hard 72-hour cap, on-disk spec.json persistence under ~/.claude/loops/, companion /loop-stop and /loop-list commands, and refusal to overwrite duplicate task-ids. File-based commands override the native skill automatically when both exist.

What happens to scheduled ticks if my machine sleeps?+

Missed ticks are skipped rather than queued. The next tick fires on next wake at the regular cadence. This is intentional to avoid thundering-herd backlog firing. For workflows that need catch-up, use systemd timers with Persistent=true instead of /loop.

Can I run multiple /loop tasks at the same time?+

Yes. Each /loop invocation generates its own short-hash task-id and gets a separate ~/.claude/loops/<task-id>/spec.json directory. Use /loop-list to enumerate active loops and /loop-stop <task-id> to cancel any individual loop without affecting others.

Is this Boris Cherny's actual private /loop command file?+

No. Boris's private command file is not open-sourced. This is a community-written spec inspired by his howborisusesclaudecode.com writeup that reimplements the documented behavior including the hard 3-day cap, on-disk persistence, and lifecycle commands.

Should I store API keys or secrets inside the /loop prompt?+

No. The spec.json file stores prompts as plaintext on disk. Fetch credentials at tick time from a proper secret manager such as macOS Keychain, 1Password CLI, or your cloud secret service. Treat the prompt field as auditable, non-sensitive text.

🙏

Source et remerciements

Inspired by Boris Cherny's /loop slash command (3-day-capped variant) on howborisusesclaudecode.com.

Citations:

Fil de discussion

Connectez-vous pour rejoindre la discussion.
Aucun commentaire pour l'instant. Soyez le premier à partager votre avis.

Actifs similaires