@1agh/maude 1.0.11 → 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/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/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/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 +72 -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 -545
- 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/backgrounding-claude-auth.sh +0 -12
- package/apps/studio/test/fixtures/fake-claude-auth.mjs +0 -23
- 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/noisy-claude-auth.mjs +0 -27
- 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/fixtures/wedged-claude-auth.sh +0 -11
- 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 -337
- 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,226 +0,0 @@
|
|
|
1
|
-
// Cloud Phase 27 D3, end to end: two members of one cell keep their own place.
|
|
2
|
-
//
|
|
3
|
-
// The unit test next door proves the path helpers; this proves the wiring — a
|
|
4
|
-
// real server in workspace mode, two vouched sessions, and the two files the
|
|
5
|
-
// plan names by hand: `_active.json` (selection, open tabs) and
|
|
6
|
-
// `_canvas-state/<slug>.view.json` (the camera).
|
|
7
|
-
//
|
|
8
|
-
// The last test is the one that must never go red for the desktop: with no
|
|
9
|
-
// session header the server writes exactly the paths it always wrote.
|
|
10
|
-
|
|
11
|
-
import { describe, expect, test } from 'bun:test';
|
|
12
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
13
|
-
import { join } from 'node:path';
|
|
14
|
-
|
|
15
|
-
import { isMaudeRuntimeState } from '../git/service.ts';
|
|
16
|
-
import { bootServer, killProc, makeSandbox, nextPort } from './_helpers.ts';
|
|
17
|
-
|
|
18
|
-
/** The proxy's vouched headers for one member (studio-proxy.mjs injects these). */
|
|
19
|
-
function asMember(session: string, role = 'owner') {
|
|
20
|
-
return {
|
|
21
|
-
'x-maude-session': session,
|
|
22
|
-
'x-maude-role': role,
|
|
23
|
-
'x-maude-readonly': '0',
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const CANVAS = '.design/ui/fixture.html';
|
|
28
|
-
|
|
29
|
-
describe('two members, one cell', () => {
|
|
30
|
-
test('the camera is per member, and the desktop path is untouched', async () => {
|
|
31
|
-
const { root, designRoot } = makeSandbox();
|
|
32
|
-
const port = nextPort();
|
|
33
|
-
const proc = await bootServer(root, port, {
|
|
34
|
-
MAUDE_WORKSPACE_MODE: '1',
|
|
35
|
-
// A dev checkout resolves Playwright, a legitimate devDependency that
|
|
36
|
-
// would otherwise fail the module half of the containment assert before
|
|
37
|
-
// workspace mode could be tested at all.
|
|
38
|
-
MAUDE_WORKSPACE_ALLOW_DEV_MODULES: '1',
|
|
39
|
-
});
|
|
40
|
-
try {
|
|
41
|
-
const base = `http://localhost:${port}`;
|
|
42
|
-
const patch = (session: string | null, zoom: number) =>
|
|
43
|
-
fetch(`${base}/_api/canvas-meta`, {
|
|
44
|
-
method: 'PATCH',
|
|
45
|
-
headers: {
|
|
46
|
-
'content-type': 'application/json',
|
|
47
|
-
...(session ? asMember(session) : {}),
|
|
48
|
-
},
|
|
49
|
-
body: JSON.stringify({
|
|
50
|
-
file: CANVAS,
|
|
51
|
-
patch: { viewport: { x: zoom * 10, y: 0, zoom } },
|
|
52
|
-
}),
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
const alice = await patch('aaaaaaaaaaaaaaaa', 2);
|
|
56
|
-
const bob = await patch('bbbbbbbbbbbbbbbb', 3);
|
|
57
|
-
expect(alice.status).toBe(200);
|
|
58
|
-
expect(bob.status).toBe(200);
|
|
59
|
-
|
|
60
|
-
// Each member's camera is its own FILE — the whole point.
|
|
61
|
-
const aliceView = join(
|
|
62
|
-
designRoot,
|
|
63
|
-
'_canvas-state',
|
|
64
|
-
'aaaaaaaaaaaaaaaa',
|
|
65
|
-
'ui-fixture.view.json'
|
|
66
|
-
);
|
|
67
|
-
const bobView = join(designRoot, '_canvas-state', 'bbbbbbbbbbbbbbbb', 'ui-fixture.view.json');
|
|
68
|
-
expect(existsSync(aliceView)).toBe(true);
|
|
69
|
-
expect(existsSync(bobView)).toBe(true);
|
|
70
|
-
expect((await Bun.file(aliceView).json()).viewport.zoom).toBe(2);
|
|
71
|
-
expect((await Bun.file(bobView).json()).viewport.zoom).toBe(3);
|
|
72
|
-
|
|
73
|
-
// And each reads back their OWN camera, not the last writer's.
|
|
74
|
-
const read = async (session: string) => {
|
|
75
|
-
const r = await fetch(`${base}/_api/canvas-meta?file=${encodeURIComponent(CANVAS)}`, {
|
|
76
|
-
headers: asMember(session),
|
|
77
|
-
});
|
|
78
|
-
return (await r.json()) as { viewport?: { zoom?: number } };
|
|
79
|
-
};
|
|
80
|
-
expect((await read('aaaaaaaaaaaaaaaa')).viewport?.zoom).toBe(2);
|
|
81
|
-
expect((await read('bbbbbbbbbbbbbbbb')).viewport?.zoom).toBe(3);
|
|
82
|
-
} finally {
|
|
83
|
-
await killProc(proc);
|
|
84
|
-
}
|
|
85
|
-
}, 30_000);
|
|
86
|
-
|
|
87
|
-
test('with no session header the camera lands where it always did', async () => {
|
|
88
|
-
// The desktop regression gate. A `_canvas-state/<slug>.view.json` at the
|
|
89
|
-
// top level, no subdirectory, byte-for-byte the pre-D3 layout.
|
|
90
|
-
const { root, designRoot } = makeSandbox();
|
|
91
|
-
const port = nextPort();
|
|
92
|
-
const proc = await bootServer(root, port);
|
|
93
|
-
try {
|
|
94
|
-
const res = await fetch(`http://localhost:${port}/_api/canvas-meta`, {
|
|
95
|
-
method: 'PATCH',
|
|
96
|
-
headers: { 'content-type': 'application/json' },
|
|
97
|
-
body: JSON.stringify({ file: CANVAS, patch: { viewport: { x: 1, y: 2, zoom: 1.5 } } }),
|
|
98
|
-
});
|
|
99
|
-
expect(res.status).toBe(200);
|
|
100
|
-
expect(existsSync(join(designRoot, '_canvas-state', 'ui-fixture.view.json'))).toBe(true);
|
|
101
|
-
} finally {
|
|
102
|
-
await killProc(proc);
|
|
103
|
-
}
|
|
104
|
-
}, 30_000);
|
|
105
|
-
|
|
106
|
-
test('a forged session key cannot escape the canvas-state directory', async () => {
|
|
107
|
-
// The key becomes a path segment, so it is a traversal surface. The proxy
|
|
108
|
-
// strips inbound `x-maude-*` before injecting its own, which is the real
|
|
109
|
-
// defence; this is the second one.
|
|
110
|
-
const { root, designRoot } = makeSandbox();
|
|
111
|
-
const port = nextPort();
|
|
112
|
-
const proc = await bootServer(root, port, {
|
|
113
|
-
MAUDE_WORKSPACE_MODE: '1',
|
|
114
|
-
// A dev checkout resolves Playwright, a legitimate devDependency that
|
|
115
|
-
// would otherwise fail the module half of the containment assert before
|
|
116
|
-
// workspace mode could be tested at all.
|
|
117
|
-
MAUDE_WORKSPACE_ALLOW_DEV_MODULES: '1',
|
|
118
|
-
});
|
|
119
|
-
try {
|
|
120
|
-
const res = await fetch(`http://localhost:${port}/_api/canvas-meta`, {
|
|
121
|
-
method: 'PATCH',
|
|
122
|
-
headers: {
|
|
123
|
-
'content-type': 'application/json',
|
|
124
|
-
'x-maude-session': '../../../../tmp/pwned',
|
|
125
|
-
'x-maude-role': 'owner',
|
|
126
|
-
'x-maude-readonly': '0',
|
|
127
|
-
},
|
|
128
|
-
body: JSON.stringify({ file: CANVAS, patch: { viewport: { x: 0, y: 0, zoom: 1 } } }),
|
|
129
|
-
});
|
|
130
|
-
expect(res.status).toBe(200);
|
|
131
|
-
// Refused, not sanitized — so it lands on the shared singleton, exactly
|
|
132
|
-
// where a request with no session at all would.
|
|
133
|
-
expect(existsSync(join(designRoot, '_canvas-state', 'ui-fixture.view.json'))).toBe(true);
|
|
134
|
-
expect(existsSync('/tmp/pwned')).toBe(false);
|
|
135
|
-
} finally {
|
|
136
|
-
await killProc(proc);
|
|
137
|
-
}
|
|
138
|
-
}, 30_000);
|
|
139
|
-
|
|
140
|
-
test('`_active.json` is per member too', async () => {
|
|
141
|
-
// Selection + open tabs travel over the inspector WebSocket, so this drives
|
|
142
|
-
// the socket the way the client does — including the handshake, which is
|
|
143
|
-
// where the session is stamped (a role, and now an identity, is per session
|
|
144
|
-
// and a handshake is the one moment it is unambiguous).
|
|
145
|
-
const { root, designRoot } = makeSandbox();
|
|
146
|
-
const port = nextPort();
|
|
147
|
-
const proc = await bootServer(root, port, {
|
|
148
|
-
MAUDE_WORKSPACE_MODE: '1',
|
|
149
|
-
// A dev checkout resolves Playwright, a legitimate devDependency that
|
|
150
|
-
// would otherwise fail the module half of the containment assert before
|
|
151
|
-
// workspace mode could be tested at all.
|
|
152
|
-
MAUDE_WORKSPACE_ALLOW_DEV_MODULES: '1',
|
|
153
|
-
});
|
|
154
|
-
try {
|
|
155
|
-
const openAs = (session: string, file: string) =>
|
|
156
|
-
new Promise<void>((resolve, reject) => {
|
|
157
|
-
const ws = new WebSocket(`ws://localhost:${port}/_ws`, {
|
|
158
|
-
headers: asMember(session),
|
|
159
|
-
} as unknown as string[]);
|
|
160
|
-
const timer = setTimeout(() => reject(new Error('socket timeout')), 8000);
|
|
161
|
-
ws.onopen = () => {
|
|
162
|
-
ws.send(JSON.stringify({ type: 'active', file }));
|
|
163
|
-
ws.send(JSON.stringify({ type: 'tabs', tabs: [file] }));
|
|
164
|
-
setTimeout(() => {
|
|
165
|
-
clearTimeout(timer);
|
|
166
|
-
ws.close();
|
|
167
|
-
resolve();
|
|
168
|
-
}, 400);
|
|
169
|
-
};
|
|
170
|
-
ws.onerror = (e) => {
|
|
171
|
-
clearTimeout(timer);
|
|
172
|
-
reject(e);
|
|
173
|
-
};
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
await openAs('aaaaaaaaaaaaaaaa', '.design/ui/alice.tsx');
|
|
177
|
-
await openAs('bbbbbbbbbbbbbbbb', '.design/ui/bob.tsx');
|
|
178
|
-
await Bun.sleep(300);
|
|
179
|
-
|
|
180
|
-
const aliceState = await Bun.file(join(designRoot, '_active.aaaaaaaaaaaaaaaa.json')).json();
|
|
181
|
-
const bobState = await Bun.file(join(designRoot, '_active.bbbbbbbbbbbbbbbb.json')).json();
|
|
182
|
-
expect(aliceState.active).toBe('.design/ui/alice.tsx');
|
|
183
|
-
expect(bobState.active).toBe('.design/ui/bob.tsx');
|
|
184
|
-
// Neither clobbered the other, which before D3 is exactly what happened.
|
|
185
|
-
expect(aliceState.open_tabs).toEqual(['.design/ui/alice.tsx']);
|
|
186
|
-
expect(bobState.open_tabs).toEqual(['.design/ui/bob.tsx']);
|
|
187
|
-
} finally {
|
|
188
|
-
await killProc(proc);
|
|
189
|
-
}
|
|
190
|
-
}, 30_000);
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
describe('per-member runtime state is runtime state to git', () => {
|
|
194
|
-
test('all three matchers agree that `_active.<session>.json` is not a commit', () => {
|
|
195
|
-
// The comment in session-scope.ts CLAIMED a sibling kept every matcher
|
|
196
|
-
// correct. It did not: `.gitignore`, the CLI's ignore block and the
|
|
197
|
-
// studio's own `isMaudeRuntimeState` all matched `_active.json` by NAME, so
|
|
198
|
-
// each member's file showed as untracked to EVERYONE, "Save all" staged it,
|
|
199
|
-
// and a push published one person's open tabs, active canvas and selection
|
|
200
|
-
// into the tenant's remote.
|
|
201
|
-
const key = 'a1b2c3d4e5f60718';
|
|
202
|
-
|
|
203
|
-
// 1. the studio's own matcher — what the Changes panel filters by
|
|
204
|
-
expect(isMaudeRuntimeState(`.design/_active.${key}.json`)).toBe(true);
|
|
205
|
-
expect(isMaudeRuntimeState('.design/_active.json')).toBe(true);
|
|
206
|
-
expect(isMaudeRuntimeState(`.design/_canvas-state/${key}/ui-home.view.json`)).toBe(true);
|
|
207
|
-
// …and it must not have widened into ordinary files on the way.
|
|
208
|
-
expect(isMaudeRuntimeState('.design/ui/Home.tsx')).toBe(false);
|
|
209
|
-
expect(isMaudeRuntimeState('.design/ui/Home.meta.json')).toBe(false);
|
|
210
|
-
expect(isMaudeRuntimeState('.design/_activeXjson')).toBe(false);
|
|
211
|
-
|
|
212
|
-
// 2. this repo's own .gitignore
|
|
213
|
-
const ignored = (rel: string) =>
|
|
214
|
-
Bun.spawnSync(['git', 'check-ignore', '-q', rel], {
|
|
215
|
-
cwd: join(import.meta.dir, '..', '..', '..'),
|
|
216
|
-
}).exitCode === 0;
|
|
217
|
-
expect(ignored(`.design/_active.${key}.json`)).toBe(true);
|
|
218
|
-
|
|
219
|
-
// 3. the block the CLI writes into a downstream project
|
|
220
|
-
const block = readFileSync(
|
|
221
|
-
join(import.meta.dir, '..', '..', '..', 'cli', 'lib', 'gitignore-block.mjs'),
|
|
222
|
-
'utf8'
|
|
223
|
-
);
|
|
224
|
-
expect(block).toContain('_active.*.json');
|
|
225
|
-
});
|
|
226
|
-
});
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
// Cloud Phase 27 D3 — whose runtime state is this?
|
|
2
|
-
//
|
|
3
|
-
// `_active.json` and `_canvas-state/<slug>.view.json` are per-MACHINE
|
|
4
|
-
// singletons by design (DDR-115), which is right for a desktop and wrong for a
|
|
5
|
-
// cell: one studio process serves an owner and a viewer, so a colleague opening
|
|
6
|
-
// a canvas switched YOUR tab and their pan moved YOUR camera. Silently — it
|
|
7
|
-
// read as flakiness, not as two people sharing one file.
|
|
8
|
-
//
|
|
9
|
-
// The first test is the one that matters most: OUTSIDE a cell nothing changes.
|
|
10
|
-
|
|
11
|
-
import { describe, expect, test } from 'bun:test';
|
|
12
|
-
|
|
13
|
-
import {
|
|
14
|
-
currentSession,
|
|
15
|
-
normalizeSessionKey,
|
|
16
|
-
runInSession,
|
|
17
|
-
sessionDir,
|
|
18
|
-
sessionFile,
|
|
19
|
-
} from '../session-scope.ts';
|
|
20
|
-
|
|
21
|
-
describe('session scope', () => {
|
|
22
|
-
test('with no session every path is byte-for-byte what it was', () => {
|
|
23
|
-
expect(currentSession()).toBe('');
|
|
24
|
-
expect(sessionDir('/repo/.design/_canvas-state')).toBe('/repo/.design/_canvas-state');
|
|
25
|
-
expect(sessionFile('/repo/.design/_active.json')).toBe('/repo/.design/_active.json');
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
test('a session gives each member their own subtree and their own active file', () => {
|
|
29
|
-
runInSession('a1b2c3d4e5f60718', () => {
|
|
30
|
-
expect(currentSession()).toBe('a1b2c3d4e5f60718');
|
|
31
|
-
expect(sessionDir('/repo/.design/_canvas-state')).toBe(
|
|
32
|
-
'/repo/.design/_canvas-state/a1b2c3d4e5f60718'
|
|
33
|
-
);
|
|
34
|
-
// A SIBLING of `_active.json`, not a rename: the runtime-state taxonomy,
|
|
35
|
-
// the gitignore and `isMaudeRuntimeState` all match that stem by name,
|
|
36
|
-
// and a sibling keeps every one of them correct with no fourth list.
|
|
37
|
-
expect(sessionFile('/repo/.design/_active.json')).toBe(
|
|
38
|
-
'/repo/.design/_active.a1b2c3d4e5f60718.json'
|
|
39
|
-
);
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
test('the scope does not leak past the call', () => {
|
|
44
|
-
runInSession('deadbeef', () => expect(currentSession()).toBe('deadbeef'));
|
|
45
|
-
expect(currentSession()).toBe('');
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
test('two sessions do not see each other', () => {
|
|
49
|
-
runInSession('one', () => {
|
|
50
|
-
expect(currentSession()).toBe('one');
|
|
51
|
-
runInSession('two', () => expect(currentSession()).toBe('two'));
|
|
52
|
-
expect(currentSession()).toBe('one');
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
test('the scope survives an await — a request is not one tick', async () => {
|
|
57
|
-
await runInSession('async1', async () => {
|
|
58
|
-
await new Promise((r) => setTimeout(r, 5));
|
|
59
|
-
expect(currentSession()).toBe('async1');
|
|
60
|
-
await Promise.resolve();
|
|
61
|
-
expect(currentSession()).toBe('async1');
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
test('a key that is not proxy-shaped is refused, not sanitized', () => {
|
|
66
|
-
// The value becomes a path segment, so this is the traversal gate — and it
|
|
67
|
-
// REJECTS rather than strips, because a key we had to repair is not one
|
|
68
|
-
// whose intent we should be guessing. Falling back to the shared singleton
|
|
69
|
-
// is the same behaviour a desktop already has.
|
|
70
|
-
for (const bad of [
|
|
71
|
-
'../../etc/passwd',
|
|
72
|
-
'a/b',
|
|
73
|
-
'a\\b',
|
|
74
|
-
'.',
|
|
75
|
-
'..',
|
|
76
|
-
'has space',
|
|
77
|
-
'x'.repeat(65),
|
|
78
|
-
'',
|
|
79
|
-
null,
|
|
80
|
-
undefined,
|
|
81
|
-
]) {
|
|
82
|
-
expect(normalizeSessionKey(bad as string)).toBe('');
|
|
83
|
-
}
|
|
84
|
-
for (const good of ['abc123', 'a1b2c3d4e5f60718', 'A_b-9']) {
|
|
85
|
-
expect(normalizeSessionKey(good)).toBe(good);
|
|
86
|
-
}
|
|
87
|
-
// …and a refused key means the shared path, never a traversed one.
|
|
88
|
-
runInSession('../../etc', () => {
|
|
89
|
-
expect(sessionDir('/repo/.design/_canvas-state')).toBe('/repo/.design/_canvas-state');
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
test('a file with no extension still gets a distinct per-session name', () => {
|
|
94
|
-
runInSession('k', () => {
|
|
95
|
-
expect(sessionFile('/repo/.design/_active')).toBe('/repo/.design/_active.k');
|
|
96
|
-
// A dot in a PARENT directory must not be mistaken for the extension.
|
|
97
|
-
expect(sessionFile('/repo/my.dir/_active')).toBe('/repo/my.dir/_active.k');
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
});
|