@1agh/maude 1.0.11 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/apps/studio/acp/bridge.ts +18 -13
- package/apps/studio/acp/index.ts +43 -7
- package/apps/studio/acp/transcript-io.ts +394 -0
- package/apps/studio/acp/transcript.ts +103 -38
- package/apps/studio/annotations-layer.tsx +191 -116
- package/apps/studio/annotations-model.ts +39 -0
- package/apps/studio/annotations-sync.ts +50 -0
- package/apps/studio/api.ts +821 -55
- package/apps/studio/bin/_import-figma.mjs +57 -11
- package/apps/studio/bin/_seed-fixture.mjs +163 -0
- package/apps/studio/bin/annotate.mjs +3 -1
- package/apps/studio/bin/server-up.sh +17 -2
- package/apps/studio/canvas-edit.ts +391 -7
- package/apps/studio/canvas-imports.ts +89 -0
- package/apps/studio/canvas-lib.tsx +82 -18
- package/apps/studio/canvas-notice-message.ts +16 -0
- package/apps/studio/canvas-notifications.tsx +19 -0
- package/apps/studio/canvas-shell.tsx +57 -6
- package/apps/studio/client/app.jsx +943 -248
- package/apps/studio/client/apply-edit-request.ts +55 -0
- package/apps/studio/client/export-center.jsx +125 -67
- package/apps/studio/client/github.js +38 -1
- package/apps/studio/client/index-loader.ts +76 -0
- package/apps/studio/client/panels/CloudBar.jsx +52 -6
- package/apps/studio/client/panels/GitPanel.jsx +103 -0
- package/apps/studio/client/panels/OnboardingWizard.jsx +36 -7
- package/apps/studio/client/panels/RepoBranchSwitcher.jsx +92 -27
- package/apps/studio/client/panels/SourceConflictPanel.jsx +166 -0
- package/apps/studio/client/panels/SyncPanel.jsx +238 -4
- package/apps/studio/client/panels/TeamProjects.jsx +376 -0
- package/apps/studio/client/panels/file-deep-link-dialog.jsx +54 -0
- package/apps/studio/client/photo-knobs.jsx +3 -0
- package/apps/studio/client/report-bug.jsx +19 -1
- package/apps/studio/client/share-dialog.jsx +91 -0
- package/apps/studio/client/share-link.js +94 -0
- package/apps/studio/client/styles/3-shell-maude.css +69 -18
- package/apps/studio/client/styles/4-components.css +44 -1
- package/apps/studio/client/tree-row-menu.jsx +48 -3
- package/apps/studio/client/whats-new.jsx +26 -32
- package/apps/studio/cloud/endpoints.ts +132 -0
- package/apps/studio/collab/index.ts +4 -0
- package/apps/studio/collab/persistence.ts +137 -17
- package/apps/studio/collab/registry.ts +19 -21
- package/apps/studio/collab/room.ts +13 -2
- package/apps/studio/context.ts +59 -0
- package/apps/studio/debug-bundle.ts +13 -0
- package/apps/studio/dist/client.bundle.js +1911 -1879
- package/apps/studio/dist/runtime/.min-sizes.json +1 -0
- package/apps/studio/dist/runtime/sonner.js +1 -0
- 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 +296 -19
- package/apps/studio/inspect.ts +19 -0
- package/apps/studio/managed-projects.ts +150 -0
- package/apps/studio/mem.ts +45 -9
- package/apps/studio/notifications.tsx +292 -0
- package/apps/studio/runtime-bundle.ts +2 -0
- package/apps/studio/server.ts +69 -6
- package/apps/studio/sync/accepted-cold-start.ts +225 -0
- package/apps/studio/sync/accepted-link.ts +320 -0
- package/apps/studio/sync/action-stage.ts +343 -0
- package/apps/studio/sync/agent.ts +104 -45
- package/apps/studio/sync/asset-push.ts +1 -47
- package/apps/studio/sync/cell-file-events.ts +3 -0
- package/apps/studio/sync/codec.ts +192 -34
- 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/ctl-provider.ts +15 -2
- package/apps/studio/sync/document-discovery.ts +81 -0
- package/apps/studio/sync/file-ledger.ts +117 -0
- package/apps/studio/sync/file-membership.ts +10 -2
- package/apps/studio/sync/file-plane.ts +926 -47
- package/apps/studio/sync/index.ts +1786 -36
- package/apps/studio/sync/journal-client.ts +13 -1
- package/apps/studio/sync/migrate-seed.ts +150 -22
- package/apps/studio/sync/poke.ts +4 -2
- package/apps/studio/sync/presentation.ts +311 -5
- package/apps/studio/sync/projection.ts +820 -23
- package/apps/studio/sync/repeated-module.ts +73 -0
- package/apps/studio/sync/retry-after.ts +169 -0
- package/apps/studio/sync/revision-barrier.ts +129 -0
- package/apps/studio/sync/seed-progress.ts +218 -0
- package/apps/studio/sync/seed-repair.ts +46 -0
- package/apps/studio/sync/source-merge.ts +100 -0
- package/apps/studio/sync/source-ops.ts +289 -0
- package/apps/studio/sync/source-recovery.ts +70 -0
- package/apps/studio/sync/source-validation.ts +56 -0
- package/apps/studio/sync/status.ts +201 -6
- package/apps/studio/sync/transaction-client.ts +460 -0
- package/apps/studio/sync/transport-error.ts +111 -0
- package/apps/studio/sync/writer-registry.ts +236 -0
- package/apps/studio/text-caret.ts +35 -0
- package/apps/studio/undo-hud.tsx +9 -87
- package/apps/studio/use-canvas-media-drop.tsx +4 -39
- package/apps/studio/whats-new.json +173 -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 +892 -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 +33 -9
- package/plugins/design/dependencies.json +3 -3
- package/plugins/design/templates/_shell.html +47 -0
- package/plugins/flow/.claude-plugin/config.schema.json +8 -0
- package/plugins/flow/dependencies.json +3 -3
- 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
|
@@ -25,7 +25,9 @@ export type SyncPhase =
|
|
|
25
25
|
| 'stalled'
|
|
26
26
|
| 'refused'
|
|
27
27
|
| 'offline'
|
|
28
|
-
| 'nothing-syncable'
|
|
28
|
+
| 'nothing-syncable'
|
|
29
|
+
/** The link works, but part of the project did not get through. */
|
|
30
|
+
| 'attention';
|
|
29
31
|
|
|
30
32
|
/**
|
|
31
33
|
* How long `connecting…` may honestly stay on screen with ZERO documents
|
|
@@ -71,6 +73,18 @@ export interface SyncStatusLike extends Partial<SyncStatusSnapshot> {
|
|
|
71
73
|
tsxCount?: number;
|
|
72
74
|
reason?: string;
|
|
73
75
|
canvases?: number;
|
|
76
|
+
/**
|
|
77
|
+
* The other lanes `_sync.json` carries (`status.ts`): source-sync conflicts,
|
|
78
|
+
* the file plane, the asset push. Typed `unknown` on purpose — they are read
|
|
79
|
+
* off disk with no schema and validated below, never trusted.
|
|
80
|
+
*/
|
|
81
|
+
conflicts?: unknown;
|
|
82
|
+
files?: unknown;
|
|
83
|
+
assets?: unknown;
|
|
84
|
+
/** Accepted-revisions save counters (plan T29) — validated below. */
|
|
85
|
+
accepted?: unknown;
|
|
86
|
+
/** An AI action open or held (plan T16) — validated below. */
|
|
87
|
+
aiAction?: unknown;
|
|
74
88
|
}
|
|
75
89
|
|
|
76
90
|
/** Hub-supplied text that reaches a UI. Bounded, never markup. */
|
|
@@ -143,6 +157,118 @@ function readCounts(
|
|
|
143
157
|
return { synced: docs.synced, pending: docs.pending, rejected: docs.rejected };
|
|
144
158
|
}
|
|
145
159
|
|
|
160
|
+
const isCount = (n: unknown): n is number => typeof n === 'number' && Number.isInteger(n) && n >= 0;
|
|
161
|
+
const isRecord = (v: unknown): v is Record<string, unknown> =>
|
|
162
|
+
v !== null && typeof v === 'object' && !Array.isArray(v);
|
|
163
|
+
|
|
164
|
+
/** What the non-document lanes say, validated. */
|
|
165
|
+
interface LaneFacts {
|
|
166
|
+
/** A payload field we cannot read. Fail closed: never "synced". */
|
|
167
|
+
unreadable: boolean;
|
|
168
|
+
/** Canvases whose source change was refused and is waiting (#121 / T2). */
|
|
169
|
+
sourceSlugs: string[];
|
|
170
|
+
failedFiles: number;
|
|
171
|
+
tooLarge: number;
|
|
172
|
+
blockedOther: number;
|
|
173
|
+
/** Changes a breaker is holding for a person's decision. */
|
|
174
|
+
held: number;
|
|
175
|
+
failedMedia: number;
|
|
176
|
+
/** Files or media still moving on their own. */
|
|
177
|
+
moving:
|
|
178
|
+
| { delivered: number; tracked: number }
|
|
179
|
+
| { media: { done: number; total: number } }
|
|
180
|
+
| null;
|
|
181
|
+
paused: boolean;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Audit 2026-09-13 P0 #3 — "synced" is a claim about the whole project, not
|
|
186
|
+
* about the document sockets. The payload already carried refused source
|
|
187
|
+
* changes, failed files, a blocked seed and failed uploads; the summary read
|
|
188
|
+
* none of them and said "Synced … all 91 canvases" over all four.
|
|
189
|
+
*/
|
|
190
|
+
function readLanes(status: SyncStatusLike): LaneFacts {
|
|
191
|
+
const facts: LaneFacts = {
|
|
192
|
+
unreadable: false,
|
|
193
|
+
sourceSlugs: [],
|
|
194
|
+
failedFiles: 0,
|
|
195
|
+
tooLarge: 0,
|
|
196
|
+
blockedOther: 0,
|
|
197
|
+
held: 0,
|
|
198
|
+
failedMedia: 0,
|
|
199
|
+
moving: null,
|
|
200
|
+
paused: false,
|
|
201
|
+
};
|
|
202
|
+
const { conflicts, files, assets } = status;
|
|
203
|
+
if (conflicts !== undefined) {
|
|
204
|
+
if (!Array.isArray(conflicts)) facts.unreadable = true;
|
|
205
|
+
else {
|
|
206
|
+
for (const c of conflicts) {
|
|
207
|
+
// `body-rejected` is the only kind that stays until it is resolved
|
|
208
|
+
// (`clearSourceConflict`); cold-start notes record a decision made.
|
|
209
|
+
if (isRecord(c) && c.kind === 'body-rejected') {
|
|
210
|
+
facts.sourceSlugs.push(typeof c.slug === 'string' ? c.slug : '(unnamed)');
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (files !== undefined) {
|
|
216
|
+
if (!isRecord(files)) facts.unreadable = true;
|
|
217
|
+
else {
|
|
218
|
+
for (const key of ['synced', 'pulled', 'conflicts', 'pushed', 'failed'] as const) {
|
|
219
|
+
if (files[key] !== undefined && !isCount(files[key])) facts.unreadable = true;
|
|
220
|
+
}
|
|
221
|
+
if (isCount(files.failed)) facts.failedFiles = files.failed;
|
|
222
|
+
if (Array.isArray(files.held)) {
|
|
223
|
+
for (const h of files.held) facts.held += isRecord(h) && isCount(h.count) ? h.count : 1;
|
|
224
|
+
}
|
|
225
|
+
if (isRecord(files.rateLimited)) facts.paused = true;
|
|
226
|
+
const progress = files.progress;
|
|
227
|
+
if (isRecord(progress)) {
|
|
228
|
+
if (Array.isArray(progress.blocked)) {
|
|
229
|
+
for (const b of progress.blocked) {
|
|
230
|
+
if (!isRecord(b) || !isCount(b.count)) continue;
|
|
231
|
+
if (b.class === 'too-large') facts.tooLarge += b.count;
|
|
232
|
+
else facts.blockedOther += b.count;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
if (progress.phase === 'paused') facts.paused = true;
|
|
236
|
+
if (
|
|
237
|
+
progress.phase === 'scanning' ||
|
|
238
|
+
progress.phase === 'seeding' ||
|
|
239
|
+
progress.phase === 'paused'
|
|
240
|
+
) {
|
|
241
|
+
facts.moving =
|
|
242
|
+
isCount(progress.delivered) && isCount(progress.tracked)
|
|
243
|
+
? {
|
|
244
|
+
delivered: Math.min(progress.delivered, progress.tracked),
|
|
245
|
+
tracked: progress.tracked,
|
|
246
|
+
}
|
|
247
|
+
: { delivered: 0, tracked: 0 };
|
|
248
|
+
}
|
|
249
|
+
} else if (progress !== undefined) facts.unreadable = true;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
if (assets !== undefined) {
|
|
253
|
+
if (!isRecord(assets)) facts.unreadable = true;
|
|
254
|
+
else {
|
|
255
|
+
if (isCount(assets.failedCount)) facts.failedMedia = assets.failedCount;
|
|
256
|
+
else if (assets.failedCount !== undefined) facts.unreadable = true;
|
|
257
|
+
if (assets.finished === false && !facts.moving) {
|
|
258
|
+
facts.moving = {
|
|
259
|
+
media: {
|
|
260
|
+
done: isCount(assets.done) ? assets.done : 0,
|
|
261
|
+
total: isCount(assets.total) ? assets.total : 0,
|
|
262
|
+
},
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return facts;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const plural = (n: number, one: string, many = `${one}s`) => `${n} ${n === 1 ? one : many}`;
|
|
271
|
+
|
|
146
272
|
/**
|
|
147
273
|
* Read a sync payload the way a person would.
|
|
148
274
|
*
|
|
@@ -170,7 +296,26 @@ export function syncPresentation(
|
|
|
170
296
|
status.startedAt > 0
|
|
171
297
|
? status.startedAt
|
|
172
298
|
: null;
|
|
173
|
-
|
|
299
|
+
/**
|
|
300
|
+
* @param credentialUnknown Can an expired sign-in still be the cause?
|
|
301
|
+
*
|
|
302
|
+
* ONLY BLAME THE SIGN-IN WHEN THE SIGN-IN COULD BE THE PROBLEM (issue #118).
|
|
303
|
+
* This unconditionally told the person to reconnect the workspace because
|
|
304
|
+
* "the sign-in may have expired" — at call sites that have ALREADY proved
|
|
305
|
+
* `rejected === 0`, i.e. where the hub has refused exactly nothing and the
|
|
306
|
+
* credential is demonstrably fine. Naming a cause we have evidence against is
|
|
307
|
+
* worse than naming none: it sent the reporter to Resync, which re-handshakes
|
|
308
|
+
* every canvas against a hub that is not answering, times out the fresh
|
|
309
|
+
* monitor's grace window, and lands on `offline`. The product talked the
|
|
310
|
+
* person into making its own display worse.
|
|
311
|
+
*
|
|
312
|
+
* A rejection has its OWN branch (`phase: 'refused'`) and outranks this one,
|
|
313
|
+
* and it is the branch that may legitimately say "credential". Here we say
|
|
314
|
+
* what we actually know: the hub is not completing handshakes. Only the
|
|
315
|
+
* legacy no-`docs` payload, where refusals are unknowable, keeps the older
|
|
316
|
+
* hedge — and it is written as a possibility rather than a diagnosis.
|
|
317
|
+
*/
|
|
318
|
+
const stalled = (credentialUnknown = false): SyncPresentation => {
|
|
174
319
|
// `?? now` rather than a cast: every call site is behind `isStalled`, which
|
|
175
320
|
// has already proved `startedAt` is a number — and a future one that isn't
|
|
176
321
|
// reads "1 minute" instead of "NaN minutes".
|
|
@@ -180,7 +325,9 @@ export function syncPresentation(
|
|
|
180
325
|
online: false,
|
|
181
326
|
label: 'stalled',
|
|
182
327
|
title: `Nothing has synced with ${project} in the ${min} minute${min === 1 ? '' : 's'} since Maude started trying.`,
|
|
183
|
-
next:
|
|
328
|
+
next: credentialUnknown
|
|
329
|
+
? 'Maude keeps retrying. If it persists, reconnect the workspace — the sign-in may have expired.'
|
|
330
|
+
: 'Maude keeps retrying — the workspace is reachable but is not completing handshakes.',
|
|
184
331
|
names: [],
|
|
185
332
|
};
|
|
186
333
|
};
|
|
@@ -203,6 +350,54 @@ export function syncPresentation(
|
|
|
203
350
|
const queued = status.queuedOps ?? 0;
|
|
204
351
|
const queueNote = queued > 0 ? ` ${queued} local edit${queued === 1 ? '' : 's'} are queued.` : '';
|
|
205
352
|
const unreachable = status.state === 'offline' || status.state === 'offline-long';
|
|
353
|
+
const lanes = readLanes(status);
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Part of the project did not get through. `sourceOnly` is the ranking
|
|
357
|
+
* split: a refused source change never heals on its own, so it outranks an
|
|
358
|
+
* unreachable hub; a failed transfer may be the outage itself, so file and
|
|
359
|
+
* media problems rank below it.
|
|
360
|
+
*/
|
|
361
|
+
const attention = (sourceOnly: boolean): SyncPresentation | null => {
|
|
362
|
+
const parts: string[] = [];
|
|
363
|
+
let items = 0;
|
|
364
|
+
const add = (n: number, text: string) => {
|
|
365
|
+
if (n <= 0) return;
|
|
366
|
+
parts.push(text);
|
|
367
|
+
items += n;
|
|
368
|
+
};
|
|
369
|
+
const src = lanes.sourceSlugs.length;
|
|
370
|
+
add(src, `${plural(src, 'source change')} ${src === 1 ? 'was' : 'were'} not applied`);
|
|
371
|
+
if (!sourceOnly) {
|
|
372
|
+
add(lanes.failedFiles, `${plural(lanes.failedFiles, 'file')} could not be delivered`);
|
|
373
|
+
add(
|
|
374
|
+
lanes.tooLarge,
|
|
375
|
+
`${plural(lanes.tooLarge, 'file')} ${lanes.tooLarge === 1 ? 'is' : 'are'} too large to sync`
|
|
376
|
+
);
|
|
377
|
+
add(
|
|
378
|
+
lanes.blockedOther,
|
|
379
|
+
`${plural(lanes.blockedOther, 'file')} ${lanes.blockedOther === 1 ? 'is' : 'are'} blocked`
|
|
380
|
+
);
|
|
381
|
+
add(
|
|
382
|
+
lanes.held,
|
|
383
|
+
`${plural(lanes.held, 'change')} ${lanes.held === 1 ? 'is' : 'are'} held for your decision`
|
|
384
|
+
);
|
|
385
|
+
add(lanes.failedMedia, `${plural(lanes.failedMedia, 'media upload')} failed`);
|
|
386
|
+
}
|
|
387
|
+
if (items === 0) return null;
|
|
388
|
+
return {
|
|
389
|
+
phase: 'attention',
|
|
390
|
+
online: false,
|
|
391
|
+
label: `${items} to review`,
|
|
392
|
+
title:
|
|
393
|
+
`${items === 1 ? 'A change needs' : `${items} changes need`} your attention in ${project}: ` +
|
|
394
|
+
`${parts.join('; ')}.` +
|
|
395
|
+
(unreachable ? ' The hub is also unreachable right now.' : '') +
|
|
396
|
+
queueNote,
|
|
397
|
+
next: 'Open the Sync panel to see what is waiting and why.',
|
|
398
|
+
names: shownNames(lanes.sourceSlugs),
|
|
399
|
+
};
|
|
400
|
+
};
|
|
206
401
|
// Validated, not taken on trust — see `readCounts`. `null` means "unreadable",
|
|
207
402
|
// which is deliberately NOT the same as "absent" (an old payload, handled
|
|
208
403
|
// below) and must never reach the synced branch.
|
|
@@ -232,6 +427,14 @@ export function syncPresentation(
|
|
|
232
427
|
};
|
|
233
428
|
}
|
|
234
429
|
|
|
430
|
+
// A refused SOURCE change outranks an unreachable hub for the same reason a
|
|
431
|
+
// refusal does: it is sticky, and it is the part that needs a person.
|
|
432
|
+
// (With the hub reachable, the same sentence lists every other lane too.)
|
|
433
|
+
if (lanes.sourceSlugs.length > 0) {
|
|
434
|
+
const sourceAttention = attention(unreachable);
|
|
435
|
+
if (sourceAttention) return sourceAttention;
|
|
436
|
+
}
|
|
437
|
+
|
|
235
438
|
// Otherwise an unreachable hub outranks every count. Whatever the documents
|
|
236
439
|
// last said, nothing is moving — and "72 synced" over a dead socket is the
|
|
237
440
|
// exact shape of lie this module exists to stop.
|
|
@@ -249,7 +452,7 @@ export function syncPresentation(
|
|
|
249
452
|
};
|
|
250
453
|
}
|
|
251
454
|
|
|
252
|
-
if (unreadable) {
|
|
455
|
+
if (unreadable || lanes.unreadable) {
|
|
253
456
|
// A payload we cannot read is not a payload that says everything is fine.
|
|
254
457
|
return {
|
|
255
458
|
phase: 'connecting',
|
|
@@ -265,7 +468,11 @@ export function syncPresentation(
|
|
|
265
468
|
// Pre-DDR-102 payload: `state` is all there is. Report it as the weaker
|
|
266
469
|
// evidence it is, rather than promoting it to a document-level claim.
|
|
267
470
|
const online = status.state === 'online' || status.flash === 'synced';
|
|
268
|
-
|
|
471
|
+
// Pre-DDR-102 payload — no per-document counts, so a refusal cannot be
|
|
472
|
+
// ruled out and the credential hedge stays.
|
|
473
|
+
if (!online && isStalled) return stalled(true);
|
|
474
|
+
const laneAttention = online ? attention(false) : null;
|
|
475
|
+
if (laneAttention) return laneAttention;
|
|
269
476
|
return {
|
|
270
477
|
phase: online ? 'synced' : 'connecting',
|
|
271
478
|
online,
|
|
@@ -292,6 +499,25 @@ export function syncPresentation(
|
|
|
292
499
|
};
|
|
293
500
|
}
|
|
294
501
|
|
|
502
|
+
// Needs a person, so it outranks work that will finish by itself.
|
|
503
|
+
const laneAttention = attention(false);
|
|
504
|
+
if (laneAttention) return laneAttention;
|
|
505
|
+
|
|
506
|
+
// Plan T16 — an AI edit that did not finish is kept on this device, not
|
|
507
|
+
// shared. It is the person's decision, so it reads as attention.
|
|
508
|
+
const ai = readAiAction(status.aiAction);
|
|
509
|
+
if (ai?.state === 'held') {
|
|
510
|
+
const n = ai.canvases;
|
|
511
|
+
return {
|
|
512
|
+
phase: 'attention',
|
|
513
|
+
online: true,
|
|
514
|
+
label: 'AI edit held',
|
|
515
|
+
title: `An unfinished AI edit to ${n} canvas${n === 1 ? '' : 'es'} is kept on this device — it is not shared with ${project} yet.`,
|
|
516
|
+
next: 'Open the Sync panel to publish it as it stands or discard it.',
|
|
517
|
+
names: [],
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
|
|
295
521
|
if (docs.pending > 0) {
|
|
296
522
|
// Zero settled yet is a different fact from some settled: one is a
|
|
297
523
|
// handshake in flight, the other is visible progress.
|
|
@@ -309,6 +535,61 @@ export function syncPresentation(
|
|
|
309
535
|
};
|
|
310
536
|
}
|
|
311
537
|
|
|
538
|
+
// Every canvas is in step, but files or media are still moving: that is
|
|
539
|
+
// syncing, not synced. The denominator is the ledger's (seed-progress.ts).
|
|
540
|
+
if (lanes.moving) {
|
|
541
|
+
const m = lanes.moving;
|
|
542
|
+
const detail =
|
|
543
|
+
'media' in m
|
|
544
|
+
? `uploading media (${m.media.done} of ${m.media.total})`
|
|
545
|
+
: m.tracked > 0
|
|
546
|
+
? `files ${m.delivered} of ${m.tracked} delivered`
|
|
547
|
+
: 'checking project files';
|
|
548
|
+
return {
|
|
549
|
+
phase: 'syncing',
|
|
550
|
+
online: true,
|
|
551
|
+
label:
|
|
552
|
+
'media' in m ? 'media ↑' : m.tracked > 0 ? `${m.delivered}/${m.tracked} files` : 'files…',
|
|
553
|
+
title:
|
|
554
|
+
`Syncing with ${project} — all ${total} canvas${total === 1 ? '' : 'es'} in step, ${detail}.` +
|
|
555
|
+
(lanes.paused ? ' Paused while the hub asks us to wait.' : '') +
|
|
556
|
+
queueNote,
|
|
557
|
+
next: 'Nothing to do — this continues on its own.',
|
|
558
|
+
names: [],
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
// Plan T29 — accepted revisions: "synced" documents only mean the replica is
|
|
563
|
+
// current. A change still waiting for the project's durable answer is saved
|
|
564
|
+
// on this device, not yet shared — so it is Saving, never Saved.
|
|
565
|
+
if (ai?.state === 'open') {
|
|
566
|
+
return {
|
|
567
|
+
phase: 'syncing',
|
|
568
|
+
online: true,
|
|
569
|
+
label: 'AI editing',
|
|
570
|
+
title: `An AI edit is in progress — its changes are shared with ${project} together when it finishes.`,
|
|
571
|
+
next: null,
|
|
572
|
+
names: [],
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
const acceptedPending = readAcceptedPending(status.accepted);
|
|
576
|
+
if (acceptedPending) {
|
|
577
|
+
const ageS = acceptedPending.oldestPendingAt
|
|
578
|
+
? Math.max(0, Math.round((Date.now() - acceptedPending.oldestPendingAt) / 1000))
|
|
579
|
+
: 0;
|
|
580
|
+
return {
|
|
581
|
+
phase: 'syncing',
|
|
582
|
+
online: true,
|
|
583
|
+
label: `saving ${acceptedPending.pending}`,
|
|
584
|
+
title:
|
|
585
|
+
`Saving ${acceptedPending.pending} change${acceptedPending.pending === 1 ? '' : 's'} to ${project}` +
|
|
586
|
+
(ageS >= 10 ? ` — the oldest has waited ${ageS} s.` : '.') +
|
|
587
|
+
' They are kept on this device until the project confirms them.',
|
|
588
|
+
next: ageS >= 60 ? 'Maude keeps trying. If this persists, check your connection.' : null,
|
|
589
|
+
names: [],
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
|
|
312
593
|
// Clamped and validated for the same reason as the doc counts: `count` is
|
|
313
594
|
// read off disk, and "1000000000 came down from the project" is not a
|
|
314
595
|
// sentence this module should be capable of producing. The ceiling is `total`
|
|
@@ -336,3 +617,28 @@ export function syncPresentation(
|
|
|
336
617
|
names: pulledCount > 0 ? shownNames(status.pulled?.names) : [],
|
|
337
618
|
};
|
|
338
619
|
}
|
|
620
|
+
|
|
621
|
+
/** `status.accepted`, validated — it is read off disk like every other count. */
|
|
622
|
+
function readAcceptedPending(
|
|
623
|
+
raw: unknown
|
|
624
|
+
): { pending: number; oldestPendingAt: number | null } | null {
|
|
625
|
+
if (!raw || typeof raw !== 'object') return null;
|
|
626
|
+
const r = raw as { pending?: unknown; oldestPendingAt?: unknown };
|
|
627
|
+
const pending = r.pending;
|
|
628
|
+
if (typeof pending !== 'number' || !Number.isInteger(pending) || pending <= 0 || pending > 1e6)
|
|
629
|
+
return null;
|
|
630
|
+
const at = r.oldestPendingAt;
|
|
631
|
+
return {
|
|
632
|
+
pending,
|
|
633
|
+
oldestPendingAt: typeof at === 'number' && Number.isFinite(at) && at > 0 ? at : null,
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
/** `status.aiAction`, validated — never trusted off disk. */
|
|
638
|
+
function readAiAction(raw: unknown): { state: 'open' | 'held'; canvases: number } | null {
|
|
639
|
+
if (!raw || typeof raw !== 'object') return null;
|
|
640
|
+
const r = raw as { state?: unknown; canvases?: unknown };
|
|
641
|
+
if (r.state !== 'open' && r.state !== 'held') return null;
|
|
642
|
+
const canvases = Array.isArray(r.canvases) ? Math.min(r.canvases.length, 10_000) : 0;
|
|
643
|
+
return { state: r.state, canvases };
|
|
644
|
+
}
|