@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,112 @@
1
+ /**
2
+ * Storyboard FlowDebug — a vanilla JS debug panel that displays flow data.
3
+ *
4
+ * Framework-agnostic: creates a DOM element, no React/Vue/etc. needed.
5
+ *
6
+ * Usage:
7
+ * import { mountFlowDebug } from '../index.js'
8
+ * mountFlowDebug(document.getElementById('debug'))
9
+ * // or
10
+ * mountFlowDebug() // appends to document.body
11
+ */
12
+ import { loadFlow } from '../data/loader.js'
13
+
14
+ const STYLES = `
15
+ .sb-scene-debug {
16
+ padding: 16px;
17
+ font-family: "Mona Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
18
+ }
19
+ .sb-scene-debug-title {
20
+ font-size: 20px;
21
+ font-weight: 600;
22
+ margin-bottom: 8px;
23
+ color: #c9d1d9;
24
+ }
25
+ .sb-scene-debug-code {
26
+ padding: 16px;
27
+ background-color: #161b22;
28
+ border-radius: 8px;
29
+ overflow: auto;
30
+ font-size: 13px;
31
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
32
+ line-height: 1.5;
33
+ max-height: 70vh;
34
+ color: #c9d1d9;
35
+ white-space: pre-wrap;
36
+ word-break: break-word;
37
+ }
38
+ .sb-scene-debug-error {
39
+ padding: 16px;
40
+ background-color: rgba(248, 81, 73, 0.1);
41
+ border-radius: 8px;
42
+ }
43
+ .sb-scene-debug-error-title {
44
+ color: #f85149;
45
+ font-weight: 600;
46
+ }
47
+ .sb-scene-debug-error-message {
48
+ color: #f85149;
49
+ margin-top: 4px;
50
+ }
51
+ `
52
+
53
+ let stylesInjected = false
54
+
55
+ /**
56
+ * Mount a flow debug panel into the DOM.
57
+ *
58
+ * @param {HTMLElement} [container=document.body] - Where to mount
59
+ * @param {string} [flowName] - Flow name override (defaults to ?flow= param or "default")
60
+ * @returns {HTMLElement} The created debug element
61
+ */
62
+ export function mountFlowDebug(container, flowName) {
63
+ const target = container || document.body
64
+ const sp = new URLSearchParams(window.location.search)
65
+ const activeFlowName = flowName
66
+ || sp.get('flow') || sp.get('scene')
67
+ || 'default'
68
+
69
+ // Inject styles once
70
+ if (!stylesInjected) {
71
+ const styleEl = document.createElement('style')
72
+ styleEl.textContent = STYLES
73
+ document.head.appendChild(styleEl)
74
+ stylesInjected = true
75
+ }
76
+
77
+ const el = document.createElement('div')
78
+ el.className = 'sb-scene-debug'
79
+
80
+ let data = null
81
+ let error = null
82
+ try {
83
+ data = loadFlow(activeFlowName)
84
+ } catch (err) {
85
+ error = err.message
86
+ }
87
+
88
+ if (error) {
89
+ el.innerHTML = `
90
+ <div class="sb-scene-debug-error">
91
+ <div class="sb-scene-debug-error-title">Error loading flow</div>
92
+ <p class="sb-scene-debug-error-message">${error}</p>
93
+ </div>`
94
+ } else {
95
+ const title = document.createElement('h2')
96
+ title.className = 'sb-scene-debug-title'
97
+ title.textContent = `Flow: ${activeFlowName}`
98
+
99
+ const pre = document.createElement('pre')
100
+ pre.className = 'sb-scene-debug-code'
101
+ pre.textContent = JSON.stringify(data, null, 2)
102
+
103
+ el.appendChild(title)
104
+ el.appendChild(pre)
105
+ }
106
+
107
+ target.appendChild(el)
108
+ return el
109
+ }
110
+
111
+ /** @deprecated Use mountFlowDebug() */
112
+ export const mountSceneDebug = mountFlowDebug
@@ -0,0 +1,141 @@
1
+ import { vi } from 'vitest'
2
+
3
+ const { mockLoadFlow } = vi.hoisted(() => ({
4
+ mockLoadFlow: vi.fn(() => ({ hello: 'world', count: 42 })),
5
+ }))
6
+
7
+ vi.mock('../data/loader.js', () => ({
8
+ loadFlow: mockLoadFlow,
9
+ }))
10
+
11
+ // We need a fresh module for each test since sceneDebug has a module-level
12
+ // `stylesInjected` boolean. We test style injection on the very first call,
13
+ // then subsequent tests just verify other behavior.
14
+ import { mountFlowDebug, mountSceneDebug } from './sceneDebug.js'
15
+
16
+ afterEach(() => {
17
+ document.body.innerHTML = ''
18
+ mockLoadFlow.mockReset()
19
+ mockLoadFlow.mockReturnValue({ hello: 'world', count: 42 })
20
+ })
21
+
22
+ describe('mountFlowDebug', () => {
23
+ it('injects styles into document.head on first call', () => {
24
+ // This MUST run first to capture the stylesInjected=false → true transition
25
+ mountFlowDebug()
26
+
27
+ const styles = document.head.querySelectorAll('style')
28
+ const hasDebugStyle = Array.from(styles).some((el) =>
29
+ el.textContent.includes('.sb-scene-debug')
30
+ )
31
+ expect(hasDebugStyle).toBe(true)
32
+ })
33
+
34
+ it('creates an element with class sb-scene-debug', () => {
35
+ const el = mountFlowDebug()
36
+
37
+ expect(el.classList.contains('sb-scene-debug')).toBe(true)
38
+ })
39
+
40
+ it('appends to document.body by default', () => {
41
+ mountFlowDebug()
42
+
43
+ expect(document.body.querySelector('.sb-scene-debug')).toBeInTheDocument()
44
+ })
45
+
46
+ it('appends to a custom container', () => {
47
+ const container = document.createElement('div')
48
+ document.body.appendChild(container)
49
+
50
+ mountFlowDebug(container)
51
+
52
+ expect(container.querySelector('.sb-scene-debug')).not.toBeNull()
53
+ })
54
+
55
+ it('returns the created element', () => {
56
+ const el = mountFlowDebug()
57
+
58
+ expect(el).toBeInstanceOf(HTMLElement)
59
+ expect(el.className).toBe('sb-scene-debug')
60
+ })
61
+
62
+ it('renders the flow name in the title', () => {
63
+ mountFlowDebug(undefined, 'my-flow')
64
+
65
+ const title = document.body.querySelector('.sb-scene-debug-title')
66
+ expect(title).not.toBeNull()
67
+ expect(title.textContent).toContain('my-flow')
68
+ })
69
+
70
+ it('defaults flow name to "default" when none is provided', () => {
71
+ mountFlowDebug()
72
+
73
+ const title = document.body.querySelector('.sb-scene-debug-title')
74
+ expect(title.textContent).toContain('default')
75
+ expect(mockLoadFlow).toHaveBeenCalledWith('default')
76
+ })
77
+
78
+ it('renders JSON data in a pre element', () => {
79
+ mountFlowDebug()
80
+
81
+ const pre = document.body.querySelector('.sb-scene-debug-code')
82
+ expect(pre).not.toBeNull()
83
+ expect(pre.tagName).toBe('PRE')
84
+
85
+ const parsed = JSON.parse(pre.textContent)
86
+ expect(parsed).toEqual({ hello: 'world', count: 42 })
87
+ })
88
+
89
+ it('shows error when loadFlow throws', () => {
90
+ mockLoadFlow.mockImplementation(() => {
91
+ throw new Error('Flow not found')
92
+ })
93
+
94
+ const el = mountFlowDebug()
95
+
96
+ const errorTitle = el.querySelector('.sb-scene-debug-error-title')
97
+ expect(errorTitle).not.toBeNull()
98
+ expect(errorTitle.textContent).toContain('Error')
99
+
100
+ const errorMsg = el.querySelector('.sb-scene-debug-error-message')
101
+ expect(errorMsg.textContent).toContain('Flow not found')
102
+
103
+ // Should NOT render the normal title/pre
104
+ expect(el.querySelector('.sb-scene-debug-title')).toBeNull()
105
+ expect(el.querySelector('.sb-scene-debug-code')).toBeNull()
106
+ })
107
+
108
+ it('uses ?scene query param when no flowName argument is given', () => {
109
+ window.history.pushState(null, '', '?scene=overview')
110
+
111
+ mountFlowDebug()
112
+
113
+ expect(mockLoadFlow).toHaveBeenCalledWith('overview')
114
+ const title = document.body.querySelector('.sb-scene-debug-title')
115
+ expect(title.textContent).toContain('overview')
116
+
117
+ // Clean up
118
+ window.history.pushState(null, '', '/')
119
+ })
120
+
121
+ it('allows multiple debug panels to be mounted', () => {
122
+ mountFlowDebug()
123
+ mountFlowDebug()
124
+
125
+ const panels = document.body.querySelectorAll('.sb-scene-debug')
126
+ expect(panels).toHaveLength(2)
127
+ })
128
+ })
129
+
130
+ // ── mountSceneDebug (deprecated alias) ──
131
+
132
+ describe('mountSceneDebug (deprecated alias)', () => {
133
+ it('is the same function as mountFlowDebug', () => {
134
+ expect(mountSceneDebug).toBe(mountFlowDebug)
135
+ })
136
+
137
+ it('mounts a debug panel', () => {
138
+ const el = mountSceneDebug()
139
+ expect(el.classList.contains('sb-scene-debug')).toBe(true)
140
+ })
141
+ })
@@ -0,0 +1,124 @@
1
+ /**
2
+ * storyboard-core — framework-agnostic data layer.
3
+ *
4
+ * This barrel exports all core utilities that have zero framework dependencies.
5
+ * Any frontend (React, Vue, Alpine, vanilla JS) can use these directly.
6
+ */
7
+
8
+ // Data index initialization
9
+ export { init } from './data/loader.js'
10
+
11
+ // Flow, object & record loading
12
+ export { loadFlow, listFlows, flowExists, getFlowsForPrototype, loadRecord, findRecord, loadObject, deepMerge } from './data/loader.js'
13
+ // Scoped name resolution
14
+ export { resolveFlowName, resolveRecordName, resolveObjectName } from './data/loader.js'
15
+ // Prototype metadata
16
+ export { listPrototypes, getPrototypeMetadata } from './data/loader.js'
17
+ // Folder metadata
18
+ export { listFolders, getFolderMetadata } from './data/loader.js'
19
+ // Canvas data
20
+ export { listCanvases, getCanvasData } from './data/loader.js'
21
+ // Story data
22
+ export { listStories, getStoryData } from './data/loader.js'
23
+ // Deprecated scene aliases
24
+ export { loadScene, listScenes, sceneExists } from './data/loader.js'
25
+
26
+ // Dot-notation path utilities
27
+ export { getByPath, setByPath, deepClone } from './data/dotPath.js'
28
+
29
+ // URL hash session state (read/write)
30
+ export { getParam, setParam, getAllParams, removeParam } from './session/session.js'
31
+
32
+ // localStorage persistence
33
+ export { getLocal, setLocal, removeLocal, getAllLocal, subscribeToStorage, getStorageSnapshot, notifyChange } from './session/localStorage.js'
34
+
35
+ // Hide mode (clean URLs)
36
+ export { isHideMode, activateHideMode, deactivateHideMode, getShadow, setShadow, removeShadow, getAllShadows, pushSnapshot, getOverrideHistory, getCurrentSnapshot, getCurrentRoute, getCurrentIndex, getNextIndex, canUndo, canRedo, undo, redo, syncHashToHistory, installHistorySync } from './session/hideMode.js'
37
+ export { interceptHideParams, installHideParamListener } from './session/interceptHideParams.js'
38
+
39
+ // Hash change subscription (for reactive frameworks)
40
+ export { subscribeToHash, getHashSnapshot } from './session/hashSubscribe.js'
41
+
42
+ // Body class sync (overrides + flow → <body> classes)
43
+ export { installBodyClassSync, setFlowClass, syncOverrideClasses } from './session/bodyClasses.js'
44
+ // Deprecated alias
45
+ export { setSceneClass } from './session/bodyClasses.js'
46
+
47
+ // Design modes (mode registry, switching, event bus)
48
+ export { registerMode, unregisterMode, getRegisteredModes, getCurrentMode, activateMode, deactivateMode, subscribeToMode, getModeSnapshot, syncModeClasses, on, off, emit, initModesConfig, isModesEnabled, getLockedMode, isModeSwitcherVisible } from './modes/modes.js'
49
+
50
+ // Tool registry (declared in modes.config.json, state managed at runtime)
51
+ export { initTools, setToolAction, setToolState, getToolState, getToolsForMode, subscribeToTools, getToolsSnapshot } from './modes/modes.js'
52
+
53
+ // Dev tools (vanilla JS, framework-agnostic)
54
+ // mountDevTools delegates to the compiled UI bundle so consumers
55
+
56
+ export { mountDevTools } from './devtools/devtools-consumer.js'
57
+ export { mountFlowDebug } from './devtools/sceneDebug.js'
58
+ // Deprecated alias
59
+ export { mountSceneDebug } from './devtools/sceneDebug.js'
60
+
61
+ // Single entry point for consumer apps
62
+ export { mountStoryboardCore } from './mountStoryboardCore.js'
63
+
64
+ // Viewfinder utilities
65
+ export { hash, resolveFlowRoute, getFlowMeta, buildPrototypeIndex, appendTokens } from './data/viewfinder.js'
66
+ // Deprecated aliases
67
+ export { resolveSceneRoute, getSceneMeta } from './data/viewfinder.js'
68
+
69
+ // Feature flags
70
+ export { initFeatureFlags, getFlag, setFlag, toggleFlag, getAllFlags, resetFlags, getFlagKeys, syncFlagBodyClasses } from './stores/featureFlags.js'
71
+
72
+ // Command actions (config-driven command menu entries)
73
+ export { initCommandActions, registerCommandAction, unregisterCommandAction, setDynamicActions, clearDynamicActions, getActionsForMode, executeAction, getActionChildren, hasChildrenProvider, subscribeToCommandActions, getCommandActionsSnapshot, setRoutingBasePath, isExcludedByRoute } from './stores/commandActions.js'
74
+
75
+ // Plugin configuration
76
+ export { initPlugins, isPluginEnabled, getPluginsConfig } from './stores/plugins.js'
77
+
78
+ // UI config (project-level chrome overrides)
79
+ export { initUIConfig, isMenuHidden, getHiddenItems } from './stores/uiConfig.js'
80
+
81
+ // Tool registry (declarative tool system)
82
+ export { initToolRegistry, registerToolModule, setToolComponent, setToolGuardResult, getToolComponent, getToolModule, getToolsForToolbar, getToolConfig, getAllToolConfigs, subscribeToToolRegistry, getToolRegistrySnapshot } from './stores/toolRegistry.js'
83
+
84
+ // Toolbar config store (reactive layered overrides: core → custom → prototype → user)
85
+ export { initToolbarConfig, setPrototypeToolbarConfig, clearPrototypeToolbarConfig, getToolbarConfig, subscribeToToolbarConfig, getToolbarConfigSnapshot, setClientToolbarOverrides, consumeClientToolbarOverrides } from './stores/toolbarConfigStore.js'
86
+
87
+ // Toolbar tool state management (runtime state for toolbar tools)
88
+ export { TOOL_STATES, initToolbarToolStates, setToolbarToolState, getToolbarToolState, isToolbarToolLocalOnly, subscribeToToolbarToolStates, getToolbarToolStatesSnapshot } from './stores/toolStateStore.js'
89
+
90
+ // Comments system
91
+ export { initCommentsConfig, getCommentsConfig, isCommentsEnabled } from './comments/config.js'
92
+
93
+ // Canvas config (paste rules, canvas-level overrides)
94
+ export { initCanvasConfig, getPasteRules, getTerminalConfig, getAgentsConfig, isTerminalResizable, getTerminalDimensions, getCanvasZoom } from './stores/canvasConfig.js'
95
+ export { getCommandPaletteConfig, initCommandPaletteConfig } from './stores/commandPaletteConfig.js'
96
+
97
+ // Unified config store
98
+ export { initConfig, getConfig, setOverrides, clearOverrides, clearAllOverrides, subscribeToConfig, getConfigSnapshot } from './stores/configStore.js'
99
+
100
+ // Customer mode config
101
+ export { initCustomerModeConfig, getCustomerModeConfig, isCustomerMode } from './stores/customerModeConfig.js'
102
+
103
+ // Theme
104
+ export {
105
+ setTheme,
106
+ getTheme,
107
+ themeState,
108
+ themeSyncState,
109
+ THEMES,
110
+ getThemeSyncTargets,
111
+ setThemeSyncTarget,
112
+ } from './stores/themeStore.js'
113
+
114
+ // Recent artifacts (command palette recents)
115
+ export { trackRecent, getRecent, clearRecent } from './stores/recentArtifacts.js'
116
+
117
+ // Fuzzy search (scoring used by command palette custom filter)
118
+ export { scoreMatch } from './utils/fuzzySearch.js'
119
+
120
+ // Icon component for UI rendering
121
+ export { default as Icon, default as IconDefault } from './ui/Icon.jsx'
122
+
123
+ // Shared UI components
124
+ export { default as BranchSelect } from './ui/BranchSelect.jsx'
@@ -0,0 +1,239 @@
1
+ /**
2
+ * Fiber Walker — React fiber tree inspector for DOM elements.
3
+ *
4
+ * Framework-agnostic (zero npm dependencies).
5
+ * Intended for dev-time inspection only — relies on React's internal
6
+ * fiber keys and _debugSource which are only present in development builds.
7
+ */
8
+
9
+ // ---------------------------------------------------------------------------
10
+ // Internal helpers
11
+ // ---------------------------------------------------------------------------
12
+
13
+ /**
14
+ * Find the React fiber key on a DOM element.
15
+ * React attaches fibers via private keys like __reactFiber$xxxx.
16
+ * The suffix changes per React instance, so we search by prefix.
17
+ *
18
+ * @param {Element} el
19
+ * @returns {string|undefined}
20
+ */
21
+ function findFiberKey(el) {
22
+ return Object.keys(el).find(
23
+ k => k.startsWith('__reactFiber$') || k.startsWith('__reactInternalInstance$')
24
+ )
25
+ }
26
+
27
+ /**
28
+ * Check whether a fiber represents a user-defined component
29
+ * (as opposed to a host element like 'div' or a React internal like Fragment).
30
+ * Handles function components, forwardRef, and memo wrappers.
31
+ *
32
+ * @param {object} fiber
33
+ * @returns {boolean}
34
+ */
35
+ function isUserComponent(fiber) {
36
+ if (!fiber || !fiber.type) return false
37
+ const t = fiber.type
38
+ // Plain function/class component
39
+ if (typeof t === 'function') return true
40
+ // forwardRef: { $$typeof: Symbol(react.forward_ref), render: fn }
41
+ // memo: { $$typeof: Symbol(react.memo), type: ... }
42
+ if (typeof t === 'object' && t !== null) {
43
+ if (typeof t.render === 'function') return true // forwardRef
44
+ if (t.$$typeof && typeof t.type === 'function') return true // memo
45
+ if (t.$$typeof && typeof t.type === 'object') return true // memo(forwardRef)
46
+ }
47
+ return false
48
+ }
49
+
50
+ /**
51
+ * Derive a human-readable name from a fiber's type.
52
+ * Handles plain components, forwardRef, and memo wrappers.
53
+ * Skips minified names (single-char or generic) in favor of 'ForwardRef'/'Memo'
54
+ * so the caller can try walking up the tree for a better name.
55
+ *
56
+ * @param {object} fiber
57
+ * @returns {string}
58
+ */
59
+ function getComponentName(fiber) {
60
+ if (!fiber || !fiber.type) return 'Unknown'
61
+ const t = fiber.type
62
+ // Plain function/class
63
+ if (typeof t === 'function') return t.displayName || t.name || 'Anonymous'
64
+ // forwardRef / memo wrapper objects
65
+ if (typeof t === 'object' && t !== null) {
66
+ if (t.displayName) return t.displayName
67
+ // forwardRef: { render: fn }
68
+ if (typeof t.render === 'function') {
69
+ const name = t.render.displayName || t.render.name
70
+ return isUsableName(name) ? name : 'ForwardRef'
71
+ }
72
+ // memo: { type: ... }
73
+ if (t.type) {
74
+ const inner = t.type
75
+ if (typeof inner === 'function') {
76
+ const name = inner.displayName || inner.name
77
+ return isUsableName(name) ? name : 'Memo'
78
+ }
79
+ // memo(forwardRef)
80
+ if (typeof inner === 'object' && inner.render) {
81
+ if (inner.displayName) return inner.displayName
82
+ const name = inner.render.displayName || inner.render.name
83
+ return isUsableName(name) ? name : 'ForwardRef'
84
+ }
85
+ }
86
+ }
87
+ return 'Unknown'
88
+ }
89
+
90
+ /**
91
+ * Check if a resolved component name is usable (not minified).
92
+ * Minified names are typically 1-2 chars or all lowercase short strings.
93
+ */
94
+ function isUsableName(name) {
95
+ if (!name) return false
96
+ // Single-char names (e, t, r, n) are almost certainly minified
97
+ if (name.length <= 2) return false
98
+ return true
99
+ }
100
+
101
+ /**
102
+ * Extract debug source info from a fiber (dev builds only).
103
+ *
104
+ * @param {object} fiber
105
+ * @returns {{ fileName: string, lineNumber: number, columnNumber: number }|null}
106
+ */
107
+ function getDebugSource(fiber) {
108
+ if (!fiber || !fiber._debugSource) return null
109
+ const src = fiber._debugSource
110
+ return {
111
+ fileName: src.fileName ?? null,
112
+ lineNumber: src.lineNumber ?? null,
113
+ columnNumber: src.columnNumber ?? null,
114
+ }
115
+ }
116
+
117
+ // ---------------------------------------------------------------------------
118
+ // Public API
119
+ // ---------------------------------------------------------------------------
120
+
121
+ /**
122
+ * Get the React fiber node attached to a DOM element.
123
+ * React attaches fibers via private keys like __reactFiber$xxx.
124
+ * Returns null if the element has no fiber (not a React-rendered element).
125
+ *
126
+ * @param {Element} el - A DOM element
127
+ * @returns {object|null} The fiber node, or null
128
+ */
129
+ export function getFiberFromElement(el) {
130
+ if (!el || typeof el !== 'object') return null
131
+ const key = findFiberKey(el)
132
+ if (!key) return null
133
+ return el[key] ?? null
134
+ }
135
+
136
+ /**
137
+ * Extract component information from a fiber node.
138
+ * Walks up the fiber tree to find the nearest user component
139
+ * (skipping host elements like div, span, etc.).
140
+ *
141
+ * Returns: { name, props, source, owner } or null
142
+ * - name: component display name or function name
143
+ * - props: current memoized props object
144
+ * - source: { fileName, lineNumber, columnNumber } from _debugSource, or null
145
+ * - owner: name of the owning/parent component, or null
146
+ *
147
+ * @param {object} fiber - A React fiber node
148
+ * @returns {{ name: string, props: object, source: object|null, owner: string|null }|null}
149
+ */
150
+ export function getComponentInfo(fiber) {
151
+ if (!fiber) return null
152
+
153
+ // Walk up to the nearest user component
154
+ let current = fiber
155
+ while (current && !isUserComponent(current)) {
156
+ current = current.return
157
+ }
158
+
159
+ if (!current) return null
160
+
161
+ let name = getComponentName(current)
162
+
163
+ // If we got a generic name (ForwardRef, Memo), try walking up
164
+ // to find the nearest ancestor with a real component name
165
+ if (name === 'ForwardRef' || name === 'Memo') {
166
+ let ancestor = current.return
167
+ while (ancestor) {
168
+ if (isUserComponent(ancestor)) {
169
+ const ancestorName = getComponentName(ancestor)
170
+ if (ancestorName !== 'ForwardRef' && ancestorName !== 'Memo' && ancestorName !== 'Unknown') {
171
+ name = ancestorName
172
+ break
173
+ }
174
+ }
175
+ ancestor = ancestor.return
176
+ }
177
+ }
178
+
179
+ const ownerFiber = current._debugOwner ?? null
180
+
181
+ return {
182
+ name,
183
+ props: current.memoizedProps ?? {},
184
+ source: getDebugSource(current),
185
+ owner: ownerFiber ? getComponentName(ownerFiber) : null,
186
+ }
187
+ }
188
+
189
+ /**
190
+ * Walk up the fiber tree and collect all user components in the chain.
191
+ * Returns an array from the given fiber up to the root.
192
+ * Each entry: { name, source }
193
+ * Skips host elements (div, span, etc.) and React internal types.
194
+ *
195
+ * @param {object} fiber - A React fiber node
196
+ * @returns {Array<{ name: string, source: object|null }>}
197
+ */
198
+ export function getComponentChain(fiber) {
199
+ const chain = []
200
+ let current = fiber
201
+
202
+ while (current) {
203
+ if (isUserComponent(current)) {
204
+ chain.push({
205
+ name: getComponentName(current),
206
+ source: getDebugSource(current),
207
+ })
208
+ }
209
+ current = current.return
210
+ }
211
+
212
+ return chain
213
+ }
214
+
215
+ /**
216
+ * Convenience: given a DOM element, get full component info.
217
+ * Combines getFiberFromElement + getComponentInfo.
218
+ *
219
+ * @param {Element} el - A DOM element
220
+ * @returns {{ name: string, props: object, source: object|null, owner: string|null }|null}
221
+ */
222
+ export function inspectElement(el) {
223
+ const fiber = getFiberFromElement(el)
224
+ if (!fiber) return null
225
+ return getComponentInfo(fiber)
226
+ }
227
+
228
+ /**
229
+ * Given a DOM element, get ALL React components in the ancestry chain.
230
+ * Combines getFiberFromElement + getComponentChain.
231
+ *
232
+ * @param {Element} el - A DOM element
233
+ * @returns {Array<{ name: string, source: object|null }>}
234
+ */
235
+ export function inspectElementChain(el) {
236
+ const fiber = getFiberFromElement(el)
237
+ if (!fiber) return []
238
+ return getComponentChain(fiber)
239
+ }