@dfosco/storyboard-core 4.2.0-beta.2 → 4.2.0-beta.21

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 (414) hide show
  1. package/commandpalette.config.json +109 -24
  2. package/dist/storyboard-ui.css +1 -1
  3. package/dist/storyboard-ui.js +17379 -28568
  4. package/dist/storyboard-ui.js.map +1 -1
  5. package/dist/tailwind.css +1 -1
  6. package/package.json +5 -2
  7. package/scaffold/agents/prompt-agent.agent.md +181 -0
  8. package/scaffold/agents/terminal-agent.agent.md +351 -0
  9. package/scaffold/codex/config.toml +246 -0
  10. package/scaffold/manifest.json +5 -0
  11. package/scaffold/skills/canvas/SKILL.md +5 -4
  12. package/scaffold/skills/ship/SKILL.md +1 -1
  13. package/scaffold/storyboard.config.json +14 -1
  14. package/scaffold/toolbar.config.json +1 -1
  15. package/src/ActionMenuButton.jsx +100 -0
  16. package/src/AutosyncMenuButton.css +67 -0
  17. package/src/AutosyncMenuButton.jsx +241 -0
  18. package/src/BranchSelect.jsx +29 -0
  19. package/src/BranchSelect.module.css +30 -0
  20. package/src/CanvasAgentsMenu.jsx +87 -0
  21. package/src/CanvasCreateMenu.jsx +609 -0
  22. package/src/CanvasSnap.css +27 -0
  23. package/src/CanvasSnap.jsx +51 -0
  24. package/src/CanvasUndoRedo.css +36 -0
  25. package/src/CanvasUndoRedo.jsx +62 -0
  26. package/src/CanvasZoomControl.css +53 -0
  27. package/src/CanvasZoomControl.jsx +49 -0
  28. package/src/CanvasZoomToFit.css +18 -0
  29. package/src/CanvasZoomToFit.jsx +26 -0
  30. package/src/CommandMenu.css +8 -0
  31. package/src/CommandMenu.jsx +286 -0
  32. package/src/CommandPalette.jsx +35 -0
  33. package/src/CommandPaletteTrigger.jsx +25 -0
  34. package/src/CommentsMenuButton.jsx +38 -0
  35. package/src/CoreUIBar.css +47 -0
  36. package/src/CoreUIBar.jsx +855 -0
  37. package/src/CreateMenuButton.jsx +116 -0
  38. package/src/HideChromeTrigger.jsx +40 -0
  39. package/src/InspectorPanel.css +109 -0
  40. package/src/InspectorPanel.jsx +629 -0
  41. package/src/PwaInstallBanner.css +42 -0
  42. package/src/PwaInstallBanner.jsx +124 -0
  43. package/src/SidePanel.jsx +260 -0
  44. package/src/ThemeMenuButton.jsx +136 -0
  45. package/src/autosync/server.js +202 -5
  46. package/src/autosync/server.test.js +112 -0
  47. package/src/canvas/__tests__/agent-integration.test.js +593 -0
  48. package/src/canvas/__tests__/helpers/browser.js +95 -0
  49. package/src/canvas/__tests__/helpers/canvas-api.js +129 -0
  50. package/src/canvas/__tests__/helpers/perf.js +118 -0
  51. package/src/canvas/__tests__/helpers/setup.js +176 -0
  52. package/src/canvas/__tests__/helpers/tmux.js +130 -0
  53. package/src/canvas/__tests__/helpers/transcript.js +129 -0
  54. package/src/canvas/__tests__/terminal-integration.test.js +175 -0
  55. package/src/canvas/hot-pool.js +757 -0
  56. package/src/canvas/materializer.js +31 -0
  57. package/src/canvas/materializer.test.js +56 -0
  58. package/src/canvas/selectedWidgets.js +65 -7
  59. package/src/canvas/server.js +1801 -22
  60. package/src/canvas/server.test.js +239 -0
  61. package/src/canvas/terminal-config.js +331 -0
  62. package/src/canvas/terminal-registry.js +38 -0
  63. package/src/canvas/terminal-server.js +1037 -29
  64. package/src/canvas/writeGuard.js +51 -3
  65. package/src/canvasConfig.js +67 -1
  66. package/src/canvasConfig.test.js +79 -1
  67. package/src/cli/agent.js +85 -0
  68. package/src/cli/branch.js +232 -0
  69. package/src/cli/canvasAdd.js +59 -12
  70. package/src/cli/canvasBatch.js +98 -0
  71. package/src/cli/canvasBounds.js +1 -1
  72. package/src/cli/canvasRead.js +1 -1
  73. package/src/cli/canvasUpdate.js +179 -0
  74. package/src/cli/create.js +38 -14
  75. package/src/cli/dev.js +157 -83
  76. package/src/cli/exit.js +23 -24
  77. package/src/cli/index.js +55 -2
  78. package/src/cli/proxy.js +96 -37
  79. package/src/cli/schemas.js +22 -4
  80. package/src/cli/server.js +148 -25
  81. package/src/cli/serverUrl.js +8 -3
  82. package/src/cli/sessions.js +131 -5
  83. package/src/cli/setup.js +109 -11
  84. package/src/cli/terminal-commands.js +16 -8
  85. package/src/cli/terminal-messaging.js +231 -0
  86. package/src/cli/terminal-welcome.js +365 -33
  87. package/src/commandActions.js +1 -0
  88. package/src/commandPaletteConfig.js +9 -0
  89. package/src/comments/auth.js +2 -1
  90. package/src/comments/ui/AuthModal.jsx +114 -0
  91. package/src/comments/ui/CommentWindow.jsx +329 -0
  92. package/src/comments/ui/CommentsDrawer.jsx +102 -0
  93. package/src/comments/ui/Composer.jsx +64 -0
  94. package/src/comments/ui/authModal.test.js +1 -1
  95. package/src/comments/ui/commentWindow.js +16 -17
  96. package/src/comments/ui/commentsDrawer.js +25 -26
  97. package/src/comments/ui/composer.js +23 -24
  98. package/src/comments/ui/index.js +2 -3
  99. package/src/configSchema.js +59 -1
  100. package/src/configStore.js +161 -0
  101. package/src/core-ui-colors.css +12 -0
  102. package/src/devtools.js +17 -19
  103. package/src/devtools.test.js +18 -9
  104. package/src/featureFlags.js +12 -5
  105. package/src/fuzzySearch.test.js +10 -0
  106. package/src/index.js +14 -2
  107. package/src/lib/components/ui/alert/alert-action.jsx +11 -0
  108. package/src/lib/components/ui/alert/alert-description.jsx +11 -0
  109. package/src/lib/components/ui/alert/alert-title.jsx +11 -0
  110. package/src/lib/components/ui/alert/alert.jsx +25 -0
  111. package/src/lib/components/ui/alert/index.js +15 -15
  112. package/src/lib/components/ui/avatar/avatar-badge.jsx +22 -0
  113. package/src/lib/components/ui/avatar/avatar-fallback.jsx +18 -0
  114. package/src/lib/components/ui/avatar/avatar-group-count.jsx +19 -0
  115. package/src/lib/components/ui/avatar/avatar-group.jsx +19 -0
  116. package/src/lib/components/ui/avatar/avatar-image.jsx +15 -0
  117. package/src/lib/components/ui/avatar/avatar.jsx +19 -0
  118. package/src/lib/components/ui/avatar/index.js +20 -20
  119. package/src/lib/components/ui/badge/badge.jsx +31 -0
  120. package/src/lib/components/ui/badge/index.js +2 -2
  121. package/src/lib/components/ui/button/button.jsx +100 -0
  122. package/src/lib/components/ui/button/index.js +9 -9
  123. package/src/lib/components/ui/card/card-action.jsx +11 -0
  124. package/src/lib/components/ui/card/card-content.jsx +11 -0
  125. package/src/lib/components/ui/card/card-description.jsx +11 -0
  126. package/src/lib/components/ui/card/card-footer.jsx +11 -0
  127. package/src/lib/components/ui/card/card-header.jsx +19 -0
  128. package/src/lib/components/ui/card/card-title.jsx +11 -0
  129. package/src/lib/components/ui/card/card.jsx +17 -0
  130. package/src/lib/components/ui/card/index.js +23 -23
  131. package/src/lib/components/ui/checkbox/checkbox.jsx +29 -0
  132. package/src/lib/components/ui/checkbox/index.js +5 -5
  133. package/src/lib/components/ui/collapsible/collapsible-content.jsx +7 -0
  134. package/src/lib/components/ui/collapsible/collapsible-trigger.jsx +7 -0
  135. package/src/lib/components/ui/collapsible/collapsible.jsx +7 -0
  136. package/src/lib/components/ui/collapsible/index.js +11 -11
  137. package/src/lib/components/ui/dialog/dialog-close.jsx +7 -0
  138. package/src/lib/components/ui/dialog/dialog-content.jsx +34 -0
  139. package/src/lib/components/ui/dialog/dialog-description.jsx +15 -0
  140. package/src/lib/components/ui/dialog/dialog-footer.jsx +23 -0
  141. package/src/lib/components/ui/dialog/dialog-header.jsx +11 -0
  142. package/src/lib/components/ui/dialog/dialog-overlay.jsx +15 -0
  143. package/src/lib/components/ui/dialog/dialog-portal.jsx +4 -0
  144. package/src/lib/components/ui/dialog/dialog-title.jsx +15 -0
  145. package/src/lib/components/ui/dialog/dialog-trigger.jsx +7 -0
  146. package/src/lib/components/ui/dialog/dialog.jsx +4 -0
  147. package/src/lib/components/ui/dialog/index.js +32 -32
  148. package/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.jsx +8 -0
  149. package/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.jsx +30 -0
  150. package/src/lib/components/ui/dropdown-menu/dropdown-menu-content.jsx +22 -0
  151. package/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.jsx +16 -0
  152. package/src/lib/components/ui/dropdown-menu/dropdown-menu-group.jsx +7 -0
  153. package/src/lib/components/ui/dropdown-menu/dropdown-menu-item.jsx +20 -0
  154. package/src/lib/components/ui/dropdown-menu/dropdown-menu-label.jsx +17 -0
  155. package/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.jsx +4 -0
  156. package/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.jsx +7 -0
  157. package/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.jsx +29 -0
  158. package/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.jsx +15 -0
  159. package/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.jsx +16 -0
  160. package/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.jsx +15 -0
  161. package/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.jsx +23 -0
  162. package/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.jsx +4 -0
  163. package/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.jsx +7 -0
  164. package/src/lib/components/ui/dropdown-menu/dropdown-menu.jsx +4 -0
  165. package/src/lib/components/ui/dropdown-menu/index.js +52 -52
  166. package/src/lib/components/ui/input/index.js +5 -5
  167. package/src/lib/components/ui/input/input.jsx +19 -0
  168. package/src/lib/components/ui/label/index.js +5 -5
  169. package/src/lib/components/ui/label/label.jsx +19 -0
  170. package/src/lib/components/ui/panel/index.js +21 -21
  171. package/src/lib/components/ui/panel/panel-body.jsx +11 -0
  172. package/src/lib/components/ui/panel/panel-close.jsx +16 -0
  173. package/src/lib/components/ui/panel/panel-content.jsx +29 -0
  174. package/src/lib/components/ui/panel/panel-footer.jsx +11 -0
  175. package/src/lib/components/ui/panel/panel-header.jsx +11 -0
  176. package/src/lib/components/ui/panel/panel-title.jsx +12 -0
  177. package/src/lib/components/ui/panel/panel.jsx +4 -0
  178. package/src/lib/components/ui/popover/index.js +26 -26
  179. package/src/lib/components/ui/popover/popover-close.jsx +7 -0
  180. package/src/lib/components/ui/popover/popover-content.jsx +22 -0
  181. package/src/lib/components/ui/popover/popover-description.jsx +11 -0
  182. package/src/lib/components/ui/popover/popover-header.jsx +11 -0
  183. package/src/lib/components/ui/popover/popover-portal.jsx +4 -0
  184. package/src/lib/components/ui/popover/popover-title.jsx +11 -0
  185. package/src/lib/components/ui/popover/popover-trigger.jsx +8 -0
  186. package/src/lib/components/ui/popover/popover.jsx +4 -0
  187. package/src/lib/components/ui/searchable-list.jsx +159 -0
  188. package/src/lib/components/ui/select/index.js +35 -35
  189. package/src/lib/components/ui/select/select-content.jsx +30 -0
  190. package/src/lib/components/ui/select/select-group-heading.jsx +17 -0
  191. package/src/lib/components/ui/select/select-group.jsx +15 -0
  192. package/src/lib/components/ui/select/select-item.jsx +26 -0
  193. package/src/lib/components/ui/select/select-label.jsx +11 -0
  194. package/src/lib/components/ui/select/select-portal.jsx +4 -0
  195. package/src/lib/components/ui/select/select-scroll-down-button.jsx +18 -0
  196. package/src/lib/components/ui/select/select-scroll-up-button.jsx +18 -0
  197. package/src/lib/components/ui/select/select-separator.jsx +15 -0
  198. package/src/lib/components/ui/select/select-trigger.jsx +25 -0
  199. package/src/lib/components/ui/select/select.jsx +4 -0
  200. package/src/lib/components/ui/separator/index.js +5 -5
  201. package/src/lib/components/ui/separator/separator.jsx +22 -0
  202. package/src/lib/components/ui/sheet/index.js +32 -32
  203. package/src/lib/components/ui/sheet/sheet-close.jsx +7 -0
  204. package/src/lib/components/ui/sheet/sheet-content.jsx +35 -0
  205. package/src/lib/components/ui/sheet/sheet-description.jsx +15 -0
  206. package/src/lib/components/ui/sheet/sheet-footer.jsx +11 -0
  207. package/src/lib/components/ui/sheet/sheet-header.jsx +11 -0
  208. package/src/lib/components/ui/sheet/sheet-overlay.jsx +15 -0
  209. package/src/lib/components/ui/sheet/sheet-portal.jsx +4 -0
  210. package/src/lib/components/ui/sheet/sheet-title.jsx +15 -0
  211. package/src/lib/components/ui/sheet/sheet-trigger.jsx +7 -0
  212. package/src/lib/components/ui/sheet/sheet.jsx +4 -0
  213. package/src/lib/components/ui/textarea/index.js +5 -5
  214. package/src/lib/components/ui/textarea/textarea.jsx +18 -0
  215. package/src/lib/components/ui/toggle/index.js +6 -9
  216. package/src/lib/components/ui/toggle/toggle.jsx +36 -0
  217. package/src/lib/components/ui/toggle-group/index.js +8 -8
  218. package/src/lib/components/ui/toggle-group/toggle-group-item.jsx +29 -0
  219. package/src/lib/components/ui/toggle-group/toggle-group.jsx +43 -0
  220. package/src/lib/components/ui/tooltip/index.js +3 -3
  221. package/src/lib/components/ui/tooltip/tooltip-content.jsx +21 -0
  222. package/src/lib/components/ui/tooltip/tooltip-trigger.jsx +23 -0
  223. package/src/lib/components/ui/tooltip/tooltip.jsx +11 -0
  224. package/src/lib/components/ui/trigger-button/index.js +3 -3
  225. package/src/lib/components/ui/trigger-button/trigger-button.css +38 -0
  226. package/src/lib/components/ui/trigger-button/trigger-button.jsx +63 -0
  227. package/src/logger/devLogger.js +238 -0
  228. package/src/logger/devLogger.test.js +193 -0
  229. package/src/modes.test.js +4 -4
  230. package/src/mountStoryboardCore.js +123 -27
  231. package/src/paletteProviders.js +3 -0
  232. package/src/paletteProviders.test.js +2 -2
  233. package/src/server/index.js +98 -36
  234. package/src/sidepanel.css +214 -0
  235. package/src/styles/tailwind.css +1 -1
  236. package/src/svelte-plugin-ui/__tests__/ModeSwitch.test.ts +8 -8
  237. package/src/svelte-plugin-ui/__tests__/ToolbarShell.test.ts +11 -10
  238. package/src/svelte-plugin-ui/components/Icon.css +11 -0
  239. package/src/svelte-plugin-ui/components/Icon.jsx +281 -0
  240. package/src/svelte-plugin-ui/components/ModeSwitch.css +90 -0
  241. package/src/svelte-plugin-ui/components/ModeSwitch.jsx +47 -0
  242. package/src/svelte-plugin-ui/components/ToolbarShell.css +80 -0
  243. package/src/svelte-plugin-ui/components/ToolbarShell.jsx +84 -0
  244. package/src/svelte-plugin-ui/components/Viewfinder.css +412 -0
  245. package/src/svelte-plugin-ui/components/Viewfinder.jsx +512 -0
  246. package/src/svelte-plugin-ui/mount.ts +12 -16
  247. package/src/toolRegistry.js +4 -4
  248. package/src/toolbarConfigStore.js +30 -0
  249. package/src/tools/handlers/autosync.js +1 -1
  250. package/src/tools/handlers/canvasAddWidget.js +1 -1
  251. package/src/tools/handlers/canvasAgents.js +19 -0
  252. package/src/tools/handlers/canvasToolbar.js +8 -8
  253. package/src/tools/handlers/commandPalette.js +9 -0
  254. package/src/tools/handlers/comments.js +1 -1
  255. package/src/tools/handlers/create.js +1 -1
  256. package/src/tools/handlers/devtools.js +16 -0
  257. package/src/tools/handlers/devtools.test.js +38 -0
  258. package/src/tools/handlers/flows.js +1 -1
  259. package/src/tools/handlers/hideChrome.js +9 -0
  260. package/src/tools/handlers/paletteTheme.js +35 -0
  261. package/src/tools/handlers/theme.js +1 -1
  262. package/src/tools/registry.js +4 -1
  263. package/src/tools/surfaces/commandList.js +3 -3
  264. package/src/tools/surfaces/mainToolbar.js +3 -3
  265. package/src/tools/surfaces/registry.js +4 -4
  266. package/src/ui/design-modes.ts +2 -2
  267. package/src/ui/viewfinder.ts +1 -1
  268. package/src/vite/server-plugin.js +242 -60
  269. package/src/workshop/features/createCanvas/CreateCanvasForm.jsx +260 -0
  270. package/src/workshop/features/createCanvas/index.js +1 -1
  271. package/src/workshop/features/createFlow/CreateFlowForm.jsx +334 -0
  272. package/src/workshop/features/createFlow/index.js +1 -1
  273. package/src/workshop/features/createPage/CreatePageForm.jsx +304 -0
  274. package/src/workshop/features/createPage/index.js +1 -1
  275. package/src/workshop/features/createPrototype/CreatePrototypeForm.jsx +289 -0
  276. package/src/workshop/features/createPrototype/index.js +1 -1
  277. package/src/workshop/features/createPrototype/server.js +98 -0
  278. package/src/workshop/features/createStory/CreateStoryForm.jsx +208 -0
  279. package/src/workshop/features/createStory/index.js +1 -1
  280. package/src/workshop/ui/WorkshopPanel.jsx +98 -0
  281. package/src/workshop/ui/mount.ts +1 -1
  282. package/src/worktree/port.js +48 -0
  283. package/src/worktree/serverRegistry.js +120 -0
  284. package/toolbar.config.json +93 -42
  285. package/widgets.config.json +580 -12
  286. package/src/ActionMenuButton.svelte +0 -119
  287. package/src/AutosyncMenuButton.svelte +0 -397
  288. package/src/CanvasCreateMenu.svelte +0 -295
  289. package/src/CanvasSnap.svelte +0 -87
  290. package/src/CanvasUndoRedo.svelte +0 -108
  291. package/src/CanvasZoomControl.svelte +0 -111
  292. package/src/CanvasZoomToFit.svelte +0 -52
  293. package/src/CommandMenu.svelte +0 -249
  294. package/src/CommandPalette.svelte +0 -33
  295. package/src/CommentsMenuButton.svelte +0 -53
  296. package/src/CoreUIBar.svelte +0 -847
  297. package/src/CreateMenuButton.svelte +0 -133
  298. package/src/DocPanel.svelte +0 -299
  299. package/src/InspectorPanel.svelte +0 -745
  300. package/src/PwaInstallBanner.svelte +0 -124
  301. package/src/SidePanel.svelte +0 -480
  302. package/src/ThemeMenuButton.svelte +0 -132
  303. package/src/comments/ui/AuthModal.svelte +0 -108
  304. package/src/comments/ui/CommentWindow.svelte +0 -333
  305. package/src/comments/ui/CommentsDrawer.svelte +0 -96
  306. package/src/comments/ui/Composer.svelte +0 -65
  307. package/src/lib/components/ui/alert/alert-action.svelte +0 -19
  308. package/src/lib/components/ui/alert/alert-description.svelte +0 -22
  309. package/src/lib/components/ui/alert/alert-title.svelte +0 -22
  310. package/src/lib/components/ui/alert/alert.svelte +0 -38
  311. package/src/lib/components/ui/avatar/avatar-badge.svelte +0 -25
  312. package/src/lib/components/ui/avatar/avatar-fallback.svelte +0 -20
  313. package/src/lib/components/ui/avatar/avatar-group-count.svelte +0 -22
  314. package/src/lib/components/ui/avatar/avatar-group.svelte +0 -22
  315. package/src/lib/components/ui/avatar/avatar-image.svelte +0 -17
  316. package/src/lib/components/ui/avatar/avatar.svelte +0 -24
  317. package/src/lib/components/ui/badge/badge.svelte +0 -44
  318. package/src/lib/components/ui/button/button.svelte +0 -108
  319. package/src/lib/components/ui/card/card-action.svelte +0 -21
  320. package/src/lib/components/ui/card/card-content.svelte +0 -19
  321. package/src/lib/components/ui/card/card-description.svelte +0 -19
  322. package/src/lib/components/ui/card/card-footer.svelte +0 -18
  323. package/src/lib/components/ui/card/card-header.svelte +0 -21
  324. package/src/lib/components/ui/card/card-title.svelte +0 -14
  325. package/src/lib/components/ui/card/card.svelte +0 -21
  326. package/src/lib/components/ui/checkbox/checkbox.svelte +0 -39
  327. package/src/lib/components/ui/collapsible/collapsible-content.svelte +0 -7
  328. package/src/lib/components/ui/collapsible/collapsible-trigger.svelte +0 -7
  329. package/src/lib/components/ui/collapsible/collapsible.svelte +0 -11
  330. package/src/lib/components/ui/dialog/dialog-close.svelte +0 -11
  331. package/src/lib/components/ui/dialog/dialog-content.svelte +0 -42
  332. package/src/lib/components/ui/dialog/dialog-description.svelte +0 -17
  333. package/src/lib/components/ui/dialog/dialog-footer.svelte +0 -29
  334. package/src/lib/components/ui/dialog/dialog-header.svelte +0 -19
  335. package/src/lib/components/ui/dialog/dialog-overlay.svelte +0 -17
  336. package/src/lib/components/ui/dialog/dialog-portal.svelte +0 -7
  337. package/src/lib/components/ui/dialog/dialog-title.svelte +0 -17
  338. package/src/lib/components/ui/dialog/dialog-trigger.svelte +0 -11
  339. package/src/lib/components/ui/dialog/dialog.svelte +0 -7
  340. package/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte +0 -16
  341. package/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte +0 -40
  342. package/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte +0 -27
  343. package/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte +0 -18
  344. package/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte +0 -7
  345. package/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte +0 -24
  346. package/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte +0 -20
  347. package/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte +0 -7
  348. package/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte +0 -16
  349. package/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte +0 -34
  350. package/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte +0 -17
  351. package/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte +0 -19
  352. package/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte +0 -17
  353. package/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte +0 -27
  354. package/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte +0 -7
  355. package/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte +0 -7
  356. package/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte +0 -7
  357. package/src/lib/components/ui/input/input.svelte +0 -40
  358. package/src/lib/components/ui/label/label.svelte +0 -20
  359. package/src/lib/components/ui/panel/panel-body.svelte +0 -13
  360. package/src/lib/components/ui/panel/panel-close.svelte +0 -16
  361. package/src/lib/components/ui/panel/panel-content.svelte +0 -33
  362. package/src/lib/components/ui/panel/panel-footer.svelte +0 -13
  363. package/src/lib/components/ui/panel/panel-header.svelte +0 -16
  364. package/src/lib/components/ui/panel/panel-title.svelte +0 -14
  365. package/src/lib/components/ui/panel/panel.svelte +0 -15
  366. package/src/lib/components/ui/popover/popover-close.svelte +0 -7
  367. package/src/lib/components/ui/popover/popover-content.svelte +0 -27
  368. package/src/lib/components/ui/popover/popover-description.svelte +0 -19
  369. package/src/lib/components/ui/popover/popover-header.svelte +0 -19
  370. package/src/lib/components/ui/popover/popover-portal.svelte +0 -7
  371. package/src/lib/components/ui/popover/popover-title.svelte +0 -19
  372. package/src/lib/components/ui/popover/popover-trigger.svelte +0 -17
  373. package/src/lib/components/ui/popover/popover.svelte +0 -7
  374. package/src/lib/components/ui/select/select-content.svelte +0 -40
  375. package/src/lib/components/ui/select/select-group-heading.svelte +0 -19
  376. package/src/lib/components/ui/select/select-group.svelte +0 -17
  377. package/src/lib/components/ui/select/select-item.svelte +0 -38
  378. package/src/lib/components/ui/select/select-label.svelte +0 -18
  379. package/src/lib/components/ui/select/select-portal.svelte +0 -7
  380. package/src/lib/components/ui/select/select-scroll-down-button.svelte +0 -20
  381. package/src/lib/components/ui/select/select-scroll-up-button.svelte +0 -20
  382. package/src/lib/components/ui/select/select-separator.svelte +0 -17
  383. package/src/lib/components/ui/select/select-trigger.svelte +0 -27
  384. package/src/lib/components/ui/select/select.svelte +0 -11
  385. package/src/lib/components/ui/separator/separator.svelte +0 -23
  386. package/src/lib/components/ui/sheet/sheet-close.svelte +0 -7
  387. package/src/lib/components/ui/sheet/sheet-content.svelte +0 -43
  388. package/src/lib/components/ui/sheet/sheet-description.svelte +0 -17
  389. package/src/lib/components/ui/sheet/sheet-footer.svelte +0 -18
  390. package/src/lib/components/ui/sheet/sheet-header.svelte +0 -19
  391. package/src/lib/components/ui/sheet/sheet-overlay.svelte +0 -17
  392. package/src/lib/components/ui/sheet/sheet-portal.svelte +0 -7
  393. package/src/lib/components/ui/sheet/sheet-title.svelte +0 -17
  394. package/src/lib/components/ui/sheet/sheet-trigger.svelte +0 -7
  395. package/src/lib/components/ui/sheet/sheet.svelte +0 -7
  396. package/src/lib/components/ui/textarea/textarea.svelte +0 -21
  397. package/src/lib/components/ui/toggle/toggle.svelte +0 -45
  398. package/src/lib/components/ui/toggle-group/toggle-group-item.svelte +0 -35
  399. package/src/lib/components/ui/toggle-group/toggle-group.svelte +0 -63
  400. package/src/lib/components/ui/tooltip/tooltip-content.svelte +0 -24
  401. package/src/lib/components/ui/tooltip/tooltip-trigger.svelte +0 -27
  402. package/src/lib/components/ui/tooltip/tooltip.svelte +0 -9
  403. package/src/lib/components/ui/trigger-button/trigger-button.svelte +0 -106
  404. package/src/svelte-plugin-ui/components/Icon.svelte +0 -181
  405. package/src/svelte-plugin-ui/components/ModeSwitch.svelte +0 -121
  406. package/src/svelte-plugin-ui/components/ToolbarShell.svelte +0 -150
  407. package/src/svelte-plugin-ui/components/Viewfinder.svelte +0 -1001
  408. package/src/tools/handlers/docs.js +0 -11
  409. package/src/workshop/features/createCanvas/CreateCanvasForm.svelte +0 -139
  410. package/src/workshop/features/createFlow/CreateFlowForm.svelte +0 -314
  411. package/src/workshop/features/createPage/CreatePageForm.svelte +0 -249
  412. package/src/workshop/features/createPrototype/CreatePrototypeForm.svelte +0 -287
  413. package/src/workshop/features/createStory/CreateStoryForm.svelte +0 -161
  414. package/src/workshop/ui/WorkshopPanel.svelte +0 -97
@@ -6,6 +6,8 @@
6
6
  * - Enable/disable autosync per scope (canvas/prototype)
7
7
  * - Direct commit + push on the current branch (scoped files only)
8
8
  * - Push watcher: every 30s runs enabled scopes in relay sequence
9
+ * - Persists state to .storyboard/autosync.json to survive server restarts
10
+ * - Pauses on branch change, resumes when user returns to target branch
9
11
  *
10
12
  * Routes (mounted at /_storyboard/autosync/):
11
13
  * GET /branches — list local git branches (excludes main/master)
@@ -16,7 +18,7 @@
16
18
  */
17
19
 
18
20
  import { execFileSync } from 'node:child_process'
19
- import { existsSync } from 'node:fs'
21
+ import { existsSync, mkdirSync, writeFileSync, readFileSync, renameSync, unlinkSync } from 'node:fs'
20
22
  import { join, resolve } from 'node:path'
21
23
 
22
24
  // ── Module-level watcher state (singleton, survives page reloads) ──
@@ -29,6 +31,8 @@ let lastSyncTime = null
29
31
  let lastError = null
30
32
  let syncing = false
31
33
  let syncingScope = null
34
+ let pausedOnBranchChange = false
35
+ let previousActiveBranch = null
32
36
 
33
37
  let enabledScopes = { canvas: false, prototype: false }
34
38
  let lastSyncByScope = { canvas: null, prototype: null }
@@ -42,6 +46,158 @@ const AUTOSYNC_SCOPES = new Set(SCOPE_ORDER)
42
46
  // Branch names must match git ref format — alphanumeric, hyphens, dots, slashes
43
47
  const BRANCH_NAME_RE = /^[\w][\w.\-/]*$/
44
48
 
49
+ // ── Persistence (.storyboard/autosync.json) ──
50
+
51
+ const PERSIST_DIR = '.storyboard'
52
+ const PERSIST_FILE = 'autosync.json'
53
+
54
+ /**
55
+ * Load persisted autosync state from disk. Returns null on missing/corrupt files.
56
+ */
57
+ export function loadPersistedState(root) {
58
+ const filePath = join(root, PERSIST_DIR, PERSIST_FILE)
59
+ try {
60
+ if (!existsSync(filePath)) return null
61
+ const raw = readFileSync(filePath, 'utf-8')
62
+ const data = JSON.parse(raw)
63
+ if (!data || typeof data !== 'object') return null
64
+ return validatePersistedState(data)
65
+ } catch {
66
+ return null
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Validate loaded state — reject invalid/protected branches and bad types.
72
+ */
73
+ function validatePersistedState(data) {
74
+ const result = {}
75
+
76
+ if (data.targetBranch && isValidBranch(data.targetBranch) && !isProtectedBranch(data.targetBranch)) {
77
+ result.targetBranch = data.targetBranch
78
+ }
79
+ if (data.originalBranch && isValidBranch(data.originalBranch)) {
80
+ result.originalBranch = data.originalBranch
81
+ }
82
+ if (data.previousActiveBranch && isValidBranch(data.previousActiveBranch)) {
83
+ result.previousActiveBranch = data.previousActiveBranch
84
+ }
85
+
86
+ result.pausedOnBranchChange = data.pausedOnBranchChange === true
87
+ result.lastSyncTime = typeof data.lastSyncTime === 'string' ? data.lastSyncTime : null
88
+ result.lastSyncByScope = {
89
+ canvas: typeof data.lastSyncByScope?.canvas === 'string' ? data.lastSyncByScope.canvas : null,
90
+ prototype: typeof data.lastSyncByScope?.prototype === 'string' ? data.lastSyncByScope.prototype : null,
91
+ }
92
+
93
+ if (data.enabledScopes && typeof data.enabledScopes === 'object') {
94
+ result.enabledScopes = {
95
+ canvas: data.enabledScopes.canvas === true,
96
+ prototype: data.enabledScopes.prototype === true,
97
+ }
98
+ } else {
99
+ result.enabledScopes = { canvas: false, prototype: false }
100
+ }
101
+
102
+ // Must have a targetBranch and at least one enabled scope to be restorable
103
+ if (!result.targetBranch || (!result.enabledScopes.canvas && !result.enabledScopes.prototype)) {
104
+ return null
105
+ }
106
+
107
+ return result
108
+ }
109
+
110
+ /**
111
+ * Persist current autosync state to disk (atomic write via tmp + rename).
112
+ */
113
+ export function persistState(root) {
114
+ const dirPath = join(root, PERSIST_DIR)
115
+ const filePath = join(dirPath, PERSIST_FILE)
116
+ const tmpPath = filePath + '.tmp'
117
+ try {
118
+ const currentBranch = getCurrentBranch(root)
119
+ const data = {
120
+ enabledScopes: { ...enabledScopes },
121
+ targetBranch,
122
+ originalBranch,
123
+ previousActiveBranch,
124
+ currentBranch,
125
+ pausedOnBranchChange,
126
+ lastSyncTime,
127
+ lastSyncByScope: { ...lastSyncByScope },
128
+ }
129
+ if (!existsSync(dirPath)) mkdirSync(dirPath, { recursive: true })
130
+ writeFileSync(tmpPath, JSON.stringify(data, null, 2) + '\n', 'utf-8')
131
+ renameSync(tmpPath, filePath)
132
+ } catch {
133
+ // Best-effort persistence — don't break autosync if disk write fails
134
+ }
135
+ }
136
+
137
+ /**
138
+ * Remove persisted state file (on explicit full disable).
139
+ */
140
+ export function clearPersistedState(root) {
141
+ const filePath = join(root, PERSIST_DIR, PERSIST_FILE)
142
+ try {
143
+ if (existsSync(filePath)) unlinkSync(filePath)
144
+ } catch { /* ignore — file may already be gone */ }
145
+ }
146
+
147
+ /**
148
+ * Restore module-level state from a validated persisted snapshot.
149
+ */
150
+ function applyPersistedState(data) {
151
+ enabledScopes = { ...data.enabledScopes }
152
+ targetBranch = data.targetBranch
153
+ originalBranch = data.originalBranch || data.targetBranch
154
+ previousActiveBranch = data.previousActiveBranch || null
155
+ pausedOnBranchChange = data.pausedOnBranchChange || false
156
+ lastSyncTime = data.lastSyncTime || null
157
+ lastSyncByScope = { ...data.lastSyncByScope }
158
+ }
159
+
160
+ // ── Branch reconciliation ──
161
+
162
+ /**
163
+ * Reconcile branch state — pause on drift, resume on return.
164
+ * Called at server startup and on each scheduler tick.
165
+ * Returns true if autosync is active (not paused), false if paused.
166
+ */
167
+ export function reconcileBranch(root) {
168
+ if (!targetBranch || !hasAnyScopeEnabled()) return true
169
+
170
+ let current
171
+ try {
172
+ current = getCurrentBranch(root)
173
+ } catch {
174
+ return false // can't determine branch — don't sync
175
+ }
176
+
177
+ if (current === targetBranch) {
178
+ // Back on the target branch — resume if we were paused
179
+ if (pausedOnBranchChange) {
180
+ pausedOnBranchChange = false
181
+ previousActiveBranch = null
182
+ persistState(root)
183
+ }
184
+ return true
185
+ }
186
+
187
+ // Branch drift — pause if not already paused
188
+ if (!pausedOnBranchChange) {
189
+ pausedOnBranchChange = true
190
+ previousActiveBranch = targetBranch
191
+ persistState(root)
192
+ }
193
+ return false
194
+ }
195
+
196
+ function isProtectedBranch(name) {
197
+ const normalized = String(name || '').toLowerCase()
198
+ return normalized === 'main' || normalized === 'master'
199
+ }
200
+
45
201
  // ── Git helpers (argv-based, no shell) ──
46
202
 
47
203
  function git(args, root) {
@@ -130,11 +286,13 @@ export function matchesAutosyncScope(scope, filePath) {
130
286
  return file === 'src/prototypes' || file.startsWith('src/prototypes/')
131
287
  }
132
288
 
133
- // canvas scope
289
+ // canvas scope — includes canvas data, canvas assets, and public storyboard assets
134
290
  return (
135
291
  file === 'src/canvas' ||
136
292
  file.startsWith('src/canvas/') ||
137
- file.endsWith('.canvas.jsonl')
293
+ file.endsWith('.canvas.jsonl') ||
294
+ file.startsWith('assets/canvas/') ||
295
+ file.startsWith('assets/.storyboard-public/')
138
296
  )
139
297
  }
140
298
 
@@ -200,6 +358,8 @@ function resetRuntimeState({ clearBranch = true } = {}) {
200
358
  enabledScopes = { canvas: false, prototype: false }
201
359
  syncing = false
202
360
  syncingScope = null
361
+ pausedOnBranchChange = false
362
+ previousActiveBranch = null
203
363
  if (clearBranch) {
204
364
  targetBranch = null
205
365
  originalBranch = null
@@ -235,6 +395,8 @@ function buildStatusPayload(root) {
235
395
  lastErrorByScope: { ...lastErrorByScope },
236
396
  syncing,
237
397
  syncingScope,
398
+ pausedOnBranchChange,
399
+ previousActiveBranch,
238
400
  }
239
401
  }
240
402
 
@@ -345,6 +507,8 @@ function runSyncCycle(root, scope) {
345
507
  lastSyncByScope[scope] = nowIso
346
508
  lastErrorByScope[scope] = null
347
509
  lastError = null
510
+ // Persist state after actual commit+push (committed is still true only if push succeeded)
511
+ if (committed) persistState(root)
348
512
  }
349
513
  syncing = false
350
514
  syncingScope = null
@@ -356,6 +520,9 @@ function runSyncCycle(root, scope) {
356
520
  function runRelayCycle(root, scopes = getEnabledScopesInOrder()) {
357
521
  if (syncing || scopes.length === 0) return true
358
522
 
523
+ // Reconcile branch state — pause on drift, resume on return
524
+ if (!reconcileBranch(root)) return true // paused — skip sync
525
+
359
526
  let ok = true
360
527
  let firstRelaySyncTime = null
361
528
 
@@ -390,6 +557,19 @@ function startScheduler(root) {
390
557
  // ── Route handler ──
391
558
 
392
559
  export function createAutosyncHandler({ root, sendJson }) {
560
+ // ── Restore persisted state on server startup ──
561
+ const persisted = loadPersistedState(root)
562
+ if (persisted) {
563
+ applyPersistedState(persisted)
564
+ reconcileBranch(root)
565
+
566
+ // Start scheduler if any scope is enabled — reconcileBranch handles
567
+ // pause/resume on each tick, so the scheduler runs even when paused
568
+ if (hasAnyScopeEnabled()) {
569
+ startScheduler(root)
570
+ }
571
+ }
572
+
393
573
  return async (req, res, { body, path: routePath, method }) => {
394
574
  // GET /branches — list local branches
395
575
  if (routePath === '/branches' && method === 'GET') {
@@ -441,9 +621,18 @@ export function createAutosyncHandler({ root, sendJson }) {
441
621
  const normalizedScope = normalizeAutosyncScope(scope)
442
622
  const hadEnabledScopes = hasAnyScopeEnabled()
443
623
 
624
+ // Allow retargeting when paused on a different branch
444
625
  if (hadEnabledScopes && targetBranch !== branch) {
445
- sendJson(res, 409, { error: `Autosync is active on ${targetBranch}. Disable all scopes before switching branch.` })
446
- return
626
+ if (pausedOnBranchChange) {
627
+ // Clear pause and retarget to the new branch
628
+ pausedOnBranchChange = false
629
+ previousActiveBranch = null
630
+ targetBranch = branch
631
+ originalBranch = currentBranch
632
+ } else {
633
+ sendJson(res, 409, { error: `Autosync is active on ${targetBranch}. Disable all scopes before switching branch.` })
634
+ return
635
+ }
447
636
  }
448
637
 
449
638
  if (!hadEnabledScopes) {
@@ -453,6 +642,9 @@ export function createAutosyncHandler({ root, sendJson }) {
453
642
 
454
643
  enabledScopes[normalizedScope] = true
455
644
  lastErrorByScope[normalizedScope] = null
645
+ pausedOnBranchChange = false
646
+ previousActiveBranch = null
647
+ persistState(root)
456
648
  startScheduler(root)
457
649
 
458
650
  // Immediate first sync for the enabled scope.
@@ -476,7 +668,12 @@ export function createAutosyncHandler({ root, sendJson }) {
476
668
  }
477
669
 
478
670
  if (!hasAnyScopeEnabled()) {
671
+ // Explicit full disable — clear persisted state entirely
479
672
  stopAutosync(root, { clearBranch: true, clearErrors: true })
673
+ clearPersistedState(root)
674
+ } else {
675
+ // Partial disable — persist the remaining state
676
+ persistState(root)
480
677
  }
481
678
 
482
679
  sendJson(res, 200, buildStatusPayload(root))
@@ -1,8 +1,14 @@
1
+ import { mkdirSync, writeFileSync, readFileSync, existsSync, rmSync } from 'node:fs'
2
+ import { join } from 'node:path'
3
+ import { tmpdir } from 'node:os'
1
4
  import {
2
5
  normalizeAutosyncScope,
3
6
  matchesAutosyncScope,
4
7
  filterFilesForAutosyncScope,
5
8
  isRetryablePushError,
9
+ loadPersistedState,
10
+ persistState,
11
+ clearPersistedState,
6
12
  } from './server.js'
7
13
 
8
14
  describe('autosync scope helpers', () => {
@@ -14,6 +20,9 @@ describe('autosync scope helpers', () => {
14
20
  it('matches canvas scope files', () => {
15
21
  expect(matchesAutosyncScope('canvas', 'src/canvas/widgets.canvas.jsonl')).toBe(true)
16
22
  expect(matchesAutosyncScope('canvas', 'src/canvas/notes.txt')).toBe(true)
23
+ expect(matchesAutosyncScope('canvas', 'assets/canvas/images/photo.png')).toBe(true)
24
+ expect(matchesAutosyncScope('canvas', 'assets/canvas/snapshots/snapshot-widget--latest.webp')).toBe(true)
25
+ expect(matchesAutosyncScope('canvas', 'assets/.storyboard-public/terminal-snapshots/agent-abc.snapshot.json')).toBe(true)
17
26
  expect(matchesAutosyncScope('canvas', 'src/prototypes/demo/default.flow.json')).toBe(false)
18
27
  })
19
28
 
@@ -45,3 +54,106 @@ describe('autosync scope helpers', () => {
45
54
  expect(isRetryablePushError('some other git error')).toBe(false)
46
55
  })
47
56
  })
57
+
58
+ describe('autosync persistence', () => {
59
+ let tmpRoot
60
+
61
+ beforeEach(() => {
62
+ tmpRoot = join(tmpdir(), `autosync-test-${Date.now()}-${Math.random().toString(36).slice(2)}`)
63
+ mkdirSync(join(tmpRoot, '.storyboard'), { recursive: true })
64
+ })
65
+
66
+ afterEach(() => {
67
+ try { rmSync(tmpRoot, { recursive: true, force: true }) } catch { /* ignore */ }
68
+ })
69
+
70
+ it('returns null for missing file', () => {
71
+ expect(loadPersistedState(tmpRoot)).toBe(null)
72
+ })
73
+
74
+ it('returns null for corrupt JSON', () => {
75
+ writeFileSync(join(tmpRoot, '.storyboard', 'autosync.json'), 'not json', 'utf-8')
76
+ expect(loadPersistedState(tmpRoot)).toBe(null)
77
+ })
78
+
79
+ it('returns null for empty object', () => {
80
+ writeFileSync(join(tmpRoot, '.storyboard', 'autosync.json'), '{}', 'utf-8')
81
+ expect(loadPersistedState(tmpRoot)).toBe(null)
82
+ })
83
+
84
+ it('returns null when no scopes enabled', () => {
85
+ const data = {
86
+ targetBranch: 'feature/test',
87
+ enabledScopes: { canvas: false, prototype: false },
88
+ }
89
+ writeFileSync(join(tmpRoot, '.storyboard', 'autosync.json'), JSON.stringify(data), 'utf-8')
90
+ expect(loadPersistedState(tmpRoot)).toBe(null)
91
+ })
92
+
93
+ it('returns null for protected branch names', () => {
94
+ const data = {
95
+ targetBranch: 'main',
96
+ enabledScopes: { canvas: true, prototype: false },
97
+ }
98
+ writeFileSync(join(tmpRoot, '.storyboard', 'autosync.json'), JSON.stringify(data), 'utf-8')
99
+ expect(loadPersistedState(tmpRoot)).toBe(null)
100
+ })
101
+
102
+ it('loads valid persisted state', () => {
103
+ const data = {
104
+ targetBranch: 'feature/test',
105
+ originalBranch: 'feature/test',
106
+ enabledScopes: { canvas: true, prototype: false },
107
+ pausedOnBranchChange: false,
108
+ lastSyncTime: '2026-04-26T19:00:00.000Z',
109
+ lastSyncByScope: { canvas: '2026-04-26T19:00:00.000Z', prototype: null },
110
+ }
111
+ writeFileSync(join(tmpRoot, '.storyboard', 'autosync.json'), JSON.stringify(data), 'utf-8')
112
+
113
+ const result = loadPersistedState(tmpRoot)
114
+ expect(result).not.toBe(null)
115
+ expect(result.targetBranch).toBe('feature/test')
116
+ expect(result.enabledScopes.canvas).toBe(true)
117
+ expect(result.enabledScopes.prototype).toBe(false)
118
+ expect(result.pausedOnBranchChange).toBe(false)
119
+ expect(result.lastSyncTime).toBe('2026-04-26T19:00:00.000Z')
120
+ })
121
+
122
+ it('loads paused state with previousActiveBranch', () => {
123
+ const data = {
124
+ targetBranch: 'feature/test',
125
+ originalBranch: 'feature/test',
126
+ previousActiveBranch: 'feature/test',
127
+ enabledScopes: { canvas: true, prototype: true },
128
+ pausedOnBranchChange: true,
129
+ }
130
+ writeFileSync(join(tmpRoot, '.storyboard', 'autosync.json'), JSON.stringify(data), 'utf-8')
131
+
132
+ const result = loadPersistedState(tmpRoot)
133
+ expect(result.pausedOnBranchChange).toBe(true)
134
+ expect(result.previousActiveBranch).toBe('feature/test')
135
+ expect(result.enabledScopes.canvas).toBe(true)
136
+ expect(result.enabledScopes.prototype).toBe(true)
137
+ })
138
+
139
+ it('rejects invalid branch names in persisted state', () => {
140
+ const data = {
141
+ targetBranch: '',
142
+ enabledScopes: { canvas: true },
143
+ }
144
+ writeFileSync(join(tmpRoot, '.storyboard', 'autosync.json'), JSON.stringify(data), 'utf-8')
145
+ expect(loadPersistedState(tmpRoot)).toBe(null)
146
+ })
147
+
148
+ it('clearPersistedState removes the file', () => {
149
+ const filePath = join(tmpRoot, '.storyboard', 'autosync.json')
150
+ writeFileSync(filePath, '{}', 'utf-8')
151
+ expect(existsSync(filePath)).toBe(true)
152
+ clearPersistedState(tmpRoot)
153
+ expect(existsSync(filePath)).toBe(false)
154
+ })
155
+
156
+ it('clearPersistedState is safe when file does not exist', () => {
157
+ expect(() => clearPersistedState(tmpRoot)).not.toThrow()
158
+ })
159
+ })