@1agh/maude 0.42.0 → 0.44.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/acp/bridge.ts +44 -10
- package/apps/studio/acp/env.ts +23 -0
- package/apps/studio/acp/login-state.ts +263 -0
- package/apps/studio/acp/plugin-bootstrap.ts +31 -25
- package/apps/studio/acp/probe.ts +152 -1
- package/apps/studio/annotations-layer.tsx +1451 -324
- package/apps/studio/annotations-model.ts +58 -0
- package/apps/studio/api.ts +568 -24
- package/apps/studio/bin/_audio-search.mjs +140 -0
- package/apps/studio/bin/_import-asset-pdf-worker.mjs +34 -0
- package/apps/studio/bin/_import-asset.mjs +815 -0
- package/apps/studio/bin/_import-brand.mjs +635 -0
- package/apps/studio/bin/_import-tokens-alias-resolver.mjs +95 -0
- package/apps/studio/bin/_import-tokens.mjs +1201 -0
- package/apps/studio/bin/_ingest-footage.mjs +386 -0
- package/apps/studio/bin/_probe-footage-playwright.mjs +269 -0
- package/apps/studio/bin/_transcribe.mjs +419 -0
- package/apps/studio/bin/_transcribe.test.mjs +80 -0
- package/apps/studio/bin/_video-playwright.mjs +141 -71
- package/apps/studio/bin/audio-search.sh +28 -0
- package/apps/studio/bin/generate.sh +154 -0
- package/apps/studio/bin/import-asset.sh +34 -0
- package/apps/studio/bin/import-brand.sh +29 -0
- package/apps/studio/bin/import-tokens.sh +33 -0
- 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 +258 -0
- package/apps/studio/bin/probe-footage.sh +28 -0
- package/apps/studio/bin/read-annotations.mjs +125 -2
- package/apps/studio/bin/transcribe.sh +39 -0
- package/apps/studio/canvas-edit.ts +656 -12
- package/apps/studio/canvas-lib.tsx +637 -10
- package/apps/studio/canvas-pipeline.ts +65 -7
- package/apps/studio/canvas-shell.tsx +156 -16
- package/apps/studio/client/app.jsx +2385 -699
- package/apps/studio/client/export-center.jsx +35 -1
- package/apps/studio/client/generate-dialog.jsx +352 -0
- package/apps/studio/client/github.js +18 -0
- package/apps/studio/client/inspector-controls.jsx +781 -0
- package/apps/studio/client/panels/BrandUploadPanel.jsx +233 -0
- package/apps/studio/client/panels/ChatPanel.jsx +15 -33
- package/apps/studio/client/panels/GitPanel.jsx +8 -0
- package/apps/studio/client/panels/IntroVideoDialog.jsx +44 -0
- package/apps/studio/client/panels/OnboardingWizard.jsx +12 -0
- package/apps/studio/client/panels/ReadinessList.jsx +227 -7
- package/apps/studio/client/panels/RepoBranchSwitcher.jsx +133 -21
- package/apps/studio/client/panels/SettingsPanel.jsx +828 -0
- package/apps/studio/client/panels/SetupChecklist.jsx +223 -0
- 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 +432 -0
- package/apps/studio/client/styles/3-shell-maude.css +376 -28
- package/apps/studio/client/styles/4-components.css +223 -0
- package/apps/studio/client/styles/6-acp-chat.css +86 -0
- package/apps/studio/client/tour/quick-setup-tour.js +39 -0
- package/apps/studio/commands/annotation-strokes-command.ts +13 -3
- package/apps/studio/commands/edit-source-command.ts +31 -4
- package/apps/studio/config.schema.json +70 -0
- package/apps/studio/context-menu.tsx +42 -8
- package/apps/studio/context.ts +16 -0
- package/apps/studio/design-setup-readiness.ts +115 -0
- package/apps/studio/dist/client.bundle.js +5572 -21
- 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/draw/palette.ts +34 -0
- package/apps/studio/exporters/jobs.ts +47 -5
- package/apps/studio/exporters/video.ts +24 -4
- package/apps/studio/footage/schema.test.ts +287 -0
- package/apps/studio/footage/schema.ts +662 -0
- package/apps/studio/footage-store.ts +235 -0
- package/apps/studio/fs-watch.ts +10 -0
- package/apps/studio/generation/adapters/elevenlabs.ts +370 -0
- package/apps/studio/generation/adapters/gemini.ts +542 -0
- package/apps/studio/generation/adapters/groq.test.ts +80 -0
- package/apps/studio/generation/adapters/groq.ts +247 -0
- package/apps/studio/generation/audio-library.test.ts +95 -0
- package/apps/studio/generation/audio-library.ts +156 -0
- package/apps/studio/generation/captions.test.ts +78 -0
- package/apps/studio/generation/captions.ts +132 -0
- package/apps/studio/generation/download.ts +76 -0
- package/apps/studio/generation/elevenlabs.test.ts +223 -0
- package/apps/studio/generation/gemini.test.ts +350 -0
- package/apps/studio/generation/jobs.test.ts +128 -0
- package/apps/studio/generation/jobs.ts +243 -0
- package/apps/studio/generation/keys.test.ts +75 -0
- package/apps/studio/generation/keys.ts +162 -0
- package/apps/studio/generation/prefs.test.ts +95 -0
- package/apps/studio/generation/prefs.ts +82 -0
- package/apps/studio/generation/registry.ts +88 -0
- package/apps/studio/generation/types.test.ts +123 -0
- package/apps/studio/generation/types.ts +266 -0
- package/apps/studio/generation/whisper-models.test.ts +152 -0
- package/apps/studio/generation/whisper-models.ts +257 -0
- package/apps/studio/generation/whisper-spike-results.md +61 -0
- package/apps/studio/git/endpoints.ts +68 -7
- package/apps/studio/git/service.ts +199 -21
- package/apps/studio/github/service.ts +67 -0
- package/apps/studio/handoff.ts +3 -2
- package/apps/studio/http.ts +1039 -22
- package/apps/studio/input-router.tsx +10 -0
- package/apps/studio/inspect.ts +53 -1
- package/apps/studio/media/intro.mp4 +0 -0
- package/apps/studio/media-commit-chain.ts +119 -0
- package/apps/studio/paths.ts +20 -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/readiness.ts +108 -20
- package/apps/studio/runtime-bundle.ts +29 -6
- package/apps/studio/scaffold-design.ts +1145 -0
- package/apps/studio/server.ts +18 -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/_helpers.ts +15 -2
- package/apps/studio/test/acp-bootstrap-brief.test.ts +11 -0
- package/apps/studio/test/acp-bridge.test.ts +34 -1
- package/apps/studio/test/acp-commands.test.ts +2 -1
- package/apps/studio/test/acp-env.test.ts +30 -0
- package/apps/studio/test/acp-plugin-bootstrap.test.ts +23 -57
- package/apps/studio/test/acp-session-plugins.test.ts +72 -1
- package/apps/studio/test/annotation-strokes-command.test.ts +17 -0
- package/apps/studio/test/annotations-layer.test.ts +174 -0
- 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 +50 -0
- package/apps/studio/test/csp-canvas-shell.test.ts +11 -0
- package/apps/studio/test/csrf-write-guard.test.ts +23 -1
- package/apps/studio/test/design-setup-readiness.test.ts +155 -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 +154 -0
- package/apps/studio/test/fixtures/fake-claude-auth.mjs +13 -0
- package/apps/studio/test/footage-store.test.ts +100 -0
- package/apps/studio/test/generate-route.test.ts +106 -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/import-asset-browser.test.ts +64 -0
- package/apps/studio/test/import-asset-route.test.ts +71 -0
- package/apps/studio/test/import-asset.test.ts +399 -0
- package/apps/studio/test/import-brand-browser.test.ts +88 -0
- package/apps/studio/test/import-brand-route.test.ts +120 -0
- package/apps/studio/test/import-brand.test.ts +206 -0
- package/apps/studio/test/import-tokens.test.ts +722 -0
- 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/media-commit-chain.test.ts +210 -0
- package/apps/studio/test/photo-bg-remove-validation.test.ts +71 -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/readiness.test.ts +13 -11
- package/apps/studio/test/scaffold-design.test.ts +122 -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/tour-overlay.test.tsx +16 -0
- 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 +49 -21
- package/apps/studio/ui-prefs.ts +130 -0
- 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 +40 -1
- package/apps/studio/use-chrome-visibility.tsx +8 -2
- package/apps/studio/use-selection-set.tsx +21 -0
- package/apps/studio/video-comp.tsx +48 -7
- package/apps/studio/whats-new.json +149 -0
- package/apps/studio/ws.ts +5 -0
- package/cli/bin/maude.mjs +6 -6
- package/cli/commands/design.mjs +67 -3
- package/cli/lib/gitignore-block.mjs +2 -0
- package/cli/lib/pkg-root.mjs +107 -0
- package/cli/lib/pkg-root.test.mjs +79 -0
- package/cli/lib/reconstruct-toolset.test.mjs +194 -0
- package/cli/lib/update-check.mjs +8 -0
- package/package.json +13 -11
- package/plugins/design/dependencies.json +18 -0
- package/plugins/design/templates/_shell.html +1 -0
|
@@ -126,84 +126,132 @@ try {
|
|
|
126
126
|
// — both fall through to the frame-step path below.
|
|
127
127
|
const useRenderer = !!renderLib && format !== 'gif' && !!compId;
|
|
128
128
|
|
|
129
|
+
// When the whole-comp renderer path throws we DON'T fail the export. The most
|
|
130
|
+
// common cause is a `RangeError: Maximum call stack size exceeded` from
|
|
131
|
+
// @remotion/web-renderer's guardless recursive DOM precompositing on a
|
|
132
|
+
// deeply-nested comp (RCA issue-video-mp4-rendermediaonweb-stack-overflow):
|
|
133
|
+
// one native recursion level per nested opacity/transform/filter/mask layer,
|
|
134
|
+
// no depth cap. Instead we degrade to the frame-step screenshot + mediabunny
|
|
135
|
+
// path below, which goes through Chromium's native compositor and is immune to
|
|
136
|
+
// that recursion. The one cost is audio — the frame-step path is video-only —
|
|
137
|
+
// so a comp that overflows the audio renderer still exports, just muted. That
|
|
138
|
+
// beats a hard failure with no file. `video.ts` always passes --encode-lib
|
|
139
|
+
// (only --render-lib is conditional), so the fallback has all it needs here.
|
|
140
|
+
let renderFallbackReason = null;
|
|
141
|
+
|
|
129
142
|
if (useRenderer) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
143
|
+
try {
|
|
144
|
+
const t0 = Date.now();
|
|
145
|
+
const libSrc = readFileSync(renderLib, 'utf8');
|
|
146
|
+
await page.addScriptTag({ content: libSrc, type: 'module' });
|
|
147
|
+
await page.waitForFunction(() => typeof window.__maudeRenderVideo__ === 'function', {
|
|
148
|
+
timeout: timeoutMs,
|
|
149
|
+
});
|
|
136
150
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
151
|
+
const explicitFrames = Number(framesArg);
|
|
152
|
+
const frameRange =
|
|
153
|
+
Number.isFinite(explicitFrames) && explicitFrames > 0 ? [0, explicitFrames - 1] : null;
|
|
140
154
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
155
|
+
const rendered = await page.evaluate(
|
|
156
|
+
async ({ compId, container, scale, muted, frameRange, licenseKey }) => {
|
|
157
|
+
return window.__maude_render_video__(compId, {
|
|
158
|
+
container,
|
|
159
|
+
scale,
|
|
160
|
+
muted,
|
|
161
|
+
frameRange,
|
|
162
|
+
licenseKey,
|
|
163
|
+
});
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
compId,
|
|
167
|
+
container: format,
|
|
168
|
+
scale: deviceScaleFactor,
|
|
169
|
+
muted: !wantAudio,
|
|
147
170
|
frameRange,
|
|
148
171
|
licenseKey,
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
{
|
|
152
|
-
compId,
|
|
153
|
-
container: format,
|
|
154
|
-
scale: deviceScaleFactor,
|
|
155
|
-
muted: !wantAudio,
|
|
156
|
-
frameRange,
|
|
157
|
-
licenseKey,
|
|
158
|
-
}
|
|
159
|
-
);
|
|
172
|
+
}
|
|
173
|
+
);
|
|
160
174
|
|
|
161
|
-
|
|
175
|
+
writeFileSync(out, Buffer.from(rendered.b64, 'base64'));
|
|
162
176
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
177
|
+
// Comp meta for the summary (diagnostic only — video.ts reads `container`).
|
|
178
|
+
const compMeta = await page.evaluate(
|
|
179
|
+
(id) =>
|
|
180
|
+
(typeof window.__maude_comps__ === 'function' ? window.__maude_comps__() : []).find(
|
|
181
|
+
(c) => c.id === id
|
|
182
|
+
) ?? null,
|
|
183
|
+
compId
|
|
184
|
+
);
|
|
185
|
+
const frameCount = frameRange
|
|
186
|
+
? frameRange[1] - frameRange[0] + 1
|
|
187
|
+
: (compMeta?.durationInFrames ?? 0);
|
|
188
|
+
|
|
189
|
+
const result = {
|
|
190
|
+
fps: compMeta?.fps ?? null,
|
|
191
|
+
frameCount,
|
|
192
|
+
width: Math.round((compMeta?.width ?? 0) * deviceScaleFactor),
|
|
193
|
+
height: Math.round((compMeta?.height ?? 0) * deviceScaleFactor),
|
|
194
|
+
out,
|
|
195
|
+
bytes: rendered.bytes,
|
|
196
|
+
container: rendered.container,
|
|
197
|
+
codec: rendered.videoCodec,
|
|
198
|
+
audioCodec: rendered.audioCodec,
|
|
199
|
+
};
|
|
200
|
+
const ms = Date.now() - t0;
|
|
201
|
+
console.error(
|
|
202
|
+
`✓ rendered ${rendered.container}/${rendered.videoCodec}` +
|
|
203
|
+
`${rendered.audioCodec ? `+${rendered.audioCodec}` : ' (muted)'} → ${out} (${rendered.bytes} B) in ${ms}ms`
|
|
204
|
+
);
|
|
205
|
+
console.log(JSON.stringify(result));
|
|
206
|
+
} catch (err) {
|
|
207
|
+
// Collapse newlines — the message carries an in-page (untrusted canvas,
|
|
208
|
+
// DDR-054) error + stack, and it flows to console.error / the job's
|
|
209
|
+
// persisted error, so a forged "\n[FATAL] …" line can't be injected into
|
|
210
|
+
// the dev-server's stderr or the history ledger.
|
|
211
|
+
renderFallbackReason = oneLine(err instanceof Error ? err.message : String(err));
|
|
212
|
+
console.error(
|
|
213
|
+
`⚠ renderMediaOnWeb failed (${renderFallbackReason}); falling back to ` +
|
|
214
|
+
'frame-step screenshot capture — video will export WITHOUT audio'
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Frame-step path: the normal route for gif / ordinary / comp-less artboards
|
|
220
|
+
// (useRenderer === false), AND the graceful-degradation fallback when the
|
|
221
|
+
// renderer above threw (renderFallbackReason !== null).
|
|
222
|
+
if (!useRenderer || renderFallbackReason !== null) {
|
|
223
|
+
try {
|
|
224
|
+
await frameStepCapture({
|
|
225
|
+
page,
|
|
226
|
+
handle,
|
|
227
|
+
compId,
|
|
228
|
+
fpsArg,
|
|
229
|
+
framesArg,
|
|
230
|
+
dumpDir,
|
|
231
|
+
encodeLib,
|
|
232
|
+
format,
|
|
233
|
+
out,
|
|
234
|
+
mode,
|
|
235
|
+
deviceScaleFactor,
|
|
236
|
+
timeoutMs,
|
|
237
|
+
fallbackReason: renderFallbackReason,
|
|
238
|
+
});
|
|
239
|
+
} catch (fallbackErr) {
|
|
240
|
+
// If we only reached the frame-step path because the renderer already
|
|
241
|
+
// failed, surface BOTH failures so a genuine bug isn't hidden behind the
|
|
242
|
+
// fallback's own error.
|
|
243
|
+
if (renderFallbackReason !== null) {
|
|
244
|
+
const fb = oneLine(
|
|
245
|
+
fallbackErr instanceof Error ? fallbackErr.message : String(fallbackErr)
|
|
246
|
+
);
|
|
247
|
+
throw new Error(
|
|
248
|
+
`video export failed on both paths — renderMediaOnWeb: ${renderFallbackReason}; ` +
|
|
249
|
+
`frame-step fallback: ${fb}`,
|
|
250
|
+
{ cause: fallbackErr }
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
throw fallbackErr;
|
|
254
|
+
}
|
|
207
255
|
}
|
|
208
256
|
} finally {
|
|
209
257
|
await browser.close();
|
|
@@ -227,6 +275,10 @@ async function frameStepCapture({
|
|
|
227
275
|
mode,
|
|
228
276
|
deviceScaleFactor,
|
|
229
277
|
timeoutMs,
|
|
278
|
+
// Set (to the renderer's error message) only when this run is the
|
|
279
|
+
// graceful-degradation fallback for a failed renderMediaOnWeb path; stamps
|
|
280
|
+
// `degraded`/`audioDropped` onto the stdout summary so video.ts can warn.
|
|
281
|
+
fallbackReason = null,
|
|
230
282
|
}) {
|
|
231
283
|
const rect0 = await handle.evaluate((el) => {
|
|
232
284
|
const r = el.getBoundingClientRect();
|
|
@@ -352,10 +404,22 @@ async function frameStepCapture({
|
|
|
352
404
|
{ b64, isGif }
|
|
353
405
|
);
|
|
354
406
|
}
|
|
407
|
+
// Machine-readable progress (stdout) — spawnShim parses `MAUDE_PROGRESS`
|
|
408
|
+
// lines → onProgress → job.progress → the live bar in the Exports panel, so
|
|
409
|
+
// a long frame-step render (the renderMediaOnWeb-overflow fallback) shows
|
|
410
|
+
// "N of M" instead of a static "Exporting…". Filtered out of the summary
|
|
411
|
+
// stdout the exporter reads. Human log stays throttled on stderr.
|
|
412
|
+
console.log(`MAUDE_PROGRESS {"current":${f + 1},"total":${frameCount}}`);
|
|
355
413
|
if (f % 30 === 0) console.error(`frame ${f + 1}/${frameCount}`);
|
|
356
414
|
}
|
|
357
415
|
|
|
358
416
|
let result = { fps, frameCount, width: outW, height: outH, framePaths };
|
|
417
|
+
// Degradation marker — this run only encodes video (no audio), so when we're
|
|
418
|
+
// standing in for a failed audio renderer, tell the exporter the export is
|
|
419
|
+
// degraded and audio was dropped (RCA issue-video-mp4-rendermediaonweb-stack-overflow).
|
|
420
|
+
if (fallbackReason !== null) {
|
|
421
|
+
result = { ...result, degraded: true, audioDropped: true, fallbackReason };
|
|
422
|
+
}
|
|
359
423
|
if (encoding) {
|
|
360
424
|
const enc = await page.evaluate(
|
|
361
425
|
async ({ isGif }) =>
|
|
@@ -450,3 +514,9 @@ async function seekFrame(page, frame, fps, mode) {
|
|
|
450
514
|
function cssEscape(s) {
|
|
451
515
|
return String(s).replace(/["\\\]]/g, '\\$&');
|
|
452
516
|
}
|
|
517
|
+
|
|
518
|
+
/** Collapse CR/LF runs to a single space — used to neutralize log/ledger
|
|
519
|
+
* injection from untrusted in-page (canvas-origin, DDR-054) error text. */
|
|
520
|
+
function oneLine(s) {
|
|
521
|
+
return String(s).replace(/[\r\n]+/g, ' ');
|
|
522
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# audio-search.sh — feature-ai-media-generation (Task 2.5, DDR-164). Reuse-before-
|
|
3
|
+
# you-pay for AUDIO: before generating a new music/SFX/VO track, search the
|
|
4
|
+
# project's own generated audio + the user's ElevenLabs history and prefer an
|
|
5
|
+
# existing suitable track over spending credits. The search + reuse run
|
|
6
|
+
# server-side (the key is resolved by the sidecar), so this is a pure fetch to
|
|
7
|
+
# the running dev server — mirrors generate.sh.
|
|
8
|
+
#
|
|
9
|
+
# Reached via `maude design audio-search` (never a raw bin path — DDR-062).
|
|
10
|
+
#
|
|
11
|
+
# Usage:
|
|
12
|
+
# audio-search.sh --query "<text>" [--root <repo>] [--reuse <historyId>] [--json]
|
|
13
|
+
#
|
|
14
|
+
# Requires a running dev server (caller runs `maude design server-up` first).
|
|
15
|
+
#
|
|
16
|
+
# Stdout (last line, --reuse): the localized /assets/<sha8>.mp3 path.
|
|
17
|
+
# Exit: 0 ok / 1 server problem / 2 bad args / 3 search/reuse failed.
|
|
18
|
+
|
|
19
|
+
set -euo pipefail
|
|
20
|
+
|
|
21
|
+
if ! command -v bun >/dev/null 2>&1; then
|
|
22
|
+
echo "audio-search.sh: bun is required (hard dependency — see plugins/design/dependencies.json)." >&2
|
|
23
|
+
echo " Install: curl -fsSL https://bun.sh/install | bash" >&2
|
|
24
|
+
exit 1
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
28
|
+
exec bun run "$SCRIPT_DIR/_audio-search.mjs" "$@"
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# generate.sh — feature-ai-media-generation (Phase 0, DDR-16x). Headless BYOK
|
|
3
|
+
# AI-media generation: POST a GenRequest to the running dev server's privileged
|
|
4
|
+
# /_api/generate-jobs route, poll the job to completion, and print the produced
|
|
5
|
+
# content-addressed asset path (`/assets/<sha8>.<ext>`).
|
|
6
|
+
#
|
|
7
|
+
# The thin, non-browser sibling of the studio generate dialog — the provider call
|
|
8
|
+
# happens SERVER-SIDE (the sidecar resolves the key from the OS keychain /
|
|
9
|
+
# ~/.config/maude/keys.json and calls the provider directly), so this verb is a
|
|
10
|
+
# pure JSON curl + poll, exactly like photo-adjust.sh. No client-side inference,
|
|
11
|
+
# so a harness canvas + agent-browser would be pure overhead.
|
|
12
|
+
#
|
|
13
|
+
# Reached via `maude design generate` (never a raw bin path — DDR-062).
|
|
14
|
+
#
|
|
15
|
+
# Usage:
|
|
16
|
+
# generate.sh --prompt "<text>" [--provider gemini|elevenlabs] [--model <id>]
|
|
17
|
+
# [--modality image|audio|video] [--aspect 16:9] [--source assets/<sha8>.<ext>]
|
|
18
|
+
# [--kind music|sfx|tts] [--voice <voice_id>] [--duration <seconds>]
|
|
19
|
+
# [--root <repo>] [--timeout <sec>]
|
|
20
|
+
#
|
|
21
|
+
# --source turns an IMAGE call into a maskless EDIT (Nano Banana): the content-
|
|
22
|
+
# addressed source image is read server-side into the request and the prompt
|
|
23
|
+
# describes the change; a NEW content-addressed asset is produced (the original
|
|
24
|
+
# is never mutated). For --modality video it is the image-to-video SEED (a still
|
|
25
|
+
# → a clip, so a generated clip can match a generated hero's style).
|
|
26
|
+
#
|
|
27
|
+
# --modality audio (provider elevenlabs): --kind music (default) | sfx | tts.
|
|
28
|
+
# tts needs --voice <voice_id>; music/sfx take an optional --duration in seconds.
|
|
29
|
+
# Produces assets/<sha8>.mp3. (Transcription is a separate verb: `maude design
|
|
30
|
+
# transcribe`, which writes SRT/VTT.)
|
|
31
|
+
#
|
|
32
|
+
# --modality video (provider gemini / Veo 3.1): ASYNC — the clip takes ~1–10 min;
|
|
33
|
+
# the poll timeout defaults to 600s for video (180s otherwise). Produces
|
|
34
|
+
# assets/<sha8>.mp4 + a provenance assets/<sha8>.footage.json stub so the clip is
|
|
35
|
+
# reel-ready (see /design:reel Step 1.5).
|
|
36
|
+
#
|
|
37
|
+
# The key is NEVER passed here — it lives server-side. Add it in Settings
|
|
38
|
+
# (⌘,) or drop it into ~/.config/maude/keys.json (mode 0600).
|
|
39
|
+
#
|
|
40
|
+
# Requires a running dev server (caller runs `maude design server-up` first);
|
|
41
|
+
# reads the port from <designRoot>/_server.json.
|
|
42
|
+
#
|
|
43
|
+
# Stdout (last line): the produced asset path `/assets/<sha8>.<ext>` (for $(...)).
|
|
44
|
+
# Stderr: progress / diagnostics.
|
|
45
|
+
# Exit: 0 ok / 1 server problem / 2 bad args / 3 generation failed.
|
|
46
|
+
|
|
47
|
+
set -euo pipefail
|
|
48
|
+
|
|
49
|
+
PROMPT="" PROVIDER="gemini" MODEL="" MODALITY="image" ASPECT="" SOURCE="" REPO="" TIMEOUT=""
|
|
50
|
+
# Audio params (Phase 2) — kind = music|sfx|tts; voice = an ElevenLabs voice_id
|
|
51
|
+
# (required for tts); duration = seconds (music/sfx length).
|
|
52
|
+
KIND="" VOICE="" DURATION=""
|
|
53
|
+
|
|
54
|
+
while [ $# -gt 0 ]; do
|
|
55
|
+
case "$1" in
|
|
56
|
+
--prompt) PROMPT="$2"; shift 2 ;;
|
|
57
|
+
--provider) PROVIDER="$2"; shift 2 ;;
|
|
58
|
+
--model) MODEL="$2"; shift 2 ;;
|
|
59
|
+
--modality) MODALITY="$2"; shift 2 ;;
|
|
60
|
+
--aspect) ASPECT="$2"; shift 2 ;;
|
|
61
|
+
--source) SOURCE="$2"; shift 2 ;;
|
|
62
|
+
--kind) KIND="$2"; shift 2 ;;
|
|
63
|
+
--voice) VOICE="$2"; shift 2 ;;
|
|
64
|
+
--duration) DURATION="$2"; shift 2 ;;
|
|
65
|
+
--root) REPO="$2"; shift 2 ;;
|
|
66
|
+
--timeout) TIMEOUT="$2"; shift 2 ;;
|
|
67
|
+
--help|-h) sed -n '2,41p' "$0" | sed 's/^# \?//'; exit 0 ;;
|
|
68
|
+
*) echo "generate.sh: unknown arg '$1'" >&2; exit 2 ;;
|
|
69
|
+
esac
|
|
70
|
+
done
|
|
71
|
+
|
|
72
|
+
# generate.sh produces MEDIA (image / audio) from a prompt. Transcription is a
|
|
73
|
+
# different shape (audio → captions) reached via `maude design transcribe`, which
|
|
74
|
+
# writes SRT/VTT files — not this verb, whose contract is "print the produced
|
|
75
|
+
# asset path".
|
|
76
|
+
[ -n "$PROMPT" ] || { echo "generate.sh: --prompt is required" >&2; exit 2; }
|
|
77
|
+
command -v jq >/dev/null 2>&1 || { echo "generate.sh: jq is required" >&2; exit 1; }
|
|
78
|
+
|
|
79
|
+
# Async video (Veo) takes minutes — default the poll window wider than the
|
|
80
|
+
# seconds-fast image/audio calls unless the caller pinned --timeout explicitly.
|
|
81
|
+
if [ -z "$TIMEOUT" ]; then
|
|
82
|
+
if [ "$MODALITY" = "video" ]; then TIMEOUT="600"; else TIMEOUT="180"; fi
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
if [ -z "$REPO" ]; then
|
|
86
|
+
REPO="${CLAUDE_PROJECT_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"
|
|
87
|
+
fi
|
|
88
|
+
DESIGN_ROOT="$REPO/.design"
|
|
89
|
+
[ -d "$DESIGN_ROOT" ] || { echo "generate.sh: no .design/ under $REPO" >&2; exit 1; }
|
|
90
|
+
|
|
91
|
+
STATE="$DESIGN_ROOT/_server.json"
|
|
92
|
+
[ -f "$STATE" ] || { echo "generate.sh: no _server.json (start the dev server first)" >&2; exit 1; }
|
|
93
|
+
PORT=$(jq -r '.port // empty' "$STATE" 2>/dev/null)
|
|
94
|
+
[ -n "$PORT" ] || { echo "generate.sh: could not read port from $STATE" >&2; exit 1; }
|
|
95
|
+
|
|
96
|
+
BASE="http://127.0.0.1:$PORT/_api/generate-jobs"
|
|
97
|
+
|
|
98
|
+
# Normalize a --source to the `assets/<sha8>.<ext>` form the route validates
|
|
99
|
+
# (strip a leading slash the canvas-relative writers emit).
|
|
100
|
+
SOURCE="${SOURCE#/}"
|
|
101
|
+
|
|
102
|
+
# Build the audio params object (only the set keys) — audioKind / voice_id /
|
|
103
|
+
# durationSeconds are opaque to the spine; each adapter validates its own subset.
|
|
104
|
+
PARAMS=$(jq -n --arg kind "$KIND" --arg voice "$VOICE" --arg dur "$DURATION" '
|
|
105
|
+
{}
|
|
106
|
+
+ (if $kind != "" then { audioKind: $kind } else {} end)
|
|
107
|
+
+ (if $voice != "" then { voice_id: $voice } else {} end)
|
|
108
|
+
+ (if $dur != "" then { durationSeconds: ($dur|tonumber) } else {} end)')
|
|
109
|
+
|
|
110
|
+
# Build the request body — jq handles all prompt escaping. Omit empty optionals.
|
|
111
|
+
BODY=$(jq -n \
|
|
112
|
+
--arg modality "$MODALITY" --arg provider "$PROVIDER" --arg model "$MODEL" \
|
|
113
|
+
--arg prompt "$PROMPT" --arg aspect "$ASPECT" --arg source "$SOURCE" \
|
|
114
|
+
--argjson params "$PARAMS" '
|
|
115
|
+
{ modality: $modality, provider: $provider }
|
|
116
|
+
+ (if $prompt != "" then { prompt: $prompt } else {} end)
|
|
117
|
+
+ (if $model != "" then { model: $model } else {} end)
|
|
118
|
+
+ (if $aspect != "" then { aspectRatio: $aspect } else {} end)
|
|
119
|
+
+ (if $source != "" then { sourceAsset: $source } else {} end)
|
|
120
|
+
+ (if ($params|length) > 0 then { params: $params } else {} end)')
|
|
121
|
+
|
|
122
|
+
echo "generate.sh: submitting to $PROVIDER ($MODALITY)…" >&2
|
|
123
|
+
RESP=$(curl -s -X POST -H 'Content-Type: application/json' -d "$BODY" "$BASE")
|
|
124
|
+
JOB_ID=$(printf '%s' "$RESP" | jq -r '.jobId // empty' 2>/dev/null || echo "")
|
|
125
|
+
if [ -z "$JOB_ID" ]; then
|
|
126
|
+
echo "generate.sh: enqueue rejected: $RESP" >&2
|
|
127
|
+
exit 3
|
|
128
|
+
fi
|
|
129
|
+
echo "generate.sh: job $JOB_ID queued — polling…" >&2
|
|
130
|
+
|
|
131
|
+
# Poll the job list until this job is done/failed, or the timeout elapses.
|
|
132
|
+
DEADLINE=$(( $(date +%s) + TIMEOUT ))
|
|
133
|
+
while :; do
|
|
134
|
+
JOBS=$(curl -s "$BASE" 2>/dev/null || echo '{}')
|
|
135
|
+
JOB=$(printf '%s' "$JOBS" | jq -c --arg id "$JOB_ID" '.jobs[]? | select(.id == $id)' 2>/dev/null || echo "")
|
|
136
|
+
STATUS=$(printf '%s' "$JOB" | jq -r '.status // empty' 2>/dev/null || echo "")
|
|
137
|
+
case "$STATUS" in
|
|
138
|
+
done)
|
|
139
|
+
ASSET=$(printf '%s' "$JOB" | jq -r '.assets[0] // empty' 2>/dev/null || echo "")
|
|
140
|
+
[ -n "$ASSET" ] || { echo "generate.sh: job done but produced no asset" >&2; exit 3; }
|
|
141
|
+
# Normalize to the leading-slash canvas-relative form writers use.
|
|
142
|
+
printf '/%s\n' "${ASSET#/}"
|
|
143
|
+
exit 0 ;;
|
|
144
|
+
failed)
|
|
145
|
+
ERR=$(printf '%s' "$JOB" | jq -r '.error // "unknown error"' 2>/dev/null || echo "unknown")
|
|
146
|
+
echo "generate.sh: generation failed: $ERR" >&2
|
|
147
|
+
exit 3 ;;
|
|
148
|
+
esac
|
|
149
|
+
if [ "$(date +%s)" -ge "$DEADLINE" ]; then
|
|
150
|
+
echo "generate.sh: timed out after ${TIMEOUT}s (job still $STATUS)" >&2
|
|
151
|
+
exit 3
|
|
152
|
+
fi
|
|
153
|
+
sleep 2
|
|
154
|
+
done
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# import-asset.sh — hardened local-file SVG/PDF ingestion. Thin shim over
|
|
3
|
+
# _import-asset.mjs; reached via `maude design import-asset` (DDR-062), never
|
|
4
|
+
# a raw bin path. See _import-asset.mjs + DDR-167 for the full security
|
|
5
|
+
# rationale. Requires bun (not the node/bun fallback fetch-asset.sh uses) —
|
|
6
|
+
# _import-asset.mjs imports the `.ts` SVGO engine module directly, same
|
|
7
|
+
# constraint as svg-optimize.sh.
|
|
8
|
+
#
|
|
9
|
+
# Usage:
|
|
10
|
+
# import-asset.sh <local-path> --root <repo> [--design-root .design]
|
|
11
|
+
# [--kind svg|pdf|raster] [--json]
|
|
12
|
+
#
|
|
13
|
+
# stdout on success = one reference path per line (e.g. /assets/a44d3d60.svg).
|
|
14
|
+
# PDF import is not yet available (DDR-167 addendum) — the verb accepts a
|
|
15
|
+
# .pdf input and fails loud naming why, rather than silently rejecting it as
|
|
16
|
+
# an unknown flag. `raster` (PNG/JPEG, magic-byte sniffed) content-addresses
|
|
17
|
+
# a local image as-is — added for DDR-174/T15's vision-reconstruction source.
|
|
18
|
+
#
|
|
19
|
+
# Exit: 0 ok · 1 not-yet-available/other · 2 usage · 3 sanitize/validation
|
|
20
|
+
# reject · 4 read/parse error · 5 unsupported media type ·
|
|
21
|
+
# 6 write/containment error.
|
|
22
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
23
|
+
|
|
24
|
+
case "$1" in
|
|
25
|
+
--help|-h) sed -n '2,17p' "$0" | sed 's/^# \?//'; exit 0 ;;
|
|
26
|
+
esac
|
|
27
|
+
|
|
28
|
+
if ! command -v bun >/dev/null 2>&1; then
|
|
29
|
+
echo "import-asset.sh: bun is required (hard dependency — see plugins/design/dependencies.json)." >&2
|
|
30
|
+
echo " Install: curl -fsSL https://bun.sh/install | bash" >&2
|
|
31
|
+
exit 1
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
exec bun run "$SCRIPT_DIR/_import-asset.mjs" "$@"
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# import-brand.sh — brand-file typed-cue extraction (DDR-173). Thin shim over
|
|
3
|
+
# _import-brand.mjs; reached via `maude design import-brand` (DDR-062), never
|
|
4
|
+
# a raw bin path. Operates ONLY on an already-DDR-167-sanitized SVG asset
|
|
5
|
+
# (as produced by `maude design import-asset`) — never re-reads or
|
|
6
|
+
# re-sanitizes the original brand file (DDR-173 Decision 2: no parallel,
|
|
7
|
+
# ungated read path). Requires bun — _import-brand.mjs imports
|
|
8
|
+
# _import-tokens.mjs's `.mjs` grammar reuse and happy-dom directly.
|
|
9
|
+
#
|
|
10
|
+
# Usage:
|
|
11
|
+
# import-brand.sh <sanitized-svg-path> --root <repo> [--design-root .design] [--json]
|
|
12
|
+
#
|
|
13
|
+
# stdout on success = the typed payload `{ palette, fonts, logoRef, logoRasterRef }`.
|
|
14
|
+
#
|
|
15
|
+
# Exit: 0 ok · 1 other · 2 usage · 3 validation/hardening reject ·
|
|
16
|
+
# 4 read/parse error · 6 write/containment error.
|
|
17
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
18
|
+
|
|
19
|
+
case "$1" in
|
|
20
|
+
--help|-h) sed -n '2,15p' "$0" | sed 's/^# \?//'; exit 0 ;;
|
|
21
|
+
esac
|
|
22
|
+
|
|
23
|
+
if ! command -v bun >/dev/null 2>&1; then
|
|
24
|
+
echo "import-brand.sh: bun is required (hard dependency — see plugins/design/dependencies.json)." >&2
|
|
25
|
+
echo " Install: curl -fsSL https://bun.sh/install | bash" >&2
|
|
26
|
+
exit 1
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
exec bun run "$SCRIPT_DIR/_import-brand.mjs" "$@"
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# import-tokens.sh — token-file import (W3C design-tokens / Style-Dictionary
|
|
3
|
+
# JSON / raw CSS custom properties -> the DS CSS-variable contract). Thin
|
|
4
|
+
# shim over _import-tokens.mjs; reached via `maude design import-tokens`
|
|
5
|
+
# (DDR-062), never a raw bin path. See _import-tokens.mjs + DDR-172 for the
|
|
6
|
+
# full mapping contract + security rationale. Requires bun — _import-tokens.mjs
|
|
7
|
+
# imports the `.ts` palette/paths modules directly, same constraint as
|
|
8
|
+
# import-asset.sh.
|
|
9
|
+
#
|
|
10
|
+
# All args are forwarded quoted ("$@") — never unquoted or eval-expanded
|
|
11
|
+
# (DDR-172 Decision 8 wrapper-hygiene requirement; the charset/shape
|
|
12
|
+
# validation itself happens in _import-tokens.mjs, not here).
|
|
13
|
+
#
|
|
14
|
+
# Usage:
|
|
15
|
+
# import-tokens.sh <token-file> --root <repo> [--design-root .design]
|
|
16
|
+
# [--ds <name> | --new-ds <name>] [--theme <name>]
|
|
17
|
+
# [--force-insert] [--json]
|
|
18
|
+
#
|
|
19
|
+
# Exit: 0 ok · 1 other · 2 usage · 3 validation/mapping reject ·
|
|
20
|
+
# 4 read/parse error · 5 unsupported format · 6 write/containment error.
|
|
21
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
22
|
+
|
|
23
|
+
case "$1" in
|
|
24
|
+
--help|-h) sed -n '2,16p' "$0" | sed 's/^# \?//'; exit 0 ;;
|
|
25
|
+
esac
|
|
26
|
+
|
|
27
|
+
if ! command -v bun >/dev/null 2>&1; then
|
|
28
|
+
echo "import-tokens.sh: bun is required (hard dependency — see plugins/design/dependencies.json)." >&2
|
|
29
|
+
echo " Install: curl -fsSL https://bun.sh/install | bash" >&2
|
|
30
|
+
exit 1
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
exec bun run "$SCRIPT_DIR/_import-tokens.mjs" "$@"
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ingest-footage.sh — thin shim over _ingest-footage.mjs; reached via
|
|
3
|
+
# `maude design ingest-footage` (DDR-062), never a raw bin path. See
|
|
4
|
+
# _ingest-footage.mjs for the full rationale (feature-footage-analysis-director).
|
|
5
|
+
#
|
|
6
|
+
# Usage:
|
|
7
|
+
# ingest-footage.sh <dir> --root <repo> [--design-root .design]
|
|
8
|
+
# [--recursive] [--max-bytes N]
|
|
9
|
+
#
|
|
10
|
+
# stdout on success = a JSON manifest { clips, skipped, assetsDir }.
|
|
11
|
+
# Exit: 0 ok (even with skips) · 2 usage · 6 write/containment error · 1 other.
|
|
12
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
13
|
+
|
|
14
|
+
case "$1" in
|
|
15
|
+
--help|-h) sed -n '2,14p' "$0" | sed 's/^# \?//'; exit 0 ;;
|
|
16
|
+
esac
|
|
17
|
+
|
|
18
|
+
# Prefer node (always present with a maude install); fall back to bun in a dev
|
|
19
|
+
# tree that has bun but a shimmed node. The module is pure Node ESM — no .ts.
|
|
20
|
+
if command -v node >/dev/null 2>&1; then
|
|
21
|
+
exec node "$SCRIPT_DIR/_ingest-footage.mjs" "$@"
|
|
22
|
+
elif command -v bun >/dev/null 2>&1; then
|
|
23
|
+
exec bun run "$SCRIPT_DIR/_ingest-footage.mjs" "$@"
|
|
24
|
+
else
|
|
25
|
+
echo "ingest-footage.sh: node or bun is required." >&2
|
|
26
|
+
exit 1
|
|
27
|
+
fi
|