@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,21 @@
1
+ /**
2
+ * set-setter-collision — warns when a class `setter name=X` and a React
3
+ * state `state name=X` appear in the same file.
4
+ *
5
+ * Why this rule exists:
6
+ * KERN has two nearby-but-different primitives that an LLM author can
7
+ * reach for by accident:
8
+ * - `setter name=X params="v:T"` inside a `class` → emits the JS
9
+ * object-style accessor `set X(v: T) { body }`.
10
+ * - `set name=X` inside an `on` handler → emits the React hook call
11
+ * `setX(value)`, which requires a sibling `state name=X`.
12
+ * When both appear in the same file with the same name, the reader loses
13
+ * track of which spelling is the right one for the current site. The rule
14
+ * fires `warning` on each offending node so the author can either rename
15
+ * one of them or consciously accept the overlap.
16
+ *
17
+ * Scope: this is a .kern-source lint rule (ships with `reviewKernSource`).
18
+ * Layer: `kern-source`, severity `warning`, precision `high`.
19
+ */
20
+ import type { KernSourceRule } from './kern-source.js';
21
+ export declare const setSetterCollision: KernSourceRule;
@@ -0,0 +1,74 @@
1
+ /**
2
+ * set-setter-collision — warns when a class `setter name=X` and a React
3
+ * state `state name=X` appear in the same file.
4
+ *
5
+ * Why this rule exists:
6
+ * KERN has two nearby-but-different primitives that an LLM author can
7
+ * reach for by accident:
8
+ * - `setter name=X params="v:T"` inside a `class` → emits the JS
9
+ * object-style accessor `set X(v: T) { body }`.
10
+ * - `set name=X` inside an `on` handler → emits the React hook call
11
+ * `setX(value)`, which requires a sibling `state name=X`.
12
+ * When both appear in the same file with the same name, the reader loses
13
+ * track of which spelling is the right one for the current site. The rule
14
+ * fires `warning` on each offending node so the author can either rename
15
+ * one of them or consciously accept the overlap.
16
+ *
17
+ * Scope: this is a .kern-source lint rule (ships with `reviewKernSource`).
18
+ * Layer: `kern-source`, severity `warning`, precision `high`.
19
+ */
20
+ import { finding } from './utils.js';
21
+ function getName(node) {
22
+ const n = node.props?.name;
23
+ return typeof n === 'string' ? n : undefined;
24
+ }
25
+ function collectByType(nodes, types, acc = new Map()) {
26
+ for (const node of nodes) {
27
+ if (types.has(node.type)) {
28
+ const n = getName(node);
29
+ if (n) {
30
+ const arr = acc.get(n) ?? [];
31
+ arr.push(node);
32
+ acc.set(n, arr);
33
+ }
34
+ }
35
+ if (node.children)
36
+ collectByType(node.children, types, acc);
37
+ }
38
+ return acc;
39
+ }
40
+ const SETTER_TYPES = new Set(['setter']);
41
+ const STATE_TYPES = new Set(['state']);
42
+ export const setSetterCollision = (nodes, filePath) => {
43
+ const setters = collectByType(nodes, SETTER_TYPES);
44
+ if (setters.size === 0)
45
+ return [];
46
+ const states = collectByType(nodes, STATE_TYPES);
47
+ if (states.size === 0)
48
+ return [];
49
+ const findings = [];
50
+ for (const [name, setterNodes] of setters) {
51
+ const stateNodes = states.get(name);
52
+ if (!stateNodes || stateNodes.length === 0)
53
+ continue;
54
+ const message = `\`setter name=${name}\` and \`state name=${name}\` both declared in this file — ` +
55
+ 'the class emits `set ' +
56
+ name +
57
+ '(v)` while the state emits `set' +
58
+ name[0].toUpperCase() +
59
+ name.slice(1) +
60
+ '(v)`. Rename one side or document the overlap.';
61
+ for (const setterNode of setterNodes) {
62
+ findings.push(finding('set-setter-name-collision', 'warning', 'pattern', message, filePath, setterNode.loc?.line ?? 1, setterNode.loc?.col ?? 1, {
63
+ suggestion: '`setter` defines a JS object accessor (`set X(v)`); `set` inside an `on` handler calls the React setter (`setX(v)`). Pick the spelling that matches author intent and rename the other.',
64
+ }));
65
+ }
66
+ for (const stateNode of stateNodes) {
67
+ findings.push(finding('set-setter-name-collision', 'warning', 'pattern', message, filePath, stateNode.loc?.line ?? 1, stateNode.loc?.col ?? 1, {
68
+ suggestion: '`setter` defines a JS object accessor (`set X(v)`); `set` inside an `on` handler calls the React setter (`setX(v)`). Pick the spelling that matches author intent and rename the other.',
69
+ }));
70
+ }
71
+ }
72
+ return findings;
73
+ };
74
+ //# sourceMappingURL=set-setter-collision.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-setter-collision.js","sourceRoot":"","sources":["../../src/rules/set-setter-collision.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
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 type { ReviewFinding, ReviewRule, RuleContext } from '../types.js';
29
+ export declare function suggestKernPrimitive(ctx: RuleContext): ReviewFinding[];
30
+ export declare const suggestKernPrimitiveRules: ReviewRule[];