@vibe-agent-toolkit/vat-development-agents 0.1.32-rc.5 → 0.1.33-rc.1

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.
@@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ### Added
11
+ - Three new skill-smell validation codes (all default `warning`, per skill-smell philosophy):
12
+ - `SKILL_FRONTMATTER_EXTRA_FIELDS`: frontmatter contains keys beyond the standard agentskills.io + Claude Code set. Allowed keys derive from `AgentSkillFrontmatterSchema` at module load, so the rule tracks the schema. Actionable when adopters put project-specific fields (`version:`, `tools:`, `permissions:`) at top level — `metadata.*` is the right home for custom data.
13
+ - `SKILL_CROSS_SKILL_AUTH_UNDECLARED`: body prose declares a sibling-skill or `ANTHROPIC_*_KEY` dependency (e.g., "Requires `vibe-agent-toolkit:vat-enterprise-org`", "Requires `ANTHROPIC_ADMIN_API_KEY`") but the description omits it. Narrow heuristic to keep false-positive rate low; bare `ANTHROPIC_API_KEY` (the universal Claude-API default) is explicitly excluded.
14
+ - `SKILL_DESCRIPTION_STALE_IN_PACKAGE`: detector registered and documented; pipeline wiring deferred to a follow-up RC so adopters aren't surprised by an unexpected warning until the name is settled (the code detects mixed YAML scalar styles across sibling skills — not staleness — and is a rename candidate before it ships observable output).
15
+
16
+ ### Changed
17
+ - `actions/checkout` and `actions/setup-node` bumped from `@v4` to `@v6` across `.github/workflows/*.yml`. Runs on Node 24; removes the Sept-2026 deprecation warning on `v4` runners.
18
+
19
+ ### Fixed
20
+ - `packages/cli/test/system/audit-dogfooding.system.test.ts` test 1 (`should successfully audit vibe-agent-toolkit project root`) now runs on Windows. The `skipIf(process.platform === 'win32')` was added in 0.1.32 when the test timed out at 120s; the narrow `gitCheckIgnoredBatch` fallback fix that landed alongside it dropped audit wall time ~4x, so the smoke test fits in budget again. Windows CI will confirm.
21
+ - Stale JSDoc examples referencing `vibe-agent-toolkit:resources` (renamed to `vibe-agent-toolkit:vat-knowledge-resources` during the 0.1.32 plugin restructure) replaced with `vibe-agent-toolkit:vat-audit` in `packages/cli/src/commands/claude/plugin/build.ts`, `packages/cli/src/commands/skills/build.ts`, `packages/agent-schema/src/package-metadata.ts`, and the companion test constant.
22
+
23
+ ## [0.1.32] - 2026-04-19
24
+
10
25
  ### Added
11
26
  - **Evidence substrate** (`@vibe-agent-toolkit/agent-skills/evidence`). Parsers produce neutral `EvidenceRecord`s with stable pattern IDs from `PATTERN_REGISTRY`; a derivation step rolls evidence into capability `Observation`s; a verdict engine compares observations against declared targets. Designed so pattern refinement never changes the observation contract.
12
27
  - **`vat audit --verbose`** renders the evidence chain beneath each `CAPABILITY_*` observation — pattern ID, file, line, match text — and includes an `evidence[]` array in YAML output. Use it to debug false positives or confirm what a detector actually saw.
@@ -59,6 +74,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
59
74
  - **`SKILL_NAME_MISMATCHES_DIR` false positive:** the mismatch check no longer fires when `SKILL.md` lives directly inside a generic container directory (`skills/`, `resources/`). The parent directory name in those layouts carries no signal about what the skill is named.
60
75
  - Three directory-targeted markdown links in VAT docs (`CLAUDE.md`, `docs/README.md`, `docs/getting-started.md`) now point at specific files, silencing the corresponding `LINK_TARGETS_DIRECTORY` errors on VAT's own docs.
61
76
 
77
+ ### Performance
78
+ - **~4x speedup on monorepo-scale `vat audit`.** `gitCheckIgnoredBatch` (used by the audit walker for every directory it visits) was unconditionally running a per-path `isGitIgnored` fallback after the batch `git check-ignore --stdin` call — spawning one git subprocess per non-ignored path even when the batch's results were authoritative. The fallback now only runs when the batch exits 128 (the fatal "beyond a symbolic link" case it was designed for), per git's documented exit-code semantics. Measurements on the VAT monorepo: `vat audit .` drops from ~30s → ~7s on this laptop. Correctness verified on `avonrisk-sdlc` (which has gitignored symlinks into OneDrive) — audit produces the same zero-error, same-warning output in ~7s.
79
+
62
80
  ### Removed
63
81
  - **BREAKING:** `COMPAT_REQUIRES_BROWSER_AUTH`, `COMPAT_REQUIRES_LOCAL_SHELL`, `COMPAT_REQUIRES_EXTERNAL_CLI` codes (replaced by `CAPABILITY_*` + `COMPAT_TARGET_*`).
64
82
  - **BREAKING:** `CompatibilityEvidence` type, legacy `Verdict` string union (`'compatible' | 'needs-review' | 'incompatible'`), `ImpactLevel` type, `ALL_TARGETS` export, `aggregateVerdicts`, `hasNonOkImpact` helpers.
@@ -73,6 +91,17 @@ Pre-1.0 breaking. Callers must:
73
91
  3. If consuming `CompatibilityResult` programmatically, migrate from `analyzed`/`declared` fields to `verdicts`/`declaredTargets`.
74
92
  4. Declare runtime targets in at least one layer (plugin, marketplace defaults, or config) or accept `COMPAT_TARGET_UNDECLARED` info emissions.
75
93
  5. Run `vat audit --verbose` to inspect evidence and confirm the refactor's output matches intent.
94
+ 6. If any prompt, CLAUDE.md, or repo-level doc references the `vibe-agent-toolkit` Claude plugin skills by their old names, update them:
95
+ - `vibe-agent-toolkit:authoring` → `vibe-agent-toolkit:vat-skill-authoring` (SKILL.md side) or `vibe-agent-toolkit:vat-agent-authoring` (TypeScript-agent side)
96
+ - `vibe-agent-toolkit:resources` → `vibe-agent-toolkit:vat-knowledge-resources`
97
+ - `vibe-agent-toolkit:distribution` → `vibe-agent-toolkit:vat-skill-distribution`
98
+ - `vibe-agent-toolkit:org-admin` → `vibe-agent-toolkit:vat-enterprise-org`
99
+ - `vibe-agent-toolkit:audit` → `vibe-agent-toolkit:vat-audit`
100
+ - `vibe-agent-toolkit:debugging` — retired from the plugin; the contributor guide lives at `docs/contributing/vat-debugging.md` in the VAT repo.
101
+ - `vibe-agent-toolkit:install` — retired from the plugin; the architecture doc lives at `docs/contributing/vat-install-architecture.md` in the VAT repo.
102
+ - The `skill-quality-checklist` skill is now `vibe-agent-toolkit:vat-skill-review` (also accessible via `vat skill review <path>` CLI).
103
+ Adopter repos that don't invoke the VAT plugin skills by name need no changes.
104
+ 7. Replace any `SKILL_NAME_RESERVED_WORD` references in `validation.severity` / `validation.allow` with `RESERVED_WORD_IN_NAME`. Default severity is now `warning` (was error); re-override if your policy demands `error`.
76
105
 
77
106
  ## [0.1.31] - 2026-04-17
78
107
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vibe-agent-toolkit",
3
3
  "description": "Development agents and skills for building with vibe-agent-toolkit",
4
- "version": "0.1.32-rc.5",
4
+ "version": "0.1.33-rc.1",
5
5
  "author": {
6
6
  "name": "vibe-agent-toolkit contributors"
7
7
  }
@@ -6,7 +6,7 @@ description: Use for Anthropic Enterprise/Team org administration via the Admin
6
6
  # Claude Org Administration
7
7
 
8
8
  **For Anthropic org admins only.** Requires `ANTHROPIC_ADMIN_API_KEY` (Enterprise/Team plan).
9
- If you don't have an admin key, this skill is not for you — use `vibe-agent-toolkit:distribution`
9
+ If you don't have an admin key, this skill is not for you — use `vibe-agent-toolkit:vat-skill-distribution`
10
10
  for local plugin management instead.
11
11
 
12
12
  ## Two Ways to Use It
@@ -62,12 +62,12 @@ Tooling enforcement: items marked with a bracketed code (e.g., `[SKILL_DESCRIPTI
62
62
 
63
63
  ### Frontmatter hygiene
64
64
 
65
- - **[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.
66
- - **[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.
65
+ - **[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. `[SKILL_FRONTMATTER_EXTRA_FIELDS]` warns on non-standard keys.
66
+ - **[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. `[SKILL_DESCRIPTION_STALE_IN_PACKAGE]` flags mixed styles across a package (detector implemented, pipeline wiring pending).
67
67
 
68
68
  ### Cross-skill dependencies
69
69
 
70
- - **[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.
70
+ - **[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. `[SKILL_CROSS_SKILL_AUTH_UNDECLARED]` flags body prose that requires a sibling skill or `ANTHROPIC_*_KEY` env var without naming it in the description.
71
71
 
72
72
  ### Readability
73
73
 
@@ -7,7 +7,7 @@ export const meta = {
7
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: {
@@ -7,7 +7,7 @@ export const meta = {
7
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
8
  };
9
9
 
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";
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. \`[SKILL_FRONTMATTER_EXTRA_FIELDS]\` warns on non-standard keys.\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. \`[SKILL_DESCRIPTION_STALE_IN_PACKAGE]\` flags mixed styles across a package (detector implemented, pipeline wiring pending).\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. \`[SKILL_CROSS_SKILL_AUTH_UNDECLARED]\` flags body prose that requires a sibling skill or \`ANTHROPIC_*_KEY\` env var without naming it in the description.\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";
11
11
 
12
12
  export const fragments = {
13
13
  guidanceFreshness: {
@@ -22,8 +22,8 @@ export const fragments = {
22
22
  },
23
23
  general-AllSkills: {
24
24
  header: "## General — All Skills",
25
- body: "### 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.",
26
- text: "## 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."
25
+ body: "### 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. \`[SKILL_FRONTMATTER_EXTRA_FIELDS]\` warns on non-standard keys.\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. \`[SKILL_DESCRIPTION_STALE_IN_PACKAGE]\` flags mixed styles across a package (detector implemented, pipeline wiring pending).\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. \`[SKILL_CROSS_SKILL_AUTH_UNDECLARED]\` flags body prose that requires a sibling skill or \`ANTHROPIC_*_KEY\` env var without naming it in the description.\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.",
26
+ text: "## 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. \`[SKILL_FRONTMATTER_EXTRA_FIELDS]\` warns on non-standard keys.\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. \`[SKILL_DESCRIPTION_STALE_IN_PACKAGE]\` flags mixed styles across a package (detector implemented, pipeline wiring pending).\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. \`[SKILL_CROSS_SKILL_AUTH_UNDECLARED]\` flags body prose that requires a sibling skill or \`ANTHROPIC_*_KEY\` env var without naming it in the description.\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."
27
27
  },
28
28
  cliBackedSkills-AdditionalChecks: {
29
29
  header: "## CLI-Backed Skills — Additional Checks",
@@ -6,7 +6,7 @@ description: Use for Anthropic Enterprise/Team org administration via the Admin
6
6
  # Claude Org Administration
7
7
 
8
8
  **For Anthropic org admins only.** Requires `ANTHROPIC_ADMIN_API_KEY` (Enterprise/Team plan).
9
- If you don't have an admin key, this skill is not for you — use `vibe-agent-toolkit:distribution`
9
+ If you don't have an admin key, this skill is not for you — use `vibe-agent-toolkit:vat-skill-distribution`
10
10
  for local plugin management instead.
11
11
 
12
12
  ## Two Ways to Use It
@@ -62,12 +62,12 @@ Tooling enforcement: items marked with a bracketed code (e.g., `[SKILL_DESCRIPTI
62
62
 
63
63
  ### Frontmatter hygiene
64
64
 
65
- - **[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.
66
- - **[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.
65
+ - **[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. `[SKILL_FRONTMATTER_EXTRA_FIELDS]` warns on non-standard keys.
66
+ - **[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. `[SKILL_DESCRIPTION_STALE_IN_PACKAGE]` flags mixed styles across a package (detector implemented, pipeline wiring pending).
67
67
 
68
68
  ### Cross-skill dependencies
69
69
 
70
- - **[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.
70
+ - **[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. `[SKILL_CROSS_SKILL_AUTH_UNDECLARED]` flags body prose that requires a sibling skill or `ANTHROPIC_*_KEY` env var without naming it in the description.
71
71
 
72
72
  ### Readability
73
73
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibe-agent-toolkit/vat-development-agents",
3
- "version": "0.1.32-rc.5",
3
+ "version": "0.1.33-rc.1",
4
4
  "description": "VAT development agents - dogfooding the vibe-agent-toolkit",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -67,13 +67,13 @@
67
67
  "postinstall": "vat claude plugin install --npm-postinstall || exit 0"
68
68
  },
69
69
  "dependencies": {
70
- "@vibe-agent-toolkit/agent-schema": "0.1.32-rc.5",
71
- "@vibe-agent-toolkit/cli": "0.1.32-rc.5",
70
+ "@vibe-agent-toolkit/agent-schema": "0.1.33-rc.1",
71
+ "@vibe-agent-toolkit/cli": "0.1.33-rc.1",
72
72
  "yaml": "^2.8.2"
73
73
  },
74
74
  "devDependencies": {
75
75
  "@types/node": "^25.0.3",
76
- "@vibe-agent-toolkit/resource-compiler": "0.1.32-rc.5",
76
+ "@vibe-agent-toolkit/resource-compiler": "0.1.33-rc.1",
77
77
  "ts-patch": "^3.2.1",
78
78
  "typescript": "^5.7.3"
79
79
  },