You kick off a refactor. Claude makes progress. Then it stops and waits. You type “keep going”. It runs another turn. You type “continue”. Another turn. You’re not doing agentic work — you’re manually paging through a task that should be running on its own.
Two commands eliminate this: /loop and /goal. They look similar on the surface — both keep Claude working without you prompting each step — but they solve different problems.
/loopruns a prompt on a schedule. You define the cadence; Claude keeps firing until you stop it./goalruns Claude until a condition is met. You define the end state; a separate model decides when it’s achieved.
Here’s when each one makes sense:
/loop | /goal | |
|---|---|---|
| Next turn starts | After a time interval | When the previous turn ends |
| Stops when | You stop it, or 7 days pass | A model confirms the condition holds |
| Best for | Polling, monitoring, babysitting | Multi-turn work with a verifiable endpoint |
/loop — Work on a schedule
/loop schedules a prompt to fire repeatedly while your session stays open. It comes in three modes depending on what you give it.
Fixed interval
The most explicit form. Supply an interval and a prompt — Claude converts it to a cron job, confirms the cadence, and starts the clock:
/loop 5m check if the deployment finished and summarize what happened
Supported units are s, m, h, and d. Intervals that don’t map to clean cron steps — like 7m or 90m — get rounded to the nearest valid step, and Claude tells you what it picked. The interval can come first or trail the prompt as a clause:
/loop check the deploy every 10 minutes
Dynamic interval
Omit the interval and Claude picks the timing itself. After each iteration it observes the situation and chooses a wait — short when things are actively changing, longer when nothing is pending:
/loop check CI and address any review comments
This pairs naturally with the Monitor tool: instead of polling on a timer, Claude can launch a background watcher that streams output as it arrives. More responsive and usually more token-efficient than a fixed interval.
Bare loop — built-in maintenance
Run /loop with nothing after it and Claude uses a built-in maintenance prompt that works through the following, in order:
- Continue any unfinished work from the conversation
- Tend to the current PR — review comments, failed CI, merge conflicts
- Run cleanup passes when there’s nothing urgent
/loop
This is the “I’m stepping away, keep the branch healthy” mode. Add an interval — /loop 15m — to run it on a fixed schedule instead.
To replace the built-in prompt with your own default, create .claude/loop.md in your project:
Check the `release/next` PR. If CI is red, pull the failing job log,
diagnose, and push a minimal fix. If new review comments have arrived,
address each one. If everything is green, say so in one line.
Claude picks this up automatically on the next iteration. You can edit the file while a loop is running — changes take effect immediately.
Stopping and managing loops
Press Esc to cancel a pending wakeup for a /loop. To list or cancel tasks, just ask:
what scheduled tasks do I have?
cancel the deploy check job
Key limitations before you start:
- Session-scoped: tasks stop if you close the terminal or start a new conversation.
--resumerestores them if they haven’t expired. - No catch-up: if Claude is busy when a task fires, it queues once — not once per missed interval.
- 7-day expiry: every recurring task deletes itself after 7 days. Recreate it or use Routines for work that needs to last longer.
- Costs scale with frequency: a task spending $0.05 per run costs $14/day at 5-minute intervals. Use dynamic mode for anything that should slow down when there’s nothing to do.
/goal — Work until done
/goal sets a completion condition and Claude runs toward it until an independent model confirms it’s been reached:
/goal all tests in test/auth pass and the lint step is clean
That one command starts a turn with the condition as the directive. After each turn, a small fast model (Haiku by default) reads the conversation transcript and returns a yes-or-no decision. A “no” includes a short reason that becomes guidance for the next turn. A “yes” clears the goal and records it as achieved in the transcript.
💡 Pro tip: Run
/goalwith no argument while a goal is active to check status: turns completed, tokens spent so far, and the evaluator’s most recent reason.
Writing a condition that holds up
The evaluator doesn’t run commands or read files — it reads what Claude surfaced in the transcript. Write conditions as things Claude’s own output can demonstrate:
Good conditions:
/goal npm test exits 0 and git status is clean
/goal every file in src/api/ has at least one test in test/api/
/goal the CHANGELOG.md has an entry for every PR merged this week
Conditions that will mislead you:
/goal the code looks clean # subjective — the evaluator can only read text
/goal the UI feels polished # can't be verified from the transcript alone
A solid condition has three parts:
- One measurable end state — a test result, a file count, a build exit code
- A stated check — how Claude should prove it (
npm testexits 0,git statusis clean) - Constraints that matter — “no other test file is modified”
To cap how long a goal runs, include a turn limit: or stop after 20 turns. Claude tracks progress against this clause each turn.
Non-interactive usage
/goal works in headless mode, which makes it composable with scripts and CI:
claude -p "/goal CHANGELOG.md has an entry for every PR merged this week"
This runs the goal to completion in a single invocation. Ctrl+C stops it early.
Clear a goal early
/goal clear
stop, off, cancel, reset, and none all work as aliases.
The evaluator’s blind spot
/goal is only as reliable as what the evaluator can see — and it can only see the transcript.
The practical consequence: verification that requires executing the artifact is invisible to the evaluator. An app that passes all of Claude’s in-transcript tests but renders broken UI will still satisfy a goal of “all features work,” because the evaluator reads what Claude reported, not what your browser shows.
⚠️ Warning: Use
/goalwhere the goal and the measure coincide. Tests pass, build exits 0, file count matches a target — these work because the measure and the target are the same thing. “Looks clean” or “is well-structured” are not verifiable from text alone, and the evaluator will eventually say yes when the transcript sounds confident enough.
When you need the actual artifact executed and inspected, a Stop hook with a deterministic script gives you real verification that /goal alone cannot provide.
Combining with auto mode
/goal removes per-turn prompts. Auto mode removes per-tool prompts within each turn. Together they give you fully hands-off execution:
/auto
/goal all acceptance criteria in docs/design.md are implemented and tests pass
Claude runs tools freely, loops until the evaluator says done, and you come back to a finished task.
Quick decision guide
| Scenario | Command |
|---|---|
| Babysit a deploy while I step away | /loop 5m check the deploy status |
| Keep a PR clean while I focus elsewhere | /loop |
| Migrate a module until it compiles and tests pass | /goal npm test exits 0 and no lint errors |
| Monitor CI on a long-running job | /loop 10m check CI status |
| Work through a bug backlog until it’s empty | /goal all issues labeled bug are closed or have a linked fix PR |
| One-shot reminder in 45 minutes | ”in 45 minutes, remind me to push the release branch” |
These two commands don’t replace your judgment — they extend your reach. The more precisely you can describe what “done” looks like or how often a check makes sense, the more of the work Claude can carry without you standing over it.
When the end state is verifiable, reach for /goal. When the work repeats on a rhythm, reach for /loop. If you’re unsure which fits, ask yourself: does this task end when a condition holds, or when you decide to stop it?