@pattern-algebra/core 0.0.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 (154) hide show
  1. package/README.md +571 -0
  2. package/dist/automaton/complement.d.ts +20 -0
  3. package/dist/automaton/complement.d.ts.map +1 -0
  4. package/dist/automaton/complement.js +36 -0
  5. package/dist/automaton/complement.js.map +1 -0
  6. package/dist/automaton/complement.test.d.ts +2 -0
  7. package/dist/automaton/complement.test.d.ts.map +1 -0
  8. package/dist/automaton/complement.test.js +114 -0
  9. package/dist/automaton/complement.test.js.map +1 -0
  10. package/dist/automaton/determinize.d.ts +41 -0
  11. package/dist/automaton/determinize.d.ts.map +1 -0
  12. package/dist/automaton/determinize.js +310 -0
  13. package/dist/automaton/determinize.js.map +1 -0
  14. package/dist/automaton/determinize.test.d.ts +2 -0
  15. package/dist/automaton/determinize.test.d.ts.map +1 -0
  16. package/dist/automaton/determinize.test.js +134 -0
  17. package/dist/automaton/determinize.test.js.map +1 -0
  18. package/dist/automaton/emptiness.d.ts +41 -0
  19. package/dist/automaton/emptiness.d.ts.map +1 -0
  20. package/dist/automaton/emptiness.js +262 -0
  21. package/dist/automaton/emptiness.js.map +1 -0
  22. package/dist/automaton/emptiness.test.d.ts +2 -0
  23. package/dist/automaton/emptiness.test.d.ts.map +1 -0
  24. package/dist/automaton/emptiness.test.js +154 -0
  25. package/dist/automaton/emptiness.test.js.map +1 -0
  26. package/dist/automaton/index.d.ts +10 -0
  27. package/dist/automaton/index.d.ts.map +1 -0
  28. package/dist/automaton/index.js +11 -0
  29. package/dist/automaton/index.js.map +1 -0
  30. package/dist/automaton/intersect.d.ts +35 -0
  31. package/dist/automaton/intersect.d.ts.map +1 -0
  32. package/dist/automaton/intersect.js +302 -0
  33. package/dist/automaton/intersect.js.map +1 -0
  34. package/dist/automaton/pattern-algebra.d.ts +62 -0
  35. package/dist/automaton/pattern-algebra.d.ts.map +1 -0
  36. package/dist/automaton/pattern-algebra.js +309 -0
  37. package/dist/automaton/pattern-algebra.js.map +1 -0
  38. package/dist/automaton/pattern-algebra.test.d.ts +2 -0
  39. package/dist/automaton/pattern-algebra.test.d.ts.map +1 -0
  40. package/dist/automaton/pattern-algebra.test.js +223 -0
  41. package/dist/automaton/pattern-algebra.test.js.map +1 -0
  42. package/dist/compile/automaton-builder.d.ts +47 -0
  43. package/dist/compile/automaton-builder.d.ts.map +1 -0
  44. package/dist/compile/automaton-builder.js +211 -0
  45. package/dist/compile/automaton-builder.js.map +1 -0
  46. package/dist/compile/compiler.d.ts +32 -0
  47. package/dist/compile/compiler.d.ts.map +1 -0
  48. package/dist/compile/compiler.js +47 -0
  49. package/dist/compile/compiler.js.map +1 -0
  50. package/dist/compile/index.d.ts +8 -0
  51. package/dist/compile/index.d.ts.map +1 -0
  52. package/dist/compile/index.js +8 -0
  53. package/dist/compile/index.js.map +1 -0
  54. package/dist/compile/quick-reject.d.ts +28 -0
  55. package/dist/compile/quick-reject.d.ts.map +1 -0
  56. package/dist/compile/quick-reject.js +147 -0
  57. package/dist/compile/quick-reject.js.map +1 -0
  58. package/dist/containment/analysis.d.ts +60 -0
  59. package/dist/containment/analysis.d.ts.map +1 -0
  60. package/dist/containment/analysis.js +378 -0
  61. package/dist/containment/analysis.js.map +1 -0
  62. package/dist/containment/containment.d.ts +23 -0
  63. package/dist/containment/containment.d.ts.map +1 -0
  64. package/dist/containment/containment.js +681 -0
  65. package/dist/containment/containment.js.map +1 -0
  66. package/dist/containment/containment.test.d.ts +2 -0
  67. package/dist/containment/containment.test.d.ts.map +1 -0
  68. package/dist/containment/containment.test.js +209 -0
  69. package/dist/containment/containment.test.js.map +1 -0
  70. package/dist/containment/index.d.ts +7 -0
  71. package/dist/containment/index.d.ts.map +1 -0
  72. package/dist/containment/index.js +7 -0
  73. package/dist/containment/index.js.map +1 -0
  74. package/dist/core-alpha.d.ts +1253 -0
  75. package/dist/core-beta.d.ts +1253 -0
  76. package/dist/core-public.d.ts +1253 -0
  77. package/dist/core-unstripped.d.ts +1253 -0
  78. package/dist/index.d.ts +32 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.js +49 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/match/index.d.ts +8 -0
  83. package/dist/match/index.d.ts.map +1 -0
  84. package/dist/match/index.js +8 -0
  85. package/dist/match/index.js.map +1 -0
  86. package/dist/match/matcher.d.ts +40 -0
  87. package/dist/match/matcher.d.ts.map +1 -0
  88. package/dist/match/matcher.js +256 -0
  89. package/dist/match/matcher.js.map +1 -0
  90. package/dist/match/matcher.test.d.ts +2 -0
  91. package/dist/match/matcher.test.d.ts.map +1 -0
  92. package/dist/match/matcher.test.js +185 -0
  93. package/dist/match/matcher.test.js.map +1 -0
  94. package/dist/match/path-utils.d.ts +132 -0
  95. package/dist/match/path-utils.d.ts.map +1 -0
  96. package/dist/match/path-utils.js +223 -0
  97. package/dist/match/path-utils.js.map +1 -0
  98. package/dist/match/path-utils.test.d.ts +2 -0
  99. package/dist/match/path-utils.test.d.ts.map +1 -0
  100. package/dist/match/path-utils.test.js +193 -0
  101. package/dist/match/path-utils.test.js.map +1 -0
  102. package/dist/match/segment-matcher.d.ts +25 -0
  103. package/dist/match/segment-matcher.d.ts.map +1 -0
  104. package/dist/match/segment-matcher.js +267 -0
  105. package/dist/match/segment-matcher.js.map +1 -0
  106. package/dist/parse/brace-expansion.d.ts +34 -0
  107. package/dist/parse/brace-expansion.d.ts.map +1 -0
  108. package/dist/parse/brace-expansion.js +294 -0
  109. package/dist/parse/brace-expansion.js.map +1 -0
  110. package/dist/parse/brace-expansion.test.d.ts +2 -0
  111. package/dist/parse/brace-expansion.test.d.ts.map +1 -0
  112. package/dist/parse/brace-expansion.test.js +105 -0
  113. package/dist/parse/brace-expansion.test.js.map +1 -0
  114. package/dist/parse/index.d.ts +8 -0
  115. package/dist/parse/index.d.ts.map +1 -0
  116. package/dist/parse/index.js +8 -0
  117. package/dist/parse/index.js.map +1 -0
  118. package/dist/parse/parser.d.ts +15 -0
  119. package/dist/parse/parser.d.ts.map +1 -0
  120. package/dist/parse/parser.js +526 -0
  121. package/dist/parse/parser.js.map +1 -0
  122. package/dist/parse/parser.test.d.ts +2 -0
  123. package/dist/parse/parser.test.d.ts.map +1 -0
  124. package/dist/parse/parser.test.js +266 -0
  125. package/dist/parse/parser.test.js.map +1 -0
  126. package/dist/parse/validator.d.ts +30 -0
  127. package/dist/parse/validator.d.ts.map +1 -0
  128. package/dist/parse/validator.js +115 -0
  129. package/dist/parse/validator.js.map +1 -0
  130. package/dist/parse/validator.test.d.ts +2 -0
  131. package/dist/parse/validator.test.d.ts.map +1 -0
  132. package/dist/parse/validator.test.js +45 -0
  133. package/dist/parse/validator.test.js.map +1 -0
  134. package/dist/types/ast.d.ts +158 -0
  135. package/dist/types/ast.d.ts.map +1 -0
  136. package/dist/types/ast.js +2 -0
  137. package/dist/types/ast.js.map +1 -0
  138. package/dist/types/automaton.d.ts +150 -0
  139. package/dist/types/automaton.d.ts.map +1 -0
  140. package/dist/types/automaton.js +2 -0
  141. package/dist/types/automaton.js.map +1 -0
  142. package/dist/types/containment.d.ts +257 -0
  143. package/dist/types/containment.d.ts.map +1 -0
  144. package/dist/types/containment.js +5 -0
  145. package/dist/types/containment.js.map +1 -0
  146. package/dist/types/errors.d.ts +37 -0
  147. package/dist/types/errors.d.ts.map +1 -0
  148. package/dist/types/errors.js +24 -0
  149. package/dist/types/errors.js.map +1 -0
  150. package/dist/types/index.d.ts +10 -0
  151. package/dist/types/index.d.ts.map +1 -0
  152. package/dist/types/index.js +6 -0
  153. package/dist/types/index.js.map +1 -0
  154. package/package.json +48 -0
@@ -0,0 +1,1253 @@
1
+ /**
2
+ * Path Pattern Language Library
3
+ *
4
+ * A library for parsing, compiling, matching, and comparing path patterns
5
+ * (globs and restricted regexes). Designed for downstream use by policy systems.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+
10
+ /**
11
+ * Brace expansion creates alternation between pattern branches.
12
+ *
13
+ * @example
14
+ * "\{src,lib\}/**\/*.ts" becomes:
15
+ * Alternation([
16
+ * SegmentSequence([Literal("src"), Globstar, Wildcard("*.ts")]),
17
+ * SegmentSequence([Literal("lib"), Globstar, Wildcard("*.ts")])
18
+ * ])
19
+ *
20
+ * @public
21
+ */
22
+ export declare interface Alternation {
23
+ readonly type: 'alternation';
24
+ readonly branches: readonly PatternNode[];
25
+ }
26
+
27
+ /**
28
+ * Analyze the relationship between two patterns in detail.
29
+ *
30
+ * Provides comprehensive information about how patterns relate,
31
+ * including the intersection and set differences.
32
+ *
33
+ * @param a - First compiled pattern
34
+ * @param b - Second compiled pattern
35
+ * @returns Full analysis of pattern relationship
36
+ *
37
+ * @public
38
+ */
39
+ export declare function analyzePatterns(a: CompiledPattern, b: CompiledPattern): PatternAnalysis;
40
+
41
+ /**
42
+ * Comparison of pattern anchoring (absolute vs relative).
43
+ * @public
44
+ */
45
+ export declare interface AnchoringComparison {
46
+ /** Whether the anchoring differs between patterns */
47
+ readonly differ: boolean;
48
+ /** Whether pattern A is absolute (starts with / or ~) */
49
+ readonly patternAAbsolute: boolean;
50
+ /** Whether pattern B is absolute (starts with / or ~) */
51
+ readonly patternBAbsolute: boolean;
52
+ /** Human-readable explanation of the difference */
53
+ readonly explanation?: string;
54
+ }
55
+
56
+ /**
57
+ * Apply quick-reject filter to a path.
58
+ *
59
+ * @param path - Normalized path to check
60
+ * @param filter - Quick-reject filter
61
+ * @returns false if path definitely doesn't match, true if it might match
62
+ *
63
+ * @public
64
+ */
65
+ export declare function applyQuickReject(path: string, filter: QuickRejectFilter): boolean;
66
+
67
+ /**
68
+ * Determine if two patterns are disjoint (no common paths).
69
+ *
70
+ * @param a - First pattern
71
+ * @param b - Second pattern
72
+ * @returns true if patterns have no paths in common
73
+ *
74
+ * @public
75
+ */
76
+ export declare function areDisjoint(a: CompiledPattern, b: CompiledPattern): boolean;
77
+
78
+ /**
79
+ * Determine if two patterns are equivalent (match the same set of paths).
80
+ *
81
+ * @param a - First pattern
82
+ * @param b - Second pattern
83
+ * @returns true if patterns are equivalent
84
+ *
85
+ * @public
86
+ */
87
+ export declare function areEquivalent(a: CompiledPattern, b: CompiledPattern): boolean;
88
+
89
+ /**
90
+ * Error thrown when automaton operations exceed configured limits.
91
+ *
92
+ * This typically occurs during DFA construction when a pattern
93
+ * would result in exponential state explosion.
94
+ *
95
+ * @public
96
+ */
97
+ export declare class AutomatonLimitError extends Error {
98
+ /** Error classification code */
99
+ readonly code: PatternErrorCode;
100
+ /** The limit that was exceeded */
101
+ readonly limit: number;
102
+ /** The actual value that exceeded the limit */
103
+ readonly actual: number;
104
+ constructor(code: PatternErrorCode, message: string, limit: number, actual: number);
105
+ }
106
+
107
+ /**
108
+ * A state in the segment automaton.
109
+ * @public
110
+ */
111
+ export declare interface AutomatonState {
112
+ /** Unique identifier for this state (index in the states array) */
113
+ readonly id: number;
114
+ /** Transitions from this state */
115
+ readonly transitions: readonly AutomatonTransition[];
116
+ /** Is this an accepting state? */
117
+ readonly accepting: boolean;
118
+ }
119
+
120
+ /**
121
+ * A transition in the segment automaton.
122
+ * @public
123
+ */
124
+ export declare type AutomatonTransition = LiteralTransition | WildcardTransition | GlobstarTransition | EpsilonTransition;
125
+
126
+ /**
127
+ * Build a segment automaton from a pattern AST.
128
+ *
129
+ * The automaton operates on path segments (not characters).
130
+ * This representation enables:
131
+ * - O(n) matching where n is number of path segments
132
+ * - Standard automaton operations for containment checking
133
+ *
134
+ * @param pattern - Parsed pattern AST
135
+ * @returns Segment automaton (NFA)
136
+ *
137
+ * @public
138
+ */
139
+ export declare function buildAutomaton(pattern: PathPattern): SegmentAutomaton;
140
+
141
+ /**
142
+ * Build quick-reject filters for a pattern.
143
+ *
144
+ * Quick-reject filters enable fast elimination of non-matching paths
145
+ * before full automaton simulation.
146
+ *
147
+ * @param pattern - Pattern AST
148
+ * @returns Quick-reject filter configuration
149
+ *
150
+ * @public
151
+ */
152
+ export declare function buildQuickRejectFilter(pattern: PathPattern): QuickRejectFilter;
153
+
154
+ /**
155
+ * A character class like [a-z] or [!0-9].
156
+ * @public
157
+ */
158
+ export declare interface CharClassSegment {
159
+ readonly type: 'charclass';
160
+ /** Whether this is a negated class (e.g., [!abc] or [^abc]) */
161
+ readonly negated: boolean;
162
+ /** Character ranges (e.g., a-z, 0-9) */
163
+ readonly ranges: readonly CharRange[];
164
+ /** Individual characters not in ranges */
165
+ readonly chars: string;
166
+ }
167
+
168
+ /**
169
+ * A character range within a character class.
170
+ * @public
171
+ */
172
+ export declare interface CharRange {
173
+ /** Single character - start of range */
174
+ readonly start: string;
175
+ /** Single character - end of range */
176
+ readonly end: string;
177
+ }
178
+
179
+ /**
180
+ * Check if pattern A is contained within pattern B.
181
+ *
182
+ * A ⊆ B means: every path that matches A also matches B.
183
+ *
184
+ * Uses a hybrid approach:
185
+ * 1. Structural analysis for quick checks
186
+ * 2. Sample-based testing for validation
187
+ * 3. Automaton operations for complex cases (when available)
188
+ *
189
+ * @param a - First compiled pattern
190
+ * @param b - Second compiled pattern
191
+ * @returns Containment result with explanation data
192
+ *
193
+ * @public
194
+ */
195
+ export declare function checkContainment(a: CompiledPattern, b: CompiledPattern): ContainmentResult;
196
+
197
+ /**
198
+ * Find the common prefix path between two paths.
199
+ *
200
+ * @param pathA - First path
201
+ * @param pathB - Second path
202
+ * @returns The longest common ancestor path
203
+ *
204
+ * @example
205
+ * commonPrefix('/home/user/a/b', '/home/user/c/d')
206
+ * // => '/home/user'
207
+ *
208
+ * @public
209
+ */
210
+ export declare function commonPrefix(pathA: string, pathB: string): string;
211
+
212
+ /**
213
+ * A compiled pattern ready for efficient matching.
214
+ *
215
+ * Patterns are compiled to a form optimized for:
216
+ * 1. Fast rejection of non-matching paths
217
+ * 2. Minimal backtracking during matching
218
+ * 3. Support for containment analysis
219
+ *
220
+ * @public
221
+ */
222
+ export declare interface CompiledPattern {
223
+ /** Original source pattern */
224
+ readonly source: string;
225
+ /** Parsed AST (for containment analysis) */
226
+ readonly ast: PathPattern;
227
+ /**
228
+ * Quick-reject filters applied before full matching.
229
+ * If any filter fails, the path definitely doesn't match.
230
+ */
231
+ readonly quickReject: QuickRejectFilter;
232
+ /**
233
+ * Segment automaton for matching.
234
+ * Operates on path segments, not characters.
235
+ */
236
+ readonly automaton: SegmentAutomaton;
237
+ /** Whether pattern can match paths of any depth (contains **) */
238
+ readonly isUnbounded: boolean;
239
+ /** Minimum number of segments this pattern requires */
240
+ readonly minSegments: number;
241
+ /** Maximum segments (undefined if unbounded) */
242
+ readonly maxSegments?: number;
243
+ }
244
+
245
+ /**
246
+ * Compile a pattern to an efficient matching form.
247
+ *
248
+ * The compiled pattern includes:
249
+ * - Original source and AST for debugging/analysis
250
+ * - Quick-reject filters for fast path elimination
251
+ * - Segment automaton for full matching
252
+ * - Depth constraints for optimization
253
+ *
254
+ * @param pattern - Parsed pattern AST
255
+ * @returns Compiled pattern ready for matching
256
+ *
257
+ * @public
258
+ */
259
+ export declare function compilePattern(pattern: PathPattern): CompiledPattern;
260
+
261
+ /**
262
+ * Complement a DFA by swapping accepting and non-accepting states.
263
+ *
264
+ * The complemented automaton accepts exactly the strings that the
265
+ * original automaton rejects, and vice versa.
266
+ *
267
+ * Note: Input must be deterministic. NFAs are automatically converted.
268
+ *
269
+ * @param automaton - The automaton to complement
270
+ * @returns Complemented automaton
271
+ *
272
+ * @public
273
+ */
274
+ export declare function complement(automaton: SegmentAutomaton): SegmentAutomaton;
275
+
276
+ /**
277
+ * A segment composed of multiple parts (literal + wildcard + charclass).
278
+ *
279
+ * @example "test-[0-9]*-spec.ts" is a composite of:
280
+ * - literal "test-"
281
+ * - charclass [0-9]
282
+ * - star *
283
+ * - literal "-spec.ts"
284
+ *
285
+ * @public
286
+ */
287
+ export declare interface CompositeSegment {
288
+ readonly type: 'composite';
289
+ readonly parts: readonly SegmentPart[];
290
+ }
291
+
292
+ /**
293
+ * Structured explanation of why two patterns have a particular relationship.
294
+ * Provides sufficient data for downstream systems to generate human-readable explanations.
295
+ * @public
296
+ */
297
+ export declare interface ContainmentExplanation {
298
+ /**
299
+ * High-level categorization of why containment fails (if it does).
300
+ * Empty array if A ⊆ B.
301
+ */
302
+ readonly failureReasons: readonly ContainmentFailureReason[];
303
+ /**
304
+ * Segment-by-segment comparison showing where patterns differ.
305
+ * Each entry describes one position in the path.
306
+ */
307
+ readonly segmentComparison: readonly SegmentComparisonEntry[];
308
+ /**
309
+ * Structural differences between the patterns.
310
+ */
311
+ readonly structuralDiffs: StructuralDifferences;
312
+ /**
313
+ * Witness paths that demonstrate the relationship.
314
+ * Includes counterexamples, shared paths, and illustrative examples.
315
+ */
316
+ readonly witnesses: readonly WitnessPath[];
317
+ }
318
+
319
+ /**
320
+ * Categories of reasons why containment may fail.
321
+ * Used to provide structured explanation data.
322
+ * @public
323
+ */
324
+ export declare type ContainmentFailureReason = 'depth_mismatch' | 'prefix_mismatch' | 'suffix_mismatch' | 'segment_mismatch' | 'charclass_mismatch' | 'negation_conflict' | 'alternation_escape';
325
+
326
+ /**
327
+ * Result of checking whether pattern A is contained within pattern B.
328
+ *
329
+ * A ⊆ B means: every path that matches A also matches B.
330
+ *
331
+ * This type provides rich structured data to enable downstream systems
332
+ * to generate human-readable explanations of containment results.
333
+ *
334
+ * @example
335
+ * - "src/*.ts" ⊆ "src/**" (true)
336
+ * - "src/**" ⊆ "src/*.ts" (false)
337
+ * - "*.ts" ⊆ "*" (true)
338
+ * - "\{src,lib\}/*.ts" ⊆ "**\/*.ts" (true)
339
+ *
340
+ * @public
341
+ */
342
+ export declare interface ContainmentResult {
343
+ /** The first pattern being compared */
344
+ readonly patternA: string;
345
+ /** The second pattern being compared */
346
+ readonly patternB: string;
347
+ /** Is A a subset of B? (A ⊆ B) */
348
+ readonly isSubset: boolean;
349
+ /** Is B a subset of A? (B ⊆ A) */
350
+ readonly isSuperset: boolean;
351
+ /** Is A equal to B (mutual containment)? */
352
+ readonly isEqual: boolean;
353
+ /** Do the patterns have any overlap? (A ∩ B ≠ ∅) */
354
+ readonly hasOverlap: boolean;
355
+ /** Relationship classification */
356
+ readonly relationship: PatternRelationship;
357
+ /**
358
+ * Primary counterexample: a path that matches A but not B.
359
+ * Present when isSubset is false.
360
+ */
361
+ readonly counterexample?: string;
362
+ /**
363
+ * Reverse counterexample: a path that matches B but not A.
364
+ * Present when isSuperset is false.
365
+ */
366
+ readonly reverseCounterexample?: string;
367
+ /**
368
+ * Structured explanation data for generating human-readable descriptions.
369
+ */
370
+ readonly explanation: ContainmentExplanation;
371
+ }
372
+
373
+ /**
374
+ * Count the number of patterns that would result from expansion.
375
+ * Does not actually expand - useful for limit checking.
376
+ *
377
+ * @param source - Pattern source string
378
+ * @returns Estimated expansion count, or Infinity if it would exceed reasonable limits
379
+ *
380
+ * @public
381
+ */
382
+ export declare function countBraceExpansions(source: string): number;
383
+
384
+ /**
385
+ * Count the number of accepting paths of a given length.
386
+ *
387
+ * Useful for understanding the "size" of a pattern's language.
388
+ *
389
+ * @param automaton - The automaton
390
+ * @param maxDepth - Maximum path length to consider
391
+ * @returns Object with counts per depth
392
+ *
393
+ * @public
394
+ */
395
+ export declare function countPaths(automaton: SegmentAutomaton, maxDepth: number): Map<number, number>;
396
+
397
+ /**
398
+ * Default maximum number of DFA states before throwing an error.
399
+ * This prevents exponential blowup from patterns with many alternations.
400
+ *
401
+ * @public
402
+ */
403
+ export declare const DEFAULT_MAX_DFA_STATES = 10000;
404
+
405
+ /**
406
+ * Comparison of pattern depth constraints.
407
+ * @public
408
+ */
409
+ export declare interface DepthComparison {
410
+ /** Whether the depth constraints differ between patterns */
411
+ readonly differ: boolean;
412
+ /** Minimum segment depth for pattern A */
413
+ readonly patternAMin: number;
414
+ /** Maximum segment depth for pattern A (or 'unbounded' for **) */
415
+ readonly patternAMax: number | 'unbounded';
416
+ /** Minimum segment depth for pattern B */
417
+ readonly patternBMin: number;
418
+ /** Maximum segment depth for pattern B (or 'unbounded' for **) */
419
+ readonly patternBMax: number | 'unbounded';
420
+ /** Human-readable explanation of the difference */
421
+ readonly explanation?: string;
422
+ }
423
+
424
+ /**
425
+ * Convert an NFA to a DFA using subset construction.
426
+ *
427
+ * The resulting DFA has states that correspond to sets of NFA states.
428
+ * Globstar transitions are handled by treating them as transitions
429
+ * that can match any segment.
430
+ *
431
+ * @param nfa - The NFA to determinize
432
+ * @param options - Optional configuration for the conversion
433
+ * @returns An equivalent DFA
434
+ * @throws AutomatonLimitError if DFA state count exceeds the configured limit
435
+ *
436
+ * @public
437
+ */
438
+ export declare function determinize(nfa: SegmentAutomaton, options?: DeterminizeOptions): SegmentAutomaton;
439
+
440
+ /**
441
+ * Options for DFA construction.
442
+ *
443
+ * @public
444
+ */
445
+ export declare interface DeterminizeOptions {
446
+ /**
447
+ * Maximum number of DFA states to create before throwing an error.
448
+ * Set to `Infinity` to disable the limit (not recommended).
449
+ * @defaultValue 10000
450
+ */
451
+ maxStates?: number;
452
+ }
453
+
454
+ /**
455
+ * Epsilon transition (no input consumed).
456
+ * Used for NFA construction and alternation.
457
+ * @public
458
+ */
459
+ export declare interface EpsilonTransition {
460
+ readonly type: 'epsilon';
461
+ readonly target: number;
462
+ }
463
+
464
+ /**
465
+ * Expand brace expressions in a pattern, creating multiple patterns.
466
+ *
467
+ * @example
468
+ * expandBraces(parsePattern('{src,lib}/*.ts'))
469
+ * // => [parsePattern('src/*.ts'), parsePattern('lib/*.ts')]
470
+ *
471
+ * @example
472
+ * expandBraces(parsePattern('file{1..3}.txt'))
473
+ * // => [parsePattern('file1.txt'), parsePattern('file2.txt'), parsePattern('file3.txt')]
474
+ *
475
+ * @param pattern - The pattern to expand
476
+ * @param maxExpansion - Maximum number of expanded patterns (default: 100)
477
+ * @returns Array of expanded patterns
478
+ *
479
+ * @public
480
+ */
481
+ export declare function expandBraces(pattern: PathPattern, maxExpansion?: number): readonly PathPattern[];
482
+
483
+ /**
484
+ * Find a witness string accepted by the automaton.
485
+ *
486
+ * If the automaton is non-empty, returns a path (sequence of segments)
487
+ * that leads to an accepting state.
488
+ *
489
+ * @param automaton - The automaton to find a witness for
490
+ * @returns A witness path string, or undefined if the language is empty
491
+ *
492
+ * @public
493
+ */
494
+ export declare function findWitness(automaton: SegmentAutomaton): string | undefined;
495
+
496
+ /**
497
+ * Get the basename (final segment) from a path.
498
+ *
499
+ * @param path - Path to extract basename from
500
+ * @returns The final segment of the path
501
+ *
502
+ * @public
503
+ */
504
+ export declare function getBasename(path: string): string;
505
+
506
+ /**
507
+ * Get the directory portion of a path (everything except the last segment).
508
+ *
509
+ * @param path - Path to extract directory from
510
+ * @returns The directory path
511
+ *
512
+ * @public
513
+ */
514
+ export declare function getDirname(path: string): string;
515
+
516
+ /**
517
+ * Get the file extension from a path segment or full path.
518
+ *
519
+ * @param pathOrSegment - A path or segment to extract extension from
520
+ * @returns The extension including the dot, or empty string if none
521
+ *
522
+ * @example
523
+ * getExtension('file.ts') // => '.ts'
524
+ * getExtension('file.test.ts') // => '.ts'
525
+ * getExtension('.gitignore') // => '' (dotfiles have no extension)
526
+ * getExtension('Makefile') // => ''
527
+ *
528
+ * @public
529
+ */
530
+ export declare function getExtension(pathOrSegment: string): string;
531
+
532
+ /**
533
+ * Get the maximum number of segments a pattern can match.
534
+ *
535
+ * @param pattern - Pattern AST
536
+ * @returns Maximum segment count, or undefined if unbounded (contains **)
537
+ *
538
+ * @public
539
+ */
540
+ export declare function getMaxSegments(pattern: PathPattern): number | undefined;
541
+
542
+ /**
543
+ * Get the minimum number of segments a pattern can match.
544
+ *
545
+ * @param pattern - Pattern AST
546
+ * @returns Minimum segment count
547
+ *
548
+ * @public
549
+ */
550
+ export declare function getMinSegments(pattern: PathPattern): number;
551
+
552
+ /**
553
+ * The ** globstar - matches zero or more complete segments.
554
+ * @public
555
+ */
556
+ export declare interface GlobstarSegment {
557
+ readonly type: 'globstar';
558
+ }
559
+
560
+ /**
561
+ * Globstar transition for ** (matches zero or more segments).
562
+ *
563
+ * Modeled as: epsilon to exit OR consume one segment and stay.
564
+ * @public
565
+ */
566
+ export declare interface GlobstarTransition {
567
+ readonly type: 'globstar';
568
+ /** Self-loop state (stays in same state consuming segments) */
569
+ readonly selfLoop: number;
570
+ /** Exit state (moves forward without consuming) */
571
+ readonly exit: number;
572
+ }
573
+
574
+ /**
575
+ * Determine if two patterns have any overlap.
576
+ *
577
+ * @param a - First pattern
578
+ * @param b - Second pattern
579
+ * @returns true if there exists a path matching both patterns
580
+ *
581
+ * @public
582
+ */
583
+ export declare function hasOverlap(a: CompiledPattern, b: CompiledPattern): boolean;
584
+
585
+ /**
586
+ * Compute the intersection of two automata using product construction.
587
+ *
588
+ * The resulting automaton accepts a string iff both input automata accept it.
589
+ * L(A ∩ B) = L(A) ∩ L(B)
590
+ *
591
+ * @param a - First automaton
592
+ * @param b - Second automaton
593
+ * @returns Intersection automaton
594
+ *
595
+ * @public
596
+ */
597
+ export declare function intersect(a: SegmentAutomaton, b: SegmentAutomaton): SegmentAutomaton;
598
+
599
+ /**
600
+ * Check if a path is absolute (starts with / or ~).
601
+ *
602
+ * @param path - Path to check
603
+ * @returns true if the path is absolute
604
+ *
605
+ * @public
606
+ */
607
+ export declare function isAbsolutePath(path: string): boolean;
608
+
609
+ /**
610
+ * Check if path A is a prefix of path B (A is an ancestor directory of B).
611
+ *
612
+ * @param ancestor - Potential ancestor path
613
+ * @param descendant - Potential descendant path
614
+ * @returns true if ancestor is a prefix of descendant
615
+ *
616
+ * @example
617
+ * isAncestorPath('/home/user', '/home/user/dev/file.ts') // => true
618
+ * isAncestorPath('/home/user', '/home/user') // => true (same path)
619
+ * isAncestorPath('/home/user', '/home/other') // => false
620
+ *
621
+ * @public
622
+ */
623
+ export declare function isAncestorPath(ancestor: string, descendant: string): boolean;
624
+
625
+ /**
626
+ * Check if an automaton's language is empty.
627
+ *
628
+ * Uses reachability analysis from the initial state to any accepting state.
629
+ *
630
+ * @param automaton - The automaton to check
631
+ * @returns true if the automaton accepts no strings
632
+ *
633
+ * @public
634
+ */
635
+ export declare function isEmpty(automaton: SegmentAutomaton): boolean;
636
+
637
+ /**
638
+ * Check if a pattern contains a globstar (**).
639
+ *
640
+ * @param pattern - Pattern AST
641
+ * @returns true if pattern is unbounded
642
+ *
643
+ * @public
644
+ */
645
+ export declare function isUnbounded(pattern: PathPattern): boolean;
646
+
647
+ /**
648
+ * Check if a pattern is valid (has no errors).
649
+ *
650
+ * @param pattern - The pattern to check
651
+ * @returns true if the pattern has no errors
652
+ *
653
+ * @public
654
+ */
655
+ export declare function isValidPattern(pattern: PathPattern): boolean;
656
+
657
+ /**
658
+ * An exact literal match for a path segment.
659
+ *
660
+ * @example "package.json" matches only "package.json"
661
+ *
662
+ * @public
663
+ */
664
+ export declare interface LiteralSegment {
665
+ readonly type: 'literal';
666
+ readonly value: string;
667
+ }
668
+
669
+ /**
670
+ * Transition on an exact segment match.
671
+ * @public
672
+ */
673
+ export declare interface LiteralTransition {
674
+ readonly type: 'literal';
675
+ readonly segment: string;
676
+ /** Target state ID */
677
+ readonly target: number;
678
+ }
679
+
680
+ /**
681
+ * Test if a path matches a compiled pattern.
682
+ *
683
+ * @param path - Absolute, normalized path (e.g., "/home/user/dev/foo.ts")
684
+ * @param pattern - Compiled pattern
685
+ * @returns true if path matches
686
+ *
687
+ * @public
688
+ */
689
+ export declare function matchPath(path: string, pattern: CompiledPattern): boolean;
690
+
691
+ /**
692
+ * Match a path against a pattern AST directly (without compilation).
693
+ *
694
+ * This is less efficient than using compiled patterns but useful for one-off matching.
695
+ *
696
+ * @param path - Normalized path
697
+ * @param pattern - Pattern AST
698
+ * @returns true if path matches
699
+ *
700
+ * @public
701
+ */
702
+ export declare function matchPathDirect(path: string, pattern: PathPattern): boolean;
703
+
704
+ /**
705
+ * Match a path with context (for ~ expansion and relative paths).
706
+ *
707
+ * @param path - Path to match (may be relative or contain ~)
708
+ * @param pattern - Compiled pattern
709
+ * @param context - Path context for normalization
710
+ * @returns true if normalized path matches
711
+ *
712
+ * @public
713
+ */
714
+ export declare function matchPathWithContext(path: string, pattern: CompiledPattern, context: PathContext): boolean;
715
+
716
+ /**
717
+ * Check if a path segment matches a segment pattern.
718
+ *
719
+ * @param segment - The actual path segment (e.g., "file.ts")
720
+ * @param pattern - The pattern segment from AST
721
+ * @returns true if the segment matches
722
+ *
723
+ * @public
724
+ */
725
+ export declare function matchSegment(segment: string, pattern: Segment): boolean;
726
+
727
+ /**
728
+ * Normalize a path to absolute form for consistent matching.
729
+ *
730
+ * Handles:
731
+ * - ~ expansion to home directory
732
+ * - Relative path resolution against cwd
733
+ * - . and .. resolution
734
+ * - Trailing slash normalization (removed)
735
+ * - Duplicate slash removal
736
+ * - Backslash to forward slash conversion (Windows compatibility)
737
+ *
738
+ * @param path - Input path (may be relative or contain ~)
739
+ * @param context - Context for resolution
740
+ * @returns Absolute, normalized path
741
+ *
742
+ * @public
743
+ */
744
+ export declare function normalizePath(path: string, context: PathContext): string;
745
+
746
+ /**
747
+ * Parse a pattern string into an AST.
748
+ *
749
+ * @param source - The pattern string to parse
750
+ * @returns Parsed PathPattern with AST and any errors
751
+ *
752
+ * @public
753
+ */
754
+ export declare function parsePattern(source: string): PathPattern;
755
+
756
+ /**
757
+ * Context for path resolution operations.
758
+ * @public
759
+ */
760
+ export declare interface PathContext {
761
+ /** User's home directory for ~ expansion */
762
+ readonly homeDir: string;
763
+ /** Current working directory for relative path resolution */
764
+ readonly cwd: string;
765
+ /** Optional project root for project-relative patterns */
766
+ readonly projectRoot?: string;
767
+ }
768
+
769
+ /**
770
+ * Root pattern node - the entry point for any parsed pattern.
771
+ * @public
772
+ */
773
+ export declare interface PathPattern {
774
+ /** Original pattern string for error messages and debugging */
775
+ readonly source: string;
776
+ /** Parsed structure */
777
+ readonly root: PatternNode;
778
+ /** Whether this is an absolute pattern (starts with / or ~) */
779
+ readonly isAbsolute: boolean;
780
+ /** Whether this is a negation pattern (starts with !) */
781
+ readonly isNegation: boolean;
782
+ /** Validation errors, if any */
783
+ readonly errors?: readonly PatternError[];
784
+ }
785
+
786
+ /**
787
+ * Split a normalized path into segments.
788
+ *
789
+ * @param path - A normalized absolute path (starting with /)
790
+ * @returns Array of path segments (excluding the root)
791
+ *
792
+ * @example
793
+ * pathToSegments('/home/user/dev/file.ts')
794
+ * // => ['home', 'user', 'dev', 'file.ts']
795
+ *
796
+ * @public
797
+ */
798
+ export declare function pathToSegments(path: string): readonly string[];
799
+
800
+ /**
801
+ * Detailed analysis of two patterns' relationship.
802
+ *
803
+ * Provides comprehensive data for understanding how two patterns relate,
804
+ * including the intersection and set differences.
805
+ *
806
+ * @public
807
+ */
808
+ export declare interface PatternAnalysis {
809
+ readonly patternA: string;
810
+ readonly patternB: string;
811
+ readonly relationship: PatternRelationship;
812
+ /** Full containment result with explanation */
813
+ readonly containment: ContainmentResult;
814
+ /** Description of paths matching both patterns */
815
+ readonly intersection: PatternDescription;
816
+ /** Description of paths matching A but not B */
817
+ readonly aMinusB: PatternDescription;
818
+ /** Description of paths matching B but not A */
819
+ readonly bMinusA: PatternDescription;
820
+ }
821
+
822
+ /**
823
+ * Compute the complement of a pattern.
824
+ *
825
+ * The result matches paths that do NOT match the input pattern.
826
+ * L(result) = Σ* - L(a)
827
+ *
828
+ * @param a - Pattern to complement
829
+ * @returns Pattern matching paths not matched by a
830
+ *
831
+ * @public
832
+ */
833
+ export declare function patternComplement(a: CompiledPattern): CompiledPattern;
834
+
835
+ /**
836
+ * A human-readable description of a set of paths.
837
+ * @public
838
+ */
839
+ export declare interface PatternDescription {
840
+ /** Is this set empty? */
841
+ readonly isEmpty: boolean;
842
+ /** Example paths from this set (if non-empty) */
843
+ readonly examples?: readonly string[];
844
+ /** Pattern representation (if expressible as a single pattern) */
845
+ readonly pattern?: string;
846
+ /** Natural language description */
847
+ readonly description: string;
848
+ }
849
+
850
+ /**
851
+ * Compute the difference of two patterns.
852
+ *
853
+ * The result matches paths that match a but NOT b.
854
+ * L(result) = L(a) - L(b) = L(a) ∩ L(¬b)
855
+ *
856
+ * @param a - Pattern to subtract from
857
+ * @param b - Pattern to subtract
858
+ * @returns Pattern matching paths in a but not in b
859
+ *
860
+ * @public
861
+ */
862
+ export declare function patternDifference(a: CompiledPattern, b: CompiledPattern): CompiledPattern;
863
+
864
+ /**
865
+ * A pattern validation error with location information.
866
+ * @public
867
+ */
868
+ export declare interface PatternError {
869
+ /** Error classification code */
870
+ readonly code: PatternErrorCode;
871
+ /** Human-readable error description */
872
+ readonly message: string;
873
+ /** Character position in source where error starts */
874
+ readonly position?: number;
875
+ /** Length of the problematic section */
876
+ readonly length?: number;
877
+ }
878
+
879
+ /**
880
+ * Error codes for pattern validation failures.
881
+ * @public
882
+ */
883
+ export declare type PatternErrorCode = 'INVALID_GLOBSTAR' | 'UNCLOSED_BRACKET' | 'UNCLOSED_BRACE' | 'EMPTY_CHARCLASS' | 'INVALID_RANGE' | 'EXPANSION_LIMIT' | 'NESTED_BRACES' | 'INVALID_ESCAPE' | 'BANNED_FEATURE' | 'INVALID_REGEX' | 'UNSAFE_REGEX' | 'DFA_STATE_LIMIT';
884
+
885
+ /**
886
+ * Compute the intersection of two patterns.
887
+ *
888
+ * The result matches paths that match BOTH input patterns.
889
+ * L(result) = L(a) ∩ L(b)
890
+ *
891
+ * @param a - First pattern
892
+ * @param b - Second pattern
893
+ * @returns Pattern matching paths in both a and b
894
+ *
895
+ * @public
896
+ */
897
+ export declare function patternIntersect(a: CompiledPattern, b: CompiledPattern): CompiledPattern;
898
+
899
+ /**
900
+ * A node in the pattern AST. Patterns are sequences of segments or alternations.
901
+ * @public
902
+ */
903
+ export declare type PatternNode = SegmentSequence | Alternation;
904
+
905
+ /**
906
+ * Describes the relationship between two pattern sets.
907
+ * @public
908
+ */
909
+ export declare type PatternRelationship = 'subset' | 'equal' | 'superset' | 'overlapping' | 'disjoint';
910
+
911
+ /**
912
+ * Compute the union of two patterns.
913
+ *
914
+ * The result matches paths that match EITHER input pattern.
915
+ * L(result) = L(a) ∪ L(b)
916
+ *
917
+ * @param a - First pattern
918
+ * @param b - Second pattern
919
+ * @returns Pattern matching paths in a or b (or both)
920
+ *
921
+ * @public
922
+ */
923
+ export declare function patternUnion(a: CompiledPattern, b: CompiledPattern): CompiledPattern;
924
+
925
+ /**
926
+ * Comparison of required path prefixes.
927
+ * @public
928
+ */
929
+ export declare interface PrefixComparison {
930
+ /** Whether the required prefixes differ between patterns */
931
+ readonly differ: boolean;
932
+ /** Required prefix for pattern A (if any) */
933
+ readonly patternAPrefix?: string;
934
+ /** Required prefix for pattern B (if any) */
935
+ readonly patternBPrefix?: string;
936
+ /** Human-readable explanation of the difference */
937
+ readonly explanation?: string;
938
+ }
939
+
940
+ /**
941
+ * Quick rejection filters for fast path elimination.
942
+ * @public
943
+ */
944
+ export declare interface QuickRejectFilter {
945
+ /** If pattern requires specific prefix, check it first */
946
+ readonly requiredPrefix?: string;
947
+ /** If pattern requires specific suffix, check it first */
948
+ readonly requiredSuffix?: string;
949
+ /** Minimum path length (characters) */
950
+ readonly minLength?: number;
951
+ /** Required literal segments that must appear somewhere */
952
+ readonly requiredLiterals?: readonly string[];
953
+ }
954
+
955
+ /**
956
+ * A segment represents one path component between slashes.
957
+ * @public
958
+ */
959
+ export declare type Segment = LiteralSegment | WildcardSegment | GlobstarSegment | CharClassSegment | CompositeSegment;
960
+
961
+ /**
962
+ * A finite automaton that operates on path segments rather than characters.
963
+ *
964
+ * Key insight: treating segments as tokens rather than character-by-character
965
+ * matching dramatically simplifies the automaton and enables efficient
966
+ * containment checking.
967
+ *
968
+ * Alphabet:
969
+ * - Each literal segment is a symbol
970
+ * - "*" matches any single segment (wildcard transition)
971
+ * - "**" is an epsilon loop (zero or more segments)
972
+ *
973
+ * This representation supports:
974
+ * - O(n) matching where n is number of path segments
975
+ * - Standard automaton operations (union, intersection, complement)
976
+ * - Containment checking via (A ∩ B̄ = ∅)
977
+ *
978
+ * @public
979
+ */
980
+ export declare interface SegmentAutomaton {
981
+ /** All states in the automaton */
982
+ readonly states: readonly AutomatonState[];
983
+ /** Index of the initial state */
984
+ readonly initialState: number;
985
+ /** Indices of accepting (final) states */
986
+ readonly acceptingStates: readonly number[];
987
+ /** Whether this automaton is deterministic */
988
+ readonly isDeterministic: boolean;
989
+ }
990
+
991
+ /**
992
+ * Comparison of what patterns allow at a specific segment position.
993
+ * @public
994
+ */
995
+ export declare interface SegmentComparisonEntry {
996
+ /** Segment position (0-indexed from path root) */
997
+ readonly position: number;
998
+ /** What pattern A allows at this position */
999
+ readonly patternAAllows: SegmentConstraint;
1000
+ /** What pattern B allows at this position */
1001
+ readonly patternBAllows: SegmentConstraint;
1002
+ /** Whether A's constraint is a subset of B's at this position */
1003
+ readonly aSubsetOfB: boolean;
1004
+ /** Brief description of the difference (if any) */
1005
+ readonly difference?: string;
1006
+ }
1007
+
1008
+ /**
1009
+ * Describes what a pattern allows at a segment position.
1010
+ * @public
1011
+ */
1012
+ export declare interface SegmentConstraint {
1013
+ /** The type of constraint */
1014
+ readonly type: SegmentConstraintType;
1015
+ /** For literal: the exact value required */
1016
+ readonly literalValue?: string;
1017
+ /** For wildcard: the pattern (e.g., "*.ts") */
1018
+ readonly wildcardPattern?: string;
1019
+ /** For charclass: description of allowed characters */
1020
+ readonly charclassDescription?: string;
1021
+ /** Whether this position can be skipped (due to ** before it) */
1022
+ readonly optional: boolean;
1023
+ /** Whether this position can repeat (is within a ** range) */
1024
+ readonly repeatable: boolean;
1025
+ }
1026
+
1027
+ /**
1028
+ * Types of segment constraints.
1029
+ * @public
1030
+ */
1031
+ export declare type SegmentConstraintType = 'literal' | 'wildcard' | 'charclass' | 'any' | 'any_sequence' | 'end' | 'unreachable';
1032
+
1033
+ /**
1034
+ * A pattern matcher that can test if a segment matches.
1035
+ * This can be either a native RegExp or a composite pattern.
1036
+ * @public
1037
+ */
1038
+ declare interface SegmentMatcher {
1039
+ /** Test if a string matches the pattern */
1040
+ test(str: string): boolean;
1041
+ /** The pattern source for debugging/serialization */
1042
+ readonly source: string;
1043
+ }
1044
+
1045
+ /**
1046
+ * A part of a composite segment.
1047
+ * @public
1048
+ */
1049
+ export declare type SegmentPart = {
1050
+ readonly type: 'literal';
1051
+ readonly value: string;
1052
+ } | {
1053
+ readonly type: 'star';
1054
+ } | {
1055
+ readonly type: 'question';
1056
+ } | {
1057
+ readonly type: 'charclass';
1058
+ readonly spec: CharClassSegment;
1059
+ };
1060
+
1061
+ /**
1062
+ * A sequence of path segments (the most common case).
1063
+ *
1064
+ * @example
1065
+ * "src/**\/*.ts" becomes:
1066
+ * segments: [Literal("src"), Globstar, Wildcard("*.ts")]
1067
+ *
1068
+ * @public
1069
+ */
1070
+ export declare interface SegmentSequence {
1071
+ readonly type: 'sequence';
1072
+ readonly segments: readonly Segment[];
1073
+ }
1074
+
1075
+ /**
1076
+ * Join segments back into a path.
1077
+ *
1078
+ * @param segments - Array of path segments
1079
+ * @returns Absolute path string
1080
+ *
1081
+ * @example
1082
+ * segmentsToPath(['home', 'user', 'dev', 'file.ts'])
1083
+ * // => '/home/user/dev/file.ts'
1084
+ *
1085
+ * @public
1086
+ */
1087
+ export declare function segmentsToPath(segments: readonly string[]): string;
1088
+
1089
+ /**
1090
+ * Build a RegExp from a segment pattern for automaton transitions.
1091
+ *
1092
+ * @param pattern - Segment pattern
1093
+ * @returns RegExp that matches the segment, or null for globstar/literal
1094
+ *
1095
+ * @public
1096
+ */
1097
+ export declare function segmentToRegex(pattern: Segment): RegExp | null;
1098
+
1099
+ /**
1100
+ * High-level structural differences between patterns.
1101
+ * @public
1102
+ */
1103
+ export declare interface StructuralDifferences {
1104
+ /** Whether patterns have different depth bounds */
1105
+ readonly depthDifference: DepthComparison;
1106
+ /** Whether patterns require different prefixes */
1107
+ readonly prefixDifference: PrefixComparison;
1108
+ /** Whether patterns require different suffixes */
1109
+ readonly suffixDifference: SuffixComparison;
1110
+ /** Whether one pattern is anchored and the other isn't */
1111
+ readonly anchoringDifference: AnchoringComparison;
1112
+ }
1113
+
1114
+ /**
1115
+ * Comparison of required path suffixes (e.g., file extensions).
1116
+ * @public
1117
+ */
1118
+ export declare interface SuffixComparison {
1119
+ /** Whether the required suffixes differ between patterns */
1120
+ readonly differ: boolean;
1121
+ /** Required suffix for pattern A (e.g., ".ts") */
1122
+ readonly patternASuffix?: string;
1123
+ /** Required suffix for pattern B (e.g., ".js") */
1124
+ readonly patternBSuffix?: string;
1125
+ /** Human-readable explanation of the difference */
1126
+ readonly explanation?: string;
1127
+ }
1128
+
1129
+ /**
1130
+ * Get a human-readable summary of the relationship between patterns.
1131
+ *
1132
+ * @param relationship - The pattern relationship
1133
+ * @param patternA - Source of pattern A
1134
+ * @param patternB - Source of pattern B
1135
+ * @returns Human-readable description
1136
+ *
1137
+ * @public
1138
+ */
1139
+ export declare function summarizeRelationship(relationship: PatternRelationship, patternA: string, patternB: string): string;
1140
+
1141
+ /**
1142
+ * Compute the union of two automata using NFA construction.
1143
+ *
1144
+ * The resulting automaton accepts a string iff either input automaton accepts it.
1145
+ * L(A ∪ B) = L(A) ∪ L(B)
1146
+ *
1147
+ * We use NFA union: create a new initial state with epsilon transitions
1148
+ * to both automata's initial states, then merge the states.
1149
+ *
1150
+ * @param a - First automaton
1151
+ * @param b - Second automaton
1152
+ * @returns Union automaton (NFA)
1153
+ *
1154
+ * @public
1155
+ */
1156
+ export declare function union(a: SegmentAutomaton, b: SegmentAutomaton): SegmentAutomaton;
1157
+
1158
+ /**
1159
+ * Validate a pattern against the allowed feature set.
1160
+ *
1161
+ * Returns errors for:
1162
+ * - Patterns that already have errors from parsing
1163
+ * - Invalid globstar usage
1164
+ * - Empty patterns
1165
+ * - Other structural issues
1166
+ *
1167
+ * @param pattern - The parsed pattern to validate
1168
+ * @returns Array of validation errors (empty if valid)
1169
+ *
1170
+ * @public
1171
+ */
1172
+ export declare function validatePattern(pattern: PathPattern): readonly PatternError[];
1173
+
1174
+ /**
1175
+ * Library version.
1176
+ * @public
1177
+ */
1178
+ export declare const version = "0.0.0";
1179
+
1180
+ /**
1181
+ * A part of a wildcard segment pattern.
1182
+ * @public
1183
+ */
1184
+ export declare type WildcardPart = {
1185
+ readonly type: 'literal';
1186
+ readonly value: string;
1187
+ } | {
1188
+ readonly type: 'star';
1189
+ } | {
1190
+ readonly type: 'question';
1191
+ };
1192
+
1193
+ /**
1194
+ * A segment containing wildcards (* or ?).
1195
+ *
1196
+ * Compiles to a regex pattern for the segment.
1197
+ *
1198
+ * @example
1199
+ * "*.ts" -> parts: [{ type: "star" }, { type: "literal", value: ".ts" }]
1200
+ * "test-*-spec.js" -> complex pattern
1201
+ *
1202
+ * @public
1203
+ */
1204
+ export declare interface WildcardSegment {
1205
+ readonly type: 'wildcard';
1206
+ /** Original pattern text for this segment */
1207
+ readonly pattern: string;
1208
+ /** Components for efficient prefix/suffix matching */
1209
+ readonly parts: readonly WildcardPart[];
1210
+ }
1211
+
1212
+ /**
1213
+ * Transition matching any single segment (from * or ?).
1214
+ * May have constraints from character classes or wildcards.
1215
+ * @public
1216
+ */
1217
+ export declare interface WildcardTransition {
1218
+ readonly type: 'wildcard';
1219
+ /** Pattern for segment matching (from *.ts, test-*, etc.) */
1220
+ readonly pattern: RegExp | SegmentMatcher;
1221
+ /** Original pattern string for serialization/debugging */
1222
+ readonly patternSource: string;
1223
+ readonly target: number;
1224
+ }
1225
+
1226
+ /**
1227
+ * Classification of witness paths for explanation generation.
1228
+ * @public
1229
+ */
1230
+ export declare type WitnessCategory = 'counterexample' | 'reverse_counterexample' | 'shared' | 'neither';
1231
+
1232
+ /**
1233
+ * A witness path that demonstrates a containment property.
1234
+ * @public
1235
+ */
1236
+ export declare interface WitnessPath {
1237
+ /** The actual path string */
1238
+ readonly path: string;
1239
+ /** Which pattern(s) this path matches */
1240
+ readonly matchesA: boolean;
1241
+ readonly matchesB: boolean;
1242
+ /**
1243
+ * For counterexamples, the segment index where patterns diverge.
1244
+ * Useful for highlighting the specific point of difference.
1245
+ */
1246
+ readonly divergenceIndex?: number;
1247
+ /**
1248
+ * Human-oriented classification of this witness.
1249
+ */
1250
+ readonly category: WitnessCategory;
1251
+ }
1252
+
1253
+ export { }