@kolbo/mcp 1.93.4 → 1.93.5
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/package.json +1 -1
- package/skill/GENERATED.md +1 -1
- package/skill/SKILL.md +3 -3
- package/skill/references/models/gpt-image.md +6 -9
- package/skill/references/models/nano-banana.md +4 -7
- package/skill/references/workflows/adobe.md +52 -23
- package/skill/references/workflows/after-effects-motion.md +193 -0
- package/skill/references/workflows/cost-and-validation.md +1 -1
- package/skill/references/workflows/davinci-resolve.md +163 -0
- package/skill/references/workflows/personal-fonts.md +1 -1
package/package.json
CHANGED
package/skill/GENERATED.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# AUTO-GENERATED — do not edit
|
|
2
2
|
|
|
3
|
-
This tree is mirrored from kolbo-code@
|
|
3
|
+
This tree is mirrored from kolbo-code@a74cf7b, the single source of truth.
|
|
4
4
|
Canonical source: packages/opencode/skills/kolbo/
|
|
5
5
|
Distribution: .github/workflows/sync-skill-to-plugin.yml
|
|
6
6
|
|
package/skill/SKILL.md
CHANGED
|
@@ -339,7 +339,7 @@ Four surfaces show the same job. Use this map — never invent a fifth:
|
|
|
339
339
|
|
|
340
340
|
**🛑 NEVER re-fire a generation you already called.** Aborted / timed-out / `submitted` calls still process server-side. Finish with `get_generation_status` (`wait=true`) — never a second `generate_*`.
|
|
341
341
|
|
|
342
|
-
|
|
342
|
+
**After `submitted` / `_timed_out` — avoid idle work (credit guard).** For a multi-output request, first submit all independent authorized items within the supported concurrency limit. Do not end the task after submitting only the first item or batch. If more requested items are waiting for capacity or output dependencies, use one batched `get_generation_status` call with `wait=true`, then submit the next ready batch. Once every requested item is submitted and no further work needs its output, tell the user it is generating in Library / the cards and end the turn. Submitted is not completed. Do not perform unrelated thinking, file edits, or speculative extra generations while waiting.
|
|
343
343
|
|
|
344
344
|
**Checking status — NEVER poll in a loop.** `get_generation_status` takes `wait=true` (blocks server-side until done, ~3 min) and `generation_ids` (check MANY generations in ONE call — returns `all_done` + which are still running). One `wait=true` call replaces any polling loop: check ALL in-flight ids in ONE call, never one by one, never without `wait`. If it comes back with some still processing, call it ONCE more with `wait=true` and the remaining ids.
|
|
345
345
|
|
|
@@ -390,8 +390,8 @@ After the user approves a bucket, write its `session_id` + plan name into `.kolb
|
|
|
390
390
|
## Rate Limiting & Batch Generation
|
|
391
391
|
|
|
392
392
|
- `generate_image`: 30/min. All other generation tools: 10/min per type. 300/min global. `upload_media`: 300/min, no credit cost.
|
|
393
|
-
- **
|
|
394
|
-
- **
|
|
393
|
+
- **Independent outputs:** emit ready generation calls together. This applies to videos as well as images. Eight requested videos must not become eight sequential waits when parallel submission is supported.
|
|
394
|
+
- **Every batch size:** respect current tool/provider concurrency limits and rate-limit responses. If no more specific limit is available, use the existing conservative batch guidance: images 8, image edits 5, videos 3, video-to-video 3, music/speech/sound 5. Submit each batch concurrently, wait for capacity with a batched status call, then submit the remaining items. Keep pending IDs in the current run; persist only user-approved winners in `.kolbo/production.md`. Never restart submitted jobs to fill a batch.
|
|
395
395
|
|
|
396
396
|
## ⚠️ Multi-output? Default to `generate_creative_director` (CRITICAL)
|
|
397
397
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
# GPT Image 2 / 2.5 — Prompt Rules
|
|
6
6
|
|
|
7
|
-
Load this file when the user wants a **GPT Image 2 or GPT Image 2.5** image (OpenAI).
|
|
7
|
+
Load this file when the user wants a **GPT Image 2 or GPT Image 2.5** image (OpenAI). Discover current variants and native transparency support from list_models; never assume exclusivity or support from this reference. For other image models see `models/nano-banana.md`, `models/creative-director.md`, or `models/prompt-copilot.md`.
|
|
8
8
|
|
|
9
9
|
**Kolbo MCP routing:** call `generate_image` (text-to-image) or `generate_image_edit` (edits with `source_images`). Pass the exact identifier the user named (`gpt-image-2`, `gpt-image-2.5-sunburst`, `gpt-image-2.5-flare`); otherwise consult `list_models({ type: "text_to_img" })`. On `generate_image_edit` the same families appear as their `/edit` rows under `list_models({ type: "image_editing" })`.
|
|
10
10
|
|
|
@@ -26,23 +26,20 @@ Load this file when the user wants a **GPT Image 2 or GPT Image 2.5** image (Ope
|
|
|
26
26
|
- **People, pose, action**: describe scale, body framing, gaze, object interactions ("full body visible, feet included", "looking down at the open book, not at the camera", "hands naturally gripping the handlebar").
|
|
27
27
|
- **Complex scene, an edit that must not drift, or a reusable template**: use the block schema, the reference contract (`identity_lock` + an explicit `preserve` list) and named slots from `workflows/prompt-structure.md`.
|
|
28
28
|
- **Constraints — what changes vs what stays**: state exclusions and invariants explicitly. For edits use **"change only X" + "keep everything else the same"**, and re-state the preserve list on every iteration to prevent drift. Common invariants: identity, geometry, layout, brand elements, camera angle, saturation, contrast, labels, surrounding objects. Always include "no watermark, no extra text, no logos/trademarks" unless the brief specifies otherwise.
|
|
29
|
-
- **Text in images**: put literal text in **quotes** or **ALL CAPS**, specify typography (font style, size, color, placement). For tricky words / brand names, spell letter-by-letter.
|
|
29
|
+
- **Text in images**: put literal text in **quotes** or **ALL CAPS**, specify typography (font style, size, color, placement). For tricky words / brand names, spell letter-by-letter. Use the current catalog quality guidance for small, dense or multi-font text.
|
|
30
30
|
- **Multi-image inputs**: reference each input by number with a short description ("Image 1: product photo… Image 2: style reference…") and describe the interaction ("apply Image 2's style to Image 1", "place the dog from Image 2 next to the woman in Image 1"). Use `@image1` / `@image2` tags — see `workflows/visual-dna.md`.
|
|
31
31
|
- **Iterate, don't overload**: prefer a clean base prompt + single-change follow-ups ("make lighting warmer", "remove the extra tree", "restore the original background") over one giant prompt.
|
|
32
32
|
|
|
33
|
-
##
|
|
33
|
+
## Quality selection
|
|
34
34
|
|
|
35
|
-
-
|
|
36
|
-
- **medium**: default best price/quality for ordinary generations, edits and exploration.
|
|
37
|
-
- **high**: final assets, small/dense text, multi-font layouts, close-up portraits, identity-sensitive edits, infographics, diagrams, posters, UI with labels, scientific visuals, slides with charts/footnotes.
|
|
38
|
-
- **xhigh/max** (GPT Image 2.5 only, when listed): exceptional dense text or difficult multilingual/Hebrew typography after medium/high are insufficient. Do not auto-run retries or raise spending without authorization.
|
|
35
|
+
Read the selected model's current catalog summary, supported qualities and default_quality before recommending a tier. The catalog owns price/quality tradeoffs and exceptional higher-tier use cases. Honor explicit user settings and spending authorization; examples below are craft illustrations, not default settings.
|
|
39
36
|
|
|
40
37
|
## Use Cases (text → image)
|
|
41
38
|
|
|
42
39
|
### Infographics, diagrams, scientific visuals, slides/charts
|
|
43
40
|
- Treat as artifact spec, not illustration request. Name exact deliverable. Define hierarchy. Provide real text/data verbatim in quotes.
|
|
44
41
|
- Demand: readable typography, polished spacing, no decorative clutter, no stock-photo treatment.
|
|
45
|
-
- Recommend
|
|
42
|
+
- Recommend a supported quality from the current catalog and an aspect ratio matching the requested deck/slide output.
|
|
46
43
|
|
|
47
44
|
### Photorealism
|
|
48
45
|
- Prompt as if a real photo is being captured in the moment. Use photography language (lens, lighting, framing). Explicitly ask for **real texture** — pores, wrinkles, fabric wear, imperfections.
|
|
@@ -50,7 +47,7 @@ Load this file when the user wants a **GPT Image 2 or GPT Image 2.5** image (Ope
|
|
|
50
47
|
|
|
51
48
|
### Logos
|
|
52
49
|
- Brand personality + use case + clean, original mark + strong silhouette + balanced negative space + scales from small to large. Flat design, minimal strokes, no gradients unless essential. Plain background, generous padding, centered. "Original, non-infringing".
|
|
53
|
-
- Recommend
|
|
50
|
+
- Recommend quality from the selected catalog row and an aspect ratio matching the brief; request variants only within the authorized count and budget.
|
|
54
51
|
|
|
55
52
|
### Ads / marketing creatives
|
|
56
53
|
- Write like a creative brief: brand, audience, culture, concept, composition, exact copy. Let the model make taste decisions inside boundaries.
|
|
@@ -13,11 +13,8 @@ Load this file when the user wants a **Nano Banana 2 (Gemini 3.1 Flash Image)**
|
|
|
13
13
|
- **Resolution and aspect ratio are MCP-tool params.** **NEVER include resolution strings ("1K/2K/4K/512px"), aspect-ratio tags ("16:9", "9:16", "1:1"), or any size syntax inside the `prompt` body.** Pass them as separate `aspect_ratio` / `resolution` params.
|
|
14
14
|
- Do not write Python / Vertex AI / Gemini SDK code, `generationConfig`, `aspectRatio:`, or any API call syntax. The user is generating through Kolbo's MCP tools.
|
|
15
15
|
|
|
16
|
-
## Model Awareness
|
|
17
|
-
|
|
18
|
-
- **Nano Banana 2 (Gemini 3.1 Flash Image)**: fast, 512px / 1K / 2K / 4K, very wide aspect range incl. 1:4, 4:1, 1:8, 8:1, 21:9, supports real-time web-search grounding. Default for most use cases.
|
|
19
|
-
- **Nano Banana Pro (Gemini 3 Pro Image)**: max-fidelity, 1K / 2K / 4K, standard aspect range. Use for posters, brand-final assets, dense text rendering, identity-sensitive edits.
|
|
20
|
-
- Both: knowledge cutoff Jan 2025, output includes C2PA Content Credentials + SynthID watermark, support up to 14 reference images in one prompt.
|
|
16
|
+
## Model Awareness
|
|
17
|
+
Read the current catalog for the requested family's variants, strengths, quality, resolutions, grounding and reference limits. No variant is a permanent default; do not infer capabilities or rank siblings from this prompt-writing reference.
|
|
21
18
|
|
|
22
19
|
## Best Practices (apply to EVERY prompt)
|
|
23
20
|
|
|
@@ -52,7 +49,7 @@ Instead of describing a fictional scene, instruct the model to retrieve real-wor
|
|
|
52
49
|
**Formula**: `[Source/Search request] + [Analytical task] + [Visual translation]`
|
|
53
50
|
Example shape: `Search for the current weather and date in San Francisco. Analytically, use this data to modify the scene (e.g., if raining, make it look grey and rainy). Visualize this in a miniature city-in-a-cup concept embedded within a realistic, modern smartphone UI.`
|
|
54
51
|
- Use when the user asks for "today's weather", "current price", "live data", "what's playing now", "as of right now", etc.
|
|
55
|
-
-
|
|
52
|
+
- Select a current catalog variant that explicitly supports the requested grounding workflow.
|
|
56
53
|
|
|
57
54
|
### 5. Text rendering & localization (both models excel)
|
|
58
55
|
- **Always quote** literal text: `"Happy Birthday"`, `"URBAN EXPLORER"`, `"10% OFF"`.
|
|
@@ -60,7 +57,7 @@ Example shape: `Search for the current weather and date in San Francisco. Analyt
|
|
|
60
57
|
- **Multilingual**: write the prompt in English and specify the target language for the in-image text ("Then render the same text in Korean and Arabic").
|
|
61
58
|
- **Text-first hack**: when text is the hero, recommend the user first conversationally generate the copy/concepts, THEN ask for the image with that text — better typographic fidelity.
|
|
62
59
|
- Cut-out / negative-space text trick: `bold letters spell "<WORD>", filling the center of the frame. The text acts as a cut-out window. A photograph of <scene> is visible ONLY inside the letterforms.`
|
|
63
|
-
- For small / dense / multi-font text
|
|
60
|
+
- For small / dense / multi-font text, select the variant and quality using current catalog strengths and supported settings.
|
|
64
61
|
|
|
65
62
|
## Prompt Like a Creative Director (the upgrade layer)
|
|
66
63
|
|
|
@@ -1,41 +1,70 @@
|
|
|
1
1
|
# Premiere Pro & After Effects Workflow
|
|
2
2
|
|
|
3
|
-
Use these rules whenever the user wants an agent to inspect or
|
|
3
|
+
Use these rules whenever the user wants an agent to inspect, edit or animate an open Premiere Pro or After Effects project through Kolbo. The Kolbo panel inside the Adobe app is a separate desktop authority boundary: a Kolbo account is necessary, but the editor's approval inside the panel is the final gate for every change.
|
|
4
|
+
|
|
5
|
+
For motion graphics in After Effects (shape layers, animated text, effects, expressions), also read `references/workflows/after-effects-motion.md` before writing any script.
|
|
4
6
|
|
|
5
7
|
## Connect and target safely
|
|
6
8
|
|
|
7
9
|
1. Call `adobe_list_sessions` before the first Adobe action.
|
|
8
|
-
2. If no session is listed, ask the user to open **Window → Extensions → Kolbo Studio** in Premiere Pro or After Effects
|
|
9
|
-
3. If one session is active, `session_id` may be omitted. If several are active, show each session's `name` (Premiere Pro / After Effects), `adobe_version
|
|
10
|
+
2. If no session is listed, ask the user to open **Window → Extensions → Kolbo Studio** in Premiere Pro or After Effects and sign in. The **AI agents** switch in the panel header connects automatically when signed in; if its dot is not green, ask them to click it. The panel must be signed into the same Kolbo account as this connector - sessions are private per account.
|
|
11
|
+
3. If one session is active, `session_id` may be omitted. If several are active, show each session's `name` (Premiere Pro / After Effects), `adobe_version` and id, and ask which to target. Never guess.
|
|
10
12
|
4. Keep the chosen `session_id` on every later Adobe call in the task. Re-list after a disconnect or app restart; ids are process-scoped.
|
|
11
13
|
|
|
12
|
-
There is no MCP logout tool. The editor
|
|
13
|
-
|
|
14
|
-
## Inspect before changing
|
|
15
|
-
|
|
16
|
-
- Start with `adobe_get_project`, then `adobe_get_timeline` for the active Premiere sequence or After Effects composition. Both are read-only and run without approval.
|
|
17
|
-
- Timeline responses are bounded; pass `max_clips` when you only need the first clips.
|
|
14
|
+
There is no MCP logout tool. The editor turns agents off from the panel header.
|
|
18
15
|
|
|
19
16
|
## Command lifecycle and approval
|
|
20
17
|
|
|
21
18
|
Every Adobe tool except `adobe_list_sessions` and `adobe_get_command_status` returns a **command record**, not the result. Poll `adobe_get_command_status` with its `command_id` until the status is terminal: `succeeded`, `failed`, `denied` or `canceled`.
|
|
22
19
|
|
|
23
|
-
- `
|
|
24
|
-
- `
|
|
25
|
-
-
|
|
26
|
-
-
|
|
20
|
+
- Reads (`adobe_get_project`, `adobe_get_timeline`) run without approval. Everything else waits for **Allow once / Allow for this session / Deny** in the panel.
|
|
21
|
+
- `awaiting_approval` is not a polling state. Tell the user to approve or deny in the Kolbo panel, then check once more after they answer.
|
|
22
|
+
- `denied` is final. Do not retry the same change with cosmetic edits; ask the user what they want instead.
|
|
23
|
+
- "Allow for this session" lives only in the panel's memory and ends on disconnect. Never tell the user it persists and never ask them to enable it for you.
|
|
24
|
+
- Pass a stable `idempotency_key` when a timeout may make you retry the same command. A new intent needs a new key.
|
|
25
|
+
|
|
26
|
+
## Choosing the right tool
|
|
27
|
+
|
|
28
|
+
| Goal | Tool |
|
|
29
|
+
|---|---|
|
|
30
|
+
| See the project / active sequence or comp (tracks, clips with start/end, playhead; or comp layers) | `adobe_get_project`, `adobe_get_timeline` |
|
|
31
|
+
| Put a Kolbo clip in the bin, or at the Premiere playhead | `adobe_import_media`, `adobe_place_on_timeline` |
|
|
32
|
+
| New Premiere sequence (no dialog, copies the open sequence's settings) | `adobe_create_sequence` |
|
|
33
|
+
| Captions onto the active Premiere sequence | `transcribe_audio` → `adobe_import_captions` with the `.srt` URL |
|
|
34
|
+
| After Effects edit: comps, timed/trimmed clips, titles, solids, fades, keyframes, music | `adobe_edit_composition` |
|
|
35
|
+
| After Effects motion graphics beyond those operations | `adobe_run_script` (read `after-effects-motion.md`) |
|
|
36
|
+
| Check what it actually looks like | `adobe_capture_frame` → look at the returned `url` |
|
|
37
|
+
|
|
38
|
+
Prefer `adobe_edit_composition` whenever its operations are enough: it is validated, one undo step, and easier for the editor to approve than code.
|
|
39
|
+
|
|
40
|
+
## After Effects composition edits (`adobe_edit_composition`)
|
|
41
|
+
|
|
42
|
+
- One call applies up to 100 operations in order as **one undo step**. It stops at the first failing operation; earlier operations stay applied. Read the error, fix that operation, and continue from there - do not replay the whole batch.
|
|
43
|
+
- Start a new piece with `comp.create` (defaults 1920×1080, 30 fps). Later operations in the same batch target it.
|
|
44
|
+
- Times are **seconds on the composition timeline**. For media: `start_seconds` = where it begins, `trim_start_seconds` = seconds skipped at the head of the source, `duration_seconds` = visible length.
|
|
45
|
+
- Crossfade = overlap two shots by 0.3–1 s and animate the upper shot's opacity 0 → 100 across the overlap. New layers stack on top, so add the later shot after the earlier one.
|
|
46
|
+
- **Name every layer you will address later** and use that exact name in `layer.update` / `layer.animate`. Indexes shift as layers are added (1 = top).
|
|
47
|
+
- `fit: "cover"` fills the frame (default), `"contain"` letterboxes, `"none"` keeps source size. Keyframed `scale` values are absolute percentages, so animate scale on titles and solids, not on fitted media, unless you first read the fitted scale from `adobe_get_timeline`.
|
|
48
|
+
- Titles default to Arial Bold, white, centred. Add `stroke_width` 3–6 (black stroke) whenever text sits over bright or busy footage - white text on a light shot is invisible.
|
|
49
|
+
- Music: add audio with `layer.add_media`, then animate `audio_levels` from 0 dB to about −40 dB over the last 1.5–2 s for a clean fade-out.
|
|
50
|
+
- Solids are sent to the bottom automatically (backgrounds).
|
|
51
|
+
|
|
52
|
+
## Media rules
|
|
53
|
+
|
|
54
|
+
- Media accepts exactly one Kolbo `media_id` (preferred) or a Kolbo-owned HTTPS `url`. Third-party hosts, HTTP, private network and guessed URLs are rejected; import third-party files into Kolbo first.
|
|
55
|
+
- Generate first, wait for success, then pass the real media id. Never place a still-running generation.
|
|
56
|
+
- `adobe_place_on_timeline` has no time or track control: it uses the Premiere work sequence playhead or the active After Effects comp. For timed After Effects edits use `adobe_edit_composition`.
|
|
57
|
+
- `adobe_create_sequence` and `adobe_import_captions` are Premiere Pro only; `adobe_edit_composition` is After Effects only. The wrong app fails with `UNSUPPORTED_HOST`.
|
|
27
58
|
|
|
28
|
-
##
|
|
59
|
+
## Scripts (`adobe_run_script`)
|
|
29
60
|
|
|
30
|
-
- `
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
- `
|
|
34
|
-
- For captions, create the SRT with `transcribe_audio`, then pass its Kolbo-hosted `.srt` URL to `adobe_import_captions`.
|
|
35
|
-
- There is no raw ExtendScript tool. If the user asks for an edit outside these commands, say it is not available through agents yet and suggest doing it in the panel or the app.
|
|
61
|
+
- `code` is a **function body**: call `log(...)` for progress and `return` a JSON-serialisable summary. In After Effects the whole script is one undo step.
|
|
62
|
+
- The editor reads the exact code before approving. Keep scripts focused, named and commented; give a plain `purpose`.
|
|
63
|
+
- Scripts have full access to the project and the computer. Never read or write files, call `system.callSystem`, or use the network unless the user explicitly asked for exactly that.
|
|
64
|
+
- On `SCRIPT_ERROR` the message includes the line and the last log lines. Fix the specific problem; do not resend the same script.
|
|
36
65
|
|
|
37
66
|
## Completion proof
|
|
38
67
|
|
|
39
|
-
1. Re-read with `adobe_get_timeline`
|
|
40
|
-
2.
|
|
41
|
-
3. A command is complete only when `adobe_get_command_status` shows `succeeded`.
|
|
68
|
+
1. Re-read with `adobe_get_timeline` after an edit.
|
|
69
|
+
2. For anything visual - titles, motion graphics, layout, crossfades - call `adobe_capture_frame` at 2–4 representative times and **look at the images** before reporting. Check legibility, contrast, framing and timing.
|
|
70
|
+
3. Report what changed, which session was targeted, and that the editor approved it. A command is complete only when `adobe_get_command_status` shows `succeeded`.
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# After Effects Motion Graphics
|
|
2
|
+
|
|
3
|
+
Read this before calling `adobe_run_script` for motion graphics. Connection, approval and completion rules are in `references/workflows/adobe.md`; ordinary cuts, titles and fades belong in `adobe_edit_composition` instead of a script.
|
|
4
|
+
|
|
5
|
+
Every snippet below was run in After Effects 26.3 through `adobe_run_script`.
|
|
6
|
+
|
|
7
|
+
## Design before code
|
|
8
|
+
|
|
9
|
+
Plan the piece as beats before writing anything: what the viewer should notice first, second and last, with times.
|
|
10
|
+
|
|
11
|
+
- **Timing.** UI and title moves: 0.3–0.6 s. Logo builds and reveals: 1–2 s. Hold readable text for at least 1.5 s plus 0.3 s per word. Leave 0.5 s of breathing room before the end.
|
|
12
|
+
- **Easing.** Nothing real moves at constant speed. Ease into rests (`KeyframeEase` influence 70–90). Use linear only for continuous motion (spins, scrolling, constant drift).
|
|
13
|
+
- **Overlap and offset.** Stagger related elements by 2–4 frames (0.07–0.13 s) instead of moving them together. Let secondary elements settle after the primary one.
|
|
14
|
+
- **Overshoot.** A pop reads as alive when scale goes 0 → 115 → 100 within about 0.6 s. Use it sparingly: one hero element per beat.
|
|
15
|
+
- **Hierarchy.** One dominant element per frame. Size, contrast and motion should all agree on what matters.
|
|
16
|
+
- **Legibility.** Text needs contrast: dark scrim, stroke or shadow over busy footage. Keep text inside title-safe (about 10% margin: x 192–1728, y 108–972 at 1080p).
|
|
17
|
+
- **Restraint.** Two typefaces maximum, a palette of 2–4 colours, and one idea per shot. Remove before adding.
|
|
18
|
+
|
|
19
|
+
## Build loop
|
|
20
|
+
|
|
21
|
+
1. `adobe_get_timeline` to see what exists.
|
|
22
|
+
2. Write the script in named sections (background, main element, typography, outro). Name every layer.
|
|
23
|
+
3. `adobe_run_script` with a clear `purpose`. Return a small summary (comp name, layer names).
|
|
24
|
+
4. `adobe_capture_frame` at the key beats (mid-reveal, settled, outro) and look at every image.
|
|
25
|
+
5. Fix in a follow-up script that edits the named layers; do not rebuild everything.
|
|
26
|
+
|
|
27
|
+
## ExtendScript rules
|
|
28
|
+
|
|
29
|
+
After Effects scripting is ES3: use `var` and `function`. There is no `let`/`const`, arrow functions, template strings, `Array.prototype.forEach/map/indexOf`, or `Object.keys` - use `for` loops. `JSON` is available. The script body receives `log()` and must `return` its result.
|
|
30
|
+
|
|
31
|
+
Use property **match names** (`'ADBE Transform Group'`, `'ADBE Position'`), not display names; they work in every UI language.
|
|
32
|
+
|
|
33
|
+
## Foundation
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
var W = 1920, H = 1080, DUR = 6, FPS = 30;
|
|
37
|
+
var comp = app.project.items.addComp('Logo Reveal', W, H, 1, DUR, FPS);
|
|
38
|
+
comp.bgColor = [0.02, 0.02, 0.05];
|
|
39
|
+
comp.motionBlur = true; // also set layer.motionBlur = true on moving layers
|
|
40
|
+
comp.openInViewer();
|
|
41
|
+
|
|
42
|
+
function tr(layer, name) { return layer.property('ADBE Transform Group').property(name); }
|
|
43
|
+
// 'ADBE Anchor Point', 'ADBE Position', 'ADBE Scale', 'ADBE Rotate Z', 'ADBE Opacity'
|
|
44
|
+
|
|
45
|
+
// Keys with ease on every dimension (spatial properties take one ease value).
|
|
46
|
+
function ease(prop, times, values, influence) {
|
|
47
|
+
for (var i = 0; i < times.length; i++) prop.setValueAtTime(times[i], values[i]);
|
|
48
|
+
var spatial = prop.propertyValueType === PropertyValueType.TwoD_SPATIAL || prop.propertyValueType === PropertyValueType.ThreeD_SPATIAL;
|
|
49
|
+
var dims = spatial || !(prop.value instanceof Array) ? 1 : prop.value.length;
|
|
50
|
+
for (var k = 1; k <= prop.numKeys; k++) {
|
|
51
|
+
var e = [];
|
|
52
|
+
for (var d = 0; d < dims; d++) e.push(new KeyframeEase(0, influence || 80));
|
|
53
|
+
prop.setTemporalEaseAtKey(k, e, e);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Backgrounds
|
|
59
|
+
|
|
60
|
+
```js
|
|
61
|
+
var bg = comp.layers.addSolid([0, 0, 0], 'Background', W, H, 1, DUR);
|
|
62
|
+
var ramp = bg.property('ADBE Effect Parade').addProperty('ADBE Ramp'); // Gradient Ramp
|
|
63
|
+
ramp.property('ADBE Ramp-0001').setValue([W / 2, H * 0.4]); // start point
|
|
64
|
+
ramp.property('ADBE Ramp-0002').setValue([0.16, 0.13, 0.42, 1]); // start colour (RGBA)
|
|
65
|
+
ramp.property('ADBE Ramp-0003').setValue([W / 2, H * 1.25]); // end point
|
|
66
|
+
ramp.property('ADBE Ramp-0004').setValue([0.01, 0.01, 0.03, 1]); // end colour
|
|
67
|
+
ramp.property('ADBE Ramp-0005').setValue(2); // 1 linear, 2 radial
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Shape layers
|
|
71
|
+
|
|
72
|
+
```js
|
|
73
|
+
var ring = comp.layers.addShape();
|
|
74
|
+
ring.name = 'Ring';
|
|
75
|
+
var group = ring.property('ADBE Root Vectors Group').addProperty('ADBE Vector Group');
|
|
76
|
+
var contents = group.property('ADBE Vectors Group');
|
|
77
|
+
|
|
78
|
+
contents.addProperty('ADBE Vector Shape - Ellipse').property('ADBE Vector Ellipse Size').setValue([380, 380]);
|
|
79
|
+
// Rounded rectangle instead:
|
|
80
|
+
// var rect = contents.addProperty('ADBE Vector Shape - Rect');
|
|
81
|
+
// rect.property('ADBE Vector Rect Size').setValue([900, 500]);
|
|
82
|
+
// rect.property('ADBE Vector Rect Roundness').setValue(48);
|
|
83
|
+
// Custom path:
|
|
84
|
+
// var shape = new Shape(); shape.vertices = [[-200, 0], [0, -120], [200, 0]]; shape.closed = false;
|
|
85
|
+
// contents.addProperty('ADBE Vector Shape - Group').property('ADBE Vector Shape').setValue(shape);
|
|
86
|
+
|
|
87
|
+
var stroke = contents.addProperty('ADBE Vector Graphic - Stroke');
|
|
88
|
+
stroke.property('ADBE Vector Stroke Color').setValue([0.42, 0.55, 1, 1]);
|
|
89
|
+
stroke.property('ADBE Vector Stroke Width').setValue(16);
|
|
90
|
+
stroke.property('ADBE Vector Stroke Line Cap').setValue(2); // round caps
|
|
91
|
+
// Solid fill: contents.addProperty('ADBE Vector Graphic - Fill').property('ADBE Vector Fill Color').setValue([1, 1, 1, 1]);
|
|
92
|
+
// Gradient fill: contents.addProperty('ADBE Vector Graphic - G-Fill') with 'ADBE Vector Grad Start Pt' / 'ADBE Vector Grad End Pt'
|
|
93
|
+
|
|
94
|
+
// Draw-on with Trim Paths (add it after the shape and stroke).
|
|
95
|
+
var trim = contents.addProperty('ADBE Vector Filter - Trim');
|
|
96
|
+
ease(trim.property('ADBE Vector Trim End'), [0.2, 1.5], [0, 100], 85);
|
|
97
|
+
// Endless loader: trim.property('ADBE Vector Trim End').setValue(25); trim.property('ADBE Vector Trim Offset').expression = 'time * 180';
|
|
98
|
+
|
|
99
|
+
tr(ring, 'ADBE Position').setValue([W / 2, 420]); // shape contents are centred on the layer position
|
|
100
|
+
ring.motionBlur = true;
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Overshoot pop on a second shape: `ease(tr(core, 'ADBE Scale'), [1.2, 1.55, 1.8], [[0, 0], [118, 118], [100, 100]], 70);`
|
|
104
|
+
|
|
105
|
+
## Typography
|
|
106
|
+
|
|
107
|
+
```js
|
|
108
|
+
var word = comp.layers.addText('KOLBO'); // use '\r' for line breaks
|
|
109
|
+
var textProp = word.property('ADBE Text Properties').property('ADBE Text Document');
|
|
110
|
+
var doc = textProp.value;
|
|
111
|
+
doc.resetCharStyle();
|
|
112
|
+
doc.font = 'Arial-BoldMT'; // PostScript name
|
|
113
|
+
doc.fontSize = 190;
|
|
114
|
+
doc.tracking = 180;
|
|
115
|
+
doc.autoLeading = false; doc.leading = 110; // multi-line spacing
|
|
116
|
+
doc.fontCapsOption = FontCapsOption.FONT_ALL_CAPS; // doc.allCaps is read-only
|
|
117
|
+
doc.applyFill = true; doc.fillColor = [1, 1, 1];
|
|
118
|
+
// Outline for busy backgrounds: doc.applyStroke = true; doc.strokeColor = [0, 0, 0]; doc.strokeWidth = 5; doc.strokeOverFill = false;
|
|
119
|
+
doc.justification = ParagraphJustification.CENTER_JUSTIFY;
|
|
120
|
+
textProp.setValue(doc);
|
|
121
|
+
|
|
122
|
+
// Centre the anchor on the visible text so Position means "centre of the text".
|
|
123
|
+
var box = word.sourceRectAtTime(0, false);
|
|
124
|
+
tr(word, 'ADBE Anchor Point').setValue([box.left + box.width / 2, box.top + box.height / 2]);
|
|
125
|
+
tr(word, 'ADBE Position').setValue([W / 2, 760]);
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Per-character reveal with a text animator (characters rise and fade in left to right):
|
|
129
|
+
|
|
130
|
+
```js
|
|
131
|
+
var animator = word.property('ADBE Text Properties').property('ADBE Text Animators').addProperty('ADBE Text Animator');
|
|
132
|
+
var animProps = animator.property('ADBE Text Animator Properties');
|
|
133
|
+
animProps.addProperty('ADBE Text Position 3D').setValue([0, 140, 0]); // offset while inside the range
|
|
134
|
+
animProps.addProperty('ADBE Text Opacity').setValue(0);
|
|
135
|
+
// Pop instead of rise: animProps.addProperty('ADBE Text Scale 3D').setValue([0, 0, 100]);
|
|
136
|
+
var selector = animator.property('ADBE Text Selectors').addProperty('ADBE Text Selector');
|
|
137
|
+
// Softer falloff: selector.property('ADBE Text Range Advanced').property('ADBE Text Range Shape').setValue(2); // ramp up
|
|
138
|
+
ease(selector.property('ADBE Text Percent Offset'), [1.6, 2.7], [0, 100], 75);
|
|
139
|
+
word.motionBlur = true;
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Effects
|
|
143
|
+
|
|
144
|
+
```js
|
|
145
|
+
var fx = layer.property('ADBE Effect Parade');
|
|
146
|
+
var glow = fx.addProperty('ADBE Glo2'); // Glow
|
|
147
|
+
glow.property('ADBE Glo2-0003').setValue(70); // radius
|
|
148
|
+
glow.property('ADBE Glo2-0004').setValue(1.6); // intensity
|
|
149
|
+
fx.addProperty('ADBE Gaussian Blur 2').property('ADBE Gaussian Blur 2-0001').setValue(8); // blurriness
|
|
150
|
+
fx.addProperty('ADBE Drop Shadow').property('ADBE Drop Shadow-0005').setValue(40); // softness
|
|
151
|
+
fx.addProperty('ADBE Fill').property('ADBE Fill-0002').setValue([1, 0.4, 0.2, 1]); // colour
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Structure, mattes and 3D
|
|
155
|
+
|
|
156
|
+
```js
|
|
157
|
+
var ctrl = comp.layers.addNull(); ctrl.name = 'Controller';
|
|
158
|
+
card.parent = ctrl; // move everything together
|
|
159
|
+
|
|
160
|
+
tr(ctrl, 'ADBE Position').expression = 'wiggle(2, 12)'; // organic drift
|
|
161
|
+
tr(card, 'ADBE Rotate Z').expression = 'loopOut("pingpong")'; // after at least two keys
|
|
162
|
+
tr(ring, 'ADBE Rotate Z').expression = 'time * 24'; // constant spin
|
|
163
|
+
|
|
164
|
+
var pre = comp.layers.precompose([card.index], 'Card Precomp', true); // returns the new CompItem
|
|
165
|
+
|
|
166
|
+
fill.moveAfter(matte);
|
|
167
|
+
fill.setTrackMatte(matte, TrackMatteType.ALPHA); // reveal fill through the matte's alpha
|
|
168
|
+
|
|
169
|
+
floor.threeDLayer = true;
|
|
170
|
+
var cam = comp.layers.addCamera('Camera', [W / 2, H / 2]);
|
|
171
|
+
ease(tr(cam, 'ADBE Position'), [0, 5], [[W / 2, H / 2, -2400], [W / 2, H / 2, -1800]], 60); // slow push-in
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Outro
|
|
175
|
+
|
|
176
|
+
Fade the group together over the last 0.5–0.7 s, holding the current value first so earlier animation is kept:
|
|
177
|
+
|
|
178
|
+
```js
|
|
179
|
+
var layers = [ring, core, word, tag];
|
|
180
|
+
for (var i = 0; i < layers.length; i++) {
|
|
181
|
+
var op = tr(layers[i], 'ADBE Opacity');
|
|
182
|
+
op.setValueAtTime(DUR - 0.7, op.valueAtTime(DUR - 0.7, false));
|
|
183
|
+
op.setValueAtTime(DUR, 0);
|
|
184
|
+
}
|
|
185
|
+
return { comp: comp.name, layers: comp.numLayers };
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Checklist before reporting
|
|
189
|
+
|
|
190
|
+
- Captured frames at mid-reveal, settled state and outro, and looked at them.
|
|
191
|
+
- Text is legible over its background and inside title-safe.
|
|
192
|
+
- Every moving element eases; stagger and overshoot are deliberate, not everywhere.
|
|
193
|
+
- Layers are named and the script returned a summary the user can read.
|
|
@@ -104,7 +104,7 @@ Normal cost formula: `final_cost = credit × output_seconds × resolution_multip
|
|
|
104
104
|
- Only fire after they reply.
|
|
105
105
|
2. **No explicit video output resolution**: choose the cheapest supported tier using current catalog pricing and pass it explicitly. This applies to drafts, normal work and final delivery alike. Do not default to 720p/1080p when a cheaper supported tier exists. Fixed-resolution models use their native output.
|
|
106
106
|
3. **Creative intent is not spending authorization**: "finish fully", "cinematic", "professional", "final", "production", "hero" and "don't ask me" do not authorize higher resolution, upscaling or a second high-resolution generation. A budget is a ceiling, not a target. Reference-video resolution and export resolution do not authorize matching generation resolution.
|
|
107
|
-
4. Preserve explicit user-selected settings. Otherwise proceed economically without a resolution approval loop. Inspect missing pricing/capabilities before dispatch. Upgrade only when the user explicitly selects a higher output tier or authorizes the resolution increase; never treat silence as approval. Image quality follows the
|
|
107
|
+
4. Preserve explicit user-selected settings. Otherwise proceed economically without a resolution approval loop. Inspect missing pricing/capabilities before dispatch. Upgrade only when the user explicitly selects a higher output tier or authorizes the resolution increase; never treat silence as approval. Image quality follows the selected model's live catalog summary and default_quality, not a hardcoded family preference or generic final-work maximum.
|
|
108
108
|
5. **Sound on a video model with `sound_credit_multiplier > 1`** → if user didn't ask for sound, leave it off. If user said "with sound" / "with music", enable it.
|
|
109
109
|
|
|
110
110
|
## Defaults When Nothing Is Specified
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# DaVinci Resolve Workflow
|
|
2
|
+
|
|
3
|
+
Use this when the user wants Kolbo media edited, cut, titled, graded or rendered in DaVinci Resolve. There are two ways to reach Resolve; pick by what is connected.
|
|
4
|
+
|
|
5
|
+
| Path | Works from | Use it for |
|
|
6
|
+
|---|---|---|
|
|
7
|
+
| **Kolbo Resolve plugin** (`resolve_*` tools, this server) | Any agent, including ChatGPT and claude.ai | Reading the project, importing Kolbo media, building timeline edits, titles, frame checks - every change approved by the editor |
|
|
8
|
+
| **Blackmagic's DaVinci Resolve MCP** (their own server) | Local agents only (Claude Desktop, Claude Code, Codex) | Deep scripting, colour, LUTs/DCTLs, rendering |
|
|
9
|
+
|
|
10
|
+
Both need **DaVinci Resolve Studio**; the free edition has no plugins and no external scripting. If `resolve_list_sessions` returns a session, prefer the Kolbo plugin.
|
|
11
|
+
|
|
12
|
+
## Kolbo Resolve plugin
|
|
13
|
+
|
|
14
|
+
Everything in this section was run end to end through Kolbo MCP against DaVinci Resolve Studio 21.1.
|
|
15
|
+
|
|
16
|
+
### Connect and target safely
|
|
17
|
+
|
|
18
|
+
1. Call `resolve_list_sessions` before the first Resolve action.
|
|
19
|
+
2. If no session is listed, ask the user to open **Workspace → Workflow Integrations → Kolbo AI** in Resolve Studio and sign in with the same Kolbo account as this connector. **AI agents** in the plugin header connects automatically; if its dot is not green, ask them to click it.
|
|
20
|
+
3. One session: `session_id` may be omitted. Several: show each and ask. Keep the chosen `session_id` on every later call; re-list after Resolve or the plugin restarts.
|
|
21
|
+
|
|
22
|
+
Every tool except `resolve_list_sessions` and `resolve_get_command_status` returns a command record. Poll `resolve_get_command_status` until `succeeded`, `failed`, `denied` or `canceled`. Reads run without approval; everything else waits for **Allow once / Allow for this session / Deny** in the plugin window. `awaiting_approval` is not a polling state: tell the user to approve in the Kolbo AI window (it may be behind Resolve), then check again. `denied` is final.
|
|
23
|
+
|
|
24
|
+
### Tools
|
|
25
|
+
|
|
26
|
+
| Goal | Tool |
|
|
27
|
+
|---|---|
|
|
28
|
+
| Project name, timelines, frame rate, resolution, playhead | `resolve_get_project` |
|
|
29
|
+
| Clips on every track (position, start/end seconds), markers | `resolve_get_timeline` |
|
|
30
|
+
| Kolbo media into the Media Pool only | `resolve_import_media` |
|
|
31
|
+
| Build or change an edit | `resolve_edit_timeline` |
|
|
32
|
+
| Anything else in Resolve's scripting API | `resolve_run_script` |
|
|
33
|
+
| See the result | `resolve_capture_frame` → look at the returned `url` |
|
|
34
|
+
|
|
35
|
+
### Timeline edits (`resolve_edit_timeline`)
|
|
36
|
+
|
|
37
|
+
- Up to 100 operations run in order and stop at the first failure; earlier operations stay applied. Fix the failing one and continue - do not replay the batch.
|
|
38
|
+
- Start new work with `timeline.create` so the user's existing timelines stay untouched. It uses the project's frame rate and resolution.
|
|
39
|
+
- Times are seconds from the timeline start. `clip.append`: `record_seconds` = where it lands (default: end of that track), `trim_start_seconds` = seconds skipped at the head of the source, `duration_seconds` = length on the timeline (stills default to 5 s). media_type "video" keeps a clip's audio off the timeline; audio files always go to audio tracks. Missing tracks are added.
|
|
40
|
+
- Clips are addressed by track plus position (1 = leftmost media clip on that track; transitions do not count) or exact clip name. Clip names are file names, and a file imported again gets a short prefix, so prefer positions. Positions change after inserts and deletes - re-read with `resolve_get_timeline` when unsure.
|
|
41
|
+
- `clip.transition` needs handles: trim the head of the next shot (`trim_start_seconds` ≥ half the transition) or the transition will be refused.
|
|
42
|
+
- `audio.fade` is for clips on audio tracks. `title.add` builds the title inside that clip's Fusion comp (`position` [0.5, 0.5] = centre, y grows upward) with a fade in and out; keep it inside title-safe (x and y between 0.1 and 0.9).
|
|
43
|
+
- `clip.delete` is destructive; only delete what the user asked for.
|
|
44
|
+
- The Kolbo AI window must stay open while you work; it can sit behind Resolve.
|
|
45
|
+
|
|
46
|
+
### Scripts (`resolve_run_script`)
|
|
47
|
+
|
|
48
|
+
- `code` is an **async JavaScript function body** with `resolve`, `project`, `timeline` and `log(...)` in scope. Every Resolve call returns a promise - `await` each one - and `return` a JSON-serialisable result.
|
|
49
|
+
- The editor reads the exact code before approving. Give a plain `purpose`. Never touch files, the network or other projects unless the user asked for exactly that.
|
|
50
|
+
|
|
51
|
+
## Blackmagic's DaVinci Resolve MCP
|
|
52
|
+
|
|
53
|
+
Verified against DaVinci Resolve Studio 21.1.0.17.
|
|
54
|
+
|
|
55
|
+
### Requirements - check before promising anything
|
|
56
|
+
|
|
57
|
+
- **DaVinci Resolve Studio 21.1 or later.** The free edition has no MCP server and no external scripting.
|
|
58
|
+
- A **local** agent: Claude Desktop, Claude Code or Codex on the same computer as Resolve. Browser ChatGPT and claude.ai cannot reach this server; use the Kolbo Resolve plugin from there.
|
|
59
|
+
- Connect Resolve's server from **File → Setup AI Assistants** in Resolve, and set **Preferences → System → General → External scripting using** to **Local**.
|
|
60
|
+
- Resolve must be running; the server's `launch_resolve` tool can start it.
|
|
61
|
+
|
|
62
|
+
If neither the Kolbo plugin session nor Blackmagic's tools are available, say so and give the setup steps for the path that fits the user. Do not try to control Resolve any other way.
|
|
63
|
+
|
|
64
|
+
### Blackmagic's tools (not Kolbo's)
|
|
65
|
+
|
|
66
|
+
| Tool | Use |
|
|
67
|
+
|---|---|
|
|
68
|
+
| `get_resolve_status`, `launch_resolve` | Is Resolve running / start it |
|
|
69
|
+
| `get_whats_new` (`since` is required, e.g. `"21.0"`) | Features newer than your training |
|
|
70
|
+
| `search_scripting_api`, `get_scripting_api`, `get_scripting_docs` | Look up exact API signatures before writing a script |
|
|
71
|
+
| `run_script` | Sandboxed Python: Resolve API only, no files, network or processes |
|
|
72
|
+
| `run_script_unsafe` | Python with full system access - required for importing files or downloading media |
|
|
73
|
+
| `generate_lut`, `update_dctl`, `list_luts`, `list_dctls` | Colour transforms |
|
|
74
|
+
|
|
75
|
+
Scripts get `resolve` and the current `project` pre-injected and return data by assigning `result`.
|
|
76
|
+
|
|
77
|
+
### Workflow
|
|
78
|
+
|
|
79
|
+
1. **Generate or find media with Kolbo** (`generate_video`, `generate_music`, `list_media`, …) and wait for success.
|
|
80
|
+
2. **Get the files onto disk.** In Claude Code or Codex, download the Kolbo URLs with the shell. In Claude Desktop, download inside `run_script_unsafe` with `urllib.request`. Only download Kolbo-hosted URLs.
|
|
81
|
+
3. **Protect the user's work.** Call `pm.SaveProject()` first. For anything experimental, build in a new project (`pm.CreateProject(name)`) and reload the original project at the end. Projects opened in 21.1 cannot be opened in 20.x, so never convert a user's project as a side effect.
|
|
82
|
+
4. **Import, cut and finish** with `run_script_unsafe` (see recipe).
|
|
83
|
+
5. **Verify visually.** Set the playhead and call `project.ExportCurrentFrameAsStill(path)` at representative times, then look at the stills before reporting.
|
|
84
|
+
6. Optionally render (`AddRenderJob` / `StartRendering`) and upload the result back to Kolbo with `upload_media` so it lands in the user's library.
|
|
85
|
+
|
|
86
|
+
### Verified gotchas
|
|
87
|
+
|
|
88
|
+
- **`MediaPool.ImportMedia` needs plain path strings.** The dict form in the 21.1 stubs (`[{"FilePath": ...}]`) returned `None`. On Windows, backslash paths worked.
|
|
89
|
+
- **File import fails in `run_script`**; use `run_script_unsafe` for anything that touches files.
|
|
90
|
+
- **`Timeline.InsertFusionTitleIntoTimeline("Text+")` is a ripple insert** into every unlocked track: it splits the clips and music under the playhead. With those tracks locked it inserts nothing. For a title over a shot, build it inside that clip's Fusion comp (recipe below).
|
|
91
|
+
- `AppendToTimeline` `startFrame` / `endFrame` are **source frames** at the clip's own frame rate (`GetClipProperty("FPS")`). `recordFrame` is a timeline frame; timelines start at `timeline.GetStartFrame()` (86400 = 01:00:00:00 at 24 fps).
|
|
92
|
+
- New projects default to 24 fps and UHD output.
|
|
93
|
+
|
|
94
|
+
### Recipe: cut, transition, music fade, title
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
pm = resolve.GetProjectManager()
|
|
98
|
+
original = project.GetName()
|
|
99
|
+
pm.SaveProject()
|
|
100
|
+
proj = pm.CreateProject("Kolbo Edit") or pm.LoadProject("Kolbo Edit")
|
|
101
|
+
mp = proj.GetMediaPool()
|
|
102
|
+
|
|
103
|
+
paths = [r"C:\media\shot1.mp4", r"C:\media\shot2.mp4", r"C:\media\music.mp3"]
|
|
104
|
+
items = {item.GetName(): item for item in mp.ImportMedia(paths)}
|
|
105
|
+
shot1, shot2, music = items["shot1.mp4"], items["shot2.mp4"], items["music.mp3"]
|
|
106
|
+
|
|
107
|
+
tl = mp.CreateEmptyTimeline("Kolbo Promo")
|
|
108
|
+
proj.SetCurrentTimeline(tl)
|
|
109
|
+
fps = float(proj.GetSetting("timelineFrameRate"))
|
|
110
|
+
start = tl.GetStartFrame()
|
|
111
|
+
|
|
112
|
+
def src(item, a, b):
|
|
113
|
+
clip_fps = float(item.GetClipProperty("FPS") or fps)
|
|
114
|
+
return int(a * clip_fps), int(b * clip_fps) - 1
|
|
115
|
+
|
|
116
|
+
s1, e1 = src(shot1, 0.5, 6.5)
|
|
117
|
+
s2, e2 = src(shot2, 1.0, 7.0)
|
|
118
|
+
clips = mp.AppendToTimeline([
|
|
119
|
+
{"mediaPoolItem": shot1, "startFrame": s1, "endFrame": e1, "mediaType": 1, "trackIndex": 1, "recordFrame": start},
|
|
120
|
+
{"mediaPoolItem": shot2, "startFrame": s2, "endFrame": e2, "mediaType": 1, "trackIndex": 1, "recordFrame": start + int(6 * fps)},
|
|
121
|
+
])
|
|
122
|
+
audio = mp.AppendToTimeline([{"mediaPoolItem": music, "startFrame": 0, "endFrame": int(12 * fps) - 1,
|
|
123
|
+
"mediaType": 2, "trackIndex": 1, "recordFrame": start}])
|
|
124
|
+
|
|
125
|
+
clips[0].AddTransition({"type": "Cross Dissolve", "category": "simple", "position": "end",
|
|
126
|
+
"alignment": "center", "duration": int(fps)})
|
|
127
|
+
audio[0].SetFades({"FadeIn": int(0.5 * fps), "FadeOut": int(2 * fps)})
|
|
128
|
+
|
|
129
|
+
# Title inside shot 1's Fusion comp, fading in and out (Blend keyframes are clip frames).
|
|
130
|
+
comp = clips[0].AddFusionComp()
|
|
131
|
+
media_in, media_out = comp.FindTool("MediaIn1"), comp.FindTool("MediaOut1")
|
|
132
|
+
text = comp.AddTool("TextPlus", -32768, -32768)
|
|
133
|
+
text.SetInput("StyledText", "KOLBO x DAVINCI RESOLVE")
|
|
134
|
+
text.SetInput("Size", 0.085)
|
|
135
|
+
text.SetInput("Font", "Arial")
|
|
136
|
+
text.SetInput("Style", "Bold")
|
|
137
|
+
merge = comp.AddTool("Merge", -32768, -32768)
|
|
138
|
+
merge.ConnectInput("Background", media_in)
|
|
139
|
+
merge.ConnectInput("Foreground", text)
|
|
140
|
+
media_out.ConnectInput("Input", merge)
|
|
141
|
+
merge.AddModifier("Blend", "BezierSpline")
|
|
142
|
+
for value, frame in ((0.0, 6), (1.0, 24), (1.0, 96), (0.0, 120)):
|
|
143
|
+
merge.SetInput("Blend", value, frame)
|
|
144
|
+
|
|
145
|
+
pm.SaveProject()
|
|
146
|
+
result = {"project": proj.GetName(), "timeline": tl.GetName(), "original": original}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Then verify, and restore the user's project when you are done:
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
tl = project.GetCurrentTimeline()
|
|
153
|
+
tl.SetCurrentTimecode("01:00:02:00")
|
|
154
|
+
ok = project.ExportCurrentFrameAsStill(r"C:\media\check-2s.png")
|
|
155
|
+
resolve.GetProjectManager().SaveProject()
|
|
156
|
+
resolve.GetProjectManager().LoadProject("<original project name>")
|
|
157
|
+
result = {"still": ok}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Completion proof
|
|
161
|
+
|
|
162
|
+
- Look at exported stills at the title, the transition and the end before reporting.
|
|
163
|
+
- Report which project and timeline you built, that the original project was saved and restored, and where any render landed.
|
|
@@ -42,7 +42,7 @@ it — nothing installs the font — so these are the levers that decide how clo
|
|
|
42
42
|
|
|
43
43
|
- **Model choice is the biggest one.** GPT Image 2 reproduced the uploaded letterforms
|
|
44
44
|
clearly better than GPT Image 2.5 Sunburst / Flare, which drift toward a default bold
|
|
45
|
-
Hebrew.
|
|
45
|
+
Hebrew in that test. This is historical evidence, not a standing recommendation: choose from current catalog typography strengths and supported font inputs.
|
|
46
46
|
- **Quality does not compensate.** 2K + `high` on GPT Image 2 beat both 2.5 rows at
|
|
47
47
|
`max`. Do not sell a higher tier as a fix for typography.
|
|
48
48
|
- **Weight words in the prompt beat the specimen.** "bold", "medium weight", "very large
|