@1agh/maude 0.39.1 → 0.41.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 (137) hide show
  1. package/README.md +1 -1
  2. package/apps/studio/ai-banner.tsx +2 -2
  3. package/apps/studio/annotations-context-toolbar.tsx +44 -1
  4. package/apps/studio/annotations-layer.tsx +306 -5
  5. package/apps/studio/annotations-model.ts +107 -6
  6. package/apps/studio/api.ts +1316 -67
  7. package/apps/studio/artboard-marquee.tsx +1 -1
  8. package/apps/studio/bin/_canvas-rects-playwright.mjs +55 -0
  9. package/apps/studio/bin/_canvas-rects-static.mjs +166 -0
  10. package/apps/studio/bin/_fetch-asset.mjs +556 -0
  11. package/apps/studio/bin/_html-playwright.mjs +9 -1
  12. package/apps/studio/bin/_pdf-playwright.mjs +8 -1
  13. package/apps/studio/bin/_png-playwright.mjs +8 -1
  14. package/apps/studio/bin/_pw-launch.mjs +54 -0
  15. package/apps/studio/bin/_svg-playwright.mjs +8 -1
  16. package/apps/studio/bin/_video-playwright.mjs +452 -0
  17. package/apps/studio/bin/annotate.mjs +576 -34
  18. package/apps/studio/bin/canvas-rects.sh +152 -0
  19. package/apps/studio/bin/fetch-asset.sh +34 -0
  20. package/apps/studio/bin/prep.sh +8 -1
  21. package/apps/studio/bin/read-annotations.mjs +138 -7
  22. package/apps/studio/bin/smoke.sh +42 -6
  23. package/apps/studio/build.ts +21 -0
  24. package/apps/studio/canvas-comment-mount.tsx +138 -4
  25. package/apps/studio/canvas-edit.ts +2625 -111
  26. package/apps/studio/canvas-lib.tsx +238 -2
  27. package/apps/studio/canvas-list-watch.ts +6 -2
  28. package/apps/studio/canvas-shell.tsx +514 -20
  29. package/apps/studio/client/app.jsx +2480 -52
  30. package/apps/studio/client/comments-overlay.css +130 -126
  31. package/apps/studio/client/github.js +15 -0
  32. package/apps/studio/client/panels/TimelinePanel.jsx +860 -0
  33. package/apps/studio/client/panels/timeline-parse.js +229 -0
  34. package/apps/studio/client/panels/timeline-snap.js +55 -0
  35. package/apps/studio/client/styles/3-shell-maude.css +155 -0
  36. package/apps/studio/comments-overlay.tsx +148 -41
  37. package/apps/studio/config.schema.json +14 -0
  38. package/apps/studio/context-menu.tsx +16 -6
  39. package/apps/studio/context.ts +113 -1
  40. package/apps/studio/contextual-toolbar.tsx +262 -4
  41. package/apps/studio/cursors-overlay.tsx +4 -4
  42. package/apps/studio/dist/client.bundle.js +89 -17
  43. package/apps/studio/dist/comment-mount.js +59 -1
  44. package/apps/studio/dist/runtime/.min-sizes.json +11 -1
  45. package/apps/studio/dist/runtime/@remotion_media.js +491 -0
  46. package/apps/studio/dist/runtime/@remotion_player.js +56 -0
  47. package/apps/studio/dist/runtime/@remotion_transitions.js +300 -0
  48. package/apps/studio/dist/runtime/@remotion_transitions_clock-wipe.js +1 -0
  49. package/apps/studio/dist/runtime/@remotion_transitions_fade.js +1 -0
  50. package/apps/studio/dist/runtime/@remotion_transitions_flip.js +1 -0
  51. package/apps/studio/dist/runtime/@remotion_transitions_none.js +1 -0
  52. package/apps/studio/dist/runtime/@remotion_transitions_slide.js +1 -0
  53. package/apps/studio/dist/runtime/@remotion_transitions_wipe.js +1 -0
  54. package/apps/studio/dist/runtime/REMOTION-LICENSE.md +28 -0
  55. package/apps/studio/dist/runtime/remotion.js +42 -0
  56. package/apps/studio/dist/styles.css +1 -1
  57. package/apps/studio/dom-selection.ts +127 -1
  58. package/apps/studio/drag-state.ts +24 -0
  59. package/apps/studio/equal-spacing-detector.ts +205 -0
  60. package/apps/studio/export-dialog.tsx +1 -1
  61. package/apps/studio/exporters/_browser-bundles.ts +117 -0
  62. package/apps/studio/exporters/_runtime.ts +69 -0
  63. package/apps/studio/exporters/html.ts +4 -3
  64. package/apps/studio/exporters/index.ts +28 -2
  65. package/apps/studio/exporters/pdf.ts +4 -3
  66. package/apps/studio/exporters/png.ts +5 -3
  67. package/apps/studio/exporters/pptx.ts +6 -4
  68. package/apps/studio/exporters/svg.ts +9 -5
  69. package/apps/studio/exporters/video-encode-lib.ts +200 -0
  70. package/apps/studio/exporters/video-render-lib.ts +108 -0
  71. package/apps/studio/exporters/video.ts +184 -0
  72. package/apps/studio/history.ts +47 -1
  73. package/apps/studio/http.ts +758 -27
  74. package/apps/studio/input-router.tsx +19 -1
  75. package/apps/studio/marquee-overlay.tsx +1 -1
  76. package/apps/studio/measure-overlay.tsx +241 -0
  77. package/apps/studio/participants-chrome.tsx +3 -3
  78. package/apps/studio/runtime-bundle.ts +30 -0
  79. package/apps/studio/server.ts +34 -9
  80. package/apps/studio/sizing-mode.ts +117 -0
  81. package/apps/studio/spacing-handles.ts +166 -0
  82. package/apps/studio/test/annotate-write.test.ts +890 -0
  83. package/apps/studio/test/annotations-roundtrip.test.ts +47 -0
  84. package/apps/studio/test/camera-reveal.test.tsx +173 -0
  85. package/apps/studio/test/canvas-create-api.test.ts +76 -0
  86. package/apps/studio/test/canvas-edit.test.ts +140 -0
  87. package/apps/studio/test/canvas-list-watch.test.ts +49 -0
  88. package/apps/studio/test/canvas-media-drop.test.ts +30 -1
  89. package/apps/studio/test/canvas-origin-gate.test.ts +54 -0
  90. package/apps/studio/test/canvas-rects.test.ts +198 -0
  91. package/apps/studio/test/clip-addressing.test.ts +732 -0
  92. package/apps/studio/test/comments-overlay.test.ts +117 -0
  93. package/apps/studio/test/config-reload.test.ts +230 -0
  94. package/apps/studio/test/dns-rebinding-guard.test.ts +74 -0
  95. package/apps/studio/test/dom-selection.test.ts +130 -0
  96. package/apps/studio/test/edit-css-occurrence.test.ts +81 -0
  97. package/apps/studio/test/edit-persistence.test.ts +91 -0
  98. package/apps/studio/test/edit-scope-api.test.ts +115 -0
  99. package/apps/studio/test/element-resize.test.ts +136 -0
  100. package/apps/studio/test/element-structural-api.test.ts +360 -0
  101. package/apps/studio/test/element-structural-edit.test.ts +233 -0
  102. package/apps/studio/test/equal-spacing-detector.test.ts +165 -1
  103. package/apps/studio/test/exporters/runtime.test.ts +59 -0
  104. package/apps/studio/test/file-lock.test.ts +84 -0
  105. package/apps/studio/test/fixtures/video-comp-fixture.tsx +82 -0
  106. package/apps/studio/test/history-rollback.test.ts +26 -0
  107. package/apps/studio/test/knob-props-authored.test.ts +87 -0
  108. package/apps/studio/test/read-annotations.test.ts +154 -0
  109. package/apps/studio/test/sizing-mode.test.ts +102 -0
  110. package/apps/studio/test/spacing-handles.test.ts +138 -0
  111. package/apps/studio/test/specimen-select.test.ts +88 -0
  112. package/apps/studio/test/timeline-parse.test.ts +127 -0
  113. package/apps/studio/test/timeline-snap.test.ts +85 -0
  114. package/apps/studio/test/tool-palette-insert-anchor.test.ts +84 -0
  115. package/apps/studio/test/undo-sequence-byte-compare.test.ts +211 -0
  116. package/apps/studio/test/video-asset.test.ts +163 -0
  117. package/apps/studio/test/video-comp-fixture.test.ts +50 -0
  118. package/apps/studio/test/video-comp.test.ts +168 -0
  119. package/apps/studio/test/video-render-bridge.test.ts +149 -0
  120. package/apps/studio/tool-palette.tsx +122 -2
  121. package/apps/studio/undo-hud.tsx +2 -2
  122. package/apps/studio/use-annotation-resize.tsx +6 -3
  123. package/apps/studio/use-canvas-media-drop.tsx +66 -4
  124. package/apps/studio/use-element-resize.tsx +732 -0
  125. package/apps/studio/use-keyboard-discipline.tsx +205 -15
  126. package/apps/studio/use-selection-set.tsx +14 -0
  127. package/apps/studio/use-spacing-handles.tsx +388 -0
  128. package/apps/studio/video-comp.tsx +444 -0
  129. package/apps/studio/whats-new.json +55 -0
  130. package/apps/studio/ws.ts +5 -0
  131. package/cli/commands/design.mjs +6 -1
  132. package/cli/commands/design.test.mjs +49 -1
  133. package/cli/lib/fetch-asset.test.mjs +213 -0
  134. package/package.json +8 -8
  135. package/plugins/design/dependencies.json +10 -2
  136. package/plugins/design/templates/_shell.html +25 -2
  137. package/plugins/design/templates/design-system-inspiration/_MAPPING.md +1 -1
@@ -6,11 +6,24 @@
6
6
 
7
7
  import type { Dirent } from 'node:fs';
8
8
  import { existsSync } from 'node:fs';
9
- import { readdir } from 'node:fs/promises';
9
+ import { readdir, unlink } from 'node:fs/promises';
10
10
  import path from 'node:path';
11
11
 
12
12
  import type { Context } from './context.ts';
13
13
 
14
+ /**
15
+ * Per-slug snapshot cap (G3 security, DDR-152). The structural-edit routes
16
+ * (delete / insert / resize-artboard) each write a WHOLE-FILE snapshot here, and
17
+ * an untrusted active canvas can drive them in a loop — so `_history/<slug>/`
18
+ * was the uncapped disk-fill surface the adversarial review flagged. Pruning the
19
+ * oldest pairs bounds disk regardless of edit rate; 300 pairs is still a deep
20
+ * rollback runway for real work. Read lazily so tests can tune it via env.
21
+ */
22
+ function maxSnapshotsPerSlug(): number {
23
+ const env = Number(process.env.MAUDE_MAX_SNAPSHOTS);
24
+ return Number.isFinite(env) && env > 0 ? Math.floor(env) : 300;
25
+ }
26
+
14
27
  export interface Snapshot {
15
28
  slug: string;
16
29
  ts: string; // ISO
@@ -92,9 +105,42 @@ export function createHistory(ctx: Context): History {
92
105
  };
93
106
  await Bun.write(contentPath, contentBytes);
94
107
  await Bun.write(meta.metaPath, JSON.stringify({ ...meta, file }, null, 2));
108
+ await pruneSnapshots(slug).catch(() => {
109
+ /* pruning is best-effort — never fail a snapshot over it */
110
+ });
95
111
  return meta;
96
112
  }
97
113
 
114
+ /**
115
+ * Keep only the newest MAX_SNAPSHOTS_PER_SLUG snapshot pairs for a slug,
116
+ * unlinking the oldest content-blob + `.json` sidecar beyond the cap.
117
+ * Filenames are ts-derived (`tsForFilename`) so a lexical sort is chronological.
118
+ */
119
+ async function pruneSnapshots(slug: string): Promise<void> {
120
+ const dir = path.join(ctx.paths.historyDir, slug);
121
+ let names: string[];
122
+ try {
123
+ names = await readdir(dir);
124
+ } catch {
125
+ return; // no dir yet
126
+ }
127
+ const stems = names
128
+ .filter((n) => n.endsWith('.json'))
129
+ .map((n) => n.slice(0, -'.json'.length))
130
+ .sort();
131
+ const excess = stems.length - maxSnapshotsPerSlug();
132
+ if (excess <= 0) return;
133
+ for (const stem of stems.slice(0, excess)) {
134
+ for (const n of names) {
135
+ // The meta (`<stem>.json`) and its content blob (`<stem>.<ext>`) share
136
+ // the stem; the fixed-length ISO stem is never a prefix of another.
137
+ if (n === `${stem}.json` || n.startsWith(`${stem}.`)) {
138
+ await unlink(path.join(dir, n)).catch(() => {});
139
+ }
140
+ }
141
+ }
142
+ }
143
+
98
144
  async function listSnapshots(file: string): Promise<Snapshot[]> {
99
145
  const slug = fileSlug(file, ctx.paths.designRel);
100
146
  const dir = path.join(ctx.paths.historyDir, slug);