@dfosco/storyboard-core 4.2.0-beta.2 → 4.2.0-beta.21

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 (414) hide show
  1. package/commandpalette.config.json +109 -24
  2. package/dist/storyboard-ui.css +1 -1
  3. package/dist/storyboard-ui.js +17379 -28568
  4. package/dist/storyboard-ui.js.map +1 -1
  5. package/dist/tailwind.css +1 -1
  6. package/package.json +5 -2
  7. package/scaffold/agents/prompt-agent.agent.md +181 -0
  8. package/scaffold/agents/terminal-agent.agent.md +351 -0
  9. package/scaffold/codex/config.toml +246 -0
  10. package/scaffold/manifest.json +5 -0
  11. package/scaffold/skills/canvas/SKILL.md +5 -4
  12. package/scaffold/skills/ship/SKILL.md +1 -1
  13. package/scaffold/storyboard.config.json +14 -1
  14. package/scaffold/toolbar.config.json +1 -1
  15. package/src/ActionMenuButton.jsx +100 -0
  16. package/src/AutosyncMenuButton.css +67 -0
  17. package/src/AutosyncMenuButton.jsx +241 -0
  18. package/src/BranchSelect.jsx +29 -0
  19. package/src/BranchSelect.module.css +30 -0
  20. package/src/CanvasAgentsMenu.jsx +87 -0
  21. package/src/CanvasCreateMenu.jsx +609 -0
  22. package/src/CanvasSnap.css +27 -0
  23. package/src/CanvasSnap.jsx +51 -0
  24. package/src/CanvasUndoRedo.css +36 -0
  25. package/src/CanvasUndoRedo.jsx +62 -0
  26. package/src/CanvasZoomControl.css +53 -0
  27. package/src/CanvasZoomControl.jsx +49 -0
  28. package/src/CanvasZoomToFit.css +18 -0
  29. package/src/CanvasZoomToFit.jsx +26 -0
  30. package/src/CommandMenu.css +8 -0
  31. package/src/CommandMenu.jsx +286 -0
  32. package/src/CommandPalette.jsx +35 -0
  33. package/src/CommandPaletteTrigger.jsx +25 -0
  34. package/src/CommentsMenuButton.jsx +38 -0
  35. package/src/CoreUIBar.css +47 -0
  36. package/src/CoreUIBar.jsx +855 -0
  37. package/src/CreateMenuButton.jsx +116 -0
  38. package/src/HideChromeTrigger.jsx +40 -0
  39. package/src/InspectorPanel.css +109 -0
  40. package/src/InspectorPanel.jsx +629 -0
  41. package/src/PwaInstallBanner.css +42 -0
  42. package/src/PwaInstallBanner.jsx +124 -0
  43. package/src/SidePanel.jsx +260 -0
  44. package/src/ThemeMenuButton.jsx +136 -0
  45. package/src/autosync/server.js +202 -5
  46. package/src/autosync/server.test.js +112 -0
  47. package/src/canvas/__tests__/agent-integration.test.js +593 -0
  48. package/src/canvas/__tests__/helpers/browser.js +95 -0
  49. package/src/canvas/__tests__/helpers/canvas-api.js +129 -0
  50. package/src/canvas/__tests__/helpers/perf.js +118 -0
  51. package/src/canvas/__tests__/helpers/setup.js +176 -0
  52. package/src/canvas/__tests__/helpers/tmux.js +130 -0
  53. package/src/canvas/__tests__/helpers/transcript.js +129 -0
  54. package/src/canvas/__tests__/terminal-integration.test.js +175 -0
  55. package/src/canvas/hot-pool.js +757 -0
  56. package/src/canvas/materializer.js +31 -0
  57. package/src/canvas/materializer.test.js +56 -0
  58. package/src/canvas/selectedWidgets.js +65 -7
  59. package/src/canvas/server.js +1801 -22
  60. package/src/canvas/server.test.js +239 -0
  61. package/src/canvas/terminal-config.js +331 -0
  62. package/src/canvas/terminal-registry.js +38 -0
  63. package/src/canvas/terminal-server.js +1037 -29
  64. package/src/canvas/writeGuard.js +51 -3
  65. package/src/canvasConfig.js +67 -1
  66. package/src/canvasConfig.test.js +79 -1
  67. package/src/cli/agent.js +85 -0
  68. package/src/cli/branch.js +232 -0
  69. package/src/cli/canvasAdd.js +59 -12
  70. package/src/cli/canvasBatch.js +98 -0
  71. package/src/cli/canvasBounds.js +1 -1
  72. package/src/cli/canvasRead.js +1 -1
  73. package/src/cli/canvasUpdate.js +179 -0
  74. package/src/cli/create.js +38 -14
  75. package/src/cli/dev.js +157 -83
  76. package/src/cli/exit.js +23 -24
  77. package/src/cli/index.js +55 -2
  78. package/src/cli/proxy.js +96 -37
  79. package/src/cli/schemas.js +22 -4
  80. package/src/cli/server.js +148 -25
  81. package/src/cli/serverUrl.js +8 -3
  82. package/src/cli/sessions.js +131 -5
  83. package/src/cli/setup.js +109 -11
  84. package/src/cli/terminal-commands.js +16 -8
  85. package/src/cli/terminal-messaging.js +231 -0
  86. package/src/cli/terminal-welcome.js +365 -33
  87. package/src/commandActions.js +1 -0
  88. package/src/commandPaletteConfig.js +9 -0
  89. package/src/comments/auth.js +2 -1
  90. package/src/comments/ui/AuthModal.jsx +114 -0
  91. package/src/comments/ui/CommentWindow.jsx +329 -0
  92. package/src/comments/ui/CommentsDrawer.jsx +102 -0
  93. package/src/comments/ui/Composer.jsx +64 -0
  94. package/src/comments/ui/authModal.test.js +1 -1
  95. package/src/comments/ui/commentWindow.js +16 -17
  96. package/src/comments/ui/commentsDrawer.js +25 -26
  97. package/src/comments/ui/composer.js +23 -24
  98. package/src/comments/ui/index.js +2 -3
  99. package/src/configSchema.js +59 -1
  100. package/src/configStore.js +161 -0
  101. package/src/core-ui-colors.css +12 -0
  102. package/src/devtools.js +17 -19
  103. package/src/devtools.test.js +18 -9
  104. package/src/featureFlags.js +12 -5
  105. package/src/fuzzySearch.test.js +10 -0
  106. package/src/index.js +14 -2
  107. package/src/lib/components/ui/alert/alert-action.jsx +11 -0
  108. package/src/lib/components/ui/alert/alert-description.jsx +11 -0
  109. package/src/lib/components/ui/alert/alert-title.jsx +11 -0
  110. package/src/lib/components/ui/alert/alert.jsx +25 -0
  111. package/src/lib/components/ui/alert/index.js +15 -15
  112. package/src/lib/components/ui/avatar/avatar-badge.jsx +22 -0
  113. package/src/lib/components/ui/avatar/avatar-fallback.jsx +18 -0
  114. package/src/lib/components/ui/avatar/avatar-group-count.jsx +19 -0
  115. package/src/lib/components/ui/avatar/avatar-group.jsx +19 -0
  116. package/src/lib/components/ui/avatar/avatar-image.jsx +15 -0
  117. package/src/lib/components/ui/avatar/avatar.jsx +19 -0
  118. package/src/lib/components/ui/avatar/index.js +20 -20
  119. package/src/lib/components/ui/badge/badge.jsx +31 -0
  120. package/src/lib/components/ui/badge/index.js +2 -2
  121. package/src/lib/components/ui/button/button.jsx +100 -0
  122. package/src/lib/components/ui/button/index.js +9 -9
  123. package/src/lib/components/ui/card/card-action.jsx +11 -0
  124. package/src/lib/components/ui/card/card-content.jsx +11 -0
  125. package/src/lib/components/ui/card/card-description.jsx +11 -0
  126. package/src/lib/components/ui/card/card-footer.jsx +11 -0
  127. package/src/lib/components/ui/card/card-header.jsx +19 -0
  128. package/src/lib/components/ui/card/card-title.jsx +11 -0
  129. package/src/lib/components/ui/card/card.jsx +17 -0
  130. package/src/lib/components/ui/card/index.js +23 -23
  131. package/src/lib/components/ui/checkbox/checkbox.jsx +29 -0
  132. package/src/lib/components/ui/checkbox/index.js +5 -5
  133. package/src/lib/components/ui/collapsible/collapsible-content.jsx +7 -0
  134. package/src/lib/components/ui/collapsible/collapsible-trigger.jsx +7 -0
  135. package/src/lib/components/ui/collapsible/collapsible.jsx +7 -0
  136. package/src/lib/components/ui/collapsible/index.js +11 -11
  137. package/src/lib/components/ui/dialog/dialog-close.jsx +7 -0
  138. package/src/lib/components/ui/dialog/dialog-content.jsx +34 -0
  139. package/src/lib/components/ui/dialog/dialog-description.jsx +15 -0
  140. package/src/lib/components/ui/dialog/dialog-footer.jsx +23 -0
  141. package/src/lib/components/ui/dialog/dialog-header.jsx +11 -0
  142. package/src/lib/components/ui/dialog/dialog-overlay.jsx +15 -0
  143. package/src/lib/components/ui/dialog/dialog-portal.jsx +4 -0
  144. package/src/lib/components/ui/dialog/dialog-title.jsx +15 -0
  145. package/src/lib/components/ui/dialog/dialog-trigger.jsx +7 -0
  146. package/src/lib/components/ui/dialog/dialog.jsx +4 -0
  147. package/src/lib/components/ui/dialog/index.js +32 -32
  148. package/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.jsx +8 -0
  149. package/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.jsx +30 -0
  150. package/src/lib/components/ui/dropdown-menu/dropdown-menu-content.jsx +22 -0
  151. package/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.jsx +16 -0
  152. package/src/lib/components/ui/dropdown-menu/dropdown-menu-group.jsx +7 -0
  153. package/src/lib/components/ui/dropdown-menu/dropdown-menu-item.jsx +20 -0
  154. package/src/lib/components/ui/dropdown-menu/dropdown-menu-label.jsx +17 -0
  155. package/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.jsx +4 -0
  156. package/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.jsx +7 -0
  157. package/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.jsx +29 -0
  158. package/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.jsx +15 -0
  159. package/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.jsx +16 -0
  160. package/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.jsx +15 -0
  161. package/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.jsx +23 -0
  162. package/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.jsx +4 -0
  163. package/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.jsx +7 -0
  164. package/src/lib/components/ui/dropdown-menu/dropdown-menu.jsx +4 -0
  165. package/src/lib/components/ui/dropdown-menu/index.js +52 -52
  166. package/src/lib/components/ui/input/index.js +5 -5
  167. package/src/lib/components/ui/input/input.jsx +19 -0
  168. package/src/lib/components/ui/label/index.js +5 -5
  169. package/src/lib/components/ui/label/label.jsx +19 -0
  170. package/src/lib/components/ui/panel/index.js +21 -21
  171. package/src/lib/components/ui/panel/panel-body.jsx +11 -0
  172. package/src/lib/components/ui/panel/panel-close.jsx +16 -0
  173. package/src/lib/components/ui/panel/panel-content.jsx +29 -0
  174. package/src/lib/components/ui/panel/panel-footer.jsx +11 -0
  175. package/src/lib/components/ui/panel/panel-header.jsx +11 -0
  176. package/src/lib/components/ui/panel/panel-title.jsx +12 -0
  177. package/src/lib/components/ui/panel/panel.jsx +4 -0
  178. package/src/lib/components/ui/popover/index.js +26 -26
  179. package/src/lib/components/ui/popover/popover-close.jsx +7 -0
  180. package/src/lib/components/ui/popover/popover-content.jsx +22 -0
  181. package/src/lib/components/ui/popover/popover-description.jsx +11 -0
  182. package/src/lib/components/ui/popover/popover-header.jsx +11 -0
  183. package/src/lib/components/ui/popover/popover-portal.jsx +4 -0
  184. package/src/lib/components/ui/popover/popover-title.jsx +11 -0
  185. package/src/lib/components/ui/popover/popover-trigger.jsx +8 -0
  186. package/src/lib/components/ui/popover/popover.jsx +4 -0
  187. package/src/lib/components/ui/searchable-list.jsx +159 -0
  188. package/src/lib/components/ui/select/index.js +35 -35
  189. package/src/lib/components/ui/select/select-content.jsx +30 -0
  190. package/src/lib/components/ui/select/select-group-heading.jsx +17 -0
  191. package/src/lib/components/ui/select/select-group.jsx +15 -0
  192. package/src/lib/components/ui/select/select-item.jsx +26 -0
  193. package/src/lib/components/ui/select/select-label.jsx +11 -0
  194. package/src/lib/components/ui/select/select-portal.jsx +4 -0
  195. package/src/lib/components/ui/select/select-scroll-down-button.jsx +18 -0
  196. package/src/lib/components/ui/select/select-scroll-up-button.jsx +18 -0
  197. package/src/lib/components/ui/select/select-separator.jsx +15 -0
  198. package/src/lib/components/ui/select/select-trigger.jsx +25 -0
  199. package/src/lib/components/ui/select/select.jsx +4 -0
  200. package/src/lib/components/ui/separator/index.js +5 -5
  201. package/src/lib/components/ui/separator/separator.jsx +22 -0
  202. package/src/lib/components/ui/sheet/index.js +32 -32
  203. package/src/lib/components/ui/sheet/sheet-close.jsx +7 -0
  204. package/src/lib/components/ui/sheet/sheet-content.jsx +35 -0
  205. package/src/lib/components/ui/sheet/sheet-description.jsx +15 -0
  206. package/src/lib/components/ui/sheet/sheet-footer.jsx +11 -0
  207. package/src/lib/components/ui/sheet/sheet-header.jsx +11 -0
  208. package/src/lib/components/ui/sheet/sheet-overlay.jsx +15 -0
  209. package/src/lib/components/ui/sheet/sheet-portal.jsx +4 -0
  210. package/src/lib/components/ui/sheet/sheet-title.jsx +15 -0
  211. package/src/lib/components/ui/sheet/sheet-trigger.jsx +7 -0
  212. package/src/lib/components/ui/sheet/sheet.jsx +4 -0
  213. package/src/lib/components/ui/textarea/index.js +5 -5
  214. package/src/lib/components/ui/textarea/textarea.jsx +18 -0
  215. package/src/lib/components/ui/toggle/index.js +6 -9
  216. package/src/lib/components/ui/toggle/toggle.jsx +36 -0
  217. package/src/lib/components/ui/toggle-group/index.js +8 -8
  218. package/src/lib/components/ui/toggle-group/toggle-group-item.jsx +29 -0
  219. package/src/lib/components/ui/toggle-group/toggle-group.jsx +43 -0
  220. package/src/lib/components/ui/tooltip/index.js +3 -3
  221. package/src/lib/components/ui/tooltip/tooltip-content.jsx +21 -0
  222. package/src/lib/components/ui/tooltip/tooltip-trigger.jsx +23 -0
  223. package/src/lib/components/ui/tooltip/tooltip.jsx +11 -0
  224. package/src/lib/components/ui/trigger-button/index.js +3 -3
  225. package/src/lib/components/ui/trigger-button/trigger-button.css +38 -0
  226. package/src/lib/components/ui/trigger-button/trigger-button.jsx +63 -0
  227. package/src/logger/devLogger.js +238 -0
  228. package/src/logger/devLogger.test.js +193 -0
  229. package/src/modes.test.js +4 -4
  230. package/src/mountStoryboardCore.js +123 -27
  231. package/src/paletteProviders.js +3 -0
  232. package/src/paletteProviders.test.js +2 -2
  233. package/src/server/index.js +98 -36
  234. package/src/sidepanel.css +214 -0
  235. package/src/styles/tailwind.css +1 -1
  236. package/src/svelte-plugin-ui/__tests__/ModeSwitch.test.ts +8 -8
  237. package/src/svelte-plugin-ui/__tests__/ToolbarShell.test.ts +11 -10
  238. package/src/svelte-plugin-ui/components/Icon.css +11 -0
  239. package/src/svelte-plugin-ui/components/Icon.jsx +281 -0
  240. package/src/svelte-plugin-ui/components/ModeSwitch.css +90 -0
  241. package/src/svelte-plugin-ui/components/ModeSwitch.jsx +47 -0
  242. package/src/svelte-plugin-ui/components/ToolbarShell.css +80 -0
  243. package/src/svelte-plugin-ui/components/ToolbarShell.jsx +84 -0
  244. package/src/svelte-plugin-ui/components/Viewfinder.css +412 -0
  245. package/src/svelte-plugin-ui/components/Viewfinder.jsx +512 -0
  246. package/src/svelte-plugin-ui/mount.ts +12 -16
  247. package/src/toolRegistry.js +4 -4
  248. package/src/toolbarConfigStore.js +30 -0
  249. package/src/tools/handlers/autosync.js +1 -1
  250. package/src/tools/handlers/canvasAddWidget.js +1 -1
  251. package/src/tools/handlers/canvasAgents.js +19 -0
  252. package/src/tools/handlers/canvasToolbar.js +8 -8
  253. package/src/tools/handlers/commandPalette.js +9 -0
  254. package/src/tools/handlers/comments.js +1 -1
  255. package/src/tools/handlers/create.js +1 -1
  256. package/src/tools/handlers/devtools.js +16 -0
  257. package/src/tools/handlers/devtools.test.js +38 -0
  258. package/src/tools/handlers/flows.js +1 -1
  259. package/src/tools/handlers/hideChrome.js +9 -0
  260. package/src/tools/handlers/paletteTheme.js +35 -0
  261. package/src/tools/handlers/theme.js +1 -1
  262. package/src/tools/registry.js +4 -1
  263. package/src/tools/surfaces/commandList.js +3 -3
  264. package/src/tools/surfaces/mainToolbar.js +3 -3
  265. package/src/tools/surfaces/registry.js +4 -4
  266. package/src/ui/design-modes.ts +2 -2
  267. package/src/ui/viewfinder.ts +1 -1
  268. package/src/vite/server-plugin.js +242 -60
  269. package/src/workshop/features/createCanvas/CreateCanvasForm.jsx +260 -0
  270. package/src/workshop/features/createCanvas/index.js +1 -1
  271. package/src/workshop/features/createFlow/CreateFlowForm.jsx +334 -0
  272. package/src/workshop/features/createFlow/index.js +1 -1
  273. package/src/workshop/features/createPage/CreatePageForm.jsx +304 -0
  274. package/src/workshop/features/createPage/index.js +1 -1
  275. package/src/workshop/features/createPrototype/CreatePrototypeForm.jsx +289 -0
  276. package/src/workshop/features/createPrototype/index.js +1 -1
  277. package/src/workshop/features/createPrototype/server.js +98 -0
  278. package/src/workshop/features/createStory/CreateStoryForm.jsx +208 -0
  279. package/src/workshop/features/createStory/index.js +1 -1
  280. package/src/workshop/ui/WorkshopPanel.jsx +98 -0
  281. package/src/workshop/ui/mount.ts +1 -1
  282. package/src/worktree/port.js +48 -0
  283. package/src/worktree/serverRegistry.js +120 -0
  284. package/toolbar.config.json +93 -42
  285. package/widgets.config.json +580 -12
  286. package/src/ActionMenuButton.svelte +0 -119
  287. package/src/AutosyncMenuButton.svelte +0 -397
  288. package/src/CanvasCreateMenu.svelte +0 -295
  289. package/src/CanvasSnap.svelte +0 -87
  290. package/src/CanvasUndoRedo.svelte +0 -108
  291. package/src/CanvasZoomControl.svelte +0 -111
  292. package/src/CanvasZoomToFit.svelte +0 -52
  293. package/src/CommandMenu.svelte +0 -249
  294. package/src/CommandPalette.svelte +0 -33
  295. package/src/CommentsMenuButton.svelte +0 -53
  296. package/src/CoreUIBar.svelte +0 -847
  297. package/src/CreateMenuButton.svelte +0 -133
  298. package/src/DocPanel.svelte +0 -299
  299. package/src/InspectorPanel.svelte +0 -745
  300. package/src/PwaInstallBanner.svelte +0 -124
  301. package/src/SidePanel.svelte +0 -480
  302. package/src/ThemeMenuButton.svelte +0 -132
  303. package/src/comments/ui/AuthModal.svelte +0 -108
  304. package/src/comments/ui/CommentWindow.svelte +0 -333
  305. package/src/comments/ui/CommentsDrawer.svelte +0 -96
  306. package/src/comments/ui/Composer.svelte +0 -65
  307. package/src/lib/components/ui/alert/alert-action.svelte +0 -19
  308. package/src/lib/components/ui/alert/alert-description.svelte +0 -22
  309. package/src/lib/components/ui/alert/alert-title.svelte +0 -22
  310. package/src/lib/components/ui/alert/alert.svelte +0 -38
  311. package/src/lib/components/ui/avatar/avatar-badge.svelte +0 -25
  312. package/src/lib/components/ui/avatar/avatar-fallback.svelte +0 -20
  313. package/src/lib/components/ui/avatar/avatar-group-count.svelte +0 -22
  314. package/src/lib/components/ui/avatar/avatar-group.svelte +0 -22
  315. package/src/lib/components/ui/avatar/avatar-image.svelte +0 -17
  316. package/src/lib/components/ui/avatar/avatar.svelte +0 -24
  317. package/src/lib/components/ui/badge/badge.svelte +0 -44
  318. package/src/lib/components/ui/button/button.svelte +0 -108
  319. package/src/lib/components/ui/card/card-action.svelte +0 -21
  320. package/src/lib/components/ui/card/card-content.svelte +0 -19
  321. package/src/lib/components/ui/card/card-description.svelte +0 -19
  322. package/src/lib/components/ui/card/card-footer.svelte +0 -18
  323. package/src/lib/components/ui/card/card-header.svelte +0 -21
  324. package/src/lib/components/ui/card/card-title.svelte +0 -14
  325. package/src/lib/components/ui/card/card.svelte +0 -21
  326. package/src/lib/components/ui/checkbox/checkbox.svelte +0 -39
  327. package/src/lib/components/ui/collapsible/collapsible-content.svelte +0 -7
  328. package/src/lib/components/ui/collapsible/collapsible-trigger.svelte +0 -7
  329. package/src/lib/components/ui/collapsible/collapsible.svelte +0 -11
  330. package/src/lib/components/ui/dialog/dialog-close.svelte +0 -11
  331. package/src/lib/components/ui/dialog/dialog-content.svelte +0 -42
  332. package/src/lib/components/ui/dialog/dialog-description.svelte +0 -17
  333. package/src/lib/components/ui/dialog/dialog-footer.svelte +0 -29
  334. package/src/lib/components/ui/dialog/dialog-header.svelte +0 -19
  335. package/src/lib/components/ui/dialog/dialog-overlay.svelte +0 -17
  336. package/src/lib/components/ui/dialog/dialog-portal.svelte +0 -7
  337. package/src/lib/components/ui/dialog/dialog-title.svelte +0 -17
  338. package/src/lib/components/ui/dialog/dialog-trigger.svelte +0 -11
  339. package/src/lib/components/ui/dialog/dialog.svelte +0 -7
  340. package/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte +0 -16
  341. package/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte +0 -40
  342. package/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte +0 -27
  343. package/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte +0 -18
  344. package/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte +0 -7
  345. package/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte +0 -24
  346. package/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte +0 -20
  347. package/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte +0 -7
  348. package/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte +0 -16
  349. package/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte +0 -34
  350. package/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte +0 -17
  351. package/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte +0 -19
  352. package/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte +0 -17
  353. package/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte +0 -27
  354. package/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte +0 -7
  355. package/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte +0 -7
  356. package/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte +0 -7
  357. package/src/lib/components/ui/input/input.svelte +0 -40
  358. package/src/lib/components/ui/label/label.svelte +0 -20
  359. package/src/lib/components/ui/panel/panel-body.svelte +0 -13
  360. package/src/lib/components/ui/panel/panel-close.svelte +0 -16
  361. package/src/lib/components/ui/panel/panel-content.svelte +0 -33
  362. package/src/lib/components/ui/panel/panel-footer.svelte +0 -13
  363. package/src/lib/components/ui/panel/panel-header.svelte +0 -16
  364. package/src/lib/components/ui/panel/panel-title.svelte +0 -14
  365. package/src/lib/components/ui/panel/panel.svelte +0 -15
  366. package/src/lib/components/ui/popover/popover-close.svelte +0 -7
  367. package/src/lib/components/ui/popover/popover-content.svelte +0 -27
  368. package/src/lib/components/ui/popover/popover-description.svelte +0 -19
  369. package/src/lib/components/ui/popover/popover-header.svelte +0 -19
  370. package/src/lib/components/ui/popover/popover-portal.svelte +0 -7
  371. package/src/lib/components/ui/popover/popover-title.svelte +0 -19
  372. package/src/lib/components/ui/popover/popover-trigger.svelte +0 -17
  373. package/src/lib/components/ui/popover/popover.svelte +0 -7
  374. package/src/lib/components/ui/select/select-content.svelte +0 -40
  375. package/src/lib/components/ui/select/select-group-heading.svelte +0 -19
  376. package/src/lib/components/ui/select/select-group.svelte +0 -17
  377. package/src/lib/components/ui/select/select-item.svelte +0 -38
  378. package/src/lib/components/ui/select/select-label.svelte +0 -18
  379. package/src/lib/components/ui/select/select-portal.svelte +0 -7
  380. package/src/lib/components/ui/select/select-scroll-down-button.svelte +0 -20
  381. package/src/lib/components/ui/select/select-scroll-up-button.svelte +0 -20
  382. package/src/lib/components/ui/select/select-separator.svelte +0 -17
  383. package/src/lib/components/ui/select/select-trigger.svelte +0 -27
  384. package/src/lib/components/ui/select/select.svelte +0 -11
  385. package/src/lib/components/ui/separator/separator.svelte +0 -23
  386. package/src/lib/components/ui/sheet/sheet-close.svelte +0 -7
  387. package/src/lib/components/ui/sheet/sheet-content.svelte +0 -43
  388. package/src/lib/components/ui/sheet/sheet-description.svelte +0 -17
  389. package/src/lib/components/ui/sheet/sheet-footer.svelte +0 -18
  390. package/src/lib/components/ui/sheet/sheet-header.svelte +0 -19
  391. package/src/lib/components/ui/sheet/sheet-overlay.svelte +0 -17
  392. package/src/lib/components/ui/sheet/sheet-portal.svelte +0 -7
  393. package/src/lib/components/ui/sheet/sheet-title.svelte +0 -17
  394. package/src/lib/components/ui/sheet/sheet-trigger.svelte +0 -7
  395. package/src/lib/components/ui/sheet/sheet.svelte +0 -7
  396. package/src/lib/components/ui/textarea/textarea.svelte +0 -21
  397. package/src/lib/components/ui/toggle/toggle.svelte +0 -45
  398. package/src/lib/components/ui/toggle-group/toggle-group-item.svelte +0 -35
  399. package/src/lib/components/ui/toggle-group/toggle-group.svelte +0 -63
  400. package/src/lib/components/ui/tooltip/tooltip-content.svelte +0 -24
  401. package/src/lib/components/ui/tooltip/tooltip-trigger.svelte +0 -27
  402. package/src/lib/components/ui/tooltip/tooltip.svelte +0 -9
  403. package/src/lib/components/ui/trigger-button/trigger-button.svelte +0 -106
  404. package/src/svelte-plugin-ui/components/Icon.svelte +0 -181
  405. package/src/svelte-plugin-ui/components/ModeSwitch.svelte +0 -121
  406. package/src/svelte-plugin-ui/components/ToolbarShell.svelte +0 -150
  407. package/src/svelte-plugin-ui/components/Viewfinder.svelte +0 -1001
  408. package/src/tools/handlers/docs.js +0 -11
  409. package/src/workshop/features/createCanvas/CreateCanvasForm.svelte +0 -139
  410. package/src/workshop/features/createFlow/CreateFlowForm.svelte +0 -314
  411. package/src/workshop/features/createPage/CreatePageForm.svelte +0 -249
  412. package/src/workshop/features/createPrototype/CreatePrototypeForm.svelte +0 -287
  413. package/src/workshop/features/createStory/CreateStoryForm.svelte +0 -161
  414. package/src/workshop/ui/WorkshopPanel.svelte +0 -97
package/src/cli/dev.js CHANGED
@@ -1,8 +1,13 @@
1
1
  /**
2
2
  * storyboard dev [branch] — Start Vite with correct base path.
3
3
  *
4
- * If the storyboard server is running, delegates to it via the
5
- * switch-branch API instead of spawning Vite directly.
4
+ * If a storyboard server is already running (from another `sb dev`),
5
+ * operates in "client mode": asks the existing server to spawn Vite
6
+ * for this branch, prints the URL, and exits. This allows multiple
7
+ * branches to run simultaneously through the same server + Caddy proxy.
8
+ *
9
+ * Otherwise, starts the server in the foreground as the "owner".
10
+ * Ctrl+C kills Vite, releases the port, and exits cleanly.
6
11
  *
7
12
  * Usage:
8
13
  * storyboard dev # detect worktree from cwd
@@ -16,16 +21,15 @@
16
21
 
17
22
  import * as p from '@clack/prompts'
18
23
  import http from 'node:http'
19
- import { spawn, execFileSync } from 'child_process'
24
+ import { execFileSync } from 'child_process'
20
25
  import { existsSync } from 'fs'
21
26
  import { resolve } from 'path'
22
- import { detectWorktreeName, getPort, repoRoot, worktreeDir, listWorktrees } from '../worktree/port.js'
27
+ import { detectWorktreeName, getPort, releasePort, repoRoot, worktreeDir, listWorktrees } from '../worktree/port.js'
23
28
  import { generateCaddyfile, generateRouteConfig, upsertCaddyRoute, isCaddyRunning, reloadCaddy, readDevDomain } from './proxy.js'
24
29
  import { startRenameWatcher } from '../rename-watcher/watcher.js'
25
30
  import { parseFlags } from './flags.js'
26
31
  import { hasUncommittedChanges, localBranchExists, resolveDefaultBranch } from './dev-helpers.js'
27
32
  import { compactAll } from '../canvas/compact.js'
28
- import { SERVER_PORT } from '../server/index.js'
29
33
 
30
34
  const flagSchema = {
31
35
  port: { type: 'number', description: 'Override dev server port' },
@@ -203,102 +207,115 @@ async function resolveDevTarget(branchArg, { allowCreate = true } = {}) {
203
207
  return { worktreeName: branchArg, targetCwd: targetDir, created: true }
204
208
  }
205
209
 
206
- /** Check if the storyboard server is already running */
207
- function isServerRunning() {
210
+ // ─── Server Detection ───
211
+
212
+ /**
213
+ * Check if a storyboard server is already running on the expected port.
214
+ * Returns the server's health response if running, or null.
215
+ */
216
+ function checkExistingServer(port) {
208
217
  return new Promise((resolve) => {
209
- const req = http.get(`http://localhost:${SERVER_PORT}/health`, (res) => {
210
- if (res.statusCode !== 200) { resolve(false); return }
218
+ const req = http.get(`http://localhost:${port}/health`, (res) => {
211
219
  let data = ''
212
- res.on('data', (chunk) => { data += chunk })
220
+ res.on('data', (c) => (data += c))
213
221
  res.on('end', () => {
214
- try {
215
- const json = JSON.parse(data)
216
- // Verify the server belongs to this repo's devDomain
217
- const ourDomain = readDevDomain(process.cwd())
218
- resolve(json.ok === true && json.devDomain === ourDomain)
219
- } catch { resolve(false) }
222
+ try { resolve(JSON.parse(data)) }
223
+ catch { resolve(null) }
220
224
  })
221
225
  })
222
- req.on('error', () => resolve(false))
223
- req.setTimeout(1000, () => { req.destroy(); resolve(false) })
226
+ req.on('error', () => resolve(null))
227
+ req.setTimeout(2000, () => { req.destroy(); resolve(null) })
224
228
  })
225
229
  }
226
230
 
227
- /** Ask the running server to start a branch */
228
- function requestBranchFromServer(branch) {
231
+ /**
232
+ * Ask an existing server to spawn Vite for a branch via the switch-branch API.
233
+ * Returns the parsed JSON response.
234
+ */
235
+ function requestSwitchBranch(port, branch) {
229
236
  return new Promise((resolve, reject) => {
230
237
  const body = JSON.stringify({ branch })
231
- const req = http.request(`http://localhost:${SERVER_PORT}/_storyboard/switch-branch`, {
232
- method: 'POST',
233
- headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) },
234
- }, (res) => {
235
- let data = ''
236
- res.on('data', (chunk) => { data += chunk })
237
- res.on('end', () => {
238
- try { resolve(JSON.parse(data)) }
239
- catch { reject(new Error('Invalid server response')) }
240
- })
241
- })
238
+ const req = http.request(
239
+ { hostname: 'localhost', port, path: '/_storyboard/switch-branch', method: 'POST',
240
+ headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) } },
241
+ (res) => {
242
+ let data = ''
243
+ res.on('data', (c) => (data += c))
244
+ res.on('end', () => {
245
+ try {
246
+ const json = JSON.parse(data)
247
+ if (res.statusCode >= 400) reject(new Error(json.error || `HTTP ${res.statusCode}`))
248
+ else resolve(json)
249
+ } catch { reject(new Error(`Bad response: ${data}`)) }
250
+ })
251
+ }
252
+ )
242
253
  req.on('error', reject)
243
- req.write(body)
244
- req.end()
254
+ req.setTimeout(90_000, () => { req.destroy(); reject(new Error('Timeout waiting for Vite to start')) })
255
+ req.end(body)
245
256
  })
246
257
  }
247
258
 
248
- async function main() {
249
- const { flags, positional } = parseFlags(process.argv.slice(3), flagSchema)
259
+ // ─── Client Mode ───
250
260
 
251
- const branchArg = positional[0] || undefined
252
- const overridePort = flags.port || null
253
- const allowCreate = flags.create
261
+ /**
262
+ * Run in client mode: an existing server handles Vite lifecycle.
263
+ * We just ask it to start the branch, print URLs, and exit.
264
+ */
265
+ async function runClientMode(serverPort, worktreeName, domain) {
266
+ const isMain = worktreeName === 'main'
267
+ const basePath = isMain ? '/' : `/branch--${worktreeName}/`
268
+ const proxyUrl = `http://${domain}${basePath}`
254
269
 
255
- p.intro('storyboard dev')
270
+ p.log.info(`Server already running on :${serverPort} — requesting dev session for "${worktreeName}"...`)
256
271
 
257
- const { worktreeName, targetCwd, created } = await resolveDevTarget(branchArg, { allowCreate })
272
+ try {
273
+ const result = await requestSwitchBranch(serverPort, worktreeName)
258
274
 
259
- if (created) {
260
- p.log.success(`Worktree ready: .worktrees/${worktreeName}`)
261
- } else if (branchArg) {
262
- p.log.info(`Using ${worktreeName === 'main' ? 'main repo' : `.worktrees/${worktreeName}`}`)
263
- }
275
+ if (result.status === 'already_running') {
276
+ p.log.success(`Already running: ${proxyUrl}`)
277
+ } else {
278
+ p.log.success(`Started: ${proxyUrl}`)
279
+ }
264
280
 
265
- const port = getPort(worktreeName)
266
- const isMain = worktreeName === 'main'
281
+ p.log.info(`Stop with: npx storyboard server stop ${worktreeName}`)
282
+ p.outro('Ready')
283
+ } catch (err) {
284
+ p.log.error(`Failed to start dev for "${worktreeName}": ${err.message}`)
285
+ process.exit(1)
286
+ }
287
+ }
267
288
 
268
- const basePath = isMain
269
- ? '/'
270
- : `/branch--${worktreeName}/`
289
+ // ─── Owner Mode ───
271
290
 
272
- const domain = readDevDomain(targetCwd)
291
+ /**
292
+ * Run in owner mode: start the server + Vite in the foreground.
293
+ * This is the original behavior — the process owns the server lifecycle.
294
+ */
295
+ async function runOwnerMode(worktreeName, targetCwd, domain, serverPort) {
296
+ getPort(worktreeName) // allocate port for this worktree
297
+ const isMain = worktreeName === 'main'
298
+ const basePath = isMain ? '/' : `/branch--${worktreeName}/`
273
299
  const proxyUrl = `http://${domain}${basePath}`
274
- const directUrl = `http://localhost:${port}${basePath}`
275
300
 
276
- // ── Check if storyboard server is already running ──
277
- const serverRunning = await isServerRunning()
301
+ p.log.info('Starting storyboard server...')
302
+
303
+ const { startServer, spawnViteForBranch } = await import('../server/index.js')
278
304
 
279
- if (serverRunning) {
280
- // Delegate to the running server — just ask it to start this branch
281
- p.log.info('Storyboard server detected — delegating...')
282
- try {
283
- const result = await requestBranchFromServer(worktreeName)
284
- if (result.url) {
285
- p.log.success(result.url)
286
- p.outro(result.status === 'already_running' ? 'Already running' : 'Started')
287
- } else {
288
- p.log.error(result.error || 'Failed to start branch')
289
- }
290
- } catch (err) {
291
- p.log.error(`Server communication failed: ${err.message}`)
305
+ let serverInstance
306
+ try {
307
+ serverInstance = await startServer()
308
+ } catch (err) {
309
+ if (err.code === 'EADDRINUSE') {
310
+ // Race condition: server started between our health check and bind attempt.
311
+ // Fall back to client mode.
312
+ p.log.info('Server started by another process switching to client mode...')
313
+ await runClientMode(serverPort, worktreeName, domain)
314
+ return
292
315
  }
293
- return
316
+ throw err
294
317
  }
295
318
 
296
- // ── No server running — start server + Vite together ──
297
- p.log.info('Starting storyboard server...')
298
-
299
- const { startServer, spawnViteForBranch, waitForPort: waitPort } = await import('../server/index.js')
300
- startServer()
301
-
302
319
  // Compact bloated canvas JSONL files before starting Vite
303
320
  const compacted = compactAll(targetCwd)
304
321
  if (compacted.length > 0) {
@@ -307,13 +324,9 @@ async function main() {
307
324
  }
308
325
  }
309
326
 
310
- // Spawn Vite through the server (manages the child process)
311
327
  const entry = spawnViteForBranch(worktreeName)
312
-
313
- // Start rename watcher in target directory
314
328
  const renameWatcher = startRenameWatcher(targetCwd)
315
329
 
316
- // Auto-compact every 15 minutes
317
330
  const compactInterval = setInterval(() => {
318
331
  try {
319
332
  const results = compactAll(targetCwd)
@@ -323,19 +336,42 @@ async function main() {
323
336
  } catch { /* non-critical */ }
324
337
  }, 15 * 60 * 1000)
325
338
 
326
- // Wait for Vite to be ready
327
- const ready = await waitPort(entry.port, 60_000)
339
+ function cleanup() {
340
+ renameWatcher.close()
341
+ clearInterval(compactInterval)
342
+ try { entry.child.kill('SIGTERM') } catch { /* already dead */ }
343
+ try { serverInstance.close() } catch { /* best effort */ }
344
+ releasePort(worktreeName)
345
+ process.exit(0)
346
+ }
347
+ process.on('SIGINT', cleanup)
348
+ process.on('SIGTERM', cleanup)
349
+
350
+ const ready = await (async () => {
351
+ const start = Date.now()
352
+ while (Date.now() - start < 60_000) {
353
+ if (entry.status === 'ready') return true
354
+ await new Promise(r => setTimeout(r, 300))
355
+ }
356
+ return false
357
+ })()
328
358
 
329
359
  if (ready) {
360
+ const actualDirectUrl = `http://localhost:${entry.port}${basePath}`
361
+
330
362
  if (isCaddyRunning()) {
331
- p.log.success(proxyUrl)
363
+ const routeConfig = generateRouteConfig({ [worktreeName]: entry.port })
364
+ if (upsertCaddyRoute(routeConfig)) {
365
+ generateCaddyfile({ [worktreeName]: entry.port })
366
+ }
367
+ p.log.success(`${proxyUrl}`)
368
+ p.log.info(`direct: ${actualDirectUrl}`)
332
369
  } else {
333
- p.log.success(directUrl)
370
+ p.log.success(actualDirectUrl)
334
371
  p.log.warning('Proxy not running — run `npx storyboard setup` for clean URLs')
335
372
  }
336
373
  p.outro('Ready')
337
374
 
338
- // Pipe Vite output for interactive use
339
375
  entry.child.stdout.pipe(process.stdout)
340
376
  entry.child.stderr.pipe(process.stderr)
341
377
  } else {
@@ -346,6 +382,7 @@ async function main() {
346
382
  entry.child.on('exit', (code) => {
347
383
  renameWatcher.close()
348
384
  clearInterval(compactInterval)
385
+ try { serverInstance.close() } catch { /* best effort */ }
349
386
  if (code && code !== 0) {
350
387
  p.log.error(`Vite exited with code ${code}`)
351
388
  }
@@ -353,4 +390,41 @@ async function main() {
353
390
  })
354
391
  }
355
392
 
393
+ // ─── Main ───
394
+
395
+ async function main() {
396
+ const { flags, positional } = parseFlags(process.argv.slice(3), flagSchema)
397
+
398
+ const branchArg = positional[0] || undefined
399
+ const allowCreate = flags.create
400
+
401
+ p.intro('storyboard dev')
402
+
403
+ const { worktreeName, targetCwd, created } = await resolveDevTarget(branchArg, { allowCreate })
404
+
405
+ if (created) {
406
+ p.log.success(`Worktree ready: .worktrees/${worktreeName}`)
407
+ } else if (branchArg) {
408
+ p.log.info(`Using ${worktreeName === 'main' ? 'main repo' : `.worktrees/${worktreeName}`}`)
409
+ }
410
+
411
+ const domain = readDevDomain(targetCwd)
412
+
413
+ // Check if a storyboard server is already running for this repo
414
+ const { SERVER_PORT } = await import('../server/index.js')
415
+ const existingServer = await checkExistingServer(SERVER_PORT)
416
+
417
+ if (existingServer?.ok) {
418
+ // Validate the running server belongs to the same repo (devDomain match)
419
+ if (existingServer.devDomain && existingServer.devDomain !== domain) {
420
+ p.log.error(`Port ${SERVER_PORT} is in use by a different project (domain: ${existingServer.devDomain}).`)
421
+ p.log.info('Stop it with `npx storyboard exit`, or use a different devDomain in storyboard.config.json.')
422
+ process.exit(1)
423
+ }
424
+ await runClientMode(SERVER_PORT, worktreeName, domain)
425
+ } else {
426
+ await runOwnerMode(worktreeName, targetCwd, domain, SERVER_PORT)
427
+ }
428
+ }
429
+
356
430
  main()
package/src/cli/exit.js CHANGED
@@ -1,38 +1,37 @@
1
1
  /**
2
- * storyboard exit — Stop the Caddy proxy and all running dev servers.
2
+ * storyboard exit — Stop all running dev servers and the Caddy proxy.
3
3
  */
4
4
 
5
5
  import * as p from '@clack/prompts'
6
- import { execSync } from 'child_process'
6
+ import { list, unregister } from '../worktree/serverRegistry.js'
7
+ import { isCaddyRunning, stopCaddy } from './proxy.js'
7
8
 
8
9
  p.intro('storyboard exit')
9
10
 
10
- // 1. Stop all Vite dev servers started by storyboard
11
- try {
12
- const psOutput = execSync('ps aux', { encoding: 'utf8' })
13
- const vitePids = psOutput
14
- .split('\n')
15
- .filter((line) => line.includes('vite') && line.includes('VITE_BASE_PATH'))
16
- .map((line) => line.trim().split(/\s+/)[1])
17
- .filter(Boolean)
18
-
19
- if (vitePids.length > 0) {
20
- for (const pid of vitePids) {
21
- try { process.kill(Number(pid), 'SIGTERM') } catch { /* already dead */ }
22
- }
23
- p.log.success(`Stopped ${vitePids.length} dev server${vitePids.length > 1 ? 's' : ''}`)
24
- } else {
25
- p.log.info('No dev servers running')
11
+ // 1. Stop all registered dev servers
12
+ const servers = list()
13
+ if (servers.length > 0) {
14
+ let stopped = 0
15
+ for (const s of servers) {
16
+ try {
17
+ process.kill(s.pid, 'SIGTERM')
18
+ stopped++
19
+ } catch { /* already dead */ }
20
+ unregister(s.id)
26
21
  }
27
- } catch {
22
+ p.log.success(`Stopped ${stopped} dev server${stopped !== 1 ? 's' : ''}`)
23
+ } else {
28
24
  p.log.info('No dev servers running')
29
25
  }
30
26
 
31
- // 2. Stop Caddy proxy
32
- try {
33
- execSync('sudo caddy stop >/dev/null 2>&1', { stdio: ['inherit', 'pipe', 'pipe'] })
34
- p.log.success('Proxy stopped')
35
- } catch {
27
+ // 2. Stop Caddy proxy via admin API (no sudo needed)
28
+ if (isCaddyRunning()) {
29
+ if (stopCaddy()) {
30
+ p.log.success('Proxy stopped')
31
+ } else {
32
+ p.log.warning('Failed to stop proxy via admin API')
33
+ }
34
+ } else {
36
35
  p.log.info('Proxy was not running')
37
36
  }
38
37
 
package/src/cli/index.js CHANGED
@@ -5,7 +5,8 @@
5
5
  * Commands:
6
6
  * storyboard dev Start Vite dev server + update proxy
7
7
  * storyboard setup Install deps, Caddy, start proxy
8
- * storyboard proxy Generate Caddyfile + start/reload Caddy
8
+ * storyboard proxy start Start or reload Caddy proxy
9
+ * storyboard proxy close Stop Caddy proxy
9
10
  * storyboard update:version Update @dfosco/storyboard-* packages to latest
10
11
  * storyboard update:beta Update to latest beta
11
12
  * storyboard update:alpha Update to latest alpha
@@ -53,6 +54,9 @@ function helpScreen(version) {
53
54
  ` ${bold(cyan('Development'))}`,
54
55
  cmd('dev', 'Start Vite dev server + update proxy'),
55
56
  cmd('dev [branch]', 'Start dev for a specific worktree/branch'),
57
+ cmd('server list', 'List running dev servers'),
58
+ cmd('server start [wt]', 'Start dev server for a worktree'),
59
+ cmd('server stop <wt|ID>', 'Stop a dev server'),
56
60
  cmd('code [branch]', 'Open a worktree in VS Code'),
57
61
  cmd('exit', 'Stop all dev servers and proxy'),
58
62
  '',
@@ -66,7 +70,9 @@ function helpScreen(version) {
66
70
  ` ${bold(cyan('Canvas'))}`,
67
71
  cmd('canvas add <type>', 'Add widget to a canvas'),
68
72
  ` ${dim('types: sticky-note, markdown, prototype')}`,
73
+ cmd('canvas update <id>', 'Update a widget\'s props or position'),
69
74
  cmd('canvas read [name]', 'Read canvas state and list widgets'),
75
+ cmd('canvas batch', 'Execute multiple canvas operations in one call'),
70
76
  cmd('compact [name]', 'Compact canvas JSONL files (removes bloat)'),
71
77
  cmd('compact --all', 'Force compact all canvases'),
72
78
  '',
@@ -76,11 +82,21 @@ function helpScreen(version) {
76
82
  cmd('terminal close --id <name>', 'Archive a session ' + dim('(alias: archive)')),
77
83
  cmd('terminal open --id <name>', 'Attach to a session'),
78
84
  cmd('terminal remove --id <name>', 'Permanently destroy a session'),
85
+ cmd('terminal read <id>', 'Read terminal buffer ' + dim('(+ --length N)')),
79
86
  cmd('terminal --all', 'Show sessions across all branches'),
87
+ cmd('terminal reset', 'Kill tmux server, clear registry & snapshots'),
88
+ '',
89
+ ` ${dim('Inside a storyboard terminal, shortcuts are available:')}`,
90
+ cmd('start', 'Open the welcome screen'),
91
+ cmd('start <agent>', 'Launch an agent ' + dim('(copilot, claude, codex)')),
92
+ cmd('<agent>', 'Shorthand for start <agent> ' + dim('(accepts extra flags)')),
80
93
  '',
81
94
  ` ${bold(cyan('Setup'))}`,
82
95
  cmd('setup', 'Install deps, Caddy proxy, start proxy'),
83
- cmd('proxy', 'Generate Caddyfile + start/reload Caddy'),
96
+ cmd('branch', 'Switch to a branch (interactive worktree guide)'),
97
+ cmd('branch <name>', 'Switch to a specific branch directly'),
98
+ cmd('proxy start', 'Start or reload Caddy proxy'),
99
+ cmd('proxy close', 'Stop Caddy proxy'),
84
100
  '',
85
101
  ` ${bold(cyan('Updates'))}`,
86
102
  cmd('update', 'Update storyboard packages to latest'),
@@ -105,6 +121,9 @@ switch (command) {
105
121
  case 'setup':
106
122
  import('./setup.js')
107
123
  break
124
+ case 'branch':
125
+ import('./branch.js')
126
+ break
108
127
  case 'proxy':
109
128
  import('./proxy.js')
110
129
  break
@@ -117,10 +136,14 @@ switch (command) {
117
136
  case 'canvas':
118
137
  if (process.argv[3] === 'add') {
119
138
  import('./canvasAdd.js')
139
+ } else if (process.argv[3] === 'update') {
140
+ import('./canvasUpdate.js')
120
141
  } else if (process.argv[3] === 'read' || !process.argv[3]) {
121
142
  import('./canvasRead.js')
122
143
  } else if (process.argv[3] === 'bounds') {
123
144
  import('./canvasBounds.js')
145
+ } else if (process.argv[3] === 'batch') {
146
+ import('./canvasBatch.js')
124
147
  } else {
125
148
  const version = getVersion()
126
149
  console.log(helpScreen(version))
@@ -134,12 +157,39 @@ switch (command) {
134
157
  case 'terminal':
135
158
  if (process.argv[3] === 'start') {
136
159
  import('./terminal-welcome.js')
160
+ } else if (process.argv[3] === '--help' || process.argv[3] === 'help') {
161
+ const cmd = (name, desc) => ` ${green(name.padEnd(36))}${desc}`
162
+ const cmds = [
163
+ ` ${bold(cyan('Terminal commands'))}`,
164
+ cmd('terminal', 'Browse and manage terminal sessions (interactive)'),
165
+ cmd('terminal start', 'Launch the terminal welcome prompt'),
166
+ cmd('terminal close --id <name>', 'Archive a session'),
167
+ cmd('terminal open --id <name>', 'Attach to a session'),
168
+ cmd('terminal remove --id <name>', 'Permanently destroy a session'),
169
+ cmd('terminal reset', 'Kill tmux server, clear registry & snapshots'),
170
+ '',
171
+ ` ${bold(cyan('Messaging'))}`,
172
+ cmd('terminal send <id> "msg"', 'Send a message to a terminal'),
173
+ cmd('terminal send --connected "msg"', 'Send to connected peer'),
174
+ cmd('terminal output --summary "..."', 'Save latest output (+ --content)'),
175
+ cmd('terminal status <widgetId>', 'Check terminal status'),
176
+ cmd('terminal read <widgetId>', 'Read terminal buffer (+ --length N)'),
177
+ ].join('\n')
178
+ console.log(`\n${cmds}\n`)
137
179
  } else if (process.argv[3] === 'close' || process.argv[3] === 'archive') {
138
180
  import('./terminal-commands.js')
139
181
  } else if (process.argv[3] === 'open') {
140
182
  import('./terminal-commands.js')
141
183
  } else if (process.argv[3] === 'remove') {
142
184
  import('./terminal-commands.js')
185
+ } else if (process.argv[3] === 'send') {
186
+ import('./terminal-messaging.js').then(m => m.handleSend())
187
+ } else if (process.argv[3] === 'output') {
188
+ import('./terminal-messaging.js').then(m => m.handleOutput())
189
+ } else if (process.argv[3] === 'status') {
190
+ import('./terminal-messaging.js').then(m => m.handleStatus())
191
+ } else if (process.argv[3] === 'read') {
192
+ import('./terminal-messaging.js').then(m => m.handleRead())
143
193
  } else {
144
194
  // Default: session browser (formerly `storyboard sessions`)
145
195
  import('./sessions.js')
@@ -156,6 +206,9 @@ switch (command) {
156
206
  case 'server':
157
207
  import('./server.js')
158
208
  break
209
+ case 'agent':
210
+ import('./agent.js')
211
+ break
159
212
  case 'code':
160
213
  import('./code.js')
161
214
  break