{"id":51342987,"url":"https://github.com/thepictishbeast/claude-tools","last_synced_at":"2026-07-02T09:10:41.322Z","repository":{"id":358394552,"uuid":"1241233940","full_name":"thepictishbeast/claude-tools","owner":"thepictishbeast","description":"Pause, resume, edit, and audit Claude Code cron jobs (e.g. /loop) without losing state.","archived":false,"fork":false,"pushed_at":"2026-06-30T20:51:18.000Z","size":227,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-30T22:24:05.233Z","etag":null,"topics":["anthropic","claude-code","claude-skills","cron","loop"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thepictishbeast.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-17T05:54:17.000Z","updated_at":"2026-06-30T20:51:23.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/thepictishbeast/claude-tools","commit_stats":null,"previous_names":["thepictishbeast/claude-loop-tools","thepictishbeast/claude-tools"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/thepictishbeast/claude-tools","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thepictishbeast%2Fclaude-tools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thepictishbeast%2Fclaude-tools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thepictishbeast%2Fclaude-tools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thepictishbeast%2Fclaude-tools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thepictishbeast","download_url":"https://codeload.github.com/thepictishbeast/claude-tools/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thepictishbeast%2Fclaude-tools/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35040230,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-02T02:00:06.368Z","response_time":173,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anthropic","claude-code","claude-skills","cron","loop"],"created_at":"2026-07-02T09:10:40.172Z","updated_at":"2026-07-02T09:10:41.311Z","avatar_url":"https://github.com/thepictishbeast.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# claude-tools\n\n[![test](https://github.com/thepictishbeast/claude-tools/actions/workflows/test.yml/badge.svg)](https://github.com/thepictishbeast/claude-tools/actions/workflows/test.yml)\n\n\u003e **RENAMED 2026-05-20**: this repo was `claude-loop-tools`. GitHub's\n\u003e rename redirect keeps the old URL working for clones, but new\n\u003e clones should use:\n\u003e ```sh\n\u003e git clone https://github.com/thepictishbeast/claude-tools\n\u003e ```\n\u003e Existing clones: `git remote set-url origin https://github.com/thepictishbeast/claude-tools.git`\n\u003e\n\u003e **Scope expanded**: this repo is now the **umbrella for all Claude\n\u003e Code tooling** (skills, MCPs, helper binaries) — not just `/loop-*`.\n\u003e Run `/loop-update` (or `update.sh` directly) regularly to pull\n\u003e the latest set into `~/.claude/skills/`. See [CONTRIBUTING.md](\n\u003e ./CONTRIBUTING.md) for the \"add a new tool\" workflow (Rust first,\n\u003e token-efficient, automates a frequent task).\n\u003e\n\u003e **AI agents (Claude / Codex / Cursor / etc.) — read [`META.md`](./META.md)\n\u003e first.** Single-page handoff: what this repo is, install/sync, current\n\u003e tools, the 4 design rules, the 3-step add-a-tool recipe. ~5 min read,\n\u003e answers every question before you start.\n\nPause, resume, edit, and audit Claude Code cron jobs (e.g. `/loop`).\n\nClaude Code ships with `/loop` but no way to pause a long-running\nloop without losing it, change its interval without re-typing the\nprompt, audit what's been scheduled over time, or compose loops with\nTaskList / Monitor, plus first-class skills for the agent fleet and the\nForge substrate. This adds these skills:\n\n- **`/loop \u003cverb\u003e`** — manage active loops. Consolidated 2026-06-30 from\n  the former loop-pause / loop-resume / loop-edit / loop-stop / loop-track /\n  loop-update skills into one verb-routed command, backed by the\n  `claude-loop` binary. Verbs:\n  - `pause` — pause all active cron jobs (state → `~/.claude/.paused-loops.json`, cron deleted, nothing lost).\n  - `resume [5m]` — restore the paused jobs, optional inline interval override.\n  - `edit` — change interval/prompt of an already-running loop without pause+resume.\n  - `stop` — permanently cancel a loop (deletes cron AND clears paused state).\n  - `track \u003cid\u003e` — register a raw cron into loop history.\n  - `update` — pull latest claude-tools + reinstall.\n- **`/loops`** — show a unified view of active + paused + recent\n  history (last 20 events). Auto-discovers untracked crons (raw\n  `/loop` invocations not yet in history) as a side effect.\n- **`/fleet`** — orchestrate the agent fleet (Conductor + worker swarm).\n  Defers heavy ops to the `fleet` MCP server (validate-plan / run / gate /\n  status / per-worker introspection / global STOP).\n- **`/forge`** — build / audit / reason about the Forge + Loom + Crawler\n  substrate. Defers to the `forge` MCP server (~21 typed tools).\n- **`/loop-from-task`** — wrap a TaskList task as a self-terminating\n  loop. Fires periodically, works on the task, `/loop-stop`s itself\n  when the task is marked completed.\n- **`/loop-on`** — event-driven loop using `Monitor` instead of cron.\n  Watches conditions (`pr-merged:`, `ci-status:`, `task-completed:`,\n  `port-open:`, custom `watch-cmd:`); fires the `then:` prompt when\n  the condition triggers.\n- **`/loop-health`** — single-shot lint diagnostic. Reports missing\n  canaries, oversized prompts, stale paused entries, untracked crons,\n  history-rotation candidates, stale skill-rename leftovers.\n- **`/checkpoint`** — save FULL session state (tasks + active loops\n  + background processes + dirty git trees + handoff note) to\n  `~/.claude/.checkpoint/`. Use before you `/exit` so you can pick up\n  exactly where you left off.\n- **`/restore`** — first command of a new session. Auto-updates the\n  toolkit from upstream, then reads the `~/.claude/.checkpoint/`\n  state, re-creates the TaskList, resumes paused loops, shows the\n  handoff note, then deletes the checkpoint.\n\nHistory is appended to `~/.claude/loop-history.jsonl` on every\npause/resume/edit/stop — append-only, one JSON line per event.\n\n## The non-interruption rule (please read first)\n\n\u003e **A loop fire is a SIGNAL to continue, not a command to start\n\u003e something new.** If your agent is mid-task when the loop fires,\n\u003e finish that task first. The loop will fire again in N minutes;\n\u003e the work waits.\n\nThis is the single load-bearing discipline that makes loops\nuseful instead of disruptive. Without it, agents drop mid-work\nto \"act on\" the re-injected prompt, duplicate effort across\niterations, and ship half-finished commits.\n\nConcrete rules:\n\n1. **Loop fires don't interrupt current tool calls.** Finish\n   the call, *then* read the prompt.\n2. **In-flight tasks have priority over the loop prompt.** If\n   `TaskList` shows an `in_progress` task, continue it. The\n   prompt's TASK PRIORITY list applies only when nothing is\n   in-flight.\n3. **Mid-iter user messages are tracked, not acted on\n   immediately.** The user typing while the agent is editing a\n   file should produce a new `TaskCreate`, not a context\n   switch.\n4. **Re-injection is not a new directive.** The cron-injected\n   prompt is verbose by design. The same text every fire means\n   \"standing posture\" not \"fresh instruction.\"\n5. **Tight ticks → one-line health check, no log entry unless\n   state changed.** Idle fires that produce no work should\n   leave no trace.\n\n[`CLAUDE.md`](./CLAUDE.md) is the canonical contract — every\nloop participant (AI agent or human operator) reads it before\nstarting work. The rules above are the executive summary.\n\n## Patterns (general-purpose loop design)\n\nSee [`docs/LOOP_PATTERNS.md`](./docs/LOOP_PATTERNS.md) for the\ncatalogue covering:\n\n- **Stop conditions** — empty task list / max iterations / error\n  budget exhausted / deadline / success condition met / drift\n  detection / external signal / composed-with-OR semantics.\n- **Interval strategies** — fixed cron / dynamic mode (no\n  interval token, self-paced via `ScheduleWakeup`) / adaptive\n  cron (agent retunes its own cadence via `/loop-edit` based on\n  observed state) / exponential backoff on idle / time-windowed\n  (work-hours fast, night slow).\n- **General-purpose loop design checklist + prompt template** —\n  every decision (cadence shape / interval / stop conditions /\n  scope / reporting / recovery) explicit before scheduling.\n\nThis toolkit deliberately keeps the skills low-level (`/loop`\nschedules, `/loop-edit` retunes, `/loop-stop` cancels). The\nPATTERNS doc shows how to compose them into loops that fit\narbitrary work shapes — bursty / steady / decreasing /\nevent-driven — without retyping verbose prompts.\n\n## Install\n\n```sh\ngit clone https://github.com/thepictishbeast/claude-tools\ncd claude-tools\nmkdir -p ~/.claude/skills\ncp -r skills/* ~/.claude/skills/\n```\n\nRestart Claude Code (or open a new session) so the skills are\ndiscovered.\n\n## Usage\n\n```\n/loop 1m do-some-recurring-task         # start a loop\n…\n/loops                                  # what's active/paused/recent\n\n# Modify in place (no need for pause+resume cycle):\n/loop-edit 5m                           # change interval, keep prompt\n/loop-edit prompt: \"new task text\"      # change prompt, keep interval\n/loop-edit 5m prompt: \"...\"             # change both\n/loop-edit prompt-append: \"and CC me\"   # tack onto existing prompt\n\n# Pause/resume cycle (state preserved between):\n/loop-pause                             # state saved, loop cancelled\n/loop-resume                            # restore exactly as paused\n/loop-resume 5m                         # restore with new cadence\n$EDITOR ~/.claude/.paused-loops.json    # hand-edit anything before resume\n\n# Permanent stop:\n/loop-stop                              # delete cron + clear state\n\n# Full session restart (paul wants to relaunch Claude Code):\n/checkpoint                             # save tasks, loops, bg procs, notes\n# then /exit + relaunch Claude Code (use --continue for chat history)\n/restore                                # first command in new session\n```\n\n## Editing the prompt or cron of a paused loop\n\nThe state file is a plain JSON array; edit with any text editor:\n\n```sh\n$EDITOR ~/.claude/.paused-loops.json\n```\n\nEach entry has:\n\n| field           | purpose                                              |\n|-----------------|------------------------------------------------------|\n| `cron`          | cron expression (e.g. `*/5 * * * *`)                 |\n| `cadence_human` | human-readable cadence (informational only)          |\n| `recurring`     | boolean — does the cron auto-renew?                  |\n| `prompt`        | the verbatim message Claude receives each fire       |\n| `canary_added`  | whether `/loop-pause` auto-added a canary line            |\n| `paused_at`     | ISO-8601 UTC timestamp                               |\n| `label`         | optional short label (informational only)            |\n| `id_original`   | the original job ID from before pause (informational)|\n\nSave and `/loop-resume` — the new values take effect.\n\n## The canary\n\n`/loop-pause` auto-appends a self-check sentence to the prompt if one is\nnot present:\n\n\u003e Note: if you canceled or stopped this loop, you should NOT be\n\u003e seeing this message.\n\nThis catches the bug where the cron keeps firing after the loop\nlogic has reached its \"done\" condition — the canary in the message\ntells the agent to stop and clean up.\n\nDisable canary auto-add by editing the skill's SKILL.md (find the\n\"Auto-canary check\" section and remove it), or set the saved entry's\n`canary_added` field to `false` and remove the sentence by hand from\n`prompt`.\n\n## State files\n\n| File                                | Mode | Purpose                          |\n|-------------------------------------|------|----------------------------------|\n| `~/.claude/.paused-loops.json`      | 600  | Currently-paused loops           |\n| `~/.claude/loop-history.jsonl`      | 600  | Append-only audit history        |\n\nThe mode-600 default is because prompts may contain sensitive\ncontext. The skills `chmod 600` after writing.\n\n## Design constraints\n\n- Cron entries created with `CronCreate` are **session-scoped** —\n  they die when the Claude Code session ends. The state file\n  persists, so `/loop-resume` works even across sessions.\n- `/loop` dynamic mode (no interval, uses `ScheduleWakeup`) isn't\n  cron-backed and isn't visible to these tools. Pausing a\n  dynamic-mode loop is \"stop replying\" — which happens automatically\n  when the user doesn't interact.\n- These skills don't try to deduplicate or validate cron logic.\n  They're a thin layer over `CronCreate` / `CronDelete` / `CronList`.\n\n## Loop hygiene (for AI agents)\n\nWhen `/loop` fires every minute, the same prompt is re-injected each\ntime. Without explicit hygiene, agents tend to:\n\n- Restart finished work every iteration\n- Drop mid-task work to \"act on\" the re-injected prompt\n- Lose track of what's in-flight vs. queued vs. done\n- Bloat the iteration log with duplicate state\n\n**[`CLAUDE.md`](./CLAUDE.md) is the contract every loop participant\nreads first.** Key rules it codifies:\n\n1. A loop fire is a SIGNAL to continue, not a command to start\n   something new. Finish in-flight work first.\n2. Maintain an explicit task list (`TaskCreate` / `TaskUpdate`).\n   The task list is the durable state that survives between fires;\n   the loop prompt itself doesn't carry state.\n3. Mid-iter user messages get acked + tracked as tasks, not allowed\n   to interrupt the current tool call.\n4. Tight-tick fires should produce a one-line health check and stop —\n   don't append redundant log entries for \"still healthy\".\n5. Substantive fires do work fully — don't fragment a 5-minute task\n   across 5 separate iterations.\n\nRecommended workflow:\n\n```\n/loop 5m work on the tasks in my TaskList; create new ones for\nfollow-ups; log only when state changes\n```\n\nvs. the failure mode:\n\n```\n/loop 1m do everything you can       # too aggressive — every fire\n                                       # tries to start fresh work\n```\n\n## License\n\nMIT.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthepictishbeast%2Fclaude-tools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthepictishbeast%2Fclaude-tools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthepictishbeast%2Fclaude-tools/lists"}