@beehexa/hexasync-template-model 2608.21.4 → 2610.3.1

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 (39) hide show
  1. package/dist/canonicalGraph.d.ts +153 -0
  2. package/dist/canonicalGraph.d.ts.map +1 -0
  3. package/dist/canonicalGraph.js +321 -0
  4. package/dist/canonicalGraph.js.map +1 -0
  5. package/dist/collapseRule.d.ts +125 -0
  6. package/dist/collapseRule.d.ts.map +1 -0
  7. package/dist/collapseRule.js +87 -0
  8. package/dist/collapseRule.js.map +1 -0
  9. package/dist/flowRender.d.ts +364 -18
  10. package/dist/flowRender.d.ts.map +1 -1
  11. package/dist/flowRender.js +956 -123
  12. package/dist/flowRender.js.map +1 -1
  13. package/dist/index.d.ts +8 -3
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +10 -3
  16. package/dist/index.js.map +1 -1
  17. package/dist/nodeAddress.d.ts +81 -0
  18. package/dist/nodeAddress.d.ts.map +1 -1
  19. package/dist/nodeAddress.js +70 -0
  20. package/dist/nodeAddress.js.map +1 -1
  21. package/dist/occurrenceExpansion.d.ts +50 -0
  22. package/dist/occurrenceExpansion.d.ts.map +1 -0
  23. package/dist/occurrenceExpansion.js +230 -0
  24. package/dist/occurrenceExpansion.js.map +1 -0
  25. package/dist/stepGlyph.d.ts +242 -29
  26. package/dist/stepGlyph.d.ts.map +1 -1
  27. package/dist/stepGlyph.js +403 -104
  28. package/dist/stepGlyph.js.map +1 -1
  29. package/dist/workerStepVocabularyAudit.d.ts +19 -0
  30. package/dist/workerStepVocabularyAudit.d.ts.map +1 -0
  31. package/dist/workerStepVocabularyAudit.js +134 -0
  32. package/dist/workerStepVocabularyAudit.js.map +1 -0
  33. package/dist/workflowMigration.d.ts +60 -0
  34. package/dist/workflowMigration.d.ts.map +1 -0
  35. package/dist/workflowMigration.js +75 -0
  36. package/dist/workflowMigration.js.map +1 -0
  37. package/manifests/collapse-rule.json +43 -0
  38. package/manifests/worker-step-roster.json +164 -0
  39. package/package.json +6 -2
package/dist/stepGlyph.js CHANGED
@@ -1,108 +1,155 @@
1
1
  /**
2
- * A node's label: name, then key, then the step type — with a glyph standing in for an icon.
3
- *
4
- * ### What was wrong, and it was one line in each renderer
5
- *
6
- * Both `render.ts` files built a label as `node.label ?? node.name ?? node.stepKey ?? node.address` — a
7
- * FALLBACK chain, so a step with a name showed its name and nothing else. The key and the type were computed,
8
- * carried on every node, and then dropped at the last step before drawing. A reader looking at a diagram
9
- * beside the YAML could not tell which `key:` a box was, which is the one thing they need in order to jump to
10
- * it, and `next:`/`outputs:` reference steps BY KEY.
11
- *
12
- * The brainstorm that started this feature asked for exactly this: *"each node is missing its `key` and
13
- * `type/displayType` … The key must be after the node's `name`, and the `type/displayType` must be shown as an
14
- * icon in the node"*.
15
- *
16
- * ### Why a glyph and not the SVG set
17
- *
18
- * ⚠️ Stated rather than quietly downgraded. `ux/step-icons/` holds 12 authored SVGs, and they cannot go inside
19
- * a mermaid node here: the webview renders with `securityLevel: 'strict'`, which sanitises label HTML through
20
- * DOMPurify (`renderHtml.ts:493` records the same constraint for the report), and an inline `<svg>` does not
21
- * survive that. Raising it to `'loose'` to admit one would also admit mermaid's `click … call fn()` — which is
22
- * precisely why `flowDiagram.ts` chose strict.
23
- *
24
- * So the icon slot is filled by a per-FAMILY unicode glyph, which survives sanitising, needs no asset
25
- * pipeline, and renders identically in the editor, the report and the browser host. The type name is drawn
26
- * beside it, so the glyph is a hint and never the only signal — that is the "fallback to text", present
27
- * always rather than only when something fails.
28
- *
29
- * Wiring the real SVG set belongs with the shared step-icon package the toolchain PRD lists under
30
- * *"Unblocks"*, where a `<span class="step-icon step-icon--api">` and CSS can do it without loosening mermaid.
2
+ * Every glyph must come from Arrows (U+2190–U+21FF), Geometric Shapes (U+25A0–U+25FF), or Mathematical
3
+ * Operators (U+2200–U+22FF). Those blocks have reliable coverage in the fonts a webview receives.
31
4
  */
32
- /**
33
- * Families, taken from the authored icon set (`ux/step-icons/_family-*.svg`) so the two cannot diverge.
34
- *
35
- * ⚠️ EVERY glyph must come from Arrows (U+2190–U+21FF), Geometric Shapes (U+25A0–U+25FF) or Mathematical
36
- * Operators (U+2200–U+22FF), and `stepGlyph.spec.ts` enforces it. Those three blocks have near-universal
37
- * coverage in the fonts a webview actually gets; anything outside them draws as a tofu box on some machine,
38
- * and a box is indistinguishable from "this node has no icon".
39
- *
40
- * Two of the first ten broke that rule and a reader saw both: *"why are some nodes have icons, but some are
41
- * not?"*
42
- *
43
- * * `query` was `?` — a plain ASCII question mark. It has perfect coverage and reads as a MISSING
44
- * CHARACTER, which is worse: the glyph rendered exactly as intended and still looked like a failure.
45
- * * `control` was `⑂` (U+2442), in the Optical Character Recognition block. Rare enough that common fonts
46
- * omit it, so it drew as a box.
47
- *
48
- * The lesson is that "does this codepoint exist" is the wrong question. The right one is "does it read as an
49
- * icon on a machine I have never seen", and the answer is only reliable inside those three blocks.
50
- */
51
- const GLYPHS = {
52
- /** An outbound request. */
5
+ const PARENT_GLYPHS = {
53
6
  call: '↗',
54
- /** A branch. The diamond shape the flow already draws for a decision, in the label. */
55
7
  control: '◆',
56
- /** Fan-out — dispatch, loop, batch. */
57
8
  orchestrate: '↻',
58
- /** Rows read back. Was `?`, which read as a missing character. */
59
9
  query: '≡',
60
- /** Something remembered for the rest of the run. */
61
10
  state: '▣',
62
- /** A start or an end. */
63
11
  terminal: '◉',
64
- /** Shape in, different shape out. */
65
12
  transform: '⇄',
66
- /** A screen the operator sees. */
67
13
  ui: '▤',
68
- /** Time passing. */
69
14
  wait: '◔',
70
- /** Data pushed somewhere. */
71
15
  write: '⇩',
72
16
  };
73
17
  /**
74
- * Which family a step type belongs to.
18
+ * Keep authored punctuation literal inside Mermaid 12 Markdown labels.
75
19
  *
76
- * Matched on the type name because that is what both runtimes carry — a worker step's `displayType` and a
77
- * frontend step's `type` are the same idea spelled twice (AD-21 keeps the vocabularies apart, not the
78
- * concept). Unknown types get the neutral glyph rather than no glyph, so a box never loses its icon slot and
79
- * start shifting the text alignment of its neighbours.
20
+ * Mermaid's SVG-label path drops Markdown `escape` tokens and does not decode numeric entities. U+FEFF is zero-width
21
+ * whitespace: bracketing authored Markdown punctuation with it makes the lexer keep the punctuation in ordinary text
22
+ * tokens while leaving the visible text unchanged. The renderer-owned bold delimiters are added afterwards.
23
+ *
24
+ * It lives HERE, beside the composer, rather than in `flowRender.ts` where it started: the composer and the renderer
25
+ * must escape one heading identically or the same node gets two different labels depending on which surface built it,
26
+ * and the only way to guarantee that is one function. `flowRender.ts` imports it — never the other way round, because
27
+ * that is the dependency direction this package already has.
80
28
  */
29
+ export function escapeMarkdownText(value) {
30
+ const htmlSafe = value
31
+ .replace(/[\r\n]+/g, ' ')
32
+ .replace(/&/g, '&amp;')
33
+ .replace(/"/g, '&quot;')
34
+ .replace(/</g, '&lt;')
35
+ .replace(/>/g, '&gt;')
36
+ .replace(/`/g, '&amp;#96;');
37
+ return htmlSafe.replace(/[\\*_[\]{}()#+\-.!|~]/g, (character) => `\uFEFF${character}\uFEFF`);
38
+ }
39
+ /** The sole result for absent or unknown worker vocabulary. */
40
+ export const UNMAPPED_STEP_ICON = {
41
+ family: 'unmapped',
42
+ glyph: '□',
43
+ };
44
+ /** The approved 32 drawing families, rolled up to the strict-host glyph vocabulary. */
45
+ export const STEP_FAMILY_PARENTS = {
46
+ 'call.dialect': 'call',
47
+ 'call.event': 'call',
48
+ 'call.http': 'call',
49
+ 'call.webhook': 'call',
50
+ 'control.if': 'control',
51
+ 'control.switch': 'control',
52
+ 'orchestrate.composite': 'orchestrate',
53
+ 'orchestrate.enqueue': 'orchestrate',
54
+ 'orchestrate.pull': 'orchestrate',
55
+ 'query.dsl': 'query',
56
+ 'query.file': 'query',
57
+ 'query.history': 'query',
58
+ 'query.kv': 'query',
59
+ 'query.metrics': 'query',
60
+ 'query.record': 'query',
61
+ 'query.sql': 'query',
62
+ 'state.cache': 'state',
63
+ 'state.item': 'state',
64
+ 'state.kv': 'state',
65
+ 'state.removal': 'state',
66
+ 'state.task-data': 'state',
67
+ 'terminal.begin': 'terminal',
68
+ 'terminal.end': 'terminal',
69
+ 'terminal.error': 'terminal',
70
+ 'transform.decode': 'transform',
71
+ 'transform.filter': 'transform',
72
+ 'transform.template': 'transform',
73
+ 'wait.sleep': 'wait',
74
+ 'write.delete': 'write',
75
+ 'write.index': 'write',
76
+ 'write.push': 'write',
77
+ 'write.seed': 'write',
78
+ };
79
+ /** Every id in Epic 7's authoritative 51/51 runtime roster, in manifest order. */
80
+ export const WORKER_STEP_FAMILIES = {
81
+ API: 'call.http',
82
+ BASE64_TO_MIME_TYPE: 'transform.decode',
83
+ Begin: 'terminal.begin',
84
+ CACHE: 'state.cache',
85
+ CHECK_FORMAT: 'transform.filter',
86
+ Composite: 'orchestrate.composite',
87
+ DIRECT_INDEX: 'write.index',
88
+ DOWNLOAD_CSV: 'query.file',
89
+ ENQUEUER: 'orchestrate.enqueue',
90
+ EXCEL_READER: 'query.file',
91
+ EXCEPTION: 'terminal.error',
92
+ End: 'terminal.end',
93
+ Error: 'terminal.error',
94
+ FORWARD: 'transform.filter',
95
+ GET_KEY_VALUE: 'query.kv',
96
+ GraphQL: 'call.dialect',
97
+ IF: 'control.if',
98
+ IGNORE_ITEM: 'state.item',
99
+ INVALIDATE_CACHE: 'state.cache',
100
+ JSONata: 'transform.template',
101
+ LOOKUP_STEP: 'query.history',
102
+ Liquid: 'transform.template',
103
+ METRIC_QUERY: 'query.metrics',
104
+ OData: 'call.dialect',
105
+ PUBLISH_EVENT: 'call.event',
106
+ PULLER: 'orchestrate.pull',
107
+ PUSHER: 'write.push',
108
+ QUERY_MANY: 'query.record',
109
+ QUERY_METRICS: 'query.metrics',
110
+ QUERY_SINGLE: 'query.record',
111
+ QueryDSL: 'query.dsl',
112
+ REMOVE_DATA: 'write.delete',
113
+ RESET_ITEM: 'state.item',
114
+ RESOLVE_RAW_DATA: 'transform.decode',
115
+ Restful: 'call.dialect',
116
+ SAVE_TASK_DATA: 'state.task-data',
117
+ SEED_DATA: 'write.seed',
118
+ SET_KEY_VALUE: 'state.kv',
119
+ SLEEP: 'wait.sleep',
120
+ SQL: 'query.sql',
121
+ SQL_PROXY: 'query.sql',
122
+ SWITCH: 'control.switch',
123
+ Scriban: 'transform.template',
124
+ TRACK_FOR_REMOVAL: 'state.removal',
125
+ UPDATE_ITEM_STATUS: 'state.item',
126
+ UPDATE_ITEM_SYNC_PROCESS: 'state.item',
127
+ UPDATE_TASK_DATA_STATUS: 'state.task-data',
128
+ VALUES: 'transform.template',
129
+ VERIFY_CACHED: 'state.cache',
130
+ WEBHOOK_FORWARD: 'call.webhook',
131
+ cURL: 'call.dialect',
132
+ };
133
+ /** Resolve only the worker runtime domain. Unknown and absent values are deliberately neutral. */
81
134
  export function familyOfStepType(type) {
135
+ if (!type || !Object.hasOwn(WORKER_STEP_FAMILIES, type))
136
+ return UNMAPPED_STEP_ICON.family;
137
+ return WORKER_STEP_FAMILIES[type];
138
+ }
139
+ /**
140
+ * Retained frontend-domain chain. Its meaningful fallback is existing frontend behavior and must not be used
141
+ * for worker ids.
142
+ */
143
+ export function familyOfFrontendStepType(type) {
82
144
  const t = type.toUpperCase();
83
145
  if (/FORM|SHOW|SELECT|REDIRECT|BROWSER|MESSAGE|INFO/.test(t))
84
146
  return 'ui';
85
147
  if (/^API$|HTTP|REQUEST|WEBHOOK|CALL/.test(t))
86
148
  return 'call';
87
- /**
88
- * WAIT before everything else that could claim it.
89
- *
90
- * `SLEEP` is a real corpus type (`MisaAmisCustomerCallbackMessagePusher.yaml` carries one) and the authored
91
- * set drew it its own clock. Ahead of `query` because `POLL` contains no query word but reads as one, and
92
- * ahead of `state` because `WAIT_FOR_RECENT_USER_CREATED` — an authored KEY, not a type — must not be
93
- * classified by a substring of its name if it ever reaches here as one.
94
- */
95
149
  if (/SLEEP|WAIT|DELAY|POLL|RETRY|SCHEDULE/.test(t))
96
150
  return 'wait';
97
151
  if (/SQL|QUERY|FIND|GET|READ|FETCH/.test(t))
98
152
  return 'query';
99
- /**
100
- * WRITE before STATE, because the authored set separates them and the words overlap.
101
- *
102
- * `write` is a step that PUSHES data somewhere — insert, upsert, seed, push. `state` is a step that
103
- * remembers something for the rest of the run — `SET_STORAGE`, `REGISTER_*`. `SAVE` and `WRITE` were in
104
- * the state bucket and belong here; `SET_` and `STORAGE` stay there.
105
- */
106
153
  if (/WRITE|INSERT|UPSERT|SEED|PUSH|CREATE|DELETE/.test(t))
107
154
  return 'write';
108
155
  if (/SET_|STORAGE|SAVE|UPDATE|REGISTER/.test(t))
@@ -117,39 +164,291 @@ export function familyOfStepType(type) {
117
164
  return 'terminal';
118
165
  return 'orchestrate';
119
166
  }
167
+ /** Resolve a child or parent family to a strict-host glyph. */
168
+ export function glyphOfStepFamily(family) {
169
+ if (!family)
170
+ return UNMAPPED_STEP_ICON.glyph;
171
+ const parent = Object.hasOwn(STEP_FAMILY_PARENTS, family)
172
+ ? STEP_FAMILY_PARENTS[family]
173
+ : family;
174
+ return Object.hasOwn(PARENT_GLYPHS, parent)
175
+ ? PARENT_GLYPHS[parent]
176
+ : UNMAPPED_STEP_ICON.glyph;
177
+ }
178
+ /** Resolve a worker id through the explicit child-family map and parent rollup. */
179
+ export function glyphOfStepType(type) {
180
+ return glyphOfStepFamily(familyOfStepType(type));
181
+ }
182
+ /** Resolve a frontend id through the retained regex chain. */
183
+ export function glyphOfFrontendStepType(type) {
184
+ return type
185
+ ? glyphOfStepFamily(familyOfFrontendStepType(type))
186
+ : UNMAPPED_STEP_ICON.glyph;
187
+ }
188
+ /** The dashboard tile anatomy. Hosts resolve these token names; the vocabulary never bakes in theme colours. */
189
+ export const STEP_ICON_TILE = {
190
+ alignment: 'left',
191
+ shape: 'square',
192
+ radiusToken: 'rounded.xl',
193
+ backgroundToken: 'tile-bg',
194
+ glyphToken: 'tile-glyph',
195
+ };
120
196
  /**
121
- * The glyph for a step type.
197
+ * The approved single-colour family drawings. These are path fragments rather than files so browser consumers can
198
+ * use the package without a filesystem or a remote asset origin.
199
+ */
200
+ const STEP_ICON_SVG = {
201
+ 'call.http': '<path d="M14 3h7v7"/><path d="M21 3l-9 9"/><path d="M19 14v5a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2h5"/>',
202
+ 'call.webhook': '<path d="M13 2 3 14h9l-1 8 10-12h-9l1-8z"/>',
203
+ 'call.event': '<path d="M12 11.5v.01"/><path d="M8.6 8.6a5 5 0 0 0 0 6.8"/><path d="M15.4 15.4a5 5 0 0 0 0-6.8"/><path d="M5.6 5.6a9 9 0 0 0 0 12.8"/><path d="M18.4 18.4a9 9 0 0 0 0-12.8"/>',
204
+ 'call.dialect': '<path d="M4 17l6-6-6-6"/><path d="M12 19h8"/>',
205
+ 'query.dsl': '<path d="M8 3H7a2 2 0 0 0-2 2v4a2 2 0 0 1-2 2 2 2 0 0 1 2 2v4a2 2 0 0 0 2 2h1"/><path d="M16 21h1a2 2 0 0 0 2-2v-4a2 2 0 0 1 2-2 2 2 0 0 1-2-2V5a2 2 0 0 0-2-2h-1"/><path d="M9 12h6"/>',
206
+ 'query.sql': '<ellipse cx="12" cy="5" rx="8" ry="3"/><path d="M4 5v14c0 1.66 3.58 3 8 3s8-1.34 8-3V5"/><path d="M4 12c0 1.66 3.58 3 8 3s8-1.34 8-3"/>',
207
+ 'query.record': '<path d="M8 6h13"/><path d="M8 12h13"/><path d="M8 18h13"/><path d="M3.5 6h.01"/><path d="M3.5 12h.01"/><path d="M3.5 18h.01"/>',
208
+ 'query.metrics': '<path d="M3 3v16a2 2 0 0 0 2 2h16"/><path d="M7 16v-4"/><path d="M12 16V8"/><path d="M17 16v-6"/>',
209
+ 'query.history': '<path d="M3 12a9 9 0 1 0 2.6-6.4L3 8"/><path d="M3 3v5h5"/><path d="M12 7.5V12l3 2"/>',
210
+ 'query.kv': '<circle cx="8" cy="15" r="4"/><path d="M10.85 12.15 19 4"/><path d="M18 5l2 2"/><path d="M15 8l2 2"/>',
211
+ 'query.file': '<path d="M15 2H7a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V6z"/><path d="M14 2v4a2 2 0 0 0 2 2h3"/><path d="M8.5 13h7"/><path d="M8.5 17h7"/>',
212
+ 'state.kv': '<path d="M12.6 2.6A2 2 0 0 0 11.2 2H4a2 2 0 0 0-2 2v7.2a2 2 0 0 0 .6 1.4l8.7 8.7a2.4 2.4 0 0 0 3.4 0l6.6-6.6a2.4 2.4 0 0 0 0-3.4z"/><path d="M7.5 7.5h.01"/>',
213
+ 'state.cache': '<path d="M4 8.5h16V19a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2z"/><rect x="2" y="3.5" width="20" height="5" rx="1"/><path d="M10 12.5h4"/>',
214
+ 'state.task-data': '<path d="M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z"/><path d="M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7"/><path d="M7 3v4a1 1 0 0 0 1 1h6"/>',
215
+ 'state.item': '<path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/><rect x="8" y="2" width="8" height="4" rx="1"/><path d="M9 13.5l2 2 4-4"/>',
216
+ 'state.removal': '<path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"/><path d="M4 22v-7"/>',
217
+ 'write.push': '<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="M17 8l-5-5-5 5"/><path d="M12 3v12"/>',
218
+ 'write.index': '<path d="M12 2v8"/><path d="M16 6l-4 4-4-4"/><path d="M3 14h18"/><path d="M22 14v5a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-5l3.4-6.8A2 2 0 0 1 7.2 6H8"/><path d="M6.5 17.5h.01"/>',
219
+ 'write.seed': '<path d="M7 21h10"/><path d="M12 21v-8"/><path d="M12 13C12 9 9 6 5 6c0 4 3 7 7 7z"/><path d="M12 13c0-3.5 2.5-6.5 6.5-6.5 0 3.5-2.5 6.5-6.5 6.5z"/>',
220
+ 'write.delete': '<path d="M3 6h18"/><path d="M8 6V4.5A1.5 1.5 0 0 1 9.5 3h5A1.5 1.5 0 0 1 16 4.5V6"/><path d="M18.5 6l-.9 13.1A2 2 0 0 1 15.6 21H8.4a2 2 0 0 1-2-1.9L5.5 6"/><path d="M10 11v6"/><path d="M14 11v6"/>',
221
+ 'orchestrate.enqueue': '<path d="M2 12h8"/><path d="M7 9l3 3-3 3"/><path d="M14 4h6a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-6"/><path d="M14 8v8"/>',
222
+ 'orchestrate.pull': '<path d="M4.4 14.9A7 7 0 1 1 15.7 7h1.8a4.5 4.5 0 0 1 2.4 8.3"/><path d="M12 12v9"/><path d="M8.5 17.5 12 21l3.5-3.5"/>',
223
+ 'orchestrate.composite': '<path d="M12 2.5 3.5 7v10l8.5 4.5 8.5-4.5V7z"/><path d="M3.5 7 12 11.5 20.5 7"/><path d="M12 11.5v10"/>',
224
+ 'transform.template': '<path d="M8 3H7a2 2 0 0 0-2 2v4a2 2 0 0 1-2 2 2 2 0 0 1 2 2v4a2 2 0 0 0 2 2h1"/><path d="M16 21h1a2 2 0 0 0 2-2v-4a2 2 0 0 1 2-2 2 2 0 0 1-2-2V5a2 2 0 0 0-2-2h-1"/>',
225
+ 'transform.filter': '<path d="M21.5 3.5H2.5l7.6 9v7.2l3.8 1.8v-9z"/>',
226
+ 'transform.decode': '<path d="M8 3 4 7l4 4"/><path d="M4 7h16"/><path d="M16 21l4-4-4-4"/><path d="M20 17H4"/>',
227
+ 'control.if': '<path d="M16 3h5v5"/><path d="M8 3H3v5"/><path d="M12 22v-8.3a4 4 0 0 0-1.2-2.8L3 3"/><path d="M15 9l6-6"/>',
228
+ 'control.switch': '<path d="M4 4v14a2 2 0 0 0 2 2h2"/><path d="M4 7h10"/><path d="M4 13h10"/><path d="M8 20h6"/><path d="M17 4h3"/><path d="M17 10h3"/><path d="M17 17h3"/>',
229
+ 'terminal.begin': '<circle cx="12" cy="12" r="9"/><path d="M10 8.5 16 12l-6 3.5z"/>',
230
+ 'terminal.end': '<circle cx="12" cy="12" r="9"/><rect x="9" y="9" width="6" height="6" rx="1"/>',
231
+ 'terminal.error': '<path d="M10.3 4 2.6 17.5A2 2 0 0 0 4.3 20.5h15.4a2 2 0 0 0 1.7-3L13.7 4a2 2 0 0 0-3.4 0z"/><path d="M12 9.5v4"/><path d="M12 17h.01"/>',
232
+ 'wait.sleep': '<circle cx="12" cy="12" r="9"/><path d="M12 7v5l3.5 2"/>',
233
+ };
234
+ const maskImage = (body) => {
235
+ const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">${body}</svg>`;
236
+ return `url("data:image/svg+xml,${encodeURIComponent(svg)}")`;
237
+ };
238
+ /** Normalize a family into the asset-backed class Mermaid copies to the rendered node group. */
239
+ export function stepIconClassName(family) {
240
+ const resolved = family !== undefined &&
241
+ Object.hasOwn(STEP_FAMILY_PARENTS, family)
242
+ ? family
243
+ : UNMAPPED_STEP_ICON.family;
244
+ return `ic-${resolved.replaceAll('.', '-')}`;
245
+ }
246
+ const iconAssets = {};
247
+ const defineLazyAsset = (family, parent, strictGlyph, svgBody) => {
248
+ let value;
249
+ Object.defineProperty(iconAssets, family, {
250
+ enumerable: true,
251
+ get: () => {
252
+ value ??= {
253
+ family,
254
+ parent,
255
+ className: stepIconClassName(family),
256
+ strictGlyph,
257
+ looseMaskImage: maskImage(svgBody),
258
+ tint: 'currentColor',
259
+ };
260
+ return value;
261
+ },
262
+ });
263
+ };
264
+ for (const family of Object.keys(STEP_FAMILY_PARENTS)) {
265
+ const parent = STEP_FAMILY_PARENTS[family];
266
+ defineLazyAsset(family, parent, glyphOfStepFamily(parent), STEP_ICON_SVG[family]);
267
+ }
268
+ defineLazyAsset(UNMAPPED_STEP_ICON.family, UNMAPPED_STEP_ICON.family, UNMAPPED_STEP_ICON.glyph, '<rect x="4" y="4" width="16" height="16" rx="2"/><path d="M8 8l8 8M16 8l-8 8"/>');
269
+ /**
270
+ * Complete local loose-host assets. Each mask is percent-encoded on first property access, so strict-only rendering
271
+ * pays only for class and glyph lookup.
272
+ */
273
+ export const STEP_ICON_ASSETS = iconAssets;
274
+ /**
275
+ * The in-node error marker: one glyph for a strict host, the approved drawing for a loose one.
122
276
  *
123
- * Empty for a step with NO type — there is no icon to stand in for, and a placeholder would render as a
124
- * second separator (`name · · KEY`), which is how this was caught.
277
+ * **Why `⚠` (U+26A0, Miscellaneous Symbols) and not a glyph from the three approved blocks.** `PARENT_GLYPHS`'
278
+ * Arrows / Geometric Shapes / Mathematical Operators rule exists so 32 FAMILY glyphs render in the fonts a webview
279
+ * receives; it does not cover a marker, and none of the three blocks contains an exclamation-in-triangle — the shape
280
+ * DESIGN.md names. U+26A0 was MEASURED surviving a Mermaid 12.0.0 strict-mode render inside a backtick-quoted
281
+ * markdown label on 2026-09-28, alongside `×` and `◆`, and it is the one glyph in the canvas's whole vocabulary whose
282
+ * absence would be obvious rather than silent (a failed node also carries `emphasis` width, a red stroke and a tinted
283
+ * fill, so the marker is never the only signal — `node-failed`'s three channels are independent by design).
284
+ *
285
+ * **The same glyph is used at BOTH fidelities.** Story 8.3 could split strict glyph from loose mask because the mask
286
+ * arrives through a class the host's own stylesheet paints; a run-state mark cannot, because AD-23 forbids any host
287
+ * CSS rule that carries run state onto a node. `looseMaskImage` is therefore exported for a loose host's LEGEND or
288
+ * inspector chrome — not for the node — and it reuses `terminal.error`'s approved path fragment rather than authoring
289
+ * a second exclamation-in-triangle.
125
290
  */
126
- export function glyphOfStepType(type) {
127
- if (!type)
291
+ export const RUN_STATE_ERROR_MARKER = {
292
+ glyph: '\u26a0',
293
+ className: stepIconClassName('terminal.error'),
294
+ get looseMaskImage() {
295
+ return STEP_ICON_ASSETS['terminal.error'].looseMaskImage;
296
+ },
297
+ tint: 'currentColor',
298
+ };
299
+ /** The multiplication sign the count badge reads with (`×997`). MEASURED surviving a strict-mode render. */
300
+ export const REPEAT_BADGE_GLYPH = '\u00d7';
301
+ /**
302
+ * The largest count the badge will draw.
303
+ *
304
+ * A bound, not a formatting choice: `Number.isInteger(1e21)` is TRUE, so an unbounded check drew `×1e+21` — the
305
+ * exponent notation JavaScript switches to above 1e20, which is not a count any reader can act on and not a claim
306
+ * about a run that the generator can stand behind. A billion occurrences is already far outside anything the
307
+ * accumulator can produce, so beyond it the honest answer is no badge.
308
+ */
309
+ export const REPEAT_BADGE_MAX = 1_000_000_000;
310
+ /** Is this a count worth drawing? One predicate, so the label and the style pass can never disagree. */
311
+ export function isCountableRepeat(repeat) {
312
+ return repeat !== undefined &&
313
+ Number.isSafeInteger(repeat) &&
314
+ repeat > 1 &&
315
+ repeat <= REPEAT_BADGE_MAX;
316
+ }
317
+ /** `×N` for a count worth stating, and nothing at all otherwise. */
318
+ export function repeatBadgeText(repeat) {
319
+ return isCountableRepeat(repeat) ? `${REPEAT_BADGE_GLYPH}${repeat}` : undefined;
320
+ }
321
+ /**
322
+ * What a screen reader is told about the run, in words.
323
+ *
324
+ * NFR13 forbids carrying state in colour alone, and a screen-reader user is the one reader who sees no line-work at
325
+ * all: no stroke, no dash, no opacity, no marker. So the state and the repeat count have to reach `accDescr` as text
326
+ * or they do not reach that reader at all.
327
+ *
328
+ * **`indeterminate` IS stated**, in words, even though it is the plainest thing on the canvas. The drawing gives every
329
+ * node a reading the moment a typed overlay is in use, precisely so a reader cannot confuse "the run never reached
330
+ * this" with "nobody told us about this"; a text channel that stayed silent for the indeterminate ones would hand a
331
+ * screen-reader user back exactly the ambiguity the visual rule removes. The two channels agree or one of them lies.
332
+ */
333
+ const RUN_STATE_TEXT = {
334
+ ranOk: 'ran OK',
335
+ ranFailed: 'failed',
336
+ neverReached: 'never ran',
337
+ branchNotTaken: 'branch not taken',
338
+ indeterminate: 'run state unknown',
339
+ };
340
+ export function runStateAlternativeText(runState) {
341
+ if (runState === undefined)
128
342
  return '';
129
- return GLYPHS[familyOfStepType(type)] ?? '·';
343
+ /**
344
+ * The lookup is GUARDED, not indexed.
345
+ *
346
+ * An overlay can arrive as parsed JSON or a `postMessage` payload, where `state: 'running'` is one keystroke away
347
+ * and types prove nothing. Indexed blind it would put the literal word `undefined` into `accDescr` — a sentence
348
+ * read aloud to the one reader who has no other channel.
349
+ */
350
+ const state = runState.state !== undefined && Object.hasOwn(RUN_STATE_TEXT, runState.state)
351
+ ? RUN_STATE_TEXT[runState.state]
352
+ : '';
353
+ const ran = isCountableRepeat(runState.repeat) ? `ran ${runState.repeat} times` : '';
354
+ return [state, ran].filter((part) => part !== '').join(', ');
130
355
  }
356
+ const visibleText = (value) => {
357
+ const normalized = value?.trim();
358
+ return normalized ? normalized : undefined;
359
+ };
131
360
  /**
132
- * The three lines a reader needs, in the order the brainstorm asked for: name, then key, then type.
361
+ * Compose the shared node-card anatomy and its structural renderer provenance.
133
362
  *
134
- * ⚠️ ONE LINE, not `<br/>`, and that was measured rather than assumed. The first version used `<br/>`; the
135
- * shared renderer's `escapeLabel` turns `<` into `&lt;` — correctly, it is what stops an authored step name
136
- * injecting markup — so mermaid received `&lt;br/&gt;` and would have drawn it as visible text in every box.
137
- * Weakening `escapeLabel` to admit one tag would trade a real safety property for a cosmetic one.
363
+ * The label has two semantic text roles rather than a two-physical-line limit: the bold heading may wrap, and the
364
+ * upright key/type description follows it. Strict hosts keep a Unicode glyph and explicit type text; loose hosts
365
+ * reserve the icon through the node's family class and keep the key as their description.
138
366
  *
139
- * A junction (START/END) has its own label and no key or type — it returns unchanged, because decorating a
140
- * terminal with an empty key line would put a blank row in every diagram.
367
+ * Boundary whitespace is not visible content. Normalizing it here keeps a blank explicit label from defeating the
368
+ * name/key/address fallback or moving Mermaid's bold delimiters away from the heading.
369
+ */
370
+ export function composeNodeLabelModel(node, fidelity, domain, iconFamily, runState) {
371
+ const stepKey = visibleText(node.stepKey);
372
+ const type = visibleText(node.type) ?? visibleText(node.displayType);
373
+ const heading = visibleText(node.label) ??
374
+ visibleText(node.name) ??
375
+ stepKey ??
376
+ visibleText(node.address) ??
377
+ '?';
378
+ const marker = runState?.marker === true ? RUN_STATE_ERROR_MARKER.glyph : undefined;
379
+ const badge = repeatBadgeText(runState?.repeat);
380
+ /**
381
+ * The no-anatomy early return, and why run-state content overrides it.
382
+ *
383
+ * A node with neither `stepKey` nor `type` has no card to lay out, so it returns a bare string and the renderer
384
+ * emits a plain quoted label. But a marker or a badge is a fact about the RUN, not about the card: dropping it
385
+ * here would make a failed node with no key silently indistinguishable from a healthy one. So the moment either is
386
+ * present, anatomy is composed anyway — with the heading as its only text role.
387
+ */
388
+ if (!stepKey && !type) {
389
+ if (marker === undefined && badge === undefined)
390
+ return { text: heading };
391
+ const bare = {
392
+ ...(marker ? { marker } : {}),
393
+ heading,
394
+ ...(badge ? { badge } : {}),
395
+ };
396
+ // Escaped here exactly as `renderLabelAnatomy` escapes it, through the same function: two spellings of one
397
+ // heading is two different labels for one node depending on which surface composed it.
398
+ return {
399
+ text: `\`${marker ? `${marker} ` : ''}**${escapeMarkdownText(heading)}**${badge ? ` ${badge}` : ''}\``,
400
+ anatomy: bare,
401
+ };
402
+ }
403
+ const glyph = iconFamily !== undefined
404
+ ? glyphOfStepFamily(iconFamily)
405
+ : domain === 'worker'
406
+ ? glyphOfStepType(type)
407
+ : type
408
+ ? glyphOfFrontendStepType(type)
409
+ : '';
410
+ const description = fidelity === 'loose'
411
+ ? stepKey
412
+ : [stepKey, type].filter(Boolean).join(' · ') || undefined;
413
+ const anatomy = {
414
+ ...(fidelity === 'strict' && glyph ? { icon: glyph } : {}),
415
+ // Right of the icon tile, per DESIGN.md's card order: icon tile, marker, heading, description, badge.
416
+ ...(marker ? { marker } : {}),
417
+ heading,
418
+ ...(description ? { description } : {}),
419
+ ...(badge ? { badge } : {}),
420
+ };
421
+ const composedHeading = `${anatomy.icon ? `${anatomy.icon} ` : ''}${anatomy.marker ? `${anatomy.marker} ` : ''}**${anatomy.heading}**`;
422
+ const tail = anatomy.badge ? ` ${anatomy.badge}` : '';
423
+ return {
424
+ text: anatomy.description
425
+ ? `\`${composedHeading}\n${anatomy.description}${tail}\``
426
+ : `\`${composedHeading}${tail}\``,
427
+ anatomy,
428
+ };
429
+ }
430
+ /** String-only compatibility surface; renderers use `composeNodeLabelModel` so provenance stays structural. */
431
+ export function composeNodeLabel(node, fidelity, domain, iconFamily) {
432
+ return composeNodeLabelModel(node, fidelity, domain, iconFamily).text;
433
+ }
434
+ /**
435
+ * Screen-reader text for a node. The icon is deliberately absent: strict Unicode names are noisy, while loose masks
436
+ * are decorative. Fidelity and domain stay in the signature so callers can compose visual and accessible labels from
437
+ * the same inputs without branching.
141
438
  */
142
- export function composeNodeLabel(node) {
143
- const type = node.type ?? node.displayType;
144
- const heading = node.label ?? node.name ?? node.stepKey ?? node.address;
145
- // A junction, or a node carrying neither of the two facts this function exists to add.
146
- if (!node.stepKey && !type)
147
- return heading;
148
- // The glyph leads the added half rather than the whole label, so the NAME stays what the eye lands on.
149
- // Every part is filtered, so a key with no type (or the reverse) yields ONE separator, not an empty slot.
150
- const second = [glyphOfStepType(type), [node.stepKey, type].filter(Boolean).join(' · ')]
151
- .filter(Boolean)
152
- .join(' ');
153
- return second ? `${heading} · ${second}` : heading;
439
+ export function composeAccessibleNodeLabel(node, _fidelity, _domain, runState) {
440
+ const type = node.type?.trim() || node.displayType?.trim() || undefined;
441
+ const stepKey = node.stepKey?.trim() || undefined;
442
+ const heading = [
443
+ node.name?.trim(),
444
+ node.label?.trim(),
445
+ stepKey,
446
+ node.address.trim() || '?',
447
+ ].find((value) => Boolean(value));
448
+ const detail = [stepKey, type].filter(Boolean).join(' · ');
449
+ const named = detail ? `${heading} · ${detail}` : heading;
450
+ // Run state is appended, never substituted: the reader still needs to know WHICH step failed.
451
+ const run = runStateAlternativeText(runState);
452
+ return run === '' ? named : `${named} · ${run}`;
154
453
  }
155
454
  //# sourceMappingURL=stepGlyph.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"stepGlyph.js","sourceRoot":"","sources":["../src/stepGlyph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,GAAqC;IAC/C,2BAA2B;IAC3B,IAAI,EAAE,GAAG;IACT,uFAAuF;IACvF,OAAO,EAAE,GAAG;IACZ,uCAAuC;IACvC,WAAW,EAAE,GAAG;IAChB,kEAAkE;IAClE,KAAK,EAAE,GAAG;IACV,oDAAoD;IACpD,KAAK,EAAE,GAAG;IACV,yBAAyB;IACzB,QAAQ,EAAE,GAAG;IACb,qCAAqC;IACrC,SAAS,EAAE,GAAG;IACd,kCAAkC;IAClC,EAAE,EAAE,GAAG;IACP,oBAAoB;IACpB,IAAI,EAAE,GAAG;IACT,6BAA6B;IAC7B,KAAK,EAAE,GAAG;CACX,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAC7B,IAAI,gDAAgD,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1E,IAAI,iCAAiC,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IAC7D;;;;;;;OAOG;IACH,IAAI,sCAAsC,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IAClE,IAAI,+BAA+B,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,OAAO,CAAC;IAC5D;;;;;;OAMG;IACH,IAAI,6CAA6C,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,OAAO,CAAC;IAC1E,IAAI,mCAAmC,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,OAAO,CAAC;IAChE,IAAI,8BAA8B,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,WAAW,CAAC;IAC/D,IAAI,kCAAkC,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,aAAa,CAAC;IACrE,IAAI,4BAA4B,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IAC3D,IAAI,8BAA8B,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,UAAU,CAAC;IAC9D,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,IAAwB;IACtD,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,OAAO,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC;AAC/C,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAOhC;IACC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,CAAC;IAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC;IACxE,uFAAuF;IACvF,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI;QAAE,OAAO,OAAO,CAAC;IAE3C,uGAAuG;IACvG,0GAA0G;IAC1G,MAAM,MAAM,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SACrF,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC,CAAC;IACb,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,OAAO,MAAM,MAAM,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;AACrD,CAAC"}
1
+ {"version":3,"file":"stepGlyph.js","sourceRoot":"","sources":["../src/stepGlyph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ export declare const WORKER_ROSTER_MAX_AGE_MS = 86400000;
2
+ export interface WorkerRosterAuditOptions {
3
+ readonly now: Date;
4
+ readonly maxAgeMs: number;
5
+ }
6
+ export interface WorkerRosterAudit {
7
+ readonly valid: boolean;
8
+ readonly stale: boolean;
9
+ readonly unmapped: readonly string[];
10
+ readonly missingFromRoster: readonly string[];
11
+ readonly errors: readonly string[];
12
+ readonly warnings: readonly string[];
13
+ }
14
+ /**
15
+ * Check provenance, freshness, roster shape, and bidirectional map drift without consulting a sibling
16
+ * repository or the ambient clock. Staleness is advisory; malformed provenance and roster drift are failures.
17
+ */
18
+ export declare function auditWorkerRosterManifest(manifest: unknown, options: WorkerRosterAuditOptions): WorkerRosterAudit;
19
+ //# sourceMappingURL=workerStepVocabularyAudit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workerStepVocabularyAudit.d.ts","sourceRoot":"","sources":["../src/workerStepVocabularyAudit.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,wBAAwB,WAAa,CAAC;AAEnD,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC;IACnB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9C,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAsDD;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,wBAAwB,GAChC,iBAAiB,CA6FnB"}