@vibe-agent-toolkit/resources 0.1.38 → 0.1.39-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.
- package/README.md +33 -24
- package/dist/frontmatter-link-validator.d.ts +9 -9
- package/dist/frontmatter-link-validator.d.ts.map +1 -1
- package/dist/frontmatter-link-validator.js +28 -27
- package/dist/frontmatter-link-validator.js.map +1 -1
- package/dist/frontmatter-validator.d.ts +3 -2
- package/dist/frontmatter-validator.d.ts.map +1 -1
- package/dist/frontmatter-validator.js +8 -14
- package/dist/frontmatter-validator.js.map +1 -1
- package/dist/html-link-parser.d.ts +47 -0
- package/dist/html-link-parser.d.ts.map +1 -0
- package/dist/html-link-parser.js +111 -0
- package/dist/html-link-parser.js.map +1 -0
- package/dist/html-transform.d.ts +45 -0
- package/dist/html-transform.d.ts.map +1 -0
- package/dist/html-transform.js +116 -0
- package/dist/html-transform.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/link-parser.d.ts +26 -2
- package/dist/link-parser.d.ts.map +1 -1
- package/dist/link-parser.js +40 -6
- package/dist/link-parser.js.map +1 -1
- package/dist/link-validator.d.ts +53 -6
- package/dist/link-validator.d.ts.map +1 -1
- package/dist/link-validator.js +100 -131
- package/dist/link-validator.js.map +1 -1
- package/dist/multi-schema-validator.d.ts.map +1 -1
- package/dist/multi-schema-validator.js +6 -8
- package/dist/multi-schema-validator.js.map +1 -1
- package/dist/resource-registry.d.ts +56 -13
- package/dist/resource-registry.d.ts.map +1 -1
- package/dist/resource-registry.js +165 -66
- package/dist/resource-registry.js.map +1 -1
- package/dist/schemas/link-auth.d.ts +382 -0
- package/dist/schemas/link-auth.d.ts.map +1 -0
- package/dist/schemas/link-auth.js +124 -0
- package/dist/schemas/link-auth.js.map +1 -0
- package/dist/schemas/project-config.d.ts +763 -171
- package/dist/schemas/project-config.d.ts.map +1 -1
- package/dist/schemas/project-config.js +5 -0
- package/dist/schemas/project-config.js.map +1 -1
- package/dist/schemas/resource-metadata.d.ts +46 -10
- package/dist/schemas/resource-metadata.d.ts.map +1 -1
- package/dist/schemas/resource-metadata.js +14 -1
- package/dist/schemas/resource-metadata.js.map +1 -1
- package/dist/schemas/validation-result.d.ts +36 -57
- package/dist/schemas/validation-result.d.ts.map +1 -1
- package/dist/schemas/validation-result.js +5 -27
- package/dist/schemas/validation-result.js.map +1 -1
- package/dist/types/resources.d.ts +1 -1
- package/dist/types/resources.d.ts.map +1 -1
- package/dist/types/resources.js.map +1 -1
- package/dist/utils.d.ts +10 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +14 -0
- package/dist/utils.js.map +1 -1
- package/package.json +4 -3
- package/src/frontmatter-link-validator.ts +28 -30
- package/src/frontmatter-validator.ts +19 -16
- package/src/html-link-parser.ts +140 -0
- package/src/html-transform.ts +157 -0
- package/src/index.ts +6 -1
- package/src/link-parser.ts +60 -11
- package/src/link-validator.ts +175 -145
- package/src/multi-schema-validator.ts +10 -8
- package/src/resource-registry.ts +205 -72
- package/src/schemas/link-auth.ts +146 -0
- package/src/schemas/project-config.ts +6 -0
- package/src/schemas/resource-metadata.ts +17 -1
- package/src/schemas/validation-result.ts +5 -29
- package/src/types/resources.ts +2 -1
- package/src/utils.ts +15 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod schema for `resources.linkAuth` config.
|
|
3
|
+
*
|
|
4
|
+
* Validates the shape of an adopter's linkAuth configuration: providers
|
|
5
|
+
* (each either a `use: <macro>` reference or a full inline provider) plus
|
|
6
|
+
* an optional cache config. Strict — typos in provider field names are
|
|
7
|
+
* errors, per Postel's law ("writing our output → conservative").
|
|
8
|
+
*
|
|
9
|
+
* Provider entries accept EITHER:
|
|
10
|
+
* - `{ 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.
|
|
18
|
+
*
|
|
19
|
+
* Mirrors the runtime types in `@vibe-agent-toolkit/utils`'s `link-auth/`
|
|
20
|
+
* module. Keep these aligned: a config that parses here must satisfy the
|
|
21
|
+
* `Provider` / `LinkAuthConfig` interfaces over there.
|
|
22
|
+
*
|
|
23
|
+
* Per design issue #113 §4 (vocabulary) and §5 (macros).
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import { z } from 'zod';
|
|
27
|
+
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// Leaf types
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
export const ProviderMatchSchema = z
|
|
33
|
+
.object({
|
|
34
|
+
host: z.string().min(1).describe('Glob matched against URL hostname'),
|
|
35
|
+
excludeHost: z
|
|
36
|
+
.array(z.string().min(1))
|
|
37
|
+
.optional()
|
|
38
|
+
.describe('Globs that, if any match the hostname, exclude this provider'),
|
|
39
|
+
})
|
|
40
|
+
.strict()
|
|
41
|
+
.describe('Provider selection — match.host + optional excludeHost globs');
|
|
42
|
+
|
|
43
|
+
export const RewriteRuleSchema = z
|
|
44
|
+
.object({
|
|
45
|
+
when: z.string().min(1).describe('Regex source (RFC-style, JavaScript-compatible) matched against the URL'),
|
|
46
|
+
vars: z
|
|
47
|
+
.record(z.string(), z.string())
|
|
48
|
+
.optional()
|
|
49
|
+
.describe('Computed variables, each a template that references captures from `when`'),
|
|
50
|
+
to: z.string().min(1).describe('URL template — interpolates ${capture} and ${var}'),
|
|
51
|
+
})
|
|
52
|
+
.strict()
|
|
53
|
+
.describe('A single rewrite rule (one entry in a provider\'s ordered rewrite list)');
|
|
54
|
+
|
|
55
|
+
export const ProviderAuthSchema = z
|
|
56
|
+
.object({
|
|
57
|
+
headers: z
|
|
58
|
+
.record(z.string(), z.string())
|
|
59
|
+
.describe('Header name → value template. Values interpolate ${token} and any capture/var.'),
|
|
60
|
+
})
|
|
61
|
+
.strict()
|
|
62
|
+
.describe('Auth headers attached to the authenticated fetch');
|
|
63
|
+
|
|
64
|
+
export const TokenSourceSchema = z
|
|
65
|
+
.union([
|
|
66
|
+
z.object({ env: z.string().min(1) }).strict(),
|
|
67
|
+
z
|
|
68
|
+
.object({
|
|
69
|
+
command: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]),
|
|
70
|
+
})
|
|
71
|
+
.strict(),
|
|
72
|
+
])
|
|
73
|
+
.describe('A single token source — env var, or argv command (preferred), or convenience string');
|
|
74
|
+
|
|
75
|
+
export const ProviderCheckSchema = z
|
|
76
|
+
.object({
|
|
77
|
+
method: z.enum(['GET', 'HEAD']),
|
|
78
|
+
aliveStatus: z
|
|
79
|
+
.array(z.number().int().min(100).max(599))
|
|
80
|
+
.min(1)
|
|
81
|
+
.describe('HTTP status codes meaning the URL is alive (per host semantics)'),
|
|
82
|
+
notFoundMeaning: z
|
|
83
|
+
.enum(['ambiguous', 'dead'])
|
|
84
|
+
.describe(
|
|
85
|
+
'Per-host: does 404 mean "dead" (honest 404 host like Graph) or "ambiguous" (masking host like GitHub)?',
|
|
86
|
+
),
|
|
87
|
+
})
|
|
88
|
+
.strict()
|
|
89
|
+
.describe('Status-to-outcome classifier (consumed by the resources layer, not the pure engine)');
|
|
90
|
+
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
// Provider entry (inline OR macro reference)
|
|
93
|
+
// ---------------------------------------------------------------------------
|
|
94
|
+
|
|
95
|
+
const InlineProviderSchema = z
|
|
96
|
+
.object({
|
|
97
|
+
match: ProviderMatchSchema,
|
|
98
|
+
rewrite: z.array(RewriteRuleSchema).min(1).describe('Ordered rewrite rules — first matching wins'),
|
|
99
|
+
auth: ProviderAuthSchema,
|
|
100
|
+
token: z.array(TokenSourceSchema).describe('Ordered token sources — first non-empty wins'),
|
|
101
|
+
check: ProviderCheckSchema,
|
|
102
|
+
})
|
|
103
|
+
.strict();
|
|
104
|
+
|
|
105
|
+
const MacroProviderSchema = z
|
|
106
|
+
.object({
|
|
107
|
+
use: z.string().min(1).describe('Macro name (e.g. "github", "sharepoint")'),
|
|
108
|
+
})
|
|
109
|
+
.passthrough()
|
|
110
|
+
.describe(
|
|
111
|
+
'Reference a shipped macro by name. Override fields (match/rewrite/auth/token/check) deep-merge on top at expansion time.',
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
export const ProviderEntrySchema = z
|
|
115
|
+
.union([MacroProviderSchema, InlineProviderSchema])
|
|
116
|
+
.describe('A provider entry — either { use: <macro>, ...overrides } or a full inline provider');
|
|
117
|
+
|
|
118
|
+
// ---------------------------------------------------------------------------
|
|
119
|
+
// Top-level linkAuth config
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
|
|
122
|
+
export const LinkAuthCacheSchema = z
|
|
123
|
+
.object({
|
|
124
|
+
ttlMinutes: z
|
|
125
|
+
.number()
|
|
126
|
+
.int()
|
|
127
|
+
.positive()
|
|
128
|
+
.optional()
|
|
129
|
+
.describe('Content cache TTL in minutes (default 30 — used by slice 3 content-fetch)'),
|
|
130
|
+
})
|
|
131
|
+
.strict();
|
|
132
|
+
|
|
133
|
+
export const LinkAuthConfigSchema = z
|
|
134
|
+
.object({
|
|
135
|
+
cache: LinkAuthCacheSchema.optional(),
|
|
136
|
+
providers: z
|
|
137
|
+
.array(ProviderEntrySchema)
|
|
138
|
+
.describe('Ordered list of providers — first claiming-by-host wins'),
|
|
139
|
+
})
|
|
140
|
+
.strict()
|
|
141
|
+
.describe('`resources.linkAuth` — authenticated external link resolution config');
|
|
142
|
+
|
|
143
|
+
export type LinkAuthConfig = z.infer<typeof LinkAuthConfigSchema>;
|
|
144
|
+
export type ProviderEntry = z.infer<typeof ProviderEntrySchema>;
|
|
145
|
+
export type RewriteRule = z.infer<typeof RewriteRuleSchema>;
|
|
146
|
+
export type TokenSource = z.infer<typeof TokenSourceSchema>;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { ValidationConfigSchema } from '@vibe-agent-toolkit/agent-schema';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
|
|
4
|
+
import { LinkAuthConfigSchema } from './link-auth.js';
|
|
5
|
+
|
|
4
6
|
/**
|
|
5
7
|
* Official semver regex from https://semver.org/ (anchored).
|
|
6
8
|
*
|
|
@@ -96,6 +98,10 @@ export const ResourcesConfigSchema = z.object({
|
|
|
96
98
|
.describe('Global default exclude patterns (not used by collections in Phase 2)'),
|
|
97
99
|
collections: z.record(z.string(), CollectionConfigSchema).optional()
|
|
98
100
|
.describe('Named collections of resources'),
|
|
101
|
+
validation: ValidationConfigSchema.optional()
|
|
102
|
+
.describe('Validation framework config: severity overrides and per-code allow entries (applied inside ResourceRegistry.validate)'),
|
|
103
|
+
linkAuth: LinkAuthConfigSchema.optional()
|
|
104
|
+
.describe('Authenticated external link resolution config (issue #113 / link-auth engine)'),
|
|
99
105
|
}).describe('Resources section of project configuration');
|
|
100
106
|
|
|
101
107
|
export type ResourcesConfig = z.infer<typeof ResourcesConfigSchema>;
|
|
@@ -6,6 +6,7 @@ import { SHA256Schema } from './checksum.js';
|
|
|
6
6
|
* Type of link found in markdown resources.
|
|
7
7
|
*
|
|
8
8
|
* - `local_file`: Link to a local file (relative or absolute path)
|
|
9
|
+
* - `local_directory`: Link to a local directory, e.g. a ref ending in `/`
|
|
9
10
|
* - `anchor`: Link to a heading anchor (e.g., #heading-slug)
|
|
10
11
|
* - `external`: HTTP/HTTPS URL to external resource
|
|
11
12
|
* - `email`: Mailto link
|
|
@@ -13,6 +14,7 @@ import { SHA256Schema } from './checksum.js';
|
|
|
13
14
|
*/
|
|
14
15
|
export const LinkTypeSchema = z.enum([
|
|
15
16
|
'local_file',
|
|
17
|
+
'local_directory',
|
|
16
18
|
'anchor',
|
|
17
19
|
'external',
|
|
18
20
|
'email',
|
|
@@ -36,6 +38,16 @@ export const LinkNodeTypeSchema = z.enum([
|
|
|
36
38
|
|
|
37
39
|
export type LinkNodeType = z.infer<typeof LinkNodeTypeSchema>;
|
|
38
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Zod schema for an HTML well-formedness diagnostic.
|
|
43
|
+
*/
|
|
44
|
+
export const HtmlParseErrorSchema = z.object({
|
|
45
|
+
message: z.string().describe('parse5 error code (e.g. "missing-end-tag")'),
|
|
46
|
+
line: z.number().int().positive().optional().describe('1-based source line, when known'),
|
|
47
|
+
}).describe('HTML well-formedness diagnostic');
|
|
48
|
+
|
|
49
|
+
export type HtmlParseError = z.infer<typeof HtmlParseErrorSchema>;
|
|
50
|
+
|
|
39
51
|
/**
|
|
40
52
|
* Represents a heading node in the document's table of contents.
|
|
41
53
|
*
|
|
@@ -96,6 +108,10 @@ export const ResourceMetadataSchema = z.object({
|
|
|
96
108
|
filePath: z.string().describe('Absolute path to the resource file'),
|
|
97
109
|
links: z.array(ResourceLinkSchema).describe('All links found in the resource'),
|
|
98
110
|
headings: z.array(HeadingNodeSchema).describe('Document table of contents (top-level headings only; children are nested)'),
|
|
111
|
+
anchors: z.array(z.string()).optional()
|
|
112
|
+
.describe('Fragment targets for anchor validation (HTML id/name attributes)'),
|
|
113
|
+
parseErrors: z.array(HtmlParseErrorSchema).optional()
|
|
114
|
+
.describe('HTML well-formedness diagnostics (populated for HTML resources only)'),
|
|
99
115
|
frontmatter: z.record(z.string(), z.unknown()).optional()
|
|
100
116
|
.describe('Parsed YAML frontmatter (if present in markdown file)'),
|
|
101
117
|
frontmatterError: z.string().optional()
|
|
@@ -106,6 +122,6 @@ export const ResourceMetadataSchema = z.object({
|
|
|
106
122
|
checksum: SHA256Schema.describe('SHA-256 checksum of file content'),
|
|
107
123
|
collections: z.array(z.string()).optional()
|
|
108
124
|
.describe('Collection names this resource belongs to (populated when using config-based discovery)'),
|
|
109
|
-
}).describe('Complete metadata for a markdown resource');
|
|
125
|
+
}).strict().describe('Complete metadata for a markdown resource');
|
|
110
126
|
|
|
111
127
|
export type ResourceMetadata = z.infer<typeof ResourceMetadataSchema>;
|
|
@@ -1,32 +1,7 @@
|
|
|
1
|
+
import { ValidationIssueSchema } from '@vibe-agent-toolkit/agent-schema';
|
|
1
2
|
import { z } from 'zod';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
* A single validation issue found during link validation.
|
|
5
|
-
*
|
|
6
|
-
* Issue types:
|
|
7
|
-
* - broken_file: Local file link points to non-existent file
|
|
8
|
-
* - broken_anchor: Anchor link points to non-existent heading
|
|
9
|
-
* - frontmatter_missing: Schema requires frontmatter, file has none
|
|
10
|
-
* - frontmatter_invalid_yaml: YAML syntax error in frontmatter
|
|
11
|
-
* - frontmatter_schema_error: Frontmatter fails JSON Schema validation
|
|
12
|
-
* - external_url_dead: External URL returned error status (4xx, 5xx)
|
|
13
|
-
* - external_url_timeout: External URL request timed out
|
|
14
|
-
* - external_url_error: External URL validation failed (DNS, network, etc.)
|
|
15
|
-
* - unknown_link: Unknown link type
|
|
16
|
-
*
|
|
17
|
-
* Includes details about what went wrong, where it occurred, and optionally
|
|
18
|
-
* how to fix it.
|
|
19
|
-
*/
|
|
20
|
-
export const ValidationIssueSchema = z.object({
|
|
21
|
-
resourcePath: z.string().describe('Absolute path to the resource containing the issue'),
|
|
22
|
-
line: z.number().int().positive().optional().describe('Line number where the issue occurs'),
|
|
23
|
-
type: z.string().describe('Issue type identifier (e.g., "broken_file", "broken_anchor", "frontmatter_schema_error", "unknown_link")'),
|
|
24
|
-
link: z.string().describe('The problematic link'),
|
|
25
|
-
message: z.string().describe('Human-readable description of the issue'),
|
|
26
|
-
suggestion: z.string().optional().describe('Optional suggestion for fixing the issue'),
|
|
27
|
-
}).describe('A single validation issue found during link validation');
|
|
28
|
-
|
|
29
|
-
export type ValidationIssue = z.infer<typeof ValidationIssueSchema>;
|
|
4
|
+
export { type ValidationIssue, ValidationIssueSchema } from '@vibe-agent-toolkit/agent-schema';
|
|
30
5
|
|
|
31
6
|
/**
|
|
32
7
|
* Complete results from validating a collection of resources.
|
|
@@ -38,9 +13,10 @@ export const ValidationResultSchema = z.object({
|
|
|
38
13
|
totalResources: z.number().int().nonnegative().describe('Total number of resources validated'),
|
|
39
14
|
totalLinks: z.number().int().nonnegative().describe('Total number of links found across all resources'),
|
|
40
15
|
linksByType: z.record(z.string(), z.number().int().nonnegative()).describe('Count of links by type (e.g., {"local_file": 10, "external": 5})'),
|
|
41
|
-
issues: z.array(ValidationIssueSchema).describe('
|
|
42
|
-
errorCount: z.number().int().nonnegative().describe('Number of issues
|
|
16
|
+
issues: z.array(ValidationIssueSchema).describe('Emitted validation issues (allow-filtered + severity-resolved; ignored issues dropped)'),
|
|
17
|
+
errorCount: z.number().int().nonnegative().describe('Number of emitted issues'),
|
|
43
18
|
passed: z.boolean().describe('True if validation succeeded (errorCount === 0)'),
|
|
19
|
+
hasErrors: z.boolean().describe('True when any emitted issue has resolved severity "error"'),
|
|
44
20
|
durationMs: z.number().nonnegative().describe('Validation duration in milliseconds'),
|
|
45
21
|
timestamp: z.date().describe('When validation was performed'),
|
|
46
22
|
}).describe('Complete results from validating a collection of resources');
|
package/src/types/resources.ts
CHANGED
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
* with optional absolutePath for runtime operations.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import type { ValidationIssue } from '@vibe-agent-toolkit/agent-schema';
|
|
10
|
+
|
|
9
11
|
import type { SHA256 } from '../schemas/checksum.js';
|
|
10
|
-
import type { ValidationIssue } from '../schemas/validation-result.js';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Resource type discriminator for type-safe handling
|
package/src/utils.ts
CHANGED
|
@@ -9,6 +9,21 @@ import path from 'node:path';
|
|
|
9
9
|
import { toForwardSlash, safePath } from '@vibe-agent-toolkit/utils';
|
|
10
10
|
import picomatch from 'picomatch';
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Compute a `ValidationIssue.location`: the (absolute) source file path made
|
|
14
|
+
* relative to the project root. When no project root is known, fall back to the
|
|
15
|
+
* source path forward-slashed so the location is still useful and stable.
|
|
16
|
+
*
|
|
17
|
+
* @param sourceFilePath - Absolute path to the file the issue was found in.
|
|
18
|
+
* @param projectRoot - Project root, or undefined when none could be determined.
|
|
19
|
+
* @returns Forward-slashed relative location (or the forward-slashed absolute path).
|
|
20
|
+
*/
|
|
21
|
+
export function issueLocation(sourceFilePath: string, projectRoot: string | undefined): string {
|
|
22
|
+
return projectRoot === undefined
|
|
23
|
+
? toForwardSlash(sourceFilePath)
|
|
24
|
+
: safePath.relative(projectRoot, sourceFilePath);
|
|
25
|
+
}
|
|
26
|
+
|
|
12
27
|
/**
|
|
13
28
|
* Check if a file path matches a glob pattern.
|
|
14
29
|
*
|