playrig 0.0.0-stage → 0.1.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.
Files changed (118) hide show
  1. package/AGENTS.md +106 -0
  2. package/LICENSE +37 -0
  3. package/README.md +77 -2
  4. package/bin/playrig.js +4 -0
  5. package/editions/ae/README.md +144 -0
  6. package/editions/ae/client/aeb.js +9 -0
  7. package/editions/ae/examples/hello.jsx +3 -0
  8. package/editions/ae/examples/inspect.jsx +7 -0
  9. package/editions/ae/examples/snap.jsx +15 -0
  10. package/editions/ae/lib/actions.json +159 -0
  11. package/editions/ae/lib/bridge-api.jsxinc +474 -0
  12. package/editions/ae/lib/dev.jsxinc +21 -0
  13. package/editions/ae/lib/icons/README.md +4 -0
  14. package/editions/ae/lib/icons/dot-error.svg +3 -0
  15. package/editions/ae/lib/icons/dot-idle.svg +3 -0
  16. package/editions/ae/lib/icons/dot-running.svg +3 -0
  17. package/editions/ae/lib/icons/make-png.js +25 -0
  18. package/editions/ae/lib/icons/png/dot-error.png +0 -0
  19. package/editions/ae/lib/icons/png/dot-error@2x.png +0 -0
  20. package/editions/ae/lib/icons/png/dot-idle.png +0 -0
  21. package/editions/ae/lib/icons/png/dot-idle@2x.png +0 -0
  22. package/editions/ae/lib/icons/png/dot-running.png +0 -0
  23. package/editions/ae/lib/icons/png/dot-running@2x.png +0 -0
  24. package/editions/ae/lib/icons/png/power-off.png +0 -0
  25. package/editions/ae/lib/icons/png/power-off@2x.png +0 -0
  26. package/editions/ae/lib/icons/png/power-on.png +0 -0
  27. package/editions/ae/lib/icons/png/power-on@2x.png +0 -0
  28. package/editions/ae/lib/icons/png/settings.png +0 -0
  29. package/editions/ae/lib/icons/png/settings@2x.png +0 -0
  30. package/editions/ae/lib/icons/png/status-error.png +0 -0
  31. package/editions/ae/lib/icons/png/status-error@2x.png +0 -0
  32. package/editions/ae/lib/icons/png/status-ok.png +0 -0
  33. package/editions/ae/lib/icons/png/status-ok@2x.png +0 -0
  34. package/editions/ae/lib/icons/png/status-rejected.png +0 -0
  35. package/editions/ae/lib/icons/png/status-rejected@2x.png +0 -0
  36. package/editions/ae/lib/icons/png/status-timeout.png +0 -0
  37. package/editions/ae/lib/icons/png/status-timeout@2x.png +0 -0
  38. package/editions/ae/lib/icons/png/status-unknown.png +0 -0
  39. package/editions/ae/lib/icons/png/status-unknown@2x.png +0 -0
  40. package/editions/ae/lib/icons/power-off.svg +4 -0
  41. package/editions/ae/lib/icons/power-on.svg +4 -0
  42. package/editions/ae/lib/icons/settings.svg +4 -0
  43. package/editions/ae/lib/icons/status-error.svg +4 -0
  44. package/editions/ae/lib/icons/status-ok.svg +4 -0
  45. package/editions/ae/lib/icons/status-rejected.svg +4 -0
  46. package/editions/ae/lib/icons/status-timeout.svg +4 -0
  47. package/editions/ae/lib/icons/status-unknown.svg +5 -0
  48. package/editions/ae/lib/panel-core.jsxinc +249 -0
  49. package/editions/ae/lib/update-key.pem +11 -0
  50. package/editions/ae/lib/updater.jsxinc +148 -0
  51. package/editions/ae/library-starter/INDEX.md +5 -0
  52. package/editions/ae/library-starter/README.md +161 -0
  53. package/editions/ae/library-starter/_common.jsx +187 -0
  54. package/editions/ae/library-starter/categories.json +9 -0
  55. package/editions/ae/library-starter/recipes/.gitkeep +0 -0
  56. package/editions/ae/package.json +7 -0
  57. package/editions/ae/panel/Playrig.jsx +39 -0
  58. package/editions/ae/panel/core.jsx +1026 -0
  59. package/editions/ae/skills/create-ae-recipe/SKILL.md +85 -0
  60. package/editions/ae/skills/create-ae-recipe/references/ae-patterns.md +88 -0
  61. package/editions/ae/skills/create-ae-recipe/references/video-analysis.md +72 -0
  62. package/editions/ae/skills/create-ae-recipe/scripts/media +5 -0
  63. package/editions/ae/skills/create-ae-recipe/scripts/media.py +253 -0
  64. package/editions/ae/skills/create-ae-recipe/scripts/setup.sh +17 -0
  65. package/editions/ae/skills/create-ae-video/SKILL.md +88 -0
  66. package/editions/ae/skills/create-ae-video/references/templates.md +90 -0
  67. package/editions/ae/skills/create-ae-video/scripts/preflight.js +99 -0
  68. package/editions/ae/skills/use-ae-recipes/SKILL.md +99 -0
  69. package/editions/ae/skills/use-ae-recipes/scripts/contact-sheet.jsx +10 -0
  70. package/editions/ae/skills/use-ae-recipes/scripts/edit-text.jsx +12 -0
  71. package/editions/ae/skills/use-ae-recipes/scripts/remove-comp.jsx +18 -0
  72. package/editions/pr/README.md +60 -0
  73. package/editions/pr/SCORE_PROCESS.md +41 -0
  74. package/editions/pr/client/aeb.js +9 -0
  75. package/editions/pr/examples/frame.js +6 -0
  76. package/editions/pr/examples/hello.js +4 -0
  77. package/editions/pr/organize.default.json +245 -0
  78. package/editions/pr/package.json +7 -0
  79. package/editions/pr/plugin/actions.js +79 -0
  80. package/editions/pr/plugin/dev.js +19 -0
  81. package/editions/pr/plugin/icons/README.md +4 -0
  82. package/editions/pr/plugin/icons/file-code.svg +6 -0
  83. package/editions/pr/plugin/icons/folder.svg +3 -0
  84. package/editions/pr/plugin/icons/power-off.svg +4 -0
  85. package/editions/pr/plugin/icons/power-on.svg +4 -0
  86. package/editions/pr/plugin/icons/settings.svg +4 -0
  87. package/editions/pr/plugin/icons/status-error.svg +4 -0
  88. package/editions/pr/plugin/icons/status-ok.svg +4 -0
  89. package/editions/pr/plugin/icons/status-rejected.svg +4 -0
  90. package/editions/pr/plugin/icons/status-timeout.svg +4 -0
  91. package/editions/pr/plugin/icons/status-unknown.svg +5 -0
  92. package/editions/pr/plugin/incremental.js +212 -0
  93. package/editions/pr/plugin/index.html +195 -0
  94. package/editions/pr/plugin/index.js +710 -0
  95. package/editions/pr/plugin/manifest.json +45 -0
  96. package/editions/pr/plugin/organize.js +223 -0
  97. package/editions/pr/skills/score-video/SKILL.md +69 -0
  98. package/editions/pr/skills/score-video/scripts/mix.py +112 -0
  99. package/editions/pr/skills/score-video/scripts/place.js +63 -0
  100. package/lib/ae.js +754 -0
  101. package/lib/common.js +132 -0
  102. package/lib/install.js +148 -0
  103. package/lib/main.js +107 -0
  104. package/lib/payload.js +60 -0
  105. package/lib/pr.js +239 -0
  106. package/lib/update.js +118 -0
  107. package/package.json +35 -4
  108. package/skills/create-video/SKILL.md +72 -0
  109. package/skills/create-video/references/lessons.md +31 -0
  110. package/skills/create-video/references/project-conventions.md +46 -0
  111. package/skills/create-video/scripts/ae/list-project.jsx +8 -0
  112. package/skills/create-video/scripts/ae/move-chips.jsx +14 -0
  113. package/skills/create-video/scripts/ae/organize-project.jsx +25 -0
  114. package/skills/create-video/scripts/ae/quadrant-chips.jsx +143 -0
  115. package/skills/create-video/scripts/ae/render-comps.jsx +16 -0
  116. package/skills/create-video/scripts/premiere/export-sequences.js +22 -0
  117. package/skills/create-video/scripts/premiere/make-sequences.js +24 -0
  118. package/skills/create-video/scripts/premiere/swap-media.js +43 -0
package/AGENTS.md ADDED
@@ -0,0 +1,106 @@
1
+ # Playrig: guide for coding agents
2
+
3
+ Playrig lets you control After Effects and Premiere Pro. You write a job script, submit it with the `playrig` CLI (alias `prg`), read the result, look at the frames, and iterate. This file is the canonical guide for any agent (Claude Code, Codex, others).
4
+
5
+ | Edition | App | Job language | Job global |
6
+ |---|---|---|---|
7
+ | Playrig for After Effects (`ae`) | After Effects | ExtendScript (ES3), `.jsx` | `PLAYRIG` (`BRIDGE` is an alias) |
8
+ | Playrig for Premiere Pro (`pr`) | Premiere Pro 25.6+ | modern JS in an async function body (`await` works), `.js` | `PLAYRIG` (`BRIDGE` is an alias), plus `ppro` (the `premierepro` module), `alert`, `confirm` |
9
+
10
+ Only the editions the user installed work. Check which app is open and that its panel is started before submitting anything (with no panel answering, a job ends with "No result ... Is the app open with the Playrig panel started?").
11
+
12
+ ## Submit a job
13
+
14
+ ```
15
+ playrig ae run job.jsx --snap "MAIN@4.5,9" --inspect "04_UI:2" --timeout 120
16
+ playrig pr run job.js --snap "My Sequence@4.5,9" --timeout 120
17
+ playrig ae snap "MAIN@4.5,9" # frames only, no job script
18
+ playrig pr inspect "My Sequence" # structure only
19
+ playrig status <id> [--app ae|pr]
20
+ playrig tail [--app ae|pr] [--all | --project <name>]
21
+ playrig ae lib init|list|show|run|check|index|new ... # your own recipe library (--lib <folder>)
22
+ playrig ae scratch start | status | clean --yes # same for `pr`
23
+ playrig update [ae|pr|cli] [--check] # newer versions; exit code 10 = update available
24
+ playrig where [ae|pr|library|skills|inbox:ae|inbox:pr]
25
+ ```
26
+
27
+ - Exit code is non-zero unless the job status is `ok`. `--json` prints the raw `result.json`.
28
+ - Jobs travel through a folder: `<root>/inbox/<id>.jsx|.js` (+ `<id>.json` options) in, `<root>/out/<id>/result.json` out. Root: `--root`, else `$PLAYRIG_ROOT/<ae|pr>`, else `~/Documents/Playrig/<ae|pr>` (an existing `~/Documents/AE Bridge` or `Premiere Bridge` is used until the new folder exists).
29
+ - The old `aeb` command still works (it prints a deprecation notice and forwards). Old job scripts that use `BRIDGE.` still run. The CLI and the installed panel must be updated together: a new CLI against an old panel fails with "PLAYRIG is undefined".
30
+
31
+ ## Read results and snapshots
32
+
33
+ `playrig` prints status, `action`, `about`, `project:`, the error (message, line, source line), the log, the absolute path of each snapshot PNG, and the path to `result.json`. **Open the PNGs with your image reader and look at them.** Snapshots are taken after the job ends, from the final state.
34
+
35
+ - **Always check the `project:` line** before acting on a log, and print the open project path at the start of work (`app.project.file` in AE, `PLAYRIG.project.path` in Premiere). The open project has not always been the expected one.
36
+ - `project log:` shows the project log folder. If it says NOT SYNCED, tell the user (usually the project is unsaved).
37
+ - Before starting on a project, read `<project folder>/EDIT_LOGS/JOURNAL.md`, `assets.ae.md` (AE) or `assets.md` (Premiere), and `NOTES.md` if present (decisions written by hand).
38
+ - **Never save the user's project** from a job and never overwrite the project file. Edits are in memory until they save; say so in your report.
39
+
40
+ ## Declare an action and describe every job
41
+
42
+ Every job has one action. Put it in the first lines of the job, then a one-line description:
43
+
44
+ ```js
45
+ // @action animate.keyframes
46
+ // Moved the chip pops 0.2 s later to follow the new timing
47
+ ```
48
+ (or `--action <id> --desc "..."`). The description appears in the panel. Undeclared jobs are inferred and shown as "(inferred)".
49
+
50
+ - AE actions (`packages/ae/lib/actions.json`): `bridge.test`, `project.inspect`, `frame.export`, `footage.import`, `comp.create`, `precomp.create`, `layer.add`, `layer.edit`, `text.edit`, `shape.edit`, `effect.add`, `animate.keyframes`, `expression.set`, `render.queue`, `recipe.run`, `recipe.<id>`, `scratch.baseline`, `scratch.cleanup`, `job.rejected`, `custom`.
51
+ - Premiere actions (`packages/pr/plugin/actions.js`): `bridge.test`, `project.inspect`, `frame.export`, `media.import`, `sequence.clone`, `sequence.rename`, `sequence.delete`, `clip.place`, `clip.edit`, `score.place`, `score.sync`, `audio.level`, `audio.effect`, `organize.project`, `organize.archive`, `organize.structure`, `scratch.baseline`, `scratch.cleanup`, `job.rejected`, `custom`.
52
+ - When a genuinely new kind of job appears, add an entry to the list instead of leaving it `custom`.
53
+
54
+ ## Inside a job
55
+
56
+ Each job is one undo group labelled `Playrig: <id>` (AE: automatic; Premiere: one `PLAYRIG.transact(...)` per undo step). One Edit > Undo reverts it.
57
+
58
+ - AE: `PLAYRIG.log(msg)`, `.comp(name)`, `.snap(comp, time)`, `.contactSheet(comp, start, end, step)`, `.inspect(comp, depth, time)`, `.ret(value)`, `.root`, `.json.stringify/parse`. Parameters passed with `--param k=v` arrive as `var P`.
59
+ - Premiere: `PLAYRIG.project`, `.sequence(name)`, `.transact(name, ca => ...)`, `.sync / .adopt / .owned / .clips / .place / .remove / .tag / .untag`, `.setLevelDb`, `.levelKeys`, `.dbToLevel`, organizer calls (`.organizeProject`, `.importInto`, `.ensureBin`, `.moveItem`, ...). Full list: `packages/pr/README.md`.
60
+ - `alert()` is redirected to the log; `confirm()` returns false. Don't rely on dialogs.
61
+ - A job cannot be interrupted once started; keep loops bounded. Jobs share one engine, so wrap code in a function and don't leak globals.
62
+ - If a job errors halfway, its partial changes stay.
63
+
64
+ ## Rules for jobs
65
+
66
+ ### After Effects (each one came from a real bug)
67
+
68
+ 1. **Shape group order: the first group draws on top.** A background rectangle added before content hides it. After adding each group, move it to the top with `group.moveTo(1)`, or add groups front to back.
69
+ 2. **Keyframes on layers that don't start at 0.** Opacity keys set by script on a precomp layer with `startTime ≠ 0` ended up offset by that start time. Avoid keyframing offset layers from scripts: animate inside the precomp, or set keys then check `keyTime()` against what you intended.
70
+ 3. **ExtendScript is ES3.** No `let`/`const`, arrow functions, template literals, `Array.prototype.map/forEach/indexOf`, `JSON`, `Math.sign` or `String.trim`. (`PLAYRIG.json.stringify/parse` exist.)
71
+ 4. **Property references go stale.** After `addProperty()` on a group, earlier references to siblings can become invalid. Re-fetch by index or matchName after each add.
72
+ 5. **Use matchNames, not display names**, wherever one exists (`"ADBE Vector Shape - Rect"`, `"ADBE Text Animator"`, ...). Display names break in non-English After Effects.
73
+ 6. **Expression Selector amount should return `[v, v, v]`**, not a scalar.
74
+ 7. **Always finish a job with a snapshot** of the frames you changed and look at them before reporting success. Status `ok` doesn't mean the picture is right.
75
+ 8. Fonts must be installed. After Effects substitutes missing fonts silently: check `textInfo.font` in `inspect` output.
76
+ 9. Change what exists, don't rebuild: update existing comps in place; `lib run --replace` replaces only that recipe's own layers (tagged `aeb:<recipe>:<instance>` in the layer comment; that tag name is kept for compatibility). Experiment in `SCRATCH-*` comps and clean up with `scratch`.
77
+
78
+ ### Premiere Pro (each one cost a debugging round)
79
+
80
+ 1. **Create actions inside `PLAYRIG.transact(name, ca => ...)`**, not before it (otherwise "The script object is no longer valid"). One `transact` = one undo step.
81
+ 2. **Keyframe times are SOURCE time.** A key at timeline `t` on a clip with in-point `i` and start `s` goes at `t + (i - s)`. Premiere doesn't validate it. `levelKeys` handles it.
82
+ 3. **Volume > Level: 0 dB = 0.1778** (`dbToLevel(db)`). Channel Volume 0.178 = unity. Read a known 0 dB clip before judging a mix.
83
+ 4. **`createSetInPointAction` trims the head** (clip start moves, out point stays). To slip the source under a fixed position: set in point, set out point, then `createMoveAction` back.
84
+ 5. **`createSetOutPointAction` extends or trims the tail.** To extend a clip by 2 s add 2 to its out point (the source must have the media).
85
+ 6. **`createOverwriteItemAction` snaps to frames** (2.6 s becomes 2.58 s at 24 fps) and overwrites whatever is there; a longer clip overwritten by a shorter one leaves a remnant. Check `getTrackItems` afterwards or remove the old clip first (what `sync` does).
86
+ 7. **Removing clips:** build the selection inside `TrackItemSelection.createEmptySelection(sel => ...)` and add the remove action in that callback. `createRemoveItemsAction` has failed in practice; prefer `sync`. Project items: `parentBin.createRemoveItemAction(item)`; sequences: `project.deleteSequence(seq)`.
87
+ 8. **Importing:** `PLAYRIG.importInto(paths, binPath)` (creates the bin). Never leave imports loose at the root. Look items up recursively. Bins are created, renamed and moved from the PARENT.
88
+ 9. **Effects:** `ppro.AudioFilterFactory.createComponentByDisplayName("Studio Reverb", clip)` then `chain.createAppendComponentAction(comp)`. Values are normalised 0 to 1; read them back. Don't assume effect or param names from another language or version: list `getDisplayNames()` / `displayName` first.
89
+ 10. **Snapshots** are written at the sequence's own size. An empty timeline gives black frames, which is correct. Always snapshot after a picture change.
90
+ 11. **Audio cannot be auditioned from here.** Verify by reading back clip times, levels and keyframes and by measuring files with ffmpeg; say plainly that nothing was listened to.
91
+ 12. **Change what you own.** Clips Playrig places are tagged with a name suffix `[pb:<family>:<key>]` (kept for compatibility). `await PLAYRIG.sync(seq, "sfx", desired)` moves, swaps, adds or removes only tagged clips; running it twice changes nothing; pass `{ dryRun: true }` to preview. Bring hand-placed clips under management once with `adopt`. Don't delete a sequence or empty a track for a small change.
92
+ 13. **Keep the project organized.** The bin scheme is data (`<project>/EDIT_LOGS/organize.json`, else the personal default, else `packages/pr/organize.default.json`). Dry-run `organizeProject({ dryRun: true })` before reorganizing a project that has drifted. Archive, never delete.
93
+ 14. Scratch experiments (cloning a sequence, test imports): `playrig pr scratch start` first, `scratch clean --yes` after.
94
+
95
+ ## Skills (optional, Claude Code)
96
+
97
+ `playrig install skills` copies the skills into `./.claude/skills` (`--global` for `~/.claude/skills`):
98
+ - `create-video`: brief to export across both apps (start here for a video task).
99
+ - `create-ae-video`, `use-ae-recipes`, `create-ae-recipe`: build After Effects scenes from your own recipe library, and add recipes to it (from a description or a reference video).
100
+ - `score-video`: music and sound effects in Premiere, via Epidemic Sound.
101
+
102
+ **Recipes are yours.** Playrig ships the tooling and an empty starter library, not recipes. Run `playrig ae lib init` once to create `~/Documents/Playrig/library` (or point `--lib <folder>` / `$PLAYRIG_LIBRARY` at one), then grow it with `create-ae-recipe` or `playrig ae lib new <category>/<id>`, and run `playrig ae lib index`. `playrig where library` prints the folder in use; read its `INDEX.md` first, open one recipe, run it with `playrig ae lib run <id> --param k=v`.
103
+
104
+ ## Security
105
+
106
+ Anything that can write to the inbox can run code in the app. Keep the inbox private. A panel does nothing until the user presses Start.
package/LICENSE ADDED
@@ -0,0 +1,37 @@
1
+ Playrig License, version 1.0
2
+
3
+ Copyright (c) 2026 Vivek Nigam. All rights reserved.
4
+
5
+ "Playrig" (the "Software") means the software distributed with this notice, including the After Effects panel, the Premiere Pro panel, the command-line tool, the agent skills and their documentation, under whatever name it is released (the name may change). "Licensor" means Vivek Nigam. "You" means the person or organisation using the Software.
6
+
7
+ This is a source-available license. It is NOT an open-source license: you may read and use the Software, but you may not redistribute it.
8
+
9
+ 1. WHAT YOU MAY DO
10
+ You may, free of charge, install and run the Software, as obtained from the Licensor's official channels (the official npm package, the official releases page, or an Adobe distribution the Licensor has published), for your own work, including paid client or commercial video work, on computers you or your organisation own or control. You may keep the Software's copyright and license notices in place and share links to the official channels and to the official installation instructions.
11
+
12
+ 2. WHAT YOU MAY NOT DO
13
+ a. Distribute. You may not copy, publish, upload, host, resell, sublicense, rent, lend or otherwise make the Software, or any part of it, available to anyone else, whether modified or not, whether for money or free. This includes bundling it into another product, template, installer or course download, and mirroring it. Point people to the official channels instead.
14
+ b. Remove notices. You may not remove or change copyright, license or attribution notices.
15
+ c. Misrepresent. You may not present the Software, or a modified version, as your own work or as endorsed by the Licensor, and you get no right to use the name "Playrig" or any other name, logo or trademark of the Licensor.
16
+ d. Circumvent protections. You may not bypass or disable the signature and checksum checks that the Software uses to install updates, or use the update mechanism to deliver anything other than official releases.
17
+
18
+ 3. MODIFICATIONS MUST BE CONTRIBUTED BACK
19
+ You may modify the Software for your own use only on this condition: you must contribute every modification back to the Licensor, in a form the Licensor can use (a patch, a pull request or the changed files), through the contribution channel the Licensor publishes (currently the issue tracker at https://github.com/viveknigam3003/playrig-releases/issues, or any other channel stated on the official releases page), within 30 days of first using the modification. By contributing, you grant the Licensor a perpetual, worldwide, irrevocable, royalty-free, transferable license to use, modify, publish and distribute your contribution as part of the Software, under this license or any other, and you confirm that you have the right to do so. You keep no right to distribute your modification yourself (section 2a still applies). If you do not contribute a modification within that time, your license under section 1 ends for the modified version, and you must stop using that version.
20
+
21
+ 4. THIRD-PARTY MATERIAL
22
+ The Software includes icons from Tabler Icons (MIT License), which stay under their own license. The Software works with Adobe After Effects and Adobe Premiere Pro, which you must license separately from Adobe. The Licensor is not affiliated with Adobe. Adobe, After Effects and Premiere Pro are trademarks of Adobe Inc.
23
+
24
+ 5. OWNERSHIP
25
+ The Licensor keeps all rights not expressly granted. Nothing here transfers ownership of the Software to you. Your own projects, footage and the video you make with the Software belong to you.
26
+
27
+ 6. TERMINATION
28
+ Your license ends automatically if you breach this license. It also ends for versions the Licensor withdraws for security or legal reasons, if the Licensor gives notice through the official channels. On termination you must stop using the Software and delete your copies.
29
+
30
+ 7. NO WARRANTY
31
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. THE SOFTWARE CONTROLS OTHER APPLICATIONS AND CAN CHANGE PROJECTS AND FILES: KEEP BACKUPS OF YOUR WORK. THE SOFTWARE RUNS CODE INSIDE YOUR APPLICATIONS: KEEP ITS JOB FOLDER PRIVATE.
32
+
33
+ 8. LIMITATION OF LIABILITY
34
+ TO THE MAXIMUM EXTENT ALLOWED BY LAW, THE LICENSOR IS NOT LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES, OR FOR LOSS OF DATA, PROJECTS, PROFITS OR BUSINESS, ARISING FROM THE SOFTWARE OR ITS USE, EVEN IF ADVISED OF THE POSSIBILITY. THE LICENSOR'S TOTAL LIABILITY FOR ANY CLAIM IS LIMITED TO THE AMOUNT YOU PAID FOR THE SOFTWARE, WHICH MAY BE ZERO.
35
+
36
+ 9. CHANGES TO THIS LICENSE
37
+ The Licensor may release new versions of the Software under a different license. Versions you already received stay under the license they came with.
package/README.md CHANGED
@@ -1,3 +1,78 @@
1
- # Temporary Holding Version
1
+ # Playrig
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Playrig lets Claude, Codex or any coding agent control After Effects and Premiere Pro, so you can "vibe edit" your videos while keeping the control and sophistication these apps give you out of the box.
4
+
5
+ It is one product with two editions: **Playrig for After Effects** and **Playrig for Premiere Pro**. Install one, or both.
6
+
7
+ ## Install
8
+
9
+ Requires Node 18 or newer.
10
+
11
+ ```bash
12
+ npm install -g playrig # the CLI: `playrig`, short alias `prg`
13
+
14
+ playrig install ae # Playrig for After Effects: panel into After Effects' ScriptUI Panels folder
15
+ playrig install pr # Playrig for Premiere Pro: builds "Playrig (PR).ccx" and opens the Creative Cloud installer
16
+ playrig install skills # optional: agent skills (video workflow, recipes, scoring) into ./.claude/skills (--global for ~/.claude/skills)
17
+ playrig install all # whatever applies of the above
18
+ ```
19
+
20
+ - **After Effects**: copies `Playrig.jsx` and `Playrig lib/` into every `Adobe After Effects*/Scripts/ScriptUI Panels` folder it finds. If the folder needs admin rights, the command prints the exact `sudo cp` line. Restart After Effects, then open the panel from the Window menu. An old `AE Bridge.jsx` panel must be deleted by hand.
21
+ - **Premiere Pro**: needs Premiere Pro 25.6 or newer. If the installer refuses the package (it is unsigned), load `plugin/manifest.json` through the Adobe UXP Developer Tool instead. Then open the panel from Window > Extensions.
22
+ - **Updates**: the After Effects panel updates itself from **Settings > About > Check for Updates** (and checks once a day, installing only when you agree unless you turn on automatic install). The Premiere Pro panel checks too and links to the new package; Creative Cloud delivers updates for marketplace installs. `playrig update` does the same from a terminal.
23
+ - Use `--dry-run` to see what would happen. `playrig where` shows where everything is.
24
+
25
+ ## Allow the apps to let Playrig work
26
+
27
+ - **After Effects**: Preferences > Scripting & Expressions > turn on **Allow Scripts to Write Files and Access Network**. Do this once.
28
+ - **Premiere Pro**: there is no such preference; it does not apply. The panel is a UXP plugin that declares file access in its manifest, and Premiere asks you to consent when you install it and the first time Playrig opens a file or folder. Say yes.
29
+
30
+ ## 30-second quickstart
31
+
32
+ **After Effects**
33
+
34
+ 1. Open a project, open **Window > Playrig**, press the power icon (**Start**).
35
+ 2. In a terminal: `playrig ae run "$(playrig where ae)/examples/hello.jsx"`
36
+ 3. Ask your agent: "Read AGENTS.md, then add a title comp and show me frame 2." Frames come back as PNGs the agent looks at.
37
+
38
+ **Premiere Pro**
39
+
40
+ 1. Open a project, open **Window > Extensions > Playrig**, press **Start**.
41
+ 2. In a terminal: `playrig pr run "$(playrig where pr)/examples/hello.js"`
42
+ 3. Ask your agent: "Read AGENTS.md, then list my sequences and export a frame at 4 seconds."
43
+
44
+ ## CLI reference
45
+
46
+ ```
47
+ playrig <ae|pr> run <job> [--id <id>] [--action <id>] [--desc "..."] [--snap "<comp or sequence>@t1,t2"]...
48
+ [--inspect "<comp>:<depth>" | "<sequence>"] [--timeout 120] [--no-undo] [--json] [--root <dir>]
49
+ playrig <ae|pr> snap "<comp or sequence>@t1,t2,..." export frames, no job script
50
+ playrig <ae|pr> inspect "<comp>:<depth>" | "<sequence>"
51
+ playrig status <id> [--app ae|pr] app is found for you when the id is unique
52
+ playrig tail [--app ae|pr] [--all | --project <name>] [--limit 10]
53
+ playrig <ae|pr> scratch start | status | clean --yes remove only what was added since start
54
+ playrig ae lib init|list|show|run|index|check|new ... your own recipe library (none is shipped; `lib init` creates a starter)
55
+ playrig install <ae|pr|skills|all> [--dry-run] [--no-open] [--to <folder>] [--global]
56
+ playrig update [ae|pr|cli] [--check] check for newer versions (exit code 10 = update available) and install
57
+ playrig where [ae|pr|library|skills|inbox:ae|inbox:pr]
58
+ ```
59
+
60
+ `prg` is the same command. `playrig run <file.jsx|.js>` picks the app from the extension. Job files are `.jsx` (ExtendScript) for After Effects and `.js` for Premiere Pro. Exit code is non-zero unless the job status is `ok`.
61
+
62
+ Inbox folder: `--root`, else `$PLAYRIG_ROOT/<ae|pr>`, else `~/Documents/Playrig/<ae|pr>`. An existing `~/Documents/AE Bridge` or `~/Documents/Premiere Bridge` keeps being used until the new folder exists.
63
+
64
+ Coming from the old names? `aeb ...` still works and prints a one-line deprecation notice, `BRIDGE.` in job scripts still works, and old panel settings are read on first start. Update the CLI and the panel together.
65
+
66
+ Agents: read [AGENTS.md](AGENTS.md).
67
+
68
+ ## Security
69
+
70
+ Anything that can write to the inbox folder can run code inside the app, with the app's access to your files. Keep the inbox in a private folder that only you can write to, and never share it or sync it to a folder others can write to. A panel does nothing until you press **Start**; stop it when you are not using it. The panels' only network use is the daily update check (switch it off in Settings > About). Updates for After Effects are installed only after a SHA-256 and signature check against a key shipped with the panel.
71
+
72
+ ## License
73
+
74
+ Free to use; not free to redistribute. Modifications must be contributed back. See [LICENSE](LICENSE).
75
+
76
+ ## Repository
77
+
78
+ One repo, two independently versioned editions: `packages/cli` (npm `playrig`), `packages/ae`, `packages/pr`. Tag releases per edition: `ae-v1.2.0`, `pr-v0.3.0`, `cli-v0.1.0`.
package/bin/playrig.js ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+ // playrig and its short alias prg both run this file.
4
+ require('../lib/main.js').run(process.argv.slice(2));
@@ -0,0 +1,144 @@
1
+ # Playrig for After Effects
2
+
3
+ A folder-based link between Claude and a live After Effects project (AE 2026, macOS and Windows).
4
+ Claude writes an ExtendScript job into a watched folder; a dockable panel runs it in your open project and writes back a log, errors, project inspection and PNG frames. You only render the final output.
5
+
6
+ ## Security: read this first
7
+
8
+ **Anything that can write to `<root>/inbox` can run arbitrary code inside After Effects**, with access to your files. Use a private folder that only you (and the tools you trust) can write to. Don't put the root in a shared or synced-to-others location.
9
+
10
+ - The panel runs only `*.jsx` files from `<root>/inbox` whose name matches `^[A-Za-z0-9_-]{1,64}$` and which are under 2 MB. Anything else is marked `rejected` and not run.
11
+ - The only network use is the update check (see Updates below): once a day it asks GitHub for `updates/versions.json`, and downloads only when you choose to install. Turn it off in Settings > About. Jobs themselves never use the network.
12
+ - It is off until you press **Start**, and off again after every After Effects restart unless you tick **Start automatically**.
13
+ - Each job is one undo step. Optionally, a backup copy of the project file is made before each job.
14
+
15
+ ## Prerequisites
16
+
17
+ - After Effects → Preferences → Scripting & Expressions → **Allow Scripts to Write Files and Access Network**: ON.
18
+ - Fonts used by jobs must be installed. After Effects substitutes missing fonts silently; `inspect` reports the font in use (`textInfo.font`).
19
+ - Node 18+ for the `playrig` CLI.
20
+
21
+ ## Install
22
+
23
+ `playrig install ae` does this for you (it prints a `sudo` line if the folder needs admin rights). By hand: copy into After Effects' `Scripts/ScriptUI Panels` folder (macOS `/Applications/Adobe After Effects <version>/Scripts/ScriptUI Panels/`, Windows `C:\Program Files\Adobe\Adobe After Effects <version>\Support Files\Scripts\ScriptUI Panels\`):
24
+
25
+ 1. `panel/Playrig.jsx` into that folder.
26
+ 2. The contents of `lib/` (`bridge-api.jsxinc`, `panel-core.jsxinc`, `actions.json`, `icons/png/`; `dev.jsxinc` is dev only) into a new folder `Playrig lib/` next to it.
27
+ 3. Restart After Effects and open **Window > Playrig** (the menu entry is the panel's file name).
28
+ 4. Press the **power icon** to start, or open the **gear** and tick **Start automatically**. The folder (default `~/Documents/Playrig/ae`; an existing `~/Documents/AE Bridge` is used until the new one exists) is set in Settings > General.
29
+
30
+ Upgrading from "AE Bridge": delete `AE Bridge.jsx` and `AE Bridge lib/`; saved settings are picked up automatically.
31
+
32
+ ## Updates
33
+
34
+ `Playrig.jsx` in ScriptUI Panels is a small, stable stub. The real panel lives in `Playrig lib/` beside it, and a newer verified copy in your user data folder (`~/Library/Application Support/Playrig/ae/current`, or `%APPDATA%\Playrig\ae\current`) is preferred when there is one. So updates install without admin rights; restart After Effects to use them.
35
+
36
+ - **Settings > About > Check for Updates**: reads the feed, shows what's new, and offers **Install update**. A banner also appears in the panel when one is found.
37
+ - **Check for updates automatically** (on by default): once a day. **Install updates automatically** is off by default.
38
+ - An update is installed only if its URL is on the Playrig GitHub releases page, its SHA-256 matches the feed, and its signature verifies against `update-key.pem` shipped with the panel. Signature checks use `openssl` (macOS has it; stock Windows doesn't). Without it the panel only reports the update: run `playrig update ae`, which verifies natively.
39
+ - The previous version is kept in `.../ae/previous`. To go back, delete `current` and rename `previous` to `current`.
40
+
41
+ ## The panel
42
+
43
+ ```
44
+ Playrig for After Effects ● Idle ⏻ ⚙
45
+ Motion_Videos_AI (open project)
46
+
47
+ Recent jobs 35 jobs
48
+ Status Action Time
49
+ ✓ ok Add layers 02-10-26 17:42
50
+ ✗ error Create comp 02-10-26 16:50
51
+ (summary of the selected job) [Details...]
52
+ ```
53
+
54
+ - **Power icon**: grey = stopped, green = running. **Gear**: Playrig for After Effects Settings (General: bridge folder, Start automatically, Back up the project file before each job; About).
55
+ - **Recent jobs is per project**: it shows the jobs of the project that is open (read from `EDIT_LOGS/results/` beside the `.aep`) and switches when you open another project, even while the bridge is stopped. Latest 50, newest first. For an unsaved project only this session's jobs show ("Save the project to keep its job history with it").
56
+ - Select a row to see a one-line summary of what the job did under the list (ScriptUI has no per-row tooltips); **double-click** a row or press **Details...** for the job details window (what happened, action, id, start + duration, project, error, log, frames, returned value, result path). A `*` after an action means it was inferred from the script rather than declared.
57
+ - Status uses an icon plus the word: ok (green), error (red), rejected (orange), timeout (amber), unknown (grey).
58
+ - Dev only: the details window also shows the job script when `lib/dev.jsxinc` is present (see `DEV_ONLY.md`).
59
+
60
+ The panel creates `inbox/ running/ done/ out/<id>/ backups/ rejected/` under the root.
61
+
62
+ ## Use
63
+
64
+ ```
65
+ playrig ae run examples/hello.jsx
66
+ playrig ae run examples/snap.jsx --snap "Comp 1@0,1"
67
+ playrig ae run my-job.jsx --inspect "04_UI:2" --snap "MAIN - Rightfit 15s@4.5,9"
68
+ playrig ae status <id>
69
+ playrig ae tail
70
+ ```
71
+
72
+ Root: `--root`, else `PLAYRIG_ROOT`, else `~/Documents/Playrig/ae`. Flags: `--id`, `--timeout <sec>` (default 120), `--no-undo`, `--json` (raw result).
73
+ `playrig ae run` exits non-zero unless the status is `ok`.
74
+
75
+ Without the CLI: write `inbox/<id>.jsx.tmp`, rename to `inbox/<id>.jsx` (optionally write `inbox/<id>.json` options first), then poll for `out/<id>/result.json`.
76
+
77
+ Options JSON: `{"timeoutSec":120,"undoGroup":true,"snapshots":[{"comp":"X","times":[1,2]}],"inspect":{"comp":"X","depth":2,"time":0}}`
78
+
79
+ `result.json` fields: `id, status (ok|error|timeout|rejected), startedAt, durationMs, aeVersion, project{path,dirty}, action, actionSource (declared|inferred), description, error{message,line,fileName,source}, log[], snapshots[{comp,time,file,ok}], inspect, returnValue`, plus `actionLabel` (recipe jobs), `backup` and `sync`.
80
+
81
+ ### Actions and descriptions
82
+
83
+ Every job has one **action** from the defined list in `lib/actions.json` (shared data: the panel, the CLI and a later UXP port all read it). It is the table's *Action* column. Declare it in the first lines of the job, then add a one-line description (the summary under the table and "What happened" in the details):
84
+
85
+ ```js
86
+ // @action layer.add
87
+ // Added three null layers for the camera rig
88
+ ```
89
+
90
+ or `playrig ae run job.jsx --action layer.add --desc "..."`. `playrig ae lib run <id>` sets `recipe.<id>` (label = the recipe's name) and the recipe summary itself. Undeclared jobs are classified from what the script calls (rules in `actions.json`, `inferBySource`) and shown as inferred; unknown ids show as "Custom action". Add a new entry to `actions.json` when a new kind of job appears.
91
+
92
+ Actions: `bridge.test, project.inspect, frame.export, footage.import, comp.create, precomp.create, layer.add, layer.edit, text.edit, shape.edit, effect.add, animate.keyframes, expression.set, render.queue, recipe.run, scratch.baseline, scratch.cleanup, job.rejected, custom`, and `recipe.<id>`.
93
+
94
+ `playrig ae tail` shows the latest jobs of the project of the most recent job (prints `Jobs for: <project>`); `--all` lists every project, `--project <name>` picks one.
95
+
96
+ ### PLAYRIG API in jobs (`BRIDGE` is kept as an alias)
97
+
98
+ `PLAYRIG.log(msg)`, `PLAYRIG.comp(name)`, `PLAYRIG.snap(comp, time)`, `PLAYRIG.contactSheet(comp, start, end, step)`, `PLAYRIG.inspect(comp, depth, time)` (depth 0 = that comp only), `PLAYRIG.ret(value)`, `PLAYRIG.root`, `PLAYRIG.json.stringify/parse`.
99
+
100
+ Rules for writing jobs are in `CLAUDE.md`.
101
+
102
+ ## Project-folder log (travels with the project)
103
+
104
+ After every job the panel mirrors its work into `EDIT_LOGS/` next to the `.aep` (the same folder name the Playrig for Premiere Pro uses; an older `AE-BRIDGE/` folder is renamed to it on the first job after the update):
105
+
106
+ ```
107
+ <project folder>/EDIT_LOGS/
108
+ ├── README.md how to resume on another system
109
+ ├── JOURNAL.md chronological record of every job: status, errors, log, snapshots
110
+ ├── jobs/ the exact <id>.jsx (+ <id>.json options) that ran
111
+ ├── results/<id>/ result.json + PNG snapshots
112
+ └── assets.ae.md/.json footage (relative paths, MISSING / EXTERNAL flags), comps and fonts, refreshed each job
113
+ ```
114
+
115
+ (`assets.ae.*` is named so it never overwrites the Playrig for Premiere Pro's `assets.md` when a Premiere and an AE project share a folder; `JOURNAL.md` is shared and each entry says which job it is. The panel's table and `playrig ae tail` only list results whose `project.path` is the open project.)
116
+
117
+ Move the whole project folder and a new session can read `JOURNAL.md` and `assets.ae.md` to see what was done and what is available. The root folder (`inbox/ out/ done/`) stays the transport; `EDIT_LOGS/` is the durable record. If the project has never been saved it has no folder: `result.sync` says so and the jobs are backfilled after the first job that runs on a saved project. Sync failures never fail a job; they are reported in `result.sync` (and by `aeb`). Footage outside the project folder is flagged EXTERNAL because it won't move with it; collect files into the project folder to make it portable.
118
+
119
+ ## Known limitations and notes
120
+
121
+ - **Timeouts are advisory.** ExtendScript can't interrupt a running script. If a job runs longer than `timeoutSec`, it is marked `timeout` once it returns. An infinite loop freezes After Effects.
122
+ - **Backups copy the saved file.** `app.project.save(File)` behaves like Save As and would re-point the open project at the backup, so the panel instead copies the project file on disk (`<root>/backups/<name>-<id>.aep`). The copy reflects the last save, not unsaved edits; `result.backup.reflectsUnsavedChanges` is `false`. Unsaved projects get no backup.
123
+ - `project.dirty` is reported only if the scripting DOM exposes it; otherwise `null`.
124
+ - Snapshots use `comp.saveFrameToPng` and then wait up to 10 s for the file to exist with non-zero size.
125
+ - Closing the panel stops polling.
126
+ - Project organization (folders/auto-filing, as in the Playrig for Premiere Pro) is deliberately **not** part of the Playrig for After Effects (decided with the user, 2026-10-02).
127
+ - Jobs share one persistent ExtendScript engine (`#targetengine "playrig"`), so globals can leak between jobs.
128
+
129
+ ## Status of verification
130
+
131
+ This was written without access to After Effects, so none of the After Effects-side behavior has been run yet. Please run the acceptance checks below on v26.x and note results here (in particular whether `saveFrameToPng` returns before the file is written, and whether `project.dirty` exists).
132
+
133
+ 1. `hello.jsx` → `ok` within ~2 s.
134
+ 2. A job with `throw new Error("boom")` → `error` with message, line and source.
135
+ 3. `snap.jsx` → non-empty, valid 1920×1080 PNG.
136
+ 4. Inspect your `04_UI` comp at depth 2 → panels, parents, key times, shape group order.
137
+ 5. A job adding 3 layers → one Edit → Undo removes all 3.
138
+ 6. A job calling `alert("x")` doesn't block; `x` appears in the log.
139
+ 7. `playrig ae run examples/snap.jsx --snap "Comp 1@0,1"` → prints paths, exit 0.
140
+ 8. A file named `bad name!.jsx` in `inbox/` → `rejected`, not run.
141
+
142
+ ## Still unverified (panel UX update, 2026-10-02)
143
+
144
+ Written and unit-tested without driving After Effects' UI (AE 26.5 installed; the screen-control tool was unavailable). Verified: JS syntax of all panel/lib files, `panel-core.jsxinc` against a mock File/Folder (header parsing, inference, per-project history with 70 results from two projects, sorting, 50-row limit), `playrig ae tail/--action/--desc`. **Not yet seen in AE:** ScriptUI layout and spacing (docked and floating), the 3-column listbox with header and icons, `iconbutton` power/gear icons and 16 px PNGs on a retina display, `scheduleTask` project watcher, Settings dialog (path validation, Browse), details window sizing, `AE-BRIDGE/` -> `EDIT_LOGS/` rename on the first job, opening the About links. Needs a screenshot pass with the user.
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+ // Deprecated: `aeb` is now `playrig ae <command>`. Kept so old commands and scripts keep working; it prints a notice and forwards.
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+ const candidates = [path.join(__dirname, '..', '..', 'cli', 'lib', 'main.js'), path.join(__dirname, '..', '..', '..', 'lib', 'main.js')];
7
+ const main = candidates.find((f) => fs.existsSync(f));
8
+ if (!main) { console.error('aeb is deprecated and could not find the playrig CLI. Install it: npm install -g playrig'); process.exit(2); }
9
+ require(main).legacy('ae', process.argv.slice(2));
@@ -0,0 +1,3 @@
1
+ // @action bridge.test
2
+ // Checks that Playrig can run a job (logs a greeting, changes nothing)
3
+ PLAYRIG.log("hi from After Effects");
@@ -0,0 +1,7 @@
1
+ // @action project.inspect
2
+ // Inspects the comp open in the viewer (depth 2) and returns the tree as the job's returnValue.
3
+ var item = app.project.activeItem;
4
+ if (!(item instanceof CompItem)) {
5
+ throw new Error("Open a comp in the viewer first, or edit this file to name one.");
6
+ }
7
+ PLAYRIG.ret(PLAYRIG.inspect(item.name, 2, item.time));
@@ -0,0 +1,15 @@
1
+ // @action comp.create
2
+ // Creates (or reuses) a 1920x1080 "Comp 1" with a red solid and snaps it at time 0.
3
+ var comp = null, i, it;
4
+ for (i = 1; i <= app.project.numItems; i++) {
5
+ it = app.project.item(i);
6
+ if (it instanceof CompItem && it.name === "Comp 1") { comp = it; break; }
7
+ }
8
+ if (!comp) {
9
+ comp = app.project.items.addComp("Comp 1", 1920, 1080, 1, 5, 30);
10
+ comp.layers.addSolid([1, 0, 0], "Red", 1920, 1080, 1, 5);
11
+ PLAYRIG.log("created Comp 1");
12
+ } else {
13
+ PLAYRIG.log("reusing Comp 1");
14
+ }
15
+ PLAYRIG.snap("Comp 1", 0);
@@ -0,0 +1,159 @@
1
+ {
2
+ "_about": "Shared, engine-neutral data for the Playrig for After Effects: read by the ExtendScript panel, by aeb (Node) and, later, by a UXP port. Plain JSON on purpose. Labels and summaries are display text only: renaming one renames it for every past and future job.",
3
+ "logFolder": "EDIT_LOGS",
4
+ "legacyLogFolder": "AE-BRIDGE",
5
+ "recipePrefix": "recipe.",
6
+ "actions": {
7
+ "bridge.test": {
8
+ "label": "Playrig test",
9
+ "summary": "Checked that Playrig can run a job. No project changes."
10
+ },
11
+ "project.inspect": {
12
+ "label": "Inspect project",
13
+ "summary": "Read comps, layers, effects or footage. No project changes."
14
+ },
15
+ "frame.export": {
16
+ "label": "Export frames",
17
+ "summary": "Saved still frames from a composition."
18
+ },
19
+ "footage.import": {
20
+ "label": "Import footage",
21
+ "summary": "Imported files into the project."
22
+ },
23
+ "comp.create": {
24
+ "label": "Create comp",
25
+ "summary": "Created a composition."
26
+ },
27
+ "precomp.create": {
28
+ "label": "Pre-compose layers",
29
+ "summary": "Moved layers into a new nested composition."
30
+ },
31
+ "layer.add": {
32
+ "label": "Add layers",
33
+ "summary": "Added solids, nulls, cameras, lights or footage layers to a comp."
34
+ },
35
+ "layer.edit": {
36
+ "label": "Edit layers",
37
+ "summary": "Moved, timed, parented, renamed or removed layers."
38
+ },
39
+ "text.edit": {
40
+ "label": "Edit text",
41
+ "summary": "Created or changed text layers."
42
+ },
43
+ "shape.edit": {
44
+ "label": "Edit shapes",
45
+ "summary": "Created or changed shape layers and their contents."
46
+ },
47
+ "effect.add": {
48
+ "label": "Add effects",
49
+ "summary": "Added or changed effects on layers."
50
+ },
51
+ "animate.keyframes": {
52
+ "label": "Animate (keyframes)",
53
+ "summary": "Set or changed keyframes."
54
+ },
55
+ "expression.set": {
56
+ "label": "Set expressions",
57
+ "summary": "Wrote or changed property expressions."
58
+ },
59
+ "render.queue": {
60
+ "label": "Render queue",
61
+ "summary": "Added items to or changed the render queue."
62
+ },
63
+ "recipe.run": {
64
+ "label": "Run recipe",
65
+ "summary": "Ran a recipe from the motion library."
66
+ },
67
+ "scratch.baseline": {
68
+ "label": "Check test items",
69
+ "summary": "Recorded or listed the temporary items created while experimenting. No project changes."
70
+ },
71
+ "scratch.cleanup": {
72
+ "label": "Clean up test items",
73
+ "summary": "Removed temporary comps and items created while experimenting."
74
+ },
75
+ "job.rejected": {
76
+ "label": "Rejected job",
77
+ "summary": "The job was refused before it ran."
78
+ },
79
+ "custom": {
80
+ "label": "Custom action",
81
+ "summary": "A job with no declared action."
82
+ }
83
+ },
84
+ "inferById": [
85
+ {
86
+ "re": "^scratch-clean",
87
+ "flags": "i",
88
+ "action": "scratch.cleanup"
89
+ },
90
+ {
91
+ "re": "^scratch-(start|status)",
92
+ "flags": "i",
93
+ "action": "scratch.baseline"
94
+ }
95
+ ],
96
+ "_inferNote": "Applied to the job script in order, first match wins. Jobs that carry the recipe machinery (__aebPre) are recipe.run. Declaring the action in the job header beats all of this.",
97
+ "inferBySource": [
98
+ {
99
+ "re": "__aebPre\\s*\\(",
100
+ "action": "recipe.run"
101
+ },
102
+ {
103
+ "re": "renderQueue\\.(add|item)",
104
+ "action": "render.queue"
105
+ },
106
+ {
107
+ "re": "\\.remove\\(\\)[\\s\\S]*(scratch|SCRATCH)",
108
+ "action": "scratch.cleanup"
109
+ },
110
+ {
111
+ "re": "\\.precompose\\s*\\(",
112
+ "action": "precomp.create"
113
+ },
114
+ {
115
+ "re": "importFile\\s*\\(|ImportOptions",
116
+ "action": "footage.import"
117
+ },
118
+ {
119
+ "re": "\\.addComp\\s*\\(",
120
+ "action": "comp.create"
121
+ },
122
+ {
123
+ "re": "\\.addText\\s*\\(|\\.addBoxText\\s*\\(|ADBE Text Document|TextDocument",
124
+ "action": "text.edit"
125
+ },
126
+ {
127
+ "re": "\\.addShape\\s*\\(|ADBE Vector",
128
+ "action": "shape.edit"
129
+ },
130
+ {
131
+ "re": "\\.expression\\s*=",
132
+ "action": "expression.set"
133
+ },
134
+ {
135
+ "re": "setValueAtTime|setValuesAtTimes|\\.addKey\\s*\\(|setTemporalEase",
136
+ "action": "animate.keyframes"
137
+ },
138
+ {
139
+ "re": "ADBE Effect Parade|addProperty\\s*\\(\\s*[\"']ADBE",
140
+ "action": "effect.add"
141
+ },
142
+ {
143
+ "re": "\\.addSolid\\s*\\(|\\.addNull\\s*\\(|\\.addCamera\\s*\\(|\\.addLight\\s*\\(|layers\\.add\\s*\\(",
144
+ "action": "layer.add"
145
+ },
146
+ {
147
+ "re": "\\.parent\\s*=|\\.startTime\\s*=|\\.inPoint\\s*=|\\.outPoint\\s*=|\\.moveTo\\w*\\(|\\.name\\s*=",
148
+ "action": "layer.edit"
149
+ },
150
+ {
151
+ "re": "hi from After Effects|(?:PLAYRIG|PLAYPILOT|BRIDGE)\\.log\\(\\s*[\"']hi",
152
+ "action": "bridge.test"
153
+ },
154
+ {
155
+ "re": "(?:PLAYRIG|PLAYPILOT|BRIDGE)\\.inspect|(?:PLAYRIG|PLAYPILOT|BRIDGE)\\.snap|(?:PLAYRIG|PLAYPILOT|BRIDGE)\\.contactSheet|numItems|numLayers",
156
+ "action": "project.inspect"
157
+ }
158
+ ]
159
+ }