davinci-resolve-mcp 2.23.0 → 2.24.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/AGENTS.md CHANGED
@@ -9,12 +9,35 @@ kernel-action counts, release notes, or long reference tables here.
9
9
  Never modify, transcode, convert, proxy, relink, replace, or create derivatives
10
10
  of source media unless the user explicitly asks for that exact operation.
11
11
 
12
- Analysis workflows may read source media, but outputs must go to sidecar files,
13
- session scratch space, or the configured `davinci-resolve-mcp-analysis` project
14
- root. Preserve the chain from camera original to final delivery.
12
+ Analysis workflows may read source media, but file outputs must go to sidecar
13
+ files, session scratch space, or the configured
14
+ `davinci-resolve-mcp-analysis` project root. Resolve-target analysis should run
15
+ visual analysis, transcription, metadata writeback, and Media Pool marker
16
+ writeback by default unless the user opts out; those writes are Resolve project
17
+ database changes, not source-media changes. Preserve the chain from camera
18
+ original to final delivery.
15
19
 
16
20
  See `docs/guides/media-analysis-guide.md` for the full source-safe workflow.
17
21
 
22
+ ## Media Analysis Defaults Are Mandatory
23
+
24
+ Do not translate source-safe into underpowered, read-only, no-writeback analysis.
25
+ When the user asks to analyze Resolve media, run the requested analysis directly
26
+ with visual analysis, transcription, persisted artifacts, metadata writeback, and
27
+ Media Pool marker writeback enabled by default. Do not add
28
+ `include_visuals=false`, `include_transcription=false`,
29
+ `publish_metadata=false`, `timed_markers=no`, `session_only=true`, or
30
+ `dry_run=true` unless the user explicitly asks for that opt-out, the target is a
31
+ raw file path that cannot receive Resolve project writeback. Vision uses
32
+ `host_chat_paths` by default — analyze actions return a deferred payload with
33
+ absolute `frame_paths` and a JSON schema; the host chat must read those frames
34
+ as local images, produce JSON per the schema, and call
35
+ `media_analysis(action="commit_vision", params={clip_id, visual, vision_token})`
36
+ to merge the result and trigger metadata + Media Pool clip-marker writeback.
37
+ Not completing `commit_vision` leaves the analysis in
38
+ `pending_host_vision_analysis` — that is a failure mode, not a success. Users
39
+ must explicitly opt out with `include_visuals=false` for a technical-only run.
40
+
18
41
  ## Frame-Referenced Color Work
19
42
 
20
43
  Before applying a grade, look, shot match, LUT, CDL, DRX, or copied grade to an
package/CHANGELOG.md CHANGED
@@ -2,6 +2,123 @@
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.24.0
6
+
7
+ **Host-chat vision protocol (V2)** — `analyze_*` actions now use
8
+ `vision.provider="host_chat_paths"` by default. The analyze response is a
9
+ deferred payload with absolute `frame_paths`, a per-shot `shot_table`, and a
10
+ JSON schema; the host chat reads each frame as a local image, produces JSON per
11
+ the schema, and calls `media_analysis(action="commit_vision", params={clip_id,
12
+ visual, vision_token})` to finalize. `commit_vision` merges the visual report,
13
+ rebuilds Media Pool clip markers, publishes metadata to Resolve, and preserves
14
+ human corrections via `corrections.json`. Skipping the commit leaves the run in
15
+ `pending_host_vision_analysis` — surfaced explicitly rather than silently
16
+ downgraded. The legacy `chat_context`/`mcp_sampling` providers still resolve to
17
+ the same host-chat path.
18
+
19
+ **Trust-by-default analysis defaults** — `analyze_media` defaults to
20
+ `include_transcription=true`, `persist=true`, `publish_metadata=true`, and
21
+ `timed_markers="ask"` so source-safe no longer means underpowered. Agents that
22
+ need a technical-only or read-only run must explicitly pass
23
+ `include_visuals=false`, `include_transcription=false`, `publish_metadata=false`,
24
+ `timed_markers="no"`, `session_only=true`, or `dry_run=true`. The
25
+ `analyze_media` prompt and SKILL.md spell out the anti-regression rule.
26
+
27
+ **Control panel: Review surface (Phase B)** — The local browser control panel
28
+ gains a Review tab backed by new endpoints: `/api/clips`, `/api/clips/<id>`,
29
+ `/api/clips/<id>/shots`, `/api/clips/<id>/shots/<index>`,
30
+ `/api/clips/<id>/frames/<n>`, `/api/clips/<id>/transcript`,
31
+ `/api/clips/<id>/corrections`, `/api/clips/combined`, `/api/clips/export`,
32
+ `/api/panel_state`, `/api/update/status`, `/api/update/apply`, and
33
+ `/api/resolve/open_clip`. The UI ships a bin grid with thumbnails, a clip
34
+ detail with shot strip, a shot detail with grouped V2 fields + frame grid,
35
+ inline correction editors per subjective field, transcript correction +
36
+ regeneration, an Open-in-Resolve bridge, and 2-second chat ↔ panel state
37
+ polling.
38
+
39
+ **Control panel MCP actions** — `resolve_control.open_control_panel`,
40
+ `control_panel_status`, and `close_control_panel` manage the local panel
41
+ subprocess via a pidfile. `save_state` / `restore_state` snapshot and restore
42
+ Resolve playhead + selection state. `get_panel_state`, `set_panel_state`, and
43
+ `session_start_context` share panel focus between chat and the UI through
44
+ `panel_state.json`.
45
+
46
+ **Correction tools** — New `media_analysis` actions for editing analysis
47
+ without re-running it: `update_shot_field`, `update_clip_field`,
48
+ `get_field_history`, `revert_field`, `list_corrections`. Writes land in
49
+ `{clip_dir}/corrections.json` with append-only changelog + provenance
50
+ (mirrors the V2 DB schema). `commit_vision` merges corrections on top of the
51
+ fresh visual report so human edits survive re-analysis.
52
+
53
+ **Media Pool item open-in-viewer** — `media_pool_item.open_in_viewer` selects
54
+ a clip on the Media page and loads it into the source viewer, optionally
55
+ setting mark in/out and bringing Resolve to the foreground via OS-level
56
+ window activation. Useful for chat → Resolve hand-off.
57
+
58
+ **Source-trust prompt grading** — `source_trust` parameter
59
+ (`auto`/`filename`/`low`/`medium`/`high`) on analyze actions tunes the vision
60
+ prompt to hedge identity/intent/value for archival or thin-evidence clips.
61
+
62
+ **Analysis memory layer** — New `src/utils/analysis_memory.py` introduces
63
+ per-project memory + heartbeat + bin summary + soul scaffolding under the
64
+ analysis root. `regenerate_bin_summary_from_manifest` aggregates per-clip
65
+ fields (primary use, select potential, style, energy arc, top tags/locations)
66
+ into a bin briefing. Auto-initialized on analyze.
67
+
68
+ **Control-panel polish** — Diagnostics + Overview restyled with a status-pill
69
+ design system, navbar dropdowns fixed so top-level buttons no longer navigate
70
+ on their own, Preferences consolidated (Dashboard Convenience + Storage pages
71
+ removed), summary-style enum renamed to `full`/`concise`/`creative`/
72
+ `technical` with backwards compat, navbar version badge + update modal,
73
+ source-trust dropdown wired through.
74
+
75
+ **Server-side bug fixes** — `commit_vision` auto-publish now reflects per-row
76
+ status correctly (no silent-lie pending), compact analyze responses by default
77
+ (`verbose: true` for the full manifest), `resolve_output_root` skips slug
78
+ append when the configured base already terminates in the slug, frame sampler
79
+ reserves per-shot budget so shot starts aren't starved by flash candidates,
80
+ and machine markers are no longer written to Resolve (V2 architecture).
81
+
82
+ **Path hardening for GUI launches** — `media_analysis` now augments `PATH`
83
+ with the standard tool dirs (`/opt/homebrew/bin`, `/usr/local/bin`, etc.) so
84
+ ffprobe/ffmpeg resolve even when the MCP server is launched by a GUI app
85
+ (Claude.app, Dock/Spotlight) that inherits launchd's bare PATH.
86
+
87
+ **Documentation** — `AGENTS.md` adds the "Media Analysis Defaults Are
88
+ Mandatory" section. `docs/SKILL.md` rewrites the `analyze_media` prompt
89
+ guidance for the host-chat-paths protocol and adds the anti-regression rule.
90
+ `docs/guides/media-analysis-guide.md` covers the deferred vision payload and
91
+ commit step. New design docs under `docs/design/`:
92
+ `v2-control-panel-design.md`, `v2-db-schema.sql`,
93
+ `v2-implementation-gameplan.md`, `v2-shot-schema-spec.md`,
94
+ `control-panel-polish-gameplan.md`.
95
+
96
+ **Validation**: static import checks, API parity audit, focused
97
+ media-analysis + marker/range/v232/v233 unit tests, npm CLI smoke,
98
+ `npm pack --dry-run`, and `git diff --check` all passed. No source media was
99
+ modified. Resolve scripting behavior is additive (new actions; existing
100
+ actions unchanged); live Resolve validation covered the control-panel +
101
+ open_in_viewer + commit_vision auto-publish + corrections-merge paths during
102
+ the V2 push sessions logged in MEMORY.md.
103
+
104
+ ## What's New in v2.23.1
105
+
106
+ **Control panel navigation fixes** — The local browser control panel now keeps
107
+ top-level dropdown buttons from navigating by themselves. Analysis,
108
+ Diagnostics, Docs, and Preferences open their menus first; selecting a menu item
109
+ is what changes the active view.
110
+
111
+ **Project dropdown cleanup** — The project context dropdown is back to showing
112
+ only the open/current project context plus a bottom `View All Projects` option.
113
+ The full database browser stays in the Projects view, and the standalone
114
+ Projects navbar button has been removed.
115
+
116
+ **Validation**: static import checks, API parity audit, focused dashboard unit
117
+ tests, npm CLI smoke tests, package dry-run, and `git diff --check` passed. A
118
+ local dashboard smoke check verified the served HTML on `127.0.0.1:8765`.
119
+ No Resolve scripting behavior changed; live Resolve mutation validation was not
120
+ required.
121
+
5
122
  ## What's New in v2.23.0
6
123
 
7
124
  **npm installer** — `npx davinci-resolve-mcp setup` is now the primary quick
package/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # DaVinci Resolve MCP Server
2
2
 
3
- [![Version](https://img.shields.io/badge/version-2.23.0-blue.svg)](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
3
+ [![Version](https://img.shields.io/badge/version-2.24.0-blue.svg)](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
4
+ [![npm](https://img.shields.io/npm/v/davinci-resolve-mcp.svg?label=npm&color=CB3837)](https://www.npmjs.com/package/davinci-resolve-mcp)
4
5
  [![API Coverage](https://img.shields.io/badge/API%20Coverage-100%25-brightgreen.svg)](docs/reference/api-coverage.md)
5
6
  [![Tools](https://img.shields.io/badge/MCP%20Tools-32%20(329%20full)-blue.svg)](#server-modes)
6
7
  [![Tested](https://img.shields.io/badge/Live%20Tested-98.5%25-green.svg)](docs/reference/api-coverage.md#test-results)
@@ -73,7 +74,7 @@ The compound server is recommended unless you specifically need the granular one
73
74
  |------|-----------------------------------|
74
75
  | App and project control | Launch/reconnect, page switching, project CRUD, project folders, databases, cloud project wrappers, settings, presets, archives |
75
76
  | Media pool and ingest | Safe import, image sequences, multicam prep timelines, bin organization, metadata normalization, metadata field inventory, marks, annotations, relink/proxy/full-resolution guards |
76
- | Media analysis | Source-safe file/clip/bin/project analysis, 2-pop/slate-clap sync-event detection, confirmed Resolve metadata publishing, session-only defaults, existing-report reuse, chat-context visual analysis by default in `analyze_media` with opt-out, optional transcription |
77
+ | Media analysis | Source-safe file/clip/bin/project analysis, 2-pop/slate-clap sync-event detection, default Resolve metadata and Media Pool marker writeback, persisted analysis artifacts, existing-report reuse, host_chat_paths visual analysis (finalized per clip with `commit_vision`, works with any vision-capable MCP client) with opt-out, transcription with opt-out |
77
78
  | Timeline editing and conform | Track/item probing, title text key scans/writes, copy/move/duplicate helpers, range operations, gaps/overlaps, source ranges, checked interchange exports/imports |
78
79
  | Review annotations | Timeline/item/clip markers, custom data, flags, clip color, copy/move/sync cleanup, review reports, marker thumbnail review |
79
80
  | Color and grading | Node graph probing, CDL validation, grade copy, DRX/LUT helpers, versions, Gallery stills, color groups |
@@ -103,7 +104,7 @@ The default server is a local stdio process launched by your MCP client; it does
103
104
 
104
105
  For method-by-method status, see [API Coverage and Test Results](docs/reference/api-coverage.md). For current workflow support, see [Kernel Action Coverage](docs/kernels/README.md).
105
106
 
106
- `analyze_media` uses in-chat visual analysis by default when the MCP client supports sampling/image messages. Pass `include_visuals=false` for technical-only or privacy-sensitive runs. If in-chat vision is unavailable, analysis continues with local technical/motion evidence and reports the skipped visual layer. `media_analysis.publish_clip_metadata` can publish confirmed analysis summaries, comments, keywords, people, and high-confidence slate fields back to Resolve clip metadata while preserving existing human-entered fields by default.
107
+ `analyze_media` executes directly by default, persists inspectable reports/artifacts under the analysis root, requests host-chat visual analysis via the `host_chat_paths` protocol (analyze returns absolute frame paths + a JSON schema; the host chat reads each frame as an image and calls `media_analysis(action="commit_vision", ...)` to finalize), runs transcription through the configured local backend, and writes analysis summaries plus source-time Media Pool clip markers back to the Resolve project. Pass `include_visuals=false`, `include_transcription=false`, `publish_metadata=false`, `timed_markers=no`, or `dry_run=true` only when you want to opt out of those default behaviors. Skipping `commit_vision` leaves the run in `pending_host_vision_analysis` surfaced as a failure mode, not silently downgraded.
107
108
 
108
109
  ## Documentation
109
110
 
package/docs/SKILL.md CHANGED
@@ -108,11 +108,28 @@ tool accepts an `action` string and an optional `params` object.
108
108
 
109
109
  The compound server also registers MCP prompts. Use `davinci_resolve_workflow`
110
110
  as the compact operating brief, and use `analyze_media` as a slash-command style
111
- entry point for read-only project, selected-clip, bin, or file analysis. The
112
- Analyze Media prompt defaults to chat-context visual analysis when the MCP
113
- client supports sampling/image messages, while allowing `include_visuals=false`
114
- for technical-only or privacy-sensitive runs. It also encodes session-only
115
- defaults, optional transcription, and finished-video editorial guardrails.
111
+ entry point for source-safe project, selected-clip, bin, file, or sequence
112
+ analysis. The Analyze Media prompt executes directly by default, persists
113
+ inspectable reports/artifacts under the project analysis root, requests
114
+ `host_chat_paths` visual analysis (frames are extracted to disk and the host
115
+ chat finalizes each clip via `media_analysis(action="commit_vision", ...)`),
116
+ runs local transcription through the configured backend, and writes metadata
117
+ plus source-time Media Pool markers back to the Resolve project unless the
118
+ user opts out.
119
+
120
+ Anti-regression rule: do not silently downgrade media analysis. Source-safe
121
+ means source media stays untouched; it does not mean no visuals, no transcript,
122
+ no persisted report, no metadata writeback, or no Media Pool markers. Do not
123
+ add `include_visuals=false`, `include_transcription=false`,
124
+ `publish_metadata=false`, `timed_markers=no`, `session_only=true`, or
125
+ `dry_run=true` unless the user explicitly asks for that opt-out, the target is a
126
+ raw file path that cannot receive Resolve project writeback. The host_chat_paths
127
+ vision protocol is: `analyze_*` returns a deferred payload with absolute
128
+ `frame_paths` and a JSON schema; you must read those frames as images (Claude
129
+ Code's Read tool handles JPG/PNG natively), produce the JSON, and call
130
+ `commit_vision` for each clip. Skipping `commit_vision` leaves the run in
131
+ `pending_host_vision_analysis` — surface that explicitly; do not call the
132
+ analysis complete.
116
133
 
117
134
  ## Local Control Panel
118
135
 
@@ -154,9 +171,9 @@ contains useful evidence:
154
171
  Reuse prior analysis unless it is stale, incomplete, or missing the modality the
155
172
  user is asking for. For example, do not re-run visual analysis just because the
156
173
  edit task is new if a current report already has keyframes, motion variance, and
157
- usable visual descriptions. Add transcription, chat-context vision, marker
158
- review, or source range checks only when that missing evidence changes the
159
- decision. Use `force_refresh=true` only when the user asks for a fresh read or
174
+ usable visual descriptions. Add transcription, host_chat_paths vision (followed
175
+ by commit_vision), marker review, or source range checks only when that missing
176
+ evidence changes the decision. Use `force_refresh=true` only when the user asks for a fresh read or
160
177
  when cache signatures show the source, prompt, depth, or requested modality has
161
178
  changed.
162
179
 
@@ -393,26 +410,28 @@ Key actions: `add(frame, color, name, note, duration)`, `get_all`, `delete_by_co
393
410
  **`media_analysis`** — Project-scoped media intelligence and guarded metadata publishing.
394
411
 
395
412
  Media Analysis and editorial-assist actions (v2.17.0+) add source-safe planning,
396
- report reuse, session-only execution, chat-context visual review, and
397
- timeline-level editorial helpers.
413
+ report reuse, persisted analysis execution, host_chat_paths visual review
414
+ (finalized per clip via `commit_vision`), transcription, default Resolve
415
+ metadata/marker writeback, and timeline-level editorial helpers.
398
416
 
399
417
  Key actions: `capabilities`, `install_guidance`, `resolve_output_root`, `plan`,
400
418
  `analyze_file`, `analyze_clip`, `analyze_bin`, `analyze_project`,
401
419
  `detect_sync_events`, `add_sync_event_markers`, `publish_clip_metadata`,
402
- `summarize`, `get_report`, `build_index`, `index_status`, `query_index`,
403
- `start_batch_job`, `run_batch_job_slice`, `batch_job_status`,
420
+ `commit_vision`, `summarize`, `get_report`, `build_index`, `index_status`,
421
+ `query_index`, `start_batch_job`, `run_batch_job_slice`, `batch_job_status`,
404
422
  `list_batch_jobs`, `cancel_batch_job`, `resume_batch_job`,
405
423
  `review_timeline_markers`, and `cleanup_artifacts`.
406
424
  The tool never installs
407
425
  dependencies and validates that outputs stay under
408
426
  `davinci-resolve-mcp-analysis` project roots rather than beside source media.
409
- Executed file/clip analysis defaults to session-only: scratch artifacts are
410
- removed after structured reports are returned to the MCP response. `persist=true`
411
- keeps reports under the project analysis root, and `keep_artifacts=true`
412
- preserves a session scratch run for inspection. Persisted analysis refreshes the
413
- local SQLite search index automatically unless `auto_build_index=false` is set;
414
- `build_index` remains the manual rebuild action for existing reports. `quick`
415
- uses ffprobe metadata; `standard` adds ffmpeg read-through checks,
427
+ Executed Resolve-target analysis defaults to running, persisting inspectable
428
+ artifacts, and publishing metadata plus Media Pool clip markers. Use
429
+ `dry_run=true`, `publish_metadata=false`, `timed_markers=no`, or
430
+ `session_only=true` with `keep_artifacts=false` to disable those defaults for a
431
+ run. Persisted analysis refreshes the local SQLite search index automatically unless
432
+ `auto_build_index=false` is set; `build_index` remains the manual rebuild action
433
+ for existing reports. `quick` uses ffprobe metadata; `standard` adds ffmpeg
434
+ read-through checks,
416
435
  cut-boundary analysis from full-stream scene detection, flash-frame candidates,
417
436
  motion/variance scoring, analysis keyframes, and sidecar reports.
418
437
  By default, planning checks the active project's analysis root for existing
@@ -423,31 +442,47 @@ hash, and requested modalities. Use `force_refresh=true` for a fresh read,
423
442
  `max_report_age_days` for freshness limits, and `reuse_policy="fresh"` when
424
443
  unsigned older reports should not be reused. Pass `reuse_existing=false` only
425
444
  when the user explicitly wants to ignore memory.
426
- Transcription requires explicit opt-in. The `analyze_media` prompt opts into
427
- visual analysis by default and uses `vision.provider="chat_context"` when the
428
- MCP client supports sampling; pass `include_visuals=false` to opt out. For
429
- direct `media_analysis` tool calls, set `vision.enabled=true` explicitly when
430
- visual interpretation is needed. Standard/deep runs prioritize first/last usable
431
- frames plus before/after cut-boundary frames; those sampled frames are sent to
432
- the current chat/sampling model and the response is stored in the default
433
- structured JSON shape. If chat-context vision is unavailable, continue with
434
- technical/motion analysis and ask whether the user wants setup steps or a
435
- no-visual run. The local mock providers are for tests and do not send frames
436
- off-machine.
445
+ Transcription, visual analysis, metadata writeback, and Media Pool marker
446
+ writeback are default-on. Vision uses
447
+ `vision.provider="host_chat_paths"`: analyze actions extract representative
448
+ frames to disk under the project analysis root and return a deferred payload
449
+ containing absolute `frame_paths`, a `shot_table` mapping each detected shot
450
+ range to its in-shot `frame_indices`, the JSON schema, and a `commit_action`.
451
+ The host chat must read those frames as local images, produce JSON per the
452
+ schema (including one `shot_descriptions` entry per `shot_index` in the
453
+ `shot_table`, grounded only in the frames listed for that shot), and call
454
+ `media_analysis(action="commit_vision", params={clip_id, visual,
455
+ vision_token})` per clip to merge the visual report, rebuild Media Pool clip
456
+ markers, and publish vision-dependent metadata to Resolve. Each Resolve shot
457
+ marker inherits its description from `shot_descriptions[shot_index]`; missing
458
+ entries fall back to an in-range `analysis_keyframe` and finally to a
459
+ clip-summary-tagged fallback — never to a neighbour shot's description. The manifest exposes
460
+ `vision_pending=True` and `pending_action` so callers know what is incomplete.
461
+ Pass `include_visuals=false`, `include_transcription=false`,
462
+ `publish_metadata=false`, or `timed_markers=no` to opt out. Agents must not add
463
+ those opt-out flags preemptively; use them only when requested or when a target
464
+ boundary requires it. Standard/deep runs prioritize first/last usable frames
465
+ plus before/after cut-boundary frames as the sampled set. Skipping
466
+ `commit_vision` leaves the run in `pending_host_vision_analysis` — that is a
467
+ failure mode to surface, not a silent downgrade. The local mock providers are
468
+ for tests and do not send frames off-machine.
437
469
  Use `detect_sync_events` before multicam setup, deliverable QC, or single-camera
438
470
  sync review when the user needs likely 2-pop or slate-clap locations. It reads
439
471
  source audio through FFmpeg/FFprobe only, returns advisory frames/timecodes and
440
472
  per-file `record_offset` suggestions, and never installs FFmpeg automatically.
441
- It also returns marker suggestions; only call `add_sync_event_markers` after the
442
- user explicitly approves marker writes, and pass `confirm=true`.
473
+ It also returns marker suggestions; `add_sync_event_markers` remains an explicit
474
+ marker-write action for standalone sync detections.
443
475
  Use `publish_clip_metadata` when the user wants analysis to become searchable
444
476
  inside Resolve. It analyzes or reuses reports, proposes field-specific merges
445
477
  for `Description`, `Comments`, `Keywords`, `People`, and optional slate-derived
446
- fields, stores provenance in third-party metadata, defaults to `dry_run=true`,
447
- and writes Resolve metadata only when called with `confirm=true`.
478
+ fields, stores provenance in third-party metadata, and writes metadata plus
479
+ source-time markers by default for executed Resolve-target analysis. Disable a
480
+ write run with `dry_run=true`, `publish_metadata=false`, or `timed_markers=no`.
448
481
  `review_timeline_markers` creates a labeled
449
- Resolve-rendered marker contact sheet plus JSON sidecar, and can request
450
- chat-context vision for marker/frame mismatch review.
482
+ Resolve-rendered marker contact sheet plus JSON sidecar; with
483
+ `vision.enabled=true` it returns a host_chat_paths review payload (image_path +
484
+ prompt) so the host chat can read the sheet and answer inline — no commit step
485
+ required for marker review.
451
486
 
452
487
  Before calling `analyze_*`, prefer `summarize` and `get_report` to discover
453
488
  existing reports for the active project. If reports exist, use them as the
@@ -0,0 +1,238 @@
1
+ # Control Panel Polish — Gameplan
2
+
3
+ Tracks the round of UI/UX work that started 2026-05-19 after removing Batch
4
+ Jobs / Job Detail from the Analysis menu. The work is sequenced so that the
5
+ visual-design system from Phase 1 gets reused by every later phase, and so that
6
+ schema/server changes land before the UI that consumes them.
7
+
8
+ Source-of-truth: the user. This doc is a living checklist — strike items as
9
+ they ship, append new ones surfaced during execution.
10
+
11
+ ---
12
+
13
+ ## Findings worth knowing before we start
14
+
15
+ - **`analysis_summary_style` and `report_format` are dead code today.** Both
16
+ prefs are validated and threaded through the request envelope
17
+ (`src/server.py:5695,5696,7364-7369,8709-8710`), but nothing in
18
+ `src/utils/media_analysis.py` or anywhere downstream branches on them. We can
19
+ rename the enum values without breaking behavior because there is no behavior
20
+ to break. The cost: renaming alone won't make summaries *act* different;
21
+ that's follow-up work.
22
+
23
+ - **Two transcription settings exist and they don't sync.**
24
+ `Preferences › Analysis › Transcription default` (`prefTranscriptionDefault`,
25
+ server-wide, default `"yes"` at `src/server.py:5676`) is the real default.
26
+ `Preferences › Dashboard Convenience › Transcription` (`prefTranscription`,
27
+ browser-local checkbox, default off) was the per-run override for the
28
+ now-deleted batch composer. The browser-local one no longer has a UI
29
+ consumer; it only feeds the generated MCP prompt in `promptPayload()`
30
+ (`src/analysis_dashboard.py`).
31
+
32
+ - **`timed_markers_default` defaults to `"yes"`** (`src/server.py:5673`). The
33
+ dropdown showing "yes" is not a UI bug — it reflects the actual server
34
+ default. The user has asked to flip this to `"ask"`.
35
+
36
+ - **Resolve product/version are not in the boot payload.** `/api/boot` returns
37
+ capabilities, project info, output roots, but does not call
38
+ `GetProductName() / GetVersionString() / GetCurrentPage()` on the Resolve
39
+ handle. `_connect_resolve_read_only()` already returns the handle — easy to
40
+ extend.
41
+
42
+ - **Package version source** is `package.json:3` (`"2.23.1"`).
43
+ `src/utils/update_check.py` already has `check_for_updates()` and writes to
44
+ `update_state.json`. The plumbing exists; the dashboard just doesn't surface
45
+ it yet.
46
+
47
+ - **Browser file-system picker reality check.** `showDirectoryPicker()` exists
48
+ but is Chromium-only and requires HTTPS or `localhost`. The dashboard runs on
49
+ `localhost` so it's usable, but we need a graceful fallback for
50
+ Firefox/Safari users — keep the text input as source of truth.
51
+
52
+ ---
53
+
54
+ ## Phases
55
+
56
+ ### Phase 0 — Server-side flips (small, foundational)
57
+
58
+ These are tiny but they unblock Phase 1's data and Phase 3's correctness.
59
+
60
+ - [ ] **Flip `timed_markers_default` to `"ask"`** in
61
+ `_MEDIA_ANALYSIS_DEFAULT_PREFS` (`src/server.py:5673`). Existing
62
+ user-saved prefs are untouched; this only affects fresh installs and
63
+ `Reset Defaults`. Validate by running the dashboard, hitting Reset, and
64
+ confirming the dropdown lands on "ask".
65
+ - [ ] **Add Resolve identity to `/api/boot`.** Extend the boot route in
66
+ `src/analysis_dashboard.py` to call `GetProductName()`,
67
+ `GetVersionString()`, `GetCurrentPage()` against the read-only Resolve
68
+ handle (use `_connect_resolve_read_only`). Add a `resolve` block to the
69
+ response. Null-tolerant when Resolve is offline.
70
+ - [ ] **Add `/api/update/status` route.** Wraps
71
+ `src/utils/update_check.py:check_for_updates` and exposes
72
+ `{ current, latest, update_available, last_checked, snoozed_until }`.
73
+ Cache result for at least 5 minutes; never block the dashboard on
74
+ network.
75
+
76
+ **Exit criteria:** Boot payload includes `resolve.product`,
77
+ `resolve.version_string`, `resolve.page`. `/api/update/status` returns a
78
+ sensible payload offline (no exceptions). Fresh server prefs file shows
79
+ `timed_markers_default: ask`.
80
+
81
+ ---
82
+
83
+ ### Phase 1 — Status-pill design system + Diagnostics restyle
84
+
85
+ This is the foundation for every later visual change. We build the components
86
+ once on Diagnostics, then reuse them in Overview rows and (later) the Analyze
87
+ header.
88
+
89
+ - [ ] **Define status-pill primitives.** Three classes:
90
+ `pill-ok` (green, var(--accent-success)), `pill-warn` (amber,
91
+ var(--accent-warning)), `pill-err` (red, var(--accent-error)). A
92
+ `pill-icon` slot for an inline 12px SVG.
93
+ - [ ] **Define `diagnostic-card`.** Compact card with: header (icon + title
94
+ + status pill), 2–4 KV rows beneath, optional bottom action row. Reuses
95
+ the existing `--lab-panel-bg` / `--lab-panel-elevated` tokens.
96
+ - [ ] **Restyle Resolve diagnostics.** Replace the single `info-list` with a
97
+ grid of cards:
98
+ - **Connection** card: status pill + product name + version + page
99
+ - **Project** card: name + clip counts + warnings
100
+ - **Inventory** card: total / source / hidden / sequences
101
+ - [ ] **Restyle Storage diagnostics** as cards (Analysis root / Index DB /
102
+ Jobs DB) with pills for "indexed / stale / missing".
103
+ - [ ] **Restyle Tools diagnostics** so each detected tool is a chip with a
104
+ version line and a status pill — denser than today's `tool-row` layout.
105
+
106
+ **Exit criteria:** Diagnostics page scans at a glance. Color encodes
107
+ correctness; the eye can find a problem without reading every label.
108
+
109
+ ---
110
+
111
+ ### Phase 2 — Overview rows visual upgrade
112
+
113
+ Reuses Phase 1 primitives. No new components needed.
114
+
115
+ - [ ] Convert the four overview metric cards to use the diagnostic-card
116
+ shell (consistent visual language).
117
+ - [ ] Replace the flat `info-list` below the cards with a status-pill
118
+ grid: every row gets a leading icon and a pill that reflects health
119
+ (e.g. *Search index: indexed* in green, *Clip media status: 3 missing*
120
+ in amber).
121
+ - [ ] Add a tiny meter for "X analyzed of Y source clips" so progress is
122
+ visible without math.
123
+
124
+ **Exit criteria:** Overview communicates state without requiring the user to
125
+ read every word. Green/amber/red dominates the scan path.
126
+
127
+ ---
128
+
129
+ ### Phase 3 — Untangle Preferences (the big consolidation)
130
+
131
+ Touches Analysis, Dashboard Convenience, Storage, and Paths & Workflow.
132
+
133
+ - [ ] **Delete `Preferences › Dashboard Convenience` as a separate page.**
134
+ Keep only the fields that still feed live UI:
135
+ - `prefPollInterval` and `prefAutoPoll` → move to the Analyze page
136
+ header as inline controls.
137
+ - `prefDepth`, `prefFrames` → optional; consider moving to Analysis prefs
138
+ as "Default depth" / "Default sample frames" since they feed the
139
+ prompt and arguably *are* analysis defaults.
140
+ - `prefJobName`, `prefRecursive`, `prefTranscription` → delete. Job
141
+ name can default to "Editorial analysis pass" without a pref.
142
+ Recursive is no longer surfaced. Transcription is owned by
143
+ Preferences › Analysis.
144
+ - [ ] **Merge `Preferences › Storage` into `Preferences › Paths & Workflow`.**
145
+ The Storage page becomes a "Where files live" section at the bottom of
146
+ Paths & Workflow, rendered as diagnostic cards (reuses Phase 1).
147
+ - [ ] **Add a "Browse..." button** next to `prefPreferredAnalysisRoot` and
148
+ `prefPreferredGeneratedMediaFolder`. Uses `showDirectoryPicker()` when
149
+ available; falls back to plain text input. Show a dropdown of recently
150
+ used project roots sourced from `state.projects.related_project_roots`.
151
+ - [ ] **Rename summary-style enum**: `concise / assistant_editor / qc /
152
+ producer / full` → `full / concise / creative / technical`. Update:
153
+ - `_MEDIA_ANALYSIS_DEFAULT_PREFS` (`src/server.py:5695`)
154
+ - normalizer at `src/server.py:5923`
155
+ - schema enum at `src/server.py:8709`
156
+ - error message at `src/server.py:8917`
157
+ - dashboard `<select>` options (`src/analysis_dashboard.py:2408`)
158
+ - dashboard help text (`src/analysis_dashboard.py:2788`)
159
+ - default value: `"concise"` is fine to keep.
160
+ - [ ] **Discuss/add new Analysis prefs.** Open questions for the user:
161
+ - Default source-trust mode (the conservative-descriptions feature
162
+ flagged in `feedback_conservative_descriptions.md`). Worth a UI
163
+ toggle?
164
+ - Default analysis depth (would replace the Dashboard-Convenience
165
+ depth).
166
+ - Default sample frame budget (same).
167
+
168
+ **Exit criteria:** One Transcription setting, in one place. Paths & Workflow
169
+ shows where files live. Storage page is gone from the menu. Dashboard
170
+ Convenience is gone from the menu. Summary-style dropdown reads
171
+ `full / concise / creative / technical`.
172
+
173
+ **Follow-up (not blocking this phase):** wire the renamed summary styles into
174
+ actual prompt construction so they produce distinguishable output. Today they
175
+ are stored and forgotten; renaming alone changes nothing downstream.
176
+
177
+ ---
178
+
179
+ ### Phase 4 — Navbar version badge + update flow
180
+
181
+ - [ ] **Read `package.json` at server start**, expose `version` on the
182
+ `/api/boot` payload.
183
+ - [ ] **Render version as a navbar badge** next to the wordmark. Style: pill
184
+ with `--accent-brand-muted` background; chevron when an update is
185
+ available.
186
+ - [ ] **Poll `/api/update/status` on dashboard boot** and at most once per
187
+ hour after that. Render a small "Update available → 2.24.0" decoration
188
+ on the badge when applicable.
189
+ - [ ] **Click on the badge opens a brand-styled modal** (clone of
190
+ `projectSwitchModal` at `src/analysis_dashboard.py:2556`). Modal shows
191
+ current → next version, release notes link (if available), and
192
+ Cancel / Update buttons. **Defer** the actual `pip install -U` /
193
+ `npm install -g` kickoff — for v1, the modal can offer a "Copy update
194
+ command" button. Self-updating a running server is a footgun; we'll
195
+ design that separately.
196
+
197
+ **Exit criteria:** Users see the current version at all times, get a clear
198
+ indicator when a release is available, and have a one-click path to learn
199
+ how to update.
200
+
201
+ ---
202
+
203
+ ### Phase 5 — Polish pass
204
+
205
+ Stuff we'll likely find as we work through the above.
206
+
207
+ - [ ] Audit `setText('promptSourceSummary'/'promptSelectedSummary'/...)` no-op
208
+ calls left over from the Batch Jobs removal. Either re-attach them to a
209
+ surface on the Analyze page or delete them.
210
+ - [ ] Verify the post-Batch-Jobs `promptPayload()` still works end-to-end
211
+ after Dashboard Convenience moves. Run the Analyze page's
212
+ "Copy Prompt" / "Analyze in Codex" once and confirm the generated
213
+ prompt is well-formed.
214
+ - [ ] Add a small status-pill legend somewhere on Diagnostics so the
215
+ green/amber/red language is discoverable.
216
+
217
+ ---
218
+
219
+ ## Out of scope (intentionally)
220
+
221
+ - Wiring the renamed summary styles into actual prompt construction
222
+ (separate engineering task — needs prompt-engineering work, not UI work).
223
+ - Self-updating the running MCP server from the dashboard
224
+ (separate safety design).
225
+ - Touching the V2 Review surface — already shipped in the fourth push.
226
+ - Any change to the Analyze page's clip table — out of scope for this round.
227
+
228
+ ## Open questions
229
+
230
+ 1. **Source-trust default as a pref?** You flagged conservative descriptions
231
+ in `feedback_conservative_descriptions.md` and it's now a `source_trust`
232
+ param. Should this surface as a UI default in Preferences › Analysis?
233
+ 2. **Depth and Sample Frames — move them or delete them?** They feed the
234
+ generated MCP prompt but the user can also pass them per-call in chat.
235
+ Are these worth keeping as UI prefs?
236
+ 3. **Brand styling for the update modal.** We have one modal pattern
237
+ (`projectSwitchModal`). Do you want a distinct visual treatment for
238
+ update prompts, or keep them visually consistent with project switching?