# Plugin Marketplaces

`Codex.Plugins.Marketplace` models the local
`.agents/plugins/marketplace.json` file used by Codex discovery.

## Canonical Shape

Use nested `policy.*` fields for every plugin entry:

```elixir
{:ok, marketplace} =
  Codex.Plugins.new_marketplace(
    name: "repo-marketplace",
    interface: [display_name: "Repo Plugins"],
    plugins: [
      [
        name: "demo-plugin",
        source: [source: :local, path: "./plugins/demo-plugin"],
        policy: [installation: :available, authentication: :on_install],
        category: "Productivity"
      ]
    ]
  )
```

The SDK writes:

- `policy.installation`
- `policy.authentication`
- optional `policy.products`

It does not emit legacy top-level `installPolicy` or `authPolicy` as the
canonical output shape.

## Safe Updates

Use `add_marketplace_plugin/3` for read-modify-write updates:

```elixir
{:ok, result} =
  Codex.Plugins.add_marketplace_plugin(
    "/repo/.agents/plugins/marketplace.json",
    name: "demo-plugin",
    source: [source: :local, path: "./plugins/demo-plugin"],
    policy: [installation: :available, authentication: :on_install],
    category: "Productivity"
  )
```

Behavior:

- preserves unrelated plugin entries
- preserves unknown forward-compatible keys where possible, including overwrite
  updates on an existing entry
- preserves optional compatible metadata such as `policy.products` unless you
  replace it explicitly
- refuses duplicate plugin names unless `overwrite: true`
- writes deterministic pretty JSON with a trailing newline

## Path Rules

Marketplace source paths must:

- start with `./`
- reject traversal segments such as `..`, even when the expanded path would
  still land under the marketplace root
- stay within the marketplace root
- resolve relative to the root owning `.agents/plugins/marketplace.json`

The root-containment check runs on read, write, and update flows when the
actual marketplace path is known.

For repo scope that means:

- marketplace: `<repo-root>/.agents/plugins/marketplace.json`
- plugin source path: `./plugins/<plugin-name>`

For personal scope that means:

- marketplace: `~/.agents/plugins/marketplace.json`
- plugin source path: `./plugins/<plugin-name>`

## Verification Workflow

Recommended split:

1. Author locally with `Codex.Plugins.*`.
2. Start `codex app-server` only if you want runtime verification.
3. Verify discovery with `plugin/list`.
4. Verify details with `plugin/read`.

The local authoring layer and the runtime verification layer share validation
vocabulary where it is stable, but they remain separate APIs.
