@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
package/dist/link-validator.js
CHANGED
|
@@ -16,14 +16,28 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import fs from 'node:fs/promises';
|
|
18
18
|
import path from 'node:path';
|
|
19
|
+
import { createRegistryIssue } from '@vibe-agent-toolkit/agent-schema';
|
|
19
20
|
import { isGitIgnored, verifyCaseSensitiveFilename, } from '@vibe-agent-toolkit/utils';
|
|
20
|
-
import { isWithinProject, resolveLocalHref } from './utils.js';
|
|
21
|
+
import { isWithinProject, issueLocation, resolveLocalHref } from './utils.js';
|
|
22
|
+
/**
|
|
23
|
+
* Build the common `createRegistryIssue` extras for a link issue: relative
|
|
24
|
+
* location, the problematic href, the line (only when defined — required for
|
|
25
|
+
* exactOptionalPropertyTypes), and an optional suggestion.
|
|
26
|
+
*/
|
|
27
|
+
function linkExtras(link, sourceFilePath, projectRoot, suggestion) {
|
|
28
|
+
return {
|
|
29
|
+
location: issueLocation(sourceFilePath, projectRoot),
|
|
30
|
+
link: link.href,
|
|
31
|
+
...(link.line !== undefined && { line: link.line }),
|
|
32
|
+
...(suggestion !== undefined && { suggestion }),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
21
35
|
/**
|
|
22
36
|
* Validate a single link in a markdown resource.
|
|
23
37
|
*
|
|
24
38
|
* @param link - The link to validate
|
|
25
39
|
* @param sourceFilePath - Absolute path to the file containing the link
|
|
26
|
-
* @param
|
|
40
|
+
* @param fragmentsByFile - Fragment index: file path → set of valid fragments (markdown slugs + HTML id/name)
|
|
27
41
|
* @param options - Validation options (projectRoot, skipGitIgnoreCheck)
|
|
28
42
|
* @returns ValidationIssue if link is broken, null if valid
|
|
29
43
|
*
|
|
@@ -38,12 +52,13 @@ import { isWithinProject, resolveLocalHref } from './utils.js';
|
|
|
38
52
|
* }
|
|
39
53
|
* ```
|
|
40
54
|
*/
|
|
41
|
-
export async function validateLink(link, sourceFilePath,
|
|
55
|
+
export async function validateLink(link, sourceFilePath, fragmentsByFile, options) {
|
|
42
56
|
switch (link.type) {
|
|
43
57
|
case 'local_file':
|
|
44
|
-
|
|
58
|
+
case 'local_directory':
|
|
59
|
+
return await validateLocalFileLink(link, sourceFilePath, fragmentsByFile, options);
|
|
45
60
|
case 'anchor':
|
|
46
|
-
return await validateAnchorLink(link, sourceFilePath,
|
|
61
|
+
return await validateAnchorLink(link, sourceFilePath, fragmentsByFile, options?.projectRoot);
|
|
47
62
|
case 'external':
|
|
48
63
|
// External URLs are not validated - don't report them
|
|
49
64
|
return null;
|
|
@@ -51,13 +66,7 @@ export async function validateLink(link, sourceFilePath, headingsByFile, options
|
|
|
51
66
|
// Email links are valid by default
|
|
52
67
|
return null;
|
|
53
68
|
case 'unknown':
|
|
54
|
-
return
|
|
55
|
-
resourcePath: sourceFilePath,
|
|
56
|
-
line: link.line,
|
|
57
|
-
type: 'unknown_link',
|
|
58
|
-
link: link.href,
|
|
59
|
-
message: 'Unknown link type',
|
|
60
|
-
};
|
|
69
|
+
return createRegistryIssue('LINK_UNKNOWN', 'Unknown link type', linkExtras(link, sourceFilePath, options?.projectRoot));
|
|
61
70
|
default: {
|
|
62
71
|
// TypeScript exhaustiveness check
|
|
63
72
|
const _exhaustive = link.type;
|
|
@@ -70,28 +79,14 @@ export async function validateLink(link, sourceFilePath, headingsByFile, options
|
|
|
70
79
|
* null for `resolved` (caller continues) and `anchor_only` (defensive no-op —
|
|
71
80
|
* the parser classifies anchor-only hrefs as 'anchor', not 'local_file').
|
|
72
81
|
*/
|
|
73
|
-
export function resolutionFailureIssue(resolved, link, sourceFilePath) {
|
|
82
|
+
export function resolutionFailureIssue(resolved, link, sourceFilePath, projectRoot) {
|
|
74
83
|
if (resolved.kind === 'absolute_no_root') {
|
|
75
|
-
return {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
type: 'broken_file',
|
|
79
|
-
link: link.href,
|
|
80
|
-
message: `Absolute-path link "${link.href}" requires a configured projectRoot; ` +
|
|
81
|
-
`none was provided. Configure vibe-agent-toolkit.config.yaml or run ` +
|
|
82
|
-
`from within a git repository.`,
|
|
83
|
-
suggestion: 'Rewrite as a source-relative link, or run from a directory with a config or git ancestor.',
|
|
84
|
-
};
|
|
84
|
+
return createRegistryIssue('LINK_BROKEN_FILE', `Absolute-path link "${link.href}" requires a configured projectRoot; ` +
|
|
85
|
+
`none was provided. Configure vibe-agent-toolkit.config.yaml or run ` +
|
|
86
|
+
`from within a git repository.`, linkExtras(link, sourceFilePath, projectRoot, 'Rewrite as a source-relative link, or run from a directory with a config or git ancestor.'));
|
|
85
87
|
}
|
|
86
88
|
if (resolved.kind === 'absolute_escapes_root') {
|
|
87
|
-
return {
|
|
88
|
-
resourcePath: sourceFilePath,
|
|
89
|
-
line: link.line,
|
|
90
|
-
type: 'broken_file',
|
|
91
|
-
link: link.href,
|
|
92
|
-
message: `Absolute-path link "${link.href}" escapes the project root via path traversal.`,
|
|
93
|
-
suggestion: '',
|
|
94
|
-
};
|
|
89
|
+
return createRegistryIssue('LINK_BROKEN_FILE', `Absolute-path link "${link.href}" escapes the project root via path traversal.`, linkExtras(link, sourceFilePath, projectRoot, ''));
|
|
95
90
|
}
|
|
96
91
|
return null;
|
|
97
92
|
}
|
|
@@ -99,28 +94,14 @@ export function resolutionFailureIssue(resolved, link, sourceFilePath) {
|
|
|
99
94
|
* Convert a non-existent file result into a broken_file ValidationIssue.
|
|
100
95
|
* Returns null when the file exists.
|
|
101
96
|
*/
|
|
102
|
-
export function fileExistenceIssue(fileResult, link, sourceFilePath) {
|
|
97
|
+
export function fileExistenceIssue(fileResult, link, sourceFilePath, projectRoot) {
|
|
103
98
|
if (fileResult.exists)
|
|
104
99
|
return null;
|
|
105
100
|
if (fileResult.actualName) {
|
|
106
101
|
const expectedName = path.basename(fileResult.resolvedPath);
|
|
107
|
-
return {
|
|
108
|
-
resourcePath: sourceFilePath,
|
|
109
|
-
line: link.line,
|
|
110
|
-
type: 'broken_file',
|
|
111
|
-
link: link.href,
|
|
112
|
-
message: `File found but case mismatch: expected "${expectedName}" but found "${fileResult.actualName}". This will fail on case-sensitive filesystems (Linux). Update the link to match the actual filename.`,
|
|
113
|
-
suggestion: `Use "${fileResult.actualName}" instead of "${expectedName}"`,
|
|
114
|
-
};
|
|
102
|
+
return createRegistryIssue('LINK_BROKEN_FILE', `File found but case mismatch: expected "${expectedName}" but found "${fileResult.actualName}". This will fail on case-sensitive filesystems (Linux). Update the link to match the actual filename.`, linkExtras(link, sourceFilePath, projectRoot, `Use "${fileResult.actualName}" instead of "${expectedName}"`));
|
|
115
103
|
}
|
|
116
|
-
return {
|
|
117
|
-
resourcePath: sourceFilePath,
|
|
118
|
-
line: link.line,
|
|
119
|
-
type: 'broken_file',
|
|
120
|
-
link: link.href,
|
|
121
|
-
message: `File not found: ${fileResult.resolvedPath}`,
|
|
122
|
-
suggestion: '',
|
|
123
|
-
};
|
|
104
|
+
return createRegistryIssue('LINK_BROKEN_FILE', `File not found: ${fileResult.resolvedPath}`, linkExtras(link, sourceFilePath, projectRoot, ''));
|
|
124
105
|
}
|
|
125
106
|
/**
|
|
126
107
|
* Check git-ignore safety: a non-ignored source file must not link to a
|
|
@@ -145,75 +126,56 @@ export function gitIgnoreSafetyIssue(link, sourceFilePath, resolvedTarget, optio
|
|
|
145
126
|
: isGitIgnored(resolvedTarget, options.projectRoot);
|
|
146
127
|
if (sourceIsIgnored || !targetIsIgnored)
|
|
147
128
|
return null;
|
|
148
|
-
return {
|
|
149
|
-
resourcePath: sourceFilePath,
|
|
150
|
-
line: link.line,
|
|
151
|
-
type: 'link_to_gitignored',
|
|
152
|
-
link: link.href,
|
|
153
|
-
message: `Non-ignored file links to gitignored file: ${resolvedTarget}. Gitignored files are local-only and will not exist in the repository. Remove this link or unignore the target file.`,
|
|
154
|
-
suggestion: '',
|
|
155
|
-
};
|
|
129
|
+
return createRegistryIssue('LINK_TO_GITIGNORED', `Non-ignored file links to gitignored file: ${resolvedTarget}. Gitignored files are local-only and will not exist in the repository. Remove this link or unignore the target file.`, linkExtras(link, sourceFilePath, options.projectRoot, ''));
|
|
156
130
|
}
|
|
157
131
|
/**
|
|
158
132
|
* Validate a local file link (with optional anchor).
|
|
159
133
|
*/
|
|
160
|
-
async function validateLocalFileLink(link, sourceFilePath,
|
|
134
|
+
async function validateLocalFileLink(link, sourceFilePath, fragmentsByFile, options) {
|
|
161
135
|
const resolved = resolveLocalHref(link.href, sourceFilePath, options?.projectRoot);
|
|
162
136
|
if (resolved.kind !== 'resolved') {
|
|
163
137
|
// anchor_only → null no-op; absolute_no_root / absolute_escapes_root → broken_file.
|
|
164
|
-
return resolutionFailureIssue(resolved, link, sourceFilePath);
|
|
138
|
+
return resolutionFailureIssue(resolved, link, sourceFilePath, options?.projectRoot);
|
|
165
139
|
}
|
|
166
140
|
const fileResult = await validateResolvedFile(resolved.resolvedPath);
|
|
167
|
-
const notFound = fileExistenceIssue(fileResult, link, sourceFilePath);
|
|
141
|
+
const notFound = fileExistenceIssue(fileResult, link, sourceFilePath, options?.projectRoot);
|
|
168
142
|
if (notFound)
|
|
169
143
|
return notFound;
|
|
170
|
-
if (fileResult.isDirectory) {
|
|
171
|
-
return {
|
|
172
|
-
resourcePath: sourceFilePath,
|
|
173
|
-
line: link.line,
|
|
174
|
-
type: 'broken_file',
|
|
175
|
-
link: link.href,
|
|
176
|
-
message: `Link target is a directory: ${fileResult.resolvedPath}`,
|
|
177
|
-
suggestion: 'Link to a file inside the directory (e.g., README.md or index.md), or fix the link to point at the intended file.',
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
144
|
const gitIgnoreIssue = gitIgnoreSafetyIssue(link, sourceFilePath, fileResult.resolvedPath, options);
|
|
181
145
|
if (gitIgnoreIssue)
|
|
182
146
|
return gitIgnoreIssue;
|
|
183
147
|
if (resolved.anchor) {
|
|
184
|
-
const
|
|
185
|
-
if (
|
|
186
|
-
return {
|
|
187
|
-
resourcePath: sourceFilePath,
|
|
188
|
-
line: link.line,
|
|
189
|
-
type: 'broken_anchor',
|
|
190
|
-
link: link.href,
|
|
191
|
-
message: `Anchor not found: #${resolved.anchor} in ${fileResult.resolvedPath}`,
|
|
192
|
-
suggestion: '',
|
|
193
|
-
};
|
|
148
|
+
const check = checkAnchor(resolved.anchor, fileResult.resolvedPath, fragmentsByFile);
|
|
149
|
+
if (check === 'broken') {
|
|
150
|
+
return createRegistryIssue('LINK_BROKEN_ANCHOR', `Anchor not found: #${resolved.anchor} in ${fileResult.resolvedPath}`, linkExtras(link, sourceFilePath, options?.projectRoot, ''));
|
|
194
151
|
}
|
|
195
152
|
}
|
|
196
153
|
return null;
|
|
197
154
|
}
|
|
155
|
+
/**
|
|
156
|
+
* Exhaustiveness guard for the {@link AnchorCheck} union: a compile error at the
|
|
157
|
+
* call site means a new variant was added without being handled here.
|
|
158
|
+
*/
|
|
159
|
+
function assertNever(value) {
|
|
160
|
+
throw new Error(`Unhandled AnchorCheck variant: ${String(value)}`);
|
|
161
|
+
}
|
|
198
162
|
/**
|
|
199
163
|
* Validate an anchor link (within current file).
|
|
200
164
|
*/
|
|
201
|
-
async function validateAnchorLink(link, sourceFilePath,
|
|
165
|
+
async function validateAnchorLink(link, sourceFilePath, fragmentsByFile, projectRoot) {
|
|
202
166
|
// Extract anchor (strip leading #)
|
|
203
167
|
const anchor = link.href.startsWith('#') ? link.href.slice(1) : link.href;
|
|
204
168
|
// Validate anchor exists in current file
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
};
|
|
169
|
+
const check = checkAnchor(anchor, sourceFilePath, fragmentsByFile);
|
|
170
|
+
switch (check) {
|
|
171
|
+
case 'skip':
|
|
172
|
+
case 'valid':
|
|
173
|
+
return null;
|
|
174
|
+
case 'broken':
|
|
175
|
+
return createRegistryIssue('LINK_BROKEN_ANCHOR', `Anchor not found: ${link.href}`, linkExtras(link, sourceFilePath, projectRoot, ''));
|
|
176
|
+
default:
|
|
177
|
+
return assertNever(check);
|
|
215
178
|
}
|
|
216
|
-
return null;
|
|
217
179
|
}
|
|
218
180
|
/**
|
|
219
181
|
* Verify that the resolved filesystem path exists with the correct case.
|
|
@@ -245,53 +207,60 @@ async function validateResolvedFile(resolvedPath) {
|
|
|
245
207
|
return result;
|
|
246
208
|
}
|
|
247
209
|
/**
|
|
248
|
-
*
|
|
249
|
-
*
|
|
250
|
-
* @
|
|
251
|
-
* @param targetFilePath - Absolute path to the file containing the heading
|
|
252
|
-
* @param headingsByFile - Map of file paths to their heading trees
|
|
253
|
-
* @returns True if anchor exists, false otherwise
|
|
254
|
-
*
|
|
255
|
-
* @example
|
|
256
|
-
* ```typescript
|
|
257
|
-
* const valid = await validateAnchor('my-heading', '/project/docs/guide.md', headingsMap);
|
|
258
|
-
* ```
|
|
210
|
+
* Whether a path is an HTML resource (`.html`/`.htm`). The single place the
|
|
211
|
+
* extension drives format-specific behavior: case-sensitive ids (via
|
|
212
|
+
* {@link fragmentIndexEntry}) and the HTML top-fragment navigation rule.
|
|
259
213
|
*/
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
214
|
+
export function isHtmlPath(filePath) {
|
|
215
|
+
return /\.html?$/i.test(filePath);
|
|
216
|
+
}
|
|
217
|
+
/** Build one index entry, choosing the case-folding policy from the file type. */
|
|
218
|
+
export function fragmentIndexEntry(filePath, fragments = new Set()) {
|
|
219
|
+
return { caseSensitive: isHtmlPath(filePath), fragments };
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Build a {@link FragmentIndex} from `[path, fragments]` pairs, deriving each
|
|
223
|
+
* entry's matching policy from its path. Single construction path shared by the
|
|
224
|
+
* registry and tests.
|
|
225
|
+
*/
|
|
226
|
+
export function fragmentIndex(entries = []) {
|
|
227
|
+
const map = new Map();
|
|
228
|
+
for (const [filePath, fragments] of entries) {
|
|
229
|
+
map.set(filePath, fragmentIndexEntry(filePath, fragments));
|
|
265
230
|
}
|
|
266
|
-
|
|
267
|
-
return findHeadingBySlug(headings, anchor);
|
|
231
|
+
return map;
|
|
268
232
|
}
|
|
269
233
|
/**
|
|
270
|
-
*
|
|
271
|
-
*
|
|
272
|
-
* Performs case-insensitive comparison of slugs.
|
|
234
|
+
* Check whether a fragment exists in the target file's anchor set.
|
|
273
235
|
*
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
236
|
+
* - `'skip'` — target file is not indexed; we cannot prove the anchor is
|
|
237
|
+
* broken, so callers must not emit an issue.
|
|
238
|
+
* - Matching follows the entry's `caseSensitive` policy (HTML ids exact,
|
|
239
|
+
* markdown slugs case-folded). The index carries the policy, so this never
|
|
240
|
+
* re-derives the folding rule from the file extension.
|
|
241
|
+
* - For HTML targets the empty fragment (`#`) and `top` (ASCII
|
|
242
|
+
* case-insensitive) are always valid: per the HTML fragment-navigation
|
|
243
|
+
* algorithm both scroll to the top of the document regardless of whether a
|
|
244
|
+
* matching element exists, so `href="#"` / `href="#top"` are not broken.
|
|
277
245
|
*
|
|
278
|
-
* @
|
|
279
|
-
*
|
|
280
|
-
*
|
|
281
|
-
* ```
|
|
246
|
+
* @param anchor - Fragment without the leading `#`.
|
|
247
|
+
* @param targetFilePath - Absolute path of the file the fragment lives in.
|
|
248
|
+
* @param fragmentsByFile - Fragment index carrying each file's matching policy.
|
|
282
249
|
*/
|
|
283
|
-
function
|
|
284
|
-
const
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
}
|
|
250
|
+
export function checkAnchor(anchor, targetFilePath, fragmentsByFile) {
|
|
251
|
+
const entry = fragmentsByFile.get(targetFilePath);
|
|
252
|
+
if (!entry) {
|
|
253
|
+
return 'skip';
|
|
254
|
+
}
|
|
255
|
+
// HTML spec: the empty fragment and "top" (case-insensitive) always navigate
|
|
256
|
+
// to the top of the document — valid even with no matching id. This is an
|
|
257
|
+
// HTML-format navigation rule, distinct from the case-folding policy above.
|
|
258
|
+
if (isHtmlPath(targetFilePath) && (anchor === '' || anchor.toLowerCase() === 'top')) {
|
|
259
|
+
return 'valid';
|
|
294
260
|
}
|
|
295
|
-
|
|
261
|
+
const found = entry.caseSensitive
|
|
262
|
+
? entry.fragments.has(anchor)
|
|
263
|
+
: entry.fragments.has(anchor.toLowerCase());
|
|
264
|
+
return found ? 'valid' : 'broken';
|
|
296
265
|
}
|
|
297
266
|
//# sourceMappingURL=link-validator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link-validator.js","sourceRoot":"","sources":["../src/link-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EACL,YAAY,EAEZ,2BAA2B,GAC5B,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"link-validator.js","sourceRoot":"","sources":["../src/link-validator.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multi-schema-validator.d.ts","sourceRoot":"","sources":["../src/multi-schema-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"multi-schema-validator.d.ts","sourceRoot":"","sources":["../src/multi-schema-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAuB5D;;;;;;;;;;;;GAYG;AACH,wBAAsB,8BAA8B,CAClD,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAChD,OAAO,EAAE,eAAe,EAAE,EAC1B,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,cAAc,EACpB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,eAAe,EAAE,CAAC,CA2C5B;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,OAAO,CAEnE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,eAAe,EAAE,CAQhF"}
|
|
@@ -10,8 +10,10 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { promises as fs } from 'node:fs';
|
|
12
12
|
import path from 'node:path';
|
|
13
|
+
import { createRegistryIssue } from '@vibe-agent-toolkit/agent-schema';
|
|
13
14
|
import { safePath } from '@vibe-agent-toolkit/utils';
|
|
14
15
|
import { validateFrontmatter } from './frontmatter-validator.js';
|
|
16
|
+
import { issueLocation } from './utils.js';
|
|
15
17
|
/**
|
|
16
18
|
* Load a JSON Schema from a file path
|
|
17
19
|
*
|
|
@@ -49,7 +51,7 @@ export async function validateFrontmatterMultiSchema(frontmatter, schemas, resou
|
|
|
49
51
|
// Load schema
|
|
50
52
|
const schema = await loadSchema(schemaRef.schema, projectRoot);
|
|
51
53
|
// Validate frontmatter
|
|
52
|
-
const issues = validateFrontmatter(frontmatter, schema, resourcePath, mode);
|
|
54
|
+
const issues = validateFrontmatter(frontmatter, schema, resourcePath, mode, undefined, projectRoot);
|
|
53
55
|
// Update schema reference with results
|
|
54
56
|
const result = {
|
|
55
57
|
...schemaRef,
|
|
@@ -69,13 +71,9 @@ export async function validateFrontmatterMultiSchema(frontmatter, schemas, resou
|
|
|
69
71
|
...schemaRef,
|
|
70
72
|
applied: true,
|
|
71
73
|
valid: false,
|
|
72
|
-
errors: [
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
type: 'frontmatter_schema_error',
|
|
76
|
-
link: '',
|
|
77
|
-
message: `Failed to load or validate schema ${schemaRef.schema}: ${message}`,
|
|
78
|
-
}],
|
|
74
|
+
errors: [
|
|
75
|
+
createRegistryIssue('FRONTMATTER_SCHEMA_ERROR', `Failed to load or validate schema ${schemaRef.schema}: ${message}`, { location: issueLocation(resourcePath, projectRoot), line: 1 }),
|
|
76
|
+
],
|
|
79
77
|
});
|
|
80
78
|
}
|
|
81
79
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multi-schema-validator.js","sourceRoot":"","sources":["../src/multi-schema-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAErD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"multi-schema-validator.js","sourceRoot":"","sources":["../src/multi-schema-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAErD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAIjE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;;;GAMG;AACH,KAAK,UAAU,UAAU,CAAC,UAAkB,EAAE,WAAoB;IAChE,IAAI,YAAY,GAAG,UAAU,CAAC;IAE9B,6DAA6D;IAC7D,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,WAAW,EAAE,CAAC;QAChD,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IACxD,CAAC;IAED,mEAAmE;IACnE,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACzD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAW,CAAC;AACvC,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAClD,WAAgD,EAChD,OAA0B,EAC1B,YAAoB,EACpB,IAAoB,EACpB,WAAoB;IAEpB,MAAM,OAAO,GAAsB,EAAE,CAAC;IAEtC,KAAK,MAAM,SAAS,IAAI,OAAO,EAAE,CAAC;QAChC,IAAI,CAAC;YACH,cAAc;YACd,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;YAE/D,uBAAuB;YACvB,MAAM,MAAM,GAAG,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;YAEpG,uCAAuC;YACvC,MAAM,MAAM,GAAoB;gBAC9B,GAAG,SAAS;gBACZ,OAAO,EAAE,IAAI;gBACb,KAAK,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;aAC3B,CAAC;YAEF,gEAAgE;YAChE,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtB,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;YACzB,CAAC;YAED,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,sCAAsC;YACtC,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,OAAO,CAAC,IAAI,CAAC;gBACX,GAAG,SAAS;gBACZ,OAAO,EAAE,IAAI;gBACb,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE;oBACN,mBAAmB,CACjB,0BAA0B,EAC1B,qCAAqC,SAAS,CAAC,MAAM,KAAK,OAAO,EAAE,EACnE,EAAE,QAAQ,EAAE,aAAa,CAAC,YAAY,EAAE,WAAW,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAChE;iBACF;aACF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,OAA0B;IACxD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;AACpD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAA0B;IAC3D,MAAM,SAAS,GAAsB,EAAE,CAAC;IACxC,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACf,SAAS,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -7,12 +7,26 @@
|
|
|
7
7
|
* - Link resolution (setting resolvedId for local_file links)
|
|
8
8
|
* - Query capabilities (by path, ID, or glob pattern)
|
|
9
9
|
*/
|
|
10
|
+
import { type ValidationConfig } from '@vibe-agent-toolkit/agent-schema';
|
|
10
11
|
import { type GitTracker } from '@vibe-agent-toolkit/utils';
|
|
11
12
|
import type { ResourceCollectionInterface } from './resource-collection-interface.js';
|
|
12
13
|
import type { SHA256 } from './schemas/checksum.js';
|
|
13
14
|
import type { ProjectConfig } from './schemas/project-config.js';
|
|
14
15
|
import type { ResourceMetadata } from './schemas/resource-metadata.js';
|
|
15
16
|
import type { ValidationResult } from './schemas/validation-result.js';
|
|
17
|
+
/**
|
|
18
|
+
* Typed error thrown when two resources produce the same ID.
|
|
19
|
+
*
|
|
20
|
+
* Carries the authoritative id and both paths so callers can record accurate
|
|
21
|
+
* issue data without re-deriving the id from the file path (which would be
|
|
22
|
+
* wrong when the id came from a frontmatter `idField` value).
|
|
23
|
+
*/
|
|
24
|
+
export declare class DuplicateResourceIdError extends Error {
|
|
25
|
+
readonly id: string;
|
|
26
|
+
readonly existingPath: string;
|
|
27
|
+
readonly conflictingPath: string;
|
|
28
|
+
constructor(id: string, conflictingPath: string, existingPath: string);
|
|
29
|
+
}
|
|
16
30
|
/**
|
|
17
31
|
* Options for crawling directories to add resources.
|
|
18
32
|
*/
|
|
@@ -53,6 +67,13 @@ export interface ValidateOptions {
|
|
|
53
67
|
checkExternalUrls?: boolean;
|
|
54
68
|
/** Disable cache for external URL checks (default: false) */
|
|
55
69
|
noCache?: boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Validation framework config (severity overrides + per-code allow entries).
|
|
72
|
+
* Applied INSIDE validate() via runValidationFramework — the library, not the
|
|
73
|
+
* CLI, resolves severity and drops ignored issues. Defaults to `{}` (no
|
|
74
|
+
* overrides: every issue keeps its registry default severity).
|
|
75
|
+
*/
|
|
76
|
+
validationConfig?: ValidationConfig;
|
|
56
77
|
}
|
|
57
78
|
/**
|
|
58
79
|
* Statistics about resources in the registry.
|
|
@@ -132,6 +153,11 @@ export declare class ResourceRegistry implements ResourceCollectionInterface {
|
|
|
132
153
|
* collectExternalUrls so the URLs feed into the existing health-check pass.
|
|
133
154
|
*/
|
|
134
155
|
private readonly frontmatterExternalUrlsByResource;
|
|
156
|
+
/**
|
|
157
|
+
* Collisions recorded by addResources() when two files produce the same resource id.
|
|
158
|
+
* Cleared by clear(). Surfaced as DUPLICATE_RESOURCE_ID issues in validate().
|
|
159
|
+
*/
|
|
160
|
+
private duplicateIdCollisions;
|
|
135
161
|
constructor(options?: ResourceRegistryOptions);
|
|
136
162
|
/**
|
|
137
163
|
* Create an empty registry with a base directory.
|
|
@@ -245,6 +271,16 @@ export declare class ResourceRegistry implements ResourceCollectionInterface {
|
|
|
245
271
|
* @private
|
|
246
272
|
*/
|
|
247
273
|
private collectYamlErrors;
|
|
274
|
+
/**
|
|
275
|
+
* Emit MALFORMED_HTML issues from each resource's HTML parse errors.
|
|
276
|
+
* @private
|
|
277
|
+
*/
|
|
278
|
+
private collectHtmlParseErrors;
|
|
279
|
+
/**
|
|
280
|
+
* Emit DUPLICATE_RESOURCE_ID errors for collisions recorded by addResources().
|
|
281
|
+
* @private
|
|
282
|
+
*/
|
|
283
|
+
private collectDuplicateIdErrors;
|
|
248
284
|
/**
|
|
249
285
|
* Validate all links in all resources.
|
|
250
286
|
* @private
|
|
@@ -331,10 +367,10 @@ export declare class ResourceRegistry implements ResourceCollectionInterface {
|
|
|
331
367
|
*/
|
|
332
368
|
private convertValidationResultsToIssues;
|
|
333
369
|
/**
|
|
334
|
-
* Determine issue
|
|
370
|
+
* Determine the registry issue code based on the external-URL validation error.
|
|
335
371
|
* @private
|
|
336
372
|
*/
|
|
337
|
-
private
|
|
373
|
+
private determineExternalUrlIssueCode;
|
|
338
374
|
/**
|
|
339
375
|
* Resolve links between resources in the registry.
|
|
340
376
|
*
|
|
@@ -566,11 +602,11 @@ export declare class ResourceRegistry implements ResourceCollectionInterface {
|
|
|
566
602
|
*/
|
|
567
603
|
private generateId;
|
|
568
604
|
/**
|
|
569
|
-
* Build a
|
|
570
|
-
*
|
|
571
|
-
*
|
|
605
|
+
* Build a format-neutral fragment index for anchor validation: each file's
|
|
606
|
+
* absolute path → the set of valid fragment targets. Markdown contributes
|
|
607
|
+
* heading slugs (lowercased); HTML contributes its `id`/`name` anchors.
|
|
572
608
|
*/
|
|
573
|
-
private
|
|
609
|
+
private buildFragmentIndex;
|
|
574
610
|
/**
|
|
575
611
|
* Add a resource to all indexes.
|
|
576
612
|
*
|
|
@@ -595,22 +631,29 @@ export declare class ResourceRegistry implements ResourceCollectionInterface {
|
|
|
595
631
|
/**
|
|
596
632
|
* Generate an ID from a file path.
|
|
597
633
|
*
|
|
634
|
+
* Every resource id includes a `-<ext>` suffix derived from the file extension
|
|
635
|
+
* (dot stripped, lowercased). This makes ids from different file types distinct
|
|
636
|
+
* even when the stem is identical (e.g. `foo.md` → `foo-md`, `foo.html` → `foo-html`).
|
|
637
|
+
* Extensionless files (e.g. `Makefile`) receive no suffix.
|
|
638
|
+
*
|
|
598
639
|
* When `baseDir` is provided, computes a relative path from baseDir and uses the full
|
|
599
640
|
* directory structure in the ID. When no `baseDir`, uses the filename stem only.
|
|
600
641
|
*
|
|
601
642
|
* @param filePath - Absolute file path
|
|
602
643
|
* @param baseDir - Base directory for relative path computation (optional)
|
|
603
|
-
* @returns Generated ID in kebab-case
|
|
644
|
+
* @returns Generated ID in kebab-case with `-<ext>` suffix
|
|
604
645
|
*
|
|
605
646
|
* @example
|
|
606
647
|
* ```typescript
|
|
607
|
-
* // Without baseDir: filename stem
|
|
608
|
-
* generateIdFromPath('/project/docs/User Guide.md') // 'user-guide'
|
|
609
|
-
* generateIdFromPath('/project/README.md') // 'readme'
|
|
648
|
+
* // Without baseDir: filename stem + extension suffix
|
|
649
|
+
* generateIdFromPath('/project/docs/User Guide.md') // 'user-guide-md'
|
|
650
|
+
* generateIdFromPath('/project/README.md') // 'readme-md'
|
|
651
|
+
* generateIdFromPath('/project/page.html') // 'page-html'
|
|
652
|
+
* generateIdFromPath('/project/Makefile') // 'makefile'
|
|
610
653
|
*
|
|
611
|
-
* // With baseDir: relative path
|
|
612
|
-
* generateIdFromPath('/project/docs/concepts/core/overview.md', '/project/docs') // 'concepts-core-overview'
|
|
613
|
-
* generateIdFromPath('/project/docs/guide.md', '/project/docs') // 'guide'
|
|
654
|
+
* // With baseDir: relative path + extension suffix
|
|
655
|
+
* generateIdFromPath('/project/docs/concepts/core/overview.md', '/project/docs') // 'concepts-core-overview-md'
|
|
656
|
+
* generateIdFromPath('/project/docs/guide.md', '/project/docs') // 'guide-md'
|
|
614
657
|
* ```
|
|
615
658
|
*/
|
|
616
659
|
export declare function generateIdFromPath(filePath: string, baseDir?: string): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource-registry.d.ts","sourceRoot":"","sources":["../src/resource-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,EAA0D,KAAK,UAAU,EAAqE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"resource-registry.d.ts","sourceRoot":"","sources":["../src/resource-registry.ts"],"names":[],"mappings":"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"}
|