by ksimback
Design visual, review-gated agent loops for Claude Code before you run them.
# Add to your Claude Code skills
git clone https://github.com/ksimback/looperLast scanned: 7/5/2026
{
"issues": [
{
"file": "README.md",
"line": 141,
"type": "remote-install",
"message": "Install command (remote install script piped to a shell — review the source before running): \"curl -fsSL https://raw.githubusercontent.com/ksimback/looper/main/install.sh | b\"",
"severity": "low"
},
{
"file": "README.md",
"line": 240,
"type": "dangerous-command",
"message": "Dangerous command (recursive delete of home/root): \"rm -rf \"$HOME\"",
"severity": "medium"
}
],
"status": "PASSED",
"scannedAt": "2026-07-05T07:24:47.203Z",
"npmAuditRan": true,
"pipAuditRan": true,
"promptInjectionRan": true
}looper is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by ksimback. Design visual, review-gated agent loops for Claude Code before you run them. It has 577 GitHub stars.
Yes. looper passed SkillsLLM's automated security scan — a dependency vulnerability audit plus prompt-injection heuristics — with no high-severity issues. You can read the full report in the Security Report section on this page.
Clone the repository with "git clone https://github.com/ksimback/looper" and add it to your Claude Code skills directory (see the Installation section above). looper ships a SKILL.md manifest, so compatible agents can discover and load it automatically.
looper is primarily written in Python. It is open-source under ksimback on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh looper against similar tools.
No comments yet. Be the first to share your thoughts!
Use Looper as a loop design coach and scaffolder. During design, interview,
critique, validate, and write files. After emission, offer to run the loop in
the current session using RUN_IN_SESSION.md; keep run-loop.py as the
advanced external runner.
/looper argument. If no target is given,
use ./looper-output. If the target contains an existing loop.yaml, treat
the task as an edit/resume instead of a fresh scaffold.references/goal-rubric.md.references/verification-rubric.md.references/council-rubric.md.references/control-rubric.md.references/model-detection.md.revise_until_clean must name a judge member
or human as verdict_source.max_iterations, a revision cap on
each gate, a no-progress stop, and either a budget cap or an explicit human
stop point.loop.yamlloop.resolved.jsonLOOP.mdRUN_IN_SESSION.mdrun-loop.pyloop-workspace/README.mdloop.yaml, resolve the helper Python (see Helper Python
below) and run:
"$LOOPER_PYTHON" ${CLAUDE_SKILL_DIR}/scripts/looper.py compile <target>/loop.yaml --out <target>/loop.resolved.json --render <target>/LOOP.md --session-prompt <target>/RUN_IN_SESSION.mdRUN_IN_SESSION.md directly as the active task. If no, explain that
the same file is the easy restart path and run-loop.py is available for
advanced external execution.loop.yaml, loop.resolved.json, or model registries..env, .env.*, secrets/**, and **/*.key.loop.yaml human-readable and commented where useful. The emitted
runner reads only loop.resolved.json.RUN_IN_SESSION.md as the default/easy execution handoff. It is meant
for the current LLM session or a future pasted prompt.templates/run-loop.py exactly unless the user explicitly asks to edit
the external runner contract.The installer creates a private venv inside the skill directory. Its Python
lives at .venv/bin/python on macOS/Linux and .venv/Scripts/python.exe on
Windows. Shell state does not persist between commands, so prefix every helper
invocation below with this resolution (works in POSIX shells and Git Bash on
Windows):
LOOPER_PYTHON="${CLAUDE_SKILL_DIR}/.venv/bin/python"; [ -x "$LOOPER_PYTHON" ] || LOOPER_PYTHON="${CLAUDE_SKILL_DIR}/.venv/Scripts/python.exe"; [ -x "$LOOPER_PYTHON" ] || { LOOPER_PYTHON=python3; "$LOOPER_PYTHON" -c "" >/dev/null 2>&1 || LOOPER_PYTHON=python; }
The final fallback executes the candidate rather than just locating it: on
Windows, python3 on PATH is often the Microsoft Store alias stub, which
exists but cannot run scripts. If no candidate can execute -c "", tell the
user to rerun the Looper installer (it creates the venv).
Each command below assumes the Helper Python resolution is prefixed in the same shell invocation:
"$LOOPER_PYTHON" ${CLAUDE_SKILL_DIR}/scripts/looper.py detect-models --write"$LOOPER_PYTHON" ${CLAUDE_SKILL_DIR}/scripts/looper.py register-model <id> --invoke "<cmd> [args...]""$LOOPER_PYTHON" ${CLAUDE_SKILL_DIR}/scripts/looper.py compile <target>/loop.yaml --out <target>/loop.resolved.json --render <target>/LOOP.md --session-prompt <target>/RUN_IN_SESSION.md"$LOOPER_PYTHON" ${CLAUDE_SKILL_DIR}/scripts/looper.py session-prompt <target>/loop.resolved.json --out <target>/RUN_IN_SESSION.mdUse this shape and customize labels:
+--------------------------------+
| 1. Goal + context |
| read sources |
+--------------------------------+
|
v
+--------------------------------+
| 2. Draft plan.md |
| state -> state.json |
+--------------------------------+
|
v
+--------------------------------+
| 3. Plan gate |
| verdict: reviewer-1 |
+--------------------------------+
| needs work -> revise <= 3 -> step 2
| pass
v
+--------------------------------+
| 4. Write delivery-N.md |
| log -> run-log.md |
+--------------------------------+
|
v
+--------------------------------+
| 5. Delivery gate |
| verdict: reviewer-1 |
+--------------------------------+
| needs work -> revise <= 3 -> step 4
| pass
v
+--------------------------------+
| 6. Final output |
| all gates clean |
+--------------------------------+
Stops: pass gates | max 12 iterations | no progress x2 | budget 30m, $5.0, 2000000 tokens
programmatic, judge, or human.revise_until_clean gate has a valid verdict_source.loop_control has iteration, revision, no-progress, and wall-clock or budget
caps.run-log.md and state.json path.loop.resolved.json, LOOP.md, and RUN_IN_SESSION.md compile
successfully before handoff.Looper turns a fuzzy automation idea into a reviewable loop shape before any
runner starts changing files. This example comes from
examples/ai-workflow-mapping.
flowchart TD
G["Goal + context<br/>process notes + definition of done"] --> P["Draft plan.md<br/>host: codex / gpt-5"]
P --> PG{"Plan gate<br/>judge: reviewer-1"}
PG -- "revise <= 3" --> P
PG -- "pass" --> D["Write delivery-N.md<br/>map the workflow"]
D --> DG{"Delivery gate<br/>programmatic check + judge"}
DG -- "revise <= 3" --> D
DG -- "pass" --> F["Final output<br/>all gates clean"]
S["State + log<br/>state.json + run-log.md"] -. "records" .-> P
S -. "records" .-> D
Stop["Stop guards<br/>max 12 iterations<br/>no progress x2<br/>budget caps"] -. "watch" .-> PG
Stop -. "watch" .-> DG
A loop design coach for Claude Code. Looper is a skill that helps you design a good agent loop — a sharp goal, checkable verification, and a second model in the review seat — then lets you run it in the same session or save it as a portable spec. It is a design layer first: it writes files and hands the current session a clear execution prompt.
Invoke it with /looper. It interviews you, critiques your design against built-in best-practice rubrics, lets you wire in a cross-model reviewer or judge (including non-Claude models), shows you the loop as a terminal-friendly ASCII flow preview, and writes out RUN_IN_SESSION.md, loop.yaml, a compiled loop.resolved.json, a human-readable LOOP.md, a thin run-loop.py you own and edit, plus an empty loop-workspace/ and a README for the loop.
Maintainer: Kevin Simback · GitHub @ksimback · X @ksimback License: MIT
/goal or /loop?Claude Code already ships two pieces that look loop-shaped. They're useful — and they operate at a different layer than Looper. The short version: /goal and /loop run a loop; Looper helps you design one that's worth running, then gives the current session or an external runner a clear spec to follow.
/goal actually does/goal sets a persistent objective for the session. Once set, Claude keeps it as a reference point, checks after each significant action whether the current state satisfies the goal, and keeps working until it does — so it doesn't stop and ask after every step.
That's genuinely useful for persistence. But three things are missing for serious work:
/goal takes whatever goal you type, however vague. It won't tell you the goal is unfalsifiable or that "done" was never defined. Garbage goal in, confidently-wrong loop out./loop actually does/loop is a scheduler. You give it an interval and a task; it turns that into a cron job, registers it, and re-fires the prompt or skill on that cadence — polling CI, watching a deploy, monitoring a background job. (Omit the interval and it self-paces.)
It's the right tool for "run this thing every five minutes until I say stop." It is not a loop designer: it doesn't help you decide what runs, define success criteria, or bring in a reviewer. It schedules; it doesn't critique.
Looper is the design layer that sits in front of both. It produces a well-specified loop — coached goal, typed verification, a cross-model gate — then gives you a default in-session handoff prompt plus a portable spec. The same design can be run immediately in the conversation, driven by /goal for persistence, fired on a schedule by /loop, or run later with Python. Looper doesn't replace them; it gives them something good to run.
/goal |
/loop |
Looper | |
|---|---|---|---|
| Layer | execution (in-session) | execution (scheduling) | design (pre-flight) |
| Coaches your goal | no | no | yes |
| Typed, checkable verification | no | no | yes (programmatic / judge / human) |
| Reviewer model | same model (self-check) | none | a different model, by default |
| Explicit review gates | implicit | none | plan gate + delivery gate |
| Termination guards | goal-condition only | interval / until | iteration + revision + no-progress + budget caps |
| Portable, versionable artifact | no | the cron job | loop.yaml + resolved spec |
| Runs the loop | yes | yes | yes, by handing the current session a runnable prompt; Python runner optional |
The honest summary: if you already know your loop is well-designed and you just need it to persist or to fire on a schedule, /goal and /loop are the right reach. Looper exists for the part those don't touch — making sure the loop is worth persisting before you hand it off, and making sure something other than the author is checking the work.
Sources for the
/goaland/loopbehavior described above: Claude Code skills and commands documentation at code.claude.com/docs. Behavior and version gates change frequently; verify against upstream before shipping.
Looper provides loop design discipline: a clear goal, context sources, checkable verification, reviewer/judge gates, termination guards, a portable spec, a same-session execution handoff, and lightweight run state/log files.
Looper does not provide durable orchestration. It does not schedule cron jobs for you, persist step-level retries across process restarts, manage sub-agent lifecycles, enforce concurrency controls, or store a production run history. If you need those guarantees, use Looper to design the loop and hand the resulting spec to an orchestrator built for durable execution.
Before running a loop, Looper pushes you to make these explicit:
Install as a global personal skill and slash command.
On Windows PowerShell:
irm https://raw.githubusercontent.com/ksimback/looper/main/install.ps1 | iex
On macOS/Linux:
curl -fsSL https://raw.githubusercontent.com/ksimback/looper/main/install.sh | bash
If you prefer to inspect each step, use the manual install:
Windows PowerShell:
git clone https://github.com/ksimback/looper "$env:USERPROFILE\.claude\skills\looper"
New-Item -ItemType Directory -Force "$env:USERPROFILE\.claude\commands" | Out-Null
Copy-Item "$env:USERPROFILE\.claude\skills\looper\commands\looper.md" "$env:USERPROFILE\.claude\commands\looper.md" -Force
macOS/Linux:
git clone https://github.com/ksimback/looper "$HOME/.claude/skills/looper"
mkdir -p "$HOME/.claude/commands"
cp "$HOME/.claude/skills/looper/commands/looper.md" "$HOME/.claude/commands/looper.md"
Then, in Claude Code:
/looper
Looper interviews you, writes the artifacts into a folder called looper-output,
and shows you an ASCII flow preview to confirm before anything is finalized. The
installer also creates a private .venv inside the skill directory and installs
PyYAML, which the helper compiler needs to read loop.yaml. It
then offers to run the loop right there in the same Claude Code session.
If you want a different folder name, pass it after /looper, for example
/looper client-onboarding-loop.
The default path is to let Looper continue in the same conversation. It follows
the generated RUN_IN_SESSION.md handoff, writes plan.md,
delivery-N.md, review-N.md, state.json, and run-log.md into the loop
workspace, and stops when the gates pass, a cap is reached, or repeated
no-progress is detected.
Use the Python runner when you want to run the loop later, repeatably, from another terminal, or outside the LLM session:
python3 ./looper-output/run-loop.py
For local development, this repository root is the skill root. Edit and test it
here, then install or update the global skill by cloning or copying the repo to
$HOME/.claude/skills/looper and copying commands/looper.md to
$HOME/.claude/commands/looper.md.
If Claude Code says `U