@1agh/maude 0.41.0 → 0.43.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/apps/studio/.ai/cache/_stats.json +7 -0
- package/apps/studio/acp/bootstrap-brief.ts +12 -2
- package/apps/studio/annotations-layer.tsx +1055 -278
- package/apps/studio/annotations-model.ts +58 -0
- package/apps/studio/api.ts +173 -63
- package/apps/studio/bin/_html-playwright.mjs +26 -4
- package/apps/studio/bin/_ingest-footage.mjs +386 -0
- package/apps/studio/bin/_pdf-playwright.mjs +13 -2
- package/apps/studio/bin/_png-playwright.mjs +15 -2
- package/apps/studio/bin/_pptx-playwright.mjs +17 -4
- package/apps/studio/bin/_probe-footage-playwright.mjs +269 -0
- package/apps/studio/bin/_screenshot-playwright.mjs +17 -2
- package/apps/studio/bin/_svg-playwright.mjs +26 -4
- package/apps/studio/bin/_video-playwright.mjs +141 -71
- package/apps/studio/bin/ingest-footage.sh +27 -0
- package/apps/studio/bin/photo-adjust.sh +163 -0
- package/apps/studio/bin/photo-bg-remove.sh +160 -0
- package/apps/studio/bin/probe-footage.sh +28 -0
- package/apps/studio/bin/read-annotations.mjs +125 -2
- package/apps/studio/bin/screenshot.sh +53 -4
- package/apps/studio/canvas-edit.ts +459 -10
- package/apps/studio/canvas-lib.tsx +523 -5
- package/apps/studio/canvas-pipeline.ts +65 -7
- package/apps/studio/canvas-shell.tsx +156 -16
- package/apps/studio/client/app.jsx +476 -88
- package/apps/studio/client/export-center.jsx +460 -0
- package/apps/studio/client/github.js +4 -0
- package/apps/studio/client/panels/GitPanel.jsx +8 -0
- package/apps/studio/client/panels/RepoBranchSwitcher.jsx +133 -21
- package/apps/studio/client/panels/StickerPicker.jsx +160 -0
- package/apps/studio/client/panels/TimelinePanel.jsx +15 -2
- package/apps/studio/client/photo-knobs.jsx +437 -0
- package/apps/studio/client/styles/3-shell-maude.css +59 -0
- package/apps/studio/client/styles/4-components.css +150 -0
- package/apps/studio/commands/edit-source-command.ts +31 -4
- package/apps/studio/config.schema.json +2 -2
- package/apps/studio/context-menu.tsx +31 -6
- package/apps/studio/dist/client.bundle.js +5561 -19
- package/apps/studio/dist/comment-mount.js +2 -2
- package/apps/studio/dist/runtime/.min-sizes.json +1 -0
- package/apps/studio/dist/runtime/@imgly_background-removal.js +5543 -0
- package/apps/studio/dist/runtime/pixi-js.js +519 -519
- package/apps/studio/dist/styles.css +1 -1
- package/apps/studio/dom-selection.ts +25 -0
- package/apps/studio/export-dialog.tsx +18 -25
- package/apps/studio/exporters/_runtime.ts +104 -0
- package/apps/studio/exporters/html.ts +12 -20
- package/apps/studio/exporters/index.ts +14 -2
- package/apps/studio/exporters/jobs.ts +376 -0
- package/apps/studio/exporters/pdf.ts +16 -20
- package/apps/studio/exporters/png.ts +12 -20
- package/apps/studio/exporters/pptx.ts +22 -23
- package/apps/studio/exporters/scope.ts +1 -0
- package/apps/studio/exporters/svg.ts +14 -22
- package/apps/studio/exporters/video.ts +37 -19
- package/apps/studio/footage/schema.test.ts +195 -0
- package/apps/studio/footage/schema.ts +484 -0
- package/apps/studio/footage-store.ts +235 -0
- package/apps/studio/fs-watch.ts +10 -0
- package/apps/studio/git/endpoints.ts +68 -7
- package/apps/studio/git/service.ts +198 -20
- package/apps/studio/github/service.ts +67 -0
- package/apps/studio/handoff.ts +3 -2
- package/apps/studio/http.ts +318 -64
- package/apps/studio/input-router.tsx +10 -0
- package/apps/studio/inspect.ts +53 -1
- package/apps/studio/paths.ts +10 -0
- package/apps/studio/photo/filters.ts +285 -0
- package/apps/studio/photo/pipeline.ts +607 -0
- package/apps/studio/photo/schema.ts +367 -0
- package/apps/studio/photo-store.ts +154 -0
- package/apps/studio/runtime-bundle.ts +29 -6
- package/apps/studio/server.ts +8 -2
- package/apps/studio/stickers/figjam-doodle/manifest.json +104 -0
- package/apps/studio/stickers/figjam-doodle/slice1.png +0 -0
- package/apps/studio/stickers/figjam-doodle/slice10.png +0 -0
- package/apps/studio/stickers/figjam-doodle/slice11.png +0 -0
- package/apps/studio/stickers/figjam-doodle/slice12.png +0 -0
- package/apps/studio/stickers/figjam-doodle/slice13.png +0 -0
- package/apps/studio/stickers/figjam-doodle/slice14.png +0 -0
- package/apps/studio/stickers/figjam-doodle/slice15.png +0 -0
- package/apps/studio/stickers/figjam-doodle/slice16.png +0 -0
- package/apps/studio/stickers/figjam-doodle/slice17.png +0 -0
- package/apps/studio/stickers/figjam-doodle/slice18.png +0 -0
- package/apps/studio/stickers/figjam-doodle/slice19.png +0 -0
- package/apps/studio/stickers/figjam-doodle/slice2.png +0 -0
- package/apps/studio/stickers/figjam-doodle/slice20.png +0 -0
- package/apps/studio/stickers/figjam-doodle/slice21.png +0 -0
- package/apps/studio/stickers/figjam-doodle/slice22.png +0 -0
- package/apps/studio/stickers/figjam-doodle/slice23.png +0 -0
- package/apps/studio/stickers/figjam-doodle/slice24.png +0 -0
- package/apps/studio/stickers/figjam-doodle/slice3.png +0 -0
- package/apps/studio/stickers/figjam-doodle/slice4.png +0 -0
- package/apps/studio/stickers/figjam-doodle/slice5.png +0 -0
- package/apps/studio/stickers/figjam-doodle/slice6.png +0 -0
- package/apps/studio/stickers/figjam-doodle/slice7.png +0 -0
- package/apps/studio/stickers/figjam-doodle/slice8.png +0 -0
- package/apps/studio/stickers/figjam-doodle/slice9.png +0 -0
- package/apps/studio/stickers/life-style/best.png +0 -0
- package/apps/studio/stickers/life-style/come-on.png +0 -0
- package/apps/studio/stickers/life-style/cut.png +0 -0
- package/apps/studio/stickers/life-style/detox.png +0 -0
- package/apps/studio/stickers/life-style/just.png +0 -0
- package/apps/studio/stickers/life-style/manifest.json +68 -0
- package/apps/studio/stickers/life-style/mirror.png +0 -0
- package/apps/studio/stickers/life-style/nice.png +0 -0
- package/apps/studio/stickers/life-style/objects.png +0 -0
- package/apps/studio/stickers/life-style/ok.png +0 -0
- package/apps/studio/stickers/life-style/queen.png +0 -0
- package/apps/studio/stickers/life-style/star.png +0 -0
- package/apps/studio/stickers/life-style/sun.png +0 -0
- package/apps/studio/stickers/life-style/water.png +0 -0
- package/apps/studio/stickers/life-style/yeah.png +0 -0
- package/apps/studio/stickers/life-style/you-can.png +0 -0
- package/apps/studio/stickers/opposing-thoughts/check-the-deets.png +0 -0
- package/apps/studio/stickers/opposing-thoughts/cut-it.png +0 -0
- package/apps/studio/stickers/opposing-thoughts/dope.png +0 -0
- package/apps/studio/stickers/opposing-thoughts/fresh.png +0 -0
- package/apps/studio/stickers/opposing-thoughts/hot.png +0 -0
- package/apps/studio/stickers/opposing-thoughts/idea.png +0 -0
- package/apps/studio/stickers/opposing-thoughts/keep-exploring.png +0 -0
- package/apps/studio/stickers/opposing-thoughts/killed-it.png +0 -0
- package/apps/studio/stickers/opposing-thoughts/love-it.png +0 -0
- package/apps/studio/stickers/opposing-thoughts/manifest.json +88 -0
- package/apps/studio/stickers/opposing-thoughts/not-sure.png +0 -0
- package/apps/studio/stickers/opposing-thoughts/ok.png +0 -0
- package/apps/studio/stickers/opposing-thoughts/pure-gold.png +0 -0
- package/apps/studio/stickers/opposing-thoughts/save-for-later.png +0 -0
- package/apps/studio/stickers/opposing-thoughts/steal-this.png +0 -0
- package/apps/studio/stickers/opposing-thoughts/take-a-peek.png +0 -0
- package/apps/studio/stickers/opposing-thoughts/this-or-that.png +0 -0
- package/apps/studio/stickers/opposing-thoughts/thoughts.png +0 -0
- package/apps/studio/stickers/opposing-thoughts/vibes.png +0 -0
- package/apps/studio/stickers/opposing-thoughts/winner.png +0 -0
- package/apps/studio/stickers/opposing-thoughts/wip.png +0 -0
- package/apps/studio/stickers/project-status/group-100.png +0 -0
- package/apps/studio/stickers/project-status/group-101.png +0 -0
- package/apps/studio/stickers/project-status/group-102.png +0 -0
- package/apps/studio/stickers/project-status/group-103.png +0 -0
- package/apps/studio/stickers/project-status/group-104.png +0 -0
- package/apps/studio/stickers/project-status/group-105.png +0 -0
- package/apps/studio/stickers/project-status/group-106.png +0 -0
- package/apps/studio/stickers/project-status/group-107.png +0 -0
- package/apps/studio/stickers/project-status/group-108.png +0 -0
- package/apps/studio/stickers/project-status/group-109.png +0 -0
- package/apps/studio/stickers/project-status/group-110.png +0 -0
- package/apps/studio/stickers/project-status/group-111.png +0 -0
- package/apps/studio/stickers/project-status/group-112.png +0 -0
- package/apps/studio/stickers/project-status/group-113.png +0 -0
- package/apps/studio/stickers/project-status/group-114.png +0 -0
- package/apps/studio/stickers/project-status/group-115.png +0 -0
- package/apps/studio/stickers/project-status/group-117.png +0 -0
- package/apps/studio/stickers/project-status/group-118.png +0 -0
- package/apps/studio/stickers/project-status/group-119.png +0 -0
- package/apps/studio/stickers/project-status/group-120.png +0 -0
- package/apps/studio/stickers/project-status/group-121.png +0 -0
- package/apps/studio/stickers/project-status/group-122.png +0 -0
- package/apps/studio/stickers/project-status/group-41.png +0 -0
- package/apps/studio/stickers/project-status/group-42.png +0 -0
- package/apps/studio/stickers/project-status/group-43.png +0 -0
- package/apps/studio/stickers/project-status/group-44.png +0 -0
- package/apps/studio/stickers/project-status/group-45.png +0 -0
- package/apps/studio/stickers/project-status/group-46.png +0 -0
- package/apps/studio/stickers/project-status/group-47.png +0 -0
- package/apps/studio/stickers/project-status/group-48.png +0 -0
- package/apps/studio/stickers/project-status/group-49.png +0 -0
- package/apps/studio/stickers/project-status/group-50.png +0 -0
- package/apps/studio/stickers/project-status/group-51.png +0 -0
- package/apps/studio/stickers/project-status/group-52.png +0 -0
- package/apps/studio/stickers/project-status/group-53.png +0 -0
- package/apps/studio/stickers/project-status/group-54.png +0 -0
- package/apps/studio/stickers/project-status/group-55.png +0 -0
- package/apps/studio/stickers/project-status/group-56.png +0 -0
- package/apps/studio/stickers/project-status/group-57.png +0 -0
- package/apps/studio/stickers/project-status/group-58.png +0 -0
- package/apps/studio/stickers/project-status/group-59.png +0 -0
- package/apps/studio/stickers/project-status/group-60.png +0 -0
- package/apps/studio/stickers/project-status/group-61.png +0 -0
- package/apps/studio/stickers/project-status/group-62.png +0 -0
- package/apps/studio/stickers/project-status/group-63.png +0 -0
- package/apps/studio/stickers/project-status/group-64.png +0 -0
- package/apps/studio/stickers/project-status/group-65.png +0 -0
- package/apps/studio/stickers/project-status/group-66.png +0 -0
- package/apps/studio/stickers/project-status/group-67.png +0 -0
- package/apps/studio/stickers/project-status/group-68.png +0 -0
- package/apps/studio/stickers/project-status/group-69.png +0 -0
- package/apps/studio/stickers/project-status/group-70.png +0 -0
- package/apps/studio/stickers/project-status/group-71.png +0 -0
- package/apps/studio/stickers/project-status/group-72.png +0 -0
- package/apps/studio/stickers/project-status/group-73.png +0 -0
- package/apps/studio/stickers/project-status/group-74.png +0 -0
- package/apps/studio/stickers/project-status/group-75.png +0 -0
- package/apps/studio/stickers/project-status/group-76.png +0 -0
- package/apps/studio/stickers/project-status/group-77.png +0 -0
- package/apps/studio/stickers/project-status/group-78.png +0 -0
- package/apps/studio/stickers/project-status/group-79.png +0 -0
- package/apps/studio/stickers/project-status/group-80.png +0 -0
- package/apps/studio/stickers/project-status/group-81.png +0 -0
- package/apps/studio/stickers/project-status/group-82.png +0 -0
- package/apps/studio/stickers/project-status/group-83.png +0 -0
- package/apps/studio/stickers/project-status/group-84.png +0 -0
- package/apps/studio/stickers/project-status/group-85.png +0 -0
- package/apps/studio/stickers/project-status/group-86.png +0 -0
- package/apps/studio/stickers/project-status/group-87.png +0 -0
- package/apps/studio/stickers/project-status/group-88.png +0 -0
- package/apps/studio/stickers/project-status/group-89.png +0 -0
- package/apps/studio/stickers/project-status/group-90.png +0 -0
- package/apps/studio/stickers/project-status/group-91.png +0 -0
- package/apps/studio/stickers/project-status/group-92.png +0 -0
- package/apps/studio/stickers/project-status/group-93.png +0 -0
- package/apps/studio/stickers/project-status/group-94.png +0 -0
- package/apps/studio/stickers/project-status/group-96.png +0 -0
- package/apps/studio/stickers/project-status/group-97.png +0 -0
- package/apps/studio/stickers/project-status/group-98.png +0 -0
- package/apps/studio/stickers/project-status/group-99.png +0 -0
- package/apps/studio/stickers/project-status/manifest.json +328 -0
- package/apps/studio/test/acp-bootstrap-brief.test.ts +11 -0
- package/apps/studio/test/acp-commands.test.ts +2 -1
- package/apps/studio/test/asset-api.test.ts +3 -3
- package/apps/studio/test/canvas-edit.test.ts +17 -6
- package/apps/studio/test/canvas-origin-gate.test.ts +19 -0
- package/apps/studio/test/dns-rebinding-guard.test.ts +27 -0
- package/apps/studio/test/dynamic-text-edit.test.ts +162 -0
- package/apps/studio/test/edit-source-command.test.ts +23 -0
- package/apps/studio/test/element-structural-edit.test.ts +46 -0
- package/apps/studio/test/export-center.test.tsx +287 -0
- package/apps/studio/test/export-shim-multi-capture.test.ts +83 -0
- package/apps/studio/test/exporters/history.test.ts +32 -3
- package/apps/studio/test/exporters/jobs.test.ts +263 -0
- package/apps/studio/test/footage-store.test.ts +100 -0
- package/apps/studio/test/git-branches.test.ts +97 -0
- package/apps/studio/test/github-api.test.ts +56 -1
- package/apps/studio/test/input-router.test.ts +33 -0
- package/apps/studio/test/inspect-script-syntax.test.ts +53 -0
- package/apps/studio/test/photo-canvas-bundle.test.ts +61 -0
- package/apps/studio/test/photo-edit-api.test.ts +201 -0
- package/apps/studio/test/photo-filters.test.ts +149 -0
- package/apps/studio/test/photo-pipeline.test.ts +106 -0
- package/apps/studio/test/photo-taxonomy.test.ts +96 -0
- package/apps/studio/test/read-annotations.test.ts +164 -0
- package/apps/studio/test/shell-importmap.test.ts +49 -0
- package/apps/studio/test/text-editability-stamp.test.ts +131 -0
- package/apps/studio/test/timeline-parse.test.ts +57 -0
- package/apps/studio/test/tool-palette-insert-anchor.test.ts +5 -3
- package/apps/studio/test/undo-stack.test.ts +33 -0
- package/apps/studio/test/video-asset.test.ts +5 -5
- package/apps/studio/test/video-render-bridge.test.ts +23 -1
- package/apps/studio/text-caret.ts +239 -0
- package/apps/studio/tool-palette.tsx +43 -20
- package/apps/studio/undo-stack.ts +94 -2
- package/apps/studio/use-annotation-resize.tsx +4 -4
- package/apps/studio/use-canvas-media-drop.tsx +38 -1
- package/apps/studio/use-selection-set.tsx +21 -0
- package/apps/studio/video-comp.tsx +48 -7
- package/apps/studio/whats-new.json +70 -0
- package/apps/studio/ws.ts +6 -0
- package/cli/commands/design.mjs +34 -3
- package/cli/lib/gitignore-block.mjs +2 -0
- package/package.json +10 -10
- package/plugins/design/templates/_shell.html +1 -0
|
@@ -116,6 +116,18 @@ function registry(): Map<string, CompEntry> {
|
|
|
116
116
|
return w.__maudeVideoComps;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
// rca/issue-video-artboard-frame-reset-on-edit — the LAST live-preview frame
|
|
120
|
+
// per comp, hoisted above every remount boundary (module scope, mirrors
|
|
121
|
+
// canvas-lib.tsx's `liveViewport`). A canvas edit (ACP/agent/inspector/text)
|
|
122
|
+
// remounts the canvas subtree (canvas-comment-mount.tsx `key={attempt}`), and
|
|
123
|
+
// video-comp.tsx's own module survives that remount — so a fresh VideoComp
|
|
124
|
+
// mount can read the Timeline's last position here instead of always opening
|
|
125
|
+
// on the static `posterFrame`. A full page load clears it — correct; the
|
|
126
|
+
// shell re-seeds via the `timeline-comps` re-announce (app.jsx) once the new
|
|
127
|
+
// Player registers. Never touched during capture (`hideChrome()` forces the
|
|
128
|
+
// deterministic frame 0 / render-shim frame regardless of this mirror).
|
|
129
|
+
const liveTimelineFrame = new Map<string, number>();
|
|
130
|
+
|
|
119
131
|
function clamp(n: number, lo: number, hi: number): number {
|
|
120
132
|
return Math.max(lo, Math.min(hi, n));
|
|
121
133
|
}
|
|
@@ -226,7 +238,7 @@ export interface VideoCompProps extends VideoCompMeta {
|
|
|
226
238
|
/** Show the Player's own transport chrome in PREVIEW. Auto-hidden during
|
|
227
239
|
* capture/export (the `?hide-chrome=1` shell flag). Default true. */
|
|
228
240
|
controls?: boolean;
|
|
229
|
-
/** Loop preview playback. Default
|
|
241
|
+
/** Loop preview playback. Default false — the user opts in via the Timeline. */
|
|
230
242
|
loop?: boolean;
|
|
231
243
|
/**
|
|
232
244
|
* Autoplay in preview. Default: play unless the viewer prefers reduced motion
|
|
@@ -281,7 +293,7 @@ export function VideoComp({
|
|
|
281
293
|
id,
|
|
282
294
|
inputProps,
|
|
283
295
|
controls,
|
|
284
|
-
loop =
|
|
296
|
+
loop = false,
|
|
285
297
|
autoPlay,
|
|
286
298
|
}: VideoCompProps) {
|
|
287
299
|
const ref = useRef<PlayerRef | null>(null);
|
|
@@ -301,9 +313,15 @@ export function VideoComp({
|
|
|
301
313
|
// autoplay; capture never autoplays (the shim drives frames). Opens on a
|
|
302
314
|
// poster frame ~35% in so a paused comp shows content, not an empty frame 0.
|
|
303
315
|
const play = (autoPlay ?? false) && !capturing;
|
|
304
|
-
const
|
|
316
|
+
const maxFrame = Math.max(0, durationInFrames - 1);
|
|
317
|
+
const posterFrame = capturing ? 0 : Math.min(maxFrame, Math.round(durationInFrames * 0.35));
|
|
318
|
+
// rca/issue-video-artboard-frame-reset-on-edit — reopen on the Timeline's
|
|
319
|
+
// last known frame for this comp (survives the remount that tore this
|
|
320
|
+
// instance down), not the fixed poster-frame formula. Falls back to
|
|
321
|
+
// posterFrame on a genuinely first-ever mount (nothing recorded yet).
|
|
322
|
+
const initialFrame = capturing
|
|
305
323
|
? 0
|
|
306
|
-
:
|
|
324
|
+
: clamp(liveTimelineFrame.get(compId) ?? posterFrame, 0, maxFrame);
|
|
307
325
|
|
|
308
326
|
// Register with the seek bridge for the lifetime of this mount.
|
|
309
327
|
useEffect(() => {
|
|
@@ -353,8 +371,10 @@ export function VideoComp({
|
|
|
353
371
|
if (!p) return;
|
|
354
372
|
try {
|
|
355
373
|
if (m.dgn === 'timeline-seek' && typeof m.frame === 'number') {
|
|
374
|
+
const f = clamp(Math.round(m.frame), 0, Math.max(0, durationInFrames - 1));
|
|
356
375
|
p.pause();
|
|
357
|
-
p.seekTo(
|
|
376
|
+
p.seekTo(f);
|
|
377
|
+
liveTimelineFrame.set(compId, f);
|
|
358
378
|
} else if (m.dgn === 'timeline-play') {
|
|
359
379
|
p.play();
|
|
360
380
|
} else if (m.dgn === 'timeline-pause') {
|
|
@@ -382,7 +402,9 @@ export function VideoComp({
|
|
|
382
402
|
if (!p) return;
|
|
383
403
|
const onFrame = () => {
|
|
384
404
|
try {
|
|
385
|
-
|
|
405
|
+
const f = p.getCurrentFrame();
|
|
406
|
+
liveTimelineFrame.set(compId, f);
|
|
407
|
+
postToShell({ dgn: 'timeline-frame', id: compId, frame: f });
|
|
386
408
|
} catch {
|
|
387
409
|
/* ignore */
|
|
388
410
|
}
|
|
@@ -397,6 +419,25 @@ export function VideoComp({
|
|
|
397
419
|
};
|
|
398
420
|
}, [compId]);
|
|
399
421
|
|
|
422
|
+
// iframe → shell: with loop off (now the default), the Player stops itself
|
|
423
|
+
// at the last frame — nothing else tells the Timeline panel's Play/Pause
|
|
424
|
+
// button to flip back to Play, so it reads "still playing" forever. Mirror
|
|
425
|
+
// the Player's own `ended` event so the shell can resync (rca/issue-video-
|
|
426
|
+
// artboard-loop-defaults-on).
|
|
427
|
+
useEffect(() => {
|
|
428
|
+
const p = ref.current;
|
|
429
|
+
if (!p) return;
|
|
430
|
+
const onEnded = () => postToShell({ dgn: 'timeline-ended', id: compId });
|
|
431
|
+
p.addEventListener('ended', onEnded);
|
|
432
|
+
return () => {
|
|
433
|
+
try {
|
|
434
|
+
p.removeEventListener('ended', onEnded);
|
|
435
|
+
} catch {
|
|
436
|
+
/* ignore */
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
}, [compId]);
|
|
440
|
+
|
|
400
441
|
const style = useMemo(() => ({ width: '100%', height: '100%', display: 'block' as const }), []);
|
|
401
442
|
|
|
402
443
|
return (
|
|
@@ -416,7 +457,7 @@ export function VideoComp({
|
|
|
416
457
|
controls={showControls}
|
|
417
458
|
loop={loopState}
|
|
418
459
|
autoPlay={play}
|
|
419
|
-
initialFrame={
|
|
460
|
+
initialFrame={initialFrame}
|
|
420
461
|
// Clicking the artboard must NOT toggle playback — it selects elements
|
|
421
462
|
// for editing (the whole point of a canvas). Play only via the explicit
|
|
422
463
|
// transport button (Player controls / Timeline panel). Same for the
|
|
@@ -1,6 +1,76 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "./whats-new.schema.json",
|
|
3
3
|
"entries": [
|
|
4
|
+
{
|
|
5
|
+
"id": "photo-editor",
|
|
6
|
+
"version": "0.43.0",
|
|
7
|
+
"date": "2026-07-10",
|
|
8
|
+
"kind": "feature",
|
|
9
|
+
"title": "Edit photos right on the canvas",
|
|
10
|
+
"summary": "A new Photo tab in the Inspector lets you tune any photo on your canvas — brightness, contrast, saturation, exposure, hue, sepia, grayscale, duotone, grain, pattern overlays, and vignette/reveal masks — with a live preview, whether it's an image you placed in an artboard or one you dropped/pasted onto the canvas. One click removes the background entirely (runs in your browser, no upload). Reach it from the Inspector's Photo tab or right-click \"Edit Photo…\". Every edit is also scriptable headlessly via /design:photo, so an agent can tune a photo without touching a slider.",
|
|
11
|
+
"surface": "design-ui",
|
|
12
|
+
"tour": [
|
|
13
|
+
{
|
|
14
|
+
"target": "[data-tour=\"inspector-tabs\"]",
|
|
15
|
+
"title": "Photo tab",
|
|
16
|
+
"body": "Select any photo on the canvas and a Photo tab appears here — adjustments, duotone, grain, pattern, masks, and one-click background removal.",
|
|
17
|
+
"placement": "bottom"
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"id": "footage-analysis-director-reel",
|
|
23
|
+
"version": "0.43.0",
|
|
24
|
+
"date": "2026-07-10",
|
|
25
|
+
"kind": "feature",
|
|
26
|
+
"title": "Turn a folder of clips into a cut — Maude watches your footage first",
|
|
27
|
+
"summary": "New /design:reel: point Maude at a folder of raw video (or the clips already on your canvas) and it actually WATCHES the footage first — pulling keyframes from each clip to find the good shots and read its character — then directs them like an editor into a graphics-laden cut with titles and transitions, ready to scrub on the Timeline and export to MP4. It can use several moments from one clip, orders them so they tell a story, and needs no extra install (frames are decoded in the browser, no ffmpeg). Analysis is vision-only; drop in a music track and it rides under the finished cut.",
|
|
28
|
+
"surface": "design-ui"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"id": "ssh-remote-publish-and-pr-flow",
|
|
32
|
+
"version": "0.43.0",
|
|
33
|
+
"date": "2026-07-10",
|
|
34
|
+
"kind": "feature",
|
|
35
|
+
"title": "Share to a protected branch — via a pull request",
|
|
36
|
+
"summary": "On a GitHub project, \"Add to Shared version\" now pushes your draft and opens a pull request into main, so it works even when main is protected and a direct push would be rejected — the pull-request link opens right from the dialog. Publishing and getting the latest now work on SSH remotes too, and a blue \"Get latest\" button appears in the dock the moment a teammate's work is ahead, so you're nudged to pull without hunting for it.",
|
|
37
|
+
"surface": "design-ui"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"id": "unified-text-editing",
|
|
41
|
+
"version": "0.43.0",
|
|
42
|
+
"date": "2026-07-10",
|
|
43
|
+
"kind": "feature",
|
|
44
|
+
"title": "Edit any text on the canvas, inline",
|
|
45
|
+
"summary": "Every kind of text on the canvas now edits the same predictable way — click to place a blinking caret, type, Enter to confirm, Shift+Enter for a new line — across an element's copy, shape and sticky labels, standalone text, and section titles. Text that's filled in from a list or variable (like cards built from data) is now editable in place too: double-click and change the words directly, and it's traced back to the right source. Only genuinely computed text still sends you to chat or /design:edit.",
|
|
46
|
+
"surface": "design-ui"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"id": "whiteboard-annotation-improvements",
|
|
50
|
+
"version": "0.43.0",
|
|
51
|
+
"date": "2026-07-10",
|
|
52
|
+
"kind": "feature",
|
|
53
|
+
"title": "Bulk resize, sticky authors & fun stickers",
|
|
54
|
+
"summary": "Select several stickies, shapes or images together and resize the whole group proportionally with live corner handles, instead of one at a time. Sticky notes now show who drew them with a name badge. Text editing got a real pass: a visible blinking caret everywhere you edit text, double-click places the caret where you clicked instead of selecting everything, hovering text shows a text cursor, and a new shape or sticky auto-focuses so you can start typing immediately. Also new: a searchable, FigJam-style sticker picker with genuinely fun (not emoji) bundled sticker packs, and /design:board now understands generation requests like \"make me a team sprint retro\" directly.",
|
|
55
|
+
"surface": "design-ui"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"id": "background-export-notification-center",
|
|
59
|
+
"version": "0.42.0",
|
|
60
|
+
"date": "2026-07-09",
|
|
61
|
+
"kind": "feature",
|
|
62
|
+
"title": "Exports now run in the background",
|
|
63
|
+
"summary": "Hitting Export no longer locks up the dialog until the render finishes — it closes right away and a new Exports button in the menubar tracks progress, with a toast when it's ready and a Download/Save button. Multiple exports can run at once, so a quick PNG doesn't have to wait behind a slow PDF or video. Also fixes a bug where exporting every artboard on a canvas separately could scramble some of the pages.",
|
|
64
|
+
"surface": "design-ui",
|
|
65
|
+
"tour": [
|
|
66
|
+
{
|
|
67
|
+
"target": "[data-tour=\"exports\"]",
|
|
68
|
+
"title": "Exports run in the background",
|
|
69
|
+
"body": "Kick off an export and keep working — this button shows progress and lights up when it's ready to download or save.",
|
|
70
|
+
"placement": "bottom"
|
|
71
|
+
}
|
|
72
|
+
]
|
|
73
|
+
},
|
|
4
74
|
{
|
|
5
75
|
"id": "desktop-intel-mac-support",
|
|
6
76
|
"version": "0.41.0",
|
package/apps/studio/ws.ts
CHANGED
|
@@ -216,6 +216,12 @@ export function createWs(
|
|
|
216
216
|
// Assistant panel. Inspector clients only — same-origin shell, like the rest.
|
|
217
217
|
ctx.bus.on('acp-focus', () => broadcast({ type: 'acp-focus' }));
|
|
218
218
|
|
|
219
|
+
// feature-background-export-notification-center — export job queue state
|
|
220
|
+
// changes (queued → running → progress ticks → done/failed). Full-snapshot
|
|
221
|
+
// payload per change, mirroring git-status/sync:status above. Inspector
|
|
222
|
+
// clients only — same privileged-data class as the rest of this feed.
|
|
223
|
+
ctx.bus.on('export:job', (job: unknown) => broadcast({ type: 'export:job', payload: job }));
|
|
224
|
+
|
|
219
225
|
// HMR broadcaster — turns fs:any change events into `canvas-hmr` messages.
|
|
220
226
|
// The iframe-side client (in _shell.html) decides reload strategy from `mode`.
|
|
221
227
|
// Uses broadcastHmr so the segregated canvas origin's HMR-only sockets get it.
|
package/cli/commands/design.mjs
CHANGED
|
@@ -47,6 +47,19 @@ const BIN_VERBS = new Set([
|
|
|
47
47
|
'chat-open',
|
|
48
48
|
'ensure-browser',
|
|
49
49
|
'fetch-asset',
|
|
50
|
+
// feature-photo-editor (Stage G). `photo-adjust` is the thin non-browser
|
|
51
|
+
// parametric verb (curl → /_api/photo-edit). `photo-bg-remove` is the
|
|
52
|
+
// client-side @imgly ML harness (throwaway proof canvas + agent-browser
|
|
53
|
+
// attribute poll — see photo-bg-remove.sh's header for why).
|
|
54
|
+
'photo-adjust',
|
|
55
|
+
'photo-bg-remove',
|
|
56
|
+
// feature-footage-analysis-director. `ingest-footage` copies a folder of raw
|
|
57
|
+
// clips into assets/ (content-addressed, magic-byte sniffed). `probe-footage`
|
|
58
|
+
// decodes ONE clip in headless Chromium → keyframe PNGs for the footage-analyst's
|
|
59
|
+
// vision pass. Neither boots the dev server (probe is server-independent — it
|
|
60
|
+
// reads the clip as a file:// resource).
|
|
61
|
+
'ingest-footage',
|
|
62
|
+
'probe-footage',
|
|
50
63
|
]);
|
|
51
64
|
|
|
52
65
|
// Bin verbs that boot the dev-server (directly, or by shelling into server-up.sh).
|
|
@@ -140,7 +153,7 @@ Dev-tooling (dispatch to the dev-server bash helpers — DDR-062):
|
|
|
140
153
|
screenshot · server-up · prep · slug · bootstrap-check · runtime-health
|
|
141
154
|
smoke · canvas-edit · handoff · asset-sweep · visual-sanity · fetch-asset
|
|
142
155
|
draw-build · draw-proof · svg-optimize · to-lottie · read-annotations · annotate
|
|
143
|
-
canvas-rects
|
|
156
|
+
canvas-rects · ingest-footage · probe-footage
|
|
144
157
|
Invoke the bundled helper of the same name. maude resolves it from its
|
|
145
158
|
own package root and sets CLAUDE_PLUGIN_ROOT for the child; stdout,
|
|
146
159
|
stderr, and exit code pass straight through (so command-substitution
|
|
@@ -453,7 +466,22 @@ async function runExport({ args }) {
|
|
|
453
466
|
}
|
|
454
467
|
|
|
455
468
|
const format = positional[0];
|
|
456
|
-
|
|
469
|
+
// Includes the temporal formats (DDR-148): mp4/webm/gif render through the
|
|
470
|
+
// capture spine, same POST /_api/export the UI ⌘E dialog uses. Video export
|
|
471
|
+
// is always artboard-scoped (the comp's registered meta drives fps/duration).
|
|
472
|
+
const VALID_FORMATS = new Set([
|
|
473
|
+
'png',
|
|
474
|
+
'pdf',
|
|
475
|
+
'svg',
|
|
476
|
+
'html',
|
|
477
|
+
'pptx',
|
|
478
|
+
'canva',
|
|
479
|
+
'zip',
|
|
480
|
+
'mp4',
|
|
481
|
+
'webm',
|
|
482
|
+
'gif',
|
|
483
|
+
]);
|
|
484
|
+
const VIDEO_FORMATS = new Set(['mp4', 'webm', 'gif']);
|
|
457
485
|
if (!format || !VALID_FORMATS.has(format)) {
|
|
458
486
|
process.stderr.write(
|
|
459
487
|
`maude design export: missing or unknown <format>. Try one of: ${Array.from(VALID_FORMATS).join(', ')}\n`
|
|
@@ -461,7 +489,10 @@ async function runExport({ args }) {
|
|
|
461
489
|
process.exit(2);
|
|
462
490
|
}
|
|
463
491
|
|
|
464
|
-
|
|
492
|
+
// Video formats default to artboard scope (the only scope video supports —
|
|
493
|
+
// scope.ts resolves the artboard under the active canvas); other formats keep
|
|
494
|
+
// the canvas-as-separate default.
|
|
495
|
+
const scope = flags.scope ?? (VIDEO_FORMATS.has(format) ? 'artboard' : 'canvas-as-separate');
|
|
465
496
|
const VALID_SCOPES = new Set(['selection', 'artboard', 'canvas-as-separate', 'project-raw']);
|
|
466
497
|
if (!VALID_SCOPES.has(scope)) {
|
|
467
498
|
process.stderr.write(`maude design export: unknown --scope "${scope}"\n`);
|
|
@@ -39,10 +39,12 @@ export function buildBlock(designRel = '.design') {
|
|
|
39
39
|
`${root}/_locator.json`, // regenerable slug→path index
|
|
40
40
|
`${root}/_export-history.json`,
|
|
41
41
|
// Per-machine / per-user dirs.
|
|
42
|
+
`${root}/_export-jobs/`, // background-export job byte store (regenerable — feature-background-export-notification-center)
|
|
42
43
|
`${root}/_state/`, // binary CRDT logs (regenerable from hub)
|
|
43
44
|
`${root}/_history/`,
|
|
44
45
|
`${root}/_trash/`, // soft-deleted canvases (recoverable locally — Phase 22 delete)
|
|
45
46
|
`${root}/_draw/`, // draw-agent proof canvases (regenerable — Phase 25)
|
|
47
|
+
`${root}/_photo/`, // photo-bg-remove headless proof canvases (regenerable — feature-photo-editor)
|
|
46
48
|
`${root}/_smoke/`, // batch-screenshot output (regenerable — DDR-021)
|
|
47
49
|
`${root}/_canvas-state/`, // per-machine canvas scratch + camera (`*.view.json`, DDR-115)
|
|
48
50
|
`${root}/_chat/`, // ACP transcripts (per-machine)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@1agh/maude",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.43.0",
|
|
4
4
|
"description": "Marketplace of Claude Code plugins by Michal Dovrtěl: `design` (canvas-first design iteration) + `flow` (generic agentic workflow loop with .ai second brain). Ships the `maude` CLI (with `mdcc` legacy alias) to scaffold workspace, run the design dev server, and manage configs.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -50,13 +50,13 @@
|
|
|
50
50
|
"test:e2e:desktop:onboarding": "pnpm --filter @maude/desktop-e2e e2e:onboarding"
|
|
51
51
|
},
|
|
52
52
|
"optionalDependencies": {
|
|
53
|
-
"@1agh/maude-darwin-arm64": "0.
|
|
54
|
-
"@1agh/maude-darwin-x64": "0.
|
|
55
|
-
"@1agh/maude-linux-arm64": "0.
|
|
56
|
-
"@1agh/maude-linux-arm64-musl": "0.
|
|
57
|
-
"@1agh/maude-linux-x64": "0.
|
|
58
|
-
"@1agh/maude-linux-x64-musl": "0.
|
|
59
|
-
"@1agh/maude-win32-x64": "0.
|
|
53
|
+
"@1agh/maude-darwin-arm64": "0.43.0",
|
|
54
|
+
"@1agh/maude-darwin-x64": "0.43.0",
|
|
55
|
+
"@1agh/maude-linux-arm64": "0.43.0",
|
|
56
|
+
"@1agh/maude-linux-arm64-musl": "0.43.0",
|
|
57
|
+
"@1agh/maude-linux-x64": "0.43.0",
|
|
58
|
+
"@1agh/maude-linux-x64-musl": "0.43.0",
|
|
59
|
+
"@1agh/maude-win32-x64": "0.43.0"
|
|
60
60
|
},
|
|
61
61
|
"files": [
|
|
62
62
|
"cli",
|
|
@@ -94,9 +94,9 @@
|
|
|
94
94
|
"scaffold"
|
|
95
95
|
],
|
|
96
96
|
"devDependencies": {
|
|
97
|
-
"@biomejs/biome": "^2.
|
|
97
|
+
"@biomejs/biome": "^2.5.3",
|
|
98
98
|
"@changesets/cli": "^2.27.10",
|
|
99
|
-
"@playwright/test": "^1.
|
|
99
|
+
"@playwright/test": "^1.61.1"
|
|
100
100
|
},
|
|
101
101
|
"dependencies": {
|
|
102
102
|
"ajv": "^8.20.0",
|
|
@@ -135,6 +135,7 @@
|
|
|
135
135
|
"react/jsx-runtime": "/_canvas-runtime/react_jsx-runtime.js",
|
|
136
136
|
"react/jsx-dev-runtime": "/_canvas-runtime/react_jsx-dev-runtime.js",
|
|
137
137
|
"pixi.js": "/_canvas-runtime/pixi-js.js",
|
|
138
|
+
"@imgly/background-removal": "/_canvas-runtime/@imgly_background-removal.js",
|
|
138
139
|
"motion": "/_canvas-runtime/motion.js",
|
|
139
140
|
"motion/react": "/_canvas-runtime/motion_react.js",
|
|
140
141
|
"yjs": "/_canvas-runtime/yjs.js",
|