mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-11 02:46:16 -08:00
fix(agents): handle declared package names handles and SVG use
This commit is contained in:
1 parent
91d04d94cb
commit
71999580dd
4 files changed
+68
-2
No files matched your search
@@ -69,7 +69,7 @@ Image and media references require a nonempty path that resolves to a file, not
|
||||
Direct file URLs and file-scheme HTML bases are rejected; use portable repository-relative paths.
|
||||
Image references check file existence without interpreting image fragments as
|
||||
Markdown headings; document links keep anchor checks even when sharing a target.
|
||||
SVG image hrefs (including xlink), HTML image-input, video, audio, source and track `src` assets and video posters use the same
|
||||
SVG image/use hrefs (including xlink), HTML image-input, video, audio, source and track `src` assets and video posters use the same
|
||||
existence checks as images. Entity decoding uses full HTML text/attribute rules,
|
||||
including references whose semicolon may be omitted.
|
||||
Inline guidance imports are rejected after punctuation as well as whitespace.
|
||||
@@ -91,6 +91,8 @@ from package exemptions. Recognized extensionless guidance names (including AGEN
|
||||
CLAUDE, INSTRUCTIONS, README, CONTRIBUTING and SECURITY, case-insensitively) are excluded in package subpaths too. URL-encoded
|
||||
paths do not receive package exemptions. TypeScript configuration is parsed as JSONC.
|
||||
Declared packages also permit safe subpaths; exact aliases stay exact.
|
||||
Federated handles in the @user@host form are prose, not imports.
|
||||
Exact declared packages remain exempt after version normalization.
|
||||
Declared package mentions may include a version (including semver comparators and wildcard ranges) or dist-tag qualifier.
|
||||
Qualifier handling includes unscoped names; terminal sentence punctuation is
|
||||
removed before matching a declared package, as are straight/curly apostrophe possessives.
|
||||
|
||||
@@ -77,7 +77,7 @@ function htmlNavigation(html, inspect = () => {}) {
|
||||
)
|
||||
anchors.push(attribute.value);
|
||||
if (
|
||||
(['a', 'area', 'image'].includes(node.tagName) &&
|
||||
(['a', 'area', 'image', 'use'].includes(node.tagName) &&
|
||||
attribute.name === 'href') ||
|
||||
([
|
||||
'img',
|
||||
@@ -100,6 +100,7 @@ function htmlNavigation(html, inspect = () => {}) {
|
||||
))
|
||||
)
|
||||
references.push({
|
||||
svgUse: node.tagName === 'use',
|
||||
target: attribute.value
|
||||
.replace(/[\t\n\r]/gu, '')
|
||||
.replace(/^[\u0000-\u0020]+|[\u0000-\u0020]+$/gu, ''),
|
||||
@@ -135,6 +136,16 @@ function htmlNavigation(html, inspect = () => {}) {
|
||||
for (const child of node.childNodes ?? []) visit(child);
|
||||
}
|
||||
visit(parseFragment(html));
|
||||
for (const reference of references) {
|
||||
if (
|
||||
reference.svgUse &&
|
||||
!reference.embeddedAnchors &&
|
||||
reference.target.startsWith('#')
|
||||
) {
|
||||
reference.image = false;
|
||||
reference.embeddedAnchors = anchors;
|
||||
}
|
||||
}
|
||||
return {
|
||||
anchors,
|
||||
references:
|
||||
|
||||
@@ -162,6 +162,8 @@ async function packageMentions(rootDir) {
|
||||
token.split(/[\/\\]/u).some((part) => part === '.' || part === '..')
|
||||
)
|
||||
return false;
|
||||
if (packages.includes(token) || packages.includes(`@${token}`))
|
||||
return true;
|
||||
const path = token.split(/[?#]/u, 1)[0];
|
||||
if (
|
||||
/%[\da-f]{2}/iu.test(token) ||
|
||||
@@ -224,6 +226,12 @@ export async function validateAgentGuidance({ rootDir }) {
|
||||
)) {
|
||||
const token = match[1];
|
||||
if (isPackageMention(token)) continue;
|
||||
if (
|
||||
/^[\w.-]+@(?:[a-z\d](?:[a-z\d-]*[a-z\d])?\.)+[a-z]{2,}[.,;!?]?$/iu.test(
|
||||
token
|
||||
)
|
||||
)
|
||||
continue;
|
||||
if (
|
||||
/[./\\]/u.test(token) ||
|
||||
/^(?:LICENSE|Makefile|Dockerfile|AGENTS|CLAUDE)(?:$|[.,;)])/u.test(
|
||||
|
||||
@@ -1702,3 +1702,48 @@ for (const name of ['CONTRIBUTING', 'SECURITY', 'code_of_conduct', 'SUPPORT']) {
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
test('versioned declared package may share a guidance basename', async (t) => {
|
||||
assert.deepEqual(
|
||||
await diagnostics(t, {
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: { '@scope/support': '*' },
|
||||
}),
|
||||
'AGENTS.md': 'Use @scope/support@^2',
|
||||
}),
|
||||
[]
|
||||
);
|
||||
});
|
||||
test('federated handle is not an import', async (t) => {
|
||||
assert.deepEqual(
|
||||
await diagnostics(t, { 'AGENTS.md': 'Contact @alice@example.social' }),
|
||||
[]
|
||||
);
|
||||
});
|
||||
for (const attribute of ['href', 'xlink:href']) {
|
||||
test(`SVG use references are checked: ${attribute}`, async (t) => {
|
||||
assert.ok(
|
||||
(
|
||||
await diagnostics(t, {
|
||||
'AGENTS.md': `<svg><use ${attribute}="docs/missing.svg#icon"/></svg>`,
|
||||
})
|
||||
).length > 0
|
||||
);
|
||||
assert.deepEqual(
|
||||
await diagnostics(t, {
|
||||
'AGENTS.md': `<svg><symbol id="icon"></symbol><use ${attribute}="#icon"/></svg>`,
|
||||
}),
|
||||
[]
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
test('srcdoc SVG use keeps its own anchors', async (t) => {
|
||||
assert.deepEqual(
|
||||
await diagnostics(t, {
|
||||
'AGENTS.md':
|
||||
'<iframe srcdoc="<svg><symbol id=icon></symbol><use href=\'#icon\'/></svg>"></iframe>',
|
||||
}),
|
||||
[]
|
||||
);
|
||||
});
|
||||
Reference in new issue
Block a user