@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
@@ -1,249 +0,0 @@
1
- // Cloud Phase 3 Task 2 — the S3/R2 asset lane.
2
- //
3
- // Exercised against a live in-process S3-shaped server rather than MinIO: the
4
- // properties worth proving are content-addressing, verification of bytes
5
- // received from a semi-trusted hub, and never failing a local save because a
6
- // bucket was unreachable. None of those need a storage vendor.
7
-
8
- import { afterAll, beforeAll, describe, expect, test } from 'bun:test';
9
-
10
- import { createServer, type Server } from 'node:http';
11
- import type { AddressInfo } from 'node:net';
12
- // The HUB's independent SigV4 implementation — imported to pin the two against
13
- // each other, exactly as the doc-namespace grammars are pinned.
14
- import { signRequest as hubSignRequest } from '../../hub/src/s3.mjs';
15
- import {
16
- createAssetMirror,
17
- type S3Config,
18
- s3ConfigFromEnv,
19
- sha8,
20
- sha8FromAssetPath,
21
- signRequest,
22
- verifyAssetBytes,
23
- } from '../assets-s3.ts';
24
-
25
- let server: Server;
26
- let store: Map<string, Uint8Array>;
27
- let seenAuth: string[];
28
- let cfg: S3Config;
29
-
30
- beforeAll(async () => {
31
- store = new Map();
32
- seenAuth = [];
33
- server = createServer((req, res) => {
34
- seenAuth.push(req.headers.authorization ?? '');
35
- const key = decodeURIComponent(
36
- new URL(req.url ?? '/', 'http://x').pathname.replace('/maude-assets/', '')
37
- );
38
- if (req.method === 'PUT') {
39
- const chunks: Buffer[] = [];
40
- req.on('data', (c) => chunks.push(c));
41
- req.on('end', () => {
42
- store.set(key, new Uint8Array(Buffer.concat(chunks)));
43
- res.writeHead(200).end();
44
- });
45
- return;
46
- }
47
- if (req.method === 'HEAD') {
48
- res.writeHead(store.has(key) ? 200 : 404).end();
49
- return;
50
- }
51
- if (req.method === 'GET') {
52
- const body = store.get(key);
53
- if (!body) {
54
- res.writeHead(404).end();
55
- return;
56
- }
57
- res.writeHead(200).end(Buffer.from(body));
58
- return;
59
- }
60
- res.writeHead(405).end();
61
- });
62
- await new Promise<void>((resolve) => server.listen(0, '127.0.0.1', () => resolve()));
63
- cfg = {
64
- endpoint: `http://127.0.0.1:${(server.address() as AddressInfo).port}`,
65
- bucket: 'maude-assets',
66
- accessKeyId: 'AKIAEXAMPLE',
67
- secretAccessKey: 'secret',
68
- region: 'auto',
69
- };
70
- });
71
-
72
- afterAll(async () => {
73
- await new Promise<void>((resolve) => server.close(() => resolve()));
74
- });
75
-
76
- const bytesFor = (s: string) => new TextEncoder().encode(s);
77
- const assetPath = (b: Uint8Array, ext = 'png') => `assets/${sha8(b)}.${ext}`;
78
-
79
- describe('content addressing', () => {
80
- test('sha8 is stable and differs for different bytes', () => {
81
- const a = bytesFor('hello');
82
- expect(sha8(a)).toBe(sha8(new Uint8Array(a)));
83
- expect(sha8(a)).not.toBe(sha8(bytesFor('hellp')));
84
- expect(sha8(a)).toMatch(/^[0-9a-f]{8}$/);
85
- });
86
-
87
- test('sha8FromAssetPath accepts content-addressed paths and refuses others', () => {
88
- expect(sha8FromAssetPath('assets/deadbeef.png')).toBe('deadbeef');
89
- expect(sha8FromAssetPath('assets/deadbeef')).toBe('deadbeef');
90
- expect(sha8FromAssetPath('assets/deadbeef.mp4')).toBe('deadbeef');
91
- // The shapes the REAL corpus contains beyond saveAsset's own output — a
92
- // dotted sidecar and hash+label ingested footage. A stricter pattern
93
- // classified these as "not content addressed", which made the mirror
94
- // refuse legitimate assets as unverifiable.
95
- expect(sha8FromAssetPath('assets/deadbeef.photo.json')).toBe('deadbeef');
96
- expect(sha8FromAssetPath('assets/deadbeef.footage.json')).toBe('deadbeef');
97
- expect(sha8FromAssetPath('assets/deadbeef-cloud.mp4')).toBe('deadbeef');
98
- expect(sha8FromAssetPath('assets/deadbeef-cloud.srt')).toBe('deadbeef');
99
- // Legacy / hand-placed / traversal shapes are not content-addressed. The
100
- // 8 hex chars must be a COMPLETE token — `deadbeef1` is a different name.
101
- expect(sha8FromAssetPath('assets/my-photo.png')).toBe(null);
102
- expect(sha8FromAssetPath('assets/DEADBEEF.png')).toBe(null);
103
- expect(sha8FromAssetPath('assets/deadbeef1.png')).toBe(null);
104
- expect(sha8FromAssetPath('assets/deadbeefcafe.png')).toBe(null);
105
- expect(sha8FromAssetPath('assets/sub/deadbeef.png')).toBe(null);
106
- expect(sha8FromAssetPath('../assets/deadbeef.png')).toBe(null);
107
- expect(sha8FromAssetPath('')).toBe(null);
108
- });
109
-
110
- test('verifyAssetBytes is the check that makes a semi-trusted hub usable', () => {
111
- const bytes = bytesFor('the real image');
112
- const path = assetPath(bytes);
113
- expect(verifyAssetBytes(path, bytes)).toBe(true);
114
- // ...including the labelled and sidecar shapes.
115
- expect(verifyAssetBytes(`assets/${sha8(bytes)}-cloud.mp4`, bytes)).toBe(true);
116
- expect(verifyAssetBytes(`assets/${sha8(bytes)}.photo.json`, bytes)).toBe(true);
117
- // Substituted content under the same name — the attack DDR-054 describes.
118
- expect(verifyAssetBytes(path, bytesFor('malicious replacement'))).toBe(false);
119
- // A path with no content address cannot be verified, so it is not trusted.
120
- expect(verifyAssetBytes('assets/logo.png', bytes)).toBe(false);
121
- });
122
- });
123
-
124
- describe('config', () => {
125
- test('an unconfigured lane is the default, not an error', () => {
126
- expect(s3ConfigFromEnv({})).toBe(null);
127
- // Partial config must not half-enable the lane.
128
- expect(s3ConfigFromEnv({ MAUDE_S3_BUCKET: 'b', MAUDE_S3_ENDPOINT: 'e' })).toBe(null);
129
- const mirror = createAssetMirror(null);
130
- expect(mirror.configured).toBe(false);
131
- });
132
-
133
- test('a full env set configures it, trailing slash trimmed, region defaulted', () => {
134
- const resolved = s3ConfigFromEnv({
135
- MAUDE_S3_ENDPOINT: 'https://acct.r2.cloudflarestorage.com/',
136
- MAUDE_S3_BUCKET: 'maude-assets',
137
- MAUDE_S3_ACCESS_KEY_ID: 'AKIA',
138
- MAUDE_S3_SECRET_ACCESS_KEY: 'secret',
139
- });
140
- expect(resolved?.endpoint).toBe('https://acct.r2.cloudflarestorage.com');
141
- expect(resolved?.region).toBe('auto');
142
- });
143
- });
144
-
145
- describe('SigV4 — pinned against the hub implementation', () => {
146
- test('studio and hub sign the same request identically', () => {
147
- // Two independent implementations in two independently-built packages. If
148
- // they drift, one of them is wrong against real R2 and nobody would notice
149
- // until a deploy.
150
- const shared = {
151
- endpoint: 'https://acct.r2.cloudflarestorage.com',
152
- bucket: 'maude-assets',
153
- accessKeyId: 'AKIAEXAMPLE',
154
- secretAccessKey: 'wJalrXUtnFEMI',
155
- region: 'auto',
156
- };
157
- const now = new Date('2026-07-28T20:30:00Z');
158
- for (const key of ['assets/deadbeef.png', 'assets/a b+c!.png', 'assets/ünïcode.png']) {
159
- for (const body of [null, bytesFor('payload')]) {
160
- const mine = signRequest(shared, { method: 'PUT', key, body, now });
161
- const theirs = hubSignRequest(shared, { method: 'PUT', key, body, now });
162
- expect(mine.headers.authorization).toBe(theirs.headers.authorization);
163
- expect(mine.url).toBe(theirs.url);
164
- }
165
- }
166
- });
167
-
168
- test('the payload is signed, so different bytes give a different signature', () => {
169
- const now = new Date('2026-07-28T20:30:00Z');
170
- const a = signRequest(cfg, { method: 'PUT', key: 'assets/x.png', body: bytesFor('a'), now });
171
- const b = signRequest(cfg, { method: 'PUT', key: 'assets/x.png', body: bytesFor('b'), now });
172
- expect(a.headers.authorization).not.toBe(b.headers.authorization);
173
- });
174
- });
175
-
176
- describe('the mirror, against a live S3-shaped server', () => {
177
- test('push then pull round-trips, and every request is signed', async () => {
178
- const mirror = createAssetMirror(cfg);
179
- const bytes = bytesFor('a small png, pretend');
180
- const rel = assetPath(bytes);
181
-
182
- expect(await mirror.push(rel, bytes)).toBe(true);
183
- expect(await mirror.has(rel)).toBe(true);
184
- const pulled = await mirror.pull(rel);
185
- expect(pulled).not.toBe(null);
186
- expect([...(pulled ?? [])]).toEqual([...bytes]);
187
-
188
- expect(seenAuth.length).toBeGreaterThan(0);
189
- expect(seenAuth.every((a) => a.startsWith('AWS4-HMAC-SHA256 Credential='))).toBe(true);
190
- });
191
-
192
- test('push is idempotent — content addressing means a re-push is a no-op', async () => {
193
- const mirror = createAssetMirror(cfg);
194
- const bytes = bytesFor('idempotent content');
195
- const rel = assetPath(bytes);
196
- expect(await mirror.push(rel, bytes)).toBe(true);
197
- const sizeAfterFirst = store.size;
198
- expect(await mirror.push(rel, bytes)).toBe(true);
199
- expect(store.size).toBe(sizeAfterFirst);
200
- });
201
-
202
- test('a missing object pulls as null, not an error', async () => {
203
- const mirror = createAssetMirror(cfg);
204
- expect(await mirror.pull('assets/00000000.png')).toBe(null);
205
- expect(await mirror.has('assets/00000000.png')).toBe(false);
206
- });
207
-
208
- test('SUBSTITUTED bytes are REFUSED — the hub cannot swap an asset', async () => {
209
- // Plant content under a name it does not hash to, exactly as a compromised
210
- // or malicious hub would. The pull must refuse rather than write it to disk,
211
- // where it would poison every peer that later mirrors from us.
212
- const honest = bytesFor('the real asset');
213
- const rel = assetPath(honest);
214
- store.set(rel, bytesFor('malicious replacement of the same length!!'));
215
-
216
- const warnings: string[] = [];
217
- const mirror = createAssetMirror(cfg, { log: { warn: (m: string) => warnings.push(m) } });
218
- expect(await mirror.pull(rel)).toBe(null);
219
- expect(warnings.join(' ')).toMatch(/does not hash to its own name/);
220
- });
221
-
222
- test('an unreachable bucket NEVER fails the caller — it returns false', async () => {
223
- // The local file is already on disk and in git; the bucket is the redundant
224
- // copy. Throwing here would turn a network blip into a failed save.
225
- const dead = createAssetMirror(
226
- { ...cfg, endpoint: 'http://127.0.0.1:1' },
227
- { log: { warn: () => {} } }
228
- );
229
- expect(await dead.push('assets/deadbeef.png', bytesFor('x'))).toBe(false);
230
- expect(await dead.pull('assets/deadbeef.png')).toBe(null);
231
- expect(await dead.has('assets/deadbeef.png')).toBe(false);
232
- });
233
-
234
- test('a non-2xx response is handled like a miss, not a crash', async () => {
235
- const mirror = createAssetMirror(
236
- { ...cfg, bucket: 'wrong-bucket' },
237
- { log: { warn: () => {} } }
238
- );
239
- expect(await mirror.pull('assets/deadbeef.png')).toBe(null);
240
- });
241
-
242
- test('the unconfigured mirror answers safely for every verb', async () => {
243
- const mirror = createAssetMirror(null);
244
- expect(await mirror.push('assets/deadbeef.png', bytesFor('x'))).toBe(false);
245
- expect(await mirror.pull('assets/deadbeef.png')).toBe(null);
246
- expect(await mirror.has('assets/deadbeef.png')).toBe(false);
247
- expect(mirror.describe).toBe('none');
248
- });
249
- });
@@ -1,47 +0,0 @@
1
- // Smoke: dist/maude-<platform> compiles + spawns + exits cleanly.
2
- //
3
- // We run this only when the compiled binary is already present. The full
4
- // `bun build --compile` step costs ~150 ms; CI matrix already proves it on
5
- // every release tag (Task 13). Local devs see this skip silently unless they
6
- // have already run `bun run build.ts --release`.
7
-
8
- import { describe, expect, test } from 'bun:test';
9
- import { join } from 'node:path';
10
-
11
- const PLATFORM_SLUG = (() => {
12
- const p = process.platform;
13
- const a = process.arch;
14
- if (p === 'darwin') return a === 'arm64' ? 'darwin-arm64' : 'darwin-x64';
15
- if (p === 'linux') return a === 'arm64' ? 'linux-arm64' : 'linux-x64';
16
- if (p === 'win32') return 'win32-x64';
17
- return null;
18
- })();
19
-
20
- describe('binary smoke', () => {
21
- test('compiled binary boots and exits 0 on --help / handles unknown args gracefully', async () => {
22
- if (!PLATFORM_SLUG) {
23
- console.log('binary-smoke: unsupported host platform; skipping');
24
- return;
25
- }
26
- const binPath = join(import.meta.dir, '..', 'dist', `maude-${PLATFORM_SLUG}`);
27
- const exists = await Bun.file(binPath).exists();
28
- if (!exists) {
29
- console.log(
30
- `binary-smoke: ${binPath} not built; skipping (run \`bun run build.ts --release\`)`
31
- );
32
- return;
33
- }
34
-
35
- // The compiled binary is the dev-server entry — invoking it with --root
36
- // pointing at a temp dir without .design/ causes a fail-loud exit (1).
37
- // That's enough to prove the binary is a valid executable.
38
- const proc = Bun.spawn({
39
- cmd: [binPath, '--root', '/tmp/nonexistent-maude-test'],
40
- stdout: 'pipe',
41
- stderr: 'pipe',
42
- env: { ...process.env, NO_OPEN: '1' },
43
- });
44
- const code = await proc.exited;
45
- expect(code === 0 || code === 1).toBe(true);
46
- });
47
- });
@@ -1,87 +0,0 @@
1
- // Boot artifact check — Phase 19 / DDR-044, simplified in v0.18.1.
2
- // v0.18.0 tried to `bun install` + `bun run build.ts` when node_modules/react
3
- // was missing; that misfired in every install scenario (see boot-self-heal.ts
4
- // header). v0.18.1 ships pre-built runtime bundles + just verifies they're
5
- // reachable. Missing artifact == broken install, not first-boot gap.
6
-
7
- import { afterEach, beforeEach, describe, expect, test } from 'bun:test';
8
- import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
9
- import { tmpdir } from 'node:os';
10
- import { join } from 'node:path';
11
-
12
- import { bootSelfHeal, type SelfHealOptions } from '../boot-self-heal.ts';
13
-
14
- let TMP: string;
15
-
16
- beforeEach(() => {
17
- TMP = mkdtempSync(join(tmpdir(), 'maude-self-heal-'));
18
- mkdirSync(join(TMP, 'dist', 'runtime'), { recursive: true });
19
- });
20
-
21
- afterEach(() => {
22
- rmSync(TMP, { recursive: true, force: true });
23
- });
24
-
25
- function harness(extra: Partial<SelfHealOptions> = {}) {
26
- const logs: string[] = [];
27
- let exited: number | null = null;
28
- const opts: SelfHealOptions = {
29
- here: TMP,
30
- log: (m) => logs.push(m),
31
- exit: ((code: number) => {
32
- exited = code;
33
- throw new Error(`__exit:${code}`);
34
- }) as never,
35
- ...extra,
36
- };
37
- return { opts, logs, getExited: () => exited };
38
- }
39
-
40
- function seedAll() {
41
- writeFileSync(join(TMP, 'dist', 'client.bundle.js'), '/* stub */');
42
- writeFileSync(join(TMP, 'dist', 'runtime', 'react.js'), '/* stub */');
43
- }
44
-
45
- describe('bootSelfHeal', () => {
46
- test('passes when both required artifacts present', async () => {
47
- seedAll();
48
- const { opts, logs } = harness();
49
- const result = await bootSelfHeal(opts);
50
- expect(result.verified).toEqual(['client.bundle.js', 'runtime/react.js']);
51
- expect(logs).toEqual([]);
52
- });
53
-
54
- test('exits 1 with remediation when dist/client.bundle.js missing', async () => {
55
- writeFileSync(join(TMP, 'dist', 'runtime', 'react.js'), '/* stub */');
56
- const { opts, logs, getExited } = harness();
57
- await expect(bootSelfHeal(opts)).rejects.toThrow('__exit:1');
58
- expect(getExited()).toBe(1);
59
- const msg = logs.join('\n');
60
- expect(msg).toMatch(/dist\/client\.bundle\.js/);
61
- expect(msg).toMatch(/npm uninstall -g @1agh\/maude/);
62
- });
63
-
64
- test('exits 1 with remediation when dist/runtime/react.js missing', async () => {
65
- writeFileSync(join(TMP, 'dist', 'client.bundle.js'), '/* stub */');
66
- const { opts, logs, getExited } = harness();
67
- await expect(bootSelfHeal(opts)).rejects.toThrow('__exit:1');
68
- expect(getExited()).toBe(1);
69
- const msg = logs.join('\n');
70
- expect(msg).toMatch(/dist\/runtime\/react\.js/);
71
- });
72
-
73
- test('lists ALL missing artifacts in one message (not first-fail-only)', async () => {
74
- // Nothing seeded — both missing.
75
- const { opts, logs } = harness();
76
- await expect(bootSelfHeal(opts)).rejects.toThrow('__exit:1');
77
- const msg = logs.join('\n');
78
- expect(msg).toMatch(/dist\/client\.bundle\.js/);
79
- expect(msg).toMatch(/dist\/runtime\/react\.js/);
80
- });
81
-
82
- test('remediation surfaces the looked-under path so user can verify', async () => {
83
- const { opts, logs } = harness();
84
- await expect(bootSelfHeal(opts)).rejects.toThrow();
85
- expect(logs.join('\n')).toContain(TMP);
86
- });
87
- });
@@ -1,107 +0,0 @@
1
- // browse-posture — feature-4 (browse/move split, DDR-187). The LOAD-BEARING
2
- // gate: a DOM-level proof that the boot-default `browse` tool is a pure native
3
- // pass-through (a real click handler under the cursor fires, nothing is
4
- // claimed), while the `move` (select) tool CLAIMS the same bare click (native
5
- // handler suppressed, onSelect dispatched). This promotes the input-router
6
- // comment-invariant ("bare clicks pass through") into an enforced test — the
7
- // canvas-origin-gate equivalent for the input posture.
8
- //
9
- // Needs a live DOM (capture-phase listeners + event dispatch + a real React
10
- // effect) — register happy-dom + drive a createRoot, same convention as
11
- // canvas-hmr-runtime.test.tsx / specimen-select.test.ts.
12
-
13
- import { afterAll, beforeAll, describe, expect, test } from 'bun:test';
14
- import { GlobalRegistrator } from '@happy-dom/global-registrator';
15
-
16
- beforeAll(() => {
17
- GlobalRegistrator.register();
18
- (globalThis as unknown as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
19
- });
20
- afterAll(() => {
21
- GlobalRegistrator.unregister();
22
- });
23
-
24
- import { act, useRef } from 'react';
25
- import { createRoot, type Root } from 'react-dom/client';
26
-
27
- import { type RouterCallbacks, type Tool, useInputRouter } from '../input-router.tsx';
28
-
29
- // A minimal host that mounts the router over a single native <button>. The
30
- // active tool is read fresh at event time via `getActiveTool` (a ref-backed
31
- // getter), so a test can flip the tool without re-rendering.
32
- function Harness({ getTool, callbacks }: { getTool: () => Tool; callbacks: RouterCallbacks }) {
33
- const hostRef = useRef<HTMLDivElement | null>(null);
34
- useInputRouter({ hostRef, getActiveTool: getTool, callbacks });
35
- return (
36
- <div ref={hostRef} className="dc-canvas">
37
- <button type="button" id="native-btn">
38
- Click me
39
- </button>
40
- </div>
41
- );
42
- }
43
-
44
- function fireBareLeftClick(el: Element): void {
45
- // The full native sequence the router gates: pointerdown → mousedown → click.
46
- el.dispatchEvent(new MouseEvent('pointerdown', { bubbles: true, cancelable: true, button: 0 }));
47
- el.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, cancelable: true, button: 0 }));
48
- el.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, button: 0 }));
49
- }
50
-
51
- describe('browse tool — native pass-through (boot default)', () => {
52
- test('bare click: native button handler FIRES, onSelect NOT dispatched', () => {
53
- const el = document.createElement('div');
54
- document.body.appendChild(el);
55
- const root: Root = createRoot(el);
56
- let selectCalls = 0;
57
- let nativeClicks = 0;
58
-
59
- act(() => {
60
- root.render(
61
- <Harness getTool={() => 'browse'} callbacks={{ onSelect: () => (selectCalls += 1) }} />
62
- );
63
- });
64
-
65
- const btn = el.querySelector('#native-btn') as HTMLButtonElement;
66
- btn.addEventListener('click', () => (nativeClicks += 1));
67
- act(() => {
68
- fireBareLeftClick(btn);
69
- });
70
-
71
- expect(selectCalls).toBe(0); // browse never selects
72
- expect(nativeClicks).toBe(1); // the mock stays alive
73
-
74
- act(() => root.unmount());
75
- el.remove();
76
- });
77
- });
78
-
79
- describe('move (select) tool — claims the bare click', () => {
80
- test('bare click: native button handler SUPPRESSED, onSelect dispatched', () => {
81
- const el = document.createElement('div');
82
- document.body.appendChild(el);
83
- const root: Root = createRoot(el);
84
- let selectCalls = 0;
85
- let nativeClicks = 0;
86
-
87
- act(() => {
88
- root.render(
89
- <Harness getTool={() => 'move'} callbacks={{ onSelect: () => (selectCalls += 1) }} />
90
- );
91
- });
92
-
93
- const btn = el.querySelector('#native-btn') as HTMLButtonElement;
94
- btn.addEventListener('click', () => (nativeClicks += 1));
95
- act(() => {
96
- fireBareLeftClick(btn);
97
- });
98
-
99
- // Router claims the pointerdown (dispatches select) and swallows the
100
- // synthetic click so the button under the cursor never activates.
101
- expect(selectCalls).toBe(1);
102
- expect(nativeClicks).toBe(0);
103
-
104
- act(() => root.unmount());
105
- el.remove();
106
- });
107
- });
@@ -1,46 +0,0 @@
1
- // Smoke: build.ts produces a parsable IIFE bundle that ships React 19.
2
- //
3
- // Builds into a DISPOSABLE directory (`MAUDE_DIST_DIR`), never the real one.
4
- // It used to write its unminified dev output straight over the committed
5
- // release artifacts — `dist/client.bundle.js` at 14 MB where 2 MB ships — so
6
- // merely running the test suite staged a broken release, silently, with no
7
- // server running and no obvious culprit. CLAUDE.md carried this for a while as
8
- // "observed, root cause unconfirmed". This test was the cause.
9
-
10
- import { describe, expect, test } from 'bun:test';
11
- import { mkdtempSync, rmSync } from 'node:fs';
12
- import { tmpdir } from 'node:os';
13
- import { join } from 'node:path';
14
- import { spawnSync } from 'bun';
15
-
16
- describe('client bundle', () => {
17
- // A whole client build, so it sits right on bun's 5s default and tips over
18
- // whenever the machine is busy. Given headroom explicitly rather than left as
19
- // a flake — the thing under test is the bundle, not the wall clock.
20
- test('build.ts produces a parsable IIFE bundle that ships React', async () => {
21
- const here = join(import.meta.dir, '..');
22
- const out = mkdtempSync(join(tmpdir(), 'maude-bundle-smoke-'));
23
- try {
24
- const result = spawnSync({
25
- cmd: ['bun', 'run', join(here, 'build.ts')],
26
- cwd: here,
27
- stdout: 'pipe',
28
- stderr: 'pipe',
29
- env: { ...process.env, NODE_ENV: 'development', MAUDE_DIST_DIR: out },
30
- });
31
- expect(result.exitCode).toBe(0);
32
-
33
- const bundle = Bun.file(join(out, 'client.bundle.js'));
34
- expect(await bundle.exists()).toBe(true);
35
- expect(bundle.size).toBeGreaterThan(50_000);
36
-
37
- const src = await bundle.text();
38
- // React 19 internal marker — exact constants change across minor versions,
39
- // so we look for a stable substring on the IIFE shell + a known React API.
40
- expect(src.includes('createRoot') || src.includes('react-dom')).toBe(true);
41
- expect(src.includes('useState') || src.includes('react')).toBe(true);
42
- } finally {
43
- rmSync(out, { recursive: true, force: true });
44
- }
45
- }, 60_000);
46
- });