@vibe-agent-toolkit/vat-development-agents 0.1.35 → 0.1.37

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.
@@ -9,7 +9,7 @@
9
9
  "name": "vibe-agent-toolkit",
10
10
  "description": "Development agents and skills for building with vibe-agent-toolkit",
11
11
  "source": "./plugins/vibe-agent-toolkit",
12
- "version": "0.1.35",
12
+ "version": "0.1.37",
13
13
  "author": {
14
14
  "name": "vibe-agent-toolkit contributors"
15
15
  }
@@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.1.37] - 2026-05-16
11
+
12
+ ### Fixed
13
+ - **`vat resources validate` no longer rejects unquoted ISO dates in frontmatter.** `js-yaml`'s default schema still applies the YAML 1.1 `!!timestamp` tag, silently promoting `date: 2026-04-15` to a JavaScript `Date` object. Schemas typed `{ "type": "string" }` then failed with `got: "2026-04-15T00:00:00.000Z". Expected type: "string"`. VAT now parses frontmatter (and all internal YAML) with the YAML 1.2 spec (js-yaml's `CORE_SCHEMA`), so unquoted ISO dates stay as strings — matching `yaml` (eemeli/yaml) and YAML 1.2 defaults across the ecosystem. Adopters with ADR/PRD frontmatter using the conventional unquoted date format no longer have to quote every date field. Norway-style booleans (`yes`/`no`/`on`/`off`) and octal literals were already handled correctly by js-yaml v4 defaults.
14
+
15
+ - **Clearer diagnosis when a `frontmatterSchema` resolves to a missing file.** When a `frontmatterSchema` configured as an npm bare specifier resolves through the package's `exports` map to a path that doesn't exist on disk (typically because the publishing package shipped its `exports` field but its build never wrote the artifact — e.g. a broken Windows-only main-module check in the publisher's `gen-schemas` script), `vat resources validate` now names the missing file, says "does not exist on disk", and points at the publisher's build. The previous generic "Cannot find module … Check the package's exports field, or run install in `<baseDir>`" message sent adopters hunting for install-state or path-separator bugs. `ERR_PACKAGE_PATH_NOT_EXPORTED` and "package not installed" remain distinct failure modes with their own messages.
16
+ - **`validation.allow` entries now match paths under dotfile directories.** `validation.allow[CODE].paths` globs like `**/*` and `**/SKILL.md` previously failed to match any path traversing a dotfile directory (`.claude/skills/...`, `.worktrees/<branch>/...`, `.config/...`). Allow entries on skills under those locations silently never applied, so suppressed `CAPABILITY_*` issues kept emitting and `unused` records stayed empty even when the allow was correct. Latent since `0.1.30`.
17
+ - **`excludeReferencesFromBundle` rules now match links under dotfile directories.** Same root cause: `excludeReferencesFromBundle` patterns silently failed to drop bundle references whose paths traversed a dotfile dir. Bundles included files the config asked to exclude.
18
+ - **`vat audit --exclude` patterns now match paths under dotfile directories.** Same root cause: `vat audit ~/.claude/plugins --exclude '**/foo'` silently ignored the exclude on dotfile-traversing paths.
19
+
20
+ ## [0.1.36] - 2026-05-16
21
+
22
+ ### Added
23
+ - **Frontmatter URI-reference link validation.** `vat resources validate` now walks frontmatter values at JSON Schema positions with a URI-family format (`uri-reference`, `uri`, `iri-reference`, `iri`) and validates them through the same engine as markdown links — file existence, anchor resolution, gitignore safety. Absolute URLs in those fields feed into the existing external URL health-check pass when enabled on the collection. Default-on for any collection whose schema declares those formats; opt out via `validation.checkFrontmatterLinks: false` per collection or the global CLI flag `--no-check-frontmatter-links`. Four new issue codes (`frontmatter_link_broken`, `frontmatter_anchor_missing`, `frontmatter_link_to_gitignored`, `frontmatter_unknown_link`) — see [`docs/validation-codes.md`](docs/validation-codes.md). Full guide: [`docs/guides/collection-validation.md#frontmatter-link-validation`](docs/guides/collection-validation.md#frontmatter-link-validation).
24
+ - **npm bare specifiers for `frontmatterSchema`.** Collection `frontmatterSchema` in `vibe-agent-toolkit.config.yaml` and the `vat resources validate --frontmatter-schema` flag now accept npm bare specifiers (`@scope/pkg/schemas/foo.json` or `pkg/schemas/foo.json`) in addition to filesystem paths. VAT resolves them from your project's `node_modules`, honoring the target package's `exports` map — so schema-publishing packages own their internal layout and consumers don't hardcode `dist/` paths. Filesystem-path behavior is unchanged. Full guide: [`docs/guides/collection-validation.md#schema-paths`](docs/guides/collection-validation.md#schema-paths).
25
+
10
26
  ## [0.1.35] - 2026-05-09
11
27
 
12
28
  ### Added
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "license": "MIT",
3
3
  "name": "vibe-agent-toolkit",
4
- "version": "0.1.35",
4
+ "version": "0.1.37",
5
5
  "author": {
6
6
  "name": "vibe-agent-toolkit contributors"
7
7
  },
@@ -79,6 +79,38 @@ frontmatterSchema: "@vibe-agent-toolkit/agent-skills/..." # npm package export
79
79
  3. Run `vat resources validate` — any existing docs missing required fields will be flagged
80
80
  4. Fix frontmatter in existing docs, then CI is clean
81
81
 
82
+ ## Recommend `format: "uri-reference"` for path-shaped frontmatter fields
83
+
84
+ When designing a schema for a knowledge-base collection that references other files (e.g., `parent_prd`, `supersedes`, `adr_citations[*].adr`, `artifacts`), declare `format: "uri-reference"` on the field. VAT will then validate those values against the file system using the same engine as markdown link checking — broken paths, missing anchors, gitignore violations, and unknown URI schemes all produce errors.
85
+
86
+ To require local committed files (no absolute URLs), add a `pattern` excluding scheme prefixes. Standard JSON Schema; stays portable.
87
+
88
+ VAT walks four URI-family formats: `uri-reference`, `uri`, `iri-reference`, `iri`. `uri-template` (RFC 6570) is intentionally NOT walked — templated values contain placeholders.
89
+
90
+ Absolute URLs in URI-reference fields feed into the existing external URL health-check pass when `checkUrlLinks: true` is set on the collection.
91
+
92
+ Opt-out: `checkFrontmatterLinks: false` per collection, or `--no-check-frontmatter-links` on the CLI.
93
+
94
+ ## Annotating Frontmatter Schemas with Zod 4
95
+
96
+ If your project generates JSON Schemas from Zod (via `z.toJSONSchema()`), annotate frontmatter fields that hold links with the appropriate `format` so VAT's link validator picks them up:
97
+
98
+ ```typescript
99
+ import { z } from 'zod';
100
+
101
+ const PrdFrontmatter = z.object({
102
+ spec_ref: z.string().meta({ format: 'uri-reference' }), // repo-relative or absolute
103
+ roadmap: z.url().meta({ format: 'uri' }), // full URL only
104
+ doc_anchor: z.string().meta({ format: 'json-pointer' }), // JSON Pointer
105
+ });
106
+ ```
107
+
108
+ `format` values VAT walks for link validation: `uri`, `uri-reference`, `iri`, `iri-reference`. `uri-template` (RFC 6570) is intentionally NOT walked — templated values contain placeholders.
109
+
110
+ **Zod 3 users:** `.meta()` does not exist in Zod 3. Either upgrade your schema-generation step to Zod 4 (runtime consumers can stay on Zod 3 via peer dependency + common-subset usage), or post-process the generated JSON Schema to inject `format` on the relevant field paths.
111
+
112
+ **Tip:** `format` is advisory in JSON Schema; pair it with a `pattern` regex when you also need parse-time rejection of invalid inputs.
113
+
82
114
  ## Validation Output
83
115
 
84
116
  ```yaml
@@ -23,6 +23,8 @@ export const fragments: {
23
23
  readonly aFileCanBelongToMultipleCollections: Fragment;
24
24
  readonly schemaPathFormats: Fragment;
25
25
  readonly addingANewDocType: Fragment;
26
+ readonly recommendFormatUriReferenceForPathShapedFrontmatterFields: Fragment;
27
+ readonly annotatingFrontmatterSchemasWithZod4: Fragment;
26
28
  readonly validationOutput: Fragment;
27
29
  };
28
30
 
@@ -7,7 +7,7 @@ export const meta = {
7
7
  description: "Use when working with VAT resource collections, per-directory frontmatter schema validation, link validation, or the vat resources command. Covers collection configuration, schema mapping, and validation modes."
8
8
  };
9
9
 
10
- export const text = "\n# VAT Resources: Collections & Frontmatter Validation\n\n## What Resource Collections Are\n\nA **resource collection** is a named group of files that share a validation schema.\nCollections are defined in \`vibe-agent-toolkit.config.yaml\` and enable different\ndirectories to have different required frontmatter — without writing a single line of code.\n\n## Config Format\n\n\`\`\`yaml\nversion: 1\n\nresources:\n collections:\n # Name your collection to match the doc type\n systems:\n include: [\"docs/systems/**/*.md\"]\n exclude: [\"docs/systems/README.md\"] # exclude human-only ToCs\n validation:\n frontmatterSchema: \"schemas/system.schema.json\"\n mode: permissive # required fields enforced; extra fields allowed\n\n adrs:\n include: [\"docs/architecture/adr/**/*.md\"]\n validation:\n frontmatterSchema: \"schemas/adr.schema.json\"\n mode: permissive\n\n skills:\n include: [\"**/SKILL.md\"]\n validation:\n frontmatterSchema: \"@vibe-agent-toolkit/agent-skills/schemas/skill-frontmatter.json\"\n mode: strict # SKILL.md: no extra fields beyond spec\n\`\`\`\n\n## Validation Modes\n\n| Mode | Required fields | Extra fields | Use for |\n|---|---|---|---|\n| \`permissive\` | Enforced | Allowed | Docs with project-specific extras |\n| \`strict\` | Enforced | Error | SKILL.md, API specs, tightly controlled schemas |\n\n## Running Validation\n\n\`\`\`bash\n# Validate all collections (reads vibe-agent-toolkit.config.yaml)\nvat resources validate\n\n# Validate specific collection only\nvat resources validate --collection systems\n\n# Validate with extra schema (adds to collection schemas)\nvat resources validate --frontmatter-schema ./extra.json\n\`\`\`\n\n## A File Can Belong to Multiple Collections\n\nIf a file matches multiple \`include\` patterns, **all matching schemas are validated**.\nValidation fails if any schema fails.\n\n## Schema Path Formats\n\n\`\`\`yaml\nfrontmatterSchema: \"./schemas/system.schema.json\" # relative to config\nfrontmatterSchema: \"/absolute/path/schema.json\" # absolute\nfrontmatterSchema: \"@vibe-agent-toolkit/agent-skills/...\" # npm package export\n\`\`\`\n\n## Adding a New Doc Type\n\n1. Create \`schemas/<type>.schema.json\` with \`required\` fields\n2. Add a collection entry in \`vibe-agent-toolkit.config.yaml\`\n3. Run \`vat resources validate\` — any existing docs missing required fields will be flagged\n4. Fix frontmatter in existing docs, then CI is clean\n\n## Validation Output\n\n\`\`\`yaml\nstatus: success\nfilesScanned: 47\ncollections:\n systems:\n resourceCount: 7\n hasSchema: true\n validationMode: permissive\n adrs:\n resourceCount: 12\n hasSchema: true\n validationMode: permissive\nduration: 234ms\n\`\`\`\n\nErrors appear in stderr with \`file:line: message\` format for editor navigation.\n";
10
+ export const text = "\n# VAT Resources: Collections & Frontmatter Validation\n\n## What Resource Collections Are\n\nA **resource collection** is a named group of files that share a validation schema.\nCollections are defined in \`vibe-agent-toolkit.config.yaml\` and enable different\ndirectories to have different required frontmatter — without writing a single line of code.\n\n## Config Format\n\n\`\`\`yaml\nversion: 1\n\nresources:\n collections:\n # Name your collection to match the doc type\n systems:\n include: [\"docs/systems/**/*.md\"]\n exclude: [\"docs/systems/README.md\"] # exclude human-only ToCs\n validation:\n frontmatterSchema: \"schemas/system.schema.json\"\n mode: permissive # required fields enforced; extra fields allowed\n\n adrs:\n include: [\"docs/architecture/adr/**/*.md\"]\n validation:\n frontmatterSchema: \"schemas/adr.schema.json\"\n mode: permissive\n\n skills:\n include: [\"**/SKILL.md\"]\n validation:\n frontmatterSchema: \"@vibe-agent-toolkit/agent-skills/schemas/skill-frontmatter.json\"\n mode: strict # SKILL.md: no extra fields beyond spec\n\`\`\`\n\n## Validation Modes\n\n| Mode | Required fields | Extra fields | Use for |\n|---|---|---|---|\n| \`permissive\` | Enforced | Allowed | Docs with project-specific extras |\n| \`strict\` | Enforced | Error | SKILL.md, API specs, tightly controlled schemas |\n\n## Running Validation\n\n\`\`\`bash\n# Validate all collections (reads vibe-agent-toolkit.config.yaml)\nvat resources validate\n\n# Validate specific collection only\nvat resources validate --collection systems\n\n# Validate with extra schema (adds to collection schemas)\nvat resources validate --frontmatter-schema ./extra.json\n\`\`\`\n\n## A File Can Belong to Multiple Collections\n\nIf a file matches multiple \`include\` patterns, **all matching schemas are validated**.\nValidation fails if any schema fails.\n\n## Schema Path Formats\n\n\`\`\`yaml\nfrontmatterSchema: \"./schemas/system.schema.json\" # relative to config\nfrontmatterSchema: \"/absolute/path/schema.json\" # absolute\nfrontmatterSchema: \"@vibe-agent-toolkit/agent-skills/...\" # npm package export\n\`\`\`\n\n## Adding a New Doc Type\n\n1. Create \`schemas/<type>.schema.json\` with \`required\` fields\n2. Add a collection entry in \`vibe-agent-toolkit.config.yaml\`\n3. Run \`vat resources validate\` — any existing docs missing required fields will be flagged\n4. Fix frontmatter in existing docs, then CI is clean\n\n## Recommend \`format: \"uri-reference\"\` for path-shaped frontmatter fields\n\nWhen designing a schema for a knowledge-base collection that references other files (e.g., \`parent_prd\`, \`supersedes\`, \`adr_citations[*].adr\`, \`artifacts\`), declare \`format: \"uri-reference\"\` on the field. VAT will then validate those values against the file system using the same engine as markdown link checking — broken paths, missing anchors, gitignore violations, and unknown URI schemes all produce errors.\n\nTo require local committed files (no absolute URLs), add a \`pattern\` excluding scheme prefixes. Standard JSON Schema; stays portable.\n\nVAT walks four URI-family formats: \`uri-reference\`, \`uri\`, \`iri-reference\`, \`iri\`. \`uri-template\` (RFC 6570) is intentionally NOT walked — templated values contain placeholders.\n\nAbsolute URLs in URI-reference fields feed into the existing external URL health-check pass when \`checkUrlLinks: true\` is set on the collection.\n\nOpt-out: \`checkFrontmatterLinks: false\` per collection, or \`--no-check-frontmatter-links\` on the CLI.\n\n## Annotating Frontmatter Schemas with Zod 4\n\nIf your project generates JSON Schemas from Zod (via \`z.toJSONSchema()\`), annotate frontmatter fields that hold links with the appropriate \`format\` so VAT\'s link validator picks them up:\n\n\`\`\`typescript\nimport { z } from \'zod\';\n\nconst PrdFrontmatter = z.object({\n spec_ref: z.string().meta({ format: \'uri-reference\' }), // repo-relative or absolute\n roadmap: z.url().meta({ format: \'uri\' }), // full URL only\n doc_anchor: z.string().meta({ format: \'json-pointer\' }), // JSON Pointer\n});\n\`\`\`\n\n\`format\` values VAT walks for link validation: \`uri\`, \`uri-reference\`, \`iri\`, \`iri-reference\`. \`uri-template\` (RFC 6570) is intentionally NOT walked — templated values contain placeholders.\n\n**Zod 3 users:** \`.meta()\` does not exist in Zod 3. Either upgrade your schema-generation step to Zod 4 (runtime consumers can stay on Zod 3 via peer dependency + common-subset usage), or post-process the generated JSON Schema to inject \`format\` on the relevant field paths.\n\n**Tip:** \`format\` is advisory in JSON Schema; pair it with a \`pattern\` regex when you also need parse-time rejection of invalid inputs.\n\n## Validation Output\n\n\`\`\`yaml\nstatus: success\nfilesScanned: 47\ncollections:\n systems:\n resourceCount: 7\n hasSchema: true\n validationMode: permissive\n adrs:\n resourceCount: 12\n hasSchema: true\n validationMode: permissive\nduration: 234ms\n\`\`\`\n\nErrors appear in stderr with \`file:line: message\` format for editor navigation.\n";
11
11
 
12
12
  export const fragments = {
13
13
  whatResourceCollectionsAre: {
@@ -45,6 +45,16 @@ export const fragments = {
45
45
  body: "1. Create \`schemas/<type>.schema.json\` with \`required\` fields\n2. Add a collection entry in \`vibe-agent-toolkit.config.yaml\`\n3. Run \`vat resources validate\` — any existing docs missing required fields will be flagged\n4. Fix frontmatter in existing docs, then CI is clean",
46
46
  text: "## Adding a New Doc Type\n\n1. Create \`schemas/<type>.schema.json\` with \`required\` fields\n2. Add a collection entry in \`vibe-agent-toolkit.config.yaml\`\n3. Run \`vat resources validate\` — any existing docs missing required fields will be flagged\n4. Fix frontmatter in existing docs, then CI is clean"
47
47
  },
48
+ recommendFormatUriReferenceForPathShapedFrontmatterFields: {
49
+ header: "## Recommend \`format: \"uri-reference\"\` for path-shaped frontmatter fields",
50
+ body: "When designing a schema for a knowledge-base collection that references other files (e.g., \`parent_prd\`, \`supersedes\`, \`adr_citations[*].adr\`, \`artifacts\`), declare \`format: \"uri-reference\"\` on the field. VAT will then validate those values against the file system using the same engine as markdown link checking — broken paths, missing anchors, gitignore violations, and unknown URI schemes all produce errors.\n\nTo require local committed files (no absolute URLs), add a \`pattern\` excluding scheme prefixes. Standard JSON Schema; stays portable.\n\nVAT walks four URI-family formats: \`uri-reference\`, \`uri\`, \`iri-reference\`, \`iri\`. \`uri-template\` (RFC 6570) is intentionally NOT walked — templated values contain placeholders.\n\nAbsolute URLs in URI-reference fields feed into the existing external URL health-check pass when \`checkUrlLinks: true\` is set on the collection.\n\nOpt-out: \`checkFrontmatterLinks: false\` per collection, or \`--no-check-frontmatter-links\` on the CLI.",
51
+ text: "## Recommend \`format: \"uri-reference\"\` for path-shaped frontmatter fields\n\nWhen designing a schema for a knowledge-base collection that references other files (e.g., \`parent_prd\`, \`supersedes\`, \`adr_citations[*].adr\`, \`artifacts\`), declare \`format: \"uri-reference\"\` on the field. VAT will then validate those values against the file system using the same engine as markdown link checking — broken paths, missing anchors, gitignore violations, and unknown URI schemes all produce errors.\n\nTo require local committed files (no absolute URLs), add a \`pattern\` excluding scheme prefixes. Standard JSON Schema; stays portable.\n\nVAT walks four URI-family formats: \`uri-reference\`, \`uri\`, \`iri-reference\`, \`iri\`. \`uri-template\` (RFC 6570) is intentionally NOT walked — templated values contain placeholders.\n\nAbsolute URLs in URI-reference fields feed into the existing external URL health-check pass when \`checkUrlLinks: true\` is set on the collection.\n\nOpt-out: \`checkFrontmatterLinks: false\` per collection, or \`--no-check-frontmatter-links\` on the CLI."
52
+ },
53
+ annotatingFrontmatterSchemasWithZod4: {
54
+ header: "## Annotating Frontmatter Schemas with Zod 4",
55
+ body: "If your project generates JSON Schemas from Zod (via \`z.toJSONSchema()\`), annotate frontmatter fields that hold links with the appropriate \`format\` so VAT\'s link validator picks them up:\n\n\`\`\`typescript\nimport { z } from \'zod\';\n\nconst PrdFrontmatter = z.object({\n spec_ref: z.string().meta({ format: \'uri-reference\' }), // repo-relative or absolute\n roadmap: z.url().meta({ format: \'uri\' }), // full URL only\n doc_anchor: z.string().meta({ format: \'json-pointer\' }), // JSON Pointer\n});\n\`\`\`\n\n\`format\` values VAT walks for link validation: \`uri\`, \`uri-reference\`, \`iri\`, \`iri-reference\`. \`uri-template\` (RFC 6570) is intentionally NOT walked — templated values contain placeholders.\n\n**Zod 3 users:** \`.meta()\` does not exist in Zod 3. Either upgrade your schema-generation step to Zod 4 (runtime consumers can stay on Zod 3 via peer dependency + common-subset usage), or post-process the generated JSON Schema to inject \`format\` on the relevant field paths.\n\n**Tip:** \`format\` is advisory in JSON Schema; pair it with a \`pattern\` regex when you also need parse-time rejection of invalid inputs.",
56
+ text: "## Annotating Frontmatter Schemas with Zod 4\n\nIf your project generates JSON Schemas from Zod (via \`z.toJSONSchema()\`), annotate frontmatter fields that hold links with the appropriate \`format\` so VAT\'s link validator picks them up:\n\n\`\`\`typescript\nimport { z } from \'zod\';\n\nconst PrdFrontmatter = z.object({\n spec_ref: z.string().meta({ format: \'uri-reference\' }), // repo-relative or absolute\n roadmap: z.url().meta({ format: \'uri\' }), // full URL only\n doc_anchor: z.string().meta({ format: \'json-pointer\' }), // JSON Pointer\n});\n\`\`\`\n\n\`format\` values VAT walks for link validation: \`uri\`, \`uri-reference\`, \`iri\`, \`iri-reference\`. \`uri-template\` (RFC 6570) is intentionally NOT walked — templated values contain placeholders.\n\n**Zod 3 users:** \`.meta()\` does not exist in Zod 3. Either upgrade your schema-generation step to Zod 4 (runtime consumers can stay on Zod 3 via peer dependency + common-subset usage), or post-process the generated JSON Schema to inject \`format\` on the relevant field paths.\n\n**Tip:** \`format\` is advisory in JSON Schema; pair it with a \`pattern\` regex when you also need parse-time rejection of invalid inputs."
57
+ },
48
58
  validationOutput: {
49
59
  header: "## Validation Output",
50
60
  body: "\`\`\`yaml\nstatus: success\nfilesScanned: 47\ncollections:\n systems:\n resourceCount: 7\n hasSchema: true\n validationMode: permissive\n adrs:\n resourceCount: 12\n hasSchema: true\n validationMode: permissive\nduration: 234ms\n\`\`\`\n\nErrors appear in stderr with \`file:line: message\` format for editor navigation.",
@@ -79,6 +79,38 @@ frontmatterSchema: "@vibe-agent-toolkit/agent-skills/..." # npm package export
79
79
  3. Run `vat resources validate` — any existing docs missing required fields will be flagged
80
80
  4. Fix frontmatter in existing docs, then CI is clean
81
81
 
82
+ ## Recommend `format: "uri-reference"` for path-shaped frontmatter fields
83
+
84
+ When designing a schema for a knowledge-base collection that references other files (e.g., `parent_prd`, `supersedes`, `adr_citations[*].adr`, `artifacts`), declare `format: "uri-reference"` on the field. VAT will then validate those values against the file system using the same engine as markdown link checking — broken paths, missing anchors, gitignore violations, and unknown URI schemes all produce errors.
85
+
86
+ To require local committed files (no absolute URLs), add a `pattern` excluding scheme prefixes. Standard JSON Schema; stays portable.
87
+
88
+ VAT walks four URI-family formats: `uri-reference`, `uri`, `iri-reference`, `iri`. `uri-template` (RFC 6570) is intentionally NOT walked — templated values contain placeholders.
89
+
90
+ Absolute URLs in URI-reference fields feed into the existing external URL health-check pass when `checkUrlLinks: true` is set on the collection.
91
+
92
+ Opt-out: `checkFrontmatterLinks: false` per collection, or `--no-check-frontmatter-links` on the CLI.
93
+
94
+ ## Annotating Frontmatter Schemas with Zod 4
95
+
96
+ If your project generates JSON Schemas from Zod (via `z.toJSONSchema()`), annotate frontmatter fields that hold links with the appropriate `format` so VAT's link validator picks them up:
97
+
98
+ ```typescript
99
+ import { z } from 'zod';
100
+
101
+ const PrdFrontmatter = z.object({
102
+ spec_ref: z.string().meta({ format: 'uri-reference' }), // repo-relative or absolute
103
+ roadmap: z.url().meta({ format: 'uri' }), // full URL only
104
+ doc_anchor: z.string().meta({ format: 'json-pointer' }), // JSON Pointer
105
+ });
106
+ ```
107
+
108
+ `format` values VAT walks for link validation: `uri`, `uri-reference`, `iri`, `iri-reference`. `uri-template` (RFC 6570) is intentionally NOT walked — templated values contain placeholders.
109
+
110
+ **Zod 3 users:** `.meta()` does not exist in Zod 3. Either upgrade your schema-generation step to Zod 4 (runtime consumers can stay on Zod 3 via peer dependency + common-subset usage), or post-process the generated JSON Schema to inject `format` on the relevant field paths.
111
+
112
+ **Tip:** `format` is advisory in JSON Schema; pair it with a `pattern` regex when you also need parse-time rejection of invalid inputs.
113
+
82
114
  ## Validation Output
83
115
 
84
116
  ```yaml
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibe-agent-toolkit/vat-development-agents",
3
- "version": "0.1.35",
3
+ "version": "0.1.37",
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.35",
71
- "@vibe-agent-toolkit/cli": "0.1.35",
70
+ "@vibe-agent-toolkit/agent-schema": "0.1.37",
71
+ "@vibe-agent-toolkit/cli": "0.1.37",
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.35",
76
+ "@vibe-agent-toolkit/resource-compiler": "0.1.37",
77
77
  "ts-patch": "^3.2.1",
78
78
  "typescript": "^5.7.3"
79
79
  },