@1agh/maude 0.28.0 → 0.29.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/README.md +2 -2
- package/{plugins/design/dev-server → apps/studio}/ai-banner.tsx +1 -1
- package/{plugins/design/dev-server → apps/studio}/annotations-context-toolbar.tsx +286 -6
- package/{plugins/design/dev-server → apps/studio}/annotations-layer.tsx +1209 -122
- package/{plugins/design/dev-server → apps/studio}/api.ts +486 -32
- package/{plugins/design/dev-server → apps/studio}/artboard-activity-overlay.tsx +1 -1
- package/{plugins/design/dev-server → apps/studio}/artboard-marquee.tsx +1 -1
- package/apps/studio/bin/_motion-sample-playwright.mjs +129 -0
- package/{plugins/design/dev-server → apps/studio}/bin/canvas-edit.sh +1 -1
- package/{plugins/design/dev-server → apps/studio}/bin/draw-proof.sh +37 -2
- package/{plugins/design/dev-server → apps/studio}/bin/preflight.sh +1 -1
- package/apps/studio/bin/read-annotations.mjs +438 -0
- package/apps/studio/bin/read-annotations.sh +11 -0
- package/{plugins/design/dev-server → apps/studio}/bin/runtime-health.sh +1 -1
- package/{plugins/design/dev-server → apps/studio}/bin/scenario-report.mjs +1 -1
- package/{plugins/design/dev-server → apps/studio}/bin/screenshot.sh +62 -2
- package/apps/studio/bin/server-up.sh +234 -0
- package/apps/studio/bin/to-lottie-verify.html +68 -0
- package/apps/studio/bin/to-lottie.sh +128 -0
- package/{plugins/design/dev-server → apps/studio}/bin/visual-sanity.sh +19 -3
- package/{plugins/design/dev-server → apps/studio}/build.ts +5 -3
- package/{plugins/design/dev-server → apps/studio}/canvas-arrowheads.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/canvas-comment-mount.tsx +2 -2
- package/apps/studio/canvas-create.ts +104 -0
- package/{plugins/design/dev-server → apps/studio}/canvas-cursors.ts +47 -13
- package/{plugins/design/dev-server → apps/studio}/canvas-icons.tsx +60 -1
- package/{plugins/design/dev-server → apps/studio}/canvas-lib-inline.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/canvas-lib-resolver.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/canvas-lib.tsx +41 -33
- package/{plugins/design/dev-server → apps/studio}/canvas-shell.tsx +57 -42
- package/{plugins/design/dev-server → apps/studio}/client/app.jsx +1713 -530
- package/apps/studio/client/canvas-url.js +81 -0
- package/{plugins/design/dev-server → apps/studio}/client/comments-overlay.css +41 -27
- package/{plugins/design/dev-server → apps/studio}/client/index.html +2 -1
- package/apps/studio/client/styles/1-tokens-maude.css +296 -0
- package/apps/studio/client/styles/3-shell-maude.css +459 -0
- package/{plugins/design/dev-server → apps/studio}/client/styles/3-shell.css +129 -0
- package/apps/studio/client/styles/4-components-maude.css +74 -0
- package/{plugins/design/dev-server → apps/studio}/client/styles/4-components.css +357 -34
- package/apps/studio/client/styles/5-maude-overrides.css +123 -0
- package/{plugins/design/dev-server → apps/studio}/client/styles/_index.css +9 -0
- package/{plugins/design/dev-server → apps/studio}/client/styles.css +1 -1
- package/apps/studio/client/tour/overlay.jsx +191 -0
- package/apps/studio/client/tour/usage-tour.js +35 -0
- package/apps/studio/client/whats-new-seen.js +52 -0
- package/apps/studio/client/whats-new.jsx +250 -0
- package/{plugins/design/dev-server → apps/studio}/collab/index.ts +4 -4
- package/{plugins/design/dev-server → apps/studio}/collab/persistence.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/commands/annotation-strokes-command.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/commands/equal-spacing-command.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/commands/move-artboards-command.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/comments-overlay.tsx +25 -6
- package/{plugins/design/dev-server → apps/studio}/context-menu.tsx +2 -2
- package/{plugins/design/dev-server → apps/studio}/contextual-toolbar.tsx +4 -7
- package/{plugins/design/dev-server → apps/studio}/cursors-overlay.tsx +1 -1
- package/apps/studio/dist/client.bundle.js +22825 -0
- package/apps/studio/dist/comment-mount.js +1960 -0
- package/apps/studio/dist/runtime/lib0_decoding.js +1 -0
- package/apps/studio/dist/runtime/lib0_encoding.js +1 -0
- package/apps/studio/dist/runtime/motion.js +4 -0
- package/apps/studio/dist/runtime/motion_react.js +12 -0
- package/apps/studio/dist/runtime/pixi-js.js +3397 -0
- package/apps/studio/dist/runtime/react-dom.js +1 -0
- package/apps/studio/dist/runtime/react-dom_client.js +9 -0
- package/apps/studio/dist/runtime/react.js +1 -0
- package/apps/studio/dist/runtime/react_jsx-dev-runtime.js +1 -0
- package/apps/studio/dist/runtime/react_jsx-runtime.js +1 -0
- package/apps/studio/dist/runtime/y-protocols_awareness.js +1 -0
- package/apps/studio/dist/runtime/y-protocols_sync.js +1 -0
- package/apps/studio/dist/runtime/yjs.js +5 -0
- package/apps/studio/dist/styles.css +5695 -0
- package/{plugins/design/dev-server → apps/studio}/dom-selection.ts +75 -4
- package/apps/studio/draw/animate.ts +333 -0
- package/{plugins/design/dev-server → apps/studio}/draw/brush.ts +4 -4
- package/{plugins/design/dev-server → apps/studio}/draw/composition.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/draw/geometry.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/draw/index.ts +9 -6
- package/{plugins/design/dev-server → apps/studio}/draw/layout.ts +2 -2
- package/apps/studio/draw/morph.ts +204 -0
- package/{plugins/design/dev-server → apps/studio}/draw/optimize.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/draw/palette.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/draw/primitives.ts +1 -1
- package/apps/studio/draw/serialize-animate.ts +324 -0
- package/{plugins/design/dev-server → apps/studio}/draw/serialize.ts +9 -3
- package/apps/studio/draw/test/animate.test.ts +172 -0
- package/{plugins/design/dev-server → apps/studio}/draw/test/layout.test.ts +1 -1
- package/apps/studio/draw/test/morph.test.ts +107 -0
- package/apps/studio/draw/test/serialize-animate.test.ts +142 -0
- package/{plugins/design/dev-server → apps/studio}/draw/test/serialize.test.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/equal-spacing-detector.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/equal-spacing-handles.tsx +7 -29
- package/{plugins/design/dev-server → apps/studio}/examples/perf-100-artboards.tsx +1 -2
- package/{plugins/design/dev-server → apps/studio}/export-dialog.tsx +14 -2
- package/{plugins/design/dev-server → apps/studio}/exporters/index.ts +2 -2
- package/{plugins/design/dev-server → apps/studio}/http.ts +103 -2
- package/{plugins/design/dev-server → apps/studio}/input-router.tsx +8 -1
- package/{plugins/design/dev-server → apps/studio}/inspect.ts +20 -3
- package/{plugins/design/dev-server → apps/studio}/marquee-overlay.tsx +6 -3
- package/{plugins/design/dev-server → apps/studio}/participants-chrome.tsx +1 -1
- package/{plugins/design/dev-server → apps/studio}/paths.ts +15 -11
- package/{plugins/design/dev-server → apps/studio}/server.ts +19 -1
- package/{plugins/design/dev-server → apps/studio}/sync/index.ts +6 -6
- package/{plugins/design/dev-server → apps/studio}/sync/materialize.ts +2 -2
- package/{plugins/design/dev-server → apps/studio}/test/ai-activity.test.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/test/annotations-api.test.ts +1 -2
- package/{plugins/design/dev-server → apps/studio}/test/annotations-layer.test.ts +69 -6
- package/{plugins/design/dev-server → apps/studio}/test/annotations-roundtrip.test.ts +98 -1
- package/apps/studio/test/annotations-text-format.test.ts +396 -0
- package/apps/studio/test/asset-api.test.ts +149 -0
- package/{plugins/design/dev-server → apps/studio}/test/boot-self-heal.test.ts +1 -1
- package/apps/studio/test/canvas-create-api.test.ts +361 -0
- package/{plugins/design/dev-server → apps/studio}/test/canvas-cursors.test.ts +3 -1
- package/{plugins/design/dev-server → apps/studio}/test/canvas-edit.test.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/test/canvas-hmr-runtime.test.tsx +1 -1
- package/{plugins/design/dev-server → apps/studio}/test/canvas-lib-inline.test.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/test/canvas-lib-resolver.test.ts +2 -3
- package/apps/studio/test/canvas-media-drop.test.ts +158 -0
- package/{plugins/design/dev-server → apps/studio}/test/canvas-meta-api.test.ts +1 -2
- package/{plugins/design/dev-server → apps/studio}/test/canvas-origin-gate.test.ts +18 -3
- package/apps/studio/test/canvas-url.test.ts +99 -0
- package/{plugins/design/dev-server → apps/studio}/test/collab-annotations-bridge.test.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/test/collab-bridge.test.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/test/collab-room.test.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/test/collab-stress.test.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/test/comments-api.test.ts +1 -2
- package/{plugins/design/dev-server → apps/studio}/test/compile-entry.test.ts +1 -2
- package/{plugins/design/dev-server → apps/studio}/test/exporters/canva.test.ts +1 -2
- package/{plugins/design/dev-server → apps/studio}/test/exporters/history.test.ts +1 -2
- package/{plugins/design/dev-server → apps/studio}/test/exporters/pw-launch.test.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/test/exporters/scope.test.ts +1 -2
- package/{plugins/design/dev-server → apps/studio}/test/exporters/zip.test.ts +1 -2
- package/{plugins/design/dev-server → apps/studio}/test/git-lifecycle.test.ts +1 -2
- package/{plugins/design/dev-server → apps/studio}/test/handoff-static-frames.test.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/test/hmr-broadcast.test.ts +1 -1
- package/apps/studio/test/index-data-canvas-ds.test.ts +97 -0
- package/apps/studio/test/motion-sample.test.ts +35 -0
- package/{plugins/design/dev-server → apps/studio}/test/perf-harness.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/test/phase-3.6-smoke.test.ts +3 -1
- package/apps/studio/test/read-annotations.test.ts +409 -0
- package/{plugins/design/dev-server → apps/studio}/test/runtime-bundle.test.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/test/sanitize-annotation-svg.test.ts +108 -2
- package/{plugins/design/dev-server → apps/studio}/test/shared-doc-convergence.test.ts +2 -2
- package/{plugins/design/dev-server → apps/studio}/test/shared-doc-migrate.test.ts +2 -3
- package/{plugins/design/dev-server → apps/studio}/test/shared-doc-projection.test.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/test/snap-distance-pill.test.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/test/sync-agent.test.ts +2 -3
- package/{plugins/design/dev-server → apps/studio}/test/sync-atomic-write.test.ts +2 -3
- package/{plugins/design/dev-server → apps/studio}/test/sync-connection-state.test.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/test/sync-echo-guard.test.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/test/sync-fs-mirror.test.ts +1 -2
- package/{plugins/design/dev-server → apps/studio}/test/sync-hardening.test.ts +4 -5
- package/{plugins/design/dev-server → apps/studio}/test/sync-hubs-config.test.ts +1 -2
- package/{plugins/design/dev-server → apps/studio}/test/sync-runtime.test.ts +3 -8
- package/{plugins/design/dev-server → apps/studio}/test/sync-status.test.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/test/sync-untrusted.test.ts +1 -2
- package/apps/studio/test/tour-overlay.test.tsx +56 -0
- package/{plugins/design/dev-server → apps/studio}/test/use-agent-presence.test.tsx +4 -1
- package/{plugins/design/dev-server → apps/studio}/test/use-annotation-resize.test.ts +43 -0
- package/{plugins/design/dev-server → apps/studio}/test/use-snap-guides.test.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/test/use-tool-mode.test.tsx +4 -1
- package/apps/studio/test/whats-new.test.ts +101 -0
- package/apps/studio/text-imports.d.ts +9 -0
- package/{plugins/design/dev-server → apps/studio}/tool-palette.tsx +4 -69
- package/{plugins/design/dev-server → apps/studio}/undo-hud.tsx +1 -1
- package/{plugins/design/dev-server → apps/studio}/undo-stack.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/use-agent-presence.tsx +2 -2
- package/{plugins/design/dev-server → apps/studio}/use-annotation-resize.tsx +41 -12
- package/{plugins/design/dev-server → apps/studio}/use-annotation-selection.tsx +3 -7
- package/{plugins/design/dev-server → apps/studio}/use-annotations-visibility.tsx +2 -2
- package/{plugins/design/dev-server → apps/studio}/use-artboard-drag.tsx +2 -2
- package/{plugins/design/dev-server → apps/studio}/use-canvas-activity.tsx +2 -2
- package/apps/studio/use-canvas-media-drop.tsx +343 -0
- package/{plugins/design/dev-server → apps/studio}/use-collab.tsx +4 -5
- package/{plugins/design/dev-server → apps/studio}/use-cursor-modifiers.tsx +1 -1
- package/{plugins/design/dev-server → apps/studio}/use-keyboard-discipline.tsx +5 -2
- package/{plugins/design/dev-server → apps/studio}/use-selection-set.tsx +10 -2
- package/{plugins/design/dev-server → apps/studio}/use-snap-guides.tsx +1 -1
- package/{plugins/design/dev-server → apps/studio}/use-tool-mode.tsx +4 -2
- package/{plugins/design/dev-server → apps/studio}/use-undo-stack.tsx +5 -6
- package/apps/studio/whats-new.json +139 -0
- package/apps/studio/whats-new.schema.json +70 -0
- package/apps/studio/whats-new.ts +87 -0
- package/cli/bin/maude.mjs +10 -0
- package/cli/commands/design.mjs +84 -10
- package/cli/commands/design.test.mjs +133 -1
- package/cli/commands/help.mjs +8 -2
- package/cli/commands/hub.mjs +3 -3
- package/cli/commands/hub.test.mjs +1 -1
- package/cli/commands/scenario-report.mjs +2 -9
- package/cli/lib/cache.mjs +1 -1
- package/cli/lib/config-lint.mjs +1 -1
- package/cli/lib/copy-tree.mjs +1 -1
- package/cli/lib/design-link.mjs +1 -1
- package/cli/lib/flow-design-integration.test.mjs +2 -2
- package/cli/lib/gitignore-block.mjs +1 -0
- package/cli/lib/gitignore-block.test.mjs +2 -2
- package/cli/lib/plugin-cli-reachability.test.mjs +8 -7
- package/cli/lib/preflight.mjs +1 -1
- package/cli/lib/stack-detect.mjs +1 -1
- package/package.json +16 -16
- package/plugins/design/templates/_shell.html +3 -3
- package/plugins/design/templates/brief-board.tsx.template +61 -0
- package/plugins/design/templates/canvas.tsx.template +1 -1
- package/plugins/design/templates/design-system-inspiration/SUB-AGENT-PROMPTS.md +18 -3
- package/plugins/design/templates/design-system-inspiration/core/config.json.tpl +1 -1
- package/plugins/design/templates/design-system-inspiration/core/preview/_motion-readme.md.tpl +1 -1
- package/plugins/flow/.claude-plugin/config.schema.json +16 -0
- package/plugins/design/dev-server/bin/server-up.sh +0 -135
- package/plugins/design/dev-server/dist/client.bundle.js +0 -20692
- package/plugins/design/dev-server/dist/comment-mount.js +0 -1924
- package/plugins/design/dev-server/dist/runtime/lib0_decoding.js +0 -620
- package/plugins/design/dev-server/dist/runtime/lib0_encoding.js +0 -604
- package/plugins/design/dev-server/dist/runtime/motion.js +0 -4944
- package/plugins/design/dev-server/dist/runtime/motion_react.js +0 -10056
- package/plugins/design/dev-server/dist/runtime/pixi-js.js +0 -53104
- package/plugins/design/dev-server/dist/runtime/react-dom.js +0 -231
- package/plugins/design/dev-server/dist/runtime/react-dom_client.js +0 -10357
- package/plugins/design/dev-server/dist/runtime/react.js +0 -535
- package/plugins/design/dev-server/dist/runtime/react_jsx-dev-runtime.js +0 -60
- package/plugins/design/dev-server/dist/runtime/react_jsx-runtime.js +0 -85
- package/plugins/design/dev-server/dist/runtime/y-protocols_awareness.js +0 -376
- package/plugins/design/dev-server/dist/runtime/y-protocols_sync.js +0 -100
- package/plugins/design/dev-server/dist/runtime/yjs.js +0 -6687
- package/plugins/design/dev-server/dist/styles.css +0 -2710
- package/{plugins/design/dev-server → apps/studio}/activity.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/bin/_enumerate-artboards-playwright.mjs +0 -0
- package/{plugins/design/dev-server → apps/studio}/bin/_html-playwright.mjs +0 -0
- package/{plugins/design/dev-server → apps/studio}/bin/_pdf-playwright.mjs +0 -0
- package/{plugins/design/dev-server → apps/studio}/bin/_png-playwright.mjs +0 -0
- package/{plugins/design/dev-server → apps/studio}/bin/_pptx-playwright.mjs +0 -0
- package/{plugins/design/dev-server → apps/studio}/bin/_pw-launch.mjs +0 -0
- package/{plugins/design/dev-server → apps/studio}/bin/_screenshot-playwright.mjs +0 -0
- package/{plugins/design/dev-server → apps/studio}/bin/_svg-optimize.mjs +0 -0
- package/{plugins/design/dev-server → apps/studio}/bin/_svg-playwright.mjs +0 -0
- package/{plugins/design/dev-server → apps/studio}/bin/asset-sweep.sh +0 -0
- package/{plugins/design/dev-server → apps/studio}/bin/bootstrap-check.sh +0 -0
- package/{plugins/design/dev-server → apps/studio}/bin/check-runtime-bundles.sh +0 -0
- package/{plugins/design/dev-server → apps/studio}/bin/draw-build.sh +0 -0
- package/{plugins/design/dev-server → apps/studio}/bin/handoff.sh +0 -0
- package/{plugins/design/dev-server → apps/studio}/bin/prep.sh +0 -0
- package/{plugins/design/dev-server → apps/studio}/bin/slug.sh +0 -0
- package/{plugins/design/dev-server → apps/studio}/bin/smoke.sh +0 -0
- package/{plugins/design/dev-server → apps/studio}/bin/svg-optimize.sh +0 -0
- package/{plugins/design/dev-server → apps/studio}/boot-self-heal.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/canvas-build.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/canvas-edit.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/canvas-header.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/canvas-meta.schema.json +0 -0
- package/{plugins/design/dev-server → apps/studio}/canvas-pipeline.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/client/hmr.mjs +0 -0
- package/{plugins/design/dev-server → apps/studio}/client/iframe-lazy.mjs +0 -0
- package/{plugins/design/dev-server → apps/studio}/client/styles/0-reset.css +0 -0
- package/{plugins/design/dev-server → apps/studio}/client/styles/1-tokens.css +0 -0
- package/{plugins/design/dev-server → apps/studio}/client/styles/2-layout.css +0 -0
- package/{plugins/design/dev-server → apps/studio}/client/styles/5-utilities.css +0 -0
- package/{plugins/design/dev-server → apps/studio}/collab/ai-activity.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/collab/awareness-bridge.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/collab/git-lifecycle.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/collab/protocol.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/collab/registry.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/collab/room.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/config.schema.json +0 -0
- package/{plugins/design/dev-server → apps/studio}/context.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/dist/runtime/.min-sizes.json +0 -0
- package/{plugins/design/dev-server → apps/studio}/draw/test/brush.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/draw/test/composition.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/draw/test/geometry.test.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/draw/test/gradient.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/draw/test/optimize.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/draw/test/palette.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/draw/test/primitives.test.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/examples/README.md +0 -0
- package/{plugins/design/dev-server → apps/studio}/exporters/_browser-bundles.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/exporters/canva-handoff-prompt.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/exporters/canva.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/exporters/html.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/exporters/pdf.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/exporters/png.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/exporters/pptx.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/exporters/scope.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/exporters/svg.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/exporters/zip.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/fs-watch.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/handoff.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/history.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/hmr-broadcast.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/locator.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/mem.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/runtime-bundle.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/server.mjs +0 -0
- package/{plugins/design/dev-server → apps/studio}/sync/agent.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/sync/atomic-write.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/sync/codec.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/sync/connection-state.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/sync/echo-guard.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/sync/fs-mirror.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/sync/hubs-config.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/sync/migrate-seed.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/sync/origins.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/sync/projection.ts +3 -3
- package/{plugins/design/dev-server → apps/studio}/sync/status.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/sync/untrusted.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/_helpers.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/active-state.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/activity.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/annotation-strokes-command.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/annotations-draw-modifiers.test.ts +2 -2
- package/{plugins/design/dev-server → apps/studio}/test/artboard-activity-overlay.test.tsx +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/binary-smoke.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/bundle-smoke.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/canvas-build.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/canvas-header.test.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/test/canvas-lib-motion.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/canvas-pipeline.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/canvas-route.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/collab-awareness-bridge.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/collab-loopback.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/collab-protocol.test.ts +2 -2
- package/{plugins/design/dev-server → apps/studio}/test/collab-reseed-guard.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/comment-mount.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/context-resolve-tokens.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/csp-canvas-shell.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/equal-spacing-detector.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/exporters/endpoint.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/exporters/html.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/exporters/pdf.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/exporters/png.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/exporters/pptx-deck.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/exporters/pptx.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/exporters/svg.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/fixtures/phase-20-annotations.svg +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/fixtures/phase-21-annotations.svg +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/fs-watch.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/handoff.test.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/test/history-rollback.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/hmr-classify.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/input-router.test.ts +2 -2
- package/{plugins/design/dev-server → apps/studio}/test/locator.test.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/test/marquee-overlay.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/move-artboards-command.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/participants-chrome.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/paths.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/runtime-bundle-error-mapping.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/server-lifecycle.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/shared-doc-foundation.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/sync-codec.test.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/test/sync-meta-codec.test.ts +1 -1
- package/{plugins/design/dev-server → apps/studio}/test/system-endpoint.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/tool-palette.test.tsx +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/undo-stack.test.ts +2 -2
- package/{plugins/design/dev-server → apps/studio}/test/use-annotation-selection.test.tsx +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/use-artboard-drag.test.ts +3 -3
- package/{plugins/design/dev-server → apps/studio}/test/use-canvas-activity.test.tsx +2 -2
- package/{plugins/design/dev-server → apps/studio}/test/use-collab.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/use-cursor-modifiers.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/use-keyboard-discipline.test.ts +0 -0
- package/{plugins/design/dev-server → apps/studio}/test/use-selection-set.test.tsx +1 -1
- package/{plugins/design/dev-server → apps/studio}/test/use-undo-stack.test.tsx +2 -2
- /package/{plugins/design/dev-server → apps/studio}/test/ws-handshake.test.ts +0 -0
- /package/{plugins/design/dev-server → apps/studio}/tsconfig.json +0 -0
- /package/{plugins/design/dev-server → apps/studio}/ws.ts +0 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// canvas-create.ts — Phase 22 UI add-on. Pure helpers behind POST /_api/canvas
|
|
2
|
+
// (api.ts createCanvas), which lets the browser file-tree create a blank brief
|
|
3
|
+
// board directly — no slash command, no model cost. Generation (ingesting a
|
|
4
|
+
// board's notes into artboards) stays with Claude via `/design:new`; this only
|
|
5
|
+
// stamps out the empty annotation surface.
|
|
6
|
+
//
|
|
7
|
+
// SINGLE SOURCE — the board envelope is the SAME `brief-board.tsx.template`
|
|
8
|
+
// `/design:new --blank` substitutes. We text-import it so Bun.build inlines the
|
|
9
|
+
// content into the `bun --compile` standalone binary (verified: works at dev
|
|
10
|
+
// runtime AND embeds at build time), sidestepping DDR-045 — no runtime disk read
|
|
11
|
+
// of a file that lives outside `apps/studio/`. The template stayed under the
|
|
12
|
+
// design plugin (plugins/design/templates) when the studio moved (DDR-095).
|
|
13
|
+
|
|
14
|
+
import briefBoardTemplate from '../../plugins/design/templates/brief-board.tsx.template' with {
|
|
15
|
+
type: 'text',
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const BRIEF_BOARD_TEMPLATE: string = briefBoardTemplate;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The ONE security boundary for the create endpoint. A canvas name is the only
|
|
22
|
+
* user-controlled value, and it is interpolated into BOTH a real nested
|
|
23
|
+
* filesystem path (`<group>/<name>.tsx`) AND the generated `.tsx` (JSX text) +
|
|
24
|
+
* `.meta.json` (JSON string). This strict allowlist does triple duty:
|
|
25
|
+
* • path safety — no `/`, `\`, `..`, or leading dot ⇒ no traversal;
|
|
26
|
+
* • template safety — no `<`, `>`, `{`, `}` ⇒ can't break out of JSX text;
|
|
27
|
+
* • JSON safety — no `"` or `\` ⇒ can't break out of a meta string.
|
|
28
|
+
* Unicode letters/numbers are allowed (so "Onboarding Brief" / accented names
|
|
29
|
+
* work); the first char must be a letter/number (excludes leading space/dash/dot).
|
|
30
|
+
*/
|
|
31
|
+
const NAME_RE = /^[\p{L}\p{N}][\p{L}\p{N} _-]{0,59}$/u;
|
|
32
|
+
|
|
33
|
+
export interface NameValidation {
|
|
34
|
+
ok: boolean;
|
|
35
|
+
name?: string;
|
|
36
|
+
componentName?: string;
|
|
37
|
+
error?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function validateCanvasName(raw: unknown): NameValidation {
|
|
41
|
+
if (typeof raw !== 'string') return { ok: false, error: 'name must be a string' };
|
|
42
|
+
// NFC-normalize so a decomposed (NFD) name and its composed sibling can't hash
|
|
43
|
+
// to two JS strings that collide to ONE on-disk path on a normalizing filesystem
|
|
44
|
+
// (APFS/HFS+) — which would let the 409 existence guard be bypassed and an
|
|
45
|
+
// existing board silently overwritten (Phase 22 security review, low). Collapse
|
|
46
|
+
// runs of SPACES (the one allowed whitespace) to a single space so the JS slug
|
|
47
|
+
// (`/\s+/→_`) and slug.sh (`tr ' ' '_'`) can't diverge on a double-spaced name
|
|
48
|
+
// (review #4); tabs/newlines stay un-collapsed and are rejected by NAME_RE.
|
|
49
|
+
const name = raw.normalize('NFC').trim().replace(/ +/g, ' ');
|
|
50
|
+
if (!name) return { ok: false, error: 'name is required' };
|
|
51
|
+
if (name.length > 60) return { ok: false, error: 'name must be 60 characters or fewer' };
|
|
52
|
+
if (!NAME_RE.test(name)) {
|
|
53
|
+
return {
|
|
54
|
+
ok: false,
|
|
55
|
+
error: 'name may contain only letters, numbers, spaces, hyphens and underscores',
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
// Defense in depth — the regex already forbids these, but assert no path bits
|
|
59
|
+
// survive (a regex edit must never silently re-open traversal).
|
|
60
|
+
if (name.includes('..') || name.includes('/') || name.includes('\\') || name.startsWith('.')) {
|
|
61
|
+
return { ok: false, error: 'name may not contain path separators or leading dots' };
|
|
62
|
+
}
|
|
63
|
+
return { ok: true, name, componentName: componentNameFrom(name) };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** PascalCase a name into a valid JS identifier for the component default export.
|
|
67
|
+
* Non-identifier characters split words; an empty / digit-leading result gets a
|
|
68
|
+
* `Board` prefix so the emitted `export default function <id>()` always parses. */
|
|
69
|
+
export function componentNameFrom(name: string): string {
|
|
70
|
+
// Split on NON-(letter|number) so Unicode letters survive (the validator
|
|
71
|
+
// accepts them) — `Přihlášení` → `Přihlášení`, a valid JS identifier (verified
|
|
72
|
+
// it parses), not the ASCII-mangled `PIhlEn` (review #1). Empty (all-symbol) →
|
|
73
|
+
// `BriefBoard`; a digit-leading result (incl. Unicode digits) → `Board…` so the
|
|
74
|
+
// emitted `export default function <id>()` always parses.
|
|
75
|
+
const pascal = name
|
|
76
|
+
.split(/[^\p{L}\p{N}]+/u)
|
|
77
|
+
.filter(Boolean)
|
|
78
|
+
.map((w) => w[0].toUpperCase() + w.slice(1))
|
|
79
|
+
.join('');
|
|
80
|
+
if (!pascal) return 'BriefBoard';
|
|
81
|
+
if (/^\p{Nd}/u.test(pascal)) return `Board${pascal}`;
|
|
82
|
+
return pascal;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface BriefBoardOpts {
|
|
86
|
+
name: string;
|
|
87
|
+
componentName: string;
|
|
88
|
+
dsName: string;
|
|
89
|
+
platform: string;
|
|
90
|
+
seedHint: string;
|
|
91
|
+
historyDir: string;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Substitute the brief-board template placeholders. Safe because `name`
|
|
95
|
+
* (the only user value reaching here) is validated by `validateCanvasName`,
|
|
96
|
+
* and every other field is server-derived (config / fixed strings). */
|
|
97
|
+
export function renderBriefBoard(opts: BriefBoardOpts): string {
|
|
98
|
+
return BRIEF_BOARD_TEMPLATE.replaceAll('{{NAME}}', opts.name)
|
|
99
|
+
.replaceAll('{{COMPONENT_NAME}}', opts.componentName)
|
|
100
|
+
.replaceAll('{{DS_NAME}}', opts.dsName)
|
|
101
|
+
.replaceAll('{{PLATFORM}}', opts.platform)
|
|
102
|
+
.replaceAll('{{SEED_HINT}}', opts.seedHint)
|
|
103
|
+
.replaceAll('{{HISTORY_DIR}}', opts.historyDir);
|
|
104
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file canvas-cursors.ts — Phase 24 custom tool cursors (Kenney CC0)
|
|
3
|
-
* @scope
|
|
3
|
+
* @scope apps/studio/canvas-cursors.ts
|
|
4
4
|
* @purpose FigJam/Figma-style custom cursors for EVERY canvas tool. The
|
|
5
5
|
* native crosshair / text / arrow cursors are tiny + thin and
|
|
6
6
|
* vanish on busy canvases; these are 32×32 SVG cursors that read on
|
|
@@ -46,16 +46,29 @@ const HALO = "stroke='#ffffff' stroke-linejoin='round' stroke-linecap='round'";
|
|
|
46
46
|
// Kenney's outline band (`b`) is painted WHITE (the halo) and its inner fill
|
|
47
47
|
// (`w`) is painted dark INK. Reads crisply on a LIGHT canvas (solid dark glyph)
|
|
48
48
|
// AND a dark one (white halo edge).
|
|
49
|
-
function kenney(b: string, w: string): string {
|
|
50
|
-
|
|
49
|
+
function kenney(b: string, w: string, transform?: string): string {
|
|
50
|
+
// Optional `<g transform>` for the drawing tools whose Kenney glyph needs
|
|
51
|
+
// re-orienting so the writing tip lands at the hotspot (user steer
|
|
52
|
+
// 2026-06-04: pen / highlighter "kreslí pod koncem, ne na špičce" → flipped so
|
|
53
|
+
// the nib points down-LEFT, top-right→bottom-left).
|
|
54
|
+
const open = transform ? `<g transform='${transform}'>` : '';
|
|
55
|
+
const close = transform ? '</g>' : '';
|
|
56
|
+
return `<svg ${W}>${open}<path fill='#ffffff' d='${b}'/><path fill='${INK}' d='${w}'/>${close}</svg>`;
|
|
51
57
|
}
|
|
52
58
|
|
|
59
|
+
// Vertical mirror about the 32-viewBox horizontal centre: (x,y) → (x, 32−y).
|
|
60
|
+
// Applied to pen/highlighter so the glyph lies along the top-right→bottom-left
|
|
61
|
+
// diagonal with the nib at bottom-left.
|
|
62
|
+
const FLIP_V = 'translate(0,32) scale(1,-1)';
|
|
63
|
+
|
|
64
|
+
// move → Kenney `pointer_b` (user steer 2026-06-04 — the plain variant, not the
|
|
65
|
+
// shaded one). Hotspot at the arrow tip (top).
|
|
53
66
|
const MOVE = svgCursor(
|
|
54
67
|
kenney(
|
|
55
|
-
'
|
|
56
|
-
'
|
|
68
|
+
'M10.25 8.25 L10.05 8.65 10 9 10 23.1 10.05 23.4 10.25 23.75 10.8 24 11.45 23.85 11.6 23.7 11.75 23.45 14.65 19.8 14.85 19.65 14.95 19.5 15.4 19.2 15.95 19.1 21.05 19.1 21.2 19.1 21.35 19.05 21.65 18.9 21.9 18.6 22 18.3 22 17.9 21.9 17.65 21.75 17.35 21.65 17.3 21.55 17.15 11.5 8.25 11.25 8.05 10.95 8 10.6 8.05 10.25 8.25 M9.15 6.6 L9.7 6.25 10 6.15 10.95 6 11.9 6.15 13 6.9 22.9 15.65 23 15.8 23.2 15.95 23.75 16.75 24 17.9 24 18.3 23.9 18.95 23.8 19.25 23.6 19.7 23.1 20.35 22.75 20.6 22.1 20.9 22.05 20.95 22 20.95 21.2 21.1 21.05 21.1 16.2 21.1 16.1 21.25 16.05 21.25 13.4 24.6 13.05 25.15 12.9 25.3 12.55 25.55 Q11.6 26.15 10.55 26 L10.5 26 Q9.65 25.85 9 25.3 L8.45 24.65 8.4 24.5 8.15 24.05 8 23.1 8 9 Q8 8.45 8.15 8.05 L8.25 7.75 8.45 7.35 9.15 6.6',
|
|
69
|
+
'M10.25 8.25 L10.6 8.05 10.95 8 11.25 8.05 11.5 8.25 21.55 17.15 21.65 17.3 21.75 17.35 21.9 17.65 22 17.9 22 18.3 21.9 18.6 21.65 18.9 21.35 19.05 21.2 19.1 21.05 19.1 15.95 19.1 15.4 19.2 14.95 19.5 14.85 19.65 14.65 19.8 11.75 23.45 11.6 23.7 11.45 23.85 10.8 24 10.25 23.75 10.05 23.4 10 23.1 10 9 10.05 8.65 10.25 8.25'
|
|
57
70
|
),
|
|
58
|
-
|
|
71
|
+
8,
|
|
59
72
|
5,
|
|
60
73
|
'default'
|
|
61
74
|
);
|
|
@@ -68,22 +81,40 @@ const HAND = svgCursor(
|
|
|
68
81
|
12,
|
|
69
82
|
'grab'
|
|
70
83
|
);
|
|
84
|
+
// comment → Kenney `message_round` (user steer 2026-06-04). Hotspot at the
|
|
85
|
+
// tail tip (bottom-centre), where the comment pin is dropped.
|
|
71
86
|
const COMMENT = svgCursor(
|
|
72
87
|
kenney(
|
|
73
|
-
'
|
|
74
|
-
'
|
|
88
|
+
'M28 14 Q28 9.85 24.45 6.9 20.95 4 16 4 11.05 4 7.5 6.9 L7.45 7 Q4 9.9 4 14 4 18.15 7.55 21.05 L7.5 21.05 Q9.2 22.45 11.2 23.2 L15.3 27.3 16 27.6 16.7 27.3 20.85 23.2 Q22.7 22.45 24.3 21.15 L24.45 21.05 Q28 18.15 28 14 M25.75 5.35 Q30.05 8.95 30 14 30.05 19.05 25.75 22.6 L25.4 22.85 Q23.8 24.1 22 24.9 L18.1 28.75 18.15 28.75 Q17.2 29.6 16 29.6 14.8 29.6 13.85 28.75 L13.9 28.75 10 24.9 6.6 22.85 6.25 22.6 Q1.95 19.05 2 14 1.95 8.95 6.25 5.35 10.3 2 16 2 21.7 2 25.75 5.35',
|
|
89
|
+
'M28 14 Q28 18.15 24.45 21.05 L24.3 21.15 Q22.7 22.45 20.85 23.2 L16.7 27.3 16 27.6 15.3 27.3 11.2 23.2 Q9.2 22.45 7.5 21.05 L7.55 21.05 Q4 18.15 4 14 4 9.9 7.45 7 L7.5 6.9 Q11.05 4 16 4 20.95 4 24.45 6.9 28 9.85 28 14'
|
|
75
90
|
),
|
|
76
91
|
12,
|
|
77
|
-
|
|
92
|
+
21,
|
|
78
93
|
'crosshair'
|
|
79
94
|
);
|
|
95
|
+
// pen → Kenney `drawing_pen`, mirrored vertically (FLIP_V) so the nib points
|
|
96
|
+
// down-LEFT (top-right→bottom-left diagonal). Source gradient-shade path dropped.
|
|
97
|
+
// Hotspot at the nib, bottom-left.
|
|
80
98
|
const PEN = svgCursor(
|
|
99
|
+
kenney(
|
|
100
|
+
'M4 13.1 L4 6 Q4 5.15 4.6 4.6 5.15 4 6 4 L13.1 4 Q13.95 4 14.55 4.6 L28.65 18.75 Q29.8 19.9 29.75 21.45 L29.75 21.6 29.75 21.7 Q29.75 23.2 28.7 24.35 L24.45 28.65 24.35 28.75 Q23.15 29.85 21.65 29.8 L21.55 29.8 21.4 29.8 Q20.2 29.8 19.25 29.15 L18 29.35 Q16.6 29.4 15.25 28 L15.2 27.95 8.2 20.95 Q7.6 20.35 7.6 19.55 7.6 18.7 8.2 18.1 L4.6 14.5 Q4 13.9 4 13.1 M19.5 26.65 L20.1 27.25 Q20.7 27.85 21.5 27.8 22.35 27.85 23 27.25 L27.25 22.95 Q27.8 22.35 27.75 21.55 27.8 20.75 27.2 20.15 L13.1 6 6 6 6 13.1 12.35 19.45 9.6 19.5 16.65 26.55 Q18.05 28.05 19.5 26.65 M8.05 12.3 L8 8 12.25 8.05 13.8 9.6 9.6 13.85 8.05 12.3 M15.25 11.05 L23 18.8 18.8 23.05 11.05 15.3 15.25 11.05',
|
|
101
|
+
'M15.25 11.05 L11.05 15.3 18.8 23.05 23 18.8 15.25 11.05 M12.35 19.45 L6 13.1 6 6 13.1 6 27.2 20.15 Q27.8 20.75 27.75 21.55 27.8 22.35 27.25 22.95 L23 27.25 Q22.35 27.85 21.5 27.8 20.7 27.85 20.1 27.25 L19.5 26.65 12.35 19.45 M8.05 12.3 L9.6 13.85 13.8 9.6 12.25 8.05 8 8 8.05 12.3',
|
|
102
|
+
FLIP_V
|
|
103
|
+
),
|
|
104
|
+
6,
|
|
105
|
+
18,
|
|
106
|
+
'crosshair'
|
|
107
|
+
);
|
|
108
|
+
// highlighter → Kenney `drawing_pencil`, also mirrored vertically (distinct from
|
|
109
|
+
// the pen glyph). Hotspot at the lead tip, bottom-left.
|
|
110
|
+
const HIGHLIGHTER = svgCursor(
|
|
81
111
|
kenney(
|
|
82
112
|
'M5.15 10.85 Q4 9.65 4 8.1 L4 7.95 4 7.85 Q3.95 6.2 5.1 5.15 6.25 4 7.85 4 L7.95 4 8.1 4 Q9.65 4 10.85 5.15 L11 5.3 14.3 5.25 Q15.15 5.25 15.75 5.85 L29.9 20 Q31 21.15 31 22.75 L31 22.85 31 23 Q31.05 24.5 29.9 25.7 L29.55 25.95 25.65 29.9 25.65 29.95 Q24.45 31.1 22.75 31.1 21.2 31.15 20 29.95 L5.85 15.8 Q5.25 15.2 5.25 14.35 L5.25 10.95 5.15 10.85 M19.95 24.2 L18.55 22.8 22.8 18.55 24.2 19.95 19.95 24.2 M28.45 21.4 L14.3 7.25 10.15 7.3 9.4 6.55 Q8.8 5.95 7.95 6 7.1 5.95 6.5 6.55 5.95 7.1 6 7.95 5.95 8.8 6.55 9.4 L7.25 10.1 7.25 14.35 21.4 28.5 Q22 29.1 22.75 29.1 23.6 29.1 24.2 28.5 L28.45 24.25 Q29.05 23.65 29 22.85 29.05 22 28.45 21.4 M9.25 13.5 L9.25 9.3 13.5 9.25 14.3 10.05 10.05 14.3 9.25 13.5 M17.15 21.4 L11.5 15.75 15.75 11.5 21.4 17.15 17.15 21.4',
|
|
83
|
-
'M17.15 21.4 L21.4 17.15 15.75 11.5 11.5 15.75 17.15 21.4 M28.45 21.4 Q29.05 22 29 22.85 29.05 23.65 28.45 24.25 L24.2 28.5 Q23.6 29.1 22.75 29.1 22 29.1 21.4 28.5 L7.25 14.35 7.25 10.1 6.55 9.4 Q5.95 8.8 6 7.95 5.95 7.1 6.5 6.55 7.1 5.95 7.95 6 8.8 5.95 9.4 6.55 L10.15 7.3 14.3 7.25 28.45 21.4 M19.95 24.2 L24.2 19.95 22.8 18.55 18.55 22.8 19.95 24.2 M9.25 13.5 L10.05 14.3 14.3 10.05 13.5 9.25 9.25 9.3 9.25 13.5'
|
|
113
|
+
'M17.15 21.4 L21.4 17.15 15.75 11.5 11.5 15.75 17.15 21.4 M28.45 21.4 Q29.05 22 29 22.85 29.05 23.65 28.45 24.25 L24.2 28.5 Q23.6 29.1 22.75 29.1 22 29.1 21.4 28.5 L7.25 14.35 7.25 10.1 6.55 9.4 Q5.95 8.8 6 7.95 5.95 7.1 6.5 6.55 7.1 5.95 7.95 6 8.8 5.95 9.4 6.55 L10.15 7.3 14.3 7.25 28.45 21.4 M19.95 24.2 L24.2 19.95 22.8 18.55 18.55 22.8 19.95 24.2 M9.25 13.5 L10.05 14.3 14.3 10.05 13.5 9.25 9.25 9.3 9.25 13.5',
|
|
114
|
+
FLIP_V
|
|
84
115
|
),
|
|
85
|
-
|
|
86
|
-
|
|
116
|
+
6,
|
|
117
|
+
18,
|
|
87
118
|
'crosshair'
|
|
88
119
|
);
|
|
89
120
|
const CROSSHAIR = svgCursor(
|
|
@@ -140,6 +171,9 @@ export const TOOL_CURSORS: Record<Tool, string> = Object.freeze({
|
|
|
140
171
|
hand: HAND,
|
|
141
172
|
comment: COMMENT,
|
|
142
173
|
pen: PEN,
|
|
174
|
+
// Highlighter = Kenney `drawing_pencil` rot180; pen = `drawing_pen` rot180 —
|
|
175
|
+
// distinct glyphs, both from the Kenney pack (user steer 2026-06-04).
|
|
176
|
+
highlighter: HIGHLIGHTER,
|
|
143
177
|
shape: CROSSHAIR,
|
|
144
178
|
rect: CROSSHAIR,
|
|
145
179
|
ellipse: CROSSHAIR,
|
|
@@ -168,6 +202,6 @@ export const TOOL_CURSORS: Record<Tool, string> = Object.freeze({
|
|
|
168
202
|
*/
|
|
169
203
|
export function resolveToolCursor(token: unknown): string | null {
|
|
170
204
|
if (typeof token !== 'string' || !/^[a-z-]+$/.test(token)) return null;
|
|
171
|
-
if (!Object.
|
|
205
|
+
if (!Object.hasOwn(TOOL_CURSORS, token)) return null;
|
|
172
206
|
return TOOL_CURSORS[token as Tool];
|
|
173
207
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file canvas-icons.tsx — Phase 5.1 inline-SVG icon set
|
|
3
|
-
* @scope
|
|
3
|
+
* @scope apps/studio/canvas-icons.tsx
|
|
4
4
|
* @purpose Tiny dependency-free Lucide-style icon set for the canvas
|
|
5
5
|
* chrome (tool palette, context toolbar). Each icon is a single
|
|
6
6
|
* `<svg>` with `currentColor` stroke so it inherits the button
|
|
@@ -122,6 +122,18 @@ export function IconText(props: IconProps) {
|
|
|
122
122
|
);
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
+
// Phase 23 — link (chain) glyph, used by the annotation context toolbar's
|
|
126
|
+
// "Open link" button. (Media is paste/drop-only — no toolbar buttons — so the
|
|
127
|
+
// picture-frame image icon was dropped.)
|
|
128
|
+
export function IconLink(props: IconProps) {
|
|
129
|
+
return (
|
|
130
|
+
<Svg {...props}>
|
|
131
|
+
<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" />
|
|
132
|
+
<path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" />
|
|
133
|
+
</Svg>
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
125
137
|
export function IconPresentation(props: IconProps) {
|
|
126
138
|
return (
|
|
127
139
|
<Svg {...props}>
|
|
@@ -404,11 +416,58 @@ export function IconAlignRight(props: IconProps) {
|
|
|
404
416
|
);
|
|
405
417
|
}
|
|
406
418
|
|
|
419
|
+
// ── Annotation polish text-style icons (italic / underline / lists) ──────────
|
|
420
|
+
export function IconItalic(props: IconProps) {
|
|
421
|
+
return (
|
|
422
|
+
<Svg {...props}>
|
|
423
|
+
<path d="M10 5h8M6 19h8M14 5l-4 14" />
|
|
424
|
+
</Svg>
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
export function IconUnderline(props: IconProps) {
|
|
428
|
+
return (
|
|
429
|
+
<Svg {...props}>
|
|
430
|
+
<path d="M7 4v7a5 5 0 0010 0V4M5 20h14" />
|
|
431
|
+
</Svg>
|
|
432
|
+
);
|
|
433
|
+
}
|
|
434
|
+
export function IconListBullet(props: IconProps) {
|
|
435
|
+
return (
|
|
436
|
+
<Svg {...props}>
|
|
437
|
+
<path d="M9 6h11M9 12h11M9 18h11" />
|
|
438
|
+
<circle cx="4.5" cy="6" r="1.1" fill="currentColor" stroke="none" />
|
|
439
|
+
<circle cx="4.5" cy="12" r="1.1" fill="currentColor" stroke="none" />
|
|
440
|
+
<circle cx="4.5" cy="18" r="1.1" fill="currentColor" stroke="none" />
|
|
441
|
+
</Svg>
|
|
442
|
+
);
|
|
443
|
+
}
|
|
444
|
+
export function IconListOrdered(props: IconProps) {
|
|
445
|
+
return (
|
|
446
|
+
<Svg {...props}>
|
|
447
|
+
<path d="M10 6h10M10 12h10M10 18h10" />
|
|
448
|
+
<path d="M3 5l1.4-.5V9M3 9h2.8" strokeWidth={1.4} />
|
|
449
|
+
<path d="M3.2 14.2a1 1 0 011.7.7c0 .9-1.7 1.4-1.7 2.6h2" strokeWidth={1.4} />
|
|
450
|
+
</Svg>
|
|
451
|
+
);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// ── Annotation polish — highlighter (chisel-tip marker) ──────────────────────
|
|
455
|
+
export function IconHighlighter(props: IconProps) {
|
|
456
|
+
return (
|
|
457
|
+
<Svg {...props}>
|
|
458
|
+
<path d="M14 4l6 6-8.5 8.5H6v-5.5z" />
|
|
459
|
+
<path d="M11 7l6 6" />
|
|
460
|
+
<path d="M4 21h7" strokeWidth={2.5} />
|
|
461
|
+
</Svg>
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
|
|
407
465
|
export const TOOL_ICONS: Record<string, (p: IconProps) => JSX.Element> = {
|
|
408
466
|
move: IconMove,
|
|
409
467
|
hand: IconHand,
|
|
410
468
|
comment: IconComment,
|
|
411
469
|
pen: IconPen,
|
|
470
|
+
highlighter: IconHighlighter,
|
|
412
471
|
// Phase 24 — single Shape tool. rect/ellipse kept for any legacy lookups.
|
|
413
472
|
shape: IconShape,
|
|
414
473
|
rect: IconRect,
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
// `/design:handoff` emits a self-contained shadcn registry-item.json. Canvases
|
|
5
5
|
// import their envelope + helpers from `@maude/canvas-lib`, which the dev-server
|
|
6
|
-
// resolves to its bundled `
|
|
6
|
+
// resolves to its bundled `apps/studio/canvas-lib.tsx`. The
|
|
7
7
|
// handoff drop must inline every used export so the consumer never sees the
|
|
8
8
|
// `@maude/canvas-lib` specifier — it's a dev-time virtual module, not a real
|
|
9
9
|
// npm dep.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
//
|
|
3
3
|
// Canvases import the shared canvas library via the specifier `@maude/canvas-lib`.
|
|
4
4
|
// At build time we redirect that to the dev-server-bundled source at
|
|
5
|
-
// `
|
|
5
|
+
// `apps/studio/canvas-lib.tsx` so:
|
|
6
6
|
//
|
|
7
7
|
// - the lib ships with the dev-server install (single source of truth — see
|
|
8
8
|
// DDR-025; reverses DDR-022's "project-owned source under <designRoot>/_lib/"),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file canvas-lib.tsx — dev-server-bundled canvas library
|
|
3
|
-
* @scope
|
|
3
|
+
* @scope apps/studio/canvas-lib.tsx
|
|
4
4
|
* Ships with the dev-server install; resolved at canvas build time
|
|
5
5
|
* via the `@maude/canvas-lib` virtual specifier. Per DDR-025, this
|
|
6
6
|
* is the single source of truth — no project-side copy.
|
|
@@ -67,14 +67,19 @@
|
|
|
67
67
|
* deprecation log at dev-server boot.
|
|
68
68
|
*/
|
|
69
69
|
|
|
70
|
+
import {
|
|
71
|
+
AnimatePresence as _MotionAnimatePresence,
|
|
72
|
+
motion as _motionImpl,
|
|
73
|
+
useReducedMotion as _useReducedMotion,
|
|
74
|
+
} from 'motion/react';
|
|
70
75
|
import {
|
|
71
76
|
type CSSProperties,
|
|
77
|
+
createContext,
|
|
72
78
|
Fragment,
|
|
79
|
+
isValidElement,
|
|
73
80
|
type ReactNode,
|
|
74
81
|
type PointerEvent as ReactPointerEvent,
|
|
75
82
|
type RefObject,
|
|
76
|
-
createContext,
|
|
77
|
-
isValidElement,
|
|
78
83
|
useCallback,
|
|
79
84
|
useContext,
|
|
80
85
|
useEffect,
|
|
@@ -84,12 +89,6 @@ import {
|
|
|
84
89
|
useState,
|
|
85
90
|
} from 'react';
|
|
86
91
|
|
|
87
|
-
import {
|
|
88
|
-
AnimatePresence as _MotionAnimatePresence,
|
|
89
|
-
motion as _motionImpl,
|
|
90
|
-
useReducedMotion as _useReducedMotion,
|
|
91
|
-
} from 'motion/react';
|
|
92
|
-
|
|
93
92
|
import { ArtboardActivityOverlay } from './artboard-activity-overlay.tsx';
|
|
94
93
|
import { CanvasShell } from './canvas-shell.tsx';
|
|
95
94
|
import {
|
|
@@ -138,10 +137,9 @@ const ENGINE_CSS = `
|
|
|
138
137
|
/* Canvas-shell chrome — the workspace plane + dotted grid follow the Maude
|
|
139
138
|
chrome theme (--maude-chrome-*), NOT the DS palette. See canvas-shell.tsx
|
|
140
139
|
HUD_TOKENS_CSS. Artboards (.dc-artboard) keep the DS theme. */
|
|
141
|
-
background-color: var(--maude-chrome-bg-
|
|
140
|
+
background-color: var(--maude-chrome-bg-0, #f4f1ea);
|
|
142
141
|
background-image:
|
|
143
|
-
|
|
144
|
-
linear-gradient(90deg, var(--maude-chrome-border, rgba(0,0,0,0.08)) 1px, transparent 1px);
|
|
142
|
+
radial-gradient(var(--maude-chrome-dot, rgba(0,0,0,0.12)) 1.1px, transparent 1.2px);
|
|
145
143
|
background-size: 24px 24px;
|
|
146
144
|
}
|
|
147
145
|
/* DDR-046 — Snap guides. Sibling kind = confident magenta + glow + distance
|
|
@@ -200,6 +198,17 @@ const ENGINE_CSS = `
|
|
|
200
198
|
irrelevant under zoom (zoom anchors top-left of the box). will-change
|
|
201
199
|
hints to the compositor that this layer changes often. */
|
|
202
200
|
will-change: transform;
|
|
201
|
+
/* Marquee / multi-select drags over artboards must not trigger native text
|
|
202
|
+
selection (it highlighted the canvas content). Editable surfaces re-enable
|
|
203
|
+
it below. */
|
|
204
|
+
user-select: none;
|
|
205
|
+
-webkit-user-select: none;
|
|
206
|
+
}
|
|
207
|
+
.dc-world input,
|
|
208
|
+
.dc-world textarea,
|
|
209
|
+
.dc-world [contenteditable="true"] {
|
|
210
|
+
user-select: text;
|
|
211
|
+
-webkit-user-select: text;
|
|
203
212
|
}
|
|
204
213
|
.dc-section-collapsed { display: contents; }
|
|
205
214
|
|
|
@@ -1163,7 +1172,7 @@ export function useDragStateContext(): DragStateBus | null {
|
|
|
1163
1172
|
interface DesignCanvasProps {
|
|
1164
1173
|
children: ReactNode;
|
|
1165
1174
|
/** Per-overlay opt-out. `false` hides it; omit or `true` shows it. */
|
|
1166
|
-
controls?: { minimap?: boolean; toolbar?: boolean };
|
|
1175
|
+
controls?: { minimap?: boolean; toolbar?: boolean; zoom?: boolean };
|
|
1167
1176
|
}
|
|
1168
1177
|
|
|
1169
1178
|
/**
|
|
@@ -1375,6 +1384,7 @@ function DesignCanvasInner({ children, controls }: DesignCanvasProps) {
|
|
|
1375
1384
|
);
|
|
1376
1385
|
|
|
1377
1386
|
const showMiniMap = controls?.minimap !== false;
|
|
1387
|
+
const showZoom = controls?.zoom !== false;
|
|
1378
1388
|
|
|
1379
1389
|
// Drag-state bus (Phase 4.2). Single source of truth: only one artboard
|
|
1380
1390
|
// drag is active at a time. DCArtboards write here when their local drag
|
|
@@ -1446,10 +1456,12 @@ function DesignCanvasInner({ children, controls }: DesignCanvasProps) {
|
|
|
1446
1456
|
{children}
|
|
1447
1457
|
</div>
|
|
1448
1458
|
{showMiniMap ? <DCMiniMap /> : null}
|
|
1449
|
-
{/*
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1459
|
+
{/* Plan C F6 — separate bottom-left zoom pill (the design's ZoomHud).
|
|
1460
|
+
Phase 5.1 had folded zoom into the ToolPalette; user feedback wants
|
|
1461
|
+
the design's standalone pill, so DCZoomToolbar renders here again (the
|
|
1462
|
+
ToolPalette's inline zoom is removed in tool-palette.tsx). It carries
|
|
1463
|
+
MORE than the mock — fit + actual-size — so no capability is lost. */}
|
|
1464
|
+
{showZoom ? <DCZoomToolbar /> : null}
|
|
1453
1465
|
</div>
|
|
1454
1466
|
);
|
|
1455
1467
|
|
|
@@ -1901,6 +1913,9 @@ const OVERLAY_CSS = `
|
|
|
1901
1913
|
overflow: hidden;
|
|
1902
1914
|
}
|
|
1903
1915
|
.dc-mm-hd {
|
|
1916
|
+
display: flex;
|
|
1917
|
+
align-items: center;
|
|
1918
|
+
justify-content: space-between;
|
|
1904
1919
|
padding: 5px 8px 4px;
|
|
1905
1920
|
border-bottom: 1px solid var(--maude-chrome-border, rgba(0,0,0,0.08));
|
|
1906
1921
|
letter-spacing: 0.05em;
|
|
@@ -1908,6 +1923,7 @@ const OVERLAY_CSS = `
|
|
|
1908
1923
|
font-size: 9px;
|
|
1909
1924
|
background: var(--maude-chrome-bg-1, #f4f1ea);
|
|
1910
1925
|
}
|
|
1926
|
+
.dc-mm-count { font-variant-numeric: tabular-nums; color: var(--maude-chrome-fg-2, rgba(40,30,20,0.55)); }
|
|
1911
1927
|
.dc-mm-body {
|
|
1912
1928
|
position: relative;
|
|
1913
1929
|
width: 100%;
|
|
@@ -1933,9 +1949,8 @@ const OVERLAY_CSS = `
|
|
|
1933
1949
|
}
|
|
1934
1950
|
.dc-zoom-tb {
|
|
1935
1951
|
position: absolute;
|
|
1936
|
-
left:
|
|
1952
|
+
left: 16px;
|
|
1937
1953
|
bottom: 16px;
|
|
1938
|
-
transform: translateX(-50%);
|
|
1939
1954
|
display: flex;
|
|
1940
1955
|
align-items: stretch;
|
|
1941
1956
|
background: var(--maude-chrome-bg-0, #ffffff);
|
|
@@ -2106,7 +2121,10 @@ export function DCMiniMap() {
|
|
|
2106
2121
|
return (
|
|
2107
2122
|
<div className="dc-mm" aria-hidden="true">
|
|
2108
2123
|
<div className="dc-mm-hd">
|
|
2109
|
-
|
|
2124
|
+
<span>World</span>
|
|
2125
|
+
<span className="dc-mm-count">
|
|
2126
|
+
{world.artboards.length} / {world.artboards.length}
|
|
2127
|
+
</span>
|
|
2110
2128
|
</div>
|
|
2111
2129
|
<div
|
|
2112
2130
|
className="dc-mm-body"
|
|
@@ -2204,11 +2222,7 @@ export function SpecimenHeader({
|
|
|
2204
2222
|
}
|
|
2205
2223
|
|
|
2206
2224
|
/** `<dl class="specimen-meta">` ladder. */
|
|
2207
|
-
export function SpecimenMeta({
|
|
2208
|
-
entries,
|
|
2209
|
-
}: {
|
|
2210
|
-
entries: Array<{ label: string; value: ReactNode }>;
|
|
2211
|
-
}) {
|
|
2225
|
+
export function SpecimenMeta({ entries }: { entries: Array<{ label: string; value: ReactNode }> }) {
|
|
2212
2226
|
return (
|
|
2213
2227
|
<dl className="specimen-meta">
|
|
2214
2228
|
{entries.map(({ label, value }) => (
|
|
@@ -2227,13 +2241,7 @@ export function KbdHint({ children }: { children: ReactNode }) {
|
|
|
2227
2241
|
}
|
|
2228
2242
|
|
|
2229
2243
|
/** Inline `var(--name)` value visualiser — small chip + token name. */
|
|
2230
|
-
export function TokenChip({
|
|
2231
|
-
name,
|
|
2232
|
-
swatch,
|
|
2233
|
-
}: {
|
|
2234
|
-
name: string;
|
|
2235
|
-
swatch?: boolean;
|
|
2236
|
-
}) {
|
|
2244
|
+
export function TokenChip({ name, swatch }: { name: string; swatch?: boolean }) {
|
|
2237
2245
|
return (
|
|
2238
2246
|
<span className="token-chip" data-token={name}>
|
|
2239
2247
|
{swatch ? (
|
|
@@ -2763,7 +2771,7 @@ export function ReducedMotionToggle() {
|
|
|
2763
2771
|
}
|
|
2764
2772
|
|
|
2765
2773
|
export {
|
|
2774
|
+
_MotionAnimatePresence as AnimatePresence,
|
|
2766
2775
|
_motionImpl as motion,
|
|
2767
2776
|
_useReducedMotion as useReducedMotion,
|
|
2768
|
-
_MotionAnimatePresence as AnimatePresence,
|
|
2769
2777
|
};
|