@dfosco/storyboard-core 4.2.0-beta.3 → 4.2.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.
- package/commandpalette.config.json +109 -24
- package/dist/storyboard-ui.css +1 -1
- package/dist/storyboard-ui.js +16711 -27239
- package/dist/storyboard-ui.js.map +1 -1
- package/dist/tailwind.css +1 -1
- package/package.json +5 -2
- package/scaffold/agents/prompt-agent.agent.md +181 -0
- package/scaffold/agents/terminal-agent.agent.md +351 -0
- package/scaffold/codex/config.toml +246 -0
- package/scaffold/manifest.json +5 -10
- package/scaffold/skills/canvas/SKILL.md +5 -4
- package/scaffold/skills/ship/SKILL.md +1 -1
- package/scaffold/storyboard.config.json +11 -1
- package/src/ActionMenuButton.jsx +103 -0
- package/src/AutosyncMenuButton.css +67 -0
- package/src/AutosyncMenuButton.jsx +242 -0
- package/src/BranchSelect.jsx +29 -0
- package/src/BranchSelect.module.css +30 -0
- package/src/CanvasAgentsMenu.jsx +89 -0
- package/src/CanvasCreateMenu.jsx +611 -0
- package/src/CanvasSnap.css +27 -0
- package/src/CanvasSnap.jsx +51 -0
- package/src/CanvasUndoRedo.css +36 -0
- package/src/CanvasUndoRedo.jsx +62 -0
- package/src/CanvasZoomControl.css +53 -0
- package/src/CanvasZoomControl.jsx +49 -0
- package/src/CanvasZoomToFit.css +18 -0
- package/src/CanvasZoomToFit.jsx +26 -0
- package/src/CommandMenu.css +8 -0
- package/src/CommandMenu.jsx +287 -0
- package/src/CommandPalette.jsx +35 -0
- package/src/CommandPaletteTrigger.jsx +25 -0
- package/src/CommentsMenuButton.jsx +40 -0
- package/src/CoreUIBar.css +47 -0
- package/src/CoreUIBar.jsx +858 -0
- package/src/CreateMenuButton.jsx +117 -0
- package/src/HideChromeTrigger.jsx +40 -0
- package/src/InspectorPanel.css +109 -0
- package/src/InspectorPanel.jsx +632 -0
- package/src/PwaInstallBanner.css +42 -0
- package/src/PwaInstallBanner.jsx +124 -0
- package/src/SidePanel.jsx +261 -0
- package/src/ThemeMenuButton.jsx +139 -0
- package/src/autosync/server.js +202 -5
- package/src/autosync/server.test.js +111 -0
- package/src/canvas/__tests__/agent-integration.test.js +596 -0
- package/src/canvas/__tests__/helpers/browser.js +95 -0
- package/src/canvas/__tests__/helpers/canvas-api.js +129 -0
- package/src/canvas/__tests__/helpers/perf.js +118 -0
- package/src/canvas/__tests__/helpers/setup.js +176 -0
- package/src/canvas/__tests__/helpers/tmux.js +130 -0
- package/src/canvas/__tests__/helpers/transcript.js +132 -0
- package/src/canvas/__tests__/terminal-integration.test.js +177 -0
- package/src/canvas/hot-pool.js +756 -0
- package/src/canvas/materializer.js +31 -0
- package/src/canvas/materializer.test.js +56 -0
- package/src/canvas/selectedWidgets.js +65 -7
- package/src/canvas/server.js +1802 -22
- package/src/canvas/server.test.js +239 -0
- package/src/canvas/terminal-config.js +330 -0
- package/src/canvas/terminal-registry.js +41 -3
- package/src/canvas/terminal-server.js +1098 -37
- package/src/canvas/writeGuard.js +51 -3
- package/src/canvasConfig.js +67 -1
- package/src/canvasConfig.test.js +79 -1
- package/src/cli/agent.js +85 -0
- package/src/cli/branch.js +232 -0
- package/src/cli/canvasAdd.js +61 -14
- package/src/cli/canvasBatch.js +98 -0
- package/src/cli/canvasBounds.js +1 -1
- package/src/cli/canvasRead.js +1 -1
- package/src/cli/canvasUpdate.js +179 -0
- package/src/cli/compact.js +0 -2
- package/src/cli/create.js +40 -16
- package/src/cli/dev.js +158 -84
- package/src/cli/exit.js +23 -24
- package/src/cli/index.js +55 -2
- package/src/cli/proxy.js +96 -37
- package/src/cli/schemas.js +22 -4
- package/src/cli/server.js +149 -26
- package/src/cli/serverUrl.js +8 -3
- package/src/cli/sessions.js +133 -7
- package/src/cli/setup.js +138 -12
- package/src/cli/terminal-commands.js +20 -9
- package/src/cli/terminal-messaging.js +231 -0
- package/src/cli/terminal-welcome.js +449 -34
- package/src/cli/updateVersion.js +1 -1
- package/src/commandActions.js +1 -0
- package/src/commandPaletteConfig.js +9 -0
- package/src/comments/auth.js +2 -1
- package/src/comments/ui/AuthModal.jsx +114 -0
- package/src/comments/ui/CommentWindow.jsx +329 -0
- package/src/comments/ui/CommentsDrawer.jsx +102 -0
- package/src/comments/ui/Composer.jsx +64 -0
- package/src/comments/ui/authModal.test.js +1 -1
- package/src/comments/ui/commentWindow.js +16 -17
- package/src/comments/ui/commentsDrawer.js +25 -26
- package/src/comments/ui/composer.js +23 -24
- package/src/comments/ui/index.js +2 -3
- package/src/configSchema.js +59 -1
- package/src/configStore.js +161 -0
- package/src/core-ui-colors.css +12 -0
- package/src/devtools.js +17 -19
- package/src/devtools.test.js +18 -9
- package/src/featureFlags.js +12 -5
- package/src/fuzzySearch.test.js +10 -0
- package/src/index.js +15 -3
- package/src/lib/components/ui/alert/alert-action.jsx +11 -0
- package/src/lib/components/ui/alert/alert-description.jsx +11 -0
- package/src/lib/components/ui/alert/alert-title.jsx +11 -0
- package/src/lib/components/ui/alert/alert.jsx +25 -0
- package/src/lib/components/ui/alert/index.js +15 -15
- package/src/lib/components/ui/avatar/avatar-badge.jsx +22 -0
- package/src/lib/components/ui/avatar/avatar-fallback.jsx +18 -0
- package/src/lib/components/ui/avatar/avatar-group-count.jsx +19 -0
- package/src/lib/components/ui/avatar/avatar-group.jsx +19 -0
- package/src/lib/components/ui/avatar/avatar-image.jsx +15 -0
- package/src/lib/components/ui/avatar/avatar.jsx +19 -0
- package/src/lib/components/ui/avatar/index.js +20 -20
- package/src/lib/components/ui/badge/badge.jsx +31 -0
- package/src/lib/components/ui/badge/index.js +2 -2
- package/src/lib/components/ui/button/button.jsx +100 -0
- package/src/lib/components/ui/button/index.js +9 -9
- package/src/lib/components/ui/card/card-action.jsx +11 -0
- package/src/lib/components/ui/card/card-content.jsx +11 -0
- package/src/lib/components/ui/card/card-description.jsx +11 -0
- package/src/lib/components/ui/card/card-footer.jsx +11 -0
- package/src/lib/components/ui/card/card-header.jsx +19 -0
- package/src/lib/components/ui/card/card-title.jsx +11 -0
- package/src/lib/components/ui/card/card.jsx +17 -0
- package/src/lib/components/ui/card/index.js +23 -23
- package/src/lib/components/ui/checkbox/checkbox.jsx +29 -0
- package/src/lib/components/ui/checkbox/index.js +5 -5
- package/src/lib/components/ui/collapsible/collapsible-content.jsx +7 -0
- package/src/lib/components/ui/collapsible/collapsible-trigger.jsx +7 -0
- package/src/lib/components/ui/collapsible/collapsible.jsx +7 -0
- package/src/lib/components/ui/collapsible/index.js +11 -11
- package/src/lib/components/ui/dialog/dialog-close.jsx +7 -0
- package/src/lib/components/ui/dialog/dialog-content.jsx +34 -0
- package/src/lib/components/ui/dialog/dialog-description.jsx +15 -0
- package/src/lib/components/ui/dialog/dialog-footer.jsx +23 -0
- package/src/lib/components/ui/dialog/dialog-header.jsx +11 -0
- package/src/lib/components/ui/dialog/dialog-overlay.jsx +15 -0
- package/src/lib/components/ui/dialog/dialog-portal.jsx +4 -0
- package/src/lib/components/ui/dialog/dialog-title.jsx +15 -0
- package/src/lib/components/ui/dialog/dialog-trigger.jsx +7 -0
- package/src/lib/components/ui/dialog/dialog.jsx +4 -0
- package/src/lib/components/ui/dialog/index.js +32 -32
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.jsx +8 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.jsx +30 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-content.jsx +22 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.jsx +16 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-group.jsx +7 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-item.jsx +20 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-label.jsx +17 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.jsx +4 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.jsx +7 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.jsx +29 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.jsx +15 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.jsx +16 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.jsx +15 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.jsx +23 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.jsx +4 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.jsx +7 -0
- package/src/lib/components/ui/dropdown-menu/dropdown-menu.jsx +4 -0
- package/src/lib/components/ui/dropdown-menu/index.js +52 -52
- package/src/lib/components/ui/input/index.js +5 -5
- package/src/lib/components/ui/input/input.jsx +19 -0
- package/src/lib/components/ui/label/index.js +5 -5
- package/src/lib/components/ui/label/label.jsx +19 -0
- package/src/lib/components/ui/panel/index.js +21 -21
- package/src/lib/components/ui/panel/panel-body.jsx +11 -0
- package/src/lib/components/ui/panel/panel-close.jsx +16 -0
- package/src/lib/components/ui/panel/panel-content.jsx +29 -0
- package/src/lib/components/ui/panel/panel-footer.jsx +11 -0
- package/src/lib/components/ui/panel/panel-header.jsx +11 -0
- package/src/lib/components/ui/panel/panel-title.jsx +12 -0
- package/src/lib/components/ui/panel/panel.jsx +4 -0
- package/src/lib/components/ui/popover/index.js +26 -26
- package/src/lib/components/ui/popover/popover-close.jsx +7 -0
- package/src/lib/components/ui/popover/popover-content.jsx +22 -0
- package/src/lib/components/ui/popover/popover-description.jsx +11 -0
- package/src/lib/components/ui/popover/popover-header.jsx +11 -0
- package/src/lib/components/ui/popover/popover-portal.jsx +4 -0
- package/src/lib/components/ui/popover/popover-title.jsx +11 -0
- package/src/lib/components/ui/popover/popover-trigger.jsx +8 -0
- package/src/lib/components/ui/popover/popover.jsx +4 -0
- package/src/lib/components/ui/searchable-list.jsx +160 -0
- package/src/lib/components/ui/select/index.js +35 -35
- package/src/lib/components/ui/select/select-content.jsx +30 -0
- package/src/lib/components/ui/select/select-group-heading.jsx +17 -0
- package/src/lib/components/ui/select/select-group.jsx +15 -0
- package/src/lib/components/ui/select/select-item.jsx +26 -0
- package/src/lib/components/ui/select/select-label.jsx +11 -0
- package/src/lib/components/ui/select/select-portal.jsx +4 -0
- package/src/lib/components/ui/select/select-scroll-down-button.jsx +18 -0
- package/src/lib/components/ui/select/select-scroll-up-button.jsx +18 -0
- package/src/lib/components/ui/select/select-separator.jsx +15 -0
- package/src/lib/components/ui/select/select-trigger.jsx +25 -0
- package/src/lib/components/ui/select/select.jsx +4 -0
- package/src/lib/components/ui/separator/index.js +5 -5
- package/src/lib/components/ui/separator/separator.jsx +22 -0
- package/src/lib/components/ui/sheet/index.js +32 -32
- package/src/lib/components/ui/sheet/sheet-close.jsx +7 -0
- package/src/lib/components/ui/sheet/sheet-content.jsx +35 -0
- package/src/lib/components/ui/sheet/sheet-description.jsx +15 -0
- package/src/lib/components/ui/sheet/sheet-footer.jsx +11 -0
- package/src/lib/components/ui/sheet/sheet-header.jsx +11 -0
- package/src/lib/components/ui/sheet/sheet-overlay.jsx +15 -0
- package/src/lib/components/ui/sheet/sheet-portal.jsx +4 -0
- package/src/lib/components/ui/sheet/sheet-title.jsx +15 -0
- package/src/lib/components/ui/sheet/sheet-trigger.jsx +7 -0
- package/src/lib/components/ui/sheet/sheet.jsx +4 -0
- package/src/lib/components/ui/textarea/index.js +5 -5
- package/src/lib/components/ui/textarea/textarea.jsx +18 -0
- package/src/lib/components/ui/toggle/index.js +6 -9
- package/src/lib/components/ui/toggle/toggle.jsx +36 -0
- package/src/lib/components/ui/toggle-group/index.js +8 -8
- package/src/lib/components/ui/toggle-group/toggle-group-item.jsx +29 -0
- package/src/lib/components/ui/toggle-group/toggle-group.jsx +43 -0
- package/src/lib/components/ui/tooltip/index.js +3 -3
- package/src/lib/components/ui/tooltip/tooltip-content.jsx +21 -0
- package/src/lib/components/ui/tooltip/tooltip-trigger.jsx +23 -0
- package/src/lib/components/ui/tooltip/tooltip.jsx +11 -0
- package/src/lib/components/ui/trigger-button/index.js +3 -3
- package/src/lib/components/ui/trigger-button/trigger-button.css +38 -0
- package/src/lib/components/ui/trigger-button/trigger-button.jsx +63 -0
- package/src/logger/devLogger.js +238 -0
- package/src/logger/devLogger.test.js +193 -0
- package/src/modes.test.js +4 -4
- package/src/mountStoryboardCore.js +133 -35
- package/src/paletteProviders.js +3 -0
- package/src/paletteProviders.test.js +2 -2
- package/src/server/index.js +104 -40
- package/src/sidepanel.css +214 -0
- package/src/smoothCorners.js +1 -1
- package/src/styles/tailwind.css +1 -1
- package/src/svelte-plugin-ui/__tests__/ModeSwitch.test.ts +8 -8
- package/src/svelte-plugin-ui/__tests__/ToolbarShell.test.ts +11 -10
- package/src/svelte-plugin-ui/components/Icon.css +11 -0
- package/src/svelte-plugin-ui/components/Icon.jsx +281 -0
- package/src/svelte-plugin-ui/components/ModeSwitch.css +90 -0
- package/src/svelte-plugin-ui/components/ModeSwitch.jsx +47 -0
- package/src/svelte-plugin-ui/components/ToolbarShell.css +80 -0
- package/src/svelte-plugin-ui/components/ToolbarShell.jsx +84 -0
- package/src/svelte-plugin-ui/components/Viewfinder.css +412 -0
- package/src/svelte-plugin-ui/components/Viewfinder.jsx +513 -0
- package/src/svelte-plugin-ui/mount.ts +12 -16
- package/src/toolRegistry.js +4 -4
- package/src/toolbarConfigStore.js +30 -0
- package/src/tools/handlers/autosync.js +1 -1
- package/src/tools/handlers/canvasAddWidget.js +1 -1
- package/src/tools/handlers/canvasAgents.js +20 -0
- package/src/tools/handlers/canvasToolbar.js +8 -8
- package/src/tools/handlers/commandPalette.js +9 -0
- package/src/tools/handlers/comments.js +2 -2
- package/src/tools/handlers/create.js +1 -1
- package/src/tools/handlers/devtools.js +19 -3
- package/src/tools/handlers/devtools.test.js +38 -0
- package/src/tools/handlers/featureFlags.js +1 -1
- package/src/tools/handlers/flows.js +3 -3
- package/src/tools/handlers/hideChrome.js +9 -0
- package/src/tools/handlers/paletteTheme.js +35 -0
- package/src/tools/handlers/theme.js +1 -1
- package/src/tools/registry.js +4 -1
- package/src/tools/surfaces/commandList.js +3 -3
- package/src/tools/surfaces/mainToolbar.js +3 -3
- package/src/tools/surfaces/registry.js +4 -4
- package/src/ui/design-modes.ts +2 -2
- package/src/ui/viewfinder.ts +1 -1
- package/src/vite/server-plugin.js +243 -61
- package/src/workshop/features/createCanvas/CreateCanvasForm.jsx +260 -0
- package/src/workshop/features/createCanvas/index.js +1 -1
- package/src/workshop/features/createFlow/CreateFlowForm.jsx +334 -0
- package/src/workshop/features/createFlow/index.js +1 -1
- package/src/workshop/features/createPage/CreatePageForm.jsx +304 -0
- package/src/workshop/features/createPage/index.js +1 -1
- package/src/workshop/features/createPrototype/CreatePrototypeForm.jsx +289 -0
- package/src/workshop/features/createPrototype/index.js +1 -1
- package/src/workshop/features/createPrototype/server.js +98 -0
- package/src/workshop/features/createStory/CreateStoryForm.jsx +208 -0
- package/src/workshop/features/createStory/index.js +1 -1
- package/src/workshop/ui/WorkshopPanel.jsx +98 -0
- package/src/workshop/ui/mount.ts +1 -1
- package/src/worktree/port.js +48 -0
- package/src/worktree/serverRegistry.js +120 -0
- package/toolbar.config.json +93 -42
- package/widgets.config.json +580 -12
- package/scaffold/commandpalette.config.json +0 -4
- package/scaffold/toolbar.config.json +0 -4
- package/src/ActionMenuButton.svelte +0 -119
- package/src/AutosyncMenuButton.svelte +0 -397
- package/src/CanvasCreateMenu.svelte +0 -295
- package/src/CanvasSnap.svelte +0 -87
- package/src/CanvasUndoRedo.svelte +0 -108
- package/src/CanvasZoomControl.svelte +0 -111
- package/src/CanvasZoomToFit.svelte +0 -52
- package/src/CommandMenu.svelte +0 -249
- package/src/CommandPalette.svelte +0 -33
- package/src/CommentsMenuButton.svelte +0 -53
- package/src/CoreUIBar.svelte +0 -847
- package/src/CreateMenuButton.svelte +0 -133
- package/src/DocPanel.svelte +0 -299
- package/src/InspectorPanel.svelte +0 -745
- package/src/PwaInstallBanner.svelte +0 -124
- package/src/SidePanel.svelte +0 -480
- package/src/ThemeMenuButton.svelte +0 -132
- package/src/comments/ui/AuthModal.svelte +0 -108
- package/src/comments/ui/CommentWindow.svelte +0 -333
- package/src/comments/ui/CommentsDrawer.svelte +0 -96
- package/src/comments/ui/Composer.svelte +0 -65
- package/src/lib/components/ui/alert/alert-action.svelte +0 -19
- package/src/lib/components/ui/alert/alert-description.svelte +0 -22
- package/src/lib/components/ui/alert/alert-title.svelte +0 -22
- package/src/lib/components/ui/alert/alert.svelte +0 -38
- package/src/lib/components/ui/avatar/avatar-badge.svelte +0 -25
- package/src/lib/components/ui/avatar/avatar-fallback.svelte +0 -20
- package/src/lib/components/ui/avatar/avatar-group-count.svelte +0 -22
- package/src/lib/components/ui/avatar/avatar-group.svelte +0 -22
- package/src/lib/components/ui/avatar/avatar-image.svelte +0 -17
- package/src/lib/components/ui/avatar/avatar.svelte +0 -24
- package/src/lib/components/ui/badge/badge.svelte +0 -44
- package/src/lib/components/ui/button/button.svelte +0 -108
- package/src/lib/components/ui/card/card-action.svelte +0 -21
- package/src/lib/components/ui/card/card-content.svelte +0 -19
- package/src/lib/components/ui/card/card-description.svelte +0 -19
- package/src/lib/components/ui/card/card-footer.svelte +0 -18
- package/src/lib/components/ui/card/card-header.svelte +0 -21
- package/src/lib/components/ui/card/card-title.svelte +0 -14
- package/src/lib/components/ui/card/card.svelte +0 -21
- package/src/lib/components/ui/checkbox/checkbox.svelte +0 -39
- package/src/lib/components/ui/collapsible/collapsible-content.svelte +0 -7
- package/src/lib/components/ui/collapsible/collapsible-trigger.svelte +0 -7
- package/src/lib/components/ui/collapsible/collapsible.svelte +0 -11
- package/src/lib/components/ui/dialog/dialog-close.svelte +0 -11
- package/src/lib/components/ui/dialog/dialog-content.svelte +0 -42
- package/src/lib/components/ui/dialog/dialog-description.svelte +0 -17
- package/src/lib/components/ui/dialog/dialog-footer.svelte +0 -29
- package/src/lib/components/ui/dialog/dialog-header.svelte +0 -19
- package/src/lib/components/ui/dialog/dialog-overlay.svelte +0 -17
- package/src/lib/components/ui/dialog/dialog-portal.svelte +0 -7
- package/src/lib/components/ui/dialog/dialog-title.svelte +0 -17
- package/src/lib/components/ui/dialog/dialog-trigger.svelte +0 -11
- package/src/lib/components/ui/dialog/dialog.svelte +0 -7
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte +0 -16
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte +0 -40
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte +0 -27
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte +0 -18
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte +0 -7
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte +0 -24
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte +0 -20
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte +0 -7
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte +0 -16
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte +0 -34
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte +0 -17
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte +0 -19
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte +0 -17
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte +0 -27
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte +0 -7
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte +0 -7
- package/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte +0 -7
- package/src/lib/components/ui/input/input.svelte +0 -40
- package/src/lib/components/ui/label/label.svelte +0 -20
- package/src/lib/components/ui/panel/panel-body.svelte +0 -13
- package/src/lib/components/ui/panel/panel-close.svelte +0 -16
- package/src/lib/components/ui/panel/panel-content.svelte +0 -33
- package/src/lib/components/ui/panel/panel-footer.svelte +0 -13
- package/src/lib/components/ui/panel/panel-header.svelte +0 -16
- package/src/lib/components/ui/panel/panel-title.svelte +0 -14
- package/src/lib/components/ui/panel/panel.svelte +0 -15
- package/src/lib/components/ui/popover/popover-close.svelte +0 -7
- package/src/lib/components/ui/popover/popover-content.svelte +0 -27
- package/src/lib/components/ui/popover/popover-description.svelte +0 -19
- package/src/lib/components/ui/popover/popover-header.svelte +0 -19
- package/src/lib/components/ui/popover/popover-portal.svelte +0 -7
- package/src/lib/components/ui/popover/popover-title.svelte +0 -19
- package/src/lib/components/ui/popover/popover-trigger.svelte +0 -17
- package/src/lib/components/ui/popover/popover.svelte +0 -7
- package/src/lib/components/ui/select/select-content.svelte +0 -40
- package/src/lib/components/ui/select/select-group-heading.svelte +0 -19
- package/src/lib/components/ui/select/select-group.svelte +0 -17
- package/src/lib/components/ui/select/select-item.svelte +0 -38
- package/src/lib/components/ui/select/select-label.svelte +0 -18
- package/src/lib/components/ui/select/select-portal.svelte +0 -7
- package/src/lib/components/ui/select/select-scroll-down-button.svelte +0 -20
- package/src/lib/components/ui/select/select-scroll-up-button.svelte +0 -20
- package/src/lib/components/ui/select/select-separator.svelte +0 -17
- package/src/lib/components/ui/select/select-trigger.svelte +0 -27
- package/src/lib/components/ui/select/select.svelte +0 -11
- package/src/lib/components/ui/separator/separator.svelte +0 -23
- package/src/lib/components/ui/sheet/sheet-close.svelte +0 -7
- package/src/lib/components/ui/sheet/sheet-content.svelte +0 -43
- package/src/lib/components/ui/sheet/sheet-description.svelte +0 -17
- package/src/lib/components/ui/sheet/sheet-footer.svelte +0 -18
- package/src/lib/components/ui/sheet/sheet-header.svelte +0 -19
- package/src/lib/components/ui/sheet/sheet-overlay.svelte +0 -17
- package/src/lib/components/ui/sheet/sheet-portal.svelte +0 -7
- package/src/lib/components/ui/sheet/sheet-title.svelte +0 -17
- package/src/lib/components/ui/sheet/sheet-trigger.svelte +0 -7
- package/src/lib/components/ui/sheet/sheet.svelte +0 -7
- package/src/lib/components/ui/textarea/textarea.svelte +0 -21
- package/src/lib/components/ui/toggle/toggle.svelte +0 -45
- package/src/lib/components/ui/toggle-group/toggle-group-item.svelte +0 -35
- package/src/lib/components/ui/toggle-group/toggle-group.svelte +0 -63
- package/src/lib/components/ui/tooltip/tooltip-content.svelte +0 -24
- package/src/lib/components/ui/tooltip/tooltip-trigger.svelte +0 -27
- package/src/lib/components/ui/tooltip/tooltip.svelte +0 -9
- package/src/lib/components/ui/trigger-button/trigger-button.svelte +0 -106
- package/src/svelte-plugin-ui/components/Icon.svelte +0 -181
- package/src/svelte-plugin-ui/components/ModeSwitch.svelte +0 -121
- package/src/svelte-plugin-ui/components/ToolbarShell.svelte +0 -150
- package/src/svelte-plugin-ui/components/Viewfinder.svelte +0 -1001
- package/src/tools/handlers/docs.js +0 -11
- package/src/workshop/features/createCanvas/CreateCanvasForm.svelte +0 -139
- package/src/workshop/features/createFlow/CreateFlowForm.svelte +0 -314
- package/src/workshop/features/createPage/CreatePageForm.svelte +0 -249
- package/src/workshop/features/createPrototype/CreatePrototypeForm.svelte +0 -287
- package/src/workshop/features/createStory/CreateStoryForm.svelte +0 -161
- package/src/workshop/ui/WorkshopPanel.svelte +0 -97
package/src/cli/setup.js
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import * as p from '@clack/prompts'
|
|
8
|
-
import { existsSync, writeFileSync, mkdirSync } from 'fs'
|
|
8
|
+
import { existsSync, writeFileSync, readFileSync, mkdirSync, readdirSync, symlinkSync } from 'fs'
|
|
9
9
|
import path from 'path'
|
|
10
10
|
import { execSync } from 'child_process'
|
|
11
11
|
import { generateCaddyfile, isCaddyInstalled, isCaddyRunning, startCaddy, reloadCaddy } from './proxy.js'
|
|
12
|
-
import { gettingStartedLines, dim, magenta, bold,
|
|
12
|
+
import { gettingStartedLines, dim, magenta, bold, yellow } from './intro.js'
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Run a potentially slow task with a spinner that only appears after 500ms.
|
|
@@ -188,7 +188,7 @@ if (isInstalled('code')) {
|
|
|
188
188
|
|
|
189
189
|
// 7. Asset directories
|
|
190
190
|
{
|
|
191
|
-
const dirs = ['assets/canvas/images', '.storyboard']
|
|
191
|
+
const dirs = ['assets/canvas/images', 'assets/.storyboard-public/terminal-snapshots', '.storyboard', '.storyboard/terminals', '.storyboard/terminal-buffers', '.storyboard/logs']
|
|
192
192
|
for (const dir of dirs) {
|
|
193
193
|
if (!existsSync(dir)) {
|
|
194
194
|
try { mkdirSync(dir, { recursive: true }) } catch { /* ignore */ }
|
|
@@ -211,6 +211,81 @@ if (isInstalled('code')) {
|
|
|
211
211
|
p.log.success('Canvas asset directories ready')
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
+
// 7a. Scaffold .gitignore entries for private canvas images
|
|
215
|
+
{
|
|
216
|
+
const gitignorePath = '.gitignore'
|
|
217
|
+
const privatePatterns = [
|
|
218
|
+
'src/canvas/images/~*',
|
|
219
|
+
'assets/canvas/images/~*',
|
|
220
|
+
'assets/canvas/snapshots/~*',
|
|
221
|
+
'assets/.storyboard-public/terminal-snapshots/~*',
|
|
222
|
+
]
|
|
223
|
+
if (existsSync(gitignorePath)) {
|
|
224
|
+
try {
|
|
225
|
+
let content = readFileSync(gitignorePath, 'utf-8')
|
|
226
|
+
const missing = privatePatterns.filter(p => !content.includes(p))
|
|
227
|
+
if (missing.length > 0) {
|
|
228
|
+
const block = '\n# Private canvas images (tilde prefix = not committed)\n' + missing.join('\n') + '\n'
|
|
229
|
+
content = content.trimEnd() + '\n' + block
|
|
230
|
+
writeFileSync(gitignorePath, content, 'utf-8')
|
|
231
|
+
p.log.success('Added private image patterns to .gitignore')
|
|
232
|
+
}
|
|
233
|
+
} catch { /* ignore */ }
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// 7b. Copilot agents
|
|
238
|
+
{
|
|
239
|
+
const agentsDir = '.agents'
|
|
240
|
+
if (!existsSync(agentsDir)) {
|
|
241
|
+
try { mkdirSync(agentsDir, { recursive: true }) } catch { /* ignore */ }
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const scaffoldAgents = path.resolve(import.meta.dirname, '..', '..', 'scaffold', 'agents')
|
|
245
|
+
if (existsSync(scaffoldAgents)) {
|
|
246
|
+
try {
|
|
247
|
+
const agentFiles = execSync(`ls "${scaffoldAgents}"`, { encoding: 'utf8' }).trim().split('\n').filter(Boolean)
|
|
248
|
+
for (const file of agentFiles) {
|
|
249
|
+
const dest = path.join(agentsDir, file)
|
|
250
|
+
if (!existsSync(dest)) {
|
|
251
|
+
run(`cp "${path.join(scaffoldAgents, file)}" "${dest}"`)
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
if (agentFiles.length > 0) {
|
|
255
|
+
p.log.success('Copilot agents scaffolded (.agents/)')
|
|
256
|
+
}
|
|
257
|
+
} catch { /* ignore */ }
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Create symlinks in each CLI's expected agent directory.
|
|
261
|
+
// Source of truth: .agents/*.agent.md
|
|
262
|
+
// Copilot CLI reads .github/agents/*.md
|
|
263
|
+
// Claude Code reads .claude/agents/*.md
|
|
264
|
+
// Codex CLI uses .codex/config.toml (no agent files needed)
|
|
265
|
+
try {
|
|
266
|
+
const agentFiles = readdirSync(agentsDir).filter(f => f.endsWith('.agent.md'))
|
|
267
|
+
const targets = [
|
|
268
|
+
{ dir: path.join('.github', 'agents'), label: 'Copilot CLI' },
|
|
269
|
+
{ dir: path.join('.claude', 'agents'), label: 'Claude Code' },
|
|
270
|
+
]
|
|
271
|
+
for (const { dir, label } of targets) {
|
|
272
|
+
try { mkdirSync(dir, { recursive: true }) } catch { /* ignore */ }
|
|
273
|
+
let linked = 0
|
|
274
|
+
for (const file of agentFiles) {
|
|
275
|
+
const linkName = file.replace('.agent.md', '.md')
|
|
276
|
+
const linkPath = path.join(dir, linkName)
|
|
277
|
+
const target = path.relative(dir, path.join(agentsDir, file))
|
|
278
|
+
if (!existsSync(linkPath)) {
|
|
279
|
+
try { symlinkSync(target, linkPath); linked++ } catch { /* ignore */ }
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if (linked > 0) {
|
|
283
|
+
p.log.success(`${label} agent symlinks created (${dir}/)`)
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
} catch { /* ignore */ }
|
|
287
|
+
}
|
|
288
|
+
|
|
214
289
|
// 8. Proxy
|
|
215
290
|
if (isCaddyInstalled()) {
|
|
216
291
|
const proxySpin = p.spinner()
|
|
@@ -220,18 +295,48 @@ if (isCaddyInstalled()) {
|
|
|
220
295
|
reloadCaddy(caddyfilePath)
|
|
221
296
|
proxySpin.stop('Proxy reloaded')
|
|
222
297
|
} else {
|
|
223
|
-
proxySpin.start('Starting proxy
|
|
298
|
+
proxySpin.start('Starting proxy...')
|
|
224
299
|
startCaddy(caddyfilePath)
|
|
225
300
|
proxySpin.stop('Proxy started')
|
|
226
301
|
}
|
|
227
302
|
}
|
|
228
303
|
|
|
229
304
|
// 9. Install / sync dependencies
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
)
|
|
305
|
+
// Skip npm install if a dev server is running — it would trigger Vite's
|
|
306
|
+
// file watcher and restart the server on a different port.
|
|
307
|
+
{
|
|
308
|
+
const { SERVER_PORT } = await import('../server/index.js')
|
|
309
|
+
const { readDevDomain: readDomain } = await import('./proxy.js')
|
|
310
|
+
const http = await import('node:http')
|
|
311
|
+
|
|
312
|
+
const devRunning = await new Promise((resolve) => {
|
|
313
|
+
const req = http.get(`http://localhost:${SERVER_PORT}/health`, (res) => {
|
|
314
|
+
if (res.statusCode !== 200) { resolve(false); return }
|
|
315
|
+
let data = ''
|
|
316
|
+
res.on('data', (chunk) => { data += chunk })
|
|
317
|
+
res.on('end', () => {
|
|
318
|
+
try {
|
|
319
|
+
const json = JSON.parse(data)
|
|
320
|
+
const ourDomain = readDomain()
|
|
321
|
+
resolve(json.ok === true && json.devDomain === ourDomain)
|
|
322
|
+
} catch { resolve(false) }
|
|
323
|
+
})
|
|
324
|
+
})
|
|
325
|
+
req.on('error', () => resolve(false))
|
|
326
|
+
req.setTimeout(1000, () => { req.destroy(); resolve(false) })
|
|
327
|
+
})
|
|
328
|
+
|
|
329
|
+
if (devRunning) {
|
|
330
|
+
p.log.info(dim('Skipping npm install — dev server is running (would cause restart)'))
|
|
331
|
+
p.log.info(dim('Run `npm install` manually after stopping the dev server if needed'))
|
|
332
|
+
} else {
|
|
333
|
+
await withSpin(
|
|
334
|
+
'Installing dependencies...',
|
|
335
|
+
'Dependencies installed',
|
|
336
|
+
() => { run('npm install', { stdio: 'ignore' }) }
|
|
337
|
+
)
|
|
338
|
+
}
|
|
339
|
+
}
|
|
235
340
|
|
|
236
341
|
p.note(
|
|
237
342
|
[
|
|
@@ -242,7 +347,28 @@ p.note(
|
|
|
242
347
|
'Getting started'
|
|
243
348
|
)
|
|
244
349
|
|
|
245
|
-
|
|
246
|
-
|
|
350
|
+
// Offer branch guide
|
|
351
|
+
{
|
|
352
|
+
let currentBranchName = 'main'
|
|
353
|
+
try {
|
|
354
|
+
currentBranchName = execSync('git branch --show-current', { encoding: 'utf8' }).trim() || 'main'
|
|
355
|
+
} catch { /* empty */ }
|
|
356
|
+
|
|
357
|
+
const wantBranch = await p.select({
|
|
358
|
+
message: 'Want to work from a different branch?',
|
|
359
|
+
options: [
|
|
360
|
+
{ value: true, label: 'Yes (help me create it)' },
|
|
361
|
+
{ value: false, label: `No (stay on current branch ${bold(currentBranchName)})` },
|
|
362
|
+
],
|
|
363
|
+
initialValue: false,
|
|
364
|
+
})
|
|
247
365
|
|
|
248
|
-
p.
|
|
366
|
+
if (!p.isCancel(wantBranch) && wantBranch) {
|
|
367
|
+
const { runBranchGuide } = await import('./branch.js')
|
|
368
|
+
await runBranchGuide()
|
|
369
|
+
} else {
|
|
370
|
+
console.log()
|
|
371
|
+
console.log(mascot())
|
|
372
|
+
p.outro('')
|
|
373
|
+
}
|
|
374
|
+
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import * as p from '@clack/prompts'
|
|
9
9
|
import { execSync } from 'node:child_process'
|
|
10
|
-
import { detectWorktreeName,
|
|
10
|
+
import { detectWorktreeName, resolveRunningPort } from '../worktree/port.js'
|
|
11
11
|
import { readDevDomain } from './proxy.js'
|
|
12
12
|
import { parseFlags } from './flags.js'
|
|
13
13
|
import { dim, cyan, bold, yellow } from './intro.js'
|
|
@@ -78,17 +78,25 @@ function resolveSession(sessions, id) {
|
|
|
78
78
|
return null
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
/** Detect the current tmux session name */
|
|
81
|
+
/** Detect the current tmux session name (only if it's a storyboard session) */
|
|
82
82
|
function getCurrentTmuxSession() {
|
|
83
83
|
try {
|
|
84
|
-
|
|
84
|
+
const name = execSync('tmux display-message -p "#{session_name}" 2>/dev/null', {
|
|
85
85
|
encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'],
|
|
86
86
|
}).trim()
|
|
87
|
+
// Only return if this is a storyboard terminal session
|
|
88
|
+
return name.startsWith('sb-') ? name : null
|
|
87
89
|
} catch {
|
|
88
90
|
return null
|
|
89
91
|
}
|
|
90
92
|
}
|
|
91
93
|
|
|
94
|
+
/** Check if we're inside ANY tmux (storyboard or user's own) */
|
|
95
|
+
function _isInsideTmux() {
|
|
96
|
+
return Boolean(process.env.TMUX)
|
|
97
|
+
}
|
|
98
|
+
void _isInsideTmux
|
|
99
|
+
|
|
92
100
|
// ── Close (archive) ──
|
|
93
101
|
|
|
94
102
|
async function closeSession(session, worktreeName, port) {
|
|
@@ -125,13 +133,15 @@ async function closeSession(session, worktreeName, port) {
|
|
|
125
133
|
|
|
126
134
|
// ── Open (attach) ──
|
|
127
135
|
|
|
128
|
-
async function openSession(session,
|
|
136
|
+
async function openSession(session, _worktreeName, _port) {
|
|
137
|
+
void _worktreeName
|
|
138
|
+
void _port
|
|
129
139
|
p.intro(bold('Open session'))
|
|
130
140
|
|
|
131
141
|
const label = session.name || session.tmuxName
|
|
132
|
-
const
|
|
142
|
+
const currentSb = getCurrentTmuxSession()
|
|
133
143
|
|
|
134
|
-
if (session.status === 'live' && session.tmuxName !==
|
|
144
|
+
if (session.status === 'live' && session.tmuxName !== currentSb) {
|
|
135
145
|
p.log.warn(
|
|
136
146
|
`Session ${cyan(label)} is currently live on widget ${dim(session.widgetId)} ` +
|
|
137
147
|
`in canvas ${cyan(session.canvasId)}.`
|
|
@@ -145,8 +155,9 @@ async function openSession(session, worktreeName, port) {
|
|
|
145
155
|
}
|
|
146
156
|
}
|
|
147
157
|
|
|
148
|
-
// If we're inside tmux, switch
|
|
149
|
-
if
|
|
158
|
+
// If we're inside a storyboard tmux session, use switch-client.
|
|
159
|
+
// Otherwise always use attach-session (even if user has their own tmux).
|
|
160
|
+
if (currentSb) {
|
|
150
161
|
p.outro(`Switching to ${bold(label)}...`)
|
|
151
162
|
try {
|
|
152
163
|
execSync(`tmux switch-client -t "${session.tmuxName}"`, { stdio: 'inherit' })
|
|
@@ -234,7 +245,7 @@ async function main() {
|
|
|
234
245
|
}
|
|
235
246
|
|
|
236
247
|
const worktreeName = detectWorktreeName()
|
|
237
|
-
const port =
|
|
248
|
+
const port = resolveRunningPort(worktreeName)
|
|
238
249
|
const result = await fetchSessions(worktreeName, port)
|
|
239
250
|
|
|
240
251
|
if (!result) {
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal Messaging CLI — send messages between terminals and save output.
|
|
3
|
+
*
|
|
4
|
+
* Commands:
|
|
5
|
+
* storyboard terminal send <widgetId> "message" Send a message to a terminal
|
|
6
|
+
* storyboard terminal send --connected "message" Send to connected peer
|
|
7
|
+
* storyboard terminal output --summary "..." --content "..." Save latest output
|
|
8
|
+
* storyboard terminal status <widgetId> Check terminal status
|
|
9
|
+
* storyboard terminal read <widgetId> Read terminal buffer
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { getServerUrl } from './serverUrl.js'
|
|
13
|
+
|
|
14
|
+
function parseArgs(args) {
|
|
15
|
+
const result = { positional: [], flags: {} }
|
|
16
|
+
for (let i = 0; i < args.length; i++) {
|
|
17
|
+
if (args[i].startsWith('--')) {
|
|
18
|
+
const key = args[i].slice(2)
|
|
19
|
+
const next = args[i + 1]
|
|
20
|
+
if (next && !next.startsWith('--')) {
|
|
21
|
+
result.flags[key] = next
|
|
22
|
+
i++
|
|
23
|
+
} else {
|
|
24
|
+
result.flags[key] = true
|
|
25
|
+
}
|
|
26
|
+
} else {
|
|
27
|
+
result.positional.push(args[i])
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return result
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function handleSend() {
|
|
34
|
+
const args = process.argv.slice(4) // skip: node, sb, terminal, send
|
|
35
|
+
const { positional, flags } = parseArgs(args)
|
|
36
|
+
|
|
37
|
+
// Resolve sender identity from env
|
|
38
|
+
const senderWidgetId = process.env.STORYBOARD_WIDGET_ID || null
|
|
39
|
+
|
|
40
|
+
let targetWidgetId = null
|
|
41
|
+
let message = null
|
|
42
|
+
|
|
43
|
+
if (flags.connected) {
|
|
44
|
+
// Auto-resolve connected peer
|
|
45
|
+
if (!senderWidgetId) {
|
|
46
|
+
console.error('Error: --connected requires $STORYBOARD_WIDGET_ID to be set')
|
|
47
|
+
process.exit(1)
|
|
48
|
+
}
|
|
49
|
+
// Read own config to find connected agent/terminal peers
|
|
50
|
+
try {
|
|
51
|
+
const { readTerminalConfigById, initTerminalConfig } = await import('../canvas/terminal-config.js')
|
|
52
|
+
initTerminalConfig(process.cwd())
|
|
53
|
+
const config = readTerminalConfigById(senderWidgetId)
|
|
54
|
+
const peers = (config?.connectedWidgets || []).filter(
|
|
55
|
+
(w) => w.type === 'terminal' || w.type === 'agent'
|
|
56
|
+
)
|
|
57
|
+
if (peers.length === 0) {
|
|
58
|
+
console.error('No connected terminal/agent peers found')
|
|
59
|
+
process.exit(1)
|
|
60
|
+
}
|
|
61
|
+
if (peers.length > 1) {
|
|
62
|
+
console.error(`Multiple peers found. Specify one: ${peers.map((p) => p.id).join(', ')}`)
|
|
63
|
+
process.exit(1)
|
|
64
|
+
}
|
|
65
|
+
targetWidgetId = peers[0].id
|
|
66
|
+
} catch (err) {
|
|
67
|
+
console.error(`Error resolving connected peer: ${err.message}`)
|
|
68
|
+
process.exit(1)
|
|
69
|
+
}
|
|
70
|
+
message = typeof flags.connected === 'string' ? flags.connected : positional[0]
|
|
71
|
+
} else {
|
|
72
|
+
targetWidgetId = positional[0]
|
|
73
|
+
message = positional.slice(1).join(' ') || flags.message
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (!targetWidgetId || !message) {
|
|
77
|
+
console.error('Usage: storyboard terminal send <widgetId> "message"')
|
|
78
|
+
console.error(' storyboard terminal send --connected "message"')
|
|
79
|
+
process.exit(1)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const serverUrl = getServerUrl()
|
|
83
|
+
try {
|
|
84
|
+
const res = await fetch(`${serverUrl}/_storyboard/canvas/terminal/send`, {
|
|
85
|
+
method: 'POST',
|
|
86
|
+
headers: { 'Content-Type': 'application/json' },
|
|
87
|
+
body: JSON.stringify({ widgetId: targetWidgetId, message, from: senderWidgetId }),
|
|
88
|
+
signal: AbortSignal.timeout(10000),
|
|
89
|
+
})
|
|
90
|
+
const data = await res.json()
|
|
91
|
+
if (data.success) {
|
|
92
|
+
if (data.queued) {
|
|
93
|
+
console.log(`Message queued for ${targetWidgetId} (agent not running, will deliver on start)`)
|
|
94
|
+
} else {
|
|
95
|
+
console.log(`Message delivered to ${targetWidgetId}`)
|
|
96
|
+
}
|
|
97
|
+
} else {
|
|
98
|
+
console.error(`Failed: ${data.error}`)
|
|
99
|
+
process.exit(1)
|
|
100
|
+
}
|
|
101
|
+
} catch (err) {
|
|
102
|
+
if (err.name === 'TimeoutError') {
|
|
103
|
+
console.error(`Error: request timed out — is the dev server running? (tried ${serverUrl})`)
|
|
104
|
+
} else {
|
|
105
|
+
console.error(`Error: ${err.message}`)
|
|
106
|
+
}
|
|
107
|
+
process.exit(1)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export async function handleOutput() {
|
|
112
|
+
const args = process.argv.slice(4) // skip: node, sb, terminal, output
|
|
113
|
+
const { flags } = parseArgs(args)
|
|
114
|
+
|
|
115
|
+
const widgetId = flags.widget || process.env.STORYBOARD_WIDGET_ID
|
|
116
|
+
const summary = flags.summary || ''
|
|
117
|
+
const content = flags.content || ''
|
|
118
|
+
|
|
119
|
+
if (!widgetId) {
|
|
120
|
+
console.error('Error: --widget <id> or $STORYBOARD_WIDGET_ID required')
|
|
121
|
+
process.exit(1)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const serverUrl = getServerUrl()
|
|
125
|
+
try {
|
|
126
|
+
const res = await fetch(`${serverUrl}/_storyboard/canvas/terminal/output`, {
|
|
127
|
+
method: 'POST',
|
|
128
|
+
headers: { 'Content-Type': 'application/json' },
|
|
129
|
+
body: JSON.stringify({ widgetId, content, summary }),
|
|
130
|
+
signal: AbortSignal.timeout(10000),
|
|
131
|
+
})
|
|
132
|
+
const data = await res.json()
|
|
133
|
+
if (data.success) {
|
|
134
|
+
console.log('Output saved')
|
|
135
|
+
} else {
|
|
136
|
+
console.error(`Failed: ${data.error}`)
|
|
137
|
+
process.exit(1)
|
|
138
|
+
}
|
|
139
|
+
} catch (err) {
|
|
140
|
+
if (err.name === 'TimeoutError') {
|
|
141
|
+
console.error(`Error: request timed out — is the dev server running? (tried ${serverUrl})`)
|
|
142
|
+
} else {
|
|
143
|
+
console.error(`Error: ${err.message}`)
|
|
144
|
+
}
|
|
145
|
+
process.exit(1)
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export async function handleStatus() {
|
|
150
|
+
const args = process.argv.slice(4) // skip: node, sb, terminal, status
|
|
151
|
+
const { positional } = parseArgs(args)
|
|
152
|
+
|
|
153
|
+
const widgetId = positional[0]
|
|
154
|
+
if (!widgetId) {
|
|
155
|
+
console.error('Usage: storyboard terminal status <widgetId>')
|
|
156
|
+
process.exit(1)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
try {
|
|
160
|
+
const { readTerminalConfigById, initTerminalConfig } = await import('../canvas/terminal-config.js')
|
|
161
|
+
initTerminalConfig(process.cwd())
|
|
162
|
+
const config = readTerminalConfigById(widgetId)
|
|
163
|
+
if (!config) {
|
|
164
|
+
console.error(`No config found for ${widgetId}`)
|
|
165
|
+
process.exit(1)
|
|
166
|
+
}
|
|
167
|
+
console.log(JSON.stringify({
|
|
168
|
+
widgetId: config.widgetId,
|
|
169
|
+
displayName: config.displayName || null,
|
|
170
|
+
agentStatus: config.agentStatus || null,
|
|
171
|
+
latestOutput: config.latestOutput ? { summary: config.latestOutput.summary, updatedAt: config.latestOutput.updatedAt } : null,
|
|
172
|
+
pendingMessages: (config.pendingMessages || []).length,
|
|
173
|
+
}, null, 2))
|
|
174
|
+
} catch (err) {
|
|
175
|
+
console.error(`Error: ${err.message}`)
|
|
176
|
+
process.exit(1)
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export async function handleRead() {
|
|
181
|
+
const args = process.argv.slice(4) // skip: node, sb, terminal, read
|
|
182
|
+
const { positional, flags } = parseArgs(args)
|
|
183
|
+
|
|
184
|
+
const widgetId = positional[0] || process.env.STORYBOARD_WIDGET_ID
|
|
185
|
+
if (!widgetId) {
|
|
186
|
+
console.error('Usage: storyboard terminal read <widgetId> [--length N]')
|
|
187
|
+
process.exit(1)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const length = flags.length ? parseInt(flags.length, 10) : undefined
|
|
191
|
+
|
|
192
|
+
// Try HTTP API first (dev server may have fresher data)
|
|
193
|
+
try {
|
|
194
|
+
const serverUrl = getServerUrl()
|
|
195
|
+
const qs = length ? `?length=${length}` : ''
|
|
196
|
+
const res = await fetch(`${serverUrl}/_storyboard/canvas/terminal-buffer/${encodeURIComponent(widgetId)}${qs}`, {
|
|
197
|
+
signal: AbortSignal.timeout(3000),
|
|
198
|
+
})
|
|
199
|
+
if (res.ok) {
|
|
200
|
+
const data = await res.json()
|
|
201
|
+
console.log(JSON.stringify(data, null, 2))
|
|
202
|
+
return
|
|
203
|
+
}
|
|
204
|
+
} catch {
|
|
205
|
+
// Server not reachable — read directly from file
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Fallback: read buffer file directly
|
|
209
|
+
try {
|
|
210
|
+
const { readFileSync, existsSync } = await import('node:fs')
|
|
211
|
+
const { join } = await import('node:path')
|
|
212
|
+
const bufferPath = join(process.cwd(), '.storyboard', 'terminal-buffers', `${widgetId}.buffer.json`)
|
|
213
|
+
if (!existsSync(bufferPath)) {
|
|
214
|
+
console.error(`No buffer found for ${widgetId}`)
|
|
215
|
+
process.exit(1)
|
|
216
|
+
}
|
|
217
|
+
const data = JSON.parse(readFileSync(bufferPath, 'utf8'))
|
|
218
|
+
if (length) {
|
|
219
|
+
if (data.scrollback && data.scrollback.length > length) {
|
|
220
|
+
data.scrollback = data.scrollback.slice(-length)
|
|
221
|
+
}
|
|
222
|
+
if (data.paneContent && data.paneContent.length > length) {
|
|
223
|
+
data.paneContent = data.paneContent.slice(-length)
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
console.log(JSON.stringify(data, null, 2))
|
|
227
|
+
} catch (err) {
|
|
228
|
+
console.error(`Error: ${err.message}`)
|
|
229
|
+
process.exit(1)
|
|
230
|
+
}
|
|
231
|
+
}
|