@mortice/mapwright 0.8.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 (166) hide show
  1. package/CHANGELOG.md +161 -0
  2. package/LICENSE +21 -0
  3. package/README.md +262 -0
  4. package/dist/catalogue/canonicalisation.d.ts +36 -0
  5. package/dist/catalogue/canonicalisation.js +262 -0
  6. package/dist/catalogue/config.d.ts +13 -0
  7. package/dist/catalogue/config.js +77 -0
  8. package/dist/catalogue/deterministic.d.ts +3 -0
  9. package/dist/catalogue/deterministic.js +25 -0
  10. package/dist/catalogue/diagnostics.d.ts +2 -0
  11. package/dist/catalogue/diagnostics.js +34 -0
  12. package/dist/catalogue/evidence.d.ts +1 -0
  13. package/dist/catalogue/evidence.js +10 -0
  14. package/dist/catalogue/examples.d.ts +3 -0
  15. package/dist/catalogue/examples.js +20 -0
  16. package/dist/catalogue/identity.d.ts +61 -0
  17. package/dist/catalogue/identity.js +114 -0
  18. package/dist/catalogue/ignore.d.ts +4 -0
  19. package/dist/catalogue/ignore.js +29 -0
  20. package/dist/catalogue/indexer.d.ts +20 -0
  21. package/dist/catalogue/indexer.js +1393 -0
  22. package/dist/catalogue/linkage.d.ts +16 -0
  23. package/dist/catalogue/linkage.js +419 -0
  24. package/dist/catalogue/moduleResolution.d.ts +4 -0
  25. package/dist/catalogue/moduleResolution.js +67 -0
  26. package/dist/catalogue/ordering.d.ts +13 -0
  27. package/dist/catalogue/ordering.js +86 -0
  28. package/dist/catalogue/packages.d.ts +12 -0
  29. package/dist/catalogue/packages.js +475 -0
  30. package/dist/catalogue/pythonReExports.d.ts +7 -0
  31. package/dist/catalogue/pythonReExports.js +113 -0
  32. package/dist/catalogue/resolveRefs.d.ts +40 -0
  33. package/dist/catalogue/resolveRefs.js +284 -0
  34. package/dist/catalogue/scanner.d.ts +8 -0
  35. package/dist/catalogue/scanner.js +99 -0
  36. package/dist/catalogue/schema.d.ts +289 -0
  37. package/dist/catalogue/schema.js +1 -0
  38. package/dist/catalogue/store.d.ts +41 -0
  39. package/dist/catalogue/store.js +209 -0
  40. package/dist/catalogue/templates.d.ts +18 -0
  41. package/dist/catalogue/templates.js +158 -0
  42. package/dist/catalogue/version.d.ts +12 -0
  43. package/dist/catalogue/version.js +30 -0
  44. package/dist/cli/commands/adoptionPlan.d.ts +8 -0
  45. package/dist/cli/commands/adoptionPlan.js +24 -0
  46. package/dist/cli/commands/auditDocs.d.ts +8 -0
  47. package/dist/cli/commands/auditDocs.js +24 -0
  48. package/dist/cli/commands/changeImpact.d.ts +10 -0
  49. package/dist/cli/commands/changeImpact.js +36 -0
  50. package/dist/cli/commands/changes.d.ts +12 -0
  51. package/dist/cli/commands/changes.js +31 -0
  52. package/dist/cli/commands/check.d.ts +9 -0
  53. package/dist/cli/commands/check.js +4 -0
  54. package/dist/cli/commands/compatibility.d.ts +10 -0
  55. package/dist/cli/commands/compatibility.js +43 -0
  56. package/dist/cli/commands/diff.d.ts +31 -0
  57. package/dist/cli/commands/diff.js +118 -0
  58. package/dist/cli/commands/dogfood.d.ts +8 -0
  59. package/dist/cli/commands/dogfood.js +24 -0
  60. package/dist/cli/commands/drift.d.ts +8 -0
  61. package/dist/cli/commands/drift.js +13 -0
  62. package/dist/cli/commands/index.d.ts +9 -0
  63. package/dist/cli/commands/index.js +9 -0
  64. package/dist/cli/commands/indexWorkspace.d.ts +8 -0
  65. package/dist/cli/commands/indexWorkspace.js +23 -0
  66. package/dist/cli/commands/recommendConfig.d.ts +7 -0
  67. package/dist/cli/commands/recommendConfig.js +20 -0
  68. package/dist/cli/commands/schema.d.ts +1 -0
  69. package/dist/cli/commands/schema.js +37 -0
  70. package/dist/cli/commands/template.d.ts +5 -0
  71. package/dist/cli/commands/template.js +44 -0
  72. package/dist/cli/commands/validate.d.ts +9 -0
  73. package/dist/cli/commands/validate.js +85 -0
  74. package/dist/cli/index.d.ts +2 -0
  75. package/dist/cli/index.js +211 -0
  76. package/dist/comparison/artefactValidate.d.ts +19 -0
  77. package/dist/comparison/artefactValidate.js +334 -0
  78. package/dist/comparison/candidates.d.ts +12 -0
  79. package/dist/comparison/candidates.js +391 -0
  80. package/dist/comparison/compare.d.ts +15 -0
  81. package/dist/comparison/compare.js +240 -0
  82. package/dist/comparison/compatibility.d.ts +26 -0
  83. package/dist/comparison/compatibility.js +316 -0
  84. package/dist/comparison/drift.d.ts +34 -0
  85. package/dist/comparison/drift.js +71 -0
  86. package/dist/comparison/identity.d.ts +30 -0
  87. package/dist/comparison/identity.js +73 -0
  88. package/dist/comparison/impact.d.ts +14 -0
  89. package/dist/comparison/impact.js +291 -0
  90. package/dist/comparison/index.d.ts +6 -0
  91. package/dist/comparison/index.js +6 -0
  92. package/dist/comparison/integrity.d.ts +12 -0
  93. package/dist/comparison/integrity.js +199 -0
  94. package/dist/comparison/ordering.d.ts +4 -0
  95. package/dist/comparison/ordering.js +69 -0
  96. package/dist/comparison/projections.d.ts +19 -0
  97. package/dist/comparison/projections.js +185 -0
  98. package/dist/comparison/relationshipPolicy.d.ts +19 -0
  99. package/dist/comparison/relationshipPolicy.js +98 -0
  100. package/dist/comparison/schema.d.ts +178 -0
  101. package/dist/comparison/schema.js +16 -0
  102. package/dist/comparison/store.d.ts +58 -0
  103. package/dist/comparison/store.js +462 -0
  104. package/dist/comparison/validate.d.ts +23 -0
  105. package/dist/comparison/validate.js +137 -0
  106. package/dist/comparison/version.d.ts +9 -0
  107. package/dist/comparison/version.js +11 -0
  108. package/dist/extractors/docTags.d.ts +9 -0
  109. package/dist/extractors/docTags.js +106 -0
  110. package/dist/extractors/generic.d.ts +5 -0
  111. package/dist/extractors/generic.js +3 -0
  112. package/dist/extractors/javascript.d.ts +3 -0
  113. package/dist/extractors/javascript.js +4 -0
  114. package/dist/extractors/markdown.d.ts +7 -0
  115. package/dist/extractors/markdown.js +269 -0
  116. package/dist/extractors/python.d.ts +7 -0
  117. package/dist/extractors/python.js +314 -0
  118. package/dist/extractors/typescript.d.ts +7 -0
  119. package/dist/extractors/typescript.js +387 -0
  120. package/dist/index.d.ts +2 -0
  121. package/dist/index.js +2 -0
  122. package/dist/mcp/resources.d.ts +18 -0
  123. package/dist/mcp/resources.js +57 -0
  124. package/dist/mcp/server.d.ts +2 -0
  125. package/dist/mcp/server.js +95 -0
  126. package/dist/mcp/tools.d.ts +29 -0
  127. package/dist/mcp/tools.js +902 -0
  128. package/dist/queries/adoption.d.ts +62 -0
  129. package/dist/queries/adoption.js +366 -0
  130. package/dist/queries/capabilities.d.ts +45 -0
  131. package/dist/queries/capabilities.js +124 -0
  132. package/dist/queries/changes.d.ts +33 -0
  133. package/dist/queries/changes.js +53 -0
  134. package/dist/queries/dependencies.d.ts +17 -0
  135. package/dist/queries/dependencies.js +94 -0
  136. package/dist/queries/dogfood.d.ts +50 -0
  137. package/dist/queries/dogfood.js +116 -0
  138. package/dist/queries/editingContext.d.ts +84 -0
  139. package/dist/queries/editingContext.js +240 -0
  140. package/dist/queries/examples.d.ts +8 -0
  141. package/dist/queries/examples.js +16 -0
  142. package/dist/queries/files.d.ts +8 -0
  143. package/dist/queries/files.js +14 -0
  144. package/dist/queries/lists.d.ts +94 -0
  145. package/dist/queries/lists.js +184 -0
  146. package/dist/queries/overview.d.ts +2 -0
  147. package/dist/queries/overview.js +8 -0
  148. package/dist/queries/publicApis.d.ts +60 -0
  149. package/dist/queries/publicApis.js +120 -0
  150. package/dist/queries/ranking.d.ts +67 -0
  151. package/dist/queries/ranking.js +387 -0
  152. package/dist/queries/recommendConfig.d.ts +47 -0
  153. package/dist/queries/recommendConfig.js +123 -0
  154. package/dist/queries/relationships.d.ts +5 -0
  155. package/dist/queries/relationships.js +15 -0
  156. package/dist/queries/reuseCandidates.d.ts +34 -0
  157. package/dist/queries/reuseCandidates.js +181 -0
  158. package/dist/queries/symbols.d.ts +40 -0
  159. package/dist/queries/symbols.js +41 -0
  160. package/dist/security/pathPolicy.d.ts +12 -0
  161. package/dist/security/pathPolicy.js +46 -0
  162. package/dist/security/secretPatterns.d.ts +1 -0
  163. package/dist/security/secretPatterns.js +4 -0
  164. package/dist/security/sourceAccess.d.ts +12 -0
  165. package/dist/security/sourceAccess.js +35 -0
  166. package/package.json +60 -0
@@ -0,0 +1,185 @@
1
+ function sortedUnique(values) {
2
+ return [...new Set(values ?? [])].sort();
3
+ }
4
+ function equalJson(a, b) {
5
+ return JSON.stringify(a) === JSON.stringify(b);
6
+ }
7
+ function pushFacet(facets, facet, oldValue, newValue) {
8
+ if (!equalJson(oldValue, newValue)) {
9
+ facets.push({ facet, oldValue, newValue });
10
+ }
11
+ }
12
+ function pushUnavailable(facets, facet, oldValue, newValue) {
13
+ if (oldValue == null && newValue == null) {
14
+ return;
15
+ }
16
+ if (oldValue == null || newValue == null) {
17
+ facets.push({ facet, oldValue, newValue, evidenceUnavailable: true });
18
+ return;
19
+ }
20
+ pushFacet(facets, facet, oldValue, newValue);
21
+ }
22
+ /** Strip line/column ranges from relationship evidence for semantic comparison. */
23
+ export function semanticRelationshipEvidence(evidence) {
24
+ if (evidence == null)
25
+ return null;
26
+ if (Array.isArray(evidence)) {
27
+ return evidence.map((item) => semanticRelationshipEvidence(item));
28
+ }
29
+ if (typeof evidence !== "object")
30
+ return evidence;
31
+ const rec = evidence;
32
+ const out = {};
33
+ for (const [key, value] of Object.entries(rec)) {
34
+ if (key === "line" ||
35
+ key === "startLine" ||
36
+ key === "endLine" ||
37
+ key === "startColumn" ||
38
+ key === "endColumn" ||
39
+ key === "column") {
40
+ continue;
41
+ }
42
+ out[key] = value;
43
+ }
44
+ return out;
45
+ }
46
+ export function recordKey(domain, record) {
47
+ if (domain === "files") {
48
+ return String(record.path ?? "");
49
+ }
50
+ return String(record.id ?? "");
51
+ }
52
+ export function indexDomain(domain, snapshot) {
53
+ const map = new Map();
54
+ const collection = collectionFor(domain, snapshot);
55
+ for (const item of collection) {
56
+ const rec = item;
57
+ const key = recordKey(domain, rec);
58
+ if (key) {
59
+ map.set(key, rec);
60
+ }
61
+ }
62
+ return map;
63
+ }
64
+ function collectionFor(domain, snapshot) {
65
+ switch (domain) {
66
+ case "packages":
67
+ return snapshot.packages;
68
+ case "files":
69
+ return snapshot.files;
70
+ case "symbols":
71
+ return snapshot.symbols;
72
+ case "publicApis":
73
+ return snapshot.publicApis;
74
+ case "tests":
75
+ return snapshot.tests;
76
+ case "examples":
77
+ return snapshot.examples;
78
+ case "capabilities":
79
+ return snapshot.capabilities;
80
+ case "relationships":
81
+ return snapshot.relationships;
82
+ case "diagnostics":
83
+ return snapshot.diagnostics;
84
+ }
85
+ }
86
+ /** Same-ID facet projection for a modified pair. Identity fields are not compared here. */
87
+ export function projectFacets(domain, base, head) {
88
+ const facets = [];
89
+ switch (domain) {
90
+ case "symbols":
91
+ pushUnavailable(facets, "signature_changed", base.signatureFingerprint, head.signatureFingerprint);
92
+ if (base.signatureFingerprint != null &&
93
+ head.signatureFingerprint != null &&
94
+ base.signatureFingerprint === head.signatureFingerprint) {
95
+ pushUnavailable(facets, "implementation_changed", base.implementationFingerprint, head.implementationFingerprint);
96
+ }
97
+ else if (base.signatureFingerprint != null &&
98
+ head.signatureFingerprint != null &&
99
+ base.signatureFingerprint !== head.signatureFingerprint) {
100
+ pushUnavailable(facets, "implementation_changed", base.implementationFingerprint, head.implementationFingerprint);
101
+ }
102
+ pushFacet(facets, "documentation_changed", base.doc ?? null, head.doc ?? null);
103
+ // module/file path may change without identity change only when identity excludes path;
104
+ // for same-ID symbols, path is typically identity — still allow modulePath facet when present as non-identity display
105
+ pushFacet(facets, "module_path_changed", base.modulePath ?? null, head.modulePath ?? null);
106
+ pushFacet(facets, "file_path_changed", base.filePath ?? null, head.filePath ?? null);
107
+ // Raw source ranges are display/evidence only — never semantic location_changed
108
+ pushFacet(facets, "visibility_changed", base.visibility ?? null, head.visibility ?? null);
109
+ pushFacet(facets, "export_status_changed", base.exported ?? null, head.exported ?? null);
110
+ pushFacet(facets, "canonical_target_changed", base.canonicalSymbolId ?? null, head.canonicalSymbolId ?? null);
111
+ pushFacet(facets, "capability_links_changed", sortedUnique(base.capabilities), sortedUnique(head.capabilities));
112
+ break;
113
+ case "publicApis":
114
+ pushFacet(facets, "implementation_target_changed", base.symbolId ?? null, head.symbolId ?? null);
115
+ pushFacet(facets, "documentation_changed", base.intendedUse ?? null, head.intendedUse ?? null);
116
+ pushFacet(facets, "stability_changed", base.stability ?? null, head.stability ?? null);
117
+ pushFacet(facets, "contracts_changed", sortedUnique(base.contracts), sortedUnique(head.contracts));
118
+ pushFacet(facets, "errors_changed", sortedUnique(base.errors), sortedUnique(head.errors));
119
+ pushFacet(facets, "capability_links_changed", sortedUnique(base.capabilityIds), sortedUnique(head.capabilityIds));
120
+ pushFacet(facets, "example_links_changed", sortedUnique(base.examples), sortedUnique(head.examples));
121
+ pushFacet(facets, "test_links_changed", sortedUnique(base.tests), sortedUnique(head.tests));
122
+ pushUnavailable(facets, "signature_changed", base.signature ?? null, head.signature ?? null);
123
+ break;
124
+ case "packages":
125
+ pushFacet(facets, "public_apis_changed", sortedUnique(base.publicApis), sortedUnique(head.publicApis));
126
+ pushFacet(facets, "tests_changed", sortedUnique(base.tests), sortedUnique(head.tests));
127
+ pushFacet(facets, "capabilities_changed", sortedUnique(base.capabilities), sortedUnique(head.capabilities));
128
+ pushFacet(facets, "entrypoints_changed", base.entrypoints ?? null, head.entrypoints ?? null);
129
+ pushFacet(facets, "console_scripts_changed", normalizeConsoleScripts(base.consoleScripts), normalizeConsoleScripts(head.consoleScripts));
130
+ pushFacet(facets, "import_packages_changed", sortedUnique(base.importPackages), sortedUnique(head.importPackages));
131
+ break;
132
+ case "files":
133
+ pushFacet(facets, "content_fingerprint_changed", base.hash ?? null, head.hash ?? null);
134
+ pushFacet(facets, "public_surface_changed", sortedUnique(base.publicApis), sortedUnique(head.publicApis));
135
+ break;
136
+ case "relationships":
137
+ pushFacet(facets, "evidence_changed", semanticRelationshipEvidence(base.evidence ?? base.evidenceRanges ?? null), semanticRelationshipEvidence(head.evidence ?? head.evidenceRanges ?? null));
138
+ pushFacet(facets, "confidence_changed", base.confidence ?? null, head.confidence ?? null);
139
+ pushFacet(facets, "local_discriminant_changed", base.localDiscriminant ?? null, head.localDiscriminant ?? null);
140
+ break;
141
+ case "diagnostics":
142
+ pushFacet(facets, "severity_changed", base.severity ?? null, head.severity ?? null);
143
+ pushFacet(facets, "documentation_changed", base.message ?? null, head.message ?? null);
144
+ break;
145
+ case "tests":
146
+ pushFacet(facets, "test_links_changed", sortedUnique(base.coversPublicApis), sortedUnique(head.coversPublicApis));
147
+ pushFacet(facets, "capability_links_changed", sortedUnique(base.coversCapabilities), sortedUnique(head.coversCapabilities));
148
+ break;
149
+ case "examples":
150
+ pushFacet(facets, "example_links_changed", sortedUnique(base.publicApiIds), sortedUnique(head.publicApiIds));
151
+ pushFacet(facets, "documentation_changed", base.summary ?? null, head.summary ?? null);
152
+ break;
153
+ case "capabilities":
154
+ pushFacet(facets, "public_apis_changed", sortedUnique(base.publicApis), sortedUnique(head.publicApis));
155
+ pushFacet(facets, "documentation_changed", base.summary ?? null, head.summary ?? null);
156
+ break;
157
+ }
158
+ return facets;
159
+ }
160
+ export function normalizeConsoleScripts(value) {
161
+ if (!Array.isArray(value))
162
+ return [];
163
+ return value
164
+ .map((item) => {
165
+ if (!item || typeof item !== "object")
166
+ return null;
167
+ const rec = item;
168
+ const name = String(rec.name ?? "");
169
+ const target = String(rec.target ?? "");
170
+ if (!name)
171
+ return null;
172
+ return { name, target };
173
+ })
174
+ .filter((x) => x != null)
175
+ .sort((a, b) => a.name.localeCompare(b.name) || a.target.localeCompare(b.target));
176
+ }
177
+ export function displayFields(domain, record) {
178
+ return {
179
+ packageId: record.packageId ?? null,
180
+ importPath: record.importPath ?? null,
181
+ modulePath: record.modulePath ?? record.path ?? null,
182
+ qualifiedName: record.qualifiedName ?? null,
183
+ name: record.name ?? null
184
+ };
185
+ }
@@ -0,0 +1,19 @@
1
+ import type { RelationshipType } from "../catalogue/schema.js";
2
+ /**
3
+ * Relationship direction policy for impact analysis.
4
+ * Dependant-impact follows the reverse of the dependency direction:
5
+ * changed dependency/API → find consumers (dependants).
6
+ */
7
+ export interface RelationshipImpactPolicy {
8
+ type: RelationshipType | string;
9
+ /** Endpoint that owns/provides the dependency (semantic target of consumption). */
10
+ dependencyEndpoint: "from" | "to";
11
+ /** Endpoint that depends on / consumes the other. */
12
+ dependantEndpoint: "from" | "to";
13
+ participatesInImpact: boolean;
14
+ /** When true, impact BFS walks from changed node toward dependants. */
15
+ reverseTraversalForImpact: boolean;
16
+ }
17
+ export declare function getRelationshipImpactPolicy(type: string): RelationshipImpactPolicy;
18
+ /** Normalize catalogue relationship endpoint kinds to graph-index kinds. */
19
+ export declare function normalizeEndpointKind(kind: string): string;
@@ -0,0 +1,98 @@
1
+ const POLICY = {
2
+ imports: {
3
+ type: "imports",
4
+ dependencyEndpoint: "to",
5
+ dependantEndpoint: "from",
6
+ participatesInImpact: true,
7
+ reverseTraversalForImpact: true
8
+ },
9
+ exports: {
10
+ type: "exports",
11
+ dependencyEndpoint: "to",
12
+ dependantEndpoint: "from",
13
+ participatesInImpact: true,
14
+ reverseTraversalForImpact: true
15
+ },
16
+ tests: {
17
+ type: "tests",
18
+ dependencyEndpoint: "to",
19
+ dependantEndpoint: "from",
20
+ participatesInImpact: true,
21
+ reverseTraversalForImpact: true
22
+ },
23
+ covers: {
24
+ type: "covers",
25
+ dependencyEndpoint: "to",
26
+ dependantEndpoint: "from",
27
+ participatesInImpact: true,
28
+ reverseTraversalForImpact: true
29
+ },
30
+ explicit_coverage: {
31
+ type: "explicit_coverage",
32
+ dependencyEndpoint: "to",
33
+ dependantEndpoint: "from",
34
+ participatesInImpact: true,
35
+ reverseTraversalForImpact: true
36
+ },
37
+ explicit_example: {
38
+ type: "explicit_example",
39
+ dependencyEndpoint: "to",
40
+ dependantEndpoint: "from",
41
+ participatesInImpact: true,
42
+ reverseTraversalForImpact: true
43
+ },
44
+ resolved_direct_import: {
45
+ type: "resolved_direct_import",
46
+ dependencyEndpoint: "to",
47
+ dependantEndpoint: "from",
48
+ participatesInImpact: true,
49
+ reverseTraversalForImpact: true
50
+ },
51
+ resolved_direct_usage: {
52
+ type: "resolved_direct_usage",
53
+ dependencyEndpoint: "to",
54
+ dependantEndpoint: "from",
55
+ participatesInImpact: true,
56
+ reverseTraversalForImpact: true
57
+ },
58
+ defines: {
59
+ type: "defines",
60
+ dependencyEndpoint: "to",
61
+ dependantEndpoint: "from",
62
+ participatesInImpact: false,
63
+ reverseTraversalForImpact: false
64
+ },
65
+ contains: {
66
+ type: "contains",
67
+ dependencyEndpoint: "to",
68
+ dependantEndpoint: "from",
69
+ participatesInImpact: false,
70
+ reverseTraversalForImpact: false
71
+ },
72
+ documents: {
73
+ type: "documents",
74
+ dependencyEndpoint: "to",
75
+ dependantEndpoint: "from",
76
+ participatesInImpact: true,
77
+ reverseTraversalForImpact: true
78
+ }
79
+ };
80
+ export function getRelationshipImpactPolicy(type) {
81
+ return (POLICY[type] ?? {
82
+ type,
83
+ dependencyEndpoint: "to",
84
+ dependantEndpoint: "from",
85
+ participatesInImpact: false,
86
+ reverseTraversalForImpact: false
87
+ });
88
+ }
89
+ /** Normalize catalogue relationship endpoint kinds to graph-index kinds. */
90
+ export function normalizeEndpointKind(kind) {
91
+ const map = {
92
+ publicApi: "public-api",
93
+ "public-api": "public-api",
94
+ externalPackage: "external-package",
95
+ "external-package": "external-package"
96
+ };
97
+ return map[kind] ?? kind;
98
+ }
@@ -0,0 +1,178 @@
1
+ /** Comparison contract types (comparisonSchemaVersion 1). */
2
+ export type RecordDomain = "packages" | "files" | "symbols" | "publicApis" | "tests" | "examples" | "capabilities" | "relationships" | "diagnostics";
3
+ export type FactualChangeKind = "added" | "removed" | "unchanged" | "modified";
4
+ export type CompatibilityClassification = "breaking" | "potentially_breaking" | "non_breaking" | "documentation_only" | "unknown" | "not_applicable";
5
+ export type ConfidenceCategory = "high" | "medium" | "low" | "ambiguous";
6
+ export type ImpactEvidenceLevel = "direct_evidence" | "transitive_inference" | "possible_impact";
7
+ export type DriftStatus = "no_drift" | "non_public_drift" | "public_surface_drift" | "breaking_public_drift" | "unknown";
8
+ export type RegenerationRecommendation = "none" | "catalogue_regeneration_recommended" | "catalogue_regeneration_required";
9
+ export type ComparisonErrorCode = "comparison_base_not_found" | "comparison_head_not_found" | "comparison_catalogue_invalid" | "comparison_schema_unsupported" | "comparison_identity_scheme_unsupported" | "comparison_identity_scheme_mismatch" | "comparison_identity_mismatch" | "comparison_referential_integrity_failed" | "comparison_artifact_invalid" | "comparison_lock_mismatch" | "comparison_path_rejected" | "comparison_artifact_too_large";
10
+ export interface ComparisonError {
11
+ code: ComparisonErrorCode;
12
+ message: string;
13
+ details?: unknown;
14
+ }
15
+ export interface ComparisonOptions {
16
+ enabledDomains: RecordDomain[];
17
+ normalizationPolicyId: string;
18
+ includeUnchanged: boolean;
19
+ }
20
+ export declare const DEFAULT_COMPARISON_OPTIONS: ComparisonOptions;
21
+ export interface FacetDiff {
22
+ facet: string;
23
+ oldValue: unknown;
24
+ newValue: unknown;
25
+ evidenceUnavailable?: boolean;
26
+ }
27
+ export interface ChangeRecord {
28
+ id: string;
29
+ domain: RecordDomain;
30
+ status: FactualChangeKind;
31
+ baseRecordId: string | null;
32
+ headRecordId: string | null;
33
+ /** Discriminator used when encoding change identity; null for plain factual changes. */
34
+ identityDiscriminator?: string | null;
35
+ packageId?: string | null;
36
+ importPath?: string | null;
37
+ modulePath?: string | null;
38
+ qualifiedName?: string | null;
39
+ name?: string | null;
40
+ facets: FacetDiff[];
41
+ }
42
+ export interface CompatibilityFinding {
43
+ id: string;
44
+ classification: CompatibilityClassification;
45
+ ruleId: string;
46
+ ruleVersion: string;
47
+ language: string;
48
+ publicApiId?: string | null;
49
+ changeId?: string | null;
50
+ /** Exact identity inputs used when encoding the finding ID. */
51
+ identityBaseRecordId?: string | null;
52
+ identityHeadRecordId?: string | null;
53
+ identityDiscriminator?: string | null;
54
+ changedFacets: string[];
55
+ evidence: string[];
56
+ limitations: string[];
57
+ confidence: ConfidenceCategory;
58
+ }
59
+ export interface TransitionCandidate {
60
+ id: string;
61
+ candidateKind: "probable_move" | "probable_rename" | "probable_move_and_rename" | "possible_replacement" | "ambiguous_candidate" | "public_surface_transition";
62
+ domain: RecordDomain;
63
+ baseRecordId: string;
64
+ headRecordId: string;
65
+ /** Discriminator used when encoding candidate identity. */
66
+ identityDiscriminator?: string | null;
67
+ confidence: ConfidenceCategory;
68
+ evidenceReasons: string[];
69
+ conflictingEvidence: string[];
70
+ alternativeCandidateIds: string[];
71
+ ambiguity: boolean;
72
+ transitionFacets: string[];
73
+ }
74
+ export interface ImpactPathEdge {
75
+ snapshot: "base" | "head";
76
+ relationshipType: string;
77
+ fromKind: string;
78
+ fromId: string;
79
+ toKind: string;
80
+ toId: string;
81
+ provenance?: string;
82
+ evidenceLevel: ImpactEvidenceLevel;
83
+ }
84
+ export interface ImpactSection {
85
+ total: number;
86
+ returned: number;
87
+ offset: number;
88
+ limit: number;
89
+ truncated: boolean;
90
+ /** Present when work budget prevented a complete enumeration. */
91
+ totalIsLowerBound?: boolean;
92
+ traversalIncomplete?: boolean;
93
+ records: Array<{
94
+ id: string;
95
+ kind: string;
96
+ packageId?: string | null;
97
+ qualifiedName?: string | null;
98
+ pathLength: number;
99
+ evidenceLevel: ImpactEvidenceLevel;
100
+ path: ImpactPathEdge[];
101
+ }>;
102
+ }
103
+ export interface ChangeImpactResult {
104
+ changeId: string;
105
+ baseImpact: ImpactSection;
106
+ headImpact: ImpactSection;
107
+ retainedImpact: ImpactSection;
108
+ removedImpact: ImpactSection;
109
+ addedImpact: ImpactSection;
110
+ possibleImpact: ImpactSection;
111
+ }
112
+ export interface DomainUnchangedCounts {
113
+ packages: number;
114
+ files: number;
115
+ symbols: number;
116
+ publicApis: number;
117
+ tests: number;
118
+ examples: number;
119
+ capabilities: number;
120
+ relationships: number;
121
+ diagnostics: number;
122
+ }
123
+ export interface ComparisonManifest {
124
+ comparisonSchemaVersion: number;
125
+ changeContractVersion: string;
126
+ compatibilityRuleVersion: string;
127
+ comparisonIdentityScheme: string;
128
+ comparisonProjectionVersion: string;
129
+ candidateDetectionPolicyVersion: string;
130
+ comparisonId: string;
131
+ baseCatalogueId: string;
132
+ headCatalogueId: string;
133
+ baseGeneratorVersion: string | null;
134
+ headGeneratorVersion: string | null;
135
+ comparisonGeneratorVersion: string;
136
+ options: ComparisonOptions;
137
+ counts: {
138
+ added: number;
139
+ removed: number;
140
+ modified: number;
141
+ unchanged: DomainUnchangedCounts;
142
+ compatibilityFindings: number;
143
+ candidates: number;
144
+ };
145
+ aggregateCompatibility: CompatibilityClassification | null;
146
+ }
147
+ export interface ComparisonSnapshot {
148
+ manifest: ComparisonManifest;
149
+ changes: ChangeRecord[];
150
+ compatibilityFindings: CompatibilityFinding[];
151
+ candidates: TransitionCandidate[];
152
+ /** Minimal relationship indexes for Model A source-free impact. */
153
+ graphIndex: {
154
+ base: Array<{
155
+ id?: string;
156
+ type: string;
157
+ fromKind: string;
158
+ fromId: string;
159
+ toKind: string;
160
+ toId: string;
161
+ provenance?: string;
162
+ localDiscriminant?: string | null;
163
+ confidence?: number;
164
+ }>;
165
+ head: Array<{
166
+ id?: string;
167
+ type: string;
168
+ fromKind: string;
169
+ fromId: string;
170
+ toKind: string;
171
+ toId: string;
172
+ provenance?: string;
173
+ localDiscriminant?: string | null;
174
+ confidence?: number;
175
+ }>;
176
+ };
177
+ warnings?: string[];
178
+ }
@@ -0,0 +1,16 @@
1
+ /** Comparison contract types (comparisonSchemaVersion 1). */
2
+ export const DEFAULT_COMPARISON_OPTIONS = {
3
+ enabledDomains: [
4
+ "packages",
5
+ "files",
6
+ "symbols",
7
+ "publicApis",
8
+ "tests",
9
+ "examples",
10
+ "capabilities",
11
+ "relationships",
12
+ "diagnostics"
13
+ ],
14
+ normalizationPolicyId: "default-v1",
15
+ includeUnchanged: false
16
+ };
@@ -0,0 +1,58 @@
1
+ import type { ComparisonError, ComparisonSnapshot } from "./schema.js";
2
+ export declare const COMPARISON_OUTPUT_FILES: {
3
+ readonly comparison: "comparison.json";
4
+ readonly changes: "changes.json";
5
+ readonly compatibility: "compatibility.json";
6
+ readonly impactSummary: "impact-summary.json";
7
+ readonly graphIndex: "graph-index.json";
8
+ readonly lock: "comparison.lock.json";
9
+ };
10
+ export declare const ALLOWED_ARTEFACT_FILENAMES: Set<string>;
11
+ export declare const MAX_ARTEFACT_FILE_BYTES: number;
12
+ export declare const MAX_ARTEFACT_TOTAL_BYTES: number;
13
+ export declare const MAX_CHANGE_RECORDS = 500000;
14
+ export declare const MAX_COMPAT_FINDINGS = 200000;
15
+ export declare const MAX_CANDIDATES = 100000;
16
+ export declare const MAX_GRAPH_EDGES = 1000000;
17
+ export interface ArtefactFs {
18
+ mkdirSync(dir: string, opts?: {
19
+ recursive?: boolean;
20
+ }): void;
21
+ writeFileSync(filePath: string, content: string): void;
22
+ existsSync(target: string): boolean;
23
+ renameSync(from: string, to: string): void;
24
+ rmSync(target: string, opts?: {
25
+ recursive?: boolean;
26
+ force?: boolean;
27
+ }): void;
28
+ }
29
+ export declare const defaultArtefactFs: ArtefactFs;
30
+ export declare function assertComparisonPathContained(workspaceRoot: string, relativeOrAbsolute: string): ComparisonError | null;
31
+ /**
32
+ * Transactional / rollback-safe directory replacement.
33
+ * Not claimed as single-syscall filesystem-atomic across platforms.
34
+ */
35
+ export declare function replaceDirectoryTransactionally(outputRoot: string, tmpRoot: string, fsImpl?: ArtefactFs): {
36
+ ok: true;
37
+ cleanupWarning?: string;
38
+ } | {
39
+ ok: false;
40
+ error: ComparisonError;
41
+ };
42
+ export declare function writeComparisonArtefact(outputRoot: string, comparison: ComparisonSnapshot, pretty?: boolean, fsImpl?: ArtefactFs): {
43
+ ok: true;
44
+ cleanupWarning?: string;
45
+ } | {
46
+ ok: false;
47
+ error: ComparisonError;
48
+ };
49
+ export type LoadComparisonResult = {
50
+ ok: true;
51
+ comparison: ComparisonSnapshot;
52
+ } | {
53
+ ok: false;
54
+ error: ComparisonError;
55
+ };
56
+ export declare function loadComparisonArtefact(outputRoot: string): LoadComparisonResult;
57
+ export declare function removeComparisonArtefact(outputRoot: string): void;
58
+ export declare function listArtefactFiles(outputRoot: string): string[];