@stephen-netu/design-system 0.1.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 (204) hide show
  1. package/README.md +66 -0
  2. package/package.json +130 -0
  3. package/src/b0-app-shell/clarification-overlay/ClarificationOverlay.svelte +221 -0
  4. package/src/b0-app-shell/clarification-overlay/index.ts +1 -0
  5. package/src/b0-app-shell/command-bar/CommandBar.svelte +565 -0
  6. package/src/b0-app-shell/index.ts +14 -0
  7. package/src/base.css +152 -0
  8. package/src/d0-data-viz/BarChart.svelte +236 -0
  9. package/src/d0-data-viz/CheckpointBar.svelte +574 -0
  10. package/src/d0-data-viz/CheckpointPill.svelte +297 -0
  11. package/src/d0-data-viz/MetricCard.svelte +159 -0
  12. package/src/d0-data-viz/SparkLine.svelte +66 -0
  13. package/src/d0-data-viz/StorageMap.svelte +182 -0
  14. package/src/d0-data-viz/Timeline.svelte +188 -0
  15. package/src/d0-data-viz/checkpoint-types.ts +162 -0
  16. package/src/d0-data-viz/d0-tokens.css +32 -0
  17. package/src/d0-data-viz/index.ts +58 -0
  18. package/src/d0-data-viz/storage-map-types.ts +142 -0
  19. package/src/d0-data-viz/theme-integration.ts +134 -0
  20. package/src/d0-data-viz/types.ts +53 -0
  21. package/src/demos/BspSizingInfographic.svelte +386 -0
  22. package/src/demos/BspZoneDemo.svelte +255 -0
  23. package/src/demos/ControlRoomDemo.svelte +570 -0
  24. package/src/demos/NodepadBlocksShowcase.svelte +189 -0
  25. package/src/demos/index.ts +7 -0
  26. package/src/editor/CodeEditor.svelte +188 -0
  27. package/src/editor/FindReplaceDialog.svelte +516 -0
  28. package/src/editor/MarkdownEditor.svelte +660 -0
  29. package/src/editor/index.ts +2 -0
  30. package/src/entity-graph-view/WorldView.svelte +171 -0
  31. package/src/entity-graph-view/index.ts +6 -0
  32. package/src/entity-graph-view/types.ts +364 -0
  33. package/src/epistemic/index.ts +2 -0
  34. package/src/epistemic/types.ts +134 -0
  35. package/src/epistemic/utils.ts +32 -0
  36. package/src/f0-forms/checkbox/Checkbox.svelte +158 -0
  37. package/src/f0-forms/field/FormField.svelte +91 -0
  38. package/src/f0-forms/index.ts +11 -0
  39. package/src/f0-forms/radio/RadioGroup.svelte +192 -0
  40. package/src/f0-forms/search/SearchBar.svelte +99 -0
  41. package/src/f0-forms/select/Select.svelte +198 -0
  42. package/src/f0-forms/textarea/TextArea.svelte +170 -0
  43. package/src/f0-forms/toggle/FormToggle.svelte +147 -0
  44. package/src/f0-forms/validation/validate.ts +47 -0
  45. package/src/fabric/ai/ChatPanel.svelte +648 -0
  46. package/src/fabric/ai/index.ts +11 -0
  47. package/src/fabric/data/index.ts +21 -0
  48. package/src/fabric/feedback/StatusBar.svelte +274 -0
  49. package/src/fabric/feedback/ToastContainer.svelte +122 -0
  50. package/src/fabric/feedback/index.ts +14 -0
  51. package/src/fabric/index.ts +37 -0
  52. package/src/fabric/input/CommandBar.svelte +79 -0
  53. package/src/fabric/input/KeyboardShortcuts.svelte +388 -0
  54. package/src/fabric/input/index.ts +12 -0
  55. package/src/fabric/layout/GlassBox.svelte +193 -0
  56. package/src/fabric/layout/KanbanBoard.svelte +158 -0
  57. package/src/fabric/layout/KanbanCard.svelte +226 -0
  58. package/src/fabric/layout/KanbanColumn.svelte +278 -0
  59. package/src/fabric/layout/index.ts +17 -0
  60. package/src/fabric/navigation/ActivityRail.svelte +271 -0
  61. package/src/fabric/navigation/index.ts +11 -0
  62. package/src/g0-geo/SovereignMap.svelte +149 -0
  63. package/src/g0-geo/index.ts +2 -0
  64. package/src/index.ts +68 -0
  65. package/src/l0-layout/block-writer/BlockConnectionLines.svelte +98 -0
  66. package/src/l0-layout/block-writer/BlockContent.svelte +213 -0
  67. package/src/l0-layout/block-writer/BlockHeader.svelte +230 -0
  68. package/src/l0-layout/block-writer/BlockItem.svelte +177 -0
  69. package/src/l0-layout/block-writer/BlockWriter.svelte +219 -0
  70. package/src/l0-layout/block-writer/block-writer-types.ts +63 -0
  71. package/src/l0-layout/block-writer/index.ts +24 -0
  72. package/src/l0-layout/block-writer/markdown.ts +110 -0
  73. package/src/l0-layout/chat-view/ChatViewLayout.svelte +61 -0
  74. package/src/l0-layout/epistemic/AllayDetailPanel.svelte +113 -0
  75. package/src/l0-layout/epistemic/AssayDetailPanel.svelte +164 -0
  76. package/src/l0-layout/epistemic/AvenueTrace.svelte +253 -0
  77. package/src/l0-layout/epistemic/KnowledgeDetailPanel.svelte +204 -0
  78. package/src/l0-layout/epistemic/ParadigmLens.svelte +170 -0
  79. package/src/l0-layout/epistemic/ProvenanceChain.svelte +164 -0
  80. package/src/l0-layout/epistemic/TrustView.svelte +195 -0
  81. package/src/l0-layout/epistemic/index.ts +7 -0
  82. package/src/l0-layout/grove/AccordCard.svelte +156 -0
  83. package/src/l0-layout/grove/GroveCard.svelte +197 -0
  84. package/src/l0-layout/grove/MemberBadge.svelte +96 -0
  85. package/src/l0-layout/grove/MemberList.svelte +59 -0
  86. package/src/l0-layout/grove/grove-types.ts +29 -0
  87. package/src/l0-layout/grove/index.ts +14 -0
  88. package/src/l0-layout/index.ts +45 -0
  89. package/src/l0-layout/kanban/KanbanBoard.svelte +71 -0
  90. package/src/l0-layout/kanban/KanbanCard.svelte +276 -0
  91. package/src/l0-layout/kanban/KanbanColumn.svelte +198 -0
  92. package/src/l0-layout/kanban/KanbanViewLayout.svelte +61 -0
  93. package/src/l0-layout/workspace/WorkspaceLayout.svelte +93 -0
  94. package/src/n0-node-graph/GraphEditor.svelte +342 -0
  95. package/src/n0-node-graph/GraphHistory.svelte +122 -0
  96. package/src/n0-node-graph/Node.svelte +269 -0
  97. package/src/n0-node-graph/NodeCanvas.svelte +187 -0
  98. package/src/n0-node-graph/NodeEdge.svelte +152 -0
  99. package/src/n0-node-graph/NodePalette.svelte +318 -0
  100. package/src/n0-node-graph/NodePort.svelte +128 -0
  101. package/src/n0-node-graph/index.ts +33 -0
  102. package/src/n0-node-graph/n0-tokens.css +29 -0
  103. package/src/n0-node-graph/node-port-types.ts +19 -0
  104. package/src/n0-node-graph/types.ts +96 -0
  105. package/src/n0-node-graph/validate.test.ts +722 -0
  106. package/src/n0-node-graph/validate.ts +371 -0
  107. package/src/n1-flow-canvas/FlowCanvas.svelte +202 -0
  108. package/src/n1-flow-canvas/graph-state.svelte.ts +95 -0
  109. package/src/n1-flow-canvas/index.ts +21 -0
  110. package/src/n1-flow-canvas/layout.ts +118 -0
  111. package/src/n1-flow-canvas/layout.worker.ts +128 -0
  112. package/src/n1-flow-canvas/types.ts +102 -0
  113. package/src/n1-flow-canvas/utils.ts +146 -0
  114. package/src/n2-manifold-disk/ManifoldDisk.svelte +314 -0
  115. package/src/n2-manifold-disk/index.ts +6 -0
  116. package/src/n2-manifold-disk/poincare.ts +184 -0
  117. package/src/n3-force-graph/ForceGraph.svelte +180 -0
  118. package/src/n3-force-graph/GraphTooltip.svelte +99 -0
  119. package/src/n3-force-graph/animated-edge.ts +107 -0
  120. package/src/n3-force-graph/health-node.ts +128 -0
  121. package/src/n3-force-graph/index.ts +31 -0
  122. package/src/n3-force-graph/types.ts +94 -0
  123. package/src/n4-adaptive-manifold/AdaptiveManifold.svelte +1165 -0
  124. package/src/n4-adaptive-manifold/DetailCard.svelte +212 -0
  125. package/src/n4-adaptive-manifold/SuggestionIndicator.svelte +91 -0
  126. package/src/n4-adaptive-manifold/classifier.ts +139 -0
  127. package/src/n4-adaptive-manifold/index.ts +45 -0
  128. package/src/n4-adaptive-manifold/n4-tokens.css +155 -0
  129. package/src/n4-adaptive-manifold/orchestrator.ts +301 -0
  130. package/src/n4-adaptive-manifold/phase-theme.ts +92 -0
  131. package/src/n4-adaptive-manifold/pinnacle-events.ts +135 -0
  132. package/src/n4-adaptive-manifold/providers/gravitational-provider.ts +191 -0
  133. package/src/n4-adaptive-manifold/providers/manifold-provider.ts +276 -0
  134. package/src/n4-adaptive-manifold/transition.ts +90 -0
  135. package/src/n4-adaptive-manifold/types.ts +313 -0
  136. package/src/p0-primitives/index.ts +6 -0
  137. package/src/p0-primitives/tokens/control-room.css +309 -0
  138. package/src/p0-primitives/tokens/index.ts +6 -0
  139. package/src/p0-primitives/tokens/tokens.css +140 -0
  140. package/src/p0-primitives/tokens/tokens.json +132 -0
  141. package/src/p0-primitives/types/index.ts +123 -0
  142. package/src/p0-primitives/types/plugin-types.ts +74 -0
  143. package/src/p0-primitives/utils/index.ts +39 -0
  144. package/src/platform/hud-protocol.ts +20 -0
  145. package/src/platform/index.ts +3 -0
  146. package/src/s0-state/create-store.ts +84 -0
  147. package/src/s0-state/derived.ts +41 -0
  148. package/src/s0-state/index.ts +6 -0
  149. package/src/showcase/Showcase.svelte +401 -0
  150. package/src/spatial/BspTilingCanvas.svelte +232 -0
  151. package/src/spatial/ForceCanvas.svelte +289 -0
  152. package/src/spatial/LodRenderer.svelte +334 -0
  153. package/src/spatial/SnapZoomCamera.svelte +185 -0
  154. package/src/spatial/ZoneTiler.svelte +311 -0
  155. package/src/spatial/camera-types.ts +45 -0
  156. package/src/spatial/content-proportional-bsp.ts +253 -0
  157. package/src/spatial/force-canvas-types.ts +102 -0
  158. package/src/spatial/index.ts +15 -0
  159. package/src/spatial/lod-types.ts +70 -0
  160. package/src/spatial/zone-tiler-types.ts +177 -0
  161. package/src/stores/vaultStore.svelte +14 -0
  162. package/src/t0-transport/connection.ts +34 -0
  163. package/src/t0-transport/error.ts +37 -0
  164. package/src/t0-transport/events.ts +50 -0
  165. package/src/t0-transport/index.ts +6 -0
  166. package/src/t0-transport/invoke.ts +30 -0
  167. package/src/tauri/index.ts +13 -0
  168. package/src/u0-primitives/allay-gauge/AllayGauge.svelte +90 -0
  169. package/src/u0-primitives/allay-gauge/index.ts +1 -0
  170. package/src/u0-primitives/animated-icon/AnimatedIcon.svelte +273 -0
  171. package/src/u0-primitives/animated-icon/README.md +53 -0
  172. package/src/u0-primitives/animated-icon/index.ts +31 -0
  173. package/src/u0-primitives/assay-badge/AssayBadge.svelte +121 -0
  174. package/src/u0-primitives/assay-badge/AssaySignalBar.svelte +83 -0
  175. package/src/u0-primitives/assay-badge/index.ts +2 -0
  176. package/src/u0-primitives/avatar/Avatar.svelte +177 -0
  177. package/src/u0-primitives/badge/Badge.svelte +149 -0
  178. package/src/u0-primitives/button/Button.svelte +304 -0
  179. package/src/u0-primitives/card/Card.svelte +182 -0
  180. package/src/u0-primitives/dropdown/Dropdown.svelte +305 -0
  181. package/src/u0-primitives/expert-badge/ExpertBadge.svelte +89 -0
  182. package/src/u0-primitives/expert-badge/index.ts +1 -0
  183. package/src/u0-primitives/index.ts +35 -0
  184. package/src/u0-primitives/input/Input.svelte +237 -0
  185. package/src/u0-primitives/modal/Modal.svelte +331 -0
  186. package/src/u0-primitives/modal/index.ts +1 -0
  187. package/src/u0-primitives/spinner/Spinner.svelte +129 -0
  188. package/src/u0-primitives/tabs/Tabs.svelte +225 -0
  189. package/src/u0-primitives/tabs/tabs-types.ts +11 -0
  190. package/src/u0-primitives/toggle/Toggle.svelte +161 -0
  191. package/src/u0-primitives/tooltip/Tooltip.svelte +234 -0
  192. package/src/v0-diagrams/DiagramPanel.svelte +68 -0
  193. package/src/v0-diagrams/MarkmapDiagram.svelte +56 -0
  194. package/src/v0-diagrams/MermaidDiagram.svelte +53 -0
  195. package/src/v0-diagrams/index.ts +4 -0
  196. package/src/v0-diagrams/types.ts +28 -0
  197. package/src/v0-diagrams/v0-tokens.css +6 -0
  198. package/src/vite-env.d.ts +7 -0
  199. package/src/x0-enchanted-blocks/ENCHANTED_BLOCKS_SPEC.md +457 -0
  200. package/src/x0-enchanted-blocks/components/EnchantedBlock.svelte +485 -0
  201. package/src/x0-enchanted-blocks/components/NodepadBlock.svelte +262 -0
  202. package/src/x0-enchanted-blocks/core/block-layout.ts +211 -0
  203. package/src/x0-enchanted-blocks/core/block-types.ts +227 -0
  204. package/src/x0-enchanted-blocks/index.ts +46 -0
@@ -0,0 +1,188 @@
1
+ <script lang="ts">
2
+ import type { TimelineEntry } from './types';
3
+
4
+ interface TimelineComponentProps {
5
+ entries: TimelineEntry[];
6
+ orientation?: 'horizontal' | 'vertical';
7
+ 'aria-label'?: string;
8
+ }
9
+
10
+ let {
11
+ entries,
12
+ orientation = 'vertical',
13
+ 'aria-label': ariaLabel = 'Timeline',
14
+ }: TimelineComponentProps = $props();
15
+
16
+ const DOT_RADIUS = 6;
17
+ const VERTICAL_SPACING = 80;
18
+ const HORIZONTAL_SPACING = 160;
19
+ const PADDING = 24;
20
+
21
+ let svgWidth = $derived(
22
+ orientation === 'horizontal'
23
+ ? PADDING * 2 + entries.length * HORIZONTAL_SPACING
24
+ : 320
25
+ );
26
+
27
+ let svgHeight = $derived(
28
+ orientation === 'vertical'
29
+ ? PADDING * 2 + entries.length * VERTICAL_SPACING
30
+ : 120
31
+ );
32
+ </script>
33
+
34
+ <svg
35
+ class="d0-timeline"
36
+ class:horizontal={orientation === 'horizontal'}
37
+ viewBox="0 0 {svgWidth} {svgHeight}"
38
+ xmlns="http://www.w3.org/2000/svg"
39
+ role="img"
40
+ aria-label={ariaLabel}
41
+ >
42
+ <!-- Connecting line -->
43
+ {#if entries.length > 1}
44
+ {#if orientation === 'vertical'}
45
+ <line
46
+ class="d0-timeline-line"
47
+ x1={PADDING + DOT_RADIUS}
48
+ y1={PADDING}
49
+ x2={PADDING + DOT_RADIUS}
50
+ y2={PADDING + (entries.length - 1) * VERTICAL_SPACING}
51
+ />
52
+ {:else}
53
+ <line
54
+ class="d0-timeline-line"
55
+ x1={PADDING}
56
+ y1={PADDING + DOT_RADIUS + 20}
57
+ x2={PADDING + (entries.length - 1) * HORIZONTAL_SPACING}
58
+ y2={PADDING + DOT_RADIUS + 20}
59
+ />
60
+ {/if}
61
+ {/if}
62
+
63
+ <!-- Entries -->
64
+ {#each entries as entry, i (entry.id)}
65
+ {#if orientation === 'vertical'}
66
+ {@const cy = PADDING + i * VERTICAL_SPACING}
67
+ {@const cx = PADDING + DOT_RADIUS}
68
+
69
+ <!-- Dot -->
70
+ <circle
71
+ class="d0-timeline-dot"
72
+ cx={cx}
73
+ cy={cy}
74
+ r={DOT_RADIUS}
75
+ fill={entry.color ?? undefined}
76
+ >
77
+ <title>{entry.timestamp}</title>
78
+ </circle>
79
+
80
+ <!-- Label -->
81
+ <text
82
+ class="d0-timeline-label"
83
+ x={cx + DOT_RADIUS + 12}
84
+ y={cy - 4}
85
+ dominant-baseline="auto"
86
+ >
87
+ {entry.label}
88
+ </text>
89
+
90
+ <!-- Timestamp -->
91
+ <text
92
+ class="d0-timeline-timestamp"
93
+ x={cx + DOT_RADIUS + 12}
94
+ y={cy + 14}
95
+ dominant-baseline="auto"
96
+ >
97
+ {entry.timestamp}
98
+ </text>
99
+
100
+ <!-- Description -->
101
+ {#if entry.description}
102
+ <text
103
+ class="d0-timeline-desc"
104
+ x={cx + DOT_RADIUS + 12}
105
+ y={cy + 30}
106
+ dominant-baseline="auto"
107
+ >
108
+ {entry.description}
109
+ </text>
110
+ {/if}
111
+ {:else}
112
+ {@const cx = PADDING + i * HORIZONTAL_SPACING}
113
+ {@const cy = PADDING + DOT_RADIUS + 20}
114
+
115
+ <!-- Dot -->
116
+ <circle
117
+ class="d0-timeline-dot"
118
+ cx={cx}
119
+ cy={cy}
120
+ r={DOT_RADIUS}
121
+ fill={entry.color ?? undefined}
122
+ >
123
+ <title>{entry.timestamp}</title>
124
+ </circle>
125
+
126
+ <!-- Label (above line) -->
127
+ <text
128
+ class="d0-timeline-label"
129
+ x={cx}
130
+ y={cy - DOT_RADIUS - 8}
131
+ text-anchor="middle"
132
+ >
133
+ {entry.label}
134
+ </text>
135
+
136
+ <!-- Timestamp (below line) -->
137
+ <text
138
+ class="d0-timeline-timestamp"
139
+ x={cx}
140
+ y={cy + DOT_RADIUS + 18}
141
+ text-anchor="middle"
142
+ >
143
+ {entry.timestamp}
144
+ </text>
145
+ {/if}
146
+ {/each}
147
+ </svg>
148
+
149
+ <style>
150
+ .d0-timeline {
151
+ display: block;
152
+ width: 100%;
153
+ height: auto;
154
+ }
155
+
156
+ .d0-timeline-line {
157
+ stroke: var(--d0-timeline-line, rgba(184, 115, 51, 0.3));
158
+ stroke-width: 2;
159
+ }
160
+
161
+ .d0-timeline-dot {
162
+ fill: var(--d0-timeline-dot, #b87333);
163
+ transition: r 150ms ease;
164
+ }
165
+
166
+ .d0-timeline-dot:hover {
167
+ r: 8;
168
+ }
169
+
170
+ .d0-timeline-label {
171
+ fill: var(--color-text-primary, #e8e0d0);
172
+ font-family: var(--font-sans, system-ui, sans-serif);
173
+ font-size: 13px;
174
+ font-weight: 500;
175
+ }
176
+
177
+ .d0-timeline-timestamp {
178
+ fill: var(--d0-chart-text, #a09880);
179
+ font-family: var(--font-sans, system-ui, sans-serif);
180
+ font-size: 10px;
181
+ }
182
+
183
+ .d0-timeline-desc {
184
+ fill: var(--d0-chart-text, #a09880);
185
+ font-family: var(--font-sans, system-ui, sans-serif);
186
+ font-size: 11px;
187
+ }
188
+ </style>
@@ -0,0 +1,162 @@
1
+ // D0 Data Viz — Checkpoint Timeline Types
2
+ // Pure TypeScript — no Svelte, no DOM dependencies
3
+ // ADR: ui-timeline-checkpoint-bar-001
4
+
5
+ // === Checkpoint Types ===
6
+
7
+ /** Component types for color coding per ADR spec */
8
+ export type CheckpointComponentType =
9
+ | 'rust-crate'
10
+ | 'ui-bundle'
11
+ | 'config'
12
+ | 'faculty-state'
13
+ | 'substrate-binary'
14
+ | 'system-snapshot';
15
+
16
+ /** Checkpoint status visual encoding */
17
+ export type CheckpointStatus = 'committed' | 'system' | 'proposed' | 'partial';
18
+
19
+ /** A single checkpoint entry on the timeline */
20
+ export interface Checkpoint {
21
+ /** Unique sequence number (seqno per sigchain) */
22
+ seqno: number;
23
+ /** Human-readable identifier */
24
+ id: string;
25
+ /** Component name (e.g., "ryu-hamiltonian-panel") */
26
+ component: string;
27
+ /** Component type for color coding */
28
+ componentType: CheckpointComponentType;
29
+ /** Checkpoint status for visual encoding */
30
+ status: CheckpointStatus;
31
+ /** Version transition (optional) */
32
+ version?: {
33
+ from: string;
34
+ to: string;
35
+ };
36
+ /** Author identifier */
37
+ author?: string;
38
+ /** Associated task ID */
39
+ taskId?: string;
40
+ /** Human description */
41
+ description: string;
42
+ /** Timestamp as sequence number reference */
43
+ timestamp: number;
44
+ }
45
+
46
+ /** Color mapping — references CSS custom properties set by themeStore */
47
+ export const CHECKPOINT_COLORS: Record<CheckpointComponentType, string> = {
48
+ 'rust-crate': 'var(--d0-checkpoint-rust)',
49
+ 'ui-bundle': 'var(--d0-checkpoint-ui)',
50
+ 'config': 'var(--d0-checkpoint-config)',
51
+ 'faculty-state': 'var(--d0-checkpoint-faculty)',
52
+ 'substrate-binary': 'var(--d0-checkpoint-substrate)',
53
+ 'system-snapshot': 'var(--d0-checkpoint-aggregate)',
54
+ };
55
+
56
+ /** Get checkpoint color with fallback for when CSS vars aren't set */
57
+ export function getCheckpointColor(type: CheckpointComponentType, isDark = true): string {
58
+ const fallbacks: Record<CheckpointComponentType, { light: string; dark: string }> = {
59
+ 'rust-crate': { light: '#8a5a28', dark: '#b87333' },
60
+ 'ui-bundle': { light: '#2d6b6e', dark: '#5f9ea0' },
61
+ 'config': { light: '#7c6fae', dark: '#a99fd6' },
62
+ 'faculty-state': { light: '#d4a03d', dark: '#e6c470' },
63
+ 'substrate-binary': { light: '#c75a5a', dark: '#d98a8a' },
64
+ 'system-snapshot': { light: '#6b7280', dark: '#9ca3af' },
65
+ };
66
+ return fallbacks[type][isDark ? 'dark' : 'light'];
67
+ }
68
+
69
+ /** Visual encoding for checkpoint status */
70
+ export const CHECKPOINT_STATUS_SYMBOLS: Record<CheckpointStatus, string> = {
71
+ 'committed': '◉', // Filled circle
72
+ 'system': '◎', // Double-ring circle
73
+ 'proposed': '○', // Hollow circle
74
+ 'partial': '◐', // Half-filled
75
+ };
76
+
77
+ // === Checkpoint Bar Props ===
78
+
79
+ export interface CheckpointBarProps {
80
+ checkpoints: Checkpoint[];
81
+ currentSeqno: number;
82
+ previewSeqno?: number | null;
83
+ onCheckpointClick?: (checkpoint: Checkpoint) => void;
84
+ onCheckpointDoubleClick?: (checkpoint: Checkpoint) => void;
85
+ /** Callback when "Now" handle is dragged (seqno target) */
86
+ onNowHandleDrag?: (seqno: number) => void;
87
+ /** Callback when exiting preview mode */
88
+ onExitPreview?: () => void;
89
+ 'aria-label'?: string;
90
+ }
91
+
92
+ // === Preview Mode ===
93
+
94
+ export interface PreviewState {
95
+ seqno: number;
96
+ checkpoint: Checkpoint;
97
+ isReadOnly: boolean;
98
+ }
99
+
100
+ export interface RollbackConfirmation {
101
+ targetSeqno: number;
102
+ targetCheckpoint: Checkpoint;
103
+ currentSeqno: number;
104
+ affectedComponents: string[];
105
+ archivedConversations: number;
106
+ }
107
+
108
+ // === Keyboard Navigation ===
109
+
110
+ export interface KeyboardNavigationState {
111
+ focusedIndex: number;
112
+ isPreviewMode: boolean;
113
+ }
114
+
115
+ /** Keyboard action mapping per ADR accessibility spec */
116
+ export const CHECKPOINT_KEYBOARD_ACTIONS = {
117
+ ArrowLeft: 'navigate-prev',
118
+ ArrowRight: 'navigate-next',
119
+ Enter: 'preview',
120
+ 'Shift+Enter': 'rollback',
121
+ Escape: 'exit-preview',
122
+ Home: 'jump-genesis',
123
+ End: 'jump-now',
124
+ } as const;
125
+
126
+ export type CheckpointKeyboardAction =
127
+ typeof CHECKPOINT_KEYBOARD_ACTIONS[keyof typeof CHECKPOINT_KEYBOARD_ACTIONS];
128
+
129
+ // === Store Interface (Framework Agnostic) ===
130
+
131
+ export interface TimelineStoreState {
132
+ checkpoints: Checkpoint[];
133
+ currentSeqno: number;
134
+ previewSeqno: number | null;
135
+ isScrubbing: boolean;
136
+ visibleRange: { start: number; end: number };
137
+ }
138
+
139
+ export interface TimelineStoreActions {
140
+ scrubTo(seqno: number): Promise<void>;
141
+ exitPreview(): void;
142
+ rollbackTo(seqno: number): Promise<RollbackResult>;
143
+ navigateToCheckpoint(index: number): void;
144
+ }
145
+
146
+ export interface RollbackResult {
147
+ success: boolean;
148
+ newSeqno?: number;
149
+ error?: string;
150
+ }
151
+
152
+ // === Lazy Loading Constants ===
153
+
154
+ /** Number of checkpoints to keep in memory (per ADR performance spec) */
155
+ export const VISIBLE_CHECKPOINTS = 50;
156
+
157
+ /** Checkpoint bar height in pixels (ADR spec: 48px) */
158
+ export const CHECKPOINT_BAR_HEIGHT = 48;
159
+
160
+ /** Node sizes for visual encoding */
161
+ export const CHECKPOINT_NODE_SIZE = 12;
162
+ export const CHECKPOINT_NODE_ACTIVE_SIZE = 16;
@@ -0,0 +1,32 @@
1
+ /* D0 Data Viz — CSS Design Tokens */
2
+ :root {
3
+ /* Chart */
4
+ --d0-chart-bg: var(--color-bg-panel, #222);
5
+ --d0-chart-grid: rgba(184, 115, 51, 0.1);
6
+ --d0-chart-text: var(--color-text-muted, #a09880);
7
+ --d0-chart-accent: var(--color-accent, #b87333);
8
+
9
+ /* Metric */
10
+ --d0-metric-trend-up: var(--color-success, #27ae60);
11
+ --d0-metric-trend-down: var(--color-error, #c0392b);
12
+
13
+ /* Timeline */
14
+ --d0-timeline-line: rgba(184, 115, 51, 0.3);
15
+ --d0-timeline-dot: var(--color-accent, #b87333);
16
+
17
+ /* CheckpointBar (ADR: ui-timeline-checkpoint-bar-001) */
18
+ --d0-checkpoint-bar-height: 48px;
19
+ --d0-checkpoint-node-size: 12px;
20
+ --d0-checkpoint-node-active-size: 16px;
21
+ --d0-checkpoint-line-color: rgba(184, 115, 51, 0.3);
22
+ --d0-checkpoint-tooltip-bg: rgba(34, 34, 34, 0.98);
23
+ --d0-checkpoint-tooltip-border: rgba(184, 115, 51, 0.3);
24
+
25
+ /* Checkpoint Colors by Component Type */
26
+ --d0-checkpoint-brass: #b87333;
27
+ --d0-checkpoint-teal: #5f9ea0;
28
+ --d0-checkpoint-gold: #daa520;
29
+ --d0-checkpoint-purple: #9370db;
30
+ --d0-checkpoint-red: #cd5c5c;
31
+ --d0-checkpoint-gray: #2f4f4f;
32
+ }
@@ -0,0 +1,58 @@
1
+ // D0 Data Viz — Barrel Export
2
+
3
+ // Types
4
+ export type {
5
+ DataPoint,
6
+ DataSeries,
7
+ ChartProps,
8
+ MetricCardProps,
9
+ TimelineEntry,
10
+ TimelineProps,
11
+ } from './types';
12
+
13
+ // Checkpoint Types (ADR: ui-timeline-checkpoint-bar-001)
14
+ export type {
15
+ Checkpoint,
16
+ CheckpointComponentType,
17
+ CheckpointStatus,
18
+ CheckpointBarProps,
19
+ PreviewState,
20
+ RollbackConfirmation,
21
+ RollbackResult,
22
+ TimelineStoreState,
23
+ TimelineStoreActions,
24
+ KeyboardNavigationState,
25
+ CheckpointKeyboardAction,
26
+ } from './checkpoint-types';
27
+ export {
28
+ CHECKPOINT_COLORS,
29
+ CHECKPOINT_STATUS_SYMBOLS,
30
+ CHECKPOINT_KEYBOARD_ACTIONS,
31
+ VISIBLE_CHECKPOINTS,
32
+ CHECKPOINT_BAR_HEIGHT,
33
+ CHECKPOINT_NODE_SIZE,
34
+ CHECKPOINT_NODE_ACTIVE_SIZE,
35
+ getCheckpointColor,
36
+ } from './checkpoint-types';
37
+
38
+ // StorageMap (wt:sovra-1115)
39
+ export type { StorageNode, StorageMapConfig, TreemapCell, TreemapLayout, OwnerTier } from './storage-map-types';
40
+ export { computeTreemap, formatBytes, TIER_COLORS } from './storage-map-types';
41
+
42
+ // Components
43
+ export { default as BarChart } from './BarChart.svelte';
44
+ export { default as SparkLine } from './SparkLine.svelte';
45
+ export { default as MetricCard } from './MetricCard.svelte';
46
+ export { default as Timeline } from './Timeline.svelte';
47
+ export { default as StorageMap } from './StorageMap.svelte';
48
+ export { default as CheckpointBar } from './CheckpointBar.svelte';
49
+ export { default as CheckpointPill } from './CheckpointPill.svelte';
50
+
51
+ // Theme Integration
52
+ export {
53
+ CHECKPOINT_CSS_VARS,
54
+ CHECKPOINT_COLOR_LABELS,
55
+ CHECKPOINT_DEFAULT_COLORS,
56
+ getEffectiveCheckpointColor,
57
+ THEME_INTEGRATION,
58
+ } from './theme-integration';
@@ -0,0 +1,142 @@
1
+ // StorageMap — BSP treemap types (wt:sovra-1115)
2
+ // S-02: No HashMap/HashSet — use sorted arrays for lookups.
3
+ // Pure TypeScript — no Svelte, no DOM.
4
+
5
+ /** Ownership tier for a storage node */
6
+ export type OwnerTier = 'kos' | 'external' | 'unknown';
7
+
8
+ /** A single storage node in the treemap */
9
+ export interface StorageNode {
10
+ path: string;
11
+ bytes: number;
12
+ ownerTier: OwnerTier;
13
+ label?: string;
14
+ children?: StorageNode[];
15
+ }
16
+
17
+ /** A flattened treemap cell ready for rendering */
18
+ export interface TreemapCell {
19
+ path: string;
20
+ label: string;
21
+ bytes: number;
22
+ ownerTier: OwnerTier;
23
+ x: number;
24
+ y: number;
25
+ width: number;
26
+ height: number;
27
+ }
28
+
29
+ /** Layout result from the squarified treemap algorithm */
30
+ export interface TreemapLayout {
31
+ cells: TreemapCell[];
32
+ totalBytes: number;
33
+ }
34
+
35
+ /** StorageMap component configuration */
36
+ export interface StorageMapConfig {
37
+ /** Minimum cell dimension in px. Default 32. */
38
+ minCellSize?: number;
39
+ /** Gap between cells in px. Default 2. */
40
+ gap?: number;
41
+ /** Show path labels inside cells. Default true. */
42
+ showLabels?: boolean;
43
+ }
44
+
45
+ /** Color palette per owner tier */
46
+ export const TIER_COLORS: Record<OwnerTier, { fill: string; stroke: string; text: string }> = {
47
+ kos: {
48
+ fill: 'rgba(184, 115, 51, 0.25)',
49
+ stroke: 'rgba(184, 115, 51, 0.6)',
50
+ text: '#d4a06a',
51
+ },
52
+ external: {
53
+ fill: 'rgba(160, 152, 128, 0.15)',
54
+ stroke: 'rgba(160, 152, 128, 0.4)',
55
+ text: '#a09880',
56
+ },
57
+ unknown: {
58
+ fill: 'rgba(90, 82, 69, 0.15)',
59
+ stroke: 'rgba(90, 82, 69, 0.3)',
60
+ text: '#706858',
61
+ },
62
+ };
63
+
64
+ // ── Squarified treemap layout ──────────────────────────────────────────────
65
+
66
+ /**
67
+ * Compute a squarified treemap layout for flat node lists.
68
+ * S-02: deterministic — sorted by bytes descending, no randomness.
69
+ * S-05: bounded — iterates finite node array.
70
+ */
71
+ export function computeTreemap(
72
+ nodes: StorageNode[],
73
+ width: number,
74
+ height: number,
75
+ config: StorageMapConfig = {}
76
+ ): TreemapLayout {
77
+ const gap = config.gap ?? 2;
78
+ const minCell = config.minCellSize ?? 32;
79
+
80
+ // Sort descending by size (deterministic, S-02)
81
+ const sorted = [...nodes].sort((a, b) => b.bytes - a.bytes);
82
+ const totalBytes = sorted.reduce((sum, n) => sum + n.bytes, 0);
83
+
84
+ if (totalBytes === 0 || sorted.length === 0) {
85
+ return { cells: [], totalBytes: 0 };
86
+ }
87
+
88
+ const cells: TreemapCell[] = [];
89
+ const aspectRatio = width / height;
90
+
91
+ // Simple slice-and-dice treemap (row-based for readability)
92
+ const usableWidth = width - gap * 2;
93
+ const usableHeight = height - gap * 2;
94
+
95
+ let x = gap;
96
+ let y = gap;
97
+ let rowHeight = usableHeight;
98
+
99
+ // Group into rows based on aspect ratio
100
+ const rowTarget = Math.max(1, Math.round(Math.sqrt(sorted.length / aspectRatio)));
101
+
102
+ for (let i = 0; i < sorted.length; i += rowTarget) {
103
+ const row = sorted.slice(i, i + rowTarget);
104
+ const rowBytes = row.reduce((sum, n) => sum + n.bytes, 0);
105
+
106
+ // Row height proportional to row's share of total
107
+ const actualRowHeight = Math.max(minCell, (rowBytes / totalBytes) * usableHeight);
108
+
109
+ let cellX = x;
110
+ for (const node of row) {
111
+ const cellWidth = Math.max(minCell, (node.bytes / rowBytes) * usableWidth);
112
+ const label = node.label ?? node.path.split('/').pop() ?? node.path;
113
+
114
+ cells.push({
115
+ path: node.path,
116
+ label,
117
+ bytes: node.bytes,
118
+ ownerTier: node.ownerTier,
119
+ x: cellX,
120
+ y,
121
+ width: cellWidth - gap,
122
+ height: actualRowHeight - gap,
123
+ });
124
+
125
+ cellX += cellWidth;
126
+ }
127
+
128
+ y += actualRowHeight;
129
+ }
130
+
131
+ return { cells, totalBytes };
132
+ }
133
+
134
+ /** Format bytes to human-readable string */
135
+ export function formatBytes(bytes: number): string {
136
+ if (bytes === 0) return '0 B';
137
+ const units = ['B', 'KB', 'MB', 'GB', 'TB'];
138
+ const i = Math.floor(Math.log2(bytes) / 10);
139
+ const clamped = Math.min(i, units.length - 1);
140
+ const value = bytes / Math.pow(1024, clamped);
141
+ return `${value.toFixed(clamped === 0 ? 0 : 1)} ${units[clamped]}`;
142
+ }