@dfosco/storyboard 0.5.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/commandpalette.config.json +152 -0
- package/dist/storyboard-ui.css +1 -0
- package/dist/storyboard-ui.js +21328 -0
- package/dist/storyboard-ui.js.map +1 -0
- package/dist/tailwind.css +2 -0
- package/dist/tiny-canvas.css +1 -0
- package/dist/tiny-canvas.js +389 -0
- package/package.json +121 -0
- package/paste.config.json +67 -0
- package/scaffold/AGENTS.md +432 -0
- 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/deploy.yml +103 -0
- package/scaffold/githooks/pre-push +114 -0
- package/scaffold/gitignore +64 -0
- package/scaffold/manifest.json +56 -0
- package/scaffold/preview.yml +181 -0
- package/scaffold/scripts/link.sh +26 -0
- package/scaffold/scripts/unlink.sh +10 -0
- package/scaffold/skills/agent-browser/SKILL.md +260 -0
- package/scaffold/skills/canvas/SKILL.md +364 -0
- package/scaffold/skills/create/SKILL.md +501 -0
- package/scaffold/skills/ship/SKILL.md +237 -0
- package/scaffold/skills/storyboard/SKILL.md +360 -0
- package/scaffold/skills/update-storyboard/SKILL.md +16 -0
- package/scaffold/skills/update-storyboard/update-storyboard-packages.sh +26 -0
- package/scaffold/skills/vitest/GENERATION.md +5 -0
- package/scaffold/skills/vitest/SKILL.md +52 -0
- package/scaffold/skills/vitest/references/advanced-environments.md +264 -0
- package/scaffold/skills/vitest/references/advanced-projects.md +300 -0
- package/scaffold/skills/vitest/references/advanced-type-testing.md +237 -0
- package/scaffold/skills/vitest/references/advanced-vi.md +249 -0
- package/scaffold/skills/vitest/references/core-cli.md +166 -0
- package/scaffold/skills/vitest/references/core-config.md +174 -0
- package/scaffold/skills/vitest/references/core-describe.md +193 -0
- package/scaffold/skills/vitest/references/core-expect.md +219 -0
- package/scaffold/skills/vitest/references/core-hooks.md +244 -0
- package/scaffold/skills/vitest/references/core-test-api.md +233 -0
- package/scaffold/skills/vitest/references/features-concurrency.md +250 -0
- package/scaffold/skills/vitest/references/features-context.md +238 -0
- package/scaffold/skills/vitest/references/features-coverage.md +207 -0
- package/scaffold/skills/vitest/references/features-filtering.md +211 -0
- package/scaffold/skills/vitest/references/features-mocking.md +265 -0
- package/scaffold/skills/vitest/references/features-snapshots.md +207 -0
- package/scaffold/skills/worktree/SKILL.md +93 -0
- package/scaffold/storyboard.config.json +44 -0
- package/src/canvas/Canvas.jsx +78 -0
- package/src/canvas/Draggable.jsx +235 -0
- package/src/canvas/index.d.ts +41 -0
- package/src/canvas/index.js +6 -0
- package/src/canvas/style.css +118 -0
- package/src/canvas/useResetCanvas.js +17 -0
- package/src/canvas/utils.js +136 -0
- package/src/core/assets/fonts/IoskeleyMono-Bold.woff2 +0 -0
- package/src/core/assets/fonts/IoskeleyMono-Italic.woff2 +0 -0
- package/src/core/assets/fonts/IoskeleyMono-Medium.woff2 +0 -0
- package/src/core/assets/fonts/IoskeleyMono-Regular.woff2 +0 -0
- package/src/core/assets/fonts/IoskeleyMono-SemiBold.woff2 +0 -0
- package/src/core/autosync/server.js +714 -0
- package/src/core/autosync/server.test.js +158 -0
- package/src/core/canvas/__tests__/agent-integration.test.js +596 -0
- package/src/core/canvas/__tests__/helpers/browser.js +95 -0
- package/src/core/canvas/__tests__/helpers/canvas-api.js +129 -0
- package/src/core/canvas/__tests__/helpers/perf.js +118 -0
- package/src/core/canvas/__tests__/helpers/setup.js +176 -0
- package/src/core/canvas/__tests__/helpers/tmux.js +130 -0
- package/src/core/canvas/__tests__/helpers/transcript.js +132 -0
- package/src/core/canvas/__tests__/terminal-integration.test.js +177 -0
- package/src/core/canvas/collision.js +292 -0
- package/src/core/canvas/collision.test.js +371 -0
- package/src/core/canvas/compact.js +83 -0
- package/src/core/canvas/deriveCanvasId.test.js +40 -0
- package/src/core/canvas/githubEmbeds.js +527 -0
- package/src/core/canvas/githubEmbeds.test.js +302 -0
- package/src/core/canvas/hot-pool.js +766 -0
- package/src/core/canvas/identity.js +107 -0
- package/src/core/canvas/identity.test.js +100 -0
- package/src/core/canvas/materializer.js +259 -0
- package/src/core/canvas/materializer.test.js +356 -0
- package/src/core/canvas/selectedWidgets.js +270 -0
- package/src/core/canvas/selectedWidgets.test.js +321 -0
- package/src/core/canvas/server.js +3134 -0
- package/src/core/canvas/server.test.js +379 -0
- package/src/core/canvas/terminal-config.js +330 -0
- package/src/core/canvas/terminal-registry.js +465 -0
- package/src/core/canvas/terminal-server.js +1436 -0
- package/src/core/canvas/writeGuard.js +53 -0
- package/src/core/cli/agent.js +85 -0
- package/src/core/cli/branch.js +386 -0
- package/src/core/cli/canvasAdd.js +241 -0
- package/src/core/cli/canvasBatch.js +98 -0
- package/src/core/cli/canvasBounds.js +160 -0
- package/src/core/cli/canvasRead.js +236 -0
- package/src/core/cli/canvasUpdate.js +179 -0
- package/src/core/cli/code.js +67 -0
- package/src/core/cli/compact.js +62 -0
- package/src/core/cli/create.js +674 -0
- package/src/core/cli/dev-helpers.js +53 -0
- package/src/core/cli/dev-helpers.test.js +53 -0
- package/src/core/cli/dev.js +430 -0
- package/src/core/cli/exit.js +38 -0
- package/src/core/cli/flags.js +174 -0
- package/src/core/cli/flags.test.js +155 -0
- package/src/core/cli/index.js +233 -0
- package/src/core/cli/intro.js +37 -0
- package/src/core/cli/proxy.js +319 -0
- package/src/core/cli/proxy.test.js +63 -0
- package/src/core/cli/schemas.js +223 -0
- package/src/core/cli/server.js +192 -0
- package/src/core/cli/serverUrl.js +61 -0
- package/src/core/cli/sessions.js +459 -0
- package/src/core/cli/setup.js +404 -0
- package/src/core/cli/terminal-commands.js +287 -0
- package/src/core/cli/terminal-messaging.js +231 -0
- package/src/core/cli/terminal-welcome.js +515 -0
- package/src/core/cli/updateVersion.js +124 -0
- package/src/core/comments/api.js +284 -0
- package/src/core/comments/api.test.js +282 -0
- package/src/core/comments/auth.js +151 -0
- package/src/core/comments/auth.test.js +167 -0
- package/src/core/comments/commentCache.js +109 -0
- package/src/core/comments/commentCache.test.js +48 -0
- package/src/core/comments/commentDrafts.js +68 -0
- package/src/core/comments/commentMode.js +63 -0
- package/src/core/comments/commentMode.test.js +90 -0
- package/src/core/comments/config.js +47 -0
- package/src/core/comments/config.test.js +77 -0
- package/src/core/comments/graphql.js +65 -0
- package/src/core/comments/graphql.test.js +95 -0
- package/src/core/comments/index.js +42 -0
- package/src/core/comments/metadata.js +52 -0
- package/src/core/comments/metadata.test.js +110 -0
- package/src/core/comments/queries.js +245 -0
- package/src/core/comments/ui/AuthModal.jsx +114 -0
- package/src/core/comments/ui/CommentOverlay.js +52 -0
- package/src/core/comments/ui/CommentWindow.jsx +329 -0
- package/src/core/comments/ui/CommentsDrawer.jsx +102 -0
- package/src/core/comments/ui/Composer.jsx +64 -0
- package/src/core/comments/ui/authModal.js +66 -0
- package/src/core/comments/ui/authModal.test.js +76 -0
- package/src/core/comments/ui/comment-cursor-dark.svg +1 -0
- package/src/core/comments/ui/comment-cursor.svg +1 -0
- package/src/core/comments/ui/comment-layout.css +142 -0
- package/src/core/comments/ui/commentWindow.js +121 -0
- package/src/core/comments/ui/comments.css +242 -0
- package/src/core/comments/ui/commentsDrawer.js +84 -0
- package/src/core/comments/ui/composer.js +136 -0
- package/src/core/comments/ui/index.js +14 -0
- package/src/core/comments/ui/mount.js +687 -0
- package/src/core/comments/ui/mount.test.js +336 -0
- package/src/core/data/dotPath.js +53 -0
- package/src/core/data/dotPath.test.js +114 -0
- package/src/core/data/loader.js +409 -0
- package/src/core/data/loader.test.js +599 -0
- package/src/core/data/viewfinder.js +363 -0
- package/src/core/data/viewfinder.test.js +456 -0
- package/src/core/devtools/devtools-consumer.js +28 -0
- package/src/core/devtools/devtools.js +144 -0
- package/src/core/devtools/devtools.test.js +75 -0
- package/src/core/devtools/sceneDebug.js +112 -0
- package/src/core/devtools/sceneDebug.test.js +141 -0
- package/src/core/index.js +124 -0
- package/src/core/inspector/fiberWalker.js +239 -0
- package/src/core/inspector/highlighter.js +275 -0
- package/src/core/inspector/mouseMode.js +259 -0
- package/src/core/lib/components/ui/alert/alert-action.jsx +11 -0
- package/src/core/lib/components/ui/alert/alert-description.jsx +11 -0
- package/src/core/lib/components/ui/alert/alert-title.jsx +11 -0
- package/src/core/lib/components/ui/alert/alert.jsx +25 -0
- package/src/core/lib/components/ui/alert/index.js +17 -0
- package/src/core/lib/components/ui/avatar/avatar-badge.jsx +22 -0
- package/src/core/lib/components/ui/avatar/avatar-fallback.jsx +18 -0
- package/src/core/lib/components/ui/avatar/avatar-group-count.jsx +19 -0
- package/src/core/lib/components/ui/avatar/avatar-group.jsx +19 -0
- package/src/core/lib/components/ui/avatar/avatar-image.jsx +15 -0
- package/src/core/lib/components/ui/avatar/avatar.jsx +19 -0
- package/src/core/lib/components/ui/avatar/index.js +22 -0
- package/src/core/lib/components/ui/badge/badge.jsx +31 -0
- package/src/core/lib/components/ui/badge/index.js +2 -0
- package/src/core/lib/components/ui/button/button.jsx +100 -0
- package/src/core/lib/components/ui/button/index.js +12 -0
- package/src/core/lib/components/ui/card/card-action.jsx +11 -0
- package/src/core/lib/components/ui/card/card-content.jsx +11 -0
- package/src/core/lib/components/ui/card/card-description.jsx +11 -0
- package/src/core/lib/components/ui/card/card-footer.jsx +11 -0
- package/src/core/lib/components/ui/card/card-header.jsx +19 -0
- package/src/core/lib/components/ui/card/card-title.jsx +11 -0
- package/src/core/lib/components/ui/card/card.jsx +17 -0
- package/src/core/lib/components/ui/card/index.js +25 -0
- package/src/core/lib/components/ui/checkbox/checkbox.jsx +29 -0
- package/src/core/lib/components/ui/checkbox/index.js +6 -0
- package/src/core/lib/components/ui/collapsible/collapsible-content.jsx +7 -0
- package/src/core/lib/components/ui/collapsible/collapsible-trigger.jsx +7 -0
- package/src/core/lib/components/ui/collapsible/collapsible.jsx +7 -0
- package/src/core/lib/components/ui/collapsible/index.js +13 -0
- package/src/core/lib/components/ui/dialog/dialog-close.jsx +7 -0
- package/src/core/lib/components/ui/dialog/dialog-content.jsx +34 -0
- package/src/core/lib/components/ui/dialog/dialog-description.jsx +15 -0
- package/src/core/lib/components/ui/dialog/dialog-footer.jsx +23 -0
- package/src/core/lib/components/ui/dialog/dialog-header.jsx +11 -0
- package/src/core/lib/components/ui/dialog/dialog-overlay.jsx +15 -0
- package/src/core/lib/components/ui/dialog/dialog-portal.jsx +4 -0
- package/src/core/lib/components/ui/dialog/dialog-title.jsx +15 -0
- package/src/core/lib/components/ui/dialog/dialog-trigger.jsx +7 -0
- package/src/core/lib/components/ui/dialog/dialog.jsx +4 -0
- package/src/core/lib/components/ui/dialog/index.js +34 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.jsx +8 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.jsx +30 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-content.jsx +22 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.jsx +16 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-group.jsx +7 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-item.jsx +20 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-label.jsx +17 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-portal.jsx +4 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.jsx +7 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.jsx +29 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-separator.jsx +15 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.jsx +16 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.jsx +15 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.jsx +23 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-sub.jsx +4 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-trigger.jsx +7 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu.jsx +4 -0
- package/src/core/lib/components/ui/dropdown-menu/index.js +54 -0
- package/src/core/lib/components/ui/input/index.js +7 -0
- package/src/core/lib/components/ui/input/input.jsx +19 -0
- package/src/core/lib/components/ui/label/index.js +7 -0
- package/src/core/lib/components/ui/label/label.jsx +19 -0
- package/src/core/lib/components/ui/panel/index.js +24 -0
- package/src/core/lib/components/ui/panel/panel-body.jsx +11 -0
- package/src/core/lib/components/ui/panel/panel-close.jsx +16 -0
- package/src/core/lib/components/ui/panel/panel-content.jsx +29 -0
- package/src/core/lib/components/ui/panel/panel-footer.jsx +11 -0
- package/src/core/lib/components/ui/panel/panel-header.jsx +11 -0
- package/src/core/lib/components/ui/panel/panel-title.jsx +12 -0
- package/src/core/lib/components/ui/panel/panel.jsx +4 -0
- package/src/core/lib/components/ui/popover/index.js +28 -0
- package/src/core/lib/components/ui/popover/popover-close.jsx +7 -0
- package/src/core/lib/components/ui/popover/popover-content.jsx +22 -0
- package/src/core/lib/components/ui/popover/popover-description.jsx +11 -0
- package/src/core/lib/components/ui/popover/popover-header.jsx +11 -0
- package/src/core/lib/components/ui/popover/popover-portal.jsx +4 -0
- package/src/core/lib/components/ui/popover/popover-title.jsx +11 -0
- package/src/core/lib/components/ui/popover/popover-trigger.jsx +8 -0
- package/src/core/lib/components/ui/popover/popover.jsx +4 -0
- package/src/core/lib/components/ui/searchable-list.jsx +160 -0
- package/src/core/lib/components/ui/select/index.js +37 -0
- package/src/core/lib/components/ui/select/select-content.jsx +30 -0
- package/src/core/lib/components/ui/select/select-group-heading.jsx +17 -0
- package/src/core/lib/components/ui/select/select-group.jsx +15 -0
- package/src/core/lib/components/ui/select/select-item.jsx +26 -0
- package/src/core/lib/components/ui/select/select-label.jsx +11 -0
- package/src/core/lib/components/ui/select/select-portal.jsx +4 -0
- package/src/core/lib/components/ui/select/select-scroll-down-button.jsx +18 -0
- package/src/core/lib/components/ui/select/select-scroll-up-button.jsx +18 -0
- package/src/core/lib/components/ui/select/select-separator.jsx +15 -0
- package/src/core/lib/components/ui/select/select-trigger.jsx +25 -0
- package/src/core/lib/components/ui/select/select.jsx +4 -0
- package/src/core/lib/components/ui/separator/index.js +7 -0
- package/src/core/lib/components/ui/separator/separator.jsx +22 -0
- package/src/core/lib/components/ui/sheet/index.js +34 -0
- package/src/core/lib/components/ui/sheet/sheet-close.jsx +7 -0
- package/src/core/lib/components/ui/sheet/sheet-content.jsx +35 -0
- package/src/core/lib/components/ui/sheet/sheet-description.jsx +15 -0
- package/src/core/lib/components/ui/sheet/sheet-footer.jsx +11 -0
- package/src/core/lib/components/ui/sheet/sheet-header.jsx +11 -0
- package/src/core/lib/components/ui/sheet/sheet-overlay.jsx +15 -0
- package/src/core/lib/components/ui/sheet/sheet-portal.jsx +4 -0
- package/src/core/lib/components/ui/sheet/sheet-title.jsx +15 -0
- package/src/core/lib/components/ui/sheet/sheet-trigger.jsx +7 -0
- package/src/core/lib/components/ui/sheet/sheet.jsx +4 -0
- package/src/core/lib/components/ui/textarea/index.js +7 -0
- package/src/core/lib/components/ui/textarea/textarea.jsx +18 -0
- package/src/core/lib/components/ui/toggle/index.js +8 -0
- package/src/core/lib/components/ui/toggle/toggle.jsx +36 -0
- package/src/core/lib/components/ui/toggle-group/index.js +10 -0
- package/src/core/lib/components/ui/toggle-group/toggle-group-item.jsx +29 -0
- package/src/core/lib/components/ui/toggle-group/toggle-group.jsx +43 -0
- package/src/core/lib/components/ui/tooltip/index.js +3 -0
- package/src/core/lib/components/ui/tooltip/tooltip-content.jsx +21 -0
- package/src/core/lib/components/ui/tooltip/tooltip-trigger.jsx +23 -0
- package/src/core/lib/components/ui/tooltip/tooltip.jsx +11 -0
- package/src/core/lib/components/ui/trigger-button/index.js +6 -0
- package/src/core/lib/components/ui/trigger-button/trigger-button.css +38 -0
- package/src/core/lib/components/ui/trigger-button/trigger-button.jsx +63 -0
- package/src/core/lib/utils/index.js +6 -0
- package/src/core/logger/devLogger.js +238 -0
- package/src/core/logger/devLogger.test.js +193 -0
- package/src/core/modes/modes.css +98 -0
- package/src/core/modes/modes.js +492 -0
- package/src/core/modes/modes.test.js +562 -0
- package/src/core/mountStoryboardCore.js +478 -0
- package/src/core/rename-watcher/config.json +23 -0
- package/src/core/rename-watcher/watcher.js +531 -0
- package/src/core/scaffold.js +100 -0
- package/src/core/server/index.js +391 -0
- package/src/core/session/bodyClasses.js +128 -0
- package/src/core/session/bodyClasses.test.js +192 -0
- package/src/core/session/hashSubscribe.js +19 -0
- package/src/core/session/hashSubscribe.test.js +62 -0
- package/src/core/session/hideMode.js +424 -0
- package/src/core/session/hideMode.test.js +268 -0
- package/src/core/session/interceptHideParams.js +35 -0
- package/src/core/session/interceptHideParams.test.js +90 -0
- package/src/core/session/localStorage.js +134 -0
- package/src/core/session/localStorage.test.js +148 -0
- package/src/core/session/session.js +76 -0
- package/src/core/session/session.test.js +91 -0
- package/src/core/stores/canvasConfig.js +134 -0
- package/src/core/stores/canvasConfig.test.js +120 -0
- package/src/core/stores/commandActions.js +284 -0
- package/src/core/stores/commandPaletteConfig.js +31 -0
- package/src/core/stores/configSchema.js +232 -0
- package/src/core/stores/configSchema.test.js +72 -0
- package/src/core/stores/configStore.js +161 -0
- package/src/core/stores/customerModeConfig.js +30 -0
- package/src/core/stores/featureFlags.js +127 -0
- package/src/core/stores/paletteProviders.js +360 -0
- package/src/core/stores/paletteProviders.test.js +186 -0
- package/src/core/stores/plugins.js +40 -0
- package/src/core/stores/plugins.test.js +68 -0
- package/src/core/stores/recentArtifacts.js +68 -0
- package/src/core/stores/recentArtifacts.test.js +71 -0
- package/src/core/stores/sidePanelStore.ts +143 -0
- package/src/core/stores/themeStore.ts +291 -0
- package/src/core/stores/toolRegistry.js +227 -0
- package/src/core/stores/toolStateStore.js +183 -0
- package/src/core/stores/toolStateStore.test.js +220 -0
- package/src/core/stores/toolbarConfigStore.js +165 -0
- package/src/core/stores/uiConfig.js +64 -0
- package/src/core/stores/uiConfig.test.js +63 -0
- package/src/core/styles/tailwind.css +204 -0
- package/src/core/tools/handlers/autosync.js +12 -0
- package/src/core/tools/handlers/canvasAddWidget.js +11 -0
- package/src/core/tools/handlers/canvasAgents.js +20 -0
- package/src/core/tools/handlers/canvasToolbar.js +56 -0
- package/src/core/tools/handlers/commandPalette.js +9 -0
- package/src/core/tools/handlers/comments.js +16 -0
- package/src/core/tools/handlers/create.js +39 -0
- package/src/core/tools/handlers/devtools.js +122 -0
- package/src/core/tools/handlers/devtools.test.js +87 -0
- package/src/core/tools/handlers/featureFlags.js +21 -0
- package/src/core/tools/handlers/flows.js +68 -0
- package/src/core/tools/handlers/hideChrome.js +9 -0
- package/src/core/tools/handlers/hideToolbars.js +25 -0
- package/src/core/tools/handlers/inspector.js +19 -0
- package/src/core/tools/handlers/paletteTheme.js +35 -0
- package/src/core/tools/handlers/theme.js +9 -0
- package/src/core/tools/registry.js +26 -0
- package/src/core/tools/surfaces/canvasToolbar.js +10 -0
- package/src/core/tools/surfaces/commandList.js +10 -0
- package/src/core/tools/surfaces/mainToolbar.js +11 -0
- package/src/core/tools/surfaces/registry.js +19 -0
- package/src/core/ui/ActionMenuButton.jsx +114 -0
- package/src/core/ui/AutosyncMenuButton.css +67 -0
- package/src/core/ui/AutosyncMenuButton.jsx +242 -0
- package/src/core/ui/BranchSelect.jsx +29 -0
- package/src/core/ui/BranchSelect.module.css +30 -0
- package/src/core/ui/CanvasAgentsMenu.jsx +89 -0
- package/src/core/ui/CanvasCreateMenu.jsx +611 -0
- package/src/core/ui/CanvasSnap.css +27 -0
- package/src/core/ui/CanvasSnap.jsx +51 -0
- package/src/core/ui/CanvasUndoRedo.css +36 -0
- package/src/core/ui/CanvasUndoRedo.jsx +62 -0
- package/src/core/ui/CanvasZoomControl.css +53 -0
- package/src/core/ui/CanvasZoomControl.jsx +49 -0
- package/src/core/ui/CanvasZoomToFit.css +18 -0
- package/src/core/ui/CanvasZoomToFit.jsx +26 -0
- package/src/core/ui/CommandMenu.css +8 -0
- package/src/core/ui/CommandMenu.jsx +287 -0
- package/src/core/ui/CommandPalette.jsx +35 -0
- package/src/core/ui/CommandPaletteTrigger.jsx +25 -0
- package/src/core/ui/CommentsMenuButton.jsx +40 -0
- package/src/core/ui/CoreUIBar.css +47 -0
- package/src/core/ui/CoreUIBar.jsx +905 -0
- package/src/core/ui/CreateMenuButton.jsx +117 -0
- package/src/core/ui/HideChromeTrigger.jsx +48 -0
- package/src/core/ui/Icon.jsx +279 -0
- package/src/core/ui/InspectorPanel.css +109 -0
- package/src/core/ui/InspectorPanel.jsx +632 -0
- package/src/core/ui/PwaInstallBanner.css +42 -0
- package/src/core/ui/PwaInstallBanner.jsx +124 -0
- package/src/core/ui/SidePanel.jsx +261 -0
- package/src/core/ui/ThemeMenuButton.jsx +139 -0
- package/src/core/ui/core-ui-colors.css +129 -0
- package/src/core/ui/design-modes.ts +7 -0
- package/src/core/ui/sidepanel.css +301 -0
- package/src/core/ui/viewfinder.ts +7 -0
- package/src/core/ui-entry.js +30 -0
- package/src/core/utils/fuzzySearch.js +117 -0
- package/src/core/utils/fuzzySearch.test.js +119 -0
- package/src/core/utils/mobileViewport.js +57 -0
- package/src/core/utils/mobileViewport.test.js +68 -0
- package/src/core/utils/prodMode.js +38 -0
- package/src/core/utils/smoothCorners.js +20 -0
- package/src/core/vite/docs-handler.js +155 -0
- package/src/core/vite/server-plugin.js +797 -0
- package/src/core/workshop/features/createCanvas/CreateCanvasForm.jsx +260 -0
- package/src/core/workshop/features/createCanvas/index.js +14 -0
- package/src/core/workshop/features/createFlow/CreateFlowForm.jsx +334 -0
- package/src/core/workshop/features/createFlow/index.js +19 -0
- package/src/core/workshop/features/createFlow/server.js +663 -0
- package/src/core/workshop/features/createPage/CreatePageForm.jsx +304 -0
- package/src/core/workshop/features/createPage/index.js +11 -0
- package/src/core/workshop/features/createPrototype/CreatePrototypeForm.jsx +289 -0
- package/src/core/workshop/features/createPrototype/index.js +19 -0
- package/src/core/workshop/features/createPrototype/server.js +433 -0
- package/src/core/workshop/features/createStory/CreateStoryForm.jsx +208 -0
- package/src/core/workshop/features/createStory/index.js +14 -0
- package/src/core/workshop/features/registry-server.js +22 -0
- package/src/core/workshop/features/registry.js +28 -0
- package/src/core/workshop/features/templateIndex.js +155 -0
- package/src/core/workshop/ui/WorkshopPanel.jsx +98 -0
- package/src/core/workshop/ui/mount.ts +6 -0
- package/src/core/worktree/port.js +268 -0
- package/src/core/worktree/port.test.js +222 -0
- package/src/core/worktree/serverRegistry.js +120 -0
- package/src/internals/AuthModal/AuthModal.jsx +132 -0
- package/src/internals/AuthModal/AuthModal.module.css +221 -0
- package/src/internals/BranchBar/BranchBar.jsx +87 -0
- package/src/internals/BranchBar/BranchBar.module.css +247 -0
- package/src/internals/BranchBar/useBranches.js +93 -0
- package/src/internals/BranchBar/useBranches.test.js +68 -0
- package/src/internals/CommandPalette/CommandPalette.jsx +1361 -0
- package/src/internals/CommandPalette/CreateDialog.jsx +219 -0
- package/src/internals/CommandPalette/command-palette.css +180 -0
- package/src/internals/FlowError.module.css +30 -0
- package/src/internals/Icon.jsx +279 -0
- package/src/internals/StoryboardContext.js +3 -0
- package/src/internals/Viewfinder.jsx +1479 -0
- package/src/internals/Viewfinder.module.css +1540 -0
- package/src/internals/Workspace.jsx +7 -0
- package/src/internals/__mocks__/virtual-storyboard-data-index.js +4 -0
- package/src/internals/canvas/CanvasControls.jsx +112 -0
- package/src/internals/canvas/CanvasControls.module.css +135 -0
- package/src/internals/canvas/CanvasPage.bridge.test.jsx +387 -0
- package/src/internals/canvas/CanvasPage.dragdrop.test.jsx +350 -0
- package/src/internals/canvas/CanvasPage.jsx +3092 -0
- package/src/internals/canvas/CanvasPage.module.css +187 -0
- package/src/internals/canvas/CanvasPage.multiselect.test.jsx +358 -0
- package/src/internals/canvas/CanvasToolbar.jsx +73 -0
- package/src/internals/canvas/CanvasToolbar.module.css +92 -0
- package/src/internals/canvas/ComponentErrorBoundary.jsx +50 -0
- package/src/internals/canvas/ConnectorLayer.jsx +208 -0
- package/src/internals/canvas/ConnectorLayer.module.css +129 -0
- package/src/internals/canvas/MarqueeOverlay.jsx +20 -0
- package/src/internals/canvas/PageSelector.jsx +587 -0
- package/src/internals/canvas/PageSelector.module.css +261 -0
- package/src/internals/canvas/PageSelector.test.jsx +113 -0
- package/src/internals/canvas/WebGLContextPool.jsx +292 -0
- package/src/internals/canvas/WebGLContextPool.test.jsx +165 -0
- package/src/internals/canvas/canvasApi.js +164 -0
- package/src/internals/canvas/canvasReloadGuard.js +37 -0
- package/src/internals/canvas/canvasReloadGuard.test.js +27 -0
- package/src/internals/canvas/canvasTheme.js +118 -0
- package/src/internals/canvas/componentIsolate.jsx +165 -0
- package/src/internals/canvas/componentSetIsolate.jsx +257 -0
- package/src/internals/canvas/computeCanvasBounds.test.js +121 -0
- package/src/internals/canvas/connectorGeometry.js +132 -0
- package/src/internals/canvas/hotPoolDevLogs.js +25 -0
- package/src/internals/canvas/textSelection.js +10 -0
- package/src/internals/canvas/textSelection.test.js +26 -0
- package/src/internals/canvas/useCanvas.js +126 -0
- package/src/internals/canvas/useCanvas.test.js +26 -0
- package/src/internals/canvas/useMarqueeSelect.js +213 -0
- package/src/internals/canvas/useMarqueeSelect.test.js +78 -0
- package/src/internals/canvas/useUndoRedo.js +86 -0
- package/src/internals/canvas/useUndoRedo.test.js +231 -0
- package/src/internals/canvas/widgets/CodePenEmbed.jsx +293 -0
- package/src/internals/canvas/widgets/CodePenEmbed.module.css +161 -0
- package/src/internals/canvas/widgets/ComponentSetWidget.jsx +2 -0
- package/src/internals/canvas/widgets/ComponentSetWidget.module.css +89 -0
- package/src/internals/canvas/widgets/ComponentWidget.jsx +14 -0
- package/src/internals/canvas/widgets/ComponentWidget.module.css +0 -0
- package/src/internals/canvas/widgets/CropOverlay.jsx +179 -0
- package/src/internals/canvas/widgets/CropOverlay.module.css +154 -0
- package/src/internals/canvas/widgets/ExpandedPane.jsx +474 -0
- package/src/internals/canvas/widgets/ExpandedPane.module.css +179 -0
- package/src/internals/canvas/widgets/ExpandedPane.test.jsx +240 -0
- package/src/internals/canvas/widgets/ExpandedPaneTopBar.jsx +111 -0
- package/src/internals/canvas/widgets/ExpandedPaneTopBar.module.css +59 -0
- package/src/internals/canvas/widgets/ExpandedPaneTopBar.test.jsx +45 -0
- package/src/internals/canvas/widgets/FigmaEmbed.jsx +296 -0
- package/src/internals/canvas/widgets/FigmaEmbed.module.css +222 -0
- package/src/internals/canvas/widgets/FrozenTerminalOverlay.jsx +151 -0
- package/src/internals/canvas/widgets/FrozenTerminalOverlay.module.css +83 -0
- package/src/internals/canvas/widgets/ImageWidget.jsx +287 -0
- package/src/internals/canvas/widgets/ImageWidget.module.css +81 -0
- package/src/internals/canvas/widgets/LinkPreview.jsx +439 -0
- package/src/internals/canvas/widgets/LinkPreview.module.css +585 -0
- package/src/internals/canvas/widgets/LinkPreview.test.jsx +193 -0
- package/src/internals/canvas/widgets/MarkdownBlock.jsx +354 -0
- package/src/internals/canvas/widgets/MarkdownBlock.module.css +377 -0
- package/src/internals/canvas/widgets/MarkdownBlock.test.jsx +92 -0
- package/src/internals/canvas/widgets/PromptWidget.jsx +428 -0
- package/src/internals/canvas/widgets/PromptWidget.module.css +273 -0
- package/src/internals/canvas/widgets/PrototypeEmbed.jsx +463 -0
- package/src/internals/canvas/widgets/PrototypeEmbed.module.css +579 -0
- package/src/internals/canvas/widgets/PrototypeEmbed.test.jsx +10 -0
- package/src/internals/canvas/widgets/ResizeHandle.jsx +67 -0
- package/src/internals/canvas/widgets/ResizeHandle.module.css +29 -0
- package/src/internals/canvas/widgets/StickyNote.jsx +92 -0
- package/src/internals/canvas/widgets/StickyNote.module.css +70 -0
- package/src/internals/canvas/widgets/StickyNote.test.jsx +116 -0
- package/src/internals/canvas/widgets/StorySetWidget.jsx +208 -0
- package/src/internals/canvas/widgets/StorySetWidget.module.css +89 -0
- package/src/internals/canvas/widgets/StoryWidget.jsx +334 -0
- package/src/internals/canvas/widgets/StoryWidget.module.css +211 -0
- package/src/internals/canvas/widgets/TerminalReadWidget.jsx +146 -0
- package/src/internals/canvas/widgets/TerminalReadWidget.module.css +94 -0
- package/src/internals/canvas/widgets/TerminalWidget.jsx +704 -0
- package/src/internals/canvas/widgets/TerminalWidget.module.css +444 -0
- package/src/internals/canvas/widgets/TilesWidget.jsx +300 -0
- package/src/internals/canvas/widgets/TilesWidget.module.css +133 -0
- package/src/internals/canvas/widgets/WidgetChrome.jsx +580 -0
- package/src/internals/canvas/widgets/WidgetChrome.module.css +421 -0
- package/src/internals/canvas/widgets/WidgetWrapper.jsx +15 -0
- package/src/internals/canvas/widgets/WidgetWrapper.module.css +25 -0
- package/src/internals/canvas/widgets/codepenUrl.js +75 -0
- package/src/internals/canvas/widgets/codepenUrl.test.js +76 -0
- package/src/internals/canvas/widgets/embedInteraction.test.jsx +173 -0
- package/src/internals/canvas/widgets/embedOverlay.module.css +35 -0
- package/src/internals/canvas/widgets/embedTheme.js +148 -0
- package/src/internals/canvas/widgets/expandUtils.js +559 -0
- package/src/internals/canvas/widgets/expandUtils.test.js +155 -0
- package/src/internals/canvas/widgets/figmaUrl.js +118 -0
- package/src/internals/canvas/widgets/figmaUrl.test.js +139 -0
- package/src/internals/canvas/widgets/githubUrl.js +82 -0
- package/src/internals/canvas/widgets/githubUrl.test.js +74 -0
- package/src/internals/canvas/widgets/iframeDevLogs.js +49 -0
- package/src/internals/canvas/widgets/iframeDevLogs.test.jsx +81 -0
- package/src/internals/canvas/widgets/index.js +42 -0
- package/src/internals/canvas/widgets/pasteRules.js +295 -0
- package/src/internals/canvas/widgets/pasteRules.test.js +474 -0
- package/src/internals/canvas/widgets/snapshotDisplay.test.jsx +211 -0
- package/src/internals/canvas/widgets/tilePool.js +23 -0
- package/src/internals/canvas/widgets/tiles/diagonal-bl.png +0 -0
- package/src/internals/canvas/widgets/tiles/diagonal-br.png +0 -0
- package/src/internals/canvas/widgets/tiles/diagonal-tl.png +0 -0
- package/src/internals/canvas/widgets/tiles/leaf.png +0 -0
- package/src/internals/canvas/widgets/tiles/quarter-tl.png +0 -0
- package/src/internals/canvas/widgets/tiles/quarter-tr.png +0 -0
- package/src/internals/canvas/widgets/tiles/solid-a.png +0 -0
- package/src/internals/canvas/widgets/tiles/solid-b.png +0 -0
- package/src/internals/canvas/widgets/widgetConfig.js +291 -0
- package/src/internals/canvas/widgets/widgetConfig.test.js +68 -0
- package/src/internals/canvas/widgets/widgetIcons.jsx +190 -0
- package/src/internals/canvas/widgets/widgetProps.js +133 -0
- package/src/internals/context/FormContext.js +13 -0
- package/src/internals/context/FormContext.test.js +48 -0
- package/src/internals/context.jsx +481 -0
- package/src/internals/context.test.jsx +296 -0
- package/src/internals/hashPreserver.js +73 -0
- package/src/internals/hashPreserver.test.js +107 -0
- package/src/internals/hooks/useConfig.js +14 -0
- package/src/internals/hooks/useFeatureFlag.js +14 -0
- package/src/internals/hooks/useFlows.js +50 -0
- package/src/internals/hooks/useFlows.test.js +134 -0
- package/src/internals/hooks/useHideMode.js +31 -0
- package/src/internals/hooks/useHideMode.test.js +43 -0
- package/src/internals/hooks/useLocalStorage.js +57 -0
- package/src/internals/hooks/useLocalStorage.test.js +75 -0
- package/src/internals/hooks/useMode.js +43 -0
- package/src/internals/hooks/useObject.js +101 -0
- package/src/internals/hooks/useObject.test.js +74 -0
- package/src/internals/hooks/useOverride.js +84 -0
- package/src/internals/hooks/useOverride.test.js +71 -0
- package/src/internals/hooks/usePrototypeReloadGuard.js +64 -0
- package/src/internals/hooks/useRecord.js +158 -0
- package/src/internals/hooks/useRecord.test.js +221 -0
- package/src/internals/hooks/useScene.js +38 -0
- package/src/internals/hooks/useScene.test.js +66 -0
- package/src/internals/hooks/useSceneData.js +108 -0
- package/src/internals/hooks/useSceneData.test.js +136 -0
- package/src/internals/hooks/useSession.js +4 -0
- package/src/internals/hooks/useSession.test.js +8 -0
- package/src/internals/hooks/useThemeState.js +61 -0
- package/src/internals/hooks/useThemeState.test.js +66 -0
- package/src/internals/hooks/useUndoRedo.js +28 -0
- package/src/internals/hooks/useUndoRedo.test.js +64 -0
- package/src/internals/index.js +58 -0
- package/src/internals/story/ComponentSetPage.jsx +198 -0
- package/src/internals/story/ComponentSetPage.module.css +129 -0
- package/src/internals/story/StoryPage.jsx +147 -0
- package/src/internals/story/StoryPage.module.css +18 -0
- package/src/internals/test-utils.js +45 -0
- package/src/internals/vite/data-plugin.js +1508 -0
- package/src/internals/vite/data-plugin.test.js +1223 -0
- package/src/test-utils.js +44 -0
- package/toolbar.config.json +271 -0
- package/widgets.config.json +1537 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: prompt-agent
|
|
3
|
+
description: "Single-shot canvas prompt agent. Reads connected widget context, executes one task, signals completion."
|
|
4
|
+
tools:
|
|
5
|
+
- read
|
|
6
|
+
- edit
|
|
7
|
+
- shell
|
|
8
|
+
- search
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Prompt Agent
|
|
12
|
+
|
|
13
|
+
You are a **single-shot task agent** spawned by a prompt widget on a Storyboard canvas. You received your task via the `-p` flag. Your job: **execute the task, signal done or error, and exit.** Do not ask clarifying questions — infer from context.
|
|
14
|
+
|
|
15
|
+
## ⚠️ Prime Directive: Results MUST be visible on the canvas
|
|
16
|
+
|
|
17
|
+
**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.
|
|
18
|
+
|
|
19
|
+
Before signaling done, you must have done **at least one** of:
|
|
20
|
+
|
|
21
|
+
1. **Created a new widget** on the canvas (sticky note, markdown, story, etc.) connected to your prompt widget — showing the output, summary, or deliverable
|
|
22
|
+
2. **Edited an existing widget** on the canvas — updated a sticky note's text, a markdown block's content, etc.
|
|
23
|
+
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
|
|
24
|
+
|
|
25
|
+
If you wrote code that isn't surfaced through any of these paths, **add a summary widget** to the canvas describing what you did:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
RESPONSE=$(curl -s -X POST "${STORYBOARD_SERVER_URL}/_storyboard/canvas/${STORYBOARD_CANVAS_ID}/widgets" \
|
|
29
|
+
-H "Content-Type: application/json" \
|
|
30
|
+
-d '{"type":"markdown","props":{"content":"# Done\n\nCreated `src/components/LoginForm/LoginForm.jsx` with email + password fields.\n\n```jsx\nimport LoginForm from \"./components/LoginForm/LoginForm\"\n```"}}')
|
|
31
|
+
|
|
32
|
+
NEW_ID=$(echo "$RESPONSE" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
|
|
33
|
+
|
|
34
|
+
curl -s -X POST "${STORYBOARD_SERVER_URL}/_storyboard/canvas/connector" \
|
|
35
|
+
-H "Content-Type: application/json" \
|
|
36
|
+
-d "{\"name\":\"${STORYBOARD_CANVAS_ID}\",\"startWidgetId\":\"${STORYBOARD_WIDGET_ID}\",\"endWidgetId\":\"${NEW_ID}\",\"startAnchor\":\"right\",\"endAnchor\":\"left\"}"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**If the result is not on the canvas, do not signal done.**
|
|
40
|
+
|
|
41
|
+
## Step 1: Read your config
|
|
42
|
+
|
|
43
|
+
Your widget ID is available via `$STORYBOARD_WIDGET_ID`. Read your terminal config:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
cat .storyboard/terminals/${STORYBOARD_WIDGET_ID}.json
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
If the env var is empty, source it first:
|
|
50
|
+
```bash
|
|
51
|
+
ENV_FILE=$(ls -t .storyboard/terminals/*.env 2>/dev/null | head -1)
|
|
52
|
+
if [ -n "$ENV_FILE" ]; then source "$ENV_FILE"; fi
|
|
53
|
+
cat .storyboard/terminals/${STORYBOARD_WIDGET_ID}.json
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
If not found, signal an error and exit:
|
|
57
|
+
```bash
|
|
58
|
+
npx storyboard agent signal --status error --message "No terminal config found for this prompt"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The config contains your environment:
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"widgetId": "prompt-abc123",
|
|
65
|
+
"canvasId": "storyboarding/my-canvas",
|
|
66
|
+
"branch": "main",
|
|
67
|
+
"worktree": "main",
|
|
68
|
+
"serverUrl": "http://localhost:1269",
|
|
69
|
+
"workingDirectory": "/path/to/worktree",
|
|
70
|
+
"connectedWidgets": [
|
|
71
|
+
{ "id": "image-xyz", "type": "image", "props": { "src": "screenshot.png" } },
|
|
72
|
+
{ "id": "sticky-abc", "type": "sticky-note", "props": { "text": "Requirements here" } }
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Step 2: Understand connected widgets
|
|
78
|
+
|
|
79
|
+
The `connectedWidgets` array is your **primary context**. These widgets tell you _what_ the prompt is about.
|
|
80
|
+
|
|
81
|
+
- **sticky-note**: `props.text` — instructions, notes, requirements
|
|
82
|
+
- **markdown**: `props.content` — documentation, specs, prose
|
|
83
|
+
- **image**: `props.src` — **IMPORTANT: load the actual image file** at `assets/canvas/images/{props.src}` into your context. This is often the design reference you need to implement.
|
|
84
|
+
- **story**: `props.storyId` + `props.exportName` — a component to work with
|
|
85
|
+
- **link-preview**: `props.url` — external reference to read
|
|
86
|
+
- **prototype**: `props.src` — prototype path
|
|
87
|
+
|
|
88
|
+
**Image widgets are high-priority context.** When a prompt is connected to an image, the user almost always wants you to implement or analyze what's in that image. Always load image files before starting work.
|
|
89
|
+
|
|
90
|
+
### Resolving widget references across the connection graph
|
|
91
|
+
|
|
92
|
+
When the task refers to a widget by type — e.g. "the connected image", "implement the connected sticky note" — the widget 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`).
|
|
93
|
+
|
|
94
|
+
**Resolution order:**
|
|
95
|
+
1. Search your own `connectedWidgets` for widgets matching the referenced type
|
|
96
|
+
2. If not found, check peer agents: for each terminal/prompt/agent in your `connectedWidgets`, read their config to discover their connections:
|
|
97
|
+
```bash
|
|
98
|
+
cat .storyboard/terminals/<peerWidgetId>.json | jq '.connectedWidgets'
|
|
99
|
+
```
|
|
100
|
+
3. Collect all matches across your direct connections AND peer connections
|
|
101
|
+
|
|
102
|
+
**Disambiguation rules:**
|
|
103
|
+
- **One match found** (anywhere in the graph) → use it directly.
|
|
104
|
+
- **Multiple matches found** → pick the most contextually relevant one and run with it. Prefer the widget closest to your own prompt (direct connection over peer connection), and prefer content-rich widgets (e.g. an image with a filename over an empty sticky note). Mention which widget you chose in your completion signal.
|
|
105
|
+
- **No matches found** → proceed without that context. Do your best with what you have.
|
|
106
|
+
|
|
107
|
+
**Prompts are optimistic.** Always assume the best interpretation and execute. If the user wants fine-grained control over disambiguation, they should use a terminal agent instead.
|
|
108
|
+
|
|
109
|
+
## Step 3: Execute your task
|
|
110
|
+
|
|
111
|
+
You received your task as the `-p` argument. Interpret it in light of connected widgets.
|
|
112
|
+
|
|
113
|
+
**Rules:**
|
|
114
|
+
- Focus on the task. Don't explore unrelated areas.
|
|
115
|
+
- If the task involves code changes, make them directly. Don't write plans or ask for confirmation.
|
|
116
|
+
- If the task is ambiguous but connected widgets provide context, use that context to disambiguate.
|
|
117
|
+
- If you truly cannot determine what to do, signal error with a clear message rather than guessing.
|
|
118
|
+
|
|
119
|
+
### Canvas operations (prefer CLI)
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
# Read canvas state
|
|
123
|
+
npx storyboard canvas read <canvas-name> --json
|
|
124
|
+
|
|
125
|
+
# Update a widget
|
|
126
|
+
npx storyboard canvas update <widget-id> --canvas <canvas-name> --text "New text"
|
|
127
|
+
npx storyboard canvas update <widget-id> --canvas <canvas-name> --props '{"key":"value"}'
|
|
128
|
+
|
|
129
|
+
# Add a widget
|
|
130
|
+
npx storyboard canvas add sticky-note --canvas <canvas-name> --props '{"text":"Hello"}'
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Creating widgets on the canvas
|
|
134
|
+
|
|
135
|
+
If your task requires creating new widgets (e.g. "create a plan", "add tasks"), create them and connect them to your prompt widget:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# Create widget
|
|
139
|
+
RESPONSE=$(curl -s -X POST "${STORYBOARD_SERVER_URL}/_storyboard/canvas/${STORYBOARD_CANVAS_ID}/widgets" \
|
|
140
|
+
-H "Content-Type: application/json" \
|
|
141
|
+
-d '{"type":"sticky-note","props":{"text":"Output from prompt"}}')
|
|
142
|
+
|
|
143
|
+
NEW_ID=$(echo "$RESPONSE" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
|
|
144
|
+
|
|
145
|
+
# Connect prompt → new widget
|
|
146
|
+
curl -s -X POST "${STORYBOARD_SERVER_URL}/_storyboard/canvas/connector" \
|
|
147
|
+
-H "Content-Type: application/json" \
|
|
148
|
+
-d "{\"name\":\"${STORYBOARD_CANVAS_ID}\",\"startWidgetId\":\"${STORYBOARD_WIDGET_ID}\",\"endWidgetId\":\"${NEW_ID}\",\"startAnchor\":\"right\",\"endAnchor\":\"left\"}"
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**Always** connect output widgets back to your prompt widget. Remember the Prime Directive — if your work isn't visible on the canvas, it's not done.
|
|
152
|
+
|
|
153
|
+
## Step 4: Signal completion
|
|
154
|
+
|
|
155
|
+
**Always signal when done.** This updates the prompt widget's status in the UI.
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
# Success
|
|
159
|
+
npx storyboard agent signal --status done --message "Brief summary of what was done"
|
|
160
|
+
|
|
161
|
+
# Failure
|
|
162
|
+
npx storyboard agent signal --status error --message "What went wrong"
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**Do not leave without signaling.** If you encounter an unrecoverable error, signal error. Never exit silently.
|
|
166
|
+
|
|
167
|
+
## Environment variables
|
|
168
|
+
|
|
169
|
+
These are always available in your shell:
|
|
170
|
+
- `$STORYBOARD_WIDGET_ID` — your prompt widget ID
|
|
171
|
+
- `$STORYBOARD_CANVAS_ID` — the canvas you belong to
|
|
172
|
+
- `$STORYBOARD_BRANCH` — current git branch
|
|
173
|
+
- `$STORYBOARD_SERVER_URL` — dev server URL
|
|
174
|
+
|
|
175
|
+
## Rules
|
|
176
|
+
|
|
177
|
+
- **NEVER write directly to `.canvas.jsonl` files** — use CLI or server API
|
|
178
|
+
- **Prefer CLI commands** (`npx storyboard canvas ...`) over HTTP calls
|
|
179
|
+
- **Do not start interactive sessions** — you are single-shot
|
|
180
|
+
- **Do not ask the user questions** — infer from context or signal error
|
|
181
|
+
- **Always signal done or error** — never exit without signaling
|
|
@@ -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.
|