@polderlabs/bizar 7.0.4 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (489) hide show
  1. package/.claude/settings.local.json +8 -0
  2. package/bizar-dash/DESIGN.md +729 -969
  3. package/bizar-dash/GLYPH.md +418 -0
  4. package/bizar-dash/PLAN.md +1135 -0
  5. package/bizar-dash/dist/assets/ActivityFeed-BRBtQOHB.js +6 -0
  6. package/bizar-dash/dist/assets/ActivityFeed-BRBtQOHB.js.map +1 -0
  7. package/bizar-dash/dist/assets/ActivityView-CwqhxBfh.js +1 -0
  8. package/bizar-dash/dist/assets/ActivityView-CwqhxBfh.js.map +1 -0
  9. package/bizar-dash/dist/assets/AgentActivity-6MxU-a9F.js +1 -0
  10. package/bizar-dash/dist/assets/AgentActivity-6MxU-a9F.js.map +1 -0
  11. package/bizar-dash/dist/assets/AgentsView-BYrOFdwl.js +8 -0
  12. package/bizar-dash/dist/assets/AgentsView-BYrOFdwl.js.map +1 -0
  13. package/bizar-dash/dist/assets/Badge-Cd61wsBa.js +1 -0
  14. package/bizar-dash/dist/assets/Badge-Cd61wsBa.js.map +1 -0
  15. package/bizar-dash/dist/assets/Card-C_bvqXdQ.js +1 -0
  16. package/bizar-dash/dist/assets/Card-C_bvqXdQ.js.map +1 -0
  17. package/bizar-dash/dist/assets/EmptyState-BWQuKnk9.js +1 -0
  18. package/bizar-dash/dist/assets/EmptyState-BWQuKnk9.js.map +1 -0
  19. package/bizar-dash/dist/assets/GoalsView-Dok0yt9S.js +11 -0
  20. package/bizar-dash/dist/assets/GoalsView-Dok0yt9S.js.map +1 -0
  21. package/bizar-dash/dist/assets/Grid-C62gCPqt.js +1 -0
  22. package/bizar-dash/dist/assets/Grid-C62gCPqt.js.map +1 -0
  23. package/bizar-dash/dist/assets/KanbanCard-CtTKP6ZX.js +21 -0
  24. package/bizar-dash/dist/assets/KanbanCard-CtTKP6ZX.js.map +1 -0
  25. package/bizar-dash/dist/assets/LibrariesView-BcyBQXiY.js +67 -0
  26. package/bizar-dash/dist/assets/LibrariesView-BcyBQXiY.js.map +1 -0
  27. package/bizar-dash/dist/assets/MemoryView-49wR4u-y.js +13 -0
  28. package/bizar-dash/dist/assets/MemoryView-49wR4u-y.js.map +1 -0
  29. package/bizar-dash/dist/assets/OverviewView-BtQ_UWYj.js +1 -0
  30. package/bizar-dash/dist/assets/OverviewView-BtQ_UWYj.js.map +1 -0
  31. package/bizar-dash/dist/assets/ProgressBar-CpvDeq9F.js +1 -0
  32. package/bizar-dash/dist/assets/ProgressBar-CpvDeq9F.js.map +1 -0
  33. package/bizar-dash/dist/assets/SettingsRow-DmIe5OUu.js +30 -0
  34. package/bizar-dash/dist/assets/SettingsRow-DmIe5OUu.js.map +1 -0
  35. package/bizar-dash/dist/assets/SettingsView-D1KmGWbi.js +48 -0
  36. package/bizar-dash/dist/assets/SettingsView-D1KmGWbi.js.map +1 -0
  37. package/bizar-dash/dist/assets/StatTile-BkIP32gG.js +11 -0
  38. package/bizar-dash/dist/assets/StatTile-BkIP32gG.js.map +1 -0
  39. package/bizar-dash/dist/assets/TasksView-Cba3GJ42.js +1 -0
  40. package/bizar-dash/dist/assets/TasksView-Cba3GJ42.js.map +1 -0
  41. package/bizar-dash/dist/assets/ViewHeader-D6c2cw1b.js +6 -0
  42. package/bizar-dash/dist/assets/ViewHeader-D6c2cw1b.js.map +1 -0
  43. package/bizar-dash/dist/assets/brain-DeoXNDE2.js +6 -0
  44. package/bizar-dash/dist/assets/brain-DeoXNDE2.js.map +1 -0
  45. package/bizar-dash/dist/assets/calendar-DRlQkGJc.js +6 -0
  46. package/bizar-dash/dist/assets/calendar-DRlQkGJc.js.map +1 -0
  47. package/bizar-dash/dist/assets/circle-check-DmYQ3vGp.js +6 -0
  48. package/bizar-dash/dist/assets/circle-check-DmYQ3vGp.js.map +1 -0
  49. package/bizar-dash/dist/assets/cmdk-BwN8hcKQ.js +80 -0
  50. package/bizar-dash/dist/assets/cmdk-BwN8hcKQ.js.map +1 -0
  51. package/bizar-dash/dist/assets/dnd-kit-DR2Qzzxk.js +5 -0
  52. package/bizar-dash/dist/assets/dnd-kit-DR2Qzzxk.js.map +1 -0
  53. package/bizar-dash/dist/assets/git-merge-OoqBKQer.js +6 -0
  54. package/bizar-dash/dist/assets/git-merge-OoqBKQer.js.map +1 -0
  55. package/bizar-dash/dist/assets/git-pull-request-CXBQTR2f.js +6 -0
  56. package/bizar-dash/dist/assets/git-pull-request-CXBQTR2f.js.map +1 -0
  57. package/bizar-dash/dist/assets/main-COdgjqbZ.css +1 -0
  58. package/bizar-dash/dist/assets/main-Cw6gybzS.js +109 -0
  59. package/bizar-dash/dist/assets/main-Cw6gybzS.js.map +1 -0
  60. package/bizar-dash/dist/assets/message-square-DUTeIQAR.js +6 -0
  61. package/bizar-dash/dist/assets/message-square-DUTeIQAR.js.map +1 -0
  62. package/bizar-dash/dist/assets/minus-CrStJTZ7.js +6 -0
  63. package/bizar-dash/dist/assets/minus-CrStJTZ7.js.map +1 -0
  64. package/bizar-dash/dist/assets/wrench-BJ1WIC4u.js +6 -0
  65. package/bizar-dash/dist/assets/wrench-BJ1WIC4u.js.map +1 -0
  66. package/bizar-dash/dist/{mobile.html → v8.html} +6 -9
  67. package/bizar-dash/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  68. package/bizar-dash/src/server/server.mjs +1 -57
  69. package/bizar-dash/src/web/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  70. package/bizar-dash/src/web/v8/App.tsx +188 -0
  71. package/bizar-dash/src/web/v8/__tests__/App.test.tsx +102 -0
  72. package/bizar-dash/src/web/v8/__tests__/AppShell.test.tsx +79 -0
  73. package/bizar-dash/src/web/v8/__tests__/PageSkeleton.test.tsx +12 -0
  74. package/bizar-dash/src/web/v8/__tests__/SettingsView.test.tsx +84 -0
  75. package/bizar-dash/src/web/v8/__tests__/Sidebar.test.tsx +95 -0
  76. package/bizar-dash/src/web/v8/__tests__/activity.test.tsx +63 -0
  77. package/bizar-dash/src/web/v8/__tests__/agents.test.tsx +90 -0
  78. package/bizar-dash/src/web/v8/__tests__/controls.test.tsx +135 -0
  79. package/bizar-dash/src/web/v8/__tests__/cx.test.ts +25 -0
  80. package/bizar-dash/src/web/v8/__tests__/data.test.tsx +293 -0
  81. package/bizar-dash/src/web/v8/__tests__/feedback.test.tsx +213 -0
  82. package/bizar-dash/src/web/v8/__tests__/goals.test.tsx +105 -0
  83. package/bizar-dash/src/web/v8/__tests__/kanban.test.tsx +176 -0
  84. package/bizar-dash/src/web/v8/__tests__/libraries.test.tsx +70 -0
  85. package/bizar-dash/src/web/v8/__tests__/memory.test.tsx +60 -0
  86. package/bizar-dash/src/web/v8/__tests__/navigation.test.tsx +137 -0
  87. package/bizar-dash/src/web/v8/__tests__/settings.test.tsx +104 -0
  88. package/bizar-dash/src/web/v8/__tests__/theme.test.tsx +98 -0
  89. package/bizar-dash/src/web/v8/__tests__/views.test.tsx +112 -0
  90. package/bizar-dash/src/web/v8/main.tsx +28 -0
  91. package/bizar-dash/src/web/v8/shell/AppShell.tsx +90 -0
  92. package/bizar-dash/src/web/v8/shell/PageSkeleton.tsx +29 -0
  93. package/bizar-dash/src/web/v8/shell/Sidebar.tsx +361 -0
  94. package/bizar-dash/src/web/v8/shell/StatusBar.tsx +63 -0
  95. package/bizar-dash/src/web/v8/shell/Topbar.tsx +113 -0
  96. package/bizar-dash/src/web/v8/shell/index.ts +15 -0
  97. package/bizar-dash/src/web/v8/ui/activity/ActivityFeed.tsx +137 -0
  98. package/bizar-dash/src/web/v8/ui/agents/AgentActivity.tsx +101 -0
  99. package/bizar-dash/src/web/v8/ui/agents/AgentCard.tsx +158 -0
  100. package/bizar-dash/src/web/v8/ui/controls/Button.tsx +141 -0
  101. package/bizar-dash/src/web/v8/ui/controls/ButtonGroup.tsx +32 -0
  102. package/bizar-dash/src/web/v8/ui/controls/Checkbox.tsx +49 -0
  103. package/bizar-dash/src/web/v8/ui/controls/Field.tsx +78 -0
  104. package/bizar-dash/src/web/v8/ui/controls/Form.tsx +23 -0
  105. package/bizar-dash/src/web/v8/ui/controls/IconButton.tsx +112 -0
  106. package/bizar-dash/src/web/v8/ui/controls/Input.tsx +94 -0
  107. package/bizar-dash/src/web/v8/ui/controls/RadioGroup.tsx +74 -0
  108. package/bizar-dash/src/web/v8/ui/controls/Select.tsx +171 -0
  109. package/bizar-dash/src/web/v8/ui/controls/Slider.tsx +68 -0
  110. package/bizar-dash/src/web/v8/ui/controls/Switch.tsx +56 -0
  111. package/bizar-dash/src/web/v8/ui/controls/Textarea.tsx +64 -0
  112. package/bizar-dash/src/web/v8/ui/controls/Toggle.tsx +36 -0
  113. package/bizar-dash/src/web/v8/ui/controls/ToggleGroup.tsx +85 -0
  114. package/bizar-dash/src/web/v8/ui/data/Accordion.tsx +134 -0
  115. package/bizar-dash/src/web/v8/ui/data/Avatar.tsx +175 -0
  116. package/bizar-dash/src/web/v8/ui/data/Badge.tsx +93 -0
  117. package/bizar-dash/src/web/v8/ui/data/BarList.tsx +101 -0
  118. package/bizar-dash/src/web/v8/ui/data/Card.tsx +140 -0
  119. package/bizar-dash/src/web/v8/ui/data/Chip.tsx +96 -0
  120. package/bizar-dash/src/web/v8/ui/data/Kbd.tsx +42 -0
  121. package/bizar-dash/src/web/v8/ui/data/ProgressBar.tsx +93 -0
  122. package/bizar-dash/src/web/v8/ui/data/Sparkline.tsx +98 -0
  123. package/bizar-dash/src/web/v8/ui/data/StatTile.tsx +150 -0
  124. package/bizar-dash/src/web/v8/ui/data/Table.tsx +170 -0
  125. package/bizar-dash/src/web/v8/ui/data/Timeline.tsx +130 -0
  126. package/bizar-dash/src/web/v8/ui/data/ViewHeader.tsx +122 -0
  127. package/bizar-dash/src/web/v8/ui/feedback/Alert.tsx +95 -0
  128. package/bizar-dash/src/web/v8/ui/feedback/Banner.tsx +39 -0
  129. package/bizar-dash/src/web/v8/ui/feedback/ContextMenu.tsx +143 -0
  130. package/bizar-dash/src/web/v8/ui/feedback/Dialog.tsx +149 -0
  131. package/bizar-dash/src/web/v8/ui/feedback/Drawer.tsx +8 -0
  132. package/bizar-dash/src/web/v8/ui/feedback/DropdownMenu.tsx +231 -0
  133. package/bizar-dash/src/web/v8/ui/feedback/EmptyState.tsx +48 -0
  134. package/bizar-dash/src/web/v8/ui/feedback/Popover.tsx +56 -0
  135. package/bizar-dash/src/web/v8/ui/feedback/Sheet.tsx +103 -0
  136. package/bizar-dash/src/web/v8/ui/feedback/Skeleton.tsx +67 -0
  137. package/bizar-dash/src/web/v8/ui/feedback/Spinner.tsx +30 -0
  138. package/bizar-dash/src/web/v8/ui/feedback/Toast.tsx +66 -0
  139. package/bizar-dash/src/web/v8/ui/feedback/Tooltip.tsx +89 -0
  140. package/bizar-dash/src/web/v8/ui/goals/GoalCard.tsx +176 -0
  141. package/bizar-dash/src/web/v8/ui/goals/KeyResult.tsx +115 -0
  142. package/bizar-dash/src/web/v8/ui/index.ts +322 -0
  143. package/bizar-dash/src/web/v8/ui/kanban/KanbanBoard.tsx +80 -0
  144. package/bizar-dash/src/web/v8/ui/kanban/KanbanCard.tsx +247 -0
  145. package/bizar-dash/src/web/v8/ui/kanban/KanbanColumn.tsx +181 -0
  146. package/bizar-dash/src/web/v8/ui/kanban/KanbanContextMenu.tsx +122 -0
  147. package/bizar-dash/src/web/v8/ui/kanban/KanbanQuickAdd.tsx +141 -0
  148. package/bizar-dash/src/web/v8/ui/libraries/LibraryGrid.tsx +30 -0
  149. package/bizar-dash/src/web/v8/ui/libraries/LibraryItem.tsx +161 -0
  150. package/bizar-dash/src/web/v8/ui/memory/MemoryVault.tsx +144 -0
  151. package/bizar-dash/src/web/v8/ui/navigation/CommandPalette.tsx +224 -0
  152. package/bizar-dash/src/web/v8/ui/navigation/NavLink.tsx +81 -0
  153. package/bizar-dash/src/web/v8/ui/navigation/Pagination.tsx +164 -0
  154. package/bizar-dash/src/web/v8/ui/navigation/Tabs.tsx +128 -0
  155. package/bizar-dash/src/web/v8/ui/navigation/useCommandPaletteHotkey.test.ts +79 -0
  156. package/bizar-dash/src/web/v8/ui/primitives/Box.tsx +144 -0
  157. package/bizar-dash/src/web/v8/ui/primitives/Center.tsx +40 -0
  158. package/bizar-dash/src/web/v8/ui/primitives/Cluster.tsx +67 -0
  159. package/bizar-dash/src/web/v8/ui/primitives/Grid.tsx +104 -0
  160. package/bizar-dash/src/web/v8/ui/primitives/Inline.tsx +77 -0
  161. package/bizar-dash/src/web/v8/ui/primitives/Portal.tsx +33 -0
  162. package/bizar-dash/src/web/v8/ui/primitives/ScrollArea.tsx +62 -0
  163. package/bizar-dash/src/web/v8/ui/primitives/Separator.tsx +42 -0
  164. package/bizar-dash/src/web/v8/ui/primitives/Stack.tsx +73 -0
  165. package/bizar-dash/src/web/v8/ui/primitives/VisuallyHidden.tsx +49 -0
  166. package/bizar-dash/src/web/v8/ui/settings/SettingsNav.tsx +91 -0
  167. package/bizar-dash/src/web/v8/ui/settings/SettingsRow.tsx +88 -0
  168. package/bizar-dash/src/web/v8/ui/settings/SettingsSection.tsx +109 -0
  169. package/bizar-dash/src/web/v8/ui/styles/globals.css +220 -0
  170. package/bizar-dash/src/web/v8/ui/styles/reset.css +57 -0
  171. package/bizar-dash/src/web/v8/ui/styles/tokens.css +217 -0
  172. package/bizar-dash/src/web/v8/ui/theme/DensityProvider.test.tsx +74 -0
  173. package/bizar-dash/src/web/v8/ui/theme/DensityProvider.tsx +66 -0
  174. package/bizar-dash/src/web/v8/ui/theme/ThemeProvider.test.tsx +86 -0
  175. package/bizar-dash/src/web/v8/ui/theme/ThemeProvider.tsx +94 -0
  176. package/bizar-dash/src/web/v8/ui/theme/ThemeToggle.tsx +88 -0
  177. package/bizar-dash/src/web/v8/ui/theme/useDensity.ts +15 -0
  178. package/bizar-dash/src/web/v8/ui/theme/useTheme.ts +16 -0
  179. package/bizar-dash/src/web/v8/ui/utils/cx.ts +19 -0
  180. package/bizar-dash/src/web/v8/views/Activity/ActivityView.tsx +33 -0
  181. package/bizar-dash/src/web/v8/views/Agents/AgentsView.tsx +108 -0
  182. package/bizar-dash/src/web/v8/views/CommandPalette/AppCommandPalette.test.tsx +142 -0
  183. package/bizar-dash/src/web/v8/views/CommandPalette/AppCommandPalette.tsx +144 -0
  184. package/bizar-dash/src/web/v8/views/Goals/GoalsView.tsx +84 -0
  185. package/bizar-dash/src/web/v8/views/Libraries/LibrariesView.tsx +41 -0
  186. package/bizar-dash/src/web/v8/views/Memory/MemoryView.tsx +61 -0
  187. package/bizar-dash/src/web/v8/views/Overview/OverviewView.tsx +92 -0
  188. package/bizar-dash/src/web/v8/views/Router.tsx +96 -0
  189. package/bizar-dash/src/web/v8/views/Settings/SettingsView.tsx +305 -0
  190. package/bizar-dash/src/web/v8/views/Tasks/CommandPalettePlaceholder.tsx +106 -0
  191. package/bizar-dash/src/web/v8/views/Tasks/TasksKanbanPlaceholder.tsx +62 -0
  192. package/bizar-dash/src/web/v8/views/Tasks/TasksView.tsx +74 -0
  193. package/bizar-dash/src/web/v8/vite-env.d.ts +15 -0
  194. package/bizar-dash/src/web/{mobile.html → v8.html} +4 -7
  195. package/bizar-dash/tests/setup.ts +26 -0
  196. package/bizar-dash/vite.config.ts +26 -2
  197. package/bizar-dash/vitest.config.ts +5 -3
  198. package/package.json +36 -3
  199. package/bizar-dash/dist/assets/EnvVarsSection-BfhAz3ax.js +0 -114
  200. package/bizar-dash/dist/assets/EnvVarsSection-BfhAz3ax.js.map +0 -1
  201. package/bizar-dash/dist/assets/MobileChat-DLWdv6tQ.js +0 -1
  202. package/bizar-dash/dist/assets/MobileChat-DLWdv6tQ.js.map +0 -1
  203. package/bizar-dash/dist/assets/MobileSettings-Bxv62uPY.js +0 -1
  204. package/bizar-dash/dist/assets/MobileSettings-Bxv62uPY.js.map +0 -1
  205. package/bizar-dash/dist/assets/Toast-ATSAmbdi.js +0 -26
  206. package/bizar-dash/dist/assets/Toast-ATSAmbdi.js.map +0 -1
  207. package/bizar-dash/dist/assets/__vite-browser-external-BIHI7g3E.js +0 -1
  208. package/bizar-dash/dist/assets/__vite-browser-external-BIHI7g3E.js.map +0 -1
  209. package/bizar-dash/dist/assets/main-CJAtrosO.css +0 -1
  210. package/bizar-dash/dist/assets/main-DKKj9dsq.js +0 -430
  211. package/bizar-dash/dist/assets/main-DKKj9dsq.js.map +0 -1
  212. package/bizar-dash/dist/assets/mobile-C_naUN91.js +0 -1
  213. package/bizar-dash/dist/assets/mobile-C_naUN91.js.map +0 -1
  214. package/bizar-dash/dist/assets/mobile-layout-BWLtwtfQ.css +0 -1
  215. package/bizar-dash/dist/assets/mobile-layout-GZ3bE8L6.js +0 -211
  216. package/bizar-dash/dist/assets/mobile-layout-GZ3bE8L6.js.map +0 -1
  217. package/bizar-dash/dist/assets/useSlashCommands-BOwD7lNb.js +0 -65
  218. package/bizar-dash/dist/assets/useSlashCommands-BOwD7lNb.js.map +0 -1
  219. package/bizar-dash/dist/index.html +0 -43
  220. package/bizar-dash/src/web/App.tsx +0 -915
  221. package/bizar-dash/src/web/MobileApp.tsx +0 -414
  222. package/bizar-dash/src/web/components/ArtifactCreateDialog.tsx +0 -95
  223. package/bizar-dash/src/web/components/ArtifactListDialog.tsx +0 -55
  224. package/bizar-dash/src/web/components/ArtifactViewer.tsx +0 -144
  225. package/bizar-dash/src/web/components/AuditDialog.tsx +0 -79
  226. package/bizar-dash/src/web/components/AutosaveField.tsx +0 -50
  227. package/bizar-dash/src/web/components/BackupRestore.tsx +0 -330
  228. package/bizar-dash/src/web/components/BgStatusBadge.tsx +0 -32
  229. package/bizar-dash/src/web/components/Button.tsx +0 -56
  230. package/bizar-dash/src/web/components/CanvasContextMenu.tsx +0 -68
  231. package/bizar-dash/src/web/components/Card.tsx +0 -40
  232. package/bizar-dash/src/web/components/CollapsibleSection.tsx +0 -72
  233. package/bizar-dash/src/web/components/CommandDialog.tsx +0 -66
  234. package/bizar-dash/src/web/components/DoctorPanel.tsx +0 -160
  235. package/bizar-dash/src/web/components/EmptyState.tsx +0 -30
  236. package/bizar-dash/src/web/components/EnvVarManager.tsx +0 -430
  237. package/bizar-dash/src/web/components/EvalDiff.tsx +0 -157
  238. package/bizar-dash/src/web/components/EvalExportButton.tsx +0 -27
  239. package/bizar-dash/src/web/components/EvalRunCard.tsx +0 -78
  240. package/bizar-dash/src/web/components/FileBrowser.tsx +0 -633
  241. package/bizar-dash/src/web/components/HeadroomSettings.tsx +0 -418
  242. package/bizar-dash/src/web/components/HeadroomStatus.tsx +0 -158
  243. package/bizar-dash/src/web/components/HelpDialog.tsx +0 -55
  244. package/bizar-dash/src/web/components/InviteDialog.tsx +0 -205
  245. package/bizar-dash/src/web/components/KillConfirmDialog.tsx +0 -88
  246. package/bizar-dash/src/web/components/MobileBottomNav.tsx +0 -38
  247. package/bizar-dash/src/web/components/MobileDrawer.tsx +0 -68
  248. package/bizar-dash/src/web/components/MobileHeader.tsx +0 -50
  249. package/bizar-dash/src/web/components/MobileLayout.tsx +0 -63
  250. package/bizar-dash/src/web/components/Modal.tsx +0 -215
  251. package/bizar-dash/src/web/components/Notifications.tsx +0 -242
  252. package/bizar-dash/src/web/components/ScheduleTemplateCard.tsx +0 -72
  253. package/bizar-dash/src/web/components/ScreenshotCapture.tsx +0 -138
  254. package/bizar-dash/src/web/components/ScreenshotOCR.tsx +0 -42
  255. package/bizar-dash/src/web/components/SearchModal.tsx +0 -227
  256. package/bizar-dash/src/web/components/SettingsNav.tsx +0 -117
  257. package/bizar-dash/src/web/components/SettingsSearch.tsx +0 -328
  258. package/bizar-dash/src/web/components/Sidebar.tsx +0 -89
  259. package/bizar-dash/src/web/components/Spinner.tsx +0 -19
  260. package/bizar-dash/src/web/components/StatusBadge.tsx +0 -56
  261. package/bizar-dash/src/web/components/Tag.tsx +0 -41
  262. package/bizar-dash/src/web/components/TailscaleSettings.tsx +0 -161
  263. package/bizar-dash/src/web/components/TaskCard.tsx +0 -69
  264. package/bizar-dash/src/web/components/TaskCreateSheet.tsx +0 -76
  265. package/bizar-dash/src/web/components/Toast.tsx +0 -150
  266. package/bizar-dash/src/web/components/Toggle.tsx +0 -31
  267. package/bizar-dash/src/web/components/Topbar.tsx +0 -455
  268. package/bizar-dash/src/web/components/UsageChart.tsx +0 -250
  269. package/bizar-dash/src/web/components/UsageTable.tsx +0 -90
  270. package/bizar-dash/src/web/components/VirtualList.tsx +0 -53
  271. package/bizar-dash/src/web/components/VisualPlanDialog.tsx +0 -58
  272. package/bizar-dash/src/web/components/VoiceNotesPanel.tsx +0 -211
  273. package/bizar-dash/src/web/components/VoiceRecorder.tsx +0 -105
  274. package/bizar-dash/src/web/components/WorkspaceSelector.tsx +0 -158
  275. package/bizar-dash/src/web/components/agents/CommunicationLog.tsx +0 -126
  276. package/bizar-dash/src/web/components/agents/DependencyGraph.tsx +0 -163
  277. package/bizar-dash/src/web/components/agents/QualityGates.tsx +0 -123
  278. package/bizar-dash/src/web/components/agents/RealTimeEventLog.tsx +0 -127
  279. package/bizar-dash/src/web/components/agents/RoutingDecisions.test.tsx +0 -148
  280. package/bizar-dash/src/web/components/agents/RoutingDecisions.tsx +0 -160
  281. package/bizar-dash/src/web/components/background/AttachButton.tsx +0 -96
  282. package/bizar-dash/src/web/components/background/TmuxAttachCard.tsx +0 -122
  283. package/bizar-dash/src/web/components/chat/AgentChip.tsx +0 -68
  284. package/bizar-dash/src/web/components/chat/AgentNode.tsx +0 -127
  285. package/bizar-dash/src/web/components/chat/AgentTree.tsx +0 -80
  286. package/bizar-dash/src/web/components/chat/ChatBubble.tsx +0 -60
  287. package/bizar-dash/src/web/components/chat/ChatComposer.tsx +0 -72
  288. package/bizar-dash/src/web/components/chat/ChatInfoPanel.tsx +0 -370
  289. package/bizar-dash/src/web/components/chat/ChatRail.tsx +0 -387
  290. package/bizar-dash/src/web/components/chat/ChatThread.tsx +0 -127
  291. package/bizar-dash/src/web/components/chat/ChatTopBar.tsx +0 -50
  292. package/bizar-dash/src/web/components/chat/Composer.tsx +0 -166
  293. package/bizar-dash/src/web/components/chat/ConfirmModal.tsx +0 -54
  294. package/bizar-dash/src/web/components/chat/EmptyState.tsx +0 -21
  295. package/bizar-dash/src/web/components/chat/FirstRunGreeting.tsx +0 -18
  296. package/bizar-dash/src/web/components/chat/FloatingComposer.tsx +0 -38
  297. package/bizar-dash/src/web/components/chat/InfoPanel.tsx +0 -184
  298. package/bizar-dash/src/web/components/chat/JumpToLatest.tsx +0 -58
  299. package/bizar-dash/src/web/components/chat/LoadingSkeleton.tsx +0 -19
  300. package/bizar-dash/src/web/components/chat/MessageBlock.tsx +0 -260
  301. package/bizar-dash/src/web/components/chat/MessageBubble.tsx +0 -60
  302. package/bizar-dash/src/web/components/chat/SessionList.tsx +0 -163
  303. package/bizar-dash/src/web/components/chat/SessionRowMenu.tsx +0 -206
  304. package/bizar-dash/src/web/components/chat/StreamingIndicator.tsx +0 -37
  305. package/bizar-dash/src/web/components/chat/SuggestionCards.tsx +0 -55
  306. package/bizar-dash/src/web/components/chat/WelcomeScreen.tsx +0 -36
  307. package/bizar-dash/src/web/components/chat/_legacy.ts +0 -30
  308. package/bizar-dash/src/web/components/chat/index.ts +0 -31
  309. package/bizar-dash/src/web/components/chat/useAutoGrowTextarea.ts +0 -18
  310. package/bizar-dash/src/web/components/chat/useChat.ts +0 -1190
  311. package/bizar-dash/src/web/components/chat/useSlashCommands.ts +0 -47
  312. package/bizar-dash/src/web/components/goals/GoalInput.tsx +0 -86
  313. package/bizar-dash/src/web/components/goals/PlanVisualization.tsx +0 -111
  314. package/bizar-dash/src/web/components/tasks/BacklogPanel.css +0 -109
  315. package/bizar-dash/src/web/components/tasks/BacklogPanel.tsx +0 -209
  316. package/bizar-dash/src/web/hooks/useAutosave.ts +0 -107
  317. package/bizar-dash/src/web/hooks/useI18n.ts +0 -13
  318. package/bizar-dash/src/web/index.html +0 -37
  319. package/bizar-dash/src/web/lib/api.ts +0 -237
  320. package/bizar-dash/src/web/lib/goapPlanner.ts +0 -614
  321. package/bizar-dash/src/web/lib/i18n.ts +0 -25
  322. package/bizar-dash/src/web/lib/logger.ts +0 -30
  323. package/bizar-dash/src/web/lib/markdown.tsx +0 -59
  324. package/bizar-dash/src/web/lib/search.ts +0 -115
  325. package/bizar-dash/src/web/lib/types.ts +0 -894
  326. package/bizar-dash/src/web/lib/utils.ts +0 -114
  327. package/bizar-dash/src/web/lib/ws.ts +0 -177
  328. package/bizar-dash/src/web/locales/en.json +0 -52
  329. package/bizar-dash/src/web/main.tsx +0 -43
  330. package/bizar-dash/src/web/mobile/MobileApp.tsx +0 -309
  331. package/bizar-dash/src/web/mobile/MobileBottomNav.tsx +0 -38
  332. package/bizar-dash/src/web/mobile/MobileChat.tsx +0 -138
  333. package/bizar-dash/src/web/mobile/MobileDoctor.tsx +0 -80
  334. package/bizar-dash/src/web/mobile/MobileEval.tsx +0 -167
  335. package/bizar-dash/src/web/mobile/MobileMemory.tsx +0 -108
  336. package/bizar-dash/src/web/mobile/MobileOverview.tsx +0 -213
  337. package/bizar-dash/src/web/mobile/MobileSettings.tsx +0 -251
  338. package/bizar-dash/src/web/mobile/MobileTasks.tsx +0 -94
  339. package/bizar-dash/src/web/mobile/MobileTopbar.tsx +0 -115
  340. package/bizar-dash/src/web/mobile/components/MobileBottomSheet.tsx +0 -182
  341. package/bizar-dash/src/web/mobile/components/MobileListItem.tsx +0 -64
  342. package/bizar-dash/src/web/mobile/components/MobileModal.tsx +0 -123
  343. package/bizar-dash/src/web/mobile/views/MobileActivity.tsx +0 -273
  344. package/bizar-dash/src/web/mobile/views/MobileAgents.tsx +0 -374
  345. package/bizar-dash/src/web/mobile/views/MobileArtifactCanvas.tsx +0 -439
  346. package/bizar-dash/src/web/mobile/views/MobileArtifacts.tsx +0 -143
  347. package/bizar-dash/src/web/mobile/views/MobileChat.tsx +0 -257
  348. package/bizar-dash/src/web/mobile/views/MobileConfig.tsx +0 -175
  349. package/bizar-dash/src/web/mobile/views/MobileHistory.tsx +0 -191
  350. package/bizar-dash/src/web/mobile/views/MobileMods.tsx +0 -149
  351. package/bizar-dash/src/web/mobile/views/MobileMore.tsx +0 -121
  352. package/bizar-dash/src/web/mobile/views/MobileNotifications.tsx +0 -137
  353. package/bizar-dash/src/web/mobile/views/MobilePlans.tsx +0 -26
  354. package/bizar-dash/src/web/mobile/views/MobileSchedules.tsx +0 -685
  355. package/bizar-dash/src/web/mobile/views/MobileSearchModal.tsx +0 -172
  356. package/bizar-dash/src/web/mobile/views/MobileSettings.tsx +0 -363
  357. package/bizar-dash/src/web/mobile/views/MobileSkills.tsx +0 -153
  358. package/bizar-dash/src/web/mobile/views/MobileTasks.tsx +0 -564
  359. package/bizar-dash/src/web/mobile/views/QrCodePanel.tsx +0 -69
  360. package/bizar-dash/src/web/mobile.tsx +0 -14
  361. package/bizar-dash/src/web/styles/agents-redesign.css +0 -311
  362. package/bizar-dash/src/web/styles/chat.css +0 -1740
  363. package/bizar-dash/src/web/styles/glyphs.css +0 -960
  364. package/bizar-dash/src/web/styles/main.css +0 -10389
  365. package/bizar-dash/src/web/styles/memory.css +0 -1177
  366. package/bizar-dash/src/web/styles/minimax-usage.css +0 -842
  367. package/bizar-dash/src/web/styles/mobile-chat.css +0 -5
  368. package/bizar-dash/src/web/styles/mobile-layout.css +0 -233
  369. package/bizar-dash/src/web/styles/mobile.css +0 -2181
  370. package/bizar-dash/src/web/styles/settings.css +0 -775
  371. package/bizar-dash/src/web/styles/skills.css +0 -302
  372. package/bizar-dash/src/web/styles/tasks-redesign.css +0 -253
  373. package/bizar-dash/src/web/styles/tasks.css +0 -605
  374. package/bizar-dash/src/web/ui/controls/Button.tsx +0 -77
  375. package/bizar-dash/src/web/ui/controls/Checkbox.tsx +0 -95
  376. package/bizar-dash/src/web/ui/controls/IconButton.tsx +0 -66
  377. package/bizar-dash/src/web/ui/controls/Kbd.tsx +0 -24
  378. package/bizar-dash/src/web/ui/controls/NumberInput.tsx +0 -77
  379. package/bizar-dash/src/web/ui/controls/RadioGroup.tsx +0 -109
  380. package/bizar-dash/src/web/ui/controls/SearchInput.tsx +0 -91
  381. package/bizar-dash/src/web/ui/controls/Select.tsx +0 -92
  382. package/bizar-dash/src/web/ui/controls/Slider.tsx +0 -70
  383. package/bizar-dash/src/web/ui/controls/TextInput.tsx +0 -67
  384. package/bizar-dash/src/web/ui/controls/Textarea.tsx +0 -56
  385. package/bizar-dash/src/web/ui/controls/Toggle.tsx +0 -79
  386. package/bizar-dash/src/web/ui/controls/controls.css +0 -476
  387. package/bizar-dash/src/web/ui/controls/index.ts +0 -35
  388. package/bizar-dash/src/web/ui/data/BarChart.tsx +0 -60
  389. package/bizar-dash/src/web/ui/data/DataTable.tsx +0 -216
  390. package/bizar-dash/src/web/ui/data/EmptyState.tsx +0 -60
  391. package/bizar-dash/src/web/ui/data/ErrorState.tsx +0 -56
  392. package/bizar-dash/src/web/ui/data/KeyValueList.tsx +0 -106
  393. package/bizar-dash/src/web/ui/data/LoadingState.tsx +0 -65
  394. package/bizar-dash/src/web/ui/data/Sparkline.tsx +0 -87
  395. package/bizar-dash/src/web/ui/data/StatTile.tsx +0 -87
  396. package/bizar-dash/src/web/ui/data/data.css +0 -540
  397. package/bizar-dash/src/web/ui/data/index.ts +0 -31
  398. package/bizar-dash/src/web/ui/feedback/Badge.tsx +0 -49
  399. package/bizar-dash/src/web/ui/feedback/Dialog.tsx +0 -209
  400. package/bizar-dash/src/web/ui/feedback/ProgressBar.tsx +0 -69
  401. package/bizar-dash/src/web/ui/feedback/StatusDot.tsx +0 -50
  402. package/bizar-dash/src/web/ui/feedback/Toast.tsx +0 -200
  403. package/bizar-dash/src/web/ui/feedback/Tooltip.tsx +0 -126
  404. package/bizar-dash/src/web/ui/feedback/feedback.css +0 -314
  405. package/bizar-dash/src/web/ui/feedback/index.ts +0 -43
  406. package/bizar-dash/src/web/ui/index.ts +0 -57
  407. package/bizar-dash/src/web/ui/layout/AppShell.tsx +0 -51
  408. package/bizar-dash/src/web/ui/layout/Breadcrumbs.tsx +0 -97
  409. package/bizar-dash/src/web/ui/layout/Panel.tsx +0 -73
  410. package/bizar-dash/src/web/ui/layout/PanelHeader.tsx +0 -39
  411. package/bizar-dash/src/web/ui/layout/Sidebar.tsx +0 -131
  412. package/bizar-dash/src/web/ui/layout/Tabs.tsx +0 -133
  413. package/bizar-dash/src/web/ui/layout/Topbar.tsx +0 -42
  414. package/bizar-dash/src/web/ui/layout/ViewHeader.tsx +0 -48
  415. package/bizar-dash/src/web/ui/layout/index.ts +0 -34
  416. package/bizar-dash/src/web/ui/layout/layout.css +0 -464
  417. package/bizar-dash/src/web/ui/navigation/CommandPalette.tsx +0 -199
  418. package/bizar-dash/src/web/ui/navigation/NavGroup.tsx +0 -95
  419. package/bizar-dash/src/web/ui/navigation/NavLink.tsx +0 -93
  420. package/bizar-dash/src/web/ui/navigation/index.ts +0 -17
  421. package/bizar-dash/src/web/ui/navigation/navigation.css +0 -343
  422. package/bizar-dash/src/web/ui/primitives/Box.tsx +0 -91
  423. package/bizar-dash/src/web/ui/primitives/Grid.tsx +0 -49
  424. package/bizar-dash/src/web/ui/primitives/Inline.tsx +0 -55
  425. package/bizar-dash/src/web/ui/primitives/Separator.tsx +0 -46
  426. package/bizar-dash/src/web/ui/primitives/Stack.tsx +0 -54
  427. package/bizar-dash/src/web/ui/primitives/VisuallyHidden.tsx +0 -26
  428. package/bizar-dash/src/web/ui/primitives/index.ts +0 -23
  429. package/bizar-dash/src/web/ui/primitives/primitives.css +0 -183
  430. package/bizar-dash/src/web/ui/styles/globals.css +0 -86
  431. package/bizar-dash/src/web/ui/styles/reset.css +0 -125
  432. package/bizar-dash/src/web/ui/styles/tokens.css +0 -208
  433. package/bizar-dash/src/web/ui/theme/ThemeProvider.tsx +0 -142
  434. package/bizar-dash/src/web/ui/theme/tokens.ts +0 -131
  435. package/bizar-dash/src/web/ui/theme/useTheme.ts +0 -22
  436. package/bizar-dash/src/web/ui/utils/cx.ts +0 -42
  437. package/bizar-dash/src/web/views/Activity.tsx +0 -1221
  438. package/bizar-dash/src/web/views/Agents.tsx +0 -964
  439. package/bizar-dash/src/web/views/Artifacts.tsx +0 -1494
  440. package/bizar-dash/src/web/views/BackgroundAgents.tsx +0 -822
  441. package/bizar-dash/src/web/views/Chat.tsx +0 -532
  442. package/bizar-dash/src/web/views/Config.tsx +0 -3
  443. package/bizar-dash/src/web/views/Doctor.tsx +0 -317
  444. package/bizar-dash/src/web/views/Eval.tsx +0 -372
  445. package/bizar-dash/src/web/views/EvalReport.tsx +0 -353
  446. package/bizar-dash/src/web/views/GoalPlanner.tsx +0 -158
  447. package/bizar-dash/src/web/views/Harness.tsx +0 -306
  448. package/bizar-dash/src/web/views/History.tsx +0 -353
  449. package/bizar-dash/src/web/views/Memory.tsx +0 -193
  450. package/bizar-dash/src/web/views/MiniMaxUsage.tsx +0 -942
  451. package/bizar-dash/src/web/views/ModView.tsx +0 -207
  452. package/bizar-dash/src/web/views/Mods.tsx +0 -706
  453. package/bizar-dash/src/web/views/Overview.tsx +0 -1343
  454. package/bizar-dash/src/web/views/Providers.tsx +0 -302
  455. package/bizar-dash/src/web/views/Schedules.tsx +0 -902
  456. package/bizar-dash/src/web/views/Settings.tsx +0 -308
  457. package/bizar-dash/src/web/views/Skills.tsx +0 -383
  458. package/bizar-dash/src/web/views/SpawnAgentModal.tsx +0 -221
  459. package/bizar-dash/src/web/views/Tasks.tsx +0 -789
  460. package/bizar-dash/src/web/views/Workspace.tsx +0 -294
  461. package/bizar-dash/src/web/views/glyphs/GlyphRenderer.tsx +0 -844
  462. package/bizar-dash/src/web/views/glyphs/components.tsx +0 -1098
  463. package/bizar-dash/src/web/views/memory/ConfigPanel.tsx +0 -426
  464. package/bizar-dash/src/web/views/memory/FromScreenshotPanel.tsx +0 -23
  465. package/bizar-dash/src/web/views/memory/GitSyncPanel.tsx +0 -220
  466. package/bizar-dash/src/web/views/memory/LightragPanel.tsx +0 -310
  467. package/bizar-dash/src/web/views/memory/MemoryGraphLegend.tsx +0 -29
  468. package/bizar-dash/src/web/views/memory/MemoryGraphPanel.tsx +0 -192
  469. package/bizar-dash/src/web/views/memory/MemoryGraphView.tsx +0 -336
  470. package/bizar-dash/src/web/views/memory/MemoryOverview.tsx +0 -367
  471. package/bizar-dash/src/web/views/memory/MemoryStatusCard.tsx +0 -160
  472. package/bizar-dash/src/web/views/memory/ObsidianPanel.tsx +0 -650
  473. package/bizar-dash/src/web/views/memory/SemanticSearchPanel.tsx +0 -197
  474. package/bizar-dash/src/web/views/memory/VaultFromClipboardPanel.tsx +0 -101
  475. package/bizar-dash/src/web/views/settings/ActivitySection.tsx +0 -205
  476. package/bizar-dash/src/web/views/settings/AgentSection.tsx +0 -305
  477. package/bizar-dash/src/web/views/settings/AuthSection.tsx +0 -159
  478. package/bizar-dash/src/web/views/settings/EnvVarsSection.tsx +0 -15
  479. package/bizar-dash/src/web/views/settings/GeneralSection.tsx +0 -128
  480. package/bizar-dash/src/web/views/settings/HeadroomSection.tsx +0 -39
  481. package/bizar-dash/src/web/views/settings/MemorySection.tsx +0 -154
  482. package/bizar-dash/src/web/views/settings/NetworkSection.tsx +0 -87
  483. package/bizar-dash/src/web/views/settings/NotificationsSection.tsx +0 -34
  484. package/bizar-dash/src/web/views/settings/SystemLlmSection.tsx +0 -81
  485. package/bizar-dash/src/web/views/settings/ThemeSection.tsx +0 -168
  486. package/bizar-dash/src/web/views/settings/UpdatesSection.tsx +0 -256
  487. package/bizar-dash/src/web/views/settings/WorkspacesSection.tsx +0 -189
  488. package/packages/sdk/.harness/agents.json +0 -17
  489. package/packages/sdk/.harness/topology.json +0 -4
@@ -1,1098 +0,0 @@
1
- // Glyphs block vocabulary — renders MDX blocks from plan.mdx
2
-
3
- import { useMemo, useState } from 'react';
4
- import ReactMarkdown from 'react-markdown';
5
- import remarkGfm from 'remark-gfm';
6
- import {
7
- AlertTriangle,
8
- Check,
9
- CheckCircle2,
10
- ChevronDown,
11
- Diamond,
12
- FileCode2,
13
- Info,
14
- Minus,
15
- StickyNote,
16
- XCircle,
17
- } from 'lucide-react';
18
- import { cn } from '../../lib/utils';
19
-
20
- export interface RichTextProps {
21
- id: string;
22
- children: string;
23
- }
24
-
25
- export function RichText({ id, children }: RichTextProps) {
26
- return (
27
- <div
28
- id={id}
29
- data-block-id={id}
30
- className={cn('glyph-richtext')}
31
- style={proseStyle}
32
- >
33
- <ReactMarkdown remarkPlugins={[remarkGfm]}>{children}</ReactMarkdown>
34
- </div>
35
- );
36
- }
37
-
38
- export interface CalloutProps {
39
- id: string;
40
- tone?: 'info' | 'warn' | 'success' | 'danger';
41
- children: string;
42
- }
43
-
44
- const CALLOUT_TONE: Record<NonNullable<CalloutProps['tone']>, {
45
- bg: string; border: string; fg: string; icon: typeof Info; label: string;
46
- }> = {
47
- info: { bg: 'var(--info-soft, rgba(96, 165, 250, 0.12))', border: 'var(--info)', fg: 'var(--info)', icon: Info, label: 'Note' },
48
- warn: { bg: 'var(--warning-soft, rgba(251, 191, 36, 0.15))', border: 'var(--warning)', fg: 'var(--warning)', icon: AlertTriangle, label: 'Warning' },
49
- success: { bg: 'var(--success-soft, rgba(52, 211, 153, 0.15))', border: 'var(--success)', fg: 'var(--success)', icon: CheckCircle2, label: 'Success' },
50
- danger: { bg: 'var(--error-soft, rgba(248, 113, 113, 0.12))', border: 'var(--error)', fg: 'var(--error)', icon: XCircle, label: 'Danger' },
51
- };
52
-
53
- export function Callout({ id, tone = 'info', children }: CalloutProps) {
54
- const t = CALLOUT_TONE[tone];
55
- const Icon = t.icon;
56
- return (
57
- <div
58
- id={id}
59
- data-block-id={id}
60
- className={cn('glyph-callout', `glyph-callout-${tone}`)}
61
- style={{
62
- display: 'flex',
63
- gap: 12,
64
- padding: '12px 16px',
65
- margin: '12px 0',
66
- borderLeft: `3px solid ${t.border}`,
67
- background: t.bg,
68
- borderRadius: 8,
69
- color: 'var(--text)',
70
- }}
71
- role={tone === 'danger' || tone === 'warn' ? 'alert' : undefined}
72
- >
73
- <div style={{ flexShrink: 0, color: t.fg, paddingTop: 2 }}>
74
- <Icon size={18} />
75
- </div>
76
- <div style={{ flex: 1, minWidth: 0 }}>
77
- <div style={{ fontWeight: 600, fontSize: 13, color: t.fg, marginBottom: 4 }}>
78
- {t.label}
79
- </div>
80
- <div className="glyph-richtext" style={{ ...proseStyle, fontSize: 14 }}>
81
- <ReactMarkdown remarkPlugins={[remarkGfm]}>{children}</ReactMarkdown>
82
- </div>
83
- </div>
84
- </div>
85
- );
86
- }
87
-
88
- export interface ChecklistItem {
89
- id: string;
90
- label: string;
91
- checked: boolean;
92
- }
93
- export interface ChecklistProps {
94
- id: string;
95
- items: ChecklistItem[];
96
- }
97
-
98
- export function Checklist({ id, items }: ChecklistProps) {
99
- return (
100
- <ul
101
- id={id}
102
- data-block-id={id}
103
- className="glyph-checklist"
104
- style={{
105
- listStyle: 'none',
106
- padding: 0,
107
- margin: '12px 0',
108
- display: 'flex',
109
- flexDirection: 'column',
110
- gap: 6,
111
- }}
112
- >
113
- {items.map((item) => (
114
- <li
115
- key={item.id}
116
- style={{
117
- display: 'flex',
118
- alignItems: 'flex-start',
119
- gap: 10,
120
- padding: '6px 10px',
121
- borderRadius: 6,
122
- background: 'var(--bg-elev)',
123
- border: '1px solid var(--border)',
124
- fontSize: 14,
125
- }}
126
- >
127
- <span
128
- aria-hidden
129
- style={{
130
- flexShrink: 0,
131
- marginTop: 1,
132
- width: 16,
133
- height: 16,
134
- borderRadius: 4,
135
- border: `1.5px solid ${item.checked ? 'var(--success)' : 'var(--border-strong)'}`,
136
- background: item.checked ? 'var(--success)' : 'transparent',
137
- color: 'var(--bg)',
138
- display: 'inline-flex',
139
- alignItems: 'center',
140
- justifyContent: 'center',
141
- }}
142
- >
143
- {item.checked ? <Check size={12} strokeWidth={3} /> : null}
144
- </span>
145
- <span style={{
146
- color: item.checked ? 'var(--text-dim)' : 'var(--text)',
147
- textDecoration: item.checked ? 'line-through' : 'none',
148
- wordBreak: 'break-word',
149
- }}>
150
- {item.label}
151
- </span>
152
- </li>
153
- ))}
154
- </ul>
155
- );
156
- }
157
-
158
- export interface TableProps {
159
- id: string;
160
- columns: string[];
161
- rows: string[][];
162
- }
163
-
164
- export function Table({ id, columns, rows }: TableProps) {
165
- return (
166
- <div
167
- id={id}
168
- data-block-id={id}
169
- className="glyph-table-wrap"
170
- style={{
171
- margin: '12px 0',
172
- border: '1px solid var(--border)',
173
- borderRadius: 8,
174
- overflow: 'auto',
175
- background: 'var(--bg-elev)',
176
- }}
177
- >
178
- <table
179
- style={{
180
- width: '100%',
181
- borderCollapse: 'collapse',
182
- fontSize: 13,
183
- }}
184
- >
185
- <thead>
186
- <tr>
187
- {columns.map((c, i) => (
188
- <th
189
- key={i}
190
- style={{
191
- textAlign: 'left',
192
- padding: '8px 12px',
193
- borderBottom: '1px solid var(--border-strong)',
194
- background: 'var(--bg)',
195
- color: 'var(--text-dim)',
196
- fontWeight: 600,
197
- fontSize: 12,
198
- textTransform: 'uppercase',
199
- letterSpacing: 0.3,
200
- whiteSpace: 'nowrap',
201
- }}
202
- >
203
- {c}
204
- </th>
205
- ))}
206
- </tr>
207
- </thead>
208
- <tbody>
209
- {rows.map((row, ri) => (
210
- <tr key={ri} style={{ borderTop: ri === 0 ? 'none' : '1px solid var(--border)' }}>
211
- {row.map((cell, ci) => (
212
- <td
213
- key={ci}
214
- style={{
215
- padding: '8px 12px',
216
- color: 'var(--text)',
217
- verticalAlign: 'top',
218
- wordBreak: 'break-word',
219
- }}
220
- >
221
- {cell}
222
- </td>
223
- ))}
224
- </tr>
225
- ))}
226
- </tbody>
227
- </table>
228
- </div>
229
- );
230
- }
231
-
232
- export interface CodeTab {
233
- id: string;
234
- label: string;
235
- language: string;
236
- code: string;
237
- caption?: string;
238
- }
239
- export interface CodeTabsProps {
240
- id: string;
241
- tabs: CodeTab[];
242
- }
243
-
244
- export function CodeTabs({ id, tabs }: CodeTabsProps) {
245
- const [activeId, setActiveId] = useState<string>(tabs[0]?.id ?? '');
246
- const active = useMemo(
247
- () => tabs.find((t) => t.id === activeId) ?? tabs[0],
248
- [tabs, activeId],
249
- );
250
-
251
- return (
252
- <div
253
- id={id}
254
- data-block-id={id}
255
- className="glyph-codetabs"
256
- style={{
257
- margin: '12px 0',
258
- border: '1px solid var(--border)',
259
- borderRadius: 8,
260
- overflow: 'hidden',
261
- background: 'var(--bg-elev)',
262
- }}
263
- >
264
- <div
265
- role="tablist"
266
- style={{
267
- display: 'flex',
268
- gap: 2,
269
- padding: 4,
270
- background: 'var(--bg)',
271
- borderBottom: '1px solid var(--border)',
272
- overflowX: 'auto',
273
- }}
274
- >
275
- {tabs.map((t) => {
276
- const selected = t.id === active?.id;
277
- return (
278
- <button
279
- key={t.id}
280
- type="button"
281
- role="tab"
282
- aria-selected={selected}
283
- onClick={() => setActiveId(t.id)}
284
- style={{
285
- padding: '6px 12px',
286
- fontSize: 12,
287
- fontFamily: 'var(--font-mono)',
288
- borderRadius: 6,
289
- border: 'none',
290
- cursor: 'pointer',
291
- background: selected ? 'var(--bg-elev)' : 'transparent',
292
- color: selected ? 'var(--text-strong)' : 'var(--text-dim)',
293
- boxShadow: selected ? '0 0 0 1px var(--border)' : 'none',
294
- whiteSpace: 'nowrap',
295
- }}
296
- >
297
- <span>{t.label}</span>
298
- {t.language && (
299
- <span style={{ marginLeft: 6, color: 'var(--text-dim)', fontSize: 11 }}>
300
- {t.language}
301
- </span>
302
- )}
303
- </button>
304
- );
305
- })}
306
- </div>
307
- {active && (
308
- <>
309
- <pre
310
- style={{
311
- margin: 0,
312
- padding: 14,
313
- overflowX: 'auto',
314
- fontFamily: 'var(--font-mono)',
315
- fontSize: 12.5,
316
- lineHeight: 1.55,
317
- color: 'var(--text)',
318
- background: 'var(--bg-elev)',
319
- }}
320
- >
321
- <code>{active.code}</code>
322
- </pre>
323
- {active.caption && (
324
- <div
325
- style={{
326
- padding: '8px 14px',
327
- borderTop: '1px solid var(--border)',
328
- fontSize: 12,
329
- color: 'var(--text-dim)',
330
- background: 'var(--bg)',
331
- }}
332
- >
333
- {active.caption}
334
- </div>
335
- )}
336
- </>
337
- )}
338
- </div>
339
- );
340
- }
341
-
342
- export interface DecisionOption {
343
- id: string;
344
- label: string;
345
- detail: string;
346
- recommended?: boolean;
347
- }
348
- export interface DecisionProps {
349
- id: string;
350
- title?: string;
351
- question?: string;
352
- options: DecisionOption[];
353
- }
354
-
355
- export function Decision({ id, title, question, options }: DecisionProps) {
356
- return (
357
- <div
358
- id={id}
359
- data-block-id={id}
360
- className="glyph-decision"
361
- style={{
362
- margin: '16px 0',
363
- padding: 16,
364
- border: '1px solid var(--border)',
365
- borderRadius: 10,
366
- background: 'var(--bg-elev)',
367
- }}
368
- >
369
- {title && (
370
- <h3 style={{ margin: 0, marginBottom: 4, fontSize: 15, fontWeight: 600, color: 'var(--text-strong)' }}>
371
- {title}
372
- </h3>
373
- )}
374
- {question && (
375
- <p style={{ margin: 0, marginBottom: 12, fontSize: 13, color: 'var(--text-dim)' }}>
376
- {question}
377
- </p>
378
- )}
379
- <div style={{ display: 'grid', gap: 10, gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))' }}>
380
- {options.map((opt) => {
381
- const isRec = !!opt.recommended;
382
- return (
383
- <div
384
- key={opt.id}
385
- style={{
386
- position: 'relative',
387
- padding: 12,
388
- borderRadius: 8,
389
- border: isRec ? '2px solid var(--success)' : '1px solid var(--border)',
390
- background: isRec ? 'var(--success-soft)' : 'var(--bg)',
391
- }}
392
- >
393
- {isRec && (
394
- <span
395
- style={{
396
- position: 'absolute',
397
- top: -10,
398
- right: 10,
399
- padding: '2px 8px',
400
- fontSize: 11,
401
- fontWeight: 600,
402
- color: 'var(--bg)',
403
- background: 'var(--success)',
404
- borderRadius: 999,
405
- }}
406
- >
407
- Recommended
408
- </span>
409
- )}
410
- <div style={{ fontWeight: 600, fontSize: 14, color: 'var(--text-strong)', marginBottom: 4 }}>
411
- {opt.label}
412
- </div>
413
- <div style={{ fontSize: 13, color: 'var(--text)' }}>
414
- {opt.detail}
415
- </div>
416
- </div>
417
- );
418
- })}
419
- </div>
420
- </div>
421
- );
422
- }
423
-
424
- export interface OpenQuestion {
425
- id: string;
426
- label: string;
427
- kind: 'choice' | 'text' | 'multi';
428
- options?: string[];
429
- }
430
- export interface OpenQuestionsProps {
431
- id: string;
432
- questions: OpenQuestion[];
433
- }
434
-
435
- export function OpenQuestions({ id, questions }: OpenQuestionsProps) {
436
- const [answers, setAnswers] = useState<Record<string, string | string[]>>({});
437
-
438
- function setAnswer(qid: string, value: string | string[]) {
439
- setAnswers((prev) => ({ ...prev, [qid]: value }));
440
- }
441
-
442
- return (
443
- <div
444
- id={id}
445
- data-block-id={id}
446
- className="glyph-openquestions"
447
- style={{
448
- margin: '16px 0',
449
- padding: 16,
450
- border: '1px solid var(--border)',
451
- borderRadius: 10,
452
- background: 'var(--bg-elev)',
453
- display: 'flex',
454
- flexDirection: 'column',
455
- gap: 14,
456
- }}
457
- >
458
- <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--text-strong)' }}>
459
- Open questions
460
- </div>
461
- {questions.map((q) => (
462
- <div key={q.id} style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
463
- <label
464
- htmlFor={`oq-${q.id}`}
465
- style={{ fontSize: 13, color: 'var(--text)', fontWeight: 500 }}
466
- >
467
- {q.label}
468
- </label>
469
- {q.kind === 'choice' && (
470
- <select
471
- id={`oq-${q.id}`}
472
- value={(answers[q.id] as string) ?? ''}
473
- onChange={(e) => setAnswer(q.id, e.target.value)}
474
- style={inputStyle}
475
- >
476
- <option value="">— select —</option>
477
- {(q.options ?? []).map((opt) => (
478
- <option key={opt} value={opt}>{opt}</option>
479
- ))}
480
- </select>
481
- )}
482
- {q.kind === 'text' && (
483
- <input
484
- id={`oq-${q.id}`}
485
- type="text"
486
- value={(answers[q.id] as string) ?? ''}
487
- onChange={(e) => setAnswer(q.id, e.target.value)}
488
- style={inputStyle}
489
- />
490
- )}
491
- {q.kind === 'multi' && (
492
- <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
493
- {(q.options ?? []).map((opt) => {
494
- const current = (answers[q.id] as string[]) ?? [];
495
- const checked = current.includes(opt);
496
- return (
497
- <label
498
- key={opt}
499
- style={{
500
- display: 'flex',
501
- alignItems: 'center',
502
- gap: 8,
503
- fontSize: 13,
504
- color: 'var(--text)',
505
- cursor: 'pointer',
506
- }}
507
- >
508
- <input
509
- type="checkbox"
510
- checked={checked}
511
- onChange={() => {
512
- const next = checked
513
- ? current.filter((o) => o !== opt)
514
- : [...current, opt];
515
- setAnswer(q.id, next);
516
- }}
517
- />
518
- <span>{opt}</span>
519
- </label>
520
- );
521
- })}
522
- </div>
523
- )}
524
- </div>
525
- ))}
526
- </div>
527
- );
528
- }
529
-
530
- const inputStyle: React.CSSProperties = {
531
- padding: '6px 10px',
532
- fontSize: 13,
533
- borderRadius: 6,
534
- border: '1px solid var(--border-strong)',
535
- background: 'var(--bg)',
536
- color: 'var(--text)',
537
- fontFamily: 'inherit',
538
- };
539
-
540
- export interface FileTreeEntry {
541
- path: string;
542
- change: 'added' | 'modified' | 'removed' | 'renamed';
543
- note?: string;
544
- }
545
- export interface FileTreeProps {
546
- id: string;
547
- title?: string;
548
- entries: FileTreeEntry[];
549
- }
550
-
551
- const FILE_CHANGE: Record<FileTreeEntry['change'], { bg: string; fg: string; label: string }> = {
552
- added: { bg: 'var(--success-soft)', fg: 'var(--success)', label: 'A' },
553
- modified: { bg: 'var(--info-soft, rgba(96, 165, 250, 0.12))', fg: 'var(--info)', label: 'M' },
554
- removed: { bg: 'var(--error-soft)', fg: 'var(--error)', label: 'D' },
555
- renamed: { bg: 'rgba(139, 92, 246, 0.15)', fg: 'var(--accent)', label: 'R' },
556
- };
557
-
558
- export function FileTree({ id, title, entries }: FileTreeProps) {
559
- return (
560
- <div
561
- id={id}
562
- data-block-id={id}
563
- className="glyph-filetree"
564
- style={{
565
- margin: '12px 0',
566
- padding: title ? 14 : 8,
567
- border: '1px solid var(--border)',
568
- borderRadius: 8,
569
- background: 'var(--bg-elev)',
570
- }}
571
- >
572
- {title && (
573
- <div
574
- style={{
575
- fontSize: 12,
576
- fontWeight: 600,
577
- color: 'var(--text-dim)',
578
- textTransform: 'uppercase',
579
- letterSpacing: 0.4,
580
- marginBottom: 8,
581
- }}
582
- >
583
- {title}
584
- </div>
585
- )}
586
- <ul style={{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: 2 }}>
587
- {entries.map((e) => {
588
- const t = FILE_CHANGE[e.change];
589
- return (
590
- <li
591
- key={e.path}
592
- style={{
593
- display: 'flex',
594
- alignItems: 'center',
595
- gap: 10,
596
- padding: '5px 8px',
597
- borderRadius: 5,
598
- fontSize: 13,
599
- }}
600
- >
601
- <span
602
- aria-label={e.change}
603
- title={e.change}
604
- style={{
605
- flexShrink: 0,
606
- width: 22,
607
- height: 18,
608
- borderRadius: 4,
609
- background: t.bg,
610
- color: t.fg,
611
- display: 'inline-flex',
612
- alignItems: 'center',
613
- justifyContent: 'center',
614
- fontSize: 10,
615
- fontWeight: 700,
616
- fontFamily: 'var(--font-mono)',
617
- }}
618
- >
619
- {t.label}
620
- </span>
621
- <span
622
- style={{
623
- fontFamily: 'var(--font-mono)',
624
- color: 'var(--text)',
625
- wordBreak: 'break-all',
626
- flex: 1,
627
- }}
628
- >
629
- {e.path}
630
- </span>
631
- {e.note && (
632
- <span style={{ fontSize: 12, color: 'var(--text-dim)' }}>
633
- {e.note}
634
- </span>
635
- )}
636
- </li>
637
- );
638
- })}
639
- </ul>
640
- </div>
641
- );
642
- }
643
-
644
- export interface DiffProps {
645
- id: string;
646
- filename?: string;
647
- language?: string;
648
- mode?: 'split' | 'unified';
649
- before: string;
650
- after: string;
651
- }
652
-
653
- export function Diff({ id, filename, language, mode = 'unified', before, after }: DiffProps) {
654
- const beforeLines = before.split('\n');
655
- const afterLines = after.split('\n');
656
-
657
- const header = (
658
- <div
659
- style={{
660
- display: 'flex',
661
- alignItems: 'center',
662
- gap: 8,
663
- padding: '6px 12px',
664
- background: 'var(--bg)',
665
- borderBottom: '1px solid var(--border)',
666
- fontSize: 12,
667
- color: 'var(--text-dim)',
668
- fontFamily: 'var(--font-mono)',
669
- }}
670
- >
671
- <FileCode2 size={14} />
672
- <span style={{ color: 'var(--text)' }}>{filename ?? 'diff'}</span>
673
- {language && <span>· {language}</span>}
674
- <span style={{ marginLeft: 'auto', textTransform: 'uppercase', letterSpacing: 0.3 }}>
675
- {mode}
676
- </span>
677
- </div>
678
- );
679
-
680
- const codeStyle: React.CSSProperties = {
681
- margin: 0,
682
- padding: 0,
683
- fontFamily: 'var(--font-mono)',
684
- fontSize: 12.5,
685
- lineHeight: 1.55,
686
- color: 'var(--text)',
687
- background: 'var(--bg-elev)',
688
- };
689
-
690
- const lineRow = (sign: string, content: string, kind: 'del' | 'add' | 'ctx') => {
691
- const colors: Record<typeof kind, string> = {
692
- del: 'var(--error-soft)',
693
- add: 'var(--success-soft)',
694
- ctx: 'transparent',
695
- };
696
- const signColor: Record<typeof kind, string> = {
697
- del: 'var(--error)',
698
- add: 'var(--success)',
699
- ctx: 'var(--text-dim)',
700
- };
701
- return (
702
- <div
703
- style={{
704
- display: 'flex',
705
- padding: '0 12px',
706
- background: colors[kind],
707
- }}
708
- >
709
- <span style={{ width: 18, color: signColor[kind], userSelect: 'none', flexShrink: 0 }}>{sign}</span>
710
- <span style={{ whiteSpace: 'pre', flex: 1, overflowX: 'auto' }}>{content || ' '}</span>
711
- </div>
712
- );
713
- };
714
-
715
- return (
716
- <div
717
- id={id}
718
- data-block-id={id}
719
- className="glyph-diff"
720
- style={{
721
- margin: '12px 0',
722
- border: '1px solid var(--border)',
723
- borderRadius: 8,
724
- overflow: 'hidden',
725
- background: 'var(--bg-elev)',
726
- }}
727
- >
728
- {header}
729
- {mode === 'unified' ? (
730
- <pre style={codeStyle}>
731
- {beforeLines.map((l, i) => (
732
- <div key={`b${i}`}>{lineRow('-', l, 'del')}</div>
733
- ))}
734
- {afterLines.map((l, i) => (
735
- <div key={`a${i}`}>{lineRow('+', l, 'add')}</div>
736
- ))}
737
- </pre>
738
- ) : (
739
- <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr' }}>
740
- <pre style={{ ...codeStyle, borderRight: '1px solid var(--border)' }}>
741
- {beforeLines.map((l, i) => (
742
- <div key={i}>{lineRow('-', l, 'del')}</div>
743
- ))}
744
- </pre>
745
- <pre style={codeStyle}>
746
- {afterLines.map((l, i) => (
747
- <div key={i}>{lineRow('+', l, 'add')}</div>
748
- ))}
749
- </pre>
750
- </div>
751
- )}
752
- </div>
753
- );
754
- }
755
-
756
- export interface StatProps {
757
- id: string;
758
- label: string;
759
- value: string | number;
760
- trend?: 'up' | 'down' | 'flat';
761
- hint?: string;
762
- }
763
-
764
- const TREND_STYLE: Record<NonNullable<StatProps['trend']>, { fg: string; Icon: typeof Minus; label: string }> = {
765
- up: { fg: 'var(--success)', Icon: ChevronDown, label: 'trending up' },
766
- down: { fg: 'var(--error)', Icon: ChevronDown, label: 'trending down' },
767
- flat: { fg: 'var(--text-dim)', Icon: Minus, label: 'flat' },
768
- };
769
-
770
- export function Stat({ id, label, value, trend, hint }: StatProps) {
771
- const t = trend ? TREND_STYLE[trend] : null;
772
- return (
773
- <div
774
- id={id}
775
- data-block-id={id}
776
- className="glyph-stat"
777
- style={{
778
- padding: 14,
779
- border: '1px solid var(--border)',
780
- borderRadius: 10,
781
- background: 'var(--bg-elev)',
782
- display: 'flex',
783
- flexDirection: 'column',
784
- gap: 4,
785
- minWidth: 140,
786
- }}
787
- >
788
- <div style={{ fontSize: 12, color: 'var(--text-dim)', textTransform: 'uppercase', letterSpacing: 0.4 }}>
789
- {label}
790
- </div>
791
- <div style={{ display: 'flex', alignItems: 'baseline', gap: 8 }}>
792
- <span style={{ fontSize: 24, fontWeight: 700, color: 'var(--text-strong)' }}>
793
- {value}
794
- </span>
795
- {t && (
796
- <span
797
- aria-label={t.label}
798
- style={{
799
- display: 'inline-flex',
800
- alignItems: 'center',
801
- color: t.fg,
802
- transform: t.Icon === ChevronDown && trend === 'up' ? 'rotate(180deg)' : undefined,
803
- }}
804
- >
805
- <t.Icon size={14} />
806
- </span>
807
- )}
808
- </div>
809
- {hint && (
810
- <div style={{ fontSize: 12, color: 'var(--text-dim)' }}>
811
- {hint}
812
- </div>
813
- )}
814
- </div>
815
- );
816
- }
817
-
818
- export interface WorkflowStep {
819
- id: string;
820
- label: string;
821
- type: 'task' | 'decision' | 'note';
822
- }
823
- export interface WorkflowConnection {
824
- from: string;
825
- to: string;
826
- label?: string;
827
- }
828
- export interface WorkflowProps {
829
- id: string;
830
- steps: WorkflowStep[];
831
- connections?: WorkflowConnection[];
832
- }
833
-
834
- const STEP_COLORS: Record<WorkflowStep['type'], { stroke: string; fill: string; fg: string }> = {
835
- task: { stroke: 'var(--info)', fill: 'var(--bg-elev)', fg: 'var(--text)' },
836
- decision: { stroke: 'var(--warning)', fill: 'var(--bg-elev)', fg: 'var(--text)' },
837
- note: { stroke: 'var(--border-strong)', fill: 'var(--bg)', fg: 'var(--text-dim)' },
838
- };
839
-
840
- const BOX_W = 160;
841
- const BOX_H = 56;
842
- const GAP_X = 60;
843
- const GAP_Y = 80;
844
-
845
- export function Workflow({ id, steps, connections = [] }: WorkflowProps) {
846
- if (steps.length === 0) {
847
- return (
848
- <div id={id} data-block-id={id} className="glyph-workflow">
849
- <Empty id={id} />
850
- </div>
851
- );
852
- }
853
-
854
- const byId = new Map(steps.map((s) => [s.id, s] as const));
855
- const layout = layoutSteps(steps);
856
-
857
- const cols = Math.max(...layout.map((p) => p.col)) + 1;
858
- const rows = Math.max(...layout.map((p) => p.row)) + 1;
859
- const width = cols * (BOX_W + GAP_X) + GAP_X;
860
- const height = rows * (BOX_H + GAP_Y) + GAP_Y;
861
-
862
- function nodeCenter(stepId: string): { x: number; y: number } | null {
863
- const step = byId.get(stepId);
864
- if (!step) return null;
865
- const pos = layout.find((p) => p.id === stepId);
866
- if (!pos) return null;
867
- return {
868
- x: GAP_X + pos.col * (BOX_W + GAP_X) + BOX_W / 2,
869
- y: GAP_Y + pos.row * (BOX_H + GAP_Y) + BOX_H / 2,
870
- };
871
- }
872
-
873
- return (
874
- <div
875
- id={id}
876
- data-block-id={id}
877
- className="glyph-workflow"
878
- style={{
879
- margin: '12px 0',
880
- padding: 12,
881
- border: '1px solid var(--border)',
882
- borderRadius: 10,
883
- background: 'var(--bg-elev)',
884
- overflow: 'auto',
885
- }}
886
- >
887
- <svg
888
- role="img"
889
- aria-label="Workflow diagram"
890
- width={width}
891
- height={height}
892
- style={{ display: 'block', maxWidth: '100%' }}
893
- >
894
- <defs>
895
- <marker
896
- id={`arrow-${id}`}
897
- viewBox="0 0 10 10"
898
- refX="9"
899
- refY="5"
900
- markerWidth="6"
901
- markerHeight="6"
902
- orient="auto-start-reverse"
903
- >
904
- <path d="M 0 0 L 10 5 L 0 10 z" fill="var(--text-dim)" />
905
- </marker>
906
- </defs>
907
-
908
- {connections.map((c, i) => {
909
- const from = nodeCenter(c.from);
910
- const to = nodeCenter(c.to);
911
- if (!from || !to) return null;
912
- const dx = to.x - from.x;
913
- const dy = to.y - from.y;
914
- const fromX = dx >= 0 ? from.x + BOX_W / 2 : from.x - BOX_W / 2;
915
- const toX = dx >= 0 ? to.x - BOX_W / 2 : to.x + BOX_W / 2;
916
- const fromY = dy >= 0 ? from.y + BOX_H / 2 : from.y - BOX_H / 2;
917
- const toY = dy >= 0 ? to.y - BOX_H / 2 : to.y + BOX_H / 2;
918
- const midX = (fromX + toX) / 2;
919
- const midY = (fromY + toY) / 2;
920
- return (
921
- <g key={i}>
922
- <line
923
- x1={fromX}
924
- y1={fromY}
925
- x2={toX}
926
- y2={toY}
927
- stroke="var(--text-dim)"
928
- strokeWidth={1.5}
929
- markerEnd={`url(#arrow-${id})`}
930
- />
931
- {c.label && (
932
- <text
933
- x={midX}
934
- y={midY - 4}
935
- fontSize={10}
936
- fill="var(--text-dim)"
937
- textAnchor="middle"
938
- fontFamily="var(--font-mono)"
939
- >
940
- {c.label}
941
- </text>
942
- )}
943
- </g>
944
- );
945
- })}
946
-
947
- {steps.map((s) => {
948
- const pos = layout.find((p) => p.id === s.id);
949
- if (!pos) return null;
950
- const x = GAP_X + pos.col * (BOX_W + GAP_X);
951
- const y = GAP_Y + pos.row * (BOX_H + GAP_Y);
952
- const c = STEP_COLORS[s.type];
953
- if (s.type === 'decision') {
954
- const cx = x + BOX_W / 2;
955
- const cy = y + BOX_H / 2;
956
- const points = [
957
- [cx, y],
958
- [x + BOX_W, cy],
959
- [cx, y + BOX_H],
960
- [x, cy],
961
- ]
962
- .map((p) => p.join(','))
963
- .join(' ');
964
- return (
965
- <g key={s.id}>
966
- <polygon
967
- points={points}
968
- fill={c.fill}
969
- stroke={c.stroke}
970
- strokeWidth={2}
971
- />
972
- <foreignObject x={x + 8} y={cy - 14} width={BOX_W - 16} height={28}>
973
- <div
974
- style={{
975
- display: 'flex',
976
- alignItems: 'center',
977
- justifyContent: 'center',
978
- gap: 4,
979
- fontSize: 12,
980
- color: c.fg,
981
- textAlign: 'center',
982
- lineHeight: 1.2,
983
- fontStyle: 'italic',
984
- height: '100%',
985
- }}
986
- >
987
- <Diamond size={11} />
988
- {s.label}
989
- </div>
990
- </foreignObject>
991
- </g>
992
- );
993
- }
994
- const isNote = s.type === 'note';
995
- return (
996
- <g key={s.id}>
997
- <rect
998
- x={x}
999
- y={y}
1000
- width={BOX_W}
1001
- height={BOX_H}
1002
- rx={8}
1003
- fill={c.fill}
1004
- stroke={c.stroke}
1005
- strokeWidth={isNote ? 1 : 2}
1006
- strokeDasharray={isNote ? '4 3' : undefined}
1007
- />
1008
- <foreignObject x={x + 6} y={y + 6} width={BOX_W - 12} height={BOX_H - 12}>
1009
- <div
1010
- style={{
1011
- display: 'flex',
1012
- alignItems: 'center',
1013
- justifyContent: 'center',
1014
- gap: 6,
1015
- fontSize: 12,
1016
- color: c.fg,
1017
- textAlign: 'center',
1018
- lineHeight: 1.25,
1019
- fontStyle: isNote ? 'italic' : 'normal',
1020
- height: '100%',
1021
- }}
1022
- >
1023
- {isNote && <StickyNote size={11} />}
1024
- {s.label}
1025
- </div>
1026
- </foreignObject>
1027
- </g>
1028
- );
1029
- })}
1030
- </svg>
1031
- </div>
1032
- );
1033
- }
1034
-
1035
- function Empty({ id }: { id: string }) {
1036
- return (
1037
- <div
1038
- id={id}
1039
- style={{
1040
- padding: 20,
1041
- textAlign: 'center',
1042
- color: 'var(--text-dim)',
1043
- fontSize: 13,
1044
- }}
1045
- >
1046
- No workflow steps.
1047
- </div>
1048
- );
1049
- }
1050
-
1051
- type LayoutPos = { id: string; col: number; row: number };
1052
-
1053
- function layoutSteps(steps: WorkflowStep[]): LayoutPos[] {
1054
- if (steps.length === 0) return [];
1055
- return steps.map((s, i) => ({ id: s.id, col: i, row: 0 }));
1056
- }
1057
-
1058
- const proseStyle: React.CSSProperties = {
1059
- fontSize: 14,
1060
- lineHeight: 1.6,
1061
- color: 'var(--text)',
1062
- };
1063
-
1064
- // ─── Mockup ─────────────────────────────────────────────────────────────────
1065
-
1066
- export interface MockupProps {
1067
- id: string;
1068
- title?: string;
1069
- x?: number;
1070
- y?: number;
1071
- w?: number;
1072
- h?: number;
1073
- html: string;
1074
- }
1075
-
1076
- export function Mockup({ id, title, x, y, w, h, html }: MockupProps) {
1077
- return (
1078
- <figure
1079
- id={id}
1080
- data-block-id={id}
1081
- className="glyph-mockup"
1082
- style={{ width: w, minHeight: h }}
1083
- >
1084
- {title && <figcaption className="glyph-mockup-title">{title}</figcaption>}
1085
- <div className="glyph-mockup-frame">
1086
- <div className="glyph-mockup-chrome">
1087
- <span />
1088
- <span />
1089
- <span />
1090
- </div>
1091
- <div
1092
- className="glyph-mockup-body"
1093
- dangerouslySetInnerHTML={{ __html: html }}
1094
- />
1095
- </div>
1096
- </figure>
1097
- );
1098
- }