Pinecone Codex Plugin — Contributor Guide
How this repo is wired up: the sync pipeline from pinecone-io/skills, the validators, and the release workflow. Open this file in a browser — it is self-contained.
1. Overview
Pinecone publishes one base skills library — pinecone-io/skills — that is intentionally environment-agnostic.
The base repo fans out to one downstream plugin repo per agentic IDE: Claude Code, Cursor, and (this repo) Codex.
Nothing rewrites a skill after it leaves the base repo. Every Codex-specific value — the bare skill names, the codex_plugin: source tag, the per-target wording — comes from targets/codex.yaml upstream, and tools/build.py renders the tree before it is ever copied here. Read a sync PR as content, not as a transform.
2. Repo layout
| Path | Purpose |
|---|---|
.codex-plugin/plugin.json | Required Codex plugin manifest. Identity, version, install-surface metadata, pointers to skills/ and .mcp.json. |
.agents/plugins/marketplace.json | Marketplace metadata so users can codex plugin marketplace add pinecone-io/pinecone-codex-plugin. |
.mcp.json | Bundled Pinecone MCP server config (npx -y @pinecone-database/mcp). |
skills/ | One directory per skill. Each has a SKILL.md, optionally references/*.md and scripts/*.py. |
scripts/check_*.py | Validators. See §4. |
.github/workflows/validate.yml | Runs check_all.py on every PR and on pushes to main. |
.github/workflows/release.yml | On merge to main, bumps version, updates CHANGELOG, tags release. |
README.md | User-facing install and usage docs. |
CHANGELOG.md | Version history, populated by release.yml. |
docs/index.html | This file. |
3. Sync pipeline (upstream → here)
The base repo's .github/workflows/sync-skills.yml is dispatch-only. It renders every target with uv run tools/build.py --all --check, runs tools/reconcile.py against this repo to report what the sync is about to change, then rsync -a --deletes dist/codex/skills/ over skills/ here and opens a PR on branch sync/skills, labelled skill-sync.
The --delete matters: skills/ is owned entirely by the base repo, so a file you add there by hand is removed by the next sync. Everything outside skills/ — .codex-plugin/, .agents/, .mcp.json, scripts/, docs/, README.md — is owned here and the rsync never sees it.
A PLUGIN_SYNC_PAT personal access token gives the upstream workflow push permission on this repo. The PR body carries the reconcile report and a git checkout plus build.py command that reproduces the diff byte for byte.
pinecone-io/skills, or edit targets/codex.yaml there if the difference is Codex-specific. Both live upstream, not in this repo.
4. Validators
All validators are plain Python 3 — stdlib only, no uv or pyyaml needed in CI. Run the whole suite locally:
python3 scripts/check_all.py
| Script | What it enforces |
|---|---|
check_manifest.py |
.codex-plugin/plugin.json parses; has name, version, description, skills;
name is lowercase kebab-case; version is semver;
every path field (skills, mcpServers, hooks, apps, interface.composerIcon, interface.logo, interface.screenshots) starts with ./ and resolves to a real file;
interface.brandColor is #RRGGBB if present.
|
check_marketplace.py |
.agents/plugins/marketplace.json parses; each entry has name, policy.installation, policy.authentication;
each local source.path starts with ./, stays inside the repo, points at a directory containing .codex-plugin/plugin.json.
|
check_skills.py |
Every skills/*/SKILL.md has YAML frontmatter with name and description;
name matches the directory name and does NOT start with pinecone- (catches a mis-rendered sync);
no allowed-tools key (Claude-only);
description is a single line, ≤ 1000 chars;
body has no AskUserQuestion reference.
|
check_source_tags.py |
Every source_tag= literal in skills/**/*.py matches
^codex_plugin:[a-z0-9_]+(:[a-z0-9_]+)?$.
Catches leakage from pinecone_skills:*, claude_code_plugin:*, cursor_plugin:*, etc.
|
check_links.py |
Every relative markdown link in skill docs (and README.md) resolves to an existing file inside the repo.
HTTP(S), mailto, and anchor-only links are skipped.
|
check_all.py |
Thin wrapper that runs all of the above and aggregates exit codes. CI calls this. |
name: no longer matches its directory, or a Python script carrying another plugin's source_tag prefix. If a sync PR trips either, the bug is in targets/codex.yaml upstream, not in the file here.
5. Release workflow
.github/workflows/release.yml fires on pull_request.types: [closed] against main and only proceeds when github.event.pull_request.merged == true. Bump type is decided by PR labels:
bump:major→X.0.0bump:minor→X.Y+1.0- neither (default) →
X.Y.Z+1
The job:
- Reads
.codex-plugin/plugin.json, bumps the version, writes it back. - Generates changelog bullets from
gh pr view --json commits --jq '.commits[].messageHeadline', filtering outchore:and create-pull-request entries. - Inserts a
## [X.Y.Z] - YYYY-MM-DDblock after the# Changelogheader. - Commits as
github-actions[bot], pushes the version-bump commit and av<version>tag. - Creates a GitHub release with auto-generated notes.
6. Codex plugin spec essentials
.codex-plugin/plugin.json shape
{
"name": "pinecone", // required, lowercase kebab-case
"version": "0.1.0", // semver
"description": "...", // user-facing summary
"skills": "./skills/", // path, must start with ./
"mcpServers": "./.mcp.json", // path, must start with ./
"interface": {
"displayName": "Pinecone",
"category": "Productivity",
"capabilities": ["Read", "Write"],
"defaultPrompt": ["Use Pinecone to ...", "..."],
"brandColor": "#10A37F"
}
}
Path rules: every path is relative to the plugin root, must start with ./, and must stay inside the plugin root. Assets (icons, logos, screenshots) belong under ./assets/ when present.
.agents/plugins/marketplace.json shape
{
"name": "pinecone-codex-plugins",
"interface": { "displayName": "Pinecone for Codex" },
"plugins": [
{
"name": "pinecone",
"source": { "source": "local", "path": "./" },
"policy": {
"installation": "AVAILABLE",
"authentication": "ON_INSTALL"
},
"category": "Productivity"
}
]
}
For Git-backed entries the source object uses "source": "git-subdir" with url, path, and a ref or sha.
7. Adding a new skill manually
Skills belong in pinecone-io/skills, and the next sync deletes anything added here by hand. Add a skill directly only for a throwaway local test:
- Create
skills/<skill-name>/SKILL.md. The directory name is the slug (bare, nopinecone-prefix). - Frontmatter must contain
name: <same-as-directory>and a single-linedescription. Noallowed-toolskey. - If the skill ships Python helpers, put them in
skills/<skill-name>/scripts/. EveryPinecone(...)call that setssource_tag=must usecodex_plugin:<skill>[_<operation>]. - Run
python3 scripts/check_all.py. Iterate until green. - Update
README.md's skills table. - Open a PR.
validate.ymlwill run. Merge once green and the release workflow will tag a new version.
8. Troubleshooting
| Symptom | Likely cause / fix |
|---|---|
check_skills.py fails: "name still has pinecone- prefix" |
targets/codex.yaml upstream has the wrong skill_name. It must be "{slug}", with no prefix. Fix it there and re-run the sync; editing the file here is undone by the next one. |
check_skills.py fails: "allowed-tools is a Claude Code field" |
Upstream copied a Claude-plugin SKILL.md by mistake. Strip the allowed-tools: frontmatter line. |
check_source_tags.py fails with claude_code_plugin: or pinecone_skills: |
targets/codex.yaml upstream has the wrong source_tag. It must be codex_plugin. The suffix comes from the base script and is not per-target. |
check_links.py fails on a references/foo.md path |
The reference file was moved or renamed; update the link or restore the file. |
| Release ran but didn't tag | The release job only runs when the PR is merged (not just closed). Check the PR's merge state and the workflow logs for the "Determine bump type" step. |
| MCP not loading after install | Codex needs npx on PATH; install Node.js. Confirm PINECONE_API_KEY is exported in the same shell that launched Codex. |
Source: pinecone-io/pinecone-codex-plugin · base skills: pinecone-io/skills · Codex plugin docs: developers.openai.com/codex/plugins/build.