@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,174 @@
1
+ /**
2
+ * Shared CLI flag parser — converts argv into a validated flags object.
3
+ *
4
+ * Supports:
5
+ * --key value string/number value
6
+ * --key=value equals-separated
7
+ * --bool boolean true
8
+ * --no-bool boolean false (negation prefix)
9
+ * --key a --key b repeated flags → array
10
+ *
11
+ * Usage:
12
+ * const { flags, missing, errors } = parseFlags(process.argv.slice(3), schema)
13
+ */
14
+
15
+ /**
16
+ * @typedef {Object} FlagDef
17
+ * @property {'string'|'boolean'|'number'|'array'} type
18
+ * @property {boolean} [required]
19
+ * @property {*} [default]
20
+ * @property {string} [description]
21
+ * @property {string[]} [aliases] - short or alternate names (without --)
22
+ */
23
+
24
+ /**
25
+ * @typedef {Object<string, FlagDef>} FlagSchema
26
+ */
27
+
28
+ /**
29
+ * Parse argv tokens against a schema.
30
+ *
31
+ * @param {string[]} argv - process.argv tokens (after command words are stripped)
32
+ * @param {FlagSchema} schema
33
+ * @returns {{ flags: Object, positional: string[], missing: string[], errors: string[] }}
34
+ */
35
+ export function parseFlags(argv, schema) {
36
+ const flags = {}
37
+ const positional = []
38
+ const errors = []
39
+
40
+ // Build alias → canonical name map
41
+ const aliasMap = {}
42
+ for (const [name, def] of Object.entries(schema)) {
43
+ aliasMap[name] = name
44
+ if (def.aliases) {
45
+ for (const alias of def.aliases) {
46
+ aliasMap[alias] = name
47
+ }
48
+ }
49
+ }
50
+
51
+ // Seed defaults
52
+ for (const [name, def] of Object.entries(schema)) {
53
+ if (def.default !== undefined) {
54
+ flags[name] = def.default
55
+ }
56
+ }
57
+
58
+ let i = 0
59
+ while (i < argv.length) {
60
+ const token = argv[i]
61
+
62
+ if (!token.startsWith('-')) {
63
+ positional.push(token)
64
+ i++
65
+ continue
66
+ }
67
+
68
+ // Strip leading dashes
69
+ let raw = token.replace(/^--?/, '')
70
+ let value
71
+
72
+ // Handle --key=value
73
+ const eqIdx = raw.indexOf('=')
74
+ if (eqIdx !== -1) {
75
+ value = raw.slice(eqIdx + 1)
76
+ raw = raw.slice(0, eqIdx)
77
+ }
78
+
79
+ // Handle --no-<key> negation
80
+ let negated = false
81
+ if (raw.startsWith('no-') && !aliasMap[raw]) {
82
+ const candidate = raw.slice(3)
83
+ if (aliasMap[candidate]) {
84
+ raw = candidate
85
+ negated = true
86
+ }
87
+ }
88
+
89
+ const canonical = aliasMap[raw]
90
+ if (!canonical) {
91
+ errors.push(`Unknown flag: --${raw}`)
92
+ i++
93
+ continue
94
+ }
95
+
96
+ const def = schema[canonical]
97
+
98
+ if (def.type === 'boolean') {
99
+ if (value !== undefined) {
100
+ // Handle --flag=true / --flag=false
101
+ const lower = value.toLowerCase()
102
+ if (lower === 'true' || lower === '1') flags[canonical] = !negated
103
+ else if (lower === 'false' || lower === '0') flags[canonical] = negated
104
+ else errors.push(`Flag --${raw} is boolean; use --${raw}, --no-${raw}, or --${raw}=true|false`)
105
+ } else {
106
+ flags[canonical] = !negated
107
+ }
108
+ i++
109
+ continue
110
+ }
111
+
112
+ // Consume next token as value if we didn't get one from `=`
113
+ if (value === undefined) {
114
+ i++
115
+ if (i >= argv.length) {
116
+ errors.push(`Flag --${raw} requires a value`)
117
+ continue
118
+ }
119
+ value = argv[i]
120
+ }
121
+
122
+ if (def.type === 'number') {
123
+ const num = Number(value)
124
+ if (Number.isNaN(num)) {
125
+ errors.push(`Flag --${raw} must be a number, got "${value}"`)
126
+ } else {
127
+ flags[canonical] = num
128
+ }
129
+ } else if (def.type === 'array') {
130
+ if (!Array.isArray(flags[canonical])) flags[canonical] = []
131
+ flags[canonical].push(value)
132
+ } else {
133
+ // string (or JSON for object-typed flags)
134
+ flags[canonical] = value
135
+ }
136
+
137
+ i++
138
+ }
139
+
140
+ // Check required
141
+ const missing = []
142
+ for (const [name, def] of Object.entries(schema)) {
143
+ if (def.required && (flags[name] === undefined || flags[name] === '')) {
144
+ missing.push(name)
145
+ }
146
+ }
147
+
148
+ return { flags, positional, missing, errors }
149
+ }
150
+
151
+ /**
152
+ * Check if any flags were provided (beyond defaults).
153
+ * Useful to decide interactive vs non-interactive mode.
154
+ */
155
+ export function hasFlags(argv) {
156
+ return argv.some((t) => t.startsWith('-'))
157
+ }
158
+
159
+ /**
160
+ * Format a schema into help text lines.
161
+ *
162
+ * @param {FlagSchema} schema
163
+ * @returns {string}
164
+ */
165
+ export function formatFlagHelp(schema) {
166
+ const lines = []
167
+ for (const [name, def] of Object.entries(schema)) {
168
+ const aliases = def.aliases ? def.aliases.map((a) => `-${a}`).join(', ') + ', ' : ''
169
+ const req = def.required ? ' (required)' : ''
170
+ const defVal = def.default !== undefined ? ` [default: ${def.default}]` : ''
171
+ lines.push(` ${aliases}--${name.padEnd(16)} ${def.description || ''}${req}${defVal}`)
172
+ }
173
+ return lines.join('\n')
174
+ }
@@ -0,0 +1,155 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { parseFlags, hasFlags, formatFlagHelp } from './flags.js'
3
+
4
+ const testSchema = {
5
+ name: { type: 'string', required: true, description: 'Name', aliases: ['n'] },
6
+ title: { type: 'string', description: 'Title', aliases: ['t'] },
7
+ count: { type: 'number', description: 'Count', default: 0 },
8
+ verbose: { type: 'boolean', description: 'Verbose', default: false },
9
+ tags: { type: 'array', description: 'Tags', aliases: ['g'] },
10
+ }
11
+
12
+ describe('parseFlags', () => {
13
+ it('parses --key value pairs', () => {
14
+ const { flags } = parseFlags(['--name', 'hello', '--title', 'world'], testSchema)
15
+ expect(flags.name).toBe('hello')
16
+ expect(flags.title).toBe('world')
17
+ })
18
+
19
+ it('parses --key=value syntax', () => {
20
+ const { flags } = parseFlags(['--name=hello'], testSchema)
21
+ expect(flags.name).toBe('hello')
22
+ })
23
+
24
+ it('parses short aliases', () => {
25
+ const { flags } = parseFlags(['-n', 'hello', '-t', 'world'], testSchema)
26
+ expect(flags.name).toBe('hello')
27
+ expect(flags.title).toBe('world')
28
+ })
29
+
30
+ it('parses boolean flags', () => {
31
+ const { flags } = parseFlags(['--verbose', '--name', 'x'], testSchema)
32
+ expect(flags.verbose).toBe(true)
33
+ })
34
+
35
+ it('parses --no- negation for booleans', () => {
36
+ const { flags } = parseFlags(['--no-verbose', '--name', 'x'], testSchema)
37
+ expect(flags.verbose).toBe(false)
38
+ })
39
+
40
+ it('parses --flag=false for booleans', () => {
41
+ const { flags } = parseFlags(['--verbose=false', '--name', 'x'], testSchema)
42
+ expect(flags.verbose).toBe(false)
43
+ })
44
+
45
+ it('parses --flag=true for booleans', () => {
46
+ const { flags } = parseFlags(['--verbose=true', '--name', 'x'], testSchema)
47
+ expect(flags.verbose).toBe(true)
48
+ })
49
+
50
+ it('parses --no-flag=false as double negation (true)', () => {
51
+ const { flags } = parseFlags(['--no-verbose=false', '--name', 'x'], testSchema)
52
+ expect(flags.verbose).toBe(true)
53
+ })
54
+
55
+ it('reports error for invalid boolean value', () => {
56
+ const { errors } = parseFlags(['--verbose=maybe', '--name', 'x'], testSchema)
57
+ expect(errors).toHaveLength(1)
58
+ expect(errors[0]).toContain('boolean')
59
+ })
60
+
61
+ it('parses number flags', () => {
62
+ const { flags } = parseFlags(['--name', 'x', '--count', '42'], testSchema)
63
+ expect(flags.count).toBe(42)
64
+ })
65
+
66
+ it('reports error for non-numeric number flag', () => {
67
+ const { errors } = parseFlags(['--name', 'x', '--count', 'abc'], testSchema)
68
+ expect(errors).toHaveLength(1)
69
+ expect(errors[0]).toContain('must be a number')
70
+ })
71
+
72
+ it('collects repeated flags into arrays', () => {
73
+ const { flags } = parseFlags(['--name', 'x', '-g', 'a', '-g', 'b'], testSchema)
74
+ expect(flags.tags).toEqual(['a', 'b'])
75
+ })
76
+
77
+ it('collects positional arguments', () => {
78
+ const { positional } = parseFlags(['sticky-note', '--name', 'x'], testSchema)
79
+ expect(positional).toEqual(['sticky-note'])
80
+ })
81
+
82
+ it('reports missing required flags', () => {
83
+ const { missing } = parseFlags(['--title', 'hello'], testSchema)
84
+ expect(missing).toContain('name')
85
+ })
86
+
87
+ it('does not report missing when required flag is provided', () => {
88
+ const { missing } = parseFlags(['--name', 'hello'], testSchema)
89
+ expect(missing).not.toContain('name')
90
+ })
91
+
92
+ it('reports unknown flags', () => {
93
+ const { errors } = parseFlags(['--name', 'x', '--unknown', 'y'], testSchema)
94
+ expect(errors).toHaveLength(1)
95
+ expect(errors[0]).toContain('Unknown flag')
96
+ })
97
+
98
+ it('applies defaults', () => {
99
+ const { flags } = parseFlags(['--name', 'x'], testSchema)
100
+ expect(flags.count).toBe(0)
101
+ expect(flags.verbose).toBe(false)
102
+ })
103
+
104
+ it('reports error when value flag has no value', () => {
105
+ const { errors } = parseFlags(['--name'], testSchema)
106
+ expect(errors).toHaveLength(1)
107
+ expect(errors[0]).toContain('requires a value')
108
+ })
109
+
110
+ it('returns empty results for empty argv', () => {
111
+ const { flags, positional, missing, errors } = parseFlags([], testSchema)
112
+ expect(positional).toEqual([])
113
+ expect(errors).toEqual([])
114
+ expect(missing).toContain('name')
115
+ expect(flags.count).toBe(0)
116
+ })
117
+ })
118
+
119
+ describe('hasFlags', () => {
120
+ it('returns true when argv has flags', () => {
121
+ expect(hasFlags(['--name', 'x'])).toBe(true)
122
+ })
123
+
124
+ it('returns true for short flags', () => {
125
+ expect(hasFlags(['-n', 'x'])).toBe(true)
126
+ })
127
+
128
+ it('returns false when no flags', () => {
129
+ expect(hasFlags(['positional'])).toBe(false)
130
+ })
131
+
132
+ it('returns false for empty argv', () => {
133
+ expect(hasFlags([])).toBe(false)
134
+ })
135
+ })
136
+
137
+ describe('formatFlagHelp', () => {
138
+ it('includes flag names and descriptions', () => {
139
+ const output = formatFlagHelp(testSchema)
140
+ expect(output).toContain('--name')
141
+ expect(output).toContain('Name')
142
+ expect(output).toContain('(required)')
143
+ })
144
+
145
+ it('includes aliases', () => {
146
+ const output = formatFlagHelp(testSchema)
147
+ expect(output).toContain('-n')
148
+ })
149
+
150
+ it('includes defaults', () => {
151
+ const output = formatFlagHelp(testSchema)
152
+ expect(output).toContain('[default: 0]')
153
+ expect(output).toContain('[default: false]')
154
+ })
155
+ })
@@ -0,0 +1,233 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * storyboard CLI — unified dev tooling for Storyboard projects.
4
+ *
5
+ * Commands:
6
+ * storyboard dev Start Vite dev server + update proxy
7
+ * storyboard setup Install deps, Caddy, start proxy
8
+ * storyboard proxy start Start or reload Caddy proxy
9
+ * storyboard proxy close Stop Caddy proxy
10
+ * storyboard update:version Update @dfosco/storyboard-* packages to latest
11
+ * storyboard update:beta Update to latest beta
12
+ * storyboard update:alpha Update to latest alpha
13
+ *
14
+ * Aliases: `sb` is equivalent to `storyboard`.
15
+ */
16
+
17
+ import * as p from '@clack/prompts'
18
+ import { readFileSync } from 'fs'
19
+ import { resolve } from 'path'
20
+ import { gettingStartedLines, dim, magenta, cyan, green, bold, yellow } from './intro.js'
21
+
22
+ function getVersion() {
23
+ try {
24
+ const pkg = JSON.parse(readFileSync(resolve(import.meta.dirname, '..', '..', 'package.json'), 'utf8'))
25
+ return pkg.version || '0.0.0'
26
+ } catch {
27
+ return '0.0.0'
28
+ }
29
+ }
30
+
31
+ function helpScreen(version) {
32
+ const d = dim('·')
33
+ const b = dim
34
+ const f = magenta
35
+
36
+ const mascot = [
37
+ ` ${b('╭─────────────────╮')}`,
38
+ ` ${b('│')} ${d} ${f('◠')} ${f('◡')} ${f('◠')} ${d} ${b('│')} ${bold('storyboard')} ${dim(`v${version}`)}`,
39
+ ` ${b('│')} ${d} ${d} ${d} ${d} ${d} ${b('│')} ${dim('A design tool for prototyping')}`,
40
+ ` ${b('╰─────────────────╯')}`,
41
+ ].join('\n')
42
+
43
+ const cmd = (name, desc) => ` ${green(name.padEnd(22))}${desc}`
44
+
45
+ const gettingStarted = [
46
+ '',
47
+ ...gettingStartedLines(),
48
+ ].join('\n')
49
+
50
+ const commands = [
51
+ '',
52
+ ` ${bold('All commands:')}`,
53
+ '',
54
+ ` ${bold(cyan('Development'))}`,
55
+ cmd('dev', 'Start Vite dev server + update proxy'),
56
+ cmd('dev [branch]', 'Start dev for a specific worktree/branch'),
57
+ cmd('server list', 'List running dev servers'),
58
+ cmd('server start [wt]', 'Start dev server for a worktree'),
59
+ cmd('server stop <wt|ID>', 'Stop a dev server'),
60
+ cmd('code [branch]', 'Open a worktree in VS Code'),
61
+ cmd('exit', 'Stop all dev servers and proxy'),
62
+ '',
63
+ ` ${bold(cyan('Create'))}`,
64
+ cmd('create', 'Interactive creation picker'),
65
+ cmd('create prototype', 'Create a prototype'),
66
+ cmd('create canvas', 'Create a canvas'),
67
+ cmd('create flow', 'Create a flow for a prototype'),
68
+ cmd('create page', 'Create a page in a prototype'),
69
+ '',
70
+ ` ${bold(cyan('Canvas'))}`,
71
+ cmd('canvas add <type>', 'Add widget to a canvas'),
72
+ ` ${dim('types: sticky-note, markdown, prototype')}`,
73
+ cmd('canvas update <id>', 'Update a widget\'s props or position'),
74
+ cmd('canvas read [name]', 'Read canvas state and list widgets'),
75
+ cmd('canvas batch', 'Execute multiple canvas operations in one call'),
76
+ cmd('compact [name]', 'Compact canvas JSONL files (removes bloat)'),
77
+ cmd('compact --all', 'Force compact all canvases'),
78
+ '',
79
+ ` ${bold(cyan('Terminal'))}`,
80
+ cmd('terminal', 'Browse and manage terminal sessions'),
81
+ cmd('terminal start', 'Launch the terminal welcome prompt'),
82
+ cmd('terminal close --id <name>', 'Archive a session ' + dim('(alias: archive)')),
83
+ cmd('terminal open --id <name>', 'Attach to a session'),
84
+ cmd('terminal remove --id <name>', 'Permanently destroy a session'),
85
+ cmd('terminal read <id>', 'Read terminal buffer ' + dim('(+ --length N)')),
86
+ cmd('terminal --all', 'Show sessions across all branches'),
87
+ cmd('terminal reset', 'Kill tmux server, clear registry & snapshots'),
88
+ '',
89
+ ` ${dim('Inside a storyboard terminal, shortcuts are available:')}`,
90
+ cmd('start', 'Open the welcome screen'),
91
+ cmd('start <agent>', 'Launch an agent ' + dim('(copilot, claude, codex)')),
92
+ cmd('<agent>', 'Shorthand for start <agent> ' + dim('(accepts extra flags)')),
93
+ '',
94
+ ` ${bold(cyan('Setup'))}`,
95
+ cmd('setup', 'Install deps, Caddy proxy, start proxy'),
96
+ cmd('setup --skip-branch', 'Non-interactive setup (skip branch prompt)'),
97
+ cmd('setup --branch=<name>', 'Setup + switch to a branch'),
98
+ cmd('branch', 'Switch to a branch (interactive worktree guide)'),
99
+ cmd('branch <name>', 'Switch to a specific branch directly'),
100
+ cmd('branch --worktree=<name>', 'Non-interactive branch switch'),
101
+ cmd('proxy start', 'Start or reload Caddy proxy'),
102
+ cmd('proxy close', 'Stop Caddy proxy'),
103
+ '',
104
+ ` ${bold(cyan('Updates'))}`,
105
+ cmd('update', 'Update storyboard packages to latest'),
106
+ cmd('update:<tag>', 'Update to a specific tag ' + dim('(beta, alpha, ...)')),
107
+ '',
108
+ ` ${dim('All create commands accept --flags for non-interactive use.')}`,
109
+ ` ${dim('Run')} ${yellow('npx storyboard create <type> --help')} ${dim('for flag details.')}`,
110
+ '',
111
+ ` ${dim('Usage:')} ${yellow('npx storyboard')} ${dim('<command>')}`,
112
+ ` ${dim('Alias:')} ${yellow('npx sb')} ${dim('<command>')}`,
113
+ ].join('\n')
114
+
115
+ return `\n${mascot}\n${gettingStarted}\n${commands}\n`
116
+ }
117
+
118
+ const command = process.argv[2]
119
+
120
+ switch (command) {
121
+ case 'dev':
122
+ import('./dev.js')
123
+ break
124
+ case 'setup':
125
+ import('./setup.js')
126
+ break
127
+ case 'branch':
128
+ import('./branch.js')
129
+ break
130
+ case 'proxy':
131
+ import('./proxy.js')
132
+ break
133
+ case 'create':
134
+ import('./create.js')
135
+ break
136
+ case 'compact':
137
+ import('./compact.js')
138
+ break
139
+ case 'canvas':
140
+ if (process.argv[3] === 'add') {
141
+ import('./canvasAdd.js')
142
+ } else if (process.argv[3] === 'update') {
143
+ import('./canvasUpdate.js')
144
+ } else if (process.argv[3] === 'read' || !process.argv[3]) {
145
+ import('./canvasRead.js')
146
+ } else if (process.argv[3] === 'bounds') {
147
+ import('./canvasBounds.js')
148
+ } else if (process.argv[3] === 'batch') {
149
+ import('./canvasBatch.js')
150
+ } else {
151
+ const version = getVersion()
152
+ console.log(helpScreen(version))
153
+ p.log.error(`Unknown canvas subcommand: ${bold(process.argv[3] || '(none)')}`)
154
+ process.exit(1)
155
+ }
156
+ break
157
+ case 'exit':
158
+ import('./exit.js')
159
+ break
160
+ case 'terminal':
161
+ if (process.argv[3] === 'start') {
162
+ import('./terminal-welcome.js')
163
+ } else if (process.argv[3] === '--help' || process.argv[3] === 'help') {
164
+ const cmd = (name, desc) => ` ${green(name.padEnd(36))}${desc}`
165
+ const cmds = [
166
+ ` ${bold(cyan('Terminal commands'))}`,
167
+ cmd('terminal', 'Browse and manage terminal sessions (interactive)'),
168
+ cmd('terminal start', 'Launch the terminal welcome prompt'),
169
+ cmd('terminal close --id <name>', 'Archive a session'),
170
+ cmd('terminal open --id <name>', 'Attach to a session'),
171
+ cmd('terminal remove --id <name>', 'Permanently destroy a session'),
172
+ cmd('terminal reset', 'Kill tmux server, clear registry & snapshots'),
173
+ '',
174
+ ` ${bold(cyan('Messaging'))}`,
175
+ cmd('terminal send <id> "msg"', 'Send a message to a terminal'),
176
+ cmd('terminal send --connected "msg"', 'Send to connected peer'),
177
+ cmd('terminal output --summary "..."', 'Save latest output (+ --content)'),
178
+ cmd('terminal status <widgetId>', 'Check terminal status'),
179
+ cmd('terminal read <widgetId>', 'Read terminal buffer (+ --length N)'),
180
+ ].join('\n')
181
+ console.log(`\n${cmds}\n`)
182
+ } else if (process.argv[3] === 'close' || process.argv[3] === 'archive') {
183
+ import('./terminal-commands.js')
184
+ } else if (process.argv[3] === 'open') {
185
+ import('./terminal-commands.js')
186
+ } else if (process.argv[3] === 'remove') {
187
+ import('./terminal-commands.js')
188
+ } else if (process.argv[3] === 'send') {
189
+ import('./terminal-messaging.js').then(m => m.handleSend())
190
+ } else if (process.argv[3] === 'output') {
191
+ import('./terminal-messaging.js').then(m => m.handleOutput())
192
+ } else if (process.argv[3] === 'status') {
193
+ import('./terminal-messaging.js').then(m => m.handleStatus())
194
+ } else if (process.argv[3] === 'read') {
195
+ import('./terminal-messaging.js').then(m => m.handleRead())
196
+ } else {
197
+ // Default: session browser (formerly `storyboard sessions`)
198
+ import('./sessions.js')
199
+ }
200
+ break
201
+ case 'sessions':
202
+ // Backwards compat alias
203
+ import('./sessions.js')
204
+ break
205
+ case 'terminal-welcome':
206
+ // Internal alias used by terminal-server
207
+ import('./terminal-welcome.js')
208
+ break
209
+ case 'server':
210
+ import('./server.js')
211
+ break
212
+ case 'agent':
213
+ import('./agent.js')
214
+ break
215
+ case 'code':
216
+ import('./code.js')
217
+ break
218
+ default: {
219
+ if (command === 'update' || (command && command.startsWith('update:'))) {
220
+ import('./updateVersion.js')
221
+ break
222
+ }
223
+ const version = getVersion()
224
+
225
+ if (command) {
226
+ console.log(helpScreen(version))
227
+ p.log.error(`Unknown command: ${bold(command)}`)
228
+ process.exit(1)
229
+ }
230
+
231
+ console.log(helpScreen(version))
232
+ }
233
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Single source of truth for CLI getting-started content.
3
+ * Used by both `storyboard setup` and the help screen (`storyboard`).
4
+ */
5
+
6
+ // ANSI helpers — shared across CLI modules
7
+ export const dim = (s) => `\x1b[2m${s}\x1b[0m`
8
+ export const magenta = (s) => `\x1b[35m${s}\x1b[0m`
9
+ export const cyan = (s) => `\x1b[36m${s}\x1b[0m`
10
+ export const green = (s) => `\x1b[32m${s}\x1b[0m`
11
+ export const bold = (s) => `\x1b[1m${s}\x1b[0m`
12
+ export const white = (s) => `\x1b[97m${s}\x1b[0m`
13
+ export const yellow = (s) => `\x1b[33m${s}\x1b[0m`
14
+
15
+ /**
16
+ * Returns the getting-started intro lines as an array of strings.
17
+ * @param {object} [opts]
18
+ * @param {string} [opts.indent=' '] Prefix for each non-empty line
19
+ */
20
+ export function gettingStartedLines({ indent = ' ' } = {}) {
21
+ const i = indent
22
+ return [
23
+ `${i}Welcome! Storyboard is a design tool to build and`,
24
+ `${i}collaborate on prototypes. Here's how to get started:`,
25
+ '',
26
+ `${i} ${green('npx storyboard dev')} Start developing locally`,
27
+ `${i} ${green('npx storyboard create prototype')} Create a prototype`,
28
+ `${i} ${green('npx storyboard create canvas')} Create a canvas`,
29
+ `${i} ${green('npx storyboard create component')} Create a component (.story.jsx)`,
30
+ `${i} ${green('npx storyboard canvas add sticky-note')} Add a widget to a canvas`,
31
+ '',
32
+ `${i} ${dim('Using an AI assistant? You can also ask it to')}`,
33
+ `${i} ${dim('"create a prototype", "create a canvas" or "create a component" for you!')}`,
34
+ '',
35
+ `${i} ${dim('Docs:')} ${cyan('https://github.com/dfosco/storyboard/blob/main/README.md')}`,
36
+ ]
37
+ }