@kernlang/review 3.3.4 → 3.3.6

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 (62) hide show
  1. package/dist/cache.js +1 -1
  2. package/dist/concept-rules/auth-drift.d.ts +29 -0
  3. package/dist/concept-rules/auth-drift.js +127 -0
  4. package/dist/concept-rules/auth-drift.js.map +1 -0
  5. package/dist/concept-rules/contract-drift.d.ts +21 -0
  6. package/dist/concept-rules/contract-drift.js +65 -0
  7. package/dist/concept-rules/contract-drift.js.map +1 -0
  8. package/dist/concept-rules/contract-method-drift.d.ts +22 -0
  9. package/dist/concept-rules/contract-method-drift.js +105 -0
  10. package/dist/concept-rules/contract-method-drift.js.map +1 -0
  11. package/dist/concept-rules/cross-stack-utils.d.ts +96 -0
  12. package/dist/concept-rules/cross-stack-utils.js +259 -0
  13. package/dist/concept-rules/cross-stack-utils.js.map +1 -0
  14. package/dist/concept-rules/duplicate-route.d.ts +20 -0
  15. package/dist/concept-rules/duplicate-route.js +112 -0
  16. package/dist/concept-rules/duplicate-route.js.map +1 -0
  17. package/dist/concept-rules/index.js +26 -1
  18. package/dist/concept-rules/index.js.map +1 -1
  19. package/dist/concept-rules/missing-response-model.d.ts +10 -0
  20. package/dist/concept-rules/missing-response-model.js +38 -0
  21. package/dist/concept-rules/missing-response-model.js.map +1 -0
  22. package/dist/concept-rules/orphan-route.d.ts +20 -0
  23. package/dist/concept-rules/orphan-route.js +96 -0
  24. package/dist/concept-rules/orphan-route.js.map +1 -0
  25. package/dist/concept-rules/sync-handler-does-io.d.ts +9 -0
  26. package/dist/concept-rules/sync-handler-does-io.js +56 -0
  27. package/dist/concept-rules/sync-handler-does-io.js.map +1 -0
  28. package/dist/concept-rules/tainted-across-wire.d.ts +33 -0
  29. package/dist/concept-rules/tainted-across-wire.js +95 -0
  30. package/dist/concept-rules/tainted-across-wire.js.map +1 -0
  31. package/dist/concept-rules/untyped-api-response.d.ts +30 -0
  32. package/dist/concept-rules/untyped-api-response.js +73 -0
  33. package/dist/concept-rules/untyped-api-response.js.map +1 -0
  34. package/dist/concept-rules/untyped-both-ends-response.d.ts +10 -0
  35. package/dist/concept-rules/untyped-both-ends-response.js +55 -0
  36. package/dist/concept-rules/untyped-both-ends-response.js.map +1 -0
  37. package/dist/external-tools.d.ts +17 -4
  38. package/dist/external-tools.js +12 -1
  39. package/dist/external-tools.js.map +1 -1
  40. package/dist/index.d.ts +2 -1
  41. package/dist/index.js +115 -9
  42. package/dist/index.js.map +1 -1
  43. package/dist/llm-bridge.d.ts +38 -1
  44. package/dist/llm-bridge.js +172 -12
  45. package/dist/llm-bridge.js.map +1 -1
  46. package/dist/llm-review.js +29 -11
  47. package/dist/llm-review.js.map +1 -1
  48. package/dist/mappers/ts-concepts.js +650 -11
  49. package/dist/mappers/ts-concepts.js.map +1 -1
  50. package/dist/rules/index.js +17 -1
  51. package/dist/rules/index.js.map +1 -1
  52. package/dist/rules/kern-source.js +37 -5
  53. package/dist/rules/kern-source.js.map +1 -1
  54. package/dist/rules/set-setter-collision.d.ts +21 -0
  55. package/dist/rules/set-setter-collision.js +74 -0
  56. package/dist/rules/set-setter-collision.js.map +1 -0
  57. package/dist/rules/suggest-kern-primitive.d.ts +30 -0
  58. package/dist/rules/suggest-kern-primitive.js +543 -0
  59. package/dist/rules/suggest-kern-primitive.js.map +1 -0
  60. package/dist/types.d.ts +2 -0
  61. package/dist/types.js.map +1 -1
  62. package/package.json +2 -2
@@ -0,0 +1,543 @@
1
+ /**
2
+ * suggest-kern-primitive — migration rule that flags JS patterns where an
3
+ * equivalent KERN primitive exists (array methods + fmt + conditional + async).
4
+ *
5
+ * Fires as `info` / precision=`experimental` so kern-sight hides it by default.
6
+ * Opt in with `--rule suggest-kern-primitive` for a one-shot migration scan.
7
+ *
8
+ * Covers the 22 shipped array primitives (post PR #93 + #103 + PR C):
9
+ * filter, find, some, every, findIndex, reduce, map, flatMap, flat, slice,
10
+ * at, sort, reverse, join, includes, indexOf, lastIndexOf, concat, forEach,
11
+ * compact, pluck, unique.
12
+ *
13
+ * Plus three structural primitives:
14
+ * - Template literal in `const` → `fmt name=x template="…"`
15
+ * - JSX ternary in `{…}` → `conditional if="…"` + handler/else
16
+ * - async fn with try/catch → `async name=X` + `recover`/`strategy`
17
+ *
18
+ * Special-cased shapes (route to the narrower primitive rather than the generic one):
19
+ * - `.filter(Boolean)` → `compact`
20
+ * - `.map(x => x.prop[.chain])` → `pluck`
21
+ * - `[...new Set(coll)]` → `unique`
22
+ *
23
+ * Immutability note: TS `.sort()` and `.reverse()` mutate; KERN emits the
24
+ * immutable `[...coll].sort(...)` / `[...coll].reverse()` shape. Suggestions
25
+ * for those two methods include a callout so authors can audit callers before
26
+ * migrating.
27
+ */
28
+ import { Node, SyntaxKind } from 'ts-morph';
29
+ import { finding } from './utils.js';
30
+ const ARRAY_METHODS = {
31
+ filter: { kernNode: 'filter', shape: 'predicate' },
32
+ find: { kernNode: 'find', shape: 'predicate' },
33
+ some: { kernNode: 'some', shape: 'predicate' },
34
+ every: { kernNode: 'every', shape: 'predicate' },
35
+ findIndex: { kernNode: 'findIndex', shape: 'predicate' },
36
+ map: { kernNode: 'map', shape: 'expr' },
37
+ flatMap: { kernNode: 'flatMap', shape: 'expr' },
38
+ reduce: { kernNode: 'reduce', shape: 'reduce' },
39
+ slice: { kernNode: 'slice', shape: 'slice' },
40
+ at: { kernNode: 'at', shape: 'at' },
41
+ flat: { kernNode: 'flat', shape: 'flat' },
42
+ join: { kernNode: 'join', shape: 'join' },
43
+ includes: { kernNode: 'includes', shape: 'value' },
44
+ indexOf: { kernNode: 'indexOf', shape: 'value' },
45
+ lastIndexOf: { kernNode: 'lastIndexOf', shape: 'value' },
46
+ concat: { kernNode: 'concat', shape: 'concat' },
47
+ forEach: { kernNode: 'forEach', shape: 'forEach' },
48
+ sort: { kernNode: 'sort', shape: 'sort' },
49
+ reverse: { kernNode: 'reverse', shape: 'reverse' },
50
+ };
51
+ // Node kinds whose descendants should be skipped — don't flag opportunities
52
+ // inside test files, type-only files, or generated code paths by path hint.
53
+ function shouldSkipFile(ctx) {
54
+ const p = ctx.filePath.toLowerCase();
55
+ if (p.endsWith('.d.ts'))
56
+ return true;
57
+ if (p.includes('/node_modules/'))
58
+ return true;
59
+ if (p.includes('/dist/') || p.includes('/build/'))
60
+ return true;
61
+ if (p.includes('/generated/'))
62
+ return true;
63
+ return false;
64
+ }
65
+ function isArrowLike(n) {
66
+ return !!n && (Node.isArrowFunction(n) || Node.isFunctionExpression(n));
67
+ }
68
+ /**
69
+ * Extract an arrow/function body as a single expression string.
70
+ * Returns null for block bodies (multi-statement), which aren't a clean fit
71
+ * for an inline `where=` / `expr=` suggestion — those need a handler block.
72
+ */
73
+ function extractSingleExprBody(arrow) {
74
+ const body = arrow.getBody();
75
+ if (Node.isBlock(body))
76
+ return null;
77
+ return body.getText();
78
+ }
79
+ function escapeKernString(s) {
80
+ return s.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\r?\n/g, ' ').replace(/\s+/g, ' ').trim();
81
+ }
82
+ /**
83
+ * Template-content escape: preserve whitespace (template body is significant)
84
+ * but neutralise characters that would break out of a double-quoted `template=`
85
+ * prop. `${…}` placeholders pass through untouched — that's the whole reason
86
+ * `fmt` exists.
87
+ */
88
+ function escapeKernTemplate(s) {
89
+ return s.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
90
+ }
91
+ function isJsxLike(n) {
92
+ return Node.isJsxElement(n) || Node.isJsxFragment(n) || Node.isJsxSelfClosingElement(n);
93
+ }
94
+ function paramName(arrow, idx) {
95
+ const params = arrow.getParameters();
96
+ if (params.length <= idx)
97
+ return null;
98
+ const name = params[idx].getName();
99
+ // Destructured or rest parameters — skip, they don't round-trip into a bare identifier binding.
100
+ if (name.startsWith('{') || name.startsWith('[') || name.startsWith('...'))
101
+ return null;
102
+ return name;
103
+ }
104
+ /**
105
+ * Is the arrow a Boolean-coercion shape `x => !!x` or `x => Boolean(x)` where
106
+ * the coerced expression is just the first parameter? These are the two
107
+ * common handwritten equivalents of `.filter(Boolean)` and route to `compact`.
108
+ *
109
+ * Only matches when the arrow's body references the parameter directly — not
110
+ * a property access or a computed expression — so we don't silently rewrite
111
+ * `x => !!x.active` (which is `filter where="x.active"`, not `compact`).
112
+ */
113
+ function isBooleanCoercionOfFirstParam(arrow) {
114
+ if (arrow.getParameters().length !== 1)
115
+ return false;
116
+ const param = paramName(arrow, 0);
117
+ if (!param)
118
+ return false;
119
+ const body = arrow.getBody();
120
+ if (Node.isBlock(body))
121
+ return false;
122
+ // `!!x` — PrefixUnaryExpression(!, PrefixUnaryExpression(!, <Identifier param>))
123
+ if (Node.isPrefixUnaryExpression(body) && body.getOperatorToken() === SyntaxKind.ExclamationToken) {
124
+ const inner = body.getOperand();
125
+ if (Node.isPrefixUnaryExpression(inner) && inner.getOperatorToken() === SyntaxKind.ExclamationToken) {
126
+ const innermost = inner.getOperand();
127
+ if (Node.isIdentifier(innermost) && innermost.getText() === param)
128
+ return true;
129
+ }
130
+ }
131
+ // `Boolean(x)` — CallExpression where callee is Identifier "Boolean" and sole arg is the param.
132
+ if (Node.isCallExpression(body)) {
133
+ const callee = body.getExpression();
134
+ if (Node.isIdentifier(callee) && callee.getText() === 'Boolean') {
135
+ const args = body.getArguments();
136
+ if (args.length === 1 && Node.isIdentifier(args[0]) && args[0].getText() === param)
137
+ return true;
138
+ }
139
+ }
140
+ return false;
141
+ }
142
+ /**
143
+ * If the arrow body is a property-access chain rooted at `item` (the first
144
+ * parameter), return the dot-path without the item prefix. Returns null for
145
+ * anything else — computed access, method calls, nested expressions, or
146
+ * optional-chain segments (since `pluck` emits plain dot-access that would
147
+ * throw if an intermediate is nullish).
148
+ *
149
+ * item => item.name → "name"
150
+ * u => u.profile.address.city → "profile.address.city"
151
+ * u => u.profile?.name → null (optional chain; kern `pluck` emits plain `.`)
152
+ * x => x.toUpperCase() → null (method call, not property chain)
153
+ * x => x[0] → null (computed, index access)
154
+ * x => x → null (just the parameter, no projection)
155
+ */
156
+ function propertyAccessChainFromItem(arrow, itemName) {
157
+ const body = arrow.getBody();
158
+ if (Node.isBlock(body))
159
+ return null;
160
+ if (!Node.isPropertyAccessExpression(body))
161
+ return null;
162
+ const segments = [];
163
+ let cur = body;
164
+ while (Node.isPropertyAccessExpression(cur)) {
165
+ // Optional-chain segments would require KERN to emit `item.a?.b`, which
166
+ // the current `pluck` lowering does not support. Fall back to `map`.
167
+ if (cur.hasQuestionDotToken())
168
+ return null;
169
+ segments.unshift(cur.getName());
170
+ cur = cur.getExpression();
171
+ }
172
+ if (!Node.isIdentifier(cur) || cur.getText() !== itemName)
173
+ return null;
174
+ return segments.join('.');
175
+ }
176
+ /**
177
+ * Is the TS text safe to inject into a KERN bare prop value (after `prop=`)?
178
+ * KERN's bare-prop parser stops at whitespace, `{`, and `$`. Anything else
179
+ * must be wrapped in a raw-expression form `{{ … }}` so the receiver survives
180
+ * parsing intact.
181
+ */
182
+ function isBareKernValue(s) {
183
+ return /^[A-Za-z_$][\w.$[\]]*$/.test(s);
184
+ }
185
+ /**
186
+ * Wrap a TS expression text for use as a KERN bare prop value. Identifiers
187
+ * and simple property paths pass through; anything else becomes a raw-
188
+ * expression block so whitespace/operators/calls don't break parsing.
189
+ */
190
+ function toKernInValue(s) {
191
+ return isBareKernValue(s) ? s : `{{ ${s} }}`;
192
+ }
193
+ /**
194
+ * Build the KERN primitive suggestion string for a single JS call site.
195
+ * Returns null when the call shape can't be cleanly migrated (e.g. block body,
196
+ * missing required args) — caller should skip silently in those cases.
197
+ */
198
+ function buildSuggestion(spec, collection, call) {
199
+ const args = call.getArguments();
200
+ const name = '<name>';
201
+ // Wrap non-bare receivers (chained calls, parenthesized, whitespace) so
202
+ // KERN bare-prop parsing doesn't truncate at the first space.
203
+ const inVal = toKernInValue(collection);
204
+ switch (spec.shape) {
205
+ case 'predicate': {
206
+ // Skip arrows whose body references the second (index) parameter —
207
+ // KERN's predicate-form primitives don't bind an index, so migrating
208
+ // `(x, i) => i === 0` would silently drop `i`.
209
+ if (args.length !== 1 || !isArrowLike(args[0]))
210
+ return null;
211
+ const arrow = args[0];
212
+ if (arrow.getParameters().length > 1)
213
+ return null;
214
+ const item = paramName(arrow, 0);
215
+ if (!item)
216
+ return null;
217
+ const body = extractSingleExprBody(arrow);
218
+ if (body === null)
219
+ return null;
220
+ const itemProp = item === 'item' ? '' : ` item=${item}`;
221
+ return `${spec.kernNode} name=${name} in=${inVal}${itemProp} where="${escapeKernString(body)}"`;
222
+ }
223
+ case 'expr': {
224
+ if (args.length !== 1 || !isArrowLike(args[0]))
225
+ return null;
226
+ const arrow = args[0];
227
+ if (arrow.getParameters().length > 1)
228
+ return null;
229
+ const item = paramName(arrow, 0);
230
+ if (!item)
231
+ return null;
232
+ const body = extractSingleExprBody(arrow);
233
+ if (body === null)
234
+ return null;
235
+ const itemProp = item === 'item' ? '' : ` item=${item}`;
236
+ return `${spec.kernNode} name=${name} in=${inVal}${itemProp} expr="${escapeKernString(body)}"`;
237
+ }
238
+ case 'reduce': {
239
+ if (args.length < 1 || !isArrowLike(args[0]))
240
+ return null;
241
+ const arrow = args[0];
242
+ if (arrow.getParameters().length > 2)
243
+ return null;
244
+ const acc = paramName(arrow, 0);
245
+ const item = paramName(arrow, 1);
246
+ if (!acc || !item)
247
+ return null;
248
+ const body = extractSingleExprBody(arrow);
249
+ if (body === null)
250
+ return null;
251
+ const initial = args[1]?.getText();
252
+ if (!initial)
253
+ return null;
254
+ const accProp = acc === 'acc' ? '' : ` acc=${acc}`;
255
+ const itemProp = item === 'item' ? '' : ` item=${item}`;
256
+ return `reduce name=${name} in=${inVal}${accProp}${itemProp} initial="${escapeKernString(initial)}" expr="${escapeKernString(body)}"`;
257
+ }
258
+ case 'slice': {
259
+ const parts = [`slice name=${name} in=${inVal}`];
260
+ const start = args[0]?.getText();
261
+ const end = args[1]?.getText();
262
+ if (start)
263
+ parts.push(`start=${start}`);
264
+ if (end)
265
+ parts.push(`end=${end}`);
266
+ return parts.join(' ');
267
+ }
268
+ case 'at': {
269
+ const index = args[0]?.getText();
270
+ if (!index)
271
+ return null;
272
+ return `at name=${name} in=${inVal} index=${index}`;
273
+ }
274
+ case 'flat': {
275
+ const depth = args[0]?.getText();
276
+ return depth ? `flat name=${name} in=${inVal} depth=${depth}` : `flat name=${name} in=${inVal}`;
277
+ }
278
+ case 'join': {
279
+ const arg = args[0];
280
+ if (!arg)
281
+ return `join name=${name} in=${inVal}`;
282
+ // Only string literals are safe as bare `separator=` props. Non-
283
+ // literal separators need the raw-expression form; skip everything
284
+ // else so the suggestion never changes runtime behavior.
285
+ if (Node.isStringLiteral(arg) || Node.isNoSubstitutionTemplateLiteral(arg)) {
286
+ return `join name=${name} in=${inVal} separator=${arg.getText()}`;
287
+ }
288
+ return `join name=${name} in=${inVal} separator={{ ${arg.getText()} }}`;
289
+ }
290
+ case 'value': {
291
+ const arg = args[0];
292
+ if (!arg)
293
+ return null;
294
+ const value = arg.getText();
295
+ // String literals can safely ride inside the double-quoted `value=`
296
+ // prop (with escaping). Non-literal values need the raw-expression
297
+ // form so the parser doesn't treat an identifier as a literal string.
298
+ const valueProp = Node.isStringLiteral(arg) || Node.isNoSubstitutionTemplateLiteral(arg)
299
+ ? `value="${escapeKernString(value)}"`
300
+ : `value={{ ${value} }}`;
301
+ const from = args[1]?.getText();
302
+ const fromProp = from ? ` from=${from}` : '';
303
+ return `${spec.kernNode} name=${name} in=${inVal} ${valueProp}${fromProp}`;
304
+ }
305
+ case 'concat': {
306
+ if (args.length < 1)
307
+ return null;
308
+ const withArg = args.map((a) => a.getText()).join(', ');
309
+ return `concat name=${name} in=${inVal} with={{ ${withArg} }}`;
310
+ }
311
+ case 'forEach': {
312
+ if (args.length !== 1 || !isArrowLike(args[0]))
313
+ return null;
314
+ const arrow = args[0];
315
+ const item = paramName(arrow, 0);
316
+ if (!item)
317
+ return null;
318
+ const idx = paramName(arrow, 1);
319
+ const idxProp = idx ? ` index=${idx}` : '';
320
+ const itemProp = item === 'item' ? '' : ` item=${item}`;
321
+ return `forEach in=${inVal}${itemProp}${idxProp}\n handler <<<\n ...\n >>>`;
322
+ }
323
+ case 'sort': {
324
+ if (args.length === 0) {
325
+ return `sort name=${name} in=${inVal} # NOTE: kern sort is immutable (spread source); TS .sort() mutates in place`;
326
+ }
327
+ if (!isArrowLike(args[0]))
328
+ return null;
329
+ const arrow = args[0];
330
+ const a = paramName(arrow, 0);
331
+ const b = paramName(arrow, 1);
332
+ if (!a || !b)
333
+ return null;
334
+ const body = extractSingleExprBody(arrow);
335
+ if (body === null)
336
+ return null;
337
+ const aProp = a === 'a' ? '' : ` a=${a}`;
338
+ const bProp = b === 'b' ? '' : ` b=${b}`;
339
+ return `sort name=${name} in=${inVal}${aProp}${bProp} compare="${escapeKernString(body)}" # NOTE: kern sort is immutable`;
340
+ }
341
+ case 'reverse': {
342
+ if (args.length !== 0)
343
+ return null;
344
+ return `reverse name=${name} in=${inVal} # NOTE: kern reverse is immutable`;
345
+ }
346
+ }
347
+ }
348
+ export function suggestKernPrimitive(ctx) {
349
+ if (shouldSkipFile(ctx))
350
+ return [];
351
+ const findings = [];
352
+ // `[...new Set(coll)]` → route to the dedicated `unique` primitive.
353
+ for (const arr of ctx.sourceFile.getDescendantsOfKind(SyntaxKind.ArrayLiteralExpression)) {
354
+ const elements = arr.getElements();
355
+ if (elements.length !== 1)
356
+ continue;
357
+ const first = elements[0];
358
+ if (!Node.isSpreadElement(first))
359
+ continue;
360
+ const spread = first.getExpression();
361
+ if (!Node.isNewExpression(spread))
362
+ continue;
363
+ if (spread.getExpression().getText() !== 'Set')
364
+ continue;
365
+ const args = spread.getArguments();
366
+ if (args.length !== 1)
367
+ continue;
368
+ const source = args[0].getText();
369
+ findings.push(finding('suggest-kern-primitive', 'info', 'pattern', 'JS [...new Set(...)] could migrate to KERN `unique` — named primitive for dedup', ctx.filePath, arr.getStartLineNumber(), 1, { suggestion: `unique name=<name> in=${toKernInValue(source)}` }));
370
+ }
371
+ for (const call of ctx.sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {
372
+ const callee = call.getExpression();
373
+ if (!Node.isPropertyAccessExpression(callee))
374
+ continue;
375
+ const methodName = callee.getName();
376
+ const spec = ARRAY_METHODS[methodName];
377
+ if (!spec)
378
+ continue;
379
+ const collection = callee.getExpression().getText();
380
+ const collectionIn = toKernInValue(collection);
381
+ // `.filter(Boolean)`, `.filter(x => !!x)`, `.filter(x => Boolean(x))` →
382
+ // route to the dedicated `compact` primitive. The three shapes are all
383
+ // equivalent drop-falsy idioms; KERN prefers the named primitive.
384
+ if (methodName === 'filter' && call.getArguments().length === 1) {
385
+ const arg = call.getArguments()[0];
386
+ const isBooleanRef = Node.isIdentifier(arg) && arg.getText() === 'Boolean';
387
+ const isCoercionArrow = isArrowLike(arg) && isBooleanCoercionOfFirstParam(arg);
388
+ if (isBooleanRef || isCoercionArrow) {
389
+ findings.push(finding('suggest-kern-primitive', 'info', 'pattern', 'JS drop-falsy filter could migrate to KERN `compact` — named primitive for drop-falsy', ctx.filePath, call.getStartLineNumber(), 1, { suggestion: `compact name=<name> in=${collectionIn}` }));
390
+ continue;
391
+ }
392
+ }
393
+ // `.map(x => x.prop[.chain])` → route to the dedicated `pluck` primitive.
394
+ // Only fires on single-param arrows (to skip `(x, i) => ...` which KERN
395
+ // can't represent) and non-optional property chains.
396
+ if (methodName === 'map' && call.getArguments().length === 1) {
397
+ const arg = call.getArguments()[0];
398
+ if (isArrowLike(arg) && arg.getParameters().length === 1) {
399
+ const item = paramName(arg, 0);
400
+ if (item) {
401
+ const path = propertyAccessChainFromItem(arg, item);
402
+ if (path) {
403
+ findings.push(finding('suggest-kern-primitive', 'info', 'pattern', 'JS .map(x => x.<prop>) could migrate to KERN `pluck` — named primitive for property extraction', ctx.filePath, call.getStartLineNumber(), 1, {
404
+ suggestion: item === 'item'
405
+ ? `pluck name=<name> in=${collectionIn} prop=${path}`
406
+ : `pluck name=<name> in=${collectionIn} item=${item} prop=${path}`,
407
+ }));
408
+ continue;
409
+ }
410
+ }
411
+ }
412
+ }
413
+ const suggestion = buildSuggestion(spec, collection, call);
414
+ if (!suggestion)
415
+ continue;
416
+ findings.push(finding('suggest-kern-primitive', 'info', 'pattern', `JS .${methodName}(…) could migrate to KERN \`${spec.kernNode}\` — one declarative binding instead of a handler-embedded call`, ctx.filePath, call.getStartLineNumber(), call.getStart() - call.getSourceFile().getFullText().lastIndexOf('\n', call.getStart()), { suggestion }));
417
+ }
418
+ // ── fmt detector ───────────────────────────────────────────────────────
419
+ // Two call sites map cleanly to KERN's `fmt` primitive:
420
+ //
421
+ // const label = `${count} files`; → fmt name=label template="…"
422
+ // return `${msg} (${code})`; → fmt name=<result> template="…"; return <result>
423
+ //
424
+ // Only fires on TemplateExpression (has substitutions); plain backtick
425
+ // strings are NoSubstitutionTemplateLiteral and don't need fmt.
426
+ // Single-line only — multiline templates have meaningful whitespace that's
427
+ // awkward to round-trip through a one-line suggestion.
428
+ for (const tpl of ctx.sourceFile.getDescendantsOfKind(SyntaxKind.TemplateExpression)) {
429
+ const parent = tpl.getParent();
430
+ if (!parent)
431
+ continue;
432
+ const fullText = tpl.getText();
433
+ if (!fullText.startsWith('`') || !fullText.endsWith('`') || fullText.length < 2)
434
+ continue;
435
+ const body = fullText.slice(1, -1);
436
+ if (body.includes('\n'))
437
+ continue;
438
+ // Shape A — const initializer: `const x = \`…\`;`
439
+ if (Node.isVariableDeclaration(parent) && parent.getInitializer() === tpl) {
440
+ const nameNode = parent.getNameNode();
441
+ if (!Node.isIdentifier(nameNode))
442
+ continue; // skip destructured bindings
443
+ const name = nameNode.getText();
444
+ findings.push(finding('suggest-kern-primitive', 'info', 'pattern', 'JS template literal could migrate to KERN `fmt` — named primitive for string interpolation', ctx.filePath, tpl.getStartLineNumber(), 1, { suggestion: `fmt name=${name} template="${escapeKernTemplate(body)}"` }));
445
+ continue;
446
+ }
447
+ // Shape B — return value: `return \`…\`;`
448
+ // Migration is a two-step: bind the formatted string to a named `fmt`
449
+ // node first, then `return` that name. The suggestion shows both lines
450
+ // so authors can paste directly.
451
+ if (Node.isReturnStatement(parent) && parent.getExpression() === tpl) {
452
+ findings.push(finding('suggest-kern-primitive', 'info', 'pattern', 'JS template literal in return position could migrate to KERN `fmt` — bind to a name, then return it', ctx.filePath, tpl.getStartLineNumber(), 1, { suggestion: `fmt name=<result> template="${escapeKernTemplate(body)}"\nreturn <result>` }));
453
+ continue;
454
+ }
455
+ }
456
+ // ── conditional JSX detector ───────────────────────────────────────────
457
+ // `{cond ? <A /> : <B />}` inside JSX → `conditional if="cond"` + two
458
+ // handler children. Only fires when BOTH branches are JSX (skips the
459
+ // `cond ? <A /> : null` case — that's a then-only `{cond && <A />}` shape).
460
+ // Only fires when the ternary sits inside a JsxExpression container — a
461
+ // top-level `return cond ? <A /> : <B />` doesn't cleanly map to a
462
+ // conditional node (the whole return would need rewrapping).
463
+ for (const cond of ctx.sourceFile.getDescendantsOfKind(SyntaxKind.ConditionalExpression)) {
464
+ const whenTrue = cond.getWhenTrue();
465
+ const whenFalse = cond.getWhenFalse();
466
+ if (!isJsxLike(whenTrue) || !isJsxLike(whenFalse))
467
+ continue;
468
+ const parent = cond.getParent();
469
+ if (!parent || !Node.isJsxExpression(parent))
470
+ continue;
471
+ const condText = cond.getCondition().getText();
472
+ const suggestion = `conditional if="${escapeKernString(condText)}"\n` +
473
+ ` handler <<<\n ${whenTrue.getText()}\n >>>\n` +
474
+ ` else\n handler <<<\n ${whenFalse.getText()}\n >>>`;
475
+ findings.push(finding('suggest-kern-primitive', 'info', 'pattern', 'JSX ternary could migrate to KERN `conditional` — declarative if/else render branch', ctx.filePath, cond.getStartLineNumber(), 1, { suggestion }));
476
+ }
477
+ // ── async try/catch detector ───────────────────────────────────────────
478
+ // `async function f() { try { await … } catch (e) { … } }` → `async name=f`
479
+ // with a handler child for the try body and a `recover`/`strategy` pair for
480
+ // the catch body.
481
+ //
482
+ // Only fires when:
483
+ // - the function is `async`
484
+ // - its body is a single TryStatement (so the full body maps to the async node)
485
+ // - the try block contains at least one `await` (else there's no async shape)
486
+ // - a catch clause is present (else there's no recovery to migrate)
487
+ const asyncFns = [
488
+ ...ctx.sourceFile.getDescendantsOfKind(SyntaxKind.FunctionDeclaration),
489
+ ...ctx.sourceFile.getDescendantsOfKind(SyntaxKind.FunctionExpression),
490
+ ...ctx.sourceFile.getDescendantsOfKind(SyntaxKind.ArrowFunction),
491
+ ];
492
+ for (const fn of asyncFns) {
493
+ if (!fn.isAsync())
494
+ continue;
495
+ const body = fn.getBody();
496
+ if (!body || !Node.isBlock(body))
497
+ continue;
498
+ const stmts = body.getStatements();
499
+ if (stmts.length !== 1)
500
+ continue;
501
+ const tryStmt = stmts[0];
502
+ if (!Node.isTryStatement(tryStmt))
503
+ continue;
504
+ const tryBlock = tryStmt.getTryBlock();
505
+ const catchClause = tryStmt.getCatchClause();
506
+ if (!catchClause)
507
+ continue;
508
+ if (tryBlock.getDescendantsOfKind(SyntaxKind.AwaitExpression).length === 0)
509
+ continue;
510
+ let name = '<name>';
511
+ if (Node.isFunctionDeclaration(fn)) {
512
+ name = fn.getName() ?? '<name>';
513
+ }
514
+ else {
515
+ const p = fn.getParent();
516
+ if (p && Node.isVariableDeclaration(p)) {
517
+ const n = p.getNameNode();
518
+ if (Node.isIdentifier(n))
519
+ name = n.getText();
520
+ }
521
+ }
522
+ const indent = (text, spaces) => text
523
+ .split('\n')
524
+ .map((line) => ' '.repeat(spaces) + line)
525
+ .join('\n');
526
+ const tryText = tryBlock
527
+ .getStatements()
528
+ .map((s) => s.getText())
529
+ .join('\n');
530
+ const catchText = catchClause
531
+ .getBlock()
532
+ .getStatements()
533
+ .map((s) => s.getText())
534
+ .join('\n');
535
+ const suggestion = `async name=${name}\n` +
536
+ ` handler <<<\n${indent(tryText, 4)}\n >>>\n` +
537
+ ` recover\n strategy <<<\n${indent(catchText, 6)}\n >>>`;
538
+ findings.push(finding('suggest-kern-primitive', 'info', 'pattern', 'async try/catch could migrate to KERN `async` — named primitive with `recover`/`strategy` child', ctx.filePath, fn.getStartLineNumber(), 1, { suggestion }));
539
+ }
540
+ return findings;
541
+ }
542
+ export const suggestKernPrimitiveRules = [suggestKernPrimitive];
543
+ //# sourceMappingURL=suggest-kern-primitive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suggest-kern-primitive.js","sourceRoot":"","sources":["../../src/rules/suggest-kern-primitive.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -282,6 +282,8 @@ export interface ReviewConfig {
282
282
  graphFileMap?: Map<string, GraphFile>;
283
283
  /** Path to host project's tsconfig.json — loaded into the ts-morph Project so jsx/paths/lib/allowJs match the real build. */
284
284
  tsConfigFilePath?: string;
285
+ /** When true, emit the `missing-confidence` finding for .kern files without confidence annotations. Default: false (opt-in) — teams that don't use confidence annotations see no noise. */
286
+ requireConfidenceAnnotations?: boolean;
285
287
  /** Override what dead-export treats as intentional public API. */
286
288
  publicApi?: {
287
289
  /** Absolute or projectRoot-relative paths whose exports are all public. */
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAsaH,4EAA4E;AAE5E;sEACsE;AACtE,MAAM,UAAU,iBAAiB,CAAC,MAAc,EAAE,SAAiB,EAAE,QAAgB;IACnF,OAAO,GAAG,MAAM,IAAI,SAAS,IAAI,QAAQ,EAAE,CAAC;AAC9C,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAwaH,4EAA4E;AAE5E;sEACsE;AACtE,MAAM,UAAU,iBAAiB,CAAC,MAAc,EAAE,SAAiB,EAAE,QAAgB;IACnF,OAAO,GAAG,MAAM,IAAI,SAAS,IAAI,QAAQ,EAAE,CAAC;AAC9C,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kernlang/review",
3
- "version": "3.3.4",
3
+ "version": "3.3.6",
4
4
  "description": "Kern Review — scan TS, infer .kern IR, roundtrip diff, report",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -26,7 +26,7 @@
26
26
  "license": "AGPL-3.0",
27
27
  "dependencies": {
28
28
  "ts-morph": "^28.0.0",
29
- "@kernlang/core": "3.3.4"
29
+ "@kernlang/core": "3.3.6"
30
30
  },
31
31
  "scripts": {
32
32
  "build": "tsc -b",