@vibe-agent-toolkit/resources 0.1.39-rc.9 → 0.1.39

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 (75) hide show
  1. package/dist/content-cache.d.ts +67 -0
  2. package/dist/content-cache.d.ts.map +1 -0
  3. package/dist/content-cache.js +160 -0
  4. package/dist/content-cache.js.map +1 -0
  5. package/dist/external-link-cache.d.ts +16 -2
  6. package/dist/external-link-cache.d.ts.map +1 -1
  7. package/dist/external-link-cache.js +43 -13
  8. package/dist/external-link-cache.js.map +1 -1
  9. package/dist/external-link-validator.d.ts +75 -2
  10. package/dist/external-link-validator.d.ts.map +1 -1
  11. package/dist/external-link-validator.js +184 -4
  12. package/dist/external-link-validator.js.map +1 -1
  13. package/dist/index.d.ts +4 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +12 -0
  16. package/dist/index.js.map +1 -1
  17. package/dist/link-auth-classify.d.ts +34 -0
  18. package/dist/link-auth-classify.d.ts.map +1 -0
  19. package/dist/link-auth-classify.js +42 -0
  20. package/dist/link-auth-classify.js.map +1 -0
  21. package/dist/link-auth-config-build.d.ts +47 -0
  22. package/dist/link-auth-config-build.d.ts.map +1 -0
  23. package/dist/link-auth-config-build.js +86 -0
  24. package/dist/link-auth-config-build.js.map +1 -0
  25. package/dist/link-auth-content-fetch.d.ts +75 -0
  26. package/dist/link-auth-content-fetch.d.ts.map +1 -0
  27. package/dist/link-auth-content-fetch.js +101 -0
  28. package/dist/link-auth-content-fetch.js.map +1 -0
  29. package/dist/link-auth-deps-memo.d.ts +40 -0
  30. package/dist/link-auth-deps-memo.d.ts.map +1 -0
  31. package/dist/link-auth-deps-memo.js +47 -0
  32. package/dist/link-auth-deps-memo.js.map +1 -0
  33. package/dist/link-auth-transport.d.ts +44 -0
  34. package/dist/link-auth-transport.d.ts.map +1 -0
  35. package/dist/link-auth-transport.js +151 -0
  36. package/dist/link-auth-transport.js.map +1 -0
  37. package/dist/link-parser.d.ts.map +1 -1
  38. package/dist/link-parser.js +8 -1
  39. package/dist/link-parser.js.map +1 -1
  40. package/dist/link-validator.d.ts +8 -8
  41. package/dist/link-validator.d.ts.map +1 -1
  42. package/dist/link-validator.js +51 -18
  43. package/dist/link-validator.js.map +1 -1
  44. package/dist/resource-registry.d.ts +2 -0
  45. package/dist/resource-registry.d.ts.map +1 -1
  46. package/dist/resource-registry.js +19 -4
  47. package/dist/resource-registry.js.map +1 -1
  48. package/dist/schemas/link-auth.d.ts +1049 -303
  49. package/dist/schemas/link-auth.d.ts.map +1 -1
  50. package/dist/schemas/link-auth.js +39 -20
  51. package/dist/schemas/link-auth.js.map +1 -1
  52. package/dist/schemas/project-config.d.ts +2860 -759
  53. package/dist/schemas/project-config.d.ts.map +1 -1
  54. package/dist/schemas/project-config.js +18 -1
  55. package/dist/schemas/project-config.js.map +1 -1
  56. package/dist/schemas/resource-metadata.d.ts +10 -9
  57. package/dist/schemas/resource-metadata.d.ts.map +1 -1
  58. package/dist/schemas/resource-metadata.js +2 -0
  59. package/dist/schemas/resource-metadata.js.map +1 -1
  60. package/package.json +4 -4
  61. package/src/content-cache.ts +190 -0
  62. package/src/external-link-cache.ts +50 -13
  63. package/src/external-link-validator.ts +268 -5
  64. package/src/index.ts +23 -0
  65. package/src/link-auth-classify.ts +61 -0
  66. package/src/link-auth-config-build.ts +130 -0
  67. package/src/link-auth-content-fetch.ts +146 -0
  68. package/src/link-auth-deps-memo.ts +56 -0
  69. package/src/link-auth-transport.ts +179 -0
  70. package/src/link-parser.ts +8 -1
  71. package/src/link-validator.ts +65 -17
  72. package/src/resource-registry.ts +25 -5
  73. package/src/schemas/link-auth.ts +47 -21
  74. package/src/schemas/project-config.ts +22 -1
  75. package/src/schemas/resource-metadata.ts +2 -0
@@ -3,24 +3,26 @@
3
3
  *
4
4
  * Validates the shape of an adopter's linkAuth configuration: providers
5
5
  * (each either a `use: <macro>` reference or a full inline provider) plus
6
- * an optional cache config. Stricttypos in provider field names are
7
- * errors, per Postel's law ("writing our output → conservative").
6
+ * an optional cache config. **Passthrough**per the repo Postel's Law
7
+ * rule, schemas that parse external data (adopter `vibe-agent-toolkit.config.yaml`)
8
+ * are liberal: unknown fields pass through rather than abort the parse, so
9
+ * an adopter with a forward-compatible field or a typo gets `vat resources
10
+ * validate` degrading gracefully instead of crashing. Typo-catching DX is
11
+ * a separate lint/warn pass, not a hard parse failure.
8
12
  *
9
13
  * Provider entries accept EITHER:
10
14
  * - `{ use: <name>, ...overrides }` — reference a shipped macro by name;
11
- * override fields are deep-merged on top at expansion time. Overrides
12
- * are NOT strictly typed at this layer because they must match the
13
- * macro's shape, which we cannot see until expansion. A typo in an
14
- * override silently no-ops; the full provider shape is validated
15
- * after expansion (slice 2 wires that).
16
- * - A full inline `{ match, rewrite, auth, token, check }` — every field
17
- * required, every nested object strict.
15
+ * override fields are deep-merged on top at expansion time.
16
+ * - A full inline `{ match, rewrite, auth, token, check }` — every required
17
+ * field present, with declared-field types still enforced (passthrough
18
+ * only relaxes unknown-key handling, not type checking on known fields).
18
19
  *
19
20
  * Mirrors the runtime types in `@vibe-agent-toolkit/utils`'s `link-auth/`
20
21
  * module. Keep these aligned: a config that parses here must satisfy the
21
22
  * `Provider` / `LinkAuthConfig` interfaces over there.
22
23
  *
23
- * Per design issue #113 §4 (vocabulary) and §5 (macros).
24
+ * Per design issue #113 §4 (vocabulary) and §5 (macros), and the repo
25
+ * CLAUDE.md Postel's Law rule for adopter-facing configs.
24
26
  */
25
27
 
26
28
  import { z } from 'zod';
@@ -37,7 +39,7 @@ export const ProviderMatchSchema = z
37
39
  .optional()
38
40
  .describe('Globs that, if any match the hostname, exclude this provider'),
39
41
  })
40
- .strict()
42
+ .passthrough()
41
43
  .describe('Provider selection — match.host + optional excludeHost globs');
42
44
 
43
45
  export const RewriteRuleSchema = z
@@ -49,7 +51,7 @@ export const RewriteRuleSchema = z
49
51
  .describe('Computed variables, each a template that references captures from `when`'),
50
52
  to: z.string().min(1).describe('URL template — interpolates ${capture} and ${var}'),
51
53
  })
52
- .strict()
54
+ .passthrough()
53
55
  .describe('A single rewrite rule (one entry in a provider\'s ordered rewrite list)');
54
56
 
55
57
  export const ProviderAuthSchema = z
@@ -58,17 +60,32 @@ export const ProviderAuthSchema = z
58
60
  .record(z.string(), z.string())
59
61
  .describe('Header name → value template. Values interpolate ${token} and any capture/var.'),
60
62
  })
61
- .strict()
63
+ .passthrough()
62
64
  .describe('Auth headers attached to the authenticated fetch');
63
65
 
66
+ /**
67
+ * Optional fetch-mode header overrides (§6.2). Same shape as ProviderAuth,
68
+ * different role: `auth.headers` covers the health-check request; `fetch.headers`
69
+ * covers content retrieval (e.g. GitHub `application/vnd.github.raw` instead of
70
+ * `application/vnd.github+json`). Both templates expand against the same context.
71
+ */
72
+ export const ProviderFetchSchema = z
73
+ .object({
74
+ headers: z
75
+ .record(z.string(), z.string())
76
+ .describe('Header name → value template, same templating as auth.headers.'),
77
+ })
78
+ .passthrough()
79
+ .describe('Optional content-fetch header overrides — distinct from health-check headers');
80
+
64
81
  export const TokenSourceSchema = z
65
82
  .union([
66
- z.object({ env: z.string().min(1) }).strict(),
83
+ z.object({ env: z.string().min(1) }).passthrough(),
67
84
  z
68
85
  .object({
69
86
  command: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]),
70
87
  })
71
- .strict(),
88
+ .passthrough(),
72
89
  ])
73
90
  .describe('A single token source — env var, or argv command (preferred), or convenience string');
74
91
 
@@ -85,22 +102,25 @@ export const ProviderCheckSchema = z
85
102
  'Per-host: does 404 mean "dead" (honest 404 host like Graph) or "ambiguous" (masking host like GitHub)?',
86
103
  ),
87
104
  })
88
- .strict()
105
+ .passthrough()
89
106
  .describe('Status-to-outcome classifier (consumed by the resources layer, not the pure engine)');
90
107
 
91
108
  // ---------------------------------------------------------------------------
92
109
  // Provider entry (inline OR macro reference)
93
110
  // ---------------------------------------------------------------------------
94
111
 
95
- const InlineProviderSchema = z
112
+ export const InlineProviderSchema = z
96
113
  .object({
97
114
  match: ProviderMatchSchema,
98
115
  rewrite: z.array(RewriteRuleSchema).min(1).describe('Ordered rewrite rules — first matching wins'),
99
116
  auth: ProviderAuthSchema,
117
+ fetch: ProviderFetchSchema
118
+ .optional()
119
+ .describe('Optional fetch-mode header override (§6.2) — content retrieval, distinct from health-check'),
100
120
  token: z.array(TokenSourceSchema).describe('Ordered token sources — first non-empty wins'),
101
121
  check: ProviderCheckSchema,
102
122
  })
103
- .strict();
123
+ .passthrough();
104
124
 
105
125
  const MacroProviderSchema = z
106
126
  .object({
@@ -128,7 +148,7 @@ export const LinkAuthCacheSchema = z
128
148
  .optional()
129
149
  .describe('Content cache TTL in minutes (default 30 — used by slice 3 content-fetch)'),
130
150
  })
131
- .strict();
151
+ .passthrough();
132
152
 
133
153
  export const LinkAuthConfigSchema = z
134
154
  .object({
@@ -137,10 +157,16 @@ export const LinkAuthConfigSchema = z
137
157
  .array(ProviderEntrySchema)
138
158
  .describe('Ordered list of providers — first claiming-by-host wins'),
139
159
  })
140
- .strict()
160
+ .passthrough()
141
161
  .describe('`resources.linkAuth` — authenticated external link resolution config');
142
162
 
143
- export type LinkAuthConfig = z.infer<typeof LinkAuthConfigSchema>;
163
+ /**
164
+ * Adopter-facing config shape — what an `vibe-agent-toolkit.config.yaml`
165
+ * parses to. Distinct from `@vibe-agent-toolkit/utils`'s `LinkAuthConfig`
166
+ * (the engine shape, with fully-expanded providers only). The bridge
167
+ * function `buildLinkAuthEngineConfig` converts between the two.
168
+ */
169
+ export type LinkAuthProjectConfig = z.infer<typeof LinkAuthConfigSchema>;
144
170
  export type ProviderEntry = z.infer<typeof ProviderEntrySchema>;
145
171
  export type RewriteRule = z.infer<typeof RewriteRuleSchema>;
146
172
  export type TokenSource = z.infer<typeof TokenSourceSchema>;
@@ -1,4 +1,5 @@
1
1
  import { ValidationConfigSchema } from '@vibe-agent-toolkit/agent-schema';
2
+ import { hasParentTraversalSegment, isAbsoluteAnyPlatform } from '@vibe-agent-toolkit/utils';
2
3
  import { z } from 'zod';
3
4
 
4
5
  import { LinkAuthConfigSchema } from './link-auth.js';
@@ -132,10 +133,26 @@ export const ExcludeReferencesFromBundleSchema = z.object({
132
133
  * Used for build artifacts, unlinked files, and routing overrides.
133
134
  * - source: path relative to project root (where vibe-agent-toolkit.config.yaml lives)
134
135
  * - dest: path relative to the skill's output directory (sibling to SKILL.md)
136
+ * - integrity (optional): byte-verify the copied set against the matched source set at build time
135
137
  */
136
138
  export const SkillFileEntrySchema = z.object({
137
139
  source: z.string().min(1).describe('Source path relative to project root'),
138
- dest: z.string().min(1).describe('Destination path relative to skill output directory'),
140
+ dest: z.string().min(1)
141
+ // Containment guard (zip-slip class): dest is OUR config output and is joined
142
+ // onto the skill output directory at build time, so it must stay inside it.
143
+ // Reject absolute paths (POSIX `/…`, Windows `C:\…`, UNC) and any `..`
144
+ // traversal segment. Defense-in-depth: copy sites also route through
145
+ // safePath.joinUnderRoot().
146
+ .refine(
147
+ (d) => !isAbsoluteAnyPlatform(d) && !hasParentTraversalSegment(d),
148
+ {
149
+ message:
150
+ 'dest must be a relative path contained in the skill output directory: ' +
151
+ 'no absolute paths (e.g. "/etc/x" or a Windows drive path) and no ".." traversal segments',
152
+ },
153
+ )
154
+ .describe('Destination path relative to skill output directory'),
155
+ integrity: z.boolean().optional().describe('When true, the build asserts the copied dest set exactly matches the matched source set and each file is byte-identical (a future copy-time check; late-bound)'),
139
156
  });
140
157
 
141
158
  export type SkillFileEntry = z.infer<typeof SkillFileEntrySchema>;
@@ -196,6 +213,10 @@ export const TestConfigSchema = z.object({
196
213
  * that is produced by a bundler step and not committed to source.
197
214
  * A non-zero exit code aborts the run (preflight failure, exit 2).
198
215
  */
216
+ env: z.record(z.string(), z.string()).optional()
217
+ .describe('Feature B: explicit env var injections for the experimenter spawn. Values support ${fixturesDir}, ${stagedSkillDir}, ${harnessRoot}, ${resultsDir} interpolation (resolved at stage time). Protected names (PATH, auth, model, admin) cannot be overridden.'),
218
+ passEnv: z.array(z.string().min(1)).optional()
219
+ .describe('Feature A: names of host env vars to forward to the experimenter spawn if present. Protected names are ignored with a warning.'),
199
220
  build: z.string().min(1).optional()
200
221
  .describe('Shell command run once, before staging, to generate build artifacts (cwd = config root)'),
201
222
  }).strict().describe('Per-skill vat skill test configuration');
@@ -10,6 +10,7 @@ import { SHA256Schema } from './checksum.js';
10
10
  * - `anchor`: Link to a heading anchor (e.g., #heading-slug)
11
11
  * - `external`: HTTP/HTTPS URL to external resource
12
12
  * - `email`: Mailto link
13
+ * - `embedded`: Self-contained inline resource (`data:`/`blob:` URI) — no target to validate
13
14
  * - `unknown`: Unclassified link type
14
15
  */
15
16
  export const LinkTypeSchema = z.enum([
@@ -18,6 +19,7 @@ export const LinkTypeSchema = z.enum([
18
19
  'anchor',
19
20
  'external',
20
21
  'email',
22
+ 'embedded',
21
23
  'unknown',
22
24
  ]).describe('Type of link found in markdown resources');
23
25