@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
@@ -100,7 +100,7 @@ The default location is in `.agents/plans`, but the user may ask for a specific
100
100
 
101
101
  ```bash
102
102
  npm run setup # First-time: install deps, Caddy proxy, start proxy
103
- storyboard dev # Start dev server (or: npm run dev)
103
+ npm run dev # Start dev server (wraps `storyboard dev`)
104
104
  npm run dev:vite # Start vite directly (bypasses CLI)
105
105
  npm run build # Production build
106
106
  npm run lint # Run ESLint
@@ -108,14 +108,15 @@ npm run lint # Run ESLint
108
108
 
109
109
  ### Storyboard CLI
110
110
 
111
- The `storyboard` CLI (`sb` alias) wraps dev tooling:
111
+ The `storyboard` CLI (`sb` alias) wraps dev tooling. The standard `npm run dev` script in this repo just calls `storyboard dev` — use `npm run dev` unless you need a CLI-only feature (e.g. starting a dev server for a different worktree).
112
112
 
113
+ <!-- cli-table --start-->
113
114
  | Command | Description |
114
115
  |---------|-------------|
115
- | `storyboard dev` | Start Vite with correct base path + update Caddy proxy |
116
+ | `npm run dev` _(preferred)_ | Start the Vite dev server for the current worktree |
117
+ | `storyboard dev [branch]` | Start a dev server — pass a branch to target a different worktree |
116
118
  | `storyboard code [branch]` | Open current worktree (or specific branch) in VS Code |
117
119
  | `storyboard setup` | Install deps, Caddy, `gh` check, start proxy |
118
- | `storyboard proxy` | Generate Caddyfile + start/reload Caddy |
119
120
  | `storyboard update:version [version]` | Update `@dfosco/storyboard-*` packages to latest (or specific version) |
120
121
  | `storyboard canvas read [name]` | Read canvas widgets with content, URLs, file paths, and bounds |
121
122
  | `storyboard canvas bounds [name]` | Get widget size and positional bounds (spatial queries) |
@@ -152,6 +153,7 @@ The `storyboard` CLI (`sb` alias) wraps dev tooling:
152
153
  | `storyboard messages send` | Publish and wait for correlated response |
153
154
  | `storyboard messages read` | Read events from a channel |
154
155
  | `storyboard messages batch` | Batch publish + read operations |
156
+ <!-- cli-table --end-->
155
157
 
156
158
  > **Convention: Every server API endpoint must have a corresponding CLI command with 1:1 flag-to-field mapping.** Agents use CLI commands, not curl. When adding a new API endpoint, always create a matching CLI command.
157
159
 
@@ -159,7 +161,7 @@ For the full canvas CLI reference (positioning, batch ops, collision detection),
159
161
 
160
162
  ### Dev URLs
161
163
 
162
- With Caddy proxy running (`storyboard setup`):
164
+ With Caddy proxy running (set up via `npm run setup`):
163
165
  - Main: `http://storyboard.localhost/storyboard/`
164
166
  - Worktree `fix-bug`: `http://storyboard.localhost/fix-bug/storyboard/`
165
167
 
@@ -169,7 +171,7 @@ Without proxy (fallback with port numbers):
169
171
 
170
172
  ### Dev URL session state
171
173
 
172
- Whenever Copilot starts a dev server (e.g. `storyboard dev`), save the URL as `devURL` in the SQL session database. Read the proxy URL from the dev server's startup output (`[storyboard] proxy URL: <url>`):
174
+ Whenever Copilot starts a dev server (e.g. `npm run dev`), save the URL as `devURL` in the SQL session database. Read the proxy URL from the dev server's startup output (`[storyboard] proxy URL: <url>`):
173
175
 
174
176
  ```sql
175
177
  INSERT OR REPLACE INTO session_state (key, value) VALUES ('devURL', 'http://storyboard.localhost/storyboard/');
@@ -180,7 +182,7 @@ If the proxy is not running, fall back to the direct URL from the output (`[stor
180
182
  This `devURL` is used as the default target by the **agent-browser** skill when the user says "inspect the browser", "check the page", etc. — no URL argument needed.
181
183
 
182
184
  **How `devURL` gets set:**
183
- - **Automatically** — when Copilot runs `storyboard dev` or `npm run dev`, persist the proxy URL (or direct URL if no proxy) to `devURL`.
185
+ - **Automatically** — when Copilot runs `npm run dev` (or directly `storyboard dev`), persist the proxy URL (or direct URL if no proxy) to `devURL`.
184
186
  - **From user input** — if the user says "the dev server is at http://localhost:3000", save that as `devURL`.
185
187
  - **Implicitly from inspection** — if no `devURL` is set and the user says "inspect http://storyboard.localhost/storyboard/", that URL becomes the `devURL` for the rest of the session.
186
188
 
@@ -0,0 +1,18 @@
1
+ # Storyboard
2
+
3
+ > Note: this is a scaffold-source README. The file copied to client repos
4
+ > only contains the fragment bodies — the bare `<!-- … --start-->` markers
5
+ > below are stripped on whole-file copy. Clients can also adopt individual
6
+ > fragments by adding `<!-- storyboard:scaffold/README.md:<id> --start-->`
7
+ > markers around their own content.
8
+
9
+ ## Storyboard Launcher (Desktop App)
10
+
11
+ <!-- launcher-download --start-->
12
+ Download the macOS Launcher from the [latest launcher release](https://github.com/dfosco/storyboard/releases?q=storyboard-launcher&expanded=true).
13
+
14
+ After installing, run:
15
+ ```bash
16
+ sudo xattr -rd com.apple.quarantine '/Applications/Storyboard Launcher.app'
17
+ ```
18
+ <!-- launcher-download --end-->
@@ -101,3 +101,24 @@ jobs:
101
101
  git config user.email "github-actions[bot]@users.noreply.github.com"
102
102
  git commit -m "Update branch manifest"
103
103
  git push origin gh-pages
104
+
105
+ - name: Generate artifacts index
106
+ run: |
107
+ set -e
108
+ # Remove stale worktrees from previous steps
109
+ git worktree list --porcelain | awk '/^worktree \/tmp/{print $2}' | while read wt; do
110
+ git worktree remove --force "$wt" 2>/dev/null || true
111
+ done
112
+ git fetch origin gh-pages:gh-pages 2>/dev/null || true
113
+ DEPLOY_DIR=$(mktemp -d)
114
+ git worktree add "$DEPLOY_DIR" gh-pages
115
+
116
+ node "$GITHUB_WORKSPACE/.github/workflows/scripts/aggregate-artifacts.mjs" "$DEPLOY_DIR"
117
+
118
+ cd "$DEPLOY_DIR"
119
+ git add artifacts.index.json
120
+ git diff --cached --quiet && echo "Artifacts index unchanged" && exit 0
121
+ git config user.name "github-actions[bot]"
122
+ git config user.email "github-actions[bot]@users.noreply.github.com"
123
+ git commit -m "Update artifacts index"
124
+ git push origin gh-pages
@@ -52,25 +52,19 @@ packages/core/dist/storyboard-ui.*
52
52
  # Agent Browser
53
53
  agent-browser.json
54
54
 
55
- # Auto-generated scaffold dir (copies of library config defaults — overwritten on every dev-server boot)
56
- .storyboard/scaffold/
57
-
58
- # Real-time canvas selection bridge for Copilot
59
- .storyboard/.selectedwidgets.json
60
-
61
- # Runtime/transient state (per-machine, per-session)
62
- .storyboard/agent-sessions/
63
- .storyboard/hot-pool/
64
- .storyboard/logs/
65
- .storyboard/terminal-buffers/
66
- .storyboard/messages/
67
-
68
- # Private canvas images (tilde prefix = not committed)
55
+ # <!-- runtime-state --start-->
56
+ # Storyboard runtime state + private tilde-prefixed files.
57
+ # Kept in sync by storyboard-scaffold — edit `packages/storyboard/scaffold/gitignore` in storyboard-core.
58
+ .storyboard/
69
59
  src/canvas/images/~*
70
60
  assets/canvas/images/~*
61
+ assets/canvas/images/drafts/
71
62
  assets/canvas/snapshots/~*
72
63
  assets/.storyboard-public/terminal-snapshots/~*
64
+ src/canvas/**/drafts/
65
+ src/prototypes/**/drafts/
73
66
  .sync-target
67
+ # <!-- runtime-state --end-->
74
68
 
75
69
  # Integration test results (ephemeral local artifacts)
76
70
  test-results/
@@ -115,6 +115,27 @@ jobs:
115
115
  git commit -m "Update branch manifest"
116
116
  git push origin gh-pages
117
117
 
118
+ - name: Generate artifacts index
119
+ run: |
120
+ set -e
121
+ # Remove stale worktrees from previous steps
122
+ git worktree list --porcelain | awk '/^worktree \/tmp/{print $2}' | while read wt; do
123
+ git worktree remove --force "$wt" 2>/dev/null || true
124
+ done
125
+ git fetch origin gh-pages:gh-pages 2>/dev/null || true
126
+ DEPLOY_DIR=$(mktemp -d)
127
+ git worktree add "$DEPLOY_DIR" gh-pages
128
+
129
+ node "$GITHUB_WORKSPACE/.github/workflows/scripts/aggregate-artifacts.mjs" "$DEPLOY_DIR"
130
+
131
+ cd "$DEPLOY_DIR"
132
+ git add artifacts.index.json
133
+ git diff --cached --quiet && echo "Artifacts index unchanged" && exit 0
134
+ git config user.name "github-actions[bot]"
135
+ git config user.email "github-actions[bot]@users.noreply.github.com"
136
+ git commit -m "Update artifacts index"
137
+ git push origin gh-pages
138
+
118
139
  - name: Print preview URL
119
140
  run: |
120
141
  echo "## 🔗 Branch Preview" >> "$GITHUB_STEP_SUMMARY"
@@ -179,3 +200,22 @@ jobs:
179
200
  git config user.email "github-actions[bot]@users.noreply.github.com"
180
201
  git commit -m "Update branch manifest"
181
202
  git push origin gh-pages
203
+
204
+ # cleanup-preview does not install npm dependencies. Check out the source
205
+ # tree separately so the checked-in workflow helper can run with plain Node.
206
+ - name: Checkout source workflow scripts
207
+ uses: actions/checkout@v6
208
+ with:
209
+ path: source
210
+
211
+ - name: Generate artifacts index
212
+ run: |
213
+ set -e
214
+ node source/.github/workflows/scripts/aggregate-artifacts.mjs "$GITHUB_WORKSPACE"
215
+
216
+ git add artifacts.index.json
217
+ git diff --cached --quiet && echo "Artifacts index unchanged" && exit 0
218
+ git config user.name "github-actions[bot]"
219
+ git config user.email "github-actions[bot]@users.noreply.github.com"
220
+ git commit -m "Update artifacts index"
221
+ git push origin gh-pages
@@ -3,15 +3,15 @@
3
3
  {
4
4
  "source": "scaffold/AGENTS.md",
5
5
  "target": "AGENTS.md",
6
- "mode": "updateable"
6
+ "mode": "scaffold"
7
7
  },
8
8
  {
9
9
  "source": "scaffold/gitignore",
10
10
  "target": ".gitignore",
11
- "mode": "updateable"
11
+ "mode": "scaffold"
12
12
  },
13
13
  {
14
- "source": "scaffold/storyboard.config.json",
14
+ "source": "storyboard.config.json",
15
15
  "target": "storyboard.config.json",
16
16
  "mode": "scaffold"
17
17
  },
@@ -67,6 +67,11 @@
67
67
  "target": ".github/workflows/preview.yml",
68
68
  "mode": "updateable"
69
69
  },
70
+ {
71
+ "source": "scaffold/scripts/aggregate-artifacts.mjs",
72
+ "target": ".github/workflows/scripts/aggregate-artifacts.mjs",
73
+ "mode": "updateable"
74
+ },
70
75
  {
71
76
  "source": "scaffold/githooks/",
72
77
  "target": ".githooks/",
@@ -88,6 +93,71 @@
88
93
  "source": "scaffold/codex/config.toml",
89
94
  "target": ".codex/config.toml",
90
95
  "mode": "updateable"
96
+ },
97
+ {
98
+ "source": "scaffold/src/library/mount.jsx",
99
+ "target": "src/library/mount.jsx",
100
+ "mode": "updateable"
101
+ },
102
+ {
103
+ "source": "scaffold/src/library/prototypes-entry.jsx",
104
+ "target": "src/library/prototypes-entry.jsx",
105
+ "mode": "updateable"
106
+ },
107
+ {
108
+ "source": "scaffold/src/library/routes.jsx",
109
+ "target": "src/library/routes.jsx",
110
+ "mode": "updateable"
111
+ },
112
+ {
113
+ "source": "scaffold/src/library/_app.jsx",
114
+ "target": "src/library/_app.jsx",
115
+ "mode": "updateable"
116
+ },
117
+ {
118
+ "source": "scaffold/src/library/_app.module.css",
119
+ "target": "src/library/_app.module.css",
120
+ "mode": "updateable"
121
+ },
122
+ {
123
+ "source": "scaffold/src/library/workspace.jsx",
124
+ "target": "src/library/workspace.jsx",
125
+ "mode": "updateable"
126
+ },
127
+ {
128
+ "source": "scaffold/src/library/viewfinder.jsx",
129
+ "target": "src/library/viewfinder.jsx",
130
+ "mode": "updateable"
131
+ },
132
+ {
133
+ "source": "scaffold/src/library/create.jsx",
134
+ "target": "src/library/create.jsx",
135
+ "mode": "updateable"
136
+ },
137
+ {
138
+ "source": "scaffold/src/library/index.jsx",
139
+ "target": "src/library/index.jsx",
140
+ "mode": "updateable"
141
+ },
142
+ {
143
+ "source": "scaffold/src/library/README.md",
144
+ "target": "src/library/README.md",
145
+ "mode": "updateable"
146
+ },
147
+ {
148
+ "source": "scaffold/src/_prototype.jsx",
149
+ "target": "src/_prototype.jsx",
150
+ "mode": "scaffold"
151
+ },
152
+ {
153
+ "source": "scaffold/src/_story.jsx",
154
+ "target": "src/_story.jsx",
155
+ "mode": "scaffold"
91
156
  }
157
+ ],
158
+ "fragmentSources": [
159
+ "scaffold/gitignore",
160
+ "scaffold/AGENTS.md",
161
+ "scaffold/README.md"
92
162
  ]
93
163
  }
@@ -0,0 +1,257 @@
1
+ #!/usr/bin/env node
2
+
3
+ import fs from 'fs'
4
+ import path from 'path'
5
+ import process from 'process'
6
+
7
+ const INDEX_FILENAME = 'artifacts.index.json'
8
+ const TMP_FILENAME = '.artifacts.index.json.tmp'
9
+ const SCHEMA_VERSION = 1
10
+
11
+ function compareBranchNames(a, b) {
12
+ if (a.branch === 'main' && b.branch !== 'main') return -1
13
+ if (b.branch === 'main' && a.branch !== 'main') return 1
14
+ return String(a.branch || '').localeCompare(String(b.branch || ''))
15
+ }
16
+
17
+ function withTrailingSlash(folder) {
18
+ if (!folder) return ''
19
+ return folder.endsWith('/') ? folder : `${folder}/`
20
+ }
21
+
22
+ function generatedAtMs(manifest) {
23
+ const value = Date.parse(manifest?.generatedAt || '')
24
+ return Number.isNaN(value) ? 0 : value
25
+ }
26
+
27
+ function deriveFolder(manifest, dir, ghPagesDir) {
28
+ if (dir === ghPagesDir) return ''
29
+ if (typeof manifest.folder === 'string') return manifest.folder
30
+ return path.basename(dir)
31
+ }
32
+
33
+ function deriveBranch(manifest, folder) {
34
+ if (!folder) return 'main'
35
+ if (typeof manifest.branch === 'string' && manifest.branch) return manifest.branch
36
+ return manifest.deployBranch || folder.replace(/^branch--/, '')
37
+ }
38
+
39
+ function deriveDeployBranch(manifest, branch, folder) {
40
+ if (!folder || branch === 'main') return 'main'
41
+ if (typeof manifest.deployBranch === 'string' && manifest.deployBranch) return manifest.deployBranch
42
+ return folder.replace(/^branch--/, '')
43
+ }
44
+
45
+ function readManifest(dir) {
46
+ const manifestPath = path.join(dir, 'artifacts.json')
47
+ const label = path.basename(dir) || dir
48
+
49
+ let raw
50
+ try {
51
+ raw = fs.readFileSync(manifestPath, 'utf8')
52
+ } catch (err) {
53
+ if (err?.code === 'ENOENT') {
54
+ console.info(`[aggregate-artifacts] Skipping ${label}: artifacts.json not found`)
55
+ return { manifest: null, readError: false }
56
+ }
57
+ console.warn(`[aggregate-artifacts] Skipping ${label}: could not read artifacts.json (${err.message})`)
58
+ return { manifest: null, readError: true }
59
+ }
60
+
61
+ let manifest
62
+ try {
63
+ manifest = JSON.parse(raw)
64
+ } catch (err) {
65
+ console.warn(`[aggregate-artifacts] Skipping ${label}: malformed artifacts.json (${err.message})`)
66
+ return { manifest: null, readError: false }
67
+ }
68
+
69
+ if (manifest?.schemaVersion !== SCHEMA_VERSION) {
70
+ console.warn(`[aggregate-artifacts] Skipping ${label}: unsupported schemaVersion ${manifest?.schemaVersion}`)
71
+ return { manifest: null, readError: false }
72
+ }
73
+
74
+ return { manifest, readError: false }
75
+ }
76
+
77
+ function listManifestDirs(ghPagesDir) {
78
+ const entries = fs.readdirSync(ghPagesDir, { withFileTypes: true })
79
+ const branchDirs = entries
80
+ .filter(entry => entry.isDirectory() && entry.name.startsWith('branch--'))
81
+ .map(entry => path.join(ghPagesDir, entry.name))
82
+ .sort((a, b) => path.basename(a).localeCompare(path.basename(b)))
83
+
84
+ return [ghPagesDir, ...branchDirs]
85
+ }
86
+
87
+ function collectManifests(ghPagesDir) {
88
+ const manifestsByFolder = new Map()
89
+ let readErrorCount = 0
90
+
91
+ for (const dir of listManifestDirs(ghPagesDir)) {
92
+ const { manifest, readError } = readManifest(dir)
93
+ if (readError) readErrorCount += 1
94
+ if (!manifest) continue
95
+
96
+ const folder = deriveFolder(manifest, dir, ghPagesDir)
97
+ const current = { manifest, dir, folder }
98
+ const previous = manifestsByFolder.get(folder)
99
+
100
+ if (!previous) {
101
+ manifestsByFolder.set(folder, current)
102
+ continue
103
+ }
104
+
105
+ const previousBranch = deriveBranch(previous.manifest, previous.folder)
106
+ const currentBranch = deriveBranch(manifest, folder)
107
+ const keepCurrent = generatedAtMs(manifest) > generatedAtMs(previous.manifest)
108
+ const keptBranch = keepCurrent ? currentBranch : previousBranch
109
+
110
+ console.warn(
111
+ `[aggregate-artifacts] Branch folder collision for "${folder || '(root)'}" between "${previousBranch}" and "${currentBranch}"; keeping "${keptBranch}"`,
112
+ )
113
+
114
+ if (keepCurrent) manifestsByFolder.set(folder, current)
115
+ }
116
+
117
+ if (readErrorCount > 1) {
118
+ throw new Error(`Failed to read ${readErrorCount} artifacts manifests; preserving existing ${INDEX_FILENAME}`)
119
+ }
120
+
121
+ const manifests = [...manifestsByFolder.values()]
122
+ if (manifests.length === 0) {
123
+ throw new Error(`No readable artifacts.json manifests found; preserving existing ${INDEX_FILENAME}`)
124
+ }
125
+
126
+ return manifests
127
+ }
128
+
129
+ function addPrototype(index, manifestInfo, item) {
130
+ const id = item?.artifactId || item?.id
131
+ if (!id) return
132
+
133
+ const { manifest, folder } = manifestInfo
134
+ const branch = deriveBranch(manifest, folder)
135
+ const key = String(id)
136
+
137
+ if (!index.prototypes[key]) {
138
+ index.prototypes[key] = { id: key, branches: [] }
139
+ }
140
+
141
+ index.prototypes[key].branches.push({
142
+ branch,
143
+ folder: withTrailingSlash(folder),
144
+ title: item.title ?? item.id ?? key,
145
+ route: item.route ?? null,
146
+ isExternal: Boolean(item.isExternal),
147
+ externalUrl: item.externalUrl ?? null,
148
+ folderName: item.folder ?? null,
149
+ sha: manifest.sha ?? null,
150
+ lastModified: item.lastModified ?? null,
151
+ })
152
+ }
153
+
154
+ function addCanvas(index, manifestInfo, item) {
155
+ const id = item?.artifactId || item?.id
156
+ if (!id) return
157
+
158
+ const { manifest, folder } = manifestInfo
159
+ const branch = deriveBranch(manifest, folder)
160
+ const key = String(id)
161
+
162
+ if (!index.canvases[key]) {
163
+ index.canvases[key] = { id: key, branches: [] }
164
+ }
165
+
166
+ index.canvases[key].branches.push({
167
+ branch,
168
+ folder: withTrailingSlash(folder),
169
+ name: item.name ?? item.id ?? key,
170
+ route: item.route ?? null,
171
+ folderName: item.folder ?? null,
172
+ sha: manifest.sha ?? null,
173
+ lastModified: item.lastModified ?? null,
174
+ })
175
+ }
176
+
177
+ function sortArtifactMap(map) {
178
+ const sorted = {}
179
+
180
+ for (const key of Object.keys(map).sort((a, b) => a.localeCompare(b))) {
181
+ sorted[key] = {
182
+ ...map[key],
183
+ branches: [...map[key].branches].sort(compareBranchNames),
184
+ }
185
+ }
186
+
187
+ return sorted
188
+ }
189
+
190
+ function buildIndex(manifests) {
191
+ const index = {
192
+ schemaVersion: SCHEMA_VERSION,
193
+ generatedAt: new Date().toISOString(),
194
+ branches: [],
195
+ prototypes: {},
196
+ canvases: {},
197
+ }
198
+
199
+ for (const manifestInfo of manifests) {
200
+ const { manifest, folder } = manifestInfo
201
+ const branch = deriveBranch(manifest, folder)
202
+ const deployBranch = deriveDeployBranch(manifest, branch, folder)
203
+
204
+ index.branches.push({ branch, deployBranch, folder })
205
+
206
+ for (const item of Array.isArray(manifest.prototypes) ? manifest.prototypes : []) {
207
+ addPrototype(index, manifestInfo, item)
208
+ }
209
+
210
+ for (const item of Array.isArray(manifest.canvases) ? manifest.canvases : []) {
211
+ addCanvas(index, manifestInfo, item)
212
+ }
213
+ }
214
+
215
+ index.branches = [...index.branches].sort(compareBranchNames)
216
+ index.prototypes = sortArtifactMap(index.prototypes)
217
+ index.canvases = sortArtifactMap(index.canvases)
218
+
219
+ return index
220
+ }
221
+
222
+ function writeIndex(ghPagesDir, index) {
223
+ const targetPath = path.join(ghPagesDir, INDEX_FILENAME)
224
+ const tmpPath = path.join(ghPagesDir, TMP_FILENAME)
225
+ const contents = `${JSON.stringify(index, null, 2)}\n`
226
+
227
+ fs.writeFileSync(tmpPath, contents, 'utf8')
228
+ fs.renameSync(tmpPath, targetPath)
229
+
230
+ return targetPath
231
+ }
232
+
233
+ function aggregateArtifacts(ghPagesDir) {
234
+ const resolvedDir = path.resolve(ghPagesDir)
235
+ const manifests = collectManifests(resolvedDir)
236
+ const index = buildIndex(manifests)
237
+ return writeIndex(resolvedDir, index)
238
+ }
239
+
240
+ function main() {
241
+ const ghPagesDir = process.argv[2]
242
+
243
+ if (!ghPagesDir) {
244
+ console.error('Usage: node aggregate-artifacts.mjs <gh-pages-dir>')
245
+ process.exit(1)
246
+ }
247
+
248
+ try {
249
+ const targetPath = aggregateArtifacts(ghPagesDir)
250
+ console.info(`[aggregate-artifacts] Wrote ${targetPath}`)
251
+ } catch (err) {
252
+ console.error(`[aggregate-artifacts] ${err.message}`)
253
+ process.exit(1)
254
+ }
255
+ }
256
+
257
+ main()
@@ -23,7 +23,7 @@ Reads, manipulates, and arranges widgets on a Storyboard canvas. Supports absolu
23
23
 
24
24
  ## Prerequisites
25
25
 
26
- - The dev server **must** be running (`storyboard dev` or `npm run dev`)
26
+ - The dev server **must** be running (`npm run dev`, or `storyboard dev` from the CLI directly)
27
27
  - The target canvas must already exist
28
28
 
29
29
  ## Critical: Never Parse JSONL Directly
@@ -264,7 +264,7 @@ npx storyboard setup
264
264
  npm run build
265
265
 
266
266
  # Start dev server to verify everything works
267
- npx storyboard dev
267
+ npm run dev
268
268
  ```
269
269
 
270
270
  ---
@@ -200,7 +200,7 @@ If clips was skipped in Step 3, skip this step too.
200
200
  Run the dev server in the worktree so the user can immediately preview changes:
201
201
 
202
202
  ```bash
203
- npx storyboard dev
203
+ npm run dev
204
204
  ```
205
205
 
206
206
  This is the **only** place the dev server starts during a ship workflow — the worktree skill skips its own dev server step when called from ship.
@@ -234,4 +234,4 @@ User says: "ship a feature to add canvas grid snapping"
234
234
  8. Updates architecture docs, README, DOCS as needed, commits
235
235
  9. Pushes `1.2.0--canvas-grid-snapping` to origin
236
236
  10. Marks clips tasks as closed
237
- 11. Starts dev server (`npx storyboard dev`) in the worktree
237
+ 11. Starts dev server (`npm run dev`) in the worktree
@@ -19,7 +19,7 @@ When the user asks for a worktree named `<branch-name>`:
19
19
 
20
20
  ### Preferred: Use `npx storyboard dev <branch>`
21
21
 
22
- The `storyboard` CLI handles the full worktree lifecycle in a single command:
22
+ The `storyboard` CLI handles the full worktree lifecycle in a single command. (Plain `npm run dev` only starts a server for the current worktree — to target a different worktree from anywhere, use the CLI directly.)
23
23
 
24
24
  ```bash
25
25
  npx storyboard dev <branch-name>
@@ -0,0 +1,17 @@
1
+ /**
2
+ * _prototype.jsx — wraps every prototype route in this project.
3
+ *
4
+ * Storyboard resolves this file via `import.meta.glob('/src/_prototype.{jsx,tsx}')`
5
+ * and wraps every prototype route's render with the default export — both in
6
+ * the workspace SPA and in the isolated `prototypes.html` iframe.
7
+ *
8
+ * By default, this is a pass-through (no providers, no CSS). Customize freely:
9
+ * - Add an `import './_prototype.css'` and import your design tokens / Tailwind / fonts
10
+ * - Wrap in your design system's ThemeProvider (Primer, Reshaped, Chakra, etc.)
11
+ *
12
+ * Delete this file entirely if you want prototypes to render with absolutely
13
+ * nothing inherited from storyboard.
14
+ */
15
+ export default function PrototypeWrapper({ children }) {
16
+ return children
17
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * _story.jsx — wraps every story render in this project.
3
+ *
4
+ * Covers: StoryPage routes, ComponentSetPage grid, InlineStoryRenderer
5
+ * (canvas widget), componentIsolate / componentSetIsolate (iframe entries).
6
+ *
7
+ * Pass-through default — customize like `src/_prototype.jsx` (often the two
8
+ * share the same providers; one common pattern is to re-export this file
9
+ * from `_prototype.jsx`).
10
+ */
11
+ export default function StoryWrapper({ children }) {
12
+ return children
13
+ }
@@ -0,0 +1,34 @@
1
+ # DO NOT EDIT FILES IN THIS DIRECTORY
2
+
3
+ `src/library/` contains storyboard's bootstrap boilerplate AND its workspace
4
+ pages (Workspace, Viewfinder, Create, the SPA landing index). These files
5
+ are managed by storyboard and may be overwritten by future
6
+ `storyboard update:version` runs.
7
+
8
+ The contents:
9
+
10
+ | File | What it does |
11
+ |---|---|
12
+ | `mount.jsx` | Vite SPA entry — `index.html` loads this |
13
+ | `prototypes-entry.jsx` | Vite iframe entry — `prototypes.html` loads this |
14
+ | `routes.jsx` | Generouted glue: scans `src/library/*.jsx` (workspace pages) and `src/prototypes/**` (your prototypes) |
15
+ | `_app.jsx`, `_app.module.css` | Workspace SPA shell — `StoryboardProvider`, suspense, error boundary, feature-flag banner |
16
+ | `workspace.jsx` | `/workspace` route — calls `<Workspace>` |
17
+ | `viewfinder.jsx` | `/viewfinder` redirect (kept for back-compat) |
18
+ | `create.jsx` | `/create` standalone artifact creator |
19
+ | `index.jsx` | `/` landing — `<SimpleWorkspace>` |
20
+
21
+ ## How to customize storyboard
22
+
23
+ Almost every customization knob lives elsewhere:
24
+
25
+ | What you want to change | Edit |
26
+ |---|---|
27
+ | App title, theming, feature flags, surfaces | `storyboard.config.json` |
28
+ | Provider chain for every **prototype** (design system, fonts, Tailwind) | `src/_prototype.jsx` (optional — create it if you want it) |
29
+ | Provider chain for every **story** | `src/_story.jsx` (optional) |
30
+ | Add new routes the user can navigate to inside the SPA | Add files under `src/prototypes/` |
31
+
32
+ If you have a real reason to edit a file in this directory, just edit it —
33
+ storyboard will warn (but not block) on the next sync. You opt out of sync
34
+ by adding the file path to your `.storyboard-sync.ignore` file (planned).