cc-loop is a local-first Claude Code CLI and plugin that keeps explicitly
activated Claude Code tasks running until they satisfy a minimum duration, a
target number of deliberate rounds, or an independently confirmed goal.
The project follows the same runtime and packaging structure as the source loop project:
- a Go single-binary CLI at
cmd/cc-loop; - runtime packages under
internal/; - a Claude Code plugin bundle under
plugins/cc-loop; - a local Claude Code marketplace at
.claude-plugin/marketplace.json; - release, verification, and packaging automation through Make, Mage, and GoReleaser.
- Activation by header: loops start only when the first prompt line is a valid
[[CC_LOOP ...]]header. - Three exclusive limiters:
min="...",rounds="...", orgoal="...". - Claude Code lifecycle hooks: bundled
UserPromptSubmitandStophooks. - Local state: loop records live under
${CLAUDE_CONFIG_DIR:-$HOME/.claude}/cc-loop/loops/. - Goal confirmation: a configurable headless Claude Code reviewer returns plain
text, then
cc-loopprivately interprets that text into a structured verdict. - Project overrides: a workspace
cc-loop.tomlcan override the global runtime config on a per-field basis.
Install the CLI:
go install github.com/compozy/cc-loop/cmd/cc-loop@latest
cc-loop installcc-loop install creates or refreshes:
${CLAUDE_CONFIG_DIR:-$HOME/.claude}/cc-loop/bin/cc-loop${CLAUDE_CONFIG_DIR:-$HOME/.claude}/cc-loop/loops/${CLAUDE_CONFIG_DIR:-$HOME/.claude}/cc-loop/config.toml- managed
UserPromptSubmitandStophook registrations in${CLAUDE_CONFIG_DIR:-$HOME/.claude}/settings.json
It preserves unrelated Claude Code settings and hook entries.
For marketplace-based installation, add this repository as a Claude Code marketplace:
claude plugin marketplace add compozy/cc-loop
claude plugin install cc-loop@cc-loop-pluginsFor local development:
claude plugin validate .
claude plugin marketplace add /path/to/cc-loop
claude plugin install cc-loop@cc-loop-plugins --scope userDuring plugin development you can also load the plugin directly:
claude --plugin-dir ./plugins/cc-loopRestart Claude Code, or run /reload-plugins in an active session, after
changing plugin files or managed hook settings.
Minimum duration loop:
[[CC_LOOP name="release-stress-qa" min="6h"]]
Run the full release QA plan and keep working until the time window has elapsed.
Round-count loop:
[[CC_LOOP name="release-stress-qa" rounds="3"]]
Run three deliberate implementation and verification rounds before stopping.
Goal-confirmed loop:
[[CC_LOOP name="release-stress-qa" goal="ship only after real verification"]]
Do the work, validate it with real evidence, and continue until the goal is confirmed.
Goal loops may override the confirmation model and reasoning effort:
[[CC_LOOP name="release-stress-qa" goal="ship only after real verification" confirm_model="opus" confirm_reasoning_effort="xhigh"]]
name="..." is required. Exactly one of min, rounds, or goal is required.
rounds must be a positive integer. Durations support values such as 30m,
30min, 1h 30m, 2 hours, and 45sec.
cc-loop install
cc-loop upgrade
cc-loop upgrade --version v0.1.1
cc-loop status
cc-loop status --all
cc-loop status --session-id <id>
cc-loop status --workspace-root <path>
cc-loop uninstall
cc-loop versionUse --claude-config-dir <path> to target an isolated Claude Code config
directory in tests or QA labs.
The global config lives at
${CLAUDE_CONFIG_DIR:-$HOME/.claude}/cc-loop/config.toml:
optional_skill_name = ""
optional_skill_path = ""
extra_continuation_guidance = ""
[hooks]
stop_timeout_seconds = 2700
[goal]
confirm_model = "opus"
confirm_reasoning_effort = "high"
confirm_command = "claude -p --permission-mode bypassPermissions --output-format text $MODEL_ARGV $REASONING_ARGV"
timeout_seconds = 2400
interpret_model = "haiku"
interpret_reasoning_effort = "low"
interpret_timeout_seconds = 120
max_output_bytes = 12000
[pre_loop_continue]
command = ""
cwd = "session_cwd"
timeout_seconds = 60
max_output_bytes = 12000Projects may also define cc-loop.toml in the workspace. During an active loop,
cc-loop searches from the Claude Code hook CWD up to the resolved workspace
root and uses the nearest cc-loop.toml it finds. It never searches above the
workspace root.
Effective config precedence is:
defaults -> global config -> nearest project cc-loop.toml
For project-local continuation context:
# ./cc-loop.toml
[pre_loop_continue]
command = ".claude/scripts/loop-context.sh --input $INPUT_FILE"
cwd = "workspace_root"
timeout_seconds = 30
max_output_bytes = 8000The public confirmation command receives a read-only review prompt on stdin and returns normal text. The default runner is:
claude -p --permission-mode bypassPermissions --output-format text --model opus --effort highcc-loop then runs a fixed private Claude Code interpreter command using
claude -p --output-format json --json-schema ... to convert the review text
into the internal verdict. The interpreter defaults to haiku with low
effort. Users may configure only the interpreter model, reasoning effort, and
timeout.
Available placeholders in confirm_command include:
$PROMPTand$PROMPT_FILE$CONFIRM_OUTPUT_PATH$MODEL_ARGVand$REASONING_ARGV$MODEL,$REASONING_EFFORT,$WORKSPACE_ROOT,$CWD,$SESSION_ID,$LOOP_NAME,$LOOP_SLUG,$RUNS_LOG_PATH, and$CLAUDE_CONFIG_DIR
The same values are exported with the CC_LOOP_CONFIRM_ prefix.
cc-loop uninstallThis removes only the managed
${CLAUDE_CONFIG_DIR:-$HOME/.claude}/cc-loop/ runtime directory and the
cc-loop managed hook registrations from settings.json. It preserves
unrelated Claude Code settings, installed plugins, credentials, sessions, and
hook entries.
Use the Makefile targets:
make deps
make fmt
make vet
make lint
make test
make build
make verify
make release-check
make release-snapshotmake verify runs formatting, go vet ./..., golangci-lint, race-enabled
tests, and go build ./....
cc-loop itself does not send data to a network service. It reads Claude Code
hook JSON from stdin, writes hook decisions to stdout, and stores loop state
locally under ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/cc-loop/. Goal loops invoke
the local claude command, which uses the user's configured Claude Code
provider and authentication.