Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .agents/plugins/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "primitive",
"interface": {
"displayName": "Primitive"
},
"plugins": [
{
"name": "primitive",
"source": {
"source": "local",
"path": "./"
},
"policy": {
"installation": "AVAILABLE",
"authentication": "ON_INSTALL"
},
"category": "Developer Tools"
}
]
}
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,21 @@ claude plugin install primitive@primitive

Or, from inside a session, `/plugin marketplace add primitivedotdev/skills` then `/plugin install primitive@primitive`. Run `/mcp` and pick `primitive` to sign in with your Primitive account over OAuth; the docs server needs no sign-in. The plugin carries the same skills as `npx skills add`, namespaced as `primitive:<skill>`, so install one or the other, not both.

### As a Codex plugin

In Codex, this repository is its own plugin marketplace:

```bash
codex plugin marketplace add primitivedotdev/skills
codex plugin add primitive@primitive
codex mcp login primitive
```

That installs every skill plus the hosted MCP servers. `.agents/plugins/marketplace.json` is the marketplace manifest, and Codex reads the plugin's name, icon and descriptions from `extensions["com.openai"].interface` in `plugin.json`. The older `primitivedotdev/codex-plugin` marketplace installs the same plugin from this repository.

### As an Agent Plugin

This repository is also an [Agent Plugin](https://agent-plugins.org/specification). `plugin.json` at the root is the manifest, the skills live under `skills/`, and `mcp.json` bundles Primitive's hosted MCP servers (`https://www.primitive.dev/mcp` for mail, authenticated with OAuth or a Primitive API key by your client, and `https://www.primitive.dev/mcp/docs` for public docs search, no auth). Point any Agent Plugins client at this repository to install everything at once. The Claude Code manifest lives in `.claude-plugin/` and declares the same servers. Codex installs this repository through the [`primitivedotdev/codex-plugin`](https://github.com/primitivedotdev/codex-plugin) marketplace and reads its icon, brand colour and descriptions from `extensions["com.openai"].interface` in `plugin.json`.
This repository is also an [Agent Plugin](https://agent-plugins.org/specification). `plugin.json` at the root is the manifest, the skills live under `skills/`, and `mcp.json` bundles Primitive's hosted MCP servers (`https://www.primitive.dev/mcp` for mail, authenticated with OAuth or a Primitive API key by your client, and `https://www.primitive.dev/mcp/docs` for public docs search, no auth). Point any Agent Plugins client at this repository to install everything at once. The Claude Code manifest lives in `.claude-plugin/` and declares the same servers.

## Skills

Expand Down
10 changes: 10 additions & 0 deletions scripts/check-plugin-manifests.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ if (!codexInterface) {
}
}

// Codex installs this repository as its own marketplace. The entry must keep
// pointing at the repository root, or Codex stops finding the plugin.
const codexMarketplace = read('.agents/plugins/marketplace.json')
const codexEntry = (codexMarketplace.plugins ?? []).find((plugin) => plugin.name === agentPlugin.name)
if (!codexEntry) {
problems.push(`.agents/plugins/marketplace.json does not list the "${agentPlugin.name}" plugin`)
} else if (codexEntry.source?.source !== 'local' || codexEntry.source?.path !== './') {
problems.push('.agents/plugins/marketplace.json must source the plugin from "./"')
}

const listed = (claudeMarketplace.plugins ?? []).find((plugin) => plugin.name === claudePlugin.name)
if (!listed) {
problems.push(`.claude-plugin/marketplace.json does not list the "${claudePlugin.name}" plugin`)
Expand Down
Loading