@eddacraft/anvil-core 0.1.0
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/LICENSE +14 -0
- package/dist/antipattern/index.d.ts +11 -0
- package/dist/antipattern/index.d.ts.map +1 -0
- package/dist/antipattern/index.js +31 -0
- package/dist/antipattern/patterns-css.d.ts +17 -0
- package/dist/antipattern/patterns-css.d.ts.map +1 -0
- package/dist/antipattern/patterns-css.js +72 -0
- package/dist/antipattern/patterns-html.d.ts +21 -0
- package/dist/antipattern/patterns-html.d.ts.map +1 -0
- package/dist/antipattern/patterns-html.js +139 -0
- package/dist/antipattern/patterns.d.ts +72 -0
- package/dist/antipattern/patterns.d.ts.map +1 -0
- package/dist/antipattern/patterns.js +301 -0
- package/dist/antipattern/scanner.d.ts +32 -0
- package/dist/antipattern/scanner.d.ts.map +1 -0
- package/dist/antipattern/scanner.js +89 -0
- package/dist/antipattern/types.d.ts +318 -0
- package/dist/antipattern/types.d.ts.map +1 -0
- package/dist/antipattern/types.js +278 -0
- package/dist/architecture/analyzer.d.ts +123 -0
- package/dist/architecture/analyzer.d.ts.map +1 -0
- package/dist/architecture/analyzer.js +321 -0
- package/dist/architecture/baseline.d.ts +112 -0
- package/dist/architecture/baseline.d.ts.map +1 -0
- package/dist/architecture/baseline.js +245 -0
- package/dist/architecture/compiler.d.ts +24 -0
- package/dist/architecture/compiler.d.ts.map +1 -0
- package/dist/architecture/compiler.js +57 -0
- package/dist/architecture/context.d.ts +129 -0
- package/dist/architecture/context.d.ts.map +1 -0
- package/dist/architecture/context.js +116 -0
- package/dist/architecture/dc-generator.d.ts +9 -0
- package/dist/architecture/dc-generator.d.ts.map +1 -0
- package/dist/architecture/dc-generator.js +220 -0
- package/dist/architecture/definition-schema.d.ts +128 -0
- package/dist/architecture/definition-schema.d.ts.map +1 -0
- package/dist/architecture/definition-schema.js +94 -0
- package/dist/architecture/edge-detector-html.d.ts +6 -0
- package/dist/architecture/edge-detector-html.d.ts.map +1 -0
- package/dist/architecture/edge-detector-html.js +5 -0
- package/dist/architecture/edge-detector-web.d.ts +32 -0
- package/dist/architecture/edge-detector-web.d.ts.map +1 -0
- package/dist/architecture/edge-detector-web.js +133 -0
- package/dist/architecture/edge-detector.d.ts +116 -0
- package/dist/architecture/edge-detector.d.ts.map +1 -0
- package/dist/architecture/edge-detector.js +229 -0
- package/dist/architecture/entry-detector.d.ts +44 -0
- package/dist/architecture/entry-detector.d.ts.map +1 -0
- package/dist/architecture/entry-detector.js +263 -0
- package/dist/architecture/index.d.ts +21 -0
- package/dist/architecture/index.d.ts.map +1 -0
- package/dist/architecture/index.js +48 -0
- package/dist/architecture/layer-detector.d.ts +60 -0
- package/dist/architecture/layer-detector.d.ts.map +1 -0
- package/dist/architecture/layer-detector.js +331 -0
- package/dist/architecture/rego-generator.d.ts +25 -0
- package/dist/architecture/rego-generator.d.ts.map +1 -0
- package/dist/architecture/rego-generator.js +229 -0
- package/dist/architecture/templates/index.d.ts +39 -0
- package/dist/architecture/templates/index.d.ts.map +1 -0
- package/dist/architecture/templates/index.js +124 -0
- package/dist/architecture/types.d.ts +280 -0
- package/dist/architecture/types.d.ts.map +1 -0
- package/dist/architecture/types.js +269 -0
- package/dist/architecture/yaml-parser.d.ts +13 -0
- package/dist/architecture/yaml-parser.d.ts.map +1 -0
- package/dist/architecture/yaml-parser.js +234 -0
- package/dist/config/constants.d.ts +9 -0
- package/dist/config/constants.d.ts.map +1 -0
- package/dist/config/constants.js +20 -0
- package/dist/config/index.d.ts +9 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +8 -0
- package/dist/config/loader.d.ts +41 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +76 -0
- package/dist/config/nudge-config.d.ts +35 -0
- package/dist/config/nudge-config.d.ts.map +1 -0
- package/dist/config/nudge-config.js +34 -0
- package/dist/config/types.d.ts +30 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +4 -0
- package/dist/contracts/index.d.ts +14 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +13 -0
- package/dist/contracts/schemas/aps.schema.d.ts +269 -0
- package/dist/contracts/schemas/aps.schema.d.ts.map +1 -0
- package/dist/contracts/schemas/aps.schema.js +183 -0
- package/dist/contracts/schemas/index.d.ts +12 -0
- package/dist/contracts/schemas/index.d.ts.map +1 -0
- package/dist/contracts/schemas/index.js +14 -0
- package/dist/contracts/schemas/json-schema.d.ts +14 -0
- package/dist/contracts/schemas/json-schema.d.ts.map +1 -0
- package/dist/contracts/schemas/json-schema.js +31 -0
- package/dist/contracts/schemas/warning.schema.d.ts +171 -0
- package/dist/contracts/schemas/warning.schema.d.ts.map +1 -0
- package/dist/contracts/schemas/warning.schema.js +123 -0
- package/dist/contracts/types/gate.types.d.ts +194 -0
- package/dist/contracts/types/gate.types.d.ts.map +1 -0
- package/dist/contracts/types/gate.types.js +19 -0
- package/dist/contracts/types/index.d.ts +9 -0
- package/dist/contracts/types/index.d.ts.map +1 -0
- package/dist/contracts/types/index.js +8 -0
- package/dist/crypto/hash.d.ts +47 -0
- package/dist/crypto/hash.d.ts.map +1 -0
- package/dist/crypto/hash.js +110 -0
- package/dist/crypto/index.d.ts +7 -0
- package/dist/crypto/index.d.ts.map +1 -0
- package/dist/crypto/index.js +6 -0
- package/dist/drift/index.d.ts +6 -0
- package/dist/drift/index.d.ts.map +1 -0
- package/dist/drift/index.js +5 -0
- package/dist/drift/report-generator.d.ts +21 -0
- package/dist/drift/report-generator.d.ts.map +1 -0
- package/dist/drift/report-generator.js +240 -0
- package/dist/drift/snapshot-capture.d.ts +26 -0
- package/dist/drift/snapshot-capture.d.ts.map +1 -0
- package/dist/drift/snapshot-capture.js +195 -0
- package/dist/drift/snapshot-compare.d.ts +50 -0
- package/dist/drift/snapshot-compare.d.ts.map +1 -0
- package/dist/drift/snapshot-compare.js +142 -0
- package/dist/drift/snapshot-schema.d.ts +197 -0
- package/dist/drift/snapshot-schema.d.ts.map +1 -0
- package/dist/drift/snapshot-schema.js +193 -0
- package/dist/drift/snapshot-storage.d.ts +25 -0
- package/dist/drift/snapshot-storage.d.ts.map +1 -0
- package/dist/drift/snapshot-storage.js +179 -0
- package/dist/explain/antipattern-explainer.d.ts +4 -0
- package/dist/explain/antipattern-explainer.d.ts.map +1 -0
- package/dist/explain/antipattern-explainer.js +196 -0
- package/dist/explain/boundary-explainer.d.ts +5 -0
- package/dist/explain/boundary-explainer.d.ts.map +1 -0
- package/dist/explain/boundary-explainer.js +261 -0
- package/dist/explain/explain-service.d.ts +19 -0
- package/dist/explain/explain-service.d.ts.map +1 -0
- package/dist/explain/explain-service.js +106 -0
- package/dist/explain/index.d.ts +7 -0
- package/dist/explain/index.d.ts.map +1 -0
- package/dist/explain/index.js +5 -0
- package/dist/explain/template-loader.d.ts +9 -0
- package/dist/explain/template-loader.d.ts.map +1 -0
- package/dist/explain/template-loader.js +51 -0
- package/dist/explain/types.d.ts +46 -0
- package/dist/explain/types.d.ts.map +1 -0
- package/dist/explain/types.js +31 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/provenance/collector.d.ts +86 -0
- package/dist/provenance/collector.d.ts.map +1 -0
- package/dist/provenance/collector.js +425 -0
- package/dist/provenance/git-ai-standard/git-notes.d.ts +85 -0
- package/dist/provenance/git-ai-standard/git-notes.d.ts.map +1 -0
- package/dist/provenance/git-ai-standard/git-notes.js +292 -0
- package/dist/provenance/git-ai-standard/index.d.ts +44 -0
- package/dist/provenance/git-ai-standard/index.d.ts.map +1 -0
- package/dist/provenance/git-ai-standard/index.js +47 -0
- package/dist/provenance/git-ai-standard/serializer.d.ts +54 -0
- package/dist/provenance/git-ai-standard/serializer.d.ts.map +1 -0
- package/dist/provenance/git-ai-standard/serializer.js +224 -0
- package/dist/provenance/git-ai-standard/session.d.ts +51 -0
- package/dist/provenance/git-ai-standard/session.d.ts.map +1 -0
- package/dist/provenance/git-ai-standard/session.js +118 -0
- package/dist/provenance/git-ai-standard/types.d.ts +173 -0
- package/dist/provenance/git-ai-standard/types.d.ts.map +1 -0
- package/dist/provenance/git-ai-standard/types.js +109 -0
- package/dist/provenance/index.d.ts +5 -0
- package/dist/provenance/index.d.ts.map +1 -0
- package/dist/provenance/index.js +6 -0
- package/dist/provenance/store.d.ts +83 -0
- package/dist/provenance/store.d.ts.map +1 -0
- package/dist/provenance/store.js +248 -0
- package/dist/provenance/types.d.ts +160 -0
- package/dist/provenance/types.d.ts.map +1 -0
- package/dist/provenance/types.js +112 -0
- package/dist/suppression/index.d.ts +4 -0
- package/dist/suppression/index.d.ts.map +1 -0
- package/dist/suppression/index.js +3 -0
- package/dist/suppression/parser.d.ts +31 -0
- package/dist/suppression/parser.d.ts.map +1 -0
- package/dist/suppression/parser.js +219 -0
- package/dist/suppression/service.d.ts +29 -0
- package/dist/suppression/service.d.ts.map +1 -0
- package/dist/suppression/service.js +132 -0
- package/dist/suppression/store.d.ts +61 -0
- package/dist/suppression/store.d.ts.map +1 -0
- package/dist/suppression/store.js +169 -0
- package/dist/utils/debug.d.ts +48 -0
- package/dist/utils/debug.d.ts.map +1 -0
- package/dist/utils/debug.js +100 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/path-safety.d.ts +21 -0
- package/dist/utils/path-safety.d.ts.map +1 -0
- package/dist/utils/path-safety.js +49 -0
- package/dist/utils/severity.d.ts +37 -0
- package/dist/utils/severity.d.ts.map +1 -0
- package/dist/utils/severity.js +22 -0
- package/dist/validation/aps-validator.d.ts +66 -0
- package/dist/validation/aps-validator.d.ts.map +1 -0
- package/dist/validation/aps-validator.js +173 -0
- package/dist/validation/errors.d.ts +52 -0
- package/dist/validation/errors.d.ts.map +1 -0
- package/dist/validation/errors.js +115 -0
- package/dist/validation/index.d.ts +8 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +13 -0
- package/dist/warnings/index.d.ts +2 -0
- package/dist/warnings/index.d.ts.map +1 -0
- package/dist/warnings/index.js +1 -0
- package/dist/warnings/warning-id.d.ts +180 -0
- package/dist/warnings/warning-id.d.ts.map +1 -0
- package/dist/warnings/warning-id.js +257 -0
- package/package.json +79 -0
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anti-pattern detection types
|
|
3
|
+
*
|
|
4
|
+
* Defines the Warning schema and related types for anti-pattern detection
|
|
5
|
+
* and architecture boundary violations. Follows Zod-first approach per ADR-0001.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
/**
|
|
9
|
+
* Source code location for a warning
|
|
10
|
+
*/
|
|
11
|
+
export declare const LocationSchema: z.ZodObject<{
|
|
12
|
+
file: z.ZodString;
|
|
13
|
+
line: z.ZodNumber;
|
|
14
|
+
column: z.ZodOptional<z.ZodNumber>;
|
|
15
|
+
endLine: z.ZodOptional<z.ZodNumber>;
|
|
16
|
+
endColumn: z.ZodOptional<z.ZodNumber>;
|
|
17
|
+
}, z.core.$strip>;
|
|
18
|
+
export type Location = z.infer<typeof LocationSchema>;
|
|
19
|
+
/**
|
|
20
|
+
* Drift context for boundary violations
|
|
21
|
+
*/
|
|
22
|
+
export declare const DriftSchema: z.ZodObject<{
|
|
23
|
+
isNew: z.ZodBoolean;
|
|
24
|
+
existingCount: z.ZodOptional<z.ZodNumber>;
|
|
25
|
+
baselineId: z.ZodOptional<z.ZodString>;
|
|
26
|
+
}, z.core.$strip>;
|
|
27
|
+
export type Drift = z.infer<typeof DriftSchema>;
|
|
28
|
+
/**
|
|
29
|
+
* Suppression metadata when a warning is suppressed via @anvil-ignore
|
|
30
|
+
*/
|
|
31
|
+
export declare const SuppressionSchema: z.ZodObject<{
|
|
32
|
+
reason: z.ZodString;
|
|
33
|
+
author: z.ZodOptional<z.ZodString>;
|
|
34
|
+
timestamp: z.ZodOptional<z.ZodString>;
|
|
35
|
+
scope: z.ZodEnum<{
|
|
36
|
+
file: "file";
|
|
37
|
+
line: "line";
|
|
38
|
+
statement: "statement";
|
|
39
|
+
import: "import";
|
|
40
|
+
}>;
|
|
41
|
+
}, z.core.$strip>;
|
|
42
|
+
export type Suppression = z.infer<typeof SuppressionSchema>;
|
|
43
|
+
/**
|
|
44
|
+
* Warning categories
|
|
45
|
+
*/
|
|
46
|
+
export declare const WarningCategorySchema: z.ZodEnum<{
|
|
47
|
+
"anti-pattern": "anti-pattern";
|
|
48
|
+
boundary: "boundary";
|
|
49
|
+
architecture: "architecture";
|
|
50
|
+
}>;
|
|
51
|
+
export type WarningCategory = z.infer<typeof WarningCategorySchema>;
|
|
52
|
+
/**
|
|
53
|
+
* Warning severity levels
|
|
54
|
+
*/
|
|
55
|
+
export declare const WarningSeveritySchema: z.ZodEnum<{
|
|
56
|
+
warning: "warning";
|
|
57
|
+
error: "error";
|
|
58
|
+
info: "info";
|
|
59
|
+
}>;
|
|
60
|
+
export type WarningSeverity = z.infer<typeof WarningSeveritySchema>;
|
|
61
|
+
/**
|
|
62
|
+
* Confidence levels for detection
|
|
63
|
+
*/
|
|
64
|
+
export declare const ConfidenceSchema: z.ZodEnum<{
|
|
65
|
+
high: "high";
|
|
66
|
+
medium: "medium";
|
|
67
|
+
low: "low";
|
|
68
|
+
}>;
|
|
69
|
+
export type Confidence = z.infer<typeof ConfidenceSchema>;
|
|
70
|
+
/**
|
|
71
|
+
* Core Warning schema - the primary output of anti-pattern and boundary detection
|
|
72
|
+
*/
|
|
73
|
+
export declare const WarningSchema: z.ZodObject<{
|
|
74
|
+
id: z.ZodString;
|
|
75
|
+
fingerprint: z.ZodOptional<z.ZodString>;
|
|
76
|
+
category: z.ZodEnum<{
|
|
77
|
+
"anti-pattern": "anti-pattern";
|
|
78
|
+
boundary: "boundary";
|
|
79
|
+
architecture: "architecture";
|
|
80
|
+
}>;
|
|
81
|
+
severity: z.ZodEnum<{
|
|
82
|
+
warning: "warning";
|
|
83
|
+
error: "error";
|
|
84
|
+
info: "info";
|
|
85
|
+
}>;
|
|
86
|
+
confidence: z.ZodEnum<{
|
|
87
|
+
high: "high";
|
|
88
|
+
medium: "medium";
|
|
89
|
+
low: "low";
|
|
90
|
+
}>;
|
|
91
|
+
title: z.ZodString;
|
|
92
|
+
message: z.ZodString;
|
|
93
|
+
explanation: z.ZodString;
|
|
94
|
+
suggestion: z.ZodString;
|
|
95
|
+
nudge: z.ZodOptional<z.ZodString>;
|
|
96
|
+
location: z.ZodObject<{
|
|
97
|
+
file: z.ZodString;
|
|
98
|
+
line: z.ZodNumber;
|
|
99
|
+
column: z.ZodOptional<z.ZodNumber>;
|
|
100
|
+
endLine: z.ZodOptional<z.ZodNumber>;
|
|
101
|
+
endColumn: z.ZodOptional<z.ZodNumber>;
|
|
102
|
+
}, z.core.$strip>;
|
|
103
|
+
pattern: z.ZodOptional<z.ZodString>;
|
|
104
|
+
drift: z.ZodOptional<z.ZodObject<{
|
|
105
|
+
isNew: z.ZodBoolean;
|
|
106
|
+
existingCount: z.ZodOptional<z.ZodNumber>;
|
|
107
|
+
baselineId: z.ZodOptional<z.ZodString>;
|
|
108
|
+
}, z.core.$strip>>;
|
|
109
|
+
suppressed: z.ZodOptional<z.ZodObject<{
|
|
110
|
+
reason: z.ZodString;
|
|
111
|
+
author: z.ZodOptional<z.ZodString>;
|
|
112
|
+
timestamp: z.ZodOptional<z.ZodString>;
|
|
113
|
+
scope: z.ZodEnum<{
|
|
114
|
+
file: "file";
|
|
115
|
+
line: "line";
|
|
116
|
+
statement: "statement";
|
|
117
|
+
import: "import";
|
|
118
|
+
}>;
|
|
119
|
+
}, z.core.$strip>>;
|
|
120
|
+
}, z.core.$strip>;
|
|
121
|
+
export type Warning = z.infer<typeof WarningSchema>;
|
|
122
|
+
/**
|
|
123
|
+
* Regex-based detection configuration
|
|
124
|
+
*/
|
|
125
|
+
export declare const RegexDetectionConfigSchema: z.ZodObject<{
|
|
126
|
+
type: z.ZodLiteral<"regex">;
|
|
127
|
+
pattern: z.ZodString;
|
|
128
|
+
}, z.core.$strip>;
|
|
129
|
+
/**
|
|
130
|
+
* AST-based detection configuration
|
|
131
|
+
*/
|
|
132
|
+
export declare const AstDetectionConfigSchema: z.ZodObject<{
|
|
133
|
+
type: z.ZodLiteral<"ast">;
|
|
134
|
+
astQuery: z.ZodString;
|
|
135
|
+
}, z.core.$strip>;
|
|
136
|
+
/**
|
|
137
|
+
* Detection method configuration - discriminated union ensures
|
|
138
|
+
* regex type requires pattern, ast type requires astQuery
|
|
139
|
+
*/
|
|
140
|
+
export declare const DetectionConfigSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
141
|
+
type: z.ZodLiteral<"regex">;
|
|
142
|
+
pattern: z.ZodString;
|
|
143
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
144
|
+
type: z.ZodLiteral<"ast">;
|
|
145
|
+
astQuery: z.ZodString;
|
|
146
|
+
}, z.core.$strip>], "type">;
|
|
147
|
+
export type DetectionConfig = z.infer<typeof DetectionConfigSchema>;
|
|
148
|
+
export type RegexDetectionConfig = z.infer<typeof RegexDetectionConfigSchema>;
|
|
149
|
+
export type AstDetectionConfig = z.infer<typeof AstDetectionConfigSchema>;
|
|
150
|
+
/**
|
|
151
|
+
* Anti-pattern definition - defines a detectable pattern
|
|
152
|
+
*/
|
|
153
|
+
export declare const AntiPatternSchema: z.ZodObject<{
|
|
154
|
+
id: z.ZodString;
|
|
155
|
+
name: z.ZodString;
|
|
156
|
+
category: z.ZodEnum<{
|
|
157
|
+
"escape-hatch": "escape-hatch";
|
|
158
|
+
"error-handling": "error-handling";
|
|
159
|
+
"code-quality": "code-quality";
|
|
160
|
+
"type-safety": "type-safety";
|
|
161
|
+
html: "html";
|
|
162
|
+
css: "css";
|
|
163
|
+
}>;
|
|
164
|
+
severity: z.ZodEnum<{
|
|
165
|
+
warning: "warning";
|
|
166
|
+
error: "error";
|
|
167
|
+
info: "info";
|
|
168
|
+
}>;
|
|
169
|
+
confidence: z.ZodEnum<{
|
|
170
|
+
high: "high";
|
|
171
|
+
medium: "medium";
|
|
172
|
+
low: "low";
|
|
173
|
+
}>;
|
|
174
|
+
detection: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
175
|
+
type: z.ZodLiteral<"regex">;
|
|
176
|
+
pattern: z.ZodString;
|
|
177
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
178
|
+
type: z.ZodLiteral<"ast">;
|
|
179
|
+
astQuery: z.ZodString;
|
|
180
|
+
}, z.core.$strip>], "type">;
|
|
181
|
+
title: z.ZodString;
|
|
182
|
+
explanation: z.ZodString;
|
|
183
|
+
suggestion: z.ZodString;
|
|
184
|
+
nudge: z.ZodOptional<z.ZodString>;
|
|
185
|
+
fileExtensions: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
186
|
+
allFileTypes: z.ZodOptional<z.ZodBoolean>;
|
|
187
|
+
allowlist: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
188
|
+
threshold: z.ZodOptional<z.ZodNumber>;
|
|
189
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
190
|
+
optIn: z.ZodDefault<z.ZodBoolean>;
|
|
191
|
+
documentation: z.ZodOptional<z.ZodString>;
|
|
192
|
+
}, z.core.$strip>;
|
|
193
|
+
export type AntiPattern = z.infer<typeof AntiPatternSchema>;
|
|
194
|
+
/**
|
|
195
|
+
* Collection of warnings from a check run - embeds in GateResult.details
|
|
196
|
+
*/
|
|
197
|
+
export declare const WarningResultSchema: z.ZodObject<{
|
|
198
|
+
warnings: z.ZodArray<z.ZodObject<{
|
|
199
|
+
id: z.ZodString;
|
|
200
|
+
fingerprint: z.ZodOptional<z.ZodString>;
|
|
201
|
+
category: z.ZodEnum<{
|
|
202
|
+
"anti-pattern": "anti-pattern";
|
|
203
|
+
boundary: "boundary";
|
|
204
|
+
architecture: "architecture";
|
|
205
|
+
}>;
|
|
206
|
+
severity: z.ZodEnum<{
|
|
207
|
+
warning: "warning";
|
|
208
|
+
error: "error";
|
|
209
|
+
info: "info";
|
|
210
|
+
}>;
|
|
211
|
+
confidence: z.ZodEnum<{
|
|
212
|
+
high: "high";
|
|
213
|
+
medium: "medium";
|
|
214
|
+
low: "low";
|
|
215
|
+
}>;
|
|
216
|
+
title: z.ZodString;
|
|
217
|
+
message: z.ZodString;
|
|
218
|
+
explanation: z.ZodString;
|
|
219
|
+
suggestion: z.ZodString;
|
|
220
|
+
nudge: z.ZodOptional<z.ZodString>;
|
|
221
|
+
location: z.ZodObject<{
|
|
222
|
+
file: z.ZodString;
|
|
223
|
+
line: z.ZodNumber;
|
|
224
|
+
column: z.ZodOptional<z.ZodNumber>;
|
|
225
|
+
endLine: z.ZodOptional<z.ZodNumber>;
|
|
226
|
+
endColumn: z.ZodOptional<z.ZodNumber>;
|
|
227
|
+
}, z.core.$strip>;
|
|
228
|
+
pattern: z.ZodOptional<z.ZodString>;
|
|
229
|
+
drift: z.ZodOptional<z.ZodObject<{
|
|
230
|
+
isNew: z.ZodBoolean;
|
|
231
|
+
existingCount: z.ZodOptional<z.ZodNumber>;
|
|
232
|
+
baselineId: z.ZodOptional<z.ZodString>;
|
|
233
|
+
}, z.core.$strip>>;
|
|
234
|
+
suppressed: z.ZodOptional<z.ZodObject<{
|
|
235
|
+
reason: z.ZodString;
|
|
236
|
+
author: z.ZodOptional<z.ZodString>;
|
|
237
|
+
timestamp: z.ZodOptional<z.ZodString>;
|
|
238
|
+
scope: z.ZodEnum<{
|
|
239
|
+
file: "file";
|
|
240
|
+
line: "line";
|
|
241
|
+
statement: "statement";
|
|
242
|
+
import: "import";
|
|
243
|
+
}>;
|
|
244
|
+
}, z.core.$strip>>;
|
|
245
|
+
}, z.core.$strip>>;
|
|
246
|
+
summary: z.ZodObject<{
|
|
247
|
+
total: z.ZodNumber;
|
|
248
|
+
errors: z.ZodNumber;
|
|
249
|
+
warnings: z.ZodNumber;
|
|
250
|
+
info: z.ZodNumber;
|
|
251
|
+
suppressed: z.ZodNumber;
|
|
252
|
+
}, z.core.$strip>;
|
|
253
|
+
patterns_checked: z.ZodArray<z.ZodString>;
|
|
254
|
+
}, z.core.$strip>;
|
|
255
|
+
export type WarningResult = z.infer<typeof WarningResultSchema>;
|
|
256
|
+
/**
|
|
257
|
+
* Suppression record for provenance tracking
|
|
258
|
+
*/
|
|
259
|
+
export declare const SuppressionRecordSchema: z.ZodObject<{
|
|
260
|
+
id: z.ZodString;
|
|
261
|
+
pattern_id: z.ZodString;
|
|
262
|
+
file: z.ZodString;
|
|
263
|
+
line: z.ZodNumber;
|
|
264
|
+
reason: z.ZodString;
|
|
265
|
+
author: z.ZodOptional<z.ZodString>;
|
|
266
|
+
timestamp: z.ZodString;
|
|
267
|
+
commit: z.ZodOptional<z.ZodString>;
|
|
268
|
+
scope: z.ZodEnum<{
|
|
269
|
+
file: "file";
|
|
270
|
+
line: "line";
|
|
271
|
+
statement: "statement";
|
|
272
|
+
import: "import";
|
|
273
|
+
}>;
|
|
274
|
+
expires_at: z.ZodOptional<z.ZodString>;
|
|
275
|
+
}, z.core.$strip>;
|
|
276
|
+
export type SuppressionRecord = z.infer<typeof SuppressionRecordSchema>;
|
|
277
|
+
/**
|
|
278
|
+
* Create a warning fingerprint for deduplication
|
|
279
|
+
*/
|
|
280
|
+
export declare function createWarningFingerprint(warning: Omit<Warning, 'fingerprint'>): string;
|
|
281
|
+
/**
|
|
282
|
+
* Check if a warning should be considered an error for gate purposes
|
|
283
|
+
*/
|
|
284
|
+
export declare function isBlockingWarning(warning: Warning): boolean;
|
|
285
|
+
/**
|
|
286
|
+
* Warning summary type matching WarningResultSchema.summary
|
|
287
|
+
*/
|
|
288
|
+
export interface WarningSummary {
|
|
289
|
+
total: number;
|
|
290
|
+
errors: number;
|
|
291
|
+
warnings: number;
|
|
292
|
+
info: number;
|
|
293
|
+
suppressed: number;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Count warnings by severity, including total count.
|
|
297
|
+
* Note: A warning can be both suppressed AND have a severity,
|
|
298
|
+
* so suppressed warnings are counted separately and not in their severity bucket.
|
|
299
|
+
*/
|
|
300
|
+
export declare function countBySeverity(warnings: Warning[]): WarningSummary;
|
|
301
|
+
/**
|
|
302
|
+
* Create a complete WarningResult summary from a list of warnings.
|
|
303
|
+
* Ensures consistency between warnings array and summary counts.
|
|
304
|
+
*
|
|
305
|
+
* @param warnings - Array of warnings
|
|
306
|
+
* @param patternsChecked - Array of pattern IDs that were checked
|
|
307
|
+
* @returns Complete WarningResult object
|
|
308
|
+
*/
|
|
309
|
+
export declare function createWarningResult(warnings: Warning[], patternsChecked: string[]): WarningResult;
|
|
310
|
+
/**
|
|
311
|
+
* Validate that a WarningResult's summary matches its warnings array.
|
|
312
|
+
* Useful for catching inconsistencies in manually constructed results.
|
|
313
|
+
*
|
|
314
|
+
* @param result - WarningResult to validate
|
|
315
|
+
* @returns true if summary matches warnings, false otherwise
|
|
316
|
+
*/
|
|
317
|
+
export declare function validateWarningResultConsistency(result: WarningResult): boolean;
|
|
318
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/antipattern/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anti-pattern detection types
|
|
3
|
+
*
|
|
4
|
+
* Defines the Warning schema and related types for anti-pattern detection
|
|
5
|
+
* and architecture boundary violations. Follows Zod-first approach per ADR-0001.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
// =============================================================================
|
|
9
|
+
// Location Schema
|
|
10
|
+
// =============================================================================
|
|
11
|
+
/**
|
|
12
|
+
* Source code location for a warning
|
|
13
|
+
*/
|
|
14
|
+
export const LocationSchema = z.object({
|
|
15
|
+
file: z.string().describe('File path relative to workspace root'),
|
|
16
|
+
line: z.number().int().positive().describe('Line number (1-based)'),
|
|
17
|
+
column: z.number().int().nonnegative().optional().describe('Column number (0-based)'),
|
|
18
|
+
endLine: z.number().int().positive().optional().describe('End line for multi-line spans'),
|
|
19
|
+
endColumn: z.number().int().nonnegative().optional().describe('End column for multi-line spans'),
|
|
20
|
+
});
|
|
21
|
+
// =============================================================================
|
|
22
|
+
// Drift Schema
|
|
23
|
+
// =============================================================================
|
|
24
|
+
/**
|
|
25
|
+
* Drift context for boundary violations
|
|
26
|
+
*/
|
|
27
|
+
export const DriftSchema = z.object({
|
|
28
|
+
isNew: z.boolean().describe('Whether this is a NEW violation vs existing'),
|
|
29
|
+
existingCount: z
|
|
30
|
+
.number()
|
|
31
|
+
.int()
|
|
32
|
+
.nonnegative()
|
|
33
|
+
.optional()
|
|
34
|
+
.describe('Number of existing violations of this type'),
|
|
35
|
+
baselineId: z.string().optional().describe('ID of the baseline violation if existing'),
|
|
36
|
+
});
|
|
37
|
+
// =============================================================================
|
|
38
|
+
// Suppression Schema
|
|
39
|
+
// =============================================================================
|
|
40
|
+
/**
|
|
41
|
+
* Suppression metadata when a warning is suppressed via @anvil-ignore
|
|
42
|
+
*/
|
|
43
|
+
export const SuppressionSchema = z.object({
|
|
44
|
+
reason: z.string().min(1).describe('Human-provided reason for suppression'),
|
|
45
|
+
author: z.string().optional().describe('Author who added the suppression (e.g., @jane)'),
|
|
46
|
+
timestamp: z.string().datetime().optional().describe('When the suppression was added'),
|
|
47
|
+
scope: z.enum(['statement', 'import', 'file', 'line']).describe('Scope of the suppression'),
|
|
48
|
+
});
|
|
49
|
+
// =============================================================================
|
|
50
|
+
// Warning Schema (Core)
|
|
51
|
+
// =============================================================================
|
|
52
|
+
/**
|
|
53
|
+
* Warning categories
|
|
54
|
+
*/
|
|
55
|
+
export const WarningCategorySchema = z.enum(['anti-pattern', 'boundary', 'architecture']);
|
|
56
|
+
/**
|
|
57
|
+
* Warning severity levels
|
|
58
|
+
*/
|
|
59
|
+
export const WarningSeveritySchema = z.enum(['error', 'warning', 'info']);
|
|
60
|
+
/**
|
|
61
|
+
* Confidence levels for detection
|
|
62
|
+
*/
|
|
63
|
+
export const ConfidenceSchema = z.enum(['high', 'medium', 'low']);
|
|
64
|
+
/**
|
|
65
|
+
* Core Warning schema - the primary output of anti-pattern and boundary detection
|
|
66
|
+
*/
|
|
67
|
+
export const WarningSchema = z.object({
|
|
68
|
+
// Identification
|
|
69
|
+
id: z
|
|
70
|
+
.string()
|
|
71
|
+
.regex(/^(AP|ARCH|BOUND)-\d{3}$/)
|
|
72
|
+
.describe('Warning ID (e.g., AP-001, ARCH-001, BOUND-001)'),
|
|
73
|
+
fingerprint: z
|
|
74
|
+
.string()
|
|
75
|
+
.optional()
|
|
76
|
+
.describe('Unique fingerprint for deduplication (hash of location + pattern)'),
|
|
77
|
+
// Classification
|
|
78
|
+
category: WarningCategorySchema.describe('Warning category'),
|
|
79
|
+
severity: WarningSeveritySchema.describe('Severity level'),
|
|
80
|
+
confidence: ConfidenceSchema.describe('Detection confidence'),
|
|
81
|
+
// Display
|
|
82
|
+
title: z.string().describe('Short title (e.g., "Broad eslint-disable added")'),
|
|
83
|
+
message: z.string().describe('Primary message - what happened'),
|
|
84
|
+
explanation: z.string().describe('Why this matters'),
|
|
85
|
+
suggestion: z.string().describe('What to do instead'),
|
|
86
|
+
nudge: z.string().optional().describe('Imperative coaching prompt from the pattern'),
|
|
87
|
+
// Location
|
|
88
|
+
location: LocationSchema.describe('Source code location'),
|
|
89
|
+
// Context
|
|
90
|
+
pattern: z.string().optional().describe('Named pattern or rule that triggered this'),
|
|
91
|
+
drift: DriftSchema.optional().describe('Drift context for boundary violations'),
|
|
92
|
+
// Suppression
|
|
93
|
+
suppressed: SuppressionSchema.optional().describe('Suppression metadata if suppressed'),
|
|
94
|
+
});
|
|
95
|
+
// =============================================================================
|
|
96
|
+
// Anti-Pattern Definition Schema
|
|
97
|
+
// =============================================================================
|
|
98
|
+
/**
|
|
99
|
+
* Regex-based detection configuration
|
|
100
|
+
*/
|
|
101
|
+
export const RegexDetectionConfigSchema = z.object({
|
|
102
|
+
type: z.literal('regex').describe('Regex-based detection'),
|
|
103
|
+
pattern: z.string().min(1).describe('Regex pattern string'),
|
|
104
|
+
});
|
|
105
|
+
/**
|
|
106
|
+
* AST-based detection configuration
|
|
107
|
+
*/
|
|
108
|
+
export const AstDetectionConfigSchema = z.object({
|
|
109
|
+
type: z.literal('ast').describe('AST-based detection'),
|
|
110
|
+
astQuery: z.string().min(1).describe('AST query description'),
|
|
111
|
+
});
|
|
112
|
+
/**
|
|
113
|
+
* Detection method configuration - discriminated union ensures
|
|
114
|
+
* regex type requires pattern, ast type requires astQuery
|
|
115
|
+
*/
|
|
116
|
+
export const DetectionConfigSchema = z.discriminatedUnion('type', [
|
|
117
|
+
RegexDetectionConfigSchema,
|
|
118
|
+
AstDetectionConfigSchema,
|
|
119
|
+
]);
|
|
120
|
+
/**
|
|
121
|
+
* Anti-pattern definition - defines a detectable pattern
|
|
122
|
+
*/
|
|
123
|
+
export const AntiPatternSchema = z.object({
|
|
124
|
+
// Identification
|
|
125
|
+
id: z
|
|
126
|
+
.string()
|
|
127
|
+
.regex(/^AP-\d{3}$/)
|
|
128
|
+
.describe('Pattern ID (e.g., AP-001)'),
|
|
129
|
+
name: z.string().describe('Human-readable name'),
|
|
130
|
+
// Classification
|
|
131
|
+
category: z
|
|
132
|
+
.enum(['escape-hatch', 'error-handling', 'code-quality', 'type-safety', 'html', 'css'])
|
|
133
|
+
.describe('Pattern category'),
|
|
134
|
+
severity: WarningSeveritySchema.describe('Default severity'),
|
|
135
|
+
confidence: ConfidenceSchema.describe('Detection confidence'),
|
|
136
|
+
// Detection
|
|
137
|
+
detection: DetectionConfigSchema.describe('How to detect this pattern'),
|
|
138
|
+
// Messaging
|
|
139
|
+
title: z.string().describe('Warning title template'),
|
|
140
|
+
explanation: z.string().describe('Why this pattern is problematic'),
|
|
141
|
+
suggestion: z.string().describe('Recommended alternative'),
|
|
142
|
+
nudge: z.string().optional().describe('Imperative coaching prompt for AI agents and developers'),
|
|
143
|
+
// File targeting
|
|
144
|
+
fileExtensions: z
|
|
145
|
+
.array(z.string())
|
|
146
|
+
.optional()
|
|
147
|
+
.describe('File extensions this pattern applies to (e.g., [".html", ".htm"])'),
|
|
148
|
+
allFileTypes: z
|
|
149
|
+
.boolean()
|
|
150
|
+
.optional()
|
|
151
|
+
.describe('If true, pattern applies to all scanned file types regardless of extension'),
|
|
152
|
+
// Customisation
|
|
153
|
+
allowlist: z.array(z.string()).optional().describe('File patterns to skip (glob patterns)'),
|
|
154
|
+
threshold: z
|
|
155
|
+
.number()
|
|
156
|
+
.int()
|
|
157
|
+
.positive()
|
|
158
|
+
.optional()
|
|
159
|
+
.describe('Count threshold for triggering (e.g., >3 per file)'),
|
|
160
|
+
// Enablement
|
|
161
|
+
enabled: z.boolean().default(true).describe('Whether enabled by default'),
|
|
162
|
+
optIn: z.boolean().default(false).describe('If true, disabled by default (noisy patterns)'),
|
|
163
|
+
// Documentation
|
|
164
|
+
documentation: z.string().url().optional().describe('Link to detailed documentation'),
|
|
165
|
+
});
|
|
166
|
+
// =============================================================================
|
|
167
|
+
// Warning Result Schema (for GateResult integration)
|
|
168
|
+
// =============================================================================
|
|
169
|
+
/**
|
|
170
|
+
* Collection of warnings from a check run - embeds in GateResult.details
|
|
171
|
+
*/
|
|
172
|
+
export const WarningResultSchema = z.object({
|
|
173
|
+
warnings: z.array(WarningSchema).describe('All warnings found'),
|
|
174
|
+
summary: z.object({
|
|
175
|
+
total: z.number().int().nonnegative(),
|
|
176
|
+
errors: z.number().int().nonnegative(),
|
|
177
|
+
warnings: z.number().int().nonnegative(),
|
|
178
|
+
info: z.number().int().nonnegative(),
|
|
179
|
+
suppressed: z.number().int().nonnegative(),
|
|
180
|
+
}),
|
|
181
|
+
patterns_checked: z.array(z.string()).describe('Pattern IDs that were checked'),
|
|
182
|
+
});
|
|
183
|
+
// =============================================================================
|
|
184
|
+
// Suppression Record Schema (for provenance)
|
|
185
|
+
// =============================================================================
|
|
186
|
+
/**
|
|
187
|
+
* Suppression record for provenance tracking
|
|
188
|
+
*/
|
|
189
|
+
export const SuppressionRecordSchema = z.object({
|
|
190
|
+
id: z.string().describe('Unique suppression ID'),
|
|
191
|
+
pattern_id: z.string().describe('Pattern ID being suppressed'),
|
|
192
|
+
file: z.string().describe('File containing the suppression'),
|
|
193
|
+
line: z.number().int().positive().describe('Line number of suppression comment'),
|
|
194
|
+
reason: z.string().describe('Reason provided'),
|
|
195
|
+
author: z.string().optional().describe('Author if specified'),
|
|
196
|
+
timestamp: z.string().datetime().describe('When recorded'),
|
|
197
|
+
commit: z.string().optional().describe('Git commit SHA when added'),
|
|
198
|
+
scope: z.enum(['statement', 'import', 'file', 'line']).describe('Suppression scope'),
|
|
199
|
+
expires_at: z.string().datetime().optional().describe('Expiry date for time-boxed suppressions'),
|
|
200
|
+
});
|
|
201
|
+
// =============================================================================
|
|
202
|
+
// Utility Functions
|
|
203
|
+
// =============================================================================
|
|
204
|
+
/**
|
|
205
|
+
* Create a warning fingerprint for deduplication
|
|
206
|
+
*/
|
|
207
|
+
export function createWarningFingerprint(warning) {
|
|
208
|
+
const parts = [
|
|
209
|
+
warning.id,
|
|
210
|
+
warning.location.file,
|
|
211
|
+
warning.location.line.toString(),
|
|
212
|
+
warning.pattern ?? '',
|
|
213
|
+
];
|
|
214
|
+
// Simple hash - in production would use crypto
|
|
215
|
+
return parts.join(':');
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Check if a warning should be considered an error for gate purposes
|
|
219
|
+
*/
|
|
220
|
+
export function isBlockingWarning(warning) {
|
|
221
|
+
return warning.severity === 'error' && !warning.suppressed;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Count warnings by severity, including total count.
|
|
225
|
+
* Note: A warning can be both suppressed AND have a severity,
|
|
226
|
+
* so suppressed warnings are counted separately and not in their severity bucket.
|
|
227
|
+
*/
|
|
228
|
+
export function countBySeverity(warnings) {
|
|
229
|
+
const counts = warnings.reduce((acc, w) => {
|
|
230
|
+
if (w.suppressed) {
|
|
231
|
+
acc.suppressed++;
|
|
232
|
+
}
|
|
233
|
+
else if (w.severity === 'error') {
|
|
234
|
+
acc.errors++;
|
|
235
|
+
}
|
|
236
|
+
else if (w.severity === 'warning') {
|
|
237
|
+
acc.warnings++;
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
acc.info++;
|
|
241
|
+
}
|
|
242
|
+
return acc;
|
|
243
|
+
}, { errors: 0, warnings: 0, info: 0, suppressed: 0 });
|
|
244
|
+
return {
|
|
245
|
+
total: warnings.length,
|
|
246
|
+
...counts,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Create a complete WarningResult summary from a list of warnings.
|
|
251
|
+
* Ensures consistency between warnings array and summary counts.
|
|
252
|
+
*
|
|
253
|
+
* @param warnings - Array of warnings
|
|
254
|
+
* @param patternsChecked - Array of pattern IDs that were checked
|
|
255
|
+
* @returns Complete WarningResult object
|
|
256
|
+
*/
|
|
257
|
+
export function createWarningResult(warnings, patternsChecked) {
|
|
258
|
+
return {
|
|
259
|
+
warnings,
|
|
260
|
+
summary: countBySeverity(warnings),
|
|
261
|
+
patterns_checked: patternsChecked,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Validate that a WarningResult's summary matches its warnings array.
|
|
266
|
+
* Useful for catching inconsistencies in manually constructed results.
|
|
267
|
+
*
|
|
268
|
+
* @param result - WarningResult to validate
|
|
269
|
+
* @returns true if summary matches warnings, false otherwise
|
|
270
|
+
*/
|
|
271
|
+
export function validateWarningResultConsistency(result) {
|
|
272
|
+
const computed = countBySeverity(result.warnings);
|
|
273
|
+
return (result.summary.total === computed.total &&
|
|
274
|
+
result.summary.errors === computed.errors &&
|
|
275
|
+
result.summary.warnings === computed.warnings &&
|
|
276
|
+
result.summary.info === computed.info &&
|
|
277
|
+
result.summary.suppressed === computed.suppressed);
|
|
278
|
+
}
|