@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.
- package/README.md +1 -1
- package/apps/studio/ai-banner.tsx +2 -2
- package/apps/studio/annotations-context-toolbar.tsx +44 -1
- package/apps/studio/annotations-layer.tsx +306 -5
- package/apps/studio/annotations-model.ts +107 -6
- package/apps/studio/api.ts +1316 -67
- package/apps/studio/artboard-marquee.tsx +1 -1
- package/apps/studio/bin/_canvas-rects-playwright.mjs +55 -0
- package/apps/studio/bin/_canvas-rects-static.mjs +166 -0
- package/apps/studio/bin/_fetch-asset.mjs +556 -0
- package/apps/studio/bin/_html-playwright.mjs +9 -1
- package/apps/studio/bin/_pdf-playwright.mjs +8 -1
- package/apps/studio/bin/_png-playwright.mjs +8 -1
- package/apps/studio/bin/_pw-launch.mjs +54 -0
- package/apps/studio/bin/_svg-playwright.mjs +8 -1
- package/apps/studio/bin/_video-playwright.mjs +452 -0
- package/apps/studio/bin/annotate.mjs +576 -34
- package/apps/studio/bin/canvas-rects.sh +152 -0
- package/apps/studio/bin/fetch-asset.sh +34 -0
- package/apps/studio/bin/prep.sh +8 -1
- package/apps/studio/bin/read-annotations.mjs +138 -7
- package/apps/studio/bin/smoke.sh +42 -6
- package/apps/studio/build.ts +21 -0
- package/apps/studio/canvas-comment-mount.tsx +138 -4
- package/apps/studio/canvas-edit.ts +2625 -111
- package/apps/studio/canvas-lib.tsx +238 -2
- package/apps/studio/canvas-list-watch.ts +6 -2
- package/apps/studio/canvas-shell.tsx +514 -20
- package/apps/studio/client/app.jsx +2480 -52
- package/apps/studio/client/comments-overlay.css +130 -126
- package/apps/studio/client/github.js +15 -0
- package/apps/studio/client/panels/TimelinePanel.jsx +860 -0
- package/apps/studio/client/panels/timeline-parse.js +229 -0
- package/apps/studio/client/panels/timeline-snap.js +55 -0
- package/apps/studio/client/styles/3-shell-maude.css +155 -0
- package/apps/studio/comments-overlay.tsx +148 -41
- package/apps/studio/config.schema.json +14 -0
- package/apps/studio/context-menu.tsx +16 -6
- package/apps/studio/context.ts +113 -1
- package/apps/studio/contextual-toolbar.tsx +262 -4
- package/apps/studio/cursors-overlay.tsx +4 -4
- package/apps/studio/dist/client.bundle.js +89 -17
- package/apps/studio/dist/comment-mount.js +59 -1
- package/apps/studio/dist/runtime/.min-sizes.json +11 -1
- package/apps/studio/dist/runtime/@remotion_media.js +491 -0
- package/apps/studio/dist/runtime/@remotion_player.js +56 -0
- package/apps/studio/dist/runtime/@remotion_transitions.js +300 -0
- package/apps/studio/dist/runtime/@remotion_transitions_clock-wipe.js +1 -0
- package/apps/studio/dist/runtime/@remotion_transitions_fade.js +1 -0
- package/apps/studio/dist/runtime/@remotion_transitions_flip.js +1 -0
- package/apps/studio/dist/runtime/@remotion_transitions_none.js +1 -0
- package/apps/studio/dist/runtime/@remotion_transitions_slide.js +1 -0
- package/apps/studio/dist/runtime/@remotion_transitions_wipe.js +1 -0
- package/apps/studio/dist/runtime/REMOTION-LICENSE.md +28 -0
- package/apps/studio/dist/runtime/remotion.js +42 -0
- package/apps/studio/dist/styles.css +1 -1
- package/apps/studio/dom-selection.ts +127 -1
- package/apps/studio/drag-state.ts +24 -0
- package/apps/studio/equal-spacing-detector.ts +205 -0
- package/apps/studio/export-dialog.tsx +1 -1
- package/apps/studio/exporters/_browser-bundles.ts +117 -0
- package/apps/studio/exporters/_runtime.ts +69 -0
- package/apps/studio/exporters/html.ts +4 -3
- package/apps/studio/exporters/index.ts +28 -2
- package/apps/studio/exporters/pdf.ts +4 -3
- package/apps/studio/exporters/png.ts +5 -3
- package/apps/studio/exporters/pptx.ts +6 -4
- package/apps/studio/exporters/svg.ts +9 -5
- package/apps/studio/exporters/video-encode-lib.ts +200 -0
- package/apps/studio/exporters/video-render-lib.ts +108 -0
- package/apps/studio/exporters/video.ts +184 -0
- package/apps/studio/history.ts +47 -1
- package/apps/studio/http.ts +758 -27
- package/apps/studio/input-router.tsx +19 -1
- package/apps/studio/marquee-overlay.tsx +1 -1
- package/apps/studio/measure-overlay.tsx +241 -0
- package/apps/studio/participants-chrome.tsx +3 -3
- package/apps/studio/runtime-bundle.ts +30 -0
- package/apps/studio/server.ts +34 -9
- package/apps/studio/sizing-mode.ts +117 -0
- package/apps/studio/spacing-handles.ts +166 -0
- package/apps/studio/test/annotate-write.test.ts +890 -0
- package/apps/studio/test/annotations-roundtrip.test.ts +47 -0
- package/apps/studio/test/camera-reveal.test.tsx +173 -0
- package/apps/studio/test/canvas-create-api.test.ts +76 -0
- package/apps/studio/test/canvas-edit.test.ts +140 -0
- package/apps/studio/test/canvas-list-watch.test.ts +49 -0
- package/apps/studio/test/canvas-media-drop.test.ts +30 -1
- package/apps/studio/test/canvas-origin-gate.test.ts +54 -0
- package/apps/studio/test/canvas-rects.test.ts +198 -0
- package/apps/studio/test/clip-addressing.test.ts +732 -0
- package/apps/studio/test/comments-overlay.test.ts +117 -0
- package/apps/studio/test/config-reload.test.ts +230 -0
- package/apps/studio/test/dns-rebinding-guard.test.ts +74 -0
- package/apps/studio/test/dom-selection.test.ts +130 -0
- package/apps/studio/test/edit-css-occurrence.test.ts +81 -0
- package/apps/studio/test/edit-persistence.test.ts +91 -0
- package/apps/studio/test/edit-scope-api.test.ts +115 -0
- package/apps/studio/test/element-resize.test.ts +136 -0
- package/apps/studio/test/element-structural-api.test.ts +360 -0
- package/apps/studio/test/element-structural-edit.test.ts +233 -0
- package/apps/studio/test/equal-spacing-detector.test.ts +165 -1
- package/apps/studio/test/exporters/runtime.test.ts +59 -0
- package/apps/studio/test/file-lock.test.ts +84 -0
- package/apps/studio/test/fixtures/video-comp-fixture.tsx +82 -0
- package/apps/studio/test/history-rollback.test.ts +26 -0
- package/apps/studio/test/knob-props-authored.test.ts +87 -0
- package/apps/studio/test/read-annotations.test.ts +154 -0
- package/apps/studio/test/sizing-mode.test.ts +102 -0
- package/apps/studio/test/spacing-handles.test.ts +138 -0
- package/apps/studio/test/specimen-select.test.ts +88 -0
- package/apps/studio/test/timeline-parse.test.ts +127 -0
- package/apps/studio/test/timeline-snap.test.ts +85 -0
- package/apps/studio/test/tool-palette-insert-anchor.test.ts +84 -0
- package/apps/studio/test/undo-sequence-byte-compare.test.ts +211 -0
- package/apps/studio/test/video-asset.test.ts +163 -0
- package/apps/studio/test/video-comp-fixture.test.ts +50 -0
- package/apps/studio/test/video-comp.test.ts +168 -0
- package/apps/studio/test/video-render-bridge.test.ts +149 -0
- package/apps/studio/tool-palette.tsx +122 -2
- package/apps/studio/undo-hud.tsx +2 -2
- package/apps/studio/use-annotation-resize.tsx +6 -3
- package/apps/studio/use-canvas-media-drop.tsx +66 -4
- package/apps/studio/use-element-resize.tsx +732 -0
- package/apps/studio/use-keyboard-discipline.tsx +205 -15
- package/apps/studio/use-selection-set.tsx +14 -0
- package/apps/studio/use-spacing-handles.tsx +388 -0
- package/apps/studio/video-comp.tsx +444 -0
- package/apps/studio/whats-new.json +55 -0
- package/apps/studio/ws.ts +5 -0
- package/cli/commands/design.mjs +6 -1
- package/cli/commands/design.test.mjs +49 -1
- package/cli/lib/fetch-asset.test.mjs +213 -0
- package/package.json +8 -8
- package/plugins/design/dependencies.json +10 -2
- package/plugins/design/templates/_shell.html +25 -2
- package/plugins/design/templates/design-system-inspiration/_MAPPING.md +1 -1
|
@@ -266,6 +266,30 @@ export interface LinkStroke extends StrokeBase {
|
|
|
266
266
|
title: string;
|
|
267
267
|
domain: string;
|
|
268
268
|
}
|
|
269
|
+
/**
|
|
270
|
+
* DDR-150 P4 — a video/audio file dropped on the canvas BODY (not the timeline)
|
|
271
|
+
* as a reference chip. It's the "nahazet klipy → agent z toho udělá video"
|
|
272
|
+
* artifact: a non-destructive, versioned pointer to an `assets/…` clip the agent
|
|
273
|
+
* can enumerate off the saved `.annotations.svg` (via `data-src`), then assemble
|
|
274
|
+
* into a comp. Distinct from a timeline drop (which INSERTS a `<Sequence>`) and
|
|
275
|
+
* from an ImageStroke (a rendered picture). Renders as a card: a media glyph
|
|
276
|
+
* (▶ video / ♪ audio) + the filename. `src` is ALWAYS a relative `assets/<sha8>`
|
|
277
|
+
* path (never seeked by the capture spine — it's a reference, excluded from
|
|
278
|
+
* export by `?hide-chrome`). Persists as an allowlisted `<g>` like LinkStroke —
|
|
279
|
+
* `data-src`/`data-media-kind`/`data-title` are the round-trip source of truth.
|
|
280
|
+
*/
|
|
281
|
+
export interface MediaRefStroke extends StrokeBase {
|
|
282
|
+
tool: 'mediaref';
|
|
283
|
+
x: number;
|
|
284
|
+
y: number;
|
|
285
|
+
w: number;
|
|
286
|
+
h: number;
|
|
287
|
+
/** Relative `assets/<sha8>.<ext>` path — the agent reads this off the SVG. */
|
|
288
|
+
src: string;
|
|
289
|
+
mediaKind: 'video' | 'audio';
|
|
290
|
+
/** Human-facing label (the dropped file's name). */
|
|
291
|
+
title: string;
|
|
292
|
+
}
|
|
269
293
|
/**
|
|
270
294
|
* FigJam v3 — section: a labelled organizing container. Renders as a soft
|
|
271
295
|
* rounded region with a name chip above the top-left corner; its INTERIOR is
|
|
@@ -294,6 +318,7 @@ export type Stroke =
|
|
|
294
318
|
| StickyStroke
|
|
295
319
|
| ImageStroke
|
|
296
320
|
| LinkStroke
|
|
321
|
+
| MediaRefStroke
|
|
297
322
|
| SectionStroke;
|
|
298
323
|
|
|
299
324
|
/**
|
|
@@ -528,6 +553,11 @@ export const IMAGE_MIN_SIZE = 16;
|
|
|
528
553
|
export const IMAGE_MAX_DROP_SIDE = 480;
|
|
529
554
|
export const LINK_DEFAULT_W = 260;
|
|
530
555
|
export const LINK_DEFAULT_H = 76;
|
|
556
|
+
// DDR-150 P4 — media-reference chip (dropped video/audio → assets/ pointer).
|
|
557
|
+
export const MEDIAREF_DEFAULT_W = 280;
|
|
558
|
+
export const MEDIAREF_DEFAULT_H = 76;
|
|
559
|
+
/** Video chips are taller: 26px header + a 16:9 inline player area (dogfood #8). */
|
|
560
|
+
export const MEDIAREF_VIDEO_H = 190;
|
|
531
561
|
export const LINK_CARD_FILL = '#ffffff';
|
|
532
562
|
export const LINK_CARD_STROKE = '#d4d4d8';
|
|
533
563
|
export const LINK_DOMAIN_FILL = '#71717a';
|
|
@@ -539,6 +569,12 @@ export const LINK_GLYPH_STROKE = '#52525b';
|
|
|
539
569
|
// <rect> geometry), so render/serialize only need to agree visually.
|
|
540
570
|
export const LINK_GLYPH_D1 = 'M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71';
|
|
541
571
|
export const LINK_GLYPH_D2 = 'M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71';
|
|
572
|
+
// DDR-150 P4 — media-reference chip glyphs (24×24 viewBox, filled). One source
|
|
573
|
+
// for serialize + StrokeNode render, like the link glyph. Video = play triangle;
|
|
574
|
+
// audio = a filled note. The parser ignores the glyph (reads data-* + geometry).
|
|
575
|
+
export const MEDIAREF_VIDEO_GLYPH = 'M8 5v14l11-7z';
|
|
576
|
+
export const MEDIAREF_AUDIO_GLYPH =
|
|
577
|
+
'M9 18V6l10-2v11.5a2.5 2.5 0 1 1-2-2.45V7.3L11 8.6v6.9a2.5 2.5 0 1 1-2-2.45z';
|
|
542
578
|
|
|
543
579
|
/** Card text positions, derived purely from the bbox (idempotent round-trip). */
|
|
544
580
|
export function linkCardLayout(x: number, y: number, w: number, h: number) {
|
|
@@ -1038,6 +1074,37 @@ function strokeToSvgElBase(s: Stroke): string {
|
|
|
1038
1074
|
`</g>`
|
|
1039
1075
|
);
|
|
1040
1076
|
}
|
|
1077
|
+
if (s.tool === 'mediaref') {
|
|
1078
|
+
// DDR-150 P4 — reference chip for a dropped clip. Like the link card: the
|
|
1079
|
+
// data-* are the round-trip source of truth (the agent reads data-src to
|
|
1080
|
+
// enumerate refs); the inner rect/glyph/text are the inert, sanitizer-safe
|
|
1081
|
+
// visual. NEVER a <Video>/<Audio> element (that would try to play/seek) —
|
|
1082
|
+
// it's a pointer, drawn as a still card.
|
|
1083
|
+
const nx = Math.min(s.x, s.x + s.w);
|
|
1084
|
+
const ny = Math.min(s.y, s.y + s.h);
|
|
1085
|
+
const nw = Math.abs(s.w);
|
|
1086
|
+
const nh = Math.abs(s.h);
|
|
1087
|
+
const lay = linkCardLayout(nx, ny, nw, nh);
|
|
1088
|
+
const shownTitle = clampLinkTitle(s.title, lay.textMaxChars);
|
|
1089
|
+
const glyph =
|
|
1090
|
+
s.mediaKind === 'audio'
|
|
1091
|
+
? `<path d="${MEDIAREF_AUDIO_GLYPH}"/>`
|
|
1092
|
+
: `<path d="${MEDIAREF_VIDEO_GLYPH}"/>`;
|
|
1093
|
+
return (
|
|
1094
|
+
`<g data-id="${esc(s.id)}" data-tool="mediaref" data-src="${escAttr(s.src)}" data-media-kind="${escAttr(
|
|
1095
|
+
s.mediaKind
|
|
1096
|
+
)}" data-title="${escAttr(s.title)}">` +
|
|
1097
|
+
`<rect x="${nx}" y="${ny}" width="${nw}" height="${nh}" rx="8" ry="8" fill="${LINK_CARD_FILL}" stroke="${LINK_CARD_STROKE}" stroke-width="1"/>` +
|
|
1098
|
+
`<svg x="${lay.glyph.x}" y="${lay.glyph.y}" width="${lay.glyph.size}" height="${lay.glyph.size}" viewBox="0 0 24 24" fill="${LINK_GLYPH_STROKE}" stroke="none">${glyph}</svg>` +
|
|
1099
|
+
`<text x="${lay.textX}" y="${lay.domain.y}" font-size="${lay.domain.fontSize}" fill="${LINK_DOMAIN_FILL}" dominant-baseline="hanging">${esc(
|
|
1100
|
+
`${s.mediaKind} · reference`
|
|
1101
|
+
)}</text>` +
|
|
1102
|
+
`<text x="${lay.textX}" y="${lay.title.y}" font-size="${lay.title.fontSize}" fill="${LINK_TITLE_FILL}" font-weight="600" dominant-baseline="hanging">${esc(
|
|
1103
|
+
shownTitle
|
|
1104
|
+
)}</text>` +
|
|
1105
|
+
`</g>`
|
|
1106
|
+
);
|
|
1107
|
+
}
|
|
1041
1108
|
if (s.tool === 'section') {
|
|
1042
1109
|
// FigJam v3 — inert persisted form: region rect + chip label text. Colors
|
|
1043
1110
|
// are render-time chrome; the parser reads geometry off the rect and the
|
|
@@ -1463,6 +1530,22 @@ export function svgToStrokes(svgText: string): Stroke[] {
|
|
|
1463
1530
|
push({ id, tool: 'link', x, y, w, h, url, title, domain });
|
|
1464
1531
|
continue;
|
|
1465
1532
|
}
|
|
1533
|
+
if (tool === 'mediaref') {
|
|
1534
|
+
// DDR-150 P4 — geometry off the <rect> child (mirrors link/sticky);
|
|
1535
|
+
// data-src is the pointer the agent enumerates. A src that fails the
|
|
1536
|
+
// assets/ shape is dropped to '' (an inert chip that references nothing).
|
|
1537
|
+
const rectEl = el.querySelector('rect');
|
|
1538
|
+
const x = pfloat(rectEl?.getAttribute('x'));
|
|
1539
|
+
const y = pfloat(rectEl?.getAttribute('y'));
|
|
1540
|
+
const w = pfloat(rectEl?.getAttribute('width'), MEDIAREF_DEFAULT_W);
|
|
1541
|
+
const h = pfloat(rectEl?.getAttribute('height'), MEDIAREF_DEFAULT_H);
|
|
1542
|
+
const rawSrc = el.getAttribute('data-src') || '';
|
|
1543
|
+
const src = ASSET_MEDIA_SRC_RE.test(rawSrc) ? rawSrc : '';
|
|
1544
|
+
const mediaKind = el.getAttribute('data-media-kind') === 'audio' ? 'audio' : 'video';
|
|
1545
|
+
const title = el.getAttribute('data-title') || src;
|
|
1546
|
+
push({ id, tool: 'mediaref', x, y, w, h, src, mediaKind, title });
|
|
1547
|
+
continue;
|
|
1548
|
+
}
|
|
1466
1549
|
if (tool === 'text') {
|
|
1467
1550
|
const rawAnchor = el.getAttribute('data-anchor-id');
|
|
1468
1551
|
const fontSize =
|
|
@@ -1650,8 +1733,8 @@ export function strokeHitTest(s: Stroke, wx: number, wy: number, tol: number): b
|
|
|
1650
1733
|
return onEdge;
|
|
1651
1734
|
}
|
|
1652
1735
|
const t = Math.max(tol, 'width' in s ? s.width : 2);
|
|
1653
|
-
if (s.tool === 'sticky' || s.tool === 'image' || s.tool === 'link') {
|
|
1654
|
-
// Sticky / image / link are solid cards — filled-rect hit
|
|
1736
|
+
if (s.tool === 'sticky' || s.tool === 'image' || s.tool === 'link' || s.tool === 'mediaref') {
|
|
1737
|
+
// Sticky / image / link / mediaref are solid cards — filled-rect hit inside.
|
|
1655
1738
|
const xMin = Math.min(s.x, s.x + s.w);
|
|
1656
1739
|
const xMax = Math.max(s.x, s.x + s.w);
|
|
1657
1740
|
const yMin = Math.min(s.y, s.y + s.h);
|
|
@@ -1844,6 +1927,8 @@ export function isStrokeMeaningful(s: Stroke): boolean {
|
|
|
1844
1927
|
// Phase 23 — an image needs real extent; a link needs a non-empty URL.
|
|
1845
1928
|
if (s.tool === 'image') return Math.abs(s.w) >= IMAGE_MIN_SIZE && Math.abs(s.h) >= IMAGE_MIN_SIZE;
|
|
1846
1929
|
if (s.tool === 'link') return s.url.trim().length > 0;
|
|
1930
|
+
// A media-reference chip needs a non-empty assets/ src (its whole purpose).
|
|
1931
|
+
if (s.tool === 'mediaref') return s.src.trim().length > 0;
|
|
1847
1932
|
if (s.tool === 'section')
|
|
1848
1933
|
return Math.abs(s.w) >= SECTION_MIN_SIZE && Math.abs(s.h) >= SECTION_MIN_SIZE;
|
|
1849
1934
|
return Math.hypot(s.x2 - s.x1, s.y2 - s.y1) >= 4;
|
|
@@ -1886,9 +1971,15 @@ export function strokeBBox(
|
|
|
1886
1971
|
h: Math.abs(s.y2 - s.y1),
|
|
1887
1972
|
};
|
|
1888
1973
|
}
|
|
1889
|
-
if (
|
|
1890
|
-
|
|
1891
|
-
|
|
1974
|
+
if (
|
|
1975
|
+
s.tool === 'sticky' ||
|
|
1976
|
+
s.tool === 'image' ||
|
|
1977
|
+
s.tool === 'link' ||
|
|
1978
|
+
s.tool === 'mediaref' ||
|
|
1979
|
+
s.tool === 'section'
|
|
1980
|
+
) {
|
|
1981
|
+
// Phase 23 — image + link + mediaref are rect-shaped cards, same bbox as a
|
|
1982
|
+
// sticky; FigJam v3 sections share it too.
|
|
1892
1983
|
return {
|
|
1893
1984
|
x: Math.min(s.x, s.x + s.w),
|
|
1894
1985
|
y: Math.min(s.y, s.y + s.h),
|
|
@@ -1928,7 +2019,13 @@ export function translateOne(s: Stroke, dx: number, dy: number): Stroke {
|
|
|
1928
2019
|
if (s.tool === 'ellipse') return { ...s, cx: s.cx + dx, cy: s.cy + dy };
|
|
1929
2020
|
if (s.tool === 'arrow')
|
|
1930
2021
|
return { ...s, x1: s.x1 + dx, y1: s.y1 + dy, x2: s.x2 + dx, y2: s.y2 + dy };
|
|
1931
|
-
if (
|
|
2022
|
+
if (
|
|
2023
|
+
s.tool === 'sticky' ||
|
|
2024
|
+
s.tool === 'image' ||
|
|
2025
|
+
s.tool === 'link' ||
|
|
2026
|
+
s.tool === 'mediaref' ||
|
|
2027
|
+
s.tool === 'section'
|
|
2028
|
+
)
|
|
1932
2029
|
return { ...s, x: s.x + dx, y: s.y + dy };
|
|
1933
2030
|
// text — anchored inherits its host's bbox (moves with the host); standalone
|
|
1934
2031
|
// (Phase 21) carries its own world (x, y) and translates directly.
|
|
@@ -1997,6 +2094,10 @@ export const ANNOTATION_SVG_ELEMENTS = new Set([
|
|
|
1997
2094
|
* is stripped by Rule 3. Pairs with the asset-write caps (DDR Task 9).
|
|
1998
2095
|
*/
|
|
1999
2096
|
export const ASSET_IMAGE_HREF_RE = /^assets\/[A-Za-z0-9._-]+\.(?:png|jpe?g|webp|gif)$/;
|
|
2097
|
+
// DDR-150 P4 — a media-reference chip's data-src: a relative assets/ path to a
|
|
2098
|
+
// video/audio clip (no scheme, no traversal). Same shape as the image href gate.
|
|
2099
|
+
export const ASSET_MEDIA_SRC_RE =
|
|
2100
|
+
/^assets\/[A-Za-z0-9._-]+\.(?:mp4|webm|mov|m4v|mp3|wav|m4a|aac|ogg)$/;
|
|
2000
2101
|
|
|
2001
2102
|
/**
|
|
2002
2103
|
* A3 (DDR-060 F1 re-audit) — sanitize an annotation SVG before it is persisted /
|