@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,301 @@
1
+ /**
2
+ * Side Panel — push layout styles.
3
+ *
4
+ * When the side panel is open, an `sb-sidepanel-open` class is added to <html>.
5
+ * When docked to bottom, `sb-sidepanel-bottom` is also added.
6
+ * These rules push the main content and floating UI elements to make space
7
+ * for the panel.
8
+ */
9
+
10
+ :root {
11
+ --sb--sidepanel-width: 420px;
12
+ --sb--sidepanel-height: 300px;
13
+ }
14
+
15
+ /* -----------------------------------------------------------------------
16
+ Side panel (default) — push content right
17
+ ----------------------------------------------------------------------- */
18
+
19
+ html.sb-sidepanel-open:not(.sb-sidepanel-bottom) > body > #root {
20
+ margin-right: var(--sb--sidepanel-width);
21
+ transition: margin-right 0.25s ease;
22
+ }
23
+
24
+ /* When a mode collar is active, account for the 12px gap around the panel */
25
+ html.sb-sidepanel-open:not(.sb-sidepanel-bottom).storyboard-mode-present > body > #root,
26
+ html.sb-sidepanel-open:not(.sb-sidepanel-bottom).storyboard-mode-plan > body > #root,
27
+ html.sb-sidepanel-open:not(.sb-sidepanel-bottom).storyboard-mode-inspect > body > #root {
28
+ margin-right: calc(var(--sb--sidepanel-width) + 12px);
29
+ }
30
+
31
+ html:not(.sb-sidepanel-open) > body > #root {
32
+ transition: margin-right 0.25s ease, margin-bottom 0.25s ease;
33
+ }
34
+
35
+ /* Push the CoreUIBar (fixed bottom-right) — side mode */
36
+ html.sb-sidepanel-open:not(.sb-sidepanel-bottom) [data-core-ui-bar] {
37
+ right: calc(var(--sb--sidepanel-width) + 24px) !important;
38
+ transition: right 0.25s ease;
39
+ }
40
+
41
+ html:not(.sb-sidepanel-open) [data-core-ui-bar] {
42
+ transition: right 0.25s ease, bottom 0.25s ease;
43
+ }
44
+
45
+ /* Push the ModeSwitch (fixed bottom-center) — side mode */
46
+ html.sb-sidepanel-open:not(.sb-sidepanel-bottom) .sb-mode-switch {
47
+ transform: translateX(calc(-50% - var(--sb--sidepanel-width) / 2));
48
+ transition: transform 0.25s ease;
49
+ }
50
+
51
+ html:not(.sb-sidepanel-open) .sb-mode-switch {
52
+ transition: transform 0.25s ease, bottom 0.25s ease;
53
+ }
54
+
55
+ /* When both modes collar padding AND sidepanel are active,
56
+ the collar bottom bar should not extend under the panel + its right gap */
57
+ html.sb-sidepanel-open:not(.sb-sidepanel-bottom)::before {
58
+ width: calc(100vw - var(--sb--sidepanel-width) - 12px);
59
+ }
60
+
61
+ /* -----------------------------------------------------------------------
62
+ Bottom panel — push content down
63
+ ----------------------------------------------------------------------- */
64
+
65
+ html.sb-sidepanel-open.sb-sidepanel-bottom > body > #root {
66
+ margin-bottom: var(--sb--sidepanel-height);
67
+ transition: margin-bottom 0.25s ease;
68
+ }
69
+
70
+ /* Mode collar + bottom panel */
71
+ html.sb-sidepanel-open.sb-sidepanel-bottom.storyboard-mode-present > body > #root,
72
+ html.sb-sidepanel-open.sb-sidepanel-bottom.storyboard-mode-plan > body > #root,
73
+ html.sb-sidepanel-open.sb-sidepanel-bottom.storyboard-mode-inspect > body > #root {
74
+ margin-bottom: calc(var(--sb--sidepanel-height) + 12px);
75
+ }
76
+
77
+ /* Push the CoreUIBar up — bottom mode */
78
+ html.sb-sidepanel-open.sb-sidepanel-bottom [data-core-ui-bar] {
79
+ bottom: calc(var(--sb--sidepanel-height) + 24px) !important;
80
+ transition: bottom 0.25s ease;
81
+ }
82
+
83
+ /* Push the ModeSwitch up — bottom mode */
84
+ html.sb-sidepanel-open.sb-sidepanel-bottom .sb-mode-switch {
85
+ bottom: calc(var(--sb--sidepanel-height) + 24px);
86
+ transition: bottom 0.25s ease;
87
+ }
88
+
89
+ /* -----------------------------------------------------------------------
90
+ Panel element styles (migrated from scoped styles)
91
+ ----------------------------------------------------------------------- */
92
+
93
+ .sb-sidepanel {
94
+ position: fixed;
95
+ top: var(--sb-branch-bar-height, 0px);
96
+ right: 0;
97
+ bottom: 0;
98
+ width: var(--sb--sidepanel-width, 420px);
99
+ z-index: 9998;
100
+ display: flex;
101
+ flex-direction: column;
102
+ background-color: var(--bgColor-default, var(--sb--color-background, #ffffff));
103
+ border-left: 1px solid var(--borderColor-default, var(--sb--color-border, #d0d7de));
104
+ box-shadow: -4px 0 24px rgba(0, 0, 0, 0.15);
105
+ font-family: "Mona Sans", -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
106
+ color: var(--fgColor-default, var(--sb--color-foreground, #1f2328));
107
+ animation: sb-sidepanel-slide-in 0.25s ease;
108
+ }
109
+
110
+ .sb-sidepanel--bottom {
111
+ top: auto;
112
+ right: 0;
113
+ bottom: 0;
114
+ left: 0;
115
+ width: 100% !important;
116
+ height: var(--sb--sidepanel-height, 300px);
117
+ border-left: none;
118
+ border-top: 1px solid var(--borderColor-default, var(--sb--color-border, #d0d7de));
119
+ box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.15);
120
+ animation: sb-sidepanel-slide-up 0.25s ease;
121
+ }
122
+
123
+ .sb-sidepanel-dragging {
124
+ user-select: none;
125
+ }
126
+
127
+ @keyframes sb-sidepanel-slide-in {
128
+ from { transform: translateX(100%); }
129
+ to { transform: translateX(0); }
130
+ }
131
+
132
+ @keyframes sb-sidepanel-slide-up {
133
+ from { transform: translateY(100%); }
134
+ to { transform: translateY(0); }
135
+ }
136
+
137
+ /* Mode-aware top accent bar */
138
+ .sb-sidepanel::before {
139
+ content: '';
140
+ position: absolute;
141
+ top: 0;
142
+ left: 0;
143
+ right: 0;
144
+ height: 3px;
145
+ }
146
+
147
+ /* Drag handle — side mode (left edge, vertical) */
148
+ .sb-sidepanel-drag-handle {
149
+ position: absolute;
150
+ top: 0;
151
+ left: -4px;
152
+ bottom: 0;
153
+ width: 8px;
154
+ cursor: col-resize;
155
+ z-index: 1;
156
+ display: flex;
157
+ align-items: center;
158
+ justify-content: center;
159
+ }
160
+
161
+ /* Drag handle — bottom mode (top edge, horizontal) */
162
+ .sb-sidepanel--bottom .sb-sidepanel-drag-handle {
163
+ top: -4px;
164
+ left: 0;
165
+ right: 0;
166
+ bottom: auto;
167
+ width: 100%;
168
+ height: 8px;
169
+ cursor: row-resize;
170
+ }
171
+
172
+ .sb-sidepanel-grabber {
173
+ opacity: 0;
174
+ color: rgba(0, 0, 0, 0.5);
175
+ transition: opacity 0.15s ease;
176
+ pointer-events: none;
177
+ }
178
+
179
+ .sb-sidepanel--bottom .sb-sidepanel-grabber {
180
+ transform: rotate(90deg);
181
+ }
182
+
183
+ .sb-sidepanel-drag-handle:hover .sb-sidepanel-grabber,
184
+ .sb-sidepanel-dragging .sb-sidepanel-grabber {
185
+ opacity: 1;
186
+ }
187
+
188
+ /* Header */
189
+ .sb-sidepanel-header {
190
+ display: flex;
191
+ align-items: center;
192
+ justify-content: space-between;
193
+ padding: 8px 8px 0;
194
+ flex-shrink: 0;
195
+ }
196
+
197
+ .sb-sidepanel-title {
198
+ font-size: 11px;
199
+ font-weight: 600;
200
+ text-transform: uppercase;
201
+ letter-spacing: 0.05em;
202
+ color: var(--fgColor-muted, var(--sb--color-muted-foreground, #656d76));
203
+ padding-left: 4px;
204
+ }
205
+
206
+ .sb-sidepanel-actions {
207
+ display: flex;
208
+ align-items: center;
209
+ gap: 2px;
210
+ }
211
+
212
+ .sb-sidepanel-action-btn {
213
+ appearance: none;
214
+ border: none;
215
+ background: transparent;
216
+ color: var(--fgColor-muted, var(--sb--color-muted-foreground, #656d76));
217
+ cursor: pointer;
218
+ padding: 6px;
219
+ border-radius: 6px;
220
+ display: flex;
221
+ align-items: center;
222
+ justify-content: center;
223
+ transition: background 0.15s ease, color 0.15s ease;
224
+ }
225
+
226
+ .sb-sidepanel-action-btn:hover {
227
+ background: var(--bgColor-neutral-muted, rgba(110, 118, 129, 0.1));
228
+ color: var(--fgColor-default, var(--sb--color-foreground, #1f2328));
229
+ }
230
+
231
+ /* Body */
232
+ .sb-sidepanel-body {
233
+ flex: 1;
234
+ overflow: hidden;
235
+ display: flex;
236
+ flex-direction: column;
237
+ }
238
+
239
+ .sb-sidepanel-loading {
240
+ display: flex;
241
+ align-items: center;
242
+ justify-content: center;
243
+ height: 120px;
244
+ }
245
+
246
+ .sb-sidepanel-spinner {
247
+ width: 20px;
248
+ height: 20px;
249
+ border: 2px solid var(--borderColor-default, var(--sb--color-border, #d0d7de));
250
+ border-top-color: var(--fgColor-muted, var(--sb--color-muted-foreground, #656d76));
251
+ border-radius: 50%;
252
+ animation: sb-spin 0.6s linear infinite;
253
+ }
254
+
255
+ @keyframes sb-spin {
256
+ to { transform: rotate(360deg); }
257
+ }
258
+
259
+ /* Float the side panel inside the mode collar (present/plan/inspect) */
260
+ html.storyboard-mode-present .sb-sidepanel:not(.sb-sidepanel--bottom),
261
+ html.storyboard-mode-plan .sb-sidepanel:not(.sb-sidepanel--bottom),
262
+ html.storyboard-mode-inspect .sb-sidepanel:not(.sb-sidepanel--bottom) {
263
+ top: 12px;
264
+ right: 12px;
265
+ bottom: 12px;
266
+ border-radius: var(--borderRadius-default);
267
+ border-left: none;
268
+ }
269
+
270
+ /* Float the bottom panel inside the mode collar */
271
+ html.storyboard-mode-present .sb-sidepanel--bottom,
272
+ html.storyboard-mode-plan .sb-sidepanel--bottom,
273
+ html.storyboard-mode-inspect .sb-sidepanel--bottom {
274
+ left: 12px;
275
+ right: 12px;
276
+ bottom: 12px;
277
+ width: auto !important;
278
+ border-radius: var(--borderRadius-default);
279
+ border-top: none;
280
+ }
281
+
282
+ /* Remove accent bar when collar provides mode context */
283
+ html.storyboard-mode-present .sb-sidepanel::before,
284
+ html.storyboard-mode-plan .sb-sidepanel::before,
285
+ html.storyboard-mode-inspect .sb-sidepanel::before {
286
+ display: none;
287
+ }
288
+
289
+ /* Mode-specific box-shadow matching #root treatment */
290
+ html.storyboard-mode-present .sb-sidepanel {
291
+ box-shadow: 0 0 7px 2px rgb(42 157 143 / 60%);
292
+ }
293
+
294
+ html.storyboard-mode-plan .sb-sidepanel {
295
+ box-shadow: 0 0 7px 2px rgb(74 127 173 / 60%);
296
+ }
297
+
298
+ html.storyboard-mode-inspect .sb-sidepanel {
299
+ box-shadow: 0 0 7px 2px rgb(118 85 164 / 60%);
300
+ }
301
+
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Viewfinder mount — stub (Svelte UI removed).
3
+ * These functions are no-ops. The viewfinder is rendered by React.
4
+ */
5
+
6
+ export function mountViewfinder() {}
7
+ export function unmountViewfinder() {}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * UI entry point — compiled into dist/storyboard-ui.js via Vite library build.
3
+ *
4
+ * This file is the entry for the pre-compiled UI bundle.
5
+ * It re-exports UI mount functions.
6
+ * Consumers never import this directly — they use mountStoryboardCore()
7
+ * or the package self-reference '@dfosco/storyboard/ui-runtime'.
8
+ */
9
+
10
+ // Tailwind utility + component CSS — bundled into storyboard-ui.css
11
+ import './styles/tailwind.css'
12
+
13
+ // Comments CSS
14
+ import './comments/ui/comment-layout.css'
15
+ import './comments/ui/comments.css'
16
+
17
+ // Modes CSS (design mode body classes)
18
+ import './modes/modes.css'
19
+
20
+ // CoreUIBar (floating toolbar)
21
+ export { mountDevTools, unmountDevTools } from './devtools/devtools.js'
22
+
23
+ // Comments UI
24
+ export { mountComments } from './comments/ui/mount.js'
25
+
26
+ // Viewfinder dashboard
27
+ export { mountViewfinder, unmountViewfinder } from './ui/viewfinder.ts'
28
+
29
+ // Design modes
30
+ export { mountDesignModesUI as mountDesignModes } from './ui/design-modes.ts'
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Fuzzy Search — lightweight substring + fuzzy scoring for the command palette.
3
+ *
4
+ * Scoring tiers (highest → lowest):
5
+ * 1. Exact prefix match — query matches start of text
6
+ * 2. Word-boundary match — query matches at a word boundary
7
+ * 3. Consecutive substring match — query appears as a contiguous substring
8
+ * 4. Fuzzy character match — all query chars appear in order
9
+ *
10
+ * Each tier gets a base score, with bonuses for shorter text (tighter match)
11
+ * and penalties for distance between matched characters (fuzzy only).
12
+ */
13
+
14
+ const SCORE_PREFIX = 100
15
+ const SCORE_WORD_BOUNDARY = 75
16
+ const SCORE_SUBSTRING = 50
17
+ const SCORE_FUZZY = 25
18
+
19
+ /**
20
+ * Score a single text against a query.
21
+ *
22
+ * @param {string} text — the string to search in
23
+ * @param {string} query — the search query (already lowercased by caller)
24
+ * @returns {number} Score ≥ 0 if matched, -1 if no match
25
+ */
26
+ export function scoreMatch(text, query) {
27
+ if (!query) return 0
28
+ if (!text) return -1
29
+
30
+ const lower = text.toLowerCase()
31
+ const qLen = query.length
32
+ const tLen = lower.length
33
+
34
+ // Exact prefix
35
+ if (lower.startsWith(query)) {
36
+ return SCORE_PREFIX + (1 - qLen / tLen) * 10
37
+ }
38
+
39
+ // Word-boundary match — query matches right after a non-alphanumeric char
40
+ const boundaryIdx = findWordBoundaryMatch(lower, query)
41
+ if (boundaryIdx >= 0) {
42
+ return SCORE_WORD_BOUNDARY + (1 - boundaryIdx / tLen) * 10
43
+ }
44
+
45
+ // Consecutive substring
46
+ const subIdx = lower.indexOf(query)
47
+ if (subIdx >= 0) {
48
+ return SCORE_SUBSTRING + (1 - subIdx / tLen) * 10
49
+ }
50
+
51
+ // Fuzzy — all characters in order
52
+ return fuzzyScore(lower, query)
53
+ }
54
+
55
+ /**
56
+ * Find where query matches starting at a word boundary in text.
57
+ * Word boundaries: start of string, after space, /, -, _, .
58
+ */
59
+ function findWordBoundaryMatch(text, query) {
60
+ const boundaries = /[\s/\-_.]/
61
+ for (let i = 1; i <= text.length - query.length; i++) {
62
+ if (boundaries.test(text[i - 1]) && text.startsWith(query, i)) {
63
+ return i
64
+ }
65
+ }
66
+ return -1
67
+ }
68
+
69
+ /**
70
+ * Fuzzy match — all query chars must appear in text in order.
71
+ * Score decreases with gaps between matched characters.
72
+ */
73
+ function fuzzyScore(text, query) {
74
+ let qi = 0
75
+ let totalGap = 0
76
+ let lastMatch = -1
77
+
78
+ for (let ti = 0; ti < text.length && qi < query.length; ti++) {
79
+ if (text[ti] === query[qi]) {
80
+ if (lastMatch >= 0) totalGap += ti - lastMatch - 1
81
+ lastMatch = ti
82
+ qi++
83
+ }
84
+ }
85
+
86
+ if (qi < query.length) return -1 // not all chars matched
87
+
88
+ const gapPenalty = Math.min(totalGap * 2, 20)
89
+ return SCORE_FUZZY - gapPenalty
90
+ }
91
+
92
+ /**
93
+ * Search an array of items and return scored, sorted results.
94
+ *
95
+ * @param {Array<{ label: string, [key: string]: any }>} items
96
+ * @param {string} query — raw search input
97
+ * @param {{ key?: string, maxResults?: number }} [opts]
98
+ * @returns {Array<{ item: object, score: number }>}
99
+ */
100
+ export function fuzzySearch(items, query, opts = {}) {
101
+ const key = opts.key || 'label'
102
+ const max = opts.maxResults || 50
103
+ const q = query.toLowerCase().trim()
104
+
105
+ if (!q) return items.slice(0, max).map(item => ({ item, score: 0 }))
106
+
107
+ const scored = []
108
+ for (const item of items) {
109
+ const text = item[key]
110
+ if (!text) continue
111
+ const score = scoreMatch(text, q)
112
+ if (score >= 0) scored.push({ item, score })
113
+ }
114
+
115
+ scored.sort((a, b) => b.score - a.score)
116
+ return scored.slice(0, max)
117
+ }
@@ -0,0 +1,119 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { scoreMatch, fuzzySearch } from './fuzzySearch.js'
3
+
4
+ describe('scoreMatch', () => {
5
+ it('returns 0 for empty query', () => {
6
+ expect(scoreMatch('hello', '')).toBe(0)
7
+ })
8
+
9
+ it('returns -1 for empty text', () => {
10
+ expect(scoreMatch('', 'hello')).toBe(-1)
11
+ })
12
+
13
+ it('scores exact prefix highest', () => {
14
+ const score = scoreMatch('Dashboard', 'dash')
15
+ expect(score).toBeGreaterThan(75)
16
+ })
17
+
18
+ it('scores word-boundary match above substring', () => {
19
+ const boundary = scoreMatch('my-dashboard', 'dash')
20
+ const substring = scoreMatch('syndashboard', 'dash')
21
+ expect(boundary).toBeGreaterThan(substring)
22
+ })
23
+
24
+ it('scores substring match above fuzzy', () => {
25
+ const sub = scoreMatch('syndashboard', 'dash')
26
+ const fuzzy = scoreMatch('directories and shared hosting', 'dash')
27
+ expect(sub).toBeGreaterThan(fuzzy)
28
+ })
29
+
30
+ it('returns -1 when fuzzy match fails', () => {
31
+ expect(scoreMatch('hello', 'xyz')).toBe(-1)
32
+ })
33
+
34
+ it('handles case-insensitive matching', () => {
35
+ expect(scoreMatch('Dashboard', 'dashboard')).toBeGreaterThan(0)
36
+ })
37
+
38
+ it('matches at various word boundaries', () => {
39
+ expect(scoreMatch('src/components/Button', 'button')).toBeGreaterThan(0)
40
+ expect(scoreMatch('some_thing_here', 'thing')).toBeGreaterThan(0)
41
+ expect(scoreMatch('my.config.file', 'config')).toBeGreaterThan(0)
42
+ })
43
+
44
+ it('penalizes large gaps in fuzzy matching', () => {
45
+ const tight = scoreMatch('abc', 'abc')
46
+ const loose = scoreMatch('a----b----c', 'abc')
47
+ expect(tight).toBeGreaterThan(loose)
48
+ })
49
+ })
50
+
51
+ describe('fuzzySearch', () => {
52
+ const items = [
53
+ { label: 'Dashboard' },
54
+ { label: 'Settings' },
55
+ { label: 'User Profile' },
56
+ { label: 'Go to Viewfinder' },
57
+ { label: 'DevTools' },
58
+ ]
59
+
60
+ it('returns all items for empty query (up to max)', () => {
61
+ const results = fuzzySearch(items, '')
62
+ expect(results).toHaveLength(items.length)
63
+ expect(results[0].score).toBe(0)
64
+ })
65
+
66
+ it('filters to matching items', () => {
67
+ const results = fuzzySearch(items, 'dash')
68
+ expect(results.length).toBeGreaterThanOrEqual(1)
69
+ expect(results[0].item.label).toBe('Dashboard')
70
+ })
71
+
72
+ it('ranks prefix matches above others', () => {
73
+ const items2 = [
74
+ { label: 'Find Dashboard' },
75
+ { label: 'Dashboard Overview' },
76
+ ]
77
+ const results = fuzzySearch(items2, 'dash')
78
+ expect(results[0].item.label).toBe('Dashboard Overview')
79
+ })
80
+
81
+ it('respects maxResults', () => {
82
+ const results = fuzzySearch(items, '', { maxResults: 2 })
83
+ expect(results).toHaveLength(2)
84
+ })
85
+
86
+ it('supports custom key', () => {
87
+ const data = [{ name: 'Alpha' }, { name: 'Beta' }]
88
+ const results = fuzzySearch(data, 'alp', { key: 'name' })
89
+ expect(results).toHaveLength(1)
90
+ expect(results[0].item.name).toBe('Alpha')
91
+ })
92
+
93
+ it('produces deterministic ranking for equal scores', () => {
94
+ const data = [
95
+ { label: 'aaa' },
96
+ { label: 'aab' },
97
+ { label: 'aac' },
98
+ ]
99
+ const r1 = fuzzySearch(data, 'aa')
100
+ const r2 = fuzzySearch(data, 'aa')
101
+ expect(r1.map(r => r.item.label)).toEqual(r2.map(r => r.item.label))
102
+ })
103
+
104
+ it('skips items with missing label', () => {
105
+ const data = [{ label: 'Valid' }, { other: 'no-label' }]
106
+ const results = fuzzySearch(data, 'val')
107
+ expect(results).toHaveLength(1)
108
+ })
109
+
110
+ it('ranks agent keyword matches above fuzzy component matches for "cop"', () => {
111
+ const data = [
112
+ { label: 'Component add widget create component component' },
113
+ { label: 'Agent add widget create agent copilot Copilot CLI' },
114
+ ]
115
+ const results = fuzzySearch(data, 'cop')
116
+ expect(results[0].item.label).toContain('Agent')
117
+ expect(results[0].score).toBeGreaterThan(results[1].score)
118
+ })
119
+ })
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Mobile viewport detection — reactive store for compact viewport state.
3
+ *
4
+ * Uses window.matchMedia for efficient, debounce-free detection.
5
+ * Threshold: 500px (matches the mobile breakpoint for toolbar compacting).
6
+ */
7
+
8
+ const MOBILE_QUERY = '(max-width: 499px)'
9
+
10
+ /** @type {boolean} */
11
+ let _isMobile = false
12
+
13
+ /** @type {Set<(mobile: boolean) => void>} */
14
+ const _listeners = new Set()
15
+
16
+ /** @type {MediaQueryList | null} */
17
+ let _mql = null
18
+
19
+ function _handleChange(e) {
20
+ _isMobile = e.matches
21
+ for (const cb of _listeners) cb(_isMobile)
22
+ }
23
+
24
+ // Initialize on load (SSR-safe)
25
+ if (typeof window !== 'undefined') {
26
+ _mql = window.matchMedia(MOBILE_QUERY)
27
+ _isMobile = _mql.matches
28
+ _mql.addEventListener('change', _handleChange)
29
+ }
30
+
31
+ /**
32
+ * Returns true when the viewport is narrower than 500px.
33
+ * @returns {boolean}
34
+ */
35
+ export function isMobile() {
36
+ return _isMobile
37
+ }
38
+
39
+ /**
40
+ * Subscribe to mobile state changes.
41
+ * @param {(mobile: boolean) => void} callback
42
+ * @returns {() => void} unsubscribe
43
+ */
44
+ export function subscribeToMobile(callback) {
45
+ _listeners.add(callback)
46
+ return () => _listeners.delete(callback)
47
+ }
48
+
49
+ /**
50
+ * Check if the device has a coarse pointer (touch device).
51
+ * Useful for PWA install prompts — avoids showing on narrow desktop windows.
52
+ * @returns {boolean}
53
+ */
54
+ export function isTouchDevice() {
55
+ if (typeof window === 'undefined') return false
56
+ return window.matchMedia('(pointer: coarse)').matches
57
+ }
@@ -0,0 +1,68 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
2
+
3
+ describe('mobileViewport', () => {
4
+ let matchMediaListeners = []
5
+ let matchMediaMatches = false
6
+
7
+ beforeEach(() => {
8
+ matchMediaListeners = []
9
+ matchMediaMatches = false
10
+
11
+ vi.stubGlobal('matchMedia', vi.fn((query) => {
12
+ const mql = {
13
+ matches: matchMediaMatches,
14
+ media: query,
15
+ addEventListener: vi.fn((event, cb) => {
16
+ matchMediaListeners.push(cb)
17
+ }),
18
+ removeEventListener: vi.fn(),
19
+ }
20
+ return mql
21
+ }))
22
+ })
23
+
24
+ afterEach(() => {
25
+ vi.unstubAllGlobals()
26
+ vi.resetModules()
27
+ })
28
+
29
+ it('isMobile returns false for wide viewports', async () => {
30
+ matchMediaMatches = false
31
+ const { isMobile } = await import('./mobileViewport.js')
32
+ expect(isMobile()).toBe(false)
33
+ })
34
+
35
+ it('isMobile returns true for narrow viewports', async () => {
36
+ matchMediaMatches = true
37
+ const { isMobile } = await import('./mobileViewport.js')
38
+ expect(isMobile()).toBe(true)
39
+ })
40
+
41
+ it('subscribeToMobile notifies on change', async () => {
42
+ matchMediaMatches = false
43
+ const { isMobile, subscribeToMobile } = await import('./mobileViewport.js')
44
+
45
+ const cb = vi.fn()
46
+ const unsub = subscribeToMobile(cb)
47
+
48
+ // Simulate matchMedia change event
49
+ const changeHandler = matchMediaListeners[0]
50
+ expect(changeHandler).toBeDefined()
51
+ changeHandler({ matches: true })
52
+
53
+ expect(cb).toHaveBeenCalledWith(true)
54
+ expect(isMobile()).toBe(true)
55
+
56
+ unsub()
57
+ changeHandler({ matches: false })
58
+ // Should not be called after unsubscribe
59
+ expect(cb).toHaveBeenCalledTimes(1)
60
+ })
61
+
62
+ it('isTouchDevice checks pointer: coarse', async () => {
63
+ const { isTouchDevice } = await import('./mobileViewport.js')
64
+ // Our mock returns matchMediaMatches for all queries
65
+ matchMediaMatches = false
66
+ expect(isTouchDevice()).toBe(false)
67
+ })
68
+ })