davinci-resolve-mcp 2.88.0 → 2.90.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,149 @@
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 v2.90.0
6
+
7
+ AAF turnovers parsed by `editorial.parse_interchange` on the advanced server now
8
+ carry their animation curves, the transforms nobody had interpreted, and the
9
+ effects that occupy record time while emitting nothing. All three were losses a
10
+ consumer could not see, because the parse reported itself complete.
11
+
12
+ ### Added
13
+
14
+ - **Keyframe curves ship instead of the word "varying".** A `VaryingValue` was
15
+ read for its values alone, and only to answer "one number or more than one" —
16
+ `ControlPoint.time` was never asked for, so every animated reframe reached a
17
+ consumer as `"varying"`: enough to refuse the clip, never enough to rebuild
18
+ it. Transform stages now carry `keyframes[<AvidParamName>]` and retimes carry
19
+ `speedCurve.playRate` / `speedCurve.sourceOffset`, each with its interpolation
20
+ and its points as `{t, v, frame}`.
21
+ - **`domain` names which rule produced `frame`,** because the two curve families
22
+ do not share a time domain and a single conversion rule would have been wrong
23
+ by an effect's whole length on one of them. Measured over all 2047 control
24
+ points of an 878-event Avid picture turnover: transform params are normalized
25
+ over the effect span with the endpoint inclusive (`frame = t x (length - 1)`,
26
+ which lands 1243 of 1254 points on an integer frame against 278 under
27
+ `length`), while speed maps are already in frames. Keys outside `0..1` are
28
+ kept rather than clamped — 107 of 1254 sit before the first frame or past the
29
+ last, which is what Avid leaves when an animated clip is trimmed. A curve with
30
+ one unreadable point is refused whole; interpolating through a missing key
31
+ produces a confident wrong animation.
32
+ - **`passthrough` stages carry the four uninterpreted transform operations**
33
+ (SBlend_v2, Stabilize_2, MaskImage_2, 2DMatteKey_2) that were previously
34
+ discarded whole — 22 events on the fixture. Their numbers travel in
35
+ `rawParams`, deliberately not `params`: the same parameter *name* carries
36
+ different units on different operations (SBlend's `DVE_POS_X_U` runs to -315
37
+ where Stabilize's runs to -0.92 on the same show), so there is nothing to
38
+ normalize, and a 2DMatteKey `AFX_POS_X_U` of 500 promoted into `params` would
39
+ become a ~960px shift of a clip nobody repositioned.
40
+ - **`effectsWithoutEvents` closes a hole `unhandled` structurally cannot see.**
41
+ An effect can be modelled perfectly and still emit nothing — the group is
42
+ walked, its inputs are walked, and they contain no `SourceClip`. On the
43
+ fixture `unhandled` reads `{}` (a complete parse) while 29 SubCap titles
44
+ occupy real record time and reach the consumer as nothing whatsoever. Charged
45
+ once, to the innermost cause.
46
+ - **`speedRatioFromCurve`** — the rate the offset curve itself implies, emitted
47
+ only when that curve is straight, so no variable timewarp is ever averaged
48
+ into a single number.
49
+
50
+ ### Fixed
51
+
52
+ - **The declared AAF `SpeedRatio` rational is the source span truncated to whole
53
+ frames, and 7 of 18 constant retimes on the fixture disagree with their own
54
+ curve** — `201/112 = 1.794643` where the curve says `201.6/112 = 1.80`, and at
55
+ worst `31/19 = 1.631579` against a curve reading `1.70`, a 4% speed error in a
56
+ number an operator is handed to type in by hand. Every curve slope lands on a
57
+ rate an editor would actually dial (1.7, 1.8, 2.0, 0.75); every declared value
58
+ is that rate spoiled by rounding. Both ship under their own names and neither
59
+ is substituted for the other.
60
+ - **Variable timewarps are reconstructible.** The offset curve is dense (up to
61
+ 387 points at half-frame steps) and describes where every record frame reads
62
+ from, taking the 4 variable timewarps on the fixture from "flagged, rebuild
63
+ from nothing" to fully described — including one reverse ramp whose offset
64
+ runs 301.0 to -0.78. Reverse read off the curve agreed with the declared flag
65
+ 9 of 9, in both directions.
66
+
67
+ ### Validation
68
+
69
+ - Every pre-existing field is byte-identical on the fixture, verified by a
70
+ structural diff of the full 878-event parse against the previous output; event
71
+ count, `unhandled`, and all existing counters are unchanged.
72
+ - 10 new tests in `resolve-advanced/test/aaf-sequences.test.mjs`.
73
+ - No DaVinci Resolve scripting behavior changed; this is offline interchange
74
+ parsing, so no live Resolve validation was required.
75
+
76
+ ## What's New in v2.89.0
77
+
78
+ The build gates this server already enforced are now gates an agent can ask
79
+ about, and the capability probe those gates run on no longer lies. Issue #132,
80
+ reported by @magwa101.
81
+
82
+ ### Added
83
+
84
+ - **`get_version` reports what the connected build is missing.** A new `build`
85
+ block carries `unavailable_on_this_build` — every recorded API surface this
86
+ build does not have — plus `known_gates` and the caveat that an absence from
87
+ that list is not a promise a method exists. #132 happened in a session that
88
+ opened with `get_version` and was told a number and nothing the number ruled
89
+ out. `get_resolve_version_fields` gains the same list on the granular server.
90
+ - **The version-gate registry went from 7 recorded surfaces to 41.**
91
+ `_requires_method(obj, "GetLayoutPresetList", "21.0.4")` appears 44 times
92
+ across the two servers and gates 31 distinct symbols, but
93
+ `check_version_support` — the call `resolve-session` step 2 tells an agent to
94
+ make — answered from a ledger that knew seven of them. So the one question an
95
+ agent is instructed to ask returned `unknown` for surfaces this server was
96
+ already routing on. On Studio 19.1.3.7 the session preflight named 7 missing
97
+ surfaces; it now names 40. The new floors are labelled `documented` rather
98
+ than `measured`: they come from Blackmagic's release documentation, not a live
99
+ bisect here, and an agent relaying one should be able to say which.
100
+ - **`tests/test_version_gate_drift.py`** fails when a call site and the ledger
101
+ disagree, and when a bare method name is gated at two different builds on two
102
+ different classes (which would make a bare-name lookup a coin flip). A table
103
+ copied by hand is exactly what drifts back apart.
104
+ - **`src/utils/resolve_probe.py`** — `has_method` and `api_constant`, with the
105
+ measurement behind them. A companion guard fails the suite on a bare `hasattr`
106
+ with a Resolve-shaped attribute name.
107
+
108
+ ### Fixed
109
+
110
+ - **29 capability probes across `src/` used `hasattr` on Resolve API objects,
111
+ where it is a constant `True`** (measured on Studio 19.1.3.7 across 42 checks,
112
+ recorded in `api_truth`; re-confirmed live for this release —
113
+ `hasattr(project, 'GenerateSpeech')` returns `True` on a build that has no
114
+ such method). It failed in two shapes that look nothing alike:
115
+ - `if not hasattr(clip, "RemoveMotionBlur")` is a dead branch, so the
116
+ "requires Resolve 21+" refusal never fired and the call below it raised
117
+ `AttributeError` on an older build. Eleven of these were the granular
118
+ server's Resolve 21 AI guards.
119
+ - `getattr(r, n) if hasattr(r, n) else n` never reaches its `else`, so a build
120
+ without the constant got `None` where the author wrote a string fallback —
121
+ no exception, no refusal, just a `None` travelling on into `Export()`. This
122
+ reached granular timeline export and `ExportLUT`, and three constant
123
+ lookups on the compound server. Confirmed live: a name Resolve does not
124
+ define returned `None` under the old form and now falls back correctly.
125
+ The fallback keys on `is None`, not truthiness, because `EXPORT_AAF` is
126
+ genuinely `0.0`.
127
+ - **The granular AI tools reported a missing Extras pack as success.** Resolve's
128
+ AI methods return the reason as a *string* when the pack is absent, and
129
+ `bool("Required package ... is not installed.")` is `True`. The compound
130
+ server has normalized that since the 21.0.2.4 measurement; the granular one
131
+ had not, so folder and clip audio classification returned `{"success": true}`
132
+ for a call that did not run, and `RemoveMotionBlur` / `GenerateSpeech` walked
133
+ a string into `.GetName()`. All now route through `_ai_result`, which reports
134
+ the failure and carries Resolve's own reason.
135
+ - **`Project.ApplyFairlightPresetToCurrentTimeline` was recorded on `Timeline`.**
136
+ The shipped README lists it under Project and the server calls it there; the
137
+ method's name is what made the wrong attribution look right.
138
+
139
+ ### Validation
140
+
141
+ Suite 2560 → 2580. Live-checked against the running Studio 19.1.3.7 for the
142
+ probe semantics, the refusal path, the constant fallback, and the `get_version`
143
+ preflight (40 of 41 gates unavailable, as expected on that build). The Resolve 21
144
+ and 21.0.4 surfaces themselves remain untested here — this machine cannot run
145
+ them — and the Extras-pack failure paths are pinned by a stub that reproduces
146
+ the measured attribute-fabrication behaviour rather than by a live 21 build.
147
+
5
148
  ## What's New in v2.88.0
6
149
 
7
150
  The twelve Resolve 21.0.4 surfaces that only existed on the compound server now
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-2.88.0-blue.svg)](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
5
+ [![Version](https://img.shields.io/badge/version-2.90.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-34%20(353%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-2.88.0-blue.svg)](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
5
+ [![Version](https://img.shields.io/badge/version-2.90.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-34%20(353%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
- > 本翻译对应 v2.88.0 版 README。如与英文原版有出入,以 [英文原版](README.md) 为准。
15
+ > 本翻译对应 v2.90.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
@@ -489,7 +489,16 @@ you are on the correct page first.
489
489
  Key actions:
490
490
  - `launch` — connect to or start Resolve; call this first if any tool returns a
491
491
  "Not connected" error
492
- - `get_version` — returns `{product, version, version_string}`
492
+ - `get_version` — returns `{product, version, version_string, build, mcp}`.
493
+ `build.unavailable_on_this_build` lists every recorded API surface this build
494
+ does **not** have; read it before offering anything version-gated. An absence
495
+ from that list is not a promise a method exists — most of the API has never
496
+ been version-bisected, so `check_version_support` answers `unknown` for it,
497
+ and `unknown` means probe with `name in dir(obj)`, never bare `hasattr`
498
+ (constant `True` on Resolve objects)
499
+ - `check_version_support(symbol?, resolve_version?)` — is one named symbol on
500
+ this build? Without `symbol`, the same missing-surface list `get_version`
501
+ carries. No connection needed when `resolve_version` is passed
493
502
  - `api_truth(query?)` — look up behaviorally-verified facts about quirky/unreliable
494
503
  Resolve API behavior (no connection needed); filter by substring
495
504
  - `verification_stats` — readback-verification tally (verified/contradicted/
package/install.py CHANGED
@@ -36,7 +36,7 @@ from src.utils.update_check import (
36
36
 
37
37
  # ─── Version ──────────────────────────────────────────────────────────────────
38
38
 
39
- VERSION = "2.88.0"
39
+ VERSION = "2.90.0"
40
40
  # Only hard floor: mcp[cli] requires Python 3.10+. There is no upper bound —
41
41
  # Resolve's scripting bridge loads into newer interpreters on recent builds
42
42
  # (Python 3.14 verified against Resolve Studio 20.3.2). Older Resolve builds
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "davinci-resolve-mcp",
3
- "version": "2.88.0",
3
+ "version": "2.90.0",
4
4
  "description": "NPM bootstrapper for the DaVinci Resolve MCP Server.",
5
5
  "license": "MIT",
6
6
  "author": "Samuel Gursky <samgursky@gmail.com>",