afterpresets 0.1.0 → 0.3.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 (173) hide show
  1. package/README.md +6 -4
  2. package/native-runtime/CMakeLists.txt +82 -0
  3. package/native-runtime/README.md +40 -0
  4. package/native-runtime/THIRD_PARTY_NOTICES.md +14 -0
  5. package/native-runtime/include/ap_native.h +223 -0
  6. package/native-runtime/src/apply.cpp +199 -0
  7. package/native-runtime/src/crypto.cpp +225 -0
  8. package/native-runtime/src/crypto.hpp +51 -0
  9. package/native-runtime/src/dialog.cpp +62 -0
  10. package/native-runtime/src/dialog.hpp +35 -0
  11. package/native-runtime/src/engine.cpp +909 -0
  12. package/native-runtime/src/engine.hpp +232 -0
  13. package/native-runtime/src/fsutil.cpp +291 -0
  14. package/native-runtime/src/fsutil.hpp +57 -0
  15. package/native-runtime/src/json.cpp +326 -0
  16. package/native-runtime/src/json.hpp +70 -0
  17. package/native-runtime/src/platform.hpp +83 -0
  18. package/native-runtime/src/platform_common.cpp +60 -0
  19. package/native-runtime/src/platform_mac.mm +314 -0
  20. package/native-runtime/src/platform_win.cpp +277 -0
  21. package/native-runtime/src/runtime.cpp +473 -0
  22. package/native-runtime/src/util.cpp +169 -0
  23. package/native-runtime/src/util.hpp +32 -0
  24. package/native-runtime/src/zip.cpp +243 -0
  25. package/native-runtime/src/zip.hpp +58 -0
  26. package/native-runtime/third_party/monocypher/LICENCE.md +167 -0
  27. package/native-runtime/third_party/monocypher/monocypher-ed25519.c +500 -0
  28. package/native-runtime/third_party/monocypher/monocypher-ed25519.h +140 -0
  29. package/native-runtime/third_party/monocypher/monocypher.c +2956 -0
  30. package/native-runtime/third_party/monocypher/monocypher.h +321 -0
  31. package/native-runtime/third_party/tinf/LICENSE +22 -0
  32. package/native-runtime/third_party/tinf/crc32.c +57 -0
  33. package/native-runtime/third_party/tinf/tinf.h +140 -0
  34. package/native-runtime/third_party/tinf/tinflate.c +636 -0
  35. package/native-runtime/vendor-files.json +39 -0
  36. package/package.json +6 -3
  37. package/runtime/docs/cep/host-after-effects.md +57 -0
  38. package/runtime/docs/cep/host-premiere.md +84 -0
  39. package/runtime/docs/{host.md → cep/host.md} +42 -16
  40. package/runtime/docs/{README.md → common/README.md} +10 -8
  41. package/runtime/docs/{assets.md → common/assets.md} +16 -2
  42. package/runtime/docs/{licensing.md → common/licensing.md} +1 -1
  43. package/runtime/docs/{panels.md → common/panels.md} +5 -5
  44. package/runtime/docs/{storage.md → common/storage.md} +5 -5
  45. package/runtime/docs/{updates.md → common/updates.md} +1 -1
  46. package/runtime/docs/native/README.md +44 -0
  47. package/runtime/docs/native/debugging.md +140 -0
  48. package/runtime/docs/native/rules.md +402 -0
  49. package/runtime/docs/native/testing.md +154 -0
  50. package/runtime/package.json +1 -1
  51. package/runtime/scripts/ae-sdk-docs/config.js +102 -0
  52. package/runtime/scripts/ae-sdk-docs/convert.js +430 -0
  53. package/runtime/scripts/ae-sdk-docs/index.js +314 -0
  54. package/runtime/scripts/ae-sdk-docs/source.js +205 -0
  55. package/runtime/scripts/ae-sdk-docs/split.js +170 -0
  56. package/runtime/scripts/ae-sdk-docs.js +72 -0
  57. package/runtime/src/host.js +1 -1
  58. package/runtime/src/updates.js +1 -1
  59. package/src/api/error-messages.js +1 -1
  60. package/src/build/build.js +7 -7
  61. package/src/build/html.js +1 -1
  62. package/src/build/jsx.js +2 -2
  63. package/src/build/runtime.js +3 -3
  64. package/src/check/check.js +3 -3
  65. package/src/check/native.js +14 -0
  66. package/src/check/pricing.js +1 -1
  67. package/src/check/types.js +2 -2
  68. package/src/cli.js +5 -5
  69. package/src/commands/add.js +8 -3
  70. package/src/commands/build.js +8 -2
  71. package/src/commands/check.js +11 -3
  72. package/src/commands/dev.js +9 -2
  73. package/src/commands/docs.js +5 -1
  74. package/src/commands/init.js +15 -3
  75. package/src/commands/push.js +5 -2
  76. package/src/commands/sdk.js +14 -0
  77. package/src/commands/testers.js +1 -1
  78. package/src/commands/upgrade.js +2 -2
  79. package/src/commands/whoami.js +1 -1
  80. package/src/config.js +1 -1
  81. package/src/dev/bridge.js +8 -0
  82. package/src/dev/cep-link.js +1 -1
  83. package/src/dev/debug-file.js +5 -5
  84. package/src/dev/native.js +3 -0
  85. package/src/dev/session.js +4 -3
  86. package/src/mcp/extendscript.js +10 -7
  87. package/src/mcp/host-target.js +1 -0
  88. package/src/mcp/panels.js +1 -1
  89. package/src/mcp/png.js +1 -0
  90. package/src/mcp/server.js +2 -2
  91. package/src/mcp/tools/capture.js +3 -0
  92. package/src/mcp/tools/host.js +1 -1
  93. package/src/mcp/tools/native.js +6 -0
  94. package/src/mcp/tools/panel.js +4 -4
  95. package/src/mcp/tools/project.js +47 -31
  96. package/src/mcp/tools/releases.js +23 -20
  97. package/src/native/build.js +27 -0
  98. package/src/native/cmake/CMakeLists.txt +88 -0
  99. package/src/native/cmake/zig-windows.cmake +19 -0
  100. package/src/native/effect.js +3 -0
  101. package/src/native/install.js +8 -0
  102. package/src/native/installers.js +4 -0
  103. package/src/native/pipl.js +20 -0
  104. package/src/native/restart.js +2 -0
  105. package/src/native/sdk.js +8 -0
  106. package/src/project/add-panel.js +1 -1
  107. package/src/project/docs.js +3 -1
  108. package/src/project/manifest.js +3 -2
  109. package/src/project/project.js +2 -2
  110. package/src/project/template.js +5 -1
  111. package/src/prompt.js +1 -1
  112. package/src/release/installers.js +4 -4
  113. package/src/release/native.js +3 -0
  114. package/src/release/package.js +1 -1
  115. package/src/release/publish.js +1 -1
  116. package/src/system/run-command.js +1 -1
  117. package/src/targets.js +1 -0
  118. package/src/user-config.js +2 -2
  119. package/template/cep/AGENTS.md +104 -0
  120. package/template/{README.md → cep/README.md} +16 -11
  121. package/template/cep/docs/code_guide.md +67 -0
  122. package/template/cep/docs/initial_setup.md +115 -0
  123. package/template/cep/docs/release_checklist.md +24 -0
  124. package/template/{src → cep/src}/features/home/home.html +4 -4
  125. package/template/{src → cep/src}/features/home/home.js +10 -11
  126. package/template/{src → cep/src}/shared/lib/host-theme.js +3 -3
  127. package/template/{src → cep/src}/shared/lib/view.js +1 -1
  128. package/template/{src → cep/src}/shared/ui/tokens.css +1 -1
  129. package/template/hosts/AGENTS.two-apps.md +12 -0
  130. package/template/hosts/aeft/AGENTS.host.md +10 -0
  131. package/template/hosts/aeft/jsx/aeft/home.jsx +16 -0
  132. package/template/hosts/ppro/AGENTS.host.md +15 -0
  133. package/template/hosts/ppro/jsx/ppro/home.jsx +20 -0
  134. package/template/native/.mcp.json +8 -0
  135. package/template/native/AGENTS.md +105 -0
  136. package/template/native/README.md +71 -0
  137. package/template/native/docs/code_guide.md +72 -0
  138. package/template/native/docs/initial_setup.md +179 -0
  139. package/template/native/docs/release_checklist.md +24 -0
  140. package/template/native/effect.json +16 -0
  141. package/template/native/gitignore +8 -0
  142. package/template/native/package.json +14 -0
  143. package/template/native/src/Effect.cpp +224 -0
  144. package/template/native/src/License.cpp +95 -0
  145. package/template/native/src/License.h +29 -0
  146. package/template/native/src/Render.h +68 -0
  147. package/vendor/afterpresets-additions/AfterEffects.d.ts +291 -0
  148. package/vendor/afterpresets-additions/Premiere.d.ts +179 -0
  149. package/vendor/types-for-adobe/Premiere/24.0/index.d.ts +2567 -0
  150. package/vendor/types-for-adobe/README.md +8 -4
  151. package/template/AGENTS.md +0 -168
  152. package/template/docs/initial_setup.md +0 -69
  153. package/template/jsx/home.jsx +0 -17
  154. /package/runtime/docs/{boot.md → common/boot.md} +0 -0
  155. /package/template/{.mcp.json → cep/.mcp.json} +0 -0
  156. /package/template/{gitignore → cep/gitignore} +0 -0
  157. /package/template/{package.json → cep/package.json} +0 -0
  158. /package/template/{src → cep/src}/features/home/home.css +0 -0
  159. /package/template/{src → cep/src}/features/license-screen/license-screen.css +0 -0
  160. /package/template/{src → cep/src}/features/license-screen/license-screen.html +0 -0
  161. /package/template/{src → cep/src}/features/license-screen/license-screen.js +0 -0
  162. /package/template/{src → cep/src}/features/update-screen/update-screen.css +0 -0
  163. /package/template/{src → cep/src}/features/update-screen/update-screen.html +0 -0
  164. /package/template/{src → cep/src}/features/update-screen/update-screen.js +0 -0
  165. /package/template/{src → cep/src}/panels/main/index.html +0 -0
  166. /package/template/{src → cep/src}/panels/main/main.js +0 -0
  167. /package/template/{src → cep/src}/shared/lib/dom.js +0 -0
  168. /package/template/{src → cep/src}/shared/lib/markdown.js +0 -0
  169. /package/template/{src → cep/src}/shared/ui/base.css +0 -0
  170. /package/template/{src → cep/src}/shared/ui/button.css +0 -0
  171. /package/template/{src → cep/src}/shared/ui/card.css +0 -0
  172. /package/template/{src → cep/src}/shared/ui/field.css +0 -0
  173. /package/template/{src → cep/src}/shared/ui/index.css +0 -0
@@ -0,0 +1,57 @@
1
+ ---
2
+ title: After Effects ExtendScript
3
+ description: "Rules for ExtendScript in After Effects (jsx/aeft/): undo groups, the active composition, 1-based collections, and the version range."
4
+ ---
5
+
6
+ # After Effects ExtendScript
7
+
8
+ Read [host.md](host.md) first: it explains `AP.host.eval` and how `jsx/` is
9
+ loaded. This page is about code that runs in After Effects. Put code that only
10
+ makes sense in After Effects in `jsx/aeft/`.
11
+
12
+ ## Undo
13
+
14
+ Wrap every change in one undo group so the user undoes the whole action with
15
+ one Ctrl/Cmd+Z, and close it in `finally`:
16
+
17
+ ```js
18
+ app.beginUndoGroup("Rename layers");
19
+ try {
20
+ /* changes */
21
+ } finally {
22
+ app.endUndoGroup();
23
+ }
24
+ ```
25
+
26
+ The MCP `host_eval` tool already wraps each call in an undo group named
27
+ "AfterPresets MCP".
28
+
29
+ ## The active composition
30
+
31
+ `app.project.activeItem` is often null or not a composition (a footage item, a
32
+ folder, or nothing selected). Check before using it:
33
+
34
+ ```js
35
+ var comp = app.project.activeItem;
36
+ if (!comp || !(comp instanceof CompItem)) {
37
+ return JSON.stringify({ ok: false, message: "Open or select a composition first." });
38
+ }
39
+ ```
40
+
41
+ ## Collections and times
42
+
43
+ - Collections are 1-based: `comp.layer(1)`, `app.project.item(1)`,
44
+ `comp.selectedLayers[0]` (a plain array, 0-based).
45
+ - Times are seconds (floating point). `comp.frameDuration` is one frame.
46
+
47
+ ## Versions
48
+
49
+ The extension's range is `hosts[].minVersion` in afterpresets.json (default
50
+ 17.0, After Effects 2020). Check `parseFloat(app.version)` before using newer
51
+ APIs and return `{ ok: false, message }` when they are missing.
52
+
53
+ ## Type hints
54
+
55
+ `ap check --types` checks `jsx/` against the After Effects 26.0 declarations
56
+ from types-for-adobe and lists likely mistakes. Hints can be wrong; confirm
57
+ with the MCP `host_eval` tool before changing working code.
@@ -0,0 +1,84 @@
1
+ ---
2
+ title: Premiere Pro ExtendScript
3
+ description: "Rules for ExtendScript in Premiere Pro (jsx/ppro/): no undo groups, times in ticks, 0-based track and clip collections, no QE DOM, and the version range."
4
+ ---
5
+
6
+ # Premiere Pro ExtendScript
7
+
8
+ Read [host.md](host.md) first: it explains `AP.host.eval` and how `jsx/` is
9
+ loaded. This page is about code that runs in Premiere Pro. Put code that only
10
+ makes sense in Premiere Pro in `jsx/ppro/`.
11
+
12
+ ## No undo groups
13
+
14
+ Premiere Pro's ExtendScript has no `beginUndoGroup`. Every change a script
15
+ makes (a clip moved, a marker added, a property set) is its own step in
16
+ Edit → Undo. Keep scripted edits small, do the checks before the first change,
17
+ and tell the user how many undo steps an action adds. The MCP `host_eval`
18
+ tool cannot group them either.
19
+
20
+ ## The active sequence
21
+
22
+ `app.project.activeSequence` is null when no sequence is open. Check it:
23
+
24
+ ```js
25
+ function myTool_sequenceInfo() {
26
+ var sequence = app.project.activeSequence;
27
+ if (!sequence) return JSON.stringify({ ok: false, message: "Open a sequence first." });
28
+ var clips = 0;
29
+ for (var i = 0; i < sequence.videoTracks.numTracks; i++) {
30
+ clips += sequence.videoTracks[i].clips.numItems;
31
+ }
32
+ return JSON.stringify({ ok: true, name: sequence.name, videoClips: clips });
33
+ }
34
+ ```
35
+
36
+ ## Collections
37
+
38
+ Tracks, clips, sequences and project items are 0-based collections with a
39
+ count property: `sequence.videoTracks[0]` with `numTracks`,
40
+ `track.clips[0]` with `numItems`, `app.project.sequences[0]` with
41
+ `numSequences`, `app.project.rootItem.children[0]` with `numItems`. Use a
42
+ `for` loop; they are not arrays.
43
+
44
+ ## Times are ticks
45
+
46
+ Premiere measures time in ticks: **254016000000 ticks per second**. A `Time`
47
+ object has `.seconds` (a number) and `.ticks` (a string). Create one with
48
+ `new Time()` and set either:
49
+
50
+ ```js
51
+ var t = new Time();
52
+ t.seconds = 2.5;
53
+ app.project.activeSequence.setPlayerPosition(t.ticks); // move the playhead to 2.5 s
54
+ var startSeconds = clip.start.seconds; // read a clip's start
55
+ ```
56
+
57
+ Frame-accurate maths: convert with the sequence's timebase
58
+ (`sequence.timebase`, ticks per frame, a string) instead of rounding seconds.
59
+
60
+ ## Things not to use
61
+
62
+ - **The QE DOM** (`app.enableQE()`, `qe.*`): undocumented, unsupported, and
63
+ it changes between versions. Do not ship code that needs it.
64
+ - Dialogs (`alert`, `confirm`, `File.openDialog`) block Premiere Pro while
65
+ open; the panel can show its own UI instead.
66
+
67
+ ## Projects
68
+
69
+ - `app.project` is the active project. Premiere Pro can have several projects
70
+ open (`app.projects`, `numProjects`).
71
+ - Save with `app.project.save()`. The MCP `host_scratch_project` tool creates a
72
+ new project in the temp folder and leaves the user's project open.
73
+
74
+ ## Versions
75
+
76
+ The extension's range is `hosts[].minVersion` in afterpresets.json (default
77
+ 14.0, Premiere Pro 2020). Check `app.version` before using newer APIs and
78
+ return `{ ok: false, message }` when they are missing.
79
+
80
+ ## Type hints
81
+
82
+ `ap check --types` checks `jsx/` against the Premiere Pro 24.0 declarations
83
+ from types-for-adobe (the newest set; newer APIs may be missing) and lists
84
+ likely mistakes. Hints can be wrong; confirm with the MCP `host_eval` tool.
@@ -1,21 +1,46 @@
1
1
  ---
2
- title: Calling After Effects
3
- description: Call ExtendScript functions from a panel with AP.host.eval, write jsx/ functions in ES3 that return JSON, and handle host errors.
2
+ title: Calling the app (ExtendScript)
3
+ description: Call ExtendScript functions in After Effects or Premiere Pro from a panel with AP.host.eval, write jsx/ functions in ES3 that return JSON, keep app-only code in jsx/aeft/ and jsx/ppro/, and handle host errors.
4
4
  ---
5
5
 
6
- # Calling After Effects
6
+ # Calling the app (ExtendScript)
7
7
 
8
- Panel code runs in a browser. Anything that touches After Effects (project,
9
- comps, layers, effects, files through `File`/`Folder`) runs in ExtendScript, in
10
- `jsx/`. `AP.host.eval` connects the two.
8
+ Panel code runs in a browser. Anything that touches the app (the project, its
9
+ compositions or sequences, layers or clips, files through `File`/`Folder`) runs
10
+ in ExtendScript, in `jsx/`. `AP.host.eval` connects the two. It works the same
11
+ in After Effects and Premiere Pro. What you can do in each app:
12
+
13
+ - [host-after-effects.md](host-after-effects.md): After Effects
14
+ - [host-premiere.md](host-premiere.md): Premiere Pro
11
15
 
12
16
  ## Where JSX lives
13
17
 
14
18
  Put ExtendScript in `jsx/`, one file per feature (for example
15
19
  `jsx/layers.jsx`; subfolders are fine). Every `.jsx` file there is loaded into
16
- After Effects once, before your app starts, and its functions are shared by
20
+ the app once, before your app starts, and its functions are shared by
17
21
  all panels. Call one from panel code with `ctx.host.eval("fnName", [args], cb)`.
18
22
 
23
+ Two folders are special (afterpresets.json `hosts` lists the apps):
24
+
25
+ | Folder | Loaded in |
26
+ |---|---|
27
+ | `jsx/aeft/` | After Effects only |
28
+ | `jsx/ppro/` | Premiere Pro only |
29
+ | everything else in `jsx/` | every app the extension targets |
30
+
31
+ An extension for both apps can define the same function in `jsx/aeft/` and
32
+ `jsx/ppro/` (for example `myTool_activeItemName`) and call it from shared panel
33
+ code; each app loads its own version. `ap check` warns about a folder for an
34
+ app the project does not target.
35
+
36
+ `AP.host.app` (also `ctx.host.app`) is the app running the panel: `"AEFT"`
37
+ (After Effects) or `"PPRO"` (Premiere Pro). Use it for wording that differs
38
+ between the apps, or to hide a feature that only one app has:
39
+
40
+ ```js
41
+ var noun = ctx.host.app === "PPRO" ? "sequence" : "composition";
42
+ ```
43
+
19
44
  - There is no list to keep: the CLI joins every `.jsx` file in alphabetical
20
45
  path order, with JSON support (json2) first, embeds the result in every
21
46
  panel's `main.js` (readable in `ap dev`, compiled to JSXBIN for releases),
@@ -38,11 +63,11 @@ Rules:
38
63
  objects).
39
64
  3. Return `JSON.stringify(...)`. Return a result object such as `{ ok: true, ... }`
40
65
  or `{ ok: false, message: "..." }` for expected problems.
41
- 4. Wrap changes to the project in `app.beginUndoGroup("Name")` /
42
- `app.endUndoGroup()`.
66
+ 4. Undo: in After Effects wrap changes in one undo group; Premiere Pro has
67
+ none (every change is its own undo step). See the app pages.
43
68
 
44
69
  ```js
45
- /* jsx/layers.jsx */
70
+ /* jsx/aeft/layers.jsx (After Effects) */
46
71
  function myTool_addNull(name) {
47
72
  var comp = app.project.activeItem;
48
73
  if (!comp || !(comp instanceof CompItem)) {
@@ -64,7 +89,7 @@ function myTool_addNull(name) {
64
89
  ```js
65
90
  AP.host.eval("myTool_addNull", ["Controller"], function (result) {
66
91
  if (!result || result.error) {
67
- showError(result ? result.error : "No answer from After Effects.");
92
+ showError(result ? result.error : "No answer from the app.");
68
93
  return;
69
94
  }
70
95
  if (!result.ok) {
@@ -92,19 +117,20 @@ values through `args`.
92
117
  | `result` | Cause |
93
118
  |---|---|
94
119
  | `{ error: "<message>" }` | Your function threw; the message is the thrown error's message. |
95
- | `{ error: "...is undefined" }` or similar | The function does not exist: check the name, and that its file is in `jsx/` and ends in `.jsx`. |
120
+ | `{ error: "...is undefined" }` or similar | The function does not exist: check the name, that its file is in `jsx/` and ends in `.jsx`, and that it is not in another app's folder (`jsx/aeft/`, `jsx/ppro/`). |
96
121
  | `{ error: "The host returned a non-JSON result.", raw }` | Your function returned a plain string. Return `JSON.stringify(...)`. |
97
122
  | `{ error: "The host script failed to run." }` | ExtendScript syntax error or an ES5+ feature in `jsx/`. |
98
- | `{ error: "Could not load host script: ..." }` | The embedded JSX failed to load. Read the message; usually a syntax error. |
123
+ | `{ error: "Could not load host script: ..." }` | The embedded JSX failed to load. Read the message; usually a syntax error. "This extension has no host script for X" means the build has no code for the running app (afterpresets.json `hosts`). |
99
124
 
100
125
  The JSX loads once per page. During `ap dev` every save rebuilds and reloads
101
126
  the open panels, which loads the new JSX too; after an update,
102
127
  `AP.updates.reload()` does the same. The new functions replace the old ones.
103
- Functions removed from the new code stay defined in After Effects until it
128
+ Functions removed from the new code stay defined in the app until it
104
129
  restarts, so never rely on a function being absent.
105
130
 
106
131
  ## Testing
107
132
 
108
133
  Call the function from the live panel and check the result and the project
109
- state. Use a disposable project or a duplicate composition for anything that
110
- changes layers, effects, files, or project data.
134
+ state. Use a disposable project (the MCP `host_scratch_project` tool) for
135
+ anything that changes the project. With the MCP tools, `host_eval` runs in the
136
+ app that runs the connected panel.
@@ -5,8 +5,8 @@ description: What the AfterPresets runtime does, and which reference file to rea
5
5
 
6
6
  # AfterPresets runtime reference
7
7
 
8
- These files are for the AI coding agent that builds an After Effects extension
9
- with AfterPresets. They describe the `AP.*` API that every panel gets.
8
+ These files are for the AI coding agent that builds an After Effects or Premiere
9
+ Pro extension with AfterPresets. They describe the `AP.*` API that every panel gets.
10
10
 
11
11
  ## What the runtime does
12
12
 
@@ -17,9 +17,9 @@ screen, style, and word the user sees.
17
17
  It gives you:
18
18
 
19
19
  - `AP.boot` to start the panel.
20
- - Licensing, off by default. Paid extensions must turn it on.
20
+ - Licensing, off in `AP.boot` by default (the starter project turns it on). Paid extensions must keep it on.
21
21
  - Signed updates with changelogs.
22
- - `AP.host.eval` to call After Effects (ExtendScript) functions.
22
+ - `AP.host.eval` to call ExtendScript functions in the app (After Effects or Premiere Pro).
23
23
  - `AP.panels` and `AP.events` for extensions with more than one panel.
24
24
  - `AP.paths` to find the images, videos and other files you ship.
25
25
  - `AP.storage` to save settings and other small data on this computer.
@@ -40,15 +40,17 @@ and your memory disagree, the file wins.
40
40
  | [boot.md](boot.md) | call `AP.boot`, use `ctx`, or change when the app starts |
41
41
  | [licensing.md](licensing.md) | turn licensing on, write `renderLicense`, or change the license screen |
42
42
  | [updates.md](updates.md) | change update options or the update screen, or show a changelog |
43
- | [host.md](host.md) | call After Effects from the panel or write `jsx/` code |
43
+ | [host.md](host.md) | call the app from the panel or write `jsx/` code |
44
+ | [host-after-effects.md](host-after-effects.md) | write ExtendScript for After Effects (`jsx/aeft/`) |
45
+ | [host-premiere.md](host-premiere.md) | write ExtendScript for Premiere Pro (`jsx/ppro/`) |
44
46
  | [panels.md](panels.md) | add a panel or modal, open/close panels, or send data between panels |
45
- | [assets.md](assets.md) | add images, fonts, videos or other files, or import a file into After Effects |
47
+ | [assets.md](assets.md) | add images, fonts, videos or other files, or import a file into the app |
46
48
  | [storage.md](storage.md) | save settings, recent items or any other data between launches |
47
49
 
48
50
  ## Commands you will use
49
51
 
50
52
  ```sh
51
- ap dev # build, link into After Effects, rebuild on change
53
+ ap dev # build, link into the app, rebuild on change
52
54
  ap check # static checks; also run by ap dev and ap push
53
55
  ap add panel settings --type modal
54
56
  ap push # publish a release (asks for version bump and changelog)
@@ -57,7 +59,7 @@ ap docs # refresh docs/afterpresets/ from the runtime
57
59
 
58
60
  ## Compatibility
59
61
 
60
- Panels run in Adobe CEP 10 or later (After Effects 2020+). Its browser is old
62
+ Panels run in Adobe CEP 10 or later (After Effects 2020+, Premiere Pro 2020+). Its browser is old
61
63
  (Chromium 74 in CEP 10). Write plain ES5 in panel code: `var`, `function`, no
62
64
  arrow functions, no `let`/`const`, no `class`, no template strings, no
63
65
  `fetch`-only features. ExtendScript in `jsx/` is ES3 (see [host.md](host.md)).
@@ -51,7 +51,7 @@ Use `AP.paths`; never build paths by hand.
51
51
  | `AP.paths.extension()` | Absolute path of the installed extension folder. |
52
52
  | `AP.paths.data()` | A writable folder for your own files. It survives updates. Never write into the extension folder: updates replace it. For settings use `AP.storage`; see [storage.md](storage.md). |
53
53
 
54
- ## From ExtendScript (importing into After Effects)
54
+ ## From ExtendScript (importing into the app)
55
55
 
56
56
  ExtendScript cannot see the panel's folders by itself. Pass the absolute path
57
57
  from the panel:
@@ -64,7 +64,7 @@ ctx.host.eval("importClip", [AP.paths.asset("media/intro.mp4")], function (resul
64
64
  ```
65
65
 
66
66
  ```js
67
- // jsx/media.jsx (loaded automatically, like every .jsx file in jsx/)
67
+ // After Effects: jsx/aeft/media.jsx (loaded automatically, like every .jsx file in jsx/)
68
68
  function importClip(path) {
69
69
  var file = new File(path);
70
70
  if (!file.exists) return JSON.stringify({ error: "Missing file: " + path });
@@ -72,3 +72,17 @@ function importClip(path) {
72
72
  return JSON.stringify({ ok: true, name: item.name });
73
73
  }
74
74
  ```
75
+
76
+ ```js
77
+ // Premiere Pro: jsx/ppro/media.jsx
78
+ function importClip(path) {
79
+ var file = new File(path);
80
+ if (!file.exists) return JSON.stringify({ error: "Missing file: " + path });
81
+ // importFiles(paths, suppressUI, targetBin, importAsNumberedStills)
82
+ var ok = app.project.importFiles([file.fsName], true, app.project.getInsertionBin(), false);
83
+ return JSON.stringify({ ok: ok === true, name: file.name });
84
+ }
85
+ ```
86
+
87
+ Both files define the same function name: an extension for both apps calls
88
+ `importClip` and each app loads its own version.
@@ -35,7 +35,7 @@ once.
35
35
 
36
36
  After a successful online check the API returns a signed record of it, valid
37
37
  for 12 hours, and the runtime saves it with the token. Until it runs out,
38
- launching After Effects, reloading a panel (including `ap dev` reloads) or
38
+ launching the app, reloading a panel (including `ap dev` reloads) or
39
39
  opening another panel unlocks straight away, with no network call and no
40
40
  `checking` screen. After 12 hours the license is checked online again, without blocking the
41
41
  buyer:
@@ -12,9 +12,9 @@ HTML, and JavaScript. They share `js/`, `css/`, `jsx/`, and the license.
12
12
 
13
13
  | `type` | What it is | Use it for |
14
14
  |---|---|---|
15
- | `panel` | A dockable After Effects panel, listed in **Window → Extensions** when `menu` is true | The main UI |
16
- | `modal` | A dialog that blocks After Effects until closed | Settings, confirmations, one-off forms |
17
- | `invisible` | No window; starts with After Effects and runs in the background | Listening for events, background work |
15
+ | `panel` | A dockable panel, listed in **Window → Extensions** when `menu` is true | The main UI |
16
+ | `modal` | A dialog that blocks the app until closed | Settings, confirmations, one-off forms |
17
+ | `invisible` | No window; starts with the app and runs in the background | Listening for events, background work |
18
18
 
19
19
  Panels are declared in `afterpresets.json`:
20
20
 
@@ -37,7 +37,7 @@ This creates `src/panels/<id>/index.html` and `src/panels/<id>/main.js`, and
37
37
  adds the entry to `afterpresets.json`. Each panel calls `AP.boot` in its own
38
38
  `main.js` and imports the screens and helpers it uses from `src/features/`
39
39
  and `src/shared/`. After adding a panel, restart
40
- `ap dev` and then After Effects: CEP reads the manifest only at launch.
40
+ `ap dev` and then the app: CEP reads the manifest only at launch.
41
41
 
42
42
  ## AP.panels
43
43
 
@@ -49,7 +49,7 @@ AP.panels.close("settings"); // ask another open panel to close itself
49
49
  ```
50
50
 
51
51
  - Ids are the ones in `afterpresets.json`. An invalid id throws.
52
- - `open` asks After Effects to open the extension `<bundleId>.<id>`. It returns
52
+ - `open` asks the app to open the extension `<bundleId>.<id>`. It returns
53
53
  `true` when the request was sent; it does not wait for the panel to load.
54
54
  - Data cannot be passed to `open`. Send it with `AP.events` once the other
55
55
  panel is ready (see "Handshake" below).
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: Saving data
3
- description: Where an extension keeps settings and other local state with AP.storage and AP.paths.data(), what goes inside the After Effects project instead, and what never to store.
3
+ description: Where an extension keeps settings and other local state with AP.storage and AP.paths.data(), what goes inside the app's project file instead, and what never to store.
4
4
  ---
5
5
 
6
6
  # Saving data
@@ -11,7 +11,7 @@ description: Where an extension keeps settings and other local state with AP.sto
11
11
  |---|---|
12
12
  | Settings, preferences, recent items, small caches | `AP.storage` (below) |
13
13
  | Bigger files you create or download (images, media, generated presets) | A file in `AP.paths.data()` |
14
- | Data that belongs to one After Effects project | Inside the `.aep`, from `jsx/` (it travels with the project file) |
14
+ | Data that belongs to one After Effects or Premiere Pro project | Inside the `.aep` / `.prproj`, from `jsx/` (it travels with the project file) |
15
15
  | Secrets (passwords, API keys, tokens) | Nowhere. Everything above is a plain file the user can open. |
16
16
 
17
17
  Do **not** use `localStorage`, `sessionStorage` or IndexedDB: in CEP each panel
@@ -71,12 +71,12 @@ var path = require("path");
71
71
  var file = path.join(AP.paths.data(), "thumbnails", "intro.png");
72
72
  ```
73
73
 
74
- Pass such paths to ExtendScript as arguments when After Effects needs them
74
+ Pass such paths to ExtendScript as arguments when the app needs them
75
75
  (see [assets.md](assets.md)).
76
76
 
77
- ## Inside the After Effects project
77
+ ## Inside the project file
78
78
 
79
79
  Data about one project (which presets it uses, a layout you applied) belongs in
80
- the project, not on the computer: it should follow the `.aep` to another
80
+ the project, not on the computer: it should follow the `.aep` or `.prproj` to another
81
81
  machine. Read and write it from a `jsx/` function, for example in a project
82
82
  XMP field or on a layer or comp comment, and call it with `ctx.host.eval`.
@@ -230,7 +230,7 @@ callback only.
230
230
  | `dev_build` | `ap dev` builds never install updates | Expected during development. Do not show the failure popup. |
231
231
  | `busy` | Another install is running | Try again later. |
232
232
  | `bad_signature`, `bad_checksum`, `bad_zip`, `bad_update_info` | The download failed verification; nothing was installed | Show the failure popup. Do not retry in a loop. |
233
- | `verify_unsupported` | After Effects is too old to verify signatures | Show the failure popup (reinstall from the product page). |
233
+ | `verify_unsupported` | The app is too old to verify signatures | Show the failure popup (reinstall from the product page). |
234
234
  | `download_failed`, `install_failed` | Download or copy failed (the previous version is restored) | Show the failure popup. |
235
235
 
236
236
  ## Channels
@@ -0,0 +1,44 @@
1
+ ---
2
+ title: AfterPresets native effect reference
3
+ description: Which file to read before writing or changing a C++ After Effects effect plugin built with AfterPresets.
4
+ ---
5
+
6
+ # AfterPresets native effect reference
7
+
8
+ These files are for the AI coding agent that builds an After Effects effect
9
+ plugin (C++, Adobe's effect SDK) with AfterPresets. An effect is a new entry
10
+ in the Effect menu that renders pixels, like a glow or a blur.
11
+
12
+ ## The rule
13
+
14
+ **Read [rules.md](rules.md) before you write or change any effect code, and
15
+ follow [testing.md](testing.md) before you say a change is done.** Then read
16
+ the SDK topic files for your task (index: [sdk/README.md](sdk/README.md)). Do
17
+ not guess struct fields, flag names, selectors or call order. If a file and
18
+ your memory disagree, the file wins. If the SDK guide and the SDK headers in
19
+ the project disagree, the headers win.
20
+
21
+ ## Files
22
+
23
+ | File | Read it before you |
24
+ |---|---|
25
+ | [rules.md](rules.md) | write or change any effect code: the hard rules, each with why and an example |
26
+ | [testing.md](testing.md) | say "done": build, apply the effect in After Effects, render frames and look at them |
27
+ | [debugging.md](debugging.md) | chase a crash, an effect that does not load, wrong pixels, or a slow render |
28
+ | [sdk/README.md](sdk/README.md) | use any part of the After Effects SDK: tasks mapped to small topic files |
29
+
30
+ ## About sdk/
31
+
32
+ `sdk/` is Adobe's After Effects C++ SDK guide, cut into small topic files. It
33
+ is generated on this computer from a pinned version of the community copy at
34
+ https://github.com/docsforadobe/after-effects-plugin-guide. AfterPresets does
35
+ not ship it: the guide is copyright Adobe. Never copy its text into the
36
+ product, its listing or its source files. Search it with:
37
+
38
+ ```sh
39
+ grep -rn "PF_OutFlag2_SUPPORTS_THREADED_RENDERING" docs/afterpresets/sdk/
40
+ ```
41
+
42
+ Adobe's SDK itself (headers, samples, `Util/` helpers) is not redistributed
43
+ either. The project gets it from Adobe; never commit it to a public
44
+ repository.
@@ -0,0 +1,140 @@
1
+ ---
2
+ title: Debugging a native effect
3
+ description: Find out why an effect does not load, crashes, renders wrong pixels or is slow, without an IDE - scripting checks, binary checks, crash reports, logs and debugger limits.
4
+ ---
5
+
6
+ # Debugging a native effect
7
+
8
+ You have no IDE and usually no debugger attached. Work from evidence you can
9
+ collect yourself: scripting queries through `host_eval`, frames from
10
+ `comp_capture`, the built binary, crash reports and logs. Change one thing at
11
+ a time and test again ([testing.md](testing.md)).
12
+
13
+ ## The effect does not appear or does not apply
14
+
15
+ 1. **Is it loaded?** Ask After Effects for its effect list:
16
+
17
+ ```js
18
+ var out = [];
19
+ for (var i = 0; i < app.effects.length; i++) {
20
+ var e = app.effects[i];
21
+ if (/ACME/.test(e.matchName)) out.push(e.matchName + " | " + e.displayName + " | " + e.category);
22
+ }
23
+ return out.join("\n") || "not loaded";
24
+ ```
25
+
26
+ Listed, but `addProperty` fails: you are using a different match name.
27
+ Not listed: After Effects did not load the binary; go on.
28
+ 2. **Was After Effects restarted** after the binary was installed? Plugins
29
+ load at launch only.
30
+ 3. **Is it where After Effects looks?** See
31
+ [sdk/where-installers-should-put-plug-ins.md](sdk/where-installers-should-put-plug-ins.md).
32
+ Folders whose names end in parentheses, or start with `¬` (macOS) or `~`
33
+ (Windows), are not scanned. `ap dev` installs into
34
+ `/Library/Application Support/Adobe/Common/Plug-ins/7.0/MediaCore/AfterPresets Dev/<bundleId>/`,
35
+ a folder made once with administrator rights and then owned by the user;
36
+ buyers' copies go to `MediaCore/AfterPresets/<bundleId>/`. Any other
37
+ write to the shared MediaCore folder or the After Effects `Plug-ins`
38
+ folder needs administrator rights: ask the user, never use `sudo`
39
+ yourself.
40
+ 4. **Check the binary** (macOS):
41
+
42
+ ```sh
43
+ lipo -info Effect.plugin/Contents/MacOS/Effect # arm64 and x86_64 for a universal build
44
+ nm -gU Effect.plugin/Contents/MacOS/Effect # the entry point must be exported
45
+ codesign -dv Effect.plugin # must be signed (ad-hoc is enough to develop)
46
+ xattr -l Effect.plugin # com.apple.quarantine set by downloads
47
+ ```
48
+
49
+ macOS 15 and later refuse unsigned plugins; sign development builds
50
+ ad-hoc with `codesign --force --deep --sign - Effect.plugin`, and do not
51
+ touch the bundle after signing. The PiPL needs an entry point for every
52
+ architecture you build (`CodeMacARM64`, `CodeMacIntel64`, `CodeWin64X86`).
53
+ 5. **Check the PiPL against GlobalSetup**: flags (rule 2 in
54
+ [rules.md](rules.md)), match name, version. A mismatch warning appears when
55
+ the effect is applied; ask the user to read you any dialog.
56
+ 6. **Read After Effects' plugin loading log.** It is rewritten at every
57
+ launch: `~/Library/Preferences/Adobe/After Effects/<version>/Plugin Loading.log`
58
+ (for example `26.2`). Search it for your bundle name:
59
+
60
+ ```sh
61
+ grep -n -i "MyEffect" ~/Library/Preferences/Adobe/After\ Effects/*/Plugin\ Loading.log
62
+ ```
63
+
64
+ The line "No loaders recognized this plugin … Ignore" is normal for After
65
+ Effects effects (it comes from the shared MediaCore loader). A missing
66
+ line means After Effects never saw the file (wrong folder, not
67
+ restarted); a load error points at the binary (step 4) or the PiPL
68
+ (step 5).
69
+
70
+ Whether a plugin loads also depends on how After Effects itself is signed
71
+ (hardened runtime, library validation). A result on one computer, for
72
+ example one with a re-signed or developer copy of After Effects, may not
73
+ match a customer's computer.
74
+
75
+ ## After Effects crashes
76
+
77
+ - macOS writes a crash report to `~/Library/Logs/DiagnosticReports/`
78
+ (`Adobe After Effects*.ips`). Find the crashed thread and look for frames in
79
+ your binary. Build development versions with debug symbols (`-g`) and keep
80
+ the `.dSYM`, so addresses map to functions and lines (`atos -o
81
+ Effect.plugin.dSYM/Contents/Resources/DWARF/Effect -arch arm64 -l <load
82
+ address> <address>`).
83
+ - Usual causes: reading past a row (`rowbytes`, wrong pixel type for the
84
+ depth), an exception leaving the entry point (rule 15), a world used after
85
+ `PF_DisposeWorld`, writing shared state from several render threads
86
+ (rule 11), unbalanced parameter checkouts (rule 10).
87
+ - After a crash, After Effects may show a recovery dialog at the next launch.
88
+ Ask the user to answer it; do not script around it.
89
+
90
+ ## Wrong pixels
91
+
92
+ - Capture the same frame at 8, 16 and 32 bpc. Wrong in one depth only: that
93
+ depth's code path or its maximum channel value (32768 for 16 bpc).
94
+ - Bright random colours, rainbows, black blotches: integer overflow; clamp
95
+ before converting.
96
+ - Wrong only at half resolution or with an effect before yours: downsample
97
+ factors or buffer origin ([rules.md](rules.md), rule 9).
98
+ - To see an internal value, temporarily write it into the output (for example
99
+ a red channel proportional to the value) and capture the frame. Remove it
100
+ afterwards.
101
+ - Unchanged after a rebuild: After Effects still runs the old binary
102
+ (restart), or you looked at a cached frame (`comp_capture` clears caches by
103
+ default; keep it that way).
104
+
105
+ ## Slow renders
106
+
107
+ `comp_capture` reports a render time per frame, measured after clearing the
108
+ caches. Compare before and after a change on the same frames. Typical fixes:
109
+ precompute tables once (GlobalSetup or SequenceSetup), avoid `pow`/`sqrt`/
110
+ division per pixel, fuse passes, process only the requested area, and enable
111
+ multi-frame rendering when the effect is thread-safe (rule 11).
112
+
113
+ ## Logs
114
+
115
+ The AfterPresets native runtime (`ap_native`) writes a small log for each
116
+ plugin: `~/Library/Logs/AfterPresets/<bundleId>.log` on macOS (rotated at
117
+ 1 MB; `ap_log_path()` returns the exact path). Each After Effects start adds
118
+ a `start <bundleId> <version> build=...` line, then licence and update
119
+ events. Read it with `tail -n 50`. It is safe to read: tokens and URL query
120
+ strings are scrubbed.
121
+
122
+ To log from effect code, call `ap_log(rt, level, "message")`: it never
123
+ blocks and does no file I/O on the calling thread, so it is allowed in
124
+ render code, but never log from inside the per-pixel loop. Never log licence
125
+ tokens, account data or user paths, and remove temporary logging before
126
+ release.
127
+
128
+ ## Debuggers
129
+
130
+ Attaching `lldb` to a release build of After Effects 26.5 or later on macOS is
131
+ refused because of how the application is signed. Adobe's workaround (a
132
+ re-signed copy, or developer mode for beta builds) needs the user and
133
+ administrator rights: see [sdk/debugging-ae-macos.md](sdk/debugging-ae-macos.md).
134
+ Prefer the evidence above; propose a debugger session to the user only when
135
+ it is the only way forward.
136
+
137
+ Holding Cmd+Opt+Shift (macOS) or Ctrl+Alt+Shift (Windows) while After Effects
138
+ starts resets its preferences, which clears settings a plugin may have
139
+ stored. Only the user should do this, after being told it resets all their
140
+ preferences.