fix(agents): validate media and hyphenated literal paths

This commit is contained in:
4gray committed 2026-09-20 22:51:15 +02:00
1 parent b54dc4c405
commit a73538994a
3 files changed
+40 -4

No files matched your search

+3 -1
View File
@@ -37,7 +37,8 @@ Write generic filenames as prose; commands, templates, globs, URLs, package
aliases and dotted code symbols are excluded. Bare dotted names with conventional
file suffixes (such as .md, .json or .ts) are treated as filenames. Use a `./`
prefix or Markdown link for other ambiguous filenames that resemble code symbols.
Explicit relative literal paths may contain spaces; command-option snippets are excluded.
Explicit relative literals denote paths, including spaces and hyphenated words.
Put executable command examples in fenced code when their syntax also looks like a path.
Multi-part dotfiles are path candidates too.
Conventional extensionless filenames such as Dockerfile, Makefile and LICENSE
are also path candidates; use an explicit `./` prefix for other extensionless files.
@@ -57,6 +58,7 @@ Rendered HTML anchor hrefs and image sources use the same local-reference checks
as Markdown links, including decoded attributes and fragment validation.
Image references check file existence without interpreting image fragments as
Markdown headings; document links keep anchor checks even when sharing a target.
HTML video, audio and source `src` assets use the same existence checks as images.
Inline guidance imports are rejected after punctuation as well as whitespace.
Declared scoped dependencies, scope wildcards and matching TypeScript path aliases
are recognized as package/alias mentions. Traversal and document-file imports are
+3 -3
View File
@@ -66,11 +66,12 @@ function htmlNavigation(html, inspect = () => {}) {
anchors.push(attribute.value);
if (
(node.tagName === 'a' && attribute.name === 'href') ||
(node.tagName === 'img' && attribute.name === 'src')
(['img', 'video', 'audio', 'source'].includes(node.tagName) &&
attribute.name === 'src')
)
references.push({
target: attribute.value,
image: node.tagName === 'img',
image: node.tagName !== 'a',
});
if (
['img', 'source'].includes(node.tagName) &&
@@ -178,7 +179,6 @@ function isLiteralRepositoryPath(token) {
).test(token)
)
return false;
if (/\s+-{1,2}[\p{L}]/u.test(token)) return false;
if (token.includes('YYYY-MM-DD') || /(?:^|\/)\.\.\.(?:\/|$)/u.test(token))
return false;
const path = token.split('#')[0];
@@ -921,3 +921,37 @@ test('explicit relative literal paths support spaces', async (t) => {
[]
);
});
for (const filename of ['./docs/Design - Copy.md', './docs/Design -Copy.md']) {
test(`explicit spaced filename is checked: ${filename}`, async (t) => {
assert.match(
(await diagnostics(t, { 'AGENTS.md': '`' + filename + '`' })).join(
'\n'
),
/does not exist/
);
assert.deepEqual(
await diagnostics(t, {
'AGENTS.md': '`' + filename + '`',
[filename]: '',
}),
[]
);
});
}
for (const html of [
'<video><source src="docs/demo.mp4"></video>',
'<video src="docs/demo.mp4"></video>',
'<audio src="docs/demo.mp4"></audio>',
]) {
test(`rendered media source is checked: ${html}`, async (t) => {
assert.match(
(await diagnostics(t, { 'AGENTS.md': html })).join('\n'),
/does not exist/
);
assert.deepEqual(
await diagnostics(t, { 'AGENTS.md': html, 'docs/demo.mp4': '' }),
[]
);
});
}