@backbay/glia-three 0.2.0-alpha.2

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 (172) hide show
  1. package/package.json +43 -0
  2. package/src/environment/AuroraLayer/AuroraLayer.stories.tsx +43 -0
  3. package/src/environment/AuroraLayer/AuroraLayer.tsx +200 -0
  4. package/src/environment/AuroraLayer/index.ts +2 -0
  5. package/src/environment/AuroraLayer/types.ts +30 -0
  6. package/src/environment/EnvironmentLayer/EnvironmentLayer.stories.tsx +262 -0
  7. package/src/environment/EnvironmentLayer/EnvironmentLayer.tsx +105 -0
  8. package/src/environment/EnvironmentLayer/index.ts +4 -0
  9. package/src/environment/EnvironmentLayer/presets.ts +128 -0
  10. package/src/environment/FogLayer/FogLayer.stories.tsx +83 -0
  11. package/src/environment/FogLayer/FogLayer.tsx +113 -0
  12. package/src/environment/FogLayer/index.ts +2 -0
  13. package/src/environment/FogLayer/types.ts +45 -0
  14. package/src/environment/VolumetricLight/VolumetricLight.stories.tsx +55 -0
  15. package/src/environment/VolumetricLight/VolumetricLight.tsx +188 -0
  16. package/src/environment/VolumetricLight/index.ts +2 -0
  17. package/src/environment/VolumetricLight/types.ts +33 -0
  18. package/src/environment/WeatherLayer/WeatherLayer.stories.tsx +348 -0
  19. package/src/environment/WeatherLayer/WeatherLayer.tsx +266 -0
  20. package/src/environment/WeatherLayer/cinematicCanvas.tsx +809 -0
  21. package/src/environment/WeatherLayer/colors.ts +27 -0
  22. package/src/environment/WeatherLayer/index.ts +4 -0
  23. package/src/environment/WeatherLayer/leafPresets.ts +12 -0
  24. package/src/environment/WeatherLayer/particles.ts +227 -0
  25. package/src/environment/WeatherLayer/types.ts +140 -0
  26. package/src/environment/index.ts +17 -0
  27. package/src/environment/shared/index.ts +2 -0
  28. package/src/environment/shared/noise.ts +10 -0
  29. package/src/environment/shared/performance.ts +33 -0
  30. package/src/environment/shared/types.ts +26 -0
  31. package/src/index.ts +2 -0
  32. package/src/lib/utils.ts +6 -0
  33. package/src/lib/vision-types.ts +84 -0
  34. package/src/three/AgentConsole/AgentConsole.stories.tsx +397 -0
  35. package/src/three/AgentConsole/AgentConsole.tsx +195 -0
  36. package/src/three/AgentConsole/ConsoleChat.tsx +237 -0
  37. package/src/three/AgentConsole/FocusConstellation.tsx +297 -0
  38. package/src/three/AgentConsole/GlyphAvatar.stories.tsx +110 -0
  39. package/src/three/AgentConsole/GlyphAvatar.tsx +117 -0
  40. package/src/three/AgentConsole/QuickActions.tsx +111 -0
  41. package/src/three/AgentConsole/index.ts +41 -0
  42. package/src/three/AgentConsole/types.ts +241 -0
  43. package/src/three/AmbientField/AmbientField.stories.tsx +290 -0
  44. package/src/three/AmbientField/AmbientField.tsx +307 -0
  45. package/src/three/AmbientField/BackbayFieldBus.ts +326 -0
  46. package/src/three/AmbientField/FieldProvider.tsx +83 -0
  47. package/src/three/AmbientField/index.ts +37 -0
  48. package/src/three/AmbientField/shaders/constellation.ts +384 -0
  49. package/src/three/AmbientField/types.ts +174 -0
  50. package/src/three/AttackGraph/AttackGraph.stories.tsx +144 -0
  51. package/src/three/AttackGraph/AttackGraph.tsx +325 -0
  52. package/src/three/AttackGraph/index.ts +19 -0
  53. package/src/three/AttackGraph/types.ts +97 -0
  54. package/src/three/AuditTrail/AuditTrail.stories.tsx +567 -0
  55. package/src/three/AuditTrail/AuditTrail.tsx +644 -0
  56. package/src/three/AuditTrail/index.ts +33 -0
  57. package/src/three/AuditTrail/types.ts +192 -0
  58. package/src/three/CrystallineOrganism/Breadcrumb.tsx +61 -0
  59. package/src/three/CrystallineOrganism/CrystallineOrganism.stories.tsx +509 -0
  60. package/src/three/CrystallineOrganism/CrystallineOrganism.tsx +273 -0
  61. package/src/three/CrystallineOrganism/LatticeEdge.tsx +69 -0
  62. package/src/three/CrystallineOrganism/OrganismLattice.tsx +159 -0
  63. package/src/three/CrystallineOrganism/OrganismParticles.tsx +148 -0
  64. package/src/three/CrystallineOrganism/OrganismShell.tsx +277 -0
  65. package/src/three/CrystallineOrganism/constants.ts +161 -0
  66. package/src/three/CrystallineOrganism/index.ts +17 -0
  67. package/src/three/CrystallineOrganism/layouts/hexGrid.ts +85 -0
  68. package/src/three/CrystallineOrganism/layouts/index.ts +1 -0
  69. package/src/three/CrystallineOrganism/types.ts +167 -0
  70. package/src/three/CrystallineOrganism/useOrganismEmotion.ts +84 -0
  71. package/src/three/FirewallBarrier/FirewallBarrier.stories.tsx +167 -0
  72. package/src/three/FirewallBarrier/FirewallBarrier.tsx +259 -0
  73. package/src/three/FirewallBarrier/index.ts +14 -0
  74. package/src/three/FirewallBarrier/types.ts +52 -0
  75. package/src/three/Glyph/GlyphObject.stories.tsx +577 -0
  76. package/src/three/Glyph/GlyphObject.tsx +422 -0
  77. package/src/three/Glyph/index.ts +10 -0
  78. package/src/three/Glyph/types.ts +36 -0
  79. package/src/three/Glyph/useGlyphController.ts +231 -0
  80. package/src/three/Glyph/useGlyphEmotion.ts +70 -0
  81. package/src/three/Graph3D/Graph3D.stories.tsx +269 -0
  82. package/src/three/Graph3D/Graph3D.tsx +248 -0
  83. package/src/three/Graph3D/GraphEdge.tsx +79 -0
  84. package/src/three/Graph3D/GraphNode.tsx +239 -0
  85. package/src/three/Graph3D/types.ts +66 -0
  86. package/src/three/Graph3D/utils.ts +204 -0
  87. package/src/three/IntelFeed/IntelFeed.stories.tsx +168 -0
  88. package/src/three/IntelFeed/IntelFeed.tsx +284 -0
  89. package/src/three/IntelFeed/index.ts +14 -0
  90. package/src/three/IntelFeed/types.ts +56 -0
  91. package/src/three/MetricsGalaxy/MetricsGalaxy.tsx +484 -0
  92. package/src/three/MetricsGalaxy/index.ts +6 -0
  93. package/src/three/MetricsGalaxy/types.ts +26 -0
  94. package/src/three/NetworkTopology/NetworkTopology.stories.tsx +184 -0
  95. package/src/three/NetworkTopology/NetworkTopology.tsx +421 -0
  96. package/src/three/NetworkTopology/index.ts +34 -0
  97. package/src/three/NetworkTopology/types.ts +128 -0
  98. package/src/three/ParticleField/ParticleField.stories.tsx +162 -0
  99. package/src/three/ParticleField/ParticleField.tsx +81 -0
  100. package/src/three/ParticleField/index.ts +1 -0
  101. package/src/three/PermissionMatrix/PermissionMatrix.stories.tsx +475 -0
  102. package/src/three/PermissionMatrix/PermissionMatrix.tsx +380 -0
  103. package/src/three/PermissionMatrix/index.ts +15 -0
  104. package/src/three/PermissionMatrix/types.ts +54 -0
  105. package/src/three/QuantumField/ConstellationField.tsx +238 -0
  106. package/src/three/QuantumField/FieldBus.ts +349 -0
  107. package/src/three/QuantumField/FieldLayer.tsx +430 -0
  108. package/src/three/QuantumField/FieldProvider.tsx +460 -0
  109. package/src/three/QuantumField/PcbField.tsx +406 -0
  110. package/src/three/QuantumField/QuantumField.stories.tsx +1155 -0
  111. package/src/three/QuantumField/TrailRTT.ts +212 -0
  112. package/src/three/QuantumField/WaterField.tsx +226 -0
  113. package/src/three/QuantumField/WaterSimRTT.ts +283 -0
  114. package/src/three/QuantumField/domMapping.ts +185 -0
  115. package/src/three/QuantumField/index.ts +110 -0
  116. package/src/three/QuantumField/styles/index.ts +9 -0
  117. package/src/three/QuantumField/styles/styleA.ts +526 -0
  118. package/src/three/QuantumField/styles/styleB.ts +1210 -0
  119. package/src/three/QuantumField/styles/styleC.ts +266 -0
  120. package/src/three/QuantumField/themes.ts +211 -0
  121. package/src/three/QuantumField/types.ts +380 -0
  122. package/src/three/SOCCommandCenter/SOCCommandCenter.stories.tsx +591 -0
  123. package/src/three/SOCCommandCenter/SOCCommandCenter.tsx +248 -0
  124. package/src/three/SOCCommandCenter/index.ts +26 -0
  125. package/src/three/SOCCommandCenter/types.ts +201 -0
  126. package/src/three/SecurityDashboard/SecurityDashboard.stories.tsx +508 -0
  127. package/src/three/SecurityDashboard/SecurityDashboard.tsx +507 -0
  128. package/src/three/SecurityDashboard/index.ts +37 -0
  129. package/src/three/SecurityDashboard/types.ts +143 -0
  130. package/src/three/SecurityShield/SecurityShield.stories.tsx +257 -0
  131. package/src/three/SecurityShield/SecurityShield.tsx +502 -0
  132. package/src/three/SecurityShield/index.ts +25 -0
  133. package/src/three/SecurityShield/types.ts +64 -0
  134. package/src/three/Sentinel/AvatarMode.tsx +578 -0
  135. package/src/three/Sentinel/AvatarRenderer.tsx +199 -0
  136. package/src/three/Sentinel/CameraPip.tsx +127 -0
  137. package/src/three/Sentinel/CardinalItem.tsx +83 -0
  138. package/src/three/Sentinel/CardinalMenu.tsx +370 -0
  139. package/src/three/Sentinel/DockedMiniOrb.tsx +146 -0
  140. package/src/three/Sentinel/RadialSubmenu.tsx +273 -0
  141. package/src/three/Sentinel/SentinelConversation.tsx +802 -0
  142. package/src/three/Sentinel/SentinelOrb.tsx +316 -0
  143. package/src/three/Sentinel/SentinelOverlay.tsx +146 -0
  144. package/src/three/Sentinel/SentinelProvider.tsx +145 -0
  145. package/src/three/Sentinel/SentinelTether.tsx +182 -0
  146. package/src/three/Sentinel/SigilPlaceholder.tsx +176 -0
  147. package/src/three/Sentinel/VerticalSubmenu.tsx +150 -0
  148. package/src/three/Sentinel/index.ts +145 -0
  149. package/src/three/Sentinel/sentinelStore.ts +196 -0
  150. package/src/three/Sentinel/types.ts +403 -0
  151. package/src/three/Sentinel/useCameraPermission.ts +153 -0
  152. package/src/three/Sentinel/useThrowPhysics.ts +220 -0
  153. package/src/three/SpatialWorkspace/CyntraWorkspace.tsx +84 -0
  154. package/src/three/SpatialWorkspace/JobCluster.tsx +281 -0
  155. package/src/three/SpatialWorkspace/NodeGraph.tsx +236 -0
  156. package/src/three/SpatialWorkspace/ReceiptOrbit.tsx +368 -0
  157. package/src/three/SpatialWorkspace/SpatialWorkspace.stories.tsx +547 -0
  158. package/src/three/SpatialWorkspace/SpatialWorkspace.tsx +428 -0
  159. package/src/three/SpatialWorkspace/TrustRings.tsx +228 -0
  160. package/src/three/SpatialWorkspace/adapters.ts +353 -0
  161. package/src/three/SpatialWorkspace/index.ts +85 -0
  162. package/src/three/SpatialWorkspace/nexusAdapter.ts +182 -0
  163. package/src/three/SpatialWorkspace/types.ts +389 -0
  164. package/src/three/ThreatRadar/ThreatRadar.stories.tsx +451 -0
  165. package/src/three/ThreatRadar/ThreatRadar.tsx +542 -0
  166. package/src/three/ThreatRadar/index.ts +8 -0
  167. package/src/three/ThreatRadar/types.ts +90 -0
  168. package/src/three/ThreeErrorBoundary/ThreeErrorBoundary.tsx +235 -0
  169. package/src/three/ThreeErrorBoundary/index.ts +5 -0
  170. package/src/three/index.ts +56 -0
  171. package/tsconfig.json +20 -0
  172. package/tsup.config.ts +21 -0
@@ -0,0 +1,353 @@
1
+ /**
2
+ * Entity Adapters
3
+ *
4
+ * Maps Backbay contract entities (Job, Node, Receipt, Dispute) to CrystallineOrganism props.
5
+ * This adapter layer enables the SpatialWorkspace to use the unified emotion-driven
6
+ * visualization system from CrystallineOrganism.
7
+ */
8
+
9
+ import type {
10
+ Job,
11
+ JobStatus,
12
+ Node,
13
+ NodeType,
14
+ NodeStatus,
15
+ Receipt,
16
+ ReceiptStatus,
17
+ Dispute,
18
+ DisputeStatus,
19
+ TrustTier,
20
+ } from "@backbay/contract";
21
+ import type {
22
+ CrystallineOrganismProps,
23
+ OrganismType,
24
+ OrganismState,
25
+ OrganismPower,
26
+ } from "../CrystallineOrganism";
27
+
28
+ // -----------------------------------------------------------------------------
29
+ // Adapter Interface
30
+ // -----------------------------------------------------------------------------
31
+
32
+ export interface EntityAdapter<T> {
33
+ toOrganism(entity: T): CrystallineOrganismProps;
34
+ getState(entity: T): OrganismState;
35
+ getType(entity: T): OrganismType;
36
+ getPower(entity: T): OrganismPower;
37
+ }
38
+
39
+ // -----------------------------------------------------------------------------
40
+ // Job Adapter
41
+ // -----------------------------------------------------------------------------
42
+
43
+ const JOB_STATUS_TO_STATE: Record<JobStatus, OrganismState> = {
44
+ queued: "idle",
45
+ running: "busy",
46
+ completed: "success",
47
+ blocked: "thinking",
48
+ quarantine: "error",
49
+ };
50
+
51
+ export const jobAdapter: EntityAdapter<Job> = {
52
+ toOrganism(job: Job): CrystallineOrganismProps {
53
+ return {
54
+ id: job.id,
55
+ type: this.getType(job),
56
+ label: job.type || job.id.slice(0, 8),
57
+ state: this.getState(job),
58
+ power: this.getPower(job),
59
+ };
60
+ },
61
+
62
+ getState(job: Job): OrganismState {
63
+ return JOB_STATUS_TO_STATE[job.status] ?? "idle";
64
+ },
65
+
66
+ getType(_job: Job): OrganismType {
67
+ return "task"; // Jobs are always tetrahedrons
68
+ },
69
+
70
+ getPower(job: Job): OrganismPower {
71
+ if (job.status === "running") return "elevated";
72
+ if (job.status === "quarantine") return "elevated";
73
+ return "standard";
74
+ },
75
+ };
76
+
77
+ // -----------------------------------------------------------------------------
78
+ // Node Adapter
79
+ // -----------------------------------------------------------------------------
80
+
81
+ const NODE_TYPE_TO_ORGANISM: Record<NodeType, OrganismType> = {
82
+ operator: "kernel",
83
+ fab: "workcell",
84
+ verifier: "agent",
85
+ relay: "relay",
86
+ };
87
+
88
+ const NODE_STATUS_TO_STATE: Record<NodeStatus, OrganismState> = {
89
+ online: "idle",
90
+ degraded: "thinking",
91
+ offline: "sleep",
92
+ };
93
+
94
+ const TRUST_TIER_TO_POWER: Record<TrustTier, OrganismPower> = {
95
+ bronze: "standard",
96
+ silver: "elevated",
97
+ gold: "intense",
98
+ };
99
+
100
+ export const nodeAdapter: EntityAdapter<Node> = {
101
+ toOrganism(node: Node): CrystallineOrganismProps {
102
+ return {
103
+ id: node.id,
104
+ type: this.getType(node),
105
+ label: node.id.slice(0, 8),
106
+ state: this.getState(node),
107
+ power: this.getPower(node),
108
+ };
109
+ },
110
+
111
+ getState(node: Node): OrganismState {
112
+ return NODE_STATUS_TO_STATE[node.status] ?? "idle";
113
+ },
114
+
115
+ getType(node: Node): OrganismType {
116
+ return NODE_TYPE_TO_ORGANISM[node.type] ?? "agent";
117
+ },
118
+
119
+ getPower(node: Node): OrganismPower {
120
+ return TRUST_TIER_TO_POWER[node.trust_tier] ?? "standard";
121
+ },
122
+ };
123
+
124
+ // -----------------------------------------------------------------------------
125
+ // Receipt Adapter
126
+ // -----------------------------------------------------------------------------
127
+
128
+ const RECEIPT_STATUS_TO_STATE: Record<ReceiptStatus, OrganismState> = {
129
+ pending: "listening",
130
+ passed: "success",
131
+ failed: "error",
132
+ };
133
+
134
+ export const receiptAdapter: EntityAdapter<Receipt> = {
135
+ toOrganism(receipt: Receipt): CrystallineOrganismProps {
136
+ return {
137
+ id: receipt.id,
138
+ type: this.getType(receipt),
139
+ label: receipt.id.slice(0, 6),
140
+ state: this.getState(receipt),
141
+ power: this.getPower(receipt),
142
+ };
143
+ },
144
+
145
+ getState(receipt: Receipt): OrganismState {
146
+ return RECEIPT_STATUS_TO_STATE[receipt.status] ?? "idle";
147
+ },
148
+
149
+ getType(_receipt: Receipt): OrganismType {
150
+ // Receipts are micro-tasks - use minimal task geometry
151
+ return "task";
152
+ },
153
+
154
+ getPower(receipt: Receipt): OrganismPower {
155
+ // Receipts are small - always minimal
156
+ return "minimal";
157
+ },
158
+ };
159
+
160
+ // -----------------------------------------------------------------------------
161
+ // Dispute Adapter
162
+ // -----------------------------------------------------------------------------
163
+
164
+ export const disputeAdapter: EntityAdapter<Dispute> = {
165
+ toOrganism(dispute: Dispute): CrystallineOrganismProps {
166
+ return {
167
+ id: dispute.id,
168
+ type: this.getType(dispute),
169
+ label: `Dispute ${dispute.id.slice(0, 6)}`,
170
+ state: this.getState(dispute),
171
+ power: this.getPower(dispute),
172
+ };
173
+ },
174
+
175
+ getState(dispute: Dispute): OrganismState {
176
+ // Map dispute status to organism state
177
+ const statusMap: Record<DisputeStatus, OrganismState> = {
178
+ pending: "error", // Pending disputes need attention
179
+ resolved: "success", // Resolved disputes are complete
180
+ rejected: "idle", // Rejected disputes are dismissed
181
+ };
182
+ return statusMap[dispute.status] ?? "error";
183
+ },
184
+
185
+ getType(_dispute: Dispute): OrganismType {
186
+ // Disputes are task-like items that need resolution
187
+ return "task";
188
+ },
189
+
190
+ getPower(dispute: Dispute): OrganismPower {
191
+ // Calculate severity based on age
192
+ const ageMs = Date.now() - new Date(dispute.opened_at).getTime();
193
+ const ageHours = ageMs / (1000 * 60 * 60);
194
+ if (ageHours >= 72) return "intense";
195
+ if (ageHours >= 24) return "elevated";
196
+ return "standard";
197
+ },
198
+ };
199
+
200
+ // -----------------------------------------------------------------------------
201
+ // Batch Conversion Helpers
202
+ // -----------------------------------------------------------------------------
203
+
204
+ export function jobsToOrganisms(jobs: Job[]): CrystallineOrganismProps[] {
205
+ return jobs.map((job) => jobAdapter.toOrganism(job));
206
+ }
207
+
208
+ export function nodesToOrganisms(nodes: Node[]): CrystallineOrganismProps[] {
209
+ return nodes.map((node) => nodeAdapter.toOrganism(node));
210
+ }
211
+
212
+ export function receiptsToOrganisms(receipts: Receipt[]): CrystallineOrganismProps[] {
213
+ return receipts.map((receipt) => receiptAdapter.toOrganism(receipt));
214
+ }
215
+
216
+ export function disputesToOrganisms(disputes: Dispute[]): CrystallineOrganismProps[] {
217
+ return disputes.map((dispute) => disputeAdapter.toOrganism(dispute));
218
+ }
219
+
220
+ // -----------------------------------------------------------------------------
221
+ // Cyntra Kernel Types (for Phase 6)
222
+ // -----------------------------------------------------------------------------
223
+
224
+ export interface CyntraKernelStatus {
225
+ workcells: CyntraWorkcellStatus[];
226
+ pending_issues: number;
227
+ active_runs: number;
228
+ }
229
+
230
+ export interface CyntraWorkcellStatus {
231
+ id: string;
232
+ branch: string;
233
+ toolchain: string;
234
+ state: "idle" | "running" | "blocked";
235
+ current_run?: string;
236
+ }
237
+
238
+ export interface CyntraRunStatus {
239
+ id: string;
240
+ issue_id: string;
241
+ state: "queued" | "running" | "verifying" | "completed" | "failed";
242
+ toolchain: string;
243
+ started_at?: string;
244
+ completed_at?: string;
245
+ }
246
+
247
+ export interface CyntraIssueStatus {
248
+ id: string;
249
+ title: string;
250
+ state: "open" | "in_progress" | "resolved" | "wontfix";
251
+ labels: string[];
252
+ }
253
+
254
+ // -----------------------------------------------------------------------------
255
+ // Cyntra Entity Adapters
256
+ // -----------------------------------------------------------------------------
257
+
258
+ const WORKCELL_STATE_TO_ORGANISM: Record<CyntraWorkcellStatus["state"], OrganismState> = {
259
+ idle: "idle",
260
+ running: "busy",
261
+ blocked: "error",
262
+ };
263
+
264
+ export const cyntraWorkcellAdapter: EntityAdapter<CyntraWorkcellStatus> = {
265
+ toOrganism(wc: CyntraWorkcellStatus): CrystallineOrganismProps {
266
+ return {
267
+ id: wc.id,
268
+ type: this.getType(wc),
269
+ label: wc.branch.split("/").pop() || wc.id.slice(0, 8),
270
+ state: this.getState(wc),
271
+ power: this.getPower(wc),
272
+ };
273
+ },
274
+ getState(wc: CyntraWorkcellStatus): OrganismState {
275
+ return WORKCELL_STATE_TO_ORGANISM[wc.state] ?? "idle";
276
+ },
277
+ getType(_wc: CyntraWorkcellStatus): OrganismType {
278
+ return "workcell";
279
+ },
280
+ getPower(wc: CyntraWorkcellStatus): OrganismPower {
281
+ return wc.current_run ? "elevated" : "standard";
282
+ },
283
+ };
284
+
285
+ const RUN_STATE_TO_ORGANISM: Record<CyntraRunStatus["state"], OrganismState> = {
286
+ queued: "idle",
287
+ running: "busy",
288
+ verifying: "thinking",
289
+ completed: "success",
290
+ failed: "error",
291
+ };
292
+
293
+ export const cyntraRunAdapter: EntityAdapter<CyntraRunStatus> = {
294
+ toOrganism(run: CyntraRunStatus): CrystallineOrganismProps {
295
+ return {
296
+ id: run.id,
297
+ type: this.getType(run),
298
+ label: run.issue_id.slice(0, 8),
299
+ state: this.getState(run),
300
+ power: this.getPower(run),
301
+ };
302
+ },
303
+ getState(run: CyntraRunStatus): OrganismState {
304
+ return RUN_STATE_TO_ORGANISM[run.state] ?? "idle";
305
+ },
306
+ getType(_run: CyntraRunStatus): OrganismType {
307
+ return "agent";
308
+ },
309
+ getPower(run: CyntraRunStatus): OrganismPower {
310
+ return run.state === "running" ? "elevated" : "standard";
311
+ },
312
+ };
313
+
314
+ const ISSUE_STATE_TO_ORGANISM: Record<CyntraIssueStatus["state"], OrganismState> = {
315
+ open: "idle",
316
+ in_progress: "busy",
317
+ resolved: "success",
318
+ wontfix: "sleep",
319
+ };
320
+
321
+ export const cyntraIssueAdapter: EntityAdapter<CyntraIssueStatus> = {
322
+ toOrganism(issue: CyntraIssueStatus): CrystallineOrganismProps {
323
+ return {
324
+ id: issue.id,
325
+ type: this.getType(issue),
326
+ label: issue.title.slice(0, 20),
327
+ state: this.getState(issue),
328
+ power: this.getPower(issue),
329
+ };
330
+ },
331
+ getState(issue: CyntraIssueStatus): OrganismState {
332
+ return ISSUE_STATE_TO_ORGANISM[issue.state] ?? "idle";
333
+ },
334
+ getType(_issue: CyntraIssueStatus): OrganismType {
335
+ return "task";
336
+ },
337
+ getPower(issue: CyntraIssueStatus): OrganismPower {
338
+ return issue.state === "in_progress" ? "elevated" : "standard";
339
+ },
340
+ };
341
+
342
+ // Batch converters
343
+ export function workcellsToOrganisms(workcells: CyntraWorkcellStatus[]): CrystallineOrganismProps[] {
344
+ return workcells.map((wc) => cyntraWorkcellAdapter.toOrganism(wc));
345
+ }
346
+
347
+ export function runsToOrganisms(runs: CyntraRunStatus[]): CrystallineOrganismProps[] {
348
+ return runs.map((run) => cyntraRunAdapter.toOrganism(run));
349
+ }
350
+
351
+ export function issuesToOrganisms(issues: CyntraIssueStatus[]): CrystallineOrganismProps[] {
352
+ return issues.map((issue) => cyntraIssueAdapter.toOrganism(issue));
353
+ }
@@ -0,0 +1,85 @@
1
+ /**
2
+ * SpatialWorkspace Module Exports
3
+ */
4
+
5
+ export { SpatialWorkspace } from "./SpatialWorkspace";
6
+ export type { SpatialWorkspaceProps } from "./types";
7
+
8
+ export { JobCluster } from "./JobCluster";
9
+ export type { JobClusterProps } from "./types";
10
+
11
+ export { NodeGraph } from "./NodeGraph";
12
+ export type { NodeGraphProps } from "./types";
13
+
14
+ export { ReceiptOrbit } from "./ReceiptOrbit";
15
+ export type { ReceiptOrbitProps } from "./types";
16
+
17
+ export { TrustRings } from "./TrustRings";
18
+ export type { TrustRingsProps } from "./types";
19
+
20
+ export type {
21
+ WorkspaceLayout,
22
+ WorkspaceLayoutOptions,
23
+ EntityVisual,
24
+ EntityPosition,
25
+ WorkspaceFilter,
26
+ WorkspaceSelection,
27
+ DisputeSeverity,
28
+ DisputeBeaconProps,
29
+ } from "./types";
30
+
31
+ export {
32
+ JOB_VISUALS,
33
+ NODE_VISUALS,
34
+ NODE_STATUS_MODIFIERS,
35
+ RECEIPT_VISUALS,
36
+ TRUST_RING_CONFIG,
37
+ DISPUTE_SEVERITY_VISUALS,
38
+ DEFAULT_WORKSPACE_CONFIG,
39
+ getDisputeSeverity,
40
+ } from "./types";
41
+
42
+ // Entity Adapters - map Backbay entities to CrystallineOrganism props
43
+ export {
44
+ jobAdapter,
45
+ nodeAdapter,
46
+ receiptAdapter,
47
+ disputeAdapter,
48
+ jobsToOrganisms,
49
+ nodesToOrganisms,
50
+ receiptsToOrganisms,
51
+ disputesToOrganisms,
52
+ // Cyntra entity adapters
53
+ cyntraWorkcellAdapter,
54
+ cyntraRunAdapter,
55
+ cyntraIssueAdapter,
56
+ workcellsToOrganisms,
57
+ runsToOrganisms,
58
+ issuesToOrganisms,
59
+ } from "./adapters";
60
+
61
+ export type {
62
+ EntityAdapter,
63
+ CyntraKernelStatus,
64
+ CyntraWorkcellStatus,
65
+ CyntraRunStatus,
66
+ CyntraIssueStatus,
67
+ } from "./adapters";
68
+
69
+ // CyntraWorkspace - visualize Cyntra kernel status
70
+ export { CyntraWorkspace } from "./CyntraWorkspace";
71
+ export type { CyntraWorkspaceProps } from "./CyntraWorkspace";
72
+
73
+ // Nexus adapters - map NexusItems to CrystallineOrganism props
74
+ export {
75
+ nexusAdapter,
76
+ nexusItemsToOrganisms,
77
+ getNexusOrganismScale,
78
+ canSprawlInto,
79
+ } from "./nexusAdapter";
80
+
81
+ export type {
82
+ NexusItem,
83
+ NexusItemType,
84
+ NexusItemStatus,
85
+ } from "./nexusAdapter";
@@ -0,0 +1,182 @@
1
+ /**
2
+ * Nexus Adapter
3
+ *
4
+ * Maps NexusItem entities to CrystallineOrganism props for hierarchical
5
+ * workspace visualization. Enables NexusNodes to be rendered as
6
+ * emotion-driven organisms with consistent visual language.
7
+ */
8
+
9
+ import * as THREE from "three";
10
+ import type {
11
+ CrystallineOrganismProps,
12
+ OrganismType,
13
+ OrganismState,
14
+ OrganismPower,
15
+ } from "../CrystallineOrganism";
16
+ import type { EntityAdapter } from "./adapters";
17
+
18
+ // -----------------------------------------------------------------------------
19
+ // Nexus Types (mirrored from NexusNode.tsx for decoupling)
20
+ // -----------------------------------------------------------------------------
21
+
22
+ export type NexusItemType =
23
+ | "terminal"
24
+ | "browser-tab"
25
+ | "agent-task"
26
+ | "industry"
27
+ | "workcell"
28
+ | "trade"
29
+ | "cluster"
30
+ | "index"
31
+ | "app-window";
32
+
33
+ export type NexusItemStatus =
34
+ | "idle"
35
+ | "active"
36
+ | "running"
37
+ | "error"
38
+ | "complete"
39
+ | "pending";
40
+
41
+ export interface NexusItem {
42
+ id: string;
43
+ type: NexusItemType;
44
+ label: string;
45
+ status: NexusItemStatus;
46
+ activityLevel: number; // 0-1 normalized
47
+ /** 3D position in scene (used by NexusOrganismNode) */
48
+ position: THREE.Vector3;
49
+ metadata?: {
50
+ favicon?: string;
51
+ workcellId?: string;
52
+ taskId?: string;
53
+ tradeId?: string;
54
+ industryCode?: string;
55
+ /** Jobs associated with this item (for workspace drill-down) */
56
+ jobIds?: string[];
57
+ /** Nodes associated with this item */
58
+ nodeIds?: string[];
59
+ /** Receipt count for status rings */
60
+ receiptCounts?: {
61
+ passed: number;
62
+ failed: number;
63
+ pending: number;
64
+ };
65
+ };
66
+ }
67
+
68
+ // -----------------------------------------------------------------------------
69
+ // Type Mappings
70
+ // -----------------------------------------------------------------------------
71
+
72
+ /**
73
+ * Maps NexusItemType to OrganismType geometry.
74
+ *
75
+ * Semantic mapping:
76
+ * - terminal → kernel (octahedron): Central command/control
77
+ * - browser-tab → relay (torus): Connection/communication point
78
+ * - agent-task → agent (icosahedron): AI/autonomous process
79
+ * - industry → workcell (dodecahedron): Industry sector
80
+ * - workcell → workcell (dodecahedron): Cyntra sandbox
81
+ * - trade → task (tetrahedron): Action/transaction
82
+ * - cluster → kernel (octahedron): Group container
83
+ * - index → relay (torus): Reference/lookup point
84
+ * - app-window → agent (icosahedron): Application instance
85
+ */
86
+ const NEXUS_TYPE_TO_ORGANISM: Record<NexusItemType, OrganismType> = {
87
+ terminal: "kernel",
88
+ "browser-tab": "relay",
89
+ "agent-task": "agent",
90
+ industry: "workcell",
91
+ workcell: "workcell",
92
+ trade: "task",
93
+ cluster: "kernel",
94
+ index: "relay",
95
+ "app-window": "agent",
96
+ };
97
+
98
+ /**
99
+ * Maps NexusItemStatus to OrganismState for emotion-driven visualization.
100
+ */
101
+ const NEXUS_STATUS_TO_STATE: Record<NexusItemStatus, OrganismState> = {
102
+ idle: "idle",
103
+ active: "busy",
104
+ running: "busy",
105
+ error: "error",
106
+ complete: "success",
107
+ pending: "listening",
108
+ };
109
+
110
+ // -----------------------------------------------------------------------------
111
+ // Nexus Adapter
112
+ // -----------------------------------------------------------------------------
113
+
114
+ export const nexusAdapter: EntityAdapter<NexusItem> = {
115
+ toOrganism(item: NexusItem): CrystallineOrganismProps {
116
+ return {
117
+ id: item.id,
118
+ type: this.getType(item),
119
+ label: item.label,
120
+ state: this.getState(item),
121
+ power: this.getPower(item),
122
+ };
123
+ },
124
+
125
+ getState(item: NexusItem): OrganismState {
126
+ return NEXUS_STATUS_TO_STATE[item.status] ?? "idle";
127
+ },
128
+
129
+ getType(item: NexusItem): OrganismType {
130
+ return NEXUS_TYPE_TO_ORGANISM[item.type] ?? "agent";
131
+ },
132
+
133
+ getPower(item: NexusItem): OrganismPower {
134
+ // High activity → elevated power for more intense glow
135
+ if (item.activityLevel > 0.7) return "elevated";
136
+
137
+ // Error and running states demand attention
138
+ if (item.status === "error") return "elevated";
139
+ if (item.status === "running") return "elevated";
140
+
141
+ // Clusters and terminals are important → standard+
142
+ if (item.type === "cluster" || item.type === "terminal") {
143
+ return item.activityLevel > 0.3 ? "elevated" : "standard";
144
+ }
145
+
146
+ return "standard";
147
+ },
148
+ };
149
+
150
+ // -----------------------------------------------------------------------------
151
+ // Batch Conversion Helpers
152
+ // -----------------------------------------------------------------------------
153
+
154
+ /**
155
+ * Convert array of NexusItems to CrystallineOrganismProps.
156
+ */
157
+ export function nexusItemsToOrganisms(
158
+ items: NexusItem[]
159
+ ): CrystallineOrganismProps[] {
160
+ return items.map((item) => nexusAdapter.toOrganism(item));
161
+ }
162
+
163
+ /**
164
+ * Get organism scale factor based on NexusItem activity level.
165
+ * Matches the existing NexusNode scaling behavior.
166
+ */
167
+ export function getNexusOrganismScale(item: NexusItem): number {
168
+ // Scale based on activity level: 0.8 to 1.2
169
+ return 0.8 + item.activityLevel * 0.4;
170
+ }
171
+
172
+ /**
173
+ * Check if a NexusItem can be sprawled into (has detail workspace).
174
+ */
175
+ export function canSprawlInto(item: NexusItem): boolean {
176
+ return (
177
+ item.type === "cluster" ||
178
+ item.type === "workcell" ||
179
+ item.type === "industry" ||
180
+ item.type === "terminal"
181
+ );
182
+ }