@dfosco/storyboard 0.7.1 → 0.9.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 (323) hide show
  1. package/dist/storyboard-ui.css +1 -1
  2. package/dist/storyboard-ui.js +14128 -10953
  3. package/dist/storyboard-ui.js.map +1 -1
  4. package/dist/tailwind.css +1 -1
  5. package/dist/tiny-canvas.css +1 -1
  6. package/package.json +138 -128
  7. package/scaffold/AGENTS.md +9 -7
  8. package/scaffold/README.md +18 -0
  9. package/scaffold/deploy.yml +21 -0
  10. package/scaffold/gitignore +8 -14
  11. package/scaffold/preview.yml +40 -0
  12. package/scaffold/{manifest.json → scaffold.config.json} +73 -3
  13. package/scaffold/scripts/aggregate-artifacts.mjs +257 -0
  14. package/scaffold/skills/canvas/SKILL.md +1 -1
  15. package/scaffold/skills/migrate-0.5.0/SKILL.md +1 -1
  16. package/scaffold/skills/ship/SKILL.md +2 -2
  17. package/scaffold/skills/worktree/SKILL.md +1 -1
  18. package/scaffold/src/_prototype.jsx +17 -0
  19. package/scaffold/src/_story.jsx +13 -0
  20. package/scaffold/src/library/README.md +34 -0
  21. package/scaffold/src/library/_app.jsx +41 -0
  22. package/scaffold/src/library/_app.module.css +2 -0
  23. package/scaffold/src/library/create.jsx +10 -0
  24. package/scaffold/src/library/index.jsx +14 -0
  25. package/scaffold/src/library/mount.jsx +51 -0
  26. package/scaffold/src/library/prototypes-entry.jsx +57 -0
  27. package/scaffold/src/library/routes.jsx +205 -0
  28. package/scaffold/src/library/viewfinder.jsx +13 -0
  29. package/scaffold/src/library/workspace.jsx +17 -0
  30. package/scripts/aggregate-artifacts.mjs +257 -0
  31. package/src/canvas/style.css +16 -16
  32. package/src/core/artifact/operations.js +54 -15
  33. package/src/core/artifact/schemas/canvas.schema.json +7 -1
  34. package/src/core/autosync/server.test.js +1 -1
  35. package/src/core/canvas/hot-pool.js +21 -33
  36. package/src/core/canvas/materializer.js +39 -13
  37. package/src/core/canvas/selectedWidgets.js +1 -1
  38. package/src/core/canvas/server.js +376 -100
  39. package/src/core/canvas/server.test.js +472 -2
  40. package/src/core/canvas/terminal-server.js +144 -57
  41. package/src/core/canvas/undoRedo.js +174 -0
  42. package/src/core/canvas/undoRedo.test.js +250 -0
  43. package/src/core/cli/artifact.js +2 -0
  44. package/src/core/cli/buildManifest.js +34 -0
  45. package/src/core/cli/canvasRedo.js +44 -0
  46. package/src/core/cli/canvasUndo.js +40 -0
  47. package/src/core/cli/create.js +151 -23
  48. package/src/core/cli/dev.js +23 -35
  49. package/src/core/cli/index.js +21 -0
  50. package/src/core/cli/schemas.js +8 -4
  51. package/src/core/cli/serverUrl.js +24 -0
  52. package/src/core/cli/setup.js +14 -25
  53. package/src/core/cli/terminal-welcome.js +12 -6
  54. package/src/core/cli/updateVersion.js +42 -2
  55. package/src/core/cli/workleaf.js +140 -0
  56. package/src/core/comments/api.js +1 -1
  57. package/src/core/comments/queries.js +3 -0
  58. package/src/core/comments/ui/CommentWindow.jsx +3 -2
  59. package/src/core/comments/ui/comment-layout.css +14 -14
  60. package/src/core/data/artifactIndex.js +235 -0
  61. package/src/core/data/artifactIndex.test.js +203 -0
  62. package/src/core/data/artifactManifest.js +290 -0
  63. package/src/core/data/artifactManifest.test.js +207 -0
  64. package/src/core/data/viewfinder.js +47 -7
  65. package/src/core/index.js +24 -1
  66. package/src/core/inspector/highlighter.js +1 -1
  67. package/src/core/inspector/mouseMode.js +2 -2
  68. package/src/core/lib/components/ui/avatar/avatar-fallback.jsx +2 -2
  69. package/src/core/lib/components/ui/avatar/avatar-image.jsx +2 -2
  70. package/src/core/lib/components/ui/avatar/avatar.jsx +2 -2
  71. package/src/core/lib/components/ui/checkbox/checkbox.jsx +12 -9
  72. package/src/core/lib/components/ui/dialog/dialog-content.jsx +45 -31
  73. package/src/core/lib/components/ui/dialog/dialog-trigger.jsx +9 -5
  74. package/src/core/lib/components/ui/dialog/dialog.jsx +12 -3
  75. package/src/core/lib/components/ui/dialog/dialog.module.css +118 -0
  76. package/src/core/lib/components/ui/dialog/index.js +4 -34
  77. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.jsx +3 -3
  78. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.jsx +19 -9
  79. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-content.jsx +8 -8
  80. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.jsx +2 -2
  81. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-group.jsx +2 -2
  82. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-item.jsx +15 -4
  83. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-portal.jsx +2 -2
  84. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.jsx +2 -2
  85. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.jsx +14 -7
  86. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-separator.jsx +2 -2
  87. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.jsx +8 -4
  88. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.jsx +4 -4
  89. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-sub.jsx +2 -2
  90. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-trigger.jsx +8 -2
  91. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu.jsx +2 -2
  92. package/src/core/lib/components/ui/label/label.jsx +1 -2
  93. package/src/core/lib/components/ui/panel/panel-close.jsx +7 -4
  94. package/src/core/lib/components/ui/panel/panel-content.jsx +7 -9
  95. package/src/core/lib/components/ui/panel/panel-title.jsx +3 -3
  96. package/src/core/lib/components/ui/panel/panel.jsx +11 -2
  97. package/src/core/lib/components/ui/separator/separator.jsx +6 -4
  98. package/src/core/lib/components/ui/tooltip/tooltip-content.jsx +7 -6
  99. package/src/core/lib/components/ui/tooltip/tooltip-trigger.jsx +13 -6
  100. package/src/core/lib/components/ui/tooltip/tooltip.jsx +5 -5
  101. package/src/core/modes/modes.css +4 -4
  102. package/src/core/mountStoryboardCore.js +287 -83
  103. package/src/core/mountStoryboardCore.test.js +198 -0
  104. package/src/core/rename-watcher/config.json +1 -1
  105. package/src/core/rename-watcher/watcher.js +330 -37
  106. package/src/core/rename-watcher/watcher.test.js +253 -0
  107. package/src/core/scaffold/fragments.js +287 -0
  108. package/src/core/scaffold/fragments.test.js +401 -0
  109. package/src/core/scaffold/index.js +291 -0
  110. package/src/core/scaffold/migrateLegacyGitignore.js +157 -0
  111. package/src/core/scaffold/scaffold-integration.test.js +247 -0
  112. package/src/core/scaffold.js +4 -97
  113. package/src/core/stores/canvasInteractionStore.js +120 -0
  114. package/src/core/stores/canvasInteractionStore.test.js +126 -0
  115. package/src/core/stores/configSchema.js +64 -8
  116. package/src/core/stores/configSchema.test.js +3 -0
  117. package/src/core/stores/customerModeConfig.js +24 -3
  118. package/src/core/stores/customerModeConfig.test.js +46 -0
  119. package/src/core/stores/presentationStore.js +118 -0
  120. package/src/core/stores/presentationStore.test.js +114 -0
  121. package/src/core/stores/recentArtifacts.js +49 -2
  122. package/src/core/stores/recentArtifacts.test.js +59 -6
  123. package/src/core/stores/themeBootstrap.js +264 -0
  124. package/src/core/stores/themeBootstrap.test.js +211 -0
  125. package/src/core/stores/themeStore.test.js +154 -0
  126. package/src/core/stores/themeStore.ts +235 -220
  127. package/src/core/stores/uiConfig.js +10 -2
  128. package/src/core/styles/generateThemesCss.js +63 -0
  129. package/src/core/styles/tailwind.css +150 -94
  130. package/src/core/styles/workspace-chrome.css +13 -0
  131. package/src/core/tools/handlers/paletteTheme.js +11 -8
  132. package/src/core/ui/ActionMenuButton.jsx +2 -1
  133. package/src/core/ui/AutosyncMenuButton.css +7 -7
  134. package/src/core/ui/BranchSelect.module.css +5 -5
  135. package/src/core/ui/CanvasCreateMenu.jsx +1 -19
  136. package/src/core/ui/ChromeSlot.jsx +92 -0
  137. package/src/core/ui/ChromeSlot.test.jsx +140 -0
  138. package/src/core/ui/CoreUIBar.css +5 -5
  139. package/src/core/ui/CoreUIBar.jsx +170 -142
  140. package/src/core/ui/InspectorPanel.css +5 -5
  141. package/src/core/ui/InspectorPanel.jsx +9 -9
  142. package/src/core/ui/PwaInstallBanner.css +5 -5
  143. package/src/core/ui/PwaInstallBanner.jsx +5 -5
  144. package/src/core/ui/ThemeMenuButton.jsx +45 -30
  145. package/src/core/ui/core-ui-colors.css +28 -66
  146. package/src/core/ui/sidepanel.css +12 -12
  147. package/src/core/vite/server-plugin.js +13 -0
  148. package/src/core/workleaf/cleanup.js +102 -0
  149. package/src/core/workleaf/create.js +199 -0
  150. package/src/core/workleaf/delete.js +101 -0
  151. package/src/core/workleaf/list.js +57 -0
  152. package/src/core/workleaf/merge.js +238 -0
  153. package/src/core/workleaf/paths.js +146 -0
  154. package/src/core/workleaf/paths.test.js +230 -0
  155. package/src/core/workshop/features/createCanvas/CreateCanvasForm.jsx +130 -34
  156. package/src/core/workshop/features/createFlow/server.js +5 -1
  157. package/src/core/workshop/features/createPrototype/server.js +5 -1
  158. package/src/core/workshop/features/templateIndex.js +28 -1
  159. package/src/core/worktree/port.js +48 -5
  160. package/src/core/worktree/port.test.js +42 -0
  161. package/src/internals/ArtifactForm/ArtifactForm.jsx +173 -112
  162. package/src/internals/ArtifactForm/ArtifactForm.module.css +51 -69
  163. package/src/internals/ArtifactForm/artifactSchemas.js +40 -5
  164. package/src/internals/AuthModal/AuthModal.module.css +34 -34
  165. package/src/internals/BaseUiForm/BaseUiForm.jsx +293 -0
  166. package/src/internals/BaseUiForm/BaseUiForm.module.css +542 -0
  167. package/src/internals/BranchBar/BranchBar.module.css +4 -4
  168. package/src/internals/BranchesDropdown/BranchesDropdown.jsx +69 -0
  169. package/src/internals/BranchesDropdown/BranchesDropdown.module.css +84 -0
  170. package/src/internals/CommandPalette/CommandPalette.jsx +41 -29
  171. package/src/internals/CommandPalette/CreateArtifactForm.jsx +150 -0
  172. package/src/internals/CommandPalette/CreateDialog.jsx +20 -110
  173. package/src/internals/CommandPalette/WidgetArtifactDialog.css +16 -16
  174. package/src/internals/CommandPalette/WidgetArtifactDialog.jsx +1 -1
  175. package/src/internals/CommandPalette/command-palette.css +14 -14
  176. package/src/internals/CommandPalette/createHelpers.js +30 -0
  177. package/src/internals/CreatePage/CreatePage.jsx +57 -0
  178. package/src/internals/CreatePage/CreatePage.module.css +34 -0
  179. package/src/internals/Dialog.jsx +51 -0
  180. package/src/internals/FlowError.module.css +5 -5
  181. package/src/internals/PrototypeErrorBoundary.module.css +15 -15
  182. package/src/internals/SimpleWorkspace/SimpleWorkspace.jsx +534 -0
  183. package/src/internals/SimpleWorkspace/SimpleWorkspace.module.css +323 -0
  184. package/src/internals/Tooltip.jsx +39 -0
  185. package/src/internals/Viewfinder.jsx +229 -64
  186. package/src/internals/Viewfinder.module.css +253 -182
  187. package/src/internals/canvas/CanvasControls.module.css +11 -11
  188. package/src/internals/canvas/CanvasPage.bridge.test.jsx +11 -37
  189. package/src/internals/canvas/CanvasPage.jsx +358 -217
  190. package/src/internals/canvas/CanvasPage.module.css +20 -19
  191. package/src/internals/canvas/CanvasPage.multiselect.test.jsx +39 -26
  192. package/src/internals/canvas/CanvasToolbar.module.css +11 -11
  193. package/src/internals/canvas/ConnectorLayer.jsx +39 -2
  194. package/src/internals/canvas/ConnectorLayer.module.css +10 -10
  195. package/src/internals/canvas/PageSelector.jsx +15 -1
  196. package/src/internals/canvas/PageSelector.module.css +41 -27
  197. package/src/internals/canvas/canvasApi.js +40 -5
  198. package/src/internals/canvas/canvasTheme.js +22 -111
  199. package/src/internals/canvas/isolation/createIsolationMiddleware.js +68 -0
  200. package/src/internals/canvas/isolation/mountIsolationApp.jsx +88 -0
  201. package/src/internals/canvas/isolation/prototypeRoutes.jsx +140 -0
  202. package/src/internals/canvas/isolation/prototypesEntry.jsx +28 -0
  203. package/src/internals/canvas/isolation/storiesEntry.jsx +20 -0
  204. package/src/internals/canvas/isolation/storyRoutes.jsx +55 -0
  205. package/src/internals/canvas/useUndoRedo.js +75 -60
  206. package/src/internals/canvas/useUndoRedo.test.js +46 -178
  207. package/src/internals/canvas/widgets/CodePenEmbed.jsx +16 -36
  208. package/src/internals/canvas/widgets/CodePenEmbed.module.css +12 -12
  209. package/src/internals/canvas/widgets/CropOverlay.module.css +23 -23
  210. package/src/internals/canvas/widgets/ExpandedPane.module.css +8 -8
  211. package/src/internals/canvas/widgets/ExpandedPaneTopBar.jsx +1 -1
  212. package/src/internals/canvas/widgets/FigmaEmbed.jsx +15 -36
  213. package/src/internals/canvas/widgets/FigmaEmbed.module.css +15 -15
  214. package/src/internals/canvas/widgets/FrozenTerminalOverlay.jsx +30 -21
  215. package/src/internals/canvas/widgets/FrozenTerminalOverlay.module.css +5 -5
  216. package/src/internals/canvas/widgets/ImageWidget.jsx +7 -2
  217. package/src/internals/canvas/widgets/ImageWidget.module.css +3 -3
  218. package/src/internals/canvas/widgets/LinkPreview.module.css +79 -80
  219. package/src/internals/canvas/widgets/MarkdownBlock.module.css +31 -31
  220. package/src/internals/canvas/widgets/PromptWidget.jsx +2 -16
  221. package/src/internals/canvas/widgets/PromptWidget.module.css +33 -33
  222. package/src/internals/canvas/widgets/PrototypeEmbed.jsx +92 -17
  223. package/src/internals/canvas/widgets/PrototypeEmbed.module.css +58 -56
  224. package/src/internals/canvas/widgets/PrototypeEmbed.test.jsx +118 -4
  225. package/src/internals/canvas/widgets/ResizeHandle.module.css +4 -4
  226. package/src/internals/canvas/widgets/StorySetWidget.jsx +53 -25
  227. package/src/internals/canvas/widgets/StoryWidget.jsx +71 -56
  228. package/src/internals/canvas/widgets/StoryWidget.module.css +22 -20
  229. package/src/internals/canvas/widgets/TerminalReadWidget.jsx +13 -15
  230. package/src/internals/canvas/widgets/TerminalReadWidget.module.css +4 -4
  231. package/src/internals/canvas/widgets/TerminalWidget.jsx +56 -45
  232. package/src/internals/canvas/widgets/TerminalWidget.module.css +10 -10
  233. package/src/internals/canvas/widgets/TilesWidget.module.css +17 -17
  234. package/src/internals/canvas/widgets/WidgetChrome.jsx +1 -1
  235. package/src/internals/canvas/widgets/WidgetChrome.module.css +76 -61
  236. package/src/internals/canvas/widgets/WidgetWrapper.module.css +2 -2
  237. package/src/internals/canvas/widgets/embedOverlay.module.css +14 -4
  238. package/src/internals/canvas/widgets/embedTheme.js +12 -104
  239. package/src/internals/canvas/widgets/expandUtils.js +19 -19
  240. package/src/internals/canvas/widgets/normalizeLegacyEmbedSrc.js +74 -0
  241. package/src/internals/canvas/widgets/widgetConfig.js +5 -5
  242. package/src/internals/context.jsx +22 -1
  243. package/src/internals/context.test.jsx +47 -0
  244. package/src/internals/hooks/useArtifactIndex.js +31 -0
  245. package/src/internals/hooks/useArtifactIndex.test.js +45 -0
  246. package/src/internals/hooks/usePrototypeReloadGuard.js +14 -8
  247. package/src/internals/index.js +6 -0
  248. package/src/internals/loadConsumerWrapper.js +60 -0
  249. package/src/internals/story/ComponentSetPage.jsx +75 -34
  250. package/src/internals/story/ComponentSetPage.module.css +14 -14
  251. package/src/internals/story/StoryPage.jsx +16 -25
  252. package/src/internals/story/StoryPage.module.css +2 -2
  253. package/src/internals/vite/data-plugin.js +317 -149
  254. package/src/internals/vite/data-plugin.test.js +11 -11
  255. package/{scaffold/storyboard.config.json → storyboard.config.json} +25 -0
  256. package/terminal.config.json +1 -1
  257. package/src/core/lib/components/ui/card/card-action.jsx +0 -11
  258. package/src/core/lib/components/ui/card/card-content.jsx +0 -11
  259. package/src/core/lib/components/ui/card/card-description.jsx +0 -11
  260. package/src/core/lib/components/ui/card/card-footer.jsx +0 -11
  261. package/src/core/lib/components/ui/card/card-header.jsx +0 -19
  262. package/src/core/lib/components/ui/card/card-title.jsx +0 -11
  263. package/src/core/lib/components/ui/card/card.jsx +0 -17
  264. package/src/core/lib/components/ui/card/index.js +0 -25
  265. package/src/core/lib/components/ui/collapsible/collapsible-content.jsx +0 -7
  266. package/src/core/lib/components/ui/collapsible/collapsible-trigger.jsx +0 -7
  267. package/src/core/lib/components/ui/collapsible/collapsible.jsx +0 -7
  268. package/src/core/lib/components/ui/collapsible/index.js +0 -13
  269. package/src/core/lib/components/ui/dialog/dialog-close.jsx +0 -7
  270. package/src/core/lib/components/ui/dialog/dialog-description.jsx +0 -15
  271. package/src/core/lib/components/ui/dialog/dialog-footer.jsx +0 -23
  272. package/src/core/lib/components/ui/dialog/dialog-header.jsx +0 -11
  273. package/src/core/lib/components/ui/dialog/dialog-overlay.jsx +0 -15
  274. package/src/core/lib/components/ui/dialog/dialog-portal.jsx +0 -4
  275. package/src/core/lib/components/ui/dialog/dialog-title.jsx +0 -15
  276. package/src/core/lib/components/ui/popover/index.js +0 -28
  277. package/src/core/lib/components/ui/popover/popover-close.jsx +0 -7
  278. package/src/core/lib/components/ui/popover/popover-content.jsx +0 -22
  279. package/src/core/lib/components/ui/popover/popover-description.jsx +0 -11
  280. package/src/core/lib/components/ui/popover/popover-header.jsx +0 -11
  281. package/src/core/lib/components/ui/popover/popover-portal.jsx +0 -4
  282. package/src/core/lib/components/ui/popover/popover-title.jsx +0 -11
  283. package/src/core/lib/components/ui/popover/popover-trigger.jsx +0 -8
  284. package/src/core/lib/components/ui/popover/popover.jsx +0 -4
  285. package/src/core/lib/components/ui/select/index.js +0 -37
  286. package/src/core/lib/components/ui/select/select-content.jsx +0 -30
  287. package/src/core/lib/components/ui/select/select-group-heading.jsx +0 -17
  288. package/src/core/lib/components/ui/select/select-group.jsx +0 -15
  289. package/src/core/lib/components/ui/select/select-item.jsx +0 -26
  290. package/src/core/lib/components/ui/select/select-label.jsx +0 -11
  291. package/src/core/lib/components/ui/select/select-portal.jsx +0 -4
  292. package/src/core/lib/components/ui/select/select-scroll-down-button.jsx +0 -18
  293. package/src/core/lib/components/ui/select/select-scroll-up-button.jsx +0 -18
  294. package/src/core/lib/components/ui/select/select-separator.jsx +0 -15
  295. package/src/core/lib/components/ui/select/select-trigger.jsx +0 -25
  296. package/src/core/lib/components/ui/select/select.jsx +0 -4
  297. package/src/core/lib/components/ui/sheet/index.js +0 -34
  298. package/src/core/lib/components/ui/sheet/sheet-close.jsx +0 -7
  299. package/src/core/lib/components/ui/sheet/sheet-content.jsx +0 -35
  300. package/src/core/lib/components/ui/sheet/sheet-description.jsx +0 -15
  301. package/src/core/lib/components/ui/sheet/sheet-footer.jsx +0 -11
  302. package/src/core/lib/components/ui/sheet/sheet-header.jsx +0 -11
  303. package/src/core/lib/components/ui/sheet/sheet-overlay.jsx +0 -15
  304. package/src/core/lib/components/ui/sheet/sheet-portal.jsx +0 -4
  305. package/src/core/lib/components/ui/sheet/sheet-title.jsx +0 -15
  306. package/src/core/lib/components/ui/sheet/sheet-trigger.jsx +0 -7
  307. package/src/core/lib/components/ui/sheet/sheet.jsx +0 -4
  308. package/src/core/lib/components/ui/toggle/index.js +0 -8
  309. package/src/core/lib/components/ui/toggle/toggle.jsx +0 -36
  310. package/src/core/lib/components/ui/toggle-group/index.js +0 -10
  311. package/src/core/lib/components/ui/toggle-group/toggle-group-item.jsx +0 -29
  312. package/src/core/lib/components/ui/toggle-group/toggle-group.jsx +0 -43
  313. package/src/internals/canvas/StoryErrorBoundary.jsx +0 -47
  314. package/src/internals/canvas/WebGLContextPool.jsx +0 -291
  315. package/src/internals/canvas/WebGLContextPool.test.jsx +0 -165
  316. package/src/internals/canvas/componentIsolate.jsx +0 -144
  317. package/src/internals/canvas/componentSetIsolate.jsx +0 -300
  318. package/src/internals/canvas/widgets/ComponentSetWidget.module.css +0 -89
  319. package/src/internals/canvas/widgets/InlineStoryRenderer.jsx +0 -129
  320. package/src/internals/canvas/widgets/InlineStoryRenderer.test.jsx +0 -68
  321. package/src/internals/canvas/widgets/StorySetWidget.module.css +0 -89
  322. package/src/primer/ThemeSync.jsx +0 -73
  323. package/src/primer/index.js +0 -1
@@ -33,7 +33,7 @@
33
33
  width: 12px;
34
34
  height: 12px;
35
35
  background: #ffffff;
36
- border: 2px solid var(--fgColor-accent, #0969da);
36
+ border: 2px solid var(--color-foreground-accent, #0969da);
37
37
  border-radius: 2px;
38
38
  z-index: 12;
39
39
  }
@@ -55,8 +55,8 @@
55
55
  justify-content: center;
56
56
  gap: 6px;
57
57
  padding: 4px 8px;
58
- background: var(--bgColor-default, #ffffff);
59
- border: 1.6px solid var(--borderColor-muted, #d0d7de);
58
+ background: var(--color-background, #ffffff);
59
+ border: 1.6px solid var(--color-border-muted, #d0d7de);
60
60
  border-radius: 20px;
61
61
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
62
62
  white-space: nowrap;
@@ -64,8 +64,8 @@
64
64
  }
65
65
 
66
66
  :global([data-sb-canvas-theme^='dark']) .cropBar {
67
- background: var(--bgColor-muted, #161b22);
68
- border-color: var(--borderColor-muted, #373e47);
67
+ background: var(--color-background-muted, #161b22);
68
+ border-color: var(--color-border-muted, #373e47);
69
69
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
70
70
  }
71
71
 
@@ -79,76 +79,76 @@
79
79
  border-radius: 6px;
80
80
  font-size: 12px;
81
81
  font-weight: 500;
82
- color: var(--fgColor-default, #1f2328);
82
+ color: var(--color-foreground, #1f2328);
83
83
  transition: background 100ms;
84
84
  }
85
85
 
86
86
  :global([data-sb-canvas-theme^='dark']) .cropBarBtn {
87
- color: var(--fgColor-default, #e6edf3);
87
+ color: var(--color-foreground, #e6edf3);
88
88
  }
89
89
 
90
90
  .cropBarBtn:hover {
91
- background: var(--bgColor-neutral-muted, #eaeef2);
91
+ background: var(--color-background-neutral-muted, #eaeef2);
92
92
  }
93
93
 
94
94
  :global([data-sb-canvas-theme^='dark']) .cropBarBtn:hover {
95
- background: var(--bgColor-neutral-muted, #272c33);
95
+ background: var(--color-background-neutral-muted, #272c33);
96
96
  }
97
97
 
98
98
  .cropBarBtnSave {
99
- background: var(--bgColor-success-emphasis, #1a7f37);
100
- color: var(--fgColor-onEmphasis, #ffffff);
99
+ background: var(--color-background-success-emphasis, #1a7f37);
100
+ color: var(--color-foreground-on-emphasis, #ffffff);
101
101
  }
102
102
 
103
103
  .cropBarBtnSave:hover {
104
- background: var(--bgColor-success-emphasis, #2da44e);
104
+ background: var(--color-background-success-emphasis, #2da44e);
105
105
  filter: brightness(1.1);
106
106
  }
107
107
 
108
108
  :global([data-sb-canvas-theme^='dark']) .cropBarBtnSave {
109
- background: var(--bgColor-success-emphasis, #238636);
110
- color: var(--fgColor-onEmphasis, #ffffff);
109
+ background: var(--color-background-success-emphasis, #238636);
110
+ color: var(--color-foreground-on-emphasis, #ffffff);
111
111
  }
112
112
 
113
113
  :global([data-sb-canvas-theme^='dark']) .cropBarBtnSave:hover {
114
- background: var(--bgColor-success-emphasis, #2ea043);
114
+ background: var(--color-background-success-emphasis, #2ea043);
115
115
  filter: brightness(1.1);
116
116
  }
117
117
 
118
118
  .cropBarBtnCancel {
119
- color: var(--fgColor-muted, #656d76);
119
+ color: var(--color-foreground-muted, #656d76);
120
120
  }
121
121
 
122
122
  :global([data-sb-canvas-theme^='dark']) .cropBarBtnCancel {
123
- color: var(--fgColor-muted, #8b949e);
123
+ color: var(--color-foreground-muted, #8b949e);
124
124
  }
125
125
 
126
126
  .cropBarBtnCancel:hover {
127
- color: var(--fgColor-default, #1f2328);
127
+ color: var(--color-foreground, #1f2328);
128
128
  }
129
129
 
130
130
  :global([data-sb-canvas-theme^='dark']) .cropBarBtnCancel:hover {
131
- color: var(--fgColor-default, #e6edf3);
131
+ color: var(--color-foreground, #e6edf3);
132
132
  }
133
133
 
134
134
  .dimensions {
135
135
  font-size: 11px;
136
136
  font-weight: 500;
137
- color: var(--fgColor-muted, #656d76);
137
+ color: var(--color-foreground-muted, #656d76);
138
138
  padding: 0 4px;
139
139
  font-variant-numeric: tabular-nums;
140
140
  }
141
141
 
142
142
  :global([data-sb-canvas-theme^='dark']) .dimensions {
143
- color: var(--fgColor-muted, #8b949e);
143
+ color: var(--color-foreground-muted, #8b949e);
144
144
  }
145
145
 
146
146
  .separator {
147
147
  width: 1px;
148
148
  height: 16px;
149
- background: var(--borderColor-muted, #d0d7de);
149
+ background: var(--color-border-muted, #d0d7de);
150
150
  }
151
151
 
152
152
  :global([data-sb-canvas-theme^='dark']) .separator {
153
- background: var(--borderColor-muted, #373e47);
153
+ background: var(--color-border-muted, #373e47);
154
154
  }
@@ -26,7 +26,7 @@
26
26
  position: relative;
27
27
  border-radius: 12px;
28
28
  overflow: hidden;
29
- background: var(--bgColor-default, #ffffff);
29
+ background: var(--color-background, #ffffff);
30
30
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.4);
31
31
  display: flex;
32
32
  flex-direction: column;
@@ -58,7 +58,7 @@
58
58
  display: flex;
59
59
  flex-direction: column;
60
60
  overflow: hidden;
61
- background: var(--bgColor-default, #ffffff);
61
+ background: var(--color-background, #ffffff);
62
62
  animation: expandedPaneScaleIn 0.2s ease;
63
63
  }
64
64
 
@@ -165,7 +165,7 @@
165
165
 
166
166
  .divider:hover,
167
167
  .divider:active {
168
- background: var(--bgColor-accent-muted, rgba(9, 105, 218, 0.15));
168
+ background: var(--color-background-accent-muted, rgba(9, 105, 218, 0.15));
169
169
  }
170
170
 
171
171
  .divider::after {
@@ -175,13 +175,13 @@
175
175
  bottom: 0;
176
176
  left: 50%;
177
177
  width: 1px;
178
- background: var(--borderColor-muted, #d8dee4);
178
+ background: var(--color-border-muted, #d8dee4);
179
179
  transform: translateX(-50%);
180
180
  }
181
181
 
182
182
  .divider:hover::after,
183
183
  .divider:active::after {
184
- background: var(--fgColor-accent, #0969da);
184
+ background: var(--color-foreground-accent, #0969da);
185
185
  width: 2px;
186
186
  }
187
187
 
@@ -200,7 +200,7 @@
200
200
 
201
201
  .rowDivider:hover,
202
202
  .rowDivider:active {
203
- background: var(--bgColor-accent-muted, rgba(9, 105, 218, 0.15));
203
+ background: var(--color-background-accent-muted, rgba(9, 105, 218, 0.15));
204
204
  }
205
205
 
206
206
  .rowDivider::after {
@@ -210,12 +210,12 @@
210
210
  right: 0;
211
211
  top: 50%;
212
212
  height: 1px;
213
- background: var(--borderColor-muted, #d8dee4);
213
+ background: var(--color-border-muted, #d8dee4);
214
214
  transform: translateY(-50%);
215
215
  }
216
216
 
217
217
  .rowDivider:hover::after,
218
218
  .rowDivider:active::after {
219
- background: var(--fgColor-accent, #0969da);
219
+ background: var(--color-foreground-accent, #0969da);
220
220
  height: 2px;
221
221
  }
@@ -13,7 +13,7 @@
13
13
  * Combined with `getState` for toggle resolution and `onAction` for dispatch.
14
14
  */
15
15
  import { ScreenNormalIcon } from '@primer/octicons-react'
16
- import { Tooltip } from '@primer/react'
16
+ import Tooltip from '../../Tooltip.jsx'
17
17
  import { ICON_REGISTRY } from './widgetIcons.jsx'
18
18
  import { getWidgetMeta } from './widgetConfig.js'
19
19
  import Icon from '../../Icon.jsx'
@@ -57,7 +57,6 @@ export default forwardRef(function FigmaEmbed({ id: widgetId, props, onUpdate, r
57
57
  const height = readProp(props, 'height', figmaEmbedSchema)
58
58
 
59
59
  const [interactive, setInteractive] = useState(false)
60
- const [showIframe, setShowIframe] = useState(true)
61
60
  const [expandMode, setExpandMode] = useExpandOverride('figma', widgetId)
62
61
  const expanded = expandMode !== null
63
62
 
@@ -65,8 +64,6 @@ export default forwardRef(function FigmaEmbed({ id: widgetId, props, onUpdate, r
65
64
  const embedRef = useRef(null)
66
65
  const inlineContainerRef = useRef(null)
67
66
  const modalContainerRef = useRef(null)
68
- const teardownTimerRef = useRef(null)
69
- const exitSessionRef = useRef(0)
70
67
 
71
68
  // Validate URL at render time — only embed known Figma URLs
72
69
  const isValid = useMemo(() => isFigmaUrl(url), [url])
@@ -77,14 +74,11 @@ export default forwardRef(function FigmaEmbed({ id: widgetId, props, onUpdate, r
77
74
 
78
75
  useIframeDevLogs({
79
76
  widget: 'FigmaEmbed',
80
- loaded: showIframe && Boolean(embedUrl),
77
+ loaded: Boolean(embedUrl),
81
78
  src: embedUrl,
82
79
  })
83
80
 
84
81
  const enterInteractive = useCallback(() => {
85
- exitSessionRef.current++
86
- clearTimeout(teardownTimerRef.current)
87
- setShowIframe(true)
88
82
  setInteractive(true)
89
83
  }, [])
90
84
 
@@ -93,21 +87,12 @@ export default forwardRef(function FigmaEmbed({ id: widgetId, props, onUpdate, r
93
87
  function handlePointerDown(e) {
94
88
  if (embedRef.current && !embedRef.current.contains(e.target)) {
95
89
  setInteractive(false)
96
- // Keep iframe alive for 5 min — Figma is slow to reload
97
- const session = ++exitSessionRef.current
98
- clearTimeout(teardownTimerRef.current)
99
- teardownTimerRef.current = setTimeout(() => {
100
- if (exitSessionRef.current !== session) return
101
- setShowIframe(false)
102
- }, 5 * 60 * 1000)
103
90
  }
104
91
  }
105
92
  document.addEventListener('pointerdown', handlePointerDown)
106
93
  return () => document.removeEventListener('pointerdown', handlePointerDown)
107
94
  }, [interactive, expanded])
108
95
 
109
- useEffect(() => () => clearTimeout(teardownTimerRef.current), [])
110
-
111
96
  // Reparent iframe DOM node between inline container and modal.
112
97
  // Uses moveBefore() (Chrome 133+) which preserves the iframe's
113
98
  // browsing context — no reload. Falls back to appendChild.
@@ -147,10 +132,8 @@ export default forwardRef(function FigmaEmbed({ id: widgetId, props, onUpdate, r
147
132
  if (actionId === 'open-external') {
148
133
  if (url) window.open(url, '_blank', 'noopener')
149
134
  } else if (actionId === 'expand' || actionId === 'expand-single') {
150
- setShowIframe(true)
151
135
  setExpandMode('single')
152
136
  } else if (actionId === 'split-screen') {
153
- setShowIframe(true)
154
137
  setExpandMode('split')
155
138
  }
156
139
  },
@@ -166,24 +149,20 @@ export default forwardRef(function FigmaEmbed({ id: widgetId, props, onUpdate, r
166
149
  </div>
167
150
  {embedUrl ? (
168
151
  <>
169
- {showIframe ? (
170
- <div
171
- ref={inlineContainerRef}
172
- className={styles.iframeContainer}
173
- style={expanded ? { visibility: 'hidden' } : undefined}
174
- >
175
- <iframe
176
- ref={iframeRef}
177
- src={embedUrl}
178
- className={styles.iframe}
179
- title={`Figma ${typeLabel}: ${title}`}
180
- allowFullScreen
181
- onLoad={(e) => e.target.blur()}
182
- />
183
- </div>
184
- ) : (
185
- <div className={styles.iframeContainer} />
186
- )}
152
+ <div
153
+ ref={inlineContainerRef}
154
+ className={styles.iframeContainer}
155
+ style={expanded ? { visibility: 'hidden' } : undefined}
156
+ >
157
+ <iframe
158
+ ref={iframeRef}
159
+ src={embedUrl}
160
+ className={styles.iframe}
161
+ title={`Figma ${typeLabel}: ${title}`}
162
+ allowFullScreen
163
+ onLoad={(e) => e.target.blur()}
164
+ />
165
+ </div>
187
166
  {!interactive && !expanded && (
188
167
  <div
189
168
  className={overlayStyles.interactOverlay}
@@ -1,8 +1,8 @@
1
1
  .embed {
2
2
  position: relative;
3
3
  overflow: hidden;
4
- background: var(--bgColor-default, #ffffff);
5
- border: 3px solid var(--borderColor-default, #d0d7de);
4
+ background: var(--color-background, #ffffff);
5
+ border: 3px solid var(--color-border, #d0d7de);
6
6
  border-radius: 12px;
7
7
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
8
8
  }
@@ -14,9 +14,9 @@
14
14
  padding: 6px 10px;
15
15
  font-size: 12px;
16
16
  font-weight: 500;
17
- color: var(--fgColor-muted, #656d76);
18
- background: var(--bgColor-muted, #f6f8fa);
19
- border-bottom: 1px solid var(--borderColor-muted, #d8dee4);
17
+ color: var(--color-foreground-muted, #656d76);
18
+ background: var(--color-background-muted, #f6f8fa);
19
+ border-bottom: 1px solid var(--color-border-muted, #d8dee4);
20
20
  white-space: nowrap;
21
21
  overflow: hidden;
22
22
  text-overflow: ellipsis;
@@ -57,12 +57,12 @@
57
57
  background: linear-gradient(
58
58
  135deg,
59
59
  transparent 40%,
60
- var(--borderColor-muted, rgba(0, 0, 0, 0.15)) 40%,
61
- var(--borderColor-muted, rgba(0, 0, 0, 0.15)) 50%,
60
+ var(--color-border-muted, rgba(0, 0, 0, 0.15)) 40%,
61
+ var(--color-border-muted, rgba(0, 0, 0, 0.15)) 50%,
62
62
  transparent 50%,
63
63
  transparent 65%,
64
- var(--borderColor-muted, rgba(0, 0, 0, 0.15)) 65%,
65
- var(--borderColor-muted, rgba(0, 0, 0, 0.15)) 75%,
64
+ var(--color-border-muted, rgba(0, 0, 0, 0.15)) 65%,
65
+ var(--color-border-muted, rgba(0, 0, 0, 0.15)) 75%,
66
66
  transparent 75%
67
67
  );
68
68
  opacity: 0;
@@ -98,7 +98,7 @@
98
98
  position: relative;
99
99
  border-radius: 12px;
100
100
  overflow: hidden;
101
- background: var(--bgColor-default, #ffffff);
101
+ background: var(--color-background, #ffffff);
102
102
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.4);
103
103
  animation: expandScaleIn 0.2s ease;
104
104
  }
@@ -147,7 +147,7 @@
147
147
  height: 100%;
148
148
  position: relative;
149
149
  overflow: hidden;
150
- background: var(--bgColor-default, #ffffff);
150
+ background: var(--color-background, #ffffff);
151
151
  }
152
152
 
153
153
  .expandSplitBody {
@@ -170,7 +170,7 @@
170
170
  min-width: 0;
171
171
  height: 100%;
172
172
  overflow: hidden;
173
- border-right: 1px solid var(--borderColor-muted, #d8dee4);
173
+ border-right: 1px solid var(--color-border-muted, #d8dee4);
174
174
  }
175
175
 
176
176
  .expandSplitRight {
@@ -184,7 +184,7 @@
184
184
  width: 100%;
185
185
  height: 100%;
186
186
  overflow: auto;
187
- background: var(--bgColor-default, #ffffff);
187
+ background: var(--color-background, #ffffff);
188
188
  }
189
189
 
190
190
  .expandSecondaryIframe {
@@ -211,12 +211,12 @@
211
211
  }
212
212
 
213
213
  .emptyIcon {
214
- color: var(--fgColor-muted, #656d76);
214
+ color: var(--color-foreground-muted, #656d76);
215
215
  opacity: 0.5;
216
216
  }
217
217
 
218
218
  .emptyLabel {
219
- color: var(--fgColor-muted, #656d76);
219
+ color: var(--color-foreground-muted, #656d76);
220
220
  font-size: 13px;
221
221
  font-style: italic;
222
222
  }
@@ -48,32 +48,41 @@ export default function FrozenTerminalOverlay({ widgetId, onActivate }) {
48
48
 
49
49
  async function fetchSnapshot() {
50
50
  const baseUrl = getBaseUrl()
51
- const urls = [
52
- `${baseUrl}_storyboard/canvas/terminal-snapshot/${widgetId}`,
53
- `${baseUrl}_storyboard/terminal-snapshots/${widgetId}.snapshot.json`,
54
- ]
55
-
56
- for (const url of urls) {
57
- try {
58
- const res = await fetch(url)
59
- if (!res.ok) continue
51
+ // Try the dev-server REST endpoint first, then fall back to the static
52
+ // consolidated index (production builds / no server).
53
+ const restUrl = `${baseUrl}_storyboard/canvas/terminal-snapshot/${widgetId}`
54
+ const indexUrl = `${baseUrl}_storyboard/terminal-snapshots/agents.snapshot.json`
55
+
56
+ try {
57
+ const res = await fetch(restUrl)
58
+ if (res.ok) {
60
59
  const data = await res.json()
61
60
  if (cancelled) return
62
61
  const text = data.paneContent || data.content || data.output || ''
63
- if (!text) continue
64
-
65
- const converter = await getConverter()
66
- if (cancelled) return
67
- if (converter) {
68
- setHtml(converter.toHtml(text))
69
- } else {
70
- setPlainText(stripAnsi(text))
62
+ if (text) {
63
+ const converter = await getConverter()
64
+ if (cancelled) return
65
+ if (converter) setHtml(converter.toHtml(text))
66
+ else setPlainText(stripAnsi(text))
67
+ return
71
68
  }
72
- return
73
- } catch {
74
- continue
75
69
  }
76
- }
70
+ } catch { /* fall through to static index */ }
71
+
72
+ try {
73
+ const res = await fetch(indexUrl)
74
+ if (!res.ok) return
75
+ const data = await res.json()
76
+ if (cancelled) return
77
+ const entry = data?.agents?.[widgetId]
78
+ if (!entry) return
79
+ const text = entry.paneContent || entry.content || entry.output || ''
80
+ if (!text) return
81
+ const converter = await getConverter()
82
+ if (cancelled) return
83
+ if (converter) setHtml(converter.toHtml(text))
84
+ else setPlainText(stripAnsi(text))
85
+ } catch { /* empty */ }
77
86
  }
78
87
 
79
88
  fetchSnapshot()
@@ -12,7 +12,7 @@
12
12
  position: absolute;
13
13
  inset: 0;
14
14
  overflow: hidden;
15
- padding: var(--base-size-16, 16px);
15
+ padding: 16px;
16
16
  font-family: 'Ghostty', 'SF Mono', 'Menlo', 'Monaco', 'Courier New', monospace;
17
17
  font-size: 12px;
18
18
  line-height: 1.4;
@@ -46,10 +46,10 @@
46
46
 
47
47
  /* Matches interactHint from embedOverlay — solid pill button, always visible */
48
48
  .actionButton {
49
- color: var(--fgColor-onInverse, #fff);
50
- background-color: var(--bgColor-inverse, #21262d);
51
- padding: var(--base-size-12, 12px) var(--base-size-16, 16px);
52
- border-radius: var(--base-size-6, 6px);
49
+ color: var(--color-foreground-on-inverse, #fff);
50
+ background-color: var(--color-background-inverse, #21262d);
51
+ padding: 12px 16px;
52
+ border-radius: 6px;
53
53
  font-size: 14px;
54
54
  font-weight: 600;
55
55
  pointer-events: none;
@@ -137,7 +137,10 @@ const ImageWidget = forwardRef(function ImageWidget({ id, props, onUpdate, resiz
137
137
  const blobUrl = URL.createObjectURL(blob)
138
138
  const a = document.createElement('a')
139
139
  a.href = blobUrl
140
- a.download = src.replace(/^~/, '')
140
+ // Strip optional drafts/ directory prefix and leading ~ from the
141
+ // downloaded filename — the user wants the bare basename.
142
+ const baseName = src.includes('/') ? src.slice(src.lastIndexOf('/') + 1) : src
143
+ a.download = baseName.replace(/^~/, '')
141
144
  document.body.appendChild(a)
142
145
  a.click()
143
146
  document.body.removeChild(a)
@@ -156,7 +159,9 @@ const ImageWidget = forwardRef(function ImageWidget({ id, props, onUpdate, resiz
156
159
  .catch((err) => console.error('[canvas] Failed to copy image:', err))
157
160
  } else if (actionId === 'copy-file-path') {
158
161
  if (!src) return
159
- navigator.clipboard.writeText(`src/canvas/images/${src}`).catch(() => {})
162
+ // `src` may include an optional `drafts/` prefix; in both cases the
163
+ // file lives under assets/canvas/images/.
164
+ navigator.clipboard.writeText(`assets/canvas/images/${src}`).catch(() => {})
160
165
  }
161
166
  }
162
167
  }), [src, onUpdate])
@@ -55,8 +55,8 @@
55
55
  font-weight: 600;
56
56
  line-height: 1.4;
57
57
  letter-spacing: 0.02em;
58
- color: var(--fgColor-onEmphasis, #fff);
59
- background: var(--bgColor-neutral-emphasis, rgba(0, 0, 0, 0.55));
58
+ color: var(--color-foreground-on-emphasis, #fff);
59
+ background: var(--color-background-neutral-emphasis, rgba(0, 0, 0, 0.55));
60
60
  pointer-events: none;
61
61
  }
62
62
 
@@ -69,7 +69,7 @@
69
69
  align-items: center;
70
70
  justify-content: center;
71
71
  overflow: auto;
72
- background: var(--bgColor-inset, #f6f8fa);
72
+ background: var(--color-background-inset, #f6f8fa);
73
73
  }
74
74
 
75
75
  .expandedImage {