@1agh/maude 0.39.1 → 0.40.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 (82) hide show
  1. package/README.md +1 -1
  2. package/apps/studio/annotations-context-toolbar.tsx +44 -1
  3. package/apps/studio/annotations-layer.tsx +253 -3
  4. package/apps/studio/annotations-model.ts +107 -6
  5. package/apps/studio/api.ts +812 -64
  6. package/apps/studio/bin/_html-playwright.mjs +9 -1
  7. package/apps/studio/bin/_pdf-playwright.mjs +8 -1
  8. package/apps/studio/bin/_png-playwright.mjs +8 -1
  9. package/apps/studio/bin/_pw-launch.mjs +54 -0
  10. package/apps/studio/bin/_svg-playwright.mjs +8 -1
  11. package/apps/studio/bin/_video-playwright.mjs +452 -0
  12. package/apps/studio/bin/prep.sh +8 -1
  13. package/apps/studio/canvas-edit.ts +1885 -104
  14. package/apps/studio/canvas-lib.tsx +19 -0
  15. package/apps/studio/canvas-list-watch.ts +6 -2
  16. package/apps/studio/canvas-shell.tsx +27 -0
  17. package/apps/studio/client/app.jsx +1029 -30
  18. package/apps/studio/client/github.js +7 -0
  19. package/apps/studio/client/panels/TimelinePanel.jsx +860 -0
  20. package/apps/studio/client/panels/timeline-parse.js +229 -0
  21. package/apps/studio/client/panels/timeline-snap.js +55 -0
  22. package/apps/studio/client/styles/3-shell-maude.css +107 -0
  23. package/apps/studio/config.schema.json +14 -0
  24. package/apps/studio/context-menu.tsx +1 -1
  25. package/apps/studio/context.ts +113 -1
  26. package/apps/studio/dist/client.bundle.js +88 -16
  27. package/apps/studio/dist/comment-mount.js +1 -1
  28. package/apps/studio/dist/runtime/.min-sizes.json +11 -1
  29. package/apps/studio/dist/runtime/@remotion_media.js +491 -0
  30. package/apps/studio/dist/runtime/@remotion_player.js +56 -0
  31. package/apps/studio/dist/runtime/@remotion_transitions.js +300 -0
  32. package/apps/studio/dist/runtime/@remotion_transitions_clock-wipe.js +1 -0
  33. package/apps/studio/dist/runtime/@remotion_transitions_fade.js +1 -0
  34. package/apps/studio/dist/runtime/@remotion_transitions_flip.js +1 -0
  35. package/apps/studio/dist/runtime/@remotion_transitions_none.js +1 -0
  36. package/apps/studio/dist/runtime/@remotion_transitions_slide.js +1 -0
  37. package/apps/studio/dist/runtime/@remotion_transitions_wipe.js +1 -0
  38. package/apps/studio/dist/runtime/REMOTION-LICENSE.md +28 -0
  39. package/apps/studio/dist/runtime/remotion.js +42 -0
  40. package/apps/studio/dist/styles.css +1 -1
  41. package/apps/studio/exporters/_browser-bundles.ts +117 -0
  42. package/apps/studio/exporters/_runtime.ts +69 -0
  43. package/apps/studio/exporters/html.ts +4 -3
  44. package/apps/studio/exporters/index.ts +28 -2
  45. package/apps/studio/exporters/pdf.ts +4 -3
  46. package/apps/studio/exporters/png.ts +5 -3
  47. package/apps/studio/exporters/pptx.ts +6 -4
  48. package/apps/studio/exporters/svg.ts +9 -5
  49. package/apps/studio/exporters/video-encode-lib.ts +200 -0
  50. package/apps/studio/exporters/video-render-lib.ts +108 -0
  51. package/apps/studio/exporters/video.ts +184 -0
  52. package/apps/studio/http.ts +535 -27
  53. package/apps/studio/input-router.tsx +7 -1
  54. package/apps/studio/runtime-bundle.ts +30 -0
  55. package/apps/studio/server.ts +34 -9
  56. package/apps/studio/test/annotations-roundtrip.test.ts +47 -0
  57. package/apps/studio/test/canvas-create-api.test.ts +76 -0
  58. package/apps/studio/test/canvas-edit.test.ts +90 -0
  59. package/apps/studio/test/canvas-list-watch.test.ts +49 -0
  60. package/apps/studio/test/canvas-media-drop.test.ts +30 -1
  61. package/apps/studio/test/canvas-origin-gate.test.ts +36 -0
  62. package/apps/studio/test/clip-addressing.test.ts +732 -0
  63. package/apps/studio/test/config-reload.test.ts +230 -0
  64. package/apps/studio/test/dns-rebinding-guard.test.ts +74 -0
  65. package/apps/studio/test/edit-persistence.test.ts +91 -0
  66. package/apps/studio/test/exporters/runtime.test.ts +59 -0
  67. package/apps/studio/test/file-lock.test.ts +84 -0
  68. package/apps/studio/test/fixtures/video-comp-fixture.tsx +82 -0
  69. package/apps/studio/test/timeline-parse.test.ts +127 -0
  70. package/apps/studio/test/timeline-snap.test.ts +85 -0
  71. package/apps/studio/test/video-asset.test.ts +163 -0
  72. package/apps/studio/test/video-comp-fixture.test.ts +50 -0
  73. package/apps/studio/test/video-comp.test.ts +168 -0
  74. package/apps/studio/test/video-render-bridge.test.ts +149 -0
  75. package/apps/studio/use-annotation-resize.tsx +6 -3
  76. package/apps/studio/use-canvas-media-drop.tsx +66 -4
  77. package/apps/studio/video-comp.tsx +444 -0
  78. package/apps/studio/whats-new.json +27 -0
  79. package/apps/studio/ws.ts +5 -0
  80. package/package.json +8 -8
  81. package/plugins/design/templates/_shell.html +25 -2
  82. package/plugins/design/templates/design-system-inspiration/_MAPPING.md +1 -1
@@ -108,6 +108,13 @@ import { useSelectionSetOptional } from './use-selection-set.tsx';
108
108
  import { MaybeToolProvider, useToolModeOptional } from './use-tool-mode.tsx';
109
109
  import { UndoStackProvider, useUndoSinks, useUndoStackOptional } from './use-undo-stack.tsx';
110
110
 
111
+ export type { CompSnapshot, VideoCompMeta, VideoCompProps } from './video-comp.tsx';
112
+ // DDR-148 — video-comp canvas kind. Re-exported so `@maude/canvas-lib` exposes
113
+ // <VideoComp> (Remotion composition mounted in <Player> + the deterministic
114
+ // seek bridge). Its `remotion`/`@remotion/player` imports resolve through the
115
+ // canvas importmap (RUNTIME_PACKAGES), same as react/motion.
116
+ export { VideoComp } from './video-comp.tsx';
117
+
111
118
  // ─────────────────────────────────────────────────────────────────────────────
112
119
  // Module constants
113
120
 
@@ -1497,6 +1504,18 @@ function DesignCanvasInner({ children, controls }: DesignCanvasProps) {
1497
1504
  return bestId;
1498
1505
  }, [artboards, controller.viewport]);
1499
1506
 
1507
+ // DDR-148 — report the viewport-active artboard (nearest the centre) to the
1508
+ // shell so the Timeline panel FOLLOWS whichever artboard the user pans to,
1509
+ // not just the one they cmd+click. Fires on every pan/zoom that changes it.
1510
+ useEffect(() => {
1511
+ if (typeof window === 'undefined' || window.parent === window) return;
1512
+ try {
1513
+ window.parent.postMessage({ dgn: 'active-artboard', id: activeArtboardId }, '*');
1514
+ } catch {
1515
+ /* cross-origin parent without our listener — no-op */
1516
+ }
1517
+ }, [activeArtboardId]);
1518
+
1500
1519
  // The world's transform is owned by useViewportController (writes straight
1501
1520
  // to `worldRef.current.style.transform`). Rendering the transform from
1502
1521
  // React state instead would race: between React's commit and the
@@ -86,7 +86,11 @@ export function createCanvasListWatch(
86
86
  // default config newCanvasDir IS a group; a config pointing it outside
87
87
  // canvasGroups would have the canvas absent from /_index-data too, so the
88
88
  // watcher stays consistent with what the tree can actually show.
89
- const groupPaths = (ctx.cfg.canvasGroups ?? []).map((g) => g.path);
89
+ //
90
+ // Read at USE time, never captured — `reloadConfig` (context.ts) hot-swaps
91
+ // ctx.cfg in place when config.json changes on disk, and a group added
92
+ // mid-session (`/design:setup-ds` adding `system`) must gate correctly.
93
+ const groupPaths = () => (ctx.cfg.canvasGroups ?? []).map((g) => g.path);
90
94
 
91
95
  // null = not yet seeded; the first refresh captures the baseline and emits
92
96
  // nothing (canvases already on disk at boot aren't "added").
@@ -156,7 +160,7 @@ export function createCanvasListWatch(
156
160
  }
157
161
 
158
162
  const off = ctx.bus.on('fs:any', (rel: string) => {
159
- if (!isCanvasCandidate(rel, groupPaths)) return;
163
+ if (!isCanvasCandidate(rel, groupPaths())) return;
160
164
  schedule();
161
165
  });
162
166
 
@@ -94,6 +94,7 @@ import {
94
94
  useAnnotationSelectionOptional,
95
95
  } from './use-annotation-selection.tsx';
96
96
  import { AnnotationsVisibilityProvider } from './use-annotations-visibility.tsx';
97
+ import { showCanvasToast } from './use-canvas-media-drop.tsx';
97
98
  import { ChromeVisibilityProvider, useChromeVisibility } from './use-chrome-visibility.tsx';
98
99
  import { useCollab } from './use-collab.tsx';
99
100
  import { useCursorModifiers } from './use-cursor-modifiers.tsx';
@@ -1780,6 +1781,11 @@ function CanvasRouter({
1780
1781
  if (!host) return;
1781
1782
  let editing: HTMLElement | null = null;
1782
1783
  let original = '';
1784
+ // DDR-150 P1 — the committed-but-unconfirmed edit, so a shell rejection
1785
+ // (dynamic/mixed content the engine refuses) can revert the optimistic
1786
+ // contenteditable text instead of letting it silently vanish on the next
1787
+ // reload. Mirrors the reorder-failed revert below. Cleared on revert.
1788
+ let lastTextCommit: { el: HTMLElement; original: string } | null = null;
1783
1789
  const onBlur = (): void => commitEdit(true);
1784
1790
  const onKey = (e: KeyboardEvent): void => {
1785
1791
  if (e.key === 'Escape') {
@@ -1815,6 +1821,8 @@ function CanvasRouter({
1815
1821
  } catch {
1816
1822
  /* detached / cross-origin */
1817
1823
  }
1824
+ // Stash the optimistic edit so a shell rejection can revert it (DDR-150 P1).
1825
+ lastTextCommit = { el: elx, original };
1818
1826
  // Record onto the in-canvas undo stack so Cmd+Z reverts the rewrite. The
1819
1827
  // edit already posted above (record, don't re-run do()). before/after are
1820
1828
  // the trimmed bodies the edit-text endpoint persists.
@@ -1855,10 +1863,29 @@ function CanvasRouter({
1855
1863
  /* selection API unavailable */
1856
1864
  }
1857
1865
  };
1866
+ // The shell rejected the last inline text edit — revert the optimistic
1867
+ // contenteditable text so the canvas reflects the true (unsaved) source
1868
+ // rather than a change that silently disappears on the next reload (DDR-150 P1).
1869
+ const onEditReverted = (e: MessageEvent): void => {
1870
+ if (e.source !== window.parent) return;
1871
+ const m = e.data as { dgn?: string; op?: string; reason?: string } | null;
1872
+ if (m?.dgn !== 'edit-reverted' || m.op !== 'text' || !lastTextCommit) return;
1873
+ try {
1874
+ lastTextCommit.el.textContent = lastTextCommit.original;
1875
+ } catch {
1876
+ /* detached — a subsequent reload re-syncs */
1877
+ }
1878
+ showCanvasToast(
1879
+ `Couldn't save that text — ${m.reason || 'not editable inline'}. Edit it via chat.`
1880
+ );
1881
+ lastTextCommit = null;
1882
+ };
1858
1883
  // Capture phase so we beat the fit-to-view dblclick handler.
1859
1884
  host.addEventListener('dblclick', onDbl, true);
1885
+ window.addEventListener('message', onEditReverted);
1860
1886
  return () => {
1861
1887
  host.removeEventListener('dblclick', onDbl, true);
1888
+ window.removeEventListener('message', onEditReverted);
1862
1889
  if (editing) teardown(editing);
1863
1890
  };
1864
1891
  }, [hostRef]);