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.
Files changed (71) hide show
  1. prpr-1.0.0/.gitignore +78 -0
  2. prpr-1.0.0/CHANGELOG.md +148 -0
  3. prpr-1.0.0/LICENSE +21 -0
  4. prpr-1.0.0/PKG-INFO +188 -0
  5. prpr-1.0.0/README.md +143 -0
  6. prpr-1.0.0/packaging/homebrew/README.md +29 -0
  7. prpr-1.0.0/plugin/main.js +467 -0
  8. prpr-1.0.0/plugin/manifest.json +21 -0
  9. prpr-1.0.0/prpr/__init__.py +66 -0
  10. prpr-1.0.0/prpr/__main__.py +6 -0
  11. prpr-1.0.0/prpr/_js.py +1609 -0
  12. prpr-1.0.0/prpr/_version.py +24 -0
  13. prpr-1.0.0/prpr/bridge.py +406 -0
  14. prpr-1.0.0/prpr/cli/__init__.py +6 -0
  15. prpr-1.0.0/prpr/cli/commands/__init__.py +1 -0
  16. prpr-1.0.0/prpr/cli/commands/apply.py +79 -0
  17. prpr-1.0.0/prpr/cli/commands/clip.py +183 -0
  18. prpr-1.0.0/prpr/cli/commands/completion.py +72 -0
  19. prpr-1.0.0/prpr/cli/commands/diff.py +49 -0
  20. prpr-1.0.0/prpr/cli/commands/effects.py +161 -0
  21. prpr-1.0.0/prpr/cli/commands/lint.py +25 -0
  22. prpr-1.0.0/prpr/cli/commands/mcp.py +498 -0
  23. prpr-1.0.0/prpr/cli/commands/media.py +216 -0
  24. prpr-1.0.0/prpr/cli/commands/metadata.py +53 -0
  25. prpr-1.0.0/prpr/cli/commands/monitor.py +85 -0
  26. prpr-1.0.0/prpr/cli/commands/plugin.py +65 -0
  27. prpr-1.0.0/prpr/cli/commands/project.py +177 -0
  28. prpr-1.0.0/prpr/cli/commands/render.py +161 -0
  29. prpr-1.0.0/prpr/cli/commands/schema.py +44 -0
  30. prpr-1.0.0/prpr/cli/commands/script.py +114 -0
  31. prpr-1.0.0/prpr/cli/commands/serve.py +83 -0
  32. prpr-1.0.0/prpr/cli/commands/snapshot.py +98 -0
  33. prpr-1.0.0/prpr/cli/commands/spec.py +38 -0
  34. prpr-1.0.0/prpr/cli/commands/timeline.py +432 -0
  35. prpr-1.0.0/prpr/cli/main.py +352 -0
  36. prpr-1.0.0/prpr/cli/output.py +155 -0
  37. prpr-1.0.0/prpr/cli/session.py +56 -0
  38. prpr-1.0.0/prpr/connection.py +464 -0
  39. prpr-1.0.0/prpr/daemon.py +424 -0
  40. prpr-1.0.0/prpr/diff.py +122 -0
  41. prpr-1.0.0/prpr/doctor.py +96 -0
  42. prpr-1.0.0/prpr/effects.py +128 -0
  43. prpr-1.0.0/prpr/errors.py +184 -0
  44. prpr-1.0.0/prpr/events.py +123 -0
  45. prpr-1.0.0/prpr/interchange.py +59 -0
  46. prpr-1.0.0/prpr/lint.py +100 -0
  47. prpr-1.0.0/prpr/mcp/__init__.py +36 -0
  48. prpr-1.0.0/prpr/mcp/server.py +2766 -0
  49. prpr-1.0.0/prpr/media.py +333 -0
  50. prpr-1.0.0/prpr/premiere.py +181 -0
  51. prpr-1.0.0/prpr/project.py +204 -0
  52. prpr-1.0.0/prpr/render.py +355 -0
  53. prpr-1.0.0/prpr/schema.py +292 -0
  54. prpr-1.0.0/prpr/snapshot.py +187 -0
  55. prpr-1.0.0/prpr/spec.py +293 -0
  56. prpr-1.0.0/prpr/timeline.py +603 -0
  57. prpr-1.0.0/pyproject.toml +163 -0
  58. prpr-1.0.0/tests/__init__.py +0 -0
  59. prpr-1.0.0/tests/conftest.py +164 -0
  60. prpr-1.0.0/tests/test_cli_commands.py +142 -0
  61. prpr-1.0.0/tests/test_daemon.py +98 -0
  62. prpr-1.0.0/tests/test_errors.py +81 -0
  63. prpr-1.0.0/tests/test_events.py +61 -0
  64. prpr-1.0.0/tests/test_library_surface.py +116 -0
  65. prpr-1.0.0/tests/test_mcp_handlers.py +114 -0
  66. prpr-1.0.0/tests/test_mcp_server.py +145 -0
  67. prpr-1.0.0/tests/test_media_and_render.py +124 -0
  68. prpr-1.0.0/tests/test_plugin_freshness.py +48 -0
  69. prpr-1.0.0/tests/test_plugin_version_sync.py +42 -0
  70. prpr-1.0.0/tests/test_spec_diff_lint.py +99 -0
  71. 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
@@ -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: MIT](https://img.shields.io/badge/license-MIT-green.svg)](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: MIT](https://img.shields.io/badge/license-MIT-green.svg)](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`.