davinci-resolve-mcp 2.135.0 → 2.136.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
@@ -66,8 +66,8 @@ semantics.
66
66
  - Public overview, current stats, and docs map: `README.md`
67
67
  - Historical release notes: `CHANGELOG.md`
68
68
  - AI assistant operating reference: `docs/SKILL.md`
69
- - Craft guidance for non-Claude-Code clients: the `knowledge` tool serves
70
- `.claude/skills/`, `docs/guides/`, and `docs/kernels/` as resolved prose over
69
+ - Craft guidance for remote clients: the `knowledge` tool serves
70
+ `.agents/skills/`, `docs/guides/`, and `docs/kernels/` as resolved prose over
71
71
  MCP. When you add a skill, guide, or kernel it is indexed automatically — a
72
72
  drift guard fails the suite if anything in those directories is unreachable
73
73
  - Release checklist and validation rules: `docs/process/release-process.md`
@@ -95,6 +95,12 @@ semantics.
95
95
  - Installer: `install.py`
96
96
  - Tests: `tests/`
97
97
  - Examples: `examples/`
98
+ - Portable agent assets: `.agents/skills/`, `.agents/roles/`, `.agents/hooks/`
99
+ - Client adapters: `.claude/` and `.codex/`. Skills are byte-identical in
100
+ `.claude/skills/` (edit either copy, then run
101
+ `scripts/agent-rules/sync_portable_assets.py`); hooks are canonical in
102
+ `.agents/hooks/` with thin shims; `.claude/agents/*` keep their frontmatter
103
+ (tools/model pins) over the shared `.agents/roles/*` bodies
98
104
 
99
105
  ## Common Commands
100
106
 
@@ -130,8 +136,10 @@ for Resolve scripting; 3.13/3.14 are accepted and verified on Resolve Studio
130
136
  Per-domain routers pair the live tools with their offline (advanced-server)
131
137
  counterparts. Every domain is available on demand in ANY MCP client as a slash
132
138
  prompt (`/color_grade_workflow`, `/timeline_edit_workflow`, `/conform_workflow`,
133
- `/delivery_workflow`, `/analyze_media`) and, in Claude Code, as a `.claude/skills/`
134
- skill. Full per-action depth lives in `docs/kernels/`.
139
+ `/delivery_workflow`, `/analyze_media`) and as canonical skills in
140
+ `.agents/skills/` (Claude Code loads content-complete `.claude/skills/` copies
141
+ kept byte-identical by `scripts/agent-rules/sync_portable_assets.py` and its
142
+ parity guard). Full per-action depth lives in `docs/kernels/`.
135
143
 
136
144
  - **Color / Grade** (`/color_grade_workflow`, skill `resolve-color`) — grading, correcting, shot matching, developing looks, or applying/modifying LUTs, CDLs, DRX grades, or copied grades. Live: timeline_item_color. Offline: drx. Depth: docs/kernels/color-grade-kernel.md + docs/guides/color-decision-guide.md.
137
145
  - **Timeline Edit** (`/timeline_edit_workflow`, skill `resolve-edit`) — cutting, trimming, pacing, duplicating/moving clips, copying ranges, building variants, tightening a cut, or generating an editorial changelist. Live: timeline. Offline: editorial. Depth: docs/kernels/timeline-edit-kernel.md + docs/guides/editorial-decision-guide.md.
package/docs/README.md CHANGED
@@ -41,57 +41,63 @@ ignored scratch folders such as `docs/_scratch/`.
41
41
  - [Project Lifecycle](kernels/project-lifecycle-kernel.md)
42
42
  - [Extension Authoring](kernels/extension-authoring-kernel.md)
43
43
 
44
- ## Claude Code Skills
45
-
46
- Per-domain skills in `.claude/skills/` route craft ↔ live tools ↔ offline
47
- advanced tools automatically when an agent works in that domain. They are thin
48
- bridges the authoritative depth stays in the kernels and guides above.
49
-
50
- - `resolve-mcp` (`.claude/skills/resolve-mcp/SKILL.md`) orientation/index: the map to the domain skills below (self-trigger; not an auto-loader)
51
- - `resolve-color` (`.claude/skills/resolve-color/SKILL.md`) grading, looks, shot match, LUT/CDL/DRX
52
- - `resolve-edit` (`.claude/skills/resolve-edit/SKILL.md`) cutting, ranges, variants, changelist
53
- - `resolve-conform` (`.claude/skills/resolve-conform/SKILL.md`) conform, relink, finishing QC, grade tracing
54
- - `resolve-delivery` (`.claude/skills/resolve-delivery/SKILL.md`) — render, deliverable QC, media/provenance
55
- - `resolve-fusion` (`.claude/skills/resolve-fusion/SKILL.md`) Fusion comps (titles, motion graphics, VFX)
56
- - `resolve-audio` (`.claude/skills/resolve-audio/SKILL.md`) audio/Fairlight tracks, buses, loudness, sync
57
- - `resolve-media-pool` (`.claude/skills/resolve-media-pool/SKILL.md`) media pool ingest, organize, multicam
58
- - `resolve-media-analysis` (`.claude/skills/resolve-media-analysis/SKILL.md`) source-safe media intelligence
59
-
60
- Each skill is a directory containing `SKILL.md`. Claude Code does not discover
61
- loose `.md` files in `.claude/skills/`; a skill placed at the top level of that
62
- directory silently never loads.
44
+ ## Portable Agent Skills
45
+
46
+ Per-domain skills in `.agents/skills/` route craft ↔ live tools ↔ offline
47
+ advanced tools automatically when an agent works in that domain. This is the
48
+ canonical, client-neutral source. Codex discovers it directly; Claude Code loads
49
+ `.claude/skills/` copies that are CONTENT-COMPLETE and byte-identical to the
50
+ canonical filesClaude routes on the frontmatter description at selection
51
+ time, so a pointer stub would degrade skill routing. Edit either copy, then run
52
+ `scripts/agent-rules/sync_portable_assets.py`; the parity guard
53
+ (`tests/test_portable_asset_parity.py`) fails the suite on drift.
54
+
55
+ - `resolve-mcp` — orientation/index: the map to the domain skills below (self-trigger; not an auto-loader)
56
+ - `resolve-color` — grading, looks, shot match, LUT/CDL/DRX
57
+ - `resolve-edit` — cutting, ranges, variants, changelist
58
+ - `resolve-conform` — conform, relink, finishing QC, grade tracing
59
+ - `resolve-delivery` — render, deliverable QC, media/provenance
60
+ - `resolve-fusion` Fusion comps (titles, motion graphics, VFX)
61
+ - `resolve-audio` audio/Fairlight tracks, buses, loudness, sync
62
+ - `resolve-media-pool` media pool ingest, organize, multicam
63
+ - `resolve-media-analysis` — source-safe media intelligence
64
+
65
+ Each canonical skill is a directory containing `SKILL.md`. The Claude adapter
66
+ uses the same directory shape because Claude Code does not discover loose files.
63
67
 
64
68
  Two end-to-end assembly recipes sit alongside the domain skills. Where a domain
65
69
  skill routes, these two walk a whole job:
66
70
 
67
- - `resolve-rough-cut` (`.claude/skills/resolve-rough-cut/SKILL.md`) — **additive**:
71
+ - `resolve-rough-cut` — **additive**:
68
72
  select shots from a folder of many clips into an assembled timeline.
69
- - `resolve-tighten-recording` (`.claude/skills/resolve-tighten-recording/SKILL.md`)
73
+ - `resolve-tighten-recording`
70
74
  — **subtractive**: remove dead air from one long single-take recording.
71
75
 
72
76
  Three more sit outside the domain routing:
73
77
 
74
- - `house-style` (`.claude/skills/house-style/SKILL.md`) — accumulated editorial
75
- corrections, so the same note is not given twice. Claude-only; append to it
78
+ - `house-style` — accumulated editorial
79
+ corrections, so the same note is not given twice. Append to it
76
80
  when an editorial decision is corrected.
77
- - `resolve-session` (`.claude/skills/resolve-session/SKILL.md`) — `/resolve-session`
81
+ - `resolve-session` — `/resolve-session`
78
82
  connects, confirms edition and bridge, and reports project/timeline/pool state.
79
- - `release-check` (`.claude/skills/release-check/SKILL.md`) — `/release-check`
83
+ - `release-check` — `/release-check`
80
84
  walks a version bump using [docs/process/release-process.md](process/release-process.md)
81
85
  as the sole source; the skill wraps that doc, it does not duplicate it.
82
86
 
83
87
  The offline half of every one is the advanced server; see
84
88
  [Advanced Server](../resolve-advanced/README.md).
85
89
 
86
- ## Claude Code Hooks and Subagents
90
+ ## Portable Hooks and Reviewers
87
91
 
88
- Four hooks live in `.claude/hooks/` — two `PreToolUse` guards enforcing rules
89
- `AGENTS.md` states in prose, and two `PostToolUse` checks that surface
90
- engineering drift right after the edit that caused it instead of at the next
91
- test run. All four ship as scripts but are **not** wired up by default — the
92
- repository does not enable hooks on your behalf. Opt in by adding the block
93
- below to your own `.claude/settings.local.json` (gitignored, so it stays
94
- yours):
92
+ Four canonical hooks live in `.agents/hooks/` — two `PreToolUse` guards
93
+ enforcing rules `AGENTS.md` states in prose, and two `PostToolUse` checks that
94
+ surface engineering drift immediately after the edit that caused it. Thin
95
+ wrappers in `.claude/hooks/` and `.codex/hooks/` translate only the host
96
+ protocol; policy stays in the canonical scripts.
97
+
98
+ Codex wiring is committed in `.codex/hooks.json`. Because project hooks execute
99
+ commands, review and trust that file through Codex's `/hooks` UI. Claude Code
100
+ users opt in by adding this block to `.claude/settings.local.json`:
95
101
 
96
102
  ```json
97
103
  {
@@ -139,18 +145,18 @@ yours):
139
145
  }
140
146
  ```
141
147
 
142
- Hooks are read at session start, so restart Claude Code after adding them. The
143
- four are:
148
+ Hooks are read at session start, so restart the client after enabling them. The
149
+ four canonical policies are:
144
150
 
145
- - `.claude/hooks/frame_verification_guard.py` — denies grade-applying actions on
151
+ - `.agents/hooks/frame_verification_guard.py` — denies grade-applying actions on
146
152
  `timeline_item_color` until the session has actually looked at a
147
153
  Resolve-rendered frame, and asks before whole-grade artifacts
148
154
  (`safe_copy_grade`, `bulk_match_to_hero`) overwrite hand-work. `dry_run`
149
155
  passes through untouched.
150
- - `.claude/hooks/source_media_guard.py` — denies shell commands that write,
156
+ - `.agents/hooks/source_media_guard.py` — denies shell commands that write,
151
157
  move, or delete source media outside a scratch root. Reads (`ffprobe`, and
152
158
  `ffmpeg` writing into scratch) pass.
153
- - `.claude/hooks/agent_rules_drift_check.py` — after an edit to anything
159
+ - `.agents/hooks/agent_rules_drift_check.py` — after an edit to anything
154
160
  `generate.mjs` reads (`docs/SKILL.md`, `docs/kernels/README.md`,
155
161
  `resolve-advanced/README.md`, and `generate.mjs` itself, which carries the
156
162
  DOMAINS manifest inline) or to `AGENTS.md`, which it writes, runs
@@ -160,7 +166,7 @@ four are:
160
166
  blocks. Skips quietly if `node` isn't on `PATH`. **If `generate.mjs` grows a
161
167
  new input, add it to `SOURCE_PATHS` in the hook** — an unwatched input is a
162
168
  silent hook on exactly the edit it exists to catch.
163
- - `.claude/hooks/run_matching_test.py` — after an edit to `src/<module>.py`,
169
+ - `.agents/hooks/run_matching_test.py` — after an edit to `src/<module>.py`,
164
170
  runs the matching `tests/test_<module>.py` if one exists, using the project
165
171
  venv (`venv/bin/python`) so `pytest` is actually importable. Informational
166
172
  only; skips quietly if there's no matching test file or no working `pytest`.
@@ -169,8 +175,13 @@ four are:
169
175
  for `src/server.py` or `src/granular/common.py`. Silence means "no matching
170
176
  test file", not "this edit is fine".
171
177
 
172
- Three review subagents in `.claude/agents/` run in their own context so bulky
173
- output (frame images, full test transcripts) stays out of the main session:
178
+ Codex does not currently support an interactive `ask` result from `PreToolUse`.
179
+ For the two whole-grade actions, its adapter adds a warning while the MCP
180
+ server's confirmation-token gate remains authoritative. Hard denials, including
181
+ missing frame evidence and source-media writes, block in both clients.
182
+
183
+ Three canonical reviewer roles live in `.agents/roles/`, with native Codex
184
+ definitions under `.codex/agents/` and Claude adapters under `.claude/agents/`:
174
185
 
175
186
  - `cut-reviewer` — screens an assembled timeline from its frames and reports on
176
187
  pacing, shot order, continuity, and coverage gaps.
package/docs/SKILL.md CHANGED
@@ -207,7 +207,7 @@ Operating rules an agent must know:
207
207
 
208
208
  Per-domain depth for both servers lives in the kernels (`docs/kernels/`), each of
209
209
  which carries an "Advanced (offline) server" section where an offline counterpart
210
- exists. Claude Code skills in `.claude/skills/` (`resolve-color`, `resolve-edit`,
210
+ exists. Portable skills in `.agents/skills/` (`resolve-color`, `resolve-edit`,
211
211
  `resolve-conform`, `resolve-delivery`, `resolve-media-analysis`) route
212
212
  craft ↔ live ↔ offline automatically when working in that domain.
213
213
 
@@ -38,7 +38,7 @@ two:
38
38
  - Timeline Edit → `editorial` (interchange + changelist), `drt`
39
39
 
40
40
  Per-domain Claude Code skills route craft ↔ live ↔ offline automatically and live
41
- in `.claude/skills/`: `resolve-color`, `resolve-edit`, `resolve-conform`,
41
+ in `.agents/skills/`: `resolve-color`, `resolve-edit`, `resolve-conform`,
42
42
  `resolve-delivery` (plus `resolve-media-analysis`). `docs/SKILL.md` is the
43
43
  top-level brief for both servers.
44
44
 
@@ -121,7 +121,7 @@ patches audio **offline, no Resolve running**:
121
121
 
122
122
  Rule of thumb: plan/measure offline, apply mix/track changes live; use
123
123
  `fairlight` for bus work the scripting API can't reach. See the `resolve-audio`
124
- skill (`.claude/skills/resolve-audio/SKILL.md`) and the `/audio_workflow` prompt.
124
+ skill (`.agents/skills/resolve-audio/SKILL.md`) and the `/audio_workflow` prompt.
125
125
 
126
126
  ## Live Probe
127
127
 
@@ -156,7 +156,7 @@ Cross-server rules an agent must know:
156
156
  - **Deps.** The grading catalog needs `sharp`; call the advanced `capabilities`
157
157
  tool for live status and install hints.
158
158
 
159
- See the `resolve-color` skill (`.claude/skills/resolve-color/SKILL.md`) for the
159
+ See the `resolve-color` skill (`.agents/skills/resolve-color/SKILL.md`) for the
160
160
  craft ↔ live ↔ offline routing and the frame-first rule.
161
161
 
162
162
  ## Live Probe
@@ -119,7 +119,7 @@ running**, via the `fusion` tool:
119
119
  Rule of thumb: author and verify the comp offline, then apply it live with
120
120
  `fusion_comp` `safe_add_tool` → `safe_set_inputs` → `safe_connect_tools` (the
121
121
  `to_api_calls` output maps directly onto those). See the `resolve-fusion` skill
122
- (`.claude/skills/resolve-fusion/SKILL.md`) and the `/fusion_workflow` prompt.
122
+ (`.agents/skills/resolve-fusion/SKILL.md`) and the `/fusion_workflow` prompt.
123
123
 
124
124
  ## Live Probe
125
125
 
@@ -137,7 +137,7 @@ actions):
137
137
  Rule of thumb: verify and inventory the card offline *before* importing, then
138
138
  import/organize live. `media` also serves the delivery side (see the
139
139
  `resolve-delivery` skill). See the `resolve-media-pool` skill
140
- (`.claude/skills/resolve-media-pool/SKILL.md`) and the `/media_pool_workflow` prompt. Never
140
+ (`.agents/skills/resolve-media-pool/SKILL.md`) and the `/media_pool_workflow` prompt. Never
141
141
  rename or derive camera originals without explicit approval.
142
142
 
143
143
  ## Live Evidence
@@ -135,7 +135,7 @@ Rules an agent must know:
135
135
  - **Deps.** `deliverable`/`media` QC needs **ffmpeg + ffprobe on PATH** (GPL, not
136
136
  bundled) — call the advanced `capabilities` tool for status + install hints.
137
137
 
138
- See the `resolve-delivery` skill (`.claude/skills/resolve-delivery/SKILL.md`) for the
138
+ See the `resolve-delivery` skill (`.agents/skills/resolve-delivery/SKILL.md`) for the
139
139
  craft ↔ live ↔ offline routing.
140
140
 
141
141
  ## Live Evidence
@@ -160,7 +160,7 @@ Gotchas the live path shares:
160
160
  - **Deps.** `better-sqlite3` gates lineage/reverse/DB; `sharp`/ffmpeg gate frame
161
161
  compare — call the advanced `capabilities` tool.
162
162
 
163
- See the `resolve-conform` skill (`.claude/skills/resolve-conform/SKILL.md`) for the
163
+ See the `resolve-conform` skill (`.agents/skills/resolve-conform/SKILL.md`) for the
164
164
  craft ↔ live ↔ offline routing.
165
165
 
166
166
  ## Live Probe
@@ -196,7 +196,7 @@ Use these to answer "what changed between v3 and v4" or to hand a conform an
196
196
  accurate change list without opening either timeline. For conforming/relinking
197
197
  that change list, see the Timeline Conform / Interchange kernel and the
198
198
  `resolve-conform` skill; for the edit ↔ offline routing, see the `resolve-edit`
199
- skill (`.claude/skills/resolve-edit/SKILL.md`).
199
+ skill (`.agents/skills/resolve-edit/SKILL.md`).
200
200
 
201
201
  ## Development Guardrails
202
202
 
package/install.py CHANGED
@@ -37,7 +37,7 @@ from src.utils.update_check import (
37
37
 
38
38
  # ─── Version ──────────────────────────────────────────────────────────────────
39
39
 
40
- VERSION = "2.135.0"
40
+ VERSION = "2.136.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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "davinci-resolve-mcp",
3
- "version": "2.135.0",
3
+ "version": "2.136.0",
4
4
  "description": "NPM bootstrapper for the DaVinci Resolve MCP Server.",
5
5
  "license": "MIT",
6
6
  "author": "Samuel Gursky <samgursky@gmail.com>",
@@ -24,7 +24,8 @@ cannot drift.
24
24
  | Platform | File(s) | Trigger | Source |
25
25
  |---|---|---|---|
26
26
  | Codex / OpenCode / Zed / others | `AGENTS.md` (`## Domain Routing` block) | always-on | generated block |
27
- | Claude Code | `.claude/skills/<name>/SKILL.md` | semantic (description) | hand-authored (rich) |
27
+ | Codex and compatible agents | `.agents/skills/<name>/SKILL.md` | semantic (description) | hand-authored canonical skill |
28
+ | Claude Code | `.claude/skills/<name>/SKILL.md` | semantic (description) | thin adapter to canonical skill |
28
29
  | Cursor | `.cursor/rules/*.mdc` | `alwaysApply` repo rule + per-domain `description` (agent-requested) | generated |
29
30
  | VS Code / Copilot | `.github/copilot-instructions.md` + `.github/instructions/*.instructions.md` | always-on + `applyTo` | generated |
30
31
  | Windsurf | `.windsurf/rules/*.md` + `.windsurfrules` | rules dir + legacy flat | generated |
@@ -33,8 +34,9 @@ cannot drift.
33
34
  | Continue | `.continue/rules/resolve-mcp.md` | always-on | generated |
34
35
  | Claude Desktop | — (chat client, no repo rules) | — | MCP prompts only |
35
36
 
36
- `.claude/skills/*` stays hand-authored (Claude's rich semantic skills). Each
37
- one is a **directory** holding a `SKILL.md` named for its frontmatter `name`;
37
+ `.agents/skills/*` stays hand-authored as the canonical rich skill source.
38
+ `.claude/skills/*` contains only compatibility adapters. Each skill is a
39
+ **directory** holding a `SKILL.md` named for its frontmatter `name`;
38
40
  a loose `.md` at the top level of `.claude/skills/` is never discovered and
39
41
  fails silently. Every
40
42
  other file is generated. `AGENTS.md` remains the universal backstop for any
@@ -65,7 +67,7 @@ node scripts/agent-rules/generate.mjs --check # exit 1 if anything is stale (C
65
67
 
66
68
  - **New domain:** add an entry to `DOMAINS` in `generate.mjs`, add a matching
67
69
  `@mcp.prompt` in `src/server.py`, and (optionally) a rich
68
- `.claude/skills/<name>/SKILL.md`. Regenerate.
70
+ `.agents/skills/<name>/SKILL.md` and add/update its client adapter. Regenerate.
69
71
  - **New platform:** add an `emit(...)` for its convention in `generate.mjs`,
70
72
  reusing `domainBody(d)` / `repoHygiene`. Regenerate. Do not hand-edit generated
71
73
  files — the drift guard will fail.
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env python3
2
+ """Sync the portable agent assets (`.agents/`) with their Claude adapters.
3
+
4
+ The layout contract (adapted from PR #173):
5
+
6
+ - `.agents/skills/*/SKILL.md` is the canonical, host-neutral skill corpus —
7
+ the `knowledge` MCP tool serves it, and non-Claude hosts read it directly.
8
+ - `.claude/skills/*/SKILL.md` is a CONTENT-COMPLETE copy, byte-identical to
9
+ the canonical file. Claude Code routes on the frontmatter description at
10
+ selection time, so the adapter must carry the full text — a pointer stub
11
+ would cost a read per invocation and hide the trigger phrasing.
12
+ - `.agents/roles/*.md` is the body (frontmatter stripped) of the matching
13
+ `.claude/agents/*.md`. The Claude file keeps its frontmatter — name,
14
+ description, tools, and the deliberate `model:` pin — which host-neutral
15
+ role files cannot carry.
16
+ - `.agents/hooks/*.py` is canonical executable logic; `.claude/hooks` and
17
+ `.codex/hooks` are thin runpy shims (execution-only surfaces need no
18
+ content duplication).
19
+
20
+ Edit EITHER side of a skill (they are identical); edit `.claude/agents` for
21
+ roles. Then run this script to restore the invariant:
22
+
23
+ venv/bin/python scripts/agent-rules/sync_portable_assets.py # write
24
+ venv/bin/python scripts/agent-rules/sync_portable_assets.py --check # verify only
25
+
26
+ `tests/test_portable_asset_parity.py` fails the suite when the invariant is
27
+ broken, so drift cannot land.
28
+ """
29
+
30
+ from __future__ import annotations
31
+
32
+ import argparse
33
+ import re
34
+ import sys
35
+ from pathlib import Path
36
+
37
+ REPO = Path(__file__).resolve().parents[2]
38
+ CLAUDE_SKILLS = REPO / ".claude" / "skills"
39
+ AGENT_SKILLS = REPO / ".agents" / "skills"
40
+ CLAUDE_AGENTS = REPO / ".claude" / "agents"
41
+ AGENT_ROLES = REPO / ".agents" / "roles"
42
+
43
+ _FRONTMATTER_RE = re.compile(r"^---\n.*?\n---\n\n?", re.S)
44
+
45
+
46
+ def strip_frontmatter(text: str) -> str:
47
+ m = _FRONTMATTER_RE.match(text)
48
+ return text[m.end():] if m else text
49
+
50
+
51
+ def skill_pairs():
52
+ names = sorted(
53
+ {p.parent.name for p in CLAUDE_SKILLS.glob("*/SKILL.md")}
54
+ | {p.parent.name for p in AGENT_SKILLS.glob("*/SKILL.md")}
55
+ )
56
+ for name in names:
57
+ yield name, CLAUDE_SKILLS / name / "SKILL.md", AGENT_SKILLS / name / "SKILL.md"
58
+
59
+
60
+ def role_pairs():
61
+ names = sorted(
62
+ {p.stem for p in CLAUDE_AGENTS.glob("*.md")} | {p.stem for p in AGENT_ROLES.glob("*.md")}
63
+ )
64
+ for name in names:
65
+ yield name, CLAUDE_AGENTS / f"{name}.md", AGENT_ROLES / f"{name}.md"
66
+
67
+
68
+ def run(check_only: bool) -> int:
69
+ problems: list[str] = []
70
+ for name, claude_p, agent_p in skill_pairs():
71
+ if not claude_p.exists():
72
+ problems.append(f"skill '{name}': canonical exists but .claude adapter is missing — it would never load in Claude Code")
73
+ if not check_only and agent_p.exists():
74
+ claude_p.parent.mkdir(parents=True, exist_ok=True)
75
+ claude_p.write_text(agent_p.read_text())
76
+ continue
77
+ src = claude_p.read_text()
78
+ if not agent_p.exists() or agent_p.read_text() != src:
79
+ problems.append(f"skill '{name}': .agents copy {'missing' if not agent_p.exists() else 'differs'}")
80
+ if not check_only:
81
+ agent_p.parent.mkdir(parents=True, exist_ok=True)
82
+ agent_p.write_text(src)
83
+ for name, claude_p, role_p in role_pairs():
84
+ if not claude_p.exists():
85
+ problems.append(f"role '{name}': .agents/roles exists but .claude/agents is missing — restore the frontmatter file by hand (it carries tools/model pins this script cannot invent)")
86
+ continue
87
+ body = strip_frontmatter(claude_p.read_text())
88
+ if not role_p.exists() or role_p.read_text() != body:
89
+ problems.append(f"role '{name}': .agents/roles {'missing' if not role_p.exists() else 'differs from the .claude/agents body'}")
90
+ if not check_only:
91
+ role_p.parent.mkdir(parents=True, exist_ok=True)
92
+ role_p.write_text(body)
93
+ if problems:
94
+ for p in problems:
95
+ print(("DRIFT: " if check_only else "SYNCED: ") + p)
96
+ return 1 if check_only else 0
97
+ print("portable assets in sync")
98
+ return 0
99
+
100
+
101
+ def main() -> int:
102
+ ap = argparse.ArgumentParser(description=__doc__)
103
+ ap.add_argument("--check", action="store_true", help="verify only; non-zero exit on drift")
104
+ args = ap.parse_args()
105
+ return run(check_only=args.check)
106
+
107
+
108
+ if __name__ == "__main__":
109
+ sys.exit(main())
@@ -87,7 +87,7 @@ if not logging.getLogger().handlers:
87
87
  handlers=[logging.StreamHandler()],
88
88
  )
89
89
 
90
- VERSION = "2.135.0"
90
+ VERSION = "2.136.0"
91
91
  logger = logging.getLogger("davinci-resolve-mcp")
92
92
  logger.info(f"Starting DaVinci Resolve MCP Server v{VERSION}")
93
93
  logger.info(f"Detected platform: {get_platform()}")
package/src/server.py CHANGED
@@ -11,7 +11,7 @@ Usage:
11
11
  python src/server.py --full # Start the 353-tool granular server instead
12
12
  """
13
13
 
14
- VERSION = "2.135.0"
14
+ VERSION = "2.136.0"
15
15
 
16
16
  import base64
17
17
  import os
@@ -545,8 +545,8 @@ def prep_color_handoff(output_dir: str = "") -> str:
545
545
  # ─── Per-domain workflow routers ───────────────────────────────────────────────
546
546
  # Cross-platform depth: these surface as slash commands in EVERY MCP client
547
547
  # (Codex, Cursor, Copilot, Continue, Claude Desktop, …), so per-domain routing is
548
- # not limited to Claude Code's .claude/skills/. They mirror the repo skills of the
549
- # same name; keep them in sync with docs/kernels/*.
548
+ # not limited to one client's adapters. They mirror the canonical `.agents/skills/`
549
+ # skills of the same name; keep them in sync with docs/kernels/*.
550
550
 
551
551
 
552
552
  @mcp.prompt(
@@ -2,7 +2,7 @@
2
2
 
3
3
  This repository carries a real body of craft guidance: how to tighten a recording
4
4
  without cutting the breath out of it, what to look at before applying a grade, which
5
- Resolve API calls silently lie. It lives in two places — `.claude/skills/*/SKILL.md`
5
+ Resolve API calls silently lie. It lives in two places — `.agents/skills/*/SKILL.md`
6
6
  and `docs/guides` + `docs/kernels` — and until now both were reachable only by an
7
7
  agent that could open files in this checkout.
8
8
 
@@ -57,7 +57,7 @@ from pathlib import Path
57
57
  from typing import Any, Dict, List, Optional, Tuple
58
58
 
59
59
  REPO_ROOT = Path(__file__).resolve().parents[2]
60
- SKILLS_DIR = REPO_ROOT / ".claude" / "skills"
60
+ SKILLS_DIR = REPO_ROOT / ".agents" / "skills"
61
61
  GUIDES_DIR = REPO_ROOT / "docs" / "guides"
62
62
  KERNELS_DIR = REPO_ROOT / "docs" / "kernels"
63
63
 
@@ -217,24 +217,10 @@ def _first_paragraph(body: str) -> str:
217
217
  def _title_of(body: str, fallback: str) -> str:
218
218
  for line in body.splitlines():
219
219
  if line.startswith("# "):
220
- # `# Resolve Tighten Recording — Claude Code Skill` is scaffolding for one
221
- # client. The subject is everything before the dash.
222
- title = line[2:].strip()
223
- return re.sub(r"\s*[—-]\s*Claude Code Skill\s*$", "", title).strip()
220
+ return line[2:].strip()
224
221
  return fallback
225
222
 
226
223
 
227
- def _strip_client_scaffolding(body: str) -> str:
228
- """Drop the one H1 that names a specific client. Prose is left alone."""
229
- return re.sub(
230
- r"^#\s+(.*?)\s*[—-]\s*Claude Code Skill\s*$",
231
- lambda m: f"# {m.group(1)}",
232
- body,
233
- count=1,
234
- flags=re.M,
235
- )
236
-
237
-
238
224
  _DOC_REF_RE = re.compile(r"`(docs/[^`\s]+\.md)`|\]\((docs/[^)\s]+\.md)\)")
239
225
 
240
226
 
@@ -275,7 +261,7 @@ def _build_index() -> Dict[str, Dict[str, Any]]:
275
261
  "summary": fields.get("description", "") or _first_paragraph(body),
276
262
  "category": "repo" if topic in _REPO_SKILLS else "workflow",
277
263
  "path": str(skill_md.relative_to(REPO_ROOT)),
278
- "body": _strip_client_scaffolding(body).strip(),
264
+ "body": body.strip(),
279
265
  }
280
266
 
281
267
  for category, directory in (("guide", GUIDES_DIR), ("kernel", KERNELS_DIR)):