@almadar/shell-web 0.0.0-stage → 1.0.0

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 (266) hide show
  1. package/bundling.d.mts +18 -0
  2. package/bundling.mjs +28 -0
  3. package/dist/ArbitraryClassCompiler-CO_iASBn.d.ts +195 -0
  4. package/dist/AvlGlyph-EPJKFEO3.js +6 -0
  5. package/dist/AvlStateMachine-RKZIKNGC.js +9 -0
  6. package/dist/AvlTransitionDetail-63SD6GZF.js +11 -0
  7. package/dist/AvlTransitionExplainer-ZBTLOM3T.js +12 -0
  8. package/dist/BehaviorView-YS5G4GNB.js +11 -0
  9. package/dist/Canvas3DHost-BkZQB5l2.d.ts +552 -0
  10. package/dist/EventBusProvider-BFFHfN4O.d.ts +296 -0
  11. package/dist/FileTree-BCFnBEuQ.d.ts +254 -0
  12. package/dist/FlowCanvas-3JRMNJLV.css +1756 -0
  13. package/dist/FlowCanvas-AUMTWMNG.js +26 -0
  14. package/dist/GameAudioProvider-ceM_n0ey.d.ts +90 -0
  15. package/dist/KaTeX_AMS-Regular-CYEKBG2K.woff +0 -0
  16. package/dist/KaTeX_AMS-Regular-JKX5W2C4.ttf +0 -0
  17. package/dist/KaTeX_AMS-Regular-U6PRYMIZ.woff2 +0 -0
  18. package/dist/KaTeX_Caligraphic-Bold-5QL5CMTE.woff2 +0 -0
  19. package/dist/KaTeX_Caligraphic-Bold-WZ3QSGD3.woff +0 -0
  20. package/dist/KaTeX_Caligraphic-Bold-ZTS3R3HK.ttf +0 -0
  21. package/dist/KaTeX_Caligraphic-Regular-3LKEU76G.woff +0 -0
  22. package/dist/KaTeX_Caligraphic-Regular-A7XRTZ5Q.ttf +0 -0
  23. package/dist/KaTeX_Caligraphic-Regular-KX5MEWCF.woff2 +0 -0
  24. package/dist/KaTeX_Fraktur-Bold-2QVFK6NQ.woff2 +0 -0
  25. package/dist/KaTeX_Fraktur-Bold-T4SWXBMT.woff +0 -0
  26. package/dist/KaTeX_Fraktur-Bold-WGHVTYOR.ttf +0 -0
  27. package/dist/KaTeX_Fraktur-Regular-2PEIFJSJ.woff2 +0 -0
  28. package/dist/KaTeX_Fraktur-Regular-5U4OPH2X.ttf +0 -0
  29. package/dist/KaTeX_Fraktur-Regular-PQMHCIK6.woff +0 -0
  30. package/dist/KaTeX_Main-Bold-2GA4IZIN.woff +0 -0
  31. package/dist/KaTeX_Main-Bold-W5FBVCZM.ttf +0 -0
  32. package/dist/KaTeX_Main-Bold-YP5VVQRP.woff2 +0 -0
  33. package/dist/KaTeX_Main-BoldItalic-4P4C7HJH.woff +0 -0
  34. package/dist/KaTeX_Main-BoldItalic-N4V3DX7S.woff2 +0 -0
  35. package/dist/KaTeX_Main-BoldItalic-ODMLBJJQ.ttf +0 -0
  36. package/dist/KaTeX_Main-Italic-I43T2HSR.ttf +0 -0
  37. package/dist/KaTeX_Main-Italic-RELBIK7M.woff2 +0 -0
  38. package/dist/KaTeX_Main-Italic-SASNQFN2.woff +0 -0
  39. package/dist/KaTeX_Main-Regular-ARRPAO67.woff2 +0 -0
  40. package/dist/KaTeX_Main-Regular-P5I74A2A.woff +0 -0
  41. package/dist/KaTeX_Main-Regular-W74P5G27.ttf +0 -0
  42. package/dist/KaTeX_Math-BoldItalic-6EBV3DK5.woff +0 -0
  43. package/dist/KaTeX_Math-BoldItalic-K4WTGH3J.woff2 +0 -0
  44. package/dist/KaTeX_Math-BoldItalic-VB447A4D.ttf +0 -0
  45. package/dist/KaTeX_Math-Italic-6KGCHLFN.woff2 +0 -0
  46. package/dist/KaTeX_Math-Italic-KKK3USB2.woff +0 -0
  47. package/dist/KaTeX_Math-Italic-SON4MRCA.ttf +0 -0
  48. package/dist/KaTeX_SansSerif-Bold-RRNVJFFW.woff2 +0 -0
  49. package/dist/KaTeX_SansSerif-Bold-STQ6RXC7.ttf +0 -0
  50. package/dist/KaTeX_SansSerif-Bold-X5M5EMOD.woff +0 -0
  51. package/dist/KaTeX_SansSerif-Italic-HMPFTM52.woff2 +0 -0
  52. package/dist/KaTeX_SansSerif-Italic-PSN4QKYX.woff +0 -0
  53. package/dist/KaTeX_SansSerif-Italic-WTBAZBGY.ttf +0 -0
  54. package/dist/KaTeX_SansSerif-Regular-2TL3USAE.ttf +0 -0
  55. package/dist/KaTeX_SansSerif-Regular-OQCII6EP.woff +0 -0
  56. package/dist/KaTeX_SansSerif-Regular-XIQ62X4E.woff2 +0 -0
  57. package/dist/KaTeX_Script-Regular-72OLXYNA.ttf +0 -0
  58. package/dist/KaTeX_Script-Regular-A5IFOEBS.woff +0 -0
  59. package/dist/KaTeX_Script-Regular-APUWIHLP.woff2 +0 -0
  60. package/dist/KaTeX_Size1-Regular-4HRHTS65.woff +0 -0
  61. package/dist/KaTeX_Size1-Regular-5LRUTBFT.woff2 +0 -0
  62. package/dist/KaTeX_Size1-Regular-7K6AASVL.ttf +0 -0
  63. package/dist/KaTeX_Size2-Regular-222HN3GT.ttf +0 -0
  64. package/dist/KaTeX_Size2-Regular-K5ZHAIS6.woff +0 -0
  65. package/dist/KaTeX_Size2-Regular-LELKET5D.woff2 +0 -0
  66. package/dist/KaTeX_Size3-Regular-TLFPAHDE.woff +0 -0
  67. package/dist/KaTeX_Size3-Regular-UFCO6WCA.ttf +0 -0
  68. package/dist/KaTeX_Size3-Regular-WQRQ47UD.woff2 +0 -0
  69. package/dist/KaTeX_Size4-Regular-7PGNVPQK.ttf +0 -0
  70. package/dist/KaTeX_Size4-Regular-CDMV7U5C.woff2 +0 -0
  71. package/dist/KaTeX_Size4-Regular-PKMWZHNC.woff +0 -0
  72. package/dist/KaTeX_Typewriter-Regular-3F5K6SQ6.ttf +0 -0
  73. package/dist/KaTeX_Typewriter-Regular-MJMFSK64.woff +0 -0
  74. package/dist/KaTeX_Typewriter-Regular-VBYJ4NRC.woff2 +0 -0
  75. package/dist/KernelEngineContext-CcxGYtlr.d.ts +33 -0
  76. package/dist/LayersPanel-M2LHWUFF.js +6 -0
  77. package/dist/ModuleCard-QHDGK5XK.js +7 -0
  78. package/dist/OrbInspector-MHLJ6OEE.css +1756 -0
  79. package/dist/OrbInspector-QCPEPUPH.js +26 -0
  80. package/dist/Select-B-iDdnvE.d.ts +185 -0
  81. package/dist/ServerBridge-Bqsj-lOU.d.ts +124 -0
  82. package/dist/ThemeContext-DJmO59xd.d.ts +147 -0
  83. package/dist/UISlotContext-Dl_ewwCI.d.ts +79 -0
  84. package/dist/UISlotRenderer-C7WWOK43.js +26 -0
  85. package/dist/UISlotRenderer-KVFO6J7R.css +1756 -0
  86. package/dist/auth/browser/index.d.ts +2 -0
  87. package/dist/auth/browser/index.js +2 -0
  88. package/dist/auth/react/index.d.ts +56 -0
  89. package/dist/auth/react/index.js +157 -0
  90. package/dist/avl/index.css +1756 -0
  91. package/dist/avl/index.d.ts +2248 -0
  92. package/dist/avl/index.js +2693 -0
  93. package/dist/avl-3d-context-BycmO6tG.d.ts +201 -0
  94. package/dist/avl-schema-parser-CtJxJ9KU.d.ts +132 -0
  95. package/dist/avl-zoom-state-CKMVuBFg.d.ts +17 -0
  96. package/dist/chunk-3BBUBJFF.js +339 -0
  97. package/dist/chunk-3S54FWRC.js +131 -0
  98. package/dist/chunk-3VZ36ZKO.js +775 -0
  99. package/dist/chunk-4T3P43NS.js +1133 -0
  100. package/dist/chunk-4YXBKHHM.js +11488 -0
  101. package/dist/chunk-57DC34LY.js +525 -0
  102. package/dist/chunk-5QTYQTPS.js +15 -0
  103. package/dist/chunk-A2LR6VQQ.js +349 -0
  104. package/dist/chunk-AB3X7QTE.js +505 -0
  105. package/dist/chunk-AE7VCQB6.js +561 -0
  106. package/dist/chunk-AGXD77SL.js +98 -0
  107. package/dist/chunk-AU7O65OX.js +66 -0
  108. package/dist/chunk-CPLN6NBQ.js +701 -0
  109. package/dist/chunk-DZBQA2OW.js +176 -0
  110. package/dist/chunk-E6KA4J6N.js +227 -0
  111. package/dist/chunk-EOWMARUB.js +16 -0
  112. package/dist/chunk-G7DCAZ22.js +19 -0
  113. package/dist/chunk-GFXCPUMX.js +1334 -0
  114. package/dist/chunk-HH5KSMH5.js +311 -0
  115. package/dist/chunk-ILQXJ2AR.js +280 -0
  116. package/dist/chunk-ILZ7ORX7.js +432 -0
  117. package/dist/chunk-K4MOPSEL.js +674 -0
  118. package/dist/chunk-LHP2TK7O.js +47587 -0
  119. package/dist/chunk-P4ZFUQFF.js +93 -0
  120. package/dist/chunk-PCR37T3U.js +296 -0
  121. package/dist/chunk-PRXQGGCO.js +580 -0
  122. package/dist/chunk-REXYVBUO.js +191 -0
  123. package/dist/chunk-ROICKAU7.js +24 -0
  124. package/dist/chunk-SP5CDJ6K.js +338 -0
  125. package/dist/chunk-TUPZWTRE.js +1051 -0
  126. package/dist/chunk-TXAUOLWZ.js +490 -0
  127. package/dist/chunk-TZZBINQY.js +82 -0
  128. package/dist/chunk-UTDC2NEA.js +14 -0
  129. package/dist/chunk-UU57VNS2.js +1053 -0
  130. package/dist/chunk-UXLE3IPR.js +421 -0
  131. package/dist/chunk-VO2TTLS5.js +94 -0
  132. package/dist/chunk-X3DMMX27.js +11 -0
  133. package/dist/chunk-YHMRX6YA.js +455 -0
  134. package/dist/components/index.css +1756 -0
  135. package/dist/components/index.d.ts +11299 -0
  136. package/dist/components/index.js +1110 -0
  137. package/dist/context/index.d.ts +8 -0
  138. package/dist/context/index.js +8 -0
  139. package/dist/core.d.ts +2599 -0
  140. package/dist/core.js +3 -0
  141. package/dist/design-classes/index.cjs +431 -0
  142. package/dist/design-classes/index.d.cts +165 -0
  143. package/dist/design-classes/index.d.ts +165 -0
  144. package/dist/design-classes/index.js +399 -0
  145. package/dist/emojiItems-QGSNAABW.js +20 -0
  146. package/dist/fx-CmQjnHmT.d.ts +371 -0
  147. package/dist/hooks/index.d.ts +971 -0
  148. package/dist/hooks/index.js +8 -0
  149. package/dist/index.d.ts +408 -0
  150. package/dist/index.js +178 -0
  151. package/dist/katexPlugin-FA7NX4PE.css +1161 -0
  152. package/dist/katexPlugin-NCDKOOQY.js +2 -0
  153. package/dist/kernel-client-TZKGHJRY.js +516 -0
  154. package/dist/kernel-wire-wNdAPfhJ.d.ts +88 -0
  155. package/dist/lib/index.d.ts +602 -0
  156. package/dist/lib/index.js +1289 -0
  157. package/dist/paintDispatch-CuJLsr9Y.d.ts +688 -0
  158. package/dist/parseLessonSegments-GpCeMrb2.d.ts +334 -0
  159. package/dist/perf-CKiBKbkw.d.ts +22 -0
  160. package/dist/perf-Dr28-AgT.d.ts +57 -0
  161. package/dist/prism-X5YWKXO5.js +136 -0
  162. package/dist/providers/index.css +1756 -0
  163. package/dist/providers/index.d.ts +355 -0
  164. package/dist/providers/index.js +29 -0
  165. package/dist/renderer/index.d.ts +465 -0
  166. package/dist/renderer/index.js +4 -0
  167. package/dist/runtime/index.css +1756 -0
  168. package/dist/runtime/index.d.ts +239 -0
  169. package/dist/runtime/index.js +28 -0
  170. package/dist/slot-host-CPzrxLo9.d.ts +48 -0
  171. package/dist/ssr/index.cjs +9739 -0
  172. package/dist/ssr/index.d.cts +464 -0
  173. package/dist/ssr/index.d.ts +464 -0
  174. package/dist/ssr/index.js +9703 -0
  175. package/dist/storage/browser/index.d.ts +1 -0
  176. package/dist/storage/browser/index.js +2 -0
  177. package/dist/test-support.d.ts +42 -0
  178. package/dist/test-support.js +181 -0
  179. package/dist/themeTokens-CRd8AEDF.d.ts +125 -0
  180. package/dist/three/index.css +503 -0
  181. package/dist/three/index.d.ts +1185 -0
  182. package/dist/three/index.js +3908 -0
  183. package/dist/useUISlots-CiobNFGb.d.ts +211 -0
  184. package/dist/verification-C5pTeMJv.d.ts +66 -0
  185. package/dist/verificationRegistry-CVrcxG1s.d.ts +122 -0
  186. package/dist/wrapCallbackForEvent-B9QLbhxX.d.ts +19 -0
  187. package/index.css +199 -0
  188. package/package.json +273 -3
  189. package/src/core/lib/band-shapes.json +7 -0
  190. package/src/core/locales/ar.json +1276 -0
  191. package/src/core/locales/en.json +1276 -0
  192. package/src/core/locales/index.ts +54 -0
  193. package/src/core/locales/sl.json +1276 -0
  194. package/src/core/tokens/native-tokens.json +369 -0
  195. package/tailwind-compile.cjs +29 -0
  196. package/tailwind-preset.cjs +1020 -0
  197. package/themes/_base.css +451 -0
  198. package/themes/_contract.md +307 -0
  199. package/themes/_fonts-kenney.css +11 -0
  200. package/themes/_fonts.css +12 -0
  201. package/themes/_foundation.css +105 -0
  202. package/themes/_head.css +22 -0
  203. package/themes/_presets.css +67 -0
  204. package/themes/almadar-heritage.css +455 -0
  205. package/themes/almadar-website.css +269 -0
  206. package/themes/almadar.css +269 -0
  207. package/themes/aqua.css +455 -0
  208. package/themes/arabesque.css +459 -0
  209. package/themes/art-deco.css +457 -0
  210. package/themes/art-nouveau.css +459 -0
  211. package/themes/atelier.css +463 -0
  212. package/themes/bauhaus.css +461 -0
  213. package/themes/bloomberg-dense.css +463 -0
  214. package/themes/blueprint.css +457 -0
  215. package/themes/clay.css +449 -0
  216. package/themes/comic.css +453 -0
  217. package/themes/constructivist.css +457 -0
  218. package/themes/corporate.css +449 -0
  219. package/themes/cyberpunk.css +453 -0
  220. package/themes/frutiger-aero.css +458 -0
  221. package/themes/game-adventure.css +201 -0
  222. package/themes/game-rpg.css +203 -0
  223. package/themes/game-sci-fi.css +201 -0
  224. package/themes/game-ui-pack.css +200 -0
  225. package/themes/gazette.css +449 -0
  226. package/themes/glass.css +457 -0
  227. package/themes/gothic.css +453 -0
  228. package/themes/index.css +21 -0
  229. package/themes/ink-wash.css +459 -0
  230. package/themes/kawaii.css +459 -0
  231. package/themes/kflow.css +310 -0
  232. package/themes/kiosk.css +449 -0
  233. package/themes/linear-clean.css +463 -0
  234. package/themes/luxury.css +451 -0
  235. package/themes/mac-classic.css +455 -0
  236. package/themes/material.css +463 -0
  237. package/themes/memphis.css +453 -0
  238. package/themes/mid-century.css +455 -0
  239. package/themes/minimalist.css +449 -0
  240. package/themes/mudcloth.css +459 -0
  241. package/themes/nata.css +310 -0
  242. package/themes/neon.css +453 -0
  243. package/themes/neumorphic.css +451 -0
  244. package/themes/newsprint.css +455 -0
  245. package/themes/notion-editorial.css +463 -0
  246. package/themes/orb.css +465 -0
  247. package/themes/pixel.css +449 -0
  248. package/themes/prism.css +309 -0
  249. package/themes/rawi.css +310 -0
  250. package/themes/retro.css +452 -0
  251. package/themes/risograph.css +463 -0
  252. package/themes/scandi.css +469 -0
  253. package/themes/sketch.css +455 -0
  254. package/themes/solarpunk.css +469 -0
  255. package/themes/steampunk.css +451 -0
  256. package/themes/swiss.css +455 -0
  257. package/themes/terminal.css +466 -0
  258. package/themes/trait-wars.css +487 -0
  259. package/themes/ukiyo-e.css +459 -0
  260. package/themes/vaporwave.css +455 -0
  261. package/themes/victorian.css +453 -0
  262. package/themes/wabi-sabi.css +459 -0
  263. package/themes/win95.css +455 -0
  264. package/themes/wireframe.css +439 -0
  265. package/themes/zine.css +455 -0
  266. package/README.md +0 -3
@@ -0,0 +1,211 @@
1
+ import React__default from 'react';
2
+ import { UISlot, RenderItemLambda, EventPayloadValue, RowSetMarker } from '@almadar/core';
3
+
4
+ /**
5
+ * useUISlots Hook
6
+ *
7
+ * Core hook for managing UI slot rendering in the trait-driven architecture.
8
+ * Traits use render_ui effects to dynamically render content into slots.
9
+ *
10
+ * Slots:
11
+ * - main: Primary content area
12
+ * - sidebar: Left/right sidebar
13
+ * - modal: Modal overlay
14
+ * - drawer: Slide-in drawer
15
+ * - overlay: Full-screen overlay
16
+ * - center: Centered popup
17
+ * - toast: Toast notifications
18
+ * - hud-top: Game HUD top bar
19
+ * - hud-bottom: Game HUD bottom bar
20
+ * - floating: Draggable floating panel
21
+ *
22
+ * Multi-source model (2026-04-24):
23
+ * A slot can receive renders from multiple source traits across independent
24
+ * batches (e.g. in the playground, ProbeCreate renders "main" on INIT, then
25
+ * later ProbePersistor cascades a render into "main" too). Prior code stored
26
+ * a single SlotContent per slot and last-writer-wins silently dropped
27
+ * earlier traits' frames. Internally the manager now holds a
28
+ * `Record<UISlot, Record<sourceKey, SlotContent>>` map and consumers see an
29
+ * aggregated view: a single SlotContent for single-source slots, or a
30
+ * synthetic `stack` wrapper when 2+ sources are active simultaneously.
31
+ * This mirrors the compiled-path page layout's VStack-of-trait-views.
32
+ *
33
+ * @packageDocumentation
34
+ */
35
+
36
+ /**
37
+ * Render-prop callback after fn-form-lambda conversion or
38
+ * `wrapCallbackForEvent` wrapping. Pattern components consume these as
39
+ * `renderItem` / `onTabChange` / `onClick` / etc. The arg list is
40
+ * contravariant (`never[]` accepts any caller shape — event handlers,
41
+ * 2-arg `(item, index)` render-props, etc.); the return is the union of
42
+ * shapes seen at this layer. Pattern-level prop types narrow the
43
+ * signature for each consumer downstream.
44
+ */
45
+ type SlotCallback = (...args: never[]) => void | React__default.ReactNode | EventPayloadValue;
46
+ /**
47
+ * Render-ui prop value: any leaf flowing from a `(render-ui slot {...})`
48
+ * effect into a React pattern component. The union enumerates every
49
+ * shape the renderer can receive — no `unknown` escape hatch.
50
+ *
51
+ * - JSON primitives (`string`, `number`, `boolean`, `Date`, `null`,
52
+ * `undefined`) come through `BindingResolver`.
53
+ * - `RenderItemLambda` is the unconverted tuple form `["fn", arg, body]`;
54
+ * `SlotCallback` is the post-conversion callable form.
55
+ * - `React.ReactNode` covers substituted `<TraitFrame>` elements.
56
+ * - The recursive array + object branches mirror the `EventPayloadValue`
57
+ * shape but with `SlotPropValue` leaves so functions and React nodes
58
+ * can appear at any depth (e.g. `tabs[].content: "@trait.X"` surviving
59
+ * substitution into a `ReactElement`).
60
+ */
61
+ type SlotPropValue = string | number | boolean | Date | null | undefined | RenderItemLambda | SlotCallback | React__default.ReactElement | RowSetMarker | ReadonlyArray<SlotPropValue> | {
62
+ readonly [key: string]: SlotPropValue;
63
+ };
64
+ /**
65
+ * Pattern-specific props carried by a rendered slot. The slot manager
66
+ * routes these from `(render-ui slot {...})` effects to React pattern
67
+ * components without coercion.
68
+ */
69
+ type SlotProps = Record<string, SlotPropValue>;
70
+ /**
71
+ * Content rendered in a slot
72
+ */
73
+ interface SlotContent {
74
+ /** Unique ID for this content */
75
+ id: string;
76
+ /** Pattern/component type to render */
77
+ pattern: string;
78
+ /** Props to pass to the pattern component. A bare string is a whole-slot
79
+ * trait-embed reference (`(render-ui main "@trait.X")`) — the renderer lifts
80
+ * it to a TraitFrame. */
81
+ props: SlotProps | string;
82
+ /** Priority for conflict resolution (higher wins) */
83
+ priority: number;
84
+ /** Auto-dismiss timestamp (for toasts) */
85
+ autoDismissAt?: number;
86
+ /** Callback when dismissed */
87
+ onDismiss?: () => void;
88
+ /** Source trait that rendered this content */
89
+ sourceTrait?: string;
90
+ /** Stable node ID from the schema pattern tree (for edit mode overlay targeting) */
91
+ nodeId?: string;
92
+ /** Slot this content was rendered into (= SlotRenderConfig.target) — contextual-edit address. */
93
+ slot?: string;
94
+ /** Transition event key that produced this render (raw, as fired). */
95
+ transitionEvent?: string;
96
+ /** State the trait was in when this render fired (the from-state). */
97
+ fromState?: string;
98
+ /** linkedEntity of the source trait — contextual-edit address. */
99
+ entity?: string;
100
+ }
101
+ /**
102
+ * Configuration for render_ui effect
103
+ */
104
+ interface SlotRenderConfig {
105
+ /** Target slot */
106
+ target: UISlot;
107
+ /** Pattern/component to render */
108
+ pattern: string;
109
+ /** Props for the pattern — or a bare `@trait.X` embed string */
110
+ props?: SlotProps | string;
111
+ /** Priority (default: 0) */
112
+ priority?: number;
113
+ /** Auto-dismiss after ms (for toasts) */
114
+ autoDismissMs?: number;
115
+ /** Callback on dismiss */
116
+ onDismiss?: () => void;
117
+ /** Source trait name */
118
+ sourceTrait?: string;
119
+ /** Transition event key that produced this render (raw, as fired). */
120
+ transitionEvent?: string;
121
+ /** State the trait was in when this render fired (the from-state). */
122
+ fromState?: string;
123
+ /** linkedEntity of the source trait. */
124
+ entity?: string;
125
+ }
126
+ /**
127
+ * Callback for slot changes
128
+ */
129
+ type SlotChangeCallback = (slot: UISlot, content: SlotContent | null) => void;
130
+ /**
131
+ * Fires when a specific trait's current render-ui output changes.
132
+ * Used by `<TraitFrame>` to subscribe only to the trait it embeds,
133
+ * avoiding wide re-renders when unrelated slots update.
134
+ *
135
+ * Per-trait index stores exactly one entry per trait (the most recent
136
+ * render), so the callback signature carries just the new content —
137
+ * no per-slot disambiguation needed.
138
+ */
139
+ type TraitChangeCallback = (content: SlotContent | null) => void;
140
+ /**
141
+ * UI Slot Manager interface
142
+ */
143
+ interface UISlotManager {
144
+ /**
145
+ * Current aggregate content for each slot. Single-source slots hold
146
+ * that source's SlotContent; multi-source slots hold a synthetic
147
+ * `stack` wrapper whose `children` prop is the list of per-source
148
+ * pattern configs in insertion order. Single consumers can continue
149
+ * to read `slots[slot]` without knowing the slot is multi-source.
150
+ */
151
+ slots: Partial<Record<UISlot, SlotContent | null>>;
152
+ /** Render content to a slot */
153
+ render: (config: SlotRenderConfig) => string;
154
+ /** Clear all source entries from a slot */
155
+ clear: (slot: UISlot) => void;
156
+ /** Clear a single source's contribution from a slot, keeping others */
157
+ clearBySource: (slot: UISlot, sourceTrait: string) => void;
158
+ /** Clear content by ID */
159
+ clearById: (id: string) => void;
160
+ /** Clear all slots */
161
+ clearAll: () => void;
162
+ /** Subscribe to slot changes */
163
+ subscribe: (callback: SlotChangeCallback) => () => void;
164
+ /** Check if a slot has content */
165
+ hasContent: (slot: UISlot) => boolean;
166
+ /** Get aggregated content for a slot (single or synthetic stack) */
167
+ getContent: (slot: UISlot) => SlotContent | null;
168
+ /**
169
+ * Look up the most recent `render-ui` output a given trait produced,
170
+ * keyed by `SlotContent.sourceTrait`. Returns `null` when the trait
171
+ * hasn't rendered yet.
172
+ *
173
+ * Backs the `@trait.X` binding's client-side resolution via
174
+ * `<TraitFrame>`. See `docs/Almadar_Std_Gaps.md` §3.8. The binding is
175
+ * single-segment — there's intentionally no slot disambiguation.
176
+ */
177
+ getTraitContent: (traitName: string) => SlotContent | null;
178
+ /**
179
+ * Subscribe to changes in a specific trait's render output. Returns
180
+ * an unsubscribe function.
181
+ *
182
+ * Scoped per-trait so `<TraitFrame>` components only re-render when
183
+ * the trait they embed actually changes — not on every slot update.
184
+ */
185
+ subscribeTrait: (traitName: string, callback: TraitChangeCallback) => () => void;
186
+ /**
187
+ * Update only the per-trait sidecar without writing to any slot.
188
+ *
189
+ * Used for embed-aware slot routing: when a trait is referenced via
190
+ * `@trait.X` by a sibling layout's render-ui, its render output should
191
+ * not stack into the same slot the layout writes — the layout owns the
192
+ * slot and embeds the trait's frame via `<TraitFrame>`. This method
193
+ * keeps the per-trait sidecar (`traitIndexRef`) up-to-date so
194
+ * `<TraitFrame>` re-renders, while leaving `slots[target]` untouched.
195
+ *
196
+ * Mirrors what the compiled-path codegen does structurally — atoms
197
+ * inlined as JSX inside the layout's pattern, not writing slots.
198
+ */
199
+ updateTraitContent: (traitName: string, content: Omit<SlotContent, 'id' | 'sourceTrait'>) => string;
200
+ }
201
+ declare const DEFAULT_SLOTS: Partial<Record<UISlot, SlotContent | null>>;
202
+ /**
203
+ * Create a UI Slot Manager instance.
204
+ *
205
+ * This is the internal hook that creates the manager.
206
+ * Use `useUISlots()` from context in components.
207
+ */
208
+ declare function useUISlotManager(): UISlotManager;
209
+
210
+ export { DEFAULT_SLOTS as D, useUISlotManager as u };
211
+ export type { SlotChangeCallback as S, UISlotManager as U, SlotContent as a, SlotRenderConfig as b, SlotPropValue as c };
@@ -0,0 +1,66 @@
1
+ import { OrbitalVerificationAPI, EventPayload, BusEvent } from '@almadar/core';
2
+
3
+ /**
4
+ * Renderer-agnostic `window.__orbitalVerification` bridge.
5
+ *
6
+ * The single observation point Playwright-based verifiers
7
+ * (`runtime-verify`, `orbital-verify`, `@almadar-io/verify`) use to read
8
+ * state out of a live app and drive events into it. The wire types live
9
+ * in `@almadar/core` (see `types/verification.ts`); this module owns only
10
+ * the minimal exposure plumbing so any UI library — React, Web
11
+ * Components, or a future renderer — can populate the same contract
12
+ * without duplicating it.
13
+ *
14
+ * Framework-specific state (transition traces, reducer snapshots, bridge
15
+ * health) is left empty by default; a renderer that tracks them can
16
+ * override the readers after {@link ensureVerificationApi} runs. The two
17
+ * bindings every renderer must provide are {@link bindEventBus} (so
18
+ * automation can `sendEvent`) and {@link bindTraitStateGetter} (so
19
+ * automation can `getTraitState`).
20
+ *
21
+ * @packageDocumentation
22
+ */
23
+
24
+ declare global {
25
+ interface Window {
26
+ __orbitalVerification?: OrbitalVerificationAPI;
27
+ }
28
+ }
29
+ /**
30
+ * Minimal structural surface a renderer's event bus must satisfy to be
31
+ * driven by automation. Matches the runtime `EventBus` (`emit` +
32
+ * optional `onAny`) without forcing a concrete class, so any UI
33
+ * library's bus — including `@almadar/runtime`'s own — plugs in.
34
+ */
35
+ interface VerificationBus {
36
+ emit: (type: string, payload?: EventPayload) => void;
37
+ onAny?: (listener: (event: BusEvent) => void) => () => void;
38
+ }
39
+ /**
40
+ * Ensure `window.__orbitalVerification` exists with the required
41
+ * readers, then return it. Returns `undefined` outside a DOM (SSR /
42
+ * tests without a window). Idempotent: an existing object is returned
43
+ * untouched so a renderer that already registered readers keeps them.
44
+ */
45
+ declare function ensureVerificationApi(): OrbitalVerificationAPI | undefined;
46
+ /** Read the current bridge, if any. SSR-safe. */
47
+ declare function getOrbitalVerification(): OrbitalVerificationAPI | undefined;
48
+ /**
49
+ * Bind the renderer's event bus so automation can send events and read
50
+ * a rolling emission log.
51
+ *
52
+ * `sendEvent(event, payload, traitScope)` mirrors the React bridge:
53
+ * when `traitScope` is provided the event is emitted on the qualified
54
+ * key `UI:${traitScope}.${event}` (matching codegen-emitted
55
+ * subscription keys); otherwise the legacy bare form `UI:${event}` is
56
+ * used. An already-`UI:`-prefixed event is emitted verbatim.
57
+ */
58
+ declare function bindEventBus(eventBus: VerificationBus): void;
59
+ /**
60
+ * Bind a trait-state getter so automation can query a trait's current
61
+ * state machine state by name.
62
+ */
63
+ declare function bindTraitStateGetter(getter: (traitName: string) => string | undefined): void;
64
+
65
+ export { bindTraitStateGetter as a, bindEventBus as b, ensureVerificationApi as e, getOrbitalVerification as g };
66
+ export type { VerificationBus as V };
@@ -0,0 +1,122 @@
1
+ import { D as DrawableNode } from './paintDispatch-CuJLsr9Y.js';
2
+ import { OrbitalVerificationAPI, TraitStateSnapshot, EventPayload, BusEvent, VerificationCheck, BridgeHealth, VerificationSnapshot, VerificationSummary, TransitionTrace, EventRequest, EventResponse, ServerResponseTrace, EffectTrace, CheckStatus, ServerEffectResult, AssetLoadStatus } from '@almadar/core';
3
+ import { EventTransport } from '@almadar/shell-runtime/client/EventTransport';
4
+ import './verification-C5pTeMJv.js';
5
+
6
+ /**
7
+ * Verification Registry - Tracks runtime verification checks and transition traces
8
+ *
9
+ * Provides:
10
+ * 1. A checklist of pass/fail checks (INIT has fetch, bridge connected, etc.)
11
+ * 2. A full transition timeline with effect execution results
12
+ * 3. ServerBridge health snapshot
13
+ * 4. window.__orbitalVerification for Playwright/automation
14
+ *
15
+ * @packageDocumentation
16
+ */
17
+
18
+ type ChangeListener = () => void;
19
+ /**
20
+ * Per-trait snapshot getter. Each generated trait logic hook (or
21
+ * `useTraitStateMachine` trait binding) registers one on mount so the
22
+ * verifier can read the live reducer state for that trait.
23
+ */
24
+ type TraitSnapshotGetter = () => TraitStateSnapshot;
25
+ declare function registerCheck(id: string, label: string, status?: CheckStatus, details?: string): void;
26
+ declare function updateCheck(id: string, status: CheckStatus, details?: string): void;
27
+ declare function getAllChecks(): VerificationCheck[];
28
+ declare function recordTransition(trace: Omit<TransitionTrace, "id">): void;
29
+ declare function getTransitions(): TransitionTrace[];
30
+ declare function getTransitionsForTrait(traitName: string): TransitionTrace[];
31
+ /**
32
+ * Record a server response as a timeline entry.
33
+ * Creates a synthetic transition entry with type "server-response" to show
34
+ * what the server returned (clientEffects, data counts, emitted events).
35
+ *
36
+ * `effectResults` — the server's persist/set/call-service outcomes, already
37
+ * mapped to `EffectTrace` by the caller — populate `entry.effects` so a
38
+ * denied or failed persist is visible on this synthetic entry too. Before
39
+ * this it was always `[]`: the ONLY entry the driver's per-event
40
+ * `server:<orbital>` lookup (`default-snapshot.ts`'s `lastEffectResultsFor`)
41
+ * can find carried nothing.
42
+ */
43
+ declare function recordServerResponse(orbitalName: string, event: string, response: Omit<ServerResponseTrace, "orbitalName" | "timestamp"> & {
44
+ effectResults?: EffectTrace[];
45
+ }): void;
46
+ /** A server response's `effectResults` as timeline traces, carrying each persist's real outcome (entity, action, resulting id, denied). */
47
+ declare function serverEffectTraces(results: readonly ServerEffectResult[] | undefined): EffectTrace[];
48
+ /** Record one answered server leg on the timeline as a `server:<orbital>` trace. */
49
+ declare function recordOrbitalResponse(orbitalName: string, request: EventRequest, response: EventResponse): void;
50
+ /** `transport` with every answered post recorded on the verification timeline; the one place the circuit client's server responses are captured. */
51
+ declare function recordingTransport(transport: EventTransport): EventTransport;
52
+ declare function updateBridgeHealth(health: BridgeHealth): void;
53
+ declare function getBridgeHealth(): BridgeHealth | null;
54
+ declare function getSummary(): VerificationSummary;
55
+ declare function getSnapshot(): VerificationSnapshot;
56
+ /**
57
+ * Per-trait snapshot for the verifier.
58
+ *
59
+ * Iterates every registered trait getter and collects the live reducer
60
+ * state. Empty until at least one trait hook calls `registerTraitSnapshot`.
61
+ * A getter that throws is logged and skipped — one broken trait must not
62
+ * poison the rest of the snapshot.
63
+ */
64
+ declare function getTraitSnapshots(): TraitStateSnapshot[];
65
+ declare function subscribeToVerification(listener: ChangeListener): () => void;
66
+ declare global {
67
+ interface Window {
68
+ __orbitalVerification?: OrbitalVerificationAPI;
69
+ }
70
+ }
71
+ /** Whether a verifier is driving this page: the `__ALMADAR_VERIFY__` window flag it sets before the bundle runs. */
72
+ declare function verifierAttached(): boolean;
73
+ /**
74
+ * Wait for a transition matching the given event to appear.
75
+ * Returns the trace or null on timeout.
76
+ */
77
+ declare function waitForTransition(event: string, timeoutMs?: number): Promise<TransitionTrace | null>;
78
+ /**
79
+ * Bind the EventBus so automation can send events and log emissions.
80
+ * Call this during app initialization.
81
+ */
82
+ declare function bindEventBus(eventBus: {
83
+ emit: (type: string, payload?: EventPayload) => void;
84
+ onAny?: (listener: (event: BusEvent) => void) => () => void;
85
+ }): void;
86
+ declare function bindConfigApplier(applyConfig: NonNullable<OrbitalVerificationAPI['applyConfig']>): () => void;
87
+ /**
88
+ * Bind a trait state getter so automation can query current states.
89
+ */
90
+ declare function bindTraitStateGetter(getter: (traitName: string) => string | undefined): void;
91
+ /**
92
+ * Register a per-trait snapshot provider. The generated trait logic hook
93
+ * (or `useTraitStateMachine`) calls this once on mount, passing a getter
94
+ * that reads the current reducer state via a ref. Returns an unregister
95
+ * function for cleanup on unmount.
96
+ *
97
+ * Calling this twice for the same `traitName` replaces the previous
98
+ * getter (e.g. page navigation remounts the trait; the new registration
99
+ * wins).
100
+ */
101
+ declare function registerTraitSnapshot(traitName: string, getter: TraitSnapshotGetter): () => void;
102
+ /**
103
+ * Register a canvas frame capture function.
104
+ * Called by game organisms (IsometricCanvas, PlatformerCanvas)
105
+ * so the verifier can snapshot canvas content at checkpoints.
106
+ */
107
+ declare function bindCanvasCapture(captureFn: () => string | null): void;
108
+ /**
109
+ * Bind a reader for the last drawables list received by a canvas host.
110
+ * Lets verification scripts inspect exactly which neutral descriptors reached
111
+ * the painter without re-deriving them from state.
112
+ */
113
+ declare function bindLastDrawables(getDrawables: () => DrawableNode[] | null): void;
114
+ /**
115
+ * Update asset load status for canvas verification.
116
+ * Game organisms call this when images load or fail.
117
+ */
118
+ declare function updateAssetStatus(url: string, status: AssetLoadStatus): void;
119
+ declare function clearVerification(): void;
120
+
121
+ export { bindConfigApplier as a, bindCanvasCapture as b, bindEventBus as c, bindLastDrawables as d, bindTraitStateGetter as e, clearVerification as f, getAllChecks as g, getBridgeHealth as h, getSnapshot as i, getSummary as j, getTraitSnapshots as k, getTransitions as l, getTransitionsForTrait as m, recordServerResponse as n, recordTransition as o, recordingTransport as p, registerCheck as q, recordOrbitalResponse as r, registerTraitSnapshot as s, serverEffectTraces as t, subscribeToVerification as u, updateAssetStatus as v, updateBridgeHealth as w, updateCheck as x, verifierAttached as y, waitForTransition as z };
122
+ export type { TraitSnapshotGetter as T };
@@ -0,0 +1,19 @@
1
+ import { PatternCallbackArg } from '@almadar/core/patterns';
2
+ import { EventPayload, EventPayloadValue } from '@almadar/core';
3
+
4
+ /**
5
+ * Build the runtime wrapper that turns a string-typed callback prop
6
+ * (e.g. `onTabChange: "TAB_CHANGED"`) into a function the component can
7
+ * invoke. The wrapper consumes the component's positional callback args
8
+ * by name and dispatches an OBJECT payload `{ argName: value, ... }` so
9
+ * the bus carries the trait's declared event payload, not a raw
10
+ * positional spread. Mirrors the codegen wrapper in
11
+ * `orbital-shell-typescript/src/codegen/pattern.rs` (C2 compiled path).
12
+ *
13
+ * Single-sourcing this logic across runtime and codegen (shared shape,
14
+ * not shared code — codegen emits string source) is what keeps the two
15
+ * paths from silently diverging on payload shape.
16
+ */
17
+ declare function wrapCallbackForEvent(qualifiedEvent: string, callbackArgs: PatternCallbackArg[] | undefined, emit: (eventKey: string, payload?: EventPayload) => void): (...args: EventPayloadValue[]) => void;
18
+
19
+ export { wrapCallbackForEvent as w };
package/index.css ADDED
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Design System Styles
3
+ */
4
+
5
+ /* Load Plus Jakarta Sans from Google Fonts (Track A: preferred UI font) */
6
+ @import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700&display=swap');
7
+
8
+ /* React Flow's base styles (the canvas's node layering); ui's overrides below load after them. */
9
+ @import '@xyflow/react/dist/style.css';
10
+
11
+ @tailwind base;
12
+ @tailwind components;
13
+ @tailwind utilities;
14
+
15
+ /**
16
+ * Default fallback theme (minimalist-light — UI/UX improved per Track A eval)
17
+ * Applied when no data-theme attribute is set.
18
+ */
19
+ :root:not([data-theme]) {
20
+ --shadow-main: 0 1px 3px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.06);
21
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04);
22
+ --shadow-lg: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
23
+ --shadow-inner: inset 0 1px 2px rgba(0, 0, 0, 0.05);
24
+ --shadow-none: none;
25
+ /* Track A: more pronounced hover lift for interactive cards */
26
+ --shadow-hover: 0 8px 30px -8px rgba(0, 0, 0, 0.18), 0 2px 6px rgba(0, 0, 0, 0.08);
27
+ --shadow-active: 0 1px 2px rgba(0, 0, 0, 0.05);
28
+
29
+ --radius-none: 0px;
30
+ --radius-sm: 6px;
31
+ /* Track A: bump radii from 8/12 → 10/14 for a more modern feel */
32
+ --radius-md: 10px;
33
+ --radius-lg: 14px;
34
+ --radius-xl: 18px;
35
+ --radius-full: 9999px;
36
+
37
+ --border-width: 1px;
38
+ --border-width-thin: 1px;
39
+ --border-width-thick: 2px;
40
+
41
+ --color-primary: #18181b;
42
+ --color-primary-hover: #27272a;
43
+ --color-primary-foreground: #fafafa;
44
+ --color-secondary: #fafafa;
45
+ --color-secondary-hover: #f4f4f5;
46
+ --color-secondary-foreground: #18181b;
47
+ --color-accent: #18181b;
48
+ --color-accent-foreground: #fafafa;
49
+ --color-muted: #f1f5f9;
50
+ /* Track A: slightly darker muted-foreground for legibility */
51
+ --color-muted-foreground: #64748b;
52
+ /* Track A: background ≠ card → natural surface elevation */
53
+ --color-background: #f8fafc;
54
+ --color-foreground: #0f172a;
55
+ --color-card: #ffffff;
56
+ --color-card-foreground: #0f172a;
57
+ --color-surface: #f1f5f9;
58
+ /* Track A: soften border — semi-transparent instead of solid gray */
59
+ --color-border: rgba(0, 0, 0, 0.08);
60
+ --color-input: #e2e8f0;
61
+ --color-ring: #18181b;
62
+
63
+ --color-error: #dc2626;
64
+ --color-error-foreground: #ffffff;
65
+ --color-success: #16a34a;
66
+ --color-success-foreground: #ffffff;
67
+ --color-warning: #ca8a04;
68
+ --color-warning-foreground: #000000;
69
+ --color-info: #2563eb;
70
+ --color-info-foreground: #ffffff;
71
+
72
+ /* Track A: Plus Jakarta Sans as first preference, Inter as fallback */
73
+ --font-family:
74
+ "Plus Jakarta Sans", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
75
+ --font-weight-normal: 400;
76
+ --font-weight-medium: 500;
77
+ --font-weight-bold: 600;
78
+ --letter-spacing: -0.015em;
79
+ --line-height: 1.6;
80
+
81
+ --icon-stroke-width: 1.5;
82
+ --icon-color: currentColor;
83
+
84
+ --transition-fast: 150ms;
85
+ --transition-normal: 250ms;
86
+ --transition-slow: 400ms;
87
+ --transition-timing: cubic-bezier(0.4, 0, 0.2, 1);
88
+
89
+ --hover-scale: 1.01;
90
+ --hover-translate-y: -2px;
91
+ --hover-translate-x: 0;
92
+ --active-scale: 0.99;
93
+ --active-translate-y: 0;
94
+
95
+ --focus-ring-width: 2px;
96
+ --focus-ring-offset: 2px;
97
+ --focus-ring-color: #18181b;
98
+ }
99
+
100
+ html {
101
+ font-family: var(--font-family);
102
+ line-height: var(--line-height);
103
+ letter-spacing: var(--letter-spacing);
104
+ font-weight: var(--font-weight-normal);
105
+ color-scheme: light dark;
106
+ font-synthesis: none;
107
+ text-rendering: optimizeLegibility;
108
+ -webkit-font-smoothing: antialiased;
109
+ -moz-osx-font-smoothing: grayscale;
110
+ }
111
+
112
+ body {
113
+ margin: 0;
114
+ min-height: 100vh;
115
+ background-color: var(--color-background);
116
+ color: var(--color-foreground);
117
+ }
118
+
119
+ #root {
120
+ min-height: 100vh;
121
+ }
122
+
123
+ ::-webkit-scrollbar {
124
+ width: 8px;
125
+ height: 8px;
126
+ }
127
+
128
+ ::-webkit-scrollbar-track {
129
+ background: var(--color-muted);
130
+ }
131
+
132
+ ::-webkit-scrollbar-thumb {
133
+ background: var(--color-muted-foreground);
134
+ border-radius: var(--radius-sm);
135
+ }
136
+
137
+ ::-webkit-scrollbar-thumb:hover {
138
+ background: var(--color-foreground);
139
+ }
140
+
141
+ /**
142
+ * ReactFlow (@xyflow/react) Controls — theme overrides for FlowCanvas zoom buttons
143
+ *
144
+ * Without these, the bottom-left zoom in/out/fit buttons render as plain white
145
+ * squares from ReactFlow's default stylesheet, ignoring the active theme.
146
+ * Targets: .react-flow__controls + .react-flow__controls-button
147
+ */
148
+ .react-flow__controls {
149
+ background: var(--color-card) !important;
150
+ border: 1px solid var(--color-border) !important;
151
+ border-radius: var(--radius-md) !important;
152
+ box-shadow: var(--shadow-main) !important;
153
+ overflow: hidden;
154
+ }
155
+
156
+ .react-flow__controls-button {
157
+ background: transparent !important;
158
+ border: none !important;
159
+ border-bottom: 1px solid var(--color-border) !important;
160
+ color: var(--color-foreground) !important;
161
+ fill: var(--color-foreground) !important;
162
+ width: 28px;
163
+ height: 28px;
164
+ transition: background var(--transition-fast) var(--transition-timing);
165
+ }
166
+
167
+ .react-flow__controls-button:last-child {
168
+ border-bottom: none !important;
169
+ }
170
+
171
+ .react-flow__controls-button:hover {
172
+ background: var(--color-muted) !important;
173
+ }
174
+
175
+ .react-flow__controls-button svg {
176
+ fill: var(--color-foreground) !important;
177
+ width: 14px;
178
+ height: 14px;
179
+ }
180
+
181
+ @layer utilities {
182
+ .shadow-theme { box-shadow: var(--shadow-main); }
183
+ .shadow-theme-sm { box-shadow: var(--shadow-sm); }
184
+ .shadow-theme-lg { box-shadow: var(--shadow-lg); }
185
+ .rounded-theme { border-radius: var(--radius-md); }
186
+ .rounded-theme-sm { border-radius: var(--radius-sm); }
187
+ .rounded-theme-lg { border-radius: var(--radius-lg); }
188
+ .border-theme { border-width: var(--border-width); border-color: var(--color-border); }
189
+ .bg-theme-primary { background-color: var(--color-primary); }
190
+ .bg-theme-secondary { background-color: var(--color-secondary); }
191
+ .bg-theme-background { background-color: var(--color-background); }
192
+ .bg-theme-card { background-color: var(--color-card); }
193
+ .text-theme-foreground { color: var(--color-foreground); }
194
+ .text-theme-muted { color: var(--color-muted-foreground); }
195
+ .text-theme-primary { color: var(--color-primary); }
196
+ .font-theme-normal { font-weight: var(--font-weight-normal); }
197
+ .font-theme-medium { font-weight: var(--font-weight-medium); }
198
+ .font-theme-bold { font-weight: var(--font-weight-bold); }
199
+ }