@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
@@ -1,249 +0,0 @@
1
- <!--
2
- CreatePageForm — workshop form for creating a new page inside a prototype.
3
- -->
4
-
5
- <script lang="ts">
6
- import { onMount } from 'svelte'
7
- import { Button } from '../../../lib/components/ui/button/index.js'
8
- import { Input } from '../../../lib/components/ui/input/index.js'
9
- import { Label } from '../../../lib/components/ui/label/index.js'
10
- import * as Panel from '../../../lib/components/ui/panel/index.js'
11
- import * as DropdownMenu from '../../../lib/components/ui/dropdown-menu/index.js'
12
- import * as Alert from '../../../lib/components/ui/alert/index.js'
13
-
14
- interface Props { onClose?: () => void }
15
- let { onClose }: Props = $props()
16
-
17
- interface PrototypeEntry { name: string; folder?: string }
18
- interface PartialEntry {
19
- id: string
20
- name: string
21
- kind: 'template' | 'recipe'
22
- scope: 'global' | 'prototype'
23
- prototype?: string
24
- folder?: string
25
- }
26
-
27
- let selectedPrototype = $state('')
28
- let pagePath = $state('')
29
- let template = $state('')
30
- let prototypes: PrototypeEntry[] = $state([])
31
- let partials: PartialEntry[] = $state([])
32
- let loading = $state(true)
33
- let submitting = $state(false)
34
- let error: string | null = $state(null)
35
- let success: string | null = $state(null)
36
- let templateMenuOpen = $state(false)
37
-
38
- const selectedProtoEntry = $derived(
39
- selectedPrototype ? prototypes.find((p) => p.name === selectedPrototype) : null
40
- )
41
- const pagePrefix = $derived(selectedPrototype ? `/${selectedPrototype}/` : '/prototype-name/')
42
- const pageSuffix = $derived(
43
- pagePath.startsWith(pagePrefix) ? pagePath.slice(pagePrefix.length) : pagePath
44
- )
45
- const canSubmit = $derived(!!selectedPrototype && !!pageSuffix.trim() && !submitting)
46
- const templateChoices = $derived(
47
- selectedPrototype
48
- ? partials.filter((partial) => {
49
- if (partial.scope === 'global') return true
50
- return partial.prototype === selectedPrototype && (partial.folder || '') === (selectedProtoEntry?.folder || '')
51
- })
52
- : partials.filter((partial) => partial.scope === 'global')
53
- )
54
- const globalTemplateChoices = $derived(templateChoices.filter((partial) => partial.scope === 'global'))
55
- const localTemplateChoices = $derived(
56
- templateChoices.filter((partial) => partial.scope === 'prototype')
57
- )
58
- const localTemplateHeading = $derived(
59
- selectedPrototype || ''
60
- )
61
- const globalTemplates = $derived(globalTemplateChoices.filter((partial) => partial.kind === 'template'))
62
- const globalRecipes = $derived(globalTemplateChoices.filter((partial) => partial.kind === 'recipe'))
63
- const localTemplates = $derived(localTemplateChoices.filter((partial) => partial.kind === 'template'))
64
- const localRecipes = $derived(localTemplateChoices.filter((partial) => partial.kind === 'recipe'))
65
- const templateLabel = $derived(
66
- template ? templateChoices.find((choice) => choice.id === template)?.name ?? template : 'Blank page'
67
- )
68
-
69
- function getApiUrl() {
70
- const basePath = window.__STORYBOARD_BASE_PATH__ || '/'
71
- return basePath.replace(/\/$/, '') + '/_storyboard/workshop/pages'
72
- }
73
-
74
- onMount(async () => {
75
- try {
76
- const res = await fetch(getApiUrl())
77
- if (res.ok) {
78
- const data = await res.json()
79
- prototypes = data.prototypes || []
80
- partials = data.partials || []
81
- }
82
- } catch { /* defaults */ } finally { loading = false }
83
- })
84
-
85
- $effect(() => {
86
- if (!selectedPrototype) {
87
- pagePath = ''
88
- return
89
- }
90
- if (!pagePath || !pagePath.startsWith(pagePrefix)) {
91
- pagePath = `${pagePrefix}new-page`
92
- }
93
- })
94
-
95
- $effect(() => {
96
- if (!template) return
97
- const stillAvailable = templateChoices.some((choice) => choice.id === template)
98
- if (!stillAvailable) {
99
- template = ''
100
- }
101
- })
102
-
103
- async function submit() {
104
- if (!canSubmit) return
105
- submitting = true; error = null; success = null
106
- try {
107
- const res = await fetch(getApiUrl(), {
108
- method: 'POST',
109
- headers: { 'Content-Type': 'application/json' },
110
- body: JSON.stringify({
111
- prototype: selectedPrototype,
112
- folder: selectedProtoEntry?.folder || undefined,
113
- path: pagePath.trim(),
114
- template: template || undefined,
115
- }),
116
- })
117
- const data = await res.json()
118
- if (!res.ok) { error = data.error || 'Failed to create page'; return }
119
- success = `Created ${data.path}`
120
- } catch (err: any) {
121
- error = err.message || 'Network error'
122
- } finally {
123
- submitting = false
124
- }
125
- }
126
-
127
- function handleKeydown(e: KeyboardEvent) { if (e.key === 'Enter' && canSubmit) submit() }
128
- </script>
129
-
130
- <Panel.Header>
131
- <Panel.Title>Create page</Panel.Title>
132
- <Panel.Close />
133
- </Panel.Header>
134
-
135
- <!-- svelte-ignore a11y_no_static_element_interactions -->
136
- <div class="p-4 pt-2 space-y-5" onkeydown={handleKeydown}>
137
- <div class="space-y-1">
138
- <Label for="sb-page-prototype">Prototype</Label>
139
- <select
140
- class="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-xs transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
141
- id="sb-page-prototype"
142
- bind:value={selectedPrototype}
143
- disabled={loading}
144
- >
145
- <option value="">Select prototype</option>
146
- {#each prototypes as p}
147
- <option value={p.name}>{p.folder ? `${p.folder} / ${p.name}` : p.name}</option>
148
- {/each}
149
- </select>
150
- </div>
151
-
152
- <div class="space-y-1">
153
- <Label for="sb-page-path">Page path</Label>
154
- <div class="flex items-center gap-2">
155
- <span class="text-xs text-muted-foreground font-mono whitespace-nowrap">{pagePrefix}</span>
156
- <Input
157
- id="sb-page-path"
158
- placeholder="new-page"
159
- value={pageSuffix}
160
- oninput={(e: Event) => {
161
- const suffix = (e.target as HTMLInputElement).value.replace(/^\/+/, '')
162
- pagePath = `${pagePrefix}${suffix}`
163
- }}
164
- disabled={!selectedPrototype}
165
- />
166
- </div>
167
- </div>
168
-
169
- <div class="space-y-1">
170
- <Label>Template / recipe</Label>
171
- <DropdownMenu.Root bind:open={templateMenuOpen}>
172
- <DropdownMenu.Trigger>
173
- {#snippet child({ props })}
174
- <button
175
- {...props}
176
- class="flex h-9 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-xs transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
177
- disabled={!selectedPrototype}
178
- >
179
- <span class={template ? 'text-foreground' : 'text-muted-foreground'}>{templateLabel}</span>
180
- <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="text-muted-foreground"><path d="m6 9 6 6 6-6"/></svg>
181
- </button>
182
- {/snippet}
183
- </DropdownMenu.Trigger>
184
- <DropdownMenu.Content side="left" align="start" sideOffset={8} class="min-w-[220px]">
185
- {#if template}
186
- <DropdownMenu.Item onclick={() => { template = ''; templateMenuOpen = false }}>
187
- <span class="text-muted-foreground">Blank page</span>
188
- </DropdownMenu.Item>
189
- <DropdownMenu.Separator />
190
- {/if}
191
-
192
- {#if globalTemplates.length > 0}
193
- <DropdownMenu.Group>
194
- <DropdownMenu.GroupHeading>Templates</DropdownMenu.GroupHeading>
195
- {#each globalTemplates as item (item.id)}
196
- <DropdownMenu.Item onclick={() => { template = item.id; templateMenuOpen = false }}>
197
- {item.name}
198
- </DropdownMenu.Item>
199
- {/each}
200
- </DropdownMenu.Group>
201
- {/if}
202
-
203
- {#if localTemplates.length > 0}
204
- <DropdownMenu.Separator />
205
- <DropdownMenu.Group>
206
- <DropdownMenu.GroupHeading>{localTemplateHeading} / Templates</DropdownMenu.GroupHeading>
207
- {#each localTemplates as item (item.id)}
208
- <DropdownMenu.Item onclick={() => { template = item.id; templateMenuOpen = false }}>
209
- {item.name}
210
- </DropdownMenu.Item>
211
- {/each}
212
- </DropdownMenu.Group>
213
- {/if}
214
-
215
- {#if globalRecipes.length > 0}
216
- <DropdownMenu.Separator />
217
- <DropdownMenu.Group>
218
- <DropdownMenu.GroupHeading>Recipes</DropdownMenu.GroupHeading>
219
- {#each globalRecipes as item (item.id)}
220
- <DropdownMenu.Item onclick={() => { template = item.id; templateMenuOpen = false }}>
221
- {item.name}
222
- </DropdownMenu.Item>
223
- {/each}
224
- </DropdownMenu.Group>
225
- {/if}
226
-
227
- {#if localRecipes.length > 0}
228
- <DropdownMenu.Separator />
229
- <DropdownMenu.Group>
230
- <DropdownMenu.GroupHeading>{localTemplateHeading} / Recipes</DropdownMenu.GroupHeading>
231
- {#each localRecipes as item (item.id)}
232
- <DropdownMenu.Item onclick={() => { template = item.id; templateMenuOpen = false }}>
233
- {item.name}
234
- </DropdownMenu.Item>
235
- {/each}
236
- </DropdownMenu.Group>
237
- {/if}
238
- </DropdownMenu.Content>
239
- </DropdownMenu.Root>
240
- </div>
241
-
242
- {#if error}<Alert.Root variant="destructive"><Alert.Description>{error}</Alert.Description></Alert.Root>{/if}
243
- {#if success}<Alert.Root><Alert.Description class="text-success">{success}</Alert.Description></Alert.Root>{/if}
244
- </div>
245
-
246
- <Panel.Footer>
247
- <Button variant="outline" onclick={onClose}>Cancel</Button>
248
- <Button onclick={submit} disabled={!canSubmit}>{submitting ? 'Creating…' : 'Create page'}</Button>
249
- </Panel.Footer>
@@ -1,287 +0,0 @@
1
- <!--
2
- CreatePrototypeForm — workshop form for creating a new prototype.
3
- Uses shadcn-svelte components for all form elements.
4
- -->
5
-
6
- <script lang="ts">
7
- import { onMount } from 'svelte'
8
- import { Button } from '../../../lib/components/ui/button/index.js'
9
- import { Input } from '../../../lib/components/ui/input/index.js'
10
- import { Label } from '../../../lib/components/ui/label/index.js'
11
- import { Checkbox } from '../../../lib/components/ui/checkbox/index.js'
12
- import * as Panel from '../../../lib/components/ui/panel/index.js'
13
- import * as DropdownMenu from '../../../lib/components/ui/dropdown-menu/index.js'
14
- import * as Alert from '../../../lib/components/ui/alert/index.js'
15
-
16
- interface Props { onClose?: () => void }
17
- let { onClose }: Props = $props()
18
-
19
- let name = $state('')
20
- let title = $state('')
21
- let titleTouched = $state(false)
22
- let folder = $state('')
23
- let partial = $state('')
24
- let author = $state('')
25
- let description = $state('')
26
- let createFlow = $state(false)
27
- let isExternal = $state(false)
28
- let externalUrl = $state('')
29
-
30
- interface Partial {
31
- id: string
32
- name: string
33
- kind: 'template' | 'recipe'
34
- scope: 'global' | 'prototype'
35
- prototype?: string
36
- folder?: string
37
- }
38
-
39
- let folders: string[] = $state([])
40
- let partials: Partial[] = $state([])
41
- let loading = $state(true)
42
- let submitting = $state(false)
43
- let error: string | null = $state(null)
44
- let success: string | null = $state(null)
45
-
46
- const kebabName = $derived(
47
- name.replace(/[^a-zA-Z0-9\s_-]/g, '').trim().replace(/[\s_]+/g, '-').toLowerCase().replace(/-+/g, '-').replace(/^-|-$/g, '')
48
- )
49
- const autoTitle = $derived(
50
- kebabName ? kebabName.split('-').map((s: string) => s.charAt(0).toUpperCase() + s.slice(1)).join('').replace(/([A-Z])/g, ' $1').trim() : ''
51
- )
52
- const displayTitle = $derived(titleTouched ? title : autoTitle)
53
- const routePreview = $derived(kebabName ? `/${kebabName}` : '')
54
- const nameError = $derived(
55
- name.trim() && !kebabName ? 'Name must contain at least one alphanumeric character'
56
- : name.trim() && !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(kebabName) ? 'Name must be kebab-case'
57
- : null
58
- )
59
- const urlError: string | null = $derived.by(() => {
60
- if (!isExternal || !externalUrl.trim()) return null
61
- try {
62
- const parsed = new URL(externalUrl.trim())
63
- if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') return 'Must use http: or https: protocol'
64
- return null
65
- } catch {
66
- return 'Must be a valid URL (e.g. https://example.com)'
67
- }
68
- })
69
- const canSubmit = $derived(!!kebabName && !nameError && !submitting && (!isExternal || (!!externalUrl.trim() && !urlError)))
70
-
71
- const selectedFolderLabel = $derived(folder ? `${folder}.folder` : '')
72
- const scopedPartials = $derived(
73
- partials.filter((p) => {
74
- if (p.scope === 'global') return true
75
- if (!folder) return false
76
- return p.folder === folder
77
- })
78
- )
79
- const templateLabel = $derived(
80
- partial ? scopedPartials.find((p) => p.id === partial)?.name ?? partial : 'No template'
81
- )
82
- const templates = $derived(scopedPartials.filter((p) => p.kind === 'template'))
83
- const recipes = $derived(scopedPartials.filter((p) => p.kind === 'recipe'))
84
- const globalTemplates = $derived(templates.filter((p) => p.scope === 'global'))
85
- const globalRecipes = $derived(recipes.filter((p) => p.scope === 'global'))
86
- const localTemplates = $derived(templates.filter((p) => p.scope === 'prototype'))
87
- const localRecipes = $derived(recipes.filter((p) => p.scope === 'prototype'))
88
- let templateMenuOpen = $state(false)
89
-
90
- function getApiUrl() {
91
- const basePath = window.__STORYBOARD_BASE_PATH__ || '/'
92
- return basePath.replace(/\/$/, '') + '/_storyboard/workshop/prototypes'
93
- }
94
-
95
- onMount(async () => {
96
- try {
97
- const res = await fetch(getApiUrl())
98
- if (res.ok) {
99
- const data = await res.json()
100
- folders = data.folders || []
101
- if (data.partials?.length) { partials = data.partials }
102
- }
103
- } catch { /* defaults */ } finally { loading = false }
104
- })
105
-
106
- $effect(() => {
107
- if (!partial) return
108
- const stillAvailable = scopedPartials.some((p) => p.id === partial)
109
- if (!stillAvailable) {
110
- partial = ''
111
- }
112
- })
113
-
114
- function handleTitleInput(e: Event) { title = (e.target as HTMLInputElement).value; titleTouched = true }
115
- function handleTitleBlur() { if (!title.trim()) titleTouched = false }
116
-
117
- async function submit() {
118
- if (!canSubmit) return
119
- submitting = true; error = null; success = null
120
- try {
121
- const payload: Record<string, any> = { name: kebabName, title: displayTitle, folder: folder || undefined, author: author.trim() || undefined, description: description.trim() || undefined }
122
- if (isExternal) {
123
- payload.url = externalUrl.trim()
124
- } else {
125
- payload.recipe = partial || undefined
126
- payload.createFlow = createFlow
127
- }
128
- const res = await fetch(getApiUrl(), {
129
- method: 'POST', headers: { 'Content-Type': 'application/json' },
130
- body: JSON.stringify(payload),
131
- })
132
- const data = await res.json()
133
- if (!res.ok) { error = data.error || 'Failed to create prototype'; return }
134
- success = `Created ${data.path}`
135
- if (data.isExternal) {
136
- // External prototype — no local route to navigate to, just close after a moment
137
- setTimeout(() => onClose?.(), 1500)
138
- } else {
139
- setTimeout(() => { const base = (window.__STORYBOARD_BASE_PATH__ || '/').replace(/\/$/, ''); window.location.href = base + data.route }, 1500)
140
- }
141
- } catch (err: any) { error = err.message || 'Network error' } finally { submitting = false }
142
- }
143
-
144
- function handleKeydown(e: KeyboardEvent) { if (e.key === 'Enter' && canSubmit) submit() }
145
- </script>
146
-
147
- <Panel.Header>
148
- <Panel.Title>Create prototype</Panel.Title>
149
- <Panel.Close />
150
- </Panel.Header>
151
-
152
- <!-- svelte-ignore a11y_no_static_element_interactions -->
153
- <div class="p-4 pt-2 space-y-3" onkeydown={handleKeydown}>
154
- <div class="space-y-1">
155
- <Label for="sb-proto-name">Name</Label>
156
- <Input id="sb-proto-name" placeholder="e.g. my-prototype" autocomplete="off" spellcheck="false" bind:value={name} />
157
- {#if nameError}<p class="text-sm text-destructive">{nameError}</p>{/if}
158
- {#if routePreview && !isExternal}<p class="text-xs text-muted-foreground">Route: <code class="px-1 py-0.5 bg-muted rounded font-mono text-foreground text-xs">{routePreview}</code></p>{/if}
159
- </div>
160
-
161
- <div class="flex items-center gap-2">
162
- <Checkbox id="sb-proto-external" bind:checked={isExternal} />
163
- <Label for="sb-proto-external" class="text-sm font-normal cursor-pointer">External prototype</Label>
164
- </div>
165
-
166
- {#if isExternal}
167
- <div class="space-y-1">
168
- <Label for="sb-proto-url">URL</Label>
169
- <Input id="sb-proto-url" placeholder="https://example.com/prototype" autocomplete="off" spellcheck="false" bind:value={externalUrl} />
170
- {#if urlError}<p class="text-sm text-destructive">{urlError}</p>{/if}
171
- </div>
172
- {/if}
173
-
174
- <div class="space-y-1">
175
- <Label for="sb-proto-title">Title</Label>
176
- <Input id="sb-proto-title" placeholder={autoTitle || 'Auto-derived from name'} value={displayTitle} oninput={handleTitleInput} onblur={handleTitleBlur} />
177
- </div>
178
-
179
- <div class="grid grid-cols-2 gap-3">
180
- <div class="space-y-1">
181
- <Label for="sb-proto-folder">Folder</Label>
182
- <select class="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-xs transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50" id="sb-proto-folder" bind:value={folder} disabled={loading}>
183
- <option value="">None</option>
184
- {#each folders as f}<option value={f}>{f}</option>{/each}
185
- </select>
186
- </div>
187
- {#if !isExternal}
188
- <div class="space-y-1">
189
- <Label>Template</Label>
190
- <DropdownMenu.Root bind:open={templateMenuOpen}>
191
- <DropdownMenu.Trigger>
192
- {#snippet child({ props })}
193
- <button
194
- {...props}
195
- class="flex h-9 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-xs transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
196
- disabled={loading}
197
- >
198
- <span class={partial ? 'text-foreground' : 'text-muted-foreground'}>{templateLabel}</span>
199
- <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="text-muted-foreground"><path d="m6 9 6 6 6-6"/></svg>
200
- </button>
201
- {/snippet}
202
- </DropdownMenu.Trigger>
203
- <DropdownMenu.Content side="left" align="start" sideOffset={8} class="min-w-[180px]">
204
- {#if partial}
205
- <DropdownMenu.Item onclick={() => { partial = ''; templateMenuOpen = false }}>
206
- <span class="text-muted-foreground">Clear selection</span>
207
- </DropdownMenu.Item>
208
- <DropdownMenu.Separator />
209
- {/if}
210
-
211
- {#if templates.length > 0}
212
- <DropdownMenu.Group>
213
- <DropdownMenu.GroupHeading>Templates</DropdownMenu.GroupHeading>
214
- {#each globalTemplates as t (t.id)}
215
- <DropdownMenu.Item onclick={() => { partial = t.id; templateMenuOpen = false }}>
216
- {t.name}
217
- </DropdownMenu.Item>
218
- {/each}
219
- </DropdownMenu.Group>
220
- {/if}
221
-
222
- {#if localTemplates.length > 0}
223
- <DropdownMenu.Separator />
224
- <DropdownMenu.Group>
225
- <DropdownMenu.GroupHeading>{selectedFolderLabel || 'Prototype local'} / Templates</DropdownMenu.GroupHeading>
226
- {#each localTemplates as t (t.id)}
227
- <DropdownMenu.Item onclick={() => { partial = t.id; templateMenuOpen = false }}>
228
- {t.name}
229
- </DropdownMenu.Item>
230
- {/each}
231
- </DropdownMenu.Group>
232
- {/if}
233
-
234
- {#if globalRecipes.length > 0}
235
- <DropdownMenu.Separator />
236
- <DropdownMenu.Group>
237
- <DropdownMenu.GroupHeading>Recipes</DropdownMenu.GroupHeading>
238
- {#each globalRecipes as r (r.id)}
239
- <DropdownMenu.Item onclick={() => { partial = r.id; templateMenuOpen = false }}>
240
- {r.name}
241
- </DropdownMenu.Item>
242
- {/each}
243
- </DropdownMenu.Group>
244
- {/if}
245
-
246
- {#if localRecipes.length > 0}
247
- <DropdownMenu.Separator />
248
- <DropdownMenu.Group>
249
- <DropdownMenu.GroupHeading>{selectedFolderLabel || 'Prototype local'} / Recipes</DropdownMenu.GroupHeading>
250
- {#each localRecipes as r (r.id)}
251
- <DropdownMenu.Item onclick={() => { partial = r.id; templateMenuOpen = false }}>
252
- {r.name}
253
- </DropdownMenu.Item>
254
- {/each}
255
- </DropdownMenu.Group>
256
- {/if}
257
- </DropdownMenu.Content>
258
- </DropdownMenu.Root>
259
- </div>
260
- {/if}
261
- </div>
262
-
263
- <div class="space-y-1">
264
- <Label for="sb-proto-author">Author</Label>
265
- <Input id="sb-proto-author" placeholder="GitHub handle(s), comma-separated" bind:value={author} />
266
- </div>
267
-
268
- <div class="space-y-1">
269
- <Label for="sb-proto-desc">Description</Label>
270
- <Input id="sb-proto-desc" placeholder="Optional description" bind:value={description} />
271
- </div>
272
-
273
- {#if !isExternal}
274
- <div class="flex items-center gap-2">
275
- <Checkbox id="sb-proto-flow" bind:checked={createFlow} />
276
- <Label for="sb-proto-flow" class="text-sm font-normal cursor-pointer">Create flow file</Label>
277
- </div>
278
- {/if}
279
-
280
- {#if error}<Alert.Root variant="destructive"><Alert.Description>{error}</Alert.Description></Alert.Root>{/if}
281
- {#if success}<Alert.Root><Alert.Description class="text-success">{success}</Alert.Description></Alert.Root>{/if}
282
- </div>
283
-
284
- <Panel.Footer>
285
- <Button variant="outline" onclick={onClose}>Cancel</Button>
286
- <Button onclick={submit} disabled={!canSubmit}>{submitting ? 'Creating\u2026' : 'Create'}</Button>
287
- </Panel.Footer>