Ship a build pipeline that mirrors the agentics-kit marketplace into a single clean distribution repo — keeping only each plugin's manifest, components, README, and CHANGELOG — so users who install pull plugin-required files instead of docs/, scratch markdown, and repo configs.
Read and implement all steps in the plan at docs/plans/build-clean-plugin-dist.html — Publish a clean, stripped-down plugin distribution repo
Run as workflow — launch parallel subagents
Run a workflow to implement the plan at docs/plans/build-clean-plugin-dist.html — Publish a clean, stripped-down plugin distribution repo
build-clean-plugin-dist.html
docs/plans/build-clean-plugin-dist.html
Context
The agentics repo is both the development workspace and the install source. Its .claude-plugin/marketplace.json registers 12 active plugins via git-subdir sources whose url points at https://github.com/shawn-sandy/agentics.git. When a user installs, Claude Code pulls the plugin's path subtree — but the working repo carries a lot that has no business in an install: a 35 KB root README.md, docs/, examples/, scripts/, .playwright-mcp/, a session .png, CLAUDE.local.md, .DS_Store files, and assorted top-level markdown (ROADMAP.md, SECURITY.md, SOCIAL.md). Inside individual plugin dirs there can also be scratch notes that ship unintentionally.
The fix is a dedicated, clean distribution repo — one repo shaped exactly like the marketplace (not per-plugin repos) — generated from this source repo by a build script. The build reads marketplace.json plugins[] as the source of truth (so the six entries in removed[] and any reference-only directories never ship), copies only an allowlisted set of files per plugin, rewrites each source.url to point at the distribution repo, and publishes the result. A GitHub Action reruns the build and publishes on every release so the clean repo never drifts from source.
Decisions locked in clarification: keep rules = manifest + component dirs + README + CHANGELOG; shape = one marketplace-style repo like agentics-kit; automation = a build script plus a GitHub Action that publishes on release.
Superseded by publish-plugins-to-dist-repo-daily.html — the --publish implementation, GitHub Action, and dist repo setup described here were completed under that plan with a daily cron trigger instead of release-triggered.
Files
-
scripts/
- build-dist.mjs new
-
.github/workflows/
- publish-dist.yml new
- README.md modified add Distribution section: build command, strip rules, new install path
- CLAUDE.md modified add Distribution section
-
.claude/rules/
- marketplace.md modified note that source.url rewriting is handled by the build script, not hand-edited
-
dist/ generated
build output — not committed to source repo
- .claude-plugin/marketplace.json rewritten
- README.md generated
- LICENSE copied
- kit/plugins/<name>/ × 12 stripped
Build Pipeline
shawn-sandy/agentics
.github/workflows/publish-dist.yml
scripts/build-dist.mjs
dist/
shawn-sandy/agentics-kit
Per-plugin allowlist
- .claude-plugin/
- commands/
- skills/
- agents/
- hooks/
- hooks.json
- templates/
- README.md
- CHANGELOG.md
- LICENSE
- docs/
- *.local.md
- .DS_Store
- *.png
- .playwright-mcp/
- ROADMAP.md
- SECURITY.md
- SOCIAL.md
- examples/
- scripts/
- marketplace.json
- source.url → dist repo
- removed[] dropped
- README.md (slim)
- LICENSE (copied)
Steps
scripts/build-dist.mjs with config and a manifest-driven plugin list
merge-marketplace.mjs convention; no package.json, run via bare node) becomes the one entry point. Define an OUT_DIR (dist/), a DIST_REPO URL constant overridable via the DIST_REPO_URL env var, a KEEP allowlist (.claude-plugin, commands, skills, agents, hooks, hooks.json, templates, README.md, CHANGELOG.md, LICENSE), and a DROP denylist (docs, *.local.md, .DS_Store, *.png, .playwright-mcp). Enumerate plugins by reading marketplace.json plugins[] — never by globbing kit/plugins/*.Verify
node scripts/build-dist.mjs --list prints exactly the 12 active plugin names (memory-tools … issue-agent) and omits the 6 in removed[] (agent-creator, agent-reviewer, marketplace-builder, react-perf-analyzer, agentic-plugin-dev, code-simplifier).dist/
source.path (e.g. kit/plugins/plan-agent) and recursively copy only the KEEP top-level entries into dist/<path>/, pruning any .DS_Store encountered inside kept directories. Component dirs are copied wholesale so nested support files (e.g. skills/*/reference/, templates/) come along automatically. Start from a clean dist/ each run (delete and recreate) so stale files never linger.Verify
node scripts/build-dist.mjs, find dist/kit/plugins/plan-agent -type f lists the manifest, skills/, hooks/, hooks.json, templates/, README.md, and CHANGELOG.md — and shows no docs/, no *.local.md, no .DS_Store.marketplace.json plus slim root files
dist/.claude-plugin/marketplace.json derived from the source manifest: keep name (agentics-kit), version, owner, and every plugins[] entry, but rewrite each source.url to DIST_REPO (leaving source.path unchanged) and drop the removed[] array entirely. Generate a concise dist/README.md with the new install instructions and copy LICENSE to the dist root. Keep the JSON pretty-printed so the published manifest stays diffable.Verify
jq -r '.plugins[].source.url' dist/.claude-plugin/marketplace.json | sort -u returns only the distribution repo URL; jq '.removed' dist/.claude-plugin/marketplace.json is null; dist/README.md and dist/LICENSE exist.--check and --publish modes
--check walks the built dist/ tree and exits non-zero if any DROP pattern leaked through (a CI tripwire against accidental bloat). --publish syncs dist/ into a checkout of the distribution repo, commits with a message referencing the source commit SHA, and pushes — authenticating via a GITHUB_TOKEN env var first, falling back to a PAT (DIST_REPO_TOKEN) when set. Caveat: the default Actions GITHUB_TOKEN is scoped to the source repo and usually cannot push to a separate repo like agentics-kit; if the cross-repo push is denied, a fine-grained PAT with write on the dist repo is required (see Unresolved Questions). Publishing must clear the target working tree first so deleted plugins disappear downstream.Verify
node scripts/build-dist.mjs --check; echo $? prints 0. Temporarily drop a docs/ folder into the KEEP list, rebuild, rerun --check, and confirm it exits non-zero with a message naming the offending path; then revert..github/workflows/publish-dist.yml Action
release: { types: [published] } plus workflow_dispatch for manual reruns. Steps: checkout, actions/setup-node, node scripts/build-dist.mjs --check (fail fast on leakage), then node scripts/build-dist.mjs --publish with GITHUB_TOKEN wired in (and DIST_REPO_TOKEN as an optional override secret) and DIST_REPO_URL from a repo variable. Because the dist repo is separate, verify the token actually has cross-repo write during the first workflow_dispatch run — if the default GITHUB_TOKEN is rejected, switch the secret to a PAT. This keeps the clean repo in lockstep with releases without manual steps, mirroring the existing version-guard.yml/update-readme.yml patterns.Verify
actionlint .github/workflows/publish-dist.yml or a YAML lint) with no errors; a workflow_dispatch run from a test branch completes green and pushes a commit to the distribution repo.shawn-sandy/agentics-kit, set the DIST_REPO_URL variable on the source repo (and add a DIST_REPO_TOKEN PAT secret only if the default GITHUB_TOKEN can't push cross-repo), run the first publish manually, and document the build + install flow in README.md and CLAUDE.md (new "Distribution" section: how to run the build, what gets stripped, and the new /plugin marketplace add path). Note in .claude/rules/marketplace.md that source.url rewriting is handled by the build, not hand-edited.Verify
/plugin marketplace add shawn-sandy/agentics-kit then /plugin install plan-agent@agentics-kit installs successfully, and the installed tree contains no docs/, *.local.md, or other cruft.Acceptance Criteria
Verification
Run node scripts/build-dist.mjs locally and inspect the tree: find dist -type f | sort should show 12 plugin directories, each carrying only allowlisted files, plus a rewritten root marketplace.json, slim README.md, and LICENSE. Confirm jq reports a single distribution-repo source.url and a null removed. Run node scripts/build-dist.mjs --check and confirm exit code 0, then verify the leak tripwire by temporarily allowlisting docs and confirming a non-zero exit. Trigger the Action via workflow_dispatch and confirm it publishes a commit to the distribution repo. Finally, in a clean session, register shawn-sandy/agentics-kit and install plan-agent, then list the installed files to confirm zero cruft. The source agentics repo and its existing marketplace.json must remain unchanged except for the new script, workflow, and docs.
Completion Checklist
Completion Report
No items to report — all requirements met.
Unresolved Questions
-
Can the default GITHUB_TOKEN push to the separate agentics-kit repo?
Investigate whether a GitHub Actions workflow in shawn-sandy/agentics can push commits to a separate same-owner repo (shawn-sandy/agentics-kit) using only the default GITHUB_TOKEN. Confirm GitHub's current behavior for cross-repository writes with the default token, and if it cannot, recommend the minimal-privilege alternative (fine-grained PAT scoped to just agentics-kit contents:write, GitHub App installation token, or SSH deploy key) with the exact secret setup steps. Output a concrete recommendation for the publish-dist.yml workflow.