davinci-resolve-mcp 4.11.0 → 4.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/README.md +1 -1
  3. package/README.zh-CN.md +2 -2
  4. package/docs/SKILL.md +16 -1
  5. package/docs/guides/subtitle-track-editing.md +118 -3
  6. package/docs/guides/title-library-automation.md +109 -0
  7. package/docs/kernels/audio-fairlight-kernel.md +4 -2
  8. package/docs/kernels/fusion-composition-kernel.md +9 -0
  9. package/docs/notes/subtitle-live-automation-audit.md +82 -0
  10. package/docs/notes/title-library-acceptance.md +76 -0
  11. package/docs/reference/api-limitations.md +1 -1
  12. package/docs/reference/readwrite-symmetry.md +3 -2
  13. package/install.py +1 -1
  14. package/package.json +3 -1
  15. package/resolve-advanced/README.md +5 -1
  16. package/resolve-advanced/assets/lollipop-track.xml +59 -0
  17. package/resolve-advanced/assets/word-highlight-track.xml +61 -0
  18. package/resolve-advanced/package.json +1 -0
  19. package/resolve-advanced/server/subtitle-db.mjs +1 -0
  20. package/resolve-advanced/server/subtitle-timeline.mjs +81 -0
  21. package/resolve-advanced/vendor/drp-format/subtitle-preset.js +27 -9
  22. package/scripts/edit_subtitle_timeline.mjs +12 -0
  23. package/scripts/title_frame_metrics.py +13 -0
  24. package/scripts/title_library_report.py +95 -0
  25. package/src/granular/common.py +1 -1
  26. package/src/granular/timeline_item.py +2 -1
  27. package/src/server.py +59 -21
  28. package/src/utils/api_truth.py +8 -1
  29. package/src/utils/captions.py +10 -4
  30. package/src/utils/cube_lut.py +21 -3
  31. package/src/utils/destructive_hook.py +5 -2
  32. package/src/utils/execution_lifecycle.py +1 -0
  33. package/src/utils/qa_privacy.py +27 -0
  34. package/src/utils/subtitle_live.py +197 -0
  35. package/src/utils/title_controls.py +97 -0
  36. package/src/utils/title_library.py +44 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,92 @@
2
2
 
3
3
  Release history for the DaVinci Resolve MCP Server. The latest release is summarized in the root README; older entries live here to keep the README focused.
4
4
 
5
+ ## What's New in v4.12.0 — Live subtitle presets and title text across Fusion title tools
6
+
7
+ Contributed by @sidevconcept (#281). The live behaviour below rests on their
8
+ synthetic runs on **Resolve Studio 21.1.0.17 / Windows**; this release was not
9
+ re-measured live here (the maintainer's machine runs 19.1.3.7).
10
+
11
+ ### New
12
+
13
+ - **`timeline_ai(action="list_title_presets")`** inventories the installed
14
+ factory Fusion titles and subtitle presets: local archive, category and full
15
+ template ID. `templates_archive` points it at a custom installation. It is an
16
+ inventory, not a claim that each preset works live.
17
+ - **`timeline_ai(action="set_subtitle_preset")`** applies an installed subtitle
18
+ preset and common literal style inputs (font, size, position and so on) to a
19
+ subtitle track while Resolve stays open. It writes a **new timeline
20
+ revision** and keeps the original, compares the edit inventory, and re-exports
21
+ through Resolve to confirm the preset and controls were kept. It restores the
22
+ original timeline on failure.
23
+ - `dry_run` / `dryRun` are coerced at the dispatcher, so `"true"` previews
24
+ and never imports. A preview that would need a live capture is refused.
25
+ - The result lists `verified_components` (track counts, item names and
26
+ bounds, media IDs, preset controls) and `unverified_components` (markers,
27
+ grades, other Fusion comps, audio). Native readback is not render
28
+ verification, and the revision is not certified as a full copy.
29
+ - Staging exports are removed on success and kept for diagnosis on failure
30
+ (`staging_retained`, `staging_directory`).
31
+ - **`timeline.set_title_text` / `get_title_text` reach more than TextPlus.** The
32
+ Fusion-comp fallback now finds literal text on TextPlus, sText, Text3D and
33
+ MultiText (`TextN.StyledText` in native `TextOrder`). It follows
34
+ `StyledTextFollower` and `PublishText` without disconnecting animation, and it
35
+ skips connected, expression-driven, locked and disabled inputs rather than
36
+ flattening them. MultiText editing was validated only on Studio 21.1.0.17 /
37
+ Windows.
38
+ - **`scripts/edit_subtitle_timeline.mjs`** (backed by
39
+ `resolve-advanced/server/subtitle-timeline.mjs`) inspects an exported
40
+ subtitle track, or writes a new file with a bundled preset reference
41
+ (`Word Highlight`, `Lollipop`) or a native subtitle-template reference applied.
42
+ - Synthetic title-library validation scripts write private QA reports with
43
+ relative image links; `src/utils/qa_privacy.py` replaces host paths and
44
+ project/timeline names in saved records.
45
+
46
+ ### Docs
47
+
48
+ - New guides: `docs/guides/title-library-automation.md` and
49
+ `docs/guides/subtitle-track-editing.md`.
50
+
51
+ ### Verification
52
+
53
+ - Contributor (Studio 21.1.0.17 / Windows, synthetic media): all 134 installed
54
+ factory Fusion presets passed native application, literal text/property
55
+ readback and sampled rendered-frame checks; all 23 subtitle presets applied
56
+ without a restart.
57
+ - Here: Python offline suite and Node advanced suite (fresh `npm ci`) green;
58
+ API parity, api-limitations, read/write symmetry, agent-rule drift and
59
+ `npm pack` clean.
60
+
61
+ ## What's New in v4.11.1 — `.cube` input ranges, `"false"` import flags and the caption character cap
62
+
63
+ Three fixes from @Dev-next-gen (#286, #287, #288), each with a reproduction and a
64
+ regression test.
65
+
66
+ ### Fixes
67
+
68
+ - **A 3D `.cube` carrying `LUT_3D_INPUT_RANGE` could not be read** (#288).
69
+ `read_cube` knew `DOMAIN_MIN`/`DOMAIN_MAX` but not Resolve's own header form,
70
+ so the line fell through to the data-row branch and the whole file was refused
71
+ as a "non-numeric entry". `read_lut_summary` and `attenuate_lut_file` both
72
+ failed on it. The keyword is now read as one domain for all three channels;
73
+ attenuation still refuses a non-unit range, exactly as it does for
74
+ `DOMAIN_MIN`/`DOMAIN_MAX`.
75
+ - **On landing:** a short or non-numeric `LUT_3D_INPUT_RANGE` escaped as a bare
76
+ `ValueError`, and a short `DOMAIN_MIN`/`DOMAIN_MAX` produced a silently short
77
+ domain list. All three headers now go through one reader that raises
78
+ `CubeLutError` naming the file, line and keyword.
79
+ - **`timeline(action="import_timeline_checked")` read `"false"` as true** (#287).
80
+ `sanitize_media` / `relink_media` and `import_source_clips` were read with bare
81
+ `bool()`, so `sanitize_media="false"` still handed Resolve the sanitized copy
82
+ instead of the file passed, and `import_source_clips="false"` reached
83
+ `ImportTimelineFromFile` as `importSourceClips: True`. Both now go through
84
+ `_coerce_bool`, as the rest of `server.py` has since v4.8.20.
85
+ - **Caption orphan rebalancing could break `max_chars_per_line`** (#286).
86
+ Moving the last word of the penultimate line onto a one-word final line never
87
+ re-checked the cap, so "we had a wonderful conversation" at 20 characters came
88
+ out with a 22-character second line in the SRT/WebVTT. The move now happens
89
+ only when the merged line fits; a lone last word is the lesser fault.
90
+
5
91
  ## What's New in v4.11.0 — `rename_plan` collides names a case-insensitive volume treats as one
6
92
 
7
93
  ### Fixes
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  English | [简体中文](README.zh-CN.md)
4
4
 
5
- [![Version](https://img.shields.io/badge/version-4.11.0-blue.svg)](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
5
+ [![Version](https://img.shields.io/badge/version-4.12.0-blue.svg)](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
6
6
  [![npm](https://img.shields.io/npm/v/davinci-resolve-mcp.svg?label=npm&color=CB3837)](https://www.npmjs.com/package/davinci-resolve-mcp)
7
7
  [![API Coverage](https://img.shields.io/badge/API%20Coverage-100%25-brightgreen.svg)](docs/reference/api-coverage.md)
8
8
  [![Tools](https://img.shields.io/badge/MCP%20Tools-37%20(389%20full)-blue.svg)](#server-modes)
package/README.zh-CN.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [English](README.md) | 简体中文
4
4
 
5
- [![Version](https://img.shields.io/badge/version-4.11.0-blue.svg)](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
5
+ [![Version](https://img.shields.io/badge/version-4.12.0-blue.svg)](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
6
6
  [![npm](https://img.shields.io/npm/v/davinci-resolve-mcp.svg?label=npm&color=CB3837)](https://www.npmjs.com/package/davinci-resolve-mcp)
7
7
  [![API Coverage](https://img.shields.io/badge/API%20Coverage-100%25-brightgreen.svg)](docs/reference/api-coverage.md)
8
8
  [![Tools](https://img.shields.io/badge/MCP%20Tools-37%20(389%20full)-blue.svg)](#服务器模式)
@@ -12,7 +12,7 @@
12
12
  [![Python](https://img.shields.io/badge/python-3.10+-green.svg)](https://www.python.org/downloads/)
13
13
  [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)
14
14
 
15
- > 本翻译对应 v4.11.0 版 README。如与英文原版有出入,以 [英文原版](README.md) 为准。
15
+ > 本翻译对应 v4.12.0 版 README。如与英文原版有出入,以 [英文原版](README.md) 为准。
16
16
 
17
17
  一个 Model Context Protocol (MCP) 服务器,让 AI 助手通过官方脚本 API 控制 DaVinci Resolve Studio(达芬奇)。它提供完整的 API 覆盖,外加带护栏的工作流助手,涵盖剪辑、媒体池整理、渲染设置、审阅标记、调色、Fusion、Fairlight、项目生命周期任务、扩展开发,以及不碰源媒体的媒体分析。
18
18
 
package/docs/SKILL.md CHANGED
@@ -418,7 +418,22 @@ Operating rules an agent must know:
418
418
  `iConfirmProjectClosed:true`; every write auto-backs-up and read-back
419
419
  verifies. Resolve caches open projects in memory: after patching, fully QUIT
420
420
  and relaunch Resolve or the patch will not be visible.
421
- - **Subtitle DB edits**: `project_db` `list_captions` / `write_captions` /
421
+ - **Live subtitle effects**: use `timeline_ai.set_subtitle_preset` with Resolve
422
+ open. `timeline_ai.list_title_presets` discovers installed title/subtitle names
423
+ and full IDs. `preset` accepts a bundled or installed subtitle preset; omit it
424
+ to adjust the existing effect. `inputs` accepts common literal font/style,
425
+ size/position and text RGBA; highlight/outline controls are Word Highlight-specific.
426
+ Native DRT export/edit/import creates and selects a recoverable revision,
427
+ preserving the original. Do not ask the user to quit or relaunch for effects.
428
+ Render frames to verify appearance; inventory/readback alone is insufficient.
429
+ Installed presets are captured through the native title API in a temporary
430
+ timeline, then applied to the subtitle track. Common controls also work for
431
+ Lollipop. Never guess unmapped effect controls. `preset_reference` accepts a
432
+ native subtitle DRT; unbundled dry runs require such a reference.
433
+ Ordinary title presets use `timeline.insert_fusion_title` with the full ID,
434
+ then scoped `fusion_comp` probes and input writes. See
435
+ [title library automation](guides/title-library-automation.md) for acceptance.
436
+ - **Offline subtitle DB edits**: `project_db` `list_captions` / `write_captions` /
422
437
  `check_captions` cover text, bounds, explicit per-word timing, add and delete.
423
438
  `list_subtitle_presets` / `copy_subtitle_preset` / `set_subtitle_preset` handle
424
439
  animated Fusion holders separately from basic `list_subtitle_styles`.
@@ -1,5 +1,88 @@
1
1
  # Subtitle tracks: captions and animated presets
2
2
 
3
+ ## Live effects: keep Resolve open
4
+
5
+ For routine video changes, use the live server's
6
+ `timeline_ai(action="set_subtitle_preset", params={...})`. Do not route subtitle
7
+ effect changes to `project_db` or ask the user to quit/relaunch Resolve.
8
+
9
+ ```json
10
+ {
11
+ "action":"set_subtitle_preset",
12
+ "params":{
13
+ "track":1, "preset":"Word Highlight",
14
+ "inputs":{
15
+ "font":"Segoe UI", "fontStyle":"Black", "size":0.065,
16
+ "position":[0.5,0.4], "textRed":1, "textGreen":1, "textBlue":1,
17
+ "highlightRed":1, "highlightGreen":1, "highlightBlue":0,
18
+ "outlineEnabled":1, "outlineRed":0, "outlineGreen":0,
19
+ "outlineBlue":0, "thickness":0.1
20
+ }
21
+ }
22
+ }
23
+ ```
24
+
25
+ This exports the current native DRT, edits only its subtitle Fusion holder,
26
+ then imports and selects a new timeline revision. The original timeline remains
27
+ recoverable. Successful operations, including dry runs, delete their staging
28
+ exports. Failures keep the staging folder for diagnosis and return
29
+ `staging_retained:true` and `staging_directory`; remove that folder when diagnosis
30
+ is complete because it contains full timeline exports. Cleanup failures also
31
+ report the retained folder with a warning. It never edits the open database, changes source
32
+ media or requires an application restart. `dry_run:true` prepares the exported
33
+ revision without importing it. Omit `preset` to incrementally adjust the
34
+ current Word Highlight instead of replacing it. `preset_reference` can name
35
+ another native DRT, with `reference_track` selecting its subtitle track.
36
+ `revision_name` is optional and must be unique in the current project.
37
+
38
+ `preset:"Word Highlight"` applies a bundled native holder exported from the
39
+ synthetic Studio 21.1.0.17 acceptance project. Its reference settings are Segoe
40
+ UI Black, size 0.055, centred position, white text, yellow highlight, black
41
+ outline and thickness 0.1; these are reference settings, not claims about UI
42
+ defaults. Explicit `inputs` override them. No reference footage is bundled.
43
+ `preset:"Lollipop"` applies the bundled native Lollipop. Other installed subtitle
44
+ presets are discovered from the local `Templates.drfx`, captured by the running
45
+ Resolve as a native title in an isolated temporary timeline, then applied to the
46
+ subtitle track through native interchange. The temporary capture is removed
47
+ after restoring the original timeline; the original edit remains recoverable.
48
+ No additional vendor template files are redistributed. Use
49
+ `timeline_ai(action="list_title_presets")` to discover names, full template IDs
50
+ and categories. Supply `templates_archive` for a nonstandard installation.
51
+ Full IDs disambiguate names such as the ordinary and animated `Statement`.
52
+
53
+ All subtitle templates with the inspected `Template = TextPlus` layout accept
54
+ the common literal `font`, `fontStyle`, `size`, `position`, `textRed`, `textGreen`,
55
+ `textBlue`, and `textAlpha` controls. Highlight and outline mappings remain
56
+ specific to Word Highlight. Connected/animated controls, different layouts and
57
+ unmapped effect controls are refused. Do not guess their meanings. The live
58
+ matrix is documented in [title library automation](title-library-automation.md).
59
+ An alternate `preset_reference` can copy another decodable native holder.
60
+ For an unbundled installed preset, a mutation-free dry run needs an existing
61
+ `preset_reference`: discovering its native definition otherwise needs a temporary
62
+ live title. `dry_run` never creates that temporary timeline.
63
+
64
+ For gradient/image text fills (observed in Grey with Shadow), solid RGB inputs
65
+ are dormant. The writer refuses a colour edit that would only change those
66
+ invisible values. Pass `inputs.textFillMode:"solid"` explicitly to replace the
67
+ fill mode, then supply the desired text RGBA. The stored gradient is retained,
68
+ and the original timeline/reference remains recoverable. Font, size and position
69
+ edits can preserve the gradient by omitting text colour inputs. Readback reports
70
+ the effective `textFillMode`; absent Type1 uses the observed TextPlus solid default.
71
+
72
+ The handler checks live track counts, item names/bounds and Media Pool media IDs
73
+ against the original, then re-exports the imported timeline through Resolve and
74
+ verifies that it retained the preset controls before selecting the revision.
75
+ `verified_components` lists these checks. Markers, grades, other items' Fusion
76
+ compositions and audio content are **not** compared; they are listed in
77
+ `unverified_components`. This is not verification of a complete timeline copy.
78
+ A failed import/check
79
+ restores the previous active timeline and reports the retained failed revision.
80
+ Resolve re-export readback plus edit inventory is not render verification: inspect rendered
81
+ frames at word boundaries and across caption gaps. Native DRT import was tested
82
+ on Studio 21.1.0.17/Windows without quitting Resolve. Changing sequence IDs in
83
+ only the sequence XML loses subtitle tracks; cross-entry references must remain
84
+ intact. Resolve remaps timeline IDs itself on import.
85
+
3
86
  The advanced server's `project_db` tool edits saved local SQLite projects.
4
87
  The live server can generate subtitles with `timeline_ai.create_subtitles`,
5
88
  enumerate their items, read names/bounds and delete items. It cannot edit caption
@@ -15,7 +98,13 @@ There are two independent kinds of subtitle styling:
15
98
  holder and composition. `set_subtitle_preset` edits named Word Highlight
16
99
  controls inside its nested compressed tool section.
17
100
 
18
- ## Required workflow
101
+ ## Offline database workflow (explicit maintenance only)
102
+
103
+ The following full-quit requirement belongs to direct database writes, not
104
+ live effect automation. Keep the guard: bypassing it can lose edits. Caption
105
+ text/word-timing DB writes still use this offline workflow; for restart-free
106
+ caption corrections use the live Resolve UI. A generic `SetProperty` refusal
107
+ does not establish that all subtitle workflows require a restart.
19
108
 
20
109
  1. Generate captions in Resolve and save the project. Inspect it with
21
110
  `list_captions`, `list_subtitle_presets` and `check_captions`.
@@ -152,8 +241,9 @@ use `set_subtitle_preset` with target selectors and `inputs`.
152
241
  Colour channels are 0–1, `outlineEnabled` is 0 or 1, `size` is Fusion's
153
242
  normalised text size (not points), `position` is Fusion Center `[x,y]`, and
154
243
  `thickness` is the template's HOutlineThickness value. Parameter editing is
155
- restricted to the inspected Word Highlight template and literal Template
156
- TextPlus inputs. Connected/animated inputs and unsupported layouts are refused.
244
+ based on common literal Template TextPlus inputs for subtitle templates;
245
+ highlight and outline controls are specific to Word Highlight.
246
+ Connected/animated inputs and unsupported layouts are refused.
157
247
  Missing input values in the listing mean Resolve/template defaults, not zero.
158
248
  Other supported composition envelopes can be cloned unchanged, but cannot have
159
249
  their parameter meanings guessed. Preset holder Duration is preserved from the
@@ -225,3 +315,28 @@ whether/when UI edits are retimed on save, and SRT import preserving word
225
315
  timings on 21.1. A previously reported ImportMedia(SRT)+AppendToTimeline route
226
316
  on 21.0.4.5 is not evidence that SRT carries word timings on another build.
227
317
  Repeat the probe and render test after Resolve updates.
318
+
319
+ ## Restart-free acceptance (2026-10-08)
320
+
321
+ `tests/live_subtitle_preset_validation.py` exercised the actual Python
322
+ `timeline_ai.set_subtitle_preset` dispatcher on Studio 21.1.0.17/Windows in the
323
+ disposable synthetic QA project, without launching, quitting or reopening
324
+ Resolve. It removed the animation holder from an exported synthetic timeline,
325
+ imported that bare-caption timeline, then applied the bundled Word Highlight.
326
+ The live action verified seven captions and the video/audio bounds/media IDs,
327
+ and native re-export retained the requested white text and magenta highlight.
328
+
329
+ Three full-resolution 1080x1920 Resolve-rendered frames were visually inspected:
330
+ at 108200 the first word was magenta and the second white; at 108220 those
331
+ colours swapped; frame 108180 in the caption gap was black. This proves those
332
+ sampled frames, not every frame or other templates/builds. The harness restores
333
+ the previous timeline, playhead and page. Earlier live runs also demonstrated
334
+ incremental colour, size and position edits, followed by a random-colour change
335
+ requested as a demonstration. Random colours are not the bundled defaults.
336
+
337
+ A subsequent Lollipop test on the same running Studio session applied the
338
+ effect through the native UI, then through the updated MCP action using the
339
+ bundled reference. Resolve's re-export confirmed
340
+ `Templates/Edit/Titles/Subtitles/Animated/Lollipop`; a rendered frame showed its
341
+ native yellow text and orange outline. No application restart was needed.
342
+ This Windows acceptance does not establish Mac compatibility; repeat it there.
@@ -0,0 +1,109 @@
1
+ # Native title and subtitle library automation
2
+
3
+ Keep Resolve Studio open. Discover the installed factory Fusion presets with
4
+ `timeline_ai(action="list_title_presets", params={})`. The inventory names the
5
+ local archive, category and full template ID; it does not imply live acceptance.
6
+ Use `templates_archive` when automatic discovery cannot find a custom installation.
7
+ Factory inventory does not enumerate third-party packs or the basic non-template
8
+ Text/Scroll generators. Installed fonts and tool availability remain host-specific.
9
+
10
+ ## Ordinary Fusion titles
11
+
12
+ Insert with `timeline(action="insert_fusion_title", params={"name":
13
+ "Templates/Edit/Titles/Candy"})`, then identify the inserted clip and use
14
+ `fusion_comp.probe_fusion_comp` / `probe_fusion_tool` with `clip_id` or an explicit
15
+ timeline-item selector. Read the actual graph and controls before editing.
16
+ `safe_set_inputs` can set literal inputs on the inspected tool, including text,
17
+ font, size and colour. Many presets use TextPlus; others use sText or Text3D.
18
+ Do not assume every template has a tool called `Template`, flatten connected
19
+ animation controls, or overwrite text instances linked to another tool.
20
+
21
+ `timeline.set_title_text` also supports literal TextPlus, sText, Text3D and
22
+ MultiText inputs. For a connected StyledTextFollower it edits the modifier's
23
+ literal `Text` input; for PublishText it uses `Value`. MultiText uses the native
24
+ `TextN.StyledText` controls in native `TextOrder`; `TextValueN` changes list
25
+ labels without changing rendered text. Expressions and
26
+ unknown modifier chains are refused rather than flattened. The default text
27
+ action edits the first supported text target; use explicit Fusion tools when
28
+ changing multiple independent title lines. Render to verify the resulting text.
29
+ MultiText editing was validated only on Studio 21.1.0.17 / Windows.
30
+
31
+ Use the full template ID rather than a leaf name: `Statement` exists both as an
32
+ ordinary title and an animated subtitle. Probe `comp.GetData("TEMPLATE_ID")`
33
+ to confirm which template native insertion selected.
34
+
35
+ ## Subtitle-track presets
36
+
37
+ ```json
38
+ {"action":"set_subtitle_preset","params":{
39
+ "preset":"Templates/Edit/Titles/Subtitles/Animated/Rotate",
40
+ "inputs":{"size":0.06,"position":[0.5,0.25],
41
+ "textRed":0.15,"textGreen":0.85,"textBlue":1}
42
+ }}
43
+ ```
44
+
45
+ The live helper captures the installed template in its own temporary timeline,
46
+ exports its native composition, restores the working timeline and removes only
47
+ that temporary capture. It swaps the exported subtitle holder composition,
48
+ imports a recoverable revision, checks edit/media inventory and re-exports the
49
+ revision to confirm native preset/control retention. The original timeline
50
+ remains intact. The inventory compares track counts, item names/bounds and media
51
+ IDs; it does not compare markers, grades, other Fusion compositions or audio
52
+ content. Results list both verified and unverified components. Inspect the
53
+ revision before relying on it as a complete copy.
54
+ Successful operations, including previews, remove staging exports; failures
55
+ retain them for diagnosis and report `staging_retained` and `staging_directory`.
56
+ Cleanup failures warn and report the retained folder. These files contain full
57
+ timeline exports and should be removed after diagnosis. It never writes an open
58
+ Project.db or changes source files.
59
+
60
+ Common mapped literal controls are `font`, `fontStyle`, `size`, `position`,
61
+ `textRed`, `textGreen`, `textBlue` and `textAlpha`. Highlight/outline mappings are
62
+ specific to Word Highlight. Unsupported controls/layouts and animated or
63
+ connected input replacements are refused. An imported preset readback is not a
64
+ rendered check. Inspect caption word phases, gaps and safe margins.
65
+
66
+ Gradient/image fills do not render their dormant solid RGB values. A subtitle
67
+ colour edit refuses that case unless `textFillMode:"solid"` explicitly requests
68
+ replacement of the fill mode. Grey with Shadow uses a native gradient; preserve
69
+ it when editing only font/size/position, or explicitly select solid fill when
70
+ requesting a uniform colour. The gradient data/reference stays recoverable.
71
+ For ordinary Fusion titles, inspect the active shading mode/gradient controls;
72
+ a raw RGB readback alone does not establish the rendered fill colour.
73
+
74
+ Word Highlight and Lollipop have bundled native references. Other factory
75
+ subtitle presets require the local installation or an explicit native subtitle
76
+ `preset_reference`. Unbundled dry runs require a pre-existing reference so no
77
+ live temporary title is created during preview.
78
+
79
+ ## Repeatable acceptance
80
+
81
+ The [Windows acceptance record](../notes/title-library-acceptance.md) documents
82
+ 134 final passing cases and an interrupted ordinary-title retest that required
83
+ automatic Studio crash recovery. It does not establish universal restart-free
84
+ reliability or Mac compatibility.
85
+
86
+ `tests/live_title_library_validation.py` requires an already-open disposable
87
+ `MCP_QA_*` project with the synthetic caption fixture. It refuses to launch
88
+ Resolve, renders representative native frames, records property readback and
89
+ pixel differences, persists every case, retains test timelines and restores the
90
+ original timeline/page/playhead. Only synthetic project contents may be used.
91
+
92
+ ```powershell
93
+ venv/Scripts/python.exe tests/live_title_library_validation.py --output-dir logs/title-library-full
94
+ ```
95
+
96
+ The image metrics require Pillow and NumPy; `--image-python` can use an independent
97
+ Python installation with those packages. It runs in isolated mode, avoiding
98
+ Resolve's Python environment. `--only` selects exact names/IDs for a focused
99
+ retest. `scripts/title_library_report.py` builds a local HTML matrix and contact
100
+ sheets from one or more reports; a later retest replaces the same template's case.
101
+ The HTML uses relative links to copied QA renders under its `frames/` folder;
102
+ move the entire output folder to view it on another machine. Saved QA records
103
+ replace host workspace/home paths with anonymous markers; they do not retain
104
+ the local account name or workspace folder identity.
105
+
106
+ Acceptance distinguishes native application, literal property readback and
107
+ sampled rendered appearance. It does not certify all controls, every animation
108
+ frame, third-party packs, or Mac compatibility. Test Mac separately before
109
+ claiming cross-platform live acceptance.
@@ -1,7 +1,9 @@
1
1
  # Audio / Fairlight Kernel
2
2
 
3
- For caption text, per-word timing, additions/deletions and animated subtitle
4
- presets, use advanced `project_db` after saving and fully quitting Resolve.
3
+ For animated subtitle effects use live `timeline_ai.set_subtitle_preset` with
4
+ Resolve open. It applies/adjusts Word Highlight through native DRT interchange
5
+ and selects a recoverable revision. For caption text/word timing use the live
6
+ UI, or explicit offline advanced `project_db` maintenance after fully quitting.
5
7
  See [subtitle-track editing](../guides/subtitle-track-editing.md). The basic
6
8
  `set_subtitle_style` action does not edit animated Fusion presets.
7
9
 
@@ -1,5 +1,14 @@
1
1
  # Fusion Composition Kernel
2
2
 
3
+ Subtitle-track animation holders do not enumerate as caption Fusion comps.
4
+ For installed subtitle presets and common font, colour, size and position edits,
5
+ use live `timeline_ai.set_subtitle_preset`; Word Highlight also has mapped
6
+ highlight/outline controls. Discover presets with `timeline_ai.list_title_presets`.
7
+ See [subtitle-track editing](../guides/subtitle-track-editing.md) and
8
+ [title library automation](../guides/title-library-automation.md).
9
+ Keep Resolve open. Generic caption `SetProperty`/`GetFusionCompByIndex` is not
10
+ the route, and direct Project.db patching is reserved for explicit offline work.
11
+
3
12
  The Fusion Composition kernel expands `fusion_comp` into a safer graph
4
13
  inspection, tool creation, input write, connection, and boundary-report layer
5
14
  for timeline item Fusion comps and active Fusion page comps.
@@ -0,0 +1,82 @@
1
+ # Live subtitle automation audit — 2026-10-08
2
+
3
+ The `feat/subtitle-track-support` branch added useful caption/preset codecs but
4
+ routed effect edits only through Project.db. The subsequent full-quit guard was
5
+ correct for that database route; it did not establish that a running Resolve
6
+ could not apply the same effect through native interchange or its own UI.
7
+
8
+ ## Corrected paths
9
+
10
+ | Finding | Correction |
11
+ |---|---|
12
+ | Word Highlight edits exposed only as offline DB actions | Live `timeline_ai.set_subtitle_preset` exports native DRT, changes the exported holder, imports/selects a new revision; original retained |
13
+ | Applying an effect required a reference in another user project | Bundle a native holder from synthetic QA with explicit reference settings and no media |
14
+ | Subtitle `SetProperty` refusal sent every request to full-quit DB patching | Error now routes effects to the live action; text/timing to live UI or explicit offline maintenance |
15
+ | Skills and kernels directed animation work to the offline server | Updated audio/Fusion portable skills, kernels, operating reference, advanced README and subtitle guide |
16
+ | Codec readback could report success before Resolve parsed the composition | Re-export the imported timeline and compare its retained controls; also compare live edit inventory |
17
+
18
+ Direct DB-write safety guards remain intact. Never patch the database of an
19
+ open project, including a project loaded earlier in the same Resolve session.
20
+ Native interchange avoids that cache hazard by asking Resolve itself to import
21
+ the changed content.
22
+
23
+ ## Evidence and limits
24
+
25
+ Live validation on Studio 21.1.0.17/Windows exercised the public dispatcher,
26
+ applied Word Highlight to a bare subtitle track and verified the imported
27
+ controls through native re-export. Seven caption bounds, video/audio bounds and
28
+ media IDs matched. Rendered frames showed the requested white/magenta word
29
+ phases and a blank caption gap. Incremental colour, size and position edits also
30
+ worked, including the user's random-colour demonstration, without a restart.
31
+ See [subtitle-track editing](../guides/subtitle-track-editing.md) and the
32
+ synthetic-only live acceptance script.
33
+
34
+ That original acceptance certified Word Highlight and unchanged Lollipop
35
+ application, not universal video automation. The subsequent installed-library
36
+ expansion discovers presets, captures their native definitions without UI drags,
37
+ and maps common literal subtitle font, size, position and text RGBA controls.
38
+ Ordinary title text now includes shape/3D/MultiText and supported text modifiers
39
+ without flattening their animation. See
40
+ [title library automation](../guides/title-library-automation.md) for the test
41
+ harness and its measured limits, and the subsequent
42
+ [134-preset acceptance record](title-library-acceptance.md), including its
43
+ ordinary-title crash/recovery. Unmapped subtitle effect controls and caption
44
+ text/timing changes still need observed live UI automation unless another supported
45
+ route is available. Current granular-only clients do not expose the new compound
46
+ action; use the compound server or the shared Python helper. Installed fonts,
47
+ templates, speech models and Resolve build differences remain capabilities to
48
+ probe, not assumptions.
49
+
50
+ Remaining full-quit references under extension-authoring, offline DB maintenance
51
+ and crash recovery describe distinct operations. Newly installed Fuses and
52
+ some extension categories genuinely have restart requirements. Routine video
53
+ edits should use already available tools or native imported compositions rather
54
+ than turn extension installation into a repeated step. Do not erase those
55
+ constraints to promise "100% automated".
56
+
57
+ Code already loaded in an MCP process does not automatically change after a
58
+ Git update. Follow the installer/update instructions for the component being
59
+ updated. Bridge-script installation may require Resolve to restart. This
60
+ feature does not change the general launcher or installer lifecycle.
61
+
62
+ ## Validation record
63
+
64
+ - 169 Python tests in the relevant subtitle, safety, connection, lifecycle,
65
+ dashboard and documentation suites: passed, one skipped. A subsequent focused
66
+ run of 53 tests included the added imported-control-loss regression and passed.
67
+ - 28 Node subtitle codec/DB/native-timeline tests passed. The two new native
68
+ timeline tests also passed independently after the readback helper was added.
69
+ - Native API parity audit passed (existing undocumented-method advisories only).
70
+ - Generated API-limitations, read/write-symmetry and portable-agent assets checked.
71
+ - NPM dry-run package inspection confirmed the live bridge, codec helper and
72
+ native reference asset are included.
73
+ - Windows test-fixture corrections are split into a separate change: ps fixtures
74
+ select their intended platform, macOS path assertions normalize separators,
75
+ and dashboard temporary SQLite connections close before directory removal.
76
+
77
+ The automation is reviewed separately from subtitle database editing. Studio
78
+ stayed open during the original subtitle acceptance;
79
+ the later full-library title test has the interruption documented above.
80
+ Existing MCP processes still need to load the
81
+ updated Python code to expose the new action; that is separate from restarting
82
+ Resolve.
@@ -0,0 +1,76 @@
1
+ # Installed title library acceptance — 2026-10-08/09
2
+
3
+ Windows Resolve Studio 21.1.0.17, branch `feat/subtitle-track-support`, synthetic
4
+ project. Native definitions came from the locally installed factory
5
+ `Templates.drfx`; they were not redistributed. Source media was unchanged.
6
+
7
+ ## Final measured result
8
+
9
+ | Factory category | Applied | Property readback and sampled renders |
10
+ |---|---:|---:|
11
+ | Ordinary Fusion titles / lower thirds | 111 | 111 passed |
12
+ | Static subtitle presets | 18 | 18 passed |
13
+ | Animated subtitle presets | 5 | 5 passed |
14
+ | Total | 134 | 134 passed after corrections and retests |
15
+
16
+ Native title insertion used full IDs and checked `TEMPLATE_ID`. Supported
17
+ independent text targets received `MCP TEST` through the public title-text action
18
+ and scoped Fusion writes. Available literal size/RGB controls were exercised;
19
+ connected/expression controls were preserved. Native Deliver captures compared
20
+ the same frame before/after and sampled early/late frames. Final title contact
21
+ sheets show the requested text. Material/gradient-driven colours are not
22
+ certified by dormant RGB readback.
23
+
24
+ Subtitle tests used the public live action with size, position and text RGB.
25
+ Imported revisions preserved edit/media inventory and retained preset/controls
26
+ in a native re-export. Two caption word samples rendered visibly, with a blank
27
+ gap sample. Grey with Shadow explicitly selected solid fill for its colour test;
28
+ the native gradient reference stays recoverable. All 23 subtitle presets passed
29
+ without a Resolve application restart.
30
+
31
+ ## Corrections and session failure
32
+
33
+ - Follow StyledTextFollower base `Text` and PublishText `Value` without flattening
34
+ the owner's connected StyledText input; support sText and Text3D.
35
+ - MultiText `TextValueN` inputs are passive list labels. Rendered text uses
36
+ `TextN.StyledText`, ordered by native `TextOrder`. Inspect hidden row input
37
+ handles before writing. A regression test covers this distinction.
38
+ - Refuse subtitle RGB edits on gradient/image fills unless the caller explicitly
39
+ requests `textFillMode:"solid"`.
40
+ - Persist harness results before restoration and record restoration failure
41
+ when scripting disconnects.
42
+
43
+ The initial complete matrix inserted every preset. A focused retest stalled and
44
+ Studio exited during Two Line Slide while the old MultiText list-label path was
45
+ still loaded in that test process. This records the observed sequence, not a
46
+ proven exclusive crash cause. Process exit was verified. The same Studio
47
+ executable was recovered automatically with no existing Resolve process, and
48
+ the original QA timeline restored. No user reopen was needed. Corrected Letterbox
49
+ Text, Simple Two Lines, Two Line Slide and Zipper then passed a fresh four-case
50
+ native test. The crash prevents claiming an uninterrupted full acceptance run
51
+ or universal 100% restart-free automation.
52
+
53
+ ## Evidence and limits
54
+
55
+ Local scratch reports: `logs/title-library-full/report.json` (134 initial cases),
56
+ `logs/title-library-retest/report.json` (interrupted focused run and failure
57
+ annotation), `logs/title-library-final-retest/report.json` (four corrected cases
58
+ and restoration readback). `logs/title-library-review/index.html` and
59
+ `matrix.json` merge the latest result per template, preserve session failures and
60
+ link native full-resolution frames. Subtitle contact sheets are labelled detail
61
+ crops; individual cases retain native DRT exports. These artifacts are not
62
+ shipped vendor templates.
63
+
64
+ Reproduce using [the library guide](../guides/title-library-automation.md),
65
+ `tests/live_title_library_validation.py` on an already-open disposable synthetic
66
+ project, and `scripts/title_library_report.py`. Mac remains untested. Scope
67
+ excludes third-party packs, basic Text/Scroll generators, every effect-specific
68
+ parameter and exhaustive animation frames. Unsupported/connected controls still
69
+ require an observed supported route.
70
+
71
+ The latest relevant Python run passed 120 tests with one skip; the focused
72
+ title/subtitle run passed 22 tests. Subtitle Node tests passed 31 cases, including
73
+ explicit gradient-fill handling. Generated API limitations, read/write symmetry
74
+ and portable-agent assets/rules passed drift checks. The original synthetic
75
+ timeline and playhead were restored after the final live test.
76
+ Changes remain local; no release or publication was performed.
@@ -175,7 +175,7 @@ equivalent, blocking full automation.
175
175
 
176
176
  - **Object:** `TimelineItem / Timeline / Project`
177
177
  - **Behavior:** There is no API method to set or query subtitle font family, font size, text color, background color, outline, shadow, position, alignment, or to apply/query subtitle style presets. Older probes returned only transform/composite keys; a read-only Studio 21.1.0.17 probe returned an empty dict. Timeline.GetSetting() and Project.GetSetting() return None for all probed subtitle-style keys (e.g. 'subtitleFontName', 'subtitleFontSize', 'subtitleTextColor', 'subtitleBackgroundColor', 'subtitlePosition', 'subtitleAlignment', 'subtitlePreset', 'subtitleStyle'). Verified via dir(), GetProperty(), and GetSetting() on Resolve 21.0.0.48.
178
- - **Workaround / current handling:** No API workaround exists, but the style IS reachable below the API: it lives in Sm2TiTrack.FieldsBlob for Type=2 tracks, as an EffectFiltersBA payload whose effect 136 carries a Qt QFont descriptor (param 18) and a normalised position vector (param 17). Exposed as project_db list_subtitle_styles / set_subtitle_style (font family/size/weight/italic + position). Confirmed live on BOTH editions 2026-08-06 — Studio 19.1.3 and free 21.0.3, identical behaviour: Resolve opens a patched track and re-serialises it back to its own zstd form with the patched values intact, so it genuinely parses the write. Caveats: whole-TRACK style not per-caption, project must be CLOSED, Resolve must be fully quit and relaunched afterwards, and the track must already carry a style blob (a freshly added subtitle track has none until it is styled once in the UI). Burn-in overlays via Fusion titles remain a visual alternative but do not produce subtitle tracks. Animated Word Highlight is DIFFERENT: list_subtitle_styles may report styled:false while an animation is present. Sm2TiItem_Sm2TiTrack links a Sm2TiVideoClip holder via FusionCompHolderItems to a Sm2TiCompositionTable. The supplied Studio 21.1.0.17 reproduction verified cloning these three rows; local read-only inspection corroborated the format. Use list_subtitle_presets / copy_subtitle_preset, or set_subtitle_preset for named Word Highlight inputs inside the nested zlib tool section. These new actions check that Resolve is fully quit BEFORE writing. Holder Duration is preserved; its rendering semantics and per-caption preset layouts remain unverified.
178
+ - **Workaround / current handling:** No API workaround exists, but the style IS reachable below the API: it lives in Sm2TiTrack.FieldsBlob for Type=2 tracks, as an EffectFiltersBA payload whose effect 136 carries a Qt QFont descriptor (param 18) and a normalised position vector (param 17). Exposed as project_db list_subtitle_styles / set_subtitle_style (font family/size/weight/italic + position). Confirmed live on BOTH editions 2026-08-06 — Studio 19.1.3 and free 21.0.3, identical behaviour: Resolve opens a patched track and re-serialises it back to its own zstd form with the patched values intact, so it genuinely parses the write. Caveats: whole-TRACK style not per-caption, project must be CLOSED, Resolve must be fully quit and relaunched afterwards, and the track must already carry a style blob (a freshly added subtitle track has none until it is styled once in the UI). Burn-in overlays via Fusion titles remain a visual alternative but do not produce subtitle tracks. Animated Word Highlight is DIFFERENT: list_subtitle_styles may report styled:false while an animation is present. Sm2TiItem_Sm2TiTrack links a Sm2TiVideoClip holder via FusionCompHolderItems to a Sm2TiCompositionTable. The supplied Studio 21.1.0.17 reproduction verified cloning these three rows; local read-only inspection corroborated the format. Use list_subtitle_presets / copy_subtitle_preset, or set_subtitle_preset for named Word Highlight inputs inside the nested zlib tool section. These new actions check that Resolve is fully quit BEFORE database writing. For live Word Highlight effects instead use timeline_ai set_subtitle_preset: native DRT export, patch the exported holder, and native import as a recoverable timeline revision. On Studio 21.1.0.17/Windows (2026-10-08), colour, size and position changed visibly without quitting Resolve; clip/caption bounds and media IDs matched the original. This does not add a native subtitle setter or establish other effects/builds. Holder Duration is preserved; its rendering semantics and per-caption preset layouts remain unverified.
179
179
  - **Tags:** missing-method, subtitle, style, preset
180
180
 
181
181
  ### Speech recognition engine selection and SRT import
@@ -2,9 +2,9 @@
2
2
 
3
3
  # Read/Write Symmetry Audit
4
4
 
5
- - write-style action occurrences scanned: **126**
5
+ - write-style action occurrences scanned: **127**
6
6
  - write-style action occurrences with a matching read: **76**
7
- - distinct high-signal `set_` actions without a direct/known readback: **4**
7
+ - distinct high-signal `set_` actions without a direct/known readback: **5**
8
8
 
9
9
  ## High-signal gaps — `set_` with no direct/known readback
10
10
 
@@ -12,6 +12,7 @@
12
12
  - `set_high_priority`
13
13
  - `set_keyframe_interpolation`
14
14
  - `set_node_enabled`
15
+ - `set_subtitle_preset`
15
16
 
16
17
  ## Low-signal (create/add/insert/apply/import — usually expected): 45 distinct names
17
18
 
package/install.py CHANGED
@@ -37,7 +37,7 @@ from src.utils.update_check import (
37
37
 
38
38
  # ─── Version ──────────────────────────────────────────────────────────────────
39
39
 
40
- VERSION = "4.11.0"
40
+ VERSION = "4.12.0"
41
41
  # Only hard floor: mcp[cli] requires Python 3.10+. There is no upper bound —
42
42
  # Resolve's scripting bridge loads into newer interpreters on recent builds
43
43
  # (Python 3.14 verified against Resolve Studio 20.3.2). Older Resolve builds