@beehexa/hexasync-template-context 2608.20.18 → 2608.20.31

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 (49) hide show
  1. package/dist/completion.d.ts +80 -0
  2. package/dist/completion.d.ts.map +1 -0
  3. package/dist/completion.js +202 -0
  4. package/dist/completion.js.map +1 -0
  5. package/dist/detect.d.ts +38 -0
  6. package/dist/detect.d.ts.map +1 -0
  7. package/dist/detect.js +35 -0
  8. package/dist/detect.js.map +1 -0
  9. package/dist/environment.d.ts +79 -0
  10. package/dist/environment.d.ts.map +1 -0
  11. package/dist/environment.js +239 -0
  12. package/dist/environment.js.map +1 -0
  13. package/dist/hints.d.ts +62 -0
  14. package/dist/hints.d.ts.map +1 -0
  15. package/dist/hints.js +198 -0
  16. package/dist/hints.js.map +1 -0
  17. package/dist/index.d.ts +12 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +12 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/item.d.ts +87 -0
  22. package/dist/item.d.ts.map +1 -0
  23. package/dist/item.js +222 -0
  24. package/dist/item.js.map +1 -0
  25. package/dist/position.d.ts +36 -0
  26. package/dist/position.d.ts.map +1 -0
  27. package/dist/position.js +31 -0
  28. package/dist/position.js.map +1 -0
  29. package/dist/references.d.ts +60 -0
  30. package/dist/references.d.ts.map +1 -0
  31. package/dist/references.js +217 -0
  32. package/dist/references.js.map +1 -0
  33. package/dist/shape.d.ts +68 -0
  34. package/dist/shape.d.ts.map +1 -0
  35. package/dist/shape.js +23 -0
  36. package/dist/shape.js.map +1 -0
  37. package/dist/stepOutputs.d.ts +52 -0
  38. package/dist/stepOutputs.d.ts.map +1 -0
  39. package/dist/stepOutputs.js +102 -0
  40. package/dist/stepOutputs.js.map +1 -0
  41. package/dist/survival.d.ts +47 -0
  42. package/dist/survival.d.ts.map +1 -0
  43. package/dist/survival.js +50 -0
  44. package/dist/survival.js.map +1 -0
  45. package/dist/walk.d.ts +36 -0
  46. package/dist/walk.d.ts.map +1 -0
  47. package/dist/walk.js +162 -0
  48. package/dist/walk.js.map +1 -0
  49. package/package.json +1 -1
package/dist/walk.d.ts ADDED
@@ -0,0 +1,36 @@
1
+ /**
2
+ * One walk over a composed component's steps, yielding every context finding in it — Story 8.13.
3
+ *
4
+ * ### Why this exists rather than living in the rule
5
+ *
6
+ * Story 8.6 measured `checkPath` and `unknownStepKey` against the corpus from a walk written inside its own spec, and
7
+ * Story 8.13 needs the same walk inside a validation rule. Two walks would be two chances to disagree about which
8
+ * stage key a pusher uses or where a webhook keeps its steps — and the 8.6 measurement had **exactly that bug**: it
9
+ * special-cased only `current` for pushers, so `pusher.before.*` was checked against `beforePullSteps`, a key a pusher
10
+ * does not have. It surfaced as 84 false findings the moment the rule widened.
11
+ *
12
+ * So the walk is here, both callers use it, and the corpus parity in 8.13 is structural rather than re-asserted.
13
+ */
14
+ import { type ReferenceFinding } from './references.js';
15
+ /** The four context phases, and the stage key each one is spelled with per collection. */
16
+ export declare const PHASE_STAGE: Readonly<Record<'pullers' | 'pushers', Readonly<Record<string, string>>>>;
17
+ export type ContextRuleId = 'root-has-no-child' | 'unknown-step-key';
18
+ export interface ContextFinding extends ReferenceFinding {
19
+ /** Which of the two checks produced it, so a caller can choose a severity per rule. */
20
+ readonly rule: ContextRuleId;
21
+ /** The phase whose steps were being read, for the message and for locating the step. */
22
+ readonly phase: string;
23
+ /** The step the expression was authored in. `(step)` when the key is absent or not a scalar. */
24
+ readonly stepKey: string;
25
+ readonly stepIndex: number;
26
+ }
27
+ /**
28
+ * Every context finding in one component.
29
+ *
30
+ * ⚠️ Silent about two things by design, and the silences are load-bearing: an unknown ROOT may be a local variable or
31
+ * a loop binding, and a segment deeper than the step key may be composed at run time. A rule that reported those
32
+ * would fire on nearly every template in the corpus and be switched off within a day, taking the real findings with
33
+ * it.
34
+ */
35
+ export declare function contextFindingsFor(component: unknown, collection: 'pullers' | 'pushers'): readonly ContextFinding[];
36
+ //# sourceMappingURL=walk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walk.d.ts","sourceRoot":"","sources":["../src/walk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAKL,KAAK,gBAAgB,EACtB,MAAM,iBAAiB,CAAC;AAIzB,0FAA0F;AAC1F,eAAO,MAAM,WAAW,EAAE,QAAQ,CAChC,MAAM,CAAC,SAAS,GAAG,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CA4BhE,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,mBAAmB,GAAG,kBAAkB,CAAC;AAErE,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACtD,uFAAuF;IACvF,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,wFAAwF;IACxF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,gGAAgG;IAChG,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAQD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,OAAO,EAClB,UAAU,EAAE,SAAS,GAAG,SAAS,GAChC,SAAS,cAAc,EAAE,CAmH3B"}
package/dist/walk.js ADDED
@@ -0,0 +1,162 @@
1
+ /**
2
+ * One walk over a composed component's steps, yielding every context finding in it — Story 8.13.
3
+ *
4
+ * ### Why this exists rather than living in the rule
5
+ *
6
+ * Story 8.6 measured `checkPath` and `unknownStepKey` against the corpus from a walk written inside its own spec, and
7
+ * Story 8.13 needs the same walk inside a validation rule. Two walks would be two chances to disagree about which
8
+ * stage key a pusher uses or where a webhook keeps its steps — and the 8.6 measurement had **exactly that bug**: it
9
+ * special-cased only `current` for pushers, so `pusher.before.*` was checked against `beforePullSteps`, a key a pusher
10
+ * does not have. It surfaced as 84 false findings the moment the rule widened.
11
+ *
12
+ * So the walk is here, both callers use it, and the corpus parity in 8.13 is structural rather than re-asserted.
13
+ */
14
+ import { checkPath, expressionsIn, pathsIn, unknownStepKey, } from './references.js';
15
+ import { resolveEnvironment, stepFactsFrom } from './environment.js';
16
+ import { isNewKindPuller } from './detect.js';
17
+ /** The four context phases, and the stage key each one is spelled with per collection. */
18
+ export const PHASE_STAGE = {
19
+ pullers: {
20
+ before: 'beforePullSteps',
21
+ current: 'pullSteps',
22
+ after: 'afterPullSteps',
23
+ final: 'finalSteps',
24
+ },
25
+ /**
26
+ * ⛔ A pusher spells its phases `…PushSteps`. Measured 2026-08-14 across the corpus, counting KEY-LINE OCCURRENCES
27
+ * (`grep -rhoE '^\s+[a-zA-Z]+Steps:'`, which counts a key once per authored and per composed file):
28
+ * `beforePushSteps` 1,688 · `afterPushSteps` 1,654 · `pushSteps` 1,941.
29
+ *
30
+ * ⚠️ The BASIS matters and was missing when these were first recorded. Counting distinct components that declare
31
+ * the array instead gives ~1,612 / 1,625 / 1,939, and the Epic 8 review re-derived the occurrence figures as
32
+ * 1,661 / 1,630 / 1,914 with a slightly different expression — three methods, three answers, all defensible. The
33
+ * numbers are here to show the two spellings are of the same order, nothing finer; do not treat a small drift as
34
+ * a regression without re-running the exact command above.
35
+ *
36
+ * `finalSteps` appears **nowhere**, in either collection, on every method — so `final` is an empty phase by
37
+ * construction rather than by accident. That is the load-bearing part, and it is the one that reproduces exactly.
38
+ */
39
+ pushers: {
40
+ before: 'beforePushSteps',
41
+ current: 'pushSteps',
42
+ after: 'afterPushSteps',
43
+ final: 'finalSteps',
44
+ },
45
+ };
46
+ const arrayAt = (value, key) => {
47
+ const holder = value;
48
+ const at = holder?.[key];
49
+ return Array.isArray(at) ? at : [];
50
+ };
51
+ /**
52
+ * Every context finding in one component.
53
+ *
54
+ * ⚠️ Silent about two things by design, and the silences are load-bearing: an unknown ROOT may be a local variable or
55
+ * a loop binding, and a segment deeper than the step key may be composed at run time. A rule that reported those
56
+ * would fire on nearly every template in the corpus and be switched off within a day, taking the real findings with
57
+ * it.
58
+ */
59
+ export function contextFindingsFor(component, collection) {
60
+ const holder = component;
61
+ if (!holder || typeof holder !== 'object')
62
+ return [];
63
+ const stages = PHASE_STAGE[collection];
64
+ const newKind = collection === 'pullers' && isNewKindPuller(holder);
65
+ const phases = {};
66
+ for (const phase of Object.keys(stages)) {
67
+ phases[phase] = arrayAt(holder, stages[phase]).map((step) => stepFactsFrom(step));
68
+ }
69
+ const keysByPhase = Object.fromEntries(Object.keys(stages).map((phase) => [
70
+ phase,
71
+ phases[phase].map((facts) => facts.key),
72
+ ]));
73
+ const position = (collection === 'pushers'
74
+ ? 'pusher-step'
75
+ : newKind
76
+ ? 'new-kind-puller-step'
77
+ : 'legacy-puller-step');
78
+ const findings = [];
79
+ for (const phase of Object.keys(stages)) {
80
+ arrayAt(holder, stages[phase]).forEach((step, stepIndex) => {
81
+ const environment = resolveEnvironment({
82
+ position,
83
+ component: { collection, hasStepsArray: newKind, phases },
84
+ phase,
85
+ stepIndex,
86
+ });
87
+ const raw = step?.['key'];
88
+ const stepKey = typeof raw === 'string' || typeof raw === 'number'
89
+ ? String(raw)
90
+ : '(step)';
91
+ /**
92
+ * ⛔ A step that will not serialize must not silence the whole family.
93
+ *
94
+ * `JSON.stringify` throws on a cyclic object, and `runValidation` swallows a throwing rule with a
95
+ * `console.warn` — so ONE such component would discard every CTX finding in the project, including the good
96
+ * ones already computed. The `yaml` parser does build cyclic objects from a recursive anchor
97
+ * (`a: &x { self: *x }`) and the cycle survives the CLI's parse/stringify round trip, so this is reachable
98
+ * rather than theoretical, even though no corpus file uses anchors today. Skipping one step is a bounded loss;
99
+ * losing the rule is not.
100
+ */
101
+ let serialized;
102
+ try {
103
+ serialized = JSON.stringify(step) ?? '';
104
+ }
105
+ catch {
106
+ return;
107
+ }
108
+ const seen = new Set();
109
+ for (const expression of expressionsIn(serialized)) {
110
+ for (const path of pathsIn(expression)) {
111
+ /**
112
+ * ⛔ Deduplicated PER STEP. One authored expression is commonly repeated across a step's fields — the
113
+ * corpus's worst case reads the same broken watermark path seven times in one step — and seven identical
114
+ * findings on one line is a report an author scrolls past. The measurement counts occurrences; a report
115
+ * addresses lines.
116
+ */
117
+ if (seen.has(path))
118
+ continue;
119
+ seen.add(path);
120
+ const rootFinding = checkPath(path, environment);
121
+ if (rootFinding) {
122
+ findings.push({
123
+ ...rootFinding,
124
+ rule: 'root-has-no-child',
125
+ phase,
126
+ stepKey,
127
+ stepIndex,
128
+ });
129
+ continue;
130
+ }
131
+ /**
132
+ * ⛔ The step-key check runs ONLY under a root this position actually has.
133
+ *
134
+ * `unknownStepKey` matches the segment name (`current`, `history`, …) wherever it appears; it does not
135
+ * know whose context it is in. So a NEW-KIND puller — which shares no `puller.*` root at all (§3) —
136
+ * produced `current has no step called X` for a path whose real problem is that `puller` does not exist
137
+ * there. The corpus reported 0 such findings, which read like proof and was luck: no new-kind component
138
+ * in it happens to carry a stale `puller.*` path. A unit test found it in one run.
139
+ *
140
+ * An unknown root stays SILENT rather than becoming a finding of its own — it may be a local variable or
141
+ * a loop binding, which is the same reason `checkPath` leaves it alone.
142
+ */
143
+ const root = path.split('.')[0];
144
+ if (!root || !environment.roots.has(root))
145
+ continue;
146
+ const stepFinding = unknownStepKey(path, keysByPhase);
147
+ if (stepFinding) {
148
+ findings.push({
149
+ ...stepFinding,
150
+ rule: 'unknown-step-key',
151
+ phase,
152
+ stepKey,
153
+ stepIndex,
154
+ });
155
+ }
156
+ }
157
+ }
158
+ });
159
+ }
160
+ return findings;
161
+ }
162
+ //# sourceMappingURL=walk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walk.js","sourceRoot":"","sources":["../src/walk.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beehexa/hexasync-template-context",
3
- "version": "2608.20.18",
3
+ "version": "2608.20.31",
4
4
  "description": "The authoring context engine — given a component and a caret, what an author may legally reference.",
5
5
  "license": "SEE LICENSE IN ../../LICENSE",
6
6
  "type": "module",