Skip to content

feat(marketplace): unify Firstsun External catalog across ChatGPT/Codex and Claude Code - #15

Merged
ClaudiaFang merged 12 commits into
mainfrom
feat-016-unify-marketplace
Sep 15, 2026
Merged

ClaudiaFang merged 12 commits into
mainfrom
feat-016-unify-marketplace

Conversation

@ClaudiaFang

Copy link
Copy Markdown
Member

Summary

  • Adds a single canonical catalog (marketplace/external/catalog.json) that generates identical firstsun-external marketplace manifests for both ChatGPT/Codex (.agents/plugins/marketplace.json) and Claude Code (.claude-plugin/marketplace.json), organized into seven task-oriented plugins across the Build/Design/Grow taxonomy, covering all 86 external skills with zero overlap.
  • Each plugin (plugins/<id>/) contains real copied files (no symlinks) under a shared skills/ directory with both .codex-plugin/plugin.json and .claude-plugin/plugin.json manifests, so the package is portable when imported from GitHub.
  • scripts/sync-external-marketplace.mjs --write/--check is the single deterministic generator; a full test suite (scripts/test-external-marketplace.mjs) covers catalog validation, discovery, generation, and drift detection.
  • Wires parity enforcement into init.sh and adds a dedicated push/PR-triggered CI job (verify-marketplace) so a hand-edited generated file now actually fails CI instead of silently drifting until the next weekly sync.
  • Removes the old personal tianyao-skills/most-used-skills bundle and the five legacy plugins/external-* packages from the public marketplace surface.
  • Updates README.md and SKILLS_LIST.md to document one catalog, two clients.
  • Fixes a pre-existing bug in the weekly sync workflow's cleanup step that was deleting the tracked .agents/plugins/marketplace.json (only .agents/skills/ is meant to be gitignored) — this branch's new init.sh parity gate would otherwise have made every weekly run fail.

Implemented via Subagent-Driven Development: fresh implementer + task review per task, plus a final whole-branch review that caught the CI cleanup bug and the tautological drift check above (both fixed and re-reviewed clean).

Test plan

  • node scripts/test-external-marketplace.mjs passes
  • node scripts/sync-external-marketplace.mjs --check exits 0 with no drift
  • Running the generator twice produces zero further git diff (deterministic)
  • ./init.sh passes end-to-end including the new external-marketplace-parity gate
  • find plugins -mindepth 1 -maxdepth 1 -type d | wc -l = 7; find plugins -mindepth 4 -maxdepth 4 -name SKILL.md | wc -l = 86; find plugins -type l | wc -l = 0
  • git diff -- skills-lock.json empty (no provenance drift); git diff --stat -- custom/ empty (custom/ untouched)
  • New verify-marketplace CI job runs the test suite + --check on push/PR without a preceding --write (not tautological)

🤖 Generated with Claude Code

ClaudiaFang and others added 12 commits September 15, 2026 03:24
Add the firstsun-external catalog (7 plugins, 86 skills) plus
loadCatalog/discoverSkills library functions and a test suite covering
field validation, source-root safety, in-plugin and cross-plugin
duplicate-name rejection, expectedSkillCount enforcement, and a
repository-level contract test against the real external/ tree.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Add buildOutputs/writeOutputs/checkOutputs to external-marketplace.mjs so
the Codex (.agents/plugins/marketplace.json) and Claude Code
(.claude-plugin/marketplace.json) manifests, plus the seven catalog plugin
packages under plugins/, are generated purely from marketplace/external/catalog.json
and the real skill files on disk -- deterministic, real files only (symlinks
rejected), catalog order for plugins and alphabetical order for skills.

sync-external-marketplace.mjs now supports --write and --check modes;
--check is read-only and reports missing/changed/unexpected files as drift.

Regenerate the repository outputs: replace the personal
tianyao-skills/most-used-skills bundle and the five legacy external-*
plugins with the seven canonical catalog plugins (agent-toolkit,
software-delivery, spec-driven-development, frontend-product-design,
visual-content, career-productivity, health-wellness), and retire
plugin-most-used/. This is the intentional clean break described in the
cross-platform external marketplace design.

Verified: node scripts/test-external-marketplace.mjs passes (including all
prior Task 1 tests), sync --write followed by sync --check exits 0 with no
drift, and a second --write produces zero further git diff (byte-identical
determinism).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
buildOutputs copied skill files via readFileSync/writeFileSync, which
silently dropped the executable bit -- 19 scripts across agent-toolkit,
software-delivery, and visual-content (e.g. brainstorming's
start-server.sh, skill-creator's *.py helpers) regenerated as mode 644
instead of the original 755, breaking direct execution.

Track each copied Buffer's source mode in a module-internal WeakMap and
re-apply it with chmodSync in writeOutputs, without changing the public
buildOutputs/writeOutputs Map<string, string | Buffer> contract. Add a
test asserting a chmod 755 fixture script keeps its mode after
writeOutputs. Regenerated plugins/ so all 19 previously-flagged files are
755 again; re-verified zero further diff on a second --write and that
`sync-external-marketplace.mjs --check` still exits 0.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Wire node scripts/sync-external-marketplace.mjs --check into ./init.sh
(new "external marketplace parity" gate) and into the weekly
update-external-skills workflow as an explicit verification step after
the refresh. Also broaden the workflow's add-paths to cover both
platform manifests, the canonical catalog, and the full plugins/ tree
(replacing the now-obsolete plugins/external-*/** glob). Add a test
proving checkOutputs actually reports drift when a tracked marketplace
output file is tampered with.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Rewrite README's marketplace section and SKILLS_LIST.md's Plugins table
to describe the single firstsun-external catalog (7 plugins across
Build/Design/Grow) published to both ChatGPT/Codex and Claude Code, and
add a documentation contract test asserting the obsolete tianyao-skills,
most-used-skills, and external-career-health names are gone and every
plugin id, manifest path, and verified skill count is present.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
feat-016 done: canonical catalog generates matching Codex/Claude
manifests across 7 plugins covering all 86 external skills, with
parity enforced in init.sh/CI. Records final verification evidence
in feature_list.json and closes out progress.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…t-check gap, stale comment, vacuous doc test)

- Fix critical bug where the weekly sync workflow's cleanup step
  (`rm -rf .agents .claude/skills`) deleted the tracked
  .agents/plugins/marketplace.json, causing every run's ./init.sh step
  to fail on "missing: .agents/plugins/marketplace.json". Now only
  removes the actually-gitignored .agents/skills subdirectory.
- Add a new verify-marketplace CI job (triggered on push/pull_request
  to main) that runs the contract tests and sync --check directly
  against committed output, closing the gap where a hand-edited
  generated file could sit undetected until the next weekly sync.
- Update stale "stage these two" comment to reflect the current
  six-entry add-paths list.
- Scope the SKILLS_LIST.md doc-count assertion to the line(s)
  describing each specific plugin instead of a whole-file substring
  search, so a drifted per-plugin count can actually fail the test.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@ClaudiaFang
ClaudiaFang merged commit 014c93b into main Sep 15, 2026
2 checks passed
@ClaudiaFang
ClaudiaFang deleted the feat-016-unify-marketplace branch September 15, 2026 07:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant