resolvescript
The only resolve scripting framework out there.
Overview
Build, test, package and install DaVinci Resolve Python scripts and plugins: a small CLI with an npm-style workflow for the Resolve Scripts/ tree.
createscaffolds a project with amanifest.jsonand smoke testsdev/testrun against a mockDaVinciResolveScriptAPI - no Resolve neededbuildconsolidates the multi-file package into a single.pyfor distributionadd/install/updateresolve dependencies from GitHub, URLs, archives or local folders and record them inresolvescript.jsonpackageemitsdist/<name>-<version>.tar.gzplusSHA256SUMS.txtfuse/pluginscaffold, validate, build, package and install Fusion.fuseplugins and precompiled.pluginbinaries
Install with pip: pip install resolvescript (Python 3.9+).
| Aspect | Specification |
|---|---|
| Current version | v1.0.2 |
| Resolve support | DaVinci Resolve Free & Studio 18+ |
| License | MIT |
Quickstart
$ resolvescript create my-cool-tool
$ cd my-cool-tool
$ resolvescript dev # sandboxed dev loop against the mock API
$ resolvescript test # run the smoke tests
$ resolvescript build # single-file build -> dist/my_cool_tool.py
$ resolvescript analyze # static checks (imports, manifest, API usage)
$ resolvescript package # dist/my-cool-tool-1.0.2.tar.gz + SHA256SUMS.txt
# elsewhere, consume it:
$ resolvescript add github:example/my-cool-tool
$ resolvescript install # materialize all recorded deps into Resolve
Authoring
Directory
my-cool-tool/
manifest.json # project manifest (or manifest.xml)
my_cool_tool/ # your Python package (module name from manifest.name/python)
__init__.py
export.py
tests/
test_smoke.py
Commands
| Command | Purpose |
|---|---|
create <name> |
Scaffold a new project (--json/--xml, --template minimal|pydavinci|davinci-rest|lua|workflow|extension|fuse, --dir) |
dev |
Sandboxed dev loop / REPL against the mock Resolve API (--built for the consolidated file, --repl, --editor) |
test |
Run the project's pytest suite against the mock API (--built, -k pattern, --api-coverage) |
analyze |
Static checks: missing entrypoint/module, syntax, unused imports, unmocked API methods, attribute typing (--json) |
build |
Consolidate into a single file (--output, or the manifest consolidate.output) |
package |
Assemble dist/<name>-<version>.tar.gz + SHA256SUMS.txt (--dist DIR) |
add <spec> |
Resolve, install a dependency and record it (--no-save, --target, --scripts-root) |
install [<spec>] |
One-off install, local project, or materialize recorded deps (--locked, --dry-run) |
update [<name>] |
Re-resolve recorded deps within their ranges (--precise X.Y.Z, --fix) |
remove <name> |
Uninstall and unrecord (--no-save) |
search <query> |
Search the known sources table |
doctor |
Diagnose environment, project manifest and install registry (--json, --scripts-root) |
clean |
Clean project caches, build artifacts, and registry files (--dir, -v) |
manage list|remove |
Low-level registry operations (--json, --all) |
extensions add|remove|list |
Manage framework extensions (plugins) for the CLI itself (--force, --json) |
Exit codes: 0 ok, 1 error, 2 usage.
Specifiers
add / install <spec> accept:
name- a name from the built-in known-sources table (resolvescript search)owner/repoorgithub:owner/repo[#ref]- GitHub repo (ref = branch/tag/commit, or#semver:^1.2for a range)https://...tar.gz/.zip- direct archive URLhttps://...- a URL whose root carries amanifest.json(GitHub Pages-style hosting)file:path,./dir, an absolute path - local directory or archive.tar.gz/.zipfiles and local directories
Recorded specs live in resolvescript.json; use resolvescript install --locked for a CI/npm-ci style check that recorded artifacts still satisfy the recorded ranges.
Manifest reference
manifest.json (or manifest.xml, same shape):
{
"name": "my-cool-tool", // required
"version": "1.0.2", // required, semver
"author": "You",
"description": "...",
"python": "my_cool_tool", // package/module name (defaults to "name")
"entrypoint": "export.py", // recommended CLI/bootstrap module
"kind": "script", // "script" (default) | "extension" (plugin)
// | "workflow" (integration) | "fuse"
"targets": ["Comp"], // Scripts subfolders: Comp, Utility, Tool, Render,
// Deliver, Edit, WorkflowIntegrations, Fusion, root
"compat": { "resolve": "18.6.4", "python": "3.12" },
"release": { "owner": "you", "repo": "my-cool-tool" }, // for `add` discovery
"scripts_root": "", // per-OS override for the Resolve Scripts root
"consolidate": { "enabled": true, "output": "dist/my_tool.py", "exclude": [], "no_comment": [] },
"install": { "as_directory": true, "include": [], "exclude": [], "to": "resolve" },
"dependencies": ["github:example/dep"] // resolved on install
}
Install model
Installs drop into each OS's Resolve Scripts root under the manifest targets. Directories install as a single folder; .py-only packages can opt into install.as_directory: false multi-file installs. Every install is recorded in <ScriptsRoot>/.resolvescript/install.json (schema v1):
- keys are
<name>:<target>(directory) or<name>:<target>:<relpath>(file-based) - each entry carries
version,targets,as_directory,files,source,resolvedandintegrity install --lockedverifies registry entries against recorded specs before reusing them
--scripts-root (or RESOLVESCRIPT_SCRIPTS_ROOT) overrides OS detection.
Fusion fuses and plugins
Fuses and plugins ride the same manifest shape with "kind": "fuse" — one Lua
file Fusion compiles, or a precompiled binary Fusion loads:
$ resolvescript create Posterize --template fuse # scaffold the project
$ resolvescript fuse build # render, validate, write dist/
$ resolvescript fuse package # dist/Posterize-<version>.zip
$ resolvescript fuse install # into Fusion's Fuses root, recorded
$ resolvescript fuse list # and fuse uninstall to undo it
- Validation is two-layer — structure first (
FuRegisterClass/Create()/Process(req), theInImage/OutImageglobals), then a fullluac -pparse when Lua is installed, so a broken fuse fails here rather than inside Resolve. Generated files are ASCII-only. .pluginbinaries are deployed, never built — precompiled bundles getresolvescript plugin install | list | uninstalland nothing else; there is no source to compile.- Roots are per-OS, both overridable —
RESOLVESCRIPT_FUSES_ROOTandRESOLVESCRIPT_FUSION_PLUGINS_ROOT(or--root) point at another location. resolvescript build --installableemits one Lua file instead of a.py: drag it into Fusion's Console or Workspace and it opens an install window that writes the consolidated script where Resolve looks for it. Projects can ship their owninstaller.lua.j2to redraw that window.
Guides: docs/fuse.md, docs/plugin.md,
docs/workflow.md.
Frameworks
resolvescript ships a mock DaVinciResolveScript module with a faithful-enough Resolve color/editing/page object model for testing, plus resolvescript test --api-coverage to report which mock methods your tests actually exercise.
ResolveScript.ui — a declarative UI framework
A modern, reactive UI framework for Resolve tools. Screens are described as
plain Python (or dicts/JSON, or classes) and mounted onto real UIManager
elements — or onto a headless mirror, so the same code runs in a test with no
Resolve installed.
from ResolveScript.ui import (
Window, Column, Row, Button, TextField, Tree, Value, rows, call, run
)
sequence = Value("Sequence 01")
clips = list(media_pool.GetRootFolder().GetClipList())
run(Window("Batch Renderer", children=[
Column(
Row(TextField(value=sequence), Button("Render", variant="primary"), gap="sm"),
Tree(["Clip", "Type"], rows(clips, "GetName", call("GetClipProperty", "Type"))),
gap="md", padding="md",
)
]))
- Three authoring modes — composition functions, dicts/JSON, or
class-based
Components. They all produce the same tree and mix freely. - Retained rendering — keyed reconciliation patches individual native properties, so focus, caret position, scroll offset, selection and tree expansion survive updates. No full re-render.
- Tables without boilerplate —
rows()derivesTree/Listrows from the objects Resolve hands you, andchildren=recurses, so a full media pool browser is one call. - Two-way binding — bind a
Valueto any control and it reads and writes.TwoWay(read=..., write=...)handles stored/native representation differences. - Real theming — Qt stylesheets with hover, pressed, focus and disabled states; light and dark ship ready-made and cascade through subtrees.
- Native escape hatch — anything not wrapped is one
native(...)call away and mixes with framework widgets in the same container. - Testable headlessly —
MockBackendmirrors the element tree;require,fire,type_into,rowsand friends make UI tests short and precise.
Full guide: docs/ui.md.
Library API
ResolveScript is a first-class Python package — import it in any script:
import ResolveScript as rs
# scaffold a new project
root, written = rs.scaffold_project("my_tool", destination=".")
# static analysis
issues = rs.analyze_project(root)
# load & validate manifest
manifest = rs.load_manifest(root / "manifest.json")
rs.validate_manifest_or_throw(manifest)
# consolidate to a single file
cfg = rs.config_from_manifest(root, manifest)
result = rs.consolidate(cfg)
print(rs.summarize(result, cfg))
# package a release artifact
pkg = rs.package_project(root)
print(pkg.archive)
Every failure the library raises derives from rs.ResolveScriptError, so a single except catches them all — while the historical types keep working for existing handlers (SpecError is still a ValueError, FetchError still a RuntimeError, …):
try:
rs.validate_manifest_or_throw(manifest)
except rs.ResolveScriptError as exc:
print(f"resolvescript failed: {exc}")
Every name exported at the package root is also available from its owning submodule, e.g. rs.consolidate mirrors ResolveScript.consolidate.consolidate. The major subpackages are:
ResolveScript.manifest— model, loaders, validatorsResolveScript.sandbox— mock Resolve API, smoke runs, REPLResolveScript.sources— archive/GitHub/known-source helpersResolveScript.install— install, registry, target resolutionResolveScript.ui— declarative, reactive UI framework (seedocs/ui.md)
Version: rs.get_version() returns the installed version string.
Development
python -m venv .venv
.\.venv\Scripts\activate # Windows; source .venv/bin/activate elsewhere
pip install -e ".[dev]"
pytest
ruff check .
Milestones and the full plan live in TODO.md. CI runs the shared OseMine/workflows action; cutting a vX.Y.Z tag runs the release pipeline (sdist+wheel, checksums, GitHub release, optional PyPI publishing).
Metadata
Release files for resolvescript 1.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| resolvescript-1.1.0.tar.gz | 254.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| resolvescript-1.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 509.0 kB
Release files / resolvescript-1.1.0.tar.gz
| Download URL | resolvescript-1.1.0.tar.gz |
|---|---|
| Size | 254.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
be3df344fefc61c25a54a5ae84a3e049b2dfdd836ad87f60583cf4ecda3d30a1
|
|
BLAKE2b-256 checksum How to use checksums |
f7b48a92e249130531561605138008c2d3d61deb4877e1b65de657683e926bea
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.
Transparency logRelease files / resolvescript-1.1.0-py3-none-any.whl
| Download URL | resolvescript-1.1.0-py3-none-any.whl |
|---|---|
| Size | 254.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
55c22df9c4f27ec34862b6ee3fd89b79bc351eb70dd816b14ddb5e3b406f5faf
|
|
BLAKE2b-256 checksum How to use checksums |
96b97ccf1a03010d17619d835a68b376cdcb8f6315ab333c477b9bb9384edc79
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.
Transparency log