@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.
Files changed (215) hide show
  1. package/LICENSE +14 -0
  2. package/dist/antipattern/index.d.ts +11 -0
  3. package/dist/antipattern/index.d.ts.map +1 -0
  4. package/dist/antipattern/index.js +31 -0
  5. package/dist/antipattern/patterns-css.d.ts +17 -0
  6. package/dist/antipattern/patterns-css.d.ts.map +1 -0
  7. package/dist/antipattern/patterns-css.js +72 -0
  8. package/dist/antipattern/patterns-html.d.ts +21 -0
  9. package/dist/antipattern/patterns-html.d.ts.map +1 -0
  10. package/dist/antipattern/patterns-html.js +139 -0
  11. package/dist/antipattern/patterns.d.ts +72 -0
  12. package/dist/antipattern/patterns.d.ts.map +1 -0
  13. package/dist/antipattern/patterns.js +301 -0
  14. package/dist/antipattern/scanner.d.ts +32 -0
  15. package/dist/antipattern/scanner.d.ts.map +1 -0
  16. package/dist/antipattern/scanner.js +89 -0
  17. package/dist/antipattern/types.d.ts +318 -0
  18. package/dist/antipattern/types.d.ts.map +1 -0
  19. package/dist/antipattern/types.js +278 -0
  20. package/dist/architecture/analyzer.d.ts +123 -0
  21. package/dist/architecture/analyzer.d.ts.map +1 -0
  22. package/dist/architecture/analyzer.js +321 -0
  23. package/dist/architecture/baseline.d.ts +112 -0
  24. package/dist/architecture/baseline.d.ts.map +1 -0
  25. package/dist/architecture/baseline.js +245 -0
  26. package/dist/architecture/compiler.d.ts +24 -0
  27. package/dist/architecture/compiler.d.ts.map +1 -0
  28. package/dist/architecture/compiler.js +57 -0
  29. package/dist/architecture/context.d.ts +129 -0
  30. package/dist/architecture/context.d.ts.map +1 -0
  31. package/dist/architecture/context.js +116 -0
  32. package/dist/architecture/dc-generator.d.ts +9 -0
  33. package/dist/architecture/dc-generator.d.ts.map +1 -0
  34. package/dist/architecture/dc-generator.js +220 -0
  35. package/dist/architecture/definition-schema.d.ts +128 -0
  36. package/dist/architecture/definition-schema.d.ts.map +1 -0
  37. package/dist/architecture/definition-schema.js +94 -0
  38. package/dist/architecture/edge-detector-html.d.ts +6 -0
  39. package/dist/architecture/edge-detector-html.d.ts.map +1 -0
  40. package/dist/architecture/edge-detector-html.js +5 -0
  41. package/dist/architecture/edge-detector-web.d.ts +32 -0
  42. package/dist/architecture/edge-detector-web.d.ts.map +1 -0
  43. package/dist/architecture/edge-detector-web.js +133 -0
  44. package/dist/architecture/edge-detector.d.ts +116 -0
  45. package/dist/architecture/edge-detector.d.ts.map +1 -0
  46. package/dist/architecture/edge-detector.js +229 -0
  47. package/dist/architecture/entry-detector.d.ts +44 -0
  48. package/dist/architecture/entry-detector.d.ts.map +1 -0
  49. package/dist/architecture/entry-detector.js +263 -0
  50. package/dist/architecture/index.d.ts +21 -0
  51. package/dist/architecture/index.d.ts.map +1 -0
  52. package/dist/architecture/index.js +48 -0
  53. package/dist/architecture/layer-detector.d.ts +60 -0
  54. package/dist/architecture/layer-detector.d.ts.map +1 -0
  55. package/dist/architecture/layer-detector.js +331 -0
  56. package/dist/architecture/rego-generator.d.ts +25 -0
  57. package/dist/architecture/rego-generator.d.ts.map +1 -0
  58. package/dist/architecture/rego-generator.js +229 -0
  59. package/dist/architecture/templates/index.d.ts +39 -0
  60. package/dist/architecture/templates/index.d.ts.map +1 -0
  61. package/dist/architecture/templates/index.js +124 -0
  62. package/dist/architecture/types.d.ts +280 -0
  63. package/dist/architecture/types.d.ts.map +1 -0
  64. package/dist/architecture/types.js +269 -0
  65. package/dist/architecture/yaml-parser.d.ts +13 -0
  66. package/dist/architecture/yaml-parser.d.ts.map +1 -0
  67. package/dist/architecture/yaml-parser.js +234 -0
  68. package/dist/config/constants.d.ts +9 -0
  69. package/dist/config/constants.d.ts.map +1 -0
  70. package/dist/config/constants.js +20 -0
  71. package/dist/config/index.d.ts +9 -0
  72. package/dist/config/index.d.ts.map +1 -0
  73. package/dist/config/index.js +8 -0
  74. package/dist/config/loader.d.ts +41 -0
  75. package/dist/config/loader.d.ts.map +1 -0
  76. package/dist/config/loader.js +76 -0
  77. package/dist/config/nudge-config.d.ts +35 -0
  78. package/dist/config/nudge-config.d.ts.map +1 -0
  79. package/dist/config/nudge-config.js +34 -0
  80. package/dist/config/types.d.ts +30 -0
  81. package/dist/config/types.d.ts.map +1 -0
  82. package/dist/config/types.js +4 -0
  83. package/dist/contracts/index.d.ts +14 -0
  84. package/dist/contracts/index.d.ts.map +1 -0
  85. package/dist/contracts/index.js +13 -0
  86. package/dist/contracts/schemas/aps.schema.d.ts +269 -0
  87. package/dist/contracts/schemas/aps.schema.d.ts.map +1 -0
  88. package/dist/contracts/schemas/aps.schema.js +183 -0
  89. package/dist/contracts/schemas/index.d.ts +12 -0
  90. package/dist/contracts/schemas/index.d.ts.map +1 -0
  91. package/dist/contracts/schemas/index.js +14 -0
  92. package/dist/contracts/schemas/json-schema.d.ts +14 -0
  93. package/dist/contracts/schemas/json-schema.d.ts.map +1 -0
  94. package/dist/contracts/schemas/json-schema.js +31 -0
  95. package/dist/contracts/schemas/warning.schema.d.ts +171 -0
  96. package/dist/contracts/schemas/warning.schema.d.ts.map +1 -0
  97. package/dist/contracts/schemas/warning.schema.js +123 -0
  98. package/dist/contracts/types/gate.types.d.ts +194 -0
  99. package/dist/contracts/types/gate.types.d.ts.map +1 -0
  100. package/dist/contracts/types/gate.types.js +19 -0
  101. package/dist/contracts/types/index.d.ts +9 -0
  102. package/dist/contracts/types/index.d.ts.map +1 -0
  103. package/dist/contracts/types/index.js +8 -0
  104. package/dist/crypto/hash.d.ts +47 -0
  105. package/dist/crypto/hash.d.ts.map +1 -0
  106. package/dist/crypto/hash.js +110 -0
  107. package/dist/crypto/index.d.ts +7 -0
  108. package/dist/crypto/index.d.ts.map +1 -0
  109. package/dist/crypto/index.js +6 -0
  110. package/dist/drift/index.d.ts +6 -0
  111. package/dist/drift/index.d.ts.map +1 -0
  112. package/dist/drift/index.js +5 -0
  113. package/dist/drift/report-generator.d.ts +21 -0
  114. package/dist/drift/report-generator.d.ts.map +1 -0
  115. package/dist/drift/report-generator.js +240 -0
  116. package/dist/drift/snapshot-capture.d.ts +26 -0
  117. package/dist/drift/snapshot-capture.d.ts.map +1 -0
  118. package/dist/drift/snapshot-capture.js +195 -0
  119. package/dist/drift/snapshot-compare.d.ts +50 -0
  120. package/dist/drift/snapshot-compare.d.ts.map +1 -0
  121. package/dist/drift/snapshot-compare.js +142 -0
  122. package/dist/drift/snapshot-schema.d.ts +197 -0
  123. package/dist/drift/snapshot-schema.d.ts.map +1 -0
  124. package/dist/drift/snapshot-schema.js +193 -0
  125. package/dist/drift/snapshot-storage.d.ts +25 -0
  126. package/dist/drift/snapshot-storage.d.ts.map +1 -0
  127. package/dist/drift/snapshot-storage.js +179 -0
  128. package/dist/explain/antipattern-explainer.d.ts +4 -0
  129. package/dist/explain/antipattern-explainer.d.ts.map +1 -0
  130. package/dist/explain/antipattern-explainer.js +196 -0
  131. package/dist/explain/boundary-explainer.d.ts +5 -0
  132. package/dist/explain/boundary-explainer.d.ts.map +1 -0
  133. package/dist/explain/boundary-explainer.js +261 -0
  134. package/dist/explain/explain-service.d.ts +19 -0
  135. package/dist/explain/explain-service.d.ts.map +1 -0
  136. package/dist/explain/explain-service.js +106 -0
  137. package/dist/explain/index.d.ts +7 -0
  138. package/dist/explain/index.d.ts.map +1 -0
  139. package/dist/explain/index.js +5 -0
  140. package/dist/explain/template-loader.d.ts +9 -0
  141. package/dist/explain/template-loader.d.ts.map +1 -0
  142. package/dist/explain/template-loader.js +51 -0
  143. package/dist/explain/types.d.ts +46 -0
  144. package/dist/explain/types.d.ts.map +1 -0
  145. package/dist/explain/types.js +31 -0
  146. package/dist/index.d.ts +26 -0
  147. package/dist/index.d.ts.map +1 -0
  148. package/dist/index.js +37 -0
  149. package/dist/provenance/collector.d.ts +86 -0
  150. package/dist/provenance/collector.d.ts.map +1 -0
  151. package/dist/provenance/collector.js +425 -0
  152. package/dist/provenance/git-ai-standard/git-notes.d.ts +85 -0
  153. package/dist/provenance/git-ai-standard/git-notes.d.ts.map +1 -0
  154. package/dist/provenance/git-ai-standard/git-notes.js +292 -0
  155. package/dist/provenance/git-ai-standard/index.d.ts +44 -0
  156. package/dist/provenance/git-ai-standard/index.d.ts.map +1 -0
  157. package/dist/provenance/git-ai-standard/index.js +47 -0
  158. package/dist/provenance/git-ai-standard/serializer.d.ts +54 -0
  159. package/dist/provenance/git-ai-standard/serializer.d.ts.map +1 -0
  160. package/dist/provenance/git-ai-standard/serializer.js +224 -0
  161. package/dist/provenance/git-ai-standard/session.d.ts +51 -0
  162. package/dist/provenance/git-ai-standard/session.d.ts.map +1 -0
  163. package/dist/provenance/git-ai-standard/session.js +118 -0
  164. package/dist/provenance/git-ai-standard/types.d.ts +173 -0
  165. package/dist/provenance/git-ai-standard/types.d.ts.map +1 -0
  166. package/dist/provenance/git-ai-standard/types.js +109 -0
  167. package/dist/provenance/index.d.ts +5 -0
  168. package/dist/provenance/index.d.ts.map +1 -0
  169. package/dist/provenance/index.js +6 -0
  170. package/dist/provenance/store.d.ts +83 -0
  171. package/dist/provenance/store.d.ts.map +1 -0
  172. package/dist/provenance/store.js +248 -0
  173. package/dist/provenance/types.d.ts +160 -0
  174. package/dist/provenance/types.d.ts.map +1 -0
  175. package/dist/provenance/types.js +112 -0
  176. package/dist/suppression/index.d.ts +4 -0
  177. package/dist/suppression/index.d.ts.map +1 -0
  178. package/dist/suppression/index.js +3 -0
  179. package/dist/suppression/parser.d.ts +31 -0
  180. package/dist/suppression/parser.d.ts.map +1 -0
  181. package/dist/suppression/parser.js +219 -0
  182. package/dist/suppression/service.d.ts +29 -0
  183. package/dist/suppression/service.d.ts.map +1 -0
  184. package/dist/suppression/service.js +132 -0
  185. package/dist/suppression/store.d.ts +61 -0
  186. package/dist/suppression/store.d.ts.map +1 -0
  187. package/dist/suppression/store.js +169 -0
  188. package/dist/utils/debug.d.ts +48 -0
  189. package/dist/utils/debug.d.ts.map +1 -0
  190. package/dist/utils/debug.js +100 -0
  191. package/dist/utils/index.d.ts +4 -0
  192. package/dist/utils/index.d.ts.map +1 -0
  193. package/dist/utils/index.js +3 -0
  194. package/dist/utils/path-safety.d.ts +21 -0
  195. package/dist/utils/path-safety.d.ts.map +1 -0
  196. package/dist/utils/path-safety.js +49 -0
  197. package/dist/utils/severity.d.ts +37 -0
  198. package/dist/utils/severity.d.ts.map +1 -0
  199. package/dist/utils/severity.js +22 -0
  200. package/dist/validation/aps-validator.d.ts +66 -0
  201. package/dist/validation/aps-validator.d.ts.map +1 -0
  202. package/dist/validation/aps-validator.js +173 -0
  203. package/dist/validation/errors.d.ts +52 -0
  204. package/dist/validation/errors.d.ts.map +1 -0
  205. package/dist/validation/errors.js +115 -0
  206. package/dist/validation/index.d.ts +8 -0
  207. package/dist/validation/index.d.ts.map +1 -0
  208. package/dist/validation/index.js +13 -0
  209. package/dist/warnings/index.d.ts +2 -0
  210. package/dist/warnings/index.d.ts.map +1 -0
  211. package/dist/warnings/index.js +1 -0
  212. package/dist/warnings/warning-id.d.ts +180 -0
  213. package/dist/warnings/warning-id.d.ts.map +1 -0
  214. package/dist/warnings/warning-id.js +257 -0
  215. package/package.json +79 -0
@@ -0,0 +1,245 @@
1
+ /**
2
+ * Architecture baseline storage
3
+ *
4
+ * Handles reading/writing .anvil/architecture.json
5
+ */
6
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
7
+ import { join, dirname } from 'node:path';
8
+ import { ArchitectureBaselineSchema, createDefaultLayers, createDefaultBoundaries, } from './types.js';
9
+ import { createDebugger } from '../utils/debug.js';
10
+ const debug = createDebugger('architecture');
11
+ /**
12
+ * Default baseline file path
13
+ */
14
+ export const BASELINE_FILENAME = 'architecture.json';
15
+ export const ANVIL_DIR = '.anvil';
16
+ /**
17
+ * Get the full path to the baseline file
18
+ */
19
+ export function getBaselinePath(workspaceRoot) {
20
+ return join(workspaceRoot, ANVIL_DIR, BASELINE_FILENAME);
21
+ }
22
+ /**
23
+ * Check if a baseline exists
24
+ */
25
+ export function baselineExists(workspaceRoot) {
26
+ return existsSync(getBaselinePath(workspaceRoot));
27
+ }
28
+ /**
29
+ * Load the architecture baseline
30
+ */
31
+ export function loadBaseline(workspaceRoot) {
32
+ const path = getBaselinePath(workspaceRoot);
33
+ if (!existsSync(path)) {
34
+ debug('no baseline file found', path);
35
+ return null;
36
+ }
37
+ try {
38
+ debug('loading baseline from', path);
39
+ const content = readFileSync(path, 'utf-8');
40
+ const data = JSON.parse(content);
41
+ // Validate against schema
42
+ const result = ArchitectureBaselineSchema.safeParse(data);
43
+ if (!result.success) {
44
+ debug('invalid baseline schema', result.error.format());
45
+ console.error('Invalid architecture baseline:', result.error.format());
46
+ return null;
47
+ }
48
+ debug('baseline loaded', {
49
+ modules: result.data.baseline_snapshot.module_count,
50
+ violations: result.data.baseline_snapshot.violations.length,
51
+ });
52
+ return result.data;
53
+ }
54
+ catch (error) {
55
+ debug('failed to load baseline', error instanceof Error ? error : undefined);
56
+ console.error('Failed to load architecture baseline:', error);
57
+ return null;
58
+ }
59
+ }
60
+ /**
61
+ * Save the architecture baseline
62
+ */
63
+ export function saveBaseline(workspaceRoot, baseline) {
64
+ debug('saving baseline', { modules: baseline.baseline_snapshot.module_count });
65
+ const path = getBaselinePath(workspaceRoot);
66
+ const dir = dirname(path);
67
+ // Ensure directory exists
68
+ if (!existsSync(dir)) {
69
+ mkdirSync(dir, { recursive: true });
70
+ }
71
+ // Validate before saving
72
+ const result = ArchitectureBaselineSchema.safeParse(baseline);
73
+ if (!result.success) {
74
+ throw new Error(`Invalid baseline data: ${result.error.format()}`);
75
+ }
76
+ // Write with pretty formatting for human readability
77
+ writeFileSync(path, JSON.stringify(baseline, null, 2) + '\n', 'utf-8');
78
+ }
79
+ /**
80
+ * Create a new baseline with defaults
81
+ */
82
+ export function createBaseline(options) {
83
+ const now = new Date().toISOString();
84
+ const layers = options.layers ?? createDefaultLayers();
85
+ const boundaries = options.boundaries ?? createDefaultBoundaries(layers);
86
+ return {
87
+ schema_version: '0.1.0',
88
+ created_at: now,
89
+ updated_at: now,
90
+ entry_points: options.entryPoints ?? [],
91
+ layers,
92
+ boundaries,
93
+ baseline_snapshot: {
94
+ module_count: options.moduleCount ?? 0,
95
+ timestamp: now,
96
+ violations: options.violations ?? [],
97
+ },
98
+ };
99
+ }
100
+ /**
101
+ * Update an existing baseline
102
+ */
103
+ export function updateBaseline(existing, updates) {
104
+ const now = new Date().toISOString();
105
+ return {
106
+ ...existing,
107
+ updated_at: now,
108
+ entry_points: updates.entryPoints ?? existing.entry_points,
109
+ layers: updates.layers ?? existing.layers,
110
+ boundaries: updates.boundaries ?? existing.boundaries,
111
+ baseline_snapshot: {
112
+ ...existing.baseline_snapshot,
113
+ module_count: updates.moduleCount ?? existing.baseline_snapshot.module_count,
114
+ violations: updates.violations ?? existing.baseline_snapshot.violations,
115
+ timestamp: now,
116
+ },
117
+ };
118
+ }
119
+ /**
120
+ * Merge new violations into baseline (for incremental updates)
121
+ */
122
+ export function mergeViolations(existing, newViolations) {
123
+ const byId = new Map();
124
+ // Add existing
125
+ for (const v of existing) {
126
+ byId.set(v.id, v);
127
+ }
128
+ // Add/update new
129
+ for (const v of newViolations) {
130
+ byId.set(v.id, v);
131
+ }
132
+ return Array.from(byId.values());
133
+ }
134
+ /**
135
+ * Find violations that are NEW (not in baseline)
136
+ */
137
+ export function findNewViolations(current, baseline) {
138
+ const baselineIds = new Set(baseline.map((v) => v.id));
139
+ return current.filter((v) => !baselineIds.has(v.id));
140
+ }
141
+ /**
142
+ * Find violations that were FIXED (in baseline but not current)
143
+ */
144
+ export function findFixedViolations(current, baseline) {
145
+ const currentIds = new Set(current.map((v) => v.id));
146
+ return baseline.filter((v) => !currentIds.has(v.id));
147
+ }
148
+ /**
149
+ * Baseline manager for convenient operations
150
+ */
151
+ export class BaselineManager {
152
+ workspaceRoot;
153
+ baseline = null;
154
+ constructor(workspaceRoot) {
155
+ this.workspaceRoot = workspaceRoot;
156
+ }
157
+ /**
158
+ * Check if baseline exists
159
+ */
160
+ exists() {
161
+ return baselineExists(this.workspaceRoot);
162
+ }
163
+ /**
164
+ * Load baseline (cached)
165
+ */
166
+ load() {
167
+ if (!this.baseline) {
168
+ this.baseline = loadBaseline(this.workspaceRoot);
169
+ }
170
+ return this.baseline;
171
+ }
172
+ /**
173
+ * Force reload baseline
174
+ */
175
+ reload() {
176
+ this.baseline = loadBaseline(this.workspaceRoot);
177
+ return this.baseline;
178
+ }
179
+ /**
180
+ * Save baseline
181
+ */
182
+ save(baseline) {
183
+ saveBaseline(this.workspaceRoot, baseline);
184
+ this.baseline = baseline;
185
+ }
186
+ /**
187
+ * Create and save a new baseline
188
+ */
189
+ create(options) {
190
+ const baseline = createBaseline(options);
191
+ this.save(baseline);
192
+ return baseline;
193
+ }
194
+ /**
195
+ * Update and save existing baseline
196
+ */
197
+ update(updates) {
198
+ const existing = this.load();
199
+ if (!existing) {
200
+ return null;
201
+ }
202
+ const updated = updateBaseline(existing, updates);
203
+ this.save(updated);
204
+ return updated;
205
+ }
206
+ /**
207
+ * Get layers from baseline or defaults
208
+ */
209
+ getLayers() {
210
+ const baseline = this.load();
211
+ return baseline?.layers ?? createDefaultLayers();
212
+ }
213
+ /**
214
+ * Get boundaries from baseline or defaults
215
+ */
216
+ getBoundaries() {
217
+ const baseline = this.load();
218
+ if (baseline) {
219
+ return baseline.boundaries;
220
+ }
221
+ return createDefaultBoundaries(createDefaultLayers());
222
+ }
223
+ /**
224
+ * Check if a violation is new
225
+ */
226
+ isNewViolation(violation) {
227
+ const baseline = this.load();
228
+ if (!baseline) {
229
+ return true; // No baseline = all violations are new
230
+ }
231
+ return !baseline.baseline_snapshot.violations.some((v) => v.id === violation.id);
232
+ }
233
+ /**
234
+ * Get baseline path
235
+ */
236
+ getPath() {
237
+ return getBaselinePath(this.workspaceRoot);
238
+ }
239
+ }
240
+ /**
241
+ * Create a baseline manager
242
+ */
243
+ export function createBaselineManager(workspaceRoot) {
244
+ return new BaselineManager(workspaceRoot);
245
+ }
@@ -0,0 +1,24 @@
1
+ import type { ArchitectureDefinition } from './definition-schema.js';
2
+ export interface CompileResult {
3
+ dcConfig: {
4
+ path: string;
5
+ regenerated: boolean;
6
+ };
7
+ regoPolicy: {
8
+ path: string;
9
+ regenerated: boolean;
10
+ };
11
+ definition: ArchitectureDefinition;
12
+ }
13
+ export interface CompileOptions {
14
+ force?: boolean;
15
+ skipDC?: boolean;
16
+ skipRego?: boolean;
17
+ }
18
+ export declare function compileArchitecture(workspaceRoot: string, options?: CompileOptions): Promise<CompileResult>;
19
+ export declare function needsCompilation(workspaceRoot: string): Promise<{
20
+ dc: boolean;
21
+ rego: boolean;
22
+ any: boolean;
23
+ }>;
24
+ //# sourceMappingURL=compiler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../src/architecture/compiler.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAErE,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,OAAO,CAAA;KAAE,CAAC;IACjD,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,OAAO,CAAA;KAAE,CAAC;IACnD,UAAU,EAAE,sBAAsB,CAAC;CACpC;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAsB,mBAAmB,CACvC,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,aAAa,CAAC,CAgDxB;AAED,wBAAsB,gBAAgB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC;IACrE,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,OAAO,CAAC;IACd,GAAG,EAAE,OAAO,CAAC;CACd,CAAC,CAYD"}
@@ -0,0 +1,57 @@
1
+ import { architectureYamlExists, parseArchitectureDefinition, mergeWithTemplate, } from './yaml-parser.js';
2
+ import { createDebugger } from '../utils/debug.js';
3
+ const debug = createDebugger('compiler');
4
+ import { needsRegeneration, writeDCConfig, dcConfigExists, getDCConfigPath, } from './dc-generator.js';
5
+ import { needsRegoRegeneration, writeRegoPolicy, regoExists, getRegoPath, } from './rego-generator.js';
6
+ export async function compileArchitecture(workspaceRoot, options = {}) {
7
+ debug('compiling architecture', { workspaceRoot, options });
8
+ if (!architectureYamlExists(workspaceRoot)) {
9
+ throw new Error('No architecture.yaml found. Run: anvil architecture init');
10
+ }
11
+ const definition = await parseArchitectureDefinition(workspaceRoot);
12
+ const merged = mergeWithTemplate(definition);
13
+ debug('definition parsed', {
14
+ template: merged.template,
15
+ layerCount: Object.keys(merged.layers).length,
16
+ });
17
+ const result = {
18
+ dcConfig: { path: getDCConfigPath(workspaceRoot), regenerated: false },
19
+ regoPolicy: { path: getRegoPath(workspaceRoot), regenerated: false },
20
+ definition: merged,
21
+ };
22
+ if (!options.skipDC) {
23
+ const needsDC = options.force ||
24
+ !dcConfigExists(workspaceRoot) ||
25
+ (await needsRegeneration(workspaceRoot, merged));
26
+ if (needsDC) {
27
+ debug('regenerating dependency-cruiser config');
28
+ result.dcConfig.path = await writeDCConfig(workspaceRoot, merged);
29
+ result.dcConfig.regenerated = true;
30
+ }
31
+ }
32
+ if (!options.skipRego) {
33
+ const needsRego = options.force ||
34
+ !regoExists(workspaceRoot) ||
35
+ (await needsRegoRegeneration(workspaceRoot, merged));
36
+ if (needsRego) {
37
+ debug('regenerating Rego policy');
38
+ result.regoPolicy.path = await writeRegoPolicy(workspaceRoot, merged);
39
+ result.regoPolicy.regenerated = true;
40
+ }
41
+ }
42
+ debug('compilation complete', {
43
+ dcRegenerated: result.dcConfig.regenerated,
44
+ regoRegenerated: result.regoPolicy.regenerated,
45
+ });
46
+ return result;
47
+ }
48
+ export async function needsCompilation(workspaceRoot) {
49
+ if (!architectureYamlExists(workspaceRoot)) {
50
+ return { dc: false, rego: false, any: false };
51
+ }
52
+ const definition = await parseArchitectureDefinition(workspaceRoot);
53
+ const merged = mergeWithTemplate(definition);
54
+ const dc = !dcConfigExists(workspaceRoot) || (await needsRegeneration(workspaceRoot, merged));
55
+ const rego = !regoExists(workspaceRoot) || (await needsRegoRegeneration(workspaceRoot, merged));
56
+ return { dc, rego, any: dc || rego };
57
+ }
@@ -0,0 +1,129 @@
1
+ import { z } from 'zod';
2
+ export declare const ArchViolationSeveritySchema: z.ZodEnum<{
3
+ error: "error";
4
+ info: "info";
5
+ warn: "warn";
6
+ ignore: "ignore";
7
+ }>;
8
+ export type ArchViolationSeverity = z.infer<typeof ArchViolationSeveritySchema>;
9
+ export declare const ArchViolationSchema: z.ZodObject<{
10
+ from: z.ZodString;
11
+ to: z.ZodString;
12
+ rule: z.ZodString;
13
+ severity: z.ZodEnum<{
14
+ error: "error";
15
+ info: "info";
16
+ warn: "warn";
17
+ ignore: "ignore";
18
+ }>;
19
+ is_circular: z.ZodBoolean;
20
+ cycle: z.ZodOptional<z.ZodArray<z.ZodString>>;
21
+ is_new: z.ZodBoolean;
22
+ from_layer: z.ZodNullable<z.ZodString>;
23
+ to_layer: z.ZodNullable<z.ZodString>;
24
+ }, z.core.$strip>;
25
+ export type ArchViolation = z.infer<typeof ArchViolationSchema>;
26
+ export declare const ModuleInfoSchema: z.ZodObject<{
27
+ path: z.ZodString;
28
+ layer: z.ZodNullable<z.ZodString>;
29
+ confidence: z.ZodOptional<z.ZodEnum<{
30
+ high: "high";
31
+ medium: "medium";
32
+ low: "low";
33
+ }>>;
34
+ matched_pattern: z.ZodOptional<z.ZodString>;
35
+ dependency_count: z.ZodNumber;
36
+ dependent_count: z.ZodNumber;
37
+ is_orphan: z.ZodBoolean;
38
+ }, z.core.$strip>;
39
+ export type ModuleInfo = z.infer<typeof ModuleInfoSchema>;
40
+ export declare const LayerStatsSchema: z.ZodObject<{
41
+ name: z.ZodString;
42
+ module_count: z.ZodNumber;
43
+ violations_from: z.ZodNumber;
44
+ violations_to: z.ZodNumber;
45
+ depends_on: z.ZodArray<z.ZodString>;
46
+ patterns: z.ZodArray<z.ZodString>;
47
+ }, z.core.$strip>;
48
+ export type LayerStats = z.infer<typeof LayerStatsSchema>;
49
+ export declare const ArchitectureContextSchema: z.ZodObject<{
50
+ timestamp: z.ZodString;
51
+ summary: z.ZodObject<{
52
+ total_modules: z.ZodNumber;
53
+ total_violations: z.ZodNumber;
54
+ new_violations: z.ZodNumber;
55
+ error_count: z.ZodNumber;
56
+ warn_count: z.ZodNumber;
57
+ info_count: z.ZodNumber;
58
+ circular_count: z.ZodNumber;
59
+ orphan_count: z.ZodNumber;
60
+ layer_violation_count: z.ZodNumber;
61
+ baseline_loaded: z.ZodBoolean;
62
+ }, z.core.$strip>;
63
+ violations: z.ZodArray<z.ZodObject<{
64
+ from: z.ZodString;
65
+ to: z.ZodString;
66
+ rule: z.ZodString;
67
+ severity: z.ZodEnum<{
68
+ error: "error";
69
+ info: "info";
70
+ warn: "warn";
71
+ ignore: "ignore";
72
+ }>;
73
+ is_circular: z.ZodBoolean;
74
+ cycle: z.ZodOptional<z.ZodArray<z.ZodString>>;
75
+ is_new: z.ZodBoolean;
76
+ from_layer: z.ZodNullable<z.ZodString>;
77
+ to_layer: z.ZodNullable<z.ZodString>;
78
+ }, z.core.$strip>>;
79
+ layers: z.ZodRecord<z.ZodString, z.ZodObject<{
80
+ name: z.ZodString;
81
+ module_count: z.ZodNumber;
82
+ violations_from: z.ZodNumber;
83
+ violations_to: z.ZodNumber;
84
+ depends_on: z.ZodArray<z.ZodString>;
85
+ patterns: z.ZodArray<z.ZodString>;
86
+ }, z.core.$strip>>;
87
+ modules: z.ZodOptional<z.ZodArray<z.ZodObject<{
88
+ path: z.ZodString;
89
+ layer: z.ZodNullable<z.ZodString>;
90
+ confidence: z.ZodOptional<z.ZodEnum<{
91
+ high: "high";
92
+ medium: "medium";
93
+ low: "low";
94
+ }>>;
95
+ matched_pattern: z.ZodOptional<z.ZodString>;
96
+ dependency_count: z.ZodNumber;
97
+ dependent_count: z.ZodNumber;
98
+ is_orphan: z.ZodBoolean;
99
+ }, z.core.$strip>>>;
100
+ dependencies: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
101
+ config: z.ZodOptional<z.ZodObject<{
102
+ config_file: z.ZodOptional<z.ZodString>;
103
+ scope: z.ZodOptional<z.ZodEnum<{
104
+ affected: "affected";
105
+ full: "full";
106
+ }>>;
107
+ severity_threshold: z.ZodOptional<z.ZodEnum<{
108
+ error: "error";
109
+ info: "info";
110
+ warn: "warn";
111
+ }>>;
112
+ }, z.core.$strip>>;
113
+ }, z.core.$strip>;
114
+ export type ArchitectureContext = z.infer<typeof ArchitectureContextSchema>;
115
+ export declare function createEmptyContext(): ArchitectureContext;
116
+ export declare class ArchitectureContextBuilder {
117
+ private context;
118
+ constructor();
119
+ setSummary(summary: Partial<ArchitectureContext['summary']>): this;
120
+ addViolation(violation: ArchViolation): this;
121
+ setViolations(violations: ArchViolation[]): this;
122
+ addLayerStats(name: string, stats: Omit<LayerStats, 'name'>): this;
123
+ setModules(modules: ModuleInfo[]): this;
124
+ setDependencies(deps: Record<string, string[]>): this;
125
+ setConfig(config: ArchitectureContext['config']): this;
126
+ build(): ArchitectureContext;
127
+ }
128
+ export declare function createContextBuilder(): ArchitectureContextBuilder;
129
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/architecture/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,2BAA2B;;;;;EAA8C,CAAC;AACvF,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEhF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;iBAU9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,gBAAgB;;;;;;;;;;;;iBAQ3B,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,gBAAgB;;;;;;;iBAO3B,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAyBpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,wBAAgB,kBAAkB,IAAI,mBAAmB,CAkBxD;AAED,qBAAa,0BAA0B;IACrC,OAAO,CAAC,OAAO,CAAsB;;IAMrC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC,GAAG,IAAI;IAKlE,YAAY,CAAC,SAAS,EAAE,aAAa,GAAG,IAAI;IAK5C,aAAa,CAAC,UAAU,EAAE,aAAa,EAAE,GAAG,IAAI;IAKhD,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,GAAG,IAAI;IAKlE,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI;IAKvC,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI;IAKrD,SAAS,CAAC,MAAM,EAAE,mBAAmB,CAAC,QAAQ,CAAC,GAAG,IAAI;IAKtD,KAAK,IAAI,mBAAmB;CAI7B;AAED,wBAAgB,oBAAoB,IAAI,0BAA0B,CAEjE"}
@@ -0,0 +1,116 @@
1
+ import { z } from 'zod';
2
+ export const ArchViolationSeveritySchema = z.enum(['error', 'warn', 'info', 'ignore']);
3
+ export const ArchViolationSchema = z.object({
4
+ from: z.string(),
5
+ to: z.string(),
6
+ rule: z.string(),
7
+ severity: ArchViolationSeveritySchema,
8
+ is_circular: z.boolean(),
9
+ cycle: z.array(z.string()).optional(),
10
+ is_new: z.boolean(),
11
+ from_layer: z.string().nullable(),
12
+ to_layer: z.string().nullable(),
13
+ });
14
+ export const ModuleInfoSchema = z.object({
15
+ path: z.string(),
16
+ layer: z.string().nullable(),
17
+ confidence: z.enum(['high', 'medium', 'low']).optional(),
18
+ matched_pattern: z.string().optional(),
19
+ dependency_count: z.number().int().nonnegative(),
20
+ dependent_count: z.number().int().nonnegative(),
21
+ is_orphan: z.boolean(),
22
+ });
23
+ export const LayerStatsSchema = z.object({
24
+ name: z.string(),
25
+ module_count: z.number().int().nonnegative(),
26
+ violations_from: z.number().int().nonnegative(),
27
+ violations_to: z.number().int().nonnegative(),
28
+ depends_on: z.array(z.string()),
29
+ patterns: z.array(z.string()),
30
+ });
31
+ export const ArchitectureContextSchema = z.object({
32
+ timestamp: z.string(),
33
+ summary: z.object({
34
+ total_modules: z.number().int().nonnegative(),
35
+ total_violations: z.number().int().nonnegative(),
36
+ new_violations: z.number().int().nonnegative(),
37
+ error_count: z.number().int().nonnegative(),
38
+ warn_count: z.number().int().nonnegative(),
39
+ info_count: z.number().int().nonnegative(),
40
+ circular_count: z.number().int().nonnegative(),
41
+ orphan_count: z.number().int().nonnegative(),
42
+ layer_violation_count: z.number().int().nonnegative(),
43
+ baseline_loaded: z.boolean(),
44
+ }),
45
+ violations: z.array(ArchViolationSchema),
46
+ layers: z.record(z.string(), LayerStatsSchema),
47
+ modules: z.array(ModuleInfoSchema).optional(),
48
+ dependencies: z.record(z.string(), z.array(z.string())).optional(),
49
+ config: z
50
+ .object({
51
+ config_file: z.string().optional(),
52
+ scope: z.enum(['affected', 'full']).optional(),
53
+ severity_threshold: z.enum(['error', 'warn', 'info']).optional(),
54
+ })
55
+ .optional(),
56
+ });
57
+ export function createEmptyContext() {
58
+ return {
59
+ timestamp: new Date().toISOString(),
60
+ summary: {
61
+ total_modules: 0,
62
+ total_violations: 0,
63
+ new_violations: 0,
64
+ error_count: 0,
65
+ warn_count: 0,
66
+ info_count: 0,
67
+ circular_count: 0,
68
+ orphan_count: 0,
69
+ layer_violation_count: 0,
70
+ baseline_loaded: false,
71
+ },
72
+ violations: [],
73
+ layers: {},
74
+ };
75
+ }
76
+ export class ArchitectureContextBuilder {
77
+ context;
78
+ constructor() {
79
+ this.context = createEmptyContext();
80
+ }
81
+ setSummary(summary) {
82
+ this.context.summary = { ...this.context.summary, ...summary };
83
+ return this;
84
+ }
85
+ addViolation(violation) {
86
+ this.context.violations.push(violation);
87
+ return this;
88
+ }
89
+ setViolations(violations) {
90
+ this.context.violations = violations;
91
+ return this;
92
+ }
93
+ addLayerStats(name, stats) {
94
+ this.context.layers[name] = { name, ...stats };
95
+ return this;
96
+ }
97
+ setModules(modules) {
98
+ this.context.modules = modules;
99
+ return this;
100
+ }
101
+ setDependencies(deps) {
102
+ this.context.dependencies = deps;
103
+ return this;
104
+ }
105
+ setConfig(config) {
106
+ this.context.config = config;
107
+ return this;
108
+ }
109
+ build() {
110
+ this.context.timestamp = new Date().toISOString();
111
+ return this.context;
112
+ }
113
+ }
114
+ export function createContextBuilder() {
115
+ return new ArchitectureContextBuilder();
116
+ }
@@ -0,0 +1,9 @@
1
+ import type { ArchitectureDefinition } from './definition-schema.js';
2
+ export declare const DC_CONFIG_FILENAME = "dependency-cruiser.js";
3
+ export declare const ANVIL_DIR = ".anvil";
4
+ export declare function getDCConfigPath(workspaceRoot: string): string;
5
+ export declare function dcConfigExists(workspaceRoot: string): boolean;
6
+ export declare function needsRegeneration(workspaceRoot: string, definition: ArchitectureDefinition): Promise<boolean>;
7
+ export declare function writeDCConfig(workspaceRoot: string, definition: ArchitectureDefinition): Promise<string>;
8
+ export declare function generateDCConfig(definition: ArchitectureDefinition): string;
9
+ //# sourceMappingURL=dc-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dc-generator.d.ts","sourceRoot":"","sources":["../../src/architecture/dc-generator.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAKrE,eAAO,MAAM,kBAAkB,0BAA0B,CAAC;AAC1D,eAAO,MAAM,SAAS,WAAW,CAAC;AAElC,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED,wBAAsB,iBAAiB,CACrC,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,sBAAsB,GACjC,OAAO,CAAC,OAAO,CAAC,CAYlB;AAOD,wBAAsB,aAAa,CACjC,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,sBAAsB,GACjC,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,sBAAsB,GAAG,MAAM,CAkC3E"}