@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/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { runFile, runFileWithSource, runProject, runRule, } from './runner/index.js';
|
|
2
|
-
export type { RunFileResult, RunProjectOptions } from './runner/index.js';
|
|
1
|
+
export { runFile, runFileWithSource, runProject, runRule, applyRuleConfig, } from './runner/index.js';
|
|
2
|
+
export type { RunFileResult, RunProjectOptions, ApplyRuleConfigResult } from './runner/index.js';
|
|
3
3
|
export { traverse, parseYamlRule } from './matcher/index.js';
|
|
4
4
|
export type { YamlRuleInput } from './matcher/index.js';
|
|
5
5
|
export { builtinFunctionRules, loadBuiltinYamlRules, loadAllBuiltinRules, loadFunctionRulesFromDir, } from './rules-default/index.js';
|
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,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,iBAAiB,EACjB,UAAU,EACV,OAAO,EACP,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAEjG,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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { runFile, runFileWithSource, runProject, runRule, } from './runner/index.js';
|
|
1
|
+
export { runFile, runFileWithSource, runProject, runRule, applyRuleConfig, } from './runner/index.js';
|
|
2
2
|
export { traverse, parseYamlRule } from './matcher/index.js';
|
|
3
3
|
export { builtinFunctionRules, loadBuiltinYamlRules, loadAllBuiltinRules, loadFunctionRulesFromDir, } from './rules-default/index.js';
|
|
4
4
|
export { buildMcpServer, startStdio, handleCheckSnippet, handleListRules, checkSnippetInputSchema, } from './mcp/index.js';
|
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,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,iBAAiB,EACjB,UAAU,EACV,OAAO,EACP,eAAe,GAChB,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"}
|
|
@@ -7,23 +7,26 @@ declare const yamlRuleSchema: z.ZodObject<{
|
|
|
7
7
|
message: z.ZodString;
|
|
8
8
|
messageKo: z.ZodOptional<z.ZodString>;
|
|
9
9
|
docs: z.ZodOptional<z.ZodString>;
|
|
10
|
+
pathExclude: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
10
11
|
query: z.ZodString;
|
|
11
12
|
}, "strip", z.ZodTypeAny, {
|
|
12
13
|
language: "typescript" | "javascript" | "tsx" | "python" | ("typescript" | "javascript" | "tsx" | "python")[];
|
|
14
|
+
query: string;
|
|
13
15
|
id: string;
|
|
14
16
|
message: string;
|
|
15
17
|
severity: "error" | "warning" | "info";
|
|
16
|
-
query: string;
|
|
17
18
|
messageKo?: string | undefined;
|
|
18
19
|
docs?: string | undefined;
|
|
20
|
+
pathExclude?: string[] | undefined;
|
|
19
21
|
}, {
|
|
20
22
|
language: "typescript" | "javascript" | "tsx" | "python" | ("typescript" | "javascript" | "tsx" | "python")[];
|
|
23
|
+
query: string;
|
|
21
24
|
id: string;
|
|
22
25
|
message: string;
|
|
23
26
|
severity: "error" | "warning" | "info";
|
|
24
|
-
query: string;
|
|
25
27
|
messageKo?: string | undefined;
|
|
26
28
|
docs?: string | undefined;
|
|
29
|
+
pathExclude?: string[] | undefined;
|
|
27
30
|
}>;
|
|
28
31
|
export type YamlRuleInput = z.infer<typeof yamlRuleSchema>;
|
|
29
32
|
export declare function parseYamlRule(source: string): PatternRule;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yaml-rule.d.ts","sourceRoot":"","sources":["../../src/matcher/yaml-rule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAMvD,QAAA,MAAM,cAAc
|
|
1
|
+
{"version":3,"file":"yaml-rule.d.ts","sourceRoot":"","sources":["../../src/matcher/yaml-rule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAMvD,QAAA,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;EASlB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE3D,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,CAgBzD"}
|
|
@@ -9,6 +9,7 @@ const yamlRuleSchema = z.object({
|
|
|
9
9
|
message: z.string().min(1),
|
|
10
10
|
messageKo: z.string().optional(),
|
|
11
11
|
docs: z.string().url().optional(),
|
|
12
|
+
pathExclude: z.array(z.string().min(1)).optional(),
|
|
12
13
|
query: z.string().min(1),
|
|
13
14
|
});
|
|
14
15
|
export function parseYamlRule(source) {
|
|
@@ -20,11 +21,12 @@ export function parseYamlRule(source) {
|
|
|
20
21
|
severity: parsed.severity,
|
|
21
22
|
message: parsed.message,
|
|
22
23
|
query: parsed.query,
|
|
24
|
+
...(parsed.messageKo !== undefined ? { messageKo: parsed.messageKo } : {}),
|
|
25
|
+
...(parsed.docs !== undefined ? { docs: parsed.docs } : {}),
|
|
26
|
+
...(parsed.pathExclude !== undefined && parsed.pathExclude.length > 0
|
|
27
|
+
? { pathExclude: parsed.pathExclude }
|
|
28
|
+
: {}),
|
|
23
29
|
};
|
|
24
|
-
return
|
|
25
|
-
? { ...rule, messageKo: parsed.messageKo }
|
|
26
|
-
: parsed.docs !== undefined
|
|
27
|
-
? { ...rule, docs: parsed.docs }
|
|
28
|
-
: rule;
|
|
30
|
+
return rule;
|
|
29
31
|
}
|
|
30
32
|
//# sourceMappingURL=yaml-rule.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yaml-rule.js","sourceRoot":"","sources":["../../src/matcher/yaml-rule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAI1C,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;AAC7E,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;AAE5D,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9B,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACrB,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACnE,QAAQ,EAAE,cAAc;IACxB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACjC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CACzB,CAAC,CAAC;AAIH,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACvD,MAAM,IAAI,GAAgB;QACxB,IAAI,EAAE,SAAS;QACf,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,QAAQ,EAAE,MAAM,CAAC,QAA0C;QAC3D,QAAQ,EAAE,MAAM,CAAC,QAAoB;QACrC,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,KAAK,EAAE,MAAM,CAAC,KAAK;
|
|
1
|
+
{"version":3,"file":"yaml-rule.js","sourceRoot":"","sources":["../../src/matcher/yaml-rule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAI1C,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;AAC7E,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;AAE5D,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9B,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACrB,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACnE,QAAQ,EAAE,cAAc;IACxB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACjC,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAClD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CACzB,CAAC,CAAC;AAIH,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACvD,MAAM,IAAI,GAAgB;QACxB,IAAI,EAAE,SAAS;QACf,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,QAAQ,EAAE,MAAM,CAAC,QAA0C;QAC3D,QAAQ,EAAE,MAAM,CAAC,QAAoB;QACrC,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,GAAG,CAAC,MAAM,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,GAAG,CAAC,MAAM,CAAC,WAAW,KAAK,SAAS,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC;YACnE,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE;YACrC,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;IACF,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -3,6 +3,12 @@ language: typescript
|
|
|
3
3
|
severity: error
|
|
4
4
|
message: Use the llmClient singleton. Direct Anthropic instantiation is forbidden.
|
|
5
5
|
messageKo: llmClient 싱글톤을 사용하세요. 직접 Anthropic 인스턴스화는 금지입니다.
|
|
6
|
+
# Allow the designated LLM wrapper module to construct the SDK once. Conventions only —
|
|
7
|
+
# add an inline `// aicq-disable-next-line no-direct-anthropic` outside these paths.
|
|
8
|
+
pathExclude:
|
|
9
|
+
- '**/llm/client.*'
|
|
10
|
+
- '**/llm/index.*'
|
|
11
|
+
- '**/ai/**/*client*.*'
|
|
6
12
|
query: |
|
|
7
13
|
(new_expression
|
|
8
14
|
constructor: (identifier) @ctor
|
|
@@ -3,6 +3,14 @@ language: typescript
|
|
|
3
3
|
severity: error
|
|
4
4
|
message: Use the llmClient singleton. Direct OpenAI instantiation is forbidden.
|
|
5
5
|
messageKo: llmClient 싱글톤을 사용하세요. 직접 OpenAI 인스턴스화는 금지입니다.
|
|
6
|
+
# Allow the *designated* LLM wrapper module to construct the SDK once. Conventions only —
|
|
7
|
+
# the project structures `src/**/llm/{client,index}.ts` or `src/**/ai/**/{*client*}.ts`
|
|
8
|
+
# as the single permitted call-site. Add an inline `// aicq-disable-next-line no-direct-openai`
|
|
9
|
+
# for one-off exceptions outside these paths.
|
|
10
|
+
pathExclude:
|
|
11
|
+
- '**/llm/client.*'
|
|
12
|
+
- '**/llm/index.*'
|
|
13
|
+
- '**/ai/**/*client*.*'
|
|
6
14
|
query: |
|
|
7
15
|
(new_expression
|
|
8
16
|
constructor: (identifier) @ctor
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-magic-number.d.ts","sourceRoot":"","sources":["../../src/rules-default/no-magic-number.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"no-magic-number.d.ts","sourceRoot":"","sources":["../../src/rules-default/no-magic-number.ts"],"names":[],"mappings":";AA0HA,wBAiBG"}
|
|
@@ -1,10 +1,45 @@
|
|
|
1
1
|
import { defineRule } from '@aicqtools/rule-sdk';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
/**
|
|
3
|
+
* `no-magic-number` — info-severity rule that flags numeric literals appearing inline in
|
|
4
|
+
* application code (rather than being given a named constant). The hardest part is choosing
|
|
5
|
+
* a defensible default for "what's NOT a magic number." This rule errs on the side of fewer
|
|
6
|
+
* false positives because it ships at `info` severity and historically dominates noise budgets.
|
|
7
|
+
*
|
|
8
|
+
* Skipped contexts (all heuristic; project-specific tuning belongs in a future per-rule
|
|
9
|
+
* options seam):
|
|
10
|
+
* - Test fixture / spec files (filename heuristic)
|
|
11
|
+
* - `*.config.{ts,tsx,js,jsx}`, `*.polyfill.{ts,tsx,js,jsx}`, `**\/polyfills/**` (filename)
|
|
12
|
+
* - Variable declarator RHS (`const X = 7;` — 7 is being NAMED, not used inline)
|
|
13
|
+
* - JSX attribute values (`<View width={24} />`)
|
|
14
|
+
* - Enum members (`enum E { A = 7 }`)
|
|
15
|
+
* - Array index subscripts (`arr[42]`)
|
|
16
|
+
* - `for` loop initializer/condition/update
|
|
17
|
+
* - Arguments to obvious numeric APIs (`parseInt(s, 16)`, `Math.*`, `Number(...)`, `.toFixed(2)`,
|
|
18
|
+
* `.padStart(8, '0')`, `setTimeout(f, 100)`, `setInterval(f, 1000)`)
|
|
19
|
+
* - "Timeout-ish" variable-name contexts (carried over from alpha.6)
|
|
20
|
+
*
|
|
21
|
+
* Allowed-numbers default extended to common-sense values: powers of two, common bases,
|
|
22
|
+
* time/clock constants, etc.
|
|
23
|
+
*/
|
|
24
|
+
const ALLOWED_NUMBERS = new Set([
|
|
25
|
+
'0', '1', '-1', '2', '-2', '10', '16', '24', '60', '100', '1000', '1024',
|
|
26
|
+
]);
|
|
27
|
+
const SKIP_FILE_RE = /(\.test\.|\.spec\.|__tests__|fixtures|\.config\.|\.polyfill\.|[/\\]polyfills[/\\])/;
|
|
28
|
+
// Callee names whose numeric args are almost always intentional, not magic numbers.
|
|
29
|
+
// Matched on the leaf identifier (last name segment) — covers both `parseInt(...)` and
|
|
30
|
+
// `Number.parseInt(...)` / `globalThis.setTimeout(...)`.
|
|
31
|
+
const NUMERIC_API_CALLEES = new Set([
|
|
32
|
+
'parseInt', 'parseFloat', 'Number',
|
|
33
|
+
'setTimeout', 'setInterval', 'setImmediate',
|
|
34
|
+
'toFixed', 'toPrecision', 'toExponential', 'toString',
|
|
35
|
+
'padStart', 'padEnd', 'repeat', 'slice', 'substr', 'substring', 'charAt', 'codePointAt',
|
|
36
|
+
'round', 'floor', 'ceil', 'trunc', 'abs', 'sign', 'min', 'max', 'pow', 'log',
|
|
37
|
+
]);
|
|
38
|
+
function isInSkippedFile(filePath) {
|
|
39
|
+
return SKIP_FILE_RE.test(filePath);
|
|
5
40
|
}
|
|
6
41
|
function isInTimeoutMsContext(node, textOf) {
|
|
7
|
-
// Allow magic numbers in obvious time/duration contexts where the unit is in the variable name
|
|
42
|
+
// Allow magic numbers in obvious time/duration contexts where the unit is in the variable name.
|
|
8
43
|
let parent = node.parent;
|
|
9
44
|
while (parent) {
|
|
10
45
|
const text = textOf(parent);
|
|
@@ -16,6 +51,71 @@ function isInTimeoutMsContext(node, textOf) {
|
|
|
16
51
|
}
|
|
17
52
|
return false;
|
|
18
53
|
}
|
|
54
|
+
const SKIP_ANCESTOR_TYPES = new Set([
|
|
55
|
+
// Variable declarator: `const RETRY = 5;` — the literal IS the named constant we want.
|
|
56
|
+
'variable_declarator',
|
|
57
|
+
// Enum members: `enum E { A = 7 }`
|
|
58
|
+
'enum_body',
|
|
59
|
+
'enum_assignment',
|
|
60
|
+
// JSX attribute values: `<View width={24} />`
|
|
61
|
+
'jsx_attribute',
|
|
62
|
+
'jsx_expression',
|
|
63
|
+
// Array index subscripts: `arr[42]`
|
|
64
|
+
'subscript_expression',
|
|
65
|
+
// For loop header: `for (let i = 0; i < 5; i++) {}`
|
|
66
|
+
'for_statement',
|
|
67
|
+
'for_in_statement',
|
|
68
|
+
'for_of_statement',
|
|
69
|
+
]);
|
|
70
|
+
function hasSkippableAncestor(node) {
|
|
71
|
+
let parent = node.parent;
|
|
72
|
+
let depth = 0;
|
|
73
|
+
while (parent && depth < 8) {
|
|
74
|
+
if (SKIP_ANCESTOR_TYPES.has(parent.type))
|
|
75
|
+
return true;
|
|
76
|
+
// Stop at clear statement / function boundaries so a number deep in a function body
|
|
77
|
+
// doesn't get silently allowed by a far-away for-loop ancestor.
|
|
78
|
+
if (parent.type === 'statement_block' ||
|
|
79
|
+
parent.type === 'function_declaration' ||
|
|
80
|
+
parent.type === 'method_definition' ||
|
|
81
|
+
parent.type === 'arrow_function' ||
|
|
82
|
+
parent.type === 'function_expression') {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
parent = parent.parent;
|
|
86
|
+
depth += 1;
|
|
87
|
+
}
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Returns true if the number is a positional argument to a call expression whose final
|
|
92
|
+
* identifier is a known numeric API (parseInt, parseFloat, Math.*, .toFixed, …).
|
|
93
|
+
*/
|
|
94
|
+
function isArgOfNumericApi(node, textOf) {
|
|
95
|
+
const parent = node.parent;
|
|
96
|
+
if (!parent || parent.type !== 'arguments')
|
|
97
|
+
return false;
|
|
98
|
+
const callExpr = parent.parent;
|
|
99
|
+
if (!callExpr || callExpr.type !== 'call_expression')
|
|
100
|
+
return false;
|
|
101
|
+
const fn = callExpr.childForFieldName('function');
|
|
102
|
+
if (!fn)
|
|
103
|
+
return false;
|
|
104
|
+
// Pull out the *final* name segment whether the callee is `foo` or `Obj.foo` or `a.b.foo`.
|
|
105
|
+
let nameNode = fn;
|
|
106
|
+
while (nameNode && (nameNode.type === 'member_expression' || nameNode.type === 'parenthesized_expression')) {
|
|
107
|
+
const fromField = nameNode.childForFieldName('property');
|
|
108
|
+
const fallback = nameNode.namedChildren[nameNode.namedChildren.length - 1];
|
|
109
|
+
const prop = fromField ?? fallback ?? null;
|
|
110
|
+
if (!prop || prop === nameNode)
|
|
111
|
+
break;
|
|
112
|
+
nameNode = prop;
|
|
113
|
+
}
|
|
114
|
+
if (!nameNode)
|
|
115
|
+
return false;
|
|
116
|
+
const name = textOf(nameNode);
|
|
117
|
+
return NUMERIC_API_CALLEES.has(name);
|
|
118
|
+
}
|
|
19
119
|
export default defineRule({
|
|
20
120
|
id: 'no-magic-number',
|
|
21
121
|
language: ['typescript', 'javascript', 'tsx'],
|
|
@@ -24,16 +124,16 @@ export default defineRule({
|
|
|
24
124
|
messageKo: '매직 넘버 — 명명된 상수로 추출해 의미를 명확히 하세요.',
|
|
25
125
|
visitors: {
|
|
26
126
|
number(node, ctx) {
|
|
27
|
-
if (
|
|
127
|
+
if (isInSkippedFile(ctx.filePath))
|
|
28
128
|
return;
|
|
29
129
|
const text = ctx.textOf(node);
|
|
30
130
|
if (ALLOWED_NUMBERS.has(text))
|
|
31
131
|
return;
|
|
32
|
-
if (
|
|
132
|
+
if (hasSkippableAncestor(node))
|
|
133
|
+
return;
|
|
134
|
+
if (isArgOfNumericApi(node, ctx.textOf))
|
|
33
135
|
return;
|
|
34
|
-
|
|
35
|
-
const parent = node.parent;
|
|
36
|
-
if (parent && parent.type === 'variable_declarator')
|
|
136
|
+
if (isInTimeoutMsContext(node, ctx.textOf))
|
|
37
137
|
return;
|
|
38
138
|
ctx.report({ node });
|
|
39
139
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-magic-number.js","sourceRoot":"","sources":["../../src/rules-default/no-magic-number.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"no-magic-number.js","sourceRoot":"","sources":["../../src/rules-default/no-magic-number.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-process-env-leak.d.ts","sourceRoot":"","sources":["../../src/rules-default/no-process-env-leak.ts"],"names":[],"mappings":"AAEA;;;GAGG;;AACH,
|
|
1
|
+
{"version":3,"file":"no-process-env-leak.d.ts","sourceRoot":"","sources":["../../src/rules-default/no-process-env-leak.ts"],"names":[],"mappings":"AAEA;;;GAGG;;AACH,wBA8BG"}
|
|
@@ -22,8 +22,11 @@ export default defineRule({
|
|
|
22
22
|
innerProp &&
|
|
23
23
|
ctx.textOf(inner) === 'process' &&
|
|
24
24
|
ctx.textOf(innerProp) === 'env') {
|
|
25
|
-
// Allowlist: config
|
|
26
|
-
|
|
25
|
+
// Allowlist: `config/`, `env/`, and `*.config.*` / `*.env.*` files (e.g. `next.config.ts`,
|
|
26
|
+
// `vite.config.ts`, `jest.config.ts`). Includes a leading `.` in the prefix character
|
|
27
|
+
// class so dotted filenames where `config`/`env` is preceded by `.` (e.g. `next.config.ts`)
|
|
28
|
+
// are recognized.
|
|
29
|
+
if (/(^|[/\\.])(config|env)([/\\.]|$)/.test(ctx.filePath))
|
|
27
30
|
return;
|
|
28
31
|
ctx.report({ node });
|
|
29
32
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-process-env-leak.js","sourceRoot":"","sources":["../../src/rules-default/no-process-env-leak.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD;;;GAGG;AACH,eAAe,UAAU,CAAC;IACxB,EAAE,EAAE,qBAAqB;IACzB,QAAQ,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,KAAK,CAAC;IAC7C,QAAQ,EAAE,SAAS;IACnB,OAAO,EAAE,gEAAgE;IACzE,SAAS,EAAE,+DAA+D;IAC1E,QAAQ,EAAE;QACR,iBAAiB,CAAC,IAAI,EAAE,GAAG;YACzB,MAAM,GAAG,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;YAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;YAChD,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI;gBAAE,OAAO;YAC1B,IAAI,GAAG,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;gBACrC,MAAM,KAAK,GAAG,GAAG,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;gBAC9C,MAAM,SAAS,GAAG,GAAG,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;gBACpD,IACE,KAAK;oBACL,SAAS;oBACT,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,SAAS;oBAC/B,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,KAAK,EAC/B,CAAC;oBACD,
|
|
1
|
+
{"version":3,"file":"no-process-env-leak.js","sourceRoot":"","sources":["../../src/rules-default/no-process-env-leak.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD;;;GAGG;AACH,eAAe,UAAU,CAAC;IACxB,EAAE,EAAE,qBAAqB;IACzB,QAAQ,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,KAAK,CAAC;IAC7C,QAAQ,EAAE,SAAS;IACnB,OAAO,EAAE,gEAAgE;IACzE,SAAS,EAAE,+DAA+D;IAC1E,QAAQ,EAAE;QACR,iBAAiB,CAAC,IAAI,EAAE,GAAG;YACzB,MAAM,GAAG,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;YAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;YAChD,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI;gBAAE,OAAO;YAC1B,IAAI,GAAG,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;gBACrC,MAAM,KAAK,GAAG,GAAG,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;gBAC9C,MAAM,SAAS,GAAG,GAAG,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;gBACpD,IACE,KAAK;oBACL,SAAS;oBACT,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,SAAS;oBAC/B,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,KAAK,EAC/B,CAAC;oBACD,2FAA2F;oBAC3F,sFAAsF;oBACtF,4FAA4F;oBAC5F,kBAAkB;oBAClB,IAAI,kCAAkC,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;wBAAE,OAAO;oBAClE,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;gBACvB,CAAC;YACH,CAAC;QACH,CAAC;KACF;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Rule } from '@aicqtools/rule-sdk';
|
|
2
|
+
/**
|
|
3
|
+
* Resolution of `config.modules.guardrail.rules` (the `{ ruleId: 'off' | 'warn' | 'error' }` map)
|
|
4
|
+
* against the loaded rule set. Filters out `off`'d rules, overrides severity for `warn`/`error`
|
|
5
|
+
* entries, and reports unknown rule ids back to the caller so the CLI can warn the user once.
|
|
6
|
+
*/
|
|
7
|
+
export interface ApplyRuleConfigResult {
|
|
8
|
+
readonly rules: readonly Rule[];
|
|
9
|
+
/** rule ids that appeared in the config map but matched no loaded rule */
|
|
10
|
+
readonly unknownIds: readonly string[];
|
|
11
|
+
}
|
|
12
|
+
type RuleLevel = 'off' | 'warn' | 'error';
|
|
13
|
+
/**
|
|
14
|
+
* Apply the user-supplied `rules:` map to a loaded rule list.
|
|
15
|
+
*
|
|
16
|
+
* - `off` → drop the rule from the returned list
|
|
17
|
+
* - `warn`/`error` → return a copy of the rule with `severity` overridden
|
|
18
|
+
* - missing entry → rule passes through unchanged
|
|
19
|
+
*
|
|
20
|
+
* Map keys that don't correspond to any loaded rule are collected in `unknownIds`. The function
|
|
21
|
+
* never throws; an invalid level value (should already be rejected by zod) is treated as "no
|
|
22
|
+
* override" rather than crashing the run.
|
|
23
|
+
*/
|
|
24
|
+
export declare function applyRuleConfig(rules: readonly Rule[], cfgMap: Readonly<Record<string, RuleLevel>> | undefined): ApplyRuleConfigResult;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=apply-rule-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply-rule-config.d.ts","sourceRoot":"","sources":["../../src/runner/apply-rule-config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAEhD;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;IAChC,0EAA0E;IAC1E,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAED,KAAK,SAAS,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;AAM1C;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,SAAS,IAAI,EAAE,EACtB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,GAAG,SAAS,GACtD,qBAAqB,CAgCvB"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const LEVEL_TO_SEVERITY = {
|
|
2
|
+
warn: 'warning',
|
|
3
|
+
error: 'error',
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Apply the user-supplied `rules:` map to a loaded rule list.
|
|
7
|
+
*
|
|
8
|
+
* - `off` → drop the rule from the returned list
|
|
9
|
+
* - `warn`/`error` → return a copy of the rule with `severity` overridden
|
|
10
|
+
* - missing entry → rule passes through unchanged
|
|
11
|
+
*
|
|
12
|
+
* Map keys that don't correspond to any loaded rule are collected in `unknownIds`. The function
|
|
13
|
+
* never throws; an invalid level value (should already be rejected by zod) is treated as "no
|
|
14
|
+
* override" rather than crashing the run.
|
|
15
|
+
*/
|
|
16
|
+
export function applyRuleConfig(rules, cfgMap) {
|
|
17
|
+
if (!cfgMap || Object.keys(cfgMap).length === 0) {
|
|
18
|
+
return { rules, unknownIds: [] };
|
|
19
|
+
}
|
|
20
|
+
const knownIds = new Set(rules.map((r) => r.id));
|
|
21
|
+
const unknownIds = [];
|
|
22
|
+
for (const id of Object.keys(cfgMap)) {
|
|
23
|
+
if (!knownIds.has(id))
|
|
24
|
+
unknownIds.push(id);
|
|
25
|
+
}
|
|
26
|
+
const out = [];
|
|
27
|
+
for (const rule of rules) {
|
|
28
|
+
const level = cfgMap[rule.id];
|
|
29
|
+
if (level === undefined) {
|
|
30
|
+
out.push(rule);
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (level === 'off')
|
|
34
|
+
continue;
|
|
35
|
+
const severity = LEVEL_TO_SEVERITY[level];
|
|
36
|
+
if (!severity) {
|
|
37
|
+
// Unrecognized level — treat as no override, never crash.
|
|
38
|
+
out.push(rule);
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
// Copy with overridden severity. `Rule` is a discriminated union; preserve the union
|
|
42
|
+
// by re-spreading per branch.
|
|
43
|
+
if (rule.kind === 'function') {
|
|
44
|
+
out.push({ ...rule, severity });
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
out.push({ ...rule, severity });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return { rules: out, unknownIds };
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=apply-rule-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply-rule-config.js","sourceRoot":"","sources":["../../src/runner/apply-rule-config.ts"],"names":[],"mappings":"AAeA,MAAM,iBAAiB,GAAgD;IACrE,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,OAAO;CACf,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe,CAC7B,KAAsB,EACtB,MAAuD;IAEvD,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;IACnC,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACjD,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACrC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7C,CAAC;IACD,MAAM,GAAG,GAAW,EAAE,CAAC;IACvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC9B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACf,SAAS;QACX,CAAC;QACD,IAAI,KAAK,KAAK,KAAK;YAAE,SAAS;QAC9B,MAAM,QAAQ,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,0DAA0D;YAC1D,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACf,SAAS;QACX,CAAC;QACD,qFAAqF;QACrF,8BAA8B;QAC9B,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC7B,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QAClC,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC;AACpC,CAAC"}
|
package/dist/runner/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export { runFile, runFileWithSource } from './run-file.js';
|
|
2
|
-
export { runProject } from './run-project.js';
|
|
2
|
+
export { runProject, resolveIgnores } from './run-project.js';
|
|
3
3
|
export { runRule } from './run-rule.js';
|
|
4
4
|
export { ruleSignature, rulesetSignature } from './ruleset-signature.js';
|
|
5
|
+
export { applyRuleConfig } from './apply-rule-config.js';
|
|
6
|
+
export type { ApplyRuleConfigResult } from './apply-rule-config.js';
|
|
5
7
|
export type { RunFileResult } from './run-file.js';
|
|
6
8
|
export type { RunProjectOptions } from './run-project.js';
|
|
7
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runner/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runner/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,YAAY,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AACpE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/runner/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { runFile, runFileWithSource } from './run-file.js';
|
|
2
|
-
export { runProject } from './run-project.js';
|
|
2
|
+
export { runProject, resolveIgnores } from './run-project.js';
|
|
3
3
|
export { runRule } from './run-rule.js';
|
|
4
4
|
export { ruleSignature, rulesetSignature } from './ruleset-signature.js';
|
|
5
|
+
export { applyRuleConfig } from './apply-rule-config.js';
|
|
5
6
|
//# sourceMappingURL=index.js.map
|
package/dist/runner/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runner/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runner/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-file.d.ts","sourceRoot":"","sources":["../../src/runner/run-file.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE5D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"run-file.d.ts","sourceRoot":"","sources":["../../src/runner/run-file.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE5D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAIhD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,SAAS,UAAU,EAAE,CAAC;CAC7C;AAED,wBAAsB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CAM9F;AAED,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,SAAS,IAAI,EAAE,GACrB,aAAa,CAsBf"}
|
package/dist/runner/run-file.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
2
|
import { detectLanguage, parseSource } from '@aicqtools/core';
|
|
3
3
|
import { runRule } from './run-rule.js';
|
|
4
|
+
import { applySuppressions, parseSuppressions } from './suppressions.js';
|
|
4
5
|
export async function runFile(filePath, rules) {
|
|
5
6
|
const language = detectLanguage(filePath);
|
|
6
7
|
if (!language)
|
|
@@ -20,7 +21,18 @@ export function runFileWithSource(filePath, source, language, rules) {
|
|
|
20
21
|
diagnostics.push(ruleFailedDiagnostic(filePath, rule.id, err));
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
|
-
|
|
24
|
+
// Apply inline-suppression directives last so they catch diagnostics from every rule
|
|
25
|
+
// (function rules, YAML pattern rules, and synthetic `@aicq/parse-failed`/rule-failed).
|
|
26
|
+
let suppressed = diagnostics;
|
|
27
|
+
try {
|
|
28
|
+
const suppressions = parseSuppressions(tree, source, language);
|
|
29
|
+
suppressed = applySuppressions(diagnostics, suppressions);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// Suppression parsing must never abort a run. If the tree shape surprises us,
|
|
33
|
+
// fall through with the unfiltered diagnostics.
|
|
34
|
+
}
|
|
35
|
+
return { filePath, language, diagnostics: suppressed };
|
|
24
36
|
}
|
|
25
37
|
function ruleFailedDiagnostic(filePath, ruleId, err) {
|
|
26
38
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-file.js","sourceRoot":"","sources":["../../src/runner/run-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9D,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"run-file.js","sourceRoot":"","sources":["../../src/runner/run-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9D,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAQzE,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,QAAgB,EAAE,KAAsB;IACpE,MAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IAC1C,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;IAEpE,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACjD,OAAO,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,QAAgB,EAChB,MAAc,EACd,QAAkB,EAClB,KAAsB;IAEtB,MAAM,IAAI,GAAG,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC3C,MAAM,WAAW,GAAiB,EAAE,CAAC;IACrC,MAAM,GAAG,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QAC3B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IACD,qFAAqF;IACrF,wFAAwF;IACxF,IAAI,UAAU,GAA0B,WAAW,CAAC;IACpD,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC/D,UAAU,GAAG,iBAAiB,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,8EAA8E;QAC9E,gDAAgD;IAClD,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;AACzD,CAAC;AAED,SAAS,oBAAoB,CAAC,QAAgB,EAAE,MAAc,EAAE,GAAY;IAC1E,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjE,OAAO;QACL,MAAM,EAAE,oBAAoB;QAC5B,QAAQ,EAAE,SAAS;QACnB,OAAO,EAAE,yBAAyB,MAAM,KAAK,OAAO,EAAE;QACtD,SAAS,EAAE,YAAY,MAAM,MAAM,OAAO,EAAE;QAC5C,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE;KACtE,CAAC;AACJ,CAAC"}
|
|
@@ -7,6 +7,18 @@ export interface RunProjectOptions {
|
|
|
7
7
|
readonly exclude: readonly string[];
|
|
8
8
|
readonly rules: readonly Rule[];
|
|
9
9
|
readonly cache?: FileCache;
|
|
10
|
+
/**
|
|
11
|
+
* When true, the file walker appends entries from the repo-root `.gitignore` to the effective
|
|
12
|
+
* exclude list. Unreadable / missing / malformed `.gitignore` is silently ignored (never throws).
|
|
13
|
+
* Defaults to false to keep behavior deterministic across projects.
|
|
14
|
+
*/
|
|
15
|
+
readonly respectGitignore?: boolean;
|
|
10
16
|
}
|
|
11
17
|
export declare function runProject(opts: RunProjectOptions): Promise<CheckResult>;
|
|
18
|
+
/**
|
|
19
|
+
* Build the final ignore list for `fast-glob`. Always starts from the configured `exclude`;
|
|
20
|
+
* when `respectGitignore` is true, parses the root `.gitignore` (best-effort) and appends its
|
|
21
|
+
* entries. Negation (`!pattern`) and trailing-slash directory entries are honored.
|
|
22
|
+
*/
|
|
23
|
+
export declare function resolveIgnores(cwd: string, exclude: readonly string[], respectGitignore: boolean): Promise<string[]>;
|
|
12
24
|
//# sourceMappingURL=run-project.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-project.d.ts","sourceRoot":"","sources":["../../src/runner/run-project.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run-project.d.ts","sourceRoot":"","sources":["../../src/runner/run-project.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAc,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAwB,MAAM,iBAAiB,CAAC;AAClE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAIhD,MAAM,WAAW,iBAAiB;IAChC,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;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CACrC;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,WAAW,CAAC,CAmD9E;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,gBAAgB,EAAE,OAAO,GACxB,OAAO,CAAC,MAAM,EAAE,CAAC,CAyBnB"}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import fastGlob from 'fast-glob';
|
|
2
|
-
import { stat } from 'node:fs/promises';
|
|
2
|
+
import { readFile, stat } from 'node:fs/promises';
|
|
3
|
+
import { resolve } from 'node:path';
|
|
3
4
|
import { FileCache, hashRulesetSignature } from '@aicqtools/core';
|
|
4
5
|
import { runFile } from './run-file.js';
|
|
5
6
|
import { rulesetSignature } from './ruleset-signature.js';
|
|
6
7
|
export async function runProject(opts) {
|
|
7
8
|
const start = Date.now();
|
|
9
|
+
const ignore = await resolveIgnores(opts.cwd, opts.exclude, opts.respectGitignore ?? false);
|
|
8
10
|
const files = await fastGlob([...opts.include], {
|
|
9
11
|
cwd: opts.cwd,
|
|
10
|
-
ignore
|
|
12
|
+
ignore,
|
|
11
13
|
absolute: true,
|
|
12
14
|
onlyFiles: true,
|
|
13
15
|
dot: false,
|
|
@@ -50,6 +52,42 @@ export async function runProject(opts) {
|
|
|
50
52
|
durationMs: Date.now() - start,
|
|
51
53
|
};
|
|
52
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Build the final ignore list for `fast-glob`. Always starts from the configured `exclude`;
|
|
57
|
+
* when `respectGitignore` is true, parses the root `.gitignore` (best-effort) and appends its
|
|
58
|
+
* entries. Negation (`!pattern`) and trailing-slash directory entries are honored.
|
|
59
|
+
*/
|
|
60
|
+
export async function resolveIgnores(cwd, exclude, respectGitignore) {
|
|
61
|
+
const ignores = [...exclude];
|
|
62
|
+
if (!respectGitignore)
|
|
63
|
+
return ignores;
|
|
64
|
+
try {
|
|
65
|
+
const gitignorePath = resolve(cwd, '.gitignore');
|
|
66
|
+
const st = await stat(gitignorePath);
|
|
67
|
+
if (!st.isFile())
|
|
68
|
+
return ignores;
|
|
69
|
+
const text = await readFile(gitignorePath, 'utf-8');
|
|
70
|
+
for (const raw of text.split(/\r?\n/)) {
|
|
71
|
+
const line = raw.trim();
|
|
72
|
+
if (line.length === 0 || line.startsWith('#'))
|
|
73
|
+
continue;
|
|
74
|
+
// We intentionally don't try to fully emulate gitignore semantics — just translate the
|
|
75
|
+
// common shapes into fast-glob globs. Anything we can't reason about we leave as-is.
|
|
76
|
+
const negated = line.startsWith('!');
|
|
77
|
+
const body = (negated ? line.slice(1) : line).trim();
|
|
78
|
+
if (body.length === 0)
|
|
79
|
+
continue;
|
|
80
|
+
// Directory entry like `out/` → `**/out/**`
|
|
81
|
+
const cleaned = body.replace(/\/$/, '');
|
|
82
|
+
const glob = cleaned.includes('/') ? cleaned : `**/${cleaned}/**`;
|
|
83
|
+
ignores.push(negated ? `!${glob}` : glob);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
// `.gitignore` missing / unreadable / not a regular file — fall through with static excludes.
|
|
88
|
+
}
|
|
89
|
+
return ignores;
|
|
90
|
+
}
|
|
53
91
|
function parseFailedDiagnostic(file, err) {
|
|
54
92
|
const message = err instanceof Error ? err.message : String(err);
|
|
55
93
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-project.js","sourceRoot":"","sources":["../../src/runner/run-project.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"run-project.js","sourceRoot":"","sources":["../../src/runner/run-project.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-rule.d.ts","sourceRoot":"","sources":["../../src/runner/run-rule.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"run-rule.d.ts","sourceRoot":"","sources":["../../src/runner/run-rule.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAGjC,OAAO,KAAK,EAAE,IAAI,EAA6B,MAAM,qBAAqB,CAAC;AAE3E,OAAO,EAAmB,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAyChE,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,IAAI,CAK5E"}
|