@yourrealm/sdk 0.0.0-alpha.1378.ce03c8dc

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 (230) hide show
  1. package/LICENSE-EXCEPTION +26 -0
  2. package/README.md +34 -0
  3. package/dist/chunk-3R6KEFOI.js +22 -0
  4. package/dist/chunk-67BDAMYX.js +376 -0
  5. package/dist/chunk-AITGS27R.js +139 -0
  6. package/dist/chunk-CMAEHQ4F.js +6 -0
  7. package/dist/chunk-MLKGABMK.js +9 -0
  8. package/dist/chunk-O3UIK34B.js +1430 -0
  9. package/dist/chunk-VHTUSZUX.js +176 -0
  10. package/dist/cli.js +9006 -0
  11. package/dist/docker.js +54 -0
  12. package/dist/index.js +1053 -0
  13. package/dist/ingress.js +436 -0
  14. package/dist/jsx-runtime.js +2 -0
  15. package/dist/preact.js +22 -0
  16. package/dist/service-url.js +11 -0
  17. package/dist/services.js +213 -0
  18. package/dist/test.js +5069 -0
  19. package/dist/ui.js +254 -0
  20. package/dist/worker-protocol.js +89 -0
  21. package/package.json +112 -0
  22. package/src/app-icon.ts +74 -0
  23. package/src/apply.ts +52 -0
  24. package/src/bundle-ui.ts +211 -0
  25. package/src/bundle.ts +546 -0
  26. package/src/cli/build-dev-landing.ts +84 -0
  27. package/src/cli/build-install-panel.ts +90 -0
  28. package/src/cli/build-runtime.ts +133 -0
  29. package/src/cli/build.ts +63 -0
  30. package/src/cli/dev.ts +107 -0
  31. package/src/cli/down.ts +60 -0
  32. package/src/cli/main.ts +56 -0
  33. package/src/cli/test.ts +61 -0
  34. package/src/cli/validate.ts +37 -0
  35. package/src/compile.ts +100 -0
  36. package/src/create-app.ts +982 -0
  37. package/src/deep-merge.ts +33 -0
  38. package/src/dev/fixture.ts +48 -0
  39. package/src/dev/install-handler.ts +383 -0
  40. package/src/dev/server.ts +968 -0
  41. package/src/dev/stack.ts +108 -0
  42. package/src/dev/state.ts +159 -0
  43. package/src/docker.ts +96 -0
  44. package/src/errors.ts +61 -0
  45. package/src/factory.ts +481 -0
  46. package/src/garage.ts +56 -0
  47. package/src/generator/hash.ts +6 -0
  48. package/src/generator/resolve-refs.ts +207 -0
  49. package/src/grants-builder.ts +100 -0
  50. package/src/grants.ts +260 -0
  51. package/src/home-api.ts +172 -0
  52. package/src/home-cookie.ts +10 -0
  53. package/src/home-registry.ts +120 -0
  54. package/src/home.ts +187 -0
  55. package/src/host-registry.ts +143 -0
  56. package/src/http-header.ts +20 -0
  57. package/src/identifiers.ts +49 -0
  58. package/src/index.ts +66 -0
  59. package/src/info.ts +64 -0
  60. package/src/ini.ts +50 -0
  61. package/src/json.ts +14 -0
  62. package/src/jsx-runtime/index.ts +5 -0
  63. package/src/keys.ts +29 -0
  64. package/src/mysql.ts +56 -0
  65. package/src/pack-build.ts +108 -0
  66. package/src/pack.ts +115 -0
  67. package/src/peer-registry.ts +121 -0
  68. package/src/peer-world.ts +117 -0
  69. package/src/permission-meta.ts +116 -0
  70. package/src/permissions.ts +108 -0
  71. package/src/pkg-root.ts +34 -0
  72. package/src/postgres.ts +79 -0
  73. package/src/preact/index.ts +27 -0
  74. package/src/redis.ts +43 -0
  75. package/src/ref.ts +271 -0
  76. package/src/remote-registry.ts +33 -0
  77. package/src/required-host-kinds.ts +110 -0
  78. package/src/resolve-context.ts +111 -0
  79. package/src/resolve.ts +471 -0
  80. package/src/runtime/docker/compose/compose-schema.ts +118 -0
  81. package/src/runtime/docker/compose/convert-to-docker-compose.ts +278 -0
  82. package/src/runtime/docker/compose/default-hardening.ts +21 -0
  83. package/src/runtime/docker/compose/effects.ts +107 -0
  84. package/src/runtime/docker/compose/index.ts +17 -0
  85. package/src/runtime/docker/compose/labels.ts +39 -0
  86. package/src/runtime/docker/compose/types.ts +78 -0
  87. package/src/runtime/docker/home-proxy-server/index.ts +177 -0
  88. package/src/runtime/docker/home-proxy-server/protocol.ts +53 -0
  89. package/src/runtime/docker/ingress/build-config.ts +819 -0
  90. package/src/runtime/docker/ingress/index.ts +16 -0
  91. package/src/runtime/docker/ingress/types.ts +182 -0
  92. package/src/runtime/docker/log-frames.ts +121 -0
  93. package/src/runtime/docker/logs-server/index.ts +366 -0
  94. package/src/runtime/docker/spawn-server/context-key.ts +82 -0
  95. package/src/runtime/docker/spawn-server/index.ts +492 -0
  96. package/src/runtime/docker/spawn-server/protocol.ts +70 -0
  97. package/src/runtime/docker/spawn-server/spec.ts +122 -0
  98. package/src/runtime/docker/stats-server/disks.ts +161 -0
  99. package/src/runtime/docker/stats-server/index.ts +322 -0
  100. package/src/runtime/home-client/index.ts +71 -0
  101. package/src/runtime/log-line.ts +24 -0
  102. package/src/runtime/logs-client/index.ts +175 -0
  103. package/src/runtime/spawn-client/index.ts +93 -0
  104. package/src/runtime/spawn-client/kaniko.ts +79 -0
  105. package/src/runtime/stats-client/index.ts +65 -0
  106. package/src/runtime/stats-sample.ts +95 -0
  107. package/src/safe-json.ts +37 -0
  108. package/src/sandbox.ts +1209 -0
  109. package/src/schema/build-apps.ts +38 -0
  110. package/src/schema/home.ts +217 -0
  111. package/src/schema/host.ts +792 -0
  112. package/src/schema/inputs.ts +26 -0
  113. package/src/schema/nodes.ts +75 -0
  114. package/src/schema/peer.ts +400 -0
  115. package/src/schema/public-domain.ts +116 -0
  116. package/src/schema/remote.ts +74 -0
  117. package/src/security.ts +594 -0
  118. package/src/serialize.ts +21 -0
  119. package/src/service-definition.ts +284 -0
  120. package/src/service-url.ts +64 -0
  121. package/src/service.ts +39 -0
  122. package/src/services/index.ts +5 -0
  123. package/src/shared.ts +65 -0
  124. package/src/speculative-silo.ts +96 -0
  125. package/src/stable-secret.ts +14 -0
  126. package/src/surfaces.ts +264 -0
  127. package/src/tailwind-bin.ts +56 -0
  128. package/src/test/boot.ts +192 -0
  129. package/src/test/compile.ts +501 -0
  130. package/src/test/describe.ts +117 -0
  131. package/src/test/index.ts +11 -0
  132. package/src/test/ingress-fixture.ts +37 -0
  133. package/src/test/types.ts +318 -0
  134. package/src/trusted-headers.ts +79 -0
  135. package/src/types.ts +126 -0
  136. package/src/ui/components/aside.tsx +96 -0
  137. package/src/ui/components/badge.tsx +42 -0
  138. package/src/ui/components/button.tsx +59 -0
  139. package/src/ui/components/card.tsx +106 -0
  140. package/src/ui/components/checkbox.tsx +37 -0
  141. package/src/ui/components/code-block.tsx +29 -0
  142. package/src/ui/components/combobox.tsx +119 -0
  143. package/src/ui/components/config-field.tsx +284 -0
  144. package/src/ui/components/dialog.tsx +137 -0
  145. package/src/ui/components/domain-editor.tsx +317 -0
  146. package/src/ui/components/domain-list.ts +205 -0
  147. package/src/ui/components/dropdown-menu.tsx +73 -0
  148. package/src/ui/components/empty-state.tsx +51 -0
  149. package/src/ui/components/highlight.ts +59 -0
  150. package/src/ui/components/icons.tsx +101 -0
  151. package/src/ui/components/image-posture.tsx +85 -0
  152. package/src/ui/components/input.tsx +28 -0
  153. package/src/ui/components/label.tsx +16 -0
  154. package/src/ui/components/line-chart.tsx +113 -0
  155. package/src/ui/components/page.tsx +39 -0
  156. package/src/ui/components/permission-row.tsx +262 -0
  157. package/src/ui/components/permission-section.tsx +51 -0
  158. package/src/ui/components/pie-chart.tsx +245 -0
  159. package/src/ui/components/schema-block.tsx +60 -0
  160. package/src/ui/components/separator.tsx +42 -0
  161. package/src/ui/components/sheet.tsx +130 -0
  162. package/src/ui/components/sidebar.tsx +650 -0
  163. package/src/ui/components/silo-picker.tsx +510 -0
  164. package/src/ui/components/skeleton.tsx +13 -0
  165. package/src/ui/components/sonner.tsx +33 -0
  166. package/src/ui/components/switch.tsx +58 -0
  167. package/src/ui/components/table-view.ts +219 -0
  168. package/src/ui/components/table.tsx +506 -0
  169. package/src/ui/components/tabs.tsx +59 -0
  170. package/src/ui/components/timeago.tsx +84 -0
  171. package/src/ui/components/tooltip.tsx +56 -0
  172. package/src/ui/components.json +21 -0
  173. package/src/ui/dev/dev-shell.tsx +145 -0
  174. package/src/ui/home/home-grid.tsx +177 -0
  175. package/src/ui/hooks/use-mobile.ts +19 -0
  176. package/src/ui/index.ts +189 -0
  177. package/src/ui/install/adapter.ts +193 -0
  178. package/src/ui/install/deploy-targets-picker.tsx +185 -0
  179. package/src/ui/install/install-app-panel.tsx +912 -0
  180. package/src/ui/install/install-error.tsx +62 -0
  181. package/src/ui/install/perms-inactive.ts +50 -0
  182. package/src/ui/install/required-fields.ts +37 -0
  183. package/src/ui/install/tabs-form.tsx +557 -0
  184. package/src/ui/tokens.css +279 -0
  185. package/src/ui/utils.ts +78 -0
  186. package/src/ui-error.ts +139 -0
  187. package/src/ui-runtime/dev-landing-entry.tsx +258 -0
  188. package/src/ui-runtime/index.ts +83 -0
  189. package/src/ui-runtime/install-entry.tsx +119 -0
  190. package/src/ui-runtime/mount.ts +367 -0
  191. package/src/ui-runtime/runtime.css +56 -0
  192. package/src/ui-surface.ts +451 -0
  193. package/src/valkey.ts +43 -0
  194. package/src/worker/extract-tar.ts +125 -0
  195. package/src/worker/identity.ts +183 -0
  196. package/src/worker/index.ts +16 -0
  197. package/src/worker/public-ip.ts +92 -0
  198. package/src/worker/queue.ts +54 -0
  199. package/src/worker/reconcile.ts +127 -0
  200. package/src/worker/start-worker.ts +227 -0
  201. package/src/worker/ui-proxy.ts +335 -0
  202. package/src/worker/uplink.ts +523 -0
  203. package/src/worker/validate.ts +34 -0
  204. package/src/worker/verify-relay.ts +102 -0
  205. package/src/worker-protocol/app-dirs.ts +94 -0
  206. package/src/worker-protocol/home-proxy-paths.ts +76 -0
  207. package/src/worker-protocol/index.ts +55 -0
  208. package/src/worker-protocol/ingress.ts +166 -0
  209. package/src/worker-protocol/logs-socket-path.ts +50 -0
  210. package/src/worker-protocol/networks.ts +39 -0
  211. package/src/worker-protocol/node-version.ts +70 -0
  212. package/src/worker-protocol/silo-paths.ts +114 -0
  213. package/src/worker-protocol/spawn-paths.ts +165 -0
  214. package/src/worker-protocol/stats-socket-path.ts +40 -0
  215. package/src/worker-protocol/update-files.ts +77 -0
  216. package/src/worker-protocol/uplink/constants.ts +86 -0
  217. package/src/worker-protocol/uplink/errors.ts +61 -0
  218. package/src/worker-protocol/uplink/frame.ts +114 -0
  219. package/src/worker-protocol/uplink/identity.ts +40 -0
  220. package/src/worker-protocol/uplink/index.ts +63 -0
  221. package/src/worker-protocol/uplink/methods.ts +462 -0
  222. package/src/worker-protocol/uplink/mux.ts +646 -0
  223. package/src/worker-protocol/uplink/protocol.ts +11 -0
  224. package/src/worker-protocol/uplink/rpc.ts +309 -0
  225. package/src/worker-protocol/uplink/session.ts +540 -0
  226. package/src/worker-protocol/uplink/test-support.ts +188 -0
  227. package/src/worker-protocol/worker-mount.ts +27 -0
  228. package/src/worker-protocol/worker-state.ts +190 -0
  229. package/src/xml.ts +49 -0
  230. package/src/yaml.ts +15 -0
@@ -0,0 +1,279 @@
1
+ /*
2
+ * Realm UI tokens — claymorphism theme.
3
+ *
4
+ * Clay shadow technique based on https://github.com/codeAdrian/clay.css/
5
+ *
6
+ * Color palette:
7
+ * Background: #f0edff (lavender)
8
+ * Primary: #7c5cfc (purple)
9
+ * Dark: #2d2456 (headings, dark cards)
10
+ * Text: #534ab7 (body text on light)
11
+ * Muted: #9b8fd4 (labels, secondary text)
12
+ * Light muted: #b8aee0 (placeholders)
13
+ * Surface: #ffffff (cards)
14
+ * Surface tinted: #f8f6ff (slightly purple cards)
15
+ * Surface light: #f4f2ff (inputs, code backgrounds)
16
+ * Blue (trust): #185fa5 / #3b82f6 / #eef4ff
17
+ * Amber (perms): #a07830 / #fef8f0
18
+ * Red (danger): #dc2626 / #fef2f2
19
+ * Green (ok): #16a34a / #22c55e / #ecfdf5
20
+ */
21
+
22
+ @source ".";
23
+
24
+ @layer base {
25
+ *,
26
+ ::after,
27
+ ::before,
28
+ ::backdrop,
29
+ ::file-selector-button {
30
+ border-color: var(--color-border);
31
+ }
32
+
33
+ /* Soft dimensional wash behind the content area so raised clay
34
+ surfaces have something to lift off of. The sidebar-inset already
35
+ paints `bg-background`; this layers a faint corner glow on top. */
36
+ [data-slot="sidebar-inset"] {
37
+ background-image:
38
+ radial-gradient(1100px circle at 100% -10%, rgba(155, 125, 255, 0.18), transparent 45%),
39
+ radial-gradient(900px circle at -10% 110%, rgba(124, 92, 252, 0.12), transparent 50%);
40
+ }
41
+
42
+ .dark [data-slot="sidebar-inset"] {
43
+ background-image:
44
+ radial-gradient(1100px circle at 100% -10%, rgba(124, 92, 252, 0.22), transparent 45%),
45
+ radial-gradient(900px circle at -10% 110%, rgba(80, 50, 200, 0.18), transparent 50%);
46
+ }
47
+ }
48
+
49
+ :root {
50
+ --background: #f0edff;
51
+ --foreground: #2d2456;
52
+ --card: #ffffff;
53
+ --card-foreground: #2d2456;
54
+ --popover: #ffffff;
55
+ --popover-foreground: #2d2456;
56
+ --primary: #7c5cfc;
57
+ --primary-foreground: #ffffff;
58
+ --secondary: #f4f2ff;
59
+ --secondary-foreground: #534ab7;
60
+ --muted: #f4f2ff;
61
+ --muted-foreground: #9b8fd4;
62
+ --accent: #f4f2ff;
63
+ --accent-foreground: #534ab7;
64
+ --destructive: #dc2626;
65
+ --destructive-foreground: #ffffff;
66
+ --border: #d4d0e8;
67
+ --input: #e8e4ff;
68
+ --ring: #7c5cfc;
69
+ --chart-1: #7c5cfc;
70
+ --chart-2: #534ab7;
71
+ --chart-3: #9b8fd4;
72
+ --chart-4: #b8aee0;
73
+ --chart-5: #d4d0e8;
74
+ --chart-6: #6d7ce0;
75
+ --chart-7: #a774c9;
76
+ --chart-8: #6f6a99;
77
+ --sidebar: #f8f6ff;
78
+ --sidebar-foreground: #2d2456;
79
+ --sidebar-primary: #7c5cfc;
80
+ --sidebar-primary-foreground: #ffffff;
81
+ --sidebar-accent: #f0edff;
82
+ --sidebar-accent-foreground: #534ab7;
83
+ --sidebar-border: #d4d0e8;
84
+ --sidebar-ring: #7c5cfc;
85
+ --radius: 1rem;
86
+ /* Aside/callout grounds. Plain variables rather than `@theme inline`
87
+ literals, because `inline` bakes the value into the utility and a
88
+ `.dark` override of the theme key would never reach it. */
89
+ --trust-bg: #eef4ff;
90
+ --perm-bg: #fef8f0;
91
+ --danger-bg: #fef2f2;
92
+ }
93
+
94
+ .dark {
95
+ --background: #1a1433;
96
+ --foreground: #e8e4ff;
97
+ --card: #241e45;
98
+ --card-foreground: #e8e4ff;
99
+ --popover: #241e45;
100
+ --popover-foreground: #e8e4ff;
101
+ --primary: #9b7dff;
102
+ --primary-foreground: #ffffff;
103
+ --secondary: #2d2456;
104
+ --secondary-foreground: #d4d0e8;
105
+ --muted: #2d2456;
106
+ --muted-foreground: #9b8fd4;
107
+ --accent: #2d2456;
108
+ --accent-foreground: #d4d0e8;
109
+ --destructive: #f87171;
110
+ --destructive-foreground: #1a1433;
111
+ --border: #3d3566;
112
+ --input: #3d3566;
113
+ --ring: #9b7dff;
114
+ --chart-1: #9b7dff;
115
+ --chart-2: #7c5cfc;
116
+ --chart-3: #b8aee0;
117
+ --chart-4: #534ab7;
118
+ --chart-5: #3d3566;
119
+ --chart-6: #8b93ea;
120
+ --chart-7: #c294dd;
121
+ --chart-8: #8681b5;
122
+ --sidebar: #1e1838;
123
+ --sidebar-foreground: #e8e4ff;
124
+ --sidebar-primary: #9b7dff;
125
+ --sidebar-primary-foreground: #ffffff;
126
+ --sidebar-accent: #2d2456;
127
+ --sidebar-accent-foreground: #e8e4ff;
128
+ --sidebar-border: #3d3566;
129
+ --sidebar-ring: #9b7dff;
130
+ --trust-bg: #1c2f4d;
131
+ --perm-bg: #3a2e14;
132
+ --danger-bg: #3f1d1d;
133
+ }
134
+
135
+ @custom-variant dark (&:where(.dark, .dark *));
136
+
137
+ @theme inline {
138
+ --font-sans: var(--font-nunito, system-ui, sans-serif);
139
+
140
+ /* Extra small breakpoint below Tailwind's `sm` (640px), for phone-portrait
141
+ layouts. Enables `xs:` / `max-xs:` variants. */
142
+ --breakpoint-xs: 30rem;
143
+
144
+ /* ── Clay shadows (light) ──
145
+ Puffy/inflated look: a soft diagonal drop shadow (slightly more y
146
+ than x so surfaces read as lifted), a dark bottom-right inset, and
147
+ a bright top-left inset highlight. The highlight is what sells the
148
+ "soft clay" feel — keep it near-white and generous. */
149
+ --shadow-clay-sm:
150
+ 4px 6px 12px 0 rgba(100, 80, 180, 0.16), inset -2px -2px 5px 0 rgba(100, 80, 180, 0.1),
151
+ inset 2px 3px 6px 0 rgba(255, 255, 255, 0.9);
152
+ --shadow-clay:
153
+ 8px 12px 24px 0 rgba(100, 80, 180, 0.2), inset -4px -4px 10px 0 rgba(100, 80, 180, 0.1),
154
+ inset 3px 5px 14px 0 rgba(255, 255, 255, 1);
155
+ --shadow-clay-lg:
156
+ 14px 18px 38px 0 rgba(100, 80, 180, 0.24), inset -5px -5px 12px 0 rgba(100, 80, 180, 0.1),
157
+ inset 4px 7px 18px 0 rgba(255, 255, 255, 1);
158
+ --shadow-clay-primary:
159
+ 6px 9px 18px 0 rgba(124, 92, 252, 0.45), inset -3px -3px 8px 0 rgba(80, 50, 200, 0.4),
160
+ inset 3px 4px 8px 0 rgba(255, 255, 255, 0.4);
161
+
162
+ /* ── Clay shadows (dark) ── */
163
+ --shadow-clay-dark-sm:
164
+ 4px 6px 12px 0 rgba(10, 5, 30, 0.4), inset -2px -2px 5px 0 rgba(10, 5, 30, 0.3),
165
+ inset 2px 3px 6px 0 rgba(255, 255, 255, 0.05);
166
+ --shadow-clay-dark:
167
+ 8px 12px 24px 0 rgba(10, 5, 30, 0.45), inset -4px -4px 10px 0 rgba(10, 5, 30, 0.35),
168
+ inset 3px 5px 14px 0 rgba(255, 255, 255, 0.06);
169
+ --shadow-clay-dark-lg:
170
+ 14px 18px 38px 0 rgba(10, 5, 30, 0.5), inset -5px -5px 12px 0 rgba(10, 5, 30, 0.4),
171
+ inset 4px 7px 18px 0 rgba(255, 255, 255, 0.06);
172
+ --shadow-clay-dark-primary:
173
+ 6px 9px 18px 0 rgba(155, 125, 255, 0.3), inset -3px -3px 8px 0 rgba(40, 20, 120, 0.4),
174
+ inset 3px 4px 8px 0 rgba(255, 255, 255, 0.08);
175
+
176
+ /* ── Semantic clay shadows ── */
177
+ --shadow-clay-blue:
178
+ 8px 12px 24px 0 rgba(24, 95, 165, 0.16), inset -4px -4px 10px 0 rgba(24, 95, 165, 0.08),
179
+ inset 3px 5px 14px 0 rgba(255, 255, 255, 0.9);
180
+ --shadow-clay-amber:
181
+ 8px 12px 24px 0 rgba(186, 117, 23, 0.16), inset -4px -4px 10px 0 rgba(186, 117, 23, 0.08),
182
+ inset 3px 5px 14px 0 rgba(255, 255, 255, 0.9);
183
+ --shadow-clay-danger:
184
+ 8px 12px 24px 0 rgba(220, 38, 38, 0.18), inset -4px -4px 10px 0 rgba(220, 38, 38, 0.09),
185
+ inset 3px 5px 14px 0 rgba(255, 255, 255, 0.9);
186
+ --shadow-clay-ok:
187
+ 8px 12px 24px 0 rgba(22, 163, 74, 0.16), inset -4px -4px 10px 0 rgba(22, 163, 74, 0.08),
188
+ inset 3px 5px 14px 0 rgba(255, 255, 255, 0.9);
189
+ --shadow-clay-roadmap:
190
+ 8px 12px 24px 0 rgba(13, 148, 136, 0.16), inset -4px -4px 10px 0 rgba(13, 148, 136, 0.08),
191
+ inset 3px 5px 14px 0 rgba(255, 255, 255, 0.9);
192
+
193
+ /* ── Map standard shadow scale to clay ── */
194
+ --shadow-2xs: 0 0 0 0 transparent;
195
+ --shadow-xs: 0 0 0 0 transparent;
196
+ --shadow-sm: var(--shadow-clay-sm);
197
+ --shadow: var(--shadow-clay);
198
+ --shadow-md: var(--shadow-clay);
199
+ --shadow-lg: var(--shadow-clay-lg);
200
+ --shadow-xl: var(--shadow-clay-lg);
201
+ --shadow-2xl: var(--shadow-clay-lg);
202
+
203
+ /* ── Semantic colors ── */
204
+ --color-background: var(--background);
205
+ --color-foreground: var(--foreground);
206
+ --color-card: var(--card);
207
+ --color-card-foreground: var(--card-foreground);
208
+ --color-popover: var(--popover);
209
+ --color-popover-foreground: var(--popover-foreground);
210
+ --color-primary: var(--primary);
211
+ --color-primary-foreground: var(--primary-foreground);
212
+ --color-secondary: var(--secondary);
213
+ --color-secondary-foreground: var(--secondary-foreground);
214
+ --color-muted: var(--muted);
215
+ --color-muted-foreground: var(--muted-foreground);
216
+ --color-accent: var(--accent);
217
+ --color-accent-foreground: var(--accent-foreground);
218
+ --color-destructive: var(--destructive);
219
+ --color-destructive-foreground: var(--destructive-foreground);
220
+ --color-border: var(--border);
221
+ --color-input: var(--input);
222
+ --color-ring: var(--ring);
223
+ --color-chart-1: var(--chart-1);
224
+ --color-chart-2: var(--chart-2);
225
+ --color-chart-3: var(--chart-3);
226
+ --color-chart-4: var(--chart-4);
227
+ --color-chart-5: var(--chart-5);
228
+ --color-chart-6: var(--chart-6);
229
+ --color-chart-7: var(--chart-7);
230
+ --color-chart-8: var(--chart-8);
231
+ --color-sidebar: var(--sidebar);
232
+ --color-sidebar-foreground: var(--sidebar-foreground);
233
+ --color-sidebar-primary: var(--sidebar-primary);
234
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
235
+ --color-sidebar-accent: var(--sidebar-accent);
236
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
237
+ --color-sidebar-border: var(--sidebar-border);
238
+ --color-sidebar-ring: var(--sidebar-ring);
239
+ --radius-sm: calc(var(--radius) - 4px);
240
+ --radius-md: calc(var(--radius) - 2px);
241
+ --radius-lg: var(--radius);
242
+ --radius-xl: calc(var(--radius) + 4px);
243
+
244
+ /* ── Extra surface/text tokens ── */
245
+ --color-surface-tinted: #f8f6ff;
246
+ --color-surface-light: #f4f2ff;
247
+ --color-text-body: #534ab7;
248
+ --color-text-muted: #9b8fd4;
249
+ --color-text-faint: #b8aee0;
250
+ --color-text-dark: #2d2456;
251
+ --color-purple-light: #e8e4ff;
252
+ --color-purple-wash: #f0edff;
253
+
254
+ /* Trust (blue) */
255
+ --color-trust: #3b82f6;
256
+ --color-trust-bg: var(--trust-bg);
257
+ --color-trust-deep: #185fa5;
258
+ --color-trust-surface: #d0e2ff;
259
+ --color-trust-text: #1a2a4a;
260
+ --color-trust-muted: #6b8ab8;
261
+
262
+ /* Permissions (amber) */
263
+ --color-perm: #a07830;
264
+ --color-perm-bg: var(--perm-bg);
265
+
266
+ /* Danger (red) */
267
+ --color-danger: #dc2626;
268
+ --color-danger-bg: var(--danger-bg);
269
+ --color-danger-deep: #991b1b;
270
+
271
+ /* Success (green) */
272
+ --color-success: #22c55e;
273
+ --color-success-bg: #ecfdf5;
274
+ --color-success-text: #16a34a;
275
+
276
+ /* Roadmap (teal) - planned-but-not-built callouts */
277
+ --color-roadmap: #0d9488;
278
+ --color-roadmap-bg: #f0fdfa;
279
+ }
@@ -0,0 +1,78 @@
1
+ import { cloneElement, type ComponentChildren, isValidElement, type JSX, type VNode } from "preact";
2
+ import { clsx, type ClassValue } from "clsx";
3
+ import { twMerge } from "tailwind-merge";
4
+
5
+ export function cn(...inputs: ClassValue[]) {
6
+ return twMerge(clsx(inputs));
7
+ }
8
+
9
+ /**
10
+ * Props for a wrapper over a DOM element, minus `class`.
11
+ *
12
+ * Preact takes either `class` or `className` on an element, so `class` is the
13
+ * idiom everywhere else in this repo. It does NOT work on these wrappers: they
14
+ * pull `className` out, feed it through {@link cn}, and spread the rest onto
15
+ * the element - which hands preact/compat's vnode normalizer both keys at
16
+ * once. It resolves that collision by letting `className` win outright:
17
+ *
18
+ * if (props.class && !props.className) { ...keep class... }
19
+ * else if (props.className) { normalizedProps.class = normalizedProps.className = props.className }
20
+ *
21
+ * A wrapper's `className` is always set (it's `cn(...)` of its own base
22
+ * classes), so the second branch always runs and a caller's `class` is
23
+ * discarded. Silently: `ComponentProps<"div">` permits both keys, so it
24
+ * typechecks and then evaporates at runtime.
25
+ *
26
+ * Omitting `class` here turns that into a compile error at the call site.
27
+ * Wrappers over an Ark primitive don't need this - their props come from
28
+ * Ark's React types, which only have `className`.
29
+ */
30
+ export type ElementProps<T extends keyof JSX.IntrinsicElements> = Omit<
31
+ JSX.IntrinsicElements[T],
32
+ "class"
33
+ >;
34
+
35
+ type AnyProps = Record<string, unknown>;
36
+
37
+ export function mergeProps<T extends keyof JSX.IntrinsicElements = "div">(
38
+ ...sources: (Partial<JSX.IntrinsicElements[T]> | undefined | null)[]
39
+ ): JSX.IntrinsicElements[T] {
40
+ const result: Record<string, unknown> = {};
41
+ for (const source of sources) {
42
+ if (!source) continue;
43
+ for (const key of Object.keys(source)) {
44
+ const a = result[key];
45
+ const b = (source as AnyProps)[key];
46
+ if (key === "className" || key === "class") {
47
+ result[key] = cn(a as ClassValue, b as ClassValue);
48
+ } else if (key === "style") {
49
+ result[key] = { ...(a as object), ...(b as object) };
50
+ } else if (/^on[A-Z]/.test(key) && typeof a === "function" && typeof b === "function") {
51
+ result[key] = (...args: unknown[]) => {
52
+ (a as (...args: unknown[]) => unknown)(...args);
53
+ (b as (...args: unknown[]) => unknown)(...args);
54
+ };
55
+ } else {
56
+ result[key] = b;
57
+ }
58
+ }
59
+ }
60
+ return result as JSX.IntrinsicElements[T];
61
+ }
62
+
63
+ // Clones a single-element child, merging wrapper props onto it. Implements
64
+ // the shadcn/Ark `asChild` pattern: caller supplies the host element as
65
+ // children, wrapper contributes className/state/events. className, style,
66
+ // and on* handlers merge; everything else goes child-wins-over-wrapper so
67
+ // href/type/etc. survive.
68
+ export function Slot({
69
+ children,
70
+ ...props
71
+ }: { children?: ComponentChildren } & Record<string, unknown>): VNode {
72
+ if (!isValidElement(children)) {
73
+ throw new Error("Slot requires a single element as children.");
74
+ }
75
+ const child = children as VNode<AnyProps>;
76
+ const childProps = (child.props ?? {}) as AnyProps;
77
+ return cloneElement(child, mergeProps(props as never, childProps as never) as never);
78
+ }
@@ -0,0 +1,139 @@
1
+ // The typed error contract for ui loader/action calls.
2
+ //
3
+ // A loader (or action) failure is a *typed* value across all four hops
4
+ // (worker ui-proxy → Home run-loader → UiBridge postMessage → iframe
5
+ // mount): the worker emits `{ error, code }`, each relay hop preserves
6
+ // `code`, and the iframe runtime rejects the loader's promise with a
7
+ // `UiError` (an `Error` subclass carrying `code`). A widget — or, for the
8
+ // transient boot codes, the runtime's initial-load gate — branches on
9
+ // `error.code`, which the message alone can't carry: a booting container
10
+ // and a crashed one both read "no running container matches …".
11
+ //
12
+ // This file is imported from both sides of the wire: the worker
13
+ // (`@yourrealm/sdk/worker`) emits it, the iframe runtime (`mount.ts`)
14
+ // consumes it, and it's re-exported from `@yourrealm/sdk/ui` so surface
15
+ // authors can name the codes. It must stay free of any runtime-global
16
+ // (Deno, window) at module load — the SDK barrel is bundled into QuickJS.
17
+
18
+ /** The stable set of codes a ui loader/action failure can carry. */
19
+ export type UiErrorCode =
20
+ // The service has no container created at all (never deployed, or the
21
+ // app isn't pinned yet). Distinct from STARTING: there's nothing that
22
+ // will come up on its own, so this is not a spinner-forever state.
23
+ | "NO_CONTAINER"
24
+ // A container exists but isn't serving yet: created, restarting, or
25
+ // running-without-an-ip-yet. Transient — the loader's refetchInterval
26
+ // clears it once the container answers. This is the boot-window code the
27
+ // runtime's initial-load gate turns into a centered spinner.
28
+ | "CONTAINER_STARTING"
29
+ // A container exists but exited, died, or is paused. Real failure —
30
+ // surfaced to the author, never auto-retried into a spinner.
31
+ | "CONTAINER_CRASHED"
32
+ // The container was found but didn't answer within the upstream cap.
33
+ | "UPSTREAM_TIMEOUT"
34
+ // The container answered with a non-2xx, or returned a body the proxy
35
+ // couldn't pass through (non-JSON where JSON was required, oversize).
36
+ | "UPSTREAM_ERROR"
37
+ // Anything else: bad request shape, transport failure reaching the
38
+ // worker, an exception the proxy didn't anticipate.
39
+ | "INTERNAL";
40
+
41
+ /** Codes that mean "not up yet, but expected to come up on its own." */
42
+ export const TRANSIENT_UI_ERROR_CODES: ReadonlySet<UiErrorCode> = new Set(["CONTAINER_STARTING"]);
43
+
44
+ /** An `Error` that also carries a `UiErrorCode`. */
45
+ export class UiError extends Error {
46
+ readonly code: UiErrorCode;
47
+ constructor(code: UiErrorCode, message: string) {
48
+ super(message);
49
+ this.name = "UiError";
50
+ this.code = code;
51
+ }
52
+ }
53
+
54
+ /** Type guard: is this value a `UiError` (vs a plain `Error`)? */
55
+ export function isUiError(value: unknown): value is UiError {
56
+ return value instanceof UiError;
57
+ }
58
+
59
+ /** True when `err` is a UiError whose code is transient (boot window). */
60
+ export function isTransientUiError(err: unknown): boolean {
61
+ return isUiError(err) && TRANSIENT_UI_ERROR_CODES.has(err.code);
62
+ }
63
+
64
+ // --- Wire shape -------------------------------------------------------------
65
+ // The body a coded failure takes on the wire: `{ error, code }`. Plain
66
+ // helpers rather than zod so the worker's hot path pays no schema parse per
67
+ // proxy response; two fields, validated by construction at the emit site and
68
+ // by a membership check at the consume site.
69
+
70
+ const UI_ERROR_CODES: ReadonlySet<string> = new Set([
71
+ "NO_CONTAINER",
72
+ "CONTAINER_STARTING",
73
+ "CONTAINER_CRASHED",
74
+ "UPSTREAM_TIMEOUT",
75
+ "UPSTREAM_ERROR",
76
+ "INTERNAL",
77
+ ]);
78
+
79
+ /** Build the `{ error, code }` body a proxy route returns for `code`. */
80
+ export function uiErrorBody(
81
+ code: UiErrorCode,
82
+ message: string,
83
+ ): {
84
+ error: string;
85
+ code: UiErrorCode;
86
+ } {
87
+ return { error: message, code };
88
+ }
89
+
90
+ /**
91
+ * Read a `UiErrorCode` off an already-parsed response body, if one is
92
+ * present and recognized. Returns `undefined` for absent / unknown codes,
93
+ * so callers degrade to string-only behavior against an out-of-date peer.
94
+ */
95
+ export function readUiErrorCode(body: unknown): UiErrorCode | undefined {
96
+ if (!body || typeof body !== "object") return undefined;
97
+ const code = (body as { code?: unknown }).code;
98
+ return typeof code === "string" && UI_ERROR_CODES.has(code) ? (code as UiErrorCode) : undefined;
99
+ }
100
+
101
+ /** Read the human message off an error body, with a fallback. */
102
+ export function readUiErrorMessage(body: unknown, fallback: string): string {
103
+ if (body && typeof body === "object") {
104
+ const err = (body as { error?: unknown }).error;
105
+ if (typeof err === "string" && err.length > 0) return err;
106
+ }
107
+ return fallback;
108
+ }
109
+
110
+ // --- The canonical failure value ---------------------------------------------
111
+ // A ui failure IS this object, born on the worker and carried — not
112
+ // re-encoded into a string and re-parsed — through Home, the postMessage
113
+ // bridge, and the iframe. Downstream code branches on `.code`; the message
114
+ // is for humans. One shape end to end makes a fan-out of N failures a plain
115
+ // list of these, with no hop re-deciding the contract.
116
+
117
+ /** The typed failure a ui loader/action call can produce. */
118
+ export interface UiFailure {
119
+ code: UiErrorCode;
120
+ message: string;
121
+ }
122
+
123
+ /**
124
+ * Parse an already-read response/postMessage body into a `UiFailure`, or
125
+ * `undefined` if it isn't one (absent/unknown code, or no message). This is
126
+ * the single place the wire shape is validated; every consumer keys off the
127
+ * returned object instead of re-reading `error`/`code` ad hoc.
128
+ */
129
+ export function readUiFailure(body: unknown): UiFailure | undefined {
130
+ const code = readUiErrorCode(body);
131
+ if (code === undefined) return undefined;
132
+ const message = readUiErrorMessage(body, "");
133
+ return { code, message };
134
+ }
135
+
136
+ /** Build the `UiError` an iframe-side promise rejects with, from a failure. */
137
+ export function uiErrorFromFailure(f: UiFailure): UiError {
138
+ return new UiError(f.code, f.message);
139
+ }