@kernlang/review 3.1.1 → 3.1.3

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 (40) hide show
  1. package/README.md +4 -1
  2. package/dist/concept-rules/index.js +0 -2
  3. package/dist/concept-rules/index.js.map +1 -1
  4. package/dist/concept-rules/unrecovered-effect.js +2 -1
  5. package/dist/concept-rules/unrecovered-effect.js.map +1 -1
  6. package/dist/index.d.ts +1 -0
  7. package/dist/index.js +76 -4
  8. package/dist/index.js.map +1 -1
  9. package/dist/kern-lint.d.ts +9 -3
  10. package/dist/kern-lint.js +22 -3
  11. package/dist/kern-lint.js.map +1 -1
  12. package/dist/llm-bridge.js +53 -6
  13. package/dist/llm-bridge.js.map +1 -1
  14. package/dist/llm-review.js +6 -9
  15. package/dist/llm-review.js.map +1 -1
  16. package/dist/mappers/ts-concepts.js +190 -8
  17. package/dist/mappers/ts-concepts.js.map +1 -1
  18. package/dist/reporter.js +7 -4
  19. package/dist/reporter.js.map +1 -1
  20. package/dist/rule-eval.d.ts +81 -0
  21. package/dist/rule-eval.js +449 -0
  22. package/dist/rule-eval.js.map +1 -0
  23. package/dist/rule-loader.d.ts +17 -0
  24. package/dist/rule-loader.js +155 -0
  25. package/dist/rule-loader.js.map +1 -0
  26. package/dist/rules/base.js +32 -10
  27. package/dist/rules/base.js.map +1 -1
  28. package/dist/rules/null-safety.js +9 -7
  29. package/dist/rules/null-safety.js.map +1 -1
  30. package/dist/rules/react.js +45 -17
  31. package/dist/rules/react.js.map +1 -1
  32. package/dist/rules/security-v3.d.ts +6 -0
  33. package/dist/rules/security-v3.js +13 -6
  34. package/dist/rules/security-v3.js.map +1 -1
  35. package/dist/taint.js +41 -12
  36. package/dist/taint.js.map +1 -1
  37. package/dist/types.d.ts +14 -2
  38. package/dist/types.js +3 -7
  39. package/dist/types.js.map +1 -1
  40. package/package.json +11 -2
@@ -0,0 +1,449 @@
1
+ /**
2
+ * KERN Native Rule Evaluation Engine
3
+ *
4
+ * Evaluates .kern rule definitions against IR node trees.
5
+ * Rules use pattern/guard/expect/message nodes (all existing KERN types)
6
+ * under a `rule` root node.
7
+ */
8
+ import { createFingerprint } from './types.js';
9
+ // ── Concept → IR Wrapper ────────────────────────────────────────────────
10
+ /** Flatten a concept payload into plain props (skip 'kind' — it becomes node type). */
11
+ function flattenPayload(payload) {
12
+ const flat = {};
13
+ for (const [k, v] of Object.entries(payload)) {
14
+ if (k === 'kind')
15
+ continue;
16
+ flat[k] = v;
17
+ }
18
+ return flat;
19
+ }
20
+ function countUpLevels(specifier) {
21
+ const match = specifier.match(/^(\.\.\/)+/);
22
+ if (!match)
23
+ return 0;
24
+ return match[0].length / 3;
25
+ }
26
+ /** Convert a ConceptNode to an IRNode-shaped wrapper for the pattern matcher. */
27
+ export function conceptNodeToIR(concept) {
28
+ const props = {
29
+ ...flattenPayload(concept.payload),
30
+ // Metadata after payload — metadata always wins on collision
31
+ _concept: true,
32
+ evidence: concept.evidence,
33
+ confidence: concept.confidence,
34
+ language: concept.language,
35
+ };
36
+ if (concept.containerId)
37
+ props.containerId = concept.containerId;
38
+ return {
39
+ type: concept.kind,
40
+ loc: {
41
+ line: concept.primarySpan.startLine,
42
+ col: concept.primarySpan.startCol,
43
+ endLine: concept.primarySpan.endLine,
44
+ endCol: concept.primarySpan.endCol,
45
+ },
46
+ props,
47
+ children: [],
48
+ };
49
+ }
50
+ /** Convert a ConceptEdge to an IRNode-shaped wrapper for the pattern matcher. */
51
+ export function conceptEdgeToIR(edge) {
52
+ const props = {
53
+ ...flattenPayload(edge.payload),
54
+ _concept: true,
55
+ _edge: true,
56
+ sourceId: edge.sourceId,
57
+ targetId: edge.targetId,
58
+ evidence: edge.evidence,
59
+ confidence: edge.confidence,
60
+ language: edge.language,
61
+ };
62
+ if ('specifier' in edge.payload && typeof edge.payload.specifier === 'string') {
63
+ props.upLevels = countUpLevels(edge.payload.specifier);
64
+ }
65
+ return {
66
+ type: edge.kind,
67
+ loc: {
68
+ line: edge.primarySpan.startLine,
69
+ col: edge.primarySpan.startCol,
70
+ endLine: edge.primarySpan.endLine,
71
+ endCol: edge.primarySpan.endCol,
72
+ },
73
+ props,
74
+ children: [],
75
+ };
76
+ }
77
+ /** Build a rule index from a list of IR nodes, optionally including concept nodes and edges. */
78
+ export function buildRuleIndex(nodes, concepts) {
79
+ const nodesByType = new Map();
80
+ const parentMap = new Map();
81
+ const allNodes = [];
82
+ function walk(node, parent) {
83
+ allNodes.push(node);
84
+ parentMap.set(node, parent);
85
+ const list = nodesByType.get(node.type);
86
+ if (list)
87
+ list.push(node);
88
+ else
89
+ nodesByType.set(node.type, [node]);
90
+ for (const child of node.children || []) {
91
+ walk(child, node);
92
+ }
93
+ }
94
+ for (const node of nodes)
95
+ walk(node);
96
+ // Add concept nodes and edges as flat IRNode wrappers (no parent, no children)
97
+ if (concepts) {
98
+ for (const cn of concepts.nodes) {
99
+ walk(conceptNodeToIR(cn));
100
+ }
101
+ for (const ce of concepts.edges) {
102
+ walk(conceptEdgeToIR(ce));
103
+ }
104
+ }
105
+ // Build peer index — index nodes by prop values for peer-scoped guards
106
+ const peerIndex = new Map();
107
+ for (const node of allNodes) {
108
+ const np = node.props || {};
109
+ for (const [field, val] of Object.entries(np)) {
110
+ if (typeof val !== 'string' || field.startsWith('_'))
111
+ continue;
112
+ let fieldMap = peerIndex.get(field);
113
+ if (!fieldMap) {
114
+ fieldMap = new Map();
115
+ peerIndex.set(field, fieldMap);
116
+ }
117
+ let list = fieldMap.get(val);
118
+ if (!list) {
119
+ list = [];
120
+ fieldMap.set(val, list);
121
+ }
122
+ list.push(node);
123
+ }
124
+ }
125
+ return { nodesByType, parentMap, allNodes, peerIndex };
126
+ }
127
+ const NO_MATCH = { matched: false, bindings: new Map() };
128
+ /** Get props from a node safely. */
129
+ function p(node) {
130
+ return node.props || {};
131
+ }
132
+ /** Get children of a specific type. */
133
+ function childrenOf(node, type) {
134
+ const c = node.children || [];
135
+ return type ? c.filter(n => n.type === type) : c;
136
+ }
137
+ /**
138
+ * Match a pattern node against a target node.
139
+ *
140
+ * Pattern props:
141
+ * - type=X: target must have this type
142
+ * - prop=X: target must have this prop defined
143
+ * - Any other prop: target must have matching prop value
144
+ *
145
+ * Pattern children:
146
+ * - guard: evaluated as a guard clause
147
+ * - expect: evaluated as a quantifier
148
+ * - Nested pattern: matched recursively against target's children
149
+ */
150
+ export function matchPattern(pattern, target, index) {
151
+ const pp = p(pattern);
152
+ const tp = p(target);
153
+ const bindings = new Map();
154
+ // Subject filtering — concept nodes isolated from IR nodes
155
+ // subject=concept → only concept nodes; anything else → only IR nodes
156
+ const subject = pp.subject;
157
+ const isConcept = tp._concept === true;
158
+ if (subject === 'concept' && !isConcept)
159
+ return NO_MATCH;
160
+ if (subject !== 'concept' && isConcept)
161
+ return NO_MATCH;
162
+ // Type check
163
+ if (pp.type && pp.type !== target.type)
164
+ return NO_MATCH;
165
+ // Prop existence check (prop=X means "target must have prop X")
166
+ if (pp.prop) {
167
+ const propName = pp.prop;
168
+ if (tp[propName] === undefined)
169
+ return NO_MATCH;
170
+ }
171
+ // Direct prop value matching (name=value checks target.props.name === value)
172
+ // Supports pipe-separated OR: subtype=auth|validation matches either
173
+ for (const [key, val] of Object.entries(pp)) {
174
+ if (['type', 'prop', 'subject', 'not'].includes(key))
175
+ continue;
176
+ if (key.startsWith('min-') || key.startsWith('max-')) {
177
+ const propName = key.slice(4);
178
+ const targetNum = Number(tp[propName]);
179
+ const bound = Number(val);
180
+ if (propName.length === 0 || Number.isNaN(targetNum) || Number.isNaN(bound))
181
+ return NO_MATCH;
182
+ if (key.startsWith('min-') && targetNum < bound)
183
+ return NO_MATCH;
184
+ if (key.startsWith('max-') && targetNum > bound)
185
+ return NO_MATCH;
186
+ continue;
187
+ }
188
+ if (tp[key] === undefined)
189
+ continue;
190
+ const strVal = String(val);
191
+ const targetVal = String(tp[key]);
192
+ if (strVal.includes('|')) {
193
+ const alternatives = strVal.split('|');
194
+ if (!alternatives.includes(targetVal))
195
+ return NO_MATCH;
196
+ }
197
+ else {
198
+ if (targetVal !== strVal)
199
+ return NO_MATCH;
200
+ }
201
+ }
202
+ // Capture all target props as bindings for message interpolation
203
+ for (const [key, val] of Object.entries(tp)) {
204
+ bindings.set(key, val);
205
+ }
206
+ bindings.set('type', target.type);
207
+ // Evaluate child guard nodes
208
+ for (const guard of childrenOf(pattern, 'guard')) {
209
+ if (!evaluateGuard(guard, target, index))
210
+ return NO_MATCH;
211
+ }
212
+ // Evaluate child expect nodes
213
+ for (const expect of childrenOf(pattern, 'expect')) {
214
+ if (!evaluateExpect(expect, target))
215
+ return NO_MATCH;
216
+ }
217
+ // Evaluate nested pattern children (match against target's children)
218
+ for (const subPattern of childrenOf(pattern, 'pattern')) {
219
+ const subPp = p(subPattern);
220
+ const matchType = subPp.type;
221
+ const targetChildren = matchType
222
+ ? childrenOf(target, matchType)
223
+ : (target.children || []);
224
+ let anyMatch = false;
225
+ for (const child of targetChildren) {
226
+ const result = matchPattern(subPattern, child, index);
227
+ if (result.matched) {
228
+ anyMatch = true;
229
+ for (const [k, v] of result.bindings)
230
+ bindings.set(k, v);
231
+ break;
232
+ }
233
+ }
234
+ if (!anyMatch)
235
+ return NO_MATCH;
236
+ }
237
+ return { matched: true, bindings };
238
+ }
239
+ // ── Guard Evaluation ────────────────────────────────────────────────────
240
+ /**
241
+ * Evaluate a guard clause against a target node.
242
+ *
243
+ * Guard props:
244
+ * - not=true: negate the result
245
+ * - prop=X: check if target has prop X (negated: check target does NOT have prop X)
246
+ * - scope=X: check if any ancestor has type X
247
+ * - peer=X: check if any node sharing the same value of prop X matches child patterns
248
+ *
249
+ * Guard children:
250
+ * - pattern: must match against target (negated: must NOT match)
251
+ * When peer=X is set, child patterns match against peer nodes instead of target
252
+ */
253
+ export function evaluateGuard(guard, target, index) {
254
+ const gp = p(guard);
255
+ const isNegated = gp.not === 'true' || gp.not === true;
256
+ let result = true;
257
+ // Prop existence check
258
+ if (gp.prop) {
259
+ const propName = gp.prop;
260
+ const tp = p(target);
261
+ if (tp[propName] === undefined)
262
+ result = false;
263
+ }
264
+ // Scope check — walk ancestor chain (AND-combined with prop check)
265
+ if (result && gp.scope) {
266
+ const scopeType = gp.scope;
267
+ let current = index.parentMap.get(target);
268
+ let found = false;
269
+ while (current) {
270
+ if (current.type === scopeType) {
271
+ found = true;
272
+ break;
273
+ }
274
+ current = index.parentMap.get(current);
275
+ }
276
+ if (!found)
277
+ result = false;
278
+ }
279
+ // Peer check — find nodes sharing the same prop value, match child patterns against them
280
+ if (result && gp.peer) {
281
+ const peerField = gp.peer;
282
+ const targetValue = p(target)[peerField];
283
+ if (!targetValue || typeof targetValue !== 'string') {
284
+ result = false;
285
+ }
286
+ else {
287
+ const peerPatterns = childrenOf(guard, 'pattern');
288
+ if (peerPatterns.length > 0) {
289
+ const fieldMap = index.peerIndex.get(peerField);
290
+ const peers = fieldMap?.get(targetValue) || [];
291
+ let anyPeerMatch = false;
292
+ for (const peer of peers) {
293
+ if (peer === target)
294
+ continue; // skip self
295
+ let allMatch = true;
296
+ for (const pp of peerPatterns) {
297
+ if (!matchPattern(pp, peer, index).matched) {
298
+ allMatch = false;
299
+ break;
300
+ }
301
+ }
302
+ if (allMatch) {
303
+ anyPeerMatch = true;
304
+ break;
305
+ }
306
+ }
307
+ result = anyPeerMatch;
308
+ }
309
+ }
310
+ }
311
+ else {
312
+ // Child pattern matching (non-peer: match against target itself)
313
+ for (const subPattern of childrenOf(guard, 'pattern')) {
314
+ const subResult = matchPattern(subPattern, target, index);
315
+ if (!subResult.matched) {
316
+ result = false;
317
+ break;
318
+ }
319
+ }
320
+ }
321
+ return isNegated ? !result : result;
322
+ }
323
+ // ── Expect Evaluation ───────────────────────────────────────────────────
324
+ /**
325
+ * Evaluate a quantifier (expect node) against a target node.
326
+ *
327
+ * Expect props:
328
+ * - child-type=X: count children of type X
329
+ * - min=N: require at least N matching children
330
+ * - max=N: require at most N matching children
331
+ * - exact=N: require exactly N matching children
332
+ */
333
+ export function evaluateExpect(expect, target) {
334
+ const ep = p(expect);
335
+ const childType = ep['child-type'];
336
+ const matching = childType ? childrenOf(target, childType) : (target.children || []);
337
+ const count = matching.length;
338
+ const min = ep.min !== undefined ? Number(ep.min) : undefined;
339
+ const max = ep.max !== undefined ? Number(ep.max) : undefined;
340
+ const exact = ep.exact !== undefined ? Number(ep.exact) : undefined;
341
+ if (min !== undefined && !Number.isNaN(min) && count < min)
342
+ return false;
343
+ if (max !== undefined && !Number.isNaN(max) && count > max)
344
+ return false;
345
+ if (exact !== undefined && !Number.isNaN(exact) && count !== exact)
346
+ return false;
347
+ return true;
348
+ }
349
+ // ── Message Interpolation ───────────────────────────────────────────────
350
+ /**
351
+ * Interpolate {{prop}} placeholders in a message template.
352
+ */
353
+ export function interpolateMessage(template, bindings) {
354
+ return template.replace(/\{\{([\w-]+)\}\}/g, (_match, key) => {
355
+ const val = bindings.get(key);
356
+ return val !== undefined ? String(val) : `{{${key}}}`;
357
+ });
358
+ }
359
+ // ── Fix Action Construction ─────────────────────────────────────────────
360
+ /**
361
+ * Build a FixAction from a fix node (body child with multiline code).
362
+ */
363
+ function buildFixAction(fixNode, target, bindings) {
364
+ const fp = p(fixNode);
365
+ const op = fp.op || 'insert-after';
366
+ const bodyNode = childrenOf(fixNode, 'body')[0];
367
+ const code = bodyNode ? (p(bodyNode).code || '') : '';
368
+ if (!code)
369
+ return undefined;
370
+ const replacement = interpolateMessage(code, bindings);
371
+ const span = {
372
+ file: '',
373
+ startLine: target.loc?.line ?? 0,
374
+ startCol: target.loc?.col ?? 0,
375
+ endLine: target.loc?.endLine ?? target.loc?.line ?? 0,
376
+ endCol: target.loc?.endCol ?? target.loc?.col ?? 0,
377
+ };
378
+ return {
379
+ type: op,
380
+ span,
381
+ replacement,
382
+ description: fp.description || `Apply ${op} fix`,
383
+ };
384
+ }
385
+ // ── Rule Evaluation ─────────────────────────────────────────────────────
386
+ /**
387
+ * Evaluate a single native KERN rule against an indexed IR tree.
388
+ * Returns findings for all matched nodes.
389
+ * When concepts are provided, concept nodes are included in the index
390
+ * and accessible via `subject=concept` in pattern nodes.
391
+ */
392
+ export function evaluateRule(rule, index, filePath) {
393
+ const rp = p(rule);
394
+ const ruleId = rp.id || 'unnamed-rule';
395
+ const severity = rp.severity || 'warning';
396
+ const category = rp.category || 'pattern';
397
+ const confidence = rp.confidence !== undefined ? Number(rp.confidence) : undefined;
398
+ // Get the pattern node
399
+ const patternNode = childrenOf(rule, 'pattern')[0];
400
+ if (!patternNode)
401
+ return [];
402
+ // Get the message template
403
+ const messageNode = childrenOf(rule, 'message')[0];
404
+ const template = messageNode ? p(messageNode).template || '' : ruleId;
405
+ // Get optional fix node
406
+ const fixNode = childrenOf(rule, 'fix')[0];
407
+ // Determine which nodes to check based on pattern type
408
+ const patternType = p(patternNode).type;
409
+ const candidates = patternType
410
+ ? (index.nodesByType.get(patternType) || [])
411
+ : index.allNodes;
412
+ const findings = [];
413
+ for (const target of candidates) {
414
+ const result = matchPattern(patternNode, target, index);
415
+ if (!result.matched)
416
+ continue;
417
+ const message = interpolateMessage(template, result.bindings);
418
+ const line = target.loc?.line ?? 0;
419
+ const col = target.loc?.col ?? 1;
420
+ const finding = {
421
+ source: 'kern-native',
422
+ ruleId,
423
+ severity,
424
+ category,
425
+ message,
426
+ primarySpan: {
427
+ file: filePath,
428
+ startLine: line,
429
+ startCol: col,
430
+ endLine: target.loc?.endLine ?? line,
431
+ endCol: target.loc?.endCol ?? col,
432
+ },
433
+ fingerprint: createFingerprint(ruleId, line, col),
434
+ };
435
+ if (confidence !== undefined)
436
+ finding.confidence = confidence;
437
+ // Build autofix if fix node exists
438
+ if (fixNode) {
439
+ const action = buildFixAction(fixNode, target, result.bindings);
440
+ if (action) {
441
+ action.span.file = filePath;
442
+ finding.autofix = action;
443
+ }
444
+ }
445
+ findings.push(finding);
446
+ }
447
+ return findings;
448
+ }
449
+ //# sourceMappingURL=rule-eval.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule-eval.js","sourceRoot":"","sources":["../src/rule-eval.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * KERN Native Rule Loader
3
+ *
4
+ * Discovers .kern rule files, parses them, validates structure,
5
+ * and wraps each rule in a KernLintRule adapter for the existing pipeline.
6
+ */
7
+ import type { KernLintRule } from './kern-lint.js';
8
+ /**
9
+ * Load native .kern rule files from a directory.
10
+ * Returns KernLintRule adapters for all valid rules found.
11
+ * Supports `import from="other.kern"` for rule composition.
12
+ */
13
+ export declare function loadNativeRules(dirs: string[], skipIds?: Set<string>): KernLintRule[];
14
+ /**
15
+ * Load native rules from the built-in rules directory.
16
+ */
17
+ export declare function loadBuiltinNativeRules(): KernLintRule[];
@@ -0,0 +1,155 @@
1
+ /**
2
+ * KERN Native Rule Loader
3
+ *
4
+ * Discovers .kern rule files, parses them, validates structure,
5
+ * and wraps each rule in a KernLintRule adapter for the existing pipeline.
6
+ */
7
+ import { readFileSync, existsSync, readdirSync, realpathSync } from 'fs';
8
+ import { resolve, join, dirname } from 'path';
9
+ import { fileURLToPath } from 'url';
10
+ import { parseDocument } from '@kernlang/core';
11
+ import { buildRuleIndex, evaluateRule } from './rule-eval.js';
12
+ // ── Validation ──────────────────────────────────────────────────────────
13
+ /** Validate that a rule node has the required structure. */
14
+ function validateRule(rule) {
15
+ const errors = [];
16
+ const rp = rule.props || {};
17
+ const children = rule.children || [];
18
+ if (!rp.id)
19
+ errors.push('Rule missing id prop');
20
+ const hasPattern = children.some(c => c.type === 'pattern');
21
+ if (!hasPattern)
22
+ errors.push('Rule missing pattern child');
23
+ const hasMessage = children.some(c => c.type === 'message');
24
+ if (!hasMessage)
25
+ errors.push('Rule missing message child');
26
+ // Validate severity if present
27
+ if (rp.severity && !['error', 'warning', 'info'].includes(rp.severity)) {
28
+ errors.push(`Invalid severity: ${rp.severity}`);
29
+ }
30
+ // Validate category if present
31
+ if (rp.category && !['bug', 'type', 'pattern', 'style', 'structure'].includes(rp.category)) {
32
+ errors.push(`Invalid category: ${rp.category}`);
33
+ }
34
+ return errors;
35
+ }
36
+ // ── Rule Adapter ────────────────────────────────────────────────────────
37
+ /**
38
+ * Wrap a parsed rule IRNode into a KernLintRule function.
39
+ * The adapter builds a RuleIndex from the target nodes and evaluates the rule.
40
+ * When concepts are provided, concept nodes are included in the index.
41
+ */
42
+ function nativeRuleAdapter(ruleNode) {
43
+ const ruleId = ruleNode.props?.id || 'unnamed-rule';
44
+ const adapter = (nodes, concepts) => {
45
+ const index = buildRuleIndex(nodes, concepts);
46
+ // Pass empty filePath — the review pipeline patches it downstream
47
+ // (same pattern as ground-layer rules in ground-layer.ts:45)
48
+ return evaluateRule(ruleNode, index, '');
49
+ };
50
+ adapter.ruleId = ruleId;
51
+ return adapter;
52
+ }
53
+ // ── Loader ──────────────────────────────────────────────────────────────
54
+ /**
55
+ * Load rules from a single .kern file, resolving imports recursively.
56
+ * The visited set guards against circular imports.
57
+ * allowedRoots constrains import resolution — imports that escape these dirs are rejected.
58
+ */
59
+ function loadRulesFromFile(filePath, rules, visited, skipIds = new Set(), allowedRoots = []) {
60
+ const absPath = resolve(filePath);
61
+ if (visited.has(absPath))
62
+ return;
63
+ visited.add(absPath);
64
+ if (!existsSync(absPath)) {
65
+ console.warn(`[kern-native] Import not found: ${absPath}`);
66
+ return;
67
+ }
68
+ try {
69
+ const source = readFileSync(absPath, 'utf-8');
70
+ const doc = parseDocument(source);
71
+ const children = doc.children || [];
72
+ // Resolve imports first (relative to importing file)
73
+ for (const node of children) {
74
+ if (node.type !== 'import')
75
+ continue;
76
+ const from = node.props?.from || '';
77
+ if (!from || !from.endsWith('.kern'))
78
+ continue;
79
+ const importPath = resolve(dirname(absPath), from);
80
+ // Containment check: resolved import must be inside an allowed root
81
+ if (allowedRoots.length > 0) {
82
+ let realImportPath;
83
+ try {
84
+ realImportPath = realpathSync(importPath);
85
+ }
86
+ catch {
87
+ realImportPath = importPath;
88
+ }
89
+ const confined = allowedRoots.some(root => realImportPath.startsWith(root + '/') || realImportPath === root);
90
+ if (!confined) {
91
+ console.warn(`[kern-native] Import '${from}' escapes allowed roots — skipped`);
92
+ continue;
93
+ }
94
+ }
95
+ loadRulesFromFile(importPath, rules, visited, skipIds, allowedRoots);
96
+ }
97
+ // Extract and validate rule nodes
98
+ for (const ruleNode of children.filter(n => n.type === 'rule')) {
99
+ const errors = validateRule(ruleNode);
100
+ if (errors.length > 0) {
101
+ console.warn(`[kern-native] Skipping invalid rule in ${absPath}: ${errors.join(', ')}`);
102
+ continue;
103
+ }
104
+ const ruleId = ruleNode.props?.id;
105
+ if (ruleId && skipIds.has(ruleId)) {
106
+ console.warn(`[kern-native] Skipping duplicate ruleId '${ruleId}' from ${absPath} (already loaded)`);
107
+ continue;
108
+ }
109
+ const adapter = nativeRuleAdapter(ruleNode);
110
+ rules.push(adapter);
111
+ if (ruleId)
112
+ skipIds.add(ruleId);
113
+ }
114
+ }
115
+ catch (err) {
116
+ console.warn(`[kern-native] Failed to parse ${absPath}: ${err.message}`);
117
+ }
118
+ }
119
+ /**
120
+ * Load native .kern rule files from a directory.
121
+ * Returns KernLintRule adapters for all valid rules found.
122
+ * Supports `import from="other.kern"` for rule composition.
123
+ */
124
+ export function loadNativeRules(dirs, skipIds = new Set()) {
125
+ const rules = [];
126
+ const visited = new Set();
127
+ // Compute real paths of allowed roots for containment checks
128
+ const allowedRoots = dirs.map(d => { try {
129
+ return realpathSync(resolve(d));
130
+ }
131
+ catch {
132
+ return resolve(d);
133
+ } });
134
+ for (const dir of dirs) {
135
+ if (!existsSync(dir))
136
+ continue;
137
+ const files = readdirSync(dir).filter((f) => f.endsWith('.kern'));
138
+ for (const file of files) {
139
+ loadRulesFromFile(join(dir, file), rules, visited, skipIds, allowedRoots);
140
+ }
141
+ }
142
+ return rules;
143
+ }
144
+ /**
145
+ * Load native rules from the built-in rules directory.
146
+ */
147
+ export function loadBuiltinNativeRules() {
148
+ const __dirname = dirname(fileURLToPath(import.meta.url));
149
+ // Try dist/rules/native first, fall back to src/rules/native (dev mode)
150
+ const distDir = resolve(__dirname, 'rules', 'native');
151
+ const srcDir = resolve(__dirname, '..', 'src', 'rules', 'native');
152
+ const builtinDir = existsSync(distDir) ? distDir : srcDir;
153
+ return loadNativeRules([builtinDir]);
154
+ }
155
+ //# sourceMappingURL=rule-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule-loader.js","sourceRoot":"","sources":["../src/rule-loader.ts"],"names":[],"mappings":"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"}