davinci-resolve-mcp 2.61.0 → 2.62.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,110 @@
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.62.0
6
+
7
+ Community contribution by [@lukeashford](https://github.com/lukeashford)
8
+ ([#87](https://github.com/samuelgursky/davinci-resolve-mcp/pull/87), closing
9
+ [#88](https://github.com/samuelgursky/davinci-resolve-mcp/issues/88)): server
10
+ robustness for long operations plus a batch of timeline-tool ergonomics and
11
+ correctness fixes. Every new option is opt-in; default behavior is unchanged.
12
+
13
+ ### Added
14
+
15
+ - **Background jobs for long ops** — transcription, subtitle generation,
16
+ scene-cut/Dolby analysis, and timeline export/import can exceed the MCP
17
+ client's tool-window timeout. Passing `background=true` now returns a
18
+ `job_id` immediately; poll with `resolve_control(action="job_status")` or
19
+ list with `list_jobs` (both connection-free). Generic registry in
20
+ `src/utils/background_jobs.py`; workers run under the `resolve_busy` gate,
21
+ and finished jobs are pruned after an hour.
22
+ - **`create_variant_from_ranges` pack mode** — `pack=true` butts clips
23
+ together at the end of each track (omits `recordFrame`), gap-free even when
24
+ source and timeline frame rates differ. Live-validated.
25
+ - **`timeline set_current` by id/name** — accepts a stable `id`/`name`
26
+ selector (precedence id → name → index), not only the shifting 1-based
27
+ index.
28
+
29
+ ### Fixed
30
+
31
+ - **Transport wedge** — synchronous tool bodies ran inline on the single
32
+ asyncio event-loop thread, so a blocking Resolve call (or the up-to-60s
33
+ launch wait) froze the whole server including the stdio read loop. Sync tool
34
+ bodies now run in a worker thread, serialized on a bridge lock so the
35
+ single-threaded scripting bridge is never entered concurrently; degrades to
36
+ inline behavior if the SDK shape changes.
37
+ - **`create_variant_from_ranges` honesty** — results report actual placement
38
+ (`items[].placed` in both frame spaces, plus a `placement_mismatches`
39
+ count) instead of echoing the requested frames; `dry_run` resolves clip ids
40
+ and validates frame ranges so it fails on the same errors as the commit
41
+ path (and no longer leaves an orphan timeline on a bad id); the response
42
+ reports audio presence and warns on a video-only (silent) range list.
43
+ - **`get_items` / `get_items_in_track`** — validate their track selector
44
+ (structured error instead of a bare `KeyError`), accept `index` or
45
+ `track_index`, and gained `action_help` entries.
46
+ - **`apply_cuts`** — reports `skipped` cuts with reasons instead of silently
47
+ dropping non-applicable entries.
48
+ - **`action_help`** — lists every valid action (not only the documented
49
+ subset) and distinguishes an unknown action (`UNKNOWN_ACTION`) from a
50
+ valid-but-undocumented one (`HELP_NOT_REGISTERED`).
51
+
52
+ ### Documentation
53
+
54
+ - Corrected `create_variant_from_ranges` help: `clip_id` is a media-pool item
55
+ id (not a timeline-item id); `start_frame`/`end_frame` are SOURCE frames,
56
+ `end_frame` exclusive. Stated the timeline tool's frame-space convention
57
+ once, clarified `lift_range` ripple behavior on empty gaps,
58
+ `begin_run`/`end_run` batching, and the timeline-subtitle vs clip-level
59
+ transcript distinction.
60
+
61
+ ### Validation
62
+
63
+ - Full offline suite: 1,483 tests green (70 new).
64
+ - Transport offload, background jobs, and `create_variant_from_ranges`
65
+ placement/pack behavior were live-validated against Resolve Studio 21 by
66
+ the contributor; the threaded-dispatch SDK coupling was additionally
67
+ verified against the pinned mcp SDK (1.27) over a real stdio session.
68
+
69
+ ## What's New in v2.61.1
70
+
71
+ The strata cleanup batch deferred from the v2.61.0 review — behavior-neutral
72
+ consolidation and hot-path efficiency. No new actions or parameters.
73
+
74
+ ### Changed
75
+
76
+ - **One clip resolver** — `strata.resolve_clip()` replaces the four drifting
77
+ per-module wrappers, and rides the pre-v9 auto-ingest fallback hoisted out
78
+ of deep_vision into `analysis_store.resolve_clip_uuid_ingesting()`: a clip
79
+ ref that resolves for `deepen` now resolves identically for every strata
80
+ action, including on older analysis roots.
81
+ - **One float32 codec** — `pack_curve`/`unpack_curve` delegate to
82
+ `embeddings.pack_vector`/`unpack_vector` instead of duplicating the BLOB
83
+ convention.
84
+ - **Decode once** — `strata_run` decodes the media file a single time when
85
+ several audio analyzers run (prosody + beat_grid previously each ran a full
86
+ ffmpeg decode); the shared `_audio_context` preamble also collapses their
87
+ duplicated require/resolve/decode blocks.
88
+ - **Registry-derived capabilities** — `ANALYZERS` carries run function plus
89
+ requires/writes metadata; `capabilities()` derives from it, so adding an
90
+ analyzer is one entry.
91
+ - **Query-layer caching** — word-find hits clustering in one clip unpack each
92
+ curve blob once, and `timeline_strata` resolves + bundles a source clip
93
+ reused across many placements once.
94
+ - **Sargable event windows (schema v15)** — windowed `read_events` bounds its
95
+ span-overlap lower edge by the track's `MAX(duration_seconds)` (a b-tree
96
+ descent via the new `ix_events_clip_track_span` index) so
97
+ `ix_events_clip_track` range-seeks instead of scanning the track.
98
+ - `backfill_words` iterates report blobs lazily with a transcription
99
+ prefilter instead of loading every blob into memory; `detect_breaths`
100
+ drops its unreachable non-numpy fallbacks.
101
+
102
+ ### Validation
103
+
104
+ - Full offline suite: 1,431 tests green (13 new covering the shared resolver
105
+ + pre-v9 fallback, codec identity, decode-once, per-clip caching, long-span
106
+ window overlap, and the index range-seek query plan). No Resolve behavior
107
+ changed; live test not required.
108
+
5
109
  ## What's New in v2.61.0
6
110
 
7
111
  Perception strata — a timecoded track model over every analyzed clip, plus the
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # DaVinci Resolve MCP Server
2
2
 
3
- [![Version](https://img.shields.io/badge/version-2.61.0-blue.svg)](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
3
+ [![Version](https://img.shields.io/badge/version-2.62.0-blue.svg)](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
4
4
  [![npm](https://img.shields.io/npm/v/davinci-resolve-mcp.svg?label=npm&color=CB3837)](https://www.npmjs.com/package/davinci-resolve-mcp)
5
5
  [![API Coverage](https://img.shields.io/badge/API%20Coverage-100%25-brightgreen.svg)](docs/reference/api-coverage.md)
6
6
  [![Tools](https://img.shields.io/badge/MCP%20Tools-34%20(341%20full)-blue.svg)](#server-modes)
package/install.py CHANGED
@@ -35,7 +35,7 @@ from src.utils.update_check import (
35
35
 
36
36
  # ─── Version ──────────────────────────────────────────────────────────────────
37
37
 
38
- VERSION = "2.61.0"
38
+ VERSION = "2.62.0"
39
39
  # Only hard floor: mcp[cli] requires Python 3.10+. There is no upper bound —
40
40
  # Resolve's scripting bridge loads into newer interpreters on recent builds
41
41
  # (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.61.0",
3
+ "version": "2.62.0",
4
4
  "description": "NPM bootstrapper for the DaVinci Resolve MCP Server.",
5
5
  "license": "MIT",
6
6
  "author": "Samuel Gursky <samgursky@gmail.com>",
@@ -80,7 +80,7 @@ if not logging.getLogger().handlers:
80
80
  handlers=[logging.StreamHandler()],
81
81
  )
82
82
 
83
- VERSION = "2.61.0"
83
+ VERSION = "2.62.0"
84
84
  logger = logging.getLogger("davinci-resolve-mcp")
85
85
  logger.info(f"Starting DaVinci Resolve MCP Server v{VERSION}")
86
86
  logger.info(f"Detected platform: {get_platform()}")