@vibe-agent-toolkit/vat-development-agents 0.1.32-rc.4 → 0.1.32
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.
- package/dist/.claude/plugins/marketplaces/vat-skills/CHANGELOG.md +37 -4
- package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/.claude-plugin/plugin.json +1 -1
- package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/vat-adoption-and-configuration/SKILL.md +179 -0
- package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/{authoring → vat-agent-authoring}/SKILL.md +16 -134
- package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/{audit → vat-audit}/SKILL.md +1 -1
- package/dist/{skills/org-admin → .claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/vat-enterprise-org}/SKILL.md +3 -3
- package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/{resources → vat-knowledge-resources}/SKILL.md +1 -1
- package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/vat-rag/SKILL.md +104 -0
- package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/vat-skill-authoring/SKILL.md +156 -0
- package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/{distribution → vat-skill-distribution}/SKILL.md +3 -2
- package/dist/{skills/authoring/resources/skill-quality-checklist.md → .claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/vat-skill-review/SKILL.md} +16 -1
- package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/vibe-agent-toolkit/SKILL.md +40 -189
- package/dist/generated/resources/skills/CLAUDE.d.ts +28 -0
- package/dist/generated/resources/skills/CLAUDE.js +60 -0
- package/dist/generated/resources/skills/SKILL.d.ts +2 -10
- package/dist/generated/resources/skills/SKILL.js +14 -54
- package/dist/generated/resources/skills/vat-adoption-and-configuration.d.ts +29 -0
- package/dist/generated/resources/skills/vat-adoption-and-configuration.js +53 -0
- package/dist/generated/resources/skills/vat-agent-authoring.d.ts +0 -2
- package/dist/generated/resources/skills/vat-agent-authoring.js +9 -19
- package/dist/generated/resources/skills/vat-audit.js +1 -1
- package/dist/generated/resources/skills/{vat-claude-org-admin.js → vat-enterprise-org.js} +3 -3
- package/dist/generated/resources/skills/{vat-resources.js → vat-knowledge-resources.js} +1 -1
- package/dist/generated/resources/skills/{vat-install-architecture.d.ts → vat-rag.d.ts} +6 -7
- package/dist/generated/resources/skills/vat-rag.js +43 -0
- package/dist/generated/resources/skills/{vat-debugging.d.ts → vat-skill-authoring.d.ts} +7 -7
- package/dist/generated/resources/skills/vat-skill-authoring.js +48 -0
- package/dist/generated/resources/skills/{vat-skills-distribution.js → vat-skill-distribution.js} +4 -4
- package/dist/generated/resources/skills/{skill-quality-checklist.d.ts → vat-skill-review.d.ts} +5 -1
- package/dist/generated/resources/skills/{skill-quality-checklist.js → vat-skill-review.js} +10 -2
- package/dist/skills/vat-adoption-and-configuration/SKILL.md +179 -0
- package/dist/skills/{authoring → vat-agent-authoring}/SKILL.md +16 -134
- package/dist/skills/{audit → vat-audit}/SKILL.md +1 -1
- package/dist/{.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/org-admin → skills/vat-enterprise-org}/SKILL.md +3 -3
- package/dist/skills/{resources → vat-knowledge-resources}/SKILL.md +1 -1
- package/dist/skills/vat-rag/SKILL.md +104 -0
- package/dist/skills/vat-skill-authoring/SKILL.md +156 -0
- package/dist/skills/{distribution → vat-skill-distribution}/SKILL.md +3 -2
- package/dist/{.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/authoring/resources/skill-quality-checklist.md → skills/vat-skill-review/SKILL.md} +16 -1
- package/dist/skills/vibe-agent-toolkit/SKILL.md +40 -189
- package/package.json +13 -11
- package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/debugging/SKILL.md +0 -111
- package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/distribution/resources/vat-install-architecture.md +0 -229
- package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/install/SKILL.md +0 -229
- package/dist/generated/resources/skills/vat-debugging.js +0 -48
- package/dist/generated/resources/skills/vat-install-architecture.js +0 -48
- package/dist/skills/debugging/SKILL.md +0 -111
- package/dist/skills/distribution/resources/vat-install-architecture.md +0 -229
- package/dist/skills/install/SKILL.md +0 -229
- /package/dist/generated/resources/skills/{vat-claude-org-admin.d.ts → vat-enterprise-org.d.ts} +0 -0
- /package/dist/generated/resources/skills/{vat-resources.d.ts → vat-knowledge-resources.d.ts} +0 -0
- /package/dist/generated/resources/skills/{vat-skills-distribution.d.ts → vat-skill-distribution.d.ts} +0 -0
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
export const meta = {
|
|
6
|
-
name: "org
|
|
7
|
-
description: "
|
|
6
|
+
name: "vat-enterprise-org",
|
|
7
|
+
description: "Use for Anthropic Enterprise/Team org administration via the Admin API — user management, API-key auditing, cost/usage reporting, workspace admin, and enterprise skill distribution. Requires ANTHROPIC_ADMIN_API_KEY."
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
-
export const text = "\n# Claude Org Administration\n\n**For Anthropic org admins only.** Requires \`ANTHROPIC_ADMIN_API_KEY\` (Enterprise/Team plan).\nIf you don\'t have an admin key, this skill is not for you — use \`vibe-agent-toolkit:distribution\`\nfor local plugin management instead.\n\n## Two Ways to Use It\n\n### CLI — Quick Queries\n\n\`\`\`bash\nvat claude org info # Org identity\nvat claude org users list # All members\nvat claude org api-keys list --status active # Active API keys\nvat claude org cost --group-by description # Cost breakdown by model\nvat claude org usage --from 2025-01-01T00:00:00Z # Token usage since Jan\nvat claude org skills list # Workspace-scoped skills (requires ANTHROPIC_API_KEY)\n\`\`\`\n\n### Library — Scripts and Automation\n\n\`\`\`typescript\nimport { OrgApiClient, createOrgApiClientFromEnv } from \'@vibe-agent-toolkit/claude-marketplace\';\n\n// Reads ANTHROPIC_ADMIN_API_KEY and optionally ANTHROPIC_API_KEY from env\nconst client = createOrgApiClientFromEnv();\n\n// Or construct directly\nconst client = new OrgApiClient({\n adminApiKey: \'sk-ant-admin-...\',\n apiKey: \'sk-ant-api03-...\', // only needed for skills endpoints\n});\n\`\`\`\n\n## API Reference\n\n### Auth: Two Keys, Two Surfaces\n\n| Key | Env Var | Endpoints | Who Has It |\n|---|---|---|---|\n| Admin API key | \`ANTHROPIC_ADMIN_API_KEY\` | \`/v1/organizations/*\` | Org admins only |\n| Regular API key | \`ANTHROPIC_API_KEY\` | \`/v1/skills\` (beta) | Any workspace member |\n\n### Endpoints and Methods\n\n**Org identity:**\n\`\`\`typescript\nconst org = await client.get<{ id: string; type: string; name: string }>(\'/v1/organizations/me\');\n\`\`\`\n\n**Users:**\n\`\`\`typescript\n// List (paginated with limit/after_id)\nconst users = await client.get<{ data: OrgUser[]; has_more: boolean }>(\n \'/v1/organizations/users\', { limit: 100 }\n);\n\n// Get single user\nconst user = await client.get<OrgUser>(\'/v1/organizations/users/user_abc123\');\n\`\`\`\n\n**Invites:**\n\`\`\`typescript\nconst invites = await client.get<{ data: OrgInvite[]; has_more: boolean }>(\n \'/v1/organizations/invites\'\n);\n\`\`\`\n\n**Workspaces:**\n\`\`\`typescript\nconst workspaces = await client.get<{ data: OrgWorkspace[]; has_more: boolean }>(\n \'/v1/organizations/workspaces\'\n);\n\n// Workspace members\nconst members = await client.get<{ data: WorkspaceMember[]; has_more: boolean }>(\n \'/v1/organizations/workspaces/ws_abc/members\'\n);\n\`\`\`\n\n**API keys:**\n\`\`\`typescript\nconst keys = await client.get<{ data: ApiKey[]; has_more: boolean }>(\n \'/v1/organizations/api_keys\',\n { status: \'active\', workspace_id: \'ws_abc\' } // both filters optional\n);\n\`\`\`\n\n**Skills (beta — uses regular API key):**\n\`\`\`typescript\n// List skills\nconst skills = await client.getSkills<{ data: Skill[]; has_more: boolean }>(\'/v1/skills\');\n// Adds anthropic-beta: skills-2025-10-02 header automatically\n\n// Upload a skill (multipart/form-data)\nimport { buildMultipartFormData } from \'@vibe-agent-toolkit/claude-marketplace\';\nconst multipart = buildMultipartFormData(\n { display_title: \'My Skill\' },\n [{ fieldName: \'files[]\', filename: \'SKILL.md\', content: Buffer.from(skillContent) }],\n);\nconst created = await client.uploadSkill<{ id: string; latest_version: string }>(multipart);\n\n// Delete a skill\nconst deleted = await client.deleteSkill<{ id: string; type: string }>(skillId);\n\`\`\`\n\n### Report Endpoints — Pagination Quirk\n\nUsage, cost, and code-analytics endpoints have a **non-standard pagination model**.\nThey return \`has_more: true\` with a \`next_page\` cursor, but the API **rejects \`next_page\`\nas a query parameter**. Paginate by advancing \`starting_at\` to the last bucket\'s \`ending_at\`.\n\n**Usage report (daily token buckets):**\n\`\`\`typescript\ninterface UsageBucket {\n starting_at: string;\n ending_at: string;\n results: Array<{\n uncached_input_tokens: number;\n cache_read_input_tokens: number;\n output_tokens: number;\n model: string | null;\n workspace_id: string | null;\n api_key_id: string | null;\n service_tier: string | null;\n // ... other dimension fields, null if not applicable\n }>;\n}\n\n// First page\nlet resp = await client.get<{ data: UsageBucket[]; has_more: boolean }>(\n \'/v1/organizations/usage_report/messages\',\n { starting_at: \'2025-01-01T00:00:00Z\', ending_at: \'2025-12-31T23:59:59Z\' }\n);\n\n// Subsequent pages — advance starting_at, do NOT pass next_page\nconst lastBucket = resp.data.at(-1);\nresp = await client.get<{ data: UsageBucket[]; has_more: boolean }>(\n \'/v1/organizations/usage_report/messages\',\n { starting_at: lastBucket.ending_at, ending_at: \'2025-12-31T23:59:59Z\' }\n);\n\`\`\`\n\n**Cost report:**\n\`\`\`typescript\n// amount is a STRING, not a number — parse before arithmetic\ninterface CostResult {\n currency: string;\n amount: string; // \"7.0812\" — use parseFloat()\n description: string | null;\n model: string | null;\n token_type: string | null;\n // ...\n}\n\n// group_by[] needs URLSearchParams for repeated params\nconst qs = new URLSearchParams();\nqs.set(\'starting_at\', \'2025-03-01T00:00:00Z\');\nqs.set(\'ending_at\', \'2025-03-31T23:59:59Z\');\nqs.append(\'group_by[]\', \'description\');\nqs.append(\'group_by[]\', \'workspace_id\');\nconst resp = await client.get<{ data: CostBucket[] }>(\n \`/v1/organizations/cost_report?${qs.toString()}\`\n);\n\n// Sum costs\nconst total = resp.data\n .flatMap(b => b.results)\n .reduce((sum, r) => sum + parseFloat(r.amount), 0);\n\`\`\`\n\n**Code analytics (Claude Code productivity):**\n\`\`\`typescript\n// Date-only format YYYY-MM-DD. No ending_at parameter.\nconst resp = await client.get<{ data: unknown[] }>(\n \'/v1/organizations/usage_report/claude_code\',\n { starting_at: \'2025-03-01\' } // NOT ISO datetime\n);\n// Returns empty data[] when no Claude Code enterprise seats are active\n\`\`\`\n\n## Common Recipes\n\n### Monthly cost summary script\n\n\`\`\`typescript\nimport { createOrgApiClientFromEnv } from \'@vibe-agent-toolkit/claude-marketplace\';\n\nconst client = createOrgApiClientFromEnv();\nconst qs = new URLSearchParams();\nqs.set(\'starting_at\', \'2025-03-01T00:00:00Z\');\nqs.set(\'ending_at\', \'2025-04-01T00:00:00Z\');\nqs.append(\'group_by[]\', \'description\');\n\nconst allResults = [];\nlet startingAt = \'2025-03-01T00:00:00Z\';\nlet hasMore = true;\n\nwhile (hasMore) {\n qs.set(\'starting_at\', startingAt);\n const resp = await client.get(\`/v1/organizations/cost_report?${qs.toString()}\`);\n allResults.push(...resp.data);\n const last = resp.data.at(-1);\n hasMore = resp.has_more && last;\n if (last) startingAt = last.ending_at;\n}\n\nconst byDescription = new Map();\nfor (const bucket of allResults) {\n for (const r of bucket.results) {\n const key = r.description ?? \'unclassified\';\n byDescription.set(key, (byDescription.get(key) ?? 0) + parseFloat(r.amount));\n }\n}\nfor (const [desc, total] of byDescription) {\n console.log(\`${desc}: $${total.toFixed(2)}\`);\n}\n\`\`\`\n\n### API key security audit\n\n\`\`\`typescript\nconst client = createOrgApiClientFromEnv();\nconst { data: keys } = await client.get(\'/v1/organizations/api_keys\', { limit: 100 });\n\nconst issues = [];\nfor (const key of keys) {\n if (key.status === \'active\' && !key.expires_at) {\n issues.push(\`${key.name}: active with no expiry\`);\n }\n if (key.status === \'active\' && !key.workspace_id) {\n issues.push(\`${key.name}: not scoped to a workspace\`);\n }\n}\nconsole.log(issues.length ? issues.join(\'\\n\') : \'All keys look good\');\n\`\`\`\n\n### List org users who haven\'t accepted invites\n\n\`\`\`typescript\nconst client = createOrgApiClientFromEnv();\nconst { data: invites } = await client.get(\'/v1/organizations/invites\');\nconst pending = invites.filter(i => i.status !== \'accepted\');\nconsole.log(\`${pending.length} pending invites:\`, pending.map(i => i.email));\n\`\`\`\n\n## CLI Reference\n\nAll commands require \`ANTHROPIC_ADMIN_API_KEY\` unless noted.\n\n\`\`\`\nvat claude org info Org identity (id, name)\nvat claude org users list [--limit N] List members\nvat claude org users get <user-id> Get single member\nvat claude org invites list List invitations\nvat claude org workspaces list List API workspaces\nvat claude org workspaces get <id> Get single workspace\nvat claude org workspaces members list <id> Workspace members\nvat claude org api-keys list [--status S] API key inventory\nvat claude org usage [--from DT] [--to DT] Token usage report\nvat claude org cost [--from DT] [--group-by F] USD cost report\nvat claude org code-analytics [--from DATE] Claude Code metrics (YYYY-MM-DD)\nvat claude org skills list Workspace skills (needs ANTHROPIC_API_KEY)\nvat claude org skills install <source> Upload skill dir or ZIP to org\nvat claude org skills delete <skill-id> Delete a skill (versions first)\nvat claude org skills versions list <skill-id> List skill versions\nvat claude org skills versions delete <id> <ver> Delete a skill version\n\`\`\`\n\nExit codes: \`0\` success, \`1\` expected failure (stubs), \`2\` system error (missing key, API error).\n\n**Skill deletion lifecycle:** The API requires all versions to be deleted before the skill itself.\nUse \`versions list\` to find versions, \`versions delete\` each one, then \`delete\` the skill.\n\n## Enterprise Skill Distribution\n\n### Skills API (claude.ai / Console)\n\nSkills uploaded via \`POST /v1/skills\` are **workspace-scoped** and **automatically available to\nall workspace members**. There is no per-user enable/disable via the API — visibility is\nworkspace-level only. The admin UI may have additional controls not exposed in the API.\n\n**Upload from npm package:**\n\`\`\`bash\n# Upload all skills from a package\nvat claude org skills install --from-npm @scope/my-skills-package@1.0.0\n\n# Upload a single skill\nvat claude org skills install --from-npm @scope/my-skills-package@1.0.0 --skill my-skill\n\`\`\`\n\nThe package must contain \`dist/skills/<name>/SKILL.md\` (produced by \`vat skills build\`).\nIf skills are in a sub-dependency, the command searches \`node_modules/*/dist/skills/\` too.\n\n**Duplicate titles are rejected** — the API enforces unique \`display_title\` per workspace.\nWhen uploading multiple skills, failures are non-fatal; partial results are reported.\n\n### Managed Settings (Claude Code plugins)\n\nFor enterprise-wide Claude Code plugin deployment (not the Skills API), use managed settings\npushed via MDM (Jamf, Intune, SCCM, etc.):\n\n| Platform | Path |\n|---|---|\n| macOS | \`/Library/Application Support/ClaudeCode/managed-settings.json\` |\n| Linux | \`/etc/claude-code/managed-settings.json\` |\n| Windows | \`C:\\Program Files\\ClaudeCode\\managed-settings.json\` |\n\nManaged settings are **highest priority** in the settings cascade — they override user settings.\nUse this to force-enable plugins, lock down permissions, or configure organization defaults.\n\n\`\`\`json\n{\n \"enabledPlugins\": {\n \"my-plugin@my-marketplace\": true\n }\n}\n\`\`\`\n\nCombine with \`npm install -g <package>\` (via IT software deployment) to install the plugin\nbinary, then managed settings to enable it across all machines.\n\n## Not Yet Implemented\n\nThese commands exist with the correct CLI shape but return structured\n\`not-yet-implemented\` stubs (exit 1). Coming in a future release:\n\n- \`org users update/remove\` — role changes, offboarding\n- \`org invites create/delete\` — programmatic invitations\n- \`org workspaces create/archive\` — workspace lifecycle\n- \`org workspaces members add/update/remove\` — workspace membership\n- \`org api-keys update\` — rename keys\n";
|
|
10
|
+
export const text = "\n# Claude Org Administration\n\n**For Anthropic org admins only.** Requires \`ANTHROPIC_ADMIN_API_KEY\` (Enterprise/Team plan).\nIf you don\'t have an admin key, this skill is not for you — use \`vibe-agent-toolkit:vat-skill-distribution\`\nfor local plugin management instead.\n\n## Two Ways to Use It\n\n### CLI — Quick Queries\n\n\`\`\`bash\nvat claude org info # Org identity\nvat claude org users list # All members\nvat claude org api-keys list --status active # Active API keys\nvat claude org cost --group-by description # Cost breakdown by model\nvat claude org usage --from 2025-01-01T00:00:00Z # Token usage since Jan\nvat claude org skills list # Workspace-scoped skills (requires ANTHROPIC_API_KEY)\n\`\`\`\n\n### Library — Scripts and Automation\n\n\`\`\`typescript\nimport { OrgApiClient, createOrgApiClientFromEnv } from \'@vibe-agent-toolkit/claude-marketplace\';\n\n// Reads ANTHROPIC_ADMIN_API_KEY and optionally ANTHROPIC_API_KEY from env\nconst client = createOrgApiClientFromEnv();\n\n// Or construct directly\nconst client = new OrgApiClient({\n adminApiKey: \'sk-ant-admin-...\',\n apiKey: \'sk-ant-api03-...\', // only needed for skills endpoints\n});\n\`\`\`\n\n## API Reference\n\n### Auth: Two Keys, Two Surfaces\n\n| Key | Env Var | Endpoints | Who Has It |\n|---|---|---|---|\n| Admin API key | \`ANTHROPIC_ADMIN_API_KEY\` | \`/v1/organizations/*\` | Org admins only |\n| Regular API key | \`ANTHROPIC_API_KEY\` | \`/v1/skills\` (beta) | Any workspace member |\n\n### Endpoints and Methods\n\n**Org identity:**\n\`\`\`typescript\nconst org = await client.get<{ id: string; type: string; name: string }>(\'/v1/organizations/me\');\n\`\`\`\n\n**Users:**\n\`\`\`typescript\n// List (paginated with limit/after_id)\nconst users = await client.get<{ data: OrgUser[]; has_more: boolean }>(\n \'/v1/organizations/users\', { limit: 100 }\n);\n\n// Get single user\nconst user = await client.get<OrgUser>(\'/v1/organizations/users/user_abc123\');\n\`\`\`\n\n**Invites:**\n\`\`\`typescript\nconst invites = await client.get<{ data: OrgInvite[]; has_more: boolean }>(\n \'/v1/organizations/invites\'\n);\n\`\`\`\n\n**Workspaces:**\n\`\`\`typescript\nconst workspaces = await client.get<{ data: OrgWorkspace[]; has_more: boolean }>(\n \'/v1/organizations/workspaces\'\n);\n\n// Workspace members\nconst members = await client.get<{ data: WorkspaceMember[]; has_more: boolean }>(\n \'/v1/organizations/workspaces/ws_abc/members\'\n);\n\`\`\`\n\n**API keys:**\n\`\`\`typescript\nconst keys = await client.get<{ data: ApiKey[]; has_more: boolean }>(\n \'/v1/organizations/api_keys\',\n { status: \'active\', workspace_id: \'ws_abc\' } // both filters optional\n);\n\`\`\`\n\n**Skills (beta — uses regular API key):**\n\`\`\`typescript\n// List skills\nconst skills = await client.getSkills<{ data: Skill[]; has_more: boolean }>(\'/v1/skills\');\n// Adds anthropic-beta: skills-2025-10-02 header automatically\n\n// Upload a skill (multipart/form-data)\nimport { buildMultipartFormData } from \'@vibe-agent-toolkit/claude-marketplace\';\nconst multipart = buildMultipartFormData(\n { display_title: \'My Skill\' },\n [{ fieldName: \'files[]\', filename: \'SKILL.md\', content: Buffer.from(skillContent) }],\n);\nconst created = await client.uploadSkill<{ id: string; latest_version: string }>(multipart);\n\n// Delete a skill\nconst deleted = await client.deleteSkill<{ id: string; type: string }>(skillId);\n\`\`\`\n\n### Report Endpoints — Pagination Quirk\n\nUsage, cost, and code-analytics endpoints have a **non-standard pagination model**.\nThey return \`has_more: true\` with a \`next_page\` cursor, but the API **rejects \`next_page\`\nas a query parameter**. Paginate by advancing \`starting_at\` to the last bucket\'s \`ending_at\`.\n\n**Usage report (daily token buckets):**\n\`\`\`typescript\ninterface UsageBucket {\n starting_at: string;\n ending_at: string;\n results: Array<{\n uncached_input_tokens: number;\n cache_read_input_tokens: number;\n output_tokens: number;\n model: string | null;\n workspace_id: string | null;\n api_key_id: string | null;\n service_tier: string | null;\n // ... other dimension fields, null if not applicable\n }>;\n}\n\n// First page\nlet resp = await client.get<{ data: UsageBucket[]; has_more: boolean }>(\n \'/v1/organizations/usage_report/messages\',\n { starting_at: \'2025-01-01T00:00:00Z\', ending_at: \'2025-12-31T23:59:59Z\' }\n);\n\n// Subsequent pages — advance starting_at, do NOT pass next_page\nconst lastBucket = resp.data.at(-1);\nresp = await client.get<{ data: UsageBucket[]; has_more: boolean }>(\n \'/v1/organizations/usage_report/messages\',\n { starting_at: lastBucket.ending_at, ending_at: \'2025-12-31T23:59:59Z\' }\n);\n\`\`\`\n\n**Cost report:**\n\`\`\`typescript\n// amount is a STRING, not a number — parse before arithmetic\ninterface CostResult {\n currency: string;\n amount: string; // \"7.0812\" — use parseFloat()\n description: string | null;\n model: string | null;\n token_type: string | null;\n // ...\n}\n\n// group_by[] needs URLSearchParams for repeated params\nconst qs = new URLSearchParams();\nqs.set(\'starting_at\', \'2025-03-01T00:00:00Z\');\nqs.set(\'ending_at\', \'2025-03-31T23:59:59Z\');\nqs.append(\'group_by[]\', \'description\');\nqs.append(\'group_by[]\', \'workspace_id\');\nconst resp = await client.get<{ data: CostBucket[] }>(\n \`/v1/organizations/cost_report?${qs.toString()}\`\n);\n\n// Sum costs\nconst total = resp.data\n .flatMap(b => b.results)\n .reduce((sum, r) => sum + parseFloat(r.amount), 0);\n\`\`\`\n\n**Code analytics (Claude Code productivity):**\n\`\`\`typescript\n// Date-only format YYYY-MM-DD. No ending_at parameter.\nconst resp = await client.get<{ data: unknown[] }>(\n \'/v1/organizations/usage_report/claude_code\',\n { starting_at: \'2025-03-01\' } // NOT ISO datetime\n);\n// Returns empty data[] when no Claude Code enterprise seats are active\n\`\`\`\n\n## Common Recipes\n\n### Monthly cost summary script\n\n\`\`\`typescript\nimport { createOrgApiClientFromEnv } from \'@vibe-agent-toolkit/claude-marketplace\';\n\nconst client = createOrgApiClientFromEnv();\nconst qs = new URLSearchParams();\nqs.set(\'starting_at\', \'2025-03-01T00:00:00Z\');\nqs.set(\'ending_at\', \'2025-04-01T00:00:00Z\');\nqs.append(\'group_by[]\', \'description\');\n\nconst allResults = [];\nlet startingAt = \'2025-03-01T00:00:00Z\';\nlet hasMore = true;\n\nwhile (hasMore) {\n qs.set(\'starting_at\', startingAt);\n const resp = await client.get(\`/v1/organizations/cost_report?${qs.toString()}\`);\n allResults.push(...resp.data);\n const last = resp.data.at(-1);\n hasMore = resp.has_more && last;\n if (last) startingAt = last.ending_at;\n}\n\nconst byDescription = new Map();\nfor (const bucket of allResults) {\n for (const r of bucket.results) {\n const key = r.description ?? \'unclassified\';\n byDescription.set(key, (byDescription.get(key) ?? 0) + parseFloat(r.amount));\n }\n}\nfor (const [desc, total] of byDescription) {\n console.log(\`${desc}: $${total.toFixed(2)}\`);\n}\n\`\`\`\n\n### API key security audit\n\n\`\`\`typescript\nconst client = createOrgApiClientFromEnv();\nconst { data: keys } = await client.get(\'/v1/organizations/api_keys\', { limit: 100 });\n\nconst issues = [];\nfor (const key of keys) {\n if (key.status === \'active\' && !key.expires_at) {\n issues.push(\`${key.name}: active with no expiry\`);\n }\n if (key.status === \'active\' && !key.workspace_id) {\n issues.push(\`${key.name}: not scoped to a workspace\`);\n }\n}\nconsole.log(issues.length ? issues.join(\'\\n\') : \'All keys look good\');\n\`\`\`\n\n### List org users who haven\'t accepted invites\n\n\`\`\`typescript\nconst client = createOrgApiClientFromEnv();\nconst { data: invites } = await client.get(\'/v1/organizations/invites\');\nconst pending = invites.filter(i => i.status !== \'accepted\');\nconsole.log(\`${pending.length} pending invites:\`, pending.map(i => i.email));\n\`\`\`\n\n## CLI Reference\n\nAll commands require \`ANTHROPIC_ADMIN_API_KEY\` unless noted.\n\n\`\`\`\nvat claude org info Org identity (id, name)\nvat claude org users list [--limit N] List members\nvat claude org users get <user-id> Get single member\nvat claude org invites list List invitations\nvat claude org workspaces list List API workspaces\nvat claude org workspaces get <id> Get single workspace\nvat claude org workspaces members list <id> Workspace members\nvat claude org api-keys list [--status S] API key inventory\nvat claude org usage [--from DT] [--to DT] Token usage report\nvat claude org cost [--from DT] [--group-by F] USD cost report\nvat claude org code-analytics [--from DATE] Claude Code metrics (YYYY-MM-DD)\nvat claude org skills list Workspace skills (needs ANTHROPIC_API_KEY)\nvat claude org skills install <source> Upload skill dir or ZIP to org\nvat claude org skills delete <skill-id> Delete a skill (versions first)\nvat claude org skills versions list <skill-id> List skill versions\nvat claude org skills versions delete <id> <ver> Delete a skill version\n\`\`\`\n\nExit codes: \`0\` success, \`1\` expected failure (stubs), \`2\` system error (missing key, API error).\n\n**Skill deletion lifecycle:** The API requires all versions to be deleted before the skill itself.\nUse \`versions list\` to find versions, \`versions delete\` each one, then \`delete\` the skill.\n\n## Enterprise Skill Distribution\n\n### Skills API (claude.ai / Console)\n\nSkills uploaded via \`POST /v1/skills\` are **workspace-scoped** and **automatically available to\nall workspace members**. There is no per-user enable/disable via the API — visibility is\nworkspace-level only. The admin UI may have additional controls not exposed in the API.\n\n**Upload from npm package:**\n\`\`\`bash\n# Upload all skills from a package\nvat claude org skills install --from-npm @scope/my-skills-package@1.0.0\n\n# Upload a single skill\nvat claude org skills install --from-npm @scope/my-skills-package@1.0.0 --skill my-skill\n\`\`\`\n\nThe package must contain \`dist/skills/<name>/SKILL.md\` (produced by \`vat skills build\`).\nIf skills are in a sub-dependency, the command searches \`node_modules/*/dist/skills/\` too.\n\n**Duplicate titles are rejected** — the API enforces unique \`display_title\` per workspace.\nWhen uploading multiple skills, failures are non-fatal; partial results are reported.\n\n### Managed Settings (Claude Code plugins)\n\nFor enterprise-wide Claude Code plugin deployment (not the Skills API), use managed settings\npushed via MDM (Jamf, Intune, SCCM, etc.):\n\n| Platform | Path |\n|---|---|\n| macOS | \`/Library/Application Support/ClaudeCode/managed-settings.json\` |\n| Linux | \`/etc/claude-code/managed-settings.json\` |\n| Windows | \`C:\\Program Files\\ClaudeCode\\managed-settings.json\` |\n\nManaged settings are **highest priority** in the settings cascade — they override user settings.\nUse this to force-enable plugins, lock down permissions, or configure organization defaults.\n\n\`\`\`json\n{\n \"enabledPlugins\": {\n \"my-plugin@my-marketplace\": true\n }\n}\n\`\`\`\n\nCombine with \`npm install -g <package>\` (via IT software deployment) to install the plugin\nbinary, then managed settings to enable it across all machines.\n\n## Not Yet Implemented\n\nThese commands exist with the correct CLI shape but return structured\n\`not-yet-implemented\` stubs (exit 1). Coming in a future release:\n\n- \`org users update/remove\` — role changes, offboarding\n- \`org invites create/delete\` — programmatic invitations\n- \`org workspaces create/archive\` — workspace lifecycle\n- \`org workspaces members add/update/remove\` — workspace membership\n- \`org api-keys update\` — rename keys\n";
|
|
11
11
|
|
|
12
12
|
export const fragments = {
|
|
13
13
|
twoWaysToUseIt: {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
export const meta = {
|
|
6
|
-
name: "resources",
|
|
6
|
+
name: "vat-knowledge-resources",
|
|
7
7
|
description: "Use when working with VAT resource collections, per-directory frontmatter schema validation, link validation, or the vat resources command. Covers collection configuration, schema mapping, and validation modes."
|
|
8
8
|
};
|
|
9
9
|
|
|
@@ -16,13 +16,12 @@ export const meta: {
|
|
|
16
16
|
export const text: string;
|
|
17
17
|
|
|
18
18
|
export const fragments: {
|
|
19
|
-
readonly
|
|
20
|
-
readonly
|
|
21
|
-
readonly
|
|
22
|
-
readonly
|
|
23
|
-
readonly
|
|
24
|
-
readonly
|
|
25
|
-
readonly whatIsOutOfScopeForVat: Fragment;
|
|
19
|
+
readonly cliCommands: Fragment;
|
|
20
|
+
readonly whatShipsNatively: Fragment;
|
|
21
|
+
readonly extensionPoints: Fragment;
|
|
22
|
+
readonly configuration: Fragment;
|
|
23
|
+
readonly troubleshooting: Fragment;
|
|
24
|
+
readonly references: Fragment;
|
|
26
25
|
};
|
|
27
26
|
|
|
28
27
|
export type FragmentName = keyof typeof fragments;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generated from markdown file - DO NOT EDIT
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export const meta = {
|
|
6
|
+
name: "vat-rag",
|
|
7
|
+
description: "Use when running \`vat rag index\` / \`vat rag query\` or configuring RAG for agent context — covers the CLI commands, native embedding providers and vector store support, chunking, custom metadata, and extension points for adding new backends."
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const text = "\n# VAT RAG: Indexing and Querying Markdown with Native Providers\n\nThis skill covers VAT\'s RAG (retrieval-augmented generation) surface: the \`vat rag\` CLI commands, the embedding and vector-store providers that ship natively, and how to extend either side. For authoring the markdown that gets indexed (frontmatter schemas, collections) use \`vibe-agent-toolkit:vat-knowledge-resources\`.\n\n## CLI Commands\n\n\`\`\`bash\n# Index markdown into a local vector DB (default: .rag-db/)\nvat rag index docs/\n\n# Ask a natural-language question; returns the top chunks with file paths and heading context\nvat rag query \"How do I configure agent tools?\"\n\n# Inspect the current index\nvat rag stats\n\`\`\`\n\n\`vat rag index\` reads \`vibe-agent-toolkit.config.yaml\` when no path argument is given and respects the \`rag\` section for per-store configuration (multiple indices, content transforms, metadata schemas).\n\n\`\`\`bash\n# Multi-store: index separate databases for different corpora\nvat rag index --db ./dist/rag-en docs/en/\nvat rag index --db ./dist/rag-fr docs/fr/\n\n# Query a specific database\nvat rag query \"installation\" --db ./dist/rag-en\n\`\`\`\n\nSee \`vat rag --help\` for the full flag surface and \`docs/guides/rag-usage-guide.md\` for end-to-end configuration examples.\n\n## What Ships Natively\n\nVAT\'s \`@vibe-agent-toolkit/rag\` package provides the core interfaces and a small set of ready-to-use providers. The goal is \"works out of the box\" for common cases, with clean extension points for everything else.\n\n### Embedding providers\n\n| Provider | Model | Where it runs |\n|---|---|---|\n| \`TransformersEmbeddingProvider\` | \`Xenova/all-MiniLM-L6-v2\` (default) | Local, via \`transformers.js\` — no API key, CPU inference |\n| \`OpenAIEmbeddingProvider\` | \`text-embedding-3-small\` (default) | OpenAI API — requires \`OPENAI_API_KEY\` |\n\nBoth implement the \`EmbeddingProvider\` interface (\`name\`, \`model\`, \`dimensions\`, \`embed(text)\`, \`embedBatch(texts)\`), so the rest of the RAG pipeline doesn\'t care which one is wired in.\n\n### Vector store\n\n- \`@vibe-agent-toolkit/rag-lancedb\` — native LanceDB-backed store, lives on disk under \`.rag-db/\` by default. Supports approximate-nearest-neighbor search, metadata filtering, and incremental re-indexing.\n\n### Chunking and metadata\n\n- Hybrid heading-based + token-aware chunking via \`chunkMarkdown\`, integrated with \`ResourceRegistry\` so chunks inherit file-level metadata.\n- \`DefaultRAGMetadata\` — sensible defaults for markdown docs (filePath, tags, type, headingPath, sourceUrl, etc.).\n- Custom metadata — extend \`DefaultRAGMetadataSchema\` or replace it entirely. Use \`createCustomRAGChunkSchema(MySchema)\` to get type-safe chunks through the whole pipeline.\n\n### Token counters\n\n- \`FastTokenCounter\` — bytes/4 heuristic, zero-cost.\n- \`ApproximateTokenCounter\` — \`gpt-tokenizer\`-backed, closer to reality for OpenAI-style models.\n\n## Extension Points\n\nThe RAG interfaces are small on purpose. If something isn\'t supported natively, implement the interface in your own package:\n\n- **Embedding provider** — implement \`EmbeddingProvider\` (cohere, Voyage, local LLM endpoints, etc.). Register via config or pass directly to \`RAG.open({ embedding: myProvider })\`.\n- **Vector store** — implement \`RAGQueryProvider\` + \`RAGAdminProvider\` (pgvector, Pinecone, Qdrant, ChromaDB, etc.). The \`@vibe-agent-toolkit/rag-lancedb\` package is the reference implementation; mirror its shape.\n- **Content transform** — hook into the chunking pipeline to rewrite markdown (e.g. strip HTML comments, expand templates) before it hits the embedder.\n- **Custom metadata** — ship your own Zod schema and thread it through the CLI via config.\n\n**Contributions welcome**: native support for additional embedding providers and vector stores is on the roadmap. If you\'ve written a clean implementation of the RAG interfaces for another backend, open a PR — the target is a small, curated set of \"we ship and test these\" providers, with everything else available as community packages.\n\n## Configuration\n\n\`\`\`yaml\nversion: 1\n\nrag:\n stores:\n default:\n db: .rag-db/\n include: [\"docs/**/*.md\"]\n exclude: [\"docs/drafts/**\"]\n embedding:\n provider: transformers-js # or: openai\n model: Xenova/all-MiniLM-L6-v2 # embedding-specific\n\`\`\`\n\nPer-store configuration keeps multi-corpus projects (multilingual docs, product-vs-support splits) legible.\n\n## Troubleshooting\n\n- \`vat rag query\` returns empty: confirm \`vat rag stats\` shows non-zero chunks; re-run \`vat rag index\` after adding content.\n- Slow first index with \`transformers-js\`: the model downloads on first use and caches under \`~/.cache/transformers\`.\n- Drift between indexed content and live docs: re-index. LanceDB supports delete-by-filter, so \`vat rag index --rebuild\` for the specific store is safe.\n\n## References\n\n- \`vibe-agent-toolkit:vat-knowledge-resources\` — markdown collections and frontmatter schema validation (the content side)\n- [RAG Usage Guide](../../../../docs/guides/rag-usage-guide.md) — configuration walkthroughs for single-store, multi-store, and custom metadata\n- [Embedding Providers](../../../../docs/embedding-providers.md) — provider deep-dive and how to write new ones\n- [@vibe-agent-toolkit/rag](../../../../packages/rag/README.md) — package README with the full interface reference\n";
|
|
11
|
+
|
|
12
|
+
export const fragments = {
|
|
13
|
+
cliCommands: {
|
|
14
|
+
header: "## CLI Commands",
|
|
15
|
+
body: "\`\`\`bash\n# Index markdown into a local vector DB (default: .rag-db/)\nvat rag index docs/\n\n# Ask a natural-language question; returns the top chunks with file paths and heading context\nvat rag query \"How do I configure agent tools?\"\n\n# Inspect the current index\nvat rag stats\n\`\`\`\n\n\`vat rag index\` reads \`vibe-agent-toolkit.config.yaml\` when no path argument is given and respects the \`rag\` section for per-store configuration (multiple indices, content transforms, metadata schemas).\n\n\`\`\`bash\n# Multi-store: index separate databases for different corpora\nvat rag index --db ./dist/rag-en docs/en/\nvat rag index --db ./dist/rag-fr docs/fr/\n\n# Query a specific database\nvat rag query \"installation\" --db ./dist/rag-en\n\`\`\`\n\nSee \`vat rag --help\` for the full flag surface and \`docs/guides/rag-usage-guide.md\` for end-to-end configuration examples.",
|
|
16
|
+
text: "## CLI Commands\n\n\`\`\`bash\n# Index markdown into a local vector DB (default: .rag-db/)\nvat rag index docs/\n\n# Ask a natural-language question; returns the top chunks with file paths and heading context\nvat rag query \"How do I configure agent tools?\"\n\n# Inspect the current index\nvat rag stats\n\`\`\`\n\n\`vat rag index\` reads \`vibe-agent-toolkit.config.yaml\` when no path argument is given and respects the \`rag\` section for per-store configuration (multiple indices, content transforms, metadata schemas).\n\n\`\`\`bash\n# Multi-store: index separate databases for different corpora\nvat rag index --db ./dist/rag-en docs/en/\nvat rag index --db ./dist/rag-fr docs/fr/\n\n# Query a specific database\nvat rag query \"installation\" --db ./dist/rag-en\n\`\`\`\n\nSee \`vat rag --help\` for the full flag surface and \`docs/guides/rag-usage-guide.md\` for end-to-end configuration examples."
|
|
17
|
+
},
|
|
18
|
+
whatShipsNatively: {
|
|
19
|
+
header: "## What Ships Natively",
|
|
20
|
+
body: "VAT\'s \`@vibe-agent-toolkit/rag\` package provides the core interfaces and a small set of ready-to-use providers. The goal is \"works out of the box\" for common cases, with clean extension points for everything else.\n\n### Embedding providers\n\n| Provider | Model | Where it runs |\n|---|---|---|\n| \`TransformersEmbeddingProvider\` | \`Xenova/all-MiniLM-L6-v2\` (default) | Local, via \`transformers.js\` — no API key, CPU inference |\n| \`OpenAIEmbeddingProvider\` | \`text-embedding-3-small\` (default) | OpenAI API — requires \`OPENAI_API_KEY\` |\n\nBoth implement the \`EmbeddingProvider\` interface (\`name\`, \`model\`, \`dimensions\`, \`embed(text)\`, \`embedBatch(texts)\`), so the rest of the RAG pipeline doesn\'t care which one is wired in.\n\n### Vector store\n\n- \`@vibe-agent-toolkit/rag-lancedb\` — native LanceDB-backed store, lives on disk under \`.rag-db/\` by default. Supports approximate-nearest-neighbor search, metadata filtering, and incremental re-indexing.\n\n### Chunking and metadata\n\n- Hybrid heading-based + token-aware chunking via \`chunkMarkdown\`, integrated with \`ResourceRegistry\` so chunks inherit file-level metadata.\n- \`DefaultRAGMetadata\` — sensible defaults for markdown docs (filePath, tags, type, headingPath, sourceUrl, etc.).\n- Custom metadata — extend \`DefaultRAGMetadataSchema\` or replace it entirely. Use \`createCustomRAGChunkSchema(MySchema)\` to get type-safe chunks through the whole pipeline.\n\n### Token counters\n\n- \`FastTokenCounter\` — bytes/4 heuristic, zero-cost.\n- \`ApproximateTokenCounter\` — \`gpt-tokenizer\`-backed, closer to reality for OpenAI-style models.",
|
|
21
|
+
text: "## What Ships Natively\n\nVAT\'s \`@vibe-agent-toolkit/rag\` package provides the core interfaces and a small set of ready-to-use providers. The goal is \"works out of the box\" for common cases, with clean extension points for everything else.\n\n### Embedding providers\n\n| Provider | Model | Where it runs |\n|---|---|---|\n| \`TransformersEmbeddingProvider\` | \`Xenova/all-MiniLM-L6-v2\` (default) | Local, via \`transformers.js\` — no API key, CPU inference |\n| \`OpenAIEmbeddingProvider\` | \`text-embedding-3-small\` (default) | OpenAI API — requires \`OPENAI_API_KEY\` |\n\nBoth implement the \`EmbeddingProvider\` interface (\`name\`, \`model\`, \`dimensions\`, \`embed(text)\`, \`embedBatch(texts)\`), so the rest of the RAG pipeline doesn\'t care which one is wired in.\n\n### Vector store\n\n- \`@vibe-agent-toolkit/rag-lancedb\` — native LanceDB-backed store, lives on disk under \`.rag-db/\` by default. Supports approximate-nearest-neighbor search, metadata filtering, and incremental re-indexing.\n\n### Chunking and metadata\n\n- Hybrid heading-based + token-aware chunking via \`chunkMarkdown\`, integrated with \`ResourceRegistry\` so chunks inherit file-level metadata.\n- \`DefaultRAGMetadata\` — sensible defaults for markdown docs (filePath, tags, type, headingPath, sourceUrl, etc.).\n- Custom metadata — extend \`DefaultRAGMetadataSchema\` or replace it entirely. Use \`createCustomRAGChunkSchema(MySchema)\` to get type-safe chunks through the whole pipeline.\n\n### Token counters\n\n- \`FastTokenCounter\` — bytes/4 heuristic, zero-cost.\n- \`ApproximateTokenCounter\` — \`gpt-tokenizer\`-backed, closer to reality for OpenAI-style models."
|
|
22
|
+
},
|
|
23
|
+
extensionPoints: {
|
|
24
|
+
header: "## Extension Points",
|
|
25
|
+
body: "The RAG interfaces are small on purpose. If something isn\'t supported natively, implement the interface in your own package:\n\n- **Embedding provider** — implement \`EmbeddingProvider\` (cohere, Voyage, local LLM endpoints, etc.). Register via config or pass directly to \`RAG.open({ embedding: myProvider })\`.\n- **Vector store** — implement \`RAGQueryProvider\` + \`RAGAdminProvider\` (pgvector, Pinecone, Qdrant, ChromaDB, etc.). The \`@vibe-agent-toolkit/rag-lancedb\` package is the reference implementation; mirror its shape.\n- **Content transform** — hook into the chunking pipeline to rewrite markdown (e.g. strip HTML comments, expand templates) before it hits the embedder.\n- **Custom metadata** — ship your own Zod schema and thread it through the CLI via config.\n\n**Contributions welcome**: native support for additional embedding providers and vector stores is on the roadmap. If you\'ve written a clean implementation of the RAG interfaces for another backend, open a PR — the target is a small, curated set of \"we ship and test these\" providers, with everything else available as community packages.",
|
|
26
|
+
text: "## Extension Points\n\nThe RAG interfaces are small on purpose. If something isn\'t supported natively, implement the interface in your own package:\n\n- **Embedding provider** — implement \`EmbeddingProvider\` (cohere, Voyage, local LLM endpoints, etc.). Register via config or pass directly to \`RAG.open({ embedding: myProvider })\`.\n- **Vector store** — implement \`RAGQueryProvider\` + \`RAGAdminProvider\` (pgvector, Pinecone, Qdrant, ChromaDB, etc.). The \`@vibe-agent-toolkit/rag-lancedb\` package is the reference implementation; mirror its shape.\n- **Content transform** — hook into the chunking pipeline to rewrite markdown (e.g. strip HTML comments, expand templates) before it hits the embedder.\n- **Custom metadata** — ship your own Zod schema and thread it through the CLI via config.\n\n**Contributions welcome**: native support for additional embedding providers and vector stores is on the roadmap. If you\'ve written a clean implementation of the RAG interfaces for another backend, open a PR — the target is a small, curated set of \"we ship and test these\" providers, with everything else available as community packages."
|
|
27
|
+
},
|
|
28
|
+
configuration: {
|
|
29
|
+
header: "## Configuration",
|
|
30
|
+
body: "\`\`\`yaml\nversion: 1\n\nrag:\n stores:\n default:\n db: .rag-db/\n include: [\"docs/**/*.md\"]\n exclude: [\"docs/drafts/**\"]\n embedding:\n provider: transformers-js # or: openai\n model: Xenova/all-MiniLM-L6-v2 # embedding-specific\n\`\`\`\n\nPer-store configuration keeps multi-corpus projects (multilingual docs, product-vs-support splits) legible.",
|
|
31
|
+
text: "## Configuration\n\n\`\`\`yaml\nversion: 1\n\nrag:\n stores:\n default:\n db: .rag-db/\n include: [\"docs/**/*.md\"]\n exclude: [\"docs/drafts/**\"]\n embedding:\n provider: transformers-js # or: openai\n model: Xenova/all-MiniLM-L6-v2 # embedding-specific\n\`\`\`\n\nPer-store configuration keeps multi-corpus projects (multilingual docs, product-vs-support splits) legible."
|
|
32
|
+
},
|
|
33
|
+
troubleshooting: {
|
|
34
|
+
header: "## Troubleshooting",
|
|
35
|
+
body: "- \`vat rag query\` returns empty: confirm \`vat rag stats\` shows non-zero chunks; re-run \`vat rag index\` after adding content.\n- Slow first index with \`transformers-js\`: the model downloads on first use and caches under \`~/.cache/transformers\`.\n- Drift between indexed content and live docs: re-index. LanceDB supports delete-by-filter, so \`vat rag index --rebuild\` for the specific store is safe.",
|
|
36
|
+
text: "## Troubleshooting\n\n- \`vat rag query\` returns empty: confirm \`vat rag stats\` shows non-zero chunks; re-run \`vat rag index\` after adding content.\n- Slow first index with \`transformers-js\`: the model downloads on first use and caches under \`~/.cache/transformers\`.\n- Drift between indexed content and live docs: re-index. LanceDB supports delete-by-filter, so \`vat rag index --rebuild\` for the specific store is safe."
|
|
37
|
+
},
|
|
38
|
+
references: {
|
|
39
|
+
header: "## References",
|
|
40
|
+
body: "- \`vibe-agent-toolkit:vat-knowledge-resources\` — markdown collections and frontmatter schema validation (the content side)\n- [RAG Usage Guide](../../../../docs/guides/rag-usage-guide.md) — configuration walkthroughs for single-store, multi-store, and custom metadata\n- [Embedding Providers](../../../../docs/embedding-providers.md) — provider deep-dive and how to write new ones\n- [@vibe-agent-toolkit/rag](../../../../packages/rag/README.md) — package README with the full interface reference",
|
|
41
|
+
text: "## References\n\n- \`vibe-agent-toolkit:vat-knowledge-resources\` — markdown collections and frontmatter schema validation (the content side)\n- [RAG Usage Guide](../../../../docs/guides/rag-usage-guide.md) — configuration walkthroughs for single-store, multi-store, and custom metadata\n- [Embedding Providers](../../../../docs/embedding-providers.md) — provider deep-dive and how to write new ones\n- [@vibe-agent-toolkit/rag](../../../../packages/rag/README.md) — package README with the full interface reference"
|
|
42
|
+
}
|
|
43
|
+
};
|
|
@@ -16,13 +16,13 @@ export const meta: {
|
|
|
16
16
|
export const text: string;
|
|
17
17
|
|
|
18
18
|
export const fragments: {
|
|
19
|
-
readonly
|
|
20
|
-
readonly
|
|
21
|
-
readonly
|
|
22
|
-
readonly
|
|
23
|
-
readonly
|
|
24
|
-
readonly
|
|
25
|
-
readonly
|
|
19
|
+
readonly skillmdStructure: Fragment;
|
|
20
|
+
readonly bodyStructure: Fragment;
|
|
21
|
+
readonly referencesSection: Fragment;
|
|
22
|
+
readonly packagingoptionsReference: Fragment;
|
|
23
|
+
readonly validationOverrides: Fragment;
|
|
24
|
+
readonly prePublicationCheck: Fragment;
|
|
25
|
+
readonly references: Fragment;
|
|
26
26
|
};
|
|
27
27
|
|
|
28
28
|
export type FragmentName = keyof typeof fragments;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generated from markdown file - DO NOT EDIT
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export const meta = {
|
|
6
|
+
name: "vat-skill-authoring",
|
|
7
|
+
description: "Use when authoring or revising a SKILL.md file — frontmatter, body structure, references, packagingOptions (linkFollowDepth, excludeReferencesFromBundle), and validation overrides. Paired with vat-skill-review for pre-publication checks."
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const text = "\n# VAT Skill Authoring: SKILL.md Structure and Packaging\n\nThis skill covers authoring SKILL.md files for portable Claude skills: frontmatter shape, body structure, reference links, and the packaging options that control how the skill is bundled for distribution. For the TypeScript agent side (archetypes, result envelopes, orchestration, runtime adapters) use \`vibe-agent-toolkit:vat-agent-authoring\`.\n\n## SKILL.md Structure\n\nA SKILL.md file is the definition file for a portable skill. It tells Claude what the skill does and how to use it. All SKILL.md files must have YAML frontmatter:\n\n\`\`\`markdown\n---\nname: my-skill\ndescription: One sentence — what this skill does and when to use it (≤250 chars)\n---\n\n# My Skill\n\nRest of the skill documentation...\n\`\`\`\n\nRequired frontmatter fields:\n\n- \`name\` — unique identifier, kebab-case (\`^[a-z][a-z0-9-]*$\`), matches the skill\'s directory name after build. Avoid the reserved words \`claude\` and \`anthropic\` (Claude Code rejects non-certified skills using those words — surfaced as \`RESERVED_WORD_IN_NAME\`).\n- \`description\` — trigger description used for Claude\'s skill routing; be specific about activation conditions.\n\nBest practices for \`description\`:\n\n- Lead with an action verb or \`Use when <concrete trigger>\` — filler openers like \"This skill...\", \"A skill that...\", \"Use when you want to...\" fire \`SKILL_DESCRIPTION_FILLER_OPENER\`.\n- Include 2–4 trigger keywords a user is likely to type.\n- Write in third person. First-person (\"I can...\") and conversational second-person (\"You can use...\") fire \`SKILL_DESCRIPTION_WRONG_PERSON\`.\n- Keep under 250 characters so the Claude Code \`/skills\` listing doesn\'t truncate the tail (target ≤200 for safety, ≤130 if shipping a large skill collection). The hard schema limit is 1024.\n\n## Body Structure\n\n- Lead with a short orientation paragraph: what the skill owns and when to reach for it.\n- Use H2 sections for major content blocks; avoid deeply nested H3/H4 trees — they hurt Claude\'s ability to route attention inside the file.\n- Keep SKILL.md under ~500 lines. Longer than that fires \`SKILL_LENGTH_EXCEEDS_RECOMMENDED\` and is a strong signal to split via progressive disclosure (linked reference files) or to spin the content into a sibling skill.\n- Avoid time-sensitive phrasing like \"as of April 2026\" in the body — it ages the skill quickly (\`SKILL_TIME_SENSITIVE_CONTENT\`).\n\n## References Section\n\nA short \`## References\` section at the bottom is the canonical place to list linked resources. Two patterns:\n\n- **Progressive disclosure** — link to \`.md\` files inside the skill directory that get bundled. Keep reference depth ≤ 2 hops; deeper chains fire \`REFERENCE_TOO_DEEP\`.\n- **Prose references to sibling skills** — write \`vibe-agent-toolkit:vat-audit\`, not \`[vat-audit](./vat-audit.md)\`. Markdown links to sibling SKILL.md files cause the packager to transclude the other skill (and fire \`LINK_TO_SKILL_DEFINITION\`).\n\nAvoid linking to navigation files (\`README.md\`, \`index.md\`) — they\'re excluded from the bundle and the link resolves to nothing (\`LINK_TO_NAVIGATION_FILE\`).\n\n## packagingOptions Reference\n\nPackaging options are configured per skill in \`vibe-agent-toolkit.config.yaml\` under \`skills.config.<name>\`:\n\n\`\`\`yaml\nskills:\n include: [\"resources/skills/SKILL.md\", \"resources/skills/*.md\"]\n defaults:\n linkFollowDepth: 2\n config:\n my-skill:\n linkFollowDepth: 1\n resourceNaming: resource-id\n stripPrefix: knowledge-base\n excludeReferencesFromBundle:\n rules:\n - patterns: [\"**/concepts/**\"]\n template: \"Use search to find: {{link.text}}\"\n defaultTemplate: \"{{link.text}} (search knowledge base)\"\n\`\`\`\n\n**\`linkFollowDepth\`** — How deep to follow links from SKILL.md:\n\n| Value | Behavior |\n|-------|----------|\n| \`0\` | Skill file only (no links followed) |\n| \`1\` | Direct links only |\n| \`2\` | Direct + one transitive level **(default)** |\n| \`\"full\"\` | Complete transitive closure |\n\n**\`resourceNaming\`** — How bundled files are named:\n\n| Strategy | Example | Use When |\n|----------|---------|----------|\n| \`basename\` | \`overview.md\` | Few files, unique names **(default)** |\n| \`resource-id\` | \`topics-quickstart-overview.md\` | Many files, flat output |\n| \`preserve-path\` | \`topics/quickstart/overview.md\` | Preserve structure |\n\nUse \`stripPrefix\` to remove a common directory prefix (e.g., \`\"knowledge-base\"\`).\n\n**\`excludeReferencesFromBundle\`** — Rules for excluding files and rewriting their links:\n\n- \`rules[]\` — ordered glob patterns (first match wins), each with optional Handlebars template\n- \`defaultTemplate\` — applied to depth-exceeded links not matching any rule\n\n**Template variables:**\n\n| Variable | Description |\n|----------|-------------|\n| \`{{link.text}}\` | Link display text |\n| \`{{link.href}}\` | Original href (without fragment) |\n| \`{{link.fragment}}\` | Fragment including \`#\` prefix, or empty |\n| \`{{link.type}}\` | Link type (\`\"local_file\"\`, etc.) |\n| \`{{link.resource.id}}\` | Target resource ID (if resolved) |\n| \`{{link.resource.fileName}}\` | Target filename (if resolved) |\n| \`{{skill.name}}\` | Skill name from frontmatter |\n\n## Validation Overrides\n\nThe \`validation\` sub-key in a skill\'s config provides the unified override framework for VAT validation codes:\n\n\`\`\`yaml\nskills:\n config:\n my-skill:\n validation:\n severity:\n LINK_DROPPED_BY_DEPTH: error # upgrade: block on depth-dropped links\n LINK_TO_NAVIGATION_FILE: ignore # silence: this skill intentionally links to READMEs\n allow:\n PACKAGED_UNREFERENCED_FILE:\n - paths: [\"templates/runtime.json\"]\n reason: \"consumed programmatically at runtime\"\n expires: \"2026-09-30\"\n SKILL_LENGTH_EXCEEDS_RECOMMENDED:\n - reason: \"whole-skill concern; paths defaults to [\'**/*\']\"\n\`\`\`\n\nTwo sub-keys, each covering a different override granularity:\n\n- **\`severity\`** — class-level. Raise any code to \`error\` (blocks build), lower to \`warning\` (emits, non-blocking), or \`ignore\` (fully suppressed). Applies to every instance of that code.\n- **\`allow\`** — per-instance. Suppress specific \`(code, path)\` matches with a required \`reason\` and optional \`expires\` date. \`paths\` is optional (defaults to \`[\"**/*\"]\` — the whole skill). Use for legitimate exceptions that don\'t warrant code-wide silencing.\n\nCommon adjustments:\n\n- Downgrade \`LINK_DROPPED_BY_DEPTH\` to \`ignore\` when intentionally linking out to external docs.\n- Allow specific files under \`PACKAGED_UNREFERENCED_FILE\` when they\'re consumed programmatically by CLI scripts at runtime.\n- Raise \`ALLOW_EXPIRED\` to \`error\` for zero-tolerance expiry policies.\n\nExpired \`allow\` entries still apply — VAT emits \`ALLOW_EXPIRED\` as a reminder rather than silently re-surfacing the underlying issue (no surprise build breaks when a date passes). Unused \`allow\` entries surface as \`ALLOW_UNUSED\` (analogous to ESLint\'s unused-disable).\n\n\`vat audit\` is advisory: it applies \`severity\` for display grouping only, ignores \`allow\`, and always exits 0. Use \`vat skills validate\` or \`vat skills build\` for gated checks.\n\n## Pre-publication Check\n\nBefore shipping a skill, walk through the \`vibe-agent-toolkit:vat-skill-review\` checklist — it covers naming, description quality, structure, validation-code triage, and Anthropic\'s skill-authoring best practices. The \`vat skill review <skill>\` CLI command renders a skill-specific view of the same checklist.\n\n## References\n\n- \`vibe-agent-toolkit:vat-skill-review\` — pre-publication quality checklist (general + CLI-backed items, tied to VAT validation codes)\n- \`vibe-agent-toolkit:vat-skill-distribution\` — plugin/marketplace config, \`vat build\`, \`vat verify\`, npm publishing\n- \`vibe-agent-toolkit:vat-knowledge-resources\` — the \`resources:\` config section for multi-collection frontmatter schema validation\n- [Validation Codes Reference](../../../../docs/validation-codes.md) — full list of codes VAT emits, their default severity, and override recipes.\n- [Skill Quality and Compatibility — VAT\'s Stance](../../../../docs/skill-quality-and-compatibility.md) — what VAT believes makes a skill good and compatible.\n";
|
|
11
|
+
|
|
12
|
+
export const fragments = {
|
|
13
|
+
skillmdStructure: {
|
|
14
|
+
header: "## SKILL.md Structure",
|
|
15
|
+
body: "A SKILL.md file is the definition file for a portable skill. It tells Claude what the skill does and how to use it. All SKILL.md files must have YAML frontmatter:\n\n\`\`\`markdown\n---\nname: my-skill\ndescription: One sentence — what this skill does and when to use it (≤250 chars)\n---\n\n# My Skill\n\nRest of the skill documentation...\n\`\`\`\n\nRequired frontmatter fields:\n\n- \`name\` — unique identifier, kebab-case (\`^[a-z][a-z0-9-]*$\`), matches the skill\'s directory name after build. Avoid the reserved words \`claude\` and \`anthropic\` (Claude Code rejects non-certified skills using those words — surfaced as \`RESERVED_WORD_IN_NAME\`).\n- \`description\` — trigger description used for Claude\'s skill routing; be specific about activation conditions.\n\nBest practices for \`description\`:\n\n- Lead with an action verb or \`Use when <concrete trigger>\` — filler openers like \"This skill...\", \"A skill that...\", \"Use when you want to...\" fire \`SKILL_DESCRIPTION_FILLER_OPENER\`.\n- Include 2–4 trigger keywords a user is likely to type.\n- Write in third person. First-person (\"I can...\") and conversational second-person (\"You can use...\") fire \`SKILL_DESCRIPTION_WRONG_PERSON\`.\n- Keep under 250 characters so the Claude Code \`/skills\` listing doesn\'t truncate the tail (target ≤200 for safety, ≤130 if shipping a large skill collection). The hard schema limit is 1024.",
|
|
16
|
+
text: "## SKILL.md Structure\n\nA SKILL.md file is the definition file for a portable skill. It tells Claude what the skill does and how to use it. All SKILL.md files must have YAML frontmatter:\n\n\`\`\`markdown\n---\nname: my-skill\ndescription: One sentence — what this skill does and when to use it (≤250 chars)\n---\n\n# My Skill\n\nRest of the skill documentation...\n\`\`\`\n\nRequired frontmatter fields:\n\n- \`name\` — unique identifier, kebab-case (\`^[a-z][a-z0-9-]*$\`), matches the skill\'s directory name after build. Avoid the reserved words \`claude\` and \`anthropic\` (Claude Code rejects non-certified skills using those words — surfaced as \`RESERVED_WORD_IN_NAME\`).\n- \`description\` — trigger description used for Claude\'s skill routing; be specific about activation conditions.\n\nBest practices for \`description\`:\n\n- Lead with an action verb or \`Use when <concrete trigger>\` — filler openers like \"This skill...\", \"A skill that...\", \"Use when you want to...\" fire \`SKILL_DESCRIPTION_FILLER_OPENER\`.\n- Include 2–4 trigger keywords a user is likely to type.\n- Write in third person. First-person (\"I can...\") and conversational second-person (\"You can use...\") fire \`SKILL_DESCRIPTION_WRONG_PERSON\`.\n- Keep under 250 characters so the Claude Code \`/skills\` listing doesn\'t truncate the tail (target ≤200 for safety, ≤130 if shipping a large skill collection). The hard schema limit is 1024."
|
|
17
|
+
},
|
|
18
|
+
bodyStructure: {
|
|
19
|
+
header: "## Body Structure",
|
|
20
|
+
body: "- Lead with a short orientation paragraph: what the skill owns and when to reach for it.\n- Use H2 sections for major content blocks; avoid deeply nested H3/H4 trees — they hurt Claude\'s ability to route attention inside the file.\n- Keep SKILL.md under ~500 lines. Longer than that fires \`SKILL_LENGTH_EXCEEDS_RECOMMENDED\` and is a strong signal to split via progressive disclosure (linked reference files) or to spin the content into a sibling skill.\n- Avoid time-sensitive phrasing like \"as of April 2026\" in the body — it ages the skill quickly (\`SKILL_TIME_SENSITIVE_CONTENT\`).",
|
|
21
|
+
text: "## Body Structure\n\n- Lead with a short orientation paragraph: what the skill owns and when to reach for it.\n- Use H2 sections for major content blocks; avoid deeply nested H3/H4 trees — they hurt Claude\'s ability to route attention inside the file.\n- Keep SKILL.md under ~500 lines. Longer than that fires \`SKILL_LENGTH_EXCEEDS_RECOMMENDED\` and is a strong signal to split via progressive disclosure (linked reference files) or to spin the content into a sibling skill.\n- Avoid time-sensitive phrasing like \"as of April 2026\" in the body — it ages the skill quickly (\`SKILL_TIME_SENSITIVE_CONTENT\`)."
|
|
22
|
+
},
|
|
23
|
+
referencesSection: {
|
|
24
|
+
header: "## References Section",
|
|
25
|
+
body: "A short \`## References\` section at the bottom is the canonical place to list linked resources. Two patterns:\n\n- **Progressive disclosure** — link to \`.md\` files inside the skill directory that get bundled. Keep reference depth ≤ 2 hops; deeper chains fire \`REFERENCE_TOO_DEEP\`.\n- **Prose references to sibling skills** — write \`vibe-agent-toolkit:vat-audit\`, not \`[vat-audit](./vat-audit.md)\`. Markdown links to sibling SKILL.md files cause the packager to transclude the other skill (and fire \`LINK_TO_SKILL_DEFINITION\`).\n\nAvoid linking to navigation files (\`README.md\`, \`index.md\`) — they\'re excluded from the bundle and the link resolves to nothing (\`LINK_TO_NAVIGATION_FILE\`).",
|
|
26
|
+
text: "## References Section\n\nA short \`## References\` section at the bottom is the canonical place to list linked resources. Two patterns:\n\n- **Progressive disclosure** — link to \`.md\` files inside the skill directory that get bundled. Keep reference depth ≤ 2 hops; deeper chains fire \`REFERENCE_TOO_DEEP\`.\n- **Prose references to sibling skills** — write \`vibe-agent-toolkit:vat-audit\`, not \`[vat-audit](./vat-audit.md)\`. Markdown links to sibling SKILL.md files cause the packager to transclude the other skill (and fire \`LINK_TO_SKILL_DEFINITION\`).\n\nAvoid linking to navigation files (\`README.md\`, \`index.md\`) — they\'re excluded from the bundle and the link resolves to nothing (\`LINK_TO_NAVIGATION_FILE\`)."
|
|
27
|
+
},
|
|
28
|
+
packagingoptionsReference: {
|
|
29
|
+
header: "## packagingOptions Reference",
|
|
30
|
+
body: "Packaging options are configured per skill in \`vibe-agent-toolkit.config.yaml\` under \`skills.config.<name>\`:\n\n\`\`\`yaml\nskills:\n include: [\"resources/skills/SKILL.md\", \"resources/skills/*.md\"]\n defaults:\n linkFollowDepth: 2\n config:\n my-skill:\n linkFollowDepth: 1\n resourceNaming: resource-id\n stripPrefix: knowledge-base\n excludeReferencesFromBundle:\n rules:\n - patterns: [\"**/concepts/**\"]\n template: \"Use search to find: {{link.text}}\"\n defaultTemplate: \"{{link.text}} (search knowledge base)\"\n\`\`\`\n\n**\`linkFollowDepth\`** — How deep to follow links from SKILL.md:\n\n| Value | Behavior |\n|-------|----------|\n| \`0\` | Skill file only (no links followed) |\n| \`1\` | Direct links only |\n| \`2\` | Direct + one transitive level **(default)** |\n| \`\"full\"\` | Complete transitive closure |\n\n**\`resourceNaming\`** — How bundled files are named:\n\n| Strategy | Example | Use When |\n|----------|---------|----------|\n| \`basename\` | \`overview.md\` | Few files, unique names **(default)** |\n| \`resource-id\` | \`topics-quickstart-overview.md\` | Many files, flat output |\n| \`preserve-path\` | \`topics/quickstart/overview.md\` | Preserve structure |\n\nUse \`stripPrefix\` to remove a common directory prefix (e.g., \`\"knowledge-base\"\`).\n\n**\`excludeReferencesFromBundle\`** — Rules for excluding files and rewriting their links:\n\n- \`rules[]\` — ordered glob patterns (first match wins), each with optional Handlebars template\n- \`defaultTemplate\` — applied to depth-exceeded links not matching any rule\n\n**Template variables:**\n\n| Variable | Description |\n|----------|-------------|\n| \`{{link.text}}\` | Link display text |\n| \`{{link.href}}\` | Original href (without fragment) |\n| \`{{link.fragment}}\` | Fragment including \`#\` prefix, or empty |\n| \`{{link.type}}\` | Link type (\`\"local_file\"\`, etc.) |\n| \`{{link.resource.id}}\` | Target resource ID (if resolved) |\n| \`{{link.resource.fileName}}\` | Target filename (if resolved) |\n| \`{{skill.name}}\` | Skill name from frontmatter |",
|
|
31
|
+
text: "## packagingOptions Reference\n\nPackaging options are configured per skill in \`vibe-agent-toolkit.config.yaml\` under \`skills.config.<name>\`:\n\n\`\`\`yaml\nskills:\n include: [\"resources/skills/SKILL.md\", \"resources/skills/*.md\"]\n defaults:\n linkFollowDepth: 2\n config:\n my-skill:\n linkFollowDepth: 1\n resourceNaming: resource-id\n stripPrefix: knowledge-base\n excludeReferencesFromBundle:\n rules:\n - patterns: [\"**/concepts/**\"]\n template: \"Use search to find: {{link.text}}\"\n defaultTemplate: \"{{link.text}} (search knowledge base)\"\n\`\`\`\n\n**\`linkFollowDepth\`** — How deep to follow links from SKILL.md:\n\n| Value | Behavior |\n|-------|----------|\n| \`0\` | Skill file only (no links followed) |\n| \`1\` | Direct links only |\n| \`2\` | Direct + one transitive level **(default)** |\n| \`\"full\"\` | Complete transitive closure |\n\n**\`resourceNaming\`** — How bundled files are named:\n\n| Strategy | Example | Use When |\n|----------|---------|----------|\n| \`basename\` | \`overview.md\` | Few files, unique names **(default)** |\n| \`resource-id\` | \`topics-quickstart-overview.md\` | Many files, flat output |\n| \`preserve-path\` | \`topics/quickstart/overview.md\` | Preserve structure |\n\nUse \`stripPrefix\` to remove a common directory prefix (e.g., \`\"knowledge-base\"\`).\n\n**\`excludeReferencesFromBundle\`** — Rules for excluding files and rewriting their links:\n\n- \`rules[]\` — ordered glob patterns (first match wins), each with optional Handlebars template\n- \`defaultTemplate\` — applied to depth-exceeded links not matching any rule\n\n**Template variables:**\n\n| Variable | Description |\n|----------|-------------|\n| \`{{link.text}}\` | Link display text |\n| \`{{link.href}}\` | Original href (without fragment) |\n| \`{{link.fragment}}\` | Fragment including \`#\` prefix, or empty |\n| \`{{link.type}}\` | Link type (\`\"local_file\"\`, etc.) |\n| \`{{link.resource.id}}\` | Target resource ID (if resolved) |\n| \`{{link.resource.fileName}}\` | Target filename (if resolved) |\n| \`{{skill.name}}\` | Skill name from frontmatter |"
|
|
32
|
+
},
|
|
33
|
+
validationOverrides: {
|
|
34
|
+
header: "## Validation Overrides",
|
|
35
|
+
body: "The \`validation\` sub-key in a skill\'s config provides the unified override framework for VAT validation codes:\n\n\`\`\`yaml\nskills:\n config:\n my-skill:\n validation:\n severity:\n LINK_DROPPED_BY_DEPTH: error # upgrade: block on depth-dropped links\n LINK_TO_NAVIGATION_FILE: ignore # silence: this skill intentionally links to READMEs\n allow:\n PACKAGED_UNREFERENCED_FILE:\n - paths: [\"templates/runtime.json\"]\n reason: \"consumed programmatically at runtime\"\n expires: \"2026-09-30\"\n SKILL_LENGTH_EXCEEDS_RECOMMENDED:\n - reason: \"whole-skill concern; paths defaults to [\'**/*\']\"\n\`\`\`\n\nTwo sub-keys, each covering a different override granularity:\n\n- **\`severity\`** — class-level. Raise any code to \`error\` (blocks build), lower to \`warning\` (emits, non-blocking), or \`ignore\` (fully suppressed). Applies to every instance of that code.\n- **\`allow\`** — per-instance. Suppress specific \`(code, path)\` matches with a required \`reason\` and optional \`expires\` date. \`paths\` is optional (defaults to \`[\"**/*\"]\` — the whole skill). Use for legitimate exceptions that don\'t warrant code-wide silencing.\n\nCommon adjustments:\n\n- Downgrade \`LINK_DROPPED_BY_DEPTH\` to \`ignore\` when intentionally linking out to external docs.\n- Allow specific files under \`PACKAGED_UNREFERENCED_FILE\` when they\'re consumed programmatically by CLI scripts at runtime.\n- Raise \`ALLOW_EXPIRED\` to \`error\` for zero-tolerance expiry policies.\n\nExpired \`allow\` entries still apply — VAT emits \`ALLOW_EXPIRED\` as a reminder rather than silently re-surfacing the underlying issue (no surprise build breaks when a date passes). Unused \`allow\` entries surface as \`ALLOW_UNUSED\` (analogous to ESLint\'s unused-disable).\n\n\`vat audit\` is advisory: it applies \`severity\` for display grouping only, ignores \`allow\`, and always exits 0. Use \`vat skills validate\` or \`vat skills build\` for gated checks.",
|
|
36
|
+
text: "## Validation Overrides\n\nThe \`validation\` sub-key in a skill\'s config provides the unified override framework for VAT validation codes:\n\n\`\`\`yaml\nskills:\n config:\n my-skill:\n validation:\n severity:\n LINK_DROPPED_BY_DEPTH: error # upgrade: block on depth-dropped links\n LINK_TO_NAVIGATION_FILE: ignore # silence: this skill intentionally links to READMEs\n allow:\n PACKAGED_UNREFERENCED_FILE:\n - paths: [\"templates/runtime.json\"]\n reason: \"consumed programmatically at runtime\"\n expires: \"2026-09-30\"\n SKILL_LENGTH_EXCEEDS_RECOMMENDED:\n - reason: \"whole-skill concern; paths defaults to [\'**/*\']\"\n\`\`\`\n\nTwo sub-keys, each covering a different override granularity:\n\n- **\`severity\`** — class-level. Raise any code to \`error\` (blocks build), lower to \`warning\` (emits, non-blocking), or \`ignore\` (fully suppressed). Applies to every instance of that code.\n- **\`allow\`** — per-instance. Suppress specific \`(code, path)\` matches with a required \`reason\` and optional \`expires\` date. \`paths\` is optional (defaults to \`[\"**/*\"]\` — the whole skill). Use for legitimate exceptions that don\'t warrant code-wide silencing.\n\nCommon adjustments:\n\n- Downgrade \`LINK_DROPPED_BY_DEPTH\` to \`ignore\` when intentionally linking out to external docs.\n- Allow specific files under \`PACKAGED_UNREFERENCED_FILE\` when they\'re consumed programmatically by CLI scripts at runtime.\n- Raise \`ALLOW_EXPIRED\` to \`error\` for zero-tolerance expiry policies.\n\nExpired \`allow\` entries still apply — VAT emits \`ALLOW_EXPIRED\` as a reminder rather than silently re-surfacing the underlying issue (no surprise build breaks when a date passes). Unused \`allow\` entries surface as \`ALLOW_UNUSED\` (analogous to ESLint\'s unused-disable).\n\n\`vat audit\` is advisory: it applies \`severity\` for display grouping only, ignores \`allow\`, and always exits 0. Use \`vat skills validate\` or \`vat skills build\` for gated checks."
|
|
37
|
+
},
|
|
38
|
+
prePublicationCheck: {
|
|
39
|
+
header: "## Pre-publication Check",
|
|
40
|
+
body: "Before shipping a skill, walk through the \`vibe-agent-toolkit:vat-skill-review\` checklist — it covers naming, description quality, structure, validation-code triage, and Anthropic\'s skill-authoring best practices. The \`vat skill review <skill>\` CLI command renders a skill-specific view of the same checklist.",
|
|
41
|
+
text: "## Pre-publication Check\n\nBefore shipping a skill, walk through the \`vibe-agent-toolkit:vat-skill-review\` checklist — it covers naming, description quality, structure, validation-code triage, and Anthropic\'s skill-authoring best practices. The \`vat skill review <skill>\` CLI command renders a skill-specific view of the same checklist."
|
|
42
|
+
},
|
|
43
|
+
references: {
|
|
44
|
+
header: "## References",
|
|
45
|
+
body: "- \`vibe-agent-toolkit:vat-skill-review\` — pre-publication quality checklist (general + CLI-backed items, tied to VAT validation codes)\n- \`vibe-agent-toolkit:vat-skill-distribution\` — plugin/marketplace config, \`vat build\`, \`vat verify\`, npm publishing\n- \`vibe-agent-toolkit:vat-knowledge-resources\` — the \`resources:\` config section for multi-collection frontmatter schema validation\n- [Validation Codes Reference](../../../../docs/validation-codes.md) — full list of codes VAT emits, their default severity, and override recipes.\n- [Skill Quality and Compatibility — VAT\'s Stance](../../../../docs/skill-quality-and-compatibility.md) — what VAT believes makes a skill good and compatible.",
|
|
46
|
+
text: "## References\n\n- \`vibe-agent-toolkit:vat-skill-review\` — pre-publication quality checklist (general + CLI-backed items, tied to VAT validation codes)\n- \`vibe-agent-toolkit:vat-skill-distribution\` — plugin/marketplace config, \`vat build\`, \`vat verify\`, npm publishing\n- \`vibe-agent-toolkit:vat-knowledge-resources\` — the \`resources:\` config section for multi-collection frontmatter schema validation\n- [Validation Codes Reference](../../../../docs/validation-codes.md) — full list of codes VAT emits, their default severity, and override recipes.\n- [Skill Quality and Compatibility — VAT\'s Stance](../../../../docs/skill-quality-and-compatibility.md) — what VAT believes makes a skill good and compatible."
|
|
47
|
+
}
|
|
48
|
+
};
|
package/dist/generated/resources/skills/{vat-skills-distribution.js → vat-skill-distribution.js}
RENAMED
|
@@ -3,17 +3,17 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
export const meta = {
|
|
6
|
-
name: "distribution",
|
|
6
|
+
name: "vat-skill-distribution",
|
|
7
7
|
description: "Use when setting up \`vat build\`, configuring plugin distribution (marketplace, plugins, managed settings), npm publishing with postinstall hooks, or \`vat verify\` — 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## 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\": \"vat 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\`).** npm adds all \`bin\` entries from runtime dependencies to \`./node_modules/.bin/\` and puts that on PATH when running lifecycle scripts. This is how \`vat\` is available during your postinstall without being globally installed. If it is in \`devDependencies\`, npm will not install it on the user\'s machine and the postinstall will fail with \"command not found\".\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## Marketplace Distribution\n\nMarketplace distribution publishes a dedicated branch to GitHub that Claude Code users can install directly — no npm account or registry required.\n\n### How it works\n\n1. \`vat build\` compiles skills and plugin artifacts into \`dist/\`\n2. \`vat claude marketplace publish\` pushes the \`dist/.claude/\` tree to a dedicated branch (e.g. \`claude-marketplace\`) in your GitHub repo\n3. Users install via the slash command: \`/plugin marketplace add owner/repo#claude-marketplace\`\n\n### Configuration\n\nAdd a \`publish\` section under your marketplace in \`vibe-agent-toolkit.config.yaml\`:\n\n\`\`\`yaml\nclaude:\n marketplaces:\n my-marketplace:\n owner:\n name: My Organization\n plugins:\n - name: my-plugin\n description: My plugin description\n skills: \"*\"\n publish:\n github:\n repo: owner/repo # GitHub repo to publish to\n branch: claude-marketplace # branch that stores the installable artifacts\n\`\`\`\n\n### Publish workflow\n\n\`\`\`bash\nvat build # build all artifacts first\nvat claude marketplace publish # push dist/.claude/ to the publish branch\nvat claude marketplace publish --dry-run # preview what would be published (no push)\n\`\`\`\n\n### Consumer install\n\nOnce published, users install with:\n\n\`\`\`\n/plugin marketplace add owner/repo#claude-marketplace\n\`\`\`\n\nNo npm, no registry, no token required. Claude Code fetches the branch directly from GitHub.\n\n### Testing locally\n\nAfter publishing, verify the marketplace works end-to-end:\n\n\`\`\`bash\nclaude plugin marketplace add owner/repo#claude-marketplace\nclaude plugin install my-plugin@my-marketplace\nclaude plugin validate ~/.claude/plugins/cache/my-marketplace/my-plugin/<version>\nclaude plugin list # verify status: enabled\n\`\`\`\n\nStart a new Claude Code session to confirm skills load. See the [Marketplace Distribution Guide](https://github.com/jdutton/vibe-agent-toolkit/blob/main/docs/guides/marketplace-distribution.md#testing-your-marketplace) for the full testing checklist and known issues.\n\n**Note (Claude Code v2.1.81):** If re-adding a marketplace with the same name as an existing one (e.g., switching from npm to GitHub source), remove the old marketplace first: \`claude plugin marketplace remove <name>\` then re-add. Otherwise the old source is silently reused.\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 (\`vat 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## Running VAT Without Global Install\n\n\`\`\`bash\nnpx vibe-agent-toolkit <command> # npm/Node.js\nbunx vibe-agent-toolkit <command> # Bun\n\`\`\`\n\nAll \`vat\` commands in this skill work with these alternatives.\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";
|
|
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 the contributor reference at \`docs/contributing/vat-install-architecture.md\`\nin the \`vibe-agent-toolkit\` repo (contributor material, not bundled with this skill).\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\": \"vat 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\`).** npm adds all \`bin\` entries from runtime dependencies to \`./node_modules/.bin/\` and puts that on PATH when running lifecycle scripts. This is how \`vat\` is available during your postinstall without being globally installed. If it is in \`devDependencies\`, npm will not install it on the user\'s machine and the postinstall will fail with \"command not found\".\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## Marketplace Distribution\n\nMarketplace distribution publishes a dedicated branch to GitHub that Claude Code users can install directly — no npm account or registry required.\n\n### How it works\n\n1. \`vat build\` compiles skills and plugin artifacts into \`dist/\`\n2. \`vat claude marketplace publish\` pushes the \`dist/.claude/\` tree to a dedicated branch (e.g. \`claude-marketplace\`) in your GitHub repo\n3. Users install via the slash command: \`/plugin marketplace add owner/repo#claude-marketplace\`\n\n### Configuration\n\nAdd a \`publish\` section under your marketplace in \`vibe-agent-toolkit.config.yaml\`:\n\n\`\`\`yaml\nclaude:\n marketplaces:\n my-marketplace:\n owner:\n name: My Organization\n plugins:\n - name: my-plugin\n description: My plugin description\n skills: \"*\"\n publish:\n github:\n repo: owner/repo # GitHub repo to publish to\n branch: claude-marketplace # branch that stores the installable artifacts\n\`\`\`\n\n### Publish workflow\n\n\`\`\`bash\nvat build # build all artifacts first\nvat claude marketplace publish # push dist/.claude/ to the publish branch\nvat claude marketplace publish --dry-run # preview what would be published (no push)\n\`\`\`\n\n### Consumer install\n\nOnce published, users install with:\n\n\`\`\`\n/plugin marketplace add owner/repo#claude-marketplace\n\`\`\`\n\nNo npm, no registry, no token required. Claude Code fetches the branch directly from GitHub.\n\n### Testing locally\n\nAfter publishing, verify the marketplace works end-to-end:\n\n\`\`\`bash\nclaude plugin marketplace add owner/repo#claude-marketplace\nclaude plugin install my-plugin@my-marketplace\nclaude plugin validate ~/.claude/plugins/cache/my-marketplace/my-plugin/<version>\nclaude plugin list # verify status: enabled\n\`\`\`\n\nStart a new Claude Code session to confirm skills load. See the [Marketplace Distribution Guide](https://github.com/jdutton/vibe-agent-toolkit/blob/main/docs/guides/marketplace-distribution.md#testing-your-marketplace) for the full testing checklist and known issues.\n\n**Note (Claude Code v2.1.81):** If re-adding a marketplace with the same name as an existing one (e.g., switching from npm to GitHub source), remove the old marketplace first: \`claude plugin marketplace remove <name>\` then re-add. Otherwise the old source is silently reused.\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 (\`vat 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## Running VAT Without Global Install\n\n\`\`\`bash\nnpx vibe-agent-toolkit <command> # npm/Node.js\nbunx vibe-agent-toolkit <command> # Bun\n\`\`\`\n\nAll \`vat\` commands in this skill work with these alternatives.\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
13
|
scope: {
|
|
14
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
|
|
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
|
|
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 the contributor reference at \`docs/contributing/vat-install-architecture.md\`\nin the \`vibe-agent-toolkit\` repo (contributor material, not bundled with this skill).",
|
|
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 the contributor reference at \`docs/contributing/vat-install-architecture.md\`\nin the \`vibe-agent-toolkit\` repo (contributor material, not bundled with this skill)."
|
|
17
17
|
},
|
|
18
18
|
overview: {
|
|
19
19
|
header: "## Overview",
|
package/dist/generated/resources/skills/{skill-quality-checklist.d.ts → vat-skill-review.d.ts}
RENAMED
|
@@ -8,11 +8,15 @@ export interface Fragment {
|
|
|
8
8
|
readonly text: string;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
export const meta: {
|
|
11
|
+
export const meta: {
|
|
12
|
+
readonly name: string;
|
|
13
|
+
readonly description: string;
|
|
14
|
+
};
|
|
12
15
|
|
|
13
16
|
export const text: string;
|
|
14
17
|
|
|
15
18
|
export const fragments: {
|
|
19
|
+
readonly guidanceFreshness: Fragment;
|
|
16
20
|
readonly aboutThisChecklist: Fragment;
|
|
17
21
|
readonly general-AllSkills: Fragment;
|
|
18
22
|
readonly cliBackedSkills-AdditionalChecks: Fragment;
|
|
@@ -2,11 +2,19 @@
|
|
|
2
2
|
* Generated from markdown file - DO NOT EDIT
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
export const meta = {
|
|
5
|
+
export const meta = {
|
|
6
|
+
name: "vat-skill-review",
|
|
7
|
+
description: "Use when reviewing a skill before publication or running \`vat skill review\`. Pre-publication quality checklist grouped into general (all skills) and CLI-backed items, tied to VAT validation codes and Anthropic\'s skill-authoring best practices."
|
|
8
|
+
};
|
|
6
9
|
|
|
7
|
-
export const text = "# Skill Quality Checklist\n\nWork through this checklist before publishing a skill. Items are grouped into general (all skills) and CLI-backed (skills that bundle and invoke scripts).\n\n## About this checklist\n\nItems fall into two categories:\n\n- **[A]** items directly mirror Anthropic\'s official skill-authoring best practices (see the [cached guidance](../../../../docs/external/anthropic-skill-authoring-best-practices.md) or the [live doc](https://platform.claude.com/docs/en/docs/agents-and-tools/agent-skills/best-practices)). These are safe to treat as canonical.\n- **[VAT]** items are VAT-opinionated additions not explicitly in Anthropic\'s doc. They come from adopter experience, corpus observations, or Claude Code behavior changes. Individual teams can override any **[VAT]** item with \`validation.severity\` or \`validation.allow\` (with a \`reason\`).\n\nTooling enforcement: items marked with a bracketed code (e.g., \`[SKILL_DESCRIPTION_FILLER_OPENER]\`) are checked by \`vat skills validate\` / \`vat audit\`. The rest are judgment calls for a human or agent reviewer.\n\n## General — All Skills\n\n### Naming\n\n- **[A] Name format**: short, specific, lowercase-with-hyphens. Matches what the skill does, not how. \`[SKILL_NAME_INVALID]\` enforces this.\n- **[A] Prefer gerund form** (\`processing-pdfs\`, \`analyzing-spreadsheets\`). Anthropic recommends gerund form as the primary pattern — \"clearly describes the activity or capability the Skill provides.\" Noun phrases (\`pdf-processing\`) and action-oriented forms (\`process-pdfs\`) are \"acceptable alternatives.\" Avoid vague names like \`helper\`, \`utils\`, \`tools\`.\n- **[VAT] Name matches built skill directory name**: \`[SKILL_NAME_MISMATCHES_DIR]\` fires when the \`name\` frontmatter field differs from the parent directory name after build. The schema allows inference from the directory, but explicit mismatches are usually bugs.\n\n### Description\n\n- **[A] Trigger keywords first**: lead with the concepts that should trigger this skill. Claude truncates descriptions aggressively — the most important words must come first. \`Sprint analysis, velocity tracking, work item queries. Use when ...\` beats \`This skill is used for when you need to analyze sprints\`.\n- **[A] Third-person voice**: Anthropic guidance is unambiguous — \"**Always write in third person**. The description is injected into the system prompt, and inconsistent point-of-view can cause discovery problems.\" Avoid first/second person: \`I can help...\`, \`You can use...\`. \`[SKILL_DESCRIPTION_WRONG_PERSON]\` flags these.\n- **[A] \`Use when <concrete trigger>\` is the recommended pattern** — every Anthropic example uses it after a verb phrase. What\'s banned is vague variants like \`Use when you want to...\` / \`Use when you need to...\` that don\'t name a concrete trigger.\n- **[VAT] Prefer a verb phrase or \`Use when ...\` opener** — not a meta-description of the skill-as-object. \`[SKILL_DESCRIPTION_FILLER_OPENER]\` warns on \`This skill...\`, \`A skill that...\`, \`Used to...\` — these waste the first tokens describing the wrapper rather than the behavior. Anthropic doesn\'t ban these explicitly, but their own examples never use them; VAT is stricter here.\n- **[A] Be specific**: include both what the skill does and when to use it. \`[DESCRIPTION_TOO_VAGUE]\` fires below 50 chars. Anthropic\'s bad examples — \`Helps with documents\`, \`Processes data\`, \`Does stuff with files\` — are rejected for vagueness, not length.\n- **[VAT] Description ≤250 characters**: Claude Code truncates descriptions at 250 characters in the \`/skills\` listing (since v2.1.86). \`[SKILL_DESCRIPTION_OVER_CLAUDE_CODE_LIMIT]\` warns at 250; \`[SKILL_DESCRIPTION_TOO_LONG]\` errors at the 1024-char schema hard max. Aim for ≤200 chars for safety; ≤130 chars if shipping a large skill collection (60+ skills) so the total budget fits.\n\n### Body structure\n\n- **[A] SKILL.md body ≤500 lines**: Anthropic recommends keeping SKILL.md under 500 lines. \`[SKILL_LENGTH_EXCEEDS_RECOMMENDED]\` warns as you approach the limit. Split detailed content into reference files.\n- **[A] Purpose statement in first 3 lines**: an agent skimming the top of SKILL.md should understand what it does and when to use it without reading further.\n- **[A] Single responsibility**: the skill does one thing well. If it has multiple unrelated sections, consider splitting into separate skills.\n- **[A] Consistent terminology**: pick one term per concept and use it throughout. Mixing \`artifact\` / \`bundle\` / \`package\` confuses agents.\n- **[A] No time-sensitive content**: \`[SKILL_TIME_SENSITIVE_CONTENT]\` flags patterns like \`as of November 2025\` or \`after July 2026\`. Route deprecated guidance into a clearly labeled \`Old patterns\` section so agents skip it.\n\n### References and bundled files\n\n- **[A] Every bundled file is referenced**: if a file is in the package, some markdown file should link to it or explain what it is. \`[PACKAGED_UNREFERENCED_FILE]\` enforces this at build time. Dead files confuse agents and waste context.\n- **[A] References one level deep**: link reference files directly from SKILL.md, not via intermediate hubs. Claude does partial reads on nested references and may miss content several hops down. \`[REFERENCE_TOO_DEEP]\` enforces.\n- **[A] TOC on reference files >100 lines**: long reference files should include a table of contents at the top. Claude often previews with partial reads — a TOC ensures the full scope of available content is visible.\n- **[A] All links resolve**: every \`[text](path)\` link points to a file that exists. \`[LINK_MISSING_TARGET]\` and siblings enforce.\n- **[A] Build clean**: \`vat skills build\` succeeds and \`vat verify\` passes with zero errors.\n- **[A] Test the trigger**: ask \"if an agent sees only this name and description, will it know when to load this skill?\" If understanding the description requires reading the SKILL.md, the description is wrong.\n\n### Frontmatter hygiene\n\n- **[VAT] Frontmatter keys stay conservative**: use only the standard keys \`name\`, \`description\`, \`allowed-tools\` (plus \`argument-hint\` for slash-command-shaped skills). VAT generates SKILL.md under strict schema — novel keys like project-specific \`version:\` or \`metadata:\` fields will be rejected. If you need per-skill config, put it in \`vibe-agent-toolkit.config.yaml\`, not the frontmatter.\n- **[VAT] Sibling skills use consistent YAML styling**: within a single skill package, don\'t mix folded (\`description: >-\`) and inline (\`description: \"...\"\`) string forms. Pick one and apply it to every skill.\n\n### Cross-skill dependencies\n\n- **[VAT] State cross-skill dependencies in the description**: if this skill delegates auth, pre-flight, or setup to a sibling skill, say so in the description (\`Requires ado skill for auth\`). Agents may load one without the other; a silent dependency fails mysteriously at runtime.\n\n### Readability\n\n- **[VAT] Large tables move to reference files**: if a table exceeds ~15 rows, move it to a sibling reference file and link from SKILL.md. Long tables compete for context budget and push the main skill content further down.\n\n## CLI-Backed Skills — Additional Checks\n\nThese apply to skills that bundle executable scripts and instruct agents to run commands.\n\n- **[VAT] Environment guard**: the skill checks that the CLI binary exists before running commands (e.g., verify \`scripts/cli.mjs\` is present). Agents should get a clear error, not a cryptic Node.js stack trace.\n- **[VAT] Pre-flight auth check**: if the CLI requires credentials or tokens, the skill verifies them before operations. Fail fast with clear guidance on how to authenticate.\n- **[VAT] CLI invocation section**: provide exact command patterns with placeholder arguments. Agents copy these verbatim — ambiguous prose gets misinterpreted.\n- **[VAT] Error handling guidance**: document what to do when the CLI fails. Which errors are retryable? When should the agent stop and ask the user?\n- **[VAT] No bare command names in prose or tables**: agents may try to execute anything that looks like a command. Wrap command references in context or use code blocks with clear framing.\n- **[VAT] Cross-platform commands**: avoid \`timeout\` (not on macOS), platform-specific \`sed\` flags, \`grep -P\`, and other non-portable utilities. If platform-specific, document alternatives.\n- **[VAT] \`files\` config declares CLI binaries**: use \`files\` entries in \`vibe-agent-toolkit.config.yaml\` so VAT copies scripts into the skill package at build time. Don\'t rely on external copy scripts.\n- **[VAT] Document bundled assets and templates**: if scripts reference files programmatically (not via markdown links), explain what\'s bundled and why in the SKILL.md. The consuming agent should understand the full package contents.\n\n## Using This Checklist\n\nThis is a living document. When a new failure pattern is discovered in skill authoring, add a checklist item here. The goal is shift-left: catch issues before they ship rather than debugging them in production.\n\nItems marked as checks (not automated validation) are judgment calls that tooling can\'t fully enforce. An agent or human reviews them manually. Items that *can* be automated are enforced by \`vat skills validate\` / \`vat audit\` — their validation-code IDs are shown in brackets above.\n\nWhen a VAT validation code fires, its \`fix:\` field will suggest a concrete remediation; this checklist is the reference for the underlying principle. For a walkthrough that combines automated validation with this checklist, run \`vat skill review <path>\`.\n\n**Source of truth**: [Anthropic\'s skill-authoring best practices](https://platform.claude.com/docs/en/docs/agents-and-tools/agent-skills/best-practices). See [\`docs/external/anthropic-skill-authoring-best-practices.md\`](../../../../docs/external/anthropic-skill-authoring-best-practices.md) for a cached copy of the load-bearing portions with the VAT-vs-Anthropic delta called out.\n\nReviewed against external best practices (Anthropic skill-authoring docs, anthropics/skills repository, Claude Code release notes through 2026-04-18).\n";
|
|
10
|
+
export const text = "\n# Skill Quality Checklist (vat skill review)\n\nWork through this checklist before publishing a skill. Items are grouped into general (all skills) and CLI-backed (skills that bundle and invoke scripts).\n\nThis content is also surfaced by the \`vat skill review\` CLI command, which formats the checklist around a specific skill\'s validation output.\n\n## Guidance freshness\n\nSkill authoring standards move fast. Before applying this checklist to a non-trivial change:\n\n- Re-fetch the source of \`docs/external/anthropic-skill-authoring-best-practices.md\` named in its preamble. If the content has shifted, update the cache and this checklist together.\n- Web search for the latest Claude Code release notes when trigger semantics, frontmatter rules, or packaging behavior may have changed. Don\'t rely on training-data recall.\n- Promote any manual item below to a programmatic validator when the pattern is detectable from file contents — see the shift-left notes in \`packages/vat-development-agents/resources/skills/CLAUDE.md\`.\n\n## About this checklist\n\nItems fall into two categories:\n\n- **[A]** items directly mirror Anthropic\'s official skill-authoring best practices (see the [cached guidance](../../../../docs/external/anthropic-skill-authoring-best-practices.md) or the [live doc](https://platform.claude.com/docs/en/docs/agents-and-tools/agent-skills/best-practices)). These are safe to treat as canonical.\n- **[VAT]** items are VAT-opinionated additions not explicitly in Anthropic\'s doc. They come from adopter experience, corpus observations, or Claude Code behavior changes. Individual teams can override any **[VAT]** item with \`validation.severity\` or \`validation.allow\` (with a \`reason\`).\n\nTooling enforcement: items marked with a bracketed code (e.g., \`[SKILL_DESCRIPTION_FILLER_OPENER]\`) are checked by \`vat skills validate\` / \`vat audit\`. The rest are judgment calls for a human or agent reviewer.\n\n## General — All Skills\n\n### Naming\n\n- **[A] Name format**: short, specific, lowercase-with-hyphens. Matches what the skill does, not how. \`[SKILL_NAME_INVALID]\` enforces this.\n- **[A] Prefer gerund form** (\`processing-pdfs\`, \`analyzing-spreadsheets\`). Anthropic recommends gerund form as the primary pattern — \"clearly describes the activity or capability the Skill provides.\" Noun phrases (\`pdf-processing\`) and action-oriented forms (\`process-pdfs\`) are \"acceptable alternatives.\" Avoid vague names like \`helper\`, \`utils\`, \`tools\`.\n- **[VAT] Name matches built skill directory name**: \`[SKILL_NAME_MISMATCHES_DIR]\` fires when the \`name\` frontmatter field differs from the parent directory name after build. The schema allows inference from the directory, but explicit mismatches are usually bugs.\n\n### Description\n\n- **[A] Trigger keywords first**: lead with the concepts that should trigger this skill. Claude truncates descriptions aggressively — the most important words must come first. \`Sprint analysis, velocity tracking, work item queries. Use when ...\` beats \`This skill is used for when you need to analyze sprints\`.\n- **[A] Third-person voice**: Anthropic guidance is unambiguous — \"**Always write in third person**. The description is injected into the system prompt, and inconsistent point-of-view can cause discovery problems.\" Avoid first/second person: \`I can help...\`, \`You can use...\`. \`[SKILL_DESCRIPTION_WRONG_PERSON]\` flags these.\n- **[A] \`Use when <concrete trigger>\` is the recommended pattern** — every Anthropic example uses it after a verb phrase. What\'s banned is vague variants like \`Use when you want to...\` / \`Use when you need to...\` that don\'t name a concrete trigger.\n- **[VAT] Prefer a verb phrase or \`Use when ...\` opener** — not a meta-description of the skill-as-object. \`[SKILL_DESCRIPTION_FILLER_OPENER]\` warns on \`This skill...\`, \`A skill that...\`, \`Used to...\` — these waste the first tokens describing the wrapper rather than the behavior. Anthropic doesn\'t ban these explicitly, but their own examples never use them; VAT is stricter here.\n- **[A] Be specific**: include both what the skill does and when to use it. \`[DESCRIPTION_TOO_VAGUE]\` fires below 50 chars. Anthropic\'s bad examples — \`Helps with documents\`, \`Processes data\`, \`Does stuff with files\` — are rejected for vagueness, not length.\n- **[VAT] Description ≤250 characters**: Claude Code truncates descriptions at 250 characters in the \`/skills\` listing (since v2.1.86). \`[SKILL_DESCRIPTION_OVER_CLAUDE_CODE_LIMIT]\` warns at 250; \`[SKILL_DESCRIPTION_TOO_LONG]\` errors at the 1024-char schema hard max. Aim for ≤200 chars for safety; ≤130 chars if shipping a large skill collection (60+ skills) so the total budget fits.\n\n### Body structure\n\n- **[A] SKILL.md body ≤500 lines**: Anthropic recommends keeping SKILL.md under 500 lines. \`[SKILL_LENGTH_EXCEEDS_RECOMMENDED]\` warns as you approach the limit. Split detailed content into reference files.\n- **[A] Purpose statement in first 3 lines**: an agent skimming the top of SKILL.md should understand what it does and when to use it without reading further.\n- **[A] Single responsibility**: the skill does one thing well. If it has multiple unrelated sections, consider splitting into separate skills.\n- **[A] Consistent terminology**: pick one term per concept and use it throughout. Mixing \`artifact\` / \`bundle\` / \`package\` confuses agents.\n- **[A] No time-sensitive content**: \`[SKILL_TIME_SENSITIVE_CONTENT]\` flags patterns like \`as of November 2025\` or \`after July 2026\`. Route deprecated guidance into a clearly labeled \`Old patterns\` section so agents skip it.\n\n### References and bundled files\n\n- **[A] Every bundled file is referenced**: if a file is in the package, some markdown file should link to it or explain what it is. \`[PACKAGED_UNREFERENCED_FILE]\` enforces this at build time. Dead files confuse agents and waste context.\n- **[A] References one level deep**: link reference files directly from SKILL.md, not via intermediate hubs. Claude does partial reads on nested references and may miss content several hops down. \`[REFERENCE_TOO_DEEP]\` enforces.\n- **[A] TOC on reference files >100 lines**: long reference files should include a table of contents at the top. Claude often previews with partial reads — a TOC ensures the full scope of available content is visible.\n- **[A] All links resolve**: every \`[text](path)\` link points to a file that exists. \`[LINK_MISSING_TARGET]\` and siblings enforce.\n- **[A] Build clean**: \`vat skills build\` succeeds and \`vat verify\` passes with zero errors.\n- **[A] Test the trigger**: ask \"if an agent sees only this name and description, will it know when to load this skill?\" If understanding the description requires reading the SKILL.md, the description is wrong.\n\n### Frontmatter hygiene\n\n- **[VAT] Frontmatter keys stay conservative**: use only the standard keys \`name\`, \`description\`, \`allowed-tools\` (plus \`argument-hint\` for slash-command-shaped skills). VAT generates SKILL.md under strict schema — novel keys like project-specific \`version:\` or \`metadata:\` fields will be rejected. If you need per-skill config, put it in \`vibe-agent-toolkit.config.yaml\`, not the frontmatter.\n- **[VAT] Sibling skills use consistent YAML styling**: within a single skill package, don\'t mix folded (\`description: >-\`) and inline (\`description: \"...\"\`) string forms. Pick one and apply it to every skill.\n\n### Cross-skill dependencies\n\n- **[VAT] State cross-skill dependencies in the description**: if this skill delegates auth, pre-flight, or setup to a sibling skill, say so in the description (\`Requires ado skill for auth\`). Agents may load one without the other; a silent dependency fails mysteriously at runtime.\n\n### Readability\n\n- **[VAT] Large tables move to reference files**: if a table exceeds ~15 rows, move it to a sibling reference file and link from SKILL.md. Long tables compete for context budget and push the main skill content further down.\n\n## CLI-Backed Skills — Additional Checks\n\nThese apply to skills that bundle executable scripts and instruct agents to run commands.\n\n- **[VAT] Environment guard**: the skill checks that the CLI binary exists before running commands (e.g., verify \`scripts/cli.mjs\` is present). Agents should get a clear error, not a cryptic Node.js stack trace.\n- **[VAT] Pre-flight auth check**: if the CLI requires credentials or tokens, the skill verifies them before operations. Fail fast with clear guidance on how to authenticate.\n- **[VAT] CLI invocation section**: provide exact command patterns with placeholder arguments. Agents copy these verbatim — ambiguous prose gets misinterpreted.\n- **[VAT] Error handling guidance**: document what to do when the CLI fails. Which errors are retryable? When should the agent stop and ask the user?\n- **[VAT] No bare command names in prose or tables**: agents may try to execute anything that looks like a command. Wrap command references in context or use code blocks with clear framing.\n- **[VAT] Cross-platform commands**: avoid \`timeout\` (not on macOS), platform-specific \`sed\` flags, \`grep -P\`, and other non-portable utilities. If platform-specific, document alternatives.\n- **[VAT] \`files\` config declares CLI binaries**: use \`files\` entries in \`vibe-agent-toolkit.config.yaml\` so VAT copies scripts into the skill package at build time. Don\'t rely on external copy scripts.\n- **[VAT] Document bundled assets and templates**: if scripts reference files programmatically (not via markdown links), explain what\'s bundled and why in the SKILL.md. The consuming agent should understand the full package contents.\n\n## Using This Checklist\n\nThis is a living document. When a new failure pattern is discovered in skill authoring, add a checklist item here. The goal is shift-left: catch issues before they ship rather than debugging them in production.\n\nItems marked as checks (not automated validation) are judgment calls that tooling can\'t fully enforce. An agent or human reviews them manually. Items that *can* be automated are enforced by \`vat skills validate\` / \`vat audit\` — their validation-code IDs are shown in brackets above.\n\nWhen a VAT validation code fires, its \`fix:\` field will suggest a concrete remediation; this checklist is the reference for the underlying principle. For a walkthrough that combines automated validation with this checklist, run \`vat skill review <path>\`.\n\n**Source of truth**: [Anthropic\'s skill-authoring best practices](https://platform.claude.com/docs/en/docs/agents-and-tools/agent-skills/best-practices). See [\`docs/external/anthropic-skill-authoring-best-practices.md\`](../../../../docs/external/anthropic-skill-authoring-best-practices.md) for a cached copy of the load-bearing portions with the VAT-vs-Anthropic delta called out.\n\nReviewed against external best practices (Anthropic skill-authoring docs, anthropics/skills repository, Claude Code release notes through 2026-04-18).\n";
|
|
8
11
|
|
|
9
12
|
export const fragments = {
|
|
13
|
+
guidanceFreshness: {
|
|
14
|
+
header: "## Guidance freshness",
|
|
15
|
+
body: "Skill authoring standards move fast. Before applying this checklist to a non-trivial change:\n\n- Re-fetch the source of \`docs/external/anthropic-skill-authoring-best-practices.md\` named in its preamble. If the content has shifted, update the cache and this checklist together.\n- Web search for the latest Claude Code release notes when trigger semantics, frontmatter rules, or packaging behavior may have changed. Don\'t rely on training-data recall.\n- Promote any manual item below to a programmatic validator when the pattern is detectable from file contents — see the shift-left notes in \`packages/vat-development-agents/resources/skills/CLAUDE.md\`.",
|
|
16
|
+
text: "## Guidance freshness\n\nSkill authoring standards move fast. Before applying this checklist to a non-trivial change:\n\n- Re-fetch the source of \`docs/external/anthropic-skill-authoring-best-practices.md\` named in its preamble. If the content has shifted, update the cache and this checklist together.\n- Web search for the latest Claude Code release notes when trigger semantics, frontmatter rules, or packaging behavior may have changed. Don\'t rely on training-data recall.\n- Promote any manual item below to a programmatic validator when the pattern is detectable from file contents — see the shift-left notes in \`packages/vat-development-agents/resources/skills/CLAUDE.md\`."
|
|
17
|
+
},
|
|
10
18
|
aboutThisChecklist: {
|
|
11
19
|
header: "## About this checklist",
|
|
12
20
|
body: "Items fall into two categories:\n\n- **[A]** items directly mirror Anthropic\'s official skill-authoring best practices (see the [cached guidance](../../../../docs/external/anthropic-skill-authoring-best-practices.md) or the [live doc](https://platform.claude.com/docs/en/docs/agents-and-tools/agent-skills/best-practices)). These are safe to treat as canonical.\n- **[VAT]** items are VAT-opinionated additions not explicitly in Anthropic\'s doc. They come from adopter experience, corpus observations, or Claude Code behavior changes. Individual teams can override any **[VAT]** item with \`validation.severity\` or \`validation.allow\` (with a \`reason\`).\n\nTooling enforcement: items marked with a bracketed code (e.g., \`[SKILL_DESCRIPTION_FILLER_OPENER]\`) are checked by \`vat skills validate\` / \`vat audit\`. The rest are judgment calls for a human or agent reviewer.",
|