@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,219 @@
1
+ <script module lang="ts">
2
+ // Re-export types for consumer convenience
3
+ export type {
4
+ WritingBlock,
5
+ BlockConnection,
6
+ BlockWriterSchema,
7
+ BlockWriterConfig,
8
+ WritingPhase,
9
+ BlockOrigin,
10
+ SplitDirection,
11
+ } from './block-writer-types.js';
12
+ export { PHASE_CONFIG } from './block-writer-types.js';
13
+ </script>
14
+
15
+ <script lang="ts">
16
+ import type { Snippet } from 'svelte';
17
+ import type {
18
+ BlockWriterSchema,
19
+ BlockWriterConfig,
20
+ WritingBlock,
21
+ WritingPhase,
22
+ SplitDirection,
23
+ } from './block-writer-types.js';
24
+ import type { ZoneRect } from '../../spatial/zone-tiler-types.js';
25
+ import { flattenBsp } from '../../spatial/zone-tiler-types.js';
26
+ import ZoneTiler from '../../spatial/ZoneTiler.svelte';
27
+ import BlockItem from './BlockItem.svelte';
28
+ import BlockConnectionLines from './BlockConnectionLines.svelte';
29
+
30
+ // ── Props ────────────────────────────────────────────────────────────────
31
+
32
+ interface Props {
33
+ schema: BlockWriterSchema;
34
+ config?: BlockWriterConfig;
35
+ width: number;
36
+ height: number;
37
+ onSchemaChange?: (schema: BlockWriterSchema) => void;
38
+ onBlockFocus?: (blockId: string) => void;
39
+ onBlockContentChange?: (blockId: string, content: string) => void;
40
+ onBlockPhaseChange?: (blockId: string, phase: WritingPhase) => void;
41
+ onBlockAdd?: (afterBlockId: string, direction: SplitDirection) => void;
42
+ onBlockRemove?: (blockId: string) => void;
43
+ onBlockTitleChange?: (blockId: string, title: string) => void;
44
+ onBlockEditEnd?: (blockId: string) => void;
45
+ footer?: Snippet<[WritingBlock]>;
46
+ }
47
+
48
+ let {
49
+ schema,
50
+ config,
51
+ width,
52
+ height,
53
+ onSchemaChange,
54
+ onBlockFocus,
55
+ onBlockContentChange,
56
+ onBlockPhaseChange,
57
+ onBlockAdd,
58
+ onBlockRemove,
59
+ onBlockTitleChange,
60
+ onBlockEditEnd,
61
+ footer,
62
+ }: Props = $props();
63
+
64
+ // ── Computed layout ──────────────────────────────────────────────────────
65
+
66
+ const dividerThickness = $derived(config?.dividerThickness ?? 6);
67
+
68
+ const currentZones = $derived(
69
+ flattenBsp(schema.bspTree, 0, 0, width, height, dividerThickness).zones
70
+ );
71
+
72
+ // ── Local state ──────────────────────────────────────────────────────────
73
+
74
+ let focusedBlockId = $state('');
75
+ let editingBlockId: string | null = $state(null);
76
+
77
+ // Sync focus from schema prop (one-way: schema → local)
78
+ $effect(() => {
79
+ focusedBlockId = schema.focusedBlockId;
80
+ });
81
+
82
+ // ── Zone content lookup ──────────────────────────────────────────────────
83
+
84
+ function getBlockForZone(zoneId: string): WritingBlock | undefined {
85
+ return schema.blocks.find(b => b.id === zoneId);
86
+ }
87
+
88
+ // ── Event handlers ───────────────────────────────────────────────────────
89
+
90
+ function handleFocusChange(zoneId: string) {
91
+ focusedBlockId = zoneId;
92
+ editingBlockId = null;
93
+ onBlockFocus?.(zoneId);
94
+ }
95
+
96
+ function handleResize(tree: typeof schema.bspTree) {
97
+ onSchemaChange?.({ ...schema, bspTree: tree });
98
+ }
99
+
100
+ function handleSplitRequest(zoneId: string, direction: SplitDirection) {
101
+ onBlockAdd?.(zoneId, direction);
102
+ }
103
+
104
+ function handleEditStart(blockId: string) {
105
+ editingBlockId = blockId;
106
+ focusedBlockId = blockId;
107
+ }
108
+
109
+ function handleEditEnd(blockId: string) {
110
+ if (editingBlockId === blockId) {
111
+ editingBlockId = null;
112
+ onBlockEditEnd?.(blockId);
113
+ }
114
+ }
115
+
116
+ function handleContentChange(blockId: string, content: string) {
117
+ onBlockContentChange?.(blockId, content);
118
+ }
119
+
120
+ function handlePhaseChange(blockId: string, phase: WritingPhase) {
121
+ onBlockPhaseChange?.(blockId, phase);
122
+ }
123
+
124
+ function handleSplit(blockId: string, direction: SplitDirection) {
125
+ onBlockAdd?.(blockId, direction);
126
+ }
127
+
128
+ function handleDelete(blockId: string) {
129
+ onBlockRemove?.(blockId);
130
+ }
131
+
132
+ function handleTitleChange(blockId: string, title: string) {
133
+ onBlockTitleChange?.(blockId, title);
134
+ }
135
+
136
+ // ── Keyboard shortcuts ───────────────────────────────────────────────────
137
+
138
+ function handleKeydown(e: KeyboardEvent) {
139
+ if (!focusedBlockId) return;
140
+
141
+ // Enter: start editing focused block (when not already editing)
142
+ if (e.key === 'Enter' && !editingBlockId && !e.ctrlKey && !e.metaKey) {
143
+ e.preventDefault();
144
+ editingBlockId = focusedBlockId;
145
+ return;
146
+ }
147
+
148
+ // Escape: exit editing
149
+ if (e.key === 'Escape' && editingBlockId) {
150
+ e.preventDefault();
151
+ editingBlockId = null;
152
+ return;
153
+ }
154
+ }
155
+
156
+ // ── ZoneTiler config ─────────────────────────────────────────────────────
157
+
158
+ const tilerConfig = $derived({
159
+ minZoneSize: config?.minBlockHeight ?? 80,
160
+ dividerThickness,
161
+ });
162
+ </script>
163
+
164
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
165
+ <div
166
+ class="ds-block-writer"
167
+ style:width="{width}px"
168
+ style:height="{height}px"
169
+ onkeydown={handleKeydown}
170
+ >
171
+ <!-- ZoneTiler: BSP layout where each zone = one block -->
172
+ <ZoneTiler
173
+ tree={schema.bspTree}
174
+ {width}
175
+ {height}
176
+ config={tilerConfig}
177
+ bind:focusedZoneId={focusedBlockId}
178
+ onResize={handleResize}
179
+ onFocusChange={handleFocusChange}
180
+ onSplitRequest={handleSplitRequest}
181
+ >
182
+ {#snippet zoneContent(zone: ZoneRect)}
183
+ {@const block = getBlockForZone(zone.id)}
184
+ {#if block}
185
+ <BlockItem
186
+ {block}
187
+ zoneRect={zone}
188
+ isFocused={zone.id === focusedBlockId}
189
+ isEditing={zone.id === editingBlockId}
190
+ allowHorizontalSplit={config?.allowHorizontalSplit ?? true}
191
+ onEditStart={handleEditStart}
192
+ onEditEnd={handleEditEnd}
193
+ onContentChange={handleContentChange}
194
+ onPhaseChange={handlePhaseChange}
195
+ onSplit={handleSplit}
196
+ onDelete={handleDelete}
197
+ onTitleChange={handleTitleChange}
198
+ {footer}
199
+ />
200
+ {/if}
201
+ {/snippet}
202
+ </ZoneTiler>
203
+
204
+ <!-- Connection lines SVG overlay -->
205
+ <BlockConnectionLines
206
+ connections={schema.connections}
207
+ zones={currentZones}
208
+ {focusedBlockId}
209
+ />
210
+ </div>
211
+
212
+ <style>
213
+ .ds-block-writer {
214
+ position: relative;
215
+ overflow: hidden;
216
+ background: var(--color-bg-app, #1a1a1a);
217
+ border-radius: var(--radius-md, 8px);
218
+ }
219
+ </style>
@@ -0,0 +1,63 @@
1
+ // BlockWriter — data model types
2
+ // Pure TypeScript — no Svelte, no DOM.
3
+ //
4
+ // WritingPhase is intentionally a subset of Ryu FlowColumn.
5
+ // Writing doesn't need WEED, CONSULT, or PRUNE — those are task-management phases.
6
+
7
+ import type { BspNode } from '../../spatial/zone-tiler-types.js';
8
+ export type { SplitDirection } from '../../spatial/zone-tiler-types.js';
9
+
10
+ /** Writing lifecycle — subset of Ryu FlowColumn */
11
+ export type WritingPhase = 'seed' | 'sprout' | 'go' | 'freeze' | 'compost';
12
+
13
+ /** Block origin — local equivalent of CardOrigin (no cross-package import) */
14
+ export type BlockOrigin = 'authored' | 'ingested' | 'sovereign';
15
+
16
+ /** A single writing block */
17
+ export interface WritingBlock {
18
+ id: string;
19
+ title: string;
20
+ content: string;
21
+ phase: WritingPhase;
22
+ tags: string[];
23
+ links: string[];
24
+ annotation?: string;
25
+ file_path?: string;
26
+ origin: BlockOrigin;
27
+ created_at: number;
28
+ last_edited_at: number;
29
+ }
30
+
31
+ /** Connection between two blocks */
32
+ export interface BlockConnection {
33
+ fromId: string;
34
+ toId: string;
35
+ label?: string;
36
+ }
37
+
38
+ /** Full schema — controlled state passed to BlockWriter */
39
+ export interface BlockWriterSchema {
40
+ blocks: WritingBlock[];
41
+ bspTree: BspNode;
42
+ connections: BlockConnection[];
43
+ focusedBlockId: string;
44
+ }
45
+
46
+ /** BlockWriter configuration */
47
+ export interface BlockWriterConfig {
48
+ /** Min block height in px. Default 80. */
49
+ minBlockHeight?: number;
50
+ /** Divider thickness in px. Default 6. (passed to ZoneTiler) */
51
+ dividerThickness?: number;
52
+ /** Allow horizontal splits (side-by-side blocks). Default true. */
53
+ allowHorizontalSplit?: boolean;
54
+ }
55
+
56
+ /** Phase display config — maps to Badge color variant */
57
+ export const PHASE_CONFIG: Record<WritingPhase, { label: string; color: 'warning' | 'info' | 'success' | 'accent' | 'neutral' }> = {
58
+ seed: { label: 'Seed', color: 'warning' },
59
+ sprout: { label: 'Sprout', color: 'info' },
60
+ go: { label: 'Go', color: 'success' },
61
+ freeze: { label: 'Freeze', color: 'accent' },
62
+ compost: { label: 'Compost', color: 'neutral' },
63
+ };
@@ -0,0 +1,24 @@
1
+ // BlockWriter — layout composition for visual block-based writing
2
+ // Controlled component — no internal store. Consumers own state.
3
+ // Uses ZoneTiler (BSP) for layout, contenteditable for inline editing.
4
+
5
+ export { default as BlockWriter } from './BlockWriter.svelte';
6
+ export { default as BlockItem } from './BlockItem.svelte';
7
+ export { default as BlockHeader } from './BlockHeader.svelte';
8
+ export { default as BlockContent } from './BlockContent.svelte';
9
+ export { default as BlockConnectionLines } from './BlockConnectionLines.svelte';
10
+
11
+ export type {
12
+ WritingBlock,
13
+ BlockConnection,
14
+ BlockWriterSchema,
15
+ BlockWriterConfig,
16
+ WritingPhase,
17
+ BlockOrigin,
18
+ } from './block-writer-types.js';
19
+
20
+ // SplitDirection is re-exported from the spatial module
21
+
22
+ export { PHASE_CONFIG } from './block-writer-types.js';
23
+
24
+ export { renderMarkdown, renderInlineMarkdown } from './markdown.js';
@@ -0,0 +1,110 @@
1
+ // BlockWriter — shared regex markdown renderer
2
+ // Unified from DeskViewport.svelte (lines 60-92) and Atelier's MarkdownWithProvenance.svelte (lines 15-85).
3
+ // Zero dependencies — pure regex transforms.
4
+ //
5
+ // DeskViewport adds: ~~del~~, [[wikilink]] support, * and _ emphasis
6
+ // Atelier adds: proper <li>/<ul> grouping, <p> wrapping for paragraphs
7
+ // Both: headings, blockquotes, hr, inline code/bold/italic
8
+
9
+ /** Escape all 5 HTML entities. Atelier's version (full) merged with DeskViewport's (3-char). */
10
+ function escapeHtml(text: string): string {
11
+ return text
12
+ .replace(/&/g, '&amp;')
13
+ .replace(/</g, '&lt;')
14
+ .replace(/>/g, '&gt;')
15
+ .replace(/"/g, '&quot;')
16
+ .replace(/'/g, '&#039;');
17
+ }
18
+
19
+ /** Inline markdown — bold, italic, del, code, wikilinks. Input is pre-escaped. */
20
+ function renderInline(text: string): string {
21
+ return text
22
+ .replace(/\*\*\*(.+?)\*\*\*/g, '<strong><em>$1</em></strong>')
23
+ .replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
24
+ .replace(/\*([^*<\n]{1,200})\*/g, '<em>$1</em>')
25
+ .replace(/__(.+?)__/g, '<strong>$1</strong>')
26
+ .replace(/_([^_<\n]{1,200})_/g, '<em>$1</em>')
27
+ .replace(/~~(.+?)~~/g, '<del>$1</del>')
28
+ .replace(/`([^`]{1,200})`/g, '<code class="md-code">$1</code>')
29
+ .replace(/\[\[([^\]|]{1,100})\|([^\]]{1,100})\]\]/g, '<span class="md-wiki">$2</span>')
30
+ .replace(/\[\[([^\]]{1,100})\]\]/g, '<span class="md-wiki">$1</span>');
31
+ }
32
+
33
+ /**
34
+ * Render markdown to HTML string.
35
+ * Handles: headings (h1-h6), unordered lists, ordered lists, blockquotes, hr,
36
+ * inline code/bold/italic/del/wikilinks.
37
+ *
38
+ * Input is treated as untrusted — all HTML entities are escaped before processing.
39
+ * Output is safe for {@html} without additional sanitization.
40
+ */
41
+ export function renderMarkdown(md: string): string {
42
+ if (!md) return '';
43
+
44
+ const lines = md.split('\n');
45
+ const processed: string[] = [];
46
+
47
+ for (const line of lines) {
48
+ const escaped = escapeHtml(line);
49
+
50
+ // Headings
51
+ const hm = escaped.match(/^(#{1,6}) (.+)$/);
52
+ if (hm) {
53
+ processed.push(`<h${hm[1].length} class="md-h md-h${hm[1].length}">${renderInline(hm[2])}</h${hm[1].length}>`);
54
+ continue;
55
+ }
56
+
57
+ // Unordered list items
58
+ const ul = escaped.match(/^[-*+] (.+)$/);
59
+ if (ul) {
60
+ processed.push(`<li class="md-li">${renderInline(ul[1])}</li>`);
61
+ continue;
62
+ }
63
+
64
+ // Ordered list items
65
+ const ol = escaped.match(/^(\d+)\. (.+)$/);
66
+ if (ol) {
67
+ processed.push(`<li class="md-li">${renderInline(ol[2])}</li>`);
68
+ continue;
69
+ }
70
+
71
+ // Blockquotes
72
+ const bq = escaped.match(/^> (.+)$/);
73
+ if (bq) {
74
+ processed.push(`<blockquote class="md-bq">${renderInline(bq[1])}</blockquote>`);
75
+ continue;
76
+ }
77
+
78
+ // Horizontal rule
79
+ if (/^[-*]{3,}$/.test(escaped.trim())) {
80
+ processed.push('<hr class="md-hr">');
81
+ continue;
82
+ }
83
+
84
+ // Empty line
85
+ if (escaped.trim() === '') {
86
+ processed.push('<div class="md-gap"></div>');
87
+ continue;
88
+ }
89
+
90
+ // Default: paragraph
91
+ processed.push(`<p class="md-p">${renderInline(escaped)}</p>`);
92
+ }
93
+
94
+ // Group consecutive <li> elements into <ul> (Atelier pattern)
95
+ let result = processed.join('\n');
96
+ result = result.replace(/(<li class="md-li">.*?<\/li>\n?)+/g, (match) => {
97
+ return `<ul class="md-ul">${match}</ul>`;
98
+ });
99
+
100
+ return result;
101
+ }
102
+
103
+ /**
104
+ * Render inline-only markdown (no block elements).
105
+ * Useful for single-line content like block titles, annotations, tooltips.
106
+ * Input is treated as untrusted.
107
+ */
108
+ export function renderInlineMarkdown(text: string): string {
109
+ return renderInline(escapeHtml(text));
110
+ }
@@ -0,0 +1,61 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ interface Props {
5
+ channelList?: Snippet; // E.g. Sidebar component tailored for channels
6
+ chatThread: Snippet; // E.g. ChatPanel organism
7
+ memberList?: Snippet; // E.g. ContextPanel showing right side members
8
+ class?: string;
9
+ }
10
+
11
+ let {
12
+ channelList,
13
+ chatThread,
14
+ memberList,
15
+ class: className = ''
16
+ }: Props = $props();
17
+ </script>
18
+
19
+ <div class="ds-chat-layout {className}">
20
+ {#if channelList}
21
+ <div class="ds-chat-layout-sidebar">
22
+ {@render channelList()}
23
+ </div>
24
+ {/if}
25
+
26
+ <main class="ds-chat-layout-main">
27
+ {@render chatThread()}
28
+ </main>
29
+
30
+ {#if memberList}
31
+ <div class="ds-chat-layout-members">
32
+ {@render memberList()}
33
+ </div>
34
+ {/if}
35
+ </div>
36
+
37
+ <style>
38
+ .ds-chat-layout {
39
+ display: flex;
40
+ width: 100%;
41
+ height: 100%;
42
+ overflow: hidden;
43
+ }
44
+
45
+ .ds-chat-layout-sidebar {
46
+ height: 100%;
47
+ /* Typically the Sidebar organism handles its own width/border */
48
+ }
49
+
50
+ .ds-chat-layout-main {
51
+ flex: 1;
52
+ min-width: 0;
53
+ height: 100%;
54
+ /* ChatPanel handles its own internal scrolling */
55
+ }
56
+
57
+ .ds-chat-layout-members {
58
+ height: 100%;
59
+ /* A ContextPanel is usually absolute, but can be static here */
60
+ }
61
+ </style>
@@ -0,0 +1,113 @@
1
+ <script lang="ts">
2
+ import type { AllayStageView } from '../../epistemic/types.js';
3
+ import AllayGauge from '../../u0-primitives/allay-gauge/AllayGauge.svelte';
4
+
5
+ interface Props {
6
+ allay: AllayStageView;
7
+ class?: string;
8
+ }
9
+
10
+ let { allay, class: className = '' }: Props = $props();
11
+
12
+ const STAGE_DESCRIPTIONS = [
13
+ 'Knowledge has been proposed but not yet evaluated.',
14
+ 'Content has been parsed and structure verified.',
15
+ 'Authorized — passed capability and schema checks.',
16
+ 'Executed — reasoning chain verified by ASSAY signals.',
17
+ 'Traced — provenance logged on the sigchain.',
18
+ 'Replicated — independently witnessed by multiple parties.',
19
+ ];
20
+
21
+ const description = $derived(STAGE_DESCRIPTIONS[allay.stage] ?? '');
22
+ const confidencePct = $derived(`${Math.round(allay.confidence * 100)}%`);
23
+ </script>
24
+
25
+ <div class="ds-allay-detail {className}">
26
+ <div class="gauge-section">
27
+ <AllayGauge stage={allay.stage} confidence={allay.confidence} size="lg" showLabel />
28
+ <span class="confidence">{confidencePct}</span>
29
+ </div>
30
+
31
+ <div class="stage-info">
32
+ <div class="stage-name">Stage {allay.stage}: {allay.stageName}</div>
33
+ <div class="stage-desc">{description}</div>
34
+ </div>
35
+
36
+ <div class="scale-legend">
37
+ {#each [0, 1, 2, 3, 4, 5] as s}
38
+ <div class="scale-item" class:current={s === allay.stage}>
39
+ <AllayGauge stage={s as 0|1|2|3|4|5} confidence={0.5} size="sm" />
40
+ <span>{s}</span>
41
+ </div>
42
+ {/each}
43
+ </div>
44
+ </div>
45
+
46
+ <style>
47
+ .ds-allay-detail {
48
+ display: flex;
49
+ flex-direction: column;
50
+ gap: var(--space-4);
51
+ padding: var(--space-4);
52
+ background: var(--color-bg-panel);
53
+ border-radius: var(--radius-lg);
54
+ border: 1px solid var(--border-default);
55
+ min-width: 280px;
56
+ font-family: var(--font-sans);
57
+ }
58
+
59
+ .gauge-section {
60
+ display: flex;
61
+ align-items: center;
62
+ gap: var(--space-3);
63
+ }
64
+
65
+ .confidence {
66
+ font-family: var(--font-mono);
67
+ font-size: var(--text-sm);
68
+ color: var(--color-text-secondary);
69
+ }
70
+
71
+ .stage-info {
72
+ display: flex;
73
+ flex-direction: column;
74
+ gap: var(--space-1);
75
+ }
76
+
77
+ .stage-name {
78
+ font-size: var(--text-sm);
79
+ font-weight: 600;
80
+ color: var(--color-text-primary);
81
+ }
82
+
83
+ .stage-desc {
84
+ font-size: var(--text-xs);
85
+ color: var(--color-text-secondary);
86
+ line-height: 1.5;
87
+ }
88
+
89
+ .scale-legend {
90
+ display: flex;
91
+ gap: var(--space-2);
92
+ padding-top: var(--space-2);
93
+ border-top: 1px solid var(--border-subtle);
94
+ }
95
+
96
+ .scale-item {
97
+ display: flex;
98
+ flex-direction: column;
99
+ align-items: center;
100
+ gap: 2px;
101
+ opacity: 0.5;
102
+ }
103
+
104
+ .scale-item.current {
105
+ opacity: 1;
106
+ }
107
+
108
+ .scale-item span {
109
+ font-size: var(--text-xs);
110
+ font-family: var(--font-mono);
111
+ color: var(--color-text-tertiary);
112
+ }
113
+ </style>