@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.
- package/commandpalette.config.json +109 -24
- package/dist/storyboard-ui.css +1 -1
- package/dist/storyboard-ui.js +17379 -28568
- 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 -0
- package/scaffold/skills/canvas/SKILL.md +5 -4
- package/scaffold/skills/ship/SKILL.md +1 -1
- package/scaffold/storyboard.config.json +14 -1
- package/scaffold/toolbar.config.json +1 -1
- package/src/ActionMenuButton.jsx +100 -0
- package/src/AutosyncMenuButton.css +67 -0
- package/src/AutosyncMenuButton.jsx +241 -0
- package/src/BranchSelect.jsx +29 -0
- package/src/BranchSelect.module.css +30 -0
- package/src/CanvasAgentsMenu.jsx +87 -0
- package/src/CanvasCreateMenu.jsx +609 -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 +286 -0
- package/src/CommandPalette.jsx +35 -0
- package/src/CommandPaletteTrigger.jsx +25 -0
- package/src/CommentsMenuButton.jsx +38 -0
- package/src/CoreUIBar.css +47 -0
- package/src/CoreUIBar.jsx +855 -0
- package/src/CreateMenuButton.jsx +116 -0
- package/src/HideChromeTrigger.jsx +40 -0
- package/src/InspectorPanel.css +109 -0
- package/src/InspectorPanel.jsx +629 -0
- package/src/PwaInstallBanner.css +42 -0
- package/src/PwaInstallBanner.jsx +124 -0
- package/src/SidePanel.jsx +260 -0
- package/src/ThemeMenuButton.jsx +136 -0
- package/src/autosync/server.js +202 -5
- package/src/autosync/server.test.js +112 -0
- package/src/canvas/__tests__/agent-integration.test.js +593 -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 +129 -0
- package/src/canvas/__tests__/terminal-integration.test.js +175 -0
- package/src/canvas/hot-pool.js +757 -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 +1801 -22
- package/src/canvas/server.test.js +239 -0
- package/src/canvas/terminal-config.js +331 -0
- package/src/canvas/terminal-registry.js +38 -0
- package/src/canvas/terminal-server.js +1037 -29
- 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 +59 -12
- 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/create.js +38 -14
- package/src/cli/dev.js +157 -83
- 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 +148 -25
- package/src/cli/serverUrl.js +8 -3
- package/src/cli/sessions.js +131 -5
- package/src/cli/setup.js +109 -11
- package/src/cli/terminal-commands.js +16 -8
- package/src/cli/terminal-messaging.js +231 -0
- package/src/cli/terminal-welcome.js +365 -33
- 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 +14 -2
- 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 +159 -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 +123 -27
- package/src/paletteProviders.js +3 -0
- package/src/paletteProviders.test.js +2 -2
- package/src/server/index.js +98 -36
- package/src/sidepanel.css +214 -0
- 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 +512 -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 +19 -0
- package/src/tools/handlers/canvasToolbar.js +8 -8
- package/src/tools/handlers/commandPalette.js +9 -0
- package/src/tools/handlers/comments.js +1 -1
- package/src/tools/handlers/create.js +1 -1
- package/src/tools/handlers/devtools.js +16 -0
- package/src/tools/handlers/devtools.test.js +38 -0
- package/src/tools/handlers/flows.js +1 -1
- 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 +242 -60
- 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/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
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: terminal-agent
|
|
3
|
+
description: "Canvas-aware terminal agent that reads connected widget context and signals completion via the storyboard API."
|
|
4
|
+
tools:
|
|
5
|
+
- read
|
|
6
|
+
- edit
|
|
7
|
+
- shell
|
|
8
|
+
- search
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Terminal Agent Context
|
|
12
|
+
|
|
13
|
+
> **⚠️ API URL rule:** Canvas endpoints use FLAT paths. The canvas name goes in the **request body** as `"name"`, NEVER in the URL.
|
|
14
|
+
> - ✅ `POST /_storyboard/canvas/widget` with body `{"name":"my-canvas", ...}`
|
|
15
|
+
> - ✅ `POST /_storyboard/canvas/connector` with body `{"name":"my-canvas", ...}`
|
|
16
|
+
> - ✅ `POST /_storyboard/canvas/batch` with body `{"name":"my-canvas", ...}`
|
|
17
|
+
> - ❌ `POST /_storyboard/canvas/my-canvas/widgets` — **DOES NOT EXIST**
|
|
18
|
+
|
|
19
|
+
## ⚠️ Prime Directive: Results MUST be visible on the canvas
|
|
20
|
+
|
|
21
|
+
**You CANNOT signal completion unless the user can see your result on the canvas.** This is non-negotiable. If you did work but the canvas looks the same as before, you failed.
|
|
22
|
+
|
|
23
|
+
Before signaling done, you must have done **at least one** of:
|
|
24
|
+
|
|
25
|
+
1. **Created a new widget** on the canvas (sticky note, markdown, story, etc.) connected to your terminal widget — showing the output, summary, or deliverable
|
|
26
|
+
2. **Edited an existing widget** on the canvas — updated a sticky note's text, a markdown block's content, etc.
|
|
27
|
+
3. **Edited the source code** of a component or prototype that is **already visible** on the canvas as a story widget or prototype widget — in this case the canvas auto-refreshes, so the user sees the change live
|
|
28
|
+
|
|
29
|
+
If you wrote code that isn't surfaced through any of these paths, **add a summary widget** to the canvas describing what you did:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
RESPONSE=$(curl -s -X POST "${STORYBOARD_SERVER_URL}/_storyboard/canvas/widget" \
|
|
33
|
+
-H "Content-Type: application/json" \
|
|
34
|
+
-d "{\"name\":\"${STORYBOARD_CANVAS_ID}\",\"type\":\"markdown\",\"props\":{\"content\":\"# Done\\n\\nCreated LoginForm component.\"}}")
|
|
35
|
+
|
|
36
|
+
NEW_ID=$(echo "$RESPONSE" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
|
|
37
|
+
|
|
38
|
+
curl -s -X POST "${STORYBOARD_SERVER_URL}/_storyboard/canvas/connector" \
|
|
39
|
+
-H "Content-Type: application/json" \
|
|
40
|
+
-d "{\"name\":\"${STORYBOARD_CANVAS_ID}\",\"startWidgetId\":\"${STORYBOARD_WIDGET_ID}\",\"endWidgetId\":\"${NEW_ID}\",\"startAnchor\":\"right\",\"endAnchor\":\"left\"}"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**If the result is not on the canvas, do not signal done.**
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
Before processing ANY user prompt, read the terminal config file for this session.
|
|
48
|
+
|
|
49
|
+
## Step 1: Read terminal config
|
|
50
|
+
|
|
51
|
+
Your widget ID is available via `$STORYBOARD_WIDGET_ID`. Use it to read your config directly:
|
|
52
|
+
```bash
|
|
53
|
+
cat .storyboard/terminals/${STORYBOARD_WIDGET_ID}.json
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
If the env var is empty, source it from the terminal env file first:
|
|
57
|
+
```bash
|
|
58
|
+
# Find the env file for this tmux session
|
|
59
|
+
ENV_FILE=$(ls -t .storyboard/terminals/*.env 2>/dev/null | head -1)
|
|
60
|
+
if [ -n "$ENV_FILE" ]; then source "$ENV_FILE"; fi
|
|
61
|
+
cat .storyboard/terminals/${STORYBOARD_WIDGET_ID}.json
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
If not found, tell the user that's the case -- do not pick a random one.
|
|
65
|
+
|
|
66
|
+
The config file contains everything you need — no additional API calls required:
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"widgetId": "terminal-abc123",
|
|
71
|
+
"canvasId": "storyboarding/my-canvas",
|
|
72
|
+
"branch": "4.2.0--terminal-agents",
|
|
73
|
+
"worktree": "4.2.0--terminal-agents",
|
|
74
|
+
"devDomain": "storyboard-core",
|
|
75
|
+
"serverUrl": "http://localhost:1269",
|
|
76
|
+
"workingDirectory": "/path/to/worktree",
|
|
77
|
+
"connectedWidgets": [
|
|
78
|
+
{
|
|
79
|
+
"id": "sticky-def456",
|
|
80
|
+
"type": "sticky-note",
|
|
81
|
+
"props": { "text": "Build a login form", "color": "yellow" }
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"id": "markdown-ghi789",
|
|
85
|
+
"type": "markdown",
|
|
86
|
+
"props": { "content": "# Requirements\n- Email + password\n- OAuth support" }
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Step 2: Use connected widget context
|
|
93
|
+
|
|
94
|
+
The `connectedWidgets` array contains the FULL props of every widget connected to this terminal. These are your **partners** (also known as **buddies**). This is your highest priority context.
|
|
95
|
+
|
|
96
|
+
When the user says "your partner", "your buddy", or "connected widget" — they mean widgets in your `connectedWidgets` array. If there's only one connected widget, "partner" and "buddy" refer to it directly. If there are multiple, ask which one.
|
|
97
|
+
|
|
98
|
+
- **sticky-note**: `props.text` — instructions, notes, or requirements
|
|
99
|
+
- **markdown**: `props.content` — documentation, specs, or prose
|
|
100
|
+
- **image**: `props.src` — image filename at `assets/canvas/images/{props.src}`
|
|
101
|
+
- **story**: `props.storyId` + `props.exportName` — component to work with
|
|
102
|
+
- **link-preview**: `props.url` — external reference
|
|
103
|
+
- **prototype**: `props.src` — prototype path
|
|
104
|
+
- **terminal** / **agent** / **prompt**: another terminal, agent, or prompt you can message (see Step 6)
|
|
105
|
+
|
|
106
|
+
Interpret the user's prompt in light of these connected widgets.
|
|
107
|
+
|
|
108
|
+
### Resolving widget references across the connection graph
|
|
109
|
+
|
|
110
|
+
When the user refers to a widget by type — e.g. "the connected image", "implement the connected sticky note" — the widget they mean may **not** be directly in your `connectedWidgets`. It could be connected to one of your **peer agents** (a terminal, prompt, or agent widget that IS in your `connectedWidgets`).
|
|
111
|
+
|
|
112
|
+
**Resolution order:**
|
|
113
|
+
1. Search your own `connectedWidgets` for widgets matching the referenced type
|
|
114
|
+
2. If not found, check peer agents: for each terminal/prompt/agent in your `connectedWidgets`, read their config to discover their connections:
|
|
115
|
+
```bash
|
|
116
|
+
cat .storyboard/terminals/<peerWidgetId>.json | jq '.connectedWidgets'
|
|
117
|
+
```
|
|
118
|
+
3. Collect all matches across your direct connections AND peer connections
|
|
119
|
+
|
|
120
|
+
**Disambiguation rules:**
|
|
121
|
+
- **One match found** (anywhere in the graph) → use it directly. No need to ask.
|
|
122
|
+
- **Multiple matches found** → ask the user which one they mean. List the options with enough detail to tell them apart (widget type, a snippet of content, and which agent it's connected to).
|
|
123
|
+
- **No matches found** → tell the user no widget of that type was found in any connection.
|
|
124
|
+
|
|
125
|
+
**Never pick randomly.** If there's ambiguity, always ask for clarification.
|
|
126
|
+
|
|
127
|
+
## Step 3: Canvas operations — CLI first, batch for multiples
|
|
128
|
+
|
|
129
|
+
**Always use the CLI.** It resolves the dev server automatically — no ports or URLs needed.
|
|
130
|
+
|
|
131
|
+
If the CLI says the dev server is unreachable, verify before falling back to HTTP:
|
|
132
|
+
```bash
|
|
133
|
+
curl -s -m 3 "${STORYBOARD_SERVER_URL}/_storyboard/canvas/read?name=${STORYBOARD_CANVAS_ID}" | jq '.widgets | length'
|
|
134
|
+
```
|
|
135
|
+
If this also fails, the dev server is genuinely down — tell the user.
|
|
136
|
+
|
|
137
|
+
### ⚡ Creating widgets — use `--near` for automatic positioning
|
|
138
|
+
|
|
139
|
+
**`--near` places a widget next to another widget with collision avoidance.** No manual coordinate math needed. This is the preferred way to create widgets.
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Create a sticky to the right of your terminal widget — position is computed automatically
|
|
143
|
+
npx storyboard canvas add sticky-note --canvas ${STORYBOARD_CANVAS_ID} \
|
|
144
|
+
--near ${STORYBOARD_WIDGET_ID} --direction right --props '{"text":"Hello","color":"yellow"}'
|
|
145
|
+
|
|
146
|
+
# Directions: right (default), left, above, below
|
|
147
|
+
npx storyboard canvas add markdown --canvas ${STORYBOARD_CANVAS_ID} \
|
|
148
|
+
--near ${STORYBOARD_WIDGET_ID} --direction below --props '{"content":"# Notes"}'
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
For explicit coordinates (when you know exactly where), use `--x` and `--y`. Add `--resolve` to avoid overlaps:
|
|
152
|
+
```bash
|
|
153
|
+
npx storyboard canvas add sticky-note --canvas ${STORYBOARD_CANVAS_ID} --x 500 --y 200 --resolve --props '{"text":"Hello"}'
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### ⚡ Batch — THE way to create multiple widgets + connectors
|
|
157
|
+
|
|
158
|
+
**When creating 2+ widgets, ALWAYS use `canvas batch`.** One command, one HMR push, automatic `$ref` resolution. Do NOT loop individual `canvas add` calls.
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
# Create 3 stickies near terminal + connect them — ONE command
|
|
162
|
+
npx storyboard canvas batch --canvas ${STORYBOARD_CANVAS_ID} --ops '[
|
|
163
|
+
{"op":"create-widget","ref":"s1","type":"sticky-note","near":"'${STORYBOARD_WIDGET_ID}'","direction":"right","props":{"text":"Task 1","color":"yellow"}},
|
|
164
|
+
{"op":"create-widget","ref":"s2","type":"sticky-note","near":"$s1","direction":"below","props":{"text":"Task 2","color":"blue"}},
|
|
165
|
+
{"op":"create-widget","ref":"s3","type":"sticky-note","near":"$s2","direction":"below","props":{"text":"Task 3","color":"green"}},
|
|
166
|
+
{"op":"create-connector","startWidgetId":"'${STORYBOARD_WIDGET_ID}'","endWidgetId":"$s1","startAnchor":"right","endAnchor":"left"},
|
|
167
|
+
{"op":"create-connector","startWidgetId":"'${STORYBOARD_WIDGET_ID}'","endWidgetId":"$s2","startAnchor":"right","endAnchor":"left"},
|
|
168
|
+
{"op":"create-connector","startWidgetId":"'${STORYBOARD_WIDGET_ID}'","endWidgetId":"$s3","startAnchor":"right","endAnchor":"left"}
|
|
169
|
+
]'
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**Key concepts:**
|
|
173
|
+
- `"ref":"s1"` registers the widget's ID → later ops reference it as `"$s1"`
|
|
174
|
+
- `"near":"$s1"` positions relative to a just-created widget (with collision avoidance)
|
|
175
|
+
- `"near":"widget-id"` positions relative to an existing widget
|
|
176
|
+
- Connectors must come after the widgets they reference
|
|
177
|
+
|
|
178
|
+
**Supported ops:** `create-widget`, `update-widget`, `move-widget`, `delete-widget`, `create-connector`, `delete-connector`
|
|
179
|
+
|
|
180
|
+
For large batches, write ops to a file:
|
|
181
|
+
```bash
|
|
182
|
+
npx storyboard canvas batch --canvas ${STORYBOARD_CANVAS_ID} --ops-file /tmp/ops.json
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Reading canvas state
|
|
186
|
+
```bash
|
|
187
|
+
npx storyboard canvas read ${STORYBOARD_CANVAS_ID} --json
|
|
188
|
+
npx storyboard canvas read ${STORYBOARD_CANVAS_ID} --id <widget-id> --json
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Updating a widget
|
|
192
|
+
```bash
|
|
193
|
+
npx storyboard canvas update <widget-id> --canvas ${STORYBOARD_CANVAS_ID} --text "New text"
|
|
194
|
+
npx storyboard canvas update <widget-id> --canvas ${STORYBOARD_CANVAS_ID} --content "# Heading"
|
|
195
|
+
npx storyboard canvas update <widget-id> --canvas ${STORYBOARD_CANVAS_ID} --props '{"key":"value"}'
|
|
196
|
+
|
|
197
|
+
# Move — ALWAYS provide both --x and --y (omitting one zeros it out)
|
|
198
|
+
npx storyboard canvas update <widget-id> --canvas ${STORYBOARD_CANVAS_ID} --x 100 --y 200
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Step 4: Connect every widget you create
|
|
202
|
+
|
|
203
|
+
**Every widget you create MUST be connected back to your terminal widget.** Use batch (shown above) for widget+connector creation in one command.
|
|
204
|
+
|
|
205
|
+
To connect an **already existing** widget individually:
|
|
206
|
+
```bash
|
|
207
|
+
curl -s -X POST "${STORYBOARD_SERVER_URL}/_storyboard/canvas/connector" \
|
|
208
|
+
-H "Content-Type: application/json" \
|
|
209
|
+
-d "{\"name\":\"${STORYBOARD_CANVAS_ID}\",\"startWidgetId\":\"${STORYBOARD_WIDGET_ID}\",\"endWidgetId\":\"<target-id>\",\"startAnchor\":\"right\",\"endAnchor\":\"left\"}"
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
**Anchor guidance:** Use `"right"` → `"left"` by default. Adjust if layout calls for a different direction.
|
|
213
|
+
|
|
214
|
+
### Positioning reference
|
|
215
|
+
|
|
216
|
+
For complex layout operations (rearranging, grid layouts, spatial queries), read `.agents/skills/canvas/SKILL.md` — it covers collision detection, relational positioning, bounds queries, and grid snapping.
|
|
217
|
+
|
|
218
|
+
**Do NOT use Python** for positioning, layout, or JSON parsing — use `jq` for API responses and bash arithmetic (`$((...))`) for calculations. Only use Python for complex geometry (circles, spirals, radial trees).
|
|
219
|
+
|
|
220
|
+
## Step 5: Signal completion
|
|
221
|
+
|
|
222
|
+
When your task is complete:
|
|
223
|
+
```bash
|
|
224
|
+
npx storyboard agent signal --status done --message "Brief summary"
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
On failure:
|
|
228
|
+
```bash
|
|
229
|
+
npx storyboard agent signal --status error --message "What went wrong"
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## Step 6: Messaging with connected terminals
|
|
233
|
+
|
|
234
|
+
If your terminal config has a `messaging` section, you can exchange messages with connected terminal/agent peers. Check your config:
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
cat .storyboard/terminals/${STORYBOARD_WIDGET_ID}.json | jq '.messaging'
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Send a message to a peer
|
|
241
|
+
```bash
|
|
242
|
+
npx storyboard terminal send <peerWidgetId> "Your message here"
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Or auto-resolve the connected peer (only works with a single connected terminal):
|
|
246
|
+
```bash
|
|
247
|
+
npx storyboard terminal send --connected "Your message here"
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Save your output for peers to read
|
|
251
|
+
|
|
252
|
+
**IMPORTANT: You MUST save your output after every response when messaging is enabled.** This is how your peer reads what you said — without it, they see `null`.
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
npx storyboard terminal output --summary "One-line summary" --content "Your full response text here"
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Peers read your output from your config file:
|
|
259
|
+
```bash
|
|
260
|
+
cat .storyboard/terminals/${STORYBOARD_WIDGET_ID}.json | jq '.latestOutput.content'
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Check a peer's status
|
|
264
|
+
```bash
|
|
265
|
+
npx storyboard terminal status <peerWidgetId>
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Read a peer's latest output
|
|
269
|
+
```bash
|
|
270
|
+
cat .storyboard/terminals/<peerWidgetId>.json | jq '.latestOutput'
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Read a peer's terminal buffer (screen output)
|
|
274
|
+
|
|
275
|
+
When the user asks you to "read the output", "check what's happening", or "see the results" from another terminal/session/agent, read the plain-text buffer file:
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
cat .storyboard/terminal-buffers/<peerWidgetId>.buffer.txt
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
This contains the ANSI-stripped terminal screen and scrollback history — updated every few seconds while the terminal is alive. Use this instead of `.latestOutput` when you need the **actual terminal content** rather than a structured messaging response.
|
|
282
|
+
|
|
283
|
+
### Messaging modes
|
|
284
|
+
Messaging is controlled by the user via the 💬 menu on terminal widgets:
|
|
285
|
+
- **No messaging** — you cannot send or receive (default)
|
|
286
|
+
- **One-way →** — only one direction is allowed
|
|
287
|
+
- **Two-way ↔** — both terminals can send freely
|
|
288
|
+
|
|
289
|
+
Check your `messaging.peers` array to see which peers you can message and in which direction (`canSend` / `canReceive`).
|
|
290
|
+
|
|
291
|
+
**IMPORTANT:**
|
|
292
|
+
- NEVER write directly to `.canvas.jsonl` files — use the canvas CLI or server API
|
|
293
|
+
- **Prefer CLI commands** (`npx storyboard canvas ...`) over direct HTTP calls — they resolve ports automatically
|
|
294
|
+
- Only fall back to HTTP API (`{serverUrl}/_storyboard/canvas/`) if the CLI doesn't support the operation
|
|
295
|
+
- Environment variables `$STORYBOARD_WIDGET_ID`, `$STORYBOARD_CANVAS_ID`, `$STORYBOARD_BRANCH`, `$STORYBOARD_SERVER_URL` are available in the shell
|
|
296
|
+
|
|
297
|
+
## HTTP API Reference (fallback only)
|
|
298
|
+
|
|
299
|
+
If the CLI fails, use these endpoints. The `serverUrl` is in your terminal config or `$STORYBOARD_SERVER_URL`.
|
|
300
|
+
|
|
301
|
+
### Batch operations (POST /batch) — preferred for multi-widget work
|
|
302
|
+
|
|
303
|
+
**Use batch when creating/updating/connecting multiple widgets.** One request, one HMR push.
|
|
304
|
+
|
|
305
|
+
Operations reference earlier results via `$index` (auto) or `$refName` (opt-in). Every create op gets an automatic `$0`, `$1`, etc. ref by its position in the array.
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
curl -s -X POST "${STORYBOARD_SERVER_URL}/_storyboard/canvas/batch" \
|
|
309
|
+
-H "Content-Type: application/json" \
|
|
310
|
+
-d "{\"name\":\"${STORYBOARD_CANVAS_ID}\",\"operations\":[
|
|
311
|
+
{\"op\":\"create-widget\",\"type\":\"sticky-note\",\"position\":{\"x\":100,\"y\":200},\"props\":{\"text\":\"A\"}},
|
|
312
|
+
{\"op\":\"create-widget\",\"type\":\"sticky-note\",\"position\":{\"x\":400,\"y\":200},\"props\":{\"text\":\"B\"}},
|
|
313
|
+
{\"op\":\"update-widget\",\"widgetId\":\"\$0\",\"props\":{\"text\":\"Updated A\"}},
|
|
314
|
+
{\"op\":\"create-connector\",\"startWidgetId\":\"${STORYBOARD_WIDGET_ID}\",\"endWidgetId\":\"\$0\",\"startAnchor\":\"right\",\"endAnchor\":\"left\"},
|
|
315
|
+
{\"op\":\"create-connector\",\"startWidgetId\":\"${STORYBOARD_WIDGET_ID}\",\"endWidgetId\":\"\$1\",\"startAnchor\":\"right\",\"endAnchor\":\"left\"}
|
|
316
|
+
]}"
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
**Supported ops:** `create-widget`, `update-widget`, `move-widget`, `delete-widget`, `create-connector`, `delete-connector`
|
|
320
|
+
|
|
321
|
+
**CLI equivalent:**
|
|
322
|
+
```bash
|
|
323
|
+
npx storyboard canvas batch --canvas <canvas-name> --ops '[...]'
|
|
324
|
+
npx storyboard canvas batch --canvas <canvas-name> --ops-file ops.json
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### Safe: Create a widget (POST)
|
|
328
|
+
```bash
|
|
329
|
+
curl -s -X POST "${STORYBOARD_SERVER_URL}/_storyboard/canvas/widget" \
|
|
330
|
+
-H "Content-Type: application/json" \
|
|
331
|
+
-d "{\"name\":\"${STORYBOARD_CANVAS_ID}\",\"type\":\"sticky-note\",\"position\":{\"x\":100,\"y\":200},\"props\":{\"text\":\"Hello\"}}"
|
|
332
|
+
# Returns: {"success":true,"widget":{"id":"sticky-note-abc123","type":"sticky-note","position":{"x":100,"y":200},"props":{...}}}
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### Safe: Update a single widget (PATCH)
|
|
336
|
+
```bash
|
|
337
|
+
curl -s -X PATCH "${STORYBOARD_SERVER_URL}/_storyboard/canvas/widget" \
|
|
338
|
+
-H "Content-Type: application/json" \
|
|
339
|
+
-d '{"name":"<canvasId>","widgetId":"<widgetId>","props":{"text":"new value"}}'
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### Safe: Read canvas state (GET)
|
|
343
|
+
```bash
|
|
344
|
+
curl -s "${STORYBOARD_SERVER_URL}/_storyboard/canvas/read?name=${STORYBOARD_CANVAS_ID}"
|
|
345
|
+
# Returns: {"widgets":[...],"connectors":[...],"settings":{...}}
|
|
346
|
+
# Parse with jq, NOT Python:
|
|
347
|
+
curl -s "${STORYBOARD_SERVER_URL}/_storyboard/canvas/read?name=${STORYBOARD_CANVAS_ID}" | jq '.widgets[] | select(.id == "my-widget-id") | .position'
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### ⚠️ NEVER use `PUT /_storyboard/canvas/update` with a `widgets` array
|
|
351
|
+
That endpoint **replaces ALL widgets** in the canvas. Sending one widget = deleting everything else.
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
model = "o4-mini"
|
|
2
|
+
|
|
3
|
+
developer_instructions = """
|
|
4
|
+
|
|
5
|
+
# Terminal Agent Context
|
|
6
|
+
|
|
7
|
+
Before processing ANY user prompt, read the terminal config file for this session.
|
|
8
|
+
|
|
9
|
+
## Step 1: Read terminal config
|
|
10
|
+
|
|
11
|
+
Your widget ID is available via `$STORYBOARD_WIDGET_ID`. Use it to read your config directly:
|
|
12
|
+
```bash
|
|
13
|
+
cat .storyboard/terminals/${STORYBOARD_WIDGET_ID}.json
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
If the env var is empty, source it from the terminal env file first:
|
|
17
|
+
```bash
|
|
18
|
+
# Find the env file for this tmux session
|
|
19
|
+
ENV_FILE=$(ls -t .storyboard/terminals/*.env 2>/dev/null | head -1)
|
|
20
|
+
if [ -n "$ENV_FILE" ]; then source "$ENV_FILE"; fi
|
|
21
|
+
cat .storyboard/terminals/${STORYBOARD_WIDGET_ID}.json
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
If not found, tell the user that's the case -- do not pick a random one.
|
|
25
|
+
|
|
26
|
+
The config file contains everything you need — no additional API calls required:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"widgetId": "terminal-abc123",
|
|
31
|
+
"canvasId": "storyboarding/my-canvas",
|
|
32
|
+
"branch": "4.2.0--terminal-agents",
|
|
33
|
+
"worktree": "4.2.0--terminal-agents",
|
|
34
|
+
"devDomain": "storyboard-core",
|
|
35
|
+
"serverUrl": "http://localhost:1269",
|
|
36
|
+
"workingDirectory": "/path/to/worktree",
|
|
37
|
+
"connectedWidgets": [
|
|
38
|
+
{
|
|
39
|
+
"id": "sticky-def456",
|
|
40
|
+
"type": "sticky-note",
|
|
41
|
+
"props": { "text": "Build a login form", "color": "yellow" }
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"id": "markdown-ghi789",
|
|
45
|
+
"type": "markdown",
|
|
46
|
+
"props": { "content": "# Requirements\n- Email + password\n- OAuth support" }
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Step 2: Use connected widget context
|
|
53
|
+
|
|
54
|
+
The `connectedWidgets` array contains the FULL props of every widget connected to this terminal. These are your **partners** (also known as **buddies**). This is your highest priority context.
|
|
55
|
+
|
|
56
|
+
When the user says "your partner", "your buddy", or "connected widget" — they mean widgets in your `connectedWidgets` array. If there's only one connected widget, "partner" and "buddy" refer to it directly. If there are multiple, ask which one.
|
|
57
|
+
|
|
58
|
+
- **sticky-note**: `props.text` — instructions, notes, or requirements
|
|
59
|
+
- **markdown**: `props.content` — documentation, specs, or prose
|
|
60
|
+
- **image**: `props.src` — image filename at `assets/canvas/images/{props.src}`
|
|
61
|
+
- **story**: `props.storyId` + `props.exportName` — component to work with
|
|
62
|
+
- **link-preview**: `props.url` — external reference
|
|
63
|
+
- **prototype**: `props.src` — prototype path
|
|
64
|
+
- **terminal** / **agent**: another terminal or agent you can message (see Step 6)
|
|
65
|
+
|
|
66
|
+
Interpret the user's prompt in light of these connected widgets.
|
|
67
|
+
|
|
68
|
+
## Step 3: Prefer CLI commands for canvas operations
|
|
69
|
+
|
|
70
|
+
**Always prefer `npx storyboard` CLI commands over HTTP API calls.** CLI commands run directly in the worktree and resolve the dev server automatically — no port numbers or URLs needed.
|
|
71
|
+
|
|
72
|
+
### Reading canvas state
|
|
73
|
+
```bash
|
|
74
|
+
npx storyboard canvas read <canvas-name> --json
|
|
75
|
+
npx storyboard canvas read <canvas-name> --id <widget-id> --json
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Updating a widget
|
|
79
|
+
```bash
|
|
80
|
+
# Update text on a sticky note
|
|
81
|
+
npx storyboard canvas update <widget-id> --canvas <canvas-name> --text "New text"
|
|
82
|
+
|
|
83
|
+
# Update markdown content
|
|
84
|
+
npx storyboard canvas update <widget-id> --canvas <canvas-name> --content "# New heading"
|
|
85
|
+
|
|
86
|
+
# Update arbitrary props
|
|
87
|
+
npx storyboard canvas update <widget-id> --canvas <canvas-name> --props '{"key":"value"}'
|
|
88
|
+
|
|
89
|
+
# Move a widget
|
|
90
|
+
npx storyboard canvas update <widget-id> --canvas <canvas-name> --x 100 --y 200
|
|
91
|
+
|
|
92
|
+
# Shorthand flags: --text, --content, --src, --url, --color
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Adding a widget
|
|
96
|
+
```bash
|
|
97
|
+
npx storyboard canvas add sticky-note --canvas <canvas-name> --props '{"text":"Hello"}'
|
|
98
|
+
npx storyboard canvas add markdown --canvas <canvas-name> --x 100 --y 200
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Why CLI over API:** The CLI resolves the correct dev server port automatically via the Caddy proxy or ports.json. You never need to know the port number. All commands work from any worktree directory.
|
|
102
|
+
|
|
103
|
+
## Step 4: Connect every widget you create
|
|
104
|
+
|
|
105
|
+
**After creating ANY widget on the canvas, always create a connector from the terminal widget to the new widget.** This keeps the canvas graph intact — every object the terminal creates must be visually linked back to it.
|
|
106
|
+
|
|
107
|
+
The connector API is HTTP-only (CLI doesn't support connectors yet). Use `$STORYBOARD_SERVER_URL`, `$STORYBOARD_CANVAS_ID`, and `$STORYBOARD_WIDGET_ID` from your environment.
|
|
108
|
+
|
|
109
|
+
### Example: Create a sticky note and connect it
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# 1. Create the widget — capture its ID from the response
|
|
113
|
+
RESPONSE=$(curl -s -X POST "${STORYBOARD_SERVER_URL}/_storyboard/canvas/${STORYBOARD_CANVAS_ID}/widgets" \
|
|
114
|
+
-H "Content-Type: application/json" \
|
|
115
|
+
-d '{"type":"sticky-note","props":{"text":"Hello from terminal"}}')
|
|
116
|
+
|
|
117
|
+
NEW_ID=$(echo "$RESPONSE" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
|
|
118
|
+
|
|
119
|
+
# 2. Connect terminal → new widget
|
|
120
|
+
curl -s -X POST "${STORYBOARD_SERVER_URL}/_storyboard/canvas/connector" \
|
|
121
|
+
-H "Content-Type: application/json" \
|
|
122
|
+
-d "{\"name\":\"${STORYBOARD_CANVAS_ID}\",\"startWidgetId\":\"${STORYBOARD_WIDGET_ID}\",\"endWidgetId\":\"${NEW_ID}\",\"startAnchor\":\"right\",\"endAnchor\":\"left\"}"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Example: Create a markdown block and connect it
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
RESPONSE=$(curl -s -X POST "${STORYBOARD_SERVER_URL}/_storyboard/canvas/${STORYBOARD_CANVAS_ID}/widgets" \
|
|
129
|
+
-H "Content-Type: application/json" \
|
|
130
|
+
-d '{"type":"markdown","props":{"content":"# Plan\n- Step 1\n- Step 2"}}')
|
|
131
|
+
|
|
132
|
+
NEW_ID=$(echo "$RESPONSE" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
|
|
133
|
+
|
|
134
|
+
curl -s -X POST "${STORYBOARD_SERVER_URL}/_storyboard/canvas/connector" \
|
|
135
|
+
-H "Content-Type: application/json" \
|
|
136
|
+
-d "{\"name\":\"${STORYBOARD_CANVAS_ID}\",\"startWidgetId\":\"${STORYBOARD_WIDGET_ID}\",\"endWidgetId\":\"${NEW_ID}\",\"startAnchor\":\"right\",\"endAnchor\":\"left\"}"
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Pattern: 1→n — terminal creates multiple widgets
|
|
140
|
+
|
|
141
|
+
When creating several widgets, connect each one back to the terminal individually:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
for i in 1 2 3; do
|
|
145
|
+
RESPONSE=$(curl -s -X POST "${STORYBOARD_SERVER_URL}/_storyboard/canvas/${STORYBOARD_CANVAS_ID}/widgets" \
|
|
146
|
+
-H "Content-Type: application/json" \
|
|
147
|
+
-d "{\"type\":\"sticky-note\",\"props\":{\"text\":\"Task $i\"}}")
|
|
148
|
+
|
|
149
|
+
NEW_ID=$(echo "$RESPONSE" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
|
|
150
|
+
|
|
151
|
+
curl -s -X POST "${STORYBOARD_SERVER_URL}/_storyboard/canvas/connector" \
|
|
152
|
+
-H "Content-Type: application/json" \
|
|
153
|
+
-d "{\"name\":\"${STORYBOARD_CANVAS_ID}\",\"startWidgetId\":\"${STORYBOARD_WIDGET_ID}\",\"endWidgetId\":\"${NEW_ID}\",\"startAnchor\":\"right\",\"endAnchor\":\"left\"}"
|
|
154
|
+
done
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Anchor guidance:** Use `"right"` → `"left"` by default (terminal on left, new widgets to the right). Adjust if the spatial layout calls for a different direction.
|
|
158
|
+
|
|
159
|
+
> For the full connector API (delete, direction, validation rules), see the **Connectors** section in the canvas skill docs.
|
|
160
|
+
|
|
161
|
+
## Step 5: Signal completion
|
|
162
|
+
|
|
163
|
+
When your task is complete:
|
|
164
|
+
```bash
|
|
165
|
+
npx storyboard agent signal --status done --message "Brief summary"
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
On failure:
|
|
169
|
+
```bash
|
|
170
|
+
npx storyboard agent signal --status error --message "What went wrong"
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Step 6: Messaging with connected terminals
|
|
174
|
+
|
|
175
|
+
If your terminal config has a `messaging` section, you can exchange messages with connected terminal/agent peers. Check your config:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
cat .storyboard/terminals/${STORYBOARD_WIDGET_ID}.json | jq '.messaging'
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Send a message to a peer
|
|
182
|
+
```bash
|
|
183
|
+
npx storyboard terminal send <peerWidgetId> "Your message here"
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Or auto-resolve the connected peer (only works with a single connected terminal):
|
|
187
|
+
```bash
|
|
188
|
+
npx storyboard terminal send --connected "Your message here"
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Save your output for peers to read
|
|
192
|
+
|
|
193
|
+
**IMPORTANT: You MUST save your output after every response when messaging is enabled.** This is how your peer reads what you said — without it, they see `null`.
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
npx storyboard terminal output --summary "One-line summary" --content "Your full response text here"
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Peers read your output from your config file:
|
|
200
|
+
```bash
|
|
201
|
+
cat .storyboard/terminals/${STORYBOARD_WIDGET_ID}.json | jq '.latestOutput.content'
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Check a peer's status
|
|
205
|
+
```bash
|
|
206
|
+
npx storyboard terminal status <peerWidgetId>
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Read a peer's latest output
|
|
210
|
+
```bash
|
|
211
|
+
cat .storyboard/terminals/<peerWidgetId>.json | jq '.latestOutput'
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Messaging modes
|
|
215
|
+
Messaging is controlled by the user via the 💬 menu on terminal widgets:
|
|
216
|
+
- **No messaging** — you cannot send or receive (default)
|
|
217
|
+
- **One-way →** — only one direction is allowed
|
|
218
|
+
- **Two-way ↔** — both terminals can send freely
|
|
219
|
+
|
|
220
|
+
Check your `messaging.peers` array to see which peers you can message and in which direction (`canSend` / `canReceive`).
|
|
221
|
+
|
|
222
|
+
**IMPORTANT:**
|
|
223
|
+
- NEVER write directly to `.canvas.jsonl` files — use the canvas CLI or server API
|
|
224
|
+
- **Prefer CLI commands** (`npx storyboard canvas ...`) over direct HTTP calls — they resolve ports automatically
|
|
225
|
+
- Only fall back to HTTP API (`{serverUrl}/_storyboard/canvas/`) if the CLI doesn't support the operation
|
|
226
|
+
- Environment variables `$STORYBOARD_WIDGET_ID`, `$STORYBOARD_CANVAS_ID`, `$STORYBOARD_BRANCH`, `$STORYBOARD_SERVER_URL` are available in the shell
|
|
227
|
+
|
|
228
|
+
## HTTP API Reference (fallback only)
|
|
229
|
+
|
|
230
|
+
If the CLI fails, use these endpoints. The `serverUrl` is in your terminal config or `$STORYBOARD_SERVER_URL`.
|
|
231
|
+
|
|
232
|
+
### Safe: Update a single widget (PATCH)
|
|
233
|
+
```bash
|
|
234
|
+
curl -s -X PATCH "${STORYBOARD_SERVER_URL}/_storyboard/canvas/widget" \
|
|
235
|
+
-H "Content-Type: application/json" \
|
|
236
|
+
-d '{"name":"<canvasId>","widgetId":"<widgetId>","props":{"text":"new value"}}'
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Safe: Read canvas state (GET)
|
|
240
|
+
```bash
|
|
241
|
+
curl -s "${STORYBOARD_SERVER_URL}/_storyboard/canvas/<canvasId>"
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### ⚠️ NEVER use `PUT /_storyboard/canvas/update` with a `widgets` array
|
|
245
|
+
That endpoint **replaces ALL widgets** in the canvas. Sending one widget = deleting everything else.
|
|
246
|
+
"""
|
package/scaffold/manifest.json
CHANGED
|
@@ -60,7 +60,7 @@ const { x, y, adjusted } = findFreePosition({
|
|
|
60
60
|
|------|------------|-------------|-------------|
|
|
61
61
|
| `sticky-note` | 270×170 | `text` | `color` (yellow, blue, green, pink, purple, orange), `width`, `height` |
|
|
62
62
|
| `markdown` | 530×240 | `content` (markdown) | `width` |
|
|
63
|
-
| `prototype` | 800×600 | `src` (URL/path) | `label`, `zoom` (
|
|
63
|
+
| `prototype` | 800×600 | `src` (URL/path) | `label`, `zoom` (10–250), `width`, `height` |
|
|
64
64
|
| `figma-embed` | 800×450 | `url` | `width`, `height` |
|
|
65
65
|
| `image` | — | `src` (filename) | `width`, `height`, `private` |
|
|
66
66
|
| `link-preview` | — | `url` | `title` |
|
|
@@ -209,9 +209,10 @@ Where:
|
|
|
209
209
|
|
|
210
210
|
**Implicit reference** — If the user says "to the right of the blue sticky" without an ID, read the canvas state and find the matching widget by type + props (e.g. a sticky-note with `color: "blue"`). If ambiguous, ask.
|
|
211
211
|
|
|
212
|
-
**No position given** — Place
|
|
213
|
-
|
|
214
|
-
|
|
212
|
+
**No position given** — Place near the user's viewport:
|
|
213
|
+
1. Read `.storyboard/.selectedwidgets.json` and check the `viewport` field
|
|
214
|
+
2. If viewport exists, place near `viewport.centerX, viewport.centerY` (offset slightly to avoid overlap with existing widgets)
|
|
215
|
+
3. If no viewport data, fall back to: empty canvas → `(0, 0)`, otherwise → right of rightmost widget or below last row
|
|
215
216
|
|
|
216
217
|
### Step 4: Execute the operation
|
|
217
218
|
|
|
@@ -110,7 +110,7 @@ Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>"
|
|
|
110
110
|
|
|
111
111
|
Launch a single `rubber-duck` agent with an adversarial framing. Include the plan from Step 2, the diff of all changes (`git diff HEAD~1`), and the feature requirements from the user's original prompt.
|
|
112
112
|
|
|
113
|
-
**For each changed file**, check if architecture documentation exists at `.
|
|
113
|
+
**For each changed file**, check if architecture documentation exists at `.agents/architecture/path/to/file/filename.ext.md` and include it as context in the review prompt. This gives the reviewer the documented intent, invariants, and patterns for that file.
|
|
114
114
|
|
|
115
115
|
The prompt must include:
|
|
116
116
|
|
|
@@ -24,7 +24,20 @@
|
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
26
|
"featureFlags": {},
|
|
27
|
-
"canvas": {
|
|
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
|
+
"commandPalette": {
|
|
39
|
+
"ranking": "frecency"
|
|
40
|
+
},
|
|
28
41
|
"customerMode": {
|
|
29
42
|
"enabled": false,
|
|
30
43
|
"hideChrome": false,
|