@1agh/maude 1.0.9 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/studio/acp/bridge.ts +18 -13
- package/apps/studio/acp/probe.ts +268 -16
- package/apps/studio/acp/transcript-io.ts +394 -0
- package/apps/studio/acp/transcript.ts +103 -38
- package/apps/studio/api.ts +139 -26
- package/apps/studio/bin/_import-figma.mjs +57 -11
- package/apps/studio/bin/_seed-fixture.mjs +163 -0
- package/apps/studio/canvas-imports.ts +89 -0
- package/apps/studio/client/app.jsx +257 -7
- package/apps/studio/client/export-center.jsx +15 -7
- package/apps/studio/client/panels/ReadinessList.jsx +7 -1
- package/apps/studio/client/panels/SyncPanel.jsx +125 -4
- package/apps/studio/client/report-bug.jsx +19 -1
- package/apps/studio/client/styles/3-shell-maude.css +34 -0
- package/apps/studio/client/styles/4-components.css +26 -0
- package/apps/studio/collab/persistence.ts +132 -16
- package/apps/studio/collab/registry.ts +10 -18
- package/apps/studio/debug-bundle.ts +13 -0
- package/apps/studio/dist/client.bundle.js +1128 -1128
- package/apps/studio/dist/styles.css +1 -1
- package/apps/studio/export-dialog.tsx +54 -0
- package/apps/studio/exporters/degraded.ts +19 -3
- package/apps/studio/exporters/ghostscript.ts +194 -0
- package/apps/studio/exporters/pdf-fonts.ts +261 -0
- package/apps/studio/exporters/pdf.ts +152 -3
- package/apps/studio/exporters/remote.ts +36 -1
- package/apps/studio/fs-watch.ts +45 -1
- package/apps/studio/http.ts +7 -1
- package/apps/studio/mem.ts +45 -9
- package/apps/studio/readiness.ts +42 -7
- package/apps/studio/server.ts +11 -4
- package/apps/studio/sync/agent.ts +136 -29
- package/apps/studio/sync/asset-push.ts +1 -47
- package/apps/studio/sync/codec.ts +122 -31
- package/apps/studio/sync/cold-start-apply.ts +7 -0
- package/apps/studio/sync/cold-start.ts +118 -22
- package/apps/studio/sync/comment-identity.ts +68 -0
- package/apps/studio/sync/connection-state.ts +15 -1
- package/apps/studio/sync/file-ledger.ts +117 -0
- package/apps/studio/sync/file-plane.ts +623 -27
- package/apps/studio/sync/index.ts +711 -20
- package/apps/studio/sync/journal-client.ts +13 -1
- package/apps/studio/sync/migrate-seed.ts +40 -3
- package/apps/studio/sync/presentation.ts +26 -3
- package/apps/studio/sync/retry-after.ts +169 -0
- package/apps/studio/sync/seed-progress.ts +218 -0
- package/apps/studio/sync/status.ts +122 -5
- package/apps/studio/sync/transport-error.ts +111 -0
- package/apps/studio/whats-new.json +91 -0
- package/cli/bin/maude.mjs +2 -0
- package/cli/commands/codex.mjs +191 -0
- package/cli/commands/harness.mjs +1051 -0
- package/cli/commands/help.mjs +13 -0
- package/cli/lib/design-link.mjs +190 -2
- package/cli/lib/harness/capabilities.mjs +302 -0
- package/cli/lib/harness/codex-runtime.mjs +889 -0
- package/cli/lib/harness/compatibility.mjs +27 -0
- package/cli/lib/harness/discover-claude.mjs +1393 -0
- package/cli/lib/harness/managed-state.mjs +1296 -0
- package/cli/lib/harness/model.mjs +86 -0
- package/cli/lib/harness/secrets.mjs +390 -0
- package/cli/lib/harness/targets/codex.mjs +1141 -0
- package/cli/lib/harness/targets/opencode.mjs +807 -0
- package/cli/lib/harness/transaction.mjs +1099 -0
- package/cli/lib/hubs-config.mjs +35 -8
- package/cli/templates/harness/opencode/maude-projector.ts +58 -0
- package/docs/harness-capability-matrix.md +125 -0
- package/docs/harness-environment-projection.md +95 -0
- package/package.json +32 -9
- package/plugins/flow/.claude-plugin/config.schema.json +8 -0
- package/apps/studio/.ai/cache/_stats.json +0 -7
- package/apps/studio/bin/_agent-browser-safe.test.mjs +0 -165
- package/apps/studio/bin/_curl-local.test.mjs +0 -280
- package/apps/studio/bin/_pw-launch.test.mjs +0 -90
- package/apps/studio/bin/_smart-frames.test.mjs +0 -195
- package/apps/studio/bin/_transcribe.test.mjs +0 -80
- package/apps/studio/bun.lock +0 -928
- package/apps/studio/draw/test/animate.test.ts +0 -172
- package/apps/studio/draw/test/brush.test.ts +0 -213
- package/apps/studio/draw/test/composition.test.ts +0 -141
- package/apps/studio/draw/test/geometry.test.ts +0 -199
- package/apps/studio/draw/test/gradient.test.ts +0 -167
- package/apps/studio/draw/test/layout.test.ts +0 -120
- package/apps/studio/draw/test/morph.test.ts +0 -107
- package/apps/studio/draw/test/optimize.test.ts +0 -40
- package/apps/studio/draw/test/palette.test.ts +0 -123
- package/apps/studio/draw/test/primitives.test.ts +0 -129
- package/apps/studio/draw/test/serialize-animate.test.ts +0 -142
- package/apps/studio/draw/test/serialize.test.ts +0 -105
- package/apps/studio/figma/assets.test.ts +0 -464
- package/apps/studio/figma/client.test.ts +0 -395
- package/apps/studio/figma/codegen-client.test.ts +0 -276
- package/apps/studio/figma/codegen-fonts.test.ts +0 -103
- package/apps/studio/figma/codegen-values.test.ts +0 -179
- package/apps/studio/figma/comments-to-strokes.test.ts +0 -194
- package/apps/studio/figma/fig-decode.test.ts +0 -788
- package/apps/studio/figma/fig-differential.test.ts +0 -182
- package/apps/studio/figma/fig-translator.test.ts +0 -192
- package/apps/studio/figma/fig-vector.test.ts +0 -113
- package/apps/studio/figma/from-codegen.test.ts +0 -408
- package/apps/studio/figma/sanitize.test.ts +0 -325
- package/apps/studio/figma/tailwind-map.test.ts +0 -142
- package/apps/studio/figma/to-artboard.test.ts +0 -808
- package/apps/studio/figma/to-render.test.ts +0 -180
- package/apps/studio/figma/to-strokes-roundtrip.test.ts +0 -152
- package/apps/studio/figma/to-strokes.test.ts +0 -705
- package/apps/studio/figma/to-tokens.test.ts +0 -321
- package/apps/studio/figma/url.test.ts +0 -167
- package/apps/studio/footage/schema.test.ts +0 -287
- package/apps/studio/generation/adapters/groq.test.ts +0 -80
- package/apps/studio/generation/audio-library.test.ts +0 -95
- package/apps/studio/generation/captions.test.ts +0 -78
- package/apps/studio/generation/elevenlabs.test.ts +0 -223
- package/apps/studio/generation/gemini.test.ts +0 -350
- package/apps/studio/generation/jobs.test.ts +0 -128
- package/apps/studio/generation/keys.test.ts +0 -75
- package/apps/studio/generation/prefs.test.ts +0 -95
- package/apps/studio/generation/types.test.ts +0 -123
- package/apps/studio/generation/whisper-models.test.ts +0 -179
- package/apps/studio/test/_helpers.ts +0 -108
- package/apps/studio/test/acp-activity-endpoint.test.ts +0 -183
- package/apps/studio/test/acp-activity.test.ts +0 -154
- package/apps/studio/test/acp-ai-activity.test.ts +0 -182
- package/apps/studio/test/acp-attachment-serve.test.ts +0 -74
- package/apps/studio/test/acp-bootstrap-brief.test.ts +0 -178
- package/apps/studio/test/acp-branch-guard.test.ts +0 -123
- package/apps/studio/test/acp-bridge-lifetime.test.ts +0 -475
- package/apps/studio/test/acp-bridge.test.ts +0 -301
- package/apps/studio/test/acp-capabilities.test.ts +0 -123
- package/apps/studio/test/acp-caps-bridge.test.ts +0 -279
- package/apps/studio/test/acp-commands.test.ts +0 -119
- package/apps/studio/test/acp-elicitation-bridge.test.ts +0 -480
- package/apps/studio/test/acp-elicitation.test.ts +0 -251
- package/apps/studio/test/acp-env.test.ts +0 -95
- package/apps/studio/test/acp-mode-banner.test.ts +0 -45
- package/apps/studio/test/acp-origin-gate.test.ts +0 -160
- package/apps/studio/test/acp-permission-prompt.test.ts +0 -251
- package/apps/studio/test/acp-permission.test.ts +0 -278
- package/apps/studio/test/acp-plugin-bootstrap.test.ts +0 -89
- package/apps/studio/test/acp-session-allowed-tools.test.ts +0 -235
- package/apps/studio/test/acp-session-plugins.test.ts +0 -209
- package/apps/studio/test/acp-toolgroup.test.ts +0 -76
- package/apps/studio/test/acp-transcript-view.test.ts +0 -71
- package/apps/studio/test/acp-transcript.test.ts +0 -238
- package/apps/studio/test/acp-usage-bridge.test.ts +0 -141
- package/apps/studio/test/acp-usage.test.ts +0 -143
- package/apps/studio/test/acp-write-gate.test.ts +0 -323
- package/apps/studio/test/acp-write-scope.test.ts +0 -533
- package/apps/studio/test/active-state.test.ts +0 -186
- package/apps/studio/test/activity.test.ts +0 -189
- package/apps/studio/test/ai-activity.test.ts +0 -113
- package/apps/studio/test/annotate-write.test.ts +0 -1074
- package/apps/studio/test/annotation-strokes-command.test.ts +0 -166
- package/apps/studio/test/annotations-align.test.ts +0 -88
- package/apps/studio/test/annotations-api.test.ts +0 -145
- package/apps/studio/test/annotations-bindings.test.ts +0 -262
- package/apps/studio/test/annotations-draw-modifiers.test.ts +0 -206
- package/apps/studio/test/annotations-groups.test.ts +0 -231
- package/apps/studio/test/annotations-layer.test.ts +0 -1011
- package/apps/studio/test/annotations-roundtrip.test.ts +0 -663
- package/apps/studio/test/annotations-snap.test.ts +0 -135
- package/apps/studio/test/annotations-text-format.test.ts +0 -396
- package/apps/studio/test/artboard-activity-overlay.test.tsx +0 -56
- package/apps/studio/test/artboard-guides-overlay.test.tsx +0 -152
- package/apps/studio/test/artboard-hug-commit.test.ts +0 -36
- package/apps/studio/test/artboard-kinds.test.tsx +0 -83
- package/apps/studio/test/artboard-selection-attrs.test.ts +0 -69
- package/apps/studio/test/asset-api.test.ts +0 -149
- package/apps/studio/test/assets-s3.test.ts +0 -249
- package/apps/studio/test/binary-smoke.test.ts +0 -47
- package/apps/studio/test/boot-self-heal.test.ts +0 -87
- package/apps/studio/test/browse-posture.test.tsx +0 -107
- package/apps/studio/test/bundle-smoke.test.ts +0 -46
- package/apps/studio/test/camera-reveal.test.tsx +0 -173
- package/apps/studio/test/canvas-artifacts.test.ts +0 -125
- package/apps/studio/test/canvas-build-sandbox.test.ts +0 -69
- package/apps/studio/test/canvas-build.test.ts +0 -141
- package/apps/studio/test/canvas-create-api.test.ts +0 -676
- package/apps/studio/test/canvas-cursors.test.ts +0 -164
- package/apps/studio/test/canvas-edit.test.ts +0 -470
- package/apps/studio/test/canvas-freshness-deps.test.ts +0 -64
- package/apps/studio/test/canvas-header.test.ts +0 -127
- package/apps/studio/test/canvas-hide-chrome.test.ts +0 -88
- package/apps/studio/test/canvas-hmr-runtime.test.tsx +0 -114
- package/apps/studio/test/canvas-lib-inline.test.ts +0 -146
- package/apps/studio/test/canvas-lib-motion.test.ts +0 -131
- package/apps/studio/test/canvas-lib-resolver.test.ts +0 -111
- package/apps/studio/test/canvas-list-watch.test.ts +0 -388
- package/apps/studio/test/canvas-media-drop.test.ts +0 -187
- package/apps/studio/test/canvas-meta-api.test.ts +0 -707
- package/apps/studio/test/canvas-move-api.test.ts +0 -587
- package/apps/studio/test/canvas-origin-gate.test.ts +0 -417
- package/apps/studio/test/canvas-pipeline.test.ts +0 -180
- package/apps/studio/test/canvas-rects.test.ts +0 -198
- package/apps/studio/test/canvas-reorder.test.ts +0 -211
- package/apps/studio/test/canvas-route.test.ts +0 -179
- package/apps/studio/test/canvas-shell-base.test.ts +0 -107
- package/apps/studio/test/canvas-shell-build-error.test.ts +0 -52
- package/apps/studio/test/canvas-url.test.ts +0 -138
- package/apps/studio/test/canvas-wheel-delta.test.ts +0 -42
- package/apps/studio/test/canvas-zoom-floor.test.ts +0 -73
- package/apps/studio/test/capture-core.test.ts +0 -32
- package/apps/studio/test/capture-determinism-shape.test.ts +0 -135
- package/apps/studio/test/chat-attachments.test.ts +0 -117
- package/apps/studio/test/chat-context.test.ts +0 -129
- package/apps/studio/test/chat-markdown.test.tsx +0 -58
- package/apps/studio/test/clip-addressing.test.ts +0 -738
- package/apps/studio/test/clip-ops.test.ts +0 -922
- package/apps/studio/test/cloud-build.test.ts +0 -95
- package/apps/studio/test/cloud-connect-note.test.ts +0 -135
- package/apps/studio/test/cloud-endpoints.test.ts +0 -590
- package/apps/studio/test/cloud-history-hardening.test.ts +0 -165
- package/apps/studio/test/cloud-history-posture.test.ts +0 -230
- package/apps/studio/test/cloud-managed-save-surfaces.test.ts +0 -90
- package/apps/studio/test/cloud-renew.test.ts +0 -205
- package/apps/studio/test/cloud-session-role.test.ts +0 -161
- package/apps/studio/test/cloud-shell-surfaces.test.ts +0 -170
- package/apps/studio/test/cold-start-apply.test.ts +0 -303
- package/apps/studio/test/collab-annotations-bridge.test.ts +0 -55
- package/apps/studio/test/collab-awareness-bridge.test.ts +0 -223
- package/apps/studio/test/collab-bridge.test.ts +0 -79
- package/apps/studio/test/collab-loopback.test.ts +0 -63
- package/apps/studio/test/collab-origin-gate.test.ts +0 -323
- package/apps/studio/test/collab-protocol.test.ts +0 -146
- package/apps/studio/test/collab-readonly-gate.test.ts +0 -194
- package/apps/studio/test/collab-reseed-guard.test.ts +0 -78
- package/apps/studio/test/collab-room.test.ts +0 -188
- package/apps/studio/test/collab-session-survival.test.tsx +0 -176
- package/apps/studio/test/collab-stress.test.ts +0 -129
- package/apps/studio/test/comment-mount.test.ts +0 -97
- package/apps/studio/test/comment-relay-origin-gate.test.ts +0 -117
- package/apps/studio/test/comments-api.test.ts +0 -277
- package/apps/studio/test/comments-fs-rebroadcast.test.ts +0 -155
- package/apps/studio/test/comments-overlay.test.ts +0 -117
- package/apps/studio/test/compile-entry.test.ts +0 -133
- package/apps/studio/test/component-map.test.ts +0 -48
- package/apps/studio/test/config-projection.test.ts +0 -104
- package/apps/studio/test/config-reload.test.ts +0 -230
- package/apps/studio/test/config-version.test.ts +0 -88
- package/apps/studio/test/context-resolve-tokens.test.ts +0 -97
- package/apps/studio/test/convert-to-absolute.test.ts +0 -333
- package/apps/studio/test/credential-grammar.test.ts +0 -107
- package/apps/studio/test/csp-canvas-shell.test.ts +0 -62
- package/apps/studio/test/csrf-write-guard.test.ts +0 -141
- package/apps/studio/test/debug-bundle.test.ts +0 -105
- package/apps/studio/test/design-setup-readiness.test.ts +0 -155
- package/apps/studio/test/detach-component.test.ts +0 -94
- package/apps/studio/test/dns-rebinding-guard.test.ts +0 -101
- package/apps/studio/test/dom-selection.test.ts +0 -198
- package/apps/studio/test/dynamic-text-edit.test.ts +0 -162
- package/apps/studio/test/edit-css-occurrence.test.ts +0 -81
- package/apps/studio/test/edit-persistence.test.ts +0 -91
- package/apps/studio/test/edit-scope-api.test.ts +0 -119
- package/apps/studio/test/edit-source-command.test.ts +0 -142
- package/apps/studio/test/edit-suppress.test.ts +0 -170
- package/apps/studio/test/editing-presence.test.ts +0 -103
- package/apps/studio/test/element-resize.test.ts +0 -136
- package/apps/studio/test/element-structural-api.test.ts +0 -434
- package/apps/studio/test/element-structural-edit.test.ts +0 -750
- package/apps/studio/test/ensure-browser.test.ts +0 -92
- package/apps/studio/test/equal-spacing-detector.test.ts +0 -257
- package/apps/studio/test/export-assemble.test.ts +0 -53
- package/apps/studio/test/export-browser-lane.test.ts +0 -126
- package/apps/studio/test/export-capture-fidelity.test.ts +0 -146
- package/apps/studio/test/export-capture-hygiene.test.ts +0 -675
- package/apps/studio/test/export-center.test.tsx +0 -287
- package/apps/studio/test/export-e2e-lanes.test.ts +0 -857
- package/apps/studio/test/export-format-scope-coherence.test.ts +0 -89
- package/apps/studio/test/export-lane.test.ts +0 -245
- package/apps/studio/test/export-shim-multi-capture.test.ts +0 -83
- package/apps/studio/test/exporters/canva.test.ts +0 -63
- package/apps/studio/test/exporters/degraded-propagation.test.ts +0 -123
- package/apps/studio/test/exporters/endpoint.test.ts +0 -121
- package/apps/studio/test/exporters/history.test.ts +0 -107
- package/apps/studio/test/exporters/html.test.ts +0 -26
- package/apps/studio/test/exporters/jobs.test.ts +0 -342
- package/apps/studio/test/exporters/pdf.test.ts +0 -85
- package/apps/studio/test/exporters/png.test.ts +0 -103
- package/apps/studio/test/exporters/pptx-deck.test.ts +0 -112
- package/apps/studio/test/exporters/pptx.test.ts +0 -31
- package/apps/studio/test/exporters/pw-launch.test.ts +0 -49
- package/apps/studio/test/exporters/runtime.test.ts +0 -59
- package/apps/studio/test/exporters/scope.test.ts +0 -292
- package/apps/studio/test/exporters/svg.test.ts +0 -29
- package/apps/studio/test/exporters/unsupported-media.test.ts +0 -123
- package/apps/studio/test/exporters/zip.test.ts +0 -104
- package/apps/studio/test/fetch-asset-gate.test.ts +0 -189
- package/apps/studio/test/figjam-v3-model.test.ts +0 -342
- package/apps/studio/test/figma-explode.test.ts +0 -438
- package/apps/studio/test/figma-provenance.test.ts +0 -108
- package/apps/studio/test/figma-routes.test.ts +0 -294
- package/apps/studio/test/file-lock.test.ts +0 -84
- package/apps/studio/test/fixtures/fake-claude-auth.mjs +0 -13
- package/apps/studio/test/fixtures/figjam-v3-groups-bindings.svg +0 -1
- package/apps/studio/test/fixtures/mock-acp-agent-caps.mjs +0 -158
- package/apps/studio/test/fixtures/mock-acp-agent-commands.mjs +0 -44
- package/apps/studio/test/fixtures/mock-acp-agent-elicit-flood.mjs +0 -46
- package/apps/studio/test/fixtures/mock-acp-agent-elicit-url.mjs +0 -42
- package/apps/studio/test/fixtures/mock-acp-agent-elicit.mjs +0 -63
- package/apps/studio/test/fixtures/mock-acp-agent-permission-flood.mjs +0 -51
- package/apps/studio/test/fixtures/mock-acp-agent-permission.mjs +0 -50
- package/apps/studio/test/fixtures/mock-acp-agent-slow.mjs +0 -45
- package/apps/studio/test/fixtures/mock-acp-agent-usage.mjs +0 -56
- package/apps/studio/test/fixtures/mock-acp-agent-wedged.mjs +0 -37
- package/apps/studio/test/fixtures/mock-acp-agent-write.mjs +0 -118
- package/apps/studio/test/fixtures/mock-acp-agent.mjs +0 -69
- package/apps/studio/test/fixtures/perf-canvas.mjs +0 -201
- package/apps/studio/test/fixtures/phase-20-annotations.svg +0 -1
- package/apps/studio/test/fixtures/phase-21-annotations.svg +0 -1
- package/apps/studio/test/fixtures/tiny-subset.woff2 +0 -0
- package/apps/studio/test/fixtures/video-comp-fixture.tsx +0 -82
- package/apps/studio/test/footage-store.test.ts +0 -100
- package/apps/studio/test/fs-mkdir-api.test.ts +0 -248
- package/apps/studio/test/fs-watch.test.ts +0 -41
- package/apps/studio/test/gemma-models.test.ts +0 -245
- package/apps/studio/test/generate-route.test.ts +0 -106
- package/apps/studio/test/git-api.test.ts +0 -0
- package/apps/studio/test/git-branches.test.ts +0 -341
- package/apps/studio/test/git-cloud-posture.test.ts +0 -59
- package/apps/studio/test/git-grouping.test.ts +0 -106
- package/apps/studio/test/git-lifecycle.test.ts +0 -100
- package/apps/studio/test/git-log-format.test.ts +0 -95
- package/apps/studio/test/git-safe-rel.test.ts +0 -132
- package/apps/studio/test/git-system-engine.test.ts +0 -135
- package/apps/studio/test/git-watch.test.ts +0 -97
- package/apps/studio/test/github-api.test.ts +0 -577
- package/apps/studio/test/grid-track-handles.test.ts +0 -160
- package/apps/studio/test/handoff-static-frames.test.ts +0 -215
- package/apps/studio/test/handoff.test.ts +0 -329
- package/apps/studio/test/history-rollback.test.ts +0 -88
- package/apps/studio/test/hmr-broadcast.test.ts +0 -236
- package/apps/studio/test/hmr-classify.test.ts +0 -87
- package/apps/studio/test/hub-link.test.ts +0 -80
- package/apps/studio/test/identity-cache.test.ts +0 -83
- package/apps/studio/test/import-asset-browser.test.ts +0 -64
- package/apps/studio/test/import-asset-route.test.ts +0 -71
- package/apps/studio/test/import-asset.test.ts +0 -427
- package/apps/studio/test/import-brand-browser.test.ts +0 -88
- package/apps/studio/test/import-brand-route.test.ts +0 -120
- package/apps/studio/test/import-brand.test.ts +0 -206
- package/apps/studio/test/import-figma.test.ts +0 -667
- package/apps/studio/test/import-tokens.test.ts +0 -722
- package/apps/studio/test/index-data-canvas-ds.test.ts +0 -97
- package/apps/studio/test/input-router.test.ts +0 -757
- package/apps/studio/test/inspect-script-syntax.test.ts +0 -53
- package/apps/studio/test/inspect-selections.test.ts +0 -219
- package/apps/studio/test/knob-props-authored.test.ts +0 -87
- package/apps/studio/test/layers-synthetic-groups.test.ts +0 -96
- package/apps/studio/test/locator.test.ts +0 -214
- package/apps/studio/test/marquee-overlay.test.ts +0 -94
- package/apps/studio/test/media-commit-chain.test.ts +0 -210
- package/apps/studio/test/mode-toggle.test.tsx +0 -226
- package/apps/studio/test/motion-sample.test.ts +0 -35
- package/apps/studio/test/move-artboards-command.test.ts +0 -108
- package/apps/studio/test/participants-chrome.test.ts +0 -65
- package/apps/studio/test/paths.test.ts +0 -88
- package/apps/studio/test/pdf-print-boxes.test.ts +0 -359
- package/apps/studio/test/peer-selection-follows-camera.test.tsx +0 -131
- package/apps/studio/test/perf-harness.ts +0 -193
- package/apps/studio/test/phase-3.6-smoke.test.ts +0 -79
- package/apps/studio/test/photo-bg-remove-validation.test.ts +0 -71
- package/apps/studio/test/photo-canvas-bundle.test.ts +0 -79
- package/apps/studio/test/photo-edit-api.test.ts +0 -201
- package/apps/studio/test/photo-filters.test.ts +0 -149
- package/apps/studio/test/photo-pipeline.test.ts +0 -106
- package/apps/studio/test/photo-taxonomy.test.ts +0 -96
- package/apps/studio/test/print-marks.test.ts +0 -113
- package/apps/studio/test/print-units.test.ts +0 -173
- package/apps/studio/test/read-annotations.test.ts +0 -727
- package/apps/studio/test/read-only-gate.test.ts +0 -188
- package/apps/studio/test/read-only-role.test.ts +0 -95
- package/apps/studio/test/readiness.test.ts +0 -226
- package/apps/studio/test/remote-ahead-behind-cache.test.ts +0 -89
- package/apps/studio/test/reorder-api.test.ts +0 -210
- package/apps/studio/test/repo-concurrency.test.ts +0 -146
- package/apps/studio/test/repo-lock.test.ts +0 -350
- package/apps/studio/test/report-proxy.test.ts +0 -125
- package/apps/studio/test/ripple.test.ts +0 -197
- package/apps/studio/test/runtime-bundle-error-mapping.test.ts +0 -43
- package/apps/studio/test/runtime-bundle.test.ts +0 -69
- package/apps/studio/test/sanitize-annotation-svg.test.ts +0 -238
- package/apps/studio/test/scaffold-design.test.ts +0 -122
- package/apps/studio/test/server-lifecycle.test.ts +0 -38
- package/apps/studio/test/session-runtime-state.test.ts +0 -226
- package/apps/studio/test/session-scope.test.ts +0 -100
- package/apps/studio/test/shared-doc-cell-pairing.test.ts +0 -642
- package/apps/studio/test/shared-doc-convergence.test.ts +0 -265
- package/apps/studio/test/shared-doc-foundation.test.ts +0 -63
- package/apps/studio/test/shared-doc-migrate.test.ts +0 -369
- package/apps/studio/test/shared-doc-projection.test.ts +0 -238
- package/apps/studio/test/shell-importmap.test.ts +0 -56
- package/apps/studio/test/sizing-mode.test.ts +0 -102
- package/apps/studio/test/slash-commands.test.ts +0 -117
- package/apps/studio/test/snap-distance-pill.test.ts +0 -68
- package/apps/studio/test/spacing-handles.test.ts +0 -138
- package/apps/studio/test/specimen-select.test.ts +0 -88
- package/apps/studio/test/sync-agent.test.ts +0 -660
- package/apps/studio/test/sync-annotations-cold-start.test.ts +0 -302
- package/apps/studio/test/sync-asset-push.test.ts +0 -931
- package/apps/studio/test/sync-atomic-write.test.ts +0 -62
- package/apps/studio/test/sync-attach-incremental.test.ts +0 -527
- package/apps/studio/test/sync-autocommit.test.ts +0 -537
- package/apps/studio/test/sync-canvas-path.test.ts +0 -200
- package/apps/studio/test/sync-cell-write-nudge.test.ts +0 -346
- package/apps/studio/test/sync-codec.test.ts +0 -230
- package/apps/studio/test/sync-cold-seed-dedup.test.ts +0 -187
- package/apps/studio/test/sync-cold-start.test.ts +0 -304
- package/apps/studio/test/sync-connect-honesty.test.ts +0 -114
- package/apps/studio/test/sync-connection-state.test.ts +0 -337
- package/apps/studio/test/sync-ctl-channel.test.ts +0 -508
- package/apps/studio/test/sync-decide-file.test.ts +0 -420
- package/apps/studio/test/sync-doc-name.test.ts +0 -281
- package/apps/studio/test/sync-echo-guard.test.ts +0 -96
- package/apps/studio/test/sync-file-ledger.test.ts +0 -334
- package/apps/studio/test/sync-file-membership.test.ts +0 -347
- package/apps/studio/test/sync-file-plane.test.ts +0 -976
- package/apps/studio/test/sync-file-pull.test.ts +0 -333
- package/apps/studio/test/sync-fresh-link-parity.test.ts +0 -267
- package/apps/studio/test/sync-fs-mirror.test.ts +0 -181
- package/apps/studio/test/sync-hardening.test.ts +0 -586
- package/apps/studio/test/sync-hub-listing.test.ts +0 -46
- package/apps/studio/test/sync-hubs-config.test.ts +0 -133
- package/apps/studio/test/sync-incident-replay.test.ts +0 -211
- package/apps/studio/test/sync-journal.test.ts +0 -176
- package/apps/studio/test/sync-meta-codec.test.ts +0 -199
- package/apps/studio/test/sync-migrate-flat-fallback.test.ts +0 -98
- package/apps/studio/test/sync-move-retirement.test.ts +0 -231
- package/apps/studio/test/sync-panel-surface.test.ts +0 -153
- package/apps/studio/test/sync-path-pull.test.ts +0 -531
- package/apps/studio/test/sync-presentation.test.ts +0 -262
- package/apps/studio/test/sync-pull-budget.test.ts +0 -169
- package/apps/studio/test/sync-remote-docs.test.ts +0 -333
- package/apps/studio/test/sync-resync-routes.test.ts +0 -168
- package/apps/studio/test/sync-runtime.test.ts +0 -1675
- package/apps/studio/test/sync-seed-defers-to-hub.test.ts +0 -83
- package/apps/studio/test/sync-settings-routes.test.ts +0 -195
- package/apps/studio/test/sync-settings.test.ts +0 -151
- package/apps/studio/test/sync-status.test.ts +0 -261
- package/apps/studio/test/sync-supervisor.test.ts +0 -262
- package/apps/studio/test/sync-tombstone-apply.test.ts +0 -111
- package/apps/studio/test/sync-trash.test.ts +0 -132
- package/apps/studio/test/sync-two-peer-discovery.test.ts +0 -343
- package/apps/studio/test/sync-untrusted.test.ts +0 -103
- package/apps/studio/test/system-endpoint.test.ts +0 -144
- package/apps/studio/test/text-editability-stamp.test.ts +0 -131
- package/apps/studio/test/timeline-comp-target.test.ts +0 -139
- package/apps/studio/test/timeline-media-cache.test.ts +0 -41
- package/apps/studio/test/timeline-parse.test.ts +0 -184
- package/apps/studio/test/timeline-scale.test.ts +0 -65
- package/apps/studio/test/timeline-snap.test.ts +0 -85
- package/apps/studio/test/tool-palette-insert-anchor.test.ts +0 -86
- package/apps/studio/test/tool-palette.test.tsx +0 -55
- package/apps/studio/test/tour-overlay.test.tsx +0 -90
- package/apps/studio/test/trusted-request-host.test.ts +0 -66
- package/apps/studio/test/undo-sequence-byte-compare.test.ts +0 -211
- package/apps/studio/test/undo-stack.test.ts +0 -244
- package/apps/studio/test/use-agent-presence.test.tsx +0 -117
- package/apps/studio/test/use-annotation-resize.test.ts +0 -402
- package/apps/studio/test/use-annotation-selection.test.tsx +0 -77
- package/apps/studio/test/use-artboard-drag.test.ts +0 -324
- package/apps/studio/test/use-canvas-activity.test.tsx +0 -206
- package/apps/studio/test/use-collab.test.ts +0 -0
- package/apps/studio/test/use-cursor-modifiers.test.ts +0 -59
- package/apps/studio/test/use-keyboard-discipline.test.ts +0 -27
- package/apps/studio/test/use-selection-set.test.tsx +0 -166
- package/apps/studio/test/use-snap-guides.test.ts +0 -271
- package/apps/studio/test/use-tool-mode.test.tsx +0 -186
- package/apps/studio/test/use-undo-stack.test.tsx +0 -223
- package/apps/studio/test/video-asset.test.ts +0 -163
- package/apps/studio/test/video-comp-fixture.test.ts +0 -50
- package/apps/studio/test/video-comp.test.ts +0 -270
- package/apps/studio/test/video-encode-lib.test.ts +0 -63
- package/apps/studio/test/video-render-bridge.test.ts +0 -171
- package/apps/studio/test/whats-new.test.ts +0 -113
- package/apps/studio/test/whisper-setup.test.ts +0 -97
- package/apps/studio/test/workspace-containment.test.ts +0 -382
- package/apps/studio/test/workspace-signin.test.ts +0 -292
- package/apps/studio/test/ws-handshake.test.ts +0 -33
- package/cli/commands/cache.test.mjs +0 -166
- package/cli/commands/design-link.test.mjs +0 -419
- package/cli/commands/design.test.mjs +0 -240
- package/cli/commands/doctor.test.mjs +0 -237
- package/cli/commands/hub-workspace.test.mjs +0 -275
- package/cli/commands/hub.test.mjs +0 -225
- package/cli/commands/kg.test.mjs +0 -142
- package/cli/commands/preflight.test.mjs +0 -46
- package/cli/lib/argv.test.mjs +0 -46
- package/cli/lib/cache.test.mjs +0 -303
- package/cli/lib/cell-plan.test.mjs +0 -225
- package/cli/lib/config-lint.test.mjs +0 -117
- package/cli/lib/ddr-to-kgai.test.mjs +0 -118
- package/cli/lib/design-ownership.test.mjs +0 -329
- package/cli/lib/fetch-asset.test.mjs +0 -213
- package/cli/lib/figma-codegen-reachability.test.mjs +0 -104
- package/cli/lib/figma-import-controls.test.mjs +0 -70
- package/cli/lib/flow-design-integration.test.mjs +0 -165
- package/cli/lib/gitignore-block.test.mjs +0 -136
- package/cli/lib/gitignore-drift.test.mjs +0 -156
- package/cli/lib/hubs-config.test.mjs +0 -165
- package/cli/lib/pkg-root.test.mjs +0 -111
- package/cli/lib/plugin-cli-reachability.test.mjs +0 -57
- package/cli/lib/plugin-name-namespace.test.mjs +0 -71
- package/cli/lib/reconstruct-toolset.test.mjs +0 -194
- package/cli/lib/stack-detect.test.mjs +0 -121
- package/cli/lib/update-check.test.mjs +0 -32
- package/cli/lib/workspace-plan.test.mjs +0 -699
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
// camera-reveal — Task A3 (feature-element-editing-robustness), Stage A.
|
|
2
|
-
//
|
|
3
|
-
// Regression guard for Bugs A + B: a `select-by-id` reveal must pan the camera
|
|
4
|
-
// (the `.dc-world` transform, via the viewport controller) and MUST NOT scroll
|
|
5
|
-
// the overflow:hidden `.dc-canvas` / `.dc-artboard-body` clip layers — host
|
|
6
|
-
// scroll is what desynced the camera model (phantom right strip + pan reset
|
|
7
|
-
// after an absolute-element move).
|
|
8
|
-
//
|
|
9
|
-
// canvas-shell.tsx pulls in a React/DOM dependency graph, so we register
|
|
10
|
-
// happy-dom for this file (like canvas-hmr-runtime.test.tsx) before importing.
|
|
11
|
-
|
|
12
|
-
import { afterAll, beforeAll, describe, expect, test } from 'bun:test';
|
|
13
|
-
import { GlobalRegistrator } from '@happy-dom/global-registrator';
|
|
14
|
-
|
|
15
|
-
beforeAll(() => {
|
|
16
|
-
GlobalRegistrator.register();
|
|
17
|
-
});
|
|
18
|
-
afterAll(() => {
|
|
19
|
-
GlobalRegistrator.unregister();
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
import type { ViewportControllerHandle } from '../canvas-lib.tsx';
|
|
23
|
-
import { REVEAL_MARGIN_PX, revealAxisDelta, revealElementViaCamera } from '../canvas-shell.tsx';
|
|
24
|
-
|
|
25
|
-
const M = REVEAL_MARGIN_PX;
|
|
26
|
-
|
|
27
|
-
describe('revealAxisDelta — minimal 1-axis camera pan', () => {
|
|
28
|
-
// Viewport spans [0, 1000]; usable band is [M, 1000 - M].
|
|
29
|
-
const V0 = 0;
|
|
30
|
-
const V1 = 1000;
|
|
31
|
-
|
|
32
|
-
test('fully visible → no pan', () => {
|
|
33
|
-
expect(revealAxisDelta(200, 400, V0, V1, M)).toBe(0);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
test('flush at the inset band edges → no pan', () => {
|
|
37
|
-
expect(revealAxisDelta(M, V1 - M, V0, V1, M)).toBe(0);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
test('off the start (left/top) edge → positive delta brings the start in', () => {
|
|
41
|
-
// element [-50, 100]; start (-50) is left of the inset band start (M=40).
|
|
42
|
-
const d = revealAxisDelta(-50, 100, V0, V1, M);
|
|
43
|
-
expect(d).toBe(M - -50); // vs - elStart = 40 - (-50) = 90
|
|
44
|
-
expect(d).toBeGreaterThan(0);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
test('off the end (right/bottom) edge → negative delta brings the end in', () => {
|
|
48
|
-
// element [900, 1100]; end (1100) is past the inset band end (960).
|
|
49
|
-
const d = revealAxisDelta(900, 1100, V0, V1, M);
|
|
50
|
-
expect(d).toBe(V1 - M - 1100); // ve - elEnd = 960 - 1100 = -140
|
|
51
|
-
expect(d).toBeLessThan(0);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
test('element wider than the viewport → no pan (matches scrollIntoView nearest)', () => {
|
|
55
|
-
expect(revealAxisDelta(-200, 1200, V0, V1, M)).toBe(0);
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
// Minimal fake controller — only `panBy` is exercised; the rest satisfy the type.
|
|
60
|
-
function fakeController(): {
|
|
61
|
-
handle: ViewportControllerHandle;
|
|
62
|
-
calls: Array<[number, number]>;
|
|
63
|
-
} {
|
|
64
|
-
const calls: Array<[number, number]> = [];
|
|
65
|
-
const noop = () => {};
|
|
66
|
-
const handle: ViewportControllerHandle = {
|
|
67
|
-
viewport: { x: 0, y: 0, zoom: 1 },
|
|
68
|
-
setViewport: noop,
|
|
69
|
-
panBy: (dx, dy) => calls.push([dx, dy]),
|
|
70
|
-
zoomAt: noop,
|
|
71
|
-
fit: noop,
|
|
72
|
-
reset: noop,
|
|
73
|
-
zoomIn: noop,
|
|
74
|
-
zoomOut: noop,
|
|
75
|
-
jumpTo: noop,
|
|
76
|
-
animateTo: noop,
|
|
77
|
-
isInteracting: false,
|
|
78
|
-
};
|
|
79
|
-
return { handle, calls };
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function elWithRect(rect: Partial<DOMRect>): HTMLElement {
|
|
83
|
-
const el = document.createElement('div');
|
|
84
|
-
const r = {
|
|
85
|
-
left: 0,
|
|
86
|
-
top: 0,
|
|
87
|
-
right: 0,
|
|
88
|
-
bottom: 0,
|
|
89
|
-
width: 0,
|
|
90
|
-
height: 0,
|
|
91
|
-
x: 0,
|
|
92
|
-
y: 0,
|
|
93
|
-
...rect,
|
|
94
|
-
} as DOMRect;
|
|
95
|
-
el.getBoundingClientRect = () => r;
|
|
96
|
-
return el;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
describe('revealElementViaCamera — pans the controller, never host scroll', () => {
|
|
100
|
-
test('off-screen element pans via panBy and leaves host scroll at 0', () => {
|
|
101
|
-
const host = elWithRect({
|
|
102
|
-
left: 0,
|
|
103
|
-
top: 0,
|
|
104
|
-
right: 1000,
|
|
105
|
-
bottom: 800,
|
|
106
|
-
width: 1000,
|
|
107
|
-
height: 800,
|
|
108
|
-
});
|
|
109
|
-
// Target sits past the right edge — the exact Bug B repro (overflowing element).
|
|
110
|
-
const target = elWithRect({
|
|
111
|
-
left: 1100,
|
|
112
|
-
top: 100,
|
|
113
|
-
right: 1300,
|
|
114
|
-
bottom: 200,
|
|
115
|
-
width: 200,
|
|
116
|
-
height: 100,
|
|
117
|
-
});
|
|
118
|
-
const { handle, calls } = fakeController();
|
|
119
|
-
|
|
120
|
-
revealElementViaCamera(host, target, handle);
|
|
121
|
-
|
|
122
|
-
expect(calls.length).toBe(1);
|
|
123
|
-
const [dx, dy] = calls[0];
|
|
124
|
-
expect(dx).toBeLessThan(0); // pan world left to reveal the right-side element
|
|
125
|
-
expect(dy).toBe(0); // vertically already in view
|
|
126
|
-
// The invariant: no host scroll was touched.
|
|
127
|
-
expect(host.scrollLeft).toBe(0);
|
|
128
|
-
expect(host.scrollTop).toBe(0);
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
test('already-visible element → no pan at all', () => {
|
|
132
|
-
const host = elWithRect({
|
|
133
|
-
left: 0,
|
|
134
|
-
top: 0,
|
|
135
|
-
right: 1000,
|
|
136
|
-
bottom: 800,
|
|
137
|
-
width: 1000,
|
|
138
|
-
height: 800,
|
|
139
|
-
});
|
|
140
|
-
const target = elWithRect({
|
|
141
|
-
left: 300,
|
|
142
|
-
top: 300,
|
|
143
|
-
right: 500,
|
|
144
|
-
bottom: 400,
|
|
145
|
-
width: 200,
|
|
146
|
-
height: 100,
|
|
147
|
-
});
|
|
148
|
-
const { handle, calls } = fakeController();
|
|
149
|
-
|
|
150
|
-
revealElementViaCamera(host, target, handle);
|
|
151
|
-
|
|
152
|
-
expect(calls.length).toBe(0);
|
|
153
|
-
expect(host.scrollLeft).toBe(0);
|
|
154
|
-
expect(host.scrollTop).toBe(0);
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
test('detached element (zero box) → no pan', () => {
|
|
158
|
-
const host = elWithRect({
|
|
159
|
-
left: 0,
|
|
160
|
-
top: 0,
|
|
161
|
-
right: 1000,
|
|
162
|
-
bottom: 800,
|
|
163
|
-
width: 1000,
|
|
164
|
-
height: 800,
|
|
165
|
-
});
|
|
166
|
-
const target = elWithRect({});
|
|
167
|
-
const { handle, calls } = fakeController();
|
|
168
|
-
|
|
169
|
-
revealElementViaCamera(host, target, handle);
|
|
170
|
-
|
|
171
|
-
expect(calls.length).toBe(0);
|
|
172
|
-
});
|
|
173
|
-
});
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
// canvas-artifacts.ts — the canonical artifact inventory. Pure, no server boot
|
|
2
|
-
// needed: cover inventory completeness, the divergent `_locator.json` slug
|
|
3
|
-
// shape, and relocatedName()'s path math for both a pure directory move and a
|
|
4
|
-
// combined move+rename.
|
|
5
|
-
|
|
6
|
-
import { describe, expect, test } from 'bun:test';
|
|
7
|
-
import path from 'node:path';
|
|
8
|
-
|
|
9
|
-
import { canvasArtifacts, locatorKeyFor, relocatedName } from '../canvas-artifacts.ts';
|
|
10
|
-
import type { Paths } from '../context.ts';
|
|
11
|
-
|
|
12
|
-
function fakePaths(repoRoot: string): Paths {
|
|
13
|
-
const designRoot = path.join(repoRoot, '.design');
|
|
14
|
-
return {
|
|
15
|
-
repoRoot,
|
|
16
|
-
designRel: '.design',
|
|
17
|
-
designRoot,
|
|
18
|
-
serverInfoFile: path.join(designRoot, '_server.json'),
|
|
19
|
-
activeFile: path.join(designRoot, '_active.json'),
|
|
20
|
-
commentsDir: path.join(designRoot, '_comments'),
|
|
21
|
-
canvasStateDir: path.join(designRoot, '_canvas-state'),
|
|
22
|
-
historyDir: path.join(designRoot, '_history'),
|
|
23
|
-
tokensUrlRel: '.design/system/colors_and_type.css',
|
|
24
|
-
systemDirRel: 'system',
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
describe('canvasArtifacts', () => {
|
|
29
|
-
const paths = fakePaths('/repo');
|
|
30
|
-
|
|
31
|
-
test('lists the primary + siblings + every slug-keyed sidecar', () => {
|
|
32
|
-
const artifacts = canvasArtifacts({ rel: 'ui/Foo.tsx', paths });
|
|
33
|
-
const abs = artifacts.map((a) => a.abs);
|
|
34
|
-
expect(abs).toContain(path.join(paths.designRoot, 'ui', 'Foo.tsx'));
|
|
35
|
-
expect(abs).toContain(path.join(paths.designRoot, 'ui', 'Foo.meta.json'));
|
|
36
|
-
expect(abs).toContain(path.join(paths.designRoot, 'ui', 'Foo.css'));
|
|
37
|
-
expect(abs).toContain(path.join(paths.designRoot, 'ui', 'Foo.registry.json'));
|
|
38
|
-
const slug = 'ui-foo';
|
|
39
|
-
expect(abs).toContain(path.join(paths.historyDir, slug));
|
|
40
|
-
expect(abs).toContain(path.join(paths.canvasStateDir, `${slug}.json`));
|
|
41
|
-
expect(abs).toContain(path.join(paths.canvasStateDir, `${slug}.view.json`));
|
|
42
|
-
expect(abs).toContain(path.join(paths.commentsDir, `${slug}.json`));
|
|
43
|
-
expect(abs).toContain(path.join(paths.designRoot, '_state', `${slug}.ydoc.bin`));
|
|
44
|
-
expect(abs).toContain(path.join(paths.designRoot, `${slug}.annotations.svg`));
|
|
45
|
-
expect(abs).toContain(path.join(paths.designRoot, `${slug}.edl.json`));
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
test('does NOT include _photo/ or _draw/ (asset-keyed / mark-slug-keyed, not canvas-slug-keyed)', () => {
|
|
49
|
-
const abs = canvasArtifacts({ rel: 'ui/Foo.tsx', paths }).map((a) => a.abs);
|
|
50
|
-
expect(abs.some((p) => p.includes('_photo'))).toBe(false);
|
|
51
|
-
expect(abs.some((p) => p.includes('_draw'))).toBe(false);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
test('marks exactly one primary and the rest sibling/slug-keyed', () => {
|
|
55
|
-
const artifacts = canvasArtifacts({ rel: 'ui/Foo.tsx', paths });
|
|
56
|
-
const primaries = artifacts.filter((a) => a.kind === 'primary');
|
|
57
|
-
expect(primaries.length).toBe(1);
|
|
58
|
-
expect(primaries[0]?.abs).toBe(path.join(paths.designRoot, 'ui', 'Foo.tsx'));
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
test('handles a nested rel (subfolder)', () => {
|
|
62
|
-
const artifacts = canvasArtifacts({ rel: 'ui/sub/Bar.tsx', paths });
|
|
63
|
-
const primary = artifacts.find((a) => a.kind === 'primary');
|
|
64
|
-
expect(primary?.abs).toBe(path.join(paths.designRoot, 'ui', 'sub', 'Bar.tsx'));
|
|
65
|
-
const slug = 'ui-sub-bar';
|
|
66
|
-
expect(artifacts.some((a) => a.abs === path.join(paths.historyDir, slug))).toBe(true);
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
describe('locatorKeyFor — the DIVERGENT slug shape', () => {
|
|
71
|
-
test('posix, extension-less, NOT lowercased or dash-flattened', () => {
|
|
72
|
-
expect(locatorKeyFor('ui/Onboarding Brief.tsx')).toBe('ui/Onboarding Brief');
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
test('differs from canvasSlugFromRel for a mixed-case / spaced name', () => {
|
|
76
|
-
// canvasSlugFromRel('ui/Onboarding Brief.tsx', ...) => 'ui-onboarding_brief'
|
|
77
|
-
expect(locatorKeyFor('ui/Onboarding Brief.tsx')).not.toBe('ui-onboarding_brief');
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
describe('relocatedName', () => {
|
|
82
|
-
const paths = fakePaths('/repo');
|
|
83
|
-
|
|
84
|
-
test('pure directory move (basename unchanged) — siblings track the new dir', () => {
|
|
85
|
-
const artifacts = canvasArtifacts({ rel: 'ui/Foo.tsx', paths });
|
|
86
|
-
const primary = artifacts.find((a) => a.kind === 'primary');
|
|
87
|
-
if (!primary) throw new Error('no primary');
|
|
88
|
-
expect(relocatedName(primary, 'ui/Foo.tsx', 'ui/sub/Foo.tsx', paths)).toBe(
|
|
89
|
-
path.join(paths.designRoot, 'ui', 'sub', 'Foo.tsx')
|
|
90
|
-
);
|
|
91
|
-
const meta = artifacts.find((a) => a.abs.endsWith('Foo.meta.json'));
|
|
92
|
-
if (!meta) throw new Error('no meta sibling');
|
|
93
|
-
expect(relocatedName(meta, 'ui/Foo.tsx', 'ui/sub/Foo.tsx', paths)).toBe(
|
|
94
|
-
path.join(paths.designRoot, 'ui', 'sub', 'Foo.meta.json')
|
|
95
|
-
);
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
test('slug-keyed sidecars stay in their fixed dir but re-key the filename', () => {
|
|
99
|
-
const artifacts = canvasArtifacts({ rel: 'ui/Foo.tsx', paths });
|
|
100
|
-
const history = artifacts.find((a) => a.abs === path.join(paths.historyDir, 'ui-foo'));
|
|
101
|
-
if (!history) throw new Error('no history artifact');
|
|
102
|
-
expect(relocatedName(history, 'ui/Foo.tsx', 'ui/sub/Foo.tsx', paths)).toBe(
|
|
103
|
-
path.join(paths.historyDir, 'ui-sub-foo')
|
|
104
|
-
);
|
|
105
|
-
const view = artifacts.find((a) => a.abs.endsWith('ui-foo.view.json'));
|
|
106
|
-
if (!view) throw new Error('no view artifact');
|
|
107
|
-
expect(relocatedName(view, 'ui/Foo.tsx', 'ui/sub/Foo.tsx', paths)).toBe(
|
|
108
|
-
path.join(paths.canvasStateDir, 'ui-sub-foo.view.json')
|
|
109
|
-
);
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
test('a rename (same dir, new basename) re-keys both the sibling and the slug-keyed sidecar', () => {
|
|
113
|
-
const artifacts = canvasArtifacts({ rel: 'ui/Foo.tsx', paths });
|
|
114
|
-
const primary = artifacts.find((a) => a.kind === 'primary');
|
|
115
|
-
if (!primary) throw new Error('no primary');
|
|
116
|
-
expect(relocatedName(primary, 'ui/Foo.tsx', 'ui/Bar.tsx', paths)).toBe(
|
|
117
|
-
path.join(paths.designRoot, 'ui', 'Bar.tsx')
|
|
118
|
-
);
|
|
119
|
-
const comments = artifacts.find((a) => a.abs === path.join(paths.commentsDir, 'ui-foo.json'));
|
|
120
|
-
if (!comments) throw new Error('no comments artifact');
|
|
121
|
-
expect(relocatedName(comments, 'ui/Foo.tsx', 'ui/Bar.tsx', paths)).toBe(
|
|
122
|
-
path.join(paths.commentsDir, 'ui-bar.json')
|
|
123
|
-
);
|
|
124
|
-
});
|
|
125
|
-
});
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
// Cloud Phase 27 — the sandbox child's environment.
|
|
2
|
-
//
|
|
3
|
-
// Diagnosed against a real cell: the canvas module 422'd with "Cannot find
|
|
4
|
-
// native binding" while running the identical worker command by hand with a
|
|
5
|
-
// clean environment worked. The difference was one inherited variable.
|
|
6
|
-
|
|
7
|
-
import { describe, expect, test } from 'bun:test';
|
|
8
|
-
|
|
9
|
-
import { workerEnv } from '../canvas-build-sandbox.ts';
|
|
10
|
-
|
|
11
|
-
describe('workerEnv', () => {
|
|
12
|
-
test('a compiled binary’s VIRTUAL binding path is not handed to a child', () => {
|
|
13
|
-
const env = workerEnv({
|
|
14
|
-
PATH: '/bin',
|
|
15
|
-
NAPI_RS_NATIVE_LIBRARY_PATH: '/$bunfs/root/parser.linux-arm64-gnu.node',
|
|
16
|
-
} as NodeJS.ProcessEnv);
|
|
17
|
-
expect(env.NAPI_RS_NATIVE_LIBRARY_PATH).toBeUndefined();
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
test('a REAL binding path still is', () => {
|
|
21
|
-
const env = workerEnv({
|
|
22
|
-
PATH: '/bin',
|
|
23
|
-
NAPI_RS_NATIVE_LIBRARY_PATH: '/maude/node_modules/@oxc-parser/binding-linux-arm64-gnu',
|
|
24
|
-
} as NodeJS.ProcessEnv);
|
|
25
|
-
expect(env.NAPI_RS_NATIVE_LIBRARY_PATH).toBe(
|
|
26
|
-
'/maude/node_modules/@oxc-parser/binding-linux-arm64-gnu'
|
|
27
|
-
);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
test('the child environment carries no secret — it parses tenant source', () => {
|
|
31
|
-
const env = workerEnv({
|
|
32
|
-
PATH: '/bin',
|
|
33
|
-
HUB_SECRET: 'nope',
|
|
34
|
-
AWS_SECRET_ACCESS_KEY: 'also-nope',
|
|
35
|
-
MAUDE_PROJECT_TOKEN_KEY: 'definitely-nope',
|
|
36
|
-
} as NodeJS.ProcessEnv);
|
|
37
|
-
expect(env.HUB_SECRET).toBeUndefined();
|
|
38
|
-
expect(env.AWS_SECRET_ACCESS_KEY).toBeUndefined();
|
|
39
|
-
expect(env.MAUDE_PROJECT_TOKEN_KEY).toBeUndefined();
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
// Cloud Phase 27 B2 — content-addressed media is immutable; everything else
|
|
44
|
-
// revalidates. `no-store` is right on a laptop and is a re-download of every
|
|
45
|
-
// photograph on every pan over the internet.
|
|
46
|
-
import { cacheControlFor } from '../http.ts';
|
|
47
|
-
|
|
48
|
-
describe('cacheControlFor', () => {
|
|
49
|
-
test('a content-addressed name is immutable — the name IS the content', () => {
|
|
50
|
-
for (const p of ['/x/assets/deadbeef.png', '/a/b/0123456789abcdef.mp4']) {
|
|
51
|
-
expect(cacheControlFor(p).cacheControl).toBe('public, max-age=31536000, immutable');
|
|
52
|
-
expect(cacheControlFor(p).addEtag).toBe(false);
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
test('an AUTHORED name revalidates — a designer edits hero.png in place', () => {
|
|
57
|
-
for (const p of ['/x/assets/hero.png', '/x/system/ds/colors_and_type.css', '/x/logos.svg']) {
|
|
58
|
-
expect(cacheControlFor(p).cacheControl).toBe('no-cache');
|
|
59
|
-
expect(cacheControlFor(p).addEtag).toBe(true);
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
test('a name that merely LOOKS hex-ish is not treated as content-addressed', () => {
|
|
64
|
-
// `deadbee` is 7 chars; `deadbeefs` has a non-hex char. Getting either
|
|
65
|
-
// wrong caches a mutable file for a year.
|
|
66
|
-
expect(cacheControlFor('/x/deadbee.png').cacheControl).toBe('no-cache');
|
|
67
|
-
expect(cacheControlFor('/x/deadbeefs.png').cacheControl).toBe('no-cache');
|
|
68
|
-
});
|
|
69
|
-
});
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
// canvas-build.ts — Phase 3.6 Task 6. Verify the per-canvas Bun.build wrap
|
|
2
|
-
// produces browser-loadable ES modules that:
|
|
3
|
-
// 1. preserve the data-cd-id attributes injected by canvas-pipeline pass 1,
|
|
4
|
-
// 2. import "react" / "react/jsx-dev-runtime" as standard ESM specifiers
|
|
5
|
-
// (browser resolves via importmap to /_canvas-runtime/*.js),
|
|
6
|
-
// 3. expose the default export so _shell.html can mount it.
|
|
7
|
-
|
|
8
|
-
import { describe, expect, test } from 'bun:test';
|
|
9
|
-
|
|
10
|
-
import { buildCanvasModule } from '../canvas-build.ts';
|
|
11
|
-
|
|
12
|
-
// Bun.build resolves the entrypoint against the filesystem (its virtual-loader
|
|
13
|
-
// plugin only kicks in for onLoad, after onResolve has confirmed the path
|
|
14
|
-
// exists). Each test writes its source to a real temp file and points
|
|
15
|
-
// buildCanvasModule at it; the canvas-virtual-source plugin then intercepts
|
|
16
|
-
// the onLoad and feeds the post-pass-1 TSX.
|
|
17
|
-
async function writeTmp(name: string, source: string): Promise<string> {
|
|
18
|
-
const abs = `/tmp/canvas-build-${name}-${Math.random().toString(36).slice(2, 8)}.tsx`;
|
|
19
|
-
await Bun.write(abs, source);
|
|
20
|
-
return abs;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
describe('canvas-build / buildCanvasModule', () => {
|
|
24
|
-
test('preserves data-cd-id from pass 1', async () => {
|
|
25
|
-
const src =
|
|
26
|
-
`import { useState } from "react";\n` +
|
|
27
|
-
'export default function Demo() {\n' +
|
|
28
|
-
' const [n] = useState(0);\n' +
|
|
29
|
-
` return <button className="btn">{n}</button>;\n` +
|
|
30
|
-
'}\n';
|
|
31
|
-
const abs = await writeTmp('cd-id', src);
|
|
32
|
-
const r = await buildCanvasModule(abs, src);
|
|
33
|
-
expect(r.js).toContain('data-cd-id');
|
|
34
|
-
expect(r.js).toContain('className: "btn"');
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
test('emits standard react JSX runtime import (no Bun-internal symbols)', async () => {
|
|
38
|
-
const src = 'export default function X() { return <div />; }\n';
|
|
39
|
-
const abs = await writeTmp('std-jsx', src);
|
|
40
|
-
const r = await buildCanvasModule(abs, src);
|
|
41
|
-
// Production-mode build uses react/jsx-runtime (the dev variant trips a
|
|
42
|
-
// Bun.build rename collision with React's CJS `var React` hoist; see
|
|
43
|
-
// runtime-bundle.ts comment). Accept either runtime name.
|
|
44
|
-
expect(r.js).toMatch(/react\/jsx(-dev)?-runtime/);
|
|
45
|
-
// The pre-3.6 Bun.Transpiler-only path emitted `jsxDEV_<hash>` /
|
|
46
|
-
// `jsx_<hash>`; Bun.build uses the standard name.
|
|
47
|
-
expect(r.js).not.toMatch(/jsxDEV?_[0-9a-z]{6,}/);
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
test('locator + etag mirror the canvas-pipeline result', async () => {
|
|
51
|
-
const src =
|
|
52
|
-
'export default function Y() {\n' + ' return <section><h1>hi</h1></section>;\n' + '}\n';
|
|
53
|
-
const abs = await writeTmp('locator', src);
|
|
54
|
-
const r = await buildCanvasModule(abs, src);
|
|
55
|
-
// section + h1 = 2 JSX elements → 2 locator entries.
|
|
56
|
-
expect(Object.keys(r.locator).length).toBe(2);
|
|
57
|
-
expect(r.etag).toMatch(/^[0-9a-f]+$/);
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
test('externalises react + reactDOM (no inlined copies)', async () => {
|
|
61
|
-
const src = 'export default function Z() { return <span />; }\n';
|
|
62
|
-
const abs = await writeTmp('external', src);
|
|
63
|
-
const r = await buildCanvasModule(abs, src);
|
|
64
|
-
// ReactDOM's package signature; the canvas bundle must NOT contain it,
|
|
65
|
-
// or the runtime singleton invariant breaks (two React copies).
|
|
66
|
-
expect(r.js).not.toContain('ReactCurrentOwner');
|
|
67
|
-
// jsx-runtime stays external too — the canvas should import jsxDEV via
|
|
68
|
-
// a normal specifier, not redefine it.
|
|
69
|
-
expect(r.js).not.toContain('function jsxDEV(');
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
test('exposes a default export', async () => {
|
|
73
|
-
const src = 'export default function Q() { return <i />; }\n';
|
|
74
|
-
const abs = await writeTmp('default', src);
|
|
75
|
-
const r = await buildCanvasModule(abs, src);
|
|
76
|
-
expect(r.js).toMatch(/export\s*\{[\s\S]*default[\s\S]*\}/);
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
// Spike finding M9 (studyfi-design AWS run, 2026-08-20) — the sandbox's import
|
|
81
|
-
// allowlist rejected `data:` URIs. Bundled CSS runs every `url()` through
|
|
82
|
-
// onResolve, and `url("data:image/svg+xml,…")` is the standard idiom for
|
|
83
|
-
// grain, textures and tiny inline icons — it is neither relative nor absolute,
|
|
84
|
-
// so the bare-specifier branch denied it with the npm-packages message. A
|
|
85
|
-
// design system's always-on film-grain took every canvas build down; the
|
|
86
|
-
// sandbox exists to stop NETWORK reads, and a data: URI never makes one.
|
|
87
|
-
describe('canvas-build / sandbox scheme handling (M9)', () => {
|
|
88
|
-
const GRAIN =
|
|
89
|
-
`.grain {\n` +
|
|
90
|
-
` background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise'/%3E%3C/filter%3E%3C/svg%3E");\n` +
|
|
91
|
-
`}\n`;
|
|
92
|
-
|
|
93
|
-
// REALPATH, not `/tmp` — on macOS `/tmp` is a symlink to `/private/tmp`, and
|
|
94
|
-
// Bun reports importers by their real path. A root captured through the
|
|
95
|
-
// symlink never matches, the allowlist silently disarms (returns null → the
|
|
96
|
-
// native resolver), and every "denied" assertion here would be testing
|
|
97
|
-
// nothing. Discovered by this very suite going green for the wrong reason.
|
|
98
|
-
async function tmpProject(): Promise<{ dir: string; abs: string; src: string }> {
|
|
99
|
-
const dir = `/private/tmp/canvas-build-m9-${Math.random().toString(36).slice(2, 8)}`;
|
|
100
|
-
await Bun.write(`${dir}/style.css`, GRAIN);
|
|
101
|
-
const src = `import "./style.css";\nexport default function G() { return <div className="grain" />; }\n`;
|
|
102
|
-
const abs = `${dir}/canvas.tsx`;
|
|
103
|
-
await Bun.write(abs, src);
|
|
104
|
-
return { dir, abs, src };
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
test('a data: URI inside bundled CSS survives the ARMED sandbox', async () => {
|
|
108
|
-
const { dir, abs, src } = await tmpProject();
|
|
109
|
-
const r = await buildCanvasModule(abs, src, { restrictImportsTo: dir });
|
|
110
|
-
expect(r.js).toContain('data:image/svg+xml');
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
test('the sandbox still denies a bare npm specifier — the scheme pass-through is not a hole', async () => {
|
|
114
|
-
const dir = `/private/tmp/canvas-build-m9-deny-${Math.random().toString(36).slice(2, 8)}`;
|
|
115
|
-
const src = `import x from "left-pad";\nexport default function D() { return <i>{x}</i>; }\n`;
|
|
116
|
-
const abs = `${dir}/canvas.tsx`;
|
|
117
|
-
await Bun.write(abs, src);
|
|
118
|
-
await expect(buildCanvasModule(abs, src, { restrictImportsTo: dir })).rejects.toThrow(
|
|
119
|
-
/not available when it renders in a browser/
|
|
120
|
-
);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
test('an http(s) @import is still refused by the armed sandbox — only non-network schemes pass', async () => {
|
|
124
|
-
// The spike's original fontshare failure was exactly this shape: an
|
|
125
|
-
// `@import url(https://…)` is a BUILD-TIME network fetch, so the sandbox
|
|
126
|
-
// must keep refusing it even now that data:/blob: pass. (A plain
|
|
127
|
-
// `url(https://…)` image reference never reaches onResolve — Bun's CSS
|
|
128
|
-
// loader leaves it external for the browser, where the cell CSP owns it.)
|
|
129
|
-
const dir = `/private/tmp/canvas-build-m9-http-${Math.random().toString(36).slice(2, 8)}`;
|
|
130
|
-
await Bun.write(
|
|
131
|
-
`${dir}/style.css`,
|
|
132
|
-
`@import url("https://api.fontshare.com/v2/css?f=x");\n.x { color: red; }\n`
|
|
133
|
-
);
|
|
134
|
-
const src = `import "./style.css";\nexport default function H() { return <div className="x" />; }\n`;
|
|
135
|
-
const abs = `${dir}/canvas.tsx`;
|
|
136
|
-
await Bun.write(abs, src);
|
|
137
|
-
await expect(buildCanvasModule(abs, src, { restrictImportsTo: dir })).rejects.toThrow(
|
|
138
|
-
/not available when it renders in a browser/
|
|
139
|
-
);
|
|
140
|
-
});
|
|
141
|
-
});
|