From a73538994add3fd4cb7dc7bec45ca0e195d6b6a3 Mon Sep 17 00:00:00 2001 From: 4gray Date: Sun, 20 Sep 2026 22:51:15 +0200 Subject: [PATCH] fix(agents): validate media and hyphenated literal paths --- docs/development/agent-workflow.md | 4 ++- tools/skills/agent-guidance-markdown.mjs | 6 ++-- tools/skills/validate-agent-guidance.test.mjs | 34 +++++++++++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/docs/development/agent-workflow.md b/docs/development/agent-workflow.md index 2353f1450..f3e77705a 100644 --- a/docs/development/agent-workflow.md +++ b/docs/development/agent-workflow.md @@ -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 diff --git a/tools/skills/agent-guidance-markdown.mjs b/tools/skills/agent-guidance-markdown.mjs index f6f3171b4..860824136 100644 --- a/tools/skills/agent-guidance-markdown.mjs +++ b/tools/skills/agent-guidance-markdown.mjs @@ -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]; diff --git a/tools/skills/validate-agent-guidance.test.mjs b/tools/skills/validate-agent-guidance.test.mjs index 488219464..0da056b23 100644 --- a/tools/skills/validate-agent-guidance.test.mjs +++ b/tools/skills/validate-agent-guidance.test.mjs @@ -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 [ + '', + '', + '', +]) { + 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': '' }), + [] + ); + }); +}