mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 17:06:15 -08:00
fix(agents): scan nested imports and share document suffixes
This commit is contained in:
1 parent
673d3fd791
commit
47cfc1ba4a
4 files changed
+40
-6
No files matched your search
@@ -36,7 +36,8 @@ Backticked concrete paths in root guidance and the context map are checked from
|
||||
the repository root, including unknown top-level directories and filenames.
|
||||
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 `./`
|
||||
file suffixes (such as .md, .json or .ts) are treated as filenames. Document formats
|
||||
share the suffix set used by package-import guards, including PDF and AsciiDoc. Use a `./`
|
||||
prefix or Markdown link for other ambiguous filenames that resemble code symbols.
|
||||
Explicit relative literals denote paths, including spaces, filesystem punctuation and hyphenated words.
|
||||
Put executable command examples in fenced code when their syntax also looks like a path.
|
||||
@@ -78,7 +79,8 @@ whose visible text equals their URI, so colon-labeled prose remains checked.
|
||||
A closing bracket followed by punctuation and an at-sign terminates a bare URL exclusion.
|
||||
Extensionless inline candidates are also imports when they resolve to repository files,
|
||||
checking the full filename before prefixes at ASCII/Unicode prose separators,
|
||||
including opening parentheses, brackets and braces.
|
||||
including opening parentheses, brackets and braces. Each at-sign candidate is
|
||||
checked independently, including imports nested next to a package mention.
|
||||
Declared scoped dependencies, scope wildcards and matching TypeScript path aliases
|
||||
are recognized as package/alias mentions. Traversal and document-file imports are
|
||||
rejected before those exemptions, including document paths with fragments or queries.
|
||||
|
||||
@@ -4,6 +4,9 @@ import GithubSlugger from 'github-slugger';
|
||||
import { Marked, Tokenizer } from 'marked';
|
||||
import { parseFragment } from 'parse5';
|
||||
|
||||
export const DOCUMENT_EXTENSION =
|
||||
/\.(?:md|markdown|mdown|mkd|mdx|txt|json|ya?ml|html?|rst|rest|adoc|asciidoc|pdf|doc[xm]?|dot[xm]?|od[tspgfbm]|ot[tspg]|fod[tspg]|rtf|org|tex|latex)$/iu;
|
||||
|
||||
// Inspection only: generated HTML is parsed in memory, never executed or emitted.
|
||||
const markdownLexer = new Marked({
|
||||
tokenizer: {
|
||||
@@ -280,6 +283,7 @@ function isLiteralRepositoryPath(token) {
|
||||
// This applies to user-defined symbols as well as JavaScript globals.
|
||||
if (
|
||||
/^[\p{L}_][\p{L}\p{N}_]*(?:\.[\p{L}_][\p{L}\p{N}_]*)+$/u.test(path) &&
|
||||
!DOCUMENT_EXTENSION.test(path) &&
|
||||
!/\.(?:md|mdx|json|jsonc|ya?ml|[cm]?[jt]sx?|html?|css|scss|sass|less|toml|xml|txt|sh|py|sql|svg|png|jpe?g|webp|gif|m3u8?|conf|ini|lock)$/iu.test(
|
||||
path
|
||||
)
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
} from 'node:path';
|
||||
import { fileURLToPath, pathToFileURL } from 'node:url';
|
||||
import {
|
||||
DOCUMENT_EXTENSION,
|
||||
guidanceAnchors as anchors,
|
||||
guidanceProse,
|
||||
guidanceStandaloneImports,
|
||||
@@ -160,9 +161,7 @@ async function packageMentions(rootDir) {
|
||||
/(?:^|\/)(?:AGENTS|CLAUDE|INSTRUCTIONS|README|LICENSE|LICENCE|NOTICE|COPYING|AUTHORS|CONTRIBUTORS|CHANGELOG)$/u.test(
|
||||
path
|
||||
) ||
|
||||
/\.(?:txt|json|ya?ml|html?|rst|rest|adoc|asciidoc|pdf|doc[xm]?|dot[xm]?|od[tspgfbm]|ot[tspg]|fod[tspg]|rtf|org|tex|latex)$/iu.test(
|
||||
path
|
||||
)
|
||||
DOCUMENT_EXTENSION.test(path)
|
||||
)
|
||||
return false;
|
||||
if (packages.includes(token)) return true;
|
||||
@@ -213,7 +212,7 @@ export async function validateAgentGuidance({ rootDir }) {
|
||||
const imports = guidanceStandaloneImports(markdown);
|
||||
const inlineImports = [];
|
||||
for (const match of prose.matchAll(
|
||||
/(?:^|[^\p{L}\p{N}_@])@([^\s]+)/gu
|
||||
/(?=(?:^|[^\p{L}\p{N}_@])@([^\s]+))/gu
|
||||
)) {
|
||||
const token = match[1];
|
||||
if (isPackageMention(token)) continue;
|
||||
|
||||
@@ -1557,3 +1557,32 @@ for (const opening of ['(', '[', '{']) {
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
test('package prose cannot hide nested guidance import', async (t) => {
|
||||
assert.ok(
|
||||
(
|
||||
await diagnostics(t, {
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: { '@angular/core': '*' },
|
||||
}),
|
||||
'CLAUDE.md': '@AGENTS.md\n\nUse @angular/core(@INSTRUCTIONS)',
|
||||
INSTRUCTIONS: 'Guidance',
|
||||
})
|
||||
).some((message) => message.includes('additional or inline'))
|
||||
);
|
||||
});
|
||||
for (const extension of ['pdf', 'rst', 'adoc', 'markdown', 'docm', 'latex']) {
|
||||
test(`bare document literal is checked: ${extension}`, async (t) => {
|
||||
const name = 'manual.' + extension;
|
||||
assert.ok(
|
||||
(await diagnostics(t, { 'AGENTS.md': '`' + name + '`' })).length > 0
|
||||
);
|
||||
assert.deepEqual(
|
||||
await diagnostics(t, {
|
||||
'AGENTS.md': '`' + name + '`',
|
||||
[name]: 'Document',
|
||||
}),
|
||||
[]
|
||||
);
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user