prpr 1.0.0__tar.gz
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.
- prpr-1.0.0/.gitignore +78 -0
- prpr-1.0.0/CHANGELOG.md +148 -0
- prpr-1.0.0/LICENSE +21 -0
- prpr-1.0.0/PKG-INFO +188 -0
- prpr-1.0.0/README.md +143 -0
- prpr-1.0.0/packaging/homebrew/README.md +29 -0
- prpr-1.0.0/plugin/main.js +467 -0
- prpr-1.0.0/plugin/manifest.json +21 -0
- prpr-1.0.0/prpr/__init__.py +66 -0
- prpr-1.0.0/prpr/__main__.py +6 -0
- prpr-1.0.0/prpr/_js.py +1609 -0
- prpr-1.0.0/prpr/_version.py +24 -0
- prpr-1.0.0/prpr/bridge.py +406 -0
- prpr-1.0.0/prpr/cli/__init__.py +6 -0
- prpr-1.0.0/prpr/cli/commands/__init__.py +1 -0
- prpr-1.0.0/prpr/cli/commands/apply.py +79 -0
- prpr-1.0.0/prpr/cli/commands/clip.py +183 -0
- prpr-1.0.0/prpr/cli/commands/completion.py +72 -0
- prpr-1.0.0/prpr/cli/commands/diff.py +49 -0
- prpr-1.0.0/prpr/cli/commands/effects.py +161 -0
- prpr-1.0.0/prpr/cli/commands/lint.py +25 -0
- prpr-1.0.0/prpr/cli/commands/mcp.py +498 -0
- prpr-1.0.0/prpr/cli/commands/media.py +216 -0
- prpr-1.0.0/prpr/cli/commands/metadata.py +53 -0
- prpr-1.0.0/prpr/cli/commands/monitor.py +85 -0
- prpr-1.0.0/prpr/cli/commands/plugin.py +65 -0
- prpr-1.0.0/prpr/cli/commands/project.py +177 -0
- prpr-1.0.0/prpr/cli/commands/render.py +161 -0
- prpr-1.0.0/prpr/cli/commands/schema.py +44 -0
- prpr-1.0.0/prpr/cli/commands/script.py +114 -0
- prpr-1.0.0/prpr/cli/commands/serve.py +83 -0
- prpr-1.0.0/prpr/cli/commands/snapshot.py +98 -0
- prpr-1.0.0/prpr/cli/commands/spec.py +38 -0
- prpr-1.0.0/prpr/cli/commands/timeline.py +432 -0
- prpr-1.0.0/prpr/cli/main.py +352 -0
- prpr-1.0.0/prpr/cli/output.py +155 -0
- prpr-1.0.0/prpr/cli/session.py +56 -0
- prpr-1.0.0/prpr/connection.py +464 -0
- prpr-1.0.0/prpr/daemon.py +424 -0
- prpr-1.0.0/prpr/diff.py +122 -0
- prpr-1.0.0/prpr/doctor.py +96 -0
- prpr-1.0.0/prpr/effects.py +128 -0
- prpr-1.0.0/prpr/errors.py +184 -0
- prpr-1.0.0/prpr/events.py +123 -0
- prpr-1.0.0/prpr/interchange.py +59 -0
- prpr-1.0.0/prpr/lint.py +100 -0
- prpr-1.0.0/prpr/mcp/__init__.py +36 -0
- prpr-1.0.0/prpr/mcp/server.py +2766 -0
- prpr-1.0.0/prpr/media.py +333 -0
- prpr-1.0.0/prpr/premiere.py +181 -0
- prpr-1.0.0/prpr/project.py +204 -0
- prpr-1.0.0/prpr/render.py +355 -0
- prpr-1.0.0/prpr/schema.py +292 -0
- prpr-1.0.0/prpr/snapshot.py +187 -0
- prpr-1.0.0/prpr/spec.py +293 -0
- prpr-1.0.0/prpr/timeline.py +603 -0
- prpr-1.0.0/pyproject.toml +163 -0
- prpr-1.0.0/tests/__init__.py +0 -0
- prpr-1.0.0/tests/conftest.py +164 -0
- prpr-1.0.0/tests/test_cli_commands.py +142 -0
- prpr-1.0.0/tests/test_daemon.py +98 -0
- prpr-1.0.0/tests/test_errors.py +81 -0
- prpr-1.0.0/tests/test_events.py +61 -0
- prpr-1.0.0/tests/test_library_surface.py +116 -0
- prpr-1.0.0/tests/test_mcp_handlers.py +114 -0
- prpr-1.0.0/tests/test_mcp_server.py +145 -0
- prpr-1.0.0/tests/test_media_and_render.py +124 -0
- prpr-1.0.0/tests/test_plugin_freshness.py +48 -0
- prpr-1.0.0/tests/test_plugin_version_sync.py +42 -0
- prpr-1.0.0/tests/test_spec_diff_lint.py +99 -0
- prpr-1.0.0/tests/test_timeline_with_mock.py +101 -0
prpr-1.0.0/.gitignore
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
share/python-wheels/
|
|
20
|
+
*.egg-info/
|
|
21
|
+
.installed.cfg
|
|
22
|
+
*.egg
|
|
23
|
+
MANIFEST
|
|
24
|
+
|
|
25
|
+
# Virtual environments
|
|
26
|
+
.venv/
|
|
27
|
+
venv/
|
|
28
|
+
env/
|
|
29
|
+
ENV/
|
|
30
|
+
|
|
31
|
+
# Hatch / generated version file
|
|
32
|
+
prpr/_version.py
|
|
33
|
+
|
|
34
|
+
# Testing & coverage
|
|
35
|
+
.pytest_cache/
|
|
36
|
+
.coverage
|
|
37
|
+
.coverage.*
|
|
38
|
+
htmlcov/
|
|
39
|
+
.tox/
|
|
40
|
+
.nox/
|
|
41
|
+
coverage.xml
|
|
42
|
+
*.cover
|
|
43
|
+
.hypothesis/
|
|
44
|
+
|
|
45
|
+
# Type checking
|
|
46
|
+
.mypy_cache/
|
|
47
|
+
.ruff_cache/
|
|
48
|
+
.pyre/
|
|
49
|
+
.pytype/
|
|
50
|
+
|
|
51
|
+
# IDE
|
|
52
|
+
.idea/
|
|
53
|
+
.vscode/
|
|
54
|
+
*.swp
|
|
55
|
+
*.swo
|
|
56
|
+
*~
|
|
57
|
+
|
|
58
|
+
# OS
|
|
59
|
+
.DS_Store
|
|
60
|
+
Thumbs.db
|
|
61
|
+
|
|
62
|
+
# Project-local
|
|
63
|
+
*.log
|
|
64
|
+
.env
|
|
65
|
+
.env.local
|
|
66
|
+
scratch/
|
|
67
|
+
local/
|
|
68
|
+
|
|
69
|
+
# Vendor reference material — Blackmagic's DaVinci Resolve API doc and
|
|
70
|
+
# anything else under reference/ stays local-only. Don't redistribute
|
|
71
|
+
# upstream documentation through this repo.
|
|
72
|
+
reference/
|
|
73
|
+
|
|
74
|
+
# Docs
|
|
75
|
+
site/
|
|
76
|
+
|
|
77
|
+
# UXP developer-tools session artifacts (machine-specific)
|
|
78
|
+
.uxprc
|
prpr-1.0.0/CHANGELOG.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [1.0.0] - 2026-07-10
|
|
11
|
+
|
|
12
|
+
First stable release.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
- Plugin freshness check: on connect, prpr compares the running bridge to
|
|
16
|
+
the version bundled in the pip package and (by default) UPIA-reinstalls
|
|
17
|
+
the newer one so a `pip install -U prpr` refreshes the in-Premiere bridge
|
|
18
|
+
on the next Premiere launch. Opt out with `PRPR_PLUGIN_AUTOUPDATE=0`;
|
|
19
|
+
surfaced in `prpr plugin check` and `prpr doctor --probe`.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
- Development status promoted to Production/Stable.
|
|
23
|
+
- Packaging hardened for distribution: the headless plugin ships inside
|
|
24
|
+
the wheel (`prpr/plugin_assets/`); dev-tools session files are excluded.
|
|
25
|
+
|
|
26
|
+
## [0.3.0] - 2026-07-10
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
- **The bridge plugin is now headless.** It's a `command`-entrypoint UXP
|
|
30
|
+
plugin whose `main.js` opens the WebSocket connection at module load —
|
|
31
|
+
no panel to dock, no menu to click. A UPIA-installed command plugin runs
|
|
32
|
+
its code automatically at Premiere startup (verified on 26.5: connects
|
|
33
|
+
with no panel and no developer tools). Setup is now just `prpr plugin
|
|
34
|
+
install` + one Premiere restart; the bridge then starts with Premiere
|
|
35
|
+
every launch and reconnects on its own.
|
|
36
|
+
- `prpr plugin autostart` → `prpr plugin check` (confirms the headless
|
|
37
|
+
bridge is connected). Install/doctor/error messages updated accordingly.
|
|
38
|
+
|
|
39
|
+
### Added
|
|
40
|
+
- `plugin-panel/` — the previous status-panel variant, kept for anyone who
|
|
41
|
+
wants a visible connection readout instead of the headless plugin.
|
|
42
|
+
|
|
43
|
+
## [0.2.0] - 2026-07-10
|
|
44
|
+
|
|
45
|
+
Live-validated against Adobe Premiere Pro 26.5. The full surface below was
|
|
46
|
+
driven end-to-end through the bridge (`scripts/smoke_live.py` + targeted
|
|
47
|
+
checks): transforms, keyframes, track mute/rename, marker move, keyframe
|
|
48
|
+
listing, sequence clone/settings-write, color labels, bin rename, scratch
|
|
49
|
+
disks, ingest, footage interpretation, selection read, still-frame and
|
|
50
|
+
sequence export, FCPXML export, snapshot, spec.
|
|
51
|
+
|
|
52
|
+
### Added
|
|
53
|
+
- **Transforms & keyframes**: `effects.set_param` writes any component
|
|
54
|
+
parameter (Motion/Opacity/effect params) with `PointF`/`Color`
|
|
55
|
+
coercion; pass `at_seconds` to write a keyframe. `timeline.keyframes`
|
|
56
|
+
lists keyframe times for a parameter. (transforms + keyframes
|
|
57
|
+
live-validated)
|
|
58
|
+
- **Timeline**: `track_update` (mute + rename), `clone`,
|
|
59
|
+
`create_subsequence`, `set_in_out`, `work_area` (26.5+),
|
|
60
|
+
`insert_mogrt`, `scene_edit_detection`, `move_marker`,
|
|
61
|
+
`create_from_media`, `selection` (read + clear — `setSelection`
|
|
62
|
+
crashes Premiere 26.5 beta and is refused rather than crashing the
|
|
63
|
+
host).
|
|
64
|
+
- **Media**: `attach_proxy`, `create_subclip` (26.3+),
|
|
65
|
+
`transcript_export`/`transcript_import` (26.3+),
|
|
66
|
+
`footage_interpretation`, `color_label`, `bin_rename`, `smart_bin`,
|
|
67
|
+
`purge_cache` (26.5+), `selection`.
|
|
68
|
+
- **Project**: `scratch_disks`, `ingest`, `color_settings`,
|
|
69
|
+
`import_sequences`, `import_ae_comps`, sequence `set_settings`. **App**:
|
|
70
|
+
`preference`.
|
|
71
|
+
- **Host events**: `p.events.subscribe`/`on`/`off` (EventManager —
|
|
72
|
+
project/sequence/encoder/global events delivered to Python handlers on
|
|
73
|
+
the bridge thread).
|
|
74
|
+
- **CLI/MCP** commands and tools for the above; `prpr/__main__.py`
|
|
75
|
+
(`python -m prpr`).
|
|
76
|
+
- `scripts/smoke_live.py` full live E2E; `scripts/check_parity.py`
|
|
77
|
+
cross-repo status/key-symmetry check. mypy (strict) added to CI.
|
|
78
|
+
- Parity matrix grown to 106 operations, synced with dvr.
|
|
79
|
+
|
|
80
|
+
### Changed
|
|
81
|
+
- Bridge object serialization depth 6 → 32 (nested inspect payloads).
|
|
82
|
+
- Manifest `network.domains` → `"all"` (UXP 26.5 rejects explicit
|
|
83
|
+
`ws://` entries).
|
|
84
|
+
- Daemon: `--wait`/`watch` commands forward through the daemon instead
|
|
85
|
+
of bypassing it (one-port-owner model), and the bypass parser no
|
|
86
|
+
longer mistakes an option value for the command.
|
|
87
|
+
|
|
88
|
+
## [0.1.0] - 2026-07-10
|
|
89
|
+
|
|
90
|
+
Initial release. Structural sibling of [dvr](https://github.com/mhadifilms/dvr) for Adobe Premiere Pro.
|
|
91
|
+
|
|
92
|
+
### Added
|
|
93
|
+
|
|
94
|
+
- **Bridge architecture**: bundled UXP panel (`prpr bridge`) that dials into a
|
|
95
|
+
local WebSocket server hosted by the Python side; generic RPC executor
|
|
96
|
+
(`call`/`get`/`set`/`eval`/`transaction`/`subscribe`) with an object-handle
|
|
97
|
+
registry, so the full `premierepro` API surface is reachable without plugin
|
|
98
|
+
updates. Live-validated against Premiere Pro 26.5.
|
|
99
|
+
- **Python library** (`prpr.Premiere`) mirroring dvr's object model:
|
|
100
|
+
- `project`: list open projects, `ensure`/`create`/`load`/`save`/`delete`
|
|
101
|
+
(file-based, `PRPR_PROJECTS_DIR` convention)
|
|
102
|
+
- `timeline`: sequences with dvr's timeline routing — `list`/`current`/
|
|
103
|
+
`ensure`/`create`/`switch`/`delete`/`rename`, full `inspect()` (fps, frame
|
|
104
|
+
size, tracks, items, markers, settings), `append`/`insert`/`delete_clips`,
|
|
105
|
+
markers (add/list/remove with colors, durations, types), clip queries
|
|
106
|
+
- `media`: project-panel bins and clips — `inspect` tree, `import_` with
|
|
107
|
+
bin targeting, `bin_ensure` (nested paths), `move`, `find_or_import`,
|
|
108
|
+
plus Premiere-free `scan_media_files`
|
|
109
|
+
- `render`: `.epr` preset discovery, `submit` (immediate / queue-to-app /
|
|
110
|
+
queue-to-AME) with event-driven `wait`, still-frame export
|
|
111
|
+
- `effects`: catalogs (111 video effects, 106 transitions, 81 audio effects),
|
|
112
|
+
apply by matchName, transitions with duration/alignment, component-chain
|
|
113
|
+
inspection, and `set_param` for transforms/keyframes (Motion, Opacity, any
|
|
114
|
+
component parameter; PointF/Color coercion)
|
|
115
|
+
- `interchange`: FCPXML / OTIO / AAF sequence export
|
|
116
|
+
- XMP + project metadata read/write, source monitor control, per-project
|
|
117
|
+
properties store
|
|
118
|
+
- **Declarative layer** mirroring dvr: `spec` (YAML/JSON apply with
|
|
119
|
+
plan/verify, `from_live` export), `diff` (timelines/spec/snapshot),
|
|
120
|
+
`snapshot` (capture/restore), `lint` (offline media, temp paths, empty
|
|
121
|
+
sequences)
|
|
122
|
+
- **Daemon** (`prpr serve`): Unix-socket RPC holding the bridge across CLI
|
|
123
|
+
invocations, dvr wire format, full-CLI forwarding
|
|
124
|
+
- **CLI** (`prpr`): dvr's command tree with identical output conventions
|
|
125
|
+
(json/table/yaml, `PRPR_FORMAT`, TTY auto-detection)
|
|
126
|
+
- **MCP server** (`prpr mcp serve`): dvr's tool names and registration
|
|
127
|
+
pattern; typed tools for every library capability
|
|
128
|
+
- **Cross-app parity contract**: `prpr.errors.NotSupportedError` for
|
|
129
|
+
operations Premiere's UXP API cannot perform (render queue enumeration,
|
|
130
|
+
page switching, interchange import, ...), each with cause/fix pointing to
|
|
131
|
+
the closest alternative; machine-readable matrix at `prpr schema show parity`
|
|
132
|
+
- **Diagnostics**: `prpr doctor [--probe]` (install/plugin/port checks),
|
|
133
|
+
structured `PrprError` hierarchy with `cause`/`fix`/`state` on every failure
|
|
134
|
+
- **Plugin management**: `prpr plugin install|uninstall|status` via Adobe's
|
|
135
|
+
UPIA installer with automatic `.ccx` packaging
|
|
136
|
+
- Test suite (MockBridge at the wire boundary, no Premiere required)
|
|
137
|
+
|
|
138
|
+
### Notes
|
|
139
|
+
- `timeline.work_area` (WorkAreaUtils) is feature-detected — it is absent
|
|
140
|
+
on some Premiere 26.5 builds and fails with a clear version error rather
|
|
141
|
+
than crashing.
|
|
142
|
+
- `Sequence.setSelection` crashes Premiere 26.5 beta, so `timeline.select`
|
|
143
|
+
supports read + clear only and refuses filtered selection.
|
|
144
|
+
|
|
145
|
+
[1.0.0]: https://github.com/mhadifilms/prpr/releases/tag/v1.0.0
|
|
146
|
+
[0.3.0]: https://github.com/mhadifilms/prpr/releases/tag/v0.3.0
|
|
147
|
+
[0.2.0]: https://github.com/mhadifilms/prpr/releases/tag/v0.2.0
|
|
148
|
+
[0.1.0]: https://github.com/mhadifilms/prpr/releases/tag/v0.1.0
|
prpr-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 M Hadi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
prpr-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: prpr
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Adobe Premiere Pro CLI, Python library, and MCP server. Automate editing, sequencing, and export with LLM-friendly tools for AI agents. Declarative, scriptable, structured JSON output.
|
|
5
|
+
Project-URL: Homepage, https://github.com/mhadifilms/prpr
|
|
6
|
+
Project-URL: Documentation, https://mhadifilms.github.io/prpr
|
|
7
|
+
Project-URL: Repository, https://github.com/mhadifilms/prpr
|
|
8
|
+
Project-URL: Issues, https://github.com/mhadifilms/prpr/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/mhadifilms/prpr/blob/main/CHANGELOG.md
|
|
10
|
+
Author-email: M Hadi <mhadifilms@gmail.com>
|
|
11
|
+
License: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: adobe,ai-agents,automation,cli,command-line,llm,llm-tools,mcp,mcp-server,model-context-protocol,post-production,premiere-pro,rendering,uxp,vfx,video-editing
|
|
14
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
15
|
+
Classifier: Environment :: Console
|
|
16
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
17
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
18
|
+
Classifier: Operating System :: MacOS
|
|
19
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
20
|
+
Classifier: Programming Language :: Python :: 3
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
25
|
+
Classifier: Topic :: Multimedia :: Video
|
|
26
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
27
|
+
Classifier: Typing :: Typed
|
|
28
|
+
Requires-Python: >=3.10
|
|
29
|
+
Requires-Dist: mcp>=1.0
|
|
30
|
+
Requires-Dist: pyyaml>=6.0
|
|
31
|
+
Requires-Dist: rich>=13.7
|
|
32
|
+
Requires-Dist: typer>=0.12
|
|
33
|
+
Requires-Dist: websockets>=12.0
|
|
34
|
+
Provides-Extra: dev
|
|
35
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
36
|
+
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
37
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
38
|
+
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
39
|
+
Requires-Dist: types-pyyaml; extra == 'dev'
|
|
40
|
+
Provides-Extra: docs
|
|
41
|
+
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
|
|
42
|
+
Requires-Dist: mkdocs>=1.6; extra == 'docs'
|
|
43
|
+
Requires-Dist: mkdocstrings[python]>=0.25; extra == 'docs'
|
|
44
|
+
Description-Content-Type: text/markdown
|
|
45
|
+
|
|
46
|
+
<p align="center">
|
|
47
|
+
<img src="https://raw.githubusercontent.com/mhadifilms/prpr/main/docs/assets/logo.svg" alt="prpr logo" width="140">
|
|
48
|
+
</p>
|
|
49
|
+
|
|
50
|
+
# prpr
|
|
51
|
+
|
|
52
|
+
[](LICENSE)
|
|
53
|
+
|
|
54
|
+
**The missing CLI, Python library, and MCP server for Adobe Premiere Pro.**
|
|
55
|
+
|
|
56
|
+
Declarative. Scriptable. LLM-friendly. Structural sibling of [`dvr`](https://github.com/mhadifilms/dvr) (the same project for DaVinci Resolve) — same namespaces, same routing, same error model.
|
|
57
|
+
|
|
58
|
+
`prpr` is a command-line tool, a typed Python library, and a [Model Context Protocol (MCP)](docs/mcp.md) server for automating **Adobe Premiere Pro** — editing, sequencing, effects, and export. It drives Premiere's UXP API through a bundled bridge plugin, wraps it in clean idempotent operations with structured JSON output, and makes it usable by humans, scripts, and AI agents (Claude, Cursor, and any MCP-compatible client).
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pip install prpr
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
$ prpr timeline inspect
|
|
66
|
+
{
|
|
67
|
+
"name": "Edit_v1",
|
|
68
|
+
"fps": 23.976,
|
|
69
|
+
"duration_frames": 4274,
|
|
70
|
+
"frame_size": {"width": 1920, "height": 1080},
|
|
71
|
+
"tracks": {
|
|
72
|
+
"video": [{"index": 0, "name": "Video 1", "clips": 2, "items": [...]}],
|
|
73
|
+
"audio": [{"index": 0, "name": "Audio 1", "clips": 2, "items": [...]}]
|
|
74
|
+
},
|
|
75
|
+
"markers": [{"name": "start", "start": {"seconds": 1.0}, ...}]
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## How it connects
|
|
82
|
+
|
|
83
|
+
Premiere has no external scripting socket — its UXP API runs *inside* the app, and UXP plugins can only dial **out**. So `prpr` inverts the connection:
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
prpr CLI / library / MCP ──hosts──▶ ws://127.0.0.1:8855 ◀──dials in── prpr bridge panel (UXP, inside Premiere)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
One-time setup:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
prpr plugin install # installs the headless bridge via Adobe's installer
|
|
93
|
+
# restart Premiere once so it registers the plugin
|
|
94
|
+
prpr doctor --probe # verify the whole chain
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The bridge is **headless** — a command-entrypoint UXP plugin that starts
|
|
98
|
+
with Premiere automatically. There's no panel to open or keep open.
|
|
99
|
+
|
|
100
|
+
## Why prpr exists
|
|
101
|
+
|
|
102
|
+
Premiere's UXP API is powerful but locked inside the app:
|
|
103
|
+
|
|
104
|
+
- **No external process access.** Resolve ships a Python API; Premiere gives you a JavaScript sandbox in a panel.
|
|
105
|
+
- **Action/transaction ceremony.** Every mutation needs `lockedAccess` + `executeTransaction` + action objects.
|
|
106
|
+
- **Ticks.** Time is measured in 254,016,000,000ths of a second.
|
|
107
|
+
- **Silent failures.** `importFiles()` returns `false` and moves on with its day.
|
|
108
|
+
- **No batch operators, no inspection.** You loop `getVideoTrack(i)` → `getTrackItems(...)` → six async getters per clip.
|
|
109
|
+
|
|
110
|
+
`prpr` wraps all of it: one `inspect()` call returns full structured state, mutations are single undoable transactions, every failure decodes into an error with a `cause`, a `fix`, and a `state` snapshot.
|
|
111
|
+
|
|
112
|
+
## Three ways to use it
|
|
113
|
+
|
|
114
|
+
### 1. Python library
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
from prpr import Premiere
|
|
118
|
+
|
|
119
|
+
p = Premiere() # hosts the bridge, launches Premiere if needed
|
|
120
|
+
|
|
121
|
+
p.project.ensure("MyShow") # open-or-create ~/Documents/prpr Projects/MyShow.prproj
|
|
122
|
+
p.media.import_(["/footage/a.mp4"], bin="Footage")
|
|
123
|
+
|
|
124
|
+
tl = p.timeline.ensure("Edit_v1")
|
|
125
|
+
tl.append("a.mp4")
|
|
126
|
+
tl.add_marker(1.0, name="start", note="first pass", color_index=1)
|
|
127
|
+
|
|
128
|
+
p.effects.set_param("Motion", "Scale", 50, clip_name="a.mp4") # transforms
|
|
129
|
+
p.effects.add_transition("ADBE Film Dissolve", clip_name="a.mp4")
|
|
130
|
+
|
|
131
|
+
job = p.render.submit(target_dir="/exports", preset="prores-422", wait=True)
|
|
132
|
+
print(job.output_path)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### 2. CLI
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
$ prpr project ensure MyShow
|
|
139
|
+
$ prpr media import /footage/*.mp4 --bin Footage
|
|
140
|
+
$ prpr timeline inspect | jq '.tracks.video[].items'
|
|
141
|
+
$ prpr render submit --target-dir /exports --preset prores-422 --wait
|
|
142
|
+
$ prpr apply spec.yaml # terraform-style declarative reconcile
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### 3. MCP server (for LLM agents)
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
$ prpr mcp install-claude # one-shot Claude Desktop setup
|
|
149
|
+
$ prpr mcp serve # or run the stdio server yourself
|
|
150
|
+
$ prpr mcp tools # introspect the typed tools
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## dvr ↔ prpr: one convention, two apps
|
|
154
|
+
|
|
155
|
+
`prpr` and [`dvr`](https://github.com/mhadifilms/dvr) share naming, routing, output envelopes, and the error model. An agent (or human) that knows one knows the other:
|
|
156
|
+
|
|
157
|
+
| | dvr (Resolve) | prpr (Premiere) |
|
|
158
|
+
|---|---|---|
|
|
159
|
+
| `timeline inspect` | ✅ | ✅ |
|
|
160
|
+
| `media import --bin` | ✅ | ✅ |
|
|
161
|
+
| `render submit --preset` | render presets | `.epr` presets |
|
|
162
|
+
| `render queue` | ✅ | ❌ fails: `NotSupportedError` + fix |
|
|
163
|
+
| `page edit` | ✅ | ❌ fails: `NotSupportedError` + fix |
|
|
164
|
+
| `effects apply` | ❌ fails with pointer to Resolve alternative | ✅ |
|
|
165
|
+
|
|
166
|
+
Operations one app can't perform **fail loudly** with a structured `NotSupportedError` explaining why and what to use instead — never silent degradation. The machine-readable support matrix ships in both packages:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
$ prpr schema show parity | jq '.operations["render.queue"]'
|
|
170
|
+
{"status": "dvr-only", "reason": "no enumerable render queue in UXP"}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Requirements
|
|
174
|
+
|
|
175
|
+
- Adobe Premiere Pro **25.6+** (26.x recommended; built and tested against 26.5)
|
|
176
|
+
- Python 3.10+
|
|
177
|
+
- macOS or Windows (daemon mode is macOS/Linux-style Unix sockets; Windows uses direct mode)
|
|
178
|
+
|
|
179
|
+
## Documentation
|
|
180
|
+
|
|
181
|
+
- [Getting started](docs/getting-started.md)
|
|
182
|
+
- [Library guide](docs/library.md) · [CLI reference](docs/cli.md) · [MCP server](docs/mcp.md)
|
|
183
|
+
- [Declarative specs](docs/spec.md) · [Daemon mode](docs/daemon.md)
|
|
184
|
+
- [dvr ↔ prpr parity](docs/parity.md)
|
|
185
|
+
|
|
186
|
+
## License
|
|
187
|
+
|
|
188
|
+
MIT © M Hadi
|
prpr-1.0.0/README.md
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/mhadifilms/prpr/main/docs/assets/logo.svg" alt="prpr logo" width="140">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# prpr
|
|
6
|
+
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
|
|
9
|
+
**The missing CLI, Python library, and MCP server for Adobe Premiere Pro.**
|
|
10
|
+
|
|
11
|
+
Declarative. Scriptable. LLM-friendly. Structural sibling of [`dvr`](https://github.com/mhadifilms/dvr) (the same project for DaVinci Resolve) — same namespaces, same routing, same error model.
|
|
12
|
+
|
|
13
|
+
`prpr` is a command-line tool, a typed Python library, and a [Model Context Protocol (MCP)](docs/mcp.md) server for automating **Adobe Premiere Pro** — editing, sequencing, effects, and export. It drives Premiere's UXP API through a bundled bridge plugin, wraps it in clean idempotent operations with structured JSON output, and makes it usable by humans, scripts, and AI agents (Claude, Cursor, and any MCP-compatible client).
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install prpr
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
$ prpr timeline inspect
|
|
21
|
+
{
|
|
22
|
+
"name": "Edit_v1",
|
|
23
|
+
"fps": 23.976,
|
|
24
|
+
"duration_frames": 4274,
|
|
25
|
+
"frame_size": {"width": 1920, "height": 1080},
|
|
26
|
+
"tracks": {
|
|
27
|
+
"video": [{"index": 0, "name": "Video 1", "clips": 2, "items": [...]}],
|
|
28
|
+
"audio": [{"index": 0, "name": "Audio 1", "clips": 2, "items": [...]}]
|
|
29
|
+
},
|
|
30
|
+
"markers": [{"name": "start", "start": {"seconds": 1.0}, ...}]
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## How it connects
|
|
37
|
+
|
|
38
|
+
Premiere has no external scripting socket — its UXP API runs *inside* the app, and UXP plugins can only dial **out**. So `prpr` inverts the connection:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
prpr CLI / library / MCP ──hosts──▶ ws://127.0.0.1:8855 ◀──dials in── prpr bridge panel (UXP, inside Premiere)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
One-time setup:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
prpr plugin install # installs the headless bridge via Adobe's installer
|
|
48
|
+
# restart Premiere once so it registers the plugin
|
|
49
|
+
prpr doctor --probe # verify the whole chain
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The bridge is **headless** — a command-entrypoint UXP plugin that starts
|
|
53
|
+
with Premiere automatically. There's no panel to open or keep open.
|
|
54
|
+
|
|
55
|
+
## Why prpr exists
|
|
56
|
+
|
|
57
|
+
Premiere's UXP API is powerful but locked inside the app:
|
|
58
|
+
|
|
59
|
+
- **No external process access.** Resolve ships a Python API; Premiere gives you a JavaScript sandbox in a panel.
|
|
60
|
+
- **Action/transaction ceremony.** Every mutation needs `lockedAccess` + `executeTransaction` + action objects.
|
|
61
|
+
- **Ticks.** Time is measured in 254,016,000,000ths of a second.
|
|
62
|
+
- **Silent failures.** `importFiles()` returns `false` and moves on with its day.
|
|
63
|
+
- **No batch operators, no inspection.** You loop `getVideoTrack(i)` → `getTrackItems(...)` → six async getters per clip.
|
|
64
|
+
|
|
65
|
+
`prpr` wraps all of it: one `inspect()` call returns full structured state, mutations are single undoable transactions, every failure decodes into an error with a `cause`, a `fix`, and a `state` snapshot.
|
|
66
|
+
|
|
67
|
+
## Three ways to use it
|
|
68
|
+
|
|
69
|
+
### 1. Python library
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from prpr import Premiere
|
|
73
|
+
|
|
74
|
+
p = Premiere() # hosts the bridge, launches Premiere if needed
|
|
75
|
+
|
|
76
|
+
p.project.ensure("MyShow") # open-or-create ~/Documents/prpr Projects/MyShow.prproj
|
|
77
|
+
p.media.import_(["/footage/a.mp4"], bin="Footage")
|
|
78
|
+
|
|
79
|
+
tl = p.timeline.ensure("Edit_v1")
|
|
80
|
+
tl.append("a.mp4")
|
|
81
|
+
tl.add_marker(1.0, name="start", note="first pass", color_index=1)
|
|
82
|
+
|
|
83
|
+
p.effects.set_param("Motion", "Scale", 50, clip_name="a.mp4") # transforms
|
|
84
|
+
p.effects.add_transition("ADBE Film Dissolve", clip_name="a.mp4")
|
|
85
|
+
|
|
86
|
+
job = p.render.submit(target_dir="/exports", preset="prores-422", wait=True)
|
|
87
|
+
print(job.output_path)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 2. CLI
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
$ prpr project ensure MyShow
|
|
94
|
+
$ prpr media import /footage/*.mp4 --bin Footage
|
|
95
|
+
$ prpr timeline inspect | jq '.tracks.video[].items'
|
|
96
|
+
$ prpr render submit --target-dir /exports --preset prores-422 --wait
|
|
97
|
+
$ prpr apply spec.yaml # terraform-style declarative reconcile
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### 3. MCP server (for LLM agents)
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
$ prpr mcp install-claude # one-shot Claude Desktop setup
|
|
104
|
+
$ prpr mcp serve # or run the stdio server yourself
|
|
105
|
+
$ prpr mcp tools # introspect the typed tools
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## dvr ↔ prpr: one convention, two apps
|
|
109
|
+
|
|
110
|
+
`prpr` and [`dvr`](https://github.com/mhadifilms/dvr) share naming, routing, output envelopes, and the error model. An agent (or human) that knows one knows the other:
|
|
111
|
+
|
|
112
|
+
| | dvr (Resolve) | prpr (Premiere) |
|
|
113
|
+
|---|---|---|
|
|
114
|
+
| `timeline inspect` | ✅ | ✅ |
|
|
115
|
+
| `media import --bin` | ✅ | ✅ |
|
|
116
|
+
| `render submit --preset` | render presets | `.epr` presets |
|
|
117
|
+
| `render queue` | ✅ | ❌ fails: `NotSupportedError` + fix |
|
|
118
|
+
| `page edit` | ✅ | ❌ fails: `NotSupportedError` + fix |
|
|
119
|
+
| `effects apply` | ❌ fails with pointer to Resolve alternative | ✅ |
|
|
120
|
+
|
|
121
|
+
Operations one app can't perform **fail loudly** with a structured `NotSupportedError` explaining why and what to use instead — never silent degradation. The machine-readable support matrix ships in both packages:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
$ prpr schema show parity | jq '.operations["render.queue"]'
|
|
125
|
+
{"status": "dvr-only", "reason": "no enumerable render queue in UXP"}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Requirements
|
|
129
|
+
|
|
130
|
+
- Adobe Premiere Pro **25.6+** (26.x recommended; built and tested against 26.5)
|
|
131
|
+
- Python 3.10+
|
|
132
|
+
- macOS or Windows (daemon mode is macOS/Linux-style Unix sockets; Windows uses direct mode)
|
|
133
|
+
|
|
134
|
+
## Documentation
|
|
135
|
+
|
|
136
|
+
- [Getting started](docs/getting-started.md)
|
|
137
|
+
- [Library guide](docs/library.md) · [CLI reference](docs/cli.md) · [MCP server](docs/mcp.md)
|
|
138
|
+
- [Declarative specs](docs/spec.md) · [Daemon mode](docs/daemon.md)
|
|
139
|
+
- [dvr ↔ prpr parity](docs/parity.md)
|
|
140
|
+
|
|
141
|
+
## License
|
|
142
|
+
|
|
143
|
+
MIT © M Hadi
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Homebrew formula
|
|
2
|
+
|
|
3
|
+
`prpr.rb` is the tap formula for [mhadifilms/homebrew-tap](https://github.com/mhadifilms/homebrew-tap),
|
|
4
|
+
mirroring the `dvr` formula there.
|
|
5
|
+
|
|
6
|
+
Homebrew's Python formulas vendor every dependency as a `resource` with a
|
|
7
|
+
pinned sha256, and those are generated from the **published** sdist — so
|
|
8
|
+
the formula is finalized right after the PyPI upload:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
# 1. publish prpr to PyPI (see the release checklist), then:
|
|
12
|
+
brew tap mhadifilms/tap
|
|
13
|
+
cp packaging/homebrew/prpr.rb "$(brew --repository mhadifilms/tap)/Formula/prpr.rb"
|
|
14
|
+
|
|
15
|
+
# 2. fill url + sha256 from the PyPI sdist
|
|
16
|
+
# (https://pypi.org/project/prpr/#files → tarball → "Copy SHA256")
|
|
17
|
+
|
|
18
|
+
# 3. generate the resource stanzas (replaces the <<RESOURCES>> marker)
|
|
19
|
+
brew update-python-resources "$(brew --repository mhadifilms/tap)/Formula/prpr.rb"
|
|
20
|
+
|
|
21
|
+
# 4. verify, then commit to the tap
|
|
22
|
+
brew install --build-from-source mhadifilms/tap/prpr
|
|
23
|
+
brew test mhadifilms/tap/prpr
|
|
24
|
+
brew audit --strict --online mhadifilms/tap/prpr
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`mcp` is intentionally left out of the vendored resources (the CLI and
|
|
28
|
+
library run without it); users who want the MCP server install via
|
|
29
|
+
`pip install prpr`.
|