> ## Documentation Index
> Fetch the complete documentation index at: https://moxn.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# The Dev Loop

> Iterate on a plugin against your live Moxn content, then track a branch once you publish

Publishing is a release step. While you're **building** you want a tight loop: change a skill, try it, repeat.

There are two loops, and they solve different problems. Use the first while you're writing; use the second once the change has to leave your machine.

| Loop                                   | What it does                                                          | GitHub involved? |
| -------------------------------------- | --------------------------------------------------------------------- | ---------------- |
| **Local** — `context marketplaces dev` | Materializes a Moxn ref into a directory and wires it into your agent | No               |
| **Published** — install at a branch    | Your agent tracks a GitHub branch that Moxn publishes to              | Yes              |

<Note>
  **Requires `@moxn/context-cli` 0.12.0 or newer.**

  ```bash theme={null}
  npm install -g @moxn/context-cli@latest
  context --version
  ```

  Earlier versions do not have `marketplaces` at all, and 0.11.x reports `unknown command`. Versions before 0.9 shipped a different `context plugin` / `context skill` dev loop against an API that no longer exists — those commands fail with `404 Not Found` regardless of the marketplace you point them at. If you see either symptom, upgrade first; nothing else on this page will work until you do.
</Note>

***

## Loop 1: local, no publishing

`context marketplaces dev` writes the marketplace's files at a ref into `.moxn/dev/<slug>/` and wires that directory into whichever agents you name.

```bash theme={null}
context marketplaces dev \
  --marketplace-id <uuid> \
  --ref my-feature-branch \
  --vendor claude
```

| Option                    | Meaning                                                                                                 |
| ------------------------- | ------------------------------------------------------------------------------------------------------- |
| `--marketplace-id <uuid>` | Which marketplace (required)                                                                            |
| `--ref <name>`            | Branch or ref. Omit for the marketplace's default branch                                                |
| `--vendor <name>`         | `claude`, `codex`, or `cursor`. Repeat for several. Omit to materialize the files only                  |
| `--check`                 | Write nothing; compare the existing dev tree against the ref's current head and exit `3` if it is stale |

Re-run the same command to refresh. Each materialization records the head sha it came from **inside the directory**, which is what makes `--check` meaningful — and it exits `3` rather than `1`, so a script can tell *stale* from *failed*.

### It serves drafts

Files come from the same read path an agent uses, which resolves **live working state** first and falls back to committed content. An uncommitted edit — yours, an agent's tracked change, or a colleague's in-progress typing — is materialized like anything else.

So you can try a change in a real agent **without committing or publishing it**.

<Note>
  `--check` compares the committed head the tree was built from. It answers "has the branch moved under me?", not "has someone edited a draft since?" — different questions, and the first is the one that silently invalidates a test.
</Note>

<Warning>
  **Installing the published plugin replaces your local dev copy, silently.**

  A local dev install and a published install compete for the same `<plugin>@<marketplace>` name, and the last one wins with no warning. So if you install the real published plugin to compare against what you are building — a reasonable thing to do before publishing — your agent stops resolving that name to the dev tree. Uncommitted skills vanish from the listing and edited ones revert to the published text; `/plugin install` still just reports success.

  Nothing on disk is lost — `.moxn/dev/<slug>/` is untouched. Re-run `context marketplaces dev` to point the name back at it.

  To avoid the collision entirely, do the comparison from a marketplace under a different name, or read the published bytes with `marketplaces read_file` at the committed ref instead of installing them.
</Warning>

### Each agent is wired the way that agent actually works

These are not three spellings of one mechanism:

<Tabs>
  <Tab title="Claude Code">
    Adds the directory as a marketplace. Skill bodies are re-read **mid-session**:

    ```
    edit in Moxn → context marketplaces dev … → /reload-plugins → invoke
    ```

    No restart needed.
  </Tab>

  <Tab title="Codex">
    Adds the directory, then adds the plugin.

    `codex plugin marketplace upgrade` **refuses a local directory** ("not configured as a Git marketplace"), so refreshing a local Codex marketplace is a re-`add` rather than an upgrade — which is what `dev` does for you.

    **Start a new thread afterwards.** A running session keeps the copy it loaded.
  </Tab>

  <Tab title="Cursor">
    Cursor has no CLI. Its local plugins are symlinks at `~/.cursor/plugins/local/<name>`, so `dev` links the directory there.

    **Reload Window** to pick it up.

    If something real already sits at that path, the link is refused rather than replaced — silently deleting a directory you put there is not a recovery a dev loop is entitled to make.
  </Tab>
</Tabs>

***

## Loop 2: published, tracking a branch

Once a change needs to reach other people or machines, publish it and let the agent track the branch.

**Point the marketplace at a branch, not just a repo:**

```bash theme={null}
claude plugin marketplace add owner/repo@my-feature-branch
claude plugin install my-plugin@my-marketplace
```

Then iterate: edit in Moxn on that branch, commit — which publishes to GitHub — and refresh:

```bash theme={null}
context marketplaces refresh --marketplace my-marketplace --plugin my-plugin
```

<Warning>
  **Updating the marketplace alone is not enough, and it looks like it worked.**

  `claude plugin marketplace update` advances the marketplace clone and writes the new commit's files to disk. It prints success. But the **install pointer** still names the previous commit, so every session keeps loading the *old* skill body while the files you would inspect show the new one.

  `context marketplaces refresh` runs both steps. By hand, you need both:

  ```bash theme={null}
  claude plugin marketplace update my-marketplace
  claude plugin update my-plugin@my-marketplace
  ```

  Then `/reload-plugins` in an open session, or start a new one.
</Warning>

<Warning>
  **These are terminal commands, not slash commands.** `claude plugin update x@y` runs in your shell. The similarly-named `/plugin` *inside* a Claude Code session is a different, interactive surface: it takes no arguments, so typing `/plugin update x@y` there silently opens the plugin menu and updates nothing.

  If you would rather stay in the session, the equivalent is `/plugin` → **Installed** → select the plugin → **Update**. Note that bare `/plugin` opens **Discover**, which lists plugins available to install — an already-installed plugin does not appear there.
</Warning>

### Why a branch install stays fresh

A scaffolded plugin's `plugin.json` carries no `version`, so Claude Code falls back to the **git sha** as the version key. Every Moxn commit therefore propagates, with no manual version bump.

If you do set a version, you own bumping it. What triggers an update differs by agent enough to matter — see [Distribution](/guides/marketplaces/distribution):

* **Claude Code** — version ladder, falling back to the git sha
* **Codex** — the **version string only**. A content change without a bump is stale forever, which is why Moxn stamps a content-derived cachebuster (`0.0.0+codex.<sha7>`) into the generated Codex manifest on every publish
* **Cursor** — the git sha

***

## Which loop when

**Local** while you are writing: it serves drafts, needs no commit, and turns around in seconds.

**Published** once the change has to leave your machine — a teammate testing it, CI, or another device. It costs a commit and a refresh, and it is the only one that proves what a real consumer gets.

<Note>
  Both loops need the CLI authenticated — either `MOXN_API_KEY` in the environment or a browser sign-in via `context login --workspace <slug>`. An API key wins when both are present.
</Note>
