lanekeep 0.7.0 → 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 (2) hide show
  1. package/index.d.ts +65 -2
  2. package/package.json +5 -5
package/index.d.ts CHANGED
@@ -78,8 +78,27 @@ export interface RuleCard {
78
78
  }
79
79
  }
80
80
 
81
- /** Cheap rejections applied before a file is parsed. */
81
+ /** Cheap rejections applied before a file is read or parsed. */
82
82
  export interface Gates {
83
+ /**
84
+ * Glob patterns a file's path must match for the rule to consider it.
85
+ *
86
+ * The path is relative to the project root, and the pattern must match the whole path —
87
+ * anchored, not a substring search. Patterns use the `globset` dialect, matched
88
+ * case-sensitively: `*` matches any run of characters (including `/`), `?` any single
89
+ * character, `[ab]`/`[!ab]` character classes and `{a,b}` alternates work, and `**`
90
+ * recurses directories — `src/**` admits everything under `src`, and `**` in front
91
+ * of `*.test.ts` admits a test file at any depth.
92
+ */
93
+ pathMatches?: string[]
94
+ /**
95
+ * Glob patterns that skip a file — a path matching any of these is never parsed. Checked
96
+ * before `pathMatches` and winning over it: a path a `pathMatches` pattern would have
97
+ * admitted is still skipped when a `pathNotMatches` pattern matches it.
98
+ *
99
+ * Same dialect and anchoring as `pathMatches`.
100
+ */
101
+ pathNotMatches?: string[]
83
102
  /**
84
103
  * Literal substrings a file's raw bytes must contain. A file missing any one of them is
85
104
  * never parsed.
@@ -90,6 +109,12 @@ export interface Gates {
90
109
  * form; omit the gate when no single substring covers every case.
91
110
  */
92
111
  fileContains?: string[]
112
+ /**
113
+ * Literal substrings that skip a file — a file whose raw bytes contain **any** of them is
114
+ * never parsed. The mirror image of `fileContains`'s *and*: where that gate requires every
115
+ * listed substring, this one rejects on the first that is present.
116
+ */
117
+ fileNotContains?: string[]
93
118
  }
94
119
 
95
120
  /** A replacement a rule offers for a violation. */
@@ -151,6 +176,21 @@ export interface NodeLocation {
151
176
  column: number
152
177
  }
153
178
 
179
+ /**
180
+ * A subtree's structural fingerprint: identifiers and literal values erased.
181
+ *
182
+ * Computed host-side in one walk, so a rule does not pay a per-node boundary crossing to
183
+ * inspect a tree's shape. Two functions differing only in identifier names, literal values
184
+ * or comments hash identically; differing in an operator or a statement, differently. A
185
+ * dead handle yields `undefined`, like `kind` and `loc`.
186
+ */
187
+ export interface StructureFingerprint {
188
+ /** blake3 of the normalized fold, lowercase hex. */
189
+ hash: string
190
+ /** How many nodes the fold covered — the thresholding input. */
191
+ nodes: number
192
+ }
193
+
154
194
  /** A rule's RuleContext surface. */
155
195
  export interface RuleContext {
156
196
  readonly filePath: string
@@ -165,6 +205,7 @@ export interface RuleContext {
165
205
  children(n: Node): Node[]
166
206
  namedChildren(n: Node): Node[]
167
207
  ancestors(n: Node): Node[]
208
+ structureFingerprint(n: Node): StructureFingerprint | undefined
168
209
  resolvesToImport(n: Node, module: string, name?: string): boolean
169
210
  isImportedFrom(n: Node, pattern: string): boolean
170
211
  bindingKind(n: Node): BindingKind | undefined
@@ -227,8 +268,21 @@ export interface Rule {
227
268
  * Rust matches it across a single shared parse and only matches reach `check`, which is
228
269
  * what keeps a JavaScript rule affordable. Write the narrowest query that captures what
229
270
  * you need; `check` then only refines.
271
+ *
272
+ * A single string applies to every declared language. An object maps each declared
273
+ * language to its own query — required when the grammars do not share node vocabulary
274
+ * (Python spells a call `call`, the other supported grammars say `call_expression`).
275
+ * Every declared language must have an entry and every entry must name a declared
276
+ * language; a mismatch is a config-load error naming the language.
277
+ *
278
+ * Text predicates filter matches in Rust before the handler, so a predicate can only
279
+ * narrow, never widen, what `check` sees: `#eq?`, `#not-eq?`, `#match?`, `#not-match?`,
280
+ * `#any-of?` and `#not-any-of?` are supported (plus the `any-` forms of `eq?`/`match?`).
281
+ * `#match?`/`#not-match?` run on the `regex` crate, which is deterministic and supports
282
+ * no backreferences or lookaround. `#is?`, `#is-not?`, `#set!`, or an operator the
283
+ * binding does not know is refused at compile time.
230
284
  */
231
- query: string
285
+ query: string | Partial<Record<LanguageId, string>>
232
286
  /** A per-invocation budget overriding the default, in milliseconds. */
233
287
  timeout?: number
234
288
  /** Called once per query match. */
@@ -254,6 +308,15 @@ export interface Config {
254
308
  /** Wall-clock, for the whole run. */
255
309
  global?: number
256
310
  }
311
+ /** Policy for suppression directives. All off by default. */
312
+ suppressions?: {
313
+ /** A valid directive with no `expires:` is reported. */
314
+ requireExpiry?: boolean
315
+ /** An expiry more than this many days after today is reported. */
316
+ maxExpiryDays?: number
317
+ /** Any whole-file directive is reported. */
318
+ forbidFileScope?: boolean
319
+ }
257
320
  /** The rules to run, in order. */
258
321
  rules: Rule[]
259
322
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lanekeep",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "Deterministic, AST-based architectural conformance checking",
5
5
  "license": "MIT OR Apache-2.0",
6
6
  "repository": {
@@ -23,10 +23,10 @@
23
23
  "node": ">=18"
24
24
  },
25
25
  "optionalDependencies": {
26
- "@lanekeep/darwin-arm64": "0.7.0",
27
- "@lanekeep/linux-arm64": "0.7.0",
28
- "@lanekeep/linux-x64": "0.7.0",
29
- "@lanekeep/win32-x64": "0.7.0"
26
+ "@lanekeep/darwin-arm64": "0.8.0",
27
+ "@lanekeep/linux-arm64": "0.8.0",
28
+ "@lanekeep/linux-x64": "0.8.0",
29
+ "@lanekeep/win32-x64": "0.8.0"
30
30
  },
31
31
  "main": "index.js",
32
32
  "types": "index.d.ts",