From 72d831ad5b4324545f5420df48c092647328e72f Mon Sep 17 00:00:00 2001 From: Mathieu Picciolli Date: Thu, 27 Aug 2026 09:58:29 -0400 Subject: [PATCH 1/3] ci: validate plugin and marketplace manifests on every PR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The manifests at the root are read straight from git by anyone adding this marketplace, so merging to main is the release and a broken manifest ships silently. `claude plugin validate --strict` is an offline schema check that needs no API key, which makes CI the natural place for it — a git hook would be unversioned and skippable. Also format the two tracked files that already failed `prettier --check`, and ignore the local-only .claude/settings.local.json so the local run matches CI. Co-Authored-By: Claude Opus 5 --- .github/workflows/validate.yml | 32 +++++++++++++++++++ .prettierignore | 2 ++ AGENTS.md | 25 +++++++++++---- plugins/db-editor/.codex-plugin/plugin.json | 6 +--- .../references/database-schema.md | 24 +++++++------- 5 files changed, 66 insertions(+), 23 deletions(-) create mode 100644 .github/workflows/validate.yml create mode 100644 .prettierignore diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml new file mode 100644 index 0000000..85648a3 --- /dev/null +++ b/.github/workflows/validate.yml @@ -0,0 +1,32 @@ +name: Validate + +on: + pull_request: + push: + branches: [main] + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: Install Claude Code CLI + run: npm install -g @anthropic-ai/claude-code + + - name: Validate marketplace manifest + run: claude plugin validate --strict . + + - name: Validate plugin manifests + run: | + for plugin in plugins/*/; do + echo "==> $plugin" + claude plugin validate --strict "$plugin" + done + + - name: Check formatting + run: npx --yes prettier --check "**/*.{md,json}" diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..7f485fd --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +# Local, machine-specific permission state — not part of the repo. +.claude/settings.local.json diff --git a/AGENTS.md b/AGENTS.md index 2e9c6eb..ef03a59 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -23,6 +23,7 @@ Key formats and technologies: ### Repository Layout ``` +.github/workflows/validate.yml # CI: manifest validation, bash -n, prettier .claude-plugin/marketplace.json # Claude Code marketplace definition .agents/plugins/marketplace.json # Codex/agents marketplace definition plugins/ @@ -81,14 +82,25 @@ Then apply the repository conventions below to the result. ## Testing Instructions -There is no automated test suite. "Testing" here means validation plus behavioural checks: +There is no automated test suite. "Testing" here means validation plus behavioural checks. +The validation half runs in CI on every PR and every push to `main` +([.github/workflows/validate.yml](.github/workflows/validate.yml)); run it locally before +pushing: ```bash +claude plugin validate --strict . # marketplace manifest +claude plugin validate --strict plugins/db-editor # plugin manifest + its skills +python3 -m json.tool .json > /dev/null # Codex manifests, which have no validator bash -n plugins/db-editor/skills/pcm-database/scripts/open-cdb.sh # syntax-check scripts -python3 -m json.tool .json > /dev/null # validate each JSON manifest -npx prettier --check "**/*.{md,json}" # formatting +npx prettier --check "**/*.{md,json}" # formatting ``` +`claude plugin validate` is an offline schema check — no API key, no network. It stops at the +first manifest it finds, so `.` only ever validates the marketplace: the plugin directory needs +its own invocation. Pointing it at a skill directory fails ("No manifest found"); skills are +validated through their plugin. `--strict` turns warnings the runtime tolerates — unrecognized +fields, missing metadata — into failures, which is what you want before a manifest ships. + Behavioural checks that matter more than the above: - **Triggering** — install the plugin and confirm the skill fires on paraphrases, not just the @@ -162,9 +174,10 @@ Consequences worth remembering: - Commit and PR titles follow Conventional Commits: `feat:`, `docs:`, `fix:` — e.g. `feat: add pcm-startlist skill`. - One skill or one coherent change per PR. -- Before opening: JSON manifests parse, scripts pass `bash -n`, and the skill has been - exercised against at least a few realistic prompts. Say in the PR description what you - tested it with. +- Before opening: `claude plugin validate --strict` passes on the repo root and on each + plugin directory, scripts pass `bash -n`, and the skill has been exercised against at least + a few realistic prompts. Say in the PR description what you tested it with. CI runs the + first two for you, but not the prompts. - Branch off `main`; `main` is the release branch. ## Security and Data Handling diff --git a/plugins/db-editor/.codex-plugin/plugin.json b/plugins/db-editor/.codex-plugin/plugin.json index 928ee63..ab38550 100644 --- a/plugins/db-editor/.codex-plugin/plugin.json +++ b/plugins/db-editor/.codex-plugin/plugin.json @@ -27,11 +27,7 @@ "longDescription": "Community tooling for Pro Cycling Manager. Open and edit the game database (.cdb) — rider ratings, team rosters, contracts, races — via the pcm-mcp MCP server or a lossless CDB to SQLite conversion, and compose race startlists exported as the .xml file the game imports. Unofficial project, not affiliated with or endorsed by Cyanide Studio or Nacon.", "developerName": "PCMStack", "category": "Developer Tools", - "capabilities": [ - "Interactive", - "Read", - "Write" - ], + "capabilities": ["Interactive", "Read", "Write"], "websiteURL": "https://github.com/PCMStack/agent-skills", "defaultPrompt": [ "List my Pro Cycling Manager saves", diff --git a/plugins/db-editor/skills/pcm-database/references/database-schema.md b/plugins/db-editor/skills/pcm-database/references/database-schema.md index 6e18161..4e38d9b 100644 --- a/plugins/db-editor/skills/pcm-database/references/database-schema.md +++ b/plugins/db-editor/skills/pcm-database/references/database-schema.md @@ -104,18 +104,18 @@ what you want here, and never what you want anywhere else. The columns worth knowing, with a real career as the example: -| Column | Example | Meaning | -| -------------------------------------------- | ------------------------------ | ------------------------------------------------------------------ | -| `game_i_starting_year` | `2025` | Season the career started in. | -| `gene_i_date` | `20250108` | Current in-game date, `YYYYMMDD` — 8 January 2025. See below. | -| `fkIDstage_current` | `1110` | Stage in progress → `STA_stage`, which points at the race and date. | -| `game_sz_version` | `pcm25_shipping_01.09.02.555` | The build that last wrote the save. | -| `gene_sz_modname` / `gene_i_modid` | `Default` / `0` | Active mod; these values mean none. | -| `fkIDgamemode` | `1` | Career vs. other modes. | -| `fkIDgame_state` | `2` | Where the save sits in the game's own state machine. | -| `fkIDdivision` | `0` | Division the player's team competes in. | -| `game_i_is_over` | `0` | `0` = career still active. | -| `gene_b_multiplayer`, `gene_b_hardcoreMode` | `0`, `0` | Solo, hardcore off. | +| Column | Example | Meaning | +| ------------------------------------------- | ----------------------------- | ------------------------------------------------------------------- | +| `game_i_starting_year` | `2025` | Season the career started in. | +| `gene_i_date` | `20250108` | Current in-game date, `YYYYMMDD` — 8 January 2025. See below. | +| `fkIDstage_current` | `1110` | Stage in progress → `STA_stage`, which points at the race and date. | +| `game_sz_version` | `pcm25_shipping_01.09.02.555` | The build that last wrote the save. | +| `gene_sz_modname` / `gene_i_modid` | `Default` / `0` | Active mod; these values mean none. | +| `fkIDgamemode` | `1` | Career vs. other modes. | +| `fkIDgame_state` | `2` | Where the save sits in the game's own state machine. | +| `fkIDdivision` | `0` | Division the player's team competes in. | +| `game_i_is_over` | `0` | `0` = career still active. | +| `gene_b_multiplayer`, `gene_b_hardcoreMode` | `0`, `0` | Solo, hardcore off. | Two habits that keep this reliable: From 3c03e59890322ec28a93d818b7ae683aeacf7550 Mon Sep 17 00:00:00 2001 From: Mathieu Picciolli Date: Thu, 27 Aug 2026 10:40:01 -0400 Subject: [PATCH 2/3] ci: update Node.js version to 24 in validation workflow --- .github/workflows/validate.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 85648a3..767f70a 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -13,7 +13,7 @@ jobs: - uses: actions/setup-node@v4 with: - node-version: 22 + node-version: 24 - name: Install Claude Code CLI run: npm install -g @anthropic-ai/claude-code From 4c0e15844bba5541b41c7778865144b73f630832 Mon Sep 17 00:00:00 2001 From: Mathieu Picciolli Date: Thu, 27 Aug 2026 10:41:56 -0400 Subject: [PATCH 3/3] ci: remove unused validation commands from AGENTS.md --- AGENTS.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index ef03a59..9b88b38 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -90,8 +90,6 @@ pushing: ```bash claude plugin validate --strict . # marketplace manifest claude plugin validate --strict plugins/db-editor # plugin manifest + its skills -python3 -m json.tool .json > /dev/null # Codex manifests, which have no validator -bash -n plugins/db-editor/skills/pcm-database/scripts/open-cdb.sh # syntax-check scripts npx prettier --check "**/*.{md,json}" # formatting ```