@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 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/architecture/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Architecture analysis module
3
+ *
4
+ * Provides architecture baseline management, layer detection,
5
+ * entry point detection, and boundary violation analysis.
6
+ */
7
+ // Types
8
+ export {
9
+ // Entry points
10
+ EntryPointTypeSchema, DetectionConfidenceSchema, EntryPointSchema,
11
+ // Layers
12
+ StandardLayerSchema, LayerSchema, LayersSchema,
13
+ // Boundaries
14
+ BoundarySchema,
15
+ // Violations
16
+ BaselineViolationSchema,
17
+ // Baseline
18
+ BaselineSnapshotSchema, ArchitectureBaselineSchema,
19
+ // Analysis results
20
+ LayerAssignmentSchema, DependencyEdgeSchema, BoundaryViolationSchema,
21
+ // Utilities
22
+ createViolationId, isExistingViolation, createDefaultLayers, createDefaultBoundaries, } from './types.js';
23
+ // Layer detection
24
+ export { LayerDetector, createLayerDetector } from './layer-detector.js';
25
+ // Entry point detection
26
+ export { EntryPointDetector, createEntryPointDetector } from './entry-detector.js';
27
+ // Baseline management
28
+ export { BASELINE_FILENAME, ANVIL_DIR, getBaselinePath, baselineExists, loadBaseline, saveBaseline, createBaseline, updateBaseline, mergeViolations, findNewViolations, findFixedViolations, BaselineManager, createBaselineManager, } from './baseline.js';
29
+ // Architecture analyzer
30
+ export { ArchitectureAnalyzer, createArchitectureAnalyzer, analyseArchitecture, inferBaseline, } from './analyzer.js';
31
+ // HTML/CSS edge detection
32
+ export { extractHtmlEdges, extractCssEdges } from './edge-detector-web.js';
33
+ // Edge detection
34
+ export { createEdgeFingerprint, fingerprintEdge, resolveImportPath, extractImports, extractImportsFromFiles, compareToBaseline, toDependencyEdge, deduplicateEdges, filterCrossLayerEdges, } from './edge-detector.js';
35
+ // Architecture definition schema
36
+ export { ArchitectureTemplateSchema, LayerDefinitionSchema, BoundedContextSchema, RuleSeveritySchema, ArchitectureRuleSchema, ArchitectureOptionsSchema, ArchitectureDefinitionSchema, AVAILABLE_TEMPLATES, getAvailableTemplates, isValidTemplate, ARCHITECTURE_DEFINITION_VERSION, validateArchitectureDefinition, getDefaultOptions, } from './definition-schema.js';
37
+ // YAML parser
38
+ export { ARCHITECTURE_YAML_FILENAME, getArchitectureYamlPath, architectureYamlExists, parseArchitectureDefinition, writeArchitectureYaml, getTemplateDefaults, mergeWithTemplate, createDefinitionFromTemplate, } from './yaml-parser.js';
39
+ // DC config generator
40
+ export { DC_CONFIG_FILENAME, getDCConfigPath, dcConfigExists, needsRegeneration, writeDCConfig, generateDCConfig, } from './dc-generator.js';
41
+ // Rego policy generator
42
+ export { GENERATED_POLICIES_DIR, REGO_FILENAME, REGO_PACKAGE, getRegoPath, regoExists, needsRegoRegeneration, writeRegoPolicy, generateRegoPolicy, } from './rego-generator.js';
43
+ // Architecture compiler (DC + Rego orchestration)
44
+ export { compileArchitecture, needsCompilation, } from './compiler.js';
45
+ // Template loader
46
+ export { TemplateLoader, getTemplateLoader, listTemplates, getTemplate as getArchitectureTemplate, validateTemplate, } from './templates/index.js';
47
+ // Architecture context (for OPA)
48
+ export { ArchViolationSeveritySchema, ArchViolationSchema, ModuleInfoSchema, LayerStatsSchema, ArchitectureContextSchema, createEmptyContext, ArchitectureContextBuilder, createContextBuilder, } from './context.js';
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Layer detection heuristics
3
+ *
4
+ * Detects architectural layers from directory structure and file patterns.
5
+ * Supports both single-app and monorepo project structures.
6
+ */
7
+ import type { Layers, LayerAssignment } from './types.js';
8
+ /**
9
+ * Layer detector using directory heuristics
10
+ */
11
+ export declare class LayerDetector {
12
+ private patterns;
13
+ private customLayers;
14
+ constructor(customLayers?: Layers);
15
+ /**
16
+ * Convert Layers config to LayerPattern array
17
+ */
18
+ private layersToPatterns;
19
+ /**
20
+ * Detect layer for a single file
21
+ *
22
+ * Uses position-aware matching to handle monorepo structures where package names
23
+ * may match layer patterns (e.g., packages/api/src/services/user.ts should match
24
+ * 'services', not 'api').
25
+ */
26
+ detectLayer(filePath: string): LayerAssignment;
27
+ /**
28
+ * Detect layers for multiple files
29
+ */
30
+ detectLayers(filePaths: string[]): LayerAssignment[];
31
+ /**
32
+ * Get all detected layers from a set of files
33
+ */
34
+ getDetectedLayers(filePaths: string[]): Set<string>;
35
+ /**
36
+ * Suggest layer structure based on detected patterns
37
+ */
38
+ suggestLayers(filePaths: string[]): Layers;
39
+ /**
40
+ * Get default dependencies for a layer
41
+ */
42
+ private getDefaultDependencies;
43
+ /**
44
+ * Get description for a layer
45
+ */
46
+ private getLayerDescription;
47
+ /**
48
+ * Check if a dependency from one layer to another is allowed
49
+ */
50
+ isAllowedDependency(fromLayer: string, toLayer: string, layers?: Layers): boolean;
51
+ /**
52
+ * Find files with ambiguous layer assignments
53
+ */
54
+ findAmbiguousAssignments(filePaths: string[]): LayerAssignment[];
55
+ }
56
+ /**
57
+ * Create a layer detector with default patterns
58
+ */
59
+ export declare function createLayerDetector(customLayers?: Layers): LayerDetector;
60
+ //# sourceMappingURL=layer-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layer-detector.d.ts","sourceRoot":"","sources":["../../src/architecture/layer-detector.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAuB,MAAM,YAAY,CAAC;AAoJ/E;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,YAAY,CAAuB;gBAE/B,YAAY,CAAC,EAAE,MAAM;IAWjC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAexB;;;;;;OAMG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe;IAiF9C;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,eAAe,EAAE;IAIpD;;OAEG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC;IAanD;;OAEG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM;IAkB1C;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAY9B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAY3B;;OAEG;IACH,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO;IAiBjF;;OAEG;IACH,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,eAAe,EAAE;CAKjE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,aAAa,CAExE"}
@@ -0,0 +1,331 @@
1
+ /**
2
+ * Layer detection heuristics
3
+ *
4
+ * Detects architectural layers from directory structure and file patterns.
5
+ * Supports both single-app and monorepo project structures.
6
+ */
7
+ import { minimatch } from 'minimatch';
8
+ import { createDebugger } from '../utils/debug.js';
9
+ const debug = createDebugger('architecture');
10
+ /**
11
+ * Common source root directories that indicate where the actual source code starts
12
+ */
13
+ const SOURCE_ROOT_PATTERNS = ['src', 'lib', 'source', 'app'];
14
+ /**
15
+ * Default layer patterns with priorities
16
+ * Priority determines which layer wins when patterns overlap
17
+ */
18
+ const DEFAULT_LAYER_PATTERNS = [
19
+ {
20
+ layer: 'presentation',
21
+ patterns: [
22
+ '**/controllers/**',
23
+ '**/routes/**',
24
+ '**/api/**',
25
+ '**/handlers/**',
26
+ '**/endpoints/**',
27
+ '**/views/**',
28
+ '**/pages/**',
29
+ ],
30
+ priority: 1,
31
+ },
32
+ {
33
+ layer: 'application',
34
+ patterns: [
35
+ '**/services/**',
36
+ '**/use-cases/**',
37
+ '**/usecases/**',
38
+ '**/application/**',
39
+ '**/interactors/**',
40
+ ],
41
+ priority: 2,
42
+ },
43
+ {
44
+ layer: 'domain',
45
+ patterns: ['**/domain/**', '**/entities/**', '**/models/**', '**/core/**', '**/business/**'],
46
+ priority: 3,
47
+ },
48
+ {
49
+ layer: 'infrastructure',
50
+ patterns: [
51
+ '**/repositories/**',
52
+ '**/data/**',
53
+ '**/infrastructure/**',
54
+ '**/db/**',
55
+ '**/database/**',
56
+ '**/adapters/**',
57
+ '**/external/**',
58
+ '**/clients/**',
59
+ ],
60
+ priority: 4,
61
+ },
62
+ {
63
+ layer: 'shared',
64
+ patterns: [
65
+ '**/utils/**',
66
+ '**/lib/**',
67
+ '**/common/**',
68
+ '**/shared/**',
69
+ '**/helpers/**',
70
+ '**/types/**',
71
+ '**/constants/**',
72
+ '**/config/**',
73
+ ],
74
+ priority: 5,
75
+ },
76
+ ];
77
+ /**
78
+ * Extract the directory name that a pattern would match
79
+ * e.g., "**\/controllers\/**" -> "controllers"
80
+ */
81
+ function getPatternDirectoryName(pattern) {
82
+ // Match patterns like "**/controllers/**" or "src/controllers/**"
83
+ const match = pattern.match(/\*\*\/([^/*]+)\/\*\*/);
84
+ if (match) {
85
+ return match[1];
86
+ }
87
+ // Match patterns like "controllers/**"
88
+ const simpleMatch = pattern.match(/^([^/*]+)\/\*\*/);
89
+ if (simpleMatch) {
90
+ return simpleMatch[1];
91
+ }
92
+ return null;
93
+ }
94
+ /**
95
+ * Find the position of a directory in a path (index from end, 0-based)
96
+ * Returns -1 if not found
97
+ *
98
+ * For "packages/web/src/controllers/user.ts" and "controllers":
99
+ * - parts = ["packages", "web", "src", "controllers", "user.ts"]
100
+ * - "controllers" is at index 3, length is 5
101
+ * - position from end = 5 - 3 - 1 = 1 (1 directory from the file)
102
+ */
103
+ function getDirectoryPositionFromEnd(filePath, dirName) {
104
+ const parts = filePath.split('/');
105
+ const dirIndex = parts.findIndex((part) => part === dirName);
106
+ if (dirIndex === -1)
107
+ return -1;
108
+ return parts.length - dirIndex - 1;
109
+ }
110
+ /**
111
+ * Find the source root position in a path
112
+ * Returns the index of the first source root directory (src, lib, etc.)
113
+ * Returns -1 if no source root is found
114
+ */
115
+ function findSourceRootIndex(filePath) {
116
+ const parts = filePath.split('/');
117
+ for (let i = 0; i < parts.length; i++) {
118
+ if (SOURCE_ROOT_PATTERNS.includes(parts[i])) {
119
+ return i;
120
+ }
121
+ }
122
+ return -1;
123
+ }
124
+ /**
125
+ * Check if a directory name is likely a package/app name rather than a layer directory
126
+ * by checking if it appears before the source root
127
+ */
128
+ function isBeforeSourceRoot(filePath, dirName) {
129
+ const parts = filePath.split('/');
130
+ const dirIndex = parts.findIndex((part) => part === dirName);
131
+ const sourceRootIndex = findSourceRootIndex(filePath);
132
+ // If no source root found, can't determine
133
+ if (sourceRootIndex === -1)
134
+ return false;
135
+ // If the directory appears before the source root, it's likely a package name
136
+ return dirIndex < sourceRootIndex;
137
+ }
138
+ /**
139
+ * Layer detector using directory heuristics
140
+ */
141
+ export class LayerDetector {
142
+ patterns;
143
+ customLayers = null;
144
+ constructor(customLayers) {
145
+ if (customLayers) {
146
+ this.customLayers = customLayers;
147
+ this.patterns = this.layersToPatterns(customLayers);
148
+ debug('LayerDetector created with custom layers', Object.keys(customLayers));
149
+ }
150
+ else {
151
+ this.patterns = DEFAULT_LAYER_PATTERNS;
152
+ debug('LayerDetector created with default patterns');
153
+ }
154
+ }
155
+ /**
156
+ * Convert Layers config to LayerPattern array
157
+ */
158
+ layersToPatterns(layers) {
159
+ const result = [];
160
+ let priority = 1;
161
+ for (const [name, layer] of Object.entries(layers)) {
162
+ result.push({
163
+ layer: name,
164
+ patterns: layer.patterns,
165
+ priority: priority++,
166
+ });
167
+ }
168
+ return result;
169
+ }
170
+ /**
171
+ * Detect layer for a single file
172
+ *
173
+ * Uses position-aware matching to handle monorepo structures where package names
174
+ * may match layer patterns (e.g., packages/api/src/services/user.ts should match
175
+ * 'services', not 'api').
176
+ */
177
+ detectLayer(filePath) {
178
+ const matches = [];
179
+ // Normalise path separators
180
+ const normalisedPath = filePath.replace(/\\/g, '/');
181
+ for (const layerPattern of this.patterns) {
182
+ for (const pattern of layerPattern.patterns) {
183
+ if (minimatch(normalisedPath, pattern, { matchBase: true })) {
184
+ const dirName = getPatternDirectoryName(pattern);
185
+ const positionScore = dirName
186
+ ? getDirectoryPositionFromEnd(normalisedPath, dirName)
187
+ : 999;
188
+ const beforeSrcRoot = dirName ? isBeforeSourceRoot(normalisedPath, dirName) : false;
189
+ matches.push({
190
+ layer: layerPattern.layer,
191
+ pattern,
192
+ priority: layerPattern.priority,
193
+ positionScore,
194
+ isBeforeSrcRoot: beforeSrcRoot,
195
+ });
196
+ }
197
+ }
198
+ }
199
+ if (matches.length === 0) {
200
+ return {
201
+ file: filePath,
202
+ layer: null,
203
+ confidence: 'low',
204
+ };
205
+ }
206
+ // Filter out matches that are before the source root (likely package names)
207
+ // unless ALL matches are before the source root
208
+ const afterSrcRootMatches = matches.filter((m) => !m.isBeforeSrcRoot);
209
+ const effectiveMatches = afterSrcRootMatches.length > 0 ? afterSrcRootMatches : matches;
210
+ // Sort matches by:
211
+ // 1. Position score (closer to file = better, i.e., lower score)
212
+ // 2. Layer priority as tiebreaker (lower = higher priority)
213
+ effectiveMatches.sort((a, b) => {
214
+ // First compare position score
215
+ if (a.positionScore !== b.positionScore) {
216
+ return a.positionScore - b.positionScore;
217
+ }
218
+ // Then compare layer priority
219
+ return a.priority - b.priority;
220
+ });
221
+ const bestMatch = effectiveMatches[0];
222
+ // Determine confidence based on match quality
223
+ let confidence = 'high';
224
+ // If multiple layers matched, reduce confidence
225
+ const uniqueLayers = new Set(effectiveMatches.map((m) => m.layer));
226
+ if (uniqueLayers.size > 1) {
227
+ confidence = 'medium';
228
+ }
229
+ // If the best match was before source root, reduce confidence
230
+ if (bestMatch.isBeforeSrcRoot) {
231
+ confidence = 'medium';
232
+ }
233
+ return {
234
+ file: filePath,
235
+ layer: bestMatch.layer,
236
+ confidence,
237
+ matched_pattern: bestMatch.pattern,
238
+ };
239
+ }
240
+ /**
241
+ * Detect layers for multiple files
242
+ */
243
+ detectLayers(filePaths) {
244
+ return filePaths.map((path) => this.detectLayer(path));
245
+ }
246
+ /**
247
+ * Get all detected layers from a set of files
248
+ */
249
+ getDetectedLayers(filePaths) {
250
+ const layers = new Set();
251
+ for (const path of filePaths) {
252
+ const assignment = this.detectLayer(path);
253
+ if (assignment.layer) {
254
+ layers.add(assignment.layer);
255
+ }
256
+ }
257
+ return layers;
258
+ }
259
+ /**
260
+ * Suggest layer structure based on detected patterns
261
+ */
262
+ suggestLayers(filePaths) {
263
+ const detectedLayers = this.getDetectedLayers(filePaths);
264
+ const result = {};
265
+ // Only include layers that were actually detected
266
+ for (const layerPattern of this.patterns) {
267
+ if (detectedLayers.has(layerPattern.layer)) {
268
+ result[layerPattern.layer] = {
269
+ patterns: layerPattern.patterns,
270
+ depends_on: this.getDefaultDependencies(layerPattern.layer),
271
+ description: this.getLayerDescription(layerPattern.layer),
272
+ };
273
+ }
274
+ }
275
+ return result;
276
+ }
277
+ /**
278
+ * Get default dependencies for a layer
279
+ */
280
+ getDefaultDependencies(layer) {
281
+ const deps = {
282
+ presentation: ['application', 'shared'],
283
+ application: ['domain', 'infrastructure', 'shared'],
284
+ domain: ['shared'],
285
+ infrastructure: ['domain', 'shared'],
286
+ shared: [],
287
+ };
288
+ return deps[layer] ?? [];
289
+ }
290
+ /**
291
+ * Get description for a layer
292
+ */
293
+ getLayerDescription(layer) {
294
+ const descriptions = {
295
+ presentation: 'HTTP handlers, controllers, API routes',
296
+ application: 'Business logic, use cases, services',
297
+ domain: 'Domain entities, value objects, domain logic',
298
+ infrastructure: 'Data access, external services, infrastructure',
299
+ shared: 'Shared utilities, helpers, common code',
300
+ };
301
+ return descriptions[layer] ?? `${layer} layer`;
302
+ }
303
+ /**
304
+ * Check if a dependency from one layer to another is allowed
305
+ */
306
+ isAllowedDependency(fromLayer, toLayer, layers) {
307
+ const layerConfig = layers ?? this.customLayers;
308
+ if (!layerConfig) {
309
+ // Use default rules
310
+ const defaultDeps = this.getDefaultDependencies(fromLayer);
311
+ return fromLayer === toLayer || defaultDeps.includes(toLayer);
312
+ }
313
+ const fromLayerConfig = layerConfig[fromLayer];
314
+ if (!fromLayerConfig) {
315
+ return true; // Unknown layer, allow
316
+ }
317
+ return fromLayer === toLayer || fromLayerConfig.depends_on.includes(toLayer);
318
+ }
319
+ /**
320
+ * Find files with ambiguous layer assignments
321
+ */
322
+ findAmbiguousAssignments(filePaths) {
323
+ return this.detectLayers(filePaths).filter((a) => a.confidence === 'medium' || a.confidence === 'low');
324
+ }
325
+ }
326
+ /**
327
+ * Create a layer detector with default patterns
328
+ */
329
+ export function createLayerDetector(customLayers) {
330
+ return new LayerDetector(customLayers);
331
+ }
@@ -0,0 +1,25 @@
1
+ import type { ArchitectureDefinition } from './definition-schema.js';
2
+ export declare const GENERATED_POLICIES_DIR = ".anvil/policies/.generated";
3
+ export declare const REGO_FILENAME = "architecture.rego";
4
+ export declare const REGO_PACKAGE = "anvil.policies.architecture";
5
+ /**
6
+ * Get the path to the generated Rego file
7
+ */
8
+ export declare function getRegoPath(workspaceRoot: string): string;
9
+ /**
10
+ * Check if generated Rego file exists
11
+ */
12
+ export declare function regoExists(workspaceRoot: string): boolean;
13
+ /**
14
+ * Check if Rego needs regeneration based on definition hash
15
+ */
16
+ export declare function needsRegoRegeneration(workspaceRoot: string, definition: ArchitectureDefinition): Promise<boolean>;
17
+ /**
18
+ * Write generated Rego policy file
19
+ */
20
+ export declare function writeRegoPolicy(workspaceRoot: string, definition: ArchitectureDefinition): Promise<string>;
21
+ /**
22
+ * Generate Rego policy content from architecture definition
23
+ */
24
+ export declare function generateRegoPolicy(definition: ArchitectureDefinition): string;
25
+ //# sourceMappingURL=rego-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rego-generator.d.ts","sourceRoot":"","sources":["../../src/architecture/rego-generator.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAKrE,eAAO,MAAM,sBAAsB,+BAA+B,CAAC;AACnE,eAAO,MAAM,aAAa,sBAAsB,CAAC;AACjD,eAAO,MAAM,YAAY,gCAAgC,CAAC;AAE1D;;GAEG;AACH,wBAAgB,WAAW,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,sBAAsB,GACjC,OAAO,CAAC,OAAO,CAAC,CAYlB;AAOD;;GAEG;AACH,wBAAsB,eAAe,CACnC,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,sBAAsB,GACjC,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,sBAAsB,GAAG,MAAM,CA8K7E"}