@dfosco/storyboard 0.5.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (592) hide show
  1. package/commandpalette.config.json +152 -0
  2. package/dist/storyboard-ui.css +1 -0
  3. package/dist/storyboard-ui.js +21328 -0
  4. package/dist/storyboard-ui.js.map +1 -0
  5. package/dist/tailwind.css +2 -0
  6. package/dist/tiny-canvas.css +1 -0
  7. package/dist/tiny-canvas.js +389 -0
  8. package/package.json +121 -0
  9. package/paste.config.json +67 -0
  10. package/scaffold/AGENTS.md +432 -0
  11. package/scaffold/agents/prompt-agent.agent.md +181 -0
  12. package/scaffold/agents/terminal-agent.agent.md +351 -0
  13. package/scaffold/codex/config.toml +246 -0
  14. package/scaffold/deploy.yml +103 -0
  15. package/scaffold/githooks/pre-push +114 -0
  16. package/scaffold/gitignore +64 -0
  17. package/scaffold/manifest.json +56 -0
  18. package/scaffold/preview.yml +181 -0
  19. package/scaffold/scripts/link.sh +26 -0
  20. package/scaffold/scripts/unlink.sh +10 -0
  21. package/scaffold/skills/agent-browser/SKILL.md +260 -0
  22. package/scaffold/skills/canvas/SKILL.md +364 -0
  23. package/scaffold/skills/create/SKILL.md +501 -0
  24. package/scaffold/skills/ship/SKILL.md +237 -0
  25. package/scaffold/skills/storyboard/SKILL.md +360 -0
  26. package/scaffold/skills/update-storyboard/SKILL.md +16 -0
  27. package/scaffold/skills/update-storyboard/update-storyboard-packages.sh +26 -0
  28. package/scaffold/skills/vitest/GENERATION.md +5 -0
  29. package/scaffold/skills/vitest/SKILL.md +52 -0
  30. package/scaffold/skills/vitest/references/advanced-environments.md +264 -0
  31. package/scaffold/skills/vitest/references/advanced-projects.md +300 -0
  32. package/scaffold/skills/vitest/references/advanced-type-testing.md +237 -0
  33. package/scaffold/skills/vitest/references/advanced-vi.md +249 -0
  34. package/scaffold/skills/vitest/references/core-cli.md +166 -0
  35. package/scaffold/skills/vitest/references/core-config.md +174 -0
  36. package/scaffold/skills/vitest/references/core-describe.md +193 -0
  37. package/scaffold/skills/vitest/references/core-expect.md +219 -0
  38. package/scaffold/skills/vitest/references/core-hooks.md +244 -0
  39. package/scaffold/skills/vitest/references/core-test-api.md +233 -0
  40. package/scaffold/skills/vitest/references/features-concurrency.md +250 -0
  41. package/scaffold/skills/vitest/references/features-context.md +238 -0
  42. package/scaffold/skills/vitest/references/features-coverage.md +207 -0
  43. package/scaffold/skills/vitest/references/features-filtering.md +211 -0
  44. package/scaffold/skills/vitest/references/features-mocking.md +265 -0
  45. package/scaffold/skills/vitest/references/features-snapshots.md +207 -0
  46. package/scaffold/skills/worktree/SKILL.md +93 -0
  47. package/scaffold/storyboard.config.json +44 -0
  48. package/src/canvas/Canvas.jsx +78 -0
  49. package/src/canvas/Draggable.jsx +235 -0
  50. package/src/canvas/index.d.ts +41 -0
  51. package/src/canvas/index.js +6 -0
  52. package/src/canvas/style.css +118 -0
  53. package/src/canvas/useResetCanvas.js +17 -0
  54. package/src/canvas/utils.js +136 -0
  55. package/src/core/assets/fonts/IoskeleyMono-Bold.woff2 +0 -0
  56. package/src/core/assets/fonts/IoskeleyMono-Italic.woff2 +0 -0
  57. package/src/core/assets/fonts/IoskeleyMono-Medium.woff2 +0 -0
  58. package/src/core/assets/fonts/IoskeleyMono-Regular.woff2 +0 -0
  59. package/src/core/assets/fonts/IoskeleyMono-SemiBold.woff2 +0 -0
  60. package/src/core/autosync/server.js +714 -0
  61. package/src/core/autosync/server.test.js +158 -0
  62. package/src/core/canvas/__tests__/agent-integration.test.js +596 -0
  63. package/src/core/canvas/__tests__/helpers/browser.js +95 -0
  64. package/src/core/canvas/__tests__/helpers/canvas-api.js +129 -0
  65. package/src/core/canvas/__tests__/helpers/perf.js +118 -0
  66. package/src/core/canvas/__tests__/helpers/setup.js +176 -0
  67. package/src/core/canvas/__tests__/helpers/tmux.js +130 -0
  68. package/src/core/canvas/__tests__/helpers/transcript.js +132 -0
  69. package/src/core/canvas/__tests__/terminal-integration.test.js +177 -0
  70. package/src/core/canvas/collision.js +292 -0
  71. package/src/core/canvas/collision.test.js +371 -0
  72. package/src/core/canvas/compact.js +83 -0
  73. package/src/core/canvas/deriveCanvasId.test.js +40 -0
  74. package/src/core/canvas/githubEmbeds.js +527 -0
  75. package/src/core/canvas/githubEmbeds.test.js +302 -0
  76. package/src/core/canvas/hot-pool.js +766 -0
  77. package/src/core/canvas/identity.js +107 -0
  78. package/src/core/canvas/identity.test.js +100 -0
  79. package/src/core/canvas/materializer.js +259 -0
  80. package/src/core/canvas/materializer.test.js +356 -0
  81. package/src/core/canvas/selectedWidgets.js +270 -0
  82. package/src/core/canvas/selectedWidgets.test.js +321 -0
  83. package/src/core/canvas/server.js +3134 -0
  84. package/src/core/canvas/server.test.js +379 -0
  85. package/src/core/canvas/terminal-config.js +330 -0
  86. package/src/core/canvas/terminal-registry.js +465 -0
  87. package/src/core/canvas/terminal-server.js +1436 -0
  88. package/src/core/canvas/writeGuard.js +53 -0
  89. package/src/core/cli/agent.js +85 -0
  90. package/src/core/cli/branch.js +386 -0
  91. package/src/core/cli/canvasAdd.js +241 -0
  92. package/src/core/cli/canvasBatch.js +98 -0
  93. package/src/core/cli/canvasBounds.js +160 -0
  94. package/src/core/cli/canvasRead.js +236 -0
  95. package/src/core/cli/canvasUpdate.js +179 -0
  96. package/src/core/cli/code.js +67 -0
  97. package/src/core/cli/compact.js +62 -0
  98. package/src/core/cli/create.js +674 -0
  99. package/src/core/cli/dev-helpers.js +53 -0
  100. package/src/core/cli/dev-helpers.test.js +53 -0
  101. package/src/core/cli/dev.js +430 -0
  102. package/src/core/cli/exit.js +38 -0
  103. package/src/core/cli/flags.js +174 -0
  104. package/src/core/cli/flags.test.js +155 -0
  105. package/src/core/cli/index.js +233 -0
  106. package/src/core/cli/intro.js +37 -0
  107. package/src/core/cli/proxy.js +319 -0
  108. package/src/core/cli/proxy.test.js +63 -0
  109. package/src/core/cli/schemas.js +223 -0
  110. package/src/core/cli/server.js +192 -0
  111. package/src/core/cli/serverUrl.js +61 -0
  112. package/src/core/cli/sessions.js +459 -0
  113. package/src/core/cli/setup.js +404 -0
  114. package/src/core/cli/terminal-commands.js +287 -0
  115. package/src/core/cli/terminal-messaging.js +231 -0
  116. package/src/core/cli/terminal-welcome.js +515 -0
  117. package/src/core/cli/updateVersion.js +124 -0
  118. package/src/core/comments/api.js +284 -0
  119. package/src/core/comments/api.test.js +282 -0
  120. package/src/core/comments/auth.js +151 -0
  121. package/src/core/comments/auth.test.js +167 -0
  122. package/src/core/comments/commentCache.js +109 -0
  123. package/src/core/comments/commentCache.test.js +48 -0
  124. package/src/core/comments/commentDrafts.js +68 -0
  125. package/src/core/comments/commentMode.js +63 -0
  126. package/src/core/comments/commentMode.test.js +90 -0
  127. package/src/core/comments/config.js +47 -0
  128. package/src/core/comments/config.test.js +77 -0
  129. package/src/core/comments/graphql.js +65 -0
  130. package/src/core/comments/graphql.test.js +95 -0
  131. package/src/core/comments/index.js +42 -0
  132. package/src/core/comments/metadata.js +52 -0
  133. package/src/core/comments/metadata.test.js +110 -0
  134. package/src/core/comments/queries.js +245 -0
  135. package/src/core/comments/ui/AuthModal.jsx +114 -0
  136. package/src/core/comments/ui/CommentOverlay.js +52 -0
  137. package/src/core/comments/ui/CommentWindow.jsx +329 -0
  138. package/src/core/comments/ui/CommentsDrawer.jsx +102 -0
  139. package/src/core/comments/ui/Composer.jsx +64 -0
  140. package/src/core/comments/ui/authModal.js +66 -0
  141. package/src/core/comments/ui/authModal.test.js +76 -0
  142. package/src/core/comments/ui/comment-cursor-dark.svg +1 -0
  143. package/src/core/comments/ui/comment-cursor.svg +1 -0
  144. package/src/core/comments/ui/comment-layout.css +142 -0
  145. package/src/core/comments/ui/commentWindow.js +121 -0
  146. package/src/core/comments/ui/comments.css +242 -0
  147. package/src/core/comments/ui/commentsDrawer.js +84 -0
  148. package/src/core/comments/ui/composer.js +136 -0
  149. package/src/core/comments/ui/index.js +14 -0
  150. package/src/core/comments/ui/mount.js +687 -0
  151. package/src/core/comments/ui/mount.test.js +336 -0
  152. package/src/core/data/dotPath.js +53 -0
  153. package/src/core/data/dotPath.test.js +114 -0
  154. package/src/core/data/loader.js +409 -0
  155. package/src/core/data/loader.test.js +599 -0
  156. package/src/core/data/viewfinder.js +363 -0
  157. package/src/core/data/viewfinder.test.js +456 -0
  158. package/src/core/devtools/devtools-consumer.js +28 -0
  159. package/src/core/devtools/devtools.js +144 -0
  160. package/src/core/devtools/devtools.test.js +75 -0
  161. package/src/core/devtools/sceneDebug.js +112 -0
  162. package/src/core/devtools/sceneDebug.test.js +141 -0
  163. package/src/core/index.js +124 -0
  164. package/src/core/inspector/fiberWalker.js +239 -0
  165. package/src/core/inspector/highlighter.js +275 -0
  166. package/src/core/inspector/mouseMode.js +259 -0
  167. package/src/core/lib/components/ui/alert/alert-action.jsx +11 -0
  168. package/src/core/lib/components/ui/alert/alert-description.jsx +11 -0
  169. package/src/core/lib/components/ui/alert/alert-title.jsx +11 -0
  170. package/src/core/lib/components/ui/alert/alert.jsx +25 -0
  171. package/src/core/lib/components/ui/alert/index.js +17 -0
  172. package/src/core/lib/components/ui/avatar/avatar-badge.jsx +22 -0
  173. package/src/core/lib/components/ui/avatar/avatar-fallback.jsx +18 -0
  174. package/src/core/lib/components/ui/avatar/avatar-group-count.jsx +19 -0
  175. package/src/core/lib/components/ui/avatar/avatar-group.jsx +19 -0
  176. package/src/core/lib/components/ui/avatar/avatar-image.jsx +15 -0
  177. package/src/core/lib/components/ui/avatar/avatar.jsx +19 -0
  178. package/src/core/lib/components/ui/avatar/index.js +22 -0
  179. package/src/core/lib/components/ui/badge/badge.jsx +31 -0
  180. package/src/core/lib/components/ui/badge/index.js +2 -0
  181. package/src/core/lib/components/ui/button/button.jsx +100 -0
  182. package/src/core/lib/components/ui/button/index.js +12 -0
  183. package/src/core/lib/components/ui/card/card-action.jsx +11 -0
  184. package/src/core/lib/components/ui/card/card-content.jsx +11 -0
  185. package/src/core/lib/components/ui/card/card-description.jsx +11 -0
  186. package/src/core/lib/components/ui/card/card-footer.jsx +11 -0
  187. package/src/core/lib/components/ui/card/card-header.jsx +19 -0
  188. package/src/core/lib/components/ui/card/card-title.jsx +11 -0
  189. package/src/core/lib/components/ui/card/card.jsx +17 -0
  190. package/src/core/lib/components/ui/card/index.js +25 -0
  191. package/src/core/lib/components/ui/checkbox/checkbox.jsx +29 -0
  192. package/src/core/lib/components/ui/checkbox/index.js +6 -0
  193. package/src/core/lib/components/ui/collapsible/collapsible-content.jsx +7 -0
  194. package/src/core/lib/components/ui/collapsible/collapsible-trigger.jsx +7 -0
  195. package/src/core/lib/components/ui/collapsible/collapsible.jsx +7 -0
  196. package/src/core/lib/components/ui/collapsible/index.js +13 -0
  197. package/src/core/lib/components/ui/dialog/dialog-close.jsx +7 -0
  198. package/src/core/lib/components/ui/dialog/dialog-content.jsx +34 -0
  199. package/src/core/lib/components/ui/dialog/dialog-description.jsx +15 -0
  200. package/src/core/lib/components/ui/dialog/dialog-footer.jsx +23 -0
  201. package/src/core/lib/components/ui/dialog/dialog-header.jsx +11 -0
  202. package/src/core/lib/components/ui/dialog/dialog-overlay.jsx +15 -0
  203. package/src/core/lib/components/ui/dialog/dialog-portal.jsx +4 -0
  204. package/src/core/lib/components/ui/dialog/dialog-title.jsx +15 -0
  205. package/src/core/lib/components/ui/dialog/dialog-trigger.jsx +7 -0
  206. package/src/core/lib/components/ui/dialog/dialog.jsx +4 -0
  207. package/src/core/lib/components/ui/dialog/index.js +34 -0
  208. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.jsx +8 -0
  209. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.jsx +30 -0
  210. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-content.jsx +22 -0
  211. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.jsx +16 -0
  212. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-group.jsx +7 -0
  213. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-item.jsx +20 -0
  214. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-label.jsx +17 -0
  215. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-portal.jsx +4 -0
  216. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.jsx +7 -0
  217. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.jsx +29 -0
  218. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-separator.jsx +15 -0
  219. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.jsx +16 -0
  220. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.jsx +15 -0
  221. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.jsx +23 -0
  222. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-sub.jsx +4 -0
  223. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-trigger.jsx +7 -0
  224. package/src/core/lib/components/ui/dropdown-menu/dropdown-menu.jsx +4 -0
  225. package/src/core/lib/components/ui/dropdown-menu/index.js +54 -0
  226. package/src/core/lib/components/ui/input/index.js +7 -0
  227. package/src/core/lib/components/ui/input/input.jsx +19 -0
  228. package/src/core/lib/components/ui/label/index.js +7 -0
  229. package/src/core/lib/components/ui/label/label.jsx +19 -0
  230. package/src/core/lib/components/ui/panel/index.js +24 -0
  231. package/src/core/lib/components/ui/panel/panel-body.jsx +11 -0
  232. package/src/core/lib/components/ui/panel/panel-close.jsx +16 -0
  233. package/src/core/lib/components/ui/panel/panel-content.jsx +29 -0
  234. package/src/core/lib/components/ui/panel/panel-footer.jsx +11 -0
  235. package/src/core/lib/components/ui/panel/panel-header.jsx +11 -0
  236. package/src/core/lib/components/ui/panel/panel-title.jsx +12 -0
  237. package/src/core/lib/components/ui/panel/panel.jsx +4 -0
  238. package/src/core/lib/components/ui/popover/index.js +28 -0
  239. package/src/core/lib/components/ui/popover/popover-close.jsx +7 -0
  240. package/src/core/lib/components/ui/popover/popover-content.jsx +22 -0
  241. package/src/core/lib/components/ui/popover/popover-description.jsx +11 -0
  242. package/src/core/lib/components/ui/popover/popover-header.jsx +11 -0
  243. package/src/core/lib/components/ui/popover/popover-portal.jsx +4 -0
  244. package/src/core/lib/components/ui/popover/popover-title.jsx +11 -0
  245. package/src/core/lib/components/ui/popover/popover-trigger.jsx +8 -0
  246. package/src/core/lib/components/ui/popover/popover.jsx +4 -0
  247. package/src/core/lib/components/ui/searchable-list.jsx +160 -0
  248. package/src/core/lib/components/ui/select/index.js +37 -0
  249. package/src/core/lib/components/ui/select/select-content.jsx +30 -0
  250. package/src/core/lib/components/ui/select/select-group-heading.jsx +17 -0
  251. package/src/core/lib/components/ui/select/select-group.jsx +15 -0
  252. package/src/core/lib/components/ui/select/select-item.jsx +26 -0
  253. package/src/core/lib/components/ui/select/select-label.jsx +11 -0
  254. package/src/core/lib/components/ui/select/select-portal.jsx +4 -0
  255. package/src/core/lib/components/ui/select/select-scroll-down-button.jsx +18 -0
  256. package/src/core/lib/components/ui/select/select-scroll-up-button.jsx +18 -0
  257. package/src/core/lib/components/ui/select/select-separator.jsx +15 -0
  258. package/src/core/lib/components/ui/select/select-trigger.jsx +25 -0
  259. package/src/core/lib/components/ui/select/select.jsx +4 -0
  260. package/src/core/lib/components/ui/separator/index.js +7 -0
  261. package/src/core/lib/components/ui/separator/separator.jsx +22 -0
  262. package/src/core/lib/components/ui/sheet/index.js +34 -0
  263. package/src/core/lib/components/ui/sheet/sheet-close.jsx +7 -0
  264. package/src/core/lib/components/ui/sheet/sheet-content.jsx +35 -0
  265. package/src/core/lib/components/ui/sheet/sheet-description.jsx +15 -0
  266. package/src/core/lib/components/ui/sheet/sheet-footer.jsx +11 -0
  267. package/src/core/lib/components/ui/sheet/sheet-header.jsx +11 -0
  268. package/src/core/lib/components/ui/sheet/sheet-overlay.jsx +15 -0
  269. package/src/core/lib/components/ui/sheet/sheet-portal.jsx +4 -0
  270. package/src/core/lib/components/ui/sheet/sheet-title.jsx +15 -0
  271. package/src/core/lib/components/ui/sheet/sheet-trigger.jsx +7 -0
  272. package/src/core/lib/components/ui/sheet/sheet.jsx +4 -0
  273. package/src/core/lib/components/ui/textarea/index.js +7 -0
  274. package/src/core/lib/components/ui/textarea/textarea.jsx +18 -0
  275. package/src/core/lib/components/ui/toggle/index.js +8 -0
  276. package/src/core/lib/components/ui/toggle/toggle.jsx +36 -0
  277. package/src/core/lib/components/ui/toggle-group/index.js +10 -0
  278. package/src/core/lib/components/ui/toggle-group/toggle-group-item.jsx +29 -0
  279. package/src/core/lib/components/ui/toggle-group/toggle-group.jsx +43 -0
  280. package/src/core/lib/components/ui/tooltip/index.js +3 -0
  281. package/src/core/lib/components/ui/tooltip/tooltip-content.jsx +21 -0
  282. package/src/core/lib/components/ui/tooltip/tooltip-trigger.jsx +23 -0
  283. package/src/core/lib/components/ui/tooltip/tooltip.jsx +11 -0
  284. package/src/core/lib/components/ui/trigger-button/index.js +6 -0
  285. package/src/core/lib/components/ui/trigger-button/trigger-button.css +38 -0
  286. package/src/core/lib/components/ui/trigger-button/trigger-button.jsx +63 -0
  287. package/src/core/lib/utils/index.js +6 -0
  288. package/src/core/logger/devLogger.js +238 -0
  289. package/src/core/logger/devLogger.test.js +193 -0
  290. package/src/core/modes/modes.css +98 -0
  291. package/src/core/modes/modes.js +492 -0
  292. package/src/core/modes/modes.test.js +562 -0
  293. package/src/core/mountStoryboardCore.js +478 -0
  294. package/src/core/rename-watcher/config.json +23 -0
  295. package/src/core/rename-watcher/watcher.js +531 -0
  296. package/src/core/scaffold.js +100 -0
  297. package/src/core/server/index.js +391 -0
  298. package/src/core/session/bodyClasses.js +128 -0
  299. package/src/core/session/bodyClasses.test.js +192 -0
  300. package/src/core/session/hashSubscribe.js +19 -0
  301. package/src/core/session/hashSubscribe.test.js +62 -0
  302. package/src/core/session/hideMode.js +424 -0
  303. package/src/core/session/hideMode.test.js +268 -0
  304. package/src/core/session/interceptHideParams.js +35 -0
  305. package/src/core/session/interceptHideParams.test.js +90 -0
  306. package/src/core/session/localStorage.js +134 -0
  307. package/src/core/session/localStorage.test.js +148 -0
  308. package/src/core/session/session.js +76 -0
  309. package/src/core/session/session.test.js +91 -0
  310. package/src/core/stores/canvasConfig.js +134 -0
  311. package/src/core/stores/canvasConfig.test.js +120 -0
  312. package/src/core/stores/commandActions.js +284 -0
  313. package/src/core/stores/commandPaletteConfig.js +31 -0
  314. package/src/core/stores/configSchema.js +232 -0
  315. package/src/core/stores/configSchema.test.js +72 -0
  316. package/src/core/stores/configStore.js +161 -0
  317. package/src/core/stores/customerModeConfig.js +30 -0
  318. package/src/core/stores/featureFlags.js +127 -0
  319. package/src/core/stores/paletteProviders.js +360 -0
  320. package/src/core/stores/paletteProviders.test.js +186 -0
  321. package/src/core/stores/plugins.js +40 -0
  322. package/src/core/stores/plugins.test.js +68 -0
  323. package/src/core/stores/recentArtifacts.js +68 -0
  324. package/src/core/stores/recentArtifacts.test.js +71 -0
  325. package/src/core/stores/sidePanelStore.ts +143 -0
  326. package/src/core/stores/themeStore.ts +291 -0
  327. package/src/core/stores/toolRegistry.js +227 -0
  328. package/src/core/stores/toolStateStore.js +183 -0
  329. package/src/core/stores/toolStateStore.test.js +220 -0
  330. package/src/core/stores/toolbarConfigStore.js +165 -0
  331. package/src/core/stores/uiConfig.js +64 -0
  332. package/src/core/stores/uiConfig.test.js +63 -0
  333. package/src/core/styles/tailwind.css +204 -0
  334. package/src/core/tools/handlers/autosync.js +12 -0
  335. package/src/core/tools/handlers/canvasAddWidget.js +11 -0
  336. package/src/core/tools/handlers/canvasAgents.js +20 -0
  337. package/src/core/tools/handlers/canvasToolbar.js +56 -0
  338. package/src/core/tools/handlers/commandPalette.js +9 -0
  339. package/src/core/tools/handlers/comments.js +16 -0
  340. package/src/core/tools/handlers/create.js +39 -0
  341. package/src/core/tools/handlers/devtools.js +122 -0
  342. package/src/core/tools/handlers/devtools.test.js +87 -0
  343. package/src/core/tools/handlers/featureFlags.js +21 -0
  344. package/src/core/tools/handlers/flows.js +68 -0
  345. package/src/core/tools/handlers/hideChrome.js +9 -0
  346. package/src/core/tools/handlers/hideToolbars.js +25 -0
  347. package/src/core/tools/handlers/inspector.js +19 -0
  348. package/src/core/tools/handlers/paletteTheme.js +35 -0
  349. package/src/core/tools/handlers/theme.js +9 -0
  350. package/src/core/tools/registry.js +26 -0
  351. package/src/core/tools/surfaces/canvasToolbar.js +10 -0
  352. package/src/core/tools/surfaces/commandList.js +10 -0
  353. package/src/core/tools/surfaces/mainToolbar.js +11 -0
  354. package/src/core/tools/surfaces/registry.js +19 -0
  355. package/src/core/ui/ActionMenuButton.jsx +114 -0
  356. package/src/core/ui/AutosyncMenuButton.css +67 -0
  357. package/src/core/ui/AutosyncMenuButton.jsx +242 -0
  358. package/src/core/ui/BranchSelect.jsx +29 -0
  359. package/src/core/ui/BranchSelect.module.css +30 -0
  360. package/src/core/ui/CanvasAgentsMenu.jsx +89 -0
  361. package/src/core/ui/CanvasCreateMenu.jsx +611 -0
  362. package/src/core/ui/CanvasSnap.css +27 -0
  363. package/src/core/ui/CanvasSnap.jsx +51 -0
  364. package/src/core/ui/CanvasUndoRedo.css +36 -0
  365. package/src/core/ui/CanvasUndoRedo.jsx +62 -0
  366. package/src/core/ui/CanvasZoomControl.css +53 -0
  367. package/src/core/ui/CanvasZoomControl.jsx +49 -0
  368. package/src/core/ui/CanvasZoomToFit.css +18 -0
  369. package/src/core/ui/CanvasZoomToFit.jsx +26 -0
  370. package/src/core/ui/CommandMenu.css +8 -0
  371. package/src/core/ui/CommandMenu.jsx +287 -0
  372. package/src/core/ui/CommandPalette.jsx +35 -0
  373. package/src/core/ui/CommandPaletteTrigger.jsx +25 -0
  374. package/src/core/ui/CommentsMenuButton.jsx +40 -0
  375. package/src/core/ui/CoreUIBar.css +47 -0
  376. package/src/core/ui/CoreUIBar.jsx +905 -0
  377. package/src/core/ui/CreateMenuButton.jsx +117 -0
  378. package/src/core/ui/HideChromeTrigger.jsx +48 -0
  379. package/src/core/ui/Icon.jsx +279 -0
  380. package/src/core/ui/InspectorPanel.css +109 -0
  381. package/src/core/ui/InspectorPanel.jsx +632 -0
  382. package/src/core/ui/PwaInstallBanner.css +42 -0
  383. package/src/core/ui/PwaInstallBanner.jsx +124 -0
  384. package/src/core/ui/SidePanel.jsx +261 -0
  385. package/src/core/ui/ThemeMenuButton.jsx +139 -0
  386. package/src/core/ui/core-ui-colors.css +129 -0
  387. package/src/core/ui/design-modes.ts +7 -0
  388. package/src/core/ui/sidepanel.css +301 -0
  389. package/src/core/ui/viewfinder.ts +7 -0
  390. package/src/core/ui-entry.js +30 -0
  391. package/src/core/utils/fuzzySearch.js +117 -0
  392. package/src/core/utils/fuzzySearch.test.js +119 -0
  393. package/src/core/utils/mobileViewport.js +57 -0
  394. package/src/core/utils/mobileViewport.test.js +68 -0
  395. package/src/core/utils/prodMode.js +38 -0
  396. package/src/core/utils/smoothCorners.js +20 -0
  397. package/src/core/vite/docs-handler.js +155 -0
  398. package/src/core/vite/server-plugin.js +797 -0
  399. package/src/core/workshop/features/createCanvas/CreateCanvasForm.jsx +260 -0
  400. package/src/core/workshop/features/createCanvas/index.js +14 -0
  401. package/src/core/workshop/features/createFlow/CreateFlowForm.jsx +334 -0
  402. package/src/core/workshop/features/createFlow/index.js +19 -0
  403. package/src/core/workshop/features/createFlow/server.js +663 -0
  404. package/src/core/workshop/features/createPage/CreatePageForm.jsx +304 -0
  405. package/src/core/workshop/features/createPage/index.js +11 -0
  406. package/src/core/workshop/features/createPrototype/CreatePrototypeForm.jsx +289 -0
  407. package/src/core/workshop/features/createPrototype/index.js +19 -0
  408. package/src/core/workshop/features/createPrototype/server.js +433 -0
  409. package/src/core/workshop/features/createStory/CreateStoryForm.jsx +208 -0
  410. package/src/core/workshop/features/createStory/index.js +14 -0
  411. package/src/core/workshop/features/registry-server.js +22 -0
  412. package/src/core/workshop/features/registry.js +28 -0
  413. package/src/core/workshop/features/templateIndex.js +155 -0
  414. package/src/core/workshop/ui/WorkshopPanel.jsx +98 -0
  415. package/src/core/workshop/ui/mount.ts +6 -0
  416. package/src/core/worktree/port.js +268 -0
  417. package/src/core/worktree/port.test.js +222 -0
  418. package/src/core/worktree/serverRegistry.js +120 -0
  419. package/src/internals/AuthModal/AuthModal.jsx +132 -0
  420. package/src/internals/AuthModal/AuthModal.module.css +221 -0
  421. package/src/internals/BranchBar/BranchBar.jsx +87 -0
  422. package/src/internals/BranchBar/BranchBar.module.css +247 -0
  423. package/src/internals/BranchBar/useBranches.js +93 -0
  424. package/src/internals/BranchBar/useBranches.test.js +68 -0
  425. package/src/internals/CommandPalette/CommandPalette.jsx +1361 -0
  426. package/src/internals/CommandPalette/CreateDialog.jsx +219 -0
  427. package/src/internals/CommandPalette/command-palette.css +180 -0
  428. package/src/internals/FlowError.module.css +30 -0
  429. package/src/internals/Icon.jsx +279 -0
  430. package/src/internals/StoryboardContext.js +3 -0
  431. package/src/internals/Viewfinder.jsx +1479 -0
  432. package/src/internals/Viewfinder.module.css +1540 -0
  433. package/src/internals/Workspace.jsx +7 -0
  434. package/src/internals/__mocks__/virtual-storyboard-data-index.js +4 -0
  435. package/src/internals/canvas/CanvasControls.jsx +112 -0
  436. package/src/internals/canvas/CanvasControls.module.css +135 -0
  437. package/src/internals/canvas/CanvasPage.bridge.test.jsx +387 -0
  438. package/src/internals/canvas/CanvasPage.dragdrop.test.jsx +350 -0
  439. package/src/internals/canvas/CanvasPage.jsx +3092 -0
  440. package/src/internals/canvas/CanvasPage.module.css +187 -0
  441. package/src/internals/canvas/CanvasPage.multiselect.test.jsx +358 -0
  442. package/src/internals/canvas/CanvasToolbar.jsx +73 -0
  443. package/src/internals/canvas/CanvasToolbar.module.css +92 -0
  444. package/src/internals/canvas/ComponentErrorBoundary.jsx +50 -0
  445. package/src/internals/canvas/ConnectorLayer.jsx +208 -0
  446. package/src/internals/canvas/ConnectorLayer.module.css +129 -0
  447. package/src/internals/canvas/MarqueeOverlay.jsx +20 -0
  448. package/src/internals/canvas/PageSelector.jsx +587 -0
  449. package/src/internals/canvas/PageSelector.module.css +261 -0
  450. package/src/internals/canvas/PageSelector.test.jsx +113 -0
  451. package/src/internals/canvas/WebGLContextPool.jsx +292 -0
  452. package/src/internals/canvas/WebGLContextPool.test.jsx +165 -0
  453. package/src/internals/canvas/canvasApi.js +164 -0
  454. package/src/internals/canvas/canvasReloadGuard.js +37 -0
  455. package/src/internals/canvas/canvasReloadGuard.test.js +27 -0
  456. package/src/internals/canvas/canvasTheme.js +118 -0
  457. package/src/internals/canvas/componentIsolate.jsx +165 -0
  458. package/src/internals/canvas/componentSetIsolate.jsx +257 -0
  459. package/src/internals/canvas/computeCanvasBounds.test.js +121 -0
  460. package/src/internals/canvas/connectorGeometry.js +132 -0
  461. package/src/internals/canvas/hotPoolDevLogs.js +25 -0
  462. package/src/internals/canvas/textSelection.js +10 -0
  463. package/src/internals/canvas/textSelection.test.js +26 -0
  464. package/src/internals/canvas/useCanvas.js +126 -0
  465. package/src/internals/canvas/useCanvas.test.js +26 -0
  466. package/src/internals/canvas/useMarqueeSelect.js +213 -0
  467. package/src/internals/canvas/useMarqueeSelect.test.js +78 -0
  468. package/src/internals/canvas/useUndoRedo.js +86 -0
  469. package/src/internals/canvas/useUndoRedo.test.js +231 -0
  470. package/src/internals/canvas/widgets/CodePenEmbed.jsx +293 -0
  471. package/src/internals/canvas/widgets/CodePenEmbed.module.css +161 -0
  472. package/src/internals/canvas/widgets/ComponentSetWidget.jsx +2 -0
  473. package/src/internals/canvas/widgets/ComponentSetWidget.module.css +89 -0
  474. package/src/internals/canvas/widgets/ComponentWidget.jsx +14 -0
  475. package/src/internals/canvas/widgets/ComponentWidget.module.css +0 -0
  476. package/src/internals/canvas/widgets/CropOverlay.jsx +179 -0
  477. package/src/internals/canvas/widgets/CropOverlay.module.css +154 -0
  478. package/src/internals/canvas/widgets/ExpandedPane.jsx +474 -0
  479. package/src/internals/canvas/widgets/ExpandedPane.module.css +179 -0
  480. package/src/internals/canvas/widgets/ExpandedPane.test.jsx +240 -0
  481. package/src/internals/canvas/widgets/ExpandedPaneTopBar.jsx +111 -0
  482. package/src/internals/canvas/widgets/ExpandedPaneTopBar.module.css +59 -0
  483. package/src/internals/canvas/widgets/ExpandedPaneTopBar.test.jsx +45 -0
  484. package/src/internals/canvas/widgets/FigmaEmbed.jsx +296 -0
  485. package/src/internals/canvas/widgets/FigmaEmbed.module.css +222 -0
  486. package/src/internals/canvas/widgets/FrozenTerminalOverlay.jsx +151 -0
  487. package/src/internals/canvas/widgets/FrozenTerminalOverlay.module.css +83 -0
  488. package/src/internals/canvas/widgets/ImageWidget.jsx +287 -0
  489. package/src/internals/canvas/widgets/ImageWidget.module.css +81 -0
  490. package/src/internals/canvas/widgets/LinkPreview.jsx +439 -0
  491. package/src/internals/canvas/widgets/LinkPreview.module.css +585 -0
  492. package/src/internals/canvas/widgets/LinkPreview.test.jsx +193 -0
  493. package/src/internals/canvas/widgets/MarkdownBlock.jsx +354 -0
  494. package/src/internals/canvas/widgets/MarkdownBlock.module.css +377 -0
  495. package/src/internals/canvas/widgets/MarkdownBlock.test.jsx +92 -0
  496. package/src/internals/canvas/widgets/PromptWidget.jsx +428 -0
  497. package/src/internals/canvas/widgets/PromptWidget.module.css +273 -0
  498. package/src/internals/canvas/widgets/PrototypeEmbed.jsx +463 -0
  499. package/src/internals/canvas/widgets/PrototypeEmbed.module.css +579 -0
  500. package/src/internals/canvas/widgets/PrototypeEmbed.test.jsx +10 -0
  501. package/src/internals/canvas/widgets/ResizeHandle.jsx +67 -0
  502. package/src/internals/canvas/widgets/ResizeHandle.module.css +29 -0
  503. package/src/internals/canvas/widgets/StickyNote.jsx +92 -0
  504. package/src/internals/canvas/widgets/StickyNote.module.css +70 -0
  505. package/src/internals/canvas/widgets/StickyNote.test.jsx +116 -0
  506. package/src/internals/canvas/widgets/StorySetWidget.jsx +208 -0
  507. package/src/internals/canvas/widgets/StorySetWidget.module.css +89 -0
  508. package/src/internals/canvas/widgets/StoryWidget.jsx +334 -0
  509. package/src/internals/canvas/widgets/StoryWidget.module.css +211 -0
  510. package/src/internals/canvas/widgets/TerminalReadWidget.jsx +146 -0
  511. package/src/internals/canvas/widgets/TerminalReadWidget.module.css +94 -0
  512. package/src/internals/canvas/widgets/TerminalWidget.jsx +704 -0
  513. package/src/internals/canvas/widgets/TerminalWidget.module.css +444 -0
  514. package/src/internals/canvas/widgets/TilesWidget.jsx +300 -0
  515. package/src/internals/canvas/widgets/TilesWidget.module.css +133 -0
  516. package/src/internals/canvas/widgets/WidgetChrome.jsx +580 -0
  517. package/src/internals/canvas/widgets/WidgetChrome.module.css +421 -0
  518. package/src/internals/canvas/widgets/WidgetWrapper.jsx +15 -0
  519. package/src/internals/canvas/widgets/WidgetWrapper.module.css +25 -0
  520. package/src/internals/canvas/widgets/codepenUrl.js +75 -0
  521. package/src/internals/canvas/widgets/codepenUrl.test.js +76 -0
  522. package/src/internals/canvas/widgets/embedInteraction.test.jsx +173 -0
  523. package/src/internals/canvas/widgets/embedOverlay.module.css +35 -0
  524. package/src/internals/canvas/widgets/embedTheme.js +148 -0
  525. package/src/internals/canvas/widgets/expandUtils.js +559 -0
  526. package/src/internals/canvas/widgets/expandUtils.test.js +155 -0
  527. package/src/internals/canvas/widgets/figmaUrl.js +118 -0
  528. package/src/internals/canvas/widgets/figmaUrl.test.js +139 -0
  529. package/src/internals/canvas/widgets/githubUrl.js +82 -0
  530. package/src/internals/canvas/widgets/githubUrl.test.js +74 -0
  531. package/src/internals/canvas/widgets/iframeDevLogs.js +49 -0
  532. package/src/internals/canvas/widgets/iframeDevLogs.test.jsx +81 -0
  533. package/src/internals/canvas/widgets/index.js +42 -0
  534. package/src/internals/canvas/widgets/pasteRules.js +295 -0
  535. package/src/internals/canvas/widgets/pasteRules.test.js +474 -0
  536. package/src/internals/canvas/widgets/snapshotDisplay.test.jsx +211 -0
  537. package/src/internals/canvas/widgets/tilePool.js +23 -0
  538. package/src/internals/canvas/widgets/tiles/diagonal-bl.png +0 -0
  539. package/src/internals/canvas/widgets/tiles/diagonal-br.png +0 -0
  540. package/src/internals/canvas/widgets/tiles/diagonal-tl.png +0 -0
  541. package/src/internals/canvas/widgets/tiles/leaf.png +0 -0
  542. package/src/internals/canvas/widgets/tiles/quarter-tl.png +0 -0
  543. package/src/internals/canvas/widgets/tiles/quarter-tr.png +0 -0
  544. package/src/internals/canvas/widgets/tiles/solid-a.png +0 -0
  545. package/src/internals/canvas/widgets/tiles/solid-b.png +0 -0
  546. package/src/internals/canvas/widgets/widgetConfig.js +291 -0
  547. package/src/internals/canvas/widgets/widgetConfig.test.js +68 -0
  548. package/src/internals/canvas/widgets/widgetIcons.jsx +190 -0
  549. package/src/internals/canvas/widgets/widgetProps.js +133 -0
  550. package/src/internals/context/FormContext.js +13 -0
  551. package/src/internals/context/FormContext.test.js +48 -0
  552. package/src/internals/context.jsx +481 -0
  553. package/src/internals/context.test.jsx +296 -0
  554. package/src/internals/hashPreserver.js +73 -0
  555. package/src/internals/hashPreserver.test.js +107 -0
  556. package/src/internals/hooks/useConfig.js +14 -0
  557. package/src/internals/hooks/useFeatureFlag.js +14 -0
  558. package/src/internals/hooks/useFlows.js +50 -0
  559. package/src/internals/hooks/useFlows.test.js +134 -0
  560. package/src/internals/hooks/useHideMode.js +31 -0
  561. package/src/internals/hooks/useHideMode.test.js +43 -0
  562. package/src/internals/hooks/useLocalStorage.js +57 -0
  563. package/src/internals/hooks/useLocalStorage.test.js +75 -0
  564. package/src/internals/hooks/useMode.js +43 -0
  565. package/src/internals/hooks/useObject.js +101 -0
  566. package/src/internals/hooks/useObject.test.js +74 -0
  567. package/src/internals/hooks/useOverride.js +84 -0
  568. package/src/internals/hooks/useOverride.test.js +71 -0
  569. package/src/internals/hooks/usePrototypeReloadGuard.js +64 -0
  570. package/src/internals/hooks/useRecord.js +158 -0
  571. package/src/internals/hooks/useRecord.test.js +221 -0
  572. package/src/internals/hooks/useScene.js +38 -0
  573. package/src/internals/hooks/useScene.test.js +66 -0
  574. package/src/internals/hooks/useSceneData.js +108 -0
  575. package/src/internals/hooks/useSceneData.test.js +136 -0
  576. package/src/internals/hooks/useSession.js +4 -0
  577. package/src/internals/hooks/useSession.test.js +8 -0
  578. package/src/internals/hooks/useThemeState.js +61 -0
  579. package/src/internals/hooks/useThemeState.test.js +66 -0
  580. package/src/internals/hooks/useUndoRedo.js +28 -0
  581. package/src/internals/hooks/useUndoRedo.test.js +64 -0
  582. package/src/internals/index.js +58 -0
  583. package/src/internals/story/ComponentSetPage.jsx +198 -0
  584. package/src/internals/story/ComponentSetPage.module.css +129 -0
  585. package/src/internals/story/StoryPage.jsx +147 -0
  586. package/src/internals/story/StoryPage.module.css +18 -0
  587. package/src/internals/test-utils.js +45 -0
  588. package/src/internals/vite/data-plugin.js +1508 -0
  589. package/src/internals/vite/data-plugin.test.js +1223 -0
  590. package/src/test-utils.js +44 -0
  591. package/toolbar.config.json +271 -0
  592. package/widgets.config.json +1537 -0
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Devtools tool module — developer utilities submenu.
3
+ *
4
+ * Renders as a submenu in the command menu with:
5
+ * - Show flow info
6
+ * - Reset all params
7
+ * - Hide mode toggle
8
+ * - Logout (when authenticated)
9
+ */
10
+ export const id = 'devtools'
11
+
12
+ /**
13
+ * @param {object} ctx
14
+ * @param {Function} ctx.showFlowInfoDialog - callback to open flow info dialog
15
+ */
16
+ export async function handler(ctx) {
17
+ let loader = null
18
+ let hm = null
19
+ let commentsAuth = null
20
+ let prodMode = null
21
+ let ff = null
22
+ try { loader = await import('../../index.js') } catch { /* optional */ }
23
+ try { hm = await import('../../index.js') } catch { /* optional */ }
24
+ try { commentsAuth = await import('../../comments/auth.js') } catch { /* optional */ }
25
+ try { prodMode = await import('../../utils/prodMode.js') } catch { /* optional */ }
26
+ try { ff = await import('../../index.js') } catch { /* optional */ }
27
+
28
+ return {
29
+ getChildren: () => {
30
+ const children = []
31
+ const canToggleProdMode = prodMode
32
+ && typeof window !== 'undefined'
33
+ && window.__SB_LOCAL_DEV__ === true
34
+
35
+ if (canToggleProdMode) {
36
+ children.push({
37
+ id: 'core/prod-mode',
38
+ label: 'Production mode',
39
+ type: 'toggle',
40
+ active: prodMode.isProdMode(),
41
+ execute: () => { prodMode.toggleProdMode() },
42
+ })
43
+ }
44
+ if (loader) {
45
+ children.push({
46
+ id: 'core/show-flow-info',
47
+ label: 'Show flow info',
48
+ type: 'default',
49
+ execute: () => {
50
+ const p = new URLSearchParams(window.location.search)
51
+ const name = p.get('flow') || p.get('scene') || 'default'
52
+ try {
53
+ const data = loader.loadFlow(name)
54
+ if (ctx.showFlowInfoDialog) {
55
+ ctx.showFlowInfoDialog(name, JSON.stringify(data, null, 2), null)
56
+ }
57
+ } catch (e) {
58
+ if (ctx.showFlowInfoDialog) {
59
+ ctx.showFlowInfoDialog(name, '', e.message)
60
+ }
61
+ }
62
+ },
63
+ })
64
+ }
65
+ children.push({
66
+ id: 'core/reset-params',
67
+ label: 'Reset all params',
68
+ type: 'default',
69
+ execute: () => { window.location.hash = '' },
70
+ })
71
+ if (hm) {
72
+ children.push({
73
+ id: 'core/hide-mode',
74
+ label: 'Hide mode',
75
+ type: 'toggle',
76
+ active: hm.isHideMode(),
77
+ execute: () => {
78
+ if (hm.isHideMode()) hm.deactivateHideMode()
79
+ else hm.activateHideMode()
80
+ },
81
+ })
82
+ }
83
+ if (commentsAuth?.isAuthenticated()) {
84
+ children.push({
85
+ id: 'core/logout',
86
+ label: 'Logout (remove token)',
87
+ type: 'default',
88
+ execute: () => {
89
+ commentsAuth.clearToken()
90
+ console.log('[storyboard] Token removed')
91
+ },
92
+ })
93
+ }
94
+ if (ff) {
95
+ children.push({
96
+ id: 'core/dev-logs',
97
+ label: 'Dev logs',
98
+ type: 'toggle',
99
+ active: ff.getFlag('dev-logs'),
100
+ execute: () => { ff.toggleFlag('dev-logs') },
101
+ })
102
+ }
103
+ if (ff) {
104
+ children.push({
105
+ id: 'core/canvas-auto-reload',
106
+ label: 'Canvas auto-reload',
107
+ type: 'toggle',
108
+ active: ff.getFlag('canvas-auto-reload'),
109
+ execute: () => { ff.toggleFlag('canvas-auto-reload') },
110
+ })
111
+ children.push({
112
+ id: 'core/prototype-auto-reload',
113
+ label: 'Prototype auto-reload',
114
+ type: 'toggle',
115
+ active: ff.getFlag('prototype-auto-reload'),
116
+ execute: () => { ff.toggleFlag('prototype-auto-reload') },
117
+ })
118
+ }
119
+ return children
120
+ },
121
+ }
122
+ }
@@ -0,0 +1,87 @@
1
+ import { handler as createDevtoolsHandler } from './devtools.js'
2
+
3
+ function getProdModeItem(children) {
4
+ return children.find(item => item.id === 'core/prod-mode')
5
+ }
6
+
7
+ function getCanvasAutoReloadItem(children) {
8
+ return children.find(item => item.id === 'core/canvas-auto-reload')
9
+ }
10
+
11
+ function getPrototypeAutoReloadItem(children) {
12
+ return children.find(item => item.id === 'core/prototype-auto-reload')
13
+ }
14
+
15
+ describe('devtools production mode toggle', () => {
16
+ const originalLocalDev = window.__SB_LOCAL_DEV__
17
+
18
+ beforeEach(() => {
19
+ window.history.replaceState({}, '', '/')
20
+ delete window.__SB_LOCAL_DEV__
21
+ })
22
+
23
+ afterAll(() => {
24
+ if (typeof originalLocalDev === 'undefined') delete window.__SB_LOCAL_DEV__
25
+ else window.__SB_LOCAL_DEV__ = originalLocalDev
26
+ })
27
+
28
+ it('shows the toggle in local dev', async () => {
29
+ window.__SB_LOCAL_DEV__ = true
30
+
31
+ const devtools = await createDevtoolsHandler({})
32
+ const prodModeItem = getProdModeItem(devtools.getChildren())
33
+
34
+ expect(prodModeItem).toBeTruthy()
35
+ expect(prodModeItem.active).toBe(false)
36
+ })
37
+
38
+ it('shows the toggle as active in local-dev prodMode simulation', async () => {
39
+ window.__SB_LOCAL_DEV__ = true
40
+ window.history.replaceState({}, '', '/?prodMode')
41
+
42
+ const devtools = await createDevtoolsHandler({})
43
+ const prodModeItem = getProdModeItem(devtools.getChildren())
44
+
45
+ expect(prodModeItem).toBeTruthy()
46
+ expect(prodModeItem.active).toBe(true)
47
+ })
48
+
49
+ it('hides the toggle in true production mode', async () => {
50
+ window.__SB_LOCAL_DEV__ = false
51
+
52
+ const devtools = await createDevtoolsHandler({})
53
+ const prodModeItem = getProdModeItem(devtools.getChildren())
54
+
55
+ expect(prodModeItem).toBeUndefined()
56
+ })
57
+ })
58
+
59
+ describe('devtools canvas auto-reload toggle', () => {
60
+ beforeEach(() => {
61
+ window.history.replaceState({}, '', '/')
62
+ })
63
+
64
+ it('shows the toggle as inactive by default (guard ON)', async () => {
65
+ const devtools = await createDevtoolsHandler({})
66
+ const item = getCanvasAutoReloadItem(devtools.getChildren())
67
+
68
+ expect(item).toBeTruthy()
69
+ expect(item.type).toBe('toggle')
70
+ expect(item.active).toBe(false)
71
+ })
72
+ })
73
+
74
+ describe('devtools prototype auto-reload toggle', () => {
75
+ beforeEach(() => {
76
+ window.history.replaceState({}, '', '/')
77
+ })
78
+
79
+ it('shows the toggle as active by default (reloads enabled)', async () => {
80
+ const devtools = await createDevtoolsHandler({})
81
+ const item = getPrototypeAutoReloadItem(devtools.getChildren())
82
+
83
+ expect(item).toBeTruthy()
84
+ expect(item.type).toBe('toggle')
85
+ expect(item.active).toBe(true)
86
+ })
87
+ })
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Feature Flags tool module — toggle feature flags submenu.
3
+ *
4
+ * Renders as a submenu in the command menu listing all declared flags.
5
+ */
6
+ export const id = 'feature-flags'
7
+
8
+ export async function handler() {
9
+ const ff = await import('../../index.js')
10
+
11
+ return {
12
+ getChildren: () =>
13
+ ff.getFlagKeys().map(key => ({
14
+ id: `flags/${key}`,
15
+ label: key,
16
+ type: 'toggle',
17
+ active: ff.getFlag(key),
18
+ execute: () => ff.toggleFlag(key),
19
+ })),
20
+ }
21
+ }
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Flows tool module — flow switcher action menu.
3
+ *
4
+ * Registers a command action handler that lists available flows
5
+ * for the current prototype and lets users switch between them.
6
+ */
7
+ export const id = 'flows'
8
+
9
+ export async function handler(ctx) {
10
+ const loader = await import('../../index.js')
11
+ const vf = loader
12
+ const { basePath = '/' } = ctx
13
+
14
+ return {
15
+ getChildren: () => {
16
+ let path = window.location.pathname
17
+ const base = basePath.replace(/\/+$/, '')
18
+ if (base && path.startsWith(base)) path = path.slice(base.length)
19
+ path = path.replace(/\/+$/, '') || '/'
20
+ const segments = path.split('/').filter(Boolean)
21
+
22
+ // Detect and preserve branch-- segment on deployed branch builds
23
+ const branchSegment = (segments[0] && segments[0].startsWith('branch--')) ? segments[0] : null
24
+ const protoIdx = branchSegment ? 1 : 0
25
+ const proto = segments[protoIdx] || null
26
+ if (!proto) return []
27
+
28
+ const params = new URLSearchParams(window.location.search)
29
+ const explicit = params.get('flow') || params.get('scene')
30
+ let active
31
+ if (explicit) {
32
+ active = loader.resolveFlowName(proto, explicit)
33
+ } else {
34
+ const pageFlow = path === '/' ? 'index' : (path.split('/').pop() || 'index')
35
+ const scoped = loader.resolveFlowName(proto, pageFlow)
36
+ if (loader.flowExists(scoped)) active = scoped
37
+ else {
38
+ const protoFlow = loader.resolveFlowName(proto, proto)
39
+ active = loader.flowExists(protoFlow) ? protoFlow : 'default'
40
+ }
41
+ }
42
+
43
+ const flows = loader.getFlowsForPrototype(proto)
44
+ if (flows.length <= 1) return []
45
+
46
+ return flows.map(f => {
47
+ const meta = vf.getFlowMeta(f.key)
48
+ let url = vf.resolveFlowRoute(f.key)
49
+ // Re-apply basePath and branch-- prefix so deployed branch builds stay on the correct path
50
+ const prefix = (base || '') + (branchSegment ? `/${branchSegment}` : '')
51
+ if (prefix) url = prefix + url
52
+ return {
53
+ id: f.key,
54
+ label: meta?.title || f.name,
55
+ type: 'radio',
56
+ active: f.key === active,
57
+ href: url,
58
+ execute: () => { window.location.href = url },
59
+ }
60
+ })
61
+ },
62
+ }
63
+ }
64
+
65
+ export async function component() {
66
+ const mod = await import('../../ui/ActionMenuButton.jsx')
67
+ return mod.default
68
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Hide Chrome tool — toolbar button that toggles toolbar/branch bar visibility.
3
+ */
4
+ export const id = 'hide-chrome'
5
+
6
+ export async function component() {
7
+ const mod = await import('../../ui/HideChromeTrigger.jsx')
8
+ return mod.default
9
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Hide/Show toolbars tool — command palette only.
3
+ *
4
+ * Toggles the `storyboard-chrome-hidden` class (same as Cmd+.).
5
+ * Label flips between "Hide toolbars" and "Show toolbars" based on state.
6
+ */
7
+ export const id = 'hide-toolbars'
8
+
9
+ export async function handler() {
10
+ return {
11
+ getChildren() {
12
+ const hidden = document.documentElement.classList.contains('storyboard-chrome-hidden')
13
+ return [{
14
+ id: 'core/toggle-toolbars',
15
+ label: hidden ? 'Show toolbars' : 'Hide toolbars',
16
+ type: 'default',
17
+ execute: () => {
18
+ const isHidden = document.documentElement.classList.contains('storyboard-chrome-hidden')
19
+ document.documentElement.classList.toggle('storyboard-chrome-hidden', !isHidden)
20
+ document.documentElement.classList.remove('storyboard-chrome-completely-hidden')
21
+ },
22
+ }]
23
+ },
24
+ }
25
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Inspector tool module — component inspector sidepanel.
3
+ *
4
+ * Auto-opens the panel if ?inspect= is in the URL.
5
+ */
6
+ export const id = 'inspector'
7
+
8
+ export async function setup() {
9
+ const { openPanel } = await import('../../stores/sidePanelStore.js')
10
+
11
+ try {
12
+ const inspectParam = new URL(window.location.href).searchParams.get('inspect')
13
+ if (inspectParam) {
14
+ openPanel('inspector')
15
+ }
16
+ } catch { /* ignore */ }
17
+ }
18
+
19
+ // No component needed — sidepanel tools use generic TriggerButton
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Palette Theme tool — theme submenu for the command palette.
3
+ *
4
+ * Returns theme options as children, plus a "Theme settings" entry
5
+ * that opens the toolbar Theme menu with the settings submenu expanded.
6
+ */
7
+ export const id = 'palette-theme'
8
+
9
+ export async function handler() {
10
+ const { themeState, setTheme, THEMES } = await import('../../index.js')
11
+
12
+ return {
13
+ getChildren() {
14
+ const current = themeState.theme
15
+ return [
16
+ // Theme options
17
+ ...THEMES.map(t => ({
18
+ id: `theme:${t.value}`,
19
+ label: t.name,
20
+ type: 'toggle',
21
+ active: current === t.value,
22
+ execute: () => setTheme(t.value),
23
+ })),
24
+ // "Theme settings" opens the toolbar theme menu at the settings submenu
25
+ {
26
+ id: 'theme:settings',
27
+ label: 'Theme settings',
28
+ execute: () => {
29
+ document.dispatchEvent(new CustomEvent('storyboard:open-theme-settings'))
30
+ },
31
+ },
32
+ ]
33
+ },
34
+ }
35
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Theme tool module — theme switcher menu.
3
+ */
4
+ export const id = 'theme'
5
+
6
+ export async function component() {
7
+ const mod = await import('../../ui/ThemeMenuButton.jsx')
8
+ return mod.default
9
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Tool module registry — maps tool IDs to lazy-loaded handler modules.
3
+ *
4
+ * Each handler module exports: { id, component?, handler?, setup?, guard? }
5
+ * All imports are dynamic to enable code splitting.
6
+ */
7
+ export const coreHandlers = {
8
+ create: () => import('./handlers/create.js'),
9
+ theme: () => import('./handlers/theme.js'),
10
+ 'palette-theme': () => import('./handlers/paletteTheme.js'),
11
+ comments: () => import('./handlers/comments.js'),
12
+ flows: () => import('./handlers/flows.js'),
13
+ inspector: () => import('./handlers/inspector.js'),
14
+ devtools: () => import('./handlers/devtools.js'),
15
+ 'feature-flags': () => import('./handlers/featureFlags.js'),
16
+ autosync: () => import('./handlers/autosync.js'),
17
+ 'canvas-add-widget': () => import('./handlers/canvasAddWidget.js'),
18
+ 'canvas-agents': () => import('./handlers/canvasAgents.js'),
19
+ 'canvas-toolbar': () => import('./handlers/canvasToolbar.js'),
20
+ 'hide-toolbars': () => import('./handlers/hideToolbars.js'),
21
+ 'command-palette': () => import('./handlers/commandPalette.js'),
22
+ 'hide-chrome': () => import('./handlers/hideChrome.js'),
23
+ }
24
+
25
+ // Keep legacy export name for backward compatibility
26
+ export const toolModules = coreHandlers
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Canvas Toolbar surface — floating bar at bottom-left on canvas pages.
3
+ *
4
+ * Only visible when a canvas page is active. Supports menus and
5
+ * custom render types like zoom-control.
6
+ */
7
+ export const id = 'canvas-toolbar'
8
+ export const label = 'Canvas Toolbar'
9
+ export const position = 'bottom-left'
10
+ export const renderTypes = ['menu', 'zoom-control']
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Command Palette surface — items rendered inside the ⌘K command palette.
3
+ *
4
+ * Tools here appear as menu items, submenus, or links within
5
+ * the command palette. They don't render as standalone buttons.
6
+ */
7
+ export const id = 'command-palette'
8
+ export const label = 'Command Palette'
9
+ export const position = 'overlay'
10
+ export const renderTypes = ['link', 'submenu']
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Command Toolbar surface — the primary floating bar at bottom-right.
3
+ *
4
+ * Supports all standard render types. Tools appear in reverse JSON order
5
+ * (first in config = leftmost in toolbar). The command menu button is
6
+ * always the rightmost item and is not a tool.
7
+ */
8
+ export const id = 'command-toolbar'
9
+ export const label = 'Command Toolbar'
10
+ export const position = 'bottom-right'
11
+ export const renderTypes = ['button', 'menu', 'sidepanel', 'separator']
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Surface registry — exports all available rendering surfaces.
3
+ *
4
+ * Surfaces define WHERE a tool renders. Each surface has a position,
5
+ * supported render types, and rendering logic in CoreUIBar.
6
+ *
7
+ * To add a new surface:
8
+ * 1. Create a definition file in this directory
9
+ * 2. Export it from this registry
10
+ * 3. Add rendering logic in CoreUIBar.jsx
11
+ */
12
+ export { id as commandToolbar } from './mainToolbar.js'
13
+ export { id as canvasToolbar } from './canvasToolbar.js'
14
+ export { id as commandPalette } from './commandList.js'
15
+
16
+ /**
17
+ * All surface IDs for validation.
18
+ */
19
+ export const SURFACE_IDS = ['command-toolbar', 'canvas-toolbar', 'command-palette']
@@ -0,0 +1,114 @@
1
+ import { useState, useEffect, useCallback } from 'react'
2
+ import { TriggerButton } from '../lib/components/ui/trigger-button/index.js'
3
+ import * as DropdownMenu from '../lib/components/ui/dropdown-menu/index.js'
4
+ import Icon from './Icon.jsx'
5
+ import { getActionChildren, subscribeToCommandActions } from '../index.js'
6
+
7
+ export default function ActionMenuButton({ config = {}, data: _data, localOnly: _localOnly, tabindex = -1 }) {
8
+ void _data
9
+ void _localOnly
10
+ const [menuOpen, setMenuOpen] = useState(false)
11
+ const [_actionsVersion, setActionsVersion] = useState(0)
12
+ void _actionsVersion
13
+
14
+ useEffect(() => {
15
+ const unsub = subscribeToCommandActions(() => { setActionsVersion((v) => v + 1) })
16
+ return unsub
17
+ }, [])
18
+
19
+ // Allow external callers (e.g. command palette) to open this menu
20
+ useEffect(() => {
21
+ const actionId = config.action
22
+ if (!actionId) return
23
+ function onTrigger(e) {
24
+ if (e.detail?.action === actionId) setMenuOpen(true)
25
+ }
26
+ window.addEventListener('storyboard:open-tool-menu', onTrigger)
27
+ return () => window.removeEventListener('storyboard:open-tool-menu', onTrigger)
28
+ }, [config.action])
29
+
30
+ const children = config.action ? getActionChildren(config.action) : []
31
+ const hasRadio = children.some((c) => c.type === 'radio')
32
+ const activeValue = children.find((c) => c.type === 'radio' && c.active)?.id || ''
33
+
34
+ const handleOpenChange = useCallback((open) => {
35
+ setMenuOpen(open)
36
+ if (open) setActionsVersion((v) => v + 1)
37
+ }, [])
38
+
39
+ if (children.length === 0) return null
40
+
41
+ return (
42
+ <DropdownMenu.Root open={menuOpen} onOpenChange={handleOpenChange}>
43
+ <DropdownMenu.Trigger>
44
+ <TriggerButton
45
+ active={menuOpen}
46
+ size="icon-xl"
47
+ aria-label={config.ariaLabel || config.label || 'Menu'}
48
+ tabIndex={tabindex}
49
+ >
50
+ <Icon name={config.icon || 'primer/gear'} size={16} {...(config.meta || {})} />
51
+ </TriggerButton>
52
+ </DropdownMenu.Trigger>
53
+
54
+ <DropdownMenu.Content
55
+ side="top"
56
+ align="end"
57
+ sideOffset={16}
58
+ style={config.menuWidth ? { minWidth: config.menuWidth } : undefined}
59
+ className={config.menuWidth ? '' : 'min-w-[200px]'}
60
+ >
61
+ {config.label && <DropdownMenu.Label>{config.label}</DropdownMenu.Label>}
62
+
63
+ {hasRadio ? (
64
+ <DropdownMenu.RadioGroup value={activeValue}>
65
+ {children.map((child) => {
66
+ if (child.type !== 'radio') return null
67
+ return (
68
+ <DropdownMenu.RadioItem
69
+ key={child.id || child.label}
70
+ value={child.id}
71
+ onClick={(e) => {
72
+ if (child.href && (e.metaKey || e.ctrlKey)) {
73
+ e.preventDefault(); window.open(child.href, '_blank'); setMenuOpen(false); return
74
+ }
75
+ if (child.execute) child.execute(); setMenuOpen(false)
76
+ }}
77
+ >
78
+ {child.label}
79
+ </DropdownMenu.RadioItem>
80
+ )
81
+ })}
82
+ </DropdownMenu.RadioGroup>
83
+ ) : (
84
+ children.map((child) => {
85
+ if (child.type === 'toggle') {
86
+ return (
87
+ <DropdownMenu.CheckboxItem
88
+ key={child.id || child.label}
89
+ checked={child.active}
90
+ onSelect={(e) => { e.preventDefault(); if (child.execute) child.execute(); setActionsVersion((v) => v + 1) }}
91
+ >
92
+ {child.label}
93
+ </DropdownMenu.CheckboxItem>
94
+ )
95
+ }
96
+ return (
97
+ <DropdownMenu.Item
98
+ key={child.id || child.label}
99
+ onClick={(e) => {
100
+ if (child.href && (e.metaKey || e.ctrlKey)) {
101
+ e.preventDefault(); window.open(child.href, '_blank'); setMenuOpen(false); return
102
+ }
103
+ if (child.execute) child.execute(); setMenuOpen(false)
104
+ }}
105
+ >
106
+ {child.label}
107
+ </DropdownMenu.Item>
108
+ )
109
+ })
110
+ )}
111
+ </DropdownMenu.Content>
112
+ </DropdownMenu.Root>
113
+ )
114
+ }
@@ -0,0 +1,67 @@
1
+ .menuTitle {
2
+ font-size: 13px;
3
+ font-weight: 500;
4
+ color: var(--fgColor-default, #e6edf3);
5
+ padding: 6px 6px 0;
6
+ margin: 0;
7
+ }
8
+
9
+ .description {
10
+ font-size: 12px;
11
+ color: var(--fgColor-muted, #848d97);
12
+ padding: 0 6px 4px;
13
+ margin: 0;
14
+ line-height: 1.4;
15
+ }
16
+
17
+ .branchRow {
18
+ display: flex;
19
+ flex-direction: column;
20
+ gap: 6px;
21
+ padding: 6px 6px;
22
+ }
23
+
24
+ .branchLabel {
25
+ font-size: 13px;
26
+ font-weight: 500;
27
+ color: var(--fgColor-default, #e6edf3);
28
+ }
29
+
30
+ .statusRow {
31
+ padding: 4px 6px 2px;
32
+ }
33
+
34
+ .scopeHint {
35
+ font-size: 11px;
36
+ color: var(--fgColor-muted, #848d97);
37
+ padding: 4px 0;
38
+ margin: 0;
39
+ }
40
+
41
+ .statusError {
42
+ font-size: 11px;
43
+ color: var(--fgColor-danger, #f85149);
44
+ }
45
+
46
+ .statusOk {
47
+ font-size: 11px;
48
+ color: var(--fgColor-muted, #848d97);
49
+ }
50
+
51
+ .footer {
52
+ display: flex;
53
+ align-items: center;
54
+ gap: 6px;
55
+ font-size: 12px;
56
+ color: var(--fgColor-muted, #848d97);
57
+ padding: 2px 6px 0;
58
+ margin: 0;
59
+ }
60
+
61
+ .footerDot {
62
+ width: 8px;
63
+ height: 8px;
64
+ background: hsl(212, 92%, 45%);
65
+ border-radius: 50%;
66
+ flex-shrink: 0;
67
+ }