---
title: "Install CC: the plugin and the cycle CLI | CommitCycle"
description: "CC ships as two artefacts — a Claude Code plugin and a CLI on npm. What each one gives you, which one is the wall, and how to tell what you have."
url: https://commitcycle.com/docs/start/install/
language: en
---

# Install

> CC ships as two artefacts — a Claude Code plugin and a CLI on npm. What each one gives you, which one is the wall, and how to tell what you have.

CC ships as **two artefacts built from one source**: a plugin for Claude Code, and a CLI on npm. They install separately, update separately, and do not collide — the plugin carries its own copy of the binary and puts nothing on your `PATH`.

Which one you want depends on what you are after:

| What you want                                                            | Install                                                                                                                         |
| ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
| Writes into a closed zone **blocked as they happen**, in Claude Code     | The plugin                                                                                                                      |
| `cycle` in any terminal, in any editor, in CI                            | npm                                                                                                                             |
| A guarded repository: writes blocked, and a task’s grant on this machine | Both. The plugin blocks; `cycle start` and `cycle sync`, from npm, bring the grant onto the machine. They install independently |

The distinction is not packaging trivia. **Only the plugin enforces**, and it is a Claude Code plugin. Everything else runs the process and records it. For Codex, Cursor and Windsurf, [what blocks in each editor](https://commitcycle.com/docs/start/install/#what-blocks-in-each-editor) says what exists and what has never been exercised.

## The plugin — Claude Code

```plaintext
/plugin marketplace add pow-paulinho/commitcycle-plugin
/plugin install commitcycle@commitcycle
/reload-plugins
```

Six things arrive with it as the trunk builds it (`plugin/hooks/hooks.json`, `plugin/.mcp.json`, `plugin/skills/`) — five with the published 0.1.25, which predates the context hooks:

- **The hook** — `PreToolUse` and `PostToolUse` on every tool call, and on the trunk `PostToolUseFailure` too, so a shell command that fails is contained like one that succeeds (CC-1379). This is the only part that stops a write _before_ it lands, and the only part that produces `.zones/state/events/`: a witness, not a decision.
- **A Stop hook** — `cycle reply --hook` at the end of every turn. On a task branch with a board, it posts the agent’s last reply to the task and keeps a copy in `.zones/state/replies/`. It prints nothing and never blocks.
- **Three context hooks** — `cycle context` before the first `Read` of a file in a session (the tasks that wrote it), on each prompt (up to three related tasks), and at session start, resume and compaction (the active task’s spec). They add context and never block; the prompt hook sends the prompt’s text to the board’s related-task search. See [why the code is the way it is](https://commitcycle.com/docs/reference/cli/#why-the-code-is-the-way-it-is). Not in the published 0.1.25 — [below](https://commitcycle.com/docs/start/install/#what-the-newest-release-does-not-carry-yet).
- **An MCP server** with seven tools on the trunk — `cc_zones`, `cc_intake`, `cc_interview`, `cc_scope`, `cc_status`, `cc_why`, and `cc_search`, which the published 0.1.25 does not have yet — which read the board and file or scope tasks. None of them starts work, issues a grant, or approves access. That is [D-31](https://commitcycle.com/docs/reference/mcp/), not an oversight.
- **Skills** — four on the trunk: `set-up-commitcycle` sets a repository up by asking about it, `start-work-inside-cc` files and scopes a task before the work begins, `review-against-the-ask` has a fresh subagent read the diff against the task’s four answers before the hand-in, and `review-playbooks` reviews the playbooks bullet by bullet and proposes, for each, keep, make it a check, merge or retire. The published 0.1.25 has the first two.
- **Its own binary**, for its hooks and its MCP server. No `npm install` step and nothing added to `PATH`, so it gives you no `cycle` command in a terminal — that comes from npm. Outside the project you are working in, it writes only to `~/.commitcycle/`, where sign-ins, machine pairings and the update check are kept — and, when the hook’s core cannot answer under the default `open` failure policy, one empty marker per session at `${TMPDIR:-/tmp}/cc-hook-open-<session>`, so the repair is named once a session rather than on every call.

### Why installing it cannot break your other repositories

Plugin hooks load **user-wide** — they run in every repository you open, not only the one you set up. That is exactly why the hook was held back until it could tell _“this repository never installed CC”_ from _“this task has not been started yet”_. It could not, and answered `deny` to both, so a single install would have blocked every write in every unrelated project on the machine.

It can now. A repository with no `.zones/zones.yml` is left alone silently — the hook gives no answer, so your editor’s own permission settings decide; nothing recorded, no advice. You should not be able to tell the hook ran. A repository that _has_ a zone map keeps every rule it has, and an **empty** map is not the same thing as an absent one: that is a project that ran the setup and protected nothing, and a task is still required there.

### If `/plugin` reports an old version

`/plugin` reads the version from its **local clone** of the marketplace repository, not from GitHub. A release pushed minutes ago will show as “already at the latest version” until that clone refreshes. Run `/plugin` again to update it, then `/reload-plugins` to apply.

## The CLI — npm

```bash
npm i -g commitcycle
cycle init
```

The command is `cycle`, not `cc`. On every Unix machine `cc` is already the system C compiler, and a governance tool that shadows a compiler is a governance tool people uninstall.

It ships the CLI and nothing else. So npm gives you the whole process — the board, the gate, grants, records, the closing checks — and **not the wall**.

That split is deliberate. Nothing running in someone else’s cloud can stop a file being written on your machine, and nothing installed as a library can see an editor’s tool calls. Enforcement has to live where the writes happen, which is why it arrives with the editor plugin.

## What blocks in each editor

A wall is a hook that the editor runs before each tool call, and every editor reads its hook from a file of its own. A file on disk is not a wall that fires: **Claude Code is the only editor where CommitCycle has been seen to block a write.** For Codex, Cursor and Windsurf, everything below is read from the vendor’s own documentation and from what `cycle init` writes, and none of it has been exercised against a real install of that editor.

| Editor                   | Hook file                              | Seen to block a write |
| ------------------------ | -------------------------------------- | --------------------- |
| Claude Code              | the plugin, or `.claude/settings.json` | yes                   |
| Codex                    | `.codex/hooks.json`                    | no — never exercised  |
| Cursor                   | `.cursor/hooks.json`                   | no — never exercised  |
| Windsurf (Devin Desktop) | `.windsurf/hooks.json`                 | no — never exercised  |

### Claude Code

The plugin’s `PreToolUse` hook denies a write into a closed zone before it lands. Claude Code is **fail-open** when a hook script is missing, which is why `cycle init` writes hook configuration only where a wrapper is already on disk (CC-641). macOS and Linux are the platforms that enforce today; Windows is post-MVP (D-25), and nothing blocks there yet.

### Codex, Cursor and Windsurf: what `cycle init --harness` leaves behind

The hook files for these three editors come from `cycle init --harness` with `codex`, `cursor`, `windsurf` or `all`; Codex’s is also written by default, beside Claude Code’s. Two facts decide what that command actually leaves behind:

- **It writes a hook file only where a hook wrapper is already on disk.** An editor told to run a script that is missing lets the write through without a word, so with no wrapper `cycle init` writes no hook file for any editor, and prints that it did not. Neither published artefact, the plugin or the npm package, puts a wrapper where `cycle init` looks for one.
- **The file it writes does not select that editor’s reply.** The hook picks its reply format from how it is invoked, and these entries carry no argument that picks it (CC-729), so the hook answers in Claude Code’s format. What Codex, Cursor or Windsurf does with that reply has never been observed, and `cycle init` prints beside each of these files to treat it as filed, not as enforcing.

### Codex

- **Trust.** Codex ignores a project’s `.codex/` layer, hooks included, until the project is trusted. Nothing in CommitCycle checks that, so in an untrusted project `.codex/hooks.json` is inert and nothing here can tell.
- **Not verified.** No Codex install has ever run the entry `cycle init` writes. Its shape is the one OpenAI documents, which is a different claim from “it works”.

### Cursor

- **Trust.** Cursor loads project hooks only in a trusted workspace, and nothing in CommitCycle checks that.
- **Coverage.** Only `preToolUse` is registered in `.cursor/hooks.json`, with `failClosed: true`; without it, Cursor lets the action through when a hook crashes, times out or returns invalid JSON. Shell commands, MCP calls and file reads go through separate Cursor events that are not registered, so treat shell commands and file reads in Cursor as unguarded.
- **Not verified.** `.cursor/hooks.json` has never been exercised against a Cursor install.

### Windsurf (Devin Desktop)

- **Channel.** Windsurf has no JSON reply: a denial is exit code 2 and nothing else, and any other non-zero exit lets the action proceed. `show_output`, reported to be what lets a person see why an action stopped, is not written, so a person blocked here may see the action stop with no reason given.
- **Coverage.** `.windsurf/hooks.json` registers `pre_write_code`, `pre_read_code`, `pre_run_command` and `pre_mcp_tool_use`: writes, reads, commands and MCP calls.
- **Rename.** Windsurf is being renamed Devin Desktop, and whether `.windsurf/hooks.json` keeps working, and for how long, is not documented.
- **Not verified.** `.windsurf/hooks.json` has never been exercised against a Windsurf install.

## What you actually have

`cycle doctor` answers this better than any version number, because it checks the wiring rather than the label:

```plaintext
$ cycle doctor
[  ok  ] git repository         /path/to/your/repo
[  ok  ] zone map               4 zone(s): schema, contracts, enforcement, brand
[  ok  ] hook installed         .../hook/bin/cc-hook.sh
[  ok  ] active task            CC-262 — no zones open
```

A row that is not `ok` names what is missing and what to run. The **hook installed** row is the one that separates documented from guarded: without it, everything else still works and nothing is stopped.

That row reads Claude Code’s wiring: the plugin and `.claude/settings.json`. It does not read the Codex, Cursor or Windsurf hook files, and nothing in CommitCycle can tell whether an editor trusts the project.

For the packages themselves:

```bash
npm view commitcycle version    # what the registry holds
npm ls -g commitcycle           # what this machine installed
```

and `/plugin` inside Claude Code for the plugin’s own version. There is no `cycle --version`; `cycle doctor` is the supported answer.

## Updating

The two are independent — updating one does not move the other.

```plaintext
/plugin            # refreshes the clone, then /reload-plugins
```

```bash
npm i -g commitcycle@latest
```

### What the newest release does not carry yet

These pages describe the trunk. The plugin and the npm package reach you only when a release is cut, and the newest one is **0.1.25, published on 2026-10-12**. What merged after it is on the trunk and not in any release yet, as of 2026-11-01 (the board’s `/health` names 0.1.25 as the latest):

- the three context hooks and `cycle context` (CC-1347);
- `cc_search` in the plugin’s MCP server and in `cycle mcp`, and the hook letting it through as a read (CC-1345);
- the hook letting the editor’s own folders through — the session scratchpad, the project’s memory folder, todos and plans (CC-1348) — and the outside-the-repository refusal that says what it covers (CC-456);
- the stdio `cc_intake` naming the board it filed on (CC-749), and the access-request link that names its board (CC-764);
- the hook’s `PostToolUseFailure` registration, failed shell commands contained, and a backgrounded command asked about first while a zone is closed (CC-1379);
- `cycle sync --policy-only`, `cycle verify --from-history` with several ids, a sync that skips only the ids two records collide on, and a command that takes one task refusing a second id instead of dropping it (CC-1383);
- a renamed file counted at both its paths in `cycle verify`’s manifest (CC-1382), and `cycle doctor`’s `shipped CLI vs source` line (CC-605);
- the review-against-the-ask skill, and the hand-in’s two new headings, `## Review against the ask` and `## Merge danger`, in `cycle submit --help` (CC-1358);
- the review-playbooks skill (CC-1360);
- the interview in rounds, each question with a recommended answer, in the plugin’s MCP server, `cycle mcp` and the start-work skill (CC-1361);
- `cycle handoff` counting a decision once when `docs/01-decisiones.md` indexes `.zones/decisions/`, reading `**PROPOSED` rows as open, and naming decision files whose `Status` is empty (CC-1359);
- `cycle doctor` and `cycle status` no longer calling the wrapper fail-closed, `cycle request-access` saying who answers a zone whose owner is still `cycle init`’s `TODO@` placeholder, `cycle status` saying an open zone still needs a grant to write, and `cycle init`’s Windsurf caveat no longer calling CC-728 open (CC-1369).

The board’s own changes — the connector’s tools, the console, the gate — are not part of a release; they are the board’s. `npm view commitcycle version` and `/plugin` say which release you have.

## What to read next

- [Quickstart](https://commitcycle.com/docs/start/quickstart/) — a board, a connector and a zone map, in about five minutes
- [Two accounts on one machine](https://commitcycle.com/docs/operations/accounts/) — signing in more than once, and which identity a repository uses
- [Two sessions at once](https://commitcycle.com/docs/operations/parallel-sessions/) — the layout that lets two agents work on one repository without one authorising the other’s writes
- [The three layers](https://commitcycle.com/docs/concepts/three-layers/) — what enforcement proves, and what it does not
