@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,364 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: canvas
|
|
3
|
+
description: Work with Storyboard canvases — add, move, update, remove, and arrange widgets. Use when asked to add a sticky note, move a widget, rearrange widgets, update widget content, delete a widget, or describe canvas state.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Canvas
|
|
7
|
+
|
|
8
|
+
> Triggered by: "add a sticky note", "add widget", "move widget", "delete widget", "rearrange", "update sticky", "change the text", "put a markdown", "to the right of", "below", "next to", "describe the canvas", "what's on the canvas", "list widgets", "remove widget", "look at the canvas", "read the canvas", "look at this image", "what's in this image", "describe the image"
|
|
9
|
+
|
|
10
|
+
## What This Does
|
|
11
|
+
|
|
12
|
+
Reads, manipulates, and arranges widgets on a Storyboard canvas. Supports absolute and relational positioning, bulk layout, content updates, and widget removal — all through the canvas server API.
|
|
13
|
+
|
|
14
|
+
## Prerequisites
|
|
15
|
+
|
|
16
|
+
- The dev server **must** be running (`storyboard dev` or `npm run dev`)
|
|
17
|
+
- The target canvas must already exist
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Reference: Collision Detection
|
|
22
|
+
|
|
23
|
+
**All positioning operations must use collision detection to prevent widget overlaps.**
|
|
24
|
+
|
|
25
|
+
Use the collision module at `packages/core/src/canvas/collision.js`:
|
|
26
|
+
|
|
27
|
+
```js
|
|
28
|
+
import { resolvePosition, findFreePosition, DEFAULT_SIZES } from './collision.js'
|
|
29
|
+
|
|
30
|
+
// For adding/moving widgets — resolves to a collision-free position
|
|
31
|
+
const { x, y, adjusted } = resolvePosition({
|
|
32
|
+
x: targetX,
|
|
33
|
+
y: targetY,
|
|
34
|
+
type: 'sticky-note',
|
|
35
|
+
props: { width: 270, height: 170 }, // optional — uses defaults if omitted
|
|
36
|
+
widgets: existingWidgets,
|
|
37
|
+
excludeId: 'widget-to-move', // optional — for move operations
|
|
38
|
+
gridSize: 24,
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
// Or use findFreePosition directly with explicit dimensions
|
|
42
|
+
const { x, y, adjusted } = findFreePosition({
|
|
43
|
+
x: targetX,
|
|
44
|
+
y: targetY,
|
|
45
|
+
width: 270,
|
|
46
|
+
height: 170,
|
|
47
|
+
widgets: existingWidgets,
|
|
48
|
+
excludeId: null,
|
|
49
|
+
gridSize: 24,
|
|
50
|
+
})
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Algorithm:** Tries the target position first. If collision, moves right. If still blocked, moves down. Returns the first free position, snapped to grid.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Reference: Widget Types and Default Sizes
|
|
58
|
+
|
|
59
|
+
| Type | Default W×H | Content Prop | Other Props |
|
|
60
|
+
|------|------------|-------------|-------------|
|
|
61
|
+
| `sticky-note` | 270×170 | `text` | `color` (yellow, blue, green, pink, purple, orange), `width`, `height` |
|
|
62
|
+
| `markdown` | 530×240 | `content` (markdown) | `width` |
|
|
63
|
+
| `prototype` | 800×600 | `src` (URL/path) | `label`, `zoom` (10–250), `width`, `height` |
|
|
64
|
+
| `figma-embed` | 800×450 | `url` | `width`, `height` |
|
|
65
|
+
| `image` | — | `src` (filename) | `width`, `height`, `private` |
|
|
66
|
+
| `link-preview` | — | `url` | `title` |
|
|
67
|
+
|
|
68
|
+
## Reference: Widget Content, URLs, and File Paths
|
|
69
|
+
|
|
70
|
+
Each widget type stores content in a different prop. When querying widgets, use this mapping:
|
|
71
|
+
|
|
72
|
+
| Type | Content Prop | URL | File Path |
|
|
73
|
+
|------|-------------|-----|-----------|
|
|
74
|
+
| `sticky-note` | `props.text` | — | — |
|
|
75
|
+
| `markdown` | `props.content` | — | — |
|
|
76
|
+
| `prototype` | `props.src` | `props.src` (prototype path) | — |
|
|
77
|
+
| `figma-embed` | `props.url` | `props.url` | — |
|
|
78
|
+
| `link-preview` | `props.url` | `props.url` | — |
|
|
79
|
+
| `image` | `props.src` (filename) | `/_storyboard/canvas/images/{props.src}` | `src/canvas/images/{props.src}` |
|
|
80
|
+
|
|
81
|
+
**Image widgets:** The `src` prop contains only the filename (e.g. `my-canvas--2026-04-13--10-30-00.png`). To view the actual image file, use the full path: `src/canvas/images/{props.src}`.
|
|
82
|
+
|
|
83
|
+
## Reference: Grid & Spacing
|
|
84
|
+
|
|
85
|
+
- Default grid size: **24px** (stored in the canvas JSONL as `gridSize`; fall back to 24)
|
|
86
|
+
- When positioning: **snap to grid** — `Math.round(value / gridSize) * gridSize`
|
|
87
|
+
- Standard gap between widgets: **1 grid unit** (= `gridSize`, usually 24px)
|
|
88
|
+
|
|
89
|
+
## Reference: Server API
|
|
90
|
+
|
|
91
|
+
All endpoints are at `http://localhost:{PORT}/_storyboard/canvas/`. The port is determined by the worktree:
|
|
92
|
+
|
|
93
|
+
```js
|
|
94
|
+
import { detectWorktreeName, getPort } from '@dfosco/storyboard-core/worktree/port'
|
|
95
|
+
const port = getPort(detectWorktreeName())
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Reference: CLI Commands
|
|
99
|
+
|
|
100
|
+
### Read canvas state (CLI)
|
|
101
|
+
```bash
|
|
102
|
+
npx storyboard canvas read # List all canvases
|
|
103
|
+
npx storyboard canvas read my-canvas # List all widgets with ID, content, URLs, file paths
|
|
104
|
+
npx storyboard canvas read my-canvas --json # Output as JSON (for parsing)
|
|
105
|
+
npx storyboard canvas read my-canvas --id sticky-note-abc123 # Get specific widget
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
The CLI outputs widget ID, type, position, content, and file paths (for images). Use `--json` for machine-readable output that includes enriched `content`, `url`, and `filePath` fields.
|
|
109
|
+
|
|
110
|
+
## Reference: Server API
|
|
111
|
+
|
|
112
|
+
### Read canvas state
|
|
113
|
+
```
|
|
114
|
+
GET /read?name={CANVAS_NAME}
|
|
115
|
+
```
|
|
116
|
+
Returns the materialized canvas:
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"title": "My Canvas",
|
|
120
|
+
"grid": true,
|
|
121
|
+
"gridSize": 24,
|
|
122
|
+
"widgets": [
|
|
123
|
+
{
|
|
124
|
+
"id": "sticky-note-abc123",
|
|
125
|
+
"type": "sticky-note",
|
|
126
|
+
"position": { "x": 100, "y": 200 },
|
|
127
|
+
"props": { "text": "Hello", "color": "yellow", "width": 270, "height": 170 }
|
|
128
|
+
}
|
|
129
|
+
]
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### List canvases
|
|
134
|
+
```
|
|
135
|
+
GET /list
|
|
136
|
+
```
|
|
137
|
+
Returns `{ canvases: [{ name, title, path, widgetCount }] }`.
|
|
138
|
+
|
|
139
|
+
### Add a widget
|
|
140
|
+
```
|
|
141
|
+
POST /widget
|
|
142
|
+
{ "name": "{CANVAS}", "type": "{TYPE}", "position": { "x": 0, "y": 0 }, "props": {} }
|
|
143
|
+
```
|
|
144
|
+
Or via CLI: `npx storyboard canvas add {TYPE} --canvas {NAME} --x {X} --y {Y} --props '{JSON}'`
|
|
145
|
+
|
|
146
|
+
### Remove a widget
|
|
147
|
+
```
|
|
148
|
+
DELETE /widget
|
|
149
|
+
{ "name": "{CANVAS}", "widgetId": "{WIDGET_ID}" }
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Bulk update (move, resize, reorder, update props)
|
|
153
|
+
```
|
|
154
|
+
PUT /update
|
|
155
|
+
{ "name": "{CANVAS}", "widgets": [ ...full widgets array... ] }
|
|
156
|
+
```
|
|
157
|
+
This replaces the entire widgets array. **Always read the current state first**, modify the array, then PUT it back.
|
|
158
|
+
|
|
159
|
+
### Update canvas settings
|
|
160
|
+
```
|
|
161
|
+
PUT /update
|
|
162
|
+
{ "name": "{CANVAS}", "settings": { "title": "...", "grid": true, "gridSize": 24, ... } }
|
|
163
|
+
```
|
|
164
|
+
Allowed setting keys: `title`, `description`, `grid`, `gridSize`, `colorMode`, `dotted`, `centered`, `author`, `snapToGrid`.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Procedure
|
|
169
|
+
|
|
170
|
+
### Step 1: Identify the canvas
|
|
171
|
+
|
|
172
|
+
If the user doesn't specify which canvas:
|
|
173
|
+
```bash
|
|
174
|
+
curl -s http://localhost:{PORT}/_storyboard/canvas/list
|
|
175
|
+
```
|
|
176
|
+
If there's one canvas, use it. If multiple, ask the user.
|
|
177
|
+
|
|
178
|
+
### Step 2: Read the canvas state
|
|
179
|
+
|
|
180
|
+
**Always read the current state before any operation that involves positioning or modifying existing widgets:**
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
curl -s "http://localhost:{PORT}/_storyboard/canvas/read?name={CANVAS_NAME}"
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Parse the response to get the `widgets` array and `gridSize`.
|
|
187
|
+
|
|
188
|
+
### Step 3: Resolve positioning (for add/move operations)
|
|
189
|
+
|
|
190
|
+
**Absolute** — User gives coordinates:
|
|
191
|
+
> "Add a sticky note at 200, 400" → `x=200, y=400` (snap to grid)
|
|
192
|
+
|
|
193
|
+
**Relational** — User positions relative to another widget:
|
|
194
|
+
|
|
195
|
+
| Relation | X formula | Y formula |
|
|
196
|
+
|----------|-----------|-----------|
|
|
197
|
+
| **right of** ref | `ref.x + ref.width + gap` | `ref.y` |
|
|
198
|
+
| **left of** ref | `ref.x - new.width - gap` | `ref.y` |
|
|
199
|
+
| **below** ref | `ref.x` | `ref.y + ref.height + gap` |
|
|
200
|
+
| **above** ref | `ref.x` | `ref.y - new.height - gap` |
|
|
201
|
+
| **center aligned with** ref | `ref.x + (ref.width - new.width) / 2` | (same y, or same formula for vertical) |
|
|
202
|
+
|
|
203
|
+
Where:
|
|
204
|
+
- `ref.width` = `ref.props.width` or the default width for that widget type
|
|
205
|
+
- `ref.height` = `ref.props.height` or the default height for that widget type
|
|
206
|
+
- `new.width/height` = the size of the widget being placed (from props or defaults)
|
|
207
|
+
- `gap` = `gridSize` (typically 24)
|
|
208
|
+
- **Always snap the final result**: `Math.round(value / gridSize) * gridSize`
|
|
209
|
+
|
|
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
|
+
|
|
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
|
|
216
|
+
|
|
217
|
+
### Step 4: Execute the operation
|
|
218
|
+
|
|
219
|
+
**Adding a widget:**
|
|
220
|
+
```bash
|
|
221
|
+
npx storyboard canvas add {TYPE} --canvas {NAME} --x {X} --y {Y} --props '{JSON}'
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
**Moving a widget:**
|
|
225
|
+
1. Read canvas state → get widgets array
|
|
226
|
+
2. Find the target widget by ID
|
|
227
|
+
3. Update its `position` field
|
|
228
|
+
4. PUT the full array back:
|
|
229
|
+
```bash
|
|
230
|
+
curl -X PUT http://localhost:{PORT}/_storyboard/canvas/update \
|
|
231
|
+
-H 'Content-Type: application/json' \
|
|
232
|
+
-d '{"name":"{CANVAS}","widgets":[...updated array...]}'
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
**Updating widget props** (text, color, size, content, etc.):
|
|
236
|
+
1. Read canvas state → get widgets array
|
|
237
|
+
2. Find the target widget by ID
|
|
238
|
+
3. Merge new props into `widget.props`
|
|
239
|
+
4. PUT the full array back
|
|
240
|
+
|
|
241
|
+
**Removing a widget:**
|
|
242
|
+
```bash
|
|
243
|
+
curl -X DELETE http://localhost:{PORT}/_storyboard/canvas/widget \
|
|
244
|
+
-H 'Content-Type: application/json' \
|
|
245
|
+
-d '{"name":"{CANVAS}","widgetId":"{WIDGET_ID}"}'
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
**Rearranging / laying out multiple widgets:**
|
|
249
|
+
1. Read canvas state → get widgets array
|
|
250
|
+
2. Calculate new positions for all affected widgets using the positioning formulas
|
|
251
|
+
3. PUT the full updated array back in a single call
|
|
252
|
+
|
|
253
|
+
### Step 5: Confirm
|
|
254
|
+
|
|
255
|
+
After the operation, tell the user what changed. For relational positioning, confirm the calculated coordinates. For bulk operations, summarize the layout.
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## Examples
|
|
260
|
+
|
|
261
|
+
### Add a sticky note with text
|
|
262
|
+
User: "Add a yellow sticky note saying 'TODO: fix bug' to my-canvas"
|
|
263
|
+
```bash
|
|
264
|
+
npx storyboard canvas add sticky-note --canvas my-canvas --x 0 --y 0 --props '{"text":"TODO: fix bug","color":"yellow"}'
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Relational positioning
|
|
268
|
+
User: "Add a blue sticky to the right of sticky-note-f20afo on my-canvas"
|
|
269
|
+
1. Read canvas: find `sticky-note-f20afo` at `{x: 100, y: 200}` with `width: 270`
|
|
270
|
+
2. Calculate: x = `100 + 270 + 24 = 394` → snap to `Math.round(394/24)*24 = 384`, y = `200`
|
|
271
|
+
3. Run:
|
|
272
|
+
```bash
|
|
273
|
+
npx storyboard canvas add sticky-note --canvas my-canvas --x 384 --y 200 --props '{"text":"","color":"blue"}'
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Move a widget
|
|
277
|
+
User: "Move sticky-note-abc123 below markdown-xyz789"
|
|
278
|
+
1. Read canvas: find `markdown-xyz789` at `{x: 0, y: 0}` with `height: 240`
|
|
279
|
+
2. Calculate: x = `0`, y = `0 + 240 + 24 = 264` → snap to `264`
|
|
280
|
+
3. Update the widgets array, set `sticky-note-abc123.position` to `{x: 0, y: 264}`
|
|
281
|
+
4. PUT the full array back
|
|
282
|
+
|
|
283
|
+
### Update content
|
|
284
|
+
User: "Change the text of sticky-note-abc123 to 'Done!'"
|
|
285
|
+
1. Read canvas, find `sticky-note-abc123`
|
|
286
|
+
2. Set `props.text = "Done!"`
|
|
287
|
+
3. PUT the full widgets array back
|
|
288
|
+
|
|
289
|
+
### Row of widgets
|
|
290
|
+
User: "Add three sticky notes in a row: red, blue, green"
|
|
291
|
+
|
|
292
|
+
Stride = `270 + 24 = 294` → snap to `Math.round(294/24)*24 = 288`
|
|
293
|
+
```bash
|
|
294
|
+
npx storyboard canvas add sticky-note --canvas my-canvas --x 0 --y 0 --props '{"color":"red"}'
|
|
295
|
+
npx storyboard canvas add sticky-note --canvas my-canvas --x 288 --y 0 --props '{"color":"blue"}'
|
|
296
|
+
npx storyboard canvas add sticky-note --canvas my-canvas --x 576 --y 0 --props '{"color":"green"}'
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Describe canvas state
|
|
300
|
+
User: "What's on my-canvas?"
|
|
301
|
+
|
|
302
|
+
**Option 1 — CLI (recommended):**
|
|
303
|
+
```bash
|
|
304
|
+
npx storyboard canvas read my-canvas
|
|
305
|
+
```
|
|
306
|
+
This lists all widgets with their ID, type, position, content, URLs, and file paths.
|
|
307
|
+
|
|
308
|
+
**Option 2 — API:**
|
|
309
|
+
1. Read canvas state via API
|
|
310
|
+
2. List all widgets with their type, position, key props, and ID
|
|
311
|
+
|
|
312
|
+
### Query a specific widget
|
|
313
|
+
User: "What's in widget sticky-note-abc123?"
|
|
314
|
+
```bash
|
|
315
|
+
npx storyboard canvas read my-canvas --id sticky-note-abc123
|
|
316
|
+
```
|
|
317
|
+
Or with JSON output for parsing:
|
|
318
|
+
```bash
|
|
319
|
+
npx storyboard canvas read my-canvas --id sticky-note-abc123 --json
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Remove a widget
|
|
323
|
+
User: "Delete the prototype embed on my-canvas"
|
|
324
|
+
1. Read canvas, find the widget of type `prototype`
|
|
325
|
+
2. Run:
|
|
326
|
+
```bash
|
|
327
|
+
curl -X DELETE http://localhost:{PORT}/_storyboard/canvas/widget \
|
|
328
|
+
-H 'Content-Type: application/json' \
|
|
329
|
+
-d '{"name":"my-canvas","widgetId":"prototype-xyz789"}'
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### View an image on the canvas
|
|
333
|
+
User: "Look at the image on my-canvas" or "What's in this image?"
|
|
334
|
+
|
|
335
|
+
**Step 1 — Find the image widget:**
|
|
336
|
+
```bash
|
|
337
|
+
npx storyboard canvas read my-canvas --json
|
|
338
|
+
```
|
|
339
|
+
Look for widgets with `"type": "image"`. The output includes the `filePath` field.
|
|
340
|
+
|
|
341
|
+
**Step 2 — View the image file:**
|
|
342
|
+
Use the `view` tool with the file path from the CLI output:
|
|
343
|
+
```
|
|
344
|
+
view src/canvas/images/my-canvas--2026-04-13--10-30-00.png
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
**Image file path formula:**
|
|
348
|
+
- Widget prop: `props.src` (filename only)
|
|
349
|
+
- Full path: `src/canvas/images/{props.src}`
|
|
350
|
+
|
|
351
|
+
If multiple images exist, ask which one the user wants to view, or list them with their widget IDs.
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
## Story Components on Canvas
|
|
356
|
+
|
|
357
|
+
When creating **story components** (`.story.jsx` files) for use on a canvas:
|
|
358
|
+
|
|
359
|
+
1. **Always use Primer React components** from `@primer/react` for all UI elements — buttons, forms, layout, etc.
|
|
360
|
+
2. **Always use Primer Octicons** from `@primer/octicons-react` for icons.
|
|
361
|
+
3. **Use CSS Modules** (`*.module.css`) for any custom styling beyond Primer defaults.
|
|
362
|
+
4. **Use the `create` skill** to scaffold the component — never create story files manually.
|
|
363
|
+
|
|
364
|
+
These rules ensure visual consistency across all canvas widgets and prototype pages.
|