@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.
Files changed (567) hide show
  1. package/README.md +3 -1
  2. package/apps/studio/acp/bridge.ts +18 -13
  3. package/apps/studio/acp/index.ts +43 -7
  4. package/apps/studio/acp/transcript-io.ts +394 -0
  5. package/apps/studio/acp/transcript.ts +103 -38
  6. package/apps/studio/annotations-layer.tsx +191 -116
  7. package/apps/studio/annotations-model.ts +39 -0
  8. package/apps/studio/annotations-sync.ts +50 -0
  9. package/apps/studio/api.ts +821 -55
  10. package/apps/studio/bin/_import-figma.mjs +57 -11
  11. package/apps/studio/bin/_seed-fixture.mjs +163 -0
  12. package/apps/studio/bin/annotate.mjs +3 -1
  13. package/apps/studio/bin/server-up.sh +17 -2
  14. package/apps/studio/canvas-edit.ts +391 -7
  15. package/apps/studio/canvas-imports.ts +89 -0
  16. package/apps/studio/canvas-lib.tsx +82 -18
  17. package/apps/studio/canvas-notice-message.ts +16 -0
  18. package/apps/studio/canvas-notifications.tsx +19 -0
  19. package/apps/studio/canvas-shell.tsx +57 -6
  20. package/apps/studio/client/app.jsx +943 -248
  21. package/apps/studio/client/apply-edit-request.ts +55 -0
  22. package/apps/studio/client/export-center.jsx +125 -67
  23. package/apps/studio/client/github.js +38 -1
  24. package/apps/studio/client/index-loader.ts +76 -0
  25. package/apps/studio/client/panels/CloudBar.jsx +52 -6
  26. package/apps/studio/client/panels/GitPanel.jsx +103 -0
  27. package/apps/studio/client/panels/OnboardingWizard.jsx +36 -7
  28. package/apps/studio/client/panels/RepoBranchSwitcher.jsx +92 -27
  29. package/apps/studio/client/panels/SourceConflictPanel.jsx +166 -0
  30. package/apps/studio/client/panels/SyncPanel.jsx +238 -4
  31. package/apps/studio/client/panels/TeamProjects.jsx +376 -0
  32. package/apps/studio/client/panels/file-deep-link-dialog.jsx +54 -0
  33. package/apps/studio/client/photo-knobs.jsx +3 -0
  34. package/apps/studio/client/report-bug.jsx +19 -1
  35. package/apps/studio/client/share-dialog.jsx +91 -0
  36. package/apps/studio/client/share-link.js +94 -0
  37. package/apps/studio/client/styles/3-shell-maude.css +69 -18
  38. package/apps/studio/client/styles/4-components.css +44 -1
  39. package/apps/studio/client/tree-row-menu.jsx +48 -3
  40. package/apps/studio/client/whats-new.jsx +26 -32
  41. package/apps/studio/cloud/endpoints.ts +132 -0
  42. package/apps/studio/collab/index.ts +4 -0
  43. package/apps/studio/collab/persistence.ts +137 -17
  44. package/apps/studio/collab/registry.ts +19 -21
  45. package/apps/studio/collab/room.ts +13 -2
  46. package/apps/studio/context.ts +59 -0
  47. package/apps/studio/debug-bundle.ts +13 -0
  48. package/apps/studio/dist/client.bundle.js +1911 -1879
  49. package/apps/studio/dist/runtime/.min-sizes.json +1 -0
  50. package/apps/studio/dist/runtime/sonner.js +1 -0
  51. package/apps/studio/dist/styles.css +1 -1
  52. package/apps/studio/export-dialog.tsx +54 -0
  53. package/apps/studio/exporters/degraded.ts +19 -3
  54. package/apps/studio/exporters/ghostscript.ts +194 -0
  55. package/apps/studio/exporters/pdf-fonts.ts +261 -0
  56. package/apps/studio/exporters/pdf.ts +152 -3
  57. package/apps/studio/exporters/remote.ts +36 -1
  58. package/apps/studio/fs-watch.ts +45 -1
  59. package/apps/studio/http.ts +296 -19
  60. package/apps/studio/inspect.ts +19 -0
  61. package/apps/studio/managed-projects.ts +150 -0
  62. package/apps/studio/mem.ts +45 -9
  63. package/apps/studio/notifications.tsx +292 -0
  64. package/apps/studio/runtime-bundle.ts +2 -0
  65. package/apps/studio/server.ts +69 -6
  66. package/apps/studio/sync/accepted-cold-start.ts +225 -0
  67. package/apps/studio/sync/accepted-link.ts +320 -0
  68. package/apps/studio/sync/action-stage.ts +343 -0
  69. package/apps/studio/sync/agent.ts +104 -45
  70. package/apps/studio/sync/asset-push.ts +1 -47
  71. package/apps/studio/sync/cell-file-events.ts +3 -0
  72. package/apps/studio/sync/codec.ts +192 -34
  73. package/apps/studio/sync/cold-start-apply.ts +7 -0
  74. package/apps/studio/sync/cold-start.ts +118 -22
  75. package/apps/studio/sync/comment-identity.ts +68 -0
  76. package/apps/studio/sync/connection-state.ts +15 -1
  77. package/apps/studio/sync/ctl-provider.ts +15 -2
  78. package/apps/studio/sync/document-discovery.ts +81 -0
  79. package/apps/studio/sync/file-ledger.ts +117 -0
  80. package/apps/studio/sync/file-membership.ts +10 -2
  81. package/apps/studio/sync/file-plane.ts +926 -47
  82. package/apps/studio/sync/index.ts +1786 -36
  83. package/apps/studio/sync/journal-client.ts +13 -1
  84. package/apps/studio/sync/migrate-seed.ts +150 -22
  85. package/apps/studio/sync/poke.ts +4 -2
  86. package/apps/studio/sync/presentation.ts +311 -5
  87. package/apps/studio/sync/projection.ts +820 -23
  88. package/apps/studio/sync/repeated-module.ts +73 -0
  89. package/apps/studio/sync/retry-after.ts +169 -0
  90. package/apps/studio/sync/revision-barrier.ts +129 -0
  91. package/apps/studio/sync/seed-progress.ts +218 -0
  92. package/apps/studio/sync/seed-repair.ts +46 -0
  93. package/apps/studio/sync/source-merge.ts +100 -0
  94. package/apps/studio/sync/source-ops.ts +289 -0
  95. package/apps/studio/sync/source-recovery.ts +70 -0
  96. package/apps/studio/sync/source-validation.ts +56 -0
  97. package/apps/studio/sync/status.ts +201 -6
  98. package/apps/studio/sync/transaction-client.ts +460 -0
  99. package/apps/studio/sync/transport-error.ts +111 -0
  100. package/apps/studio/sync/writer-registry.ts +236 -0
  101. package/apps/studio/text-caret.ts +35 -0
  102. package/apps/studio/undo-hud.tsx +9 -87
  103. package/apps/studio/use-canvas-media-drop.tsx +4 -39
  104. package/apps/studio/whats-new.json +173 -0
  105. package/cli/bin/maude.mjs +2 -0
  106. package/cli/commands/codex.mjs +191 -0
  107. package/cli/commands/harness.mjs +1051 -0
  108. package/cli/commands/help.mjs +13 -0
  109. package/cli/lib/design-link.mjs +190 -2
  110. package/cli/lib/harness/capabilities.mjs +302 -0
  111. package/cli/lib/harness/codex-runtime.mjs +892 -0
  112. package/cli/lib/harness/compatibility.mjs +27 -0
  113. package/cli/lib/harness/discover-claude.mjs +1393 -0
  114. package/cli/lib/harness/managed-state.mjs +1296 -0
  115. package/cli/lib/harness/model.mjs +86 -0
  116. package/cli/lib/harness/secrets.mjs +390 -0
  117. package/cli/lib/harness/targets/codex.mjs +1141 -0
  118. package/cli/lib/harness/targets/opencode.mjs +807 -0
  119. package/cli/lib/harness/transaction.mjs +1099 -0
  120. package/cli/lib/hubs-config.mjs +35 -8
  121. package/cli/templates/harness/opencode/maude-projector.ts +58 -0
  122. package/docs/harness-capability-matrix.md +125 -0
  123. package/docs/harness-environment-projection.md +95 -0
  124. package/package.json +33 -9
  125. package/plugins/design/dependencies.json +3 -3
  126. package/plugins/design/templates/_shell.html +47 -0
  127. package/plugins/flow/.claude-plugin/config.schema.json +8 -0
  128. package/plugins/flow/dependencies.json +3 -3
  129. package/apps/studio/.ai/cache/_stats.json +0 -7
  130. package/apps/studio/bin/_agent-browser-safe.test.mjs +0 -165
  131. package/apps/studio/bin/_curl-local.test.mjs +0 -280
  132. package/apps/studio/bin/_pw-launch.test.mjs +0 -90
  133. package/apps/studio/bin/_smart-frames.test.mjs +0 -195
  134. package/apps/studio/bin/_transcribe.test.mjs +0 -80
  135. package/apps/studio/bun.lock +0 -928
  136. package/apps/studio/draw/test/animate.test.ts +0 -172
  137. package/apps/studio/draw/test/brush.test.ts +0 -213
  138. package/apps/studio/draw/test/composition.test.ts +0 -141
  139. package/apps/studio/draw/test/geometry.test.ts +0 -199
  140. package/apps/studio/draw/test/gradient.test.ts +0 -167
  141. package/apps/studio/draw/test/layout.test.ts +0 -120
  142. package/apps/studio/draw/test/morph.test.ts +0 -107
  143. package/apps/studio/draw/test/optimize.test.ts +0 -40
  144. package/apps/studio/draw/test/palette.test.ts +0 -123
  145. package/apps/studio/draw/test/primitives.test.ts +0 -129
  146. package/apps/studio/draw/test/serialize-animate.test.ts +0 -142
  147. package/apps/studio/draw/test/serialize.test.ts +0 -105
  148. package/apps/studio/figma/assets.test.ts +0 -464
  149. package/apps/studio/figma/client.test.ts +0 -395
  150. package/apps/studio/figma/codegen-client.test.ts +0 -276
  151. package/apps/studio/figma/codegen-fonts.test.ts +0 -103
  152. package/apps/studio/figma/codegen-values.test.ts +0 -179
  153. package/apps/studio/figma/comments-to-strokes.test.ts +0 -194
  154. package/apps/studio/figma/fig-decode.test.ts +0 -788
  155. package/apps/studio/figma/fig-differential.test.ts +0 -182
  156. package/apps/studio/figma/fig-translator.test.ts +0 -192
  157. package/apps/studio/figma/fig-vector.test.ts +0 -113
  158. package/apps/studio/figma/from-codegen.test.ts +0 -408
  159. package/apps/studio/figma/sanitize.test.ts +0 -325
  160. package/apps/studio/figma/tailwind-map.test.ts +0 -142
  161. package/apps/studio/figma/to-artboard.test.ts +0 -808
  162. package/apps/studio/figma/to-render.test.ts +0 -180
  163. package/apps/studio/figma/to-strokes-roundtrip.test.ts +0 -152
  164. package/apps/studio/figma/to-strokes.test.ts +0 -705
  165. package/apps/studio/figma/to-tokens.test.ts +0 -321
  166. package/apps/studio/figma/url.test.ts +0 -167
  167. package/apps/studio/footage/schema.test.ts +0 -287
  168. package/apps/studio/generation/adapters/groq.test.ts +0 -80
  169. package/apps/studio/generation/audio-library.test.ts +0 -95
  170. package/apps/studio/generation/captions.test.ts +0 -78
  171. package/apps/studio/generation/elevenlabs.test.ts +0 -223
  172. package/apps/studio/generation/gemini.test.ts +0 -350
  173. package/apps/studio/generation/jobs.test.ts +0 -128
  174. package/apps/studio/generation/keys.test.ts +0 -75
  175. package/apps/studio/generation/prefs.test.ts +0 -95
  176. package/apps/studio/generation/types.test.ts +0 -123
  177. package/apps/studio/generation/whisper-models.test.ts +0 -179
  178. package/apps/studio/test/_helpers.ts +0 -108
  179. package/apps/studio/test/acp-activity-endpoint.test.ts +0 -183
  180. package/apps/studio/test/acp-activity.test.ts +0 -154
  181. package/apps/studio/test/acp-ai-activity.test.ts +0 -182
  182. package/apps/studio/test/acp-attachment-serve.test.ts +0 -74
  183. package/apps/studio/test/acp-bootstrap-brief.test.ts +0 -178
  184. package/apps/studio/test/acp-branch-guard.test.ts +0 -123
  185. package/apps/studio/test/acp-bridge-lifetime.test.ts +0 -475
  186. package/apps/studio/test/acp-bridge.test.ts +0 -545
  187. package/apps/studio/test/acp-capabilities.test.ts +0 -123
  188. package/apps/studio/test/acp-caps-bridge.test.ts +0 -279
  189. package/apps/studio/test/acp-commands.test.ts +0 -119
  190. package/apps/studio/test/acp-elicitation-bridge.test.ts +0 -480
  191. package/apps/studio/test/acp-elicitation.test.ts +0 -251
  192. package/apps/studio/test/acp-env.test.ts +0 -95
  193. package/apps/studio/test/acp-mode-banner.test.ts +0 -45
  194. package/apps/studio/test/acp-origin-gate.test.ts +0 -160
  195. package/apps/studio/test/acp-permission-prompt.test.ts +0 -251
  196. package/apps/studio/test/acp-permission.test.ts +0 -278
  197. package/apps/studio/test/acp-plugin-bootstrap.test.ts +0 -89
  198. package/apps/studio/test/acp-session-allowed-tools.test.ts +0 -235
  199. package/apps/studio/test/acp-session-plugins.test.ts +0 -209
  200. package/apps/studio/test/acp-toolgroup.test.ts +0 -76
  201. package/apps/studio/test/acp-transcript-view.test.ts +0 -71
  202. package/apps/studio/test/acp-transcript.test.ts +0 -238
  203. package/apps/studio/test/acp-usage-bridge.test.ts +0 -141
  204. package/apps/studio/test/acp-usage.test.ts +0 -143
  205. package/apps/studio/test/acp-write-gate.test.ts +0 -323
  206. package/apps/studio/test/acp-write-scope.test.ts +0 -533
  207. package/apps/studio/test/active-state.test.ts +0 -186
  208. package/apps/studio/test/activity.test.ts +0 -189
  209. package/apps/studio/test/ai-activity.test.ts +0 -113
  210. package/apps/studio/test/annotate-write.test.ts +0 -1074
  211. package/apps/studio/test/annotation-strokes-command.test.ts +0 -166
  212. package/apps/studio/test/annotations-align.test.ts +0 -88
  213. package/apps/studio/test/annotations-api.test.ts +0 -145
  214. package/apps/studio/test/annotations-bindings.test.ts +0 -262
  215. package/apps/studio/test/annotations-draw-modifiers.test.ts +0 -206
  216. package/apps/studio/test/annotations-groups.test.ts +0 -231
  217. package/apps/studio/test/annotations-layer.test.ts +0 -1011
  218. package/apps/studio/test/annotations-roundtrip.test.ts +0 -663
  219. package/apps/studio/test/annotations-snap.test.ts +0 -135
  220. package/apps/studio/test/annotations-text-format.test.ts +0 -396
  221. package/apps/studio/test/artboard-activity-overlay.test.tsx +0 -56
  222. package/apps/studio/test/artboard-guides-overlay.test.tsx +0 -152
  223. package/apps/studio/test/artboard-hug-commit.test.ts +0 -36
  224. package/apps/studio/test/artboard-kinds.test.tsx +0 -83
  225. package/apps/studio/test/artboard-selection-attrs.test.ts +0 -69
  226. package/apps/studio/test/asset-api.test.ts +0 -149
  227. package/apps/studio/test/assets-s3.test.ts +0 -249
  228. package/apps/studio/test/binary-smoke.test.ts +0 -47
  229. package/apps/studio/test/boot-self-heal.test.ts +0 -87
  230. package/apps/studio/test/browse-posture.test.tsx +0 -107
  231. package/apps/studio/test/bundle-smoke.test.ts +0 -46
  232. package/apps/studio/test/camera-reveal.test.tsx +0 -173
  233. package/apps/studio/test/canvas-artifacts.test.ts +0 -125
  234. package/apps/studio/test/canvas-build-sandbox.test.ts +0 -69
  235. package/apps/studio/test/canvas-build.test.ts +0 -141
  236. package/apps/studio/test/canvas-create-api.test.ts +0 -676
  237. package/apps/studio/test/canvas-cursors.test.ts +0 -164
  238. package/apps/studio/test/canvas-edit.test.ts +0 -470
  239. package/apps/studio/test/canvas-freshness-deps.test.ts +0 -64
  240. package/apps/studio/test/canvas-header.test.ts +0 -127
  241. package/apps/studio/test/canvas-hide-chrome.test.ts +0 -88
  242. package/apps/studio/test/canvas-hmr-runtime.test.tsx +0 -114
  243. package/apps/studio/test/canvas-lib-inline.test.ts +0 -146
  244. package/apps/studio/test/canvas-lib-motion.test.ts +0 -131
  245. package/apps/studio/test/canvas-lib-resolver.test.ts +0 -111
  246. package/apps/studio/test/canvas-list-watch.test.ts +0 -388
  247. package/apps/studio/test/canvas-media-drop.test.ts +0 -187
  248. package/apps/studio/test/canvas-meta-api.test.ts +0 -707
  249. package/apps/studio/test/canvas-move-api.test.ts +0 -587
  250. package/apps/studio/test/canvas-origin-gate.test.ts +0 -417
  251. package/apps/studio/test/canvas-pipeline.test.ts +0 -180
  252. package/apps/studio/test/canvas-rects.test.ts +0 -198
  253. package/apps/studio/test/canvas-reorder.test.ts +0 -211
  254. package/apps/studio/test/canvas-route.test.ts +0 -179
  255. package/apps/studio/test/canvas-shell-base.test.ts +0 -107
  256. package/apps/studio/test/canvas-shell-build-error.test.ts +0 -52
  257. package/apps/studio/test/canvas-url.test.ts +0 -138
  258. package/apps/studio/test/canvas-wheel-delta.test.ts +0 -42
  259. package/apps/studio/test/canvas-zoom-floor.test.ts +0 -73
  260. package/apps/studio/test/capture-core.test.ts +0 -32
  261. package/apps/studio/test/capture-determinism-shape.test.ts +0 -135
  262. package/apps/studio/test/chat-attachments.test.ts +0 -117
  263. package/apps/studio/test/chat-context.test.ts +0 -129
  264. package/apps/studio/test/chat-markdown.test.tsx +0 -58
  265. package/apps/studio/test/clip-addressing.test.ts +0 -738
  266. package/apps/studio/test/clip-ops.test.ts +0 -922
  267. package/apps/studio/test/cloud-build.test.ts +0 -95
  268. package/apps/studio/test/cloud-connect-note.test.ts +0 -135
  269. package/apps/studio/test/cloud-endpoints.test.ts +0 -590
  270. package/apps/studio/test/cloud-history-hardening.test.ts +0 -165
  271. package/apps/studio/test/cloud-history-posture.test.ts +0 -230
  272. package/apps/studio/test/cloud-managed-save-surfaces.test.ts +0 -90
  273. package/apps/studio/test/cloud-renew.test.ts +0 -205
  274. package/apps/studio/test/cloud-session-role.test.ts +0 -161
  275. package/apps/studio/test/cloud-shell-surfaces.test.ts +0 -170
  276. package/apps/studio/test/cold-start-apply.test.ts +0 -303
  277. package/apps/studio/test/collab-annotations-bridge.test.ts +0 -55
  278. package/apps/studio/test/collab-awareness-bridge.test.ts +0 -223
  279. package/apps/studio/test/collab-bridge.test.ts +0 -79
  280. package/apps/studio/test/collab-loopback.test.ts +0 -63
  281. package/apps/studio/test/collab-origin-gate.test.ts +0 -323
  282. package/apps/studio/test/collab-protocol.test.ts +0 -146
  283. package/apps/studio/test/collab-readonly-gate.test.ts +0 -194
  284. package/apps/studio/test/collab-reseed-guard.test.ts +0 -78
  285. package/apps/studio/test/collab-room.test.ts +0 -188
  286. package/apps/studio/test/collab-session-survival.test.tsx +0 -176
  287. package/apps/studio/test/collab-stress.test.ts +0 -129
  288. package/apps/studio/test/comment-mount.test.ts +0 -97
  289. package/apps/studio/test/comment-relay-origin-gate.test.ts +0 -117
  290. package/apps/studio/test/comments-api.test.ts +0 -277
  291. package/apps/studio/test/comments-fs-rebroadcast.test.ts +0 -155
  292. package/apps/studio/test/comments-overlay.test.ts +0 -117
  293. package/apps/studio/test/compile-entry.test.ts +0 -133
  294. package/apps/studio/test/component-map.test.ts +0 -48
  295. package/apps/studio/test/config-projection.test.ts +0 -104
  296. package/apps/studio/test/config-reload.test.ts +0 -230
  297. package/apps/studio/test/config-version.test.ts +0 -88
  298. package/apps/studio/test/context-resolve-tokens.test.ts +0 -97
  299. package/apps/studio/test/convert-to-absolute.test.ts +0 -333
  300. package/apps/studio/test/credential-grammar.test.ts +0 -107
  301. package/apps/studio/test/csp-canvas-shell.test.ts +0 -62
  302. package/apps/studio/test/csrf-write-guard.test.ts +0 -141
  303. package/apps/studio/test/debug-bundle.test.ts +0 -105
  304. package/apps/studio/test/design-setup-readiness.test.ts +0 -155
  305. package/apps/studio/test/detach-component.test.ts +0 -94
  306. package/apps/studio/test/dns-rebinding-guard.test.ts +0 -101
  307. package/apps/studio/test/dom-selection.test.ts +0 -198
  308. package/apps/studio/test/dynamic-text-edit.test.ts +0 -162
  309. package/apps/studio/test/edit-css-occurrence.test.ts +0 -81
  310. package/apps/studio/test/edit-persistence.test.ts +0 -91
  311. package/apps/studio/test/edit-scope-api.test.ts +0 -119
  312. package/apps/studio/test/edit-source-command.test.ts +0 -142
  313. package/apps/studio/test/edit-suppress.test.ts +0 -170
  314. package/apps/studio/test/editing-presence.test.ts +0 -103
  315. package/apps/studio/test/element-resize.test.ts +0 -136
  316. package/apps/studio/test/element-structural-api.test.ts +0 -434
  317. package/apps/studio/test/element-structural-edit.test.ts +0 -750
  318. package/apps/studio/test/ensure-browser.test.ts +0 -92
  319. package/apps/studio/test/equal-spacing-detector.test.ts +0 -257
  320. package/apps/studio/test/export-assemble.test.ts +0 -53
  321. package/apps/studio/test/export-browser-lane.test.ts +0 -126
  322. package/apps/studio/test/export-capture-fidelity.test.ts +0 -146
  323. package/apps/studio/test/export-capture-hygiene.test.ts +0 -675
  324. package/apps/studio/test/export-center.test.tsx +0 -287
  325. package/apps/studio/test/export-e2e-lanes.test.ts +0 -857
  326. package/apps/studio/test/export-format-scope-coherence.test.ts +0 -89
  327. package/apps/studio/test/export-lane.test.ts +0 -245
  328. package/apps/studio/test/export-shim-multi-capture.test.ts +0 -83
  329. package/apps/studio/test/exporters/canva.test.ts +0 -63
  330. package/apps/studio/test/exporters/degraded-propagation.test.ts +0 -123
  331. package/apps/studio/test/exporters/endpoint.test.ts +0 -121
  332. package/apps/studio/test/exporters/history.test.ts +0 -107
  333. package/apps/studio/test/exporters/html.test.ts +0 -26
  334. package/apps/studio/test/exporters/jobs.test.ts +0 -342
  335. package/apps/studio/test/exporters/pdf.test.ts +0 -85
  336. package/apps/studio/test/exporters/png.test.ts +0 -103
  337. package/apps/studio/test/exporters/pptx-deck.test.ts +0 -112
  338. package/apps/studio/test/exporters/pptx.test.ts +0 -31
  339. package/apps/studio/test/exporters/pw-launch.test.ts +0 -49
  340. package/apps/studio/test/exporters/runtime.test.ts +0 -59
  341. package/apps/studio/test/exporters/scope.test.ts +0 -292
  342. package/apps/studio/test/exporters/svg.test.ts +0 -29
  343. package/apps/studio/test/exporters/unsupported-media.test.ts +0 -123
  344. package/apps/studio/test/exporters/zip.test.ts +0 -104
  345. package/apps/studio/test/fetch-asset-gate.test.ts +0 -189
  346. package/apps/studio/test/figjam-v3-model.test.ts +0 -342
  347. package/apps/studio/test/figma-explode.test.ts +0 -438
  348. package/apps/studio/test/figma-provenance.test.ts +0 -108
  349. package/apps/studio/test/figma-routes.test.ts +0 -294
  350. package/apps/studio/test/file-lock.test.ts +0 -84
  351. package/apps/studio/test/fixtures/backgrounding-claude-auth.sh +0 -12
  352. package/apps/studio/test/fixtures/fake-claude-auth.mjs +0 -23
  353. package/apps/studio/test/fixtures/figjam-v3-groups-bindings.svg +0 -1
  354. package/apps/studio/test/fixtures/mock-acp-agent-caps.mjs +0 -158
  355. package/apps/studio/test/fixtures/mock-acp-agent-commands.mjs +0 -44
  356. package/apps/studio/test/fixtures/mock-acp-agent-elicit-flood.mjs +0 -46
  357. package/apps/studio/test/fixtures/mock-acp-agent-elicit-url.mjs +0 -42
  358. package/apps/studio/test/fixtures/mock-acp-agent-elicit.mjs +0 -63
  359. package/apps/studio/test/fixtures/mock-acp-agent-permission-flood.mjs +0 -51
  360. package/apps/studio/test/fixtures/mock-acp-agent-permission.mjs +0 -50
  361. package/apps/studio/test/fixtures/mock-acp-agent-slow.mjs +0 -45
  362. package/apps/studio/test/fixtures/mock-acp-agent-usage.mjs +0 -56
  363. package/apps/studio/test/fixtures/mock-acp-agent-wedged.mjs +0 -37
  364. package/apps/studio/test/fixtures/mock-acp-agent-write.mjs +0 -118
  365. package/apps/studio/test/fixtures/mock-acp-agent.mjs +0 -69
  366. package/apps/studio/test/fixtures/noisy-claude-auth.mjs +0 -27
  367. package/apps/studio/test/fixtures/perf-canvas.mjs +0 -201
  368. package/apps/studio/test/fixtures/phase-20-annotations.svg +0 -1
  369. package/apps/studio/test/fixtures/phase-21-annotations.svg +0 -1
  370. package/apps/studio/test/fixtures/tiny-subset.woff2 +0 -0
  371. package/apps/studio/test/fixtures/video-comp-fixture.tsx +0 -82
  372. package/apps/studio/test/fixtures/wedged-claude-auth.sh +0 -11
  373. package/apps/studio/test/footage-store.test.ts +0 -100
  374. package/apps/studio/test/fs-mkdir-api.test.ts +0 -248
  375. package/apps/studio/test/fs-watch.test.ts +0 -41
  376. package/apps/studio/test/gemma-models.test.ts +0 -245
  377. package/apps/studio/test/generate-route.test.ts +0 -106
  378. package/apps/studio/test/git-api.test.ts +0 -0
  379. package/apps/studio/test/git-branches.test.ts +0 -341
  380. package/apps/studio/test/git-cloud-posture.test.ts +0 -59
  381. package/apps/studio/test/git-grouping.test.ts +0 -106
  382. package/apps/studio/test/git-lifecycle.test.ts +0 -100
  383. package/apps/studio/test/git-log-format.test.ts +0 -95
  384. package/apps/studio/test/git-safe-rel.test.ts +0 -132
  385. package/apps/studio/test/git-system-engine.test.ts +0 -135
  386. package/apps/studio/test/git-watch.test.ts +0 -97
  387. package/apps/studio/test/github-api.test.ts +0 -577
  388. package/apps/studio/test/grid-track-handles.test.ts +0 -160
  389. package/apps/studio/test/handoff-static-frames.test.ts +0 -215
  390. package/apps/studio/test/handoff.test.ts +0 -329
  391. package/apps/studio/test/history-rollback.test.ts +0 -88
  392. package/apps/studio/test/hmr-broadcast.test.ts +0 -236
  393. package/apps/studio/test/hmr-classify.test.ts +0 -87
  394. package/apps/studio/test/hub-link.test.ts +0 -80
  395. package/apps/studio/test/identity-cache.test.ts +0 -83
  396. package/apps/studio/test/import-asset-browser.test.ts +0 -64
  397. package/apps/studio/test/import-asset-route.test.ts +0 -71
  398. package/apps/studio/test/import-asset.test.ts +0 -427
  399. package/apps/studio/test/import-brand-browser.test.ts +0 -88
  400. package/apps/studio/test/import-brand-route.test.ts +0 -120
  401. package/apps/studio/test/import-brand.test.ts +0 -206
  402. package/apps/studio/test/import-figma.test.ts +0 -667
  403. package/apps/studio/test/import-tokens.test.ts +0 -722
  404. package/apps/studio/test/index-data-canvas-ds.test.ts +0 -97
  405. package/apps/studio/test/input-router.test.ts +0 -757
  406. package/apps/studio/test/inspect-script-syntax.test.ts +0 -53
  407. package/apps/studio/test/inspect-selections.test.ts +0 -219
  408. package/apps/studio/test/knob-props-authored.test.ts +0 -87
  409. package/apps/studio/test/layers-synthetic-groups.test.ts +0 -96
  410. package/apps/studio/test/locator.test.ts +0 -214
  411. package/apps/studio/test/marquee-overlay.test.ts +0 -94
  412. package/apps/studio/test/media-commit-chain.test.ts +0 -210
  413. package/apps/studio/test/mode-toggle.test.tsx +0 -226
  414. package/apps/studio/test/motion-sample.test.ts +0 -35
  415. package/apps/studio/test/move-artboards-command.test.ts +0 -108
  416. package/apps/studio/test/participants-chrome.test.ts +0 -65
  417. package/apps/studio/test/paths.test.ts +0 -88
  418. package/apps/studio/test/pdf-print-boxes.test.ts +0 -359
  419. package/apps/studio/test/peer-selection-follows-camera.test.tsx +0 -131
  420. package/apps/studio/test/perf-harness.ts +0 -193
  421. package/apps/studio/test/phase-3.6-smoke.test.ts +0 -79
  422. package/apps/studio/test/photo-bg-remove-validation.test.ts +0 -71
  423. package/apps/studio/test/photo-canvas-bundle.test.ts +0 -79
  424. package/apps/studio/test/photo-edit-api.test.ts +0 -201
  425. package/apps/studio/test/photo-filters.test.ts +0 -149
  426. package/apps/studio/test/photo-pipeline.test.ts +0 -106
  427. package/apps/studio/test/photo-taxonomy.test.ts +0 -96
  428. package/apps/studio/test/print-marks.test.ts +0 -113
  429. package/apps/studio/test/print-units.test.ts +0 -173
  430. package/apps/studio/test/read-annotations.test.ts +0 -727
  431. package/apps/studio/test/read-only-gate.test.ts +0 -188
  432. package/apps/studio/test/read-only-role.test.ts +0 -95
  433. package/apps/studio/test/readiness.test.ts +0 -337
  434. package/apps/studio/test/remote-ahead-behind-cache.test.ts +0 -89
  435. package/apps/studio/test/reorder-api.test.ts +0 -210
  436. package/apps/studio/test/repo-concurrency.test.ts +0 -146
  437. package/apps/studio/test/repo-lock.test.ts +0 -350
  438. package/apps/studio/test/report-proxy.test.ts +0 -125
  439. package/apps/studio/test/ripple.test.ts +0 -197
  440. package/apps/studio/test/runtime-bundle-error-mapping.test.ts +0 -43
  441. package/apps/studio/test/runtime-bundle.test.ts +0 -69
  442. package/apps/studio/test/sanitize-annotation-svg.test.ts +0 -238
  443. package/apps/studio/test/scaffold-design.test.ts +0 -122
  444. package/apps/studio/test/server-lifecycle.test.ts +0 -38
  445. package/apps/studio/test/session-runtime-state.test.ts +0 -226
  446. package/apps/studio/test/session-scope.test.ts +0 -100
  447. package/apps/studio/test/shared-doc-cell-pairing.test.ts +0 -642
  448. package/apps/studio/test/shared-doc-convergence.test.ts +0 -265
  449. package/apps/studio/test/shared-doc-foundation.test.ts +0 -63
  450. package/apps/studio/test/shared-doc-migrate.test.ts +0 -369
  451. package/apps/studio/test/shared-doc-projection.test.ts +0 -238
  452. package/apps/studio/test/shell-importmap.test.ts +0 -56
  453. package/apps/studio/test/sizing-mode.test.ts +0 -102
  454. package/apps/studio/test/slash-commands.test.ts +0 -117
  455. package/apps/studio/test/snap-distance-pill.test.ts +0 -68
  456. package/apps/studio/test/spacing-handles.test.ts +0 -138
  457. package/apps/studio/test/specimen-select.test.ts +0 -88
  458. package/apps/studio/test/sync-agent.test.ts +0 -660
  459. package/apps/studio/test/sync-annotations-cold-start.test.ts +0 -302
  460. package/apps/studio/test/sync-asset-push.test.ts +0 -931
  461. package/apps/studio/test/sync-atomic-write.test.ts +0 -62
  462. package/apps/studio/test/sync-attach-incremental.test.ts +0 -527
  463. package/apps/studio/test/sync-autocommit.test.ts +0 -537
  464. package/apps/studio/test/sync-canvas-path.test.ts +0 -200
  465. package/apps/studio/test/sync-cell-write-nudge.test.ts +0 -346
  466. package/apps/studio/test/sync-codec.test.ts +0 -230
  467. package/apps/studio/test/sync-cold-seed-dedup.test.ts +0 -187
  468. package/apps/studio/test/sync-cold-start.test.ts +0 -304
  469. package/apps/studio/test/sync-connect-honesty.test.ts +0 -114
  470. package/apps/studio/test/sync-connection-state.test.ts +0 -337
  471. package/apps/studio/test/sync-ctl-channel.test.ts +0 -508
  472. package/apps/studio/test/sync-decide-file.test.ts +0 -420
  473. package/apps/studio/test/sync-doc-name.test.ts +0 -281
  474. package/apps/studio/test/sync-echo-guard.test.ts +0 -96
  475. package/apps/studio/test/sync-file-ledger.test.ts +0 -334
  476. package/apps/studio/test/sync-file-membership.test.ts +0 -347
  477. package/apps/studio/test/sync-file-plane.test.ts +0 -976
  478. package/apps/studio/test/sync-file-pull.test.ts +0 -333
  479. package/apps/studio/test/sync-fresh-link-parity.test.ts +0 -267
  480. package/apps/studio/test/sync-fs-mirror.test.ts +0 -181
  481. package/apps/studio/test/sync-hardening.test.ts +0 -586
  482. package/apps/studio/test/sync-hub-listing.test.ts +0 -46
  483. package/apps/studio/test/sync-hubs-config.test.ts +0 -133
  484. package/apps/studio/test/sync-incident-replay.test.ts +0 -211
  485. package/apps/studio/test/sync-journal.test.ts +0 -176
  486. package/apps/studio/test/sync-meta-codec.test.ts +0 -199
  487. package/apps/studio/test/sync-migrate-flat-fallback.test.ts +0 -98
  488. package/apps/studio/test/sync-move-retirement.test.ts +0 -231
  489. package/apps/studio/test/sync-panel-surface.test.ts +0 -153
  490. package/apps/studio/test/sync-path-pull.test.ts +0 -531
  491. package/apps/studio/test/sync-presentation.test.ts +0 -262
  492. package/apps/studio/test/sync-pull-budget.test.ts +0 -169
  493. package/apps/studio/test/sync-remote-docs.test.ts +0 -333
  494. package/apps/studio/test/sync-resync-routes.test.ts +0 -168
  495. package/apps/studio/test/sync-runtime.test.ts +0 -1675
  496. package/apps/studio/test/sync-seed-defers-to-hub.test.ts +0 -83
  497. package/apps/studio/test/sync-settings-routes.test.ts +0 -195
  498. package/apps/studio/test/sync-settings.test.ts +0 -151
  499. package/apps/studio/test/sync-status.test.ts +0 -261
  500. package/apps/studio/test/sync-supervisor.test.ts +0 -262
  501. package/apps/studio/test/sync-tombstone-apply.test.ts +0 -111
  502. package/apps/studio/test/sync-trash.test.ts +0 -132
  503. package/apps/studio/test/sync-two-peer-discovery.test.ts +0 -343
  504. package/apps/studio/test/sync-untrusted.test.ts +0 -103
  505. package/apps/studio/test/system-endpoint.test.ts +0 -144
  506. package/apps/studio/test/text-editability-stamp.test.ts +0 -131
  507. package/apps/studio/test/timeline-comp-target.test.ts +0 -139
  508. package/apps/studio/test/timeline-media-cache.test.ts +0 -41
  509. package/apps/studio/test/timeline-parse.test.ts +0 -184
  510. package/apps/studio/test/timeline-scale.test.ts +0 -65
  511. package/apps/studio/test/timeline-snap.test.ts +0 -85
  512. package/apps/studio/test/tool-palette-insert-anchor.test.ts +0 -86
  513. package/apps/studio/test/tool-palette.test.tsx +0 -55
  514. package/apps/studio/test/tour-overlay.test.tsx +0 -90
  515. package/apps/studio/test/trusted-request-host.test.ts +0 -66
  516. package/apps/studio/test/undo-sequence-byte-compare.test.ts +0 -211
  517. package/apps/studio/test/undo-stack.test.ts +0 -244
  518. package/apps/studio/test/use-agent-presence.test.tsx +0 -117
  519. package/apps/studio/test/use-annotation-resize.test.ts +0 -402
  520. package/apps/studio/test/use-annotation-selection.test.tsx +0 -77
  521. package/apps/studio/test/use-artboard-drag.test.ts +0 -324
  522. package/apps/studio/test/use-canvas-activity.test.tsx +0 -206
  523. package/apps/studio/test/use-collab.test.ts +0 -0
  524. package/apps/studio/test/use-cursor-modifiers.test.ts +0 -59
  525. package/apps/studio/test/use-keyboard-discipline.test.ts +0 -27
  526. package/apps/studio/test/use-selection-set.test.tsx +0 -166
  527. package/apps/studio/test/use-snap-guides.test.ts +0 -271
  528. package/apps/studio/test/use-tool-mode.test.tsx +0 -186
  529. package/apps/studio/test/use-undo-stack.test.tsx +0 -223
  530. package/apps/studio/test/video-asset.test.ts +0 -163
  531. package/apps/studio/test/video-comp-fixture.test.ts +0 -50
  532. package/apps/studio/test/video-comp.test.ts +0 -270
  533. package/apps/studio/test/video-encode-lib.test.ts +0 -63
  534. package/apps/studio/test/video-render-bridge.test.ts +0 -171
  535. package/apps/studio/test/whats-new.test.ts +0 -113
  536. package/apps/studio/test/whisper-setup.test.ts +0 -97
  537. package/apps/studio/test/workspace-containment.test.ts +0 -382
  538. package/apps/studio/test/workspace-signin.test.ts +0 -292
  539. package/apps/studio/test/ws-handshake.test.ts +0 -33
  540. package/cli/commands/cache.test.mjs +0 -166
  541. package/cli/commands/design-link.test.mjs +0 -419
  542. package/cli/commands/design.test.mjs +0 -240
  543. package/cli/commands/doctor.test.mjs +0 -237
  544. package/cli/commands/hub-workspace.test.mjs +0 -275
  545. package/cli/commands/hub.test.mjs +0 -225
  546. package/cli/commands/kg.test.mjs +0 -142
  547. package/cli/commands/preflight.test.mjs +0 -46
  548. package/cli/lib/argv.test.mjs +0 -46
  549. package/cli/lib/cache.test.mjs +0 -303
  550. package/cli/lib/cell-plan.test.mjs +0 -225
  551. package/cli/lib/config-lint.test.mjs +0 -117
  552. package/cli/lib/ddr-to-kgai.test.mjs +0 -118
  553. package/cli/lib/design-ownership.test.mjs +0 -329
  554. package/cli/lib/fetch-asset.test.mjs +0 -213
  555. package/cli/lib/figma-codegen-reachability.test.mjs +0 -104
  556. package/cli/lib/figma-import-controls.test.mjs +0 -70
  557. package/cli/lib/flow-design-integration.test.mjs +0 -165
  558. package/cli/lib/gitignore-block.test.mjs +0 -136
  559. package/cli/lib/gitignore-drift.test.mjs +0 -156
  560. package/cli/lib/hubs-config.test.mjs +0 -165
  561. package/cli/lib/pkg-root.test.mjs +0 -111
  562. package/cli/lib/plugin-cli-reachability.test.mjs +0 -57
  563. package/cli/lib/plugin-name-namespace.test.mjs +0 -71
  564. package/cli/lib/reconstruct-toolset.test.mjs +0 -194
  565. package/cli/lib/stack-detect.test.mjs +0 -121
  566. package/cli/lib/update-check.test.mjs +0 -32
  567. package/cli/lib/workspace-plan.test.mjs +0 -699
@@ -83,28 +83,55 @@ export function saveHubsConfig(config) {
83
83
  *
84
84
  * @param {string} url
85
85
  * @param {string} token
86
- * `role` is the ONE prior field carried across a relink (Cloud Phase 25 C2).
87
- * It records what the workspace vouched for at sign-in, and this path has no
88
- * fresher answer — the CLI does not sign in. Dropping it would silently show
89
- * a viewer the editing UI again, which is the exact experience the flag
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. Nothing ELSE is preserved:
92
- * `adoptedAt` is a per-machine attestation that a relink is entitled to clear.
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 priorRole = cfg.hubs[norm]?.role;
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 = cfg.hubs[norm]?.codeModulesAllowed;
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.11",
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.11",
58
- "@1agh/maude-darwin-x64": "1.0.11",
59
- "@1agh/maude-linux-arm64": "1.0.11",
60
- "@1agh/maude-linux-arm64-musl": "1.0.11",
61
- "@1agh/maude-linux-x64": "1.0.11",
62
- "@1agh/maude-linux-x64-musl": "1.0.11",
63
- "@1agh/maude-win32-x64": "1.0.11"
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": "See docs/kgai-onboarding.md — download the pinned kgai release binary (kgai is capability-gated + opt-out; nothing to install to use classic .ai/ mode)",
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": "See docs/kgai-onboarding.md — download the pinned kgai release binary (kgai is capability-gated + opt-out; nothing to install to use classic .ai/ mode)",
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.",
@@ -1,7 +0,0 @@
1
- {
2
- "hits": {},
3
- "misses": {
4
- "security": 2
5
- },
6
- "since": 1783681711349
7
- }