@vibe-agent-toolkit/vat-development-agents 0.1.20 → 0.1.21-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/.claude/plugins/marketplaces/vat-skills/.claude-plugin/marketplace.json +2 -2
  2. package/dist/.claude/plugins/marketplaces/vat-skills/plugins/{vat-development-agents → vibe-agent-toolkit}/.claude-plugin/plugin.json +1 -1
  3. package/dist/{skills/vibe-agent-toolkit__audit → .claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/audit}/SKILL.md +1 -1
  4. package/dist/{skills/vibe-agent-toolkit__agent-authoring → .claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/authoring}/SKILL.md +1 -1
  5. package/dist/{skills/vibe-agent-toolkit__debugging → .claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/debugging}/SKILL.md +1 -1
  6. package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/distribution/SKILL.md +335 -0
  7. package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/distribution/resources/vat-install-architecture.md +229 -0
  8. package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/install/SKILL.md +229 -0
  9. package/dist/.claude/plugins/marketplaces/vat-skills/plugins/{vat-development-agents/skills/vibe-agent-toolkit__resources → vibe-agent-toolkit/skills/resources}/SKILL.md +1 -1
  10. package/dist/.claude/plugins/marketplaces/vat-skills/plugins/{vat-development-agents → vibe-agent-toolkit}/skills/vibe-agent-toolkit/SKILL.md +10 -9
  11. package/dist/generated/resources/skills/SKILL.js +5 -5
  12. package/dist/generated/resources/skills/vat-agent-authoring.js +1 -1
  13. package/dist/generated/resources/skills/vat-audit.js +1 -1
  14. package/dist/generated/resources/skills/vat-debugging.js +1 -1
  15. package/dist/generated/resources/skills/vat-install-architecture.d.ts +28 -0
  16. package/dist/generated/resources/skills/vat-install-architecture.js +48 -0
  17. package/dist/generated/resources/skills/vat-resources.js +1 -1
  18. package/dist/generated/resources/skills/vat-skills-distribution.d.ts +3 -0
  19. package/dist/generated/resources/skills/vat-skills-distribution.js +27 -12
  20. package/dist/{.claude/plugins/marketplaces/vat-skills/plugins/vat-development-agents/skills/vibe-agent-toolkit__audit → skills/audit}/SKILL.md +1 -1
  21. package/dist/{.claude/plugins/marketplaces/vat-skills/plugins/vat-development-agents/skills/vibe-agent-toolkit__agent-authoring → skills/authoring}/SKILL.md +1 -1
  22. package/dist/{.claude/plugins/marketplaces/vat-skills/plugins/vat-development-agents/skills/vibe-agent-toolkit__debugging → skills/debugging}/SKILL.md +1 -1
  23. package/dist/skills/distribution/SKILL.md +335 -0
  24. package/dist/skills/distribution/resources/vat-install-architecture.md +229 -0
  25. package/dist/skills/install/SKILL.md +229 -0
  26. package/dist/skills/{vibe-agent-toolkit__resources → resources}/SKILL.md +1 -1
  27. package/dist/skills/vibe-agent-toolkit/SKILL.md +10 -9
  28. package/package.json +19 -9
  29. package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vat-development-agents/skills/vibe-agent-toolkit__skills-distribution/SKILL.md +0 -228
  30. package/dist/skills/vibe-agent-toolkit__skills-distribution/SKILL.md +0 -228
  31. /package/dist/.claude/plugins/marketplaces/vat-skills/plugins/{vat-development-agents/skills/vibe-agent-toolkit → vibe-agent-toolkit/skills/authoring}/resources/agent-authoring.md +0 -0
  32. /package/dist/.claude/plugins/marketplaces/vat-skills/plugins/{vat-development-agents/skills/vibe-agent-toolkit → vibe-agent-toolkit/skills/authoring}/resources/orchestration.md +0 -0
  33. /package/dist/.claude/plugins/marketplaces/vat-skills/plugins/{vat-development-agents/skills/vibe-agent-toolkit__debugging → vibe-agent-toolkit/skills/debugging}/resources/CLAUDE.md +0 -0
  34. /package/dist/.claude/plugins/marketplaces/vat-skills/plugins/{vat-development-agents/skills/vibe-agent-toolkit__debugging → vibe-agent-toolkit/skills/debugging}/resources/debug-and-test-vat-fixes.md +0 -0
  35. /package/dist/.claude/plugins/marketplaces/vat-skills/plugins/{vat-development-agents/skills/vibe-agent-toolkit__debugging → vibe-agent-toolkit/skills/debugging}/resources/writing-tests.md +0 -0
  36. /package/dist/.claude/plugins/marketplaces/vat-skills/plugins/{vat-development-agents → vibe-agent-toolkit}/skills/vibe-agent-toolkit/resources/adding-runtime-adapters.md +0 -0
  37. /package/dist/.claude/plugins/marketplaces/vat-skills/plugins/{vat-development-agents/skills/vibe-agent-toolkit__agent-authoring → vibe-agent-toolkit/skills/vibe-agent-toolkit}/resources/agent-authoring.md +0 -0
  38. /package/dist/.claude/plugins/marketplaces/vat-skills/plugins/{vat-development-agents → vibe-agent-toolkit}/skills/vibe-agent-toolkit/resources/compiling-markdown-to-typescript.md +0 -0
  39. /package/dist/.claude/plugins/marketplaces/vat-skills/plugins/{vat-development-agents → vibe-agent-toolkit}/skills/vibe-agent-toolkit/resources/getting-started.md +0 -0
  40. /package/dist/.claude/plugins/marketplaces/vat-skills/plugins/{vat-development-agents/skills/vibe-agent-toolkit__agent-authoring → vibe-agent-toolkit/skills/vibe-agent-toolkit}/resources/orchestration.md +0 -0
  41. /package/dist/.claude/plugins/marketplaces/vat-skills/plugins/{vat-development-agents → vibe-agent-toolkit}/skills/vibe-agent-toolkit/resources/rag-usage-guide.md +0 -0
  42. /package/dist/skills/{vibe-agent-toolkit__agent-authoring → authoring}/resources/agent-authoring.md +0 -0
  43. /package/dist/skills/{vibe-agent-toolkit__agent-authoring → authoring}/resources/orchestration.md +0 -0
  44. /package/dist/skills/{vibe-agent-toolkit__debugging → debugging}/resources/CLAUDE.md +0 -0
  45. /package/dist/skills/{vibe-agent-toolkit__debugging → debugging}/resources/debug-and-test-vat-fixes.md +0 -0
  46. /package/dist/skills/{vibe-agent-toolkit__debugging → debugging}/resources/writing-tests.md +0 -0
@@ -3,17 +3,22 @@
3
3
  */
4
4
 
5
5
  export const meta = {
6
- name: "vibe-agent-toolkit:skills-distribution",
6
+ name: "distribution",
7
7
  description: "Use when setting up vat build, configuring plugin distribution for the Claude ecosystem (marketplace, plugins, managed settings), npm publishing with postinstall hooks, or vat verify orchestration. Covers the full pipeline from skill source to installed plugin."
8
8
  };
9
9
 
10
- export const text = "\n# VAT Distribution: Build, Publish & Install\n\n## Overview\n\nVAT distributes skills as **Claude plugins** via npm packages. The pipeline:\n\n1. \`vat build\` compiles SKILL.md sources into plugin artifacts\n2. \`npm publish\` pushes the package to a registry\n3. \`npm install\` triggers a postinstall hook that registers the plugin in Claude\'s plugin system\n\nSkills installed this way appear in Claude Code as \`/plugin-name:skill-name\`.\n\n## Project Structure\n\n\`\`\`\nmy-project/\n├── package.json ← vat.skills + postinstall hook + publishConfig\n├── vibe-agent-toolkit.config.yaml ← skills: + claude: config\n├── resources/\n│ └── skills/\n│ └── SKILL.md\n└── dist/ ← generated by vat build\n ├── skills/my-skill/ ← packaged skill\n └── .claude/plugins/marketplaces/\n └── my-marketplace/plugins/my-plugin/\n ├── .claude-plugin/plugin.json\n └── skills/my-skill/SKILL.md\n\`\`\`\n\n## Step 1: package.json Configuration\n\n\`\`\`json\n{\n \"name\": \"@myorg/my-skills\",\n \"version\": \"1.0.0\",\n \"vat\": {\n \"version\": \"1.0\",\n \"skills\": [\"my-skill\"]\n },\n \"scripts\": {\n \"build:vat\": \"vat build\",\n \"postinstall\": \"vat skills install --npm-postinstall || exit 0\"\n },\n \"files\": [\"dist\", \"README.md\"],\n \"publishConfig\": {\n \"registry\": \"https://registry.npmjs.org\"\n }\n}\n\`\`\`\n\nThe \`vat.skills\` array contains skill name strings for npm discoverability. Skill source paths and packaging config live in \`vibe-agent-toolkit.config.yaml\` (see Step 2).\n\nFor private GitHub Packages registry:\n\`\`\`json\n\"publishConfig\": {\n \"registry\": \"https://npm.pkg.github.com\",\n \"access\": \"restricted\"\n}\n\`\`\`\n\nUsers installing from GitHub Packages need \`.npmrc\` with the scope registry and auth token:\n\`\`\`\n@myorg:registry=https://npm.pkg.github.com\n//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}\n\`\`\`\n\n## Step 2: vibe-agent-toolkit.config.yaml\n\n\`\`\`yaml\nversion: 1\n\nskills:\n include:\n - \"resources/skills/**/SKILL.md\"\n\nclaude:\n marketplaces:\n my-marketplace: # org/publisher identity\n owner:\n name: My Organization\n plugins:\n - name: my-plugin # installable unit\n description: My plugin description\n skills: \"*\" # all discovered skills\n\`\`\`\n\nThe \`skills:\` section discovers SKILL.md files via include/exclude globs. The \`claude:\` section defines how skills are packaged into plugins. Each marketplace has \`owner\` and \`plugins\` fields (strict schema — no extra fields).\n\n**Naming convention:** marketplace = org identity (e.g. \`acme\`), plugin = this package\n(e.g. \`acme-tools\`). Registers as \`my-plugin@my-marketplace\` in Claude\'s plugin registry.\n\n### Multiple skills in one package\n\nList all skills in \`vat.skills\` for npm discoverability:\n\n\`\`\`json\n\"vat\": {\n \"version\": \"1.0\",\n \"skills\": [\"my-linting\", \"my-testing\"]\n}\n\`\`\`\n\nUse a selector in the plugin config to include matching skills:\n\n\`\`\`yaml\nplugins:\n - name: my-plugin\n description: Linting and testing skills\n skills:\n - \"my-linting\"\n - \"my-testing\"\n\`\`\`\n\nOr use \`\"*\"\` to include all discovered skills in the plugin.\n\n## Step 3: Build\n\n\`\`\`bash\nvat build # skills phase then claude phase\nvat verify # validates resources + skills + claude artifacts\n\`\`\`\n\n### What vat build does\n\nTwo phases, run in dependency order:\n\n1. **\`vat skills build\`** — reads \`vibe-agent-toolkit.config.yaml skills:\` section, discovers SKILL.md files via include/exclude globs, compiles each into \`dist/skills/<name>/\`\n2. **\`vat claude build\`** — reads \`vibe-agent-toolkit.config.yaml claude:\` section, wraps built skills into \`dist/.claude/plugins/marketplaces/<mp>/plugins/<plugin>/\` structure with \`.claude-plugin/plugin.json\`\n\nIndividual commands still work:\n\`\`\`bash\nvat skills build # skills phase only\nvat claude build # claude plugin phase only (requires skills already built)\nvat claude verify # validate plugin artifacts only\n\`\`\`\n\n## Step 4: Publish\n\n\`\`\`bash\nnpm publish --tag next # RC/pre-release\nnpm publish # stable release\n\`\`\`\n\n## Step 5: User Install\n\n\`\`\`bash\nvat skills install npm:@myorg/my-skills\n\`\`\`\n\nOr via standard npm install (postinstall hook triggers automatically):\n\`\`\`bash\nnpm install -g @myorg/my-skills\n\`\`\`\n\n### How plugin installation works\n\nWhen \`npm install\` runs the postinstall hook (\`vat skills install --npm-postinstall\`):\n\n- VAT detects \`dist/.claude/plugins/marketplaces/\` directory in the installed package\n- Copies the plugin tree to Claude\'s plugin directory (dumb recursive copy)\n- Writes to these locations:\n 1. \`~/.claude/plugins/marketplaces/<marketplace>/plugins/<plugin>/\` — plugin files\n 2. \`~/.claude/plugins/known_marketplaces.json\` — marketplace registry\n 3. \`~/.claude/plugins/cache/<marketplace>/<plugin>/<version>/\` — version cache\n 4. \`~/.claude/plugins/installed_plugins.json\` — installation record\n 5. \`~/.claude/settings.json\` \`enabledPlugins\` — activates the plugin\n\nIf no \`dist/.claude/plugins/marketplaces/\` directory exists (package wasn\'t built before publish): a guidance message is emitted and the hook exits 0. The publisher must run \`vat build\` and re-publish.\n\nSkills are then available in Claude Code as \`/plugin-name:skill-name\`.\n\n## managed-settings.json Validation (Enterprise)\n\n\`\`\`yaml\nclaude:\n managedSettings: managed-settings.json\n\`\`\`\n\n\`vat verify\` validates this file against the ManagedSettings schema. Catches typos and schema errors before deployment. Does NOT deploy the file — deployment is a separate concern.\n\n## --target claude-web (ZIP Upload)\n\nFor uploading skills directly to \`claude.ai/settings/capabilities\`:\n\n\`\`\`bash\nvat skills package ./SKILL.md -o ./dist/ --target claude-web\n\`\`\`\n\nProduces a ZIP:\n\`\`\`\nmy-skill.zip\n└── my-skill/\n ├── SKILL.md # skill definition (required)\n ├── scripts/ # executable code (.mjs, .py, .sh) — optional\n ├── references/ # markdown reference material — optional\n └── assets/ # static data, templates, config — optional\n\`\`\`\n\nConfigure source path mappings in \`vibe-agent-toolkit.config.yaml\`:\n\`\`\`yaml\nskills:\n include:\n - \"skills/**/SKILL.md\"\n config:\n my-skill:\n claudeWebTarget:\n scripts: [\"./src/helpers/**/*.ts\"]\n assets: [\"./assets/**\"]\n\`\`\`\n\nTypeScript files in \`scripts\` are tree-shaken and compiled to standalone \`.mjs\`.\n\n## Quick Reference\n\n| Task | Command |\n|---|---|\n| Build everything | \`vat build\` |\n| Verify everything | \`vat verify\` |\n| Build skills only | \`vat skills build\` |\n| Build claude artifacts only | \`vat claude build\` |\n| Verify claude artifacts only | \`vat claude verify\` |\n| Install from npm | \`vat skills install npm:@org/pkg\` |\n| Package for claude.ai upload | \`vat skills package ./SKILL.md -o ./dist/ --target claude-web\` |\n";
10
+ export const text = "\n# VAT Distribution: Build, Publish & Install\n\n## Scope\n\nThis skill covers the **file-based install method for Claude Code CLI** (\`~/.claude/plugins/\`).\nThis is the only install method VAT currently supports.\n\nFor the full install landscape — Claude Desktop paths, enterprise CI deployment,\nAnthropic Cloud org management, MDM integration, and the \`vat plugins uninstall\`\ndesign — see [Install & Uninstall Architecture](vat-install-architecture.md).\n\n## Overview\n\nVAT distributes skills as **Claude plugins** via npm packages. The pipeline:\n\n1. \`vat build\` compiles SKILL.md sources into plugin artifacts\n2. \`npm publish\` pushes the package to a registry\n3. \`npm install\` triggers a postinstall hook that registers the plugin in Claude Code\'s plugin system\n\nSkills installed this way appear in Claude Code as \`/plugin-name:skill-name\`.\n\n## Project Structure\n\n\`\`\`\nmy-project/\n├── package.json ← vat.skills + postinstall hook + publishConfig\n├── vibe-agent-toolkit.config.yaml ← skills: + claude: config\n├── resources/\n│ └── skills/\n│ └── SKILL.md\n└── dist/ ← generated by vat build\n ├── skills/my-skill/ ← packaged skill\n └── .claude/plugins/marketplaces/\n └── my-marketplace/plugins/my-plugin/\n ├── .claude-plugin/plugin.json\n └── skills/my-skill/SKILL.md\n\`\`\`\n\n## Step 1: package.json Configuration\n\n\`\`\`json\n{\n \"name\": \"@myorg/my-skills\",\n \"version\": \"1.0.0\",\n \"vat\": {\n \"version\": \"1.0\",\n \"skills\": [\"my-skill\"]\n },\n \"dependencies\": {\n \"vibe-agent-toolkit\": \"latest\"\n },\n \"scripts\": {\n \"build:vat\": \"vat build\",\n \"postinstall\": \"node ./node_modules/vibe-agent-toolkit/dist/bin/vat.js claude plugin install --npm-postinstall 2>/dev/null || exit 0\"\n },\n \"files\": [\"dist\", \"README.md\"],\n \"publishConfig\": {\n \"registry\": \"https://registry.npmjs.org\"\n }\n}\n\`\`\`\n\n**\`vibe-agent-toolkit\` must be in \`dependencies\` (not \`devDependencies\`)** so it is present in \`node_modules\` when the postinstall hook runs on the user\'s machine. Never assume \`vat\` is available globally — your users may not be developers.\n\nThe \`vat.skills\` array contains skill name strings for npm discoverability. Skill source paths and packaging config live in \`vibe-agent-toolkit.config.yaml\` (see Step 2).\n\nFor private GitHub Packages registry:\n\`\`\`json\n\"publishConfig\": {\n \"registry\": \"https://npm.pkg.github.com\",\n \"access\": \"restricted\"\n}\n\`\`\`\n\nUsers (or IT) installing from GitHub Packages need \`.npmrc\` configured with the scope registry and a read-only token:\n\`\`\`\n@myorg:registry=https://npm.pkg.github.com\n//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}\n\`\`\`\n\nIT deploying to managed machines should pre-configure \`.npmrc\` at the system or user level before running install commands. End users do not need to understand npm or the registry — IT handles it once.\n\n## Handling Plugin Renames: vat.replaces\n\n> **Use this only when renaming a plugin, merging plugins, or cleaning up legacy flat-skill installs. Normal upgrades (same plugin name, same skills) do NOT need \`vat.replaces\` — the installer already overwrites the plugin directory on every install.**\n\n### The problem: silent stale skills\n\nWhen you rename a plugin or reorganize skills across packages, the old registration remains in Claude Code. Claude Code **does not warn you** when two plugins provide conflicting skill names — the first-registered (stale) skill silently wins. Users continue loading old content from the renamed plugin unless the old registration is explicitly removed.\n\nThis is the scenario where \`vat.replaces\` is needed:\n- Plugin renamed: \`old-plugin-name\` → \`new-plugin-name\`\n- Two old plugins merged into one new plugin\n- Skills previously installed to \`~/.claude/skills/<name>\` (legacy pre-0.1.20 flat install) now delivered via the plugin tree\n\n### How it works\n\nWhen a VAT package is installed (via postinstall hook or \`--dev\`), the installer reads \`vat.replaces\` from \`package.json\` and — **before** installing the new plugin:\n\n1. For each name in \`replaces.plugins\`: uninstalls \`<name>@<marketplace>\` — removes plugin directory, cache entry, registry entry, and \`settings.json\` entry\n2. For each name in \`replaces.flatSkills\`: deletes \`~/.claude/skills/<name>\` — removes legacy pre-0.1.20 flat installs\n\nBoth operations are idempotent — \"not found\" is handled gracefully.\n\n### Schema\n\n\`\`\`json\n\"vat\": {\n \"version\": \"1.0\",\n \"skills\": [\"authoring\", \"audit\"],\n \"replaces\": {\n \"plugins\": [\"my-old-plugin-name\"],\n \"flatSkills\": [\"my-old-skill\", \"another-old-skill\"]\n }\n}\n\`\`\`\n\nBoth \`plugins\` and \`flatSkills\` are optional arrays. The entire \`replaces\` key is optional — omit it when there is nothing to clean up.\n\n### Real example: vat-development-agents 0.1.21\n\nThis package (\`vat-development-agents\`) renamed its plugin from \`vat-development-agents\` to \`vibe-agent-toolkit\` in v0.1.21. Without \`vat.replaces\`, users who had already installed v0.1.20 would have both \`vat-development-agents@vat-skills\` and \`vibe-agent-toolkit@vat-skills\` registered — Claude Code would serve stale skill content from the old plugin.\n\nThe fix in \`package.json\`:\n\n\`\`\`json\n\"vat\": {\n \"version\": \"1.0\",\n \"skills\": [\"vibe-agent-toolkit\", \"resources\", \"distribution\", \"authoring\", \"audit\", \"debugging\", \"install\"],\n \"replaces\": {\n \"plugins\": [\"vat-development-agents\"],\n \"flatSkills\": [\"vibe-agent-toolkit\", \"resources\"]\n }\n}\n\`\`\`\n\n- \`plugins\`: removes the old plugin registration (same marketplace, old plugin name)\n- \`flatSkills\`: removes legacy \`~/.claude/skills/vibe-agent-toolkit\` and \`~/.claude/skills/resources\` entries from users who installed before 0.1.20 switched to the plugin tree\n\n### Non-obvious gotchas\n\n**1. Plugin names in \`replaces.plugins\` have NO \`@marketplace\`**\n\nThe format is just the plugin name — e.g. \`\"vat-development-agents\"\` — NOT \`\"vat-development-agents@vat-skills\"\`. The installer infers the marketplace from the current package\'s dist tree. Using \`@marketplace\` syntax here would be wrong.\n\n**2. \`replaces.plugins\` is for old plugin registrations, not for skills that moved between plugins**\n\nIf a skill moved from \`plugin-a\` to \`plugin-b\` within the same marketplace, list \`\"plugin-a\"\` in \`replaces.plugins\` to clean up the entire old plugin. You do not manage individual skills — you manage plugins.\n\n**3. \`replaces.flatSkills\` is ONLY for the legacy \`~/.claude/skills/\` location**\n\nThis is specifically for skills that were previously installed as flat files to \`~/.claude/skills/<name>\` (pre-plugin-tree, before v0.1.20). Skills within the plugin tree (under \`~/.claude/plugins/\`) are handled via \`replaces.plugins\`. Do not mix them up.\n\n**4. Normal upgrades need nothing**\n\nIf you publish a new version of the same package with the same plugin name, the installer overwrites the plugin directory automatically. \`vat.replaces\` is only for the case where the old name is different from the new name.\n\n**5. The symptom is subtle and delayed**\n\nYou will not see an error. Claude Code simply loads the first-registered skill with a given name. If the stale plugin is registered first (alphabetically or by install order), your new content is invisible until you remove the old registration.\n\n## Step 2: vibe-agent-toolkit.config.yaml\n\n\`\`\`yaml\nversion: 1\n\nskills:\n include:\n - \"resources/skills/**/SKILL.md\"\n\nclaude:\n marketplaces:\n my-marketplace: # org/publisher identity\n owner:\n name: My Organization\n plugins:\n - name: my-plugin # installable unit\n description: My plugin description\n skills: \"*\" # all discovered skills\n\`\`\`\n\nThe \`skills:\` section discovers SKILL.md files via include/exclude globs. The \`claude:\` section defines how skills are packaged into plugins. Each marketplace has \`owner\` and \`plugins\` fields (strict schema — no extra fields).\n\n**Naming convention:** marketplace = org identity (e.g. \`acme\`), plugin = this package\n(e.g. \`acme-tools\`). Registers as \`my-plugin@my-marketplace\` in Claude\'s plugin registry.\n\n### Multiple skills in one package\n\nList all skills in \`vat.skills\` for npm discoverability:\n\n\`\`\`json\n\"vat\": {\n \"version\": \"1.0\",\n \"skills\": [\"my-linting\", \"my-testing\"]\n}\n\`\`\`\n\nUse a selector in the plugin config to include matching skills:\n\n\`\`\`yaml\nplugins:\n - name: my-plugin\n description: Linting and testing skills\n skills:\n - \"my-linting\"\n - \"my-testing\"\n\`\`\`\n\nOr use \`\"*\"\` to include all discovered skills in the plugin.\n\n## Step 3: Build\n\n\`\`\`bash\nvat build # skills phase then claude phase\nvat verify # validates resources + skills + claude artifacts\n\`\`\`\n\n### What vat build does\n\nTwo phases, run in dependency order:\n\n1. **\`vat skills build\`** — reads \`vibe-agent-toolkit.config.yaml skills:\` section, discovers SKILL.md files via include/exclude globs, compiles each into \`dist/skills/<name>/\`\n2. **\`vat claude plugin build\`** — reads \`vibe-agent-toolkit.config.yaml claude:\` section, wraps built skills into \`dist/.claude/plugins/marketplaces/<mp>/plugins/<plugin>/\` structure with \`.claude-plugin/plugin.json\`. Cleans stale output before each build.\n\nIndividual commands still work:\n\`\`\`bash\nvat skills build # skills phase only\nvat claude plugin build # claude plugin phase only (requires skills already built)\n\`\`\`\n\n## Step 4: Publish\n\n\`\`\`bash\nnpm publish --tag next # RC/pre-release\nnpm publish # stable release\n\`\`\`\n\n## Step 5: User Install\n\n### Recommended: npm global install (postinstall runs automatically)\n\n\`\`\`bash\nnpm install -g @myorg/my-skills\n\`\`\`\n\nThe postinstall hook fires automatically and registers the plugin in Claude. This is the correct path for IT-managed deployments — no other tools required on the user\'s machine.\n\n### Developer/IT one-off install via npx\n\n\`\`\`bash\nnpx vibe-agent-toolkit claude plugin install npm:@myorg/my-skills\n\`\`\`\n\nDownloads and runs VAT via npx to install a package without a global install. Useful for CI, scripting, or testing from a developer machine. Requires the npm scope registry to be configured (\`.npmrc\`) if installing from a private registry.\n\n### How plugin installation works\n\nWhen \`npm install\` runs the postinstall hook (\`node ./node_modules/vibe-agent-toolkit/dist/bin/vat.js claude plugin install --npm-postinstall\`):\n\n- VAT detects \`dist/.claude/plugins/marketplaces/\` directory in the installed package\n- Copies the plugin tree to Claude\'s plugin directory (dumb recursive copy)\n- Writes to these locations:\n 1. \`~/.claude/plugins/marketplaces/<marketplace>/plugins/<plugin>/\` — plugin files\n 2. \`~/.claude/plugins/known_marketplaces.json\` — marketplace registry\n 3. \`~/.claude/plugins/cache/<marketplace>/<plugin>/<version>/\` — version cache\n 4. \`~/.claude/plugins/installed_plugins.json\` — installation record\n 5. \`~/.claude/settings.json\` \`enabledPlugins\` — activates the plugin\n\nIf no \`dist/.claude/plugins/marketplaces/\` directory exists (package wasn\'t built before publish): a guidance message is emitted and the hook exits 0. The publisher must run \`vat build\` and re-publish.\n\nSkills are then available in Claude Code as \`/plugin-name:skill-name\`.\n\n## managed-settings.json Validation (Enterprise)\n\n\`\`\`yaml\nclaude:\n managedSettings: managed-settings.json\n\`\`\`\n\n\`vat verify\` validates this file against the ManagedSettings schema. Catches typos and schema errors before deployment. Does NOT deploy the file — deployment is a separate concern.\n\n## --target claude-web (ZIP Upload)\n\nFor uploading skills directly to \`claude.ai/settings/capabilities\`:\n\n\`\`\`bash\nvat skills package ./SKILL.md -o ./dist/ --target claude-web\n\`\`\`\n\nProduces a ZIP:\n\`\`\`\nmy-skill.zip\n└── my-skill/\n ├── SKILL.md # skill definition (required)\n ├── scripts/ # executable code (.mjs, .py, .sh) — optional\n ├── references/ # markdown reference material — optional\n └── assets/ # static data, templates, config — optional\n\`\`\`\n\nConfigure source path mappings in \`vibe-agent-toolkit.config.yaml\`:\n\`\`\`yaml\nskills:\n include:\n - \"skills/**/SKILL.md\"\n config:\n my-skill:\n claudeWebTarget:\n scripts: [\"./src/helpers/**/*.ts\"]\n assets: [\"./assets/**\"]\n\`\`\`\n\nTypeScript files in \`scripts\` are tree-shaken and compiled to standalone \`.mjs\`.\n\n## Quick Reference\n\n| Task | Command |\n|---|---|\n| Build everything | \`vat build\` |\n| Verify everything | \`vat verify\` |\n| Build skills only | \`vat skills build\` |\n| Build claude plugin artifacts only | \`vat claude plugin build\` |\n| Install via npm (end user) | \`npm install -g @org/pkg\` |\n| Install via npx (developer/IT) | \`npx vibe-agent-toolkit claude plugin install npm:@org/pkg\` |\n| List installed plugins | \`vat claude plugin list\` |\n| Uninstall a plugin | \`vat claude plugin uninstall --all\` |\n| Package for claude.ai upload | \`vat skills package ./SKILL.md -o ./dist/ --target claude-web\` |\n\n## Future: Zero-Dependency Postinstall (Option B)\n\nA planned improvement: \`vat build\` would bundle the plugin install logic into \`dist/postinstall.js\` — a fully self-contained script with no npm dependencies. The postinstall script would become simply \`node ./dist/postinstall.js\`. This eliminates \`vibe-agent-toolkit\` as a runtime dependency entirely, reducing install footprint for end users. Until then, Option C (runtime \`vibe-agent-toolkit\` dep) is the correct approach.\n";
11
11
 
12
12
  export const fragments = {
13
+ scope: {
14
+ header: "## Scope",
15
+ body: "This skill covers the **file-based install method for Claude Code CLI** (\`~/.claude/plugins/\`).\nThis is the only install method VAT currently supports.\n\nFor the full install landscape — Claude Desktop paths, enterprise CI deployment,\nAnthropic Cloud org management, MDM integration, and the \`vat plugins uninstall\`\ndesign — see [Install & Uninstall Architecture](vat-install-architecture.md).",
16
+ text: "## Scope\n\nThis skill covers the **file-based install method for Claude Code CLI** (\`~/.claude/plugins/\`).\nThis is the only install method VAT currently supports.\n\nFor the full install landscape — Claude Desktop paths, enterprise CI deployment,\nAnthropic Cloud org management, MDM integration, and the \`vat plugins uninstall\`\ndesign — see [Install & Uninstall Architecture](vat-install-architecture.md)."
17
+ },
13
18
  overview: {
14
19
  header: "## Overview",
15
- body: "VAT distributes skills as **Claude plugins** via npm packages. The pipeline:\n\n1. \`vat build\` compiles SKILL.md sources into plugin artifacts\n2. \`npm publish\` pushes the package to a registry\n3. \`npm install\` triggers a postinstall hook that registers the plugin in Claude\'s plugin system\n\nSkills installed this way appear in Claude Code as \`/plugin-name:skill-name\`.",
16
- text: "## Overview\n\nVAT distributes skills as **Claude plugins** via npm packages. The pipeline:\n\n1. \`vat build\` compiles SKILL.md sources into plugin artifacts\n2. \`npm publish\` pushes the package to a registry\n3. \`npm install\` triggers a postinstall hook that registers the plugin in Claude\'s plugin system\n\nSkills installed this way appear in Claude Code as \`/plugin-name:skill-name\`."
20
+ body: "VAT distributes skills as **Claude plugins** via npm packages. The pipeline:\n\n1. \`vat build\` compiles SKILL.md sources into plugin artifacts\n2. \`npm publish\` pushes the package to a registry\n3. \`npm install\` triggers a postinstall hook that registers the plugin in Claude Code\'s plugin system\n\nSkills installed this way appear in Claude Code as \`/plugin-name:skill-name\`.",
21
+ text: "## Overview\n\nVAT distributes skills as **Claude plugins** via npm packages. The pipeline:\n\n1. \`vat build\` compiles SKILL.md sources into plugin artifacts\n2. \`npm publish\` pushes the package to a registry\n3. \`npm install\` triggers a postinstall hook that registers the plugin in Claude Code\'s plugin system\n\nSkills installed this way appear in Claude Code as \`/plugin-name:skill-name\`."
17
22
  },
18
23
  projectStructure: {
19
24
  header: "## Project Structure",
@@ -22,8 +27,13 @@ export const fragments = {
22
27
  },
23
28
  step1PackagejsonConfiguration: {
24
29
  header: "## Step 1: package.json Configuration",
25
- body: "\`\`\`json\n{\n \"name\": \"@myorg/my-skills\",\n \"version\": \"1.0.0\",\n \"vat\": {\n \"version\": \"1.0\",\n \"skills\": [\"my-skill\"]\n },\n \"scripts\": {\n \"build:vat\": \"vat build\",\n \"postinstall\": \"vat skills install --npm-postinstall || exit 0\"\n },\n \"files\": [\"dist\", \"README.md\"],\n \"publishConfig\": {\n \"registry\": \"https://registry.npmjs.org\"\n }\n}\n\`\`\`\n\nThe \`vat.skills\` array contains skill name strings for npm discoverability. Skill source paths and packaging config live in \`vibe-agent-toolkit.config.yaml\` (see Step 2).\n\nFor private GitHub Packages registry:\n\`\`\`json\n\"publishConfig\": {\n \"registry\": \"https://npm.pkg.github.com\",\n \"access\": \"restricted\"\n}\n\`\`\`\n\nUsers installing from GitHub Packages need \`.npmrc\` with the scope registry and auth token:\n\`\`\`\n@myorg:registry=https://npm.pkg.github.com\n//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}\n\`\`\`",
26
- text: "## Step 1: package.json Configuration\n\n\`\`\`json\n{\n \"name\": \"@myorg/my-skills\",\n \"version\": \"1.0.0\",\n \"vat\": {\n \"version\": \"1.0\",\n \"skills\": [\"my-skill\"]\n },\n \"scripts\": {\n \"build:vat\": \"vat build\",\n \"postinstall\": \"vat skills install --npm-postinstall || exit 0\"\n },\n \"files\": [\"dist\", \"README.md\"],\n \"publishConfig\": {\n \"registry\": \"https://registry.npmjs.org\"\n }\n}\n\`\`\`\n\nThe \`vat.skills\` array contains skill name strings for npm discoverability. Skill source paths and packaging config live in \`vibe-agent-toolkit.config.yaml\` (see Step 2).\n\nFor private GitHub Packages registry:\n\`\`\`json\n\"publishConfig\": {\n \"registry\": \"https://npm.pkg.github.com\",\n \"access\": \"restricted\"\n}\n\`\`\`\n\nUsers installing from GitHub Packages need \`.npmrc\` with the scope registry and auth token:\n\`\`\`\n@myorg:registry=https://npm.pkg.github.com\n//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}\n\`\`\`"
30
+ body: "\`\`\`json\n{\n \"name\": \"@myorg/my-skills\",\n \"version\": \"1.0.0\",\n \"vat\": {\n \"version\": \"1.0\",\n \"skills\": [\"my-skill\"]\n },\n \"dependencies\": {\n \"vibe-agent-toolkit\": \"latest\"\n },\n \"scripts\": {\n \"build:vat\": \"vat build\",\n \"postinstall\": \"node ./node_modules/vibe-agent-toolkit/dist/bin/vat.js claude plugin install --npm-postinstall 2>/dev/null || exit 0\"\n },\n \"files\": [\"dist\", \"README.md\"],\n \"publishConfig\": {\n \"registry\": \"https://registry.npmjs.org\"\n }\n}\n\`\`\`\n\n**\`vibe-agent-toolkit\` must be in \`dependencies\` (not \`devDependencies\`)** so it is present in \`node_modules\` when the postinstall hook runs on the user\'s machine. Never assume \`vat\` is available globally — your users may not be developers.\n\nThe \`vat.skills\` array contains skill name strings for npm discoverability. Skill source paths and packaging config live in \`vibe-agent-toolkit.config.yaml\` (see Step 2).\n\nFor private GitHub Packages registry:\n\`\`\`json\n\"publishConfig\": {\n \"registry\": \"https://npm.pkg.github.com\",\n \"access\": \"restricted\"\n}\n\`\`\`\n\nUsers (or IT) installing from GitHub Packages need \`.npmrc\` configured with the scope registry and a read-only token:\n\`\`\`\n@myorg:registry=https://npm.pkg.github.com\n//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}\n\`\`\`\n\nIT deploying to managed machines should pre-configure \`.npmrc\` at the system or user level before running install commands. End users do not need to understand npm or the registry — IT handles it once.",
31
+ text: "## Step 1: package.json Configuration\n\n\`\`\`json\n{\n \"name\": \"@myorg/my-skills\",\n \"version\": \"1.0.0\",\n \"vat\": {\n \"version\": \"1.0\",\n \"skills\": [\"my-skill\"]\n },\n \"dependencies\": {\n \"vibe-agent-toolkit\": \"latest\"\n },\n \"scripts\": {\n \"build:vat\": \"vat build\",\n \"postinstall\": \"node ./node_modules/vibe-agent-toolkit/dist/bin/vat.js claude plugin install --npm-postinstall 2>/dev/null || exit 0\"\n },\n \"files\": [\"dist\", \"README.md\"],\n \"publishConfig\": {\n \"registry\": \"https://registry.npmjs.org\"\n }\n}\n\`\`\`\n\n**\`vibe-agent-toolkit\` must be in \`dependencies\` (not \`devDependencies\`)** so it is present in \`node_modules\` when the postinstall hook runs on the user\'s machine. Never assume \`vat\` is available globally — your users may not be developers.\n\nThe \`vat.skills\` array contains skill name strings for npm discoverability. Skill source paths and packaging config live in \`vibe-agent-toolkit.config.yaml\` (see Step 2).\n\nFor private GitHub Packages registry:\n\`\`\`json\n\"publishConfig\": {\n \"registry\": \"https://npm.pkg.github.com\",\n \"access\": \"restricted\"\n}\n\`\`\`\n\nUsers (or IT) installing from GitHub Packages need \`.npmrc\` configured with the scope registry and a read-only token:\n\`\`\`\n@myorg:registry=https://npm.pkg.github.com\n//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}\n\`\`\`\n\nIT deploying to managed machines should pre-configure \`.npmrc\` at the system or user level before running install commands. End users do not need to understand npm or the registry — IT handles it once."
32
+ },
33
+ handlingPluginRenamesVatreplaces: {
34
+ header: "## Handling Plugin Renames: vat.replaces",
35
+ body: "> **Use this only when renaming a plugin, merging plugins, or cleaning up legacy flat-skill installs. Normal upgrades (same plugin name, same skills) do NOT need \`vat.replaces\` — the installer already overwrites the plugin directory on every install.**\n\n### The problem: silent stale skills\n\nWhen you rename a plugin or reorganize skills across packages, the old registration remains in Claude Code. Claude Code **does not warn you** when two plugins provide conflicting skill names — the first-registered (stale) skill silently wins. Users continue loading old content from the renamed plugin unless the old registration is explicitly removed.\n\nThis is the scenario where \`vat.replaces\` is needed:\n- Plugin renamed: \`old-plugin-name\` → \`new-plugin-name\`\n- Two old plugins merged into one new plugin\n- Skills previously installed to \`~/.claude/skills/<name>\` (legacy pre-0.1.20 flat install) now delivered via the plugin tree\n\n### How it works\n\nWhen a VAT package is installed (via postinstall hook or \`--dev\`), the installer reads \`vat.replaces\` from \`package.json\` and — **before** installing the new plugin:\n\n1. For each name in \`replaces.plugins\`: uninstalls \`<name>@<marketplace>\` — removes plugin directory, cache entry, registry entry, and \`settings.json\` entry\n2. For each name in \`replaces.flatSkills\`: deletes \`~/.claude/skills/<name>\` — removes legacy pre-0.1.20 flat installs\n\nBoth operations are idempotent — \"not found\" is handled gracefully.\n\n### Schema\n\n\`\`\`json\n\"vat\": {\n \"version\": \"1.0\",\n \"skills\": [\"authoring\", \"audit\"],\n \"replaces\": {\n \"plugins\": [\"my-old-plugin-name\"],\n \"flatSkills\": [\"my-old-skill\", \"another-old-skill\"]\n }\n}\n\`\`\`\n\nBoth \`plugins\` and \`flatSkills\` are optional arrays. The entire \`replaces\` key is optional — omit it when there is nothing to clean up.\n\n### Real example: vat-development-agents 0.1.21\n\nThis package (\`vat-development-agents\`) renamed its plugin from \`vat-development-agents\` to \`vibe-agent-toolkit\` in v0.1.21. Without \`vat.replaces\`, users who had already installed v0.1.20 would have both \`vat-development-agents@vat-skills\` and \`vibe-agent-toolkit@vat-skills\` registered — Claude Code would serve stale skill content from the old plugin.\n\nThe fix in \`package.json\`:\n\n\`\`\`json\n\"vat\": {\n \"version\": \"1.0\",\n \"skills\": [\"vibe-agent-toolkit\", \"resources\", \"distribution\", \"authoring\", \"audit\", \"debugging\", \"install\"],\n \"replaces\": {\n \"plugins\": [\"vat-development-agents\"],\n \"flatSkills\": [\"vibe-agent-toolkit\", \"resources\"]\n }\n}\n\`\`\`\n\n- \`plugins\`: removes the old plugin registration (same marketplace, old plugin name)\n- \`flatSkills\`: removes legacy \`~/.claude/skills/vibe-agent-toolkit\` and \`~/.claude/skills/resources\` entries from users who installed before 0.1.20 switched to the plugin tree\n\n### Non-obvious gotchas\n\n**1. Plugin names in \`replaces.plugins\` have NO \`@marketplace\`**\n\nThe format is just the plugin name — e.g. \`\"vat-development-agents\"\` — NOT \`\"vat-development-agents@vat-skills\"\`. The installer infers the marketplace from the current package\'s dist tree. Using \`@marketplace\` syntax here would be wrong.\n\n**2. \`replaces.plugins\` is for old plugin registrations, not for skills that moved between plugins**\n\nIf a skill moved from \`plugin-a\` to \`plugin-b\` within the same marketplace, list \`\"plugin-a\"\` in \`replaces.plugins\` to clean up the entire old plugin. You do not manage individual skills — you manage plugins.\n\n**3. \`replaces.flatSkills\` is ONLY for the legacy \`~/.claude/skills/\` location**\n\nThis is specifically for skills that were previously installed as flat files to \`~/.claude/skills/<name>\` (pre-plugin-tree, before v0.1.20). Skills within the plugin tree (under \`~/.claude/plugins/\`) are handled via \`replaces.plugins\`. Do not mix them up.\n\n**4. Normal upgrades need nothing**\n\nIf you publish a new version of the same package with the same plugin name, the installer overwrites the plugin directory automatically. \`vat.replaces\` is only for the case where the old name is different from the new name.\n\n**5. The symptom is subtle and delayed**\n\nYou will not see an error. Claude Code simply loads the first-registered skill with a given name. If the stale plugin is registered first (alphabetically or by install order), your new content is invisible until you remove the old registration.",
36
+ text: "## Handling Plugin Renames: vat.replaces\n\n> **Use this only when renaming a plugin, merging plugins, or cleaning up legacy flat-skill installs. Normal upgrades (same plugin name, same skills) do NOT need \`vat.replaces\` — the installer already overwrites the plugin directory on every install.**\n\n### The problem: silent stale skills\n\nWhen you rename a plugin or reorganize skills across packages, the old registration remains in Claude Code. Claude Code **does not warn you** when two plugins provide conflicting skill names — the first-registered (stale) skill silently wins. Users continue loading old content from the renamed plugin unless the old registration is explicitly removed.\n\nThis is the scenario where \`vat.replaces\` is needed:\n- Plugin renamed: \`old-plugin-name\` → \`new-plugin-name\`\n- Two old plugins merged into one new plugin\n- Skills previously installed to \`~/.claude/skills/<name>\` (legacy pre-0.1.20 flat install) now delivered via the plugin tree\n\n### How it works\n\nWhen a VAT package is installed (via postinstall hook or \`--dev\`), the installer reads \`vat.replaces\` from \`package.json\` and — **before** installing the new plugin:\n\n1. For each name in \`replaces.plugins\`: uninstalls \`<name>@<marketplace>\` — removes plugin directory, cache entry, registry entry, and \`settings.json\` entry\n2. For each name in \`replaces.flatSkills\`: deletes \`~/.claude/skills/<name>\` — removes legacy pre-0.1.20 flat installs\n\nBoth operations are idempotent — \"not found\" is handled gracefully.\n\n### Schema\n\n\`\`\`json\n\"vat\": {\n \"version\": \"1.0\",\n \"skills\": [\"authoring\", \"audit\"],\n \"replaces\": {\n \"plugins\": [\"my-old-plugin-name\"],\n \"flatSkills\": [\"my-old-skill\", \"another-old-skill\"]\n }\n}\n\`\`\`\n\nBoth \`plugins\` and \`flatSkills\` are optional arrays. The entire \`replaces\` key is optional — omit it when there is nothing to clean up.\n\n### Real example: vat-development-agents 0.1.21\n\nThis package (\`vat-development-agents\`) renamed its plugin from \`vat-development-agents\` to \`vibe-agent-toolkit\` in v0.1.21. Without \`vat.replaces\`, users who had already installed v0.1.20 would have both \`vat-development-agents@vat-skills\` and \`vibe-agent-toolkit@vat-skills\` registered — Claude Code would serve stale skill content from the old plugin.\n\nThe fix in \`package.json\`:\n\n\`\`\`json\n\"vat\": {\n \"version\": \"1.0\",\n \"skills\": [\"vibe-agent-toolkit\", \"resources\", \"distribution\", \"authoring\", \"audit\", \"debugging\", \"install\"],\n \"replaces\": {\n \"plugins\": [\"vat-development-agents\"],\n \"flatSkills\": [\"vibe-agent-toolkit\", \"resources\"]\n }\n}\n\`\`\`\n\n- \`plugins\`: removes the old plugin registration (same marketplace, old plugin name)\n- \`flatSkills\`: removes legacy \`~/.claude/skills/vibe-agent-toolkit\` and \`~/.claude/skills/resources\` entries from users who installed before 0.1.20 switched to the plugin tree\n\n### Non-obvious gotchas\n\n**1. Plugin names in \`replaces.plugins\` have NO \`@marketplace\`**\n\nThe format is just the plugin name — e.g. \`\"vat-development-agents\"\` — NOT \`\"vat-development-agents@vat-skills\"\`. The installer infers the marketplace from the current package\'s dist tree. Using \`@marketplace\` syntax here would be wrong.\n\n**2. \`replaces.plugins\` is for old plugin registrations, not for skills that moved between plugins**\n\nIf a skill moved from \`plugin-a\` to \`plugin-b\` within the same marketplace, list \`\"plugin-a\"\` in \`replaces.plugins\` to clean up the entire old plugin. You do not manage individual skills — you manage plugins.\n\n**3. \`replaces.flatSkills\` is ONLY for the legacy \`~/.claude/skills/\` location**\n\nThis is specifically for skills that were previously installed as flat files to \`~/.claude/skills/<name>\` (pre-plugin-tree, before v0.1.20). Skills within the plugin tree (under \`~/.claude/plugins/\`) are handled via \`replaces.plugins\`. Do not mix them up.\n\n**4. Normal upgrades need nothing**\n\nIf you publish a new version of the same package with the same plugin name, the installer overwrites the plugin directory automatically. \`vat.replaces\` is only for the case where the old name is different from the new name.\n\n**5. The symptom is subtle and delayed**\n\nYou will not see an error. Claude Code simply loads the first-registered skill with a given name. If the stale plugin is registered first (alphabetically or by install order), your new content is invisible until you remove the old registration."
27
37
  },
28
38
  step2VibeAgentToolkitconfigyaml: {
29
39
  header: "## Step 2: vibe-agent-toolkit.config.yaml",
@@ -32,8 +42,8 @@ export const fragments = {
32
42
  },
33
43
  step3Build: {
34
44
  header: "## Step 3: Build",
35
- body: "\`\`\`bash\nvat build # skills phase then claude phase\nvat verify # validates resources + skills + claude artifacts\n\`\`\`\n\n### What vat build does\n\nTwo phases, run in dependency order:\n\n1. **\`vat skills build\`** — reads \`vibe-agent-toolkit.config.yaml skills:\` section, discovers SKILL.md files via include/exclude globs, compiles each into \`dist/skills/<name>/\`\n2. **\`vat claude build\`** — reads \`vibe-agent-toolkit.config.yaml claude:\` section, wraps built skills into \`dist/.claude/plugins/marketplaces/<mp>/plugins/<plugin>/\` structure with \`.claude-plugin/plugin.json\`\n\nIndividual commands still work:\n\`\`\`bash\nvat skills build # skills phase only\nvat claude build # claude plugin phase only (requires skills already built)\nvat claude verify # validate plugin artifacts only\n\`\`\`",
36
- text: "## Step 3: Build\n\n\`\`\`bash\nvat build # skills phase then claude phase\nvat verify # validates resources + skills + claude artifacts\n\`\`\`\n\n### What vat build does\n\nTwo phases, run in dependency order:\n\n1. **\`vat skills build\`** — reads \`vibe-agent-toolkit.config.yaml skills:\` section, discovers SKILL.md files via include/exclude globs, compiles each into \`dist/skills/<name>/\`\n2. **\`vat claude build\`** — reads \`vibe-agent-toolkit.config.yaml claude:\` section, wraps built skills into \`dist/.claude/plugins/marketplaces/<mp>/plugins/<plugin>/\` structure with \`.claude-plugin/plugin.json\`\n\nIndividual commands still work:\n\`\`\`bash\nvat skills build # skills phase only\nvat claude build # claude plugin phase only (requires skills already built)\nvat claude verify # validate plugin artifacts only\n\`\`\`"
45
+ body: "\`\`\`bash\nvat build # skills phase then claude phase\nvat verify # validates resources + skills + claude artifacts\n\`\`\`\n\n### What vat build does\n\nTwo phases, run in dependency order:\n\n1. **\`vat skills build\`** — reads \`vibe-agent-toolkit.config.yaml skills:\` section, discovers SKILL.md files via include/exclude globs, compiles each into \`dist/skills/<name>/\`\n2. **\`vat claude plugin build\`** — reads \`vibe-agent-toolkit.config.yaml claude:\` section, wraps built skills into \`dist/.claude/plugins/marketplaces/<mp>/plugins/<plugin>/\` structure with \`.claude-plugin/plugin.json\`. Cleans stale output before each build.\n\nIndividual commands still work:\n\`\`\`bash\nvat skills build # skills phase only\nvat claude plugin build # claude plugin phase only (requires skills already built)\n\`\`\`",
46
+ text: "## Step 3: Build\n\n\`\`\`bash\nvat build # skills phase then claude phase\nvat verify # validates resources + skills + claude artifacts\n\`\`\`\n\n### What vat build does\n\nTwo phases, run in dependency order:\n\n1. **\`vat skills build\`** — reads \`vibe-agent-toolkit.config.yaml skills:\` section, discovers SKILL.md files via include/exclude globs, compiles each into \`dist/skills/<name>/\`\n2. **\`vat claude plugin build\`** — reads \`vibe-agent-toolkit.config.yaml claude:\` section, wraps built skills into \`dist/.claude/plugins/marketplaces/<mp>/plugins/<plugin>/\` structure with \`.claude-plugin/plugin.json\`. Cleans stale output before each build.\n\nIndividual commands still work:\n\`\`\`bash\nvat skills build # skills phase only\nvat claude plugin build # claude plugin phase only (requires skills already built)\n\`\`\`"
37
47
  },
38
48
  step4Publish: {
39
49
  header: "## Step 4: Publish",
@@ -42,8 +52,8 @@ export const fragments = {
42
52
  },
43
53
  step5UserInstall: {
44
54
  header: "## Step 5: User Install",
45
- body: "\`\`\`bash\nvat skills install npm:@myorg/my-skills\n\`\`\`\n\nOr via standard npm install (postinstall hook triggers automatically):\n\`\`\`bash\nnpm install -g @myorg/my-skills\n\`\`\`\n\n### How plugin installation works\n\nWhen \`npm install\` runs the postinstall hook (\`vat skills install --npm-postinstall\`):\n\n- VAT detects \`dist/.claude/plugins/marketplaces/\` directory in the installed package\n- Copies the plugin tree to Claude\'s plugin directory (dumb recursive copy)\n- Writes to these locations:\n 1. \`~/.claude/plugins/marketplaces/<marketplace>/plugins/<plugin>/\` — plugin files\n 2. \`~/.claude/plugins/known_marketplaces.json\` — marketplace registry\n 3. \`~/.claude/plugins/cache/<marketplace>/<plugin>/<version>/\` — version cache\n 4. \`~/.claude/plugins/installed_plugins.json\` — installation record\n 5. \`~/.claude/settings.json\` \`enabledPlugins\` — activates the plugin\n\nIf no \`dist/.claude/plugins/marketplaces/\` directory exists (package wasn\'t built before publish): a guidance message is emitted and the hook exits 0. The publisher must run \`vat build\` and re-publish.\n\nSkills are then available in Claude Code as \`/plugin-name:skill-name\`.",
46
- text: "## Step 5: User Install\n\n\`\`\`bash\nvat skills install npm:@myorg/my-skills\n\`\`\`\n\nOr via standard npm install (postinstall hook triggers automatically):\n\`\`\`bash\nnpm install -g @myorg/my-skills\n\`\`\`\n\n### How plugin installation works\n\nWhen \`npm install\` runs the postinstall hook (\`vat skills install --npm-postinstall\`):\n\n- VAT detects \`dist/.claude/plugins/marketplaces/\` directory in the installed package\n- Copies the plugin tree to Claude\'s plugin directory (dumb recursive copy)\n- Writes to these locations:\n 1. \`~/.claude/plugins/marketplaces/<marketplace>/plugins/<plugin>/\` — plugin files\n 2. \`~/.claude/plugins/known_marketplaces.json\` — marketplace registry\n 3. \`~/.claude/plugins/cache/<marketplace>/<plugin>/<version>/\` — version cache\n 4. \`~/.claude/plugins/installed_plugins.json\` — installation record\n 5. \`~/.claude/settings.json\` \`enabledPlugins\` — activates the plugin\n\nIf no \`dist/.claude/plugins/marketplaces/\` directory exists (package wasn\'t built before publish): a guidance message is emitted and the hook exits 0. The publisher must run \`vat build\` and re-publish.\n\nSkills are then available in Claude Code as \`/plugin-name:skill-name\`."
55
+ body: "### Recommended: npm global install (postinstall runs automatically)\n\n\`\`\`bash\nnpm install -g @myorg/my-skills\n\`\`\`\n\nThe postinstall hook fires automatically and registers the plugin in Claude. This is the correct path for IT-managed deployments — no other tools required on the user\'s machine.\n\n### Developer/IT one-off install via npx\n\n\`\`\`bash\nnpx vibe-agent-toolkit claude plugin install npm:@myorg/my-skills\n\`\`\`\n\nDownloads and runs VAT via npx to install a package without a global install. Useful for CI, scripting, or testing from a developer machine. Requires the npm scope registry to be configured (\`.npmrc\`) if installing from a private registry.\n\n### How plugin installation works\n\nWhen \`npm install\` runs the postinstall hook (\`node ./node_modules/vibe-agent-toolkit/dist/bin/vat.js claude plugin install --npm-postinstall\`):\n\n- VAT detects \`dist/.claude/plugins/marketplaces/\` directory in the installed package\n- Copies the plugin tree to Claude\'s plugin directory (dumb recursive copy)\n- Writes to these locations:\n 1. \`~/.claude/plugins/marketplaces/<marketplace>/plugins/<plugin>/\` — plugin files\n 2. \`~/.claude/plugins/known_marketplaces.json\` — marketplace registry\n 3. \`~/.claude/plugins/cache/<marketplace>/<plugin>/<version>/\` — version cache\n 4. \`~/.claude/plugins/installed_plugins.json\` — installation record\n 5. \`~/.claude/settings.json\` \`enabledPlugins\` — activates the plugin\n\nIf no \`dist/.claude/plugins/marketplaces/\` directory exists (package wasn\'t built before publish): a guidance message is emitted and the hook exits 0. The publisher must run \`vat build\` and re-publish.\n\nSkills are then available in Claude Code as \`/plugin-name:skill-name\`.",
56
+ text: "## Step 5: User Install\n\n### Recommended: npm global install (postinstall runs automatically)\n\n\`\`\`bash\nnpm install -g @myorg/my-skills\n\`\`\`\n\nThe postinstall hook fires automatically and registers the plugin in Claude. This is the correct path for IT-managed deployments — no other tools required on the user\'s machine.\n\n### Developer/IT one-off install via npx\n\n\`\`\`bash\nnpx vibe-agent-toolkit claude plugin install npm:@myorg/my-skills\n\`\`\`\n\nDownloads and runs VAT via npx to install a package without a global install. Useful for CI, scripting, or testing from a developer machine. Requires the npm scope registry to be configured (\`.npmrc\`) if installing from a private registry.\n\n### How plugin installation works\n\nWhen \`npm install\` runs the postinstall hook (\`node ./node_modules/vibe-agent-toolkit/dist/bin/vat.js claude plugin install --npm-postinstall\`):\n\n- VAT detects \`dist/.claude/plugins/marketplaces/\` directory in the installed package\n- Copies the plugin tree to Claude\'s plugin directory (dumb recursive copy)\n- Writes to these locations:\n 1. \`~/.claude/plugins/marketplaces/<marketplace>/plugins/<plugin>/\` — plugin files\n 2. \`~/.claude/plugins/known_marketplaces.json\` — marketplace registry\n 3. \`~/.claude/plugins/cache/<marketplace>/<plugin>/<version>/\` — version cache\n 4. \`~/.claude/plugins/installed_plugins.json\` — installation record\n 5. \`~/.claude/settings.json\` \`enabledPlugins\` — activates the plugin\n\nIf no \`dist/.claude/plugins/marketplaces/\` directory exists (package wasn\'t built before publish): a guidance message is emitted and the hook exits 0. The publisher must run \`vat build\` and re-publish.\n\nSkills are then available in Claude Code as \`/plugin-name:skill-name\`."
47
57
  },
48
58
  managedSettingsjsonValidationEnterprise: {
49
59
  header: "## managed-settings.json Validation (Enterprise)",
@@ -57,7 +67,12 @@ export const fragments = {
57
67
  },
58
68
  quickReference: {
59
69
  header: "## Quick Reference",
60
- body: "| Task | Command |\n|---|---|\n| Build everything | \`vat build\` |\n| Verify everything | \`vat verify\` |\n| Build skills only | \`vat skills build\` |\n| Build claude artifacts only | \`vat claude build\` |\n| Verify claude artifacts only | \`vat claude verify\` |\n| Install from npm | \`vat skills install npm:@org/pkg\` |\n| Package for claude.ai upload | \`vat skills package ./SKILL.md -o ./dist/ --target claude-web\` |",
61
- text: "## Quick Reference\n\n| Task | Command |\n|---|---|\n| Build everything | \`vat build\` |\n| Verify everything | \`vat verify\` |\n| Build skills only | \`vat skills build\` |\n| Build claude artifacts only | \`vat claude build\` |\n| Verify claude artifacts only | \`vat claude verify\` |\n| Install from npm | \`vat skills install npm:@org/pkg\` |\n| Package for claude.ai upload | \`vat skills package ./SKILL.md -o ./dist/ --target claude-web\` |"
70
+ body: "| Task | Command |\n|---|---|\n| Build everything | \`vat build\` |\n| Verify everything | \`vat verify\` |\n| Build skills only | \`vat skills build\` |\n| Build claude plugin artifacts only | \`vat claude plugin build\` |\n| Install via npm (end user) | \`npm install -g @org/pkg\` |\n| Install via npx (developer/IT) | \`npx vibe-agent-toolkit claude plugin install npm:@org/pkg\` |\n| List installed plugins | \`vat claude plugin list\` |\n| Uninstall a plugin | \`vat claude plugin uninstall --all\` |\n| Package for claude.ai upload | \`vat skills package ./SKILL.md -o ./dist/ --target claude-web\` |",
71
+ text: "## Quick Reference\n\n| Task | Command |\n|---|---|\n| Build everything | \`vat build\` |\n| Verify everything | \`vat verify\` |\n| Build skills only | \`vat skills build\` |\n| Build claude plugin artifacts only | \`vat claude plugin build\` |\n| Install via npm (end user) | \`npm install -g @org/pkg\` |\n| Install via npx (developer/IT) | \`npx vibe-agent-toolkit claude plugin install npm:@org/pkg\` |\n| List installed plugins | \`vat claude plugin list\` |\n| Uninstall a plugin | \`vat claude plugin uninstall --all\` |\n| Package for claude.ai upload | \`vat skills package ./SKILL.md -o ./dist/ --target claude-web\` |"
72
+ },
73
+ futureZeroDependencyPostinstallOptionB: {
74
+ header: "## Future: Zero-Dependency Postinstall (Option B)",
75
+ body: "A planned improvement: \`vat build\` would bundle the plugin install logic into \`dist/postinstall.js\` — a fully self-contained script with no npm dependencies. The postinstall script would become simply \`node ./dist/postinstall.js\`. This eliminates \`vibe-agent-toolkit\` as a runtime dependency entirely, reducing install footprint for end users. Until then, Option C (runtime \`vibe-agent-toolkit\` dep) is the correct approach.",
76
+ text: "## Future: Zero-Dependency Postinstall (Option B)\n\nA planned improvement: \`vat build\` would bundle the plugin install logic into \`dist/postinstall.js\` — a fully self-contained script with no npm dependencies. The postinstall script would become simply \`node ./dist/postinstall.js\`. This eliminates \`vibe-agent-toolkit\` as a runtime dependency entirely, reducing install footprint for end users. Until then, Option C (runtime \`vibe-agent-toolkit\` dep) is the correct approach."
62
77
  }
63
78
  };
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: vibe-agent-toolkit:audit
2
+ name: audit
3
3
  description: Use when running vat audit to validate Claude plugins, agent skills, or marketplaces. Covers the audit command, --compat flag for surface compatibility analysis, --exclude for noise filtering, and interpreting audit output.
4
4
  ---
5
5
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: vibe-agent-toolkit:agent-authoring
2
+ name: authoring
3
3
  description: Use when authoring SKILL.md files, designing agent architectures, or configuring packaging options. Covers SKILL.md structure, agent archetypes, orchestration patterns, and validation override patterns.
4
4
  ---
5
5
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: vibe-agent-toolkit:debugging
2
+ name: debugging
3
3
  description: >-
4
4
  Debug unexpected VAT behavior, reproduce bugs, test local vibe-agent-toolkit
5
5
  changes in adopter projects (VAT_ROOT_DIR), write failing tests before fixing,
@@ -0,0 +1,335 @@
1
+ ---
2
+ name: distribution
3
+ description: Use when setting up vat build, configuring plugin distribution for the Claude ecosystem (marketplace, plugins, managed settings), npm publishing with postinstall hooks, or vat verify orchestration. Covers the full pipeline from skill source to installed plugin.
4
+ ---
5
+
6
+ # VAT Distribution: Build, Publish & Install
7
+
8
+ ## Scope
9
+
10
+ This skill covers the **file-based install method for Claude Code CLI** (`~/.claude/plugins/`).
11
+ This is the only install method VAT currently supports.
12
+
13
+ For the full install landscape — Claude Desktop paths, enterprise CI deployment,
14
+ Anthropic Cloud org management, MDM integration, and the `vat plugins uninstall`
15
+ design — see [Install & Uninstall Architecture](resources/vat-install-architecture.md).
16
+
17
+ ## Overview
18
+
19
+ VAT distributes skills as **Claude plugins** via npm packages. The pipeline:
20
+
21
+ 1. `vat build` compiles SKILL.md sources into plugin artifacts
22
+ 2. `npm publish` pushes the package to a registry
23
+ 3. `npm install` triggers a postinstall hook that registers the plugin in Claude Code's plugin system
24
+
25
+ Skills installed this way appear in Claude Code as `/plugin-name:skill-name`.
26
+
27
+ ## Project Structure
28
+
29
+ ```
30
+ my-project/
31
+ ├── package.json ← vat.skills + postinstall hook + publishConfig
32
+ ├── vibe-agent-toolkit.config.yaml ← skills: + claude: config
33
+ ├── resources/
34
+ │ └── skills/
35
+ │ └── SKILL.md
36
+ └── dist/ ← generated by vat build
37
+ ├── skills/my-skill/ ← packaged skill
38
+ └── .claude/plugins/marketplaces/
39
+ └── my-marketplace/plugins/my-plugin/
40
+ ├── .claude-plugin/plugin.json
41
+ └── skills/my-skill/SKILL.md
42
+ ```
43
+
44
+ ## Step 1: package.json Configuration
45
+
46
+ ```json
47
+ {
48
+ "name": "@myorg/my-skills",
49
+ "version": "1.0.0",
50
+ "vat": {
51
+ "version": "1.0",
52
+ "skills": ["my-skill"]
53
+ },
54
+ "dependencies": {
55
+ "vibe-agent-toolkit": "latest"
56
+ },
57
+ "scripts": {
58
+ "build:vat": "vat build",
59
+ "postinstall": "node ./node_modules/vibe-agent-toolkit/dist/bin/vat.js claude plugin install --npm-postinstall 2>/dev/null || exit 0"
60
+ },
61
+ "files": ["dist", "README.md"],
62
+ "publishConfig": {
63
+ "registry": "https://registry.npmjs.org"
64
+ }
65
+ }
66
+ ```
67
+
68
+ **`vibe-agent-toolkit` must be in `dependencies` (not `devDependencies`)** so it is present in `node_modules` when the postinstall hook runs on the user's machine. Never assume `vat` is available globally — your users may not be developers.
69
+
70
+ The `vat.skills` array contains skill name strings for npm discoverability. Skill source paths and packaging config live in `vibe-agent-toolkit.config.yaml` (see Step 2).
71
+
72
+ For private GitHub Packages registry:
73
+ ```json
74
+ "publishConfig": {
75
+ "registry": "https://npm.pkg.github.com",
76
+ "access": "restricted"
77
+ }
78
+ ```
79
+
80
+ Users (or IT) installing from GitHub Packages need `.npmrc` configured with the scope registry and a read-only token:
81
+ ```
82
+ @myorg:registry=https://npm.pkg.github.com
83
+ //npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}
84
+ ```
85
+
86
+ IT deploying to managed machines should pre-configure `.npmrc` at the system or user level before running install commands. End users do not need to understand npm or the registry — IT handles it once.
87
+
88
+ ## Handling Plugin Renames: vat.replaces
89
+
90
+ > **Use this only when renaming a plugin, merging plugins, or cleaning up legacy flat-skill installs. Normal upgrades (same plugin name, same skills) do NOT need `vat.replaces` — the installer already overwrites the plugin directory on every install.**
91
+
92
+ ### The problem: silent stale skills
93
+
94
+ When you rename a plugin or reorganize skills across packages, the old registration remains in Claude Code. Claude Code **does not warn you** when two plugins provide conflicting skill names — the first-registered (stale) skill silently wins. Users continue loading old content from the renamed plugin unless the old registration is explicitly removed.
95
+
96
+ This is the scenario where `vat.replaces` is needed:
97
+ - Plugin renamed: `old-plugin-name` → `new-plugin-name`
98
+ - Two old plugins merged into one new plugin
99
+ - Skills previously installed to `~/.claude/skills/<name>` (legacy pre-0.1.20 flat install) now delivered via the plugin tree
100
+
101
+ ### How it works
102
+
103
+ When a VAT package is installed (via postinstall hook or `--dev`), the installer reads `vat.replaces` from `package.json` and — **before** installing the new plugin:
104
+
105
+ 1. For each name in `replaces.plugins`: uninstalls `<name>@<marketplace>` — removes plugin directory, cache entry, registry entry, and `settings.json` entry
106
+ 2. For each name in `replaces.flatSkills`: deletes `~/.claude/skills/<name>` — removes legacy pre-0.1.20 flat installs
107
+
108
+ Both operations are idempotent — "not found" is handled gracefully.
109
+
110
+ ### Schema
111
+
112
+ ```json
113
+ "vat": {
114
+ "version": "1.0",
115
+ "skills": ["authoring", "audit"],
116
+ "replaces": {
117
+ "plugins": ["my-old-plugin-name"],
118
+ "flatSkills": ["my-old-skill", "another-old-skill"]
119
+ }
120
+ }
121
+ ```
122
+
123
+ Both `plugins` and `flatSkills` are optional arrays. The entire `replaces` key is optional — omit it when there is nothing to clean up.
124
+
125
+ ### Real example: vat-development-agents 0.1.21
126
+
127
+ This package (`vat-development-agents`) renamed its plugin from `vat-development-agents` to `vibe-agent-toolkit` in v0.1.21. Without `vat.replaces`, users who had already installed v0.1.20 would have both `vat-development-agents@vat-skills` and `vibe-agent-toolkit@vat-skills` registered — Claude Code would serve stale skill content from the old plugin.
128
+
129
+ The fix in `package.json`:
130
+
131
+ ```json
132
+ "vat": {
133
+ "version": "1.0",
134
+ "skills": ["vibe-agent-toolkit", "resources", "distribution", "authoring", "audit", "debugging", "install"],
135
+ "replaces": {
136
+ "plugins": ["vat-development-agents"],
137
+ "flatSkills": ["vibe-agent-toolkit", "resources"]
138
+ }
139
+ }
140
+ ```
141
+
142
+ - `plugins`: removes the old plugin registration (same marketplace, old plugin name)
143
+ - `flatSkills`: removes legacy `~/.claude/skills/vibe-agent-toolkit` and `~/.claude/skills/resources` entries from users who installed before 0.1.20 switched to the plugin tree
144
+
145
+ ### Non-obvious gotchas
146
+
147
+ **1. Plugin names in `replaces.plugins` have NO `@marketplace`**
148
+
149
+ The format is just the plugin name — e.g. `"vat-development-agents"` — NOT `"vat-development-agents@vat-skills"`. The installer infers the marketplace from the current package's dist tree. Using `@marketplace` syntax here would be wrong.
150
+
151
+ **2. `replaces.plugins` is for old plugin registrations, not for skills that moved between plugins**
152
+
153
+ If a skill moved from `plugin-a` to `plugin-b` within the same marketplace, list `"plugin-a"` in `replaces.plugins` to clean up the entire old plugin. You do not manage individual skills — you manage plugins.
154
+
155
+ **3. `replaces.flatSkills` is ONLY for the legacy `~/.claude/skills/` location**
156
+
157
+ This is specifically for skills that were previously installed as flat files to `~/.claude/skills/<name>` (pre-plugin-tree, before v0.1.20). Skills within the plugin tree (under `~/.claude/plugins/`) are handled via `replaces.plugins`. Do not mix them up.
158
+
159
+ **4. Normal upgrades need nothing**
160
+
161
+ If you publish a new version of the same package with the same plugin name, the installer overwrites the plugin directory automatically. `vat.replaces` is only for the case where the old name is different from the new name.
162
+
163
+ **5. The symptom is subtle and delayed**
164
+
165
+ You will not see an error. Claude Code simply loads the first-registered skill with a given name. If the stale plugin is registered first (alphabetically or by install order), your new content is invisible until you remove the old registration.
166
+
167
+ ## Step 2: vibe-agent-toolkit.config.yaml
168
+
169
+ ```yaml
170
+ version: 1
171
+
172
+ skills:
173
+ include:
174
+ - "resources/skills/**/SKILL.md"
175
+
176
+ claude:
177
+ marketplaces:
178
+ my-marketplace: # org/publisher identity
179
+ owner:
180
+ name: My Organization
181
+ plugins:
182
+ - name: my-plugin # installable unit
183
+ description: My plugin description
184
+ skills: "*" # all discovered skills
185
+ ```
186
+
187
+ The `skills:` section discovers SKILL.md files via include/exclude globs. The `claude:` section defines how skills are packaged into plugins. Each marketplace has `owner` and `plugins` fields (strict schema — no extra fields).
188
+
189
+ **Naming convention:** marketplace = org identity (e.g. `acme`), plugin = this package
190
+ (e.g. `acme-tools`). Registers as `my-plugin@my-marketplace` in Claude's plugin registry.
191
+
192
+ ### Multiple skills in one package
193
+
194
+ List all skills in `vat.skills` for npm discoverability:
195
+
196
+ ```json
197
+ "vat": {
198
+ "version": "1.0",
199
+ "skills": ["my-linting", "my-testing"]
200
+ }
201
+ ```
202
+
203
+ Use a selector in the plugin config to include matching skills:
204
+
205
+ ```yaml
206
+ plugins:
207
+ - name: my-plugin
208
+ description: Linting and testing skills
209
+ skills:
210
+ - "my-linting"
211
+ - "my-testing"
212
+ ```
213
+
214
+ Or use `"*"` to include all discovered skills in the plugin.
215
+
216
+ ## Step 3: Build
217
+
218
+ ```bash
219
+ vat build # skills phase then claude phase
220
+ vat verify # validates resources + skills + claude artifacts
221
+ ```
222
+
223
+ ### What vat build does
224
+
225
+ Two phases, run in dependency order:
226
+
227
+ 1. **`vat skills build`** — reads `vibe-agent-toolkit.config.yaml skills:` section, discovers SKILL.md files via include/exclude globs, compiles each into `dist/skills/<name>/`
228
+ 2. **`vat claude plugin build`** — reads `vibe-agent-toolkit.config.yaml claude:` section, wraps built skills into `dist/.claude/plugins/marketplaces/<mp>/plugins/<plugin>/` structure with `.claude-plugin/plugin.json`. Cleans stale output before each build.
229
+
230
+ Individual commands still work:
231
+ ```bash
232
+ vat skills build # skills phase only
233
+ vat claude plugin build # claude plugin phase only (requires skills already built)
234
+ ```
235
+
236
+ ## Step 4: Publish
237
+
238
+ ```bash
239
+ npm publish --tag next # RC/pre-release
240
+ npm publish # stable release
241
+ ```
242
+
243
+ ## Step 5: User Install
244
+
245
+ ### Recommended: npm global install (postinstall runs automatically)
246
+
247
+ ```bash
248
+ npm install -g @myorg/my-skills
249
+ ```
250
+
251
+ The postinstall hook fires automatically and registers the plugin in Claude. This is the correct path for IT-managed deployments — no other tools required on the user's machine.
252
+
253
+ ### Developer/IT one-off install via npx
254
+
255
+ ```bash
256
+ npx vibe-agent-toolkit claude plugin install npm:@myorg/my-skills
257
+ ```
258
+
259
+ Downloads and runs VAT via npx to install a package without a global install. Useful for CI, scripting, or testing from a developer machine. Requires the npm scope registry to be configured (`.npmrc`) if installing from a private registry.
260
+
261
+ ### How plugin installation works
262
+
263
+ When `npm install` runs the postinstall hook (`node ./node_modules/vibe-agent-toolkit/dist/bin/vat.js claude plugin install --npm-postinstall`):
264
+
265
+ - VAT detects `dist/.claude/plugins/marketplaces/` directory in the installed package
266
+ - Copies the plugin tree to Claude's plugin directory (dumb recursive copy)
267
+ - Writes to these locations:
268
+ 1. `~/.claude/plugins/marketplaces/<marketplace>/plugins/<plugin>/` — plugin files
269
+ 2. `~/.claude/plugins/known_marketplaces.json` — marketplace registry
270
+ 3. `~/.claude/plugins/cache/<marketplace>/<plugin>/<version>/` — version cache
271
+ 4. `~/.claude/plugins/installed_plugins.json` — installation record
272
+ 5. `~/.claude/settings.json` `enabledPlugins` — activates the plugin
273
+
274
+ If no `dist/.claude/plugins/marketplaces/` directory exists (package wasn't built before publish): a guidance message is emitted and the hook exits 0. The publisher must run `vat build` and re-publish.
275
+
276
+ Skills are then available in Claude Code as `/plugin-name:skill-name`.
277
+
278
+ ## managed-settings.json Validation (Enterprise)
279
+
280
+ ```yaml
281
+ claude:
282
+ managedSettings: managed-settings.json
283
+ ```
284
+
285
+ `vat verify` validates this file against the ManagedSettings schema. Catches typos and schema errors before deployment. Does NOT deploy the file — deployment is a separate concern.
286
+
287
+ ## --target claude-web (ZIP Upload)
288
+
289
+ For uploading skills directly to `claude.ai/settings/capabilities`:
290
+
291
+ ```bash
292
+ vat skills package ./SKILL.md -o ./dist/ --target claude-web
293
+ ```
294
+
295
+ Produces a ZIP:
296
+ ```
297
+ my-skill.zip
298
+ └── my-skill/
299
+ ├── SKILL.md # skill definition (required)
300
+ ├── scripts/ # executable code (.mjs, .py, .sh) — optional
301
+ ├── references/ # markdown reference material — optional
302
+ └── assets/ # static data, templates, config — optional
303
+ ```
304
+
305
+ Configure source path mappings in `vibe-agent-toolkit.config.yaml`:
306
+ ```yaml
307
+ skills:
308
+ include:
309
+ - "skills/**/SKILL.md"
310
+ config:
311
+ my-skill:
312
+ claudeWebTarget:
313
+ scripts: ["./src/helpers/**/*.ts"]
314
+ assets: ["./assets/**"]
315
+ ```
316
+
317
+ TypeScript files in `scripts` are tree-shaken and compiled to standalone `.mjs`.
318
+
319
+ ## Quick Reference
320
+
321
+ | Task | Command |
322
+ |---|---|
323
+ | Build everything | `vat build` |
324
+ | Verify everything | `vat verify` |
325
+ | Build skills only | `vat skills build` |
326
+ | Build claude plugin artifacts only | `vat claude plugin build` |
327
+ | Install via npm (end user) | `npm install -g @org/pkg` |
328
+ | Install via npx (developer/IT) | `npx vibe-agent-toolkit claude plugin install npm:@org/pkg` |
329
+ | List installed plugins | `vat claude plugin list` |
330
+ | Uninstall a plugin | `vat claude plugin uninstall --all` |
331
+ | Package for claude.ai upload | `vat skills package ./SKILL.md -o ./dist/ --target claude-web` |
332
+
333
+ ## Future: Zero-Dependency Postinstall (Option B)
334
+
335
+ A planned improvement: `vat build` would bundle the plugin install logic into `dist/postinstall.js` — a fully self-contained script with no npm dependencies. The postinstall script would become simply `node ./dist/postinstall.js`. This eliminates `vibe-agent-toolkit` as a runtime dependency entirely, reducing install footprint for end users. Until then, Option C (runtime `vibe-agent-toolkit` dep) is the correct approach.