@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
package/cli/lib/hubs-config.mjs
CHANGED
|
@@ -83,28 +83,55 @@ export function saveHubsConfig(config) {
|
|
|
83
83
|
*
|
|
84
84
|
* @param {string} url
|
|
85
85
|
* @param {string} token
|
|
86
|
-
* `role`
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
86
|
+
* `role` and `expiresAt` are the prior fields carried across a relink (Cloud
|
|
87
|
+
* Phase 25 C2; `expiresAt` added 2026-09-03).
|
|
88
|
+
*
|
|
89
|
+
* `role` records what the workspace vouched for at sign-in, and this path has
|
|
90
|
+
* no fresher answer — the CLI does not sign in. Dropping it would silently
|
|
91
|
+
* show a viewer the editing UI again, which is the exact experience the flag
|
|
90
92
|
* exists to prevent; a stale value costs a redundant hidden affordance and
|
|
91
|
-
* self-corrects at the next workspace sign-in.
|
|
92
|
-
*
|
|
93
|
+
* self-corrects at the next workspace sign-in.
|
|
94
|
+
*
|
|
95
|
+
* `expiresAt` is carried ONLY when the incoming token is byte-identical to the
|
|
96
|
+
* stored one — it describes the token, not the machine, so a new token
|
|
97
|
+
* invalidates it. Dropping it unconditionally is what left a linked project
|
|
98
|
+
* with no pre-expiry renewal timer at all.
|
|
99
|
+
*
|
|
100
|
+
* Nothing ELSE is preserved: `adoptedAt` is a per-machine attestation that a
|
|
101
|
+
* relink is entitled to clear.
|
|
93
102
|
*
|
|
94
103
|
* @param {{ adoptedAt?: number }} [extra]
|
|
95
104
|
*/
|
|
96
105
|
export function addHub(url, token, extra = {}) {
|
|
97
106
|
const norm = normalizeUrl(url);
|
|
98
107
|
const cfg = loadHubsConfig();
|
|
99
|
-
const
|
|
108
|
+
const prior = cfg.hubs[norm];
|
|
109
|
+
const priorRole = prior?.role;
|
|
100
110
|
// LOCAL CONSENT SURVIVES EVERY RE-SAVE. `role` is a cache of what the hub
|
|
101
111
|
// said about you at sign-in; `codeModulesAllowed` is what YOU said about the
|
|
102
112
|
// hub, and a login response must not be able to change it.
|
|
103
|
-
const priorConsent =
|
|
113
|
+
const priorConsent = prior?.codeModulesAllowed;
|
|
114
|
+
// THE EXPIRY BELONGS TO THE TOKEN, so it survives exactly when the token does.
|
|
115
|
+
//
|
|
116
|
+
// `expiresAt` is written only by the sign-in and renew paths in
|
|
117
|
+
// `apps/studio/` — the CLI has never written it and, before this, never
|
|
118
|
+
// carried it either. So `maude design link --adopt` after a workspace
|
|
119
|
+
// sign-in silently dropped it, and a record with no expiry means
|
|
120
|
+
// `scheduleRenewal()` arms no timer at all (sync/index.ts): the credential
|
|
121
|
+
// then dies mid-session with nothing having tried to renew it.
|
|
122
|
+
//
|
|
123
|
+
// CONDITIONAL ON TOKEN IDENTITY, and that is the whole subtlety. Carrying it
|
|
124
|
+
// unconditionally would be worse than dropping it: a stale expiry against a
|
|
125
|
+
// NEW token arms the timer at the wrong instant and burns a slot in the
|
|
126
|
+
// `renewalsSinceProgress` cap for nothing. Same argument as `role` above —
|
|
127
|
+
// "this path has no fresher answer" — except that a relink CAN supply a new
|
|
128
|
+
// token, which is what makes the check necessary.
|
|
129
|
+
const priorExpiry = prior?.token === token ? prior?.expiresAt : undefined;
|
|
104
130
|
cfg.hubs[norm] = {
|
|
105
131
|
token,
|
|
106
132
|
linkedAt: Date.now(),
|
|
107
133
|
...(priorRole ? { role: priorRole } : {}),
|
|
134
|
+
...(typeof priorExpiry === 'number' ? { expiresAt: priorExpiry } : {}),
|
|
108
135
|
...(typeof priorConsent === 'boolean' ? { codeModulesAllowed: priorConsent } : {}),
|
|
109
136
|
...extra,
|
|
110
137
|
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
|
|
5
|
+
const inventoryPath = join(
|
|
6
|
+
dirname(fileURLToPath(import.meta.url)),
|
|
7
|
+
'maude-projector.inventory.json'
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
function mergeAbsent(target, additions) {
|
|
11
|
+
for (const [name, value] of Object.entries(additions ?? {})) {
|
|
12
|
+
if (!Object.hasOwn(target, name)) target[name] = value;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export async function MaudeProjectorPlugin() {
|
|
17
|
+
let inventory = null;
|
|
18
|
+
try {
|
|
19
|
+
inventory = JSON.parse(await readFile(inventoryPath, 'utf8'));
|
|
20
|
+
} catch {
|
|
21
|
+
return {};
|
|
22
|
+
}
|
|
23
|
+
if (inventory?.schemaVersion !== 1 || inventory.target !== 'opencode') return {};
|
|
24
|
+
|
|
25
|
+
for (const [name, value] of Object.entries(inventory.environment ?? {})) {
|
|
26
|
+
if (!/^[A-Z_][A-Z0-9_]*$/.test(name) || typeof value !== 'string') continue;
|
|
27
|
+
const reference =
|
|
28
|
+
/^\$\{([A-Z_][A-Z0-9_]*)\}$/.exec(value)?.[1] ??
|
|
29
|
+
/^\{env:([A-Z_][A-Z0-9_]*)\}$/.exec(value)?.[1];
|
|
30
|
+
if (reference) {
|
|
31
|
+
if (process.env[reference] !== undefined) process.env[name] = process.env[reference];
|
|
32
|
+
} else {
|
|
33
|
+
process.env[name] = value;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
config: async (config) => {
|
|
39
|
+
config.agent ??= {};
|
|
40
|
+
config.command ??= {};
|
|
41
|
+
config.mcp ??= {};
|
|
42
|
+
config.permission ??= {};
|
|
43
|
+
mergeAbsent(config.agent, inventory.config.agent);
|
|
44
|
+
mergeAbsent(config.command, inventory.config.command);
|
|
45
|
+
mergeAbsent(config.mcp, inventory.config.mcp);
|
|
46
|
+
mergeAbsent(config.permission, inventory.config.permission);
|
|
47
|
+
config.instructions ??= [];
|
|
48
|
+
for (const path of inventory.config.instructions ?? []) {
|
|
49
|
+
if (!config.instructions.includes(path)) config.instructions.push(path);
|
|
50
|
+
}
|
|
51
|
+
config.skills ??= {};
|
|
52
|
+
config.skills.paths ??= [];
|
|
53
|
+
for (const path of inventory.config.skills?.paths ?? []) {
|
|
54
|
+
if (!config.skills.paths.includes(path)) config.skills.paths.push(path);
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Harness Capability Matrix
|
|
2
|
+
|
|
3
|
+
Reviewed: 2026-09-01
|
|
4
|
+
|
|
5
|
+
This document freezes the initial semantic contract for projecting a Claude Code and Maude environment into OpenCode and Codex. Claude remains the authoring source. A target status describes one representation only; it is not a claim of full parity.
|
|
6
|
+
|
|
7
|
+
## Tested Versions
|
|
8
|
+
|
|
9
|
+
| Harness | Version | Verification |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| Claude Code | 2.1.241 | Installed CLI plus current settings, hooks, subagent, skill, plugin, and MCP documentation. |
|
|
12
|
+
| OpenCode | 1.18.25 | Installed CLI; `opencode debug config` run with isolated `HOME` and `XDG_CONFIG_HOME`. |
|
|
13
|
+
| Codex | 0.152.0 | Installed CLI; generated config passed `codex --strict-config doctor --json` in an isolated `CODEX_HOME`. |
|
|
14
|
+
|
|
15
|
+
Generated output is valid only for a target version accepted by the versioned capability registry. Unknown target versions fail `check` and do not mutate target state.
|
|
16
|
+
|
|
17
|
+
## Status Contract
|
|
18
|
+
|
|
19
|
+
- `native`: the target documents compatible representation and relevant semantics.
|
|
20
|
+
- `degraded`: Maude can emit a narrower or differently-invoked representation and reports the exact loss.
|
|
21
|
+
- `unsupported`: no safe equivalent exists; Maude emits no active behavior.
|
|
22
|
+
- Security-relevant `degraded` records fail strict mode unless an explicit target override acknowledges that exact degradation.
|
|
23
|
+
- Security-relevant `unsupported` records always fail strict mode.
|
|
24
|
+
- Unknown capabilities fail closed and cannot be promoted by an override.
|
|
25
|
+
|
|
26
|
+
## Capability Matrix
|
|
27
|
+
|
|
28
|
+
| Source category | OpenCode | Codex | Fail-closed behavior |
|
|
29
|
+
| --- | --- | --- | --- |
|
|
30
|
+
| Global and project `CLAUDE.md` instructions | `native` fallback, `degraded` when a target instruction file shadows it | `native` through `project_doc_fallback_filenames`, `degraded` when `AGENTS.md` shadows it | Report the shadowing file; never overwrite or adopt it implicitly. |
|
|
31
|
+
| Imported Claude instructions | `degraded` to explicit `instructions` paths/globs | `degraded` to the `AGENTS.md` chain or a generated reference | Preserve source order and report import-semantic differences. |
|
|
32
|
+
| `.claude/rules/**/*.md` | `degraded` to scoped instruction globs | `degraded` to generated skill/instruction references | Do not claim Claude path-condition semantics when the target cannot enforce them. |
|
|
33
|
+
| Scalar Claude settings | `degraded` per registered key | `degraded` per registered key and allowed scope | Unknown keys are reported and omitted. |
|
|
34
|
+
| Map/list setting precedence | `degraded`; lower into OpenCode's merge layers | `degraded`; lower into Codex's CLI/project/profile/user/system layers | Retain all contributing sources; refuse ambiguous security conflicts. |
|
|
35
|
+
| User/project marketplace plugin selection | `degraded`; lower individual compatible assets | `native` plugin lifecycle in the pre-launch bridge; `degraded` in static projection | Runtime mirrors preserve selected plugin identity; static projection never claims lifecycle parity. |
|
|
36
|
+
| Claude custom commands | `degraded` to OpenCode commands | `degraded` to Codex skills/plugins | Preserve body and description; report frontmatter, argument, and invocation differences. |
|
|
37
|
+
| Claude subagents | `degraded` to OpenCode agents | `unsupported`; Codex custom agents inherit the parent tool registry | Do not emit a role whose Claude tool restrictions cannot be enforced; remove previously managed roles and report them. |
|
|
38
|
+
| Claude skills | `native` for target-valid `SKILL.md` assets | `native` for target-valid skills/plugin assets | Validate frontmatter and references; malformed skills are invalid source, not skipped. |
|
|
39
|
+
| STDIO MCP | `native` local MCP | `native` STDIO MCP | Preserve command/args and environment references without spawning the server. |
|
|
40
|
+
| Streamable HTTP MCP | `native` remote MCP | `native` HTTP MCP | Validate URL and reference syntax; never make a discovery-time request. |
|
|
41
|
+
| Legacy SSE MCP | `degraded` to remote transport after compatibility validation | `degraded` to streamable HTTP after compatibility validation | Disabled unless endpoint compatibility is explicitly proven. |
|
|
42
|
+
| Disabled MCP | `native` with `enabled: false` | `native` with `enabled: false` | A disabled source can never become enabled implicitly. |
|
|
43
|
+
| MCP OAuth | `degraded`; target OAuth options differ | `degraded`; target OAuth options differ | Unsupported callback/client-secret fields remain disabled and reported. |
|
|
44
|
+
| MCP headers and environment | `native` for `{env:NAME}`-style references after syntax conversion | `native` for target environment-backed header fields | Never interpolate variables; reject credential-shaped literals. |
|
|
45
|
+
| Command hooks with equivalent event, input, output, blocking, timeout, and failure semantics | `degraded` through exact compatible plugin hooks | `native` only for proven Codex hook equivalents and persisted hook trust | Any failed equivalence dimension leaves the hook disabled. |
|
|
46
|
+
| HTTP hooks | `unsupported` without a separately reviewed target-native implementation | `unsupported` | Emit no active hook and fail strict mode. |
|
|
47
|
+
| Prompt hooks | `unsupported` | `unsupported` | Parse for inventory, emit no active hook, fail strict mode. |
|
|
48
|
+
| Agent hooks | `unsupported` | `unsupported` | Parse for inventory, emit no active hook, fail strict mode. |
|
|
49
|
+
| Unknown hook handlers | `unsupported` | `unsupported` | Preserve the source inventory record, emit no active hook, and fail strict mode. |
|
|
50
|
+
| Hook matchers, output, and blocking decisions | `degraded` only when all semantics match | `degraded` only when all semantics match | Never approximate lifecycle events or discard hook output/errors. |
|
|
51
|
+
| Permission allow rules | `degraded` per exactly expressible tool/path/command scope | `degraded` through approval, sandbox, and exec-policy intersections | A scoped rule can never become blanket allow. |
|
|
52
|
+
| Permission ask rules | `degraded` where the target has the same approval boundary | `degraded` through approval policy plus sandbox/exec policy | If exact scope is unavailable, retain deny/default posture and report loss. |
|
|
53
|
+
| Permission deny rules | `degraded` per exactly expressible scope | `degraded` through sandbox and exec-policy denial; runtime `Read(path)` rules become stricter filesystem denies | Deny wins; an unrepresentable deny blocks migration or keeps runtime bypass inert. |
|
|
54
|
+
| Claude permission modes | `unsupported` as direct mappings | `degraded` to narrower approval/sandbox combinations; trusted runtime `bypassPermissions` uses a no-prompt permission profile | Static projection stays narrow. Runtime bypass activates only when every ask/deny rule is conservatively representable. |
|
|
55
|
+
| Generic environment injection | `degraded` through a bounded thin plugin using references | `degraded` through shell environment policy and MCP-specific fields | Preserve names/references only; do not read current values. |
|
|
56
|
+
| Keychain identifiers | `degraded` reference-only | `degraded` reference-only | Never read, copy, log, or back up resolved credentials. |
|
|
57
|
+
| `.ai/` state | `degraded` reference/register in place | `degraded` reference/register in place | Never copy the state tree into target directories. |
|
|
58
|
+
| `.design/` state | `degraded` reference/register in place | `degraded` reference/register in place | Never copy the state tree into target directories. |
|
|
59
|
+
| kgai prompt integration | `degraded` through bounded target-native prompt/plugin wiring | `degraded` through bounded target-native instruction/hook wiring | Treat graph output as untrusted data; transcript-dependent behavior remains disabled. |
|
|
60
|
+
| Target config ownership | `native` managed JSON entries/files through Maude manifest | `native` managed TOML entries/files through Maude manifest | Existing state requires preview and explicit adoption; external edits stop all writes. |
|
|
61
|
+
|
|
62
|
+
## Precedence Findings
|
|
63
|
+
|
|
64
|
+
Claude inputs are normalized from least to most specific while preserving every contributor: global instructions/settings/assets/MCP, user-enabled plugin assets, project instructions/settings/assets/MCP, project-enabled plugin assets, then `.claude/settings.local.json`. Claude settings lists generally accumulate, scalar/map conflicts prefer the higher-precedence layer, hooks accumulate, and permissions resolve deny before ask before allow.
|
|
65
|
+
|
|
66
|
+
OpenCode merges remote, global, custom-config, project, `.opencode`, inline, managed, and MDM configuration layers. Later conflicting values win; the projector therefore owns individual entries and one thin plugin registration rather than replacing a complete `opencode.json`.
|
|
67
|
+
|
|
68
|
+
Codex resolves CLI overrides, trusted project layers from root to current directory, the selected profile, user config, system config, and defaults, while managed requirements constrain the result. Project config cannot own provider/authentication, notification, profile-selection, or telemetry-routing settings.
|
|
69
|
+
|
|
70
|
+
## TOML Writer Decision
|
|
71
|
+
|
|
72
|
+
Codex managed merge will use exact-pinned `@decimalturn/toml-patch@3.0.5` under Node 20. It is dependency-free, supports TOML 1.1, and preserves comments, whitespace, formatting, and existing order. The writer must parse the complete existing document, mutate only manifest-owned keys in the parsed object, and patch the complete object back. Passing a partial object is forbidden because omitted user keys may be removed. Tests must cover comments, unknown keys, arrays of tables, idempotence, and malformed input.
|
|
73
|
+
|
|
74
|
+
## Active Adapter Audit
|
|
75
|
+
|
|
76
|
+
`~/Dotfiles/opencode/claude-parity.ts` is prior art, not a correctness oracle. The current adapter:
|
|
77
|
+
|
|
78
|
+
- widens any scoped `Bash(...)` allow to blanket Bash access;
|
|
79
|
+
- broadens `auto` and `bypassPermissions` to unrestricted read/edit/Bash/web/external-directory access;
|
|
80
|
+
- drops ask rules, most deny rules, MCP permission rules, and unknown tools;
|
|
81
|
+
- resolves `${NAME}` header references to live values;
|
|
82
|
+
- silently ignores malformed JSON/frontmatter and unsupported agent fields;
|
|
83
|
+
- approximates Claude `SessionStart`/`Stop`, runs discovered commands detached, and discards output/errors/timeouts/blocking behavior;
|
|
84
|
+
- injects a Codex MCP with independent `approval_policy="never"` and `sandbox_mode="workspace-write"`;
|
|
85
|
+
- has no ownership manifest, adoption, conflict detection, atomic transaction, rollback, or exhaustive inventory assertion.
|
|
86
|
+
|
|
87
|
+
None of these behaviors may be carried into the projector.
|
|
88
|
+
|
|
89
|
+
## Contract Transcript
|
|
90
|
+
|
|
91
|
+
The T0 spike used isolated homes and did not load user secrets:
|
|
92
|
+
|
|
93
|
+
```text
|
|
94
|
+
$ claude --version
|
|
95
|
+
2.1.241 (Claude Code)
|
|
96
|
+
|
|
97
|
+
$ opencode --version
|
|
98
|
+
1.18.25
|
|
99
|
+
|
|
100
|
+
$ HOME=<isolated> XDG_CONFIG_HOME=<isolated> opencode debug config
|
|
101
|
+
{ "$schema": "https://opencode.ai/config.json", "agent": {}, "plugin": [], "command": {} ... }
|
|
102
|
+
|
|
103
|
+
$ codex --version
|
|
104
|
+
codex-cli 0.152.0
|
|
105
|
+
|
|
106
|
+
$ pnpm view @decimalturn/toml-patch version time.modified engines dependencies
|
|
107
|
+
3.0.5; updated 2026-08-30; Node >=16; no dependencies
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Executable conformance in later gates must use isolated `HOME`, `XDG_CONFIG_HOME`, and `CODEX_HOME`, committed safe fixtures, and no arbitrary discovered hooks.
|
|
111
|
+
|
|
112
|
+
## Sources
|
|
113
|
+
|
|
114
|
+
- [Claude Code settings](https://docs.anthropic.com/en/docs/claude-code/settings)
|
|
115
|
+
- [Claude Code hooks](https://docs.anthropic.com/en/docs/claude-code/hooks)
|
|
116
|
+
- [Claude Code subagents](https://docs.anthropic.com/en/docs/claude-code/sub-agents)
|
|
117
|
+
- [Claude Code skills](https://docs.anthropic.com/en/docs/claude-code/skills)
|
|
118
|
+
- [OpenCode configuration](https://opencode.ai/docs/config/)
|
|
119
|
+
- [OpenCode plugins](https://opencode.ai/docs/plugins/)
|
|
120
|
+
- [OpenCode configuration source](https://github.com/anomalyco/opencode/blob/dev/packages/core/src/config.ts)
|
|
121
|
+
- [Codex configuration reference](https://developers.openai.com/codex/config-file/config-reference)
|
|
122
|
+
- [Codex AGENTS.md discovery](https://developers.openai.com/codex/agent-configuration/agents-md)
|
|
123
|
+
- [Codex hooks](https://developers.openai.com/codex/hooks)
|
|
124
|
+
- [Codex skills](https://developers.openai.com/codex/build-skills)
|
|
125
|
+
- [`@decimalturn/toml-patch`](https://www.npmjs.com/package/@decimalturn/toml-patch)
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Harness environment projection
|
|
2
|
+
|
|
3
|
+
Claude Code and Maude remain the authoring source. `maude harness` generates managed,
|
|
4
|
+
target-native OpenCode and Codex files without resolving secret references or copying
|
|
5
|
+
`.ai` and `.design` state.
|
|
6
|
+
|
|
7
|
+
Every command requires exactly one scope: `--global` or `--project <root>`. Projection
|
|
8
|
+
verbs require `--targets opencode,codex`; `adopt` and `remove` require one `--target`.
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
maude harness migrate --from claude --targets opencode,codex --project .
|
|
12
|
+
maude harness migrate --from claude --targets opencode,codex --project . --yes
|
|
13
|
+
maude harness sync --targets opencode,codex --project .
|
|
14
|
+
maude harness check --targets opencode,codex --project . --strict --json
|
|
15
|
+
maude harness status --project . --json
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
`migrate`, `diff`, and `adopt` preview by default. Mutations run only after complete
|
|
19
|
+
target-specific validation and confirmation or `--yes`. Confirmation never overrides
|
|
20
|
+
literal-secret rejection, unsupported security semantics, invalid sources or targets,
|
|
21
|
+
or ownership conflicts. `sync` commits all requested targets in one managed transaction.
|
|
22
|
+
|
|
23
|
+
Machine-local ownership, backups, recovery material, and manifests live below
|
|
24
|
+
`~/.config/maude/harness/`. `remove` touches manifest-owned output only and restores an
|
|
25
|
+
adopted backup when present. Generated reports contain references and hashes, not secret
|
|
26
|
+
values.
|
|
27
|
+
|
|
28
|
+
Exit codes are stable: `0` clean/success, `1` drift or declined preview, `2` usage,
|
|
29
|
+
`3` strict/unsupported security failure, `4` ownership conflict, `5` invalid source,
|
|
30
|
+
`6` invalid target/config/version, and `7` interrupted transaction or required recovery.
|
|
31
|
+
|
|
32
|
+
No postinstall, startup, plugin hook, or `maude init` path invokes harness mutation.
|
|
33
|
+
|
|
34
|
+
## Codex pre-launch bridge
|
|
35
|
+
|
|
36
|
+
`maude codex [args...]` is a separate machine-local bridge for daily Codex use. Before
|
|
37
|
+
launching the real Codex executable it reads the effective Claude plugin selection for
|
|
38
|
+
the current project when Codex marks that project trusted (otherwise only global Claude
|
|
39
|
+
selection applies), materializes owner-only runtime marketplace mirrors below
|
|
40
|
+
`~/.config/maude/harness/codex-runtime/`, and reconciles those plugins through Codex's
|
|
41
|
+
native `plugin marketplace` and `plugin add/remove` commands. `maude codex sync --json`
|
|
42
|
+
performs the same reconciliation without starting a session.
|
|
43
|
+
|
|
44
|
+
For a Codex-trusted project whose effective Claude settings select
|
|
45
|
+
`permissions.defaultMode: "bypassPermissions"`, the bridge adds a launch-only Codex
|
|
46
|
+
permission profile with `approval_policy="never"`, root filesystem write access, and
|
|
47
|
+
full network access. Claude `Read(path)` deny rules become stricter Codex filesystem
|
|
48
|
+
denies. Any Claude ask rule or unrepresentable deny keeps runtime bypass inert. These
|
|
49
|
+
overrides are passed on the command line and are not persisted. A pre-existing
|
|
50
|
+
`sandbox_mode`, an explicit sandbox/permission-profile override, a remote target, or an
|
|
51
|
+
ambiguous working-directory override keeps the launch fail-closed so the deny profile
|
|
52
|
+
cannot be silently disabled. Any `-C`/`--cd` path is authorized first and then forwarded
|
|
53
|
+
only in canonical form; path identity and trust are checked again immediately before
|
|
54
|
+
launch. Runtime-only defaults such as the skill context budget are also passed as CLI
|
|
55
|
+
overrides instead of rewriting user-owned Codex config.
|
|
56
|
+
|
|
57
|
+
`-C` and `--cd` are resolved before project trust and settings discovery, so authority
|
|
58
|
+
cannot be borrowed from one project and applied to another. Remote and Codex Cloud
|
|
59
|
+
sessions are rejected before runtime reconciliation, so local plugins, MCP state, and
|
|
60
|
+
permissions are never mutated for a remote launch. Runtime reconciliation is serialized
|
|
61
|
+
by the same crash-safe scope-lock primitive used by transactional harness writes.
|
|
62
|
+
|
|
63
|
+
Claude commands are exposed as namespaced Codex skills. Claude agents are reported but
|
|
64
|
+
not installed: Codex custom agents inherit the parent's tool registry, so a read-only
|
|
65
|
+
sandbox cannot enforce Claude agent tool restrictions. The bridge removes role files it
|
|
66
|
+
managed before this limitation was proven. Standalone Claude MCP servers are merged with
|
|
67
|
+
plugin MCP servers. Bearer credentials must reference an environment variable or exactly
|
|
68
|
+
match one already present in the launch environment; credential values are never pooled
|
|
69
|
+
into bridge state or persisted config. The current Codex CLI cannot write pass-through
|
|
70
|
+
environment names for STDIO MCP servers without materializing values, so the runtime bridge
|
|
71
|
+
rejects those entries; the transactional `maude harness` lowerer remains the supported path.
|
|
72
|
+
|
|
73
|
+
The bridge never writes into the current repository and does not copy `.ai` or `.design`.
|
|
74
|
+
A `CODEX_HOME` inside the current project is rejected rather than weakening that boundary.
|
|
75
|
+
A shell launcher may safely shadow the real Codex binary when it sets
|
|
76
|
+
`MAUDE_CODEX_REAL` to that binary before executing `maude codex`. This runtime path
|
|
77
|
+
complements the explicit, transactional `maude harness` migration workflow; it does not
|
|
78
|
+
adopt repository files or retire existing adapters by itself.
|
|
79
|
+
|
|
80
|
+
Real-workspace conformance can keep sources and generated target files physically
|
|
81
|
+
separate: set `MAUDE_HARNESS_SOURCE_HOME` to the read-only Claude source home and
|
|
82
|
+
`MAUDE_HARNESS_PROJECT_TARGET_ROOT` to a temporary project target root. These are
|
|
83
|
+
diagnostic/operator controls; normal migration should leave both unset. A temporary
|
|
84
|
+
source mirror may set the path-delimited `MAUDE_HARNESS_ALLOWED_PLUGIN_ROOTS` to
|
|
85
|
+
explicit read-only plugin cache roots referenced by its installation index.
|
|
86
|
+
|
|
87
|
+
The npm package contains the harness command, lowerers, capability/compatibility registry,
|
|
88
|
+
OpenCode runtime template, and Codex pre-launch bridge. Test fixtures, tests, backups, machine-local manifests,
|
|
89
|
+
logs, workspace metadata, and secrets are not part of that published harness surface.
|
|
90
|
+
|
|
91
|
+
Harness output is version-locked to the target versions listed by the capability registry
|
|
92
|
+
and to the machine-local manifest schema. `check` refuses an unsupported target or schema
|
|
93
|
+
before writing anything and prints two recovery choices: upgrade Maude for a newer registry,
|
|
94
|
+
or install the target version supported by the current Maude release. Never delete an
|
|
95
|
+
incompatible manifest or its backups as an upgrade shortcut.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@1agh/maude",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Marketplace of Claude Code plugins by Michal Dovrtěl: `design` (canvas-first design iteration) + `flow` (generic agentic workflow loop with .ai second brain). Ships the `maude` CLI (with `mdcc` legacy alias) to scaffold workspace, run the design dev server, and manage configs.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -51,20 +51,40 @@
|
|
|
51
51
|
"test:e2e:desktop:onboarding": "pnpm --filter @maude/desktop-e2e e2e:onboarding",
|
|
52
52
|
"test:e2e:desktop:acp-cold-start": "pnpm --filter @maude/desktop-e2e e2e:acp-cold-start",
|
|
53
53
|
"test:e2e:desktop:parity": "pnpm --filter @maude/desktop-e2e e2e:parity",
|
|
54
|
+
"test:e2e:desktop:sidecar-respawn": "pnpm --filter @maude/desktop-e2e e2e:sidecar-respawn",
|
|
55
|
+
"test:e2e:desktop:team-project": "pnpm --filter @maude/desktop-e2e e2e:team-project",
|
|
54
56
|
"test:e2e:desktop:parity:cloud": "pnpm --filter @maude/desktop-e2e e2e:parity:cloud"
|
|
55
57
|
},
|
|
56
58
|
"optionalDependencies": {
|
|
57
|
-
"@1agh/maude-darwin-arm64": "1.0
|
|
58
|
-
"@1agh/maude-darwin-x64": "1.0
|
|
59
|
-
"@1agh/maude-linux-arm64": "1.0
|
|
60
|
-
"@1agh/maude-linux-arm64-musl": "1.0
|
|
61
|
-
"@1agh/maude-linux-x64": "1.0
|
|
62
|
-
"@1agh/maude-linux-x64-musl": "1.0
|
|
63
|
-
"@1agh/maude-win32-x64": "1.0
|
|
59
|
+
"@1agh/maude-darwin-arm64": "1.3.0",
|
|
60
|
+
"@1agh/maude-darwin-x64": "1.3.0",
|
|
61
|
+
"@1agh/maude-linux-arm64": "1.3.0",
|
|
62
|
+
"@1agh/maude-linux-arm64-musl": "1.3.0",
|
|
63
|
+
"@1agh/maude-linux-x64": "1.3.0",
|
|
64
|
+
"@1agh/maude-linux-x64-musl": "1.3.0",
|
|
65
|
+
"@1agh/maude-win32-x64": "1.3.0"
|
|
64
66
|
},
|
|
65
67
|
"files": [
|
|
66
68
|
"cli",
|
|
69
|
+
"!cli/.platform-binary-path",
|
|
70
|
+
"!cli/**/*.test.mjs",
|
|
71
|
+
"!cli/fixtures",
|
|
72
|
+
"!cli/**/fixtures",
|
|
73
|
+
"!cli/**/backups",
|
|
74
|
+
"!cli/**/logs",
|
|
75
|
+
"!cli/**/.DS_Store",
|
|
67
76
|
"apps/studio",
|
|
77
|
+
"!apps/studio/.ai",
|
|
78
|
+
"!apps/studio/bun.lock",
|
|
79
|
+
"!apps/studio/test",
|
|
80
|
+
"!apps/studio/**/test",
|
|
81
|
+
"!apps/studio/**/tests",
|
|
82
|
+
"!apps/studio/**/fixtures",
|
|
83
|
+
"!apps/studio/**/backups",
|
|
84
|
+
"!apps/studio/**/logs",
|
|
85
|
+
"!apps/studio/**/*.test.*",
|
|
86
|
+
"!apps/studio/**/*.spec.*",
|
|
87
|
+
"!apps/studio/**/.DS_Store",
|
|
68
88
|
"plugins/design/dependencies.json",
|
|
69
89
|
"plugins/design/dependencies.schema.json",
|
|
70
90
|
"plugins/design/templates",
|
|
@@ -72,6 +92,8 @@
|
|
|
72
92
|
"plugins/flow/dependencies.schema.json",
|
|
73
93
|
"plugins/flow/templates",
|
|
74
94
|
"plugins/flow/.claude-plugin/config.schema.json",
|
|
95
|
+
"docs/harness-capability-matrix.md",
|
|
96
|
+
"docs/harness-environment-projection.md",
|
|
75
97
|
"LICENSE",
|
|
76
98
|
"README.md"
|
|
77
99
|
],
|
|
@@ -104,9 +126,11 @@
|
|
|
104
126
|
"lucide-react": "^1.24.0"
|
|
105
127
|
},
|
|
106
128
|
"dependencies": {
|
|
129
|
+
"@decimalturn/toml-patch": "3.0.5",
|
|
107
130
|
"ajv": "^8.20.0",
|
|
108
131
|
"ajv-formats": "^3.0.1",
|
|
109
132
|
"happy-dom": "20.10.6",
|
|
110
|
-
"svgo": "^4.0.1"
|
|
133
|
+
"svgo": "^4.0.1",
|
|
134
|
+
"yaml": "2.9.0"
|
|
111
135
|
}
|
|
112
136
|
}
|
|
@@ -152,11 +152,11 @@
|
|
|
152
152
|
"hardness": "soft",
|
|
153
153
|
"check": {
|
|
154
154
|
"command": "kg version",
|
|
155
|
-
"expectExit": 0
|
|
155
|
+
"expectExit": 0,
|
|
156
|
+
"minVersion": "1.5.1"
|
|
156
157
|
},
|
|
157
158
|
"install": {
|
|
158
|
-
"preferred": "
|
|
159
|
-
"darwin": "curl -fsSL https://github.com/kgaidev/kgai/releases/download/v1.0.0/kg-darwin-arm64 -o /usr/local/bin/kg && chmod +x /usr/local/bin/kg"
|
|
159
|
+
"preferred": "Install kgai >= 1.5.1 using https://github.com/kgaidev/kgai installation instructions; reuse the existing trusted store. Classic file workflows need no kgai installation."
|
|
160
160
|
},
|
|
161
161
|
"autoInstall": false,
|
|
162
162
|
"fallbackBehavior": "Design DS/canvas/brand decisions are not recorded to the kgai graph; the classic .ai/ path (via /flow:record-ddr) and on-disk sidecars are unchanged.",
|
|
@@ -138,6 +138,7 @@
|
|
|
138
138
|
"react-dom/client": "./_canvas-runtime/react-dom_client.js",
|
|
139
139
|
"react/jsx-runtime": "./_canvas-runtime/react_jsx-runtime.js",
|
|
140
140
|
"react/jsx-dev-runtime": "./_canvas-runtime/react_jsx-dev-runtime.js",
|
|
141
|
+
"sonner": "./_canvas-runtime/sonner.js",
|
|
141
142
|
"pixi.js": "./_canvas-runtime/pixi-js.js",
|
|
142
143
|
"@imgly/background-removal": "./_canvas-runtime/@imgly_background-removal.js",
|
|
143
144
|
"motion": "./_canvas-runtime/motion.js",
|
|
@@ -331,6 +332,7 @@
|
|
|
331
332
|
// - module: location.reload() — the canvas module re-fetches.
|
|
332
333
|
// - hard: location.reload() — _lib/* changed, everything re-bundles.
|
|
333
334
|
// The WS connection retries on close (dev-server restart resilience).
|
|
335
|
+
const pendingMediaHeals = new WeakMap();
|
|
334
336
|
function connectHmr() {
|
|
335
337
|
const proto = location.protocol === 'https:' ? 'wss' : 'ws';
|
|
336
338
|
// `base` for the same reason every other URL here carries it: on the
|
|
@@ -534,6 +536,51 @@
|
|
|
534
536
|
// working one is a cheap refetch of now-cached bytes.
|
|
535
537
|
el.setAttribute('href', href.split('?')[0] + '?v=' + v);
|
|
536
538
|
}
|
|
539
|
+
// A reference can reach a peer before its video/audio bytes.
|
|
540
|
+
// Retry failed players when those bytes arrive, without resetting
|
|
541
|
+
// healthy playback or dropping capability parameters from the URL.
|
|
542
|
+
const arrivedUrl = new URL(withCap('/' + designRel + '/' + msg.file), document.baseURI);
|
|
543
|
+
for (const media of document.querySelectorAll('video, audio')) {
|
|
544
|
+
if (media.readyState > 0) continue;
|
|
545
|
+
const candidates = media.hasAttribute('src')
|
|
546
|
+
? [media]
|
|
547
|
+
: Array.from(media.querySelectorAll('source[src]'));
|
|
548
|
+
const targets = candidates.flatMap((target) => {
|
|
549
|
+
const src = target.getAttribute('src');
|
|
550
|
+
if (!src) return [];
|
|
551
|
+
try {
|
|
552
|
+
const url = new URL(src, document.baseURI);
|
|
553
|
+
if (url.origin !== arrivedUrl.origin || url.pathname !== arrivedUrl.pathname) return [];
|
|
554
|
+
url.searchParams.set('v', String(v));
|
|
555
|
+
return [{ target, src, next: url.href }];
|
|
556
|
+
} catch { return []; }
|
|
557
|
+
});
|
|
558
|
+
if (!targets.length) continue;
|
|
559
|
+
pendingMediaHeals.get(media)?.();
|
|
560
|
+
const clear = () => {
|
|
561
|
+
media.removeEventListener('error', retry, true);
|
|
562
|
+
media.removeEventListener('loadedmetadata', clear);
|
|
563
|
+
media.removeEventListener('emptied', clear);
|
|
564
|
+
pendingMediaHeals.delete(media);
|
|
565
|
+
};
|
|
566
|
+
const retry = () => {
|
|
567
|
+
clear();
|
|
568
|
+
if (!media.isConnected || media.readyState > 0) return;
|
|
569
|
+
if (targets.some(({ target, src }) => target.getAttribute('src') !== src)) return;
|
|
570
|
+
for (const { target, next } of targets) target.setAttribute('src', next);
|
|
571
|
+
media.load();
|
|
572
|
+
};
|
|
573
|
+
if (media.error || media.networkState === 3) {
|
|
574
|
+
retry();
|
|
575
|
+
} else if (media.networkState === 2) {
|
|
576
|
+
// The initial response can still be an older in-flight 404.
|
|
577
|
+
// One arrival permits one retry; success/source change cancels it.
|
|
578
|
+
pendingMediaHeals.set(media, clear);
|
|
579
|
+
media.addEventListener('error', retry, true);
|
|
580
|
+
media.addEventListener('loadedmetadata', clear);
|
|
581
|
+
media.addEventListener('emptied', clear);
|
|
582
|
+
}
|
|
583
|
+
}
|
|
537
584
|
}
|
|
538
585
|
} catch (e) {
|
|
539
586
|
console.warn('[canvas-shell] HMR message parse error', e);
|
|
@@ -459,6 +459,14 @@
|
|
|
459
459
|
"minLength": 1
|
|
460
460
|
}
|
|
461
461
|
},
|
|
462
|
+
"qualityScoped": {
|
|
463
|
+
"type": "object",
|
|
464
|
+
"description": "Scoped (changed-files / changed-packages-only) gate variants for the IMPLEMENTATION inner loop (`/flow:utils-verify`, per-task `/flow:execute`, `/flow:bug-fix`). Same flat shape as `quality` — gate name → shell command string, keys mirror `quality` (conventionally `lint`, `format`, `typecheck`, `tests`). During implementation these run INSTEAD of the repo-wide `quality.*` commands; a missing key means the inner loop defers that gate to `/flow:validate` (it never falls back to the repo-wide command). `/flow:validate` and `/flow:done` ignore this block entirely — the full `quality.*` pipeline remains the single outer gate. Monorepo example: `\"lint\": \"turbo run lint --filter='[origin/main]'\"` — note changed-only `[base]`, NOT dependents-inclusive `...[base]`, which selects nearly the whole monorepo whenever a shared package is touched; dependent breakage is `/flow:validate`'s job.",
|
|
465
|
+
"additionalProperties": {
|
|
466
|
+
"type": "string",
|
|
467
|
+
"minLength": 1
|
|
468
|
+
}
|
|
469
|
+
},
|
|
462
470
|
"integrations": {
|
|
463
471
|
"type": "object",
|
|
464
472
|
"additionalProperties": false,
|
|
@@ -101,11 +101,11 @@
|
|
|
101
101
|
"hardness": "soft",
|
|
102
102
|
"check": {
|
|
103
103
|
"command": "kg version",
|
|
104
|
-
"expectExit": 0
|
|
104
|
+
"expectExit": 0,
|
|
105
|
+
"minVersion": "1.5.1"
|
|
105
106
|
},
|
|
106
107
|
"install": {
|
|
107
|
-
"preferred": "
|
|
108
|
-
"darwin": "curl -fsSL https://github.com/kgaidev/kgai/releases/download/v1.0.0/kg-darwin-arm64 -o /usr/local/bin/kg && chmod +x /usr/local/bin/kg"
|
|
108
|
+
"preferred": "Install kgai >= 1.5.1 using https://github.com/kgaidev/kgai installation instructions; reuse the existing trusted store. Classic file workflows need no kgai installation."
|
|
109
109
|
},
|
|
110
110
|
"autoInstall": false,
|
|
111
111
|
"fallbackBehavior": "flow/design fall back to the classic .ai/decisions/ + STATE.md file path (no regression). The kgai knowledge-graph backend (kg context/ingest/sync, cross-repo company memory) is inactive.",
|