@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
|
@@ -2157,3 +2157,29 @@
|
|
|
2157
2157
|
color: var(--fg-3);
|
|
2158
2158
|
overflow-wrap: anywhere;
|
|
2159
2159
|
}
|
|
2160
|
+
|
|
2161
|
+
/* Seed progress (feature-large-project-seed).
|
|
2162
|
+
A bar rather than a number alone: a large project's seed is minutes to hours
|
|
2163
|
+
of work, and "1 412" reads the same whether it is a quarter done or finished.
|
|
2164
|
+
Track and fill use existing tokens — no new colours enter the system here. */
|
|
2165
|
+
.sp-progress-track {
|
|
2166
|
+
height: 4px;
|
|
2167
|
+
border-radius: 2px;
|
|
2168
|
+
background: var(--bg-2);
|
|
2169
|
+
overflow: hidden;
|
|
2170
|
+
margin: 6px 0 4px;
|
|
2171
|
+
}
|
|
2172
|
+
.sp-progress-fill {
|
|
2173
|
+
height: 100%;
|
|
2174
|
+
background: var(--accent);
|
|
2175
|
+
border-radius: 2px;
|
|
2176
|
+
transition: width var(--dur-2, 240ms) ease;
|
|
2177
|
+
}
|
|
2178
|
+
@media (prefers-reduced-motion: reduce) {
|
|
2179
|
+
.sp-progress-fill { transition-duration: 1ms; }
|
|
2180
|
+
}
|
|
2181
|
+
/* The falsifiable half (DDR-214) — present, quiet, never the headline. */
|
|
2182
|
+
.sp-raw-counters {
|
|
2183
|
+
opacity: 0.6;
|
|
2184
|
+
font-size: 0.9em;
|
|
2185
|
+
}
|
|
@@ -10,6 +10,7 @@ import type { Api } from '../api.ts';
|
|
|
10
10
|
import type { Context } from '../context.ts';
|
|
11
11
|
// From the LEAF, never from `sync/codec.ts` — codec imports `Y_TYPES` from this
|
|
12
12
|
// file, so reaching for it here would close a cycle (see sync/limits.ts).
|
|
13
|
+
import { commentKey } from '../sync/comment-identity.ts';
|
|
13
14
|
import { MAX_ANNOTATIONS_BYTES, MAX_COMMENTS_BYTES, withinByteCap } from '../sync/limits.ts';
|
|
14
15
|
import { ensureStateDir, type RoomCallbacks } from './room.ts';
|
|
15
16
|
|
|
@@ -82,15 +83,91 @@ export function createPersistence(deps: PersistenceDeps): RoomCallbacks {
|
|
|
82
83
|
const { ctx, api, fileForSlug } = deps;
|
|
83
84
|
const stateDir = ensureStateDir(ctx.paths.designRoot);
|
|
84
85
|
|
|
85
|
-
// Per-slug
|
|
86
|
-
//
|
|
87
|
-
//
|
|
88
|
-
//
|
|
89
|
-
//
|
|
90
|
-
//
|
|
91
|
-
//
|
|
92
|
-
//
|
|
93
|
-
|
|
86
|
+
// Per-slug: every comment identity this doc has EVER carried (issue #111).
|
|
87
|
+
//
|
|
88
|
+
// This subsumes the old `seenComments` latch — "have we ever projected a
|
|
89
|
+
// NON-empty array for this canvas", which gated the delete-all write so a
|
|
90
|
+
// never-populated doc could not clobber a non-empty local file with `[]`
|
|
91
|
+
// (DDR-064's receiving-peer gap). Same question, better evidence.
|
|
92
|
+
//
|
|
93
|
+
// It also answers the question the projection could not ask at all before,
|
|
94
|
+
// and the one this issue is about: is the doc AHEAD of the file (a real
|
|
95
|
+
// change, write it) or BEHIND it (a write the doc has not caught up with —
|
|
96
|
+
// writing would erase it)?
|
|
97
|
+
//
|
|
98
|
+
// Identity settles it without a wire-format change. An id on disk that the
|
|
99
|
+
// doc has held and dropped is a genuine delete and must materialize. An id on
|
|
100
|
+
// disk the doc has NEVER held is something the doc has not seen yet, and
|
|
101
|
+
// dropping it is silent data loss — the reporter's "add a second comment and
|
|
102
|
+
// it disappears after a few seconds". `Room.flush()` fires on ANY doc update
|
|
103
|
+
// and every hub update re-arms it, so on a linked project a flush lands in
|
|
104
|
+
// that window constantly; on a local one it essentially never does, which is
|
|
105
|
+
// exactly the scoping the reporter gave ("connected to a custom hub").
|
|
106
|
+
const docSeenComments = new Map<string, Set<string>>();
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Ceiling on identities remembered per canvas — DDR-054 §2d applied to a set
|
|
110
|
+
* rather than a byte length.
|
|
111
|
+
*
|
|
112
|
+
* The doc is populated by the hub, so what lands in this set is peer-supplied
|
|
113
|
+
* and the set only ever grows: without a bound, a hostile hub streaming
|
|
114
|
+
* distinct comment ids is unbounded memory on every linked peer. Eviction is
|
|
115
|
+
* oldest-first (JS sets keep insertion order), and it degrades in the SAFE
|
|
116
|
+
* direction — an evicted id reads as "never seen", so the projection defers
|
|
117
|
+
* the write instead of deleting. The cost is that a delete of a very old
|
|
118
|
+
* comment on a canvas that has carried more than this many distinct comments
|
|
119
|
+
* may not materialize, which is a far better failure than losing one.
|
|
120
|
+
*/
|
|
121
|
+
const MAX_SEEN_COMMENT_IDS = 10_000;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Docs already wired to their slug's identity set.
|
|
125
|
+
*
|
|
126
|
+
* WEAK on purpose: a room dropped when its last browser leaves destroys its
|
|
127
|
+
* doc, and a strong reference here would keep every doc of every canvas the
|
|
128
|
+
* user ever opened alive for the process's lifetime. The observer closes over
|
|
129
|
+
* the SET, not the other way round, so nothing else pins the doc either.
|
|
130
|
+
*/
|
|
131
|
+
const observedCommentDocs = new WeakSet<Y.Doc>();
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* The identity set for `slug`, observing `doc` so it records an id the moment
|
|
135
|
+
* it ENTERS the array.
|
|
136
|
+
*
|
|
137
|
+
* Sampling at flush time alone is not enough, and the gap is a real delete
|
|
138
|
+
* bug rather than a theoretical one: an id that arrives and is deleted again
|
|
139
|
+
* between two flushes (a local add, then a remote delete inside the same
|
|
140
|
+
* 800 ms debounce — every doc update re-arms the timer, so this is the common
|
|
141
|
+
* shape, not a rare one) would never be recorded, the guard below would read
|
|
142
|
+
* the surviving disk copy as "never seen", and the delete could never
|
|
143
|
+
* materialize. The observer only ever ADDS, which is what makes it a record
|
|
144
|
+
* of what the doc has held rather than of what it holds.
|
|
145
|
+
*
|
|
146
|
+
* The set is per SLUG and the wiring is per DOC: a slug's room can be rebuilt
|
|
147
|
+
* on a fresh doc, and the ids carry over because this peer did see them.
|
|
148
|
+
*/
|
|
149
|
+
function commentIdsSeenBy(slug: string, doc: Y.Doc): Set<string> {
|
|
150
|
+
let ids = docSeenComments.get(slug);
|
|
151
|
+
if (!ids) {
|
|
152
|
+
ids = new Set<string>();
|
|
153
|
+
docSeenComments.set(slug, ids);
|
|
154
|
+
}
|
|
155
|
+
if (observedCommentDocs.has(doc)) return ids;
|
|
156
|
+
observedCommentDocs.add(doc);
|
|
157
|
+
|
|
158
|
+
const seen = ids;
|
|
159
|
+
const arr = doc.getArray<unknown>(Y_TYPES.comments);
|
|
160
|
+
const absorb = () => {
|
|
161
|
+
for (const c of arr.toArray()) seen.add(commentKey(c));
|
|
162
|
+
for (const stale of seen) {
|
|
163
|
+
if (seen.size <= MAX_SEEN_COMMENT_IDS) break;
|
|
164
|
+
seen.delete(stale); // oldest first — insertion order
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
absorb();
|
|
168
|
+
arr.observe(absorb);
|
|
169
|
+
return ids;
|
|
170
|
+
}
|
|
94
171
|
|
|
95
172
|
function ydocBinPath(slug: string): string {
|
|
96
173
|
return path.join(stateDir, `${slug}.ydoc.bin`);
|
|
@@ -108,6 +185,13 @@ export function createPersistence(deps: PersistenceDeps): RoomCallbacks {
|
|
|
108
185
|
}
|
|
109
186
|
|
|
110
187
|
async function seed(slug: string, doc: Y.Doc): Promise<void> {
|
|
188
|
+
// Start recording comment identities at ROOM MOUNT, before anything can
|
|
189
|
+
// gate out (issue #111). `persistJson` would otherwise be the first thing
|
|
190
|
+
// to observe this doc, which is one flush too late: an id added and deleted
|
|
191
|
+
// before that flush would never be recorded, and its delete could never
|
|
192
|
+
// materialize. This is the earliest callback that sees the doc.
|
|
193
|
+
commentIdsSeenBy(slug, doc);
|
|
194
|
+
|
|
111
195
|
// Phase 9.2 (DDR-064) — under sharedDoc the migrate-seed + hub provider own
|
|
112
196
|
// initial population for a pinned slug; a local file-seed here would push
|
|
113
197
|
// fresh Y.Array items that DUPLICATE the hub's canonical items on merge
|
|
@@ -136,7 +220,22 @@ export function createPersistence(deps: PersistenceDeps): RoomCallbacks {
|
|
|
136
220
|
doc.transact(() => {
|
|
137
221
|
if (comments.length > 0) {
|
|
138
222
|
const arr = doc.getArray<unknown>(Y_TYPES.comments);
|
|
139
|
-
|
|
223
|
+
// Push only what the array does not already hold (issue #112). This was
|
|
224
|
+
// an unconditional `arr.push(comments)`, which concatenates whenever the
|
|
225
|
+
// doc is NOT empty at seed time — the DDR-064 Risk 1 window that
|
|
226
|
+
// `shouldSeed`/`isPinned` closes only when the pin already exists, i.e.
|
|
227
|
+
// not when a room is mounted a beat before the hub provider attaches.
|
|
228
|
+
// The identity rule is `commentKey`, shared with the codec's diff and
|
|
229
|
+
// the cold-start union; the leaf import is deliberate — this file owns
|
|
230
|
+
// `Y_TYPES`, so it can never import `sync/codec.ts` back (see above).
|
|
231
|
+
const present = new Set(arr.toArray().map(commentKey));
|
|
232
|
+
const missing = comments.filter((c) => {
|
|
233
|
+
const k = commentKey(c);
|
|
234
|
+
if (present.has(k)) return false;
|
|
235
|
+
present.add(k);
|
|
236
|
+
return true;
|
|
237
|
+
});
|
|
238
|
+
if (missing.length > 0) arr.push(missing);
|
|
140
239
|
}
|
|
141
240
|
if (svg && typeof svg === 'string') {
|
|
142
241
|
const map = doc.getMap<string>(Y_TYPES.annotations);
|
|
@@ -151,14 +250,31 @@ export function createPersistence(deps: PersistenceDeps): RoomCallbacks {
|
|
|
151
250
|
|
|
152
251
|
// Comments — Y.Array projection back to JSON. Write whenever the doc holds
|
|
153
252
|
// comments, OR when it just emptied after previously holding some (so a
|
|
154
|
-
// delete-all materializes on EVERY peer's disk, not just the originator's)
|
|
155
|
-
//
|
|
156
|
-
//
|
|
253
|
+
// delete-all materializes on EVERY peer's disk, not just the originator's),
|
|
254
|
+
// and never from a doc that was never populated at all (cold start before
|
|
255
|
+
// seed/migrate completes), which would clobber a non-empty local file.
|
|
256
|
+
//
|
|
257
|
+
// `everSeen` is that latch as well as the freshness oracle below — one
|
|
258
|
+
// notion of "this doc has held comments" instead of two that can disagree.
|
|
259
|
+
// It replaces a per-slug flag sampled HERE, which could not see a comment
|
|
260
|
+
// that arrived and was deleted again between two flushes: the flag stayed
|
|
261
|
+
// unset, so the delete-all read as "never populated" and never reached
|
|
262
|
+
// disk. Both readings need the same fact, and only the observer has it.
|
|
157
263
|
const arr = doc.getArray(Y_TYPES.comments);
|
|
158
264
|
const list = arr.toArray() as Parameters<Api['saveCommentsForFile']>[1];
|
|
159
|
-
|
|
160
|
-
if (list.length > 0 ||
|
|
161
|
-
|
|
265
|
+
const everSeen = commentIdsSeenBy(slug, doc);
|
|
266
|
+
if (list.length > 0 || everSeen.size > 0) {
|
|
267
|
+
// Issue #111 — refuse to project a doc that is BEHIND the file. An id on
|
|
268
|
+
// disk this doc has never carried is a write still in flight towards it
|
|
269
|
+
// (a mutation whose file→doc import has not landed, an external edit to
|
|
270
|
+
// `_comments/<slug>.json`); overwriting it deletes a real comment with no
|
|
271
|
+
// error and no recovery. Deferring is safe and self-clearing: whatever
|
|
272
|
+
// brings that id into the doc is itself a doc update, which re-arms the
|
|
273
|
+
// flush, and the next pass writes the merged state. A delete still
|
|
274
|
+
// materializes — its id IS in `everSeen`, so the write proceeds.
|
|
275
|
+
const onDisk = await api.loadCommentsForFile(file);
|
|
276
|
+
const behind = onDisk.some((c) => !everSeen.has(commentKey(c)));
|
|
277
|
+
if (!behind && withinCap(slug, 'comments', JSON.stringify(list), MAX_COMMENTS_BYTES)) {
|
|
162
278
|
await api.saveCommentsForFile(file, list);
|
|
163
279
|
}
|
|
164
280
|
}
|
|
@@ -8,17 +8,12 @@
|
|
|
8
8
|
|
|
9
9
|
import type { Awareness } from 'y-protocols/awareness';
|
|
10
10
|
|
|
11
|
+
import { applyCommentsToDoc } from '../sync/codec.ts';
|
|
11
12
|
import { bridgeAwareness } from './awareness-bridge.ts';
|
|
12
13
|
import { Y_TYPES } from './persistence.ts';
|
|
13
14
|
import type { Room, RoomCallbacks } from './room.ts';
|
|
14
15
|
import { createRoom } from './room.ts';
|
|
15
16
|
|
|
16
|
-
/** Structural equality via canonical JSON — used by the syncRoomFrom* no-op
|
|
17
|
-
* guards. Comment lists are small; stringify is cheap + dependency-free. */
|
|
18
|
-
function jsonEqual(a: unknown, b: unknown): boolean {
|
|
19
|
-
return JSON.stringify(a) === JSON.stringify(b);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
17
|
export interface Registry {
|
|
23
18
|
/** Get-or-create. Reuses an existing room for the same slug. */
|
|
24
19
|
get(slug: string): Room;
|
|
@@ -186,18 +181,15 @@ export function createRegistry(callbacks: RoomCallbacks): Registry {
|
|
|
186
181
|
function syncRoomFromComments(slug: string, comments: readonly unknown[]): void {
|
|
187
182
|
const room = rooms.get(slug);
|
|
188
183
|
if (!room) return;
|
|
189
|
-
|
|
190
|
-
//
|
|
191
|
-
//
|
|
192
|
-
//
|
|
193
|
-
//
|
|
194
|
-
//
|
|
195
|
-
//
|
|
196
|
-
|
|
197
|
-
room.doc
|
|
198
|
-
if (arr.length > 0) arr.delete(0, arr.length);
|
|
199
|
-
if (comments.length > 0) arr.push(comments as unknown[]);
|
|
200
|
-
}, 'inspector-write');
|
|
184
|
+
// Through the codec's identity-keyed diff, NOT a local delete-all + push
|
|
185
|
+
// (issue #112). This bridge fires after EVERY comment mutation, so it was
|
|
186
|
+
// one of the three writers that could collide with an in-flight hub update
|
|
187
|
+
// and leave the array holding both runs. The codec keeps the no-op guard
|
|
188
|
+
// this function used to carry inline — an unchanged list emits no
|
|
189
|
+
// transaction, so re-seeding the live room from a disk change (sync-agent
|
|
190
|
+
// or design:edit write — see createCollab's fs hook) still can't spin the
|
|
191
|
+
// 800 ms persist storm the old equality short-circuit existed to prevent.
|
|
192
|
+
applyCommentsToDoc(room.doc, comments as unknown[], 'inspector-write');
|
|
201
193
|
}
|
|
202
194
|
|
|
203
195
|
function syncRoomFromAnnotations(slug: string, svg: string): void {
|
|
@@ -120,6 +120,13 @@ export function scrub(text: string, opts: ScrubOptions = {}): string {
|
|
|
120
120
|
export interface DebugBundle {
|
|
121
121
|
app: { maudeVersion: string; platform: string; arch: string };
|
|
122
122
|
context: { projectName: string | null; activeCanvas: string | null };
|
|
123
|
+
/** Server process memory at report time (#119). A runaway-memory report used
|
|
124
|
+
* to arrive as a number the user eyeballed in Activity Monitor, with nothing
|
|
125
|
+
* in the bundle to confirm or refute it — and the log ring was silent
|
|
126
|
+
* because the heap watch was measuring the wrong counter. `rss` is the same
|
|
127
|
+
* number the user sees, so a future report of this class carries its own
|
|
128
|
+
* evidence. Bytes; process-level, never per-request. */
|
|
129
|
+
process: { rssBytes: number; heapUsedBytes: number; uptimeSeconds: number };
|
|
123
130
|
logs: { serverLogTail: string };
|
|
124
131
|
}
|
|
125
132
|
|
|
@@ -137,6 +144,7 @@ export function buildDebugBundle(args: {
|
|
|
137
144
|
tailLines?: number;
|
|
138
145
|
}): DebugBundle {
|
|
139
146
|
const scrubOpts: ScrubOptions = { repoRoot: args.repoRoot };
|
|
147
|
+
const memory = process.memoryUsage();
|
|
140
148
|
return {
|
|
141
149
|
app: {
|
|
142
150
|
maudeVersion: args.maudeVersion,
|
|
@@ -147,6 +155,11 @@ export function buildDebugBundle(args: {
|
|
|
147
155
|
projectName: args.projectName,
|
|
148
156
|
activeCanvas: args.activeCanvas ? scrub(args.activeCanvas, scrubOpts) : null,
|
|
149
157
|
},
|
|
158
|
+
process: {
|
|
159
|
+
rssBytes: memory.rss,
|
|
160
|
+
heapUsedBytes: memory.heapUsed,
|
|
161
|
+
uptimeSeconds: Math.round(process.uptime()),
|
|
162
|
+
},
|
|
150
163
|
logs: {
|
|
151
164
|
serverLogTail: logRingLines(args.tailLines ?? 200)
|
|
152
165
|
.map((l) => scrub(l, scrubOpts))
|