premiere-pro-mcp 1.15.0 → 1.15.2

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.
package/CHANGELOG.md CHANGED
@@ -6,6 +6,38 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [1.15.2] - 2026-09-14
10
+
11
+ ### Fixed
12
+
13
+ - `trim_clip` now rolls back source metadata to prevent clip corruption when a partial write occurs (source points changed but timeline edge didn't move). Previously these clips entered a permanently-stuck state. (#509, #503)
14
+ - `export_frame`, `capture_frame`, `freeze_frame`, and the `export_sequence_*_review_frames` tools now write the requested frame on macOS Premiere Pro 26.5 / 27 beta. QE still exporters take `(timecodeString, pathWithoutExtension)`; the previous `(path, width, height)` call returned `false` without writing a file, so every frame export fell through to the Media Encoder fallback. Frame time is now formatted with `Time.getFormatted()` in the sequence's display format (drop-frame included), the editor's playhead is no longer moved, and the result reports the timecode and frame index that were rendered. (#510)
15
+ - Preset discovery (`get_encoder_presets`, the default `export_sequence` preset, proxy ingest presets, and the still-image fallback) now looks inside the `.app` bundle that lives one level below `/Applications/Adobe Media Encoder <version>/` on macOS. Previously only the user's own presets under `~/Documents/Adobe/Adobe Media Encoder/*/Presets` were found. (#510)
16
+ - `verify_premiere_connection` now aligns panel and active sequence identity checks. (#501)
17
+ - `create_mogrt_recipe` now exposes composition parameter controls correctly. (#504)
18
+ - `apply_mogrt` now surfaces buildToolScript and importMGT error details. (#505)
19
+ - `inspect_color_value` argument unwrapping no longer fails. (#506)
20
+
21
+ ### Changed
22
+
23
+ - Removed orphaned chat-plugin directory and build scripts. (#502)
24
+ - Pinned Adobe type definitions at 26.3 until drift receipts are rewritten for stable 26.5. (#508)
25
+
26
+ ## [1.15.1] - 2026-09-11
27
+
28
+ ### Fixed
29
+
30
+ - Use a null destination for UXP project-root file imports, matching the Premiere API contract.
31
+ - Consolidate exported page aliases with permanent redirects and improve homepage accessibility, image delivery, and installation journeys.
32
+
33
+ ### Changed
34
+
35
+ - Add a searchable tool reference, precise client configuration, and clearer competitive evaluation guidance.
36
+ - Refresh the homepage experiment with Premiere artwork and gallery layouts, with end-to-end journey coverage.
37
+ - Update landing dependencies and comparable GitHub search measurement.
38
+
39
+ Automated checks do not establish licensed Premiere or After Effects playback or rendered-output verification.
40
+
9
41
  ## [1.15.0] - 2026-09-08
10
42
 
11
43
  ### Added
package/README.md CHANGED
@@ -10,6 +10,8 @@
10
10
 
11
11
  Free, MIT licensed, local-first, and published to npm as [`premiere-pro-mcp`](https://www.npmjs.com/package/premiere-pro-mcp) — the only package name that installs this project.
12
12
 
13
+ [Website](https://premiere-pro-mcp.com/) · [Setup guides](https://premiere-pro-mcp.com/blog/how-to-set-up-premiere-pro-mcp/) · [Search tools](https://premiere-pro-mcp.com/tools/) · [Troubleshooting](https://premiere-pro-mcp.com/docs/troubleshooting/) · [Release facts](https://premiere-pro-mcp.com/facts/)
14
+
13
15
  Development source: 369 core tools across 53 modules, 4 resources, and 17 guided workflows. A connected UXP host adds 93 capability-gated tools.
14
16
 
15
17
  The [completed AE render handoff](docs/after-effects-render-handoff.md) previews and confirms importing one finished render into an existing Premiere bin, with host and file rechecks and an import receipt.
@@ -95,14 +97,21 @@ It is also separate from other MCP servers for Premiere Pro. The only npm packag
95
97
  published from this repository is `premiere-pro-mcp`, and no other package name
96
98
  installs it.
97
99
 
100
+ **Comparing similarly named packages?** Both this package and
101
+ `adobe-premiere-pro-mcp` declare a `premiere-pro-mcp` executable. Verify the package
102
+ and repository before configuring a client. The new
103
+ [local configuration helper](docs/client-configuration.md) prints Claude, Cursor,
104
+ VS Code, or Codex settings that point directly to this installation. It is a
105
+ feature included in v1.15.1 and later.
106
+
98
107
  The current source exposes 369 core tools for supported workflow steps spanning the supported ExtendScript, QE DOM, local media and interchange analysis, revisioned project-context retrieval, safe edit-planning, project-intake preview, review handoff, connection verification, and guarded After Effects MOGRT authoring, batch, library, render-queue, inspection, and Premiere-handoff workflows. A compatible, authenticated UXP panel adds 93 documented, capability-gated tools without replacing the production CEP bridge.
99
108
 
100
109
  <a id="latest-release"></a>
101
110
 
102
- ### Latest release: 1.15.0
111
+ ### Latest release: 1.15.2
103
112
 
104
- The previously published v1.14.9 npm artifact contains **349 core tools**, 347 in its default profile,
105
- and 440 with a compatible UXP connection. The development catalog above can include
113
+ The published v1.15.1 npm artifact contains **369 core tools**, 367 in its default profile,
114
+ and 460 with a compatible UXP connection. The development catalog above can include
106
115
  unreleased work. See the [versioned facts and package provenance](https://premiere-pro-mcp.com/facts/).
107
116
 
108
117
  ### Try a bounded workflow
@@ -151,7 +160,7 @@ if the connection is unavailable.
151
160
  local Premiere processes. See the generated [supported action catalog](docs/supported-actions.md)
152
161
  for individual capability and verification contracts.
153
162
 
154
- See the [v1.15.0 release notes](https://github.com/leancoderkavy/premiere-pro-mcp/releases/tag/v1.15.0)
163
+ See the [v1.15.1 release notes](https://github.com/leancoderkavy/premiere-pro-mcp/releases/tag/v1.15.1)
155
164
  for complete details. Live installation in Premiere Pro still requires host verification.
156
165
 
157
166
  ### Current MCP protocol support
@@ -198,9 +207,9 @@ their bins, media rules, and organization rules before a facility uses one.
198
207
 
199
208
  ### Easiest supported path: Claude Desktop
200
209
 
201
- 1. Download the current [Claude Desktop bundle (`.mcpb`)](https://github.com/leancoderkavy/premiere-pro-mcp/releases/download/v1.15.0/premiere-pro-mcp-1.15.0.mcpb).
210
+ 1. Download the current [Claude Desktop bundle (`.mcpb`)](https://github.com/leancoderkavy/premiere-pro-mcp/releases/download/v1.15.1/premiere-pro-mcp-1.15.1.mcpb).
202
211
  2. In Claude Desktop, open **Settings > Extensions > Advanced settings > Install Extension**, select the downloaded bundle, and restart Claude Desktop.
203
- 3. Download the separate [signed Premiere connector (`.zxp`)](https://github.com/leancoderkavy/premiere-pro-mcp/releases/download/v1.15.0/MCPBridgeCEP.zxp). Open it with your trusted ZXP installer. If your computer has no ZXP installer, use the npm connector installer in **Advanced setup** below.
212
+ 3. Download the separate [signed Premiere connector (`.zxp`)](https://github.com/leancoderkavy/premiere-pro-mcp/releases/download/v1.15.1/MCPBridgeCEP.zxp). Open it with your trusted ZXP installer. If your computer has no ZXP installer, use the npm connector installer in **Advanced setup** below.
204
213
  4. Restart Premiere, open a project, then open **Window > Extensions > MCP for Adobe Premiere Pro**.
205
214
  5. In Claude, enter: `Safely check my Premiere connection with verify_premiere_connection. Make no changes.`
206
215
 
@@ -497,11 +506,11 @@ From a clone of this repository:
497
506
  ```bash
498
507
  codex plugin marketplace add .
499
508
  codex plugin add premiere-pro@premiere-pro-mcp
500
- npx -y premiere-pro-mcp@1.15.0 --install-cep
509
+ npx -y premiere-pro-mcp@1.15.1 --install-cep
501
510
  ```
502
511
 
503
512
  Restart Premiere Pro and start a new Codex session after installation. The plugin
504
- launches `premiere-pro-mcp@1.15.0` through `npx`; the separate CEP installation is
513
+ launches `premiere-pro-mcp@1.15.1` through `npx`; the separate CEP installation is
505
514
  required because the MCP server communicates with the running Premiere host through
506
515
  the local bridge.
507
516
 
@@ -532,7 +541,7 @@ For Claude Code, add this repository as a marketplace and install the plugin:
532
541
  Then install the Premiere bridge and start a new Claude Code session:
533
542
 
534
543
  ```bash
535
- npx -y premiere-pro-mcp@1.15.0 --install-cep
544
+ npx -y premiere-pro-mcp@1.15.1 --install-cep
536
545
  ```
537
546
 
538
547
  The Claude Code package lives in
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <ExtensionManifest Version="7.0" ExtensionBundleId="com.mcp.aftereffects.bridge" ExtensionBundleVersion="1.15.0" ExtensionBundleName="MCP for Adobe After Effects">
2
+ <ExtensionManifest Version="7.0" ExtensionBundleId="com.mcp.aftereffects.bridge" ExtensionBundleVersion="1.15.2" ExtensionBundleName="MCP for Adobe After Effects">
3
3
  <ExtensionList>
4
- <Extension Id="com.mcp.aftereffects.bridge.panel" Version="1.15.0"/>
4
+ <Extension Id="com.mcp.aftereffects.bridge.panel" Version="1.15.2"/>
5
5
  </ExtensionList>
6
6
  <ExecutionEnvironment>
7
7
  <HostList>
Binary file
@@ -1,8 +1,8 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <ExtensionManifest Version="7.0" ExtensionBundleId="com.mcp.premiere.bridge" ExtensionBundleVersion="1.15.0" ExtensionBundleName="MCP for Adobe Premiere Pro">
2
+ <ExtensionManifest Version="7.0" ExtensionBundleId="com.mcp.premiere.bridge" ExtensionBundleVersion="1.15.2" ExtensionBundleName="MCP for Adobe Premiere Pro">
3
3
  <ExtensionList>
4
- <Extension Id="com.mcp.premiere.bridge.panel" Version="1.15.0"/>
5
- <Extension Id="com.mcp.premiere.bridge.headless" Version="1.15.0"/>
4
+ <Extension Id="com.mcp.premiere.bridge.panel" Version="1.15.2"/>
5
+ <Extension Id="com.mcp.premiere.bridge.headless" Version="1.15.2"/>
6
6
  </ExtensionList>
7
7
  <ExecutionEnvironment>
8
8
  <HostList>
@@ -81,7 +81,7 @@
81
81
  <section class="update-section" aria-live="polite">
82
82
  <div class="update-copy">
83
83
  <span class="section-label">MCP updates</span>
84
- <strong id="updateTitle">Version 1.15.0</strong>
84
+ <strong id="updateTitle">Version 1.15.2</strong>
85
85
  <span id="updateDetail">Checking the global MCP server and connector release…</span>
86
86
  </div>
87
87
  <button id="btnUpdate" class="button button-update" onclick="handleUpdateClick()" type="button" aria-describedby="updateDetail" disabled>
@@ -7,7 +7,7 @@
7
7
  })(this, function () {
8
8
  "use strict";
9
9
 
10
- var CURRENT_VERSION = "1.15.0";
10
+ var CURRENT_VERSION = "1.15.2";
11
11
  var PACKAGE_NAME = "premiere-pro-mcp";
12
12
  var LATEST_PACKAGE_API = "https://registry.npmjs.org/" + PACKAGE_NAME;
13
13
  var LATEST_RELEASE_API =
@@ -289,9 +289,21 @@ function __collectEprFiles(folder, out) {
289
289
 
290
290
  // macOS applications are bundles: AME/Premiere resources live below Contents,
291
291
  // whereas the Windows installers put the same folders directly below the app root.
292
+ // On macOS the /Applications entry is normally a plain folder that holds the bundle
293
+ // ("/Applications/Adobe Media Encoder 2026/Adobe Media Encoder 2026.app"), so when
294
+ // Contents is not directly there, look one level down for the ".app".
292
295
  function __adobeApplicationResourceFolder(appFolder, relativePath) {
293
- var prefix = appFolder.fsName + (__isMacOS() ? "/Contents/" : "/");
294
- return new Folder(prefix + relativePath);
296
+ if (!__isMacOS()) return new Folder(appFolder.fsName + "/" + relativePath);
297
+
298
+ var direct = new Folder(appFolder.fsName + "/Contents/" + relativePath);
299
+ if (direct.exists) return direct;
300
+
301
+ var bundles = appFolder.getFiles(function(f) { return /\\.app$/i.test(f.name); });
302
+ for (var i = 0; i < bundles.length; i++) {
303
+ var nested = new Folder(bundles[i].fsName + "/Contents/" + relativePath);
304
+ if (nested.exists) return nested;
305
+ }
306
+ return direct;
295
307
  }
296
308
 
297
309
  // All export presets AME ships, plus the user's own saved presets.
@@ -370,7 +382,8 @@ function __findProxyPreset() {
370
382
 
371
383
  function __findStillPreset(outputPath) {
372
384
  var wantJpeg = /\\.jpe?g$/i.test(outputPath);
373
- var needles = wantJpeg ? ["jpeg", "jpg"] : ["png"];
385
+ var wantTiff = /\\.tiff?$/i.test(outputPath);
386
+ var needles = wantJpeg ? ["jpeg", "jpg"] : (wantTiff ? ["tiff", "tif"] : ["png"]);
374
387
  var presets = __collectAllPresets();
375
388
 
376
389
  for (var n = 0; n < needles.length; n++) {
@@ -416,63 +429,102 @@ function __firstWrittenFile(outputPath) {
416
429
  }
417
430
  }
418
431
 
419
- // Export a single frame to disk. Returns { ok, method, path, notes } / { ok:false, error, notes }.
432
+ // Premiere's own timecode string for a tick position, in the sequence's display
433
+ // format (drop-frame sequences get semicolons, a "frames" display gets a bare frame
434
+ // count). The QE still exporters take (timecodeString, pathWithoutExtension): a ticks
435
+ // string is silently read as frame 0, a bare frame number is read as a timecode, and
436
+ // the (path, width, height) call returns false without writing anything.
437
+ function __qeTimecodeForTicks(seq, ticks) {
438
+ var tb = parseFloat(seq.timebase); // ticks per frame
439
+ var frameIdx = Math.floor(parseFloat(ticks) / tb + 0.000001);
440
+ if (!(frameIdx >= 0)) frameIdx = 0;
441
+ var frameTicks = frameIdx * tb;
442
+
443
+ var displayFormat = 100;
444
+ try { displayFormat = seq.getSettings().videoDisplayFormat; } catch (e) {}
445
+ try {
446
+ var fr = new Time(); fr.ticks = String(tb);
447
+ var t = new Time(); t.ticks = String(frameTicks);
448
+ if (typeof t.getFormatted === "function") {
449
+ return { timecode: t.getFormatted(fr, displayFormat), frame: frameIdx };
450
+ }
451
+ } catch (e2) {}
452
+
453
+ // Fallback: non-drop timecode at the nominal integer base (24 for 23.976, 30 for 29.97).
454
+ var nominal = Math.round(TICKS_PER_SECOND / tb);
455
+ var ff = frameIdx % nominal;
456
+ var s = Math.floor(frameIdx / nominal) % 60;
457
+ var m = Math.floor(frameIdx / (nominal * 60)) % 60;
458
+ var h = Math.floor(frameIdx / (nominal * 3600));
459
+ return { timecode: __pad(h) + ":" + __pad(m) + ":" + __pad(s) + ":" + __pad(ff), frame: frameIdx };
460
+ }
461
+
462
+ // Export a single frame to disk. Returns { ok, method, path, notes, timecode, frame }
463
+ // / { ok:false, error, notes }.
420
464
  //
421
465
  // exportFramePNG/exportFrameJPEG do NOT exist on the public DOM sequence — only on
422
- // the QE sequence — and even there they return false and write nothing on some
423
- // builds. So we try QE first, verify against the filesystem rather than the return
424
- // value, and fall back to a one-frame Media Encoder export.
466
+ // the QE sequence — where they take a timecode string and a path WITHOUT extension
467
+ // (they append .png / .jpg themselves). The playhead is never moved: the timecode
468
+ // argument alone selects the frame. We verify against the filesystem rather than the
469
+ // return value, and fall back to a one-frame Media Encoder export.
425
470
  function __exportStillFrame(outputPath, ticks) {
426
471
  var seq = app.project.activeSequence;
427
472
  if (!seq) return { ok: false, error: "No active sequence", notes: [] };
428
473
 
429
474
  var notes = [];
430
- var savedPos = null;
431
- try { savedPos = seq.getPlayerPosition().ticks; } catch (e) {}
432
-
433
- if (ticks) {
434
- try { seq.setPlayerPosition(String(ticks)); } catch (e) { notes.push("setPlayerPosition: " + e.toString()); }
435
- }
436
475
  var atTicks = ticks;
437
476
  if (!atTicks) {
438
477
  try { atTicks = seq.getPlayerPosition().ticks; } catch (e) { atTicks = "0"; }
439
478
  }
440
479
 
441
- // Clear any stale file so that a file existing afterwards proves we wrote it.
480
+ var dot = outputPath.lastIndexOf(".");
481
+ var slash = Math.max(outputPath.lastIndexOf("/"), outputPath.lastIndexOf("\\\\"));
482
+ var ext = dot > slash ? outputPath.substring(dot).toLowerCase() : "";
483
+ if (ext === "") { outputPath = outputPath + ".png"; ext = ".png"; }
484
+ var basePath = outputPath.substring(0, outputPath.length - ext.length);
485
+ var wantJpeg = ext === ".jpg" || ext === ".jpeg";
486
+ var qeCanWrite = wantJpeg || ext === ".png";
487
+ var qePath = basePath + (wantJpeg ? ".jpg" : ".png");
488
+
489
+ // Clear any stale file (under either name) so that a file existing afterwards proves we wrote it.
442
490
  var stale = new File(outputPath);
443
491
  if (stale.exists) { try { stale.remove(); } catch (e) {} }
444
-
445
- var wantJpeg = /\\.jpe?g$/i.test(outputPath);
446
-
447
- // --- Path 1: QE DOM. Signature is (path, width, height) with string args. ---
448
- try {
449
- app.enableQE();
450
- var qeSeq = qe.project.getActiveSequence();
451
- if (!qeSeq) {
452
- notes.push("QE: no active sequence");
453
- } else {
454
- var fn = wantJpeg ? qeSeq.exportFrameJPEG : qeSeq.exportFramePNG;
455
- if (typeof fn !== "function") {
456
- notes.push("QE: exportFrame" + (wantJpeg ? "JPEG" : "PNG") + " unavailable on this build");
492
+ var staleQe = new File(qePath);
493
+ if (staleQe.exists) { try { staleQe.remove(); } catch (e) {} }
494
+
495
+ // --- Path 1: QE DOM. Signature is (timecodeString, pathWithoutExtension). ---
496
+ var at = null;
497
+ if (!qeCanWrite) {
498
+ notes.push("QE: no still exporter for " + ext + "; using Media Encoder");
499
+ } else {
500
+ try {
501
+ app.enableQE();
502
+ var qeSeq = qe.project.getActiveSequence();
503
+ if (!qeSeq) {
504
+ notes.push("QE: no active sequence");
457
505
  } else {
458
- var w = String(seq.frameSizeHorizontal);
459
- var h = String(seq.frameSizeVertical);
460
- try {
461
- notes.push("QE returned " + fn.call(qeSeq, outputPath, w, h));
462
- } catch (eArgs) {
463
- try { notes.push("QE returned " + fn.call(qeSeq, outputPath, w)); }
464
- catch (eArgs2) { notes.push("QE: " + eArgs2.toString()); }
506
+ var fn = wantJpeg ? qeSeq.exportFrameJPEG : qeSeq.exportFramePNG;
507
+ if (typeof fn !== "function") {
508
+ notes.push("QE: exportFrame" + (wantJpeg ? "JPEG" : "PNG") + " unavailable on this build");
509
+ } else {
510
+ at = __qeTimecodeForTicks(seq, atTicks);
511
+ notes.push("QE " + qeSeq.name + " @ " + at.timecode + " (frame " + at.frame + ") returned " + fn.call(qeSeq, at.timecode, basePath));
465
512
  }
466
513
  }
514
+ } catch (eQE) {
515
+ notes.push("QE: " + eQE.toString());
467
516
  }
468
- } catch (eQE) {
469
- notes.push("QE: " + eQE.toString());
517
+ }
518
+
519
+ // QE always names the file base + ".png"/".jpg"; give the caller the name they asked for.
520
+ var produced = new File(qePath);
521
+ if (qePath !== outputPath && produced.exists && produced.length > 0) {
522
+ try { produced.rename(decodeURI(new File(outputPath).name)); } catch (e) {}
470
523
  }
471
524
 
472
525
  var written = __firstWrittenFile(outputPath);
473
526
  if (written) {
474
- if (savedPos) { try { seq.setPlayerPosition(savedPos); } catch (e) {} }
475
- return { ok: true, method: "qe", path: written, notes: notes };
527
+ return { ok: true, method: "qe", path: written, notes: notes, timecode: at ? at.timecode : null, frame: at ? at.frame : null };
476
528
  }
477
529
  notes.push("QE wrote no file; falling back to Media Encoder");
478
530
 
@@ -511,10 +563,8 @@ function __exportStillFrame(outputPath, ticks) {
511
563
  notes.push("AME: " + eAME.toString());
512
564
  }
513
565
 
514
- if (savedPos) { try { seq.setPlayerPosition(savedPos); } catch (e) {} }
515
-
516
566
  written = __firstWrittenFile(outputPath);
517
- if (written) return { ok: true, method: "ame", path: written, notes: notes };
567
+ if (written) return { ok: true, method: "ame", path: written, notes: notes, timecode: null, frame: null };
518
568
 
519
569
  return {
520
570
  ok: false,
@@ -0,0 +1,11 @@
1
+ export declare const CLIENT_CONFIG_TARGETS: readonly ["claude", "cursor", "vscode", "codex"];
2
+ export type ClientConfigTarget = typeof CLIENT_CONFIG_TARGETS[number];
3
+ /** Resolve this action before any installer, update, or server startup branch. */
4
+ export declare function parseClientConfigAction(args: string[]): ClientConfigTarget | undefined;
5
+ /**
6
+ * Print a mergeable entry for this installed copy, bypassing the shared global
7
+ * command name. No file/config inspection, environment copying, or host contact.
8
+ * Paths are intentionally local and must not be included in public diagnostics.
9
+ */
10
+ export declare function renderClientConfig(target: ClientConfigTarget, nodeExecutable: string, serverEntrypoint: string, platform?: NodeJS.Platform): string;
11
+ //# sourceMappingURL=client-config.d.ts.map
@@ -0,0 +1,37 @@
1
+ import path from "node:path";
2
+ export const CLIENT_CONFIG_TARGETS = ["claude", "cursor", "vscode", "codex"];
3
+ const usage = "Usage: premiere-pro-mcp --print-client-config <claude|cursor|vscode|codex>. Use this action alone.";
4
+ /** Resolve this action before any installer, update, or server startup branch. */
5
+ export function parseClientConfigAction(args) {
6
+ if (!args.some((arg) => arg === "--print-client-config" || arg.startsWith("--print-client-config=")))
7
+ return undefined;
8
+ if (args.length !== 2 || args[0] !== "--print-client-config" ||
9
+ !CLIENT_CONFIG_TARGETS.includes(args[1])) {
10
+ throw new Error(usage);
11
+ }
12
+ return args[1];
13
+ }
14
+ /**
15
+ * Print a mergeable entry for this installed copy, bypassing the shared global
16
+ * command name. No file/config inspection, environment copying, or host contact.
17
+ * Paths are intentionally local and must not be included in public diagnostics.
18
+ */
19
+ export function renderClientConfig(target, nodeExecutable, serverEntrypoint, platform = process.platform) {
20
+ if (!CLIENT_CONFIG_TARGETS.includes(target))
21
+ throw new Error(usage);
22
+ const paths = platform === "win32" ? path.win32 : path.posix;
23
+ for (const value of [nodeExecutable, serverEntrypoint]) {
24
+ if (!paths.isAbsolute(value) || /[\u0000-\u001f\u007f]/u.test(value) || value.includes("${")) {
25
+ throw new Error("Client configuration requires absolute paths without control characters or client variable expressions.");
26
+ }
27
+ }
28
+ const entry = { command: nodeExecutable, args: [serverEntrypoint] };
29
+ if (target === "codex") {
30
+ return `[mcp_servers.premiere-pro-leancoderkavy]\ncommand = ${JSON.stringify(entry.command)}\nargs = ${JSON.stringify(entry.args)}\n`;
31
+ }
32
+ const config = target === "vscode"
33
+ ? { servers: { "premiere-pro-leancoderkavy": { type: "stdio", ...entry } } }
34
+ : { mcpServers: { "premiere-pro-leancoderkavy": entry } };
35
+ return `${JSON.stringify(config, null, 2)}\n`;
36
+ }
37
+ //# sourceMappingURL=client-config.js.map
@@ -0,0 +1,30 @@
1
+ import type http from "node:http";
2
+ export declare const HOMEPAGE_FLAG = "homepage-cinematic-2026";
3
+ export type HomepageVariant = "control" | "test";
4
+ type Properties = Record<string, string | number | boolean>;
5
+ export interface HomepageAnalytics {
6
+ evaluate(id: string): Promise<unknown>;
7
+ capture(id: string, event: string, properties: Properties): void;
8
+ shutdown(): Promise<void>;
9
+ }
10
+ export declare function homepageAnalyticsPermitted(req: Pick<http.IncomingMessage, "headers">): boolean;
11
+ /** Isolated from MCP telemetry: each visitor gets an anonymous identity. */
12
+ export declare class HomepageExperiment {
13
+ private readonly client;
14
+ private readonly secret;
15
+ private readonly enabled;
16
+ private readonly decisions;
17
+ private readonly eventCounts;
18
+ private evaluations;
19
+ constructor(client: HomepageAnalytics | undefined, secret: string, enabled: boolean);
20
+ private get active();
21
+ private sign;
22
+ private read;
23
+ private cookie;
24
+ assign(req: http.IncomingMessage, res: http.ServerResponse): Promise<HomepageVariant | undefined>;
25
+ handleEvent(req: http.IncomingMessage, res: http.ServerResponse): Promise<void>;
26
+ shutdown(): Promise<void>;
27
+ }
28
+ export declare function createHomepageExperiment(env?: NodeJS.ProcessEnv): HomepageExperiment;
29
+ export {};
30
+ //# sourceMappingURL=homepage-experiment.d.ts.map