@aicqtools/guardrail 1.0.0-alpha.5 → 1.0.0-alpha.6
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 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/suggest/analyze.d.ts +10 -0
- package/dist/suggest/analyze.d.ts.map +1 -0
- package/dist/suggest/analyze.js +169 -0
- package/dist/suggest/analyze.js.map +1 -0
- package/dist/suggest/format.d.ts +7 -0
- package/dist/suggest/format.d.ts.map +1 -0
- package/dist/suggest/format.js +102 -0
- package/dist/suggest/format.js.map +1 -0
- package/dist/suggest/index.d.ts +5 -0
- package/dist/suggest/index.d.ts.map +1 -0
- package/dist/suggest/index.js +4 -0
- package/dist/suggest/index.js.map +1 -0
- package/dist/suggest/mine.d.ts +11 -0
- package/dist/suggest/mine.d.ts.map +1 -0
- package/dist/suggest/mine.js +187 -0
- package/dist/suggest/mine.js.map +1 -0
- package/dist/suggest/types.d.ts +62 -0
- package/dist/suggest/types.d.ts.map +1 -0
- package/dist/suggest/types.js +2 -0
- package/dist/suggest/types.js.map +1 -0
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -8,5 +8,7 @@ export { renderRules, injectIntoMarkdown, syncAiRules, MARKER_START, MARKER_END,
|
|
|
8
8
|
export type { RenderOptions, SyncOptions, SyncTarget } from './sync/index.js';
|
|
9
9
|
export { renderRuleMarkdown, renderRulesIndex, buildRuleDocs } from './docs/index.js';
|
|
10
10
|
export type { BuildDocsOptions, BuildDocsResult } from './docs/index.js';
|
|
11
|
+
export { analyzeRepo, minePatterns, buildConfigSnippet, formatSuggestText, formatSuggestYaml } from './suggest/index.js';
|
|
12
|
+
export type { AnalyzeRepoOptions, DependencySource, DetectedDependency, MinePatternsOptions, PatternRuleDraft, RuleSuggestion, RuleSuggestionReport, SuggestSampleLocation, } from './suggest/index.js';
|
|
11
13
|
export type { BuildMcpServerOptions, CheckSnippetInput, CheckSnippetResult, ListRulesResult, } from './mcp/index.js';
|
|
12
14
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,iBAAiB,EACjB,UAAU,EACV,OAAO,GACR,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE1E,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC7D,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,cAAc,EACd,UAAU,EACV,kBAAkB,EAClB,eAAe,EACf,uBAAuB,GACxB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,UAAU,GACX,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE9E,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACtF,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,iBAAiB,EACjB,UAAU,EACV,OAAO,GACR,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE1E,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC7D,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,cAAc,EACd,UAAU,EACV,kBAAkB,EAClB,eAAe,EACf,uBAAuB,GACxB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,UAAU,GACX,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE9E,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACtF,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEzE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACzH,YAAY,EACV,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,qBAAqB,EACrB,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,GAChB,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -4,4 +4,5 @@ export { builtinFunctionRules, loadBuiltinYamlRules, loadAllBuiltinRules, loadFu
|
|
|
4
4
|
export { buildMcpServer, startStdio, handleCheckSnippet, handleListRules, checkSnippetInputSchema, } from './mcp/index.js';
|
|
5
5
|
export { renderRules, injectIntoMarkdown, syncAiRules, MARKER_START, MARKER_END, } from './sync/index.js';
|
|
6
6
|
export { renderRuleMarkdown, renderRulesIndex, buildRuleDocs } from './docs/index.js';
|
|
7
|
+
export { analyzeRepo, minePatterns, buildConfigSnippet, formatSuggestText, formatSuggestYaml } from './suggest/index.js';
|
|
7
8
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,iBAAiB,EACjB,UAAU,EACV,OAAO,GACR,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAG7D,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,cAAc,EACd,UAAU,EACV,kBAAkB,EAClB,eAAe,EACf,uBAAuB,GACxB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,UAAU,GACX,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,iBAAiB,EACjB,UAAU,EACV,OAAO,GACR,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAG7D,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,cAAc,EACd,UAAU,EACV,kBAAkB,EAClB,eAAe,EACf,uBAAuB,GACxB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,UAAU,GACX,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGtF,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AnalyzeRepoOptions, RuleSuggestionReport } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Approach A — built-in rule recommender. Scans the repo with all supplied rules,
|
|
4
|
+
* ranks them by how many violations they would flag, and emits a paste-ready
|
|
5
|
+
* `aicq.config.yaml` enable-snippet. Also reads `package.json` / `requirements.txt`
|
|
6
|
+
* (no AST) and flags built-in rules whose id/docs/message mentions a declared
|
|
7
|
+
* dependency ("stack match").
|
|
8
|
+
*/
|
|
9
|
+
export declare function analyzeRepo(opts: AnalyzeRepoOptions): Promise<RuleSuggestionReport>;
|
|
10
|
+
//# sourceMappingURL=analyze.d.ts.map
|
|
@@ -0,0 +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;AAapB;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA6EzF"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import { resolve } from 'node:path';
|
|
4
|
+
import fastGlob from 'fast-glob';
|
|
5
|
+
import { detectLanguage } from '@aicqtools/core';
|
|
6
|
+
import { runProject } from '../runner/run-project.js';
|
|
7
|
+
import { buildConfigSnippet } from './format.js';
|
|
8
|
+
const PARSE_FAILED_ID = '@aicq/parse-failed';
|
|
9
|
+
const DEFAULT_TOP = 10;
|
|
10
|
+
const DEFAULT_MIN_HITS = 1;
|
|
11
|
+
const MAX_SAMPLE_LOCATIONS = 2;
|
|
12
|
+
const MIN_DEP_NAME_LENGTH = 4;
|
|
13
|
+
/**
|
|
14
|
+
* Approach A — built-in rule recommender. Scans the repo with all supplied rules,
|
|
15
|
+
* ranks them by how many violations they would flag, and emits a paste-ready
|
|
16
|
+
* `aicq.config.yaml` enable-snippet. Also reads `package.json` / `requirements.txt`
|
|
17
|
+
* (no AST) and flags built-in rules whose id/docs/message mentions a declared
|
|
18
|
+
* dependency ("stack match").
|
|
19
|
+
*/
|
|
20
|
+
export async function analyzeRepo(opts) {
|
|
21
|
+
const top = Math.max(1, opts.top ?? DEFAULT_TOP);
|
|
22
|
+
const minHits = Math.max(1, opts.minHits ?? DEFAULT_MIN_HITS);
|
|
23
|
+
const result = await runProject({
|
|
24
|
+
cwd: opts.cwd,
|
|
25
|
+
include: opts.include,
|
|
26
|
+
exclude: opts.exclude,
|
|
27
|
+
rules: opts.rules,
|
|
28
|
+
...(opts.cache ? { cache: opts.cache } : {}),
|
|
29
|
+
});
|
|
30
|
+
const byRule = new Map();
|
|
31
|
+
for (const d of result.diagnostics) {
|
|
32
|
+
if (d.ruleId === PARSE_FAILED_ID)
|
|
33
|
+
continue;
|
|
34
|
+
let bucket = byRule.get(d.ruleId);
|
|
35
|
+
if (!bucket) {
|
|
36
|
+
bucket = { hits: 0, samples: [] };
|
|
37
|
+
byRule.set(d.ruleId, bucket);
|
|
38
|
+
}
|
|
39
|
+
bucket.hits += 1;
|
|
40
|
+
if (bucket.samples.length < MAX_SAMPLE_LOCATIONS) {
|
|
41
|
+
bucket.samples.push({ file: d.file, line: d.range.start.line, column: d.range.start.column });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const ruleById = new Map();
|
|
45
|
+
for (const rule of opts.rules)
|
|
46
|
+
ruleById.set(rule.id, rule);
|
|
47
|
+
const detectedDependencies = await detectDependencies(opts.cwd);
|
|
48
|
+
const depNames = new Set(detectedDependencies
|
|
49
|
+
.map((d) => bareDepName(d.name).toLowerCase())
|
|
50
|
+
.filter((n) => n.length >= MIN_DEP_NAME_LENGTH));
|
|
51
|
+
const stackMatched = new Set();
|
|
52
|
+
for (const rule of opts.rules) {
|
|
53
|
+
if (ruleMentionsDependency(rule, depNames))
|
|
54
|
+
stackMatched.add(rule.id);
|
|
55
|
+
}
|
|
56
|
+
const suggestions = [];
|
|
57
|
+
for (const [ruleId, bucket] of byRule) {
|
|
58
|
+
const rule = ruleById.get(ruleId);
|
|
59
|
+
if (!rule)
|
|
60
|
+
continue;
|
|
61
|
+
if (bucket.hits < minHits && !stackMatched.has(ruleId))
|
|
62
|
+
continue;
|
|
63
|
+
suggestions.push(makeSuggestion(rule, bucket.hits, bucket.samples, stackMatched.has(ruleId)));
|
|
64
|
+
}
|
|
65
|
+
for (const ruleId of stackMatched) {
|
|
66
|
+
if (byRule.has(ruleId))
|
|
67
|
+
continue;
|
|
68
|
+
const rule = ruleById.get(ruleId);
|
|
69
|
+
if (rule)
|
|
70
|
+
suggestions.push(makeSuggestion(rule, 0, [], true));
|
|
71
|
+
}
|
|
72
|
+
suggestions.sort((a, b) => b.hits - a.hits || a.ruleId.localeCompare(b.ruleId));
|
|
73
|
+
const capped = suggestions.slice(0, top);
|
|
74
|
+
const files = await fastGlob([...opts.include], {
|
|
75
|
+
cwd: opts.cwd,
|
|
76
|
+
ignore: [...opts.exclude],
|
|
77
|
+
absolute: true,
|
|
78
|
+
onlyFiles: true,
|
|
79
|
+
dot: false,
|
|
80
|
+
});
|
|
81
|
+
const langSet = new Set();
|
|
82
|
+
for (const file of files) {
|
|
83
|
+
const lang = detectLanguage(file);
|
|
84
|
+
if (lang)
|
|
85
|
+
langSet.add(lang);
|
|
86
|
+
}
|
|
87
|
+
const languagesPresent = [...langSet].sort();
|
|
88
|
+
return {
|
|
89
|
+
filesScanned: result.filesScanned,
|
|
90
|
+
languagesPresent,
|
|
91
|
+
durationMs: result.durationMs,
|
|
92
|
+
suggestions: capped,
|
|
93
|
+
detectedDependencies,
|
|
94
|
+
configSnippet: buildConfigSnippet(capped),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
function makeSuggestion(rule, hits, samples, stackMatch) {
|
|
98
|
+
return {
|
|
99
|
+
ruleId: rule.id,
|
|
100
|
+
hits,
|
|
101
|
+
severity: rule.severity,
|
|
102
|
+
message: rule.message,
|
|
103
|
+
...(rule.messageKo ? { messageKo: rule.messageKo } : {}),
|
|
104
|
+
...(rule.docs ? { docs: rule.docs } : {}),
|
|
105
|
+
sampleLocations: samples,
|
|
106
|
+
...(stackMatch ? { stackMatch: true } : {}),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function bareDepName(name) {
|
|
110
|
+
return name.startsWith('@') ? (name.split('/').pop() ?? name) : name;
|
|
111
|
+
}
|
|
112
|
+
function ruleMentionsDependency(rule, depNames) {
|
|
113
|
+
if (depNames.size === 0)
|
|
114
|
+
return false;
|
|
115
|
+
const idTokens = new Set(rule.id.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean));
|
|
116
|
+
const firstWord = rule.message.toLowerCase().split(/\s+/)[0] ?? '';
|
|
117
|
+
const docs = (rule.docs ?? '').toLowerCase();
|
|
118
|
+
for (const dep of depNames) {
|
|
119
|
+
if (idTokens.has(dep) || firstWord === dep || (docs.length > 0 && docs.includes(dep)))
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
async function detectDependencies(cwd) {
|
|
125
|
+
const out = [];
|
|
126
|
+
const seen = new Set();
|
|
127
|
+
const add = (rawName, source) => {
|
|
128
|
+
const name = rawName.trim();
|
|
129
|
+
if (!name || seen.has(`${source}:${name}`))
|
|
130
|
+
return;
|
|
131
|
+
seen.add(`${source}:${name}`);
|
|
132
|
+
out.push({ name, source });
|
|
133
|
+
};
|
|
134
|
+
const pkgPath = resolve(cwd, 'package.json');
|
|
135
|
+
if (existsSync(pkgPath)) {
|
|
136
|
+
try {
|
|
137
|
+
const pkg = JSON.parse(await readFile(pkgPath, 'utf-8'));
|
|
138
|
+
for (const key of ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies']) {
|
|
139
|
+
const deps = pkg[key];
|
|
140
|
+
if (deps && typeof deps === 'object' && !Array.isArray(deps)) {
|
|
141
|
+
for (const name of Object.keys(deps))
|
|
142
|
+
add(name, 'package.json');
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
/* ignore unreadable / invalid package.json */
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
const reqPath = resolve(cwd, 'requirements.txt');
|
|
151
|
+
if (existsSync(reqPath)) {
|
|
152
|
+
try {
|
|
153
|
+
const txt = await readFile(reqPath, 'utf-8');
|
|
154
|
+
for (const line of txt.split(/\r?\n/)) {
|
|
155
|
+
const trimmed = line.trim();
|
|
156
|
+
if (!trimmed || trimmed.startsWith('#') || trimmed.startsWith('-'))
|
|
157
|
+
continue;
|
|
158
|
+
const name = trimmed.split(/[<>=!~;[\s]/)[0];
|
|
159
|
+
if (name)
|
|
160
|
+
add(name, 'requirements.txt');
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
/* ignore unreadable requirements.txt */
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return out;
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=analyze.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze.js","sourceRoot":"","sources":["../../src/suggest/analyze.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Locale } from '@aicqtools/core';
|
|
2
|
+
import type { RuleSuggestion, RuleSuggestionReport } from './types.js';
|
|
3
|
+
/** A paste-ready `aicq.config.yaml` fragment that enables the suggested rules. */
|
|
4
|
+
export declare function buildConfigSnippet(suggestions: readonly RuleSuggestion[]): string;
|
|
5
|
+
export declare function formatSuggestText(report: RuleSuggestionReport, locale: Locale): string;
|
|
6
|
+
export declare function formatSuggestYaml(report: RuleSuggestionReport): string;
|
|
7
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +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;AAKzF,kFAAkF;AAClF,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,SAAS,cAAc,EAAE,GAAG,MAAM,CAYjF;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAqDtF;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAYtE"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { stringify as stringifyYaml } from 'yaml';
|
|
2
|
+
import { t } from '@aicqtools/core';
|
|
3
|
+
const NOISY_RATIO = 10;
|
|
4
|
+
const MESSAGE_WIDTH = 64;
|
|
5
|
+
/** A paste-ready `aicq.config.yaml` fragment that enables the suggested rules. */
|
|
6
|
+
export function buildConfigSnippet(suggestions) {
|
|
7
|
+
if (suggestions.length === 0)
|
|
8
|
+
return '';
|
|
9
|
+
const lines = ['modules:', ' guardrail:', ' rules:'];
|
|
10
|
+
for (const s of suggestions) {
|
|
11
|
+
const level = s.severity === 'error' ? 'error' : 'warn';
|
|
12
|
+
const note = s.hits > 0
|
|
13
|
+
? ` # ${s.hits} hit${s.hits === 1 ? '' : 's'}${s.stackMatch ? ', stack match' : ''}`
|
|
14
|
+
: ' # stack match';
|
|
15
|
+
lines.push(` ${s.ruleId}: ${level}${note}`);
|
|
16
|
+
}
|
|
17
|
+
return lines.join('\n');
|
|
18
|
+
}
|
|
19
|
+
export function formatSuggestText(report, locale) {
|
|
20
|
+
const lines = [];
|
|
21
|
+
lines.push(t(locale, 'cli.rules.suggest.header', {
|
|
22
|
+
files: report.filesScanned,
|
|
23
|
+
langs: report.languagesPresent.length > 0 ? report.languagesPresent.join(', ') : '-',
|
|
24
|
+
ms: report.durationMs,
|
|
25
|
+
}));
|
|
26
|
+
lines.push('');
|
|
27
|
+
if (report.suggestions.length === 0) {
|
|
28
|
+
lines.push(t(locale, 'cli.rules.suggest.none'));
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
lines.push(t(locale, 'cli.rules.suggest.tableHeader'));
|
|
32
|
+
const noisy = new Set();
|
|
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) => {
|
|
40
|
+
const flags = [];
|
|
41
|
+
if (s.stackMatch)
|
|
42
|
+
flags.push(t(locale, 'cli.rules.suggest.stackMatchNote'));
|
|
43
|
+
if (noisy.has(i))
|
|
44
|
+
flags.push(t(locale, 'cli.rules.suggest.noisyNote'));
|
|
45
|
+
const flagStr = flags.length > 0 ? ` ${flags.join(' ')}` : '';
|
|
46
|
+
lines.push(` ${s.ruleId} ${s.hits} ${s.severity} ${truncate(s.message, MESSAGE_WIDTH)}${flagStr}`);
|
|
47
|
+
for (const loc of s.sampleLocations)
|
|
48
|
+
lines.push(` ${loc.file}:${loc.line}:${loc.column}`);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
if (report.detectedDependencies.length > 0) {
|
|
52
|
+
lines.push('');
|
|
53
|
+
lines.push(t(locale, 'cli.rules.suggest.detectedStack', {
|
|
54
|
+
deps: report.detectedDependencies.map((d) => d.name).join(', '),
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
57
|
+
if (report.configSnippet) {
|
|
58
|
+
lines.push('');
|
|
59
|
+
lines.push(t(locale, 'cli.rules.suggest.configHint'));
|
|
60
|
+
lines.push(report.configSnippet);
|
|
61
|
+
}
|
|
62
|
+
if (report.patternDrafts && report.patternDrafts.length > 0) {
|
|
63
|
+
lines.push('');
|
|
64
|
+
lines.push(t(locale, 'cli.rules.suggest.patternDraftsHeader', { count: report.patternDrafts.length }));
|
|
65
|
+
lines.push(formatPatternDraftsYaml(report.patternDrafts));
|
|
66
|
+
}
|
|
67
|
+
return lines.join('\n');
|
|
68
|
+
}
|
|
69
|
+
export function formatSuggestYaml(report) {
|
|
70
|
+
const parts = [];
|
|
71
|
+
if (report.configSnippet) {
|
|
72
|
+
parts.push('# Enable suggested built-in rules — paste into aicq.config.yaml');
|
|
73
|
+
parts.push(report.configSnippet);
|
|
74
|
+
}
|
|
75
|
+
if (report.patternDrafts && report.patternDrafts.length > 0) {
|
|
76
|
+
if (parts.length > 0)
|
|
77
|
+
parts.push('');
|
|
78
|
+
parts.push('# Auto-suggested draft pattern rules — review & edit, then place each under your rulesDir');
|
|
79
|
+
parts.push(formatPatternDraftsYaml(report.patternDrafts));
|
|
80
|
+
}
|
|
81
|
+
return parts.length > 0 ? parts.join('\n') : '# No suggestions.';
|
|
82
|
+
}
|
|
83
|
+
function formatPatternDraftsYaml(drafts) {
|
|
84
|
+
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)}`)
|
|
86
|
+
.join('---\n');
|
|
87
|
+
}
|
|
88
|
+
function patternDraftToYaml(draft) {
|
|
89
|
+
return stringifyYaml({
|
|
90
|
+
id: draft.id,
|
|
91
|
+
language: draft.language,
|
|
92
|
+
severity: draft.severity,
|
|
93
|
+
message: draft.message,
|
|
94
|
+
messageKo: draft.messageKo,
|
|
95
|
+
query: draft.query,
|
|
96
|
+
}, { lineWidth: 0 });
|
|
97
|
+
}
|
|
98
|
+
function truncate(value, max) {
|
|
99
|
+
const oneLine = value.replace(/\s+/g, ' ').trim();
|
|
100
|
+
return oneLine.length <= max ? oneLine : `${oneLine.slice(0, max - 1)}…`;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/suggest/format.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { analyzeRepo } from './analyze.js';
|
|
2
|
+
export { minePatterns } from './mine.js';
|
|
3
|
+
export { buildConfigSnippet, formatSuggestText, formatSuggestYaml } from './format.js';
|
|
4
|
+
export type { AnalyzeRepoOptions, DependencySource, DetectedDependency, MinePatternsOptions, PatternRuleDraft, RuleSuggestion, RuleSuggestionReport, SuggestSampleLocation, } from './types.js';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/suggest/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACvF,YAAY,EACV,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/suggest/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { MinePatternsOptions, PatternRuleDraft } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Approach B (early prototype) — mine the AST for frequently-occurring
|
|
4
|
+
* `new X(...)` / `obj.method(...)` shapes and turn the top ones into draft
|
|
5
|
+
* tree-sitter pattern rules. `severity` is conservatively `info` and the
|
|
6
|
+
* `message`/`messageKo` are TODO placeholders — these are seeds a human edits,
|
|
7
|
+
* not finished rules. Every generated query is compiled against the language
|
|
8
|
+
* grammar before it is emitted; ones that don't compile are dropped.
|
|
9
|
+
*/
|
|
10
|
+
export declare function minePatterns(opts: MinePatternsOptions): Promise<PatternRuleDraft[]>;
|
|
11
|
+
//# sourceMappingURL=mine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mine.d.ts","sourceRoot":"","sources":["../../src/suggest/mine.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAyB,MAAM,YAAY,CAAC;AA0B/F;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAyEzF"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import fastGlob from 'fast-glob';
|
|
3
|
+
import Parser from 'tree-sitter';
|
|
4
|
+
import { detectLanguage, loadLanguage, parseSource } from '@aicqtools/core';
|
|
5
|
+
import { traverse } from '../matcher/traverse.js';
|
|
6
|
+
const DEFAULT_MIN_COUNT = 5;
|
|
7
|
+
const DEFAULT_TOP = 10;
|
|
8
|
+
const MAX_FILES = 5000;
|
|
9
|
+
const MAX_SAMPLES = 2;
|
|
10
|
+
const IDENTIFIER_RE = /^[A-Za-z_$][\w$]*$/;
|
|
11
|
+
/**
|
|
12
|
+
* Approach B (early prototype) — mine the AST for frequently-occurring
|
|
13
|
+
* `new X(...)` / `obj.method(...)` shapes and turn the top ones into draft
|
|
14
|
+
* tree-sitter pattern rules. `severity` is conservatively `info` and the
|
|
15
|
+
* `message`/`messageKo` are TODO placeholders — these are seeds a human edits,
|
|
16
|
+
* not finished rules. Every generated query is compiled against the language
|
|
17
|
+
* grammar before it is emitted; ones that don't compile are dropped.
|
|
18
|
+
*/
|
|
19
|
+
export async function minePatterns(opts) {
|
|
20
|
+
const minCount = Math.max(1, opts.minCount ?? DEFAULT_MIN_COUNT);
|
|
21
|
+
const top = Math.max(1, opts.top ?? DEFAULT_TOP);
|
|
22
|
+
const files = (await fastGlob([...opts.include], {
|
|
23
|
+
cwd: opts.cwd,
|
|
24
|
+
ignore: [...opts.exclude],
|
|
25
|
+
absolute: true,
|
|
26
|
+
onlyFiles: true,
|
|
27
|
+
dot: false,
|
|
28
|
+
})).slice(0, MAX_FILES);
|
|
29
|
+
const buckets = new Map();
|
|
30
|
+
for (const file of files) {
|
|
31
|
+
const language = detectLanguage(file);
|
|
32
|
+
if (!language)
|
|
33
|
+
continue;
|
|
34
|
+
let tree;
|
|
35
|
+
let source;
|
|
36
|
+
try {
|
|
37
|
+
source = await readFile(file, 'utf-8');
|
|
38
|
+
tree = parseSource(language, source);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
continue; // per-file isolation — a broken file must not abort mining
|
|
42
|
+
}
|
|
43
|
+
const textOf = (node) => source.slice(node.startIndex, node.endIndex);
|
|
44
|
+
try {
|
|
45
|
+
traverse(tree.rootNode, (node) => {
|
|
46
|
+
const sig = extractSignature(node, language, textOf);
|
|
47
|
+
if (!sig)
|
|
48
|
+
return;
|
|
49
|
+
const key = `${language}::${sig.signature}`;
|
|
50
|
+
let bucket = buckets.get(key);
|
|
51
|
+
if (!bucket) {
|
|
52
|
+
bucket = {
|
|
53
|
+
signature: sig.signature,
|
|
54
|
+
language,
|
|
55
|
+
kind: sig.kind,
|
|
56
|
+
parts: sig.parts,
|
|
57
|
+
count: 0,
|
|
58
|
+
files: new Set(),
|
|
59
|
+
samples: [],
|
|
60
|
+
};
|
|
61
|
+
buckets.set(key, bucket);
|
|
62
|
+
}
|
|
63
|
+
bucket.count += 1;
|
|
64
|
+
bucket.files.add(file);
|
|
65
|
+
if (bucket.samples.length < MAX_SAMPLES) {
|
|
66
|
+
bucket.samples.push({
|
|
67
|
+
file,
|
|
68
|
+
line: node.startPosition.row + 1,
|
|
69
|
+
column: node.startPosition.column + 1,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const candidates = [...buckets.values()]
|
|
79
|
+
.filter((b) => b.count >= minCount)
|
|
80
|
+
.sort((a, b) => b.count - a.count || a.signature.localeCompare(b.signature));
|
|
81
|
+
const drafts = [];
|
|
82
|
+
for (const bucket of candidates) {
|
|
83
|
+
if (drafts.length >= top)
|
|
84
|
+
break;
|
|
85
|
+
const query = buildQuery(bucket);
|
|
86
|
+
if (!query || !queryCompiles(query, bucket.language))
|
|
87
|
+
continue;
|
|
88
|
+
drafts.push(makeDraft(bucket, query));
|
|
89
|
+
}
|
|
90
|
+
return drafts;
|
|
91
|
+
}
|
|
92
|
+
function extractSignature(node, language, textOf) {
|
|
93
|
+
if (language === 'python') {
|
|
94
|
+
if (node.type !== 'call')
|
|
95
|
+
return null;
|
|
96
|
+
const fn = node.childForFieldName('function');
|
|
97
|
+
if (!fn || fn.type !== 'attribute')
|
|
98
|
+
return null;
|
|
99
|
+
const obj = fn.childForFieldName('object');
|
|
100
|
+
const attr = fn.childForFieldName('attribute');
|
|
101
|
+
if (!obj || obj.type !== 'identifier' || !attr || attr.type !== 'identifier')
|
|
102
|
+
return null;
|
|
103
|
+
const o = textOf(obj);
|
|
104
|
+
const a = textOf(attr);
|
|
105
|
+
if (!IDENTIFIER_RE.test(o) || !IDENTIFIER_RE.test(a))
|
|
106
|
+
return null;
|
|
107
|
+
return { signature: `call:${o}.${a}`, kind: 'call', parts: [o, a] };
|
|
108
|
+
}
|
|
109
|
+
// typescript / tsx / javascript
|
|
110
|
+
if (node.type === 'new_expression') {
|
|
111
|
+
const ctor = node.childForFieldName('constructor');
|
|
112
|
+
if (!ctor || ctor.type !== 'identifier')
|
|
113
|
+
return null;
|
|
114
|
+
const name = textOf(ctor);
|
|
115
|
+
if (!IDENTIFIER_RE.test(name))
|
|
116
|
+
return null;
|
|
117
|
+
return { signature: `new:${name}`, kind: 'new', parts: [name] };
|
|
118
|
+
}
|
|
119
|
+
if (node.type === 'call_expression') {
|
|
120
|
+
const fn = node.childForFieldName('function');
|
|
121
|
+
if (!fn || fn.type !== 'member_expression')
|
|
122
|
+
return null;
|
|
123
|
+
const obj = fn.childForFieldName('object');
|
|
124
|
+
const prop = fn.childForFieldName('property');
|
|
125
|
+
if (!obj || obj.type !== 'identifier' || !prop || prop.type !== 'property_identifier')
|
|
126
|
+
return null;
|
|
127
|
+
const o = textOf(obj);
|
|
128
|
+
const p = textOf(prop);
|
|
129
|
+
if (!IDENTIFIER_RE.test(o) || !IDENTIFIER_RE.test(p))
|
|
130
|
+
return null;
|
|
131
|
+
return { signature: `call:${o}.${p}`, kind: 'call', parts: [o, p] };
|
|
132
|
+
}
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
function buildQuery(bucket) {
|
|
136
|
+
if (bucket.kind === 'new') {
|
|
137
|
+
const name = bucket.parts[0];
|
|
138
|
+
if (!name)
|
|
139
|
+
return null;
|
|
140
|
+
return `(new_expression\n constructor: (identifier) @ctor\n (#eq? @ctor "${name}"))`;
|
|
141
|
+
}
|
|
142
|
+
const [obj, prop] = bucket.parts;
|
|
143
|
+
if (!obj || !prop)
|
|
144
|
+
return null;
|
|
145
|
+
if (bucket.language === 'python') {
|
|
146
|
+
return (`(call\n` +
|
|
147
|
+
` function: (attribute\n` +
|
|
148
|
+
` object: (identifier) @obj\n` +
|
|
149
|
+
` attribute: (identifier) @attr)\n` +
|
|
150
|
+
` (#eq? @obj "${obj}")\n` +
|
|
151
|
+
` (#eq? @attr "${prop}"))`);
|
|
152
|
+
}
|
|
153
|
+
return (`(call_expression\n` +
|
|
154
|
+
` function: (member_expression\n` +
|
|
155
|
+
` object: (identifier) @obj\n` +
|
|
156
|
+
` property: (property_identifier) @prop)\n` +
|
|
157
|
+
` (#eq? @obj "${obj}")\n` +
|
|
158
|
+
` (#eq? @prop "${prop}"))`);
|
|
159
|
+
}
|
|
160
|
+
function queryCompiles(query, language) {
|
|
161
|
+
try {
|
|
162
|
+
// eslint-disable-next-line no-new
|
|
163
|
+
new Parser.Query(loadLanguage(language), query);
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
function makeDraft(bucket, query) {
|
|
171
|
+
const slug = bucket.signature
|
|
172
|
+
.toLowerCase()
|
|
173
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
174
|
+
.replace(/^-+|-+$/g, '');
|
|
175
|
+
const filesN = bucket.files.size;
|
|
176
|
+
const fileWord = (n, en) => (en ? `file${n === 1 ? '' : 's'}` : '개');
|
|
177
|
+
return {
|
|
178
|
+
id: `suggested-${slug}`,
|
|
179
|
+
language: bucket.language,
|
|
180
|
+
severity: 'info',
|
|
181
|
+
message: `TODO: explain why \`${bucket.signature}\` warrants a project rule — auto-suggested, ${bucket.count} occurrences across ${filesN} ${fileWord(filesN, true)}.`,
|
|
182
|
+
messageKo: `TODO: \`${bucket.signature}\` 사용을 프로젝트 룰로 만들 이유를 설명하세요 — 자동 제안, 파일 ${filesN}${fileWord(filesN, false)}에서 ${bucket.count}회.`,
|
|
183
|
+
query,
|
|
184
|
+
meta: { count: bucket.count, files: filesN, sampleLocations: bucket.samples },
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=mine.js.map
|
|
@@ -0,0 +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;AAGlD,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAC5B,MAAM,WAAW,GAAG,EAAE,CAAC;AACvB,MAAM,SAAS,GAAG,IAAI,CAAC;AACvB,MAAM,WAAW,GAAG,CAAC,CAAC;AACtB,MAAM,aAAa,GAAG,oBAAoB,CAAC;AAoB3C;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAyB;IAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,QAAQ,IAAI,iBAAiB,CAAC,CAAC;IACjE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,IAAI,WAAW,CAAC,CAAC;IAEjD,MAAM,KAAK,GAAG,CACZ,MAAM,QAAQ,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE;QAChC,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;QACzB,QAAQ,EAAE,IAAI;QACd,SAAS,EAAE,IAAI;QACf,GAAG,EAAE,KAAK;KACX,CAAC,CACH,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IAEtB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAyB,CAAC;IAEjD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC,QAAQ;YAAE,SAAS;QACxB,IAAI,IAAiB,CAAC;QACtB,IAAI,MAAc,CAAC;QACnB,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACvC,IAAI,GAAG,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC;YACP,SAAS,CAAC,2DAA2D;QACvE,CAAC;QACD,MAAM,MAAM,GAAG,CAAC,IAAuB,EAAU,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACjG,IAAI,CAAC;YACH,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;gBAC/B,MAAM,GAAG,GAAG,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;gBACrD,IAAI,CAAC,GAAG;oBAAE,OAAO;gBACjB,MAAM,GAAG,GAAG,GAAG,QAAQ,KAAK,GAAG,CAAC,SAAS,EAAE,CAAC;gBAC5C,IAAI,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAC9B,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,MAAM,GAAG;wBACP,SAAS,EAAE,GAAG,CAAC,SAAS;wBACxB,QAAQ;wBACR,IAAI,EAAE,GAAG,CAAC,IAAI;wBACd,KAAK,EAAE,GAAG,CAAC,KAAK;wBAChB,KAAK,EAAE,CAAC;wBACR,KAAK,EAAE,IAAI,GAAG,EAAE;wBAChB,OAAO,EAAE,EAAE;qBACZ,CAAC;oBACF,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;gBAC3B,CAAC;gBACD,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;gBAClB,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACvB,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,WAAW,EAAE,CAAC;oBACxC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;wBAClB,IAAI;wBACJ,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC;wBAChC,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC;qBACtC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;IAED,MAAM,UAAU,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;SACrC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,QAAQ,CAAC;SAClC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAE/E,MAAM,MAAM,GAAuB,EAAE,CAAC;IACtC,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;QAChC,IAAI,MAAM,CAAC,MAAM,IAAI,GAAG;YAAE,MAAM;QAChC,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;QACjC,IAAI,CAAC,KAAK,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC;YAAE,SAAS;QAC/D,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,gBAAgB,CACvB,IAAuB,EACvB,QAAkB,EAClB,MAAwC;IAExC,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC;QACtC,MAAM,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;QAC9C,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,IAAI,KAAK,WAAW;YAAE,OAAO,IAAI,CAAC;QAChD,MAAM,GAAG,GAAG,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QAC3C,MAAM,IAAI,GAAG,EAAE,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;QAC/C,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY;YAAE,OAAO,IAAI,CAAC;QAC1F,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACtB,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QACvB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QAClE,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IACtE,CAAC;IAED,gCAAgC;IAChC,IAAI,IAAI,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY;YAAE,OAAO,IAAI,CAAC;QACrD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAC3C,OAAO,EAAE,SAAS,EAAE,OAAO,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;IAClE,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;QACpC,MAAM,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;QAC9C,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,IAAI,KAAK,mBAAmB;YAAE,OAAO,IAAI,CAAC;QACxD,MAAM,GAAG,GAAG,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QAC3C,MAAM,IAAI,GAAG,EAAE,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;QAC9C,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,qBAAqB;YAAE,OAAO,IAAI,CAAC;QACnG,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACtB,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QACvB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QAClE,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IACtE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,UAAU,CAAC,MAAqB;IACvC,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC7B,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACvB,OAAO,sEAAsE,IAAI,KAAK,CAAC;IACzF,CAAC;IACD,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC;IACjC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAC/B,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,CACL,SAAS;YACT,0BAA0B;YAC1B,iCAAiC;YACjC,sCAAsC;YACtC,iBAAiB,GAAG,MAAM;YAC1B,kBAAkB,IAAI,KAAK,CAC5B,CAAC;IACJ,CAAC;IACD,OAAO,CACL,oBAAoB;QACpB,kCAAkC;QAClC,iCAAiC;QACjC,8CAA8C;QAC9C,iBAAiB,GAAG,MAAM;QAC1B,kBAAkB,IAAI,KAAK,CAC5B,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,KAAa,EAAE,QAAkB;IACtD,IAAI,CAAC;QACH,kCAAkC;QAClC,IAAI,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,CAAC;QAChD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,MAAqB,EAAE,KAAa;IACrD,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS;SAC1B,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC3B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;IACjC,MAAM,QAAQ,GAAG,CAAC,CAAS,EAAE,EAAW,EAAU,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC9F,OAAO;QACL,EAAE,EAAE,aAAa,IAAI,EAAE;QACvB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,uBAAuB,MAAM,CAAC,SAAS,gDAAgD,MAAM,CAAC,KAAK,uBAAuB,MAAM,IAAI,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG;QACtK,SAAS,EAAE,WAAW,MAAM,CAAC,SAAS,2CAA2C,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,MAAM,CAAC,KAAK,IAAI;QACvI,KAAK;QACL,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,CAAC,OAAO,EAAE;KAC9E,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { FileCache, Language, Severity } from '@aicqtools/core';
|
|
2
|
+
import type { Rule } from '@aicqtools/rule-sdk';
|
|
3
|
+
export interface SuggestSampleLocation {
|
|
4
|
+
readonly file: string;
|
|
5
|
+
readonly line: number;
|
|
6
|
+
readonly column: number;
|
|
7
|
+
}
|
|
8
|
+
export interface RuleSuggestion {
|
|
9
|
+
readonly ruleId: string;
|
|
10
|
+
readonly hits: number;
|
|
11
|
+
readonly severity: Severity;
|
|
12
|
+
readonly message: string;
|
|
13
|
+
readonly messageKo?: string;
|
|
14
|
+
readonly docs?: string;
|
|
15
|
+
readonly sampleLocations: readonly SuggestSampleLocation[];
|
|
16
|
+
readonly stackMatch?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export type DependencySource = 'package.json' | 'requirements.txt';
|
|
19
|
+
export interface DetectedDependency {
|
|
20
|
+
readonly name: string;
|
|
21
|
+
readonly source: DependencySource;
|
|
22
|
+
}
|
|
23
|
+
export interface PatternRuleDraft {
|
|
24
|
+
readonly id: string;
|
|
25
|
+
readonly language: Language;
|
|
26
|
+
readonly severity: 'info';
|
|
27
|
+
readonly message: string;
|
|
28
|
+
readonly messageKo: string;
|
|
29
|
+
readonly query: string;
|
|
30
|
+
readonly meta: {
|
|
31
|
+
readonly count: number;
|
|
32
|
+
readonly files: number;
|
|
33
|
+
readonly sampleLocations: readonly SuggestSampleLocation[];
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export interface RuleSuggestionReport {
|
|
37
|
+
readonly filesScanned: number;
|
|
38
|
+
readonly languagesPresent: readonly Language[];
|
|
39
|
+
readonly durationMs: number;
|
|
40
|
+
readonly suggestions: readonly RuleSuggestion[];
|
|
41
|
+
readonly detectedDependencies: readonly DetectedDependency[];
|
|
42
|
+
/** A paste-ready `aicq.config.yaml` fragment that enables the suggested rules. */
|
|
43
|
+
readonly configSnippet: string;
|
|
44
|
+
readonly patternDrafts?: readonly PatternRuleDraft[];
|
|
45
|
+
}
|
|
46
|
+
export interface AnalyzeRepoOptions {
|
|
47
|
+
readonly cwd: string;
|
|
48
|
+
readonly include: readonly string[];
|
|
49
|
+
readonly exclude: readonly string[];
|
|
50
|
+
readonly rules: readonly Rule[];
|
|
51
|
+
readonly cache?: FileCache;
|
|
52
|
+
readonly top?: number;
|
|
53
|
+
readonly minHits?: number;
|
|
54
|
+
}
|
|
55
|
+
export interface MinePatternsOptions {
|
|
56
|
+
readonly cwd: string;
|
|
57
|
+
readonly include: readonly string[];
|
|
58
|
+
readonly exclude: readonly string[];
|
|
59
|
+
readonly minCount?: number;
|
|
60
|
+
readonly top?: number;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/suggest/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAEhD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,eAAe,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAC3D,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,MAAM,gBAAgB,GAAG,cAAc,GAAG,kBAAkB,CAAC;AAEnE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;CACnC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE;QACb,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,eAAe,EAAE,SAAS,qBAAqB,EAAE,CAAC;KAC5D,CAAC;CACH;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,gBAAgB,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC/C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,SAAS,cAAc,EAAE,CAAC;IAChD,QAAQ,CAAC,oBAAoB,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC7D,kFAAkF;IAClF,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,gBAAgB,EAAE,CAAC;CACtD;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;IAChC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/suggest/types.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aicqtools/guardrail",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Deterministic AI code guardrail engine — 37 built-in rules, hybrid YAML/function DSL, MCP server, .cursorrules sync, sqlite cache.",
|
|
6
6
|
"keywords": [
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"fast-glob": "^3.3.2",
|
|
45
45
|
"yaml": "^2.6.1",
|
|
46
46
|
"zod": "^3.23.8",
|
|
47
|
-
"@aicqtools/core": "1.0.0-alpha.
|
|
48
|
-
"@aicqtools/rule-sdk": "1.0.0-alpha.
|
|
47
|
+
"@aicqtools/core": "1.0.0-alpha.6",
|
|
48
|
+
"@aicqtools/rule-sdk": "1.0.0-alpha.6"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
51
|
"tree-sitter": "~0.22.4"
|