@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,265 @@
1
+ ---
2
+ name: mocking
3
+ description: Mock functions, modules, timers, and dates with vi utilities
4
+ ---
5
+
6
+ # Mocking
7
+
8
+ ## Mock Functions
9
+
10
+ ```ts
11
+ import { expect, vi } from 'vitest'
12
+
13
+ // Create mock function
14
+ const fn = vi.fn()
15
+ fn('hello')
16
+
17
+ expect(fn).toHaveBeenCalled()
18
+ expect(fn).toHaveBeenCalledWith('hello')
19
+
20
+ // With implementation
21
+ const add = vi.fn((a, b) => a + b)
22
+ expect(add(1, 2)).toBe(3)
23
+
24
+ // Mock return values
25
+ fn.mockReturnValue(42)
26
+ fn.mockReturnValueOnce(1).mockReturnValueOnce(2)
27
+ fn.mockResolvedValue({ data: true })
28
+ fn.mockRejectedValue(new Error('fail'))
29
+
30
+ // Mock implementation
31
+ fn.mockImplementation((x) => x * 2)
32
+ fn.mockImplementationOnce(() => 'first call')
33
+ ```
34
+
35
+ ## Spying on Objects
36
+
37
+ ```ts
38
+ const cart = {
39
+ getTotal: () => 100,
40
+ }
41
+
42
+ const spy = vi.spyOn(cart, 'getTotal')
43
+ cart.getTotal()
44
+
45
+ expect(spy).toHaveBeenCalled()
46
+
47
+ // Mock implementation
48
+ spy.mockReturnValue(200)
49
+ expect(cart.getTotal()).toBe(200)
50
+
51
+ // Restore original
52
+ spy.mockRestore()
53
+ ```
54
+
55
+ ## Module Mocking
56
+
57
+ ```ts
58
+ // vi.mock is hoisted to top of file
59
+ vi.mock('./api', () => ({
60
+ fetchUser: vi.fn(() => ({ id: 1, name: 'Mock' })),
61
+ }))
62
+
63
+ import { fetchUser } from './api'
64
+
65
+ test('mocked module', () => {
66
+ expect(fetchUser()).toEqual({ id: 1, name: 'Mock' })
67
+ })
68
+ ```
69
+
70
+ ### Partial Mock
71
+
72
+ ```ts
73
+ vi.mock('./utils', async (importOriginal) => {
74
+ const actual = await importOriginal()
75
+ return {
76
+ ...actual,
77
+ specificFunction: vi.fn(),
78
+ }
79
+ })
80
+ ```
81
+
82
+ ### Auto-mock with Spy
83
+
84
+ ```ts
85
+ // Keep implementation but spy on calls
86
+ vi.mock('./calculator', { spy: true })
87
+
88
+ import { add } from './calculator'
89
+
90
+ test('spy on module', () => {
91
+ const result = add(1, 2) // Real implementation
92
+ expect(result).toBe(3)
93
+ expect(add).toHaveBeenCalledWith(1, 2)
94
+ })
95
+ ```
96
+
97
+ ### Manual Mocks (__mocks__)
98
+
99
+ ```
100
+ src/
101
+ __mocks__/
102
+ axios.ts # Mocks 'axios'
103
+ api/
104
+ __mocks__/
105
+ client.ts # Mocks './client'
106
+ client.ts
107
+ ```
108
+
109
+ ```ts
110
+ // Just call vi.mock with no factory
111
+ vi.mock('axios')
112
+ vi.mock('./api/client')
113
+ ```
114
+
115
+ ## Dynamic Mocking (vi.doMock)
116
+
117
+ Not hoisted - use for dynamic imports:
118
+
119
+ ```ts
120
+ test('dynamic mock', async () => {
121
+ vi.doMock('./config', () => ({
122
+ apiUrl: 'http://test.local',
123
+ }))
124
+
125
+ const { apiUrl } = await import('./config')
126
+ expect(apiUrl).toBe('http://test.local')
127
+
128
+ vi.doUnmock('./config')
129
+ })
130
+ ```
131
+
132
+ ## Mock Timers
133
+
134
+ ```ts
135
+ import { afterEach, beforeEach, vi } from 'vitest'
136
+
137
+ beforeEach(() => {
138
+ vi.useFakeTimers()
139
+ })
140
+
141
+ afterEach(() => {
142
+ vi.useRealTimers()
143
+ })
144
+
145
+ test('timers', () => {
146
+ const fn = vi.fn()
147
+ setTimeout(fn, 1000)
148
+
149
+ expect(fn).not.toHaveBeenCalled()
150
+
151
+ vi.advanceTimersByTime(1000)
152
+ expect(fn).toHaveBeenCalled()
153
+ })
154
+
155
+ // Other timer methods
156
+ vi.runAllTimers() // Run all pending timers
157
+ vi.runOnlyPendingTimers() // Run only currently pending
158
+ vi.advanceTimersToNextTimer() // Advance to next timer
159
+ ```
160
+
161
+ ### Async Timer Methods
162
+
163
+ ```ts
164
+ test('async timers', async () => {
165
+ vi.useFakeTimers()
166
+
167
+ let resolved = false
168
+ setTimeout(() => Promise.resolve().then(() => { resolved = true }), 100)
169
+
170
+ await vi.advanceTimersByTimeAsync(100)
171
+ expect(resolved).toBe(true)
172
+ })
173
+ ```
174
+
175
+ ## Mock Dates
176
+
177
+ ```ts
178
+ vi.setSystemTime(new Date('2024-01-01'))
179
+ expect(new Date().getFullYear()).toBe(2024)
180
+
181
+ vi.useRealTimers() // Restore
182
+ ```
183
+
184
+ ## Mock Globals
185
+
186
+ ```ts
187
+ vi.stubGlobal('fetch', vi.fn(() =>
188
+ Promise.resolve({ json: () => ({ data: 'mock' }) })
189
+ ))
190
+
191
+ // Restore
192
+ vi.unstubAllGlobals()
193
+ ```
194
+
195
+ ## Mock Environment Variables
196
+
197
+ ```ts
198
+ vi.stubEnv('API_KEY', 'test-key')
199
+ expect(import.meta.env.API_KEY).toBe('test-key')
200
+
201
+ // Restore
202
+ vi.unstubAllEnvs()
203
+ ```
204
+
205
+ ## Clearing Mocks
206
+
207
+ ```ts
208
+ const fn = vi.fn()
209
+ fn()
210
+
211
+ fn.mockClear() // Clear call history
212
+ fn.mockReset() // Clear history + implementation
213
+ fn.mockRestore() // Restore original (for spies)
214
+
215
+ // Global
216
+ vi.clearAllMocks()
217
+ vi.resetAllMocks()
218
+ vi.restoreAllMocks()
219
+ ```
220
+
221
+ ## Config Auto-Reset
222
+
223
+ ```ts
224
+ // vitest.config.ts
225
+ defineConfig({
226
+ test: {
227
+ clearMocks: true, // Clear before each test
228
+ mockReset: true, // Reset before each test
229
+ restoreMocks: true, // Restore after each test
230
+ unstubEnvs: true, // Restore env vars
231
+ unstubGlobals: true, // Restore globals
232
+ },
233
+ })
234
+ ```
235
+
236
+ ## Hoisted Variables for Mocks
237
+
238
+ ```ts
239
+ const mockFn = vi.hoisted(() => vi.fn())
240
+
241
+ vi.mock('./module', () => ({
242
+ getData: mockFn,
243
+ }))
244
+
245
+ import { getData } from './module'
246
+
247
+ test('hoisted mock', () => {
248
+ mockFn.mockReturnValue('test')
249
+ expect(getData()).toBe('test')
250
+ })
251
+ ```
252
+
253
+ ## Key Points
254
+
255
+ - `vi.mock` is hoisted - called before imports
256
+ - Use `vi.doMock` for dynamic, non-hoisted mocking
257
+ - Always restore mocks to avoid test pollution
258
+ - Use `{ spy: true }` to keep implementation but track calls
259
+ - `vi.hoisted` lets you reference variables in mock factories
260
+
261
+ <!--
262
+ Source references:
263
+ - https://vitest.dev/guide/mocking.html
264
+ - https://vitest.dev/api/vi.html
265
+ -->
@@ -0,0 +1,207 @@
1
+ ---
2
+ name: snapshot-testing
3
+ description: Snapshot testing with file, inline, and file snapshots
4
+ ---
5
+
6
+ # Snapshot Testing
7
+
8
+ Snapshot tests capture output and compare against stored references.
9
+
10
+ ## Basic Snapshot
11
+
12
+ ```ts
13
+ import { expect, test } from 'vitest'
14
+
15
+ test('snapshot', () => {
16
+ const result = generateOutput()
17
+ expect(result).toMatchSnapshot()
18
+ })
19
+ ```
20
+
21
+ First run creates `.snap` file:
22
+
23
+ ```js
24
+ // __snapshots__/test.spec.ts.snap
25
+ exports['snapshot 1'] = `
26
+ {
27
+ "id": 1,
28
+ "name": "test"
29
+ }
30
+ `
31
+ ```
32
+
33
+ ## Inline Snapshots
34
+
35
+ Stored directly in test file:
36
+
37
+ ```ts
38
+ test('inline snapshot', () => {
39
+ const data = { foo: 'bar' }
40
+ expect(data).toMatchInlineSnapshot()
41
+ })
42
+ ```
43
+
44
+ Vitest updates the test file:
45
+
46
+ ```ts
47
+ test('inline snapshot', () => {
48
+ const data = { foo: 'bar' }
49
+ expect(data).toMatchInlineSnapshot(`
50
+ {
51
+ "foo": "bar",
52
+ }
53
+ `)
54
+ })
55
+ ```
56
+
57
+ ## File Snapshots
58
+
59
+ Compare against explicit file:
60
+
61
+ ```ts
62
+ test('render html', async () => {
63
+ const html = renderComponent()
64
+ await expect(html).toMatchFileSnapshot('./expected/component.html')
65
+ })
66
+ ```
67
+
68
+ ## Snapshot Hints
69
+
70
+ Add descriptive hints:
71
+
72
+ ```ts
73
+ test('multiple snapshots', () => {
74
+ expect(header).toMatchSnapshot('header')
75
+ expect(body).toMatchSnapshot('body content')
76
+ expect(footer).toMatchSnapshot('footer')
77
+ })
78
+ ```
79
+
80
+ ## Object Shape Matching
81
+
82
+ Match partial structure:
83
+
84
+ ```ts
85
+ test('shape snapshot', () => {
86
+ const data = {
87
+ id: Math.random(),
88
+ created: new Date(),
89
+ name: 'test'
90
+ }
91
+
92
+ expect(data).toMatchSnapshot({
93
+ id: expect.any(Number),
94
+ created: expect.any(Date),
95
+ })
96
+ })
97
+ ```
98
+
99
+ ## Error Snapshots
100
+
101
+ ```ts
102
+ test('error message', () => {
103
+ expect(() => {
104
+ throw new Error('Something went wrong')
105
+ }).toThrowErrorMatchingSnapshot()
106
+ })
107
+
108
+ test('inline error', () => {
109
+ expect(() => {
110
+ throw new Error('Bad input')
111
+ }).toThrowErrorMatchingInlineSnapshot(`[Error: Bad input]`)
112
+ })
113
+ ```
114
+
115
+ ## Updating Snapshots
116
+
117
+ ```bash
118
+ # Update all snapshots
119
+ vitest -u
120
+ vitest --update
121
+
122
+ # In watch mode, press 'u' to update failed snapshots
123
+ ```
124
+
125
+ ## Custom Serializers
126
+
127
+ Add custom snapshot formatting:
128
+
129
+ ```ts
130
+ expect.addSnapshotSerializer({
131
+ test(val) {
132
+ return val && typeof val.toJSON === 'function'
133
+ },
134
+ serialize(val, config, indentation, depth, refs, printer) {
135
+ return printer(val.toJSON(), config, indentation, depth, refs)
136
+ },
137
+ })
138
+ ```
139
+
140
+ Or via config:
141
+
142
+ ```ts
143
+ // vitest.config.ts
144
+ defineConfig({
145
+ test: {
146
+ snapshotSerializers: ['./my-serializer.ts'],
147
+ },
148
+ })
149
+ ```
150
+
151
+ ## Snapshot Format Options
152
+
153
+ ```ts
154
+ defineConfig({
155
+ test: {
156
+ snapshotFormat: {
157
+ printBasicPrototype: false, // Don't print Array/Object prototypes
158
+ escapeString: false,
159
+ },
160
+ },
161
+ })
162
+ ```
163
+
164
+ ## Concurrent Test Snapshots
165
+
166
+ Use context's expect:
167
+
168
+ ```ts
169
+ test.concurrent('concurrent 1', async ({ expect }) => {
170
+ expect(await getData()).toMatchSnapshot()
171
+ })
172
+
173
+ test.concurrent('concurrent 2', async ({ expect }) => {
174
+ expect(await getOther()).toMatchSnapshot()
175
+ })
176
+ ```
177
+
178
+ ## Snapshot File Location
179
+
180
+ Default: `__snapshots__/<test-file>.snap`
181
+
182
+ Customize:
183
+
184
+ ```ts
185
+ defineConfig({
186
+ test: {
187
+ resolveSnapshotPath: (testPath, snapExtension) => {
188
+ return testPath.replace('__tests__', '__snapshots__') + snapExtension
189
+ },
190
+ },
191
+ })
192
+ ```
193
+
194
+ ## Key Points
195
+
196
+ - Commit snapshot files to version control
197
+ - Review snapshot changes in code review
198
+ - Use hints for multiple snapshots in one test
199
+ - Use `toMatchFileSnapshot` for large outputs (HTML, JSON)
200
+ - Inline snapshots auto-update in test file
201
+ - Use context's `expect` for concurrent tests
202
+
203
+ <!--
204
+ Source references:
205
+ - https://vitest.dev/guide/snapshot.html
206
+ - https://vitest.dev/api/expect.html#tomatchsnapshot
207
+ -->
@@ -0,0 +1,93 @@
1
+ # Worktree Skill
2
+
3
+ > Triggered by: "create worktree", "new worktree", "worktree for", "worktree"
4
+
5
+ ## What This Does
6
+
7
+ Creates a git worktree for a given branch name inside `worktrees/` and switches into it.
8
+
9
+ ---
10
+
11
+ ## How to Execute
12
+
13
+ When the user asks for a worktree named `<branch-name>`:
14
+
15
+ ### Step 1: Create the worktree
16
+
17
+ If the branch already exists locally or on the remote:
18
+
19
+ ```bash
20
+ git worktree add worktrees/<branch-name> <branch-name>
21
+ ```
22
+
23
+ If the branch does NOT exist yet, create it **from the current branch** (NOT from main):
24
+
25
+ ```bash
26
+ CURRENT_BRANCH=$(git branch --show-current)
27
+ git worktree add worktrees/<branch-name> -b <branch-name> "$CURRENT_BRANCH"
28
+ ```
29
+
30
+ > **⚠️ CRITICAL:** Always pass the current branch as the start-point. Without it, git defaults to HEAD of the main worktree, which may be a completely different branch.
31
+
32
+ ### Step 2: Register a dev-server port
33
+
34
+ Assign a unique port for this worktree so multiple dev servers can run simultaneously.
35
+
36
+ If using `@dfosco/storyboard-core`:
37
+
38
+ ```bash
39
+ node -e "import('@dfosco/storyboard-core/worktree/port').then(m => console.log(m.getPort('<branch-name>')))"
40
+ ```
41
+
42
+ Or if the project has `scripts/worktree-port.js`:
43
+
44
+ ```bash
45
+ node scripts/worktree-port.js <branch-name>
46
+ ```
47
+
48
+ This writes to `worktrees/ports.json` (gitignored). The dev server (`npx storyboard-dev`) reads from this file automatically.
49
+
50
+ ### Step 3: Change into the worktree directory
51
+
52
+ ```bash
53
+ cd worktrees/<branch-name>
54
+ ```
55
+
56
+ All subsequent commands in the session should run from this directory.
57
+
58
+ ### Step 4: Confirm
59
+
60
+ Print the current working directory, branch, and assigned port to confirm:
61
+
62
+ ```bash
63
+ pwd && git branch --show-current
64
+ ```
65
+
66
+ ### Step 5: Start dev server
67
+
68
+ Run the dev server in the worktree. If using the storyboard-dev launcher:
69
+
70
+ ```bash
71
+ npx storyboard-dev
72
+ ```
73
+
74
+ Or if using a custom dev script:
75
+
76
+ ```bash
77
+ npm run dev
78
+ ```
79
+
80
+ The dev server automatically uses the port assigned in Step 2.
81
+
82
+ **Skip this step if the worktree skill was invoked from the ship skill** — ship runs the dev server as its own final step to avoid starting it twice.
83
+
84
+ ---
85
+
86
+ ## Notes
87
+
88
+ - Worktrees live in `worktrees/` at the repo root — this directory is already gitignored.
89
+ - The branch name comes from the user's request (e.g., "create worktree comments-redo" → branch is `comments-redo`).
90
+ - **Always slugify** the branch name (Step 0) before creating the worktree. Dots cause issues with subdomain routing and are replaced with hyphens.
91
+ - If the worktree already exists, inform the user and `cd` into it instead of recreating it.
92
+ - Port assignments are stable — once a worktree gets a port, it keeps it across restarts.
93
+ - To see all assigned ports, check `worktrees/ports.json`.
@@ -0,0 +1,44 @@
1
+ {
2
+ "customDomain": "",
3
+ "repository": {
4
+ "owner": "",
5
+ "name": ""
6
+ },
7
+ "modes": {
8
+ "enabled": false
9
+ },
10
+ "comments": {
11
+ "discussions": {
12
+ "category": "Comments"
13
+ }
14
+ },
15
+ "plugins": {
16
+ "devtools": true
17
+ },
18
+ "workshop": {
19
+ "enabled": false,
20
+ "features": {
21
+ "createPrototype": true,
22
+ "createFlow": true,
23
+ "createCanvas": true
24
+ }
25
+ },
26
+ "featureFlags": {},
27
+ "canvas": {
28
+ "github": {
29
+ "embedBehavior": "link-preview",
30
+ "ghGuard": "copy"
31
+ },
32
+ "terminal": {
33
+ "resizable": false,
34
+ "defaultWidth": 800,
35
+ "defaultHeight": 450
36
+ }
37
+ },
38
+ "customerMode": {
39
+ "enabled": false,
40
+ "hideChrome": false,
41
+ "hideHomepage": false,
42
+ "protoHomepage": ""
43
+ }
44
+ }
@@ -0,0 +1,78 @@
1
+ import { Children } from 'react';
2
+ import Draggable from './Draggable';
3
+ import { findDragId, generateDragId } from './utils';
4
+
5
+ function readInitialPosition(child, pad = 0) {
6
+ const x = Number(child?.props?.['data-tc-x']);
7
+ const y = Number(child?.props?.['data-tc-y']);
8
+ if (Number.isFinite(x) && Number.isFinite(y)) {
9
+ return { x: Math.max(pad, x), y: Math.max(pad, y) };
10
+ }
11
+ return null;
12
+ }
13
+
14
+ /** Read an optional CSS selector that restricts drag to a handle element. */
15
+ function readHandle(child) {
16
+ return child?.props?.['data-tc-handle'] || null;
17
+ }
18
+
19
+ function Canvas({
20
+ children,
21
+ dotted = false,
22
+ grid = false,
23
+ gridSize,
24
+ snapGrid,
25
+ colorMode = 'auto',
26
+ locked = false,
27
+ boundaryPad,
28
+ onDragStart,
29
+ onDrag,
30
+ onDragEnd,
31
+ }) {
32
+ const showDots = dotted || grid;
33
+ const visualGridSize = gridSize;
34
+ const pad = boundaryPad ?? gridSize ?? 0;
35
+ const dotRadius = visualGridSize && visualGridSize < 16 ? 1 : 2;
36
+ const canvasStyle = visualGridSize
37
+ ? {
38
+ '--tc-grid-size': `${visualGridSize}px`,
39
+ '--tc-grid-offset': `${visualGridSize / -2}px`,
40
+ '--tc-dot-radius': `${dotRadius}px`,
41
+ }
42
+ : undefined;
43
+
44
+ return (
45
+ <main
46
+ className="tc-canvas"
47
+ data-dotted={showDots || undefined}
48
+ data-locked={locked || undefined}
49
+ data-color-mode={colorMode !== 'auto' ? colorMode : undefined}
50
+ style={canvasStyle}
51
+ >
52
+ {Children.map(children, (child, index) => {
53
+ const dragId = findDragId(child) ?? generateDragId(child, index);
54
+ const initialPosition = readInitialPosition(child, pad);
55
+ const handle = readHandle(child);
56
+ return (
57
+ <Draggable
58
+ key={dragId}
59
+ gridSize={gridSize}
60
+ snapGrid={snapGrid}
61
+ dragId={dragId}
62
+ initialPosition={initialPosition}
63
+ onDragStart={onDragStart}
64
+ onDrag={onDrag}
65
+ onDragEnd={onDragEnd}
66
+ handle={handle}
67
+ locked={locked}
68
+ boundaryPad={pad}
69
+ >
70
+ {child}
71
+ </Draggable>
72
+ );
73
+ })}
74
+ </main>
75
+ );
76
+ }
77
+
78
+ export default Canvas;