@vibe-agent-toolkit/vat-development-agents 0.1.29 → 0.1.30-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/.claude/plugins/marketplaces/vat-skills/CHANGELOG.md +20 -0
  2. package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/.claude-plugin/plugin.json +1 -1
  3. package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/audit/SKILL.md +21 -16
  4. package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/authoring/SKILL.md +30 -12
  5. package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/authoring/resources/skill-quality-checklist.md +42 -0
  6. package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/debugging/SKILL.md +4 -4
  7. package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/vibe-agent-toolkit/SKILL.md +6 -6
  8. package/dist/generated/resources/skills/vat-agent-authoring.js +3 -3
  9. package/dist/generated/resources/skills/vat-audit.js +5 -5
  10. package/dist/skills/audit/SKILL.md +21 -16
  11. package/dist/skills/authoring/SKILL.md +30 -12
  12. package/dist/skills/authoring/resources/skill-quality-checklist.md +42 -0
  13. package/dist/skills/debugging/SKILL.md +4 -4
  14. package/dist/skills/vibe-agent-toolkit/SKILL.md +6 -6
  15. package/package.json +4 -4
  16. package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/debugging/resources/CLAUDE.md +0 -539
  17. package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/debugging/resources/debug-and-test-vat-fixes.md +0 -111
  18. package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/debugging/resources/writing-tests.md +0 -577
  19. package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/vibe-agent-toolkit/resources/adding-runtime-adapters.md +0 -628
  20. package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/vibe-agent-toolkit/resources/agent-authoring.md +0 -905
  21. package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/vibe-agent-toolkit/resources/compiling-markdown-to-typescript.md +0 -501
  22. package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/vibe-agent-toolkit/resources/getting-started.md +0 -360
  23. package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/vibe-agent-toolkit/resources/orchestration.md +0 -859
  24. package/dist/.claude/plugins/marketplaces/vat-skills/plugins/vibe-agent-toolkit/skills/vibe-agent-toolkit/resources/rag-usage-guide.md +0 -770
  25. package/dist/skills/debugging/resources/CLAUDE.md +0 -539
  26. package/dist/skills/debugging/resources/debug-and-test-vat-fixes.md +0 -111
  27. package/dist/skills/debugging/resources/writing-tests.md +0 -577
  28. package/dist/skills/vibe-agent-toolkit/resources/adding-runtime-adapters.md +0 -628
  29. package/dist/skills/vibe-agent-toolkit/resources/agent-authoring.md +0 -905
  30. package/dist/skills/vibe-agent-toolkit/resources/compiling-markdown-to-typescript.md +0 -501
  31. package/dist/skills/vibe-agent-toolkit/resources/getting-started.md +0 -360
  32. package/dist/skills/vibe-agent-toolkit/resources/orchestration.md +0 -859
  33. package/dist/skills/vibe-agent-toolkit/resources/rag-usage-guide.md +0 -770
@@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ### Changed
11
+ - **BREAKING: Unified validation framework replaces `ignoreValidationErrors`.** Every overridable integrity check now flows through a single `validation` block (`severity` + `allow`) under `skills.defaults` / `skills.config.<name>` in `vibe-agent-toolkit.config.yaml`. The previous non-overridable error tier (`OUTSIDE_PROJECT_BOUNDARY`, `LINK_TARGETS_DIRECTORY`, `LINKS_TO_NAVIGATION_FILES`) is removed and replaced by unified `LINK_*` codes that accept the same overrides as everything else. Project-config schemas are now strict — configs containing the removed `ignoreValidationErrors` field (or any other unknown key) fail at parse time with `"Unrecognized key(s) in object"` instead of silently dropping, so upgrades surface the migration work immediately. See [jdutton/vibe-agent-toolkit#83](https://github.com/jdutton/vibe-agent-toolkit/issues/83) for full design rationale and the canonical code reference at `docs/validation-codes.md`.
12
+ - **BREAKING: `PACKAGED_UNREFERENCED_FILE` and `PACKAGED_BROKEN_LINK` now block the build.** Previously logged at info level without affecting exit code; now default severity `error` with `vat skills build` exiting `1`. Downgrade via `validation.severity: { PACKAGED_UNREFERENCED_FILE: warning }` if needed.
13
+ - **BREAKING: Expired `allow` entries no longer silently re-fire the underlying error.** The allow entry still applies; VAT emits a new `ALLOW_EXPIRED` warning to surface the stale date for re-review. Opt in to strict expiry with `validation.severity: { ALLOW_EXPIRED: error }`.
14
+ - **`vat audit` is now advisory.** Audit always exits `0` regardless of validation severity, honors `validation.severity` for display grouping only, and ignores `validation.allow`. Use `vat skills validate` or `vat skills build` for gated checks with per-path allow entries.
15
+
16
+ ### Added
17
+ - **New validation codes** — `LINK_OUTSIDE_PROJECT`, `LINK_TARGETS_DIRECTORY`, `LINK_TO_NAVIGATION_FILE`, `LINK_TO_GITIGNORED_FILE`, `LINK_MISSING_TARGET`, `LINK_TO_SKILL_DEFINITION`, `LINK_DROPPED_BY_DEPTH`, `ALLOW_EXPIRED`, `ALLOW_UNUSED`. Full reference at `docs/validation-codes.md` with defaults, descriptions, and fix hints. `LINK_TO_SKILL_DEFINITION` fires only for cross-skill SKILL.md references; transitive self-references (a bundled resource linking back to the skill's own SKILL.md) are treated as no-ops.
18
+ - **`LINK_MISSING_TARGET`** closes a previously silent walker drop path: links to non-existent (non-deferred) files are now reported at the walker with a clear message, rather than only surfacing post-build as a generic `PACKAGED_BROKEN_LINK`.
19
+ - **`ALLOW_UNUSED`** — analogous to ESLint's unused-disable — surfaces `allow` entries that match no emitted issues.
20
+ - **Per-path `validation.allow`** with required `reason` and optional `expires` date, providing an audit trail for legitimate exceptions. `paths` is optional and defaults to `["**/*"]` (the whole skill) — so concerns that apply to an entire skill can omit the paths array entirely.
21
+ - **Canonical code reference** at `docs/validation-codes.md`, test-locked against the code registry so new codes cannot ship without documentation.
22
+
23
+ ### Migration
24
+
25
+ | Old | New |
26
+ |---|---|
27
+ | `ignoreValidationErrors: { CODE: "reason" }` | `validation.severity: { CODE: ignore }` |
28
+ | `ignoreValidationErrors: { CODE: { reason, expires } }` | `validation.severity: { CODE: ignore }` for code-wide silence, OR `validation.allow: { CODE: [{ paths, reason, expires }] }` for scoped allow entries with re-review on expiry |
29
+
10
30
  ## [0.1.29] - 2026-04-16
11
31
 
12
32
  ### Added
@@ -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.29",
4
+ "version": "0.1.30-rc.2",
5
5
  "author": {
6
6
  "name": "vibe-agent-toolkit contributors"
7
7
  }
@@ -69,9 +69,12 @@ Use this before a release to determine which surfaces each plugin supports.
69
69
 
70
70
  ## Exit Codes
71
71
 
72
- - `0`clean (or `--user` mode: always 0, informational)
73
- - `1` — validation errors found
74
- - `2` — system error (path not found, permission denied)
72
+ `vat audit` is **advisory** it reports every issue it detects but never blocks on validation severity:
73
+
74
+ - `0` — always, when the audit completes, regardless of errors or warnings in the report.
75
+ - `2` — system error (path not found, permission denied, etc.) — the audit could not run.
76
+
77
+ For gated checks that exit `1` on validation errors, use `vat skills validate` or `vat skills build` instead. Those commands apply `validation.severity` and honor `validation.allow` from config.
75
78
 
76
79
  ## CI Usage
77
80
 
@@ -93,19 +96,21 @@ summary:
93
96
  errors: 0
94
97
  ```
95
98
 
96
- Warnings (exit 0) vs errors (exit 1):
97
- - **Errors:** Missing required frontmatter, broken links, invalid plugin.json schema
99
+ Severity taxonomy in audit output:
100
+ - **Errors:** Missing required frontmatter, broken links, invalid plugin.json schema, link integrity violations
98
101
  - **Warnings:** Skill too long, description too short, best practice violations
99
102
 
100
- Suppress specific warnings with `ignoreValidationErrors` in `package.json`:
101
- ```json
102
- {
103
- "vat": {
104
- "skills": [{
105
- "ignoreValidationErrors": {
106
- "SKILL_LENGTH_EXCEEDS_RECOMMENDED": "Complex domain requires full detail"
107
- }
108
- }]
109
- }
110
- }
103
+ Audit always exits `0` regardless — surface-level severity drives display grouping only.
104
+
105
+ **Hiding codes from audit output.** Audit ignores `validation.allow` by design (it is the read-only report), but it does honor `validation.severity`. Set a code to `ignore` in `vibe-agent-toolkit.config.yaml` to suppress it from the audit output:
106
+
107
+ ```yaml
108
+ skills:
109
+ config:
110
+ my-skill:
111
+ validation:
112
+ severity:
113
+ LINK_TO_NAVIGATION_FILE: ignore # hidden from audit output
111
114
  ```
115
+
116
+ **Per-instance allow entries.** For per-path suppression with an audit trail, use `validation.allow` and run `vat skills validate` or `vat skills build` — those commands apply `allow` and gate the build. See `docs/validation-codes.md` for the full code reference and the VAT agent-authoring skill for configuration patterns.
@@ -298,19 +298,37 @@ Use `stripPrefix` to remove a common directory prefix (e.g., `"knowledge-base"`)
298
298
  | `{{link.resource.fileName}}` | Target filename (if resolved) |
299
299
  | `{{skill.name}}` | Skill name from frontmatter |
300
300
 
301
- **`ignoreValidationErrors`** — Override specific validation rules when justified:
302
-
303
- ```json
304
- "ignoreValidationErrors": {
305
- "SKILL_LENGTH_EXCEEDS_RECOMMENDED": "Large domain requires detailed examples",
306
- "NO_PROGRESSIVE_DISCLOSURE": {
307
- "reason": "Temporary refactoring planned",
308
- "expires": "2026-06-30"
309
- }
310
- }
301
+ **`validation`** — Unified framework for overriding default severity and allowing specific issue instances:
302
+
303
+ ```yaml
304
+ # In vibe-agent-toolkit.config.yaml under skills.defaults or skills.config.<name>
305
+ validation:
306
+ severity:
307
+ LINK_DROPPED_BY_DEPTH: error # upgrade: block on depth-dropped links
308
+ LINK_TO_NAVIGATION_FILE: ignore # silence: this skill intentionally links to READMEs
309
+ allow:
310
+ PACKAGED_UNREFERENCED_FILE:
311
+ - paths: ["templates/runtime.json"]
312
+ reason: "consumed programmatically at runtime"
313
+ expires: "2026-09-30"
314
+ SKILL_LENGTH_EXCEEDS_RECOMMENDED:
315
+ - reason: "whole-skill concern; paths defaults to ['**/*']"
311
316
  ```
312
317
 
313
- Use sparingly. Prefer fixing the underlying issue over suppressing warnings.
318
+ Two sub-keys, each covering a different override granularity:
319
+
320
+ - **`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.
321
+ - **`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.
322
+
323
+ Things adopters typically adjust:
324
+
325
+ - Downgrade `LINK_DROPPED_BY_DEPTH` to `ignore` when intentionally linking out to external docs.
326
+ - Allow specific files under `PACKAGED_UNREFERENCED_FILE` when they're consumed programmatically by CLI scripts at runtime.
327
+ - Raise `ALLOW_EXPIRED` to `error` for zero-tolerance expiry policies.
328
+
329
+ Expired `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).
330
+
331
+ Full code reference at `docs/validation-codes.md`. `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.
314
332
 
315
333
  ## Testing Agents
316
334
 
@@ -368,7 +386,7 @@ const output2 = await agent.execute({
368
386
 
369
387
  ## References
370
388
 
371
- - Skill Quality Checklist — Pre-publication checklist for all skills (general + CLI-backed)
389
+ - [Skill Quality Checklist](resources/skill-quality-checklist.md) — Pre-publication checklist for all skills (general + CLI-backed)
372
390
  - agent-authoring.md — Complete patterns guide
373
391
  - orchestration.md — Multi-agent workflows
374
392
  - [Building Effective Agents - Anthropic](https://www.anthropic.com/research/building-effective-agents)
@@ -0,0 +1,42 @@
1
+ # Skill Quality Checklist
2
+
3
+ Work through this checklist before publishing a skill. Items are grouped into general (all skills) and CLI-backed (skills that bundle and invoke scripts).
4
+
5
+ ## General — All Skills
6
+
7
+ - [ ] **Name**: short, specific, lowercase-with-hyphens. Matches what the skill does, not how.
8
+ - [ ] **Description — 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" not "This skill is used for when you need to analyze sprints."
9
+ - [ ] **Description — no filler openers, third-person voice**: never start with "This skill...", "A skill that...", "Used to...", "Use when you want to..." — these waste the first tokens on zero-information words. Avoid first/second person ("I can help...", "You can use...") — Anthropic guidance is third person throughout.
10
+ - [ ] **Description ≤250 characters**: Claude Code truncates descriptions at 250 characters in the `/skills` listing (since v2.1.86). Aim for ≤200 chars for safety; ≤130 chars if shipping a large skill collection (60+ skills) so the total budget fits.
11
+ - [ ] **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.
12
+ - [ ] **SKILL.md body ≤500 lines**: Anthropic recommends keeping SKILL.md under 500 lines. Split detailed content into reference files when approaching the limit.
13
+ - [ ] **Single responsibility**: the skill does one thing well. If it has multiple unrelated sections, consider splitting into separate skills.
14
+ - [ ] **Consistent terminology**: pick one term per concept and use it throughout. Switching between synonyms ("artifact" vs "bundle" vs "package") confuses agents.
15
+ - [ ] **No time-sensitive content**: avoid "as of November 2025" or "use the new API after July 2026". Route deprecated guidance into a clearly labeled "old patterns" section so agents skip it.
16
+ - [ ] **Every bundled file is referenced**: if a file is in the package, some markdown file should link to it or explain what it is. Dead files confuse agents and waste context.
17
+ - [ ] **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.
18
+ - [ ] **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.
19
+ - [ ] **All links resolve**: every `[text](path)` link points to a file that exists. Run `vat verify` to check.
20
+ - [ ] **Build clean**: `vat skills build` succeeds and `vat verify` passes with zero errors.
21
+ - [ ] **Test the trigger**: ask yourself "if an agent sees only this name and description, will it know when to load this skill?" If you need to read the SKILL.md to understand the description, the description is wrong.
22
+
23
+ ## CLI-Backed Skills — Additional Checks
24
+
25
+ These apply to skills that bundle executable scripts and instruct agents to run commands.
26
+
27
+ - [ ] **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.
28
+ - [ ] **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.
29
+ - [ ] **CLI invocation section**: provide exact command patterns with placeholder arguments. Agents copy these verbatim — ambiguous prose gets misinterpreted.
30
+ - [ ] **Error handling guidance**: document what to do when the CLI fails. Which errors are retryable? When should the agent stop and ask the user?
31
+ - [ ] **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.
32
+ - [ ] **Cross-platform commands**: avoid `timeout` (not on macOS), platform-specific `sed` flags, `grep -P`, and other non-portable utilities. If platform-specific, document alternatives.
33
+ - [ ] **`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.
34
+ - [ ] **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.
35
+
36
+ ## Using This Checklist
37
+
38
+ This 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.
39
+
40
+ Items 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 already enforced by `vat verify` — this checklist covers the gaps.
41
+
42
+ Reviewed against external best practices (Anthropic skills documentation, anthropics/skills repository, superpowers conventions, Claude Code release notes through 2026-04-15) before initial publication.
@@ -79,7 +79,7 @@ Before changing VAT source code, write a test that reproduces the bug:
79
79
  - **CLI behavior** → add an integration test in `packages/cli/test/integration/`
80
80
  - **End-to-end workflow** → add a system test in `packages/cli/test/system/`
81
81
 
82
- See [docs/writing-tests.md](resources/writing-tests.md) for test patterns and
82
+ See docs/writing-tests.md for test patterns and
83
83
  the unit/integration/system classification guide.
84
84
 
85
85
  ## Step 5: Validate Before Committing
@@ -106,6 +106,6 @@ is safe to commit. Do not commit until `bun run validate` passes.
106
106
 
107
107
  ## See Also
108
108
 
109
- - [docs/debug-and-test-vat-fixes.md](resources/debug-and-test-vat-fixes.md) — Full reference
110
- - [docs/writing-tests.md](resources/writing-tests.md) — Test patterns and classification
111
- - [packages/cli/CLAUDE.md](resources/CLAUDE.md) — CLI development guidelines
109
+ - docs/debug-and-test-vat-fixes.md — Full reference
110
+ - docs/writing-tests.md — Test patterns and classification
111
+ - [packages/cli/CLAUDE.md]() — CLI development guidelines
@@ -182,12 +182,12 @@ You've successfully adopted VAT when:
182
182
 
183
183
  ## Documentation Index
184
184
 
185
- - [Getting Started Guide](resources/getting-started.md)
186
- - [Agent Authoring Guide](resources/agent-authoring.md) — patterns and code examples
187
- - [Orchestration Guide](resources/orchestration.md) — multi-agent workflows
188
- - [RAG Usage Guide](resources/rag-usage-guide.md)
189
- - [Resource Compiler Guide](resources/compiling-markdown-to-typescript.md)
190
- - [Runtime Adapters](resources/adding-runtime-adapters.md)
185
+ - Getting Started Guide
186
+ - Agent Authoring Guide — patterns and code examples
187
+ - Orchestration Guide — multi-agent workflows
188
+ - RAG Usage Guide
189
+ - Resource Compiler Guide
190
+ - Runtime Adapters
191
191
  - Examples: `@vibe-agent-toolkit/vat-example-cat-agents`
192
192
 
193
193
  ## Running VAT
@@ -7,7 +7,7 @@ export const meta = {
7
7
  description: "Use when authoring SKILL.md files, designing agent architectures, or configuring packaging options. Covers SKILL.md structure, agent archetypes, orchestration patterns, and validation override patterns."
8
8
  };
9
9
 
10
- export const text = "\n# VAT Agent Authoring: SKILL.md, Archetypes & Patterns\n\n## SKILL.md Structure\n\nA SKILL.md file is the definition file for a VAT agent skill. It tells Claude what the skill\ndoes 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 (max 200 chars)\n---\n\n# My Skill\n\nRest of the skill documentation...\n\`\`\`\n\nRequired frontmatter fields:\n- \`name\` — unique identifier, kebab-case, matches the skill\'s directory name\n- \`description\` — trigger description used for skill routing; be specific about activation conditions\n\nBest practices for \`description\`:\n- Start with \"Use when...\" to make activation conditions explicit\n- Include the key commands or concepts the skill covers\n- Keep under 200 characters\n\n## Agent Archetypes\n\nVAT supports four agent archetypes for different use cases.\n\n### Archetype 1: Pure Function Tool\n\n**When to use:** Stateless validation, transformation, computation — no LLM needed.\n\n**Characteristics:** Deterministic output, fast execution, easy to test.\n\n**Example use cases:** Input validation, data transformation, format conversion, rules-based logic.\n\n\`\`\`typescript\nexport async function validateInput(input: MyInput): Promise<ValidationResult> {\n if (input.text.length < 5) {\n return { status: \'error\', error: \'too-short\' };\n }\n return { status: \'success\', data: { valid: true } };\n}\n\`\`\`\n\n### Archetype 2: One-Shot LLM Analyzer\n\n**When to use:** Single LLM call for analysis, classification, or generation.\n\n**Characteristics:** One LLM call per execution, stateless, handles LLM errors.\n\n**Example use cases:** Sentiment analysis, text classification, entity extraction, creative generation.\n\n\`\`\`typescript\nexport async function analyzeSentiment(text: string, context: AgentContext) {\n const response = await context.callLLM([\n { role: \'user\', content: \`Analyze sentiment: \"${text}\"\` }\n ]);\n\n const parsed = JSON.parse(response);\n return { status: \'success\', data: parsed };\n}\n\`\`\`\n\n### Archetype 3: Conversational Assistant\n\n**When to use:** Multi-turn dialogue, progressive data collection across sessions.\n\n**Characteristics:** Multiple LLM calls, maintains session state, phases (gathering → ready → complete).\n\n**Example use cases:** Customer support chatbots, product advisors, interview agents, multi-step forms.\n\n\`\`\`typescript\nexport async function conversationalAgent(\n message: string,\n sessionState: SessionState\n) {\n if (sessionState.phase === \'gathering\') {\n return {\n reply: \"Can you tell me more about X?\",\n sessionState: { ...sessionState },\n result: { status: \'in-progress\' }\n };\n }\n\n return {\n reply: \"Here\'s your result!\",\n sessionState: { ...sessionState, phase: \'complete\' },\n result: { status: \'success\', data: finalResult }\n };\n}\n\`\`\`\n\n### Archetype 4: External Event Integrator\n\n**When to use:** Waiting for external events (approvals, webhooks, third-party APIs).\n\n**Characteristics:** Emits event, blocks waiting for response, timeout handling, mockable for testing.\n\n**Example use cases:** Human-in-the-loop approval, webhook integrations, external API polling.\n\n\`\`\`typescript\nexport async function humanApproval(\n request: ApprovalRequest,\n options = { mockable: true, timeout: 30000 }\n) {\n if (options.mockable) {\n return { status: \'success\', data: { approved: true } };\n }\n\n const response = await emitEvent(request, options.timeout);\n return { status: \'success\', data: response };\n}\n\`\`\`\n\n## Result Envelopes\n\nAlways return result envelopes — never throw exceptions for expected errors.\n\n\`\`\`typescript\n// AgentResult<TData, TError> — for single-execution agents\ntype AgentResult<TData, TError> =\n | { status: \'success\'; data: TData }\n | { status: \'error\'; error: TError };\n\n// StatefulAgentResult — for conversational agents\ntype StatefulAgentResult<TData, TError, TMetadata> =\n | { status: \'in-progress\'; metadata?: TMetadata }\n | { status: \'success\'; data: TData }\n | { status: \'error\'; error: TError };\n\`\`\`\n\nStandard LLM error literals: \`\'llm-refusal\'\`, \`\'llm-invalid-output\'\`, \`\'llm-timeout\'\`,\n\`\'llm-rate-limit\'\`, \`\'llm-token-limit\'\`, \`\'llm-unavailable\'\`.\n\nAlways check status before accessing data:\n\`\`\`typescript\nconst output = await myAgent.execute(input);\nif (output.result.status === \'success\') {\n console.log(output.result.data);\n} else if (output.result.status === \'error\') {\n console.error(\'Failed:\', output.result.error);\n}\n\`\`\`\n\n## Orchestration Patterns\n\n### Sequential Pipeline\n\n\`\`\`typescript\nconst analysisOutput = await analyzer.execute(input);\nconst processedOutput = await andThen(\n analysisOutput.result,\n async (data) => {\n const out = await processor.execute(data);\n return out.result;\n }\n);\n\`\`\`\n\n### Parallel Execution\n\n\`\`\`typescript\nconst [output1, output2, output3] = await Promise.all([\n agent1.execute(input),\n agent2.execute(input),\n agent3.execute(input),\n]);\n\`\`\`\n\n### Validation Loop (Generate + Validate with Retry)\n\n\`\`\`typescript\nasync function generateValidOutput(input: MyInput, maxAttempts = 5) {\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const generatorOutput = await generator.execute(input);\n if (generatorOutput.result.status === \'error\') continue;\n\n const validatorOutput = await validator.execute(generatorOutput.result.data);\n if (validatorOutput.result.status === \'success\' &&\n validatorOutput.result.data.valid) {\n return generatorOutput.result.data;\n }\n }\n throw new Error(\'Max attempts exceeded\');\n}\n\`\`\`\n\n### Human-in-the-Loop\n\n\`\`\`typescript\nconst generatorOutput = await generator.execute(input);\nif (generatorOutput.result.status === \'success\') {\n const approvalOutput = await humanApproval.execute({\n content: generatorOutput.result.data,\n context: input,\n });\n if (approvalOutput.result.data.approved) {\n return generatorOutput.result.data;\n }\n}\n\`\`\`\n\n### Conversational Multi-Turn\n\n\`\`\`typescript\nlet session = { state: { phase: \'gathering\' }, history: [] };\n\nwhile (true) {\n const userMessage = await getUserInput();\n const output = await conversationalAgent.execute({\n message: userMessage,\n sessionState: session.state,\n });\n\n console.log(\'Agent:\', output.reply);\n session = {\n state: output.sessionState,\n history: [...session.history,\n { role: \'user\', content: userMessage },\n { role: \'assistant\', content: output.reply }\n ],\n };\n\n if (output.result.status === \'success\') break;\n if (output.result.status === \'error\') break;\n // status === \'in-progress\': continue\n}\n\`\`\`\n\n## packagingOptions Reference\n\nConfigure in your skill\'s \`vat.skills[]\` entry in \`package.json\`:\n\n\`\`\`json\n{\n \"vat\": {\n \"skills\": [{\n \"name\": \"my-skill\",\n \"source\": \"./SKILL.md\",\n \"path\": \"./dist/skills/my-skill\",\n \"packagingOptions\": {\n \"linkFollowDepth\": 1,\n \"resourceNaming\": \"resource-id\",\n \"stripPrefix\": \"knowledge-base\",\n \"excludeReferencesFromBundle\": {\n \"rules\": [\n { \"patterns\": [\"**/concepts/**\"], \"template\": \"Use search to find: {{link.text}}\" }\n ],\n \"defaultTemplate\": \"{{link.text}} (search knowledge base)\"\n }\n }\n }]\n }\n}\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- \`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**\`ignoreValidationErrors\`** — Override specific validation rules when justified:\n\n\`\`\`json\n\"ignoreValidationErrors\": {\n \"SKILL_LENGTH_EXCEEDS_RECOMMENDED\": \"Large domain requires detailed examples\",\n \"NO_PROGRESSIVE_DISCLOSURE\": {\n \"reason\": \"Temporary — refactoring planned\",\n \"expires\": \"2026-06-30\"\n }\n}\n\`\`\`\n\nUse sparingly. Prefer fixing the underlying issue over suppressing warnings.\n\n## Testing Agents\n\n### Unit Testing Pure Functions\n\n\`\`\`typescript\nimport { describe, expect, it } from \'vitest\';\nimport { resultMatchers } from \'@vibe-agent-toolkit/agent-runtime\';\n\ndescribe(\'myValidator\', () => {\n it(\'should validate correct input\', async () => {\n const output = await myValidator.execute({ text: \'valid\' });\n resultMatchers.expectSuccess(output.result);\n expect(output.result.data.valid).toBe(true);\n });\n});\n\`\`\`\n\n### Integration Testing with Mock LLM\n\n\`\`\`typescript\nimport { createMockContext } from \'@vibe-agent-toolkit/agent-runtime\';\n\nconst mockContext = createMockContext(\n JSON.stringify({ sentiment: \'positive\', confidence: 0.9 })\n);\nconst output = await myAnalyzer.execute({ text: \'Great!\' }, mockContext);\nresultMatchers.expectSuccess(output.result);\n\`\`\`\n\n### Testing Conversational Flows\n\n\`\`\`typescript\n// Turn 1\nconst output1 = await agent.execute({ message: \'Hello\' });\nexpect(output1.reply).toContain(\'name?\');\nresultMatchers.expectInProgress(output1.result);\n\n// Turn 2 — pass session state forward\nconst output2 = await agent.execute({\n message: \'My name is Alice\',\n sessionState: output1.sessionState,\n});\n\`\`\`\n\n## Best Practices\n\n1. **Return result envelopes, never throw** for expected errors\n2. **Define error types as literal unions** (\`\'invalid-format\' | \'timeout\'\`) not \`string\`\n3. **Use Zod schemas** for all input/output validation\n4. **Test all paths** — success, each error type, edge cases\n5. **Use mock mode** for external dependencies to enable offline testing\n6. **Document with JSDoc** — purpose, params, return type, example, \`@throws Never throws\`\n7. **Keep SKILL.md focused** — if it exceeds ~300 lines, split into action skills\n\n## References\n\n- [Skill Quality Checklist](skill-quality-checklist.md) — Pre-publication checklist for all skills (general + CLI-backed)\n- [agent-authoring.md](../../../../docs/agent-authoring.md) — Complete patterns guide\n- [orchestration.md](../../../../docs/orchestration.md) — Multi-agent workflows\n- [Building Effective Agents - Anthropic](https://www.anthropic.com/research/building-effective-agents)\n";
10
+ export const text = "\n# VAT Agent Authoring: SKILL.md, Archetypes & Patterns\n\n## SKILL.md Structure\n\nA SKILL.md file is the definition file for a VAT agent skill. It tells Claude what the skill\ndoes 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 (max 200 chars)\n---\n\n# My Skill\n\nRest of the skill documentation...\n\`\`\`\n\nRequired frontmatter fields:\n- \`name\` — unique identifier, kebab-case, matches the skill\'s directory name\n- \`description\` — trigger description used for skill routing; be specific about activation conditions\n\nBest practices for \`description\`:\n- Start with \"Use when...\" to make activation conditions explicit\n- Include the key commands or concepts the skill covers\n- Keep under 200 characters\n\n## Agent Archetypes\n\nVAT supports four agent archetypes for different use cases.\n\n### Archetype 1: Pure Function Tool\n\n**When to use:** Stateless validation, transformation, computation — no LLM needed.\n\n**Characteristics:** Deterministic output, fast execution, easy to test.\n\n**Example use cases:** Input validation, data transformation, format conversion, rules-based logic.\n\n\`\`\`typescript\nexport async function validateInput(input: MyInput): Promise<ValidationResult> {\n if (input.text.length < 5) {\n return { status: \'error\', error: \'too-short\' };\n }\n return { status: \'success\', data: { valid: true } };\n}\n\`\`\`\n\n### Archetype 2: One-Shot LLM Analyzer\n\n**When to use:** Single LLM call for analysis, classification, or generation.\n\n**Characteristics:** One LLM call per execution, stateless, handles LLM errors.\n\n**Example use cases:** Sentiment analysis, text classification, entity extraction, creative generation.\n\n\`\`\`typescript\nexport async function analyzeSentiment(text: string, context: AgentContext) {\n const response = await context.callLLM([\n { role: \'user\', content: \`Analyze sentiment: \"${text}\"\` }\n ]);\n\n const parsed = JSON.parse(response);\n return { status: \'success\', data: parsed };\n}\n\`\`\`\n\n### Archetype 3: Conversational Assistant\n\n**When to use:** Multi-turn dialogue, progressive data collection across sessions.\n\n**Characteristics:** Multiple LLM calls, maintains session state, phases (gathering → ready → complete).\n\n**Example use cases:** Customer support chatbots, product advisors, interview agents, multi-step forms.\n\n\`\`\`typescript\nexport async function conversationalAgent(\n message: string,\n sessionState: SessionState\n) {\n if (sessionState.phase === \'gathering\') {\n return {\n reply: \"Can you tell me more about X?\",\n sessionState: { ...sessionState },\n result: { status: \'in-progress\' }\n };\n }\n\n return {\n reply: \"Here\'s your result!\",\n sessionState: { ...sessionState, phase: \'complete\' },\n result: { status: \'success\', data: finalResult }\n };\n}\n\`\`\`\n\n### Archetype 4: External Event Integrator\n\n**When to use:** Waiting for external events (approvals, webhooks, third-party APIs).\n\n**Characteristics:** Emits event, blocks waiting for response, timeout handling, mockable for testing.\n\n**Example use cases:** Human-in-the-loop approval, webhook integrations, external API polling.\n\n\`\`\`typescript\nexport async function humanApproval(\n request: ApprovalRequest,\n options = { mockable: true, timeout: 30000 }\n) {\n if (options.mockable) {\n return { status: \'success\', data: { approved: true } };\n }\n\n const response = await emitEvent(request, options.timeout);\n return { status: \'success\', data: response };\n}\n\`\`\`\n\n## Result Envelopes\n\nAlways return result envelopes — never throw exceptions for expected errors.\n\n\`\`\`typescript\n// AgentResult<TData, TError> — for single-execution agents\ntype AgentResult<TData, TError> =\n | { status: \'success\'; data: TData }\n | { status: \'error\'; error: TError };\n\n// StatefulAgentResult — for conversational agents\ntype StatefulAgentResult<TData, TError, TMetadata> =\n | { status: \'in-progress\'; metadata?: TMetadata }\n | { status: \'success\'; data: TData }\n | { status: \'error\'; error: TError };\n\`\`\`\n\nStandard LLM error literals: \`\'llm-refusal\'\`, \`\'llm-invalid-output\'\`, \`\'llm-timeout\'\`,\n\`\'llm-rate-limit\'\`, \`\'llm-token-limit\'\`, \`\'llm-unavailable\'\`.\n\nAlways check status before accessing data:\n\`\`\`typescript\nconst output = await myAgent.execute(input);\nif (output.result.status === \'success\') {\n console.log(output.result.data);\n} else if (output.result.status === \'error\') {\n console.error(\'Failed:\', output.result.error);\n}\n\`\`\`\n\n## Orchestration Patterns\n\n### Sequential Pipeline\n\n\`\`\`typescript\nconst analysisOutput = await analyzer.execute(input);\nconst processedOutput = await andThen(\n analysisOutput.result,\n async (data) => {\n const out = await processor.execute(data);\n return out.result;\n }\n);\n\`\`\`\n\n### Parallel Execution\n\n\`\`\`typescript\nconst [output1, output2, output3] = await Promise.all([\n agent1.execute(input),\n agent2.execute(input),\n agent3.execute(input),\n]);\n\`\`\`\n\n### Validation Loop (Generate + Validate with Retry)\n\n\`\`\`typescript\nasync function generateValidOutput(input: MyInput, maxAttempts = 5) {\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const generatorOutput = await generator.execute(input);\n if (generatorOutput.result.status === \'error\') continue;\n\n const validatorOutput = await validator.execute(generatorOutput.result.data);\n if (validatorOutput.result.status === \'success\' &&\n validatorOutput.result.data.valid) {\n return generatorOutput.result.data;\n }\n }\n throw new Error(\'Max attempts exceeded\');\n}\n\`\`\`\n\n### Human-in-the-Loop\n\n\`\`\`typescript\nconst generatorOutput = await generator.execute(input);\nif (generatorOutput.result.status === \'success\') {\n const approvalOutput = await humanApproval.execute({\n content: generatorOutput.result.data,\n context: input,\n });\n if (approvalOutput.result.data.approved) {\n return generatorOutput.result.data;\n }\n}\n\`\`\`\n\n### Conversational Multi-Turn\n\n\`\`\`typescript\nlet session = { state: { phase: \'gathering\' }, history: [] };\n\nwhile (true) {\n const userMessage = await getUserInput();\n const output = await conversationalAgent.execute({\n message: userMessage,\n sessionState: session.state,\n });\n\n console.log(\'Agent:\', output.reply);\n session = {\n state: output.sessionState,\n history: [...session.history,\n { role: \'user\', content: userMessage },\n { role: \'assistant\', content: output.reply }\n ],\n };\n\n if (output.result.status === \'success\') break;\n if (output.result.status === \'error\') break;\n // status === \'in-progress\': continue\n}\n\`\`\`\n\n## packagingOptions Reference\n\nConfigure in your skill\'s \`vat.skills[]\` entry in \`package.json\`:\n\n\`\`\`json\n{\n \"vat\": {\n \"skills\": [{\n \"name\": \"my-skill\",\n \"source\": \"./SKILL.md\",\n \"path\": \"./dist/skills/my-skill\",\n \"packagingOptions\": {\n \"linkFollowDepth\": 1,\n \"resourceNaming\": \"resource-id\",\n \"stripPrefix\": \"knowledge-base\",\n \"excludeReferencesFromBundle\": {\n \"rules\": [\n { \"patterns\": [\"**/concepts/**\"], \"template\": \"Use search to find: {{link.text}}\" }\n ],\n \"defaultTemplate\": \"{{link.text}} (search knowledge base)\"\n }\n }\n }]\n }\n}\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- \`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\`** — Unified framework for overriding default severity and allowing specific issue instances:\n\n\`\`\`yaml\n# In vibe-agent-toolkit.config.yaml under skills.defaults or skills.config.<name>\nvalidation:\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\nThings adopters typically adjust:\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\nFull code reference at \`docs/validation-codes.md\`. \`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## Testing Agents\n\n### Unit Testing Pure Functions\n\n\`\`\`typescript\nimport { describe, expect, it } from \'vitest\';\nimport { resultMatchers } from \'@vibe-agent-toolkit/agent-runtime\';\n\ndescribe(\'myValidator\', () => {\n it(\'should validate correct input\', async () => {\n const output = await myValidator.execute({ text: \'valid\' });\n resultMatchers.expectSuccess(output.result);\n expect(output.result.data.valid).toBe(true);\n });\n});\n\`\`\`\n\n### Integration Testing with Mock LLM\n\n\`\`\`typescript\nimport { createMockContext } from \'@vibe-agent-toolkit/agent-runtime\';\n\nconst mockContext = createMockContext(\n JSON.stringify({ sentiment: \'positive\', confidence: 0.9 })\n);\nconst output = await myAnalyzer.execute({ text: \'Great!\' }, mockContext);\nresultMatchers.expectSuccess(output.result);\n\`\`\`\n\n### Testing Conversational Flows\n\n\`\`\`typescript\n// Turn 1\nconst output1 = await agent.execute({ message: \'Hello\' });\nexpect(output1.reply).toContain(\'name?\');\nresultMatchers.expectInProgress(output1.result);\n\n// Turn 2 — pass session state forward\nconst output2 = await agent.execute({\n message: \'My name is Alice\',\n sessionState: output1.sessionState,\n});\n\`\`\`\n\n## Best Practices\n\n1. **Return result envelopes, never throw** for expected errors\n2. **Define error types as literal unions** (\`\'invalid-format\' | \'timeout\'\`) not \`string\`\n3. **Use Zod schemas** for all input/output validation\n4. **Test all paths** — success, each error type, edge cases\n5. **Use mock mode** for external dependencies to enable offline testing\n6. **Document with JSDoc** — purpose, params, return type, example, \`@throws Never throws\`\n7. **Keep SKILL.md focused** — if it exceeds ~300 lines, split into action skills\n\n## References\n\n- [Skill Quality Checklist](skill-quality-checklist.md) — Pre-publication checklist for all skills (general + CLI-backed)\n- [agent-authoring.md](../../../../docs/agent-authoring.md) — Complete patterns guide\n- [orchestration.md](../../../../docs/orchestration.md) — Multi-agent workflows\n- [Building Effective Agents - Anthropic](https://www.anthropic.com/research/building-effective-agents)\n";
11
11
 
12
12
  export const fragments = {
13
13
  skillmdStructure: {
@@ -32,8 +32,8 @@ export const fragments = {
32
32
  },
33
33
  packagingoptionsReference: {
34
34
  header: "## packagingOptions Reference",
35
- body: "Configure in your skill\'s \`vat.skills[]\` entry in \`package.json\`:\n\n\`\`\`json\n{\n \"vat\": {\n \"skills\": [{\n \"name\": \"my-skill\",\n \"source\": \"./SKILL.md\",\n \"path\": \"./dist/skills/my-skill\",\n \"packagingOptions\": {\n \"linkFollowDepth\": 1,\n \"resourceNaming\": \"resource-id\",\n \"stripPrefix\": \"knowledge-base\",\n \"excludeReferencesFromBundle\": {\n \"rules\": [\n { \"patterns\": [\"**/concepts/**\"], \"template\": \"Use search to find: {{link.text}}\" }\n ],\n \"defaultTemplate\": \"{{link.text}} (search knowledge base)\"\n }\n }\n }]\n }\n}\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- \`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**\`ignoreValidationErrors\`** — Override specific validation rules when justified:\n\n\`\`\`json\n\"ignoreValidationErrors\": {\n \"SKILL_LENGTH_EXCEEDS_RECOMMENDED\": \"Large domain requires detailed examples\",\n \"NO_PROGRESSIVE_DISCLOSURE\": {\n \"reason\": \"Temporary refactoring planned\",\n \"expires\": \"2026-06-30\"\n }\n}\n\`\`\`\n\nUse sparingly. Prefer fixing the underlying issue over suppressing warnings.",
36
- text: "## packagingOptions Reference\n\nConfigure in your skill\'s \`vat.skills[]\` entry in \`package.json\`:\n\n\`\`\`json\n{\n \"vat\": {\n \"skills\": [{\n \"name\": \"my-skill\",\n \"source\": \"./SKILL.md\",\n \"path\": \"./dist/skills/my-skill\",\n \"packagingOptions\": {\n \"linkFollowDepth\": 1,\n \"resourceNaming\": \"resource-id\",\n \"stripPrefix\": \"knowledge-base\",\n \"excludeReferencesFromBundle\": {\n \"rules\": [\n { \"patterns\": [\"**/concepts/**\"], \"template\": \"Use search to find: {{link.text}}\" }\n ],\n \"defaultTemplate\": \"{{link.text}} (search knowledge base)\"\n }\n }\n }]\n }\n}\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- \`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**\`ignoreValidationErrors\`** — Override specific validation rules when justified:\n\n\`\`\`json\n\"ignoreValidationErrors\": {\n \"SKILL_LENGTH_EXCEEDS_RECOMMENDED\": \"Large domain requires detailed examples\",\n \"NO_PROGRESSIVE_DISCLOSURE\": {\n \"reason\": \"Temporary refactoring planned\",\n \"expires\": \"2026-06-30\"\n }\n}\n\`\`\`\n\nUse sparingly. Prefer fixing the underlying issue over suppressing warnings."
35
+ body: "Configure in your skill\'s \`vat.skills[]\` entry in \`package.json\`:\n\n\`\`\`json\n{\n \"vat\": {\n \"skills\": [{\n \"name\": \"my-skill\",\n \"source\": \"./SKILL.md\",\n \"path\": \"./dist/skills/my-skill\",\n \"packagingOptions\": {\n \"linkFollowDepth\": 1,\n \"resourceNaming\": \"resource-id\",\n \"stripPrefix\": \"knowledge-base\",\n \"excludeReferencesFromBundle\": {\n \"rules\": [\n { \"patterns\": [\"**/concepts/**\"], \"template\": \"Use search to find: {{link.text}}\" }\n ],\n \"defaultTemplate\": \"{{link.text}} (search knowledge base)\"\n }\n }\n }]\n }\n}\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- \`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\`** — Unified framework for overriding default severity and allowing specific issue instances:\n\n\`\`\`yaml\n# In vibe-agent-toolkit.config.yaml under skills.defaults or skills.config.<name>\nvalidation:\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\nThings adopters typically adjust:\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\nFull code reference at \`docs/validation-codes.md\`. \`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: "## packagingOptions Reference\n\nConfigure in your skill\'s \`vat.skills[]\` entry in \`package.json\`:\n\n\`\`\`json\n{\n \"vat\": {\n \"skills\": [{\n \"name\": \"my-skill\",\n \"source\": \"./SKILL.md\",\n \"path\": \"./dist/skills/my-skill\",\n \"packagingOptions\": {\n \"linkFollowDepth\": 1,\n \"resourceNaming\": \"resource-id\",\n \"stripPrefix\": \"knowledge-base\",\n \"excludeReferencesFromBundle\": {\n \"rules\": [\n { \"patterns\": [\"**/concepts/**\"], \"template\": \"Use search to find: {{link.text}}\" }\n ],\n \"defaultTemplate\": \"{{link.text}} (search knowledge base)\"\n }\n }\n }]\n }\n}\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- \`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\`** — Unified framework for overriding default severity and allowing specific issue instances:\n\n\`\`\`yaml\n# In vibe-agent-toolkit.config.yaml under skills.defaults or skills.config.<name>\nvalidation:\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\nThings adopters typically adjust:\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\nFull code reference at \`docs/validation-codes.md\`. \`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
37
  },
38
38
  testingAgents: {
39
39
  header: "## Testing Agents",
@@ -7,7 +7,7 @@ export const meta = {
7
7
  description: "Use when running vat audit to validate Claude plugins, agent skills, or marketplaces. Covers the audit command, --compat flag for surface compatibility analysis, --exclude for noise filtering, and interpreting audit output."
8
8
  };
9
9
 
10
- export const text = "\n# VAT Audit: Validating Plugins, Skills & Marketplaces\n\n## Running the Audit\n\n\`\`\`bash\n# Audit current directory (recursive by default)\nvat audit\n\n# Audit a specific directory\nvat audit ./plugins/\n\n# Audit your entire Claude installation\nvat audit --user\n\n# Exclude noisy directories\nvat audit --exclude \"dist/**\" --exclude \"node_modules/**\"\n\n# Verbose: show all resources, not just those with issues\nvat audit --verbose\n\n# Compatibility analysis: which Claude surfaces each plugin supports\nvat audit ./plugins/ --compat\n\`\`\`\n\n## What Gets Detected (Automatic)\n\nRunning \`vat audit <path>\` recursively walks the directory and auto-detects:\n\n| Found | Detected as |\n|---|---|\n| \`.claude-plugin/plugin.json\` in a dir | Claude Plugin |\n| \`.claude-plugin/marketplace.json\` in a dir | Claude Marketplace |\n| \`SKILL.md\` file | Agent Skill |\n| \`agent.yaml\` + \`SKILL.md\` | VAT Agent |\n| \`installed_plugins.json\` | Registry file |\n\nRecursion is the default — you do not need \`--recursive\`.\n\n## Compatibility Analysis (\`--compat\`)\n\n\`\`\`bash\nvat audit ./plugins/ --compat\n\`\`\`\n\nOutput per plugin:\n\`\`\`yaml\nplugin: mission-control\ncompatibility:\n claude-code:\n compatible: true\n evidence: []\n cowork:\n compatible: true\n evidence: []\n claude-desktop:\n compatible: false\n evidence:\n - type: python-script\n file: hooks-handlers/handler.py\n detail: Python execution not available in claude-desktop\n\`\`\`\n\nUse this before a release to determine which surfaces each plugin supports.\n\n## Exit Codes\n\n- \`0\`clean (or \`--user\` mode: always 0, informational)\n- \`1\` — validation errors found\n- \`2\` — system error (path not found, permission denied)\n\n## CI Usage\n\n\`\`\`yaml\n# vibe-validate.config.yaml\nsteps:\n - name: Plugin and skill validation\n command: vat audit plugins/ --exclude \"**/__pycache__/**\"\n\`\`\`\n\n## Interpreting Output\n\n\`\`\`yaml\nstatus: warning\nsummary:\n filesScanned: 23\n success: 21\n warnings: 2\n errors: 0\n\`\`\`\n\nWarnings (exit 0) vs errors (exit 1):\n- **Errors:** Missing required frontmatter, broken links, invalid plugin.json schema\n- **Warnings:** Skill too long, description too short, best practice violations\n\nSuppress specific warnings with \`ignoreValidationErrors\` in \`package.json\`:\n\`\`\`json\n{\n \"vat\": {\n \"skills\": [{\n \"ignoreValidationErrors\": {\n \"SKILL_LENGTH_EXCEEDS_RECOMMENDED\": \"Complex domain requires full detail\"\n }\n }]\n }\n}\n\`\`\`\n";
10
+ export const text = "\n# VAT Audit: Validating Plugins, Skills & Marketplaces\n\n## Running the Audit\n\n\`\`\`bash\n# Audit current directory (recursive by default)\nvat audit\n\n# Audit a specific directory\nvat audit ./plugins/\n\n# Audit your entire Claude installation\nvat audit --user\n\n# Exclude noisy directories\nvat audit --exclude \"dist/**\" --exclude \"node_modules/**\"\n\n# Verbose: show all resources, not just those with issues\nvat audit --verbose\n\n# Compatibility analysis: which Claude surfaces each plugin supports\nvat audit ./plugins/ --compat\n\`\`\`\n\n## What Gets Detected (Automatic)\n\nRunning \`vat audit <path>\` recursively walks the directory and auto-detects:\n\n| Found | Detected as |\n|---|---|\n| \`.claude-plugin/plugin.json\` in a dir | Claude Plugin |\n| \`.claude-plugin/marketplace.json\` in a dir | Claude Marketplace |\n| \`SKILL.md\` file | Agent Skill |\n| \`agent.yaml\` + \`SKILL.md\` | VAT Agent |\n| \`installed_plugins.json\` | Registry file |\n\nRecursion is the default — you do not need \`--recursive\`.\n\n## Compatibility Analysis (\`--compat\`)\n\n\`\`\`bash\nvat audit ./plugins/ --compat\n\`\`\`\n\nOutput per plugin:\n\`\`\`yaml\nplugin: mission-control\ncompatibility:\n claude-code:\n compatible: true\n evidence: []\n cowork:\n compatible: true\n evidence: []\n claude-desktop:\n compatible: false\n evidence:\n - type: python-script\n file: hooks-handlers/handler.py\n detail: Python execution not available in claude-desktop\n\`\`\`\n\nUse this before a release to determine which surfaces each plugin supports.\n\n## Exit Codes\n\n\`vat audit\` is **advisory** it reports every issue it detects but never blocks on validation severity:\n\n- \`0\` — always, when the audit completes, regardless of errors or warnings in the report.\n- \`2\` — system error (path not found, permission denied, etc.) — the audit could not run.\n\nFor gated checks that exit \`1\` on validation errors, use \`vat skills validate\` or \`vat skills build\` instead. Those commands apply \`validation.severity\` and honor \`validation.allow\` from config.\n\n## CI Usage\n\n\`\`\`yaml\n# vibe-validate.config.yaml\nsteps:\n - name: Plugin and skill validation\n command: vat audit plugins/ --exclude \"**/__pycache__/**\"\n\`\`\`\n\n## Interpreting Output\n\n\`\`\`yaml\nstatus: warning\nsummary:\n filesScanned: 23\n success: 21\n warnings: 2\n errors: 0\n\`\`\`\n\nSeverity taxonomy in audit output:\n- **Errors:** Missing required frontmatter, broken links, invalid plugin.json schema, link integrity violations\n- **Warnings:** Skill too long, description too short, best practice violations\n\nAudit always exits \`0\` regardless — surface-level severity drives display grouping only.\n\n**Hiding codes from audit output.** Audit ignores \`validation.allow\` by design (it is the read-only report), but it does honor \`validation.severity\`. Set a code to \`ignore\` in \`vibe-agent-toolkit.config.yaml\` to suppress it from the audit output:\n\n\`\`\`yaml\nskills:\n config:\n my-skill:\n validation:\n severity:\n LINK_TO_NAVIGATION_FILE: ignore # hidden from audit output\n\`\`\`\n\n**Per-instance allow entries.** For per-path suppression with an audit trail, use \`validation.allow\` and run \`vat skills validate\` or \`vat skills build\` — those commands apply \`allow\` and gate the build. See \`docs/validation-codes.md\` for the full code reference and the VAT agent-authoring skill for configuration patterns.\n";
11
11
 
12
12
  export const fragments = {
13
13
  runningTheAudit: {
@@ -27,8 +27,8 @@ export const fragments = {
27
27
  },
28
28
  exitCodes: {
29
29
  header: "## Exit Codes",
30
- body: "- \`0\`clean (or \`--user\` mode: always 0, informational)\n- \`1\` — validation errors found\n- \`2\` — system error (path not found, permission denied)",
31
- text: "## Exit Codes\n\n- \`0\`clean (or \`--user\` mode: always 0, informational)\n- \`1\` — validation errors found\n- \`2\` — system error (path not found, permission denied)"
30
+ body: "\`vat audit\` is **advisory** it reports every issue it detects but never blocks on validation severity:\n\n- \`0\` — always, when the audit completes, regardless of errors or warnings in the report.\n- \`2\` — system error (path not found, permission denied, etc.) — the audit could not run.\n\nFor gated checks that exit \`1\` on validation errors, use \`vat skills validate\` or \`vat skills build\` instead. Those commands apply \`validation.severity\` and honor \`validation.allow\` from config.",
31
+ text: "## Exit Codes\n\n\`vat audit\` is **advisory** it reports every issue it detects but never blocks on validation severity:\n\n- \`0\` — always, when the audit completes, regardless of errors or warnings in the report.\n- \`2\` — system error (path not found, permission denied, etc.) — the audit could not run.\n\nFor gated checks that exit \`1\` on validation errors, use \`vat skills validate\` or \`vat skills build\` instead. Those commands apply \`validation.severity\` and honor \`validation.allow\` from config."
32
32
  },
33
33
  ciUsage: {
34
34
  header: "## CI Usage",
@@ -37,7 +37,7 @@ export const fragments = {
37
37
  },
38
38
  interpretingOutput: {
39
39
  header: "## Interpreting Output",
40
- body: "\`\`\`yaml\nstatus: warning\nsummary:\n filesScanned: 23\n success: 21\n warnings: 2\n errors: 0\n\`\`\`\n\nWarnings (exit 0) vs errors (exit 1):\n- **Errors:** Missing required frontmatter, broken links, invalid plugin.json schema\n- **Warnings:** Skill too long, description too short, best practice violations\n\nSuppress specific warnings with \`ignoreValidationErrors\` in \`package.json\`:\n\`\`\`json\n{\n \"vat\": {\n \"skills\": [{\n \"ignoreValidationErrors\": {\n \"SKILL_LENGTH_EXCEEDS_RECOMMENDED\": \"Complex domain requires full detail\"\n }\n }]\n }\n}\n\`\`\`",
41
- text: "## Interpreting Output\n\n\`\`\`yaml\nstatus: warning\nsummary:\n filesScanned: 23\n success: 21\n warnings: 2\n errors: 0\n\`\`\`\n\nWarnings (exit 0) vs errors (exit 1):\n- **Errors:** Missing required frontmatter, broken links, invalid plugin.json schema\n- **Warnings:** Skill too long, description too short, best practice violations\n\nSuppress specific warnings with \`ignoreValidationErrors\` in \`package.json\`:\n\`\`\`json\n{\n \"vat\": {\n \"skills\": [{\n \"ignoreValidationErrors\": {\n \"SKILL_LENGTH_EXCEEDS_RECOMMENDED\": \"Complex domain requires full detail\"\n }\n }]\n }\n}\n\`\`\`"
40
+ body: "\`\`\`yaml\nstatus: warning\nsummary:\n filesScanned: 23\n success: 21\n warnings: 2\n errors: 0\n\`\`\`\n\nSeverity taxonomy in audit output:\n- **Errors:** Missing required frontmatter, broken links, invalid plugin.json schema, link integrity violations\n- **Warnings:** Skill too long, description too short, best practice violations\n\nAudit always exits \`0\` regardless — surface-level severity drives display grouping only.\n\n**Hiding codes from audit output.** Audit ignores \`validation.allow\` by design (it is the read-only report), but it does honor \`validation.severity\`. Set a code to \`ignore\` in \`vibe-agent-toolkit.config.yaml\` to suppress it from the audit output:\n\n\`\`\`yaml\nskills:\n config:\n my-skill:\n validation:\n severity:\n LINK_TO_NAVIGATION_FILE: ignore # hidden from audit output\n\`\`\`\n\n**Per-instance allow entries.** For per-path suppression with an audit trail, use \`validation.allow\` and run \`vat skills validate\` or \`vat skills build\` — those commands apply \`allow\` and gate the build. See \`docs/validation-codes.md\` for the full code reference and the VAT agent-authoring skill for configuration patterns.",
41
+ text: "## Interpreting Output\n\n\`\`\`yaml\nstatus: warning\nsummary:\n filesScanned: 23\n success: 21\n warnings: 2\n errors: 0\n\`\`\`\n\nSeverity taxonomy in audit output:\n- **Errors:** Missing required frontmatter, broken links, invalid plugin.json schema, link integrity violations\n- **Warnings:** Skill too long, description too short, best practice violations\n\nAudit always exits \`0\` regardless — surface-level severity drives display grouping only.\n\n**Hiding codes from audit output.** Audit ignores \`validation.allow\` by design (it is the read-only report), but it does honor \`validation.severity\`. Set a code to \`ignore\` in \`vibe-agent-toolkit.config.yaml\` to suppress it from the audit output:\n\n\`\`\`yaml\nskills:\n config:\n my-skill:\n validation:\n severity:\n LINK_TO_NAVIGATION_FILE: ignore # hidden from audit output\n\`\`\`\n\n**Per-instance allow entries.** For per-path suppression with an audit trail, use \`validation.allow\` and run \`vat skills validate\` or \`vat skills build\` — those commands apply \`allow\` and gate the build. See \`docs/validation-codes.md\` for the full code reference and the VAT agent-authoring skill for configuration patterns."
42
42
  }
43
43
  };
@@ -69,9 +69,12 @@ Use this before a release to determine which surfaces each plugin supports.
69
69
 
70
70
  ## Exit Codes
71
71
 
72
- - `0`clean (or `--user` mode: always 0, informational)
73
- - `1` — validation errors found
74
- - `2` — system error (path not found, permission denied)
72
+ `vat audit` is **advisory** it reports every issue it detects but never blocks on validation severity:
73
+
74
+ - `0` — always, when the audit completes, regardless of errors or warnings in the report.
75
+ - `2` — system error (path not found, permission denied, etc.) — the audit could not run.
76
+
77
+ For gated checks that exit `1` on validation errors, use `vat skills validate` or `vat skills build` instead. Those commands apply `validation.severity` and honor `validation.allow` from config.
75
78
 
76
79
  ## CI Usage
77
80
 
@@ -93,19 +96,21 @@ summary:
93
96
  errors: 0
94
97
  ```
95
98
 
96
- Warnings (exit 0) vs errors (exit 1):
97
- - **Errors:** Missing required frontmatter, broken links, invalid plugin.json schema
99
+ Severity taxonomy in audit output:
100
+ - **Errors:** Missing required frontmatter, broken links, invalid plugin.json schema, link integrity violations
98
101
  - **Warnings:** Skill too long, description too short, best practice violations
99
102
 
100
- Suppress specific warnings with `ignoreValidationErrors` in `package.json`:
101
- ```json
102
- {
103
- "vat": {
104
- "skills": [{
105
- "ignoreValidationErrors": {
106
- "SKILL_LENGTH_EXCEEDS_RECOMMENDED": "Complex domain requires full detail"
107
- }
108
- }]
109
- }
110
- }
103
+ Audit always exits `0` regardless — surface-level severity drives display grouping only.
104
+
105
+ **Hiding codes from audit output.** Audit ignores `validation.allow` by design (it is the read-only report), but it does honor `validation.severity`. Set a code to `ignore` in `vibe-agent-toolkit.config.yaml` to suppress it from the audit output:
106
+
107
+ ```yaml
108
+ skills:
109
+ config:
110
+ my-skill:
111
+ validation:
112
+ severity:
113
+ LINK_TO_NAVIGATION_FILE: ignore # hidden from audit output
111
114
  ```
115
+
116
+ **Per-instance allow entries.** For per-path suppression with an audit trail, use `validation.allow` and run `vat skills validate` or `vat skills build` — those commands apply `allow` and gate the build. See `docs/validation-codes.md` for the full code reference and the VAT agent-authoring skill for configuration patterns.
@@ -298,19 +298,37 @@ Use `stripPrefix` to remove a common directory prefix (e.g., `"knowledge-base"`)
298
298
  | `{{link.resource.fileName}}` | Target filename (if resolved) |
299
299
  | `{{skill.name}}` | Skill name from frontmatter |
300
300
 
301
- **`ignoreValidationErrors`** — Override specific validation rules when justified:
302
-
303
- ```json
304
- "ignoreValidationErrors": {
305
- "SKILL_LENGTH_EXCEEDS_RECOMMENDED": "Large domain requires detailed examples",
306
- "NO_PROGRESSIVE_DISCLOSURE": {
307
- "reason": "Temporary refactoring planned",
308
- "expires": "2026-06-30"
309
- }
310
- }
301
+ **`validation`** — Unified framework for overriding default severity and allowing specific issue instances:
302
+
303
+ ```yaml
304
+ # In vibe-agent-toolkit.config.yaml under skills.defaults or skills.config.<name>
305
+ validation:
306
+ severity:
307
+ LINK_DROPPED_BY_DEPTH: error # upgrade: block on depth-dropped links
308
+ LINK_TO_NAVIGATION_FILE: ignore # silence: this skill intentionally links to READMEs
309
+ allow:
310
+ PACKAGED_UNREFERENCED_FILE:
311
+ - paths: ["templates/runtime.json"]
312
+ reason: "consumed programmatically at runtime"
313
+ expires: "2026-09-30"
314
+ SKILL_LENGTH_EXCEEDS_RECOMMENDED:
315
+ - reason: "whole-skill concern; paths defaults to ['**/*']"
311
316
  ```
312
317
 
313
- Use sparingly. Prefer fixing the underlying issue over suppressing warnings.
318
+ Two sub-keys, each covering a different override granularity:
319
+
320
+ - **`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.
321
+ - **`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.
322
+
323
+ Things adopters typically adjust:
324
+
325
+ - Downgrade `LINK_DROPPED_BY_DEPTH` to `ignore` when intentionally linking out to external docs.
326
+ - Allow specific files under `PACKAGED_UNREFERENCED_FILE` when they're consumed programmatically by CLI scripts at runtime.
327
+ - Raise `ALLOW_EXPIRED` to `error` for zero-tolerance expiry policies.
328
+
329
+ Expired `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).
330
+
331
+ Full code reference at `docs/validation-codes.md`. `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.
314
332
 
315
333
  ## Testing Agents
316
334
 
@@ -368,7 +386,7 @@ const output2 = await agent.execute({
368
386
 
369
387
  ## References
370
388
 
371
- - Skill Quality Checklist — Pre-publication checklist for all skills (general + CLI-backed)
389
+ - [Skill Quality Checklist](resources/skill-quality-checklist.md) — Pre-publication checklist for all skills (general + CLI-backed)
372
390
  - agent-authoring.md — Complete patterns guide
373
391
  - orchestration.md — Multi-agent workflows
374
392
  - [Building Effective Agents - Anthropic](https://www.anthropic.com/research/building-effective-agents)
@@ -0,0 +1,42 @@
1
+ # Skill Quality Checklist
2
+
3
+ Work through this checklist before publishing a skill. Items are grouped into general (all skills) and CLI-backed (skills that bundle and invoke scripts).
4
+
5
+ ## General — All Skills
6
+
7
+ - [ ] **Name**: short, specific, lowercase-with-hyphens. Matches what the skill does, not how.
8
+ - [ ] **Description — 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" not "This skill is used for when you need to analyze sprints."
9
+ - [ ] **Description — no filler openers, third-person voice**: never start with "This skill...", "A skill that...", "Used to...", "Use when you want to..." — these waste the first tokens on zero-information words. Avoid first/second person ("I can help...", "You can use...") — Anthropic guidance is third person throughout.
10
+ - [ ] **Description ≤250 characters**: Claude Code truncates descriptions at 250 characters in the `/skills` listing (since v2.1.86). Aim for ≤200 chars for safety; ≤130 chars if shipping a large skill collection (60+ skills) so the total budget fits.
11
+ - [ ] **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.
12
+ - [ ] **SKILL.md body ≤500 lines**: Anthropic recommends keeping SKILL.md under 500 lines. Split detailed content into reference files when approaching the limit.
13
+ - [ ] **Single responsibility**: the skill does one thing well. If it has multiple unrelated sections, consider splitting into separate skills.
14
+ - [ ] **Consistent terminology**: pick one term per concept and use it throughout. Switching between synonyms ("artifact" vs "bundle" vs "package") confuses agents.
15
+ - [ ] **No time-sensitive content**: avoid "as of November 2025" or "use the new API after July 2026". Route deprecated guidance into a clearly labeled "old patterns" section so agents skip it.
16
+ - [ ] **Every bundled file is referenced**: if a file is in the package, some markdown file should link to it or explain what it is. Dead files confuse agents and waste context.
17
+ - [ ] **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.
18
+ - [ ] **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.
19
+ - [ ] **All links resolve**: every `[text](path)` link points to a file that exists. Run `vat verify` to check.
20
+ - [ ] **Build clean**: `vat skills build` succeeds and `vat verify` passes with zero errors.
21
+ - [ ] **Test the trigger**: ask yourself "if an agent sees only this name and description, will it know when to load this skill?" If you need to read the SKILL.md to understand the description, the description is wrong.
22
+
23
+ ## CLI-Backed Skills — Additional Checks
24
+
25
+ These apply to skills that bundle executable scripts and instruct agents to run commands.
26
+
27
+ - [ ] **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.
28
+ - [ ] **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.
29
+ - [ ] **CLI invocation section**: provide exact command patterns with placeholder arguments. Agents copy these verbatim — ambiguous prose gets misinterpreted.
30
+ - [ ] **Error handling guidance**: document what to do when the CLI fails. Which errors are retryable? When should the agent stop and ask the user?
31
+ - [ ] **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.
32
+ - [ ] **Cross-platform commands**: avoid `timeout` (not on macOS), platform-specific `sed` flags, `grep -P`, and other non-portable utilities. If platform-specific, document alternatives.
33
+ - [ ] **`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.
34
+ - [ ] **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.
35
+
36
+ ## Using This Checklist
37
+
38
+ This 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.
39
+
40
+ Items 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 already enforced by `vat verify` — this checklist covers the gaps.
41
+
42
+ Reviewed against external best practices (Anthropic skills documentation, anthropics/skills repository, superpowers conventions, Claude Code release notes through 2026-04-15) before initial publication.
@@ -79,7 +79,7 @@ Before changing VAT source code, write a test that reproduces the bug:
79
79
  - **CLI behavior** → add an integration test in `packages/cli/test/integration/`
80
80
  - **End-to-end workflow** → add a system test in `packages/cli/test/system/`
81
81
 
82
- See [docs/writing-tests.md](resources/writing-tests.md) for test patterns and
82
+ See docs/writing-tests.md for test patterns and
83
83
  the unit/integration/system classification guide.
84
84
 
85
85
  ## Step 5: Validate Before Committing
@@ -106,6 +106,6 @@ is safe to commit. Do not commit until `bun run validate` passes.
106
106
 
107
107
  ## See Also
108
108
 
109
- - [docs/debug-and-test-vat-fixes.md](resources/debug-and-test-vat-fixes.md) — Full reference
110
- - [docs/writing-tests.md](resources/writing-tests.md) — Test patterns and classification
111
- - [packages/cli/CLAUDE.md](resources/CLAUDE.md) — CLI development guidelines
109
+ - docs/debug-and-test-vat-fixes.md — Full reference
110
+ - docs/writing-tests.md — Test patterns and classification
111
+ - [packages/cli/CLAUDE.md]() — CLI development guidelines