davinci-resolve-mcp 2.44.0 → 2.46.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,73 @@
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.46.0
6
+
7
+ Community PR bundle: five contributed fixes and features (#62–#66), live-validated
8
+ on Resolve Studio 21.
9
+
10
+ - **Fixed** timeline marker frames are now correctly relative to the timeline
11
+ start (#66): timecode params and the playhead default rebase by
12
+ `GetStartFrame()`, so markers on hour-start timelines land where the UI
13
+ shows them instead of an hour past the end. Raw `frame` params pass through
14
+ unchanged (documented as relative). Contact sheets and marker thumbnail
15
+ review rebase the other way with a legacy-absolute guard.
16
+ - **Fixed** project lint no longer flags audio-only timelines as empty (#62);
17
+ live lint state now reports per-type `video/audio/subtitle_item_count`.
18
+ - **Added** `media_pool.check_proxy_media_compatibility` (#63): ffprobe-vs-source
19
+ signature diagnostics (resolution/fps/frames/sample rate, expected
20
+ codec/profile). Same-aspect downscales count as compatible — half-res
21
+ proxies are the normal workflow.
22
+ - **Added** readback verification envelopes (`verified_operation`) around
23
+ `media_pool.link_proxy_checked` (#63) and `media_pool.append_to_timeline`
24
+ (#64): preflight, execution, post-state readback, verification status, and a
25
+ journal event. `link_proxy_checked` gains `check_compatibility` /
26
+ `require_compatible` guards that refuse incompatible proxies before linking.
27
+ - **Added** `bins` to declarative project specs (#65): missing media-pool bin
28
+ paths plan as `ensure` actions and are created idempotently; existing bins
29
+ are noops. Bin paths normalize to the `Master/` prefix so unprefixed spec
30
+ bins converge instead of reporting perpetual drift.
31
+
32
+ ## What's New in v2.45.0
33
+
34
+ The edit engine — Phase E, the final phase of the analysis + edit-engine
35
+ program. Three evidence-driven loops on one shared skeleton: evidence query
36
+ → dry-run plan with per-decision rationale → confirm token → versioned
37
+ timeline ops → metric readback → brain_edits rows.
38
+
39
+ - **Added** a new `edit_engine` MCP tool (compound tool count: 34):
40
+ - `plan_selects` / `execute_selects` — ranks shots by deep-tier
41
+ `editorial.select_potential` and best moments (clip-level fallback for
42
+ standard-analyzed clips), story-spine order, duration budget; execution
43
+ builds a NEW selects timeline from per-shot source ranges. Additive.
44
+ - `plan_tighten` / `execute_tighten` — dead-air lifts from transcript-gap
45
+ evidence per timeline item (no transcript → reported in `skipped`,
46
+ never silently trimmed); execution assembles a tightened VARIANT
47
+ timeline from keep ranges (true partial trims via the range-copy
48
+ kernel) — the original timeline is never mutated.
49
+ - `plan_swap` / `execute_swap` — alternates for a timeline item via the
50
+ visual-similarity index, filtered to shots that can fill the slot
51
+ exactly; execution replaces the item in place (lift + positioned
52
+ append) on the version-archived timeline.
53
+ - `list_plans` / `get_plan` — plans persist under `memory/edit_plans/`
54
+ with content fingerprints; a stale or tampered plan refuses to execute.
55
+ - **Added** `src/utils/edit_engine.py` (DB-only planning/evidence layer) and
56
+ `tests/live_edit_engine_validation.py` (disposable-project live harness).
57
+ execute_* actions are confirm-token gated and registered with the
58
+ version-on-mutate hook (archive + brain_edits come from the same
59
+ machinery as every other destructive op).
60
+ - **Fixed** frame→shot mapping in the analysis store: frames now fall back
61
+ to time-containment when a report's shots don't record
62
+ `frame_indices_used` (commit paths that omit it previously produced no
63
+ shot-level visual vectors).
64
+ - **Validation**: full offline suite (1118 tests; 13 new). Live pilot on a
65
+ disposable synthetic-media Resolve project (ffmpeg + spoken audio):
66
+ 20/20 checks — selects timeline assembled (2 decisions), tighten variant
67
+ removed exactly the 15.2s of transcript dead air while keeping the
68
+ spoken 4.8s (original untouched), swap replaced the item with a 0.92
69
+ cosine alternate, brain_edits rationale rows present for all three
70
+ loops, timeline versions archived.
71
+
5
72
  ## What's New in v2.44.0
6
73
 
7
74
  Cross-clip entities + bin briefing v2 — Phase D of the analysis +
package/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # DaVinci Resolve MCP Server
2
2
 
3
- [![Version](https://img.shields.io/badge/version-2.44.0-blue.svg)](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
3
+ [![Version](https://img.shields.io/badge/version-2.46.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
- [![Tools](https://img.shields.io/badge/MCP%20Tools-33%20(341%20full)-blue.svg)](#server-modes)
6
+ [![Tools](https://img.shields.io/badge/MCP%20Tools-34%20(341%20full)-blue.svg)](#server-modes)
7
7
  [![Tested](https://img.shields.io/badge/Live%20Tested-98.5%25-green.svg)](docs/reference/api-coverage.md#test-results)
8
8
  [![DaVinci Resolve](https://img.shields.io/badge/DaVinci%20Resolve-18.5+-darkred.svg)](https://www.blackmagicdesign.com/products/davinciresolve)
9
9
  [![Python](https://img.shields.io/badge/python-3.10+-green.svg)](https://www.python.org/downloads/)
@@ -49,7 +49,7 @@ The command starts a localhost server and opens the control panel in your browse
49
49
 
50
50
  | Mode | Entry point | Tools | Best for |
51
51
  |------|-------------|-------|----------|
52
- | Compound | `src/server.py` | 33 | Default mode for most assistants. Related Resolve operations are grouped behind action parameters to keep context usage low. |
52
+ | Compound | `src/server.py` | 34 | Default mode for most assistants. Related Resolve operations are grouped behind action parameters to keep context usage low. |
53
53
  | Full / granular | `src/server.py --full` or `src/resolve_mcp_server.py` | 341 | Power users who want one MCP tool per Resolve API method. |
54
54
 
55
55
  The compound server is recommended unless you specifically need the granular one-tool-per-method surface.
package/docs/SKILL.md CHANGED
@@ -671,6 +671,41 @@ only when that mutation is intentional.
671
671
 
672
672
  ### Timelines
673
673
 
674
+ **`edit_engine`** — Evidence-driven edit loops (v2.45.0+): selects assembly,
675
+ tighten, swap.
676
+
677
+ Every loop is plan → confirm → execute. plan_* actions are dry-run by
678
+ construction: they query the DB-canonical analysis store and return a
679
+ per-decision rationale plus a stored `plan_id` (plans persist under
680
+ `memory/edit_plans/` with a content fingerprint, so a stale plan cannot run
681
+ against a changed project). execute_* actions require a `confirm_token`, run
682
+ under the version-on-mutate hook, and return before/after duration and
683
+ clip-count readback plus `brain_edits` rationale rows.
684
+
685
+ - `plan_selects(min_select_potential?, max_duration_seconds?, max_shots?,
686
+ timeline_name?, analysis_root?)` — ranks shots by deep-tier
687
+ `editorial.select_potential` / best moments (clip-level fallback for
688
+ standard-analyzed clips), story-spine order.
689
+ `execute_selects(plan_id)` creates a NEW selects timeline from the plan's
690
+ per-shot source ranges — additive; nothing existing is touched.
691
+ - `plan_tighten(timeline_name?, target_ratio?, min_pause_seconds?,
692
+ handle_seconds?)` — dead-air lifts from transcript-gap evidence for each
693
+ timeline item (items without transcripts are reported in `skipped`, never
694
+ silently trimmed). `execute_tighten(plan_id)` assembles a tightened
695
+ VARIANT timeline from the plan's keep ranges — true partial trims; the
696
+ original timeline is never mutated.
697
+ - `plan_swap(timeline_start_frame | item_name, kind="visual"|"text",
698
+ limit?)` — alternates for one timeline item via the similarity index,
699
+ filtered to shots long enough to fill the slot exactly.
700
+ `execute_swap(plan_id, alternate_index)` replaces the item in place
701
+ (lift + positioned append at the same record frame) on the
702
+ version-archived timeline.
703
+ - `list_plans(limit?)` / `get_plan(plan_id)`.
704
+
705
+ The engine needs the analysis substrate: analyzed clips in the DB (run
706
+ `db_ingest` on older roots), transcripts for tighten, and visual embeddings
707
+ (`build_embeddings(kinds=['visual'])`) for swap.
708
+
674
709
  **`timeline_versioning`** — Version-on-mutate, archive, rollback, brain-edit history (C6).
675
710
 
676
711
  Every destructive timeline op (compound, captions, ripple delete, gap close,
package/install.py CHANGED
@@ -35,7 +35,7 @@ from src.utils.update_check import (
35
35
 
36
36
  # ─── Version ──────────────────────────────────────────────────────────────────
37
37
 
38
- VERSION = "2.44.0"
38
+ VERSION = "2.46.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.44.0",
3
+ "version": "2.46.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.44.0"
83
+ VERSION = "2.46.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()}")
@@ -461,7 +461,8 @@ def timeline_add_marker(frame_id: int, color: str, name: str, note: str = "", du
461
461
  """Add a marker to the current timeline.
462
462
 
463
463
  Args:
464
- frame_id: Frame number for the marker.
464
+ frame_id: Frame number for the marker, relative to the timeline start
465
+ (frame 0 = first frame, even when the timeline starts at 01:00:00:00).
465
466
  color: Marker color (Blue, Cyan, Green, Yellow, Red, Pink, Purple, Fuchsia, Rose, Lavender, Sky, Mint, Lemon, Sand, Cocoa, Cream).
466
467
  name: Marker name.
467
468
  note: Marker note. Default: empty.