Single source of truth for what pygienium inspects (implementation-code extensions, exclude dirs, .d.ts/.min.* exclusions) shared by recon, dead-code, deep-modules, defensive-guards, comments, and complexity. Every scan task and agent prompt injects the shared scope rules instead of copy-pasted per-check lists.
146 lines
4.4 KiB
TypeScript
146 lines
4.4 KiB
TypeScript
/**
|
|
* scope.ts — canonical source-of-truth for what pygienium checks inspect.
|
|
*
|
|
* Every check (recon, dead-code, deep-modules, defensive-guards, complexity,
|
|
* comments) and every scanner agent prompt shares these definitions so the
|
|
* "only inspect implementation code" rule is stated once, not copy-pasted
|
|
* across four files that drift apart.
|
|
*
|
|
* @module pygienium/checks/scope
|
|
*/
|
|
|
|
/**
|
|
* Implementation-code file extensions pygienium inspects.
|
|
*
|
|
* Deliberately excludes documentation (`.md`, `.txt`, `.rst`), config
|
|
* (`.json`, `.yaml`, `.yml`, `.toml`, `.env`, `.ini`), type declarations
|
|
* (`.d.ts`), styles (`.css`, `.scss`), markup (`.html`, `.svg`), and lock
|
|
* files. These are not implementation code — a comments or complexity check
|
|
* flagging prose in a `.md` or a key in `package.json` is noise.
|
|
*/
|
|
export const SCOPE_EXTENSIONS: ReadonlySet<string> = new Set([
|
|
".ts",
|
|
".tsx",
|
|
".js",
|
|
".jsx",
|
|
".mjs",
|
|
".cjs",
|
|
".py",
|
|
".rb",
|
|
".go",
|
|
".rs",
|
|
".java",
|
|
".kt",
|
|
".swift",
|
|
".php",
|
|
".cs",
|
|
".lua",
|
|
]);
|
|
|
|
/**
|
|
* Directories pygienium never descends into — build output, dependency caches,
|
|
* tooling state, and VCS metadata. When walking the tree with `find`/`grep`/
|
|
* `readdir`, skip these by name to avoid wasting tokens on vendored code and
|
|
* generated artifacts the user can't act on.
|
|
*/
|
|
export const SCOPE_EXCLUDE_DIRS: ReadonlySet<string> = new Set([
|
|
"node_modules",
|
|
".git",
|
|
".hg",
|
|
".svn",
|
|
"dist",
|
|
"build",
|
|
"out",
|
|
"coverage",
|
|
".next",
|
|
".nuxt",
|
|
".turbo",
|
|
".svelte-kit",
|
|
"__pycache__",
|
|
".venv",
|
|
"venv",
|
|
"vendor",
|
|
".cache",
|
|
".pygienium",
|
|
".ralpi",
|
|
".idea",
|
|
".vscode",
|
|
]);
|
|
|
|
/**
|
|
* Compound extensions (checked after the simple extension lookup) that should
|
|
* be treated as non-source even though their tail extension appears in
|
|
* {@link SCOPE_EXTENSIONS}. The primary case: `.d.ts` type declarations are
|
|
* generated contracts, not implementation code.
|
|
*/
|
|
export const SCOPE_EXCLUDE_SUFFIXES: ReadonlySet<string> = new Set([
|
|
".d.ts",
|
|
".d.mts",
|
|
".d.cts",
|
|
".min.js",
|
|
".min.mjs",
|
|
".min.cjs",
|
|
]);
|
|
|
|
/**
|
|
* Test if a file path is implementation source pygienium should inspect.
|
|
*
|
|
* Returns `true` when the extension is in {@link SCOPE_EXTENSIONS} AND the
|
|
* path does not end with a {@link SCOPE_EXCLUDE_SUFFIXES} pattern (e.g.
|
|
* `.d.ts`).
|
|
*/
|
|
export function isScopeSource(path: string): boolean {
|
|
const lower = path.toLowerCase();
|
|
for (const suffix of SCOPE_EXCLUDE_SUFFIXES) {
|
|
if (lower.endsWith(suffix)) return false;
|
|
}
|
|
const dot = lower.lastIndexOf(".");
|
|
if (dot === -1) return false;
|
|
return SCOPE_EXTENSIONS.has(lower.slice(dot));
|
|
}
|
|
|
|
/**
|
|
* Markdown section injected into every scan task string so the sub-agent knows
|
|
* exactly what to inspect and what to skip — stated once here, not copy-pasted
|
|
* into each task builder.
|
|
*
|
|
* Agents that use `find`/`grep`/`readdir` for their own file discovery read
|
|
* this before exploring, so the exclusion list governs their search too.
|
|
*/
|
|
export function scopeRulesMarkdown(): string {
|
|
const extensions = [...SCOPE_EXTENSIONS]
|
|
.sort((a, b) => a.localeCompare(b))
|
|
.join("`, `");
|
|
const excludeDirs = [...SCOPE_EXCLUDE_DIRS]
|
|
.sort((a, b) => a.localeCompare(b))
|
|
.join("`, `");
|
|
return `## Scope of inspection
|
|
|
|
**Only inspect implementation source files.** Do not analyse documentation,
|
|
config, type declarations, build output, or dependencies — flagging those is
|
|
noise the user cannot act on.
|
|
|
|
### Inspect (extensions)
|
|
\`${extensions}\`
|
|
|
|
### Skip (directory names — never descend into)
|
|
\`${excludeDirs}\`
|
|
|
|
### Skip (file patterns)
|
|
- Type declarations: \`*.d.ts\`, \`*.d.mts\`, \`*.d.cts\` — generated contracts, not impl
|
|
- Minified bundles: \`*.min.js\`, \`*.min.mjs\`, \`*.min.cjs\` — generated, not editable
|
|
- Docs: \`*.md\`, \`*.txt\`, \`*.rst\` — prose, not code
|
|
- Config: \`*.json\`, \`*.yaml\`, \`*.yml\`, \`*.toml\`, \`*.ini\`, \`*.env\`
|
|
- Styles/markup: \`*.css\`, \`*.scss\`, \`*.html\`, \`*.svg\`
|
|
- Lock files: \`package-lock.json\`, \`*.lock\`, \`bun.lockb\`
|
|
|
|
### File discovery preference
|
|
1. **Prefer the recon snapshot** at \`<cwd>/.pygienium/recon.json\` when it
|
|
exists — it is the authoritative source inventory (git-tracked, extension-
|
|
filtered, exclude-aware). Read its \`fileCounts\` for the quick picture.
|
|
2. Otherwise enumerate files yourself, applying the rules above.
|
|
3. When using \`find\`/\`grep\`, add prune clauses for the skip directories
|
|
(e.g. \`find . -type d -name node_modules -prune -o -name '*.ts' -print\`).
|
|
`;
|
|
}
|