@aicqtools/guardrail 1.0.0-alpha.6 → 1.0.0-alpha.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/matcher/yaml-rule.d.ts +5 -2
- package/dist/matcher/yaml-rule.d.ts.map +1 -1
- package/dist/matcher/yaml-rule.js +7 -5
- package/dist/matcher/yaml-rule.js.map +1 -1
- package/dist/rules-default/no-direct-anthropic.yaml +6 -0
- package/dist/rules-default/no-direct-openai.yaml +8 -0
- package/dist/rules-default/no-magic-number.d.ts.map +1 -1
- package/dist/rules-default/no-magic-number.js +109 -9
- package/dist/rules-default/no-magic-number.js.map +1 -1
- package/dist/rules-default/no-process-env-leak.d.ts.map +1 -1
- package/dist/rules-default/no-process-env-leak.js +5 -2
- package/dist/rules-default/no-process-env-leak.js.map +1 -1
- package/dist/runner/apply-rule-config.d.ts +26 -0
- package/dist/runner/apply-rule-config.d.ts.map +1 -0
- package/dist/runner/apply-rule-config.js +52 -0
- package/dist/runner/apply-rule-config.js.map +1 -0
- package/dist/runner/index.d.ts +3 -1
- package/dist/runner/index.d.ts.map +1 -1
- package/dist/runner/index.js +2 -1
- package/dist/runner/index.js.map +1 -1
- package/dist/runner/run-file.d.ts.map +1 -1
- package/dist/runner/run-file.js +13 -1
- package/dist/runner/run-file.js.map +1 -1
- package/dist/runner/run-project.d.ts +12 -0
- package/dist/runner/run-project.d.ts.map +1 -1
- package/dist/runner/run-project.js +40 -2
- package/dist/runner/run-project.js.map +1 -1
- package/dist/runner/run-rule.d.ts.map +1 -1
- package/dist/runner/run-rule.js +17 -0
- package/dist/runner/run-rule.js.map +1 -1
- package/dist/runner/suppressions.d.ts +37 -0
- package/dist/runner/suppressions.d.ts.map +1 -0
- package/dist/runner/suppressions.js +127 -0
- package/dist/runner/suppressions.js.map +1 -0
- package/dist/suggest/analyze.d.ts.map +1 -1
- package/dist/suggest/analyze.js +27 -3
- package/dist/suggest/analyze.js.map +1 -1
- package/dist/suggest/format.d.ts +8 -2
- package/dist/suggest/format.d.ts.map +1 -1
- package/dist/suggest/format.js +40 -22
- package/dist/suggest/format.js.map +1 -1
- package/dist/suggest/mine.d.ts.map +1 -1
- package/dist/suggest/mine.js +21 -1
- package/dist/suggest/mine.js.map +1 -1
- package/dist/suggest/types.d.ts +12 -0
- package/dist/suggest/types.d.ts.map +1 -1
- package/package.json +5 -3
package/dist/runner/run-rule.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Parser from 'tree-sitter';
|
|
2
|
+
import micromatch from 'micromatch';
|
|
2
3
|
import { traverse } from '../matcher/traverse.js';
|
|
3
4
|
import { makeRuleContext } from './context.js';
|
|
4
5
|
import { loadLanguage } from '@aicqtools/core';
|
|
@@ -6,6 +7,20 @@ function ruleAppliesTo(rule, language) {
|
|
|
6
7
|
const langs = Array.isArray(rule.language) ? rule.language : [rule.language];
|
|
7
8
|
return langs.includes(language);
|
|
8
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* Honor `rule.pathExclude` — a list of micromatch globs. Matching is performed against the
|
|
12
|
+
* file path as supplied (absolute by default in normal runs, fixture-relative in unit tests),
|
|
13
|
+
* and also against the path with backslashes normalized to forward slashes so authors can write
|
|
14
|
+
* `**\/llm/client.*` without worrying about Windows separators. The match is "any glob" — one
|
|
15
|
+
* match is enough to skip the rule for the file.
|
|
16
|
+
*/
|
|
17
|
+
function isPathExcluded(rule, filePath) {
|
|
18
|
+
if (!rule.pathExclude || rule.pathExclude.length === 0)
|
|
19
|
+
return false;
|
|
20
|
+
const globs = [...rule.pathExclude];
|
|
21
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
22
|
+
return micromatch.isMatch(normalized, globs, { dot: true }) || micromatch.isMatch(filePath, globs, { dot: true });
|
|
23
|
+
}
|
|
9
24
|
function runFunctionRule(rule, run, tree) {
|
|
10
25
|
const ctx = makeRuleContext(run, rule);
|
|
11
26
|
traverse(tree.rootNode, (node) => {
|
|
@@ -28,6 +43,8 @@ function runPatternRule(rule, run, tree) {
|
|
|
28
43
|
export function runRule(rule, run, tree) {
|
|
29
44
|
if (!ruleAppliesTo(rule, run.language))
|
|
30
45
|
return;
|
|
46
|
+
if (isPathExcluded(rule, run.filePath))
|
|
47
|
+
return;
|
|
31
48
|
if (rule.kind === 'function')
|
|
32
49
|
runFunctionRule(rule, run, tree);
|
|
33
50
|
else
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-rule.js","sourceRoot":"","sources":["../../src/runner/run-rule.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"run-rule.js","sourceRoot":"","sources":["../../src/runner/run-rule.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type Parser from 'tree-sitter';
|
|
2
|
+
import type { Diagnostic, Language } from '@aicqtools/core';
|
|
3
|
+
/**
|
|
4
|
+
* Inline suppression directives — ESLint-style comment markers that suppress diagnostics
|
|
5
|
+
* for a specific line, the next line, or the entire file. Supported syntaxes:
|
|
6
|
+
*
|
|
7
|
+
* // aicq-disable-next-line <rule-id>[, <rule-id>...]
|
|
8
|
+
* // aicq-disable-line <rule-id>[, ...]
|
|
9
|
+
* // aicq-disable-file <rule-id>[, ...]
|
|
10
|
+
*
|
|
11
|
+
* Python uses `#` instead of `//`. Block comments (`/* ...\*\/`) are also recognized.
|
|
12
|
+
* The trailing rule-id list may be omitted — a bare directive suppresses *all* rules for that
|
|
13
|
+
* scope. Multiple ids may be separated by commas, whitespace, or both. Unknown ids are silently
|
|
14
|
+
* accepted (a project may rename rules; we don't want a stale directive to crash the run).
|
|
15
|
+
*/
|
|
16
|
+
export type Scope = number | 'file';
|
|
17
|
+
export interface Suppressions {
|
|
18
|
+
/** Per-line maps: line number → set of rule ids ('*' = all). */
|
|
19
|
+
readonly byLine: Map<number, Set<string> | '*'>;
|
|
20
|
+
/** File-wide suppressions. */
|
|
21
|
+
readonly fileLevel: Set<string> | '*' | null;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Walk the tree's comment nodes and produce a Suppressions map. Never throws — if the grammar
|
|
25
|
+
* yields no comment nodes for a given language, the result is empty (and applySuppressions is
|
|
26
|
+
* a no-op). The `language` parameter is reserved for future per-language tweaks; today it's
|
|
27
|
+
* only used to recognize that block comments may span multiple lines.
|
|
28
|
+
*/
|
|
29
|
+
export declare function parseSuppressions(tree: Parser.Tree, source: string, language: Language): Suppressions;
|
|
30
|
+
/**
|
|
31
|
+
* Filter diagnostics through the parsed suppressions. Diagnostics whose `ruleId` is suppressed
|
|
32
|
+
* either file-wide or on its specific line are removed. `@aicq/parse-failed` (and any other
|
|
33
|
+
* synthetic diagnostic emitted by the runner) is treated like any other rule and can be
|
|
34
|
+
* suppressed by id or with a bare directive.
|
|
35
|
+
*/
|
|
36
|
+
export declare function applySuppressions(diagnostics: readonly Diagnostic[], suppressions: Suppressions): Diagnostic[];
|
|
37
|
+
//# sourceMappingURL=suppressions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suppressions.d.ts","sourceRoot":"","sources":["../../src/runner/suppressions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAG5D;;;;;;;;;;;;GAYG;AAEH,MAAM,MAAM,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AAEpC,MAAM,WAAW,YAAY;IAC3B,gEAAgE;IAChE,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;IAChD,8BAA8B;IAC9B,QAAQ,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC;CAC9C;AAMD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,CAAC,IAAI,EACjB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,GACjB,YAAY,CA0Dd;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,SAAS,UAAU,EAAE,EAClC,YAAY,EAAE,YAAY,GACzB,UAAU,EAAE,CAed"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { traverse } from '../matcher/traverse.js';
|
|
2
|
+
const COMMENT_NODE_TYPES = new Set(['comment', 'block_comment', 'line_comment']);
|
|
3
|
+
// Capture group 1: directive verb. Group 2: optional rule-id list.
|
|
4
|
+
const DIRECTIVE_RE = /aicq-disable-(next-line|line|file)\b\s*(.*)/i;
|
|
5
|
+
/**
|
|
6
|
+
* Walk the tree's comment nodes and produce a Suppressions map. Never throws — if the grammar
|
|
7
|
+
* yields no comment nodes for a given language, the result is empty (and applySuppressions is
|
|
8
|
+
* a no-op). The `language` parameter is reserved for future per-language tweaks; today it's
|
|
9
|
+
* only used to recognize that block comments may span multiple lines.
|
|
10
|
+
*/
|
|
11
|
+
export function parseSuppressions(tree, source, language) {
|
|
12
|
+
void language; // currently uniform across supported languages
|
|
13
|
+
const byLine = new Map();
|
|
14
|
+
let fileLevel = null;
|
|
15
|
+
const mergeAtLine = (line, ids) => {
|
|
16
|
+
const existing = byLine.get(line);
|
|
17
|
+
if (existing === undefined) {
|
|
18
|
+
byLine.set(line, ids === '*' ? '*' : new Set(ids));
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (existing === '*' || ids === '*') {
|
|
22
|
+
byLine.set(line, '*');
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
for (const id of ids)
|
|
26
|
+
existing.add(id);
|
|
27
|
+
};
|
|
28
|
+
const mergeFile = (ids) => {
|
|
29
|
+
if (fileLevel === '*' || ids === '*') {
|
|
30
|
+
fileLevel = '*';
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (fileLevel === null) {
|
|
34
|
+
fileLevel = new Set(ids);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
for (const id of ids)
|
|
38
|
+
fileLevel.add(id);
|
|
39
|
+
};
|
|
40
|
+
traverse(tree.rootNode, (node) => {
|
|
41
|
+
if (!COMMENT_NODE_TYPES.has(node.type))
|
|
42
|
+
return;
|
|
43
|
+
const raw = source.slice(node.startIndex, node.endIndex);
|
|
44
|
+
// Strip comment delimiters before regex match so the body is what we scan.
|
|
45
|
+
const body = stripCommentDelimiters(raw);
|
|
46
|
+
const m = DIRECTIVE_RE.exec(body);
|
|
47
|
+
if (!m)
|
|
48
|
+
return;
|
|
49
|
+
const verb = m[1]?.toLowerCase();
|
|
50
|
+
if (!verb)
|
|
51
|
+
return;
|
|
52
|
+
const ids = parseRuleIds(m[2] ?? '');
|
|
53
|
+
if (verb === 'file') {
|
|
54
|
+
mergeFile(ids);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
// Lines are 1-based to match Diagnostic.range.start.line
|
|
58
|
+
const startLine = node.startPosition.row + 1;
|
|
59
|
+
const endLine = node.endPosition.row + 1;
|
|
60
|
+
if (verb === 'next-line') {
|
|
61
|
+
mergeAtLine(endLine + 1, ids);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
// 'line' — for a leading standalone comment, apply to the comment's own line(s).
|
|
65
|
+
// For a trailing comment (e.g. `code; // aicq-disable-line`), the comment is on the
|
|
66
|
+
// same line as the code, so this also applies correctly.
|
|
67
|
+
for (let l = startLine; l <= endLine; l++)
|
|
68
|
+
mergeAtLine(l, ids);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
return { byLine, fileLevel };
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Filter diagnostics through the parsed suppressions. Diagnostics whose `ruleId` is suppressed
|
|
75
|
+
* either file-wide or on its specific line are removed. `@aicq/parse-failed` (and any other
|
|
76
|
+
* synthetic diagnostic emitted by the runner) is treated like any other rule and can be
|
|
77
|
+
* suppressed by id or with a bare directive.
|
|
78
|
+
*/
|
|
79
|
+
export function applySuppressions(diagnostics, suppressions) {
|
|
80
|
+
if (suppressions.fileLevel === '*')
|
|
81
|
+
return [];
|
|
82
|
+
const fileSet = suppressions.fileLevel instanceof Set ? suppressions.fileLevel : null;
|
|
83
|
+
const hasAnyLine = suppressions.byLine.size > 0;
|
|
84
|
+
if (!fileSet && !hasAnyLine)
|
|
85
|
+
return [...diagnostics];
|
|
86
|
+
const out = [];
|
|
87
|
+
for (const d of diagnostics) {
|
|
88
|
+
if (fileSet && fileSet.has(d.ruleId))
|
|
89
|
+
continue;
|
|
90
|
+
const lineMap = suppressions.byLine.get(d.range.start.line);
|
|
91
|
+
if (lineMap === '*')
|
|
92
|
+
continue;
|
|
93
|
+
if (lineMap && lineMap.has(d.ruleId))
|
|
94
|
+
continue;
|
|
95
|
+
out.push(d);
|
|
96
|
+
}
|
|
97
|
+
return out;
|
|
98
|
+
}
|
|
99
|
+
function stripCommentDelimiters(raw) {
|
|
100
|
+
// `//foo` → `foo`, `# foo` → `foo`, `/* foo */` → `foo`, `<!-- foo -->` (just in case) → `foo`
|
|
101
|
+
return raw
|
|
102
|
+
.replace(/^\s*\/\*/, '')
|
|
103
|
+
.replace(/\*\/\s*$/, '')
|
|
104
|
+
.replace(/^\s*\/\//, '')
|
|
105
|
+
.replace(/^\s*#/, '')
|
|
106
|
+
.replace(/^\s*<!--/, '')
|
|
107
|
+
.replace(/-->\s*$/, '')
|
|
108
|
+
.trim();
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Split the directive tail into a set of rule ids. Empty tail → '*' (bare directive).
|
|
112
|
+
* Accepts commas, whitespace, or both as separators; ignores empty tokens; lowercases nothing
|
|
113
|
+
* (rule ids are case-sensitive). Returns `'*'` when the tail is empty.
|
|
114
|
+
*/
|
|
115
|
+
function parseRuleIds(tail) {
|
|
116
|
+
const trimmed = tail.trim();
|
|
117
|
+
if (trimmed.length === 0)
|
|
118
|
+
return '*';
|
|
119
|
+
const tokens = trimmed
|
|
120
|
+
.split(/[,\s]+/)
|
|
121
|
+
.map((s) => s.trim())
|
|
122
|
+
.filter((s) => s.length > 0);
|
|
123
|
+
if (tokens.length === 0)
|
|
124
|
+
return '*';
|
|
125
|
+
return new Set(tokens);
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=suppressions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suppressions.js","sourceRoot":"","sources":["../../src/runner/suppressions.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyze.d.ts","sourceRoot":"","sources":["../../src/suggest/analyze.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,kBAAkB,EAGlB,oBAAoB,EAErB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"analyze.d.ts","sourceRoot":"","sources":["../../src/suggest/analyze.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,kBAAkB,EAGlB,oBAAoB,EAErB,MAAM,YAAY,CAAC;AAiBpB;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAmFzF"}
|
package/dist/suggest/analyze.js
CHANGED
|
@@ -3,13 +3,17 @@ import { readFile } from 'node:fs/promises';
|
|
|
3
3
|
import { resolve } from 'node:path';
|
|
4
4
|
import fastGlob from 'fast-glob';
|
|
5
5
|
import { detectLanguage } from '@aicqtools/core';
|
|
6
|
-
import { runProject } from '../runner/run-project.js';
|
|
6
|
+
import { resolveIgnores, runProject } from '../runner/run-project.js';
|
|
7
7
|
import { buildConfigSnippet } from './format.js';
|
|
8
8
|
const PARSE_FAILED_ID = '@aicq/parse-failed';
|
|
9
9
|
const DEFAULT_TOP = 10;
|
|
10
10
|
const DEFAULT_MIN_HITS = 1;
|
|
11
11
|
const MAX_SAMPLE_LOCATIONS = 2;
|
|
12
12
|
const MIN_DEP_NAME_LENGTH = 4;
|
|
13
|
+
/** When a rule has > NOISY_RATIO times the hits of the next-ranked rule, mark it noisy. */
|
|
14
|
+
const NOISY_RATIO = 10;
|
|
15
|
+
/** Absolute floor: any info-severity rule that fires more than this is treated as noisy regardless of gap. */
|
|
16
|
+
const NOISY_ABS_THRESHOLD = 200;
|
|
13
17
|
/**
|
|
14
18
|
* Approach A — built-in rule recommender. Scans the repo with all supplied rules,
|
|
15
19
|
* ranks them by how many violations they would flag, and emits a paste-ready
|
|
@@ -26,6 +30,7 @@ export async function analyzeRepo(opts) {
|
|
|
26
30
|
exclude: opts.exclude,
|
|
27
31
|
rules: opts.rules,
|
|
28
32
|
...(opts.cache ? { cache: opts.cache } : {}),
|
|
33
|
+
...(opts.respectGitignore ? { respectGitignore: true } : {}),
|
|
29
34
|
});
|
|
30
35
|
const byRule = new Map();
|
|
31
36
|
for (const d of result.diagnostics) {
|
|
@@ -70,10 +75,15 @@ export async function analyzeRepo(opts) {
|
|
|
70
75
|
suggestions.push(makeSuggestion(rule, 0, [], true));
|
|
71
76
|
}
|
|
72
77
|
suggestions.sort((a, b) => b.hits - a.hits || a.ruleId.localeCompare(b.ruleId));
|
|
73
|
-
|
|
78
|
+
// Mark "noisy" suggestions: those whose hit count is dramatically larger than the next
|
|
79
|
+
// rule's (gap criterion) OR any info-severity rule above the absolute threshold. This
|
|
80
|
+
// information drives both the text reporter's flag and the YAML snippet's comment-out
|
|
81
|
+
// behavior, so we compute it once here.
|
|
82
|
+
const capped = applyNoisyFlag(suggestions.slice(0, top));
|
|
83
|
+
const ignore = await resolveIgnores(opts.cwd, opts.exclude, opts.respectGitignore ?? false);
|
|
74
84
|
const files = await fastGlob([...opts.include], {
|
|
75
85
|
cwd: opts.cwd,
|
|
76
|
-
ignore
|
|
86
|
+
ignore,
|
|
77
87
|
absolute: true,
|
|
78
88
|
onlyFiles: true,
|
|
79
89
|
dot: false,
|
|
@@ -106,6 +116,20 @@ function makeSuggestion(rule, hits, samples, stackMatch) {
|
|
|
106
116
|
...(stackMatch ? { stackMatch: true } : {}),
|
|
107
117
|
};
|
|
108
118
|
}
|
|
119
|
+
function applyNoisyFlag(suggestions) {
|
|
120
|
+
const out = suggestions.map((s) => ({ ...s }));
|
|
121
|
+
for (let i = 0; i < out.length; i++) {
|
|
122
|
+
const cur = out[i];
|
|
123
|
+
if (!cur)
|
|
124
|
+
continue;
|
|
125
|
+
const next = out[i + 1];
|
|
126
|
+
const gap = cur.hits > 0 && next && next.hits > 0 && cur.hits > next.hits * NOISY_RATIO;
|
|
127
|
+
const absInfo = cur.severity === 'info' && cur.hits > NOISY_ABS_THRESHOLD;
|
|
128
|
+
if (gap || absInfo)
|
|
129
|
+
cur.noisy = true;
|
|
130
|
+
}
|
|
131
|
+
return out;
|
|
132
|
+
}
|
|
109
133
|
function bareDepName(name) {
|
|
110
134
|
return name.startsWith('@') ? (name.split('/').pop() ?? name) : name;
|
|
111
135
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyze.js","sourceRoot":"","sources":["../../src/suggest/analyze.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,QAAQ,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"analyze.js","sourceRoot":"","sources":["../../src/suggest/analyze.ts"],"names":[],"mappings":"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"}
|
package/dist/suggest/format.d.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import type { Locale } from '@aicqtools/core';
|
|
2
2
|
import type { RuleSuggestion, RuleSuggestionReport } from './types.js';
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* A paste-ready `aicq.config.yaml` fragment that enables the suggested rules.
|
|
5
|
+
*
|
|
6
|
+
* Info-severity and `noisy`-flagged rules are emitted as **commented-out** lines with a note —
|
|
7
|
+
* pasting the snippet as-is never floods the project with low-signal diagnostics, but the
|
|
8
|
+
* reader sees that those rules exist and can uncomment them after tuning.
|
|
9
|
+
*/
|
|
4
10
|
export declare function buildConfigSnippet(suggestions: readonly RuleSuggestion[]): string;
|
|
5
11
|
export declare function formatSuggestText(report: RuleSuggestionReport, locale: Locale): string;
|
|
6
|
-
export declare function formatSuggestYaml(report: RuleSuggestionReport): string;
|
|
12
|
+
export declare function formatSuggestYaml(report: RuleSuggestionReport, locale?: Locale): string;
|
|
7
13
|
//# sourceMappingURL=format.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/suggest/format.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,KAAK,EAAoB,cAAc,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/suggest/format.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,KAAK,EAAoB,cAAc,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAIzF;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,SAAS,cAAc,EAAE,GAAG,MAAM,CAejF;AAcD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAgDtF;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,oBAAoB,EAAE,MAAM,GAAE,MAAa,GAAG,MAAM,CAY7F"}
|
package/dist/suggest/format.js
CHANGED
|
@@ -1,21 +1,44 @@
|
|
|
1
1
|
import { stringify as stringifyYaml } from 'yaml';
|
|
2
2
|
import { t } from '@aicqtools/core';
|
|
3
|
-
const NOISY_RATIO = 10;
|
|
4
3
|
const MESSAGE_WIDTH = 64;
|
|
5
|
-
/**
|
|
4
|
+
/**
|
|
5
|
+
* A paste-ready `aicq.config.yaml` fragment that enables the suggested rules.
|
|
6
|
+
*
|
|
7
|
+
* Info-severity and `noisy`-flagged rules are emitted as **commented-out** lines with a note —
|
|
8
|
+
* pasting the snippet as-is never floods the project with low-signal diagnostics, but the
|
|
9
|
+
* reader sees that those rules exist and can uncomment them after tuning.
|
|
10
|
+
*/
|
|
6
11
|
export function buildConfigSnippet(suggestions) {
|
|
7
12
|
if (suggestions.length === 0)
|
|
8
13
|
return '';
|
|
9
14
|
const lines = ['modules:', ' guardrail:', ' rules:'];
|
|
10
15
|
for (const s of suggestions) {
|
|
11
16
|
const level = s.severity === 'error' ? 'error' : 'warn';
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
const noteParts = [];
|
|
18
|
+
if (s.hits > 0)
|
|
19
|
+
noteParts.push(`${s.hits} hit${s.hits === 1 ? '' : 's'}`);
|
|
20
|
+
if (s.stackMatch)
|
|
21
|
+
noteParts.push('stack match');
|
|
22
|
+
const commentOut = s.severity === 'info' || s.noisy === true;
|
|
23
|
+
if (commentOut)
|
|
24
|
+
noteParts.push(`${s.severity} severity, likely noisy — review & tune before enabling`);
|
|
25
|
+
const note = noteParts.length > 0 ? ` # ${noteParts.join(', ')}` : '';
|
|
26
|
+
const prefix = commentOut ? '# ' : ' ';
|
|
27
|
+
lines.push(`${prefix}${s.ruleId}: ${level}${note}`);
|
|
16
28
|
}
|
|
17
29
|
return lines.join('\n');
|
|
18
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* Renders a multi-line banner suitable for placing above `buildConfigSnippet`'s output.
|
|
33
|
+
* Uses YAML `#` comments so the entire result is paste-safe.
|
|
34
|
+
*/
|
|
35
|
+
function snippetBanner(locale) {
|
|
36
|
+
const date = new Date().toISOString().slice(0, 10);
|
|
37
|
+
return t(locale, 'cli.rules.suggest.snippetBanner', { date })
|
|
38
|
+
.split('\n')
|
|
39
|
+
.map((line) => `# ${line}`)
|
|
40
|
+
.join('\n');
|
|
41
|
+
}
|
|
19
42
|
export function formatSuggestText(report, locale) {
|
|
20
43
|
const lines = [];
|
|
21
44
|
lines.push(t(locale, 'cli.rules.suggest.header', {
|
|
@@ -29,18 +52,11 @@ export function formatSuggestText(report, locale) {
|
|
|
29
52
|
}
|
|
30
53
|
else {
|
|
31
54
|
lines.push(t(locale, 'cli.rules.suggest.tableHeader'));
|
|
32
|
-
|
|
33
|
-
for (let i = 0; i < report.suggestions.length - 1; i++) {
|
|
34
|
-
const cur = report.suggestions[i]?.hits ?? 0;
|
|
35
|
-
const next = report.suggestions[i + 1]?.hits ?? 0;
|
|
36
|
-
if (cur > 0 && next > 0 && cur > next * NOISY_RATIO)
|
|
37
|
-
noisy.add(i);
|
|
38
|
-
}
|
|
39
|
-
report.suggestions.forEach((s, i) => {
|
|
55
|
+
report.suggestions.forEach((s) => {
|
|
40
56
|
const flags = [];
|
|
41
57
|
if (s.stackMatch)
|
|
42
58
|
flags.push(t(locale, 'cli.rules.suggest.stackMatchNote'));
|
|
43
|
-
if (noisy
|
|
59
|
+
if (s.noisy)
|
|
44
60
|
flags.push(t(locale, 'cli.rules.suggest.noisyNote'));
|
|
45
61
|
const flagStr = flags.length > 0 ? ` ${flags.join(' ')}` : '';
|
|
46
62
|
lines.push(` ${s.ruleId} ${s.hits} ${s.severity} ${truncate(s.message, MESSAGE_WIDTH)}${flagStr}`);
|
|
@@ -57,32 +73,34 @@ export function formatSuggestText(report, locale) {
|
|
|
57
73
|
if (report.configSnippet) {
|
|
58
74
|
lines.push('');
|
|
59
75
|
lines.push(t(locale, 'cli.rules.suggest.configHint'));
|
|
76
|
+
lines.push(snippetBanner(locale));
|
|
60
77
|
lines.push(report.configSnippet);
|
|
61
78
|
}
|
|
62
79
|
if (report.patternDrafts && report.patternDrafts.length > 0) {
|
|
63
80
|
lines.push('');
|
|
64
81
|
lines.push(t(locale, 'cli.rules.suggest.patternDraftsHeader', { count: report.patternDrafts.length }));
|
|
65
|
-
lines.push(formatPatternDraftsYaml(report.patternDrafts));
|
|
82
|
+
lines.push(formatPatternDraftsYaml(report.patternDrafts, locale));
|
|
66
83
|
}
|
|
67
84
|
return lines.join('\n');
|
|
68
85
|
}
|
|
69
|
-
export function formatSuggestYaml(report) {
|
|
86
|
+
export function formatSuggestYaml(report, locale = 'en') {
|
|
70
87
|
const parts = [];
|
|
71
88
|
if (report.configSnippet) {
|
|
72
|
-
parts.push(
|
|
89
|
+
parts.push(snippetBanner(locale));
|
|
73
90
|
parts.push(report.configSnippet);
|
|
74
91
|
}
|
|
75
92
|
if (report.patternDrafts && report.patternDrafts.length > 0) {
|
|
76
93
|
if (parts.length > 0)
|
|
77
94
|
parts.push('');
|
|
78
|
-
parts.push(
|
|
79
|
-
parts.push(formatPatternDraftsYaml(report.patternDrafts));
|
|
95
|
+
parts.push(`# ${t(locale, 'cli.rules.suggest.patternDraftsBanner')}`);
|
|
96
|
+
parts.push(formatPatternDraftsYaml(report.patternDrafts, locale));
|
|
80
97
|
}
|
|
81
98
|
return parts.length > 0 ? parts.join('\n') : '# No suggestions.';
|
|
82
99
|
}
|
|
83
|
-
function formatPatternDraftsYaml(drafts) {
|
|
100
|
+
function formatPatternDraftsYaml(drafts, locale) {
|
|
101
|
+
const expHeader = t(locale, 'cli.rules.suggest.experimentalLabel');
|
|
84
102
|
return drafts
|
|
85
|
-
.map((d, i) => `# --- draft ${i + 1}/${drafts.length}: ${d.id} (${d.meta.count}x across ${d.meta.files} file${d.meta.files === 1 ? '' : 's'}) ---\n${patternDraftToYaml(d)}`)
|
|
103
|
+
.map((d, i) => `# --- ${expHeader} draft ${i + 1}/${drafts.length}: ${d.id} (${d.meta.count}x across ${d.meta.files} file${d.meta.files === 1 ? '' : 's'}) ---\n${patternDraftToYaml(d)}`)
|
|
86
104
|
.join('---\n');
|
|
87
105
|
}
|
|
88
106
|
function patternDraftToYaml(draft) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/suggest/format.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,MAAM,CAAC;AAElD,OAAO,EAAE,CAAC,EAAE,MAAM,iBAAiB,CAAC;AAGpC,MAAM,
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/suggest/format.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mine.d.ts","sourceRoot":"","sources":["../../src/suggest/mine.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"mine.d.ts","sourceRoot":"","sources":["../../src/suggest/mine.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAyB,MAAM,YAAY,CAAC;AAuC/F;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CA0EzF"}
|
package/dist/suggest/mine.js
CHANGED
|
@@ -3,11 +3,24 @@ import fastGlob from 'fast-glob';
|
|
|
3
3
|
import Parser from 'tree-sitter';
|
|
4
4
|
import { detectLanguage, loadLanguage, parseSource } from '@aicqtools/core';
|
|
5
5
|
import { traverse } from '../matcher/traverse.js';
|
|
6
|
+
import { resolveIgnores } from '../runner/run-project.js';
|
|
6
7
|
const DEFAULT_MIN_COUNT = 5;
|
|
7
8
|
const DEFAULT_TOP = 10;
|
|
8
9
|
const MAX_FILES = 5000;
|
|
9
10
|
const MAX_SAMPLES = 2;
|
|
10
11
|
const IDENTIFIER_RE = /^[A-Za-z_$][\w$]*$/;
|
|
12
|
+
/**
|
|
13
|
+
* Common stdlib / global names whose `new X()` and `X.method()` invocations are universal
|
|
14
|
+
* patterns — they would generate noisy, useless draft rules ("don't construct Map", "don't
|
|
15
|
+
* call JSON.parse"). Dropping them keeps `--patterns` output focused on genuinely
|
|
16
|
+
* project-specific shapes.
|
|
17
|
+
*/
|
|
18
|
+
const STDLIB_BLOCKLIST = new Set([
|
|
19
|
+
'Array', 'Object', 'Map', 'Set', 'WeakMap', 'WeakSet', 'Date', 'Promise', 'RegExp',
|
|
20
|
+
'Error', 'TypeError', 'RangeError', 'SyntaxError',
|
|
21
|
+
'JSON', 'console', 'Math', 'process', 'Buffer', 'Symbol', 'Number', 'String', 'Boolean',
|
|
22
|
+
'Function', 'URL', 'URLSearchParams',
|
|
23
|
+
]);
|
|
11
24
|
/**
|
|
12
25
|
* Approach B (early prototype) — mine the AST for frequently-occurring
|
|
13
26
|
* `new X(...)` / `obj.method(...)` shapes and turn the top ones into draft
|
|
@@ -19,9 +32,10 @@ const IDENTIFIER_RE = /^[A-Za-z_$][\w$]*$/;
|
|
|
19
32
|
export async function minePatterns(opts) {
|
|
20
33
|
const minCount = Math.max(1, opts.minCount ?? DEFAULT_MIN_COUNT);
|
|
21
34
|
const top = Math.max(1, opts.top ?? DEFAULT_TOP);
|
|
35
|
+
const ignore = await resolveIgnores(opts.cwd, opts.exclude, opts.respectGitignore ?? false);
|
|
22
36
|
const files = (await fastGlob([...opts.include], {
|
|
23
37
|
cwd: opts.cwd,
|
|
24
|
-
ignore
|
|
38
|
+
ignore,
|
|
25
39
|
absolute: true,
|
|
26
40
|
onlyFiles: true,
|
|
27
41
|
dot: false,
|
|
@@ -104,6 +118,8 @@ function extractSignature(node, language, textOf) {
|
|
|
104
118
|
const a = textOf(attr);
|
|
105
119
|
if (!IDENTIFIER_RE.test(o) || !IDENTIFIER_RE.test(a))
|
|
106
120
|
return null;
|
|
121
|
+
if (STDLIB_BLOCKLIST.has(o))
|
|
122
|
+
return null;
|
|
107
123
|
return { signature: `call:${o}.${a}`, kind: 'call', parts: [o, a] };
|
|
108
124
|
}
|
|
109
125
|
// typescript / tsx / javascript
|
|
@@ -114,6 +130,8 @@ function extractSignature(node, language, textOf) {
|
|
|
114
130
|
const name = textOf(ctor);
|
|
115
131
|
if (!IDENTIFIER_RE.test(name))
|
|
116
132
|
return null;
|
|
133
|
+
if (STDLIB_BLOCKLIST.has(name))
|
|
134
|
+
return null;
|
|
117
135
|
return { signature: `new:${name}`, kind: 'new', parts: [name] };
|
|
118
136
|
}
|
|
119
137
|
if (node.type === 'call_expression') {
|
|
@@ -128,6 +146,8 @@ function extractSignature(node, language, textOf) {
|
|
|
128
146
|
const p = textOf(prop);
|
|
129
147
|
if (!IDENTIFIER_RE.test(o) || !IDENTIFIER_RE.test(p))
|
|
130
148
|
return null;
|
|
149
|
+
if (STDLIB_BLOCKLIST.has(o))
|
|
150
|
+
return null;
|
|
131
151
|
return { signature: `call:${o}.${p}`, kind: 'call', parts: [o, p] };
|
|
132
152
|
}
|
|
133
153
|
return null;
|
package/dist/suggest/mine.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mine.js","sourceRoot":"","sources":["../../src/suggest/mine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,QAAQ,MAAM,WAAW,CAAC;AACjC,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC5E,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"mine.js","sourceRoot":"","sources":["../../src/suggest/mine.ts"],"names":[],"mappings":"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"}
|