@kenkaiiii/gg-editor-premiere-panel 0.2.1
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/LICENSE +21 -0
- package/README.md +200 -0
- package/dist/bin/cli.d.ts +3 -0
- package/dist/bin/cli.d.ts.map +1 -0
- package/dist/bin/cli.js +159 -0
- package/dist/bin/cli.js.map +1 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +3 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/installer.d.ts +54 -0
- package/dist/src/installer.d.ts.map +1 -0
- package/dist/src/installer.js +166 -0
- package/dist/src/installer.js.map +1 -0
- package/dist/src/installer.test.d.ts +2 -0
- package/dist/src/installer.test.d.ts.map +1 -0
- package/dist/src/installer.test.js +68 -0
- package/dist/src/installer.test.js.map +1 -0
- package/dist/src/paths.d.ts +30 -0
- package/dist/src/paths.d.ts.map +1 -0
- package/dist/src/paths.js +60 -0
- package/dist/src/paths.js.map +1 -0
- package/dist/src/paths.test.d.ts +2 -0
- package/dist/src/paths.test.d.ts.map +1 -0
- package/dist/src/paths.test.js +47 -0
- package/dist/src/paths.test.js.map +1 -0
- package/package.json +42 -0
- package/panel/.debug +15 -0
- package/panel/CSXS/manifest.xml +60 -0
- package/panel/index.html +28 -0
- package/panel/jsx/runtime.jsx +163 -0
- package/panel/lib/cs-interface.js +31 -0
- package/panel/lib/server.js +161 -0
- package/panel-uxp/commands/consts.js +43 -0
- package/panel-uxp/commands/index.js +401 -0
- package/panel-uxp/commands/utils.js +115 -0
- package/panel-uxp/index.html +107 -0
- package/panel-uxp/main.js +264 -0
- package/panel-uxp/manifest.json +46 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installer.test.d.ts","sourceRoot":"","sources":["../../src/installer.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { existsSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { installUxpPlugin, isUxpPluginInstalled, panelSourceDir, uninstallUxpPlugin, uxpPluginSourceDir, } from "./installer.js";
|
|
6
|
+
import * as paths from "./paths.js";
|
|
7
|
+
describe("panelSourceDir", () => {
|
|
8
|
+
it("locates the panel/ directory containing a manifest", () => {
|
|
9
|
+
const dir = panelSourceDir();
|
|
10
|
+
expect(existsSync(join(dir, "CSXS", "manifest.xml"))).toBe(true);
|
|
11
|
+
expect(existsSync(join(dir, "index.html"))).toBe(true);
|
|
12
|
+
expect(existsSync(join(dir, "lib", "server.js"))).toBe(true);
|
|
13
|
+
expect(existsSync(join(dir, "jsx", "runtime.jsx"))).toBe(true);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
describe("uxpPluginSourceDir", () => {
|
|
17
|
+
it("locates the panel-uxp/ directory containing a UXP manifest", () => {
|
|
18
|
+
const dir = uxpPluginSourceDir();
|
|
19
|
+
expect(existsSync(join(dir, "manifest.json"))).toBe(true);
|
|
20
|
+
expect(existsSync(join(dir, "index.html"))).toBe(true);
|
|
21
|
+
expect(existsSync(join(dir, "main.js"))).toBe(true);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
describe("UXP plugin install round-trip", () => {
|
|
25
|
+
let scratch;
|
|
26
|
+
beforeEach(() => {
|
|
27
|
+
// Redirect both the parent External dir and the destination plugin dir
|
|
28
|
+
// into a tempdir so the test never touches the user's real Adobe folder.
|
|
29
|
+
scratch = mkdtempSync(join(tmpdir(), "gg-uxp-install-"));
|
|
30
|
+
vi.spyOn(paths, "userUxpPluginsDir").mockReturnValue(scratch);
|
|
31
|
+
vi.spyOn(paths, "installedUxpPluginDir").mockReturnValue(join(scratch, paths.BUNDLE_ID_UXP));
|
|
32
|
+
});
|
|
33
|
+
afterEach(() => {
|
|
34
|
+
vi.restoreAllMocks();
|
|
35
|
+
try {
|
|
36
|
+
rmSync(scratch, { recursive: true, force: true });
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
/* */
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
it("installs the plugin into the External dir and reports it installed", () => {
|
|
43
|
+
expect(isUxpPluginInstalled()).toBe(false);
|
|
44
|
+
const r = installUxpPlugin();
|
|
45
|
+
expect(r.installedTo).toContain(paths.BUNDLE_ID_UXP);
|
|
46
|
+
expect(r.copiedFiles).toBeGreaterThan(0);
|
|
47
|
+
expect(isUxpPluginInstalled()).toBe(true);
|
|
48
|
+
expect(existsSync(join(r.installedTo, "manifest.json"))).toBe(true);
|
|
49
|
+
});
|
|
50
|
+
it("overwrites a previous install rather than failing", () => {
|
|
51
|
+
installUxpPlugin();
|
|
52
|
+
// Drop a stray file in there \u2014 it should be wiped on re-install.
|
|
53
|
+
const stray = join(scratch, paths.BUNDLE_ID_UXP, "stray.txt");
|
|
54
|
+
writeFileSync(stray, "stale");
|
|
55
|
+
installUxpPlugin();
|
|
56
|
+
expect(existsSync(stray)).toBe(false);
|
|
57
|
+
});
|
|
58
|
+
it("uninstalls cleanly and reports state", () => {
|
|
59
|
+
installUxpPlugin();
|
|
60
|
+
const r = uninstallUxpPlugin();
|
|
61
|
+
expect(r.removed).toBe(true);
|
|
62
|
+
expect(isUxpPluginInstalled()).toBe(false);
|
|
63
|
+
// Second call is a no-op.
|
|
64
|
+
const r2 = uninstallUxpPlugin();
|
|
65
|
+
expect(r2.removed).toBe(false);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
//# sourceMappingURL=installer.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installer.test.js","sourceRoot":"","sources":["../../src/installer.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-platform paths for the gg-editor Premiere extensions.
|
|
3
|
+
*
|
|
4
|
+
* Two distinct extension formats live side-by-side; users on Premiere 25.6+
|
|
5
|
+
* should prefer UXP (the only path that survives Adobe's September 2026
|
|
6
|
+
* ExtendScript sunset). Both panels can be installed at once — they have
|
|
7
|
+
* different bundle ids and don't conflict.
|
|
8
|
+
*
|
|
9
|
+
* CEP install locations (Adobe docs):
|
|
10
|
+
* - macOS: ~/Library/Application Support/Adobe/CEP/extensions/<bundleId>/
|
|
11
|
+
* - Windows: %APPDATA%\Adobe\CEP\extensions\<bundleId>\
|
|
12
|
+
*
|
|
13
|
+
* UXP install locations (Adobe UXP Developer Tool docs, "External" plugins):
|
|
14
|
+
* - macOS: ~/Library/Application Support/Adobe/UXP/Plugins/External/<bundleId>/
|
|
15
|
+
* - Windows: %APPDATA%\Adobe\UXP\Plugins\External\<bundleId>\
|
|
16
|
+
*
|
|
17
|
+
* Linux is unsupported on either path — Premiere has no Linux build.
|
|
18
|
+
*/
|
|
19
|
+
export declare const BUNDLE_ID = "com.kenkaiiii.gg-editor-premiere-panel";
|
|
20
|
+
export declare const BUNDLE_ID_UXP = "com.kenkaiiii.gg-editor-premiere-panel.uxp";
|
|
21
|
+
export declare function userExtensionsDir(): string;
|
|
22
|
+
export declare function installedPanelDir(): string;
|
|
23
|
+
export declare function userUxpPluginsDir(): string;
|
|
24
|
+
export declare function installedUxpPluginDir(): string;
|
|
25
|
+
/**
|
|
26
|
+
* The set of CSXS minor versions to set PlayerDebugMode for. We set them
|
|
27
|
+
* all so users with different Premiere versions all work.
|
|
28
|
+
*/
|
|
29
|
+
export declare const CSXS_VERSIONS: string[];
|
|
30
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/paths.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;GAiBG;AAEH,eAAO,MAAM,SAAS,2CAA2C,CAAC;AAClE,eAAO,MAAM,aAAa,+CAA+C,CAAC;AAE1E,wBAAgB,iBAAiB,IAAI,MAAM,CAc1C;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAsB1C;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,UAA0B,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { homedir, platform } from "node:os";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Cross-platform paths for the gg-editor Premiere extensions.
|
|
5
|
+
*
|
|
6
|
+
* Two distinct extension formats live side-by-side; users on Premiere 25.6+
|
|
7
|
+
* should prefer UXP (the only path that survives Adobe's September 2026
|
|
8
|
+
* ExtendScript sunset). Both panels can be installed at once — they have
|
|
9
|
+
* different bundle ids and don't conflict.
|
|
10
|
+
*
|
|
11
|
+
* CEP install locations (Adobe docs):
|
|
12
|
+
* - macOS: ~/Library/Application Support/Adobe/CEP/extensions/<bundleId>/
|
|
13
|
+
* - Windows: %APPDATA%\Adobe\CEP\extensions\<bundleId>\
|
|
14
|
+
*
|
|
15
|
+
* UXP install locations (Adobe UXP Developer Tool docs, "External" plugins):
|
|
16
|
+
* - macOS: ~/Library/Application Support/Adobe/UXP/Plugins/External/<bundleId>/
|
|
17
|
+
* - Windows: %APPDATA%\Adobe\UXP\Plugins\External\<bundleId>\
|
|
18
|
+
*
|
|
19
|
+
* Linux is unsupported on either path — Premiere has no Linux build.
|
|
20
|
+
*/
|
|
21
|
+
export const BUNDLE_ID = "com.kenkaiiii.gg-editor-premiere-panel";
|
|
22
|
+
export const BUNDLE_ID_UXP = "com.kenkaiiii.gg-editor-premiere-panel.uxp";
|
|
23
|
+
export function userExtensionsDir() {
|
|
24
|
+
switch (platform()) {
|
|
25
|
+
case "darwin":
|
|
26
|
+
return join(homedir(), "Library", "Application Support", "Adobe", "CEP", "extensions");
|
|
27
|
+
case "win32":
|
|
28
|
+
return process.env.APPDATA
|
|
29
|
+
? join(process.env.APPDATA, "Adobe", "CEP", "extensions")
|
|
30
|
+
: join(homedir(), "AppData", "Roaming", "Adobe", "CEP", "extensions");
|
|
31
|
+
default:
|
|
32
|
+
throw new Error(`CEP panels are only supported on macOS and Windows (got ${platform()}). ` +
|
|
33
|
+
`Premiere has no Linux build.`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export function installedPanelDir() {
|
|
37
|
+
return join(userExtensionsDir(), BUNDLE_ID);
|
|
38
|
+
}
|
|
39
|
+
export function userUxpPluginsDir() {
|
|
40
|
+
switch (platform()) {
|
|
41
|
+
case "darwin":
|
|
42
|
+
return join(homedir(), "Library", "Application Support", "Adobe", "UXP", "Plugins", "External");
|
|
43
|
+
case "win32":
|
|
44
|
+
return process.env.APPDATA
|
|
45
|
+
? join(process.env.APPDATA, "Adobe", "UXP", "Plugins", "External")
|
|
46
|
+
: join(homedir(), "AppData", "Roaming", "Adobe", "UXP", "Plugins", "External");
|
|
47
|
+
default:
|
|
48
|
+
throw new Error(`UXP plugins are only supported on macOS and Windows (got ${platform()}). ` +
|
|
49
|
+
`Premiere has no Linux build.`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export function installedUxpPluginDir() {
|
|
53
|
+
return join(userUxpPluginsDir(), BUNDLE_ID_UXP);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The set of CSXS minor versions to set PlayerDebugMode for. We set them
|
|
57
|
+
* all so users with different Premiere versions all work.
|
|
58
|
+
*/
|
|
59
|
+
export const CSXS_VERSIONS = ["9", "10", "11", "12"];
|
|
60
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,CAAC,MAAM,SAAS,GAAG,wCAAwC,CAAC;AAClE,MAAM,CAAC,MAAM,aAAa,GAAG,4CAA4C,CAAC;AAE1E,MAAM,UAAU,iBAAiB;IAC/B,QAAQ,QAAQ,EAAE,EAAE,CAAC;QACnB,KAAK,QAAQ;YACX,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,qBAAqB,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;QACzF,KAAK,OAAO;YACV,OAAO,OAAO,CAAC,GAAG,CAAC,OAAO;gBACxB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,CAAC;gBACzD,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;QAC1E;YACE,MAAM,IAAI,KAAK,CACb,2DAA2D,QAAQ,EAAE,KAAK;gBACxE,8BAA8B,CACjC,CAAC;IACN,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,IAAI,CAAC,iBAAiB,EAAE,EAAE,SAAS,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,QAAQ,QAAQ,EAAE,EAAE,CAAC;QACnB,KAAK,QAAQ;YACX,OAAO,IAAI,CACT,OAAO,EAAE,EACT,SAAS,EACT,qBAAqB,EACrB,OAAO,EACP,KAAK,EACL,SAAS,EACT,UAAU,CACX,CAAC;QACJ,KAAK,OAAO;YACV,OAAO,OAAO,CAAC,GAAG,CAAC,OAAO;gBACxB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC;gBAClE,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;QACnF;YACE,MAAM,IAAI,KAAK,CACb,4DAA4D,QAAQ,EAAE,KAAK;gBACzE,8BAA8B,CACjC,CAAC;IACN,CAAC;AACH,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,OAAO,IAAI,CAAC,iBAAiB,EAAE,EAAE,aAAa,CAAC,CAAC;AAClD,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.test.d.ts","sourceRoot":"","sources":["../../src/paths.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { platform } from "node:os";
|
|
3
|
+
import { BUNDLE_ID, BUNDLE_ID_UXP, installedPanelDir, installedUxpPluginDir, userExtensionsDir, userUxpPluginsDir, } from "./paths.js";
|
|
4
|
+
describe("paths", () => {
|
|
5
|
+
it("BUNDLE_ID is the canonical reverse-DNS string", () => {
|
|
6
|
+
expect(BUNDLE_ID).toBe("com.kenkaiiii.gg-editor-premiere-panel");
|
|
7
|
+
});
|
|
8
|
+
it("BUNDLE_ID_UXP is distinct so CEP and UXP can coexist", () => {
|
|
9
|
+
expect(BUNDLE_ID_UXP).toBe("com.kenkaiiii.gg-editor-premiere-panel.uxp");
|
|
10
|
+
expect(BUNDLE_ID_UXP).not.toBe(BUNDLE_ID);
|
|
11
|
+
});
|
|
12
|
+
it("userExtensionsDir is platform-correct", () => {
|
|
13
|
+
if (platform() === "darwin") {
|
|
14
|
+
expect(userExtensionsDir()).toMatch(/Library\/Application Support\/Adobe\/CEP\/extensions$/);
|
|
15
|
+
}
|
|
16
|
+
else if (platform() === "win32") {
|
|
17
|
+
expect(userExtensionsDir()).toMatch(/Adobe[\\/]CEP[\\/]extensions$/);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
expect(() => userExtensionsDir()).toThrow();
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
it("userUxpPluginsDir is platform-correct", () => {
|
|
24
|
+
if (platform() === "darwin") {
|
|
25
|
+
expect(userUxpPluginsDir()).toMatch(/Library\/Application Support\/Adobe\/UXP\/Plugins\/External$/);
|
|
26
|
+
}
|
|
27
|
+
else if (platform() === "win32") {
|
|
28
|
+
expect(userUxpPluginsDir()).toMatch(/Adobe[\\/]UXP[\\/]Plugins[\\/]External$/);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
expect(() => userUxpPluginsDir()).toThrow();
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
it("installedPanelDir composes bundle id under extensions dir", () => {
|
|
35
|
+
if (platform() === "darwin" || platform() === "win32") {
|
|
36
|
+
expect(installedPanelDir()).toContain(BUNDLE_ID);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
it("installedUxpPluginDir composes UXP bundle id under External dir", () => {
|
|
40
|
+
if (platform() === "darwin" || platform() === "win32") {
|
|
41
|
+
const dir = installedUxpPluginDir();
|
|
42
|
+
expect(dir).toContain(BUNDLE_ID_UXP);
|
|
43
|
+
expect(dir).toMatch(/UXP[\\/]Plugins[\\/]External/);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
//# sourceMappingURL=paths.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.test.js","sourceRoot":"","sources":["../../src/paths.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EACL,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAEpB,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;IACrB,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;QACzE,MAAM,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,IAAI,QAAQ,EAAE,KAAK,QAAQ,EAAE,CAAC;YAC5B,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,OAAO,CAAC,uDAAuD,CAAC,CAAC;QAC/F,CAAC;aAAM,IAAI,QAAQ,EAAE,KAAK,OAAO,EAAE,CAAC;YAClC,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC;QACvE,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,EAAE,CAAC,iBAAiB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;QAC9C,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,IAAI,QAAQ,EAAE,KAAK,QAAQ,EAAE,CAAC;YAC5B,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,OAAO,CACjC,8DAA8D,CAC/D,CAAC;QACJ,CAAC;aAAM,IAAI,QAAQ,EAAE,KAAK,OAAO,EAAE,CAAC;YAClC,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,OAAO,CAAC,yCAAyC,CAAC,CAAC;QACjF,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,EAAE,CAAC,iBAAiB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;QAC9C,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,IAAI,QAAQ,EAAE,KAAK,QAAQ,IAAI,QAAQ,EAAE,KAAK,OAAO,EAAE,CAAC;YACtD,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACnD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,GAAG,EAAE;QACzE,IAAI,QAAQ,EAAE,KAAK,QAAQ,IAAI,QAAQ,EAAE,KAAK,OAAO,EAAE,CAAC;YACtD,MAAM,GAAG,GAAG,qBAAqB,EAAE,CAAC;YACpC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;YACrC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC;QACtD,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kenkaiiii/gg-editor-premiere-panel",
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Adobe Premiere Pro extension that lets gg-editor drive Premiere. Ships both a UXP plugin (Premiere 25.6+) and a legacy CEP panel (sunset Sept 2026).",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/kenkaiiii/gg-framework.git",
|
|
10
|
+
"directory": "packages/gg-editor-premiere-panel"
|
|
11
|
+
},
|
|
12
|
+
"bin": {
|
|
13
|
+
"gg-editor-premiere-panel": "./dist/bin/cli.js"
|
|
14
|
+
},
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"import": "./dist/src/index.js",
|
|
18
|
+
"types": "./dist/src/index.d.ts"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"panel",
|
|
24
|
+
"panel-uxp"
|
|
25
|
+
],
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"chalk": "^5.6.2"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/node": "^25.6.0",
|
|
31
|
+
"typescript": "^6.0.3",
|
|
32
|
+
"vitest": "^4.1.4"
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "tsc",
|
|
39
|
+
"check": "tsc --noEmit",
|
|
40
|
+
"test": "vitest run"
|
|
41
|
+
}
|
|
42
|
+
}
|
package/panel/.debug
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!--
|
|
3
|
+
CEP debug ports per host. Lets you attach Chrome DevTools to the panel
|
|
4
|
+
webview at http://localhost:8088 while developing.
|
|
5
|
+
|
|
6
|
+
This file MUST sit next to manifest.xml in the deployed extension. It is
|
|
7
|
+
ignored in production / signed bundles.
|
|
8
|
+
-->
|
|
9
|
+
<ExtensionList>
|
|
10
|
+
<Extension Id="com.kenkaiiii.gg-editor-premiere-panel">
|
|
11
|
+
<HostList>
|
|
12
|
+
<Host Name="PPRO" Port="8088" />
|
|
13
|
+
</HostList>
|
|
14
|
+
</Extension>
|
|
15
|
+
</ExtensionList>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
|
2
|
+
<!--
|
|
3
|
+
CSXS manifest for the gg-editor Premiere panel.
|
|
4
|
+
|
|
5
|
+
Hosts: PPRO (Adobe Premiere Pro), versions 14.0 → 99.9
|
|
6
|
+
Node: --enable-nodejs is required so the panel can run an HTTP server.
|
|
7
|
+
CORS: --mixed-context allows http requests from the panel's webview.
|
|
8
|
+
|
|
9
|
+
v0 targets PPRO only. Add AEFT later if we want After Effects support.
|
|
10
|
+
-->
|
|
11
|
+
<ExtensionManifest Version="11.0" ExtensionBundleId="com.kenkaiiii.gg-editor-premiere-panel"
|
|
12
|
+
ExtensionBundleVersion="0.1.0"
|
|
13
|
+
ExtensionBundleName="GG Editor Premiere Panel"
|
|
14
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
|
15
|
+
<ExtensionList>
|
|
16
|
+
<Extension Id="com.kenkaiiii.gg-editor-premiere-panel" Version="0.1.0" />
|
|
17
|
+
</ExtensionList>
|
|
18
|
+
|
|
19
|
+
<ExecutionEnvironment>
|
|
20
|
+
<HostList>
|
|
21
|
+
<Host Name="PPRO" Version="[14.0,99.9]" />
|
|
22
|
+
</HostList>
|
|
23
|
+
<LocaleList>
|
|
24
|
+
<Locale Code="All" />
|
|
25
|
+
</LocaleList>
|
|
26
|
+
<RequiredRuntimeList>
|
|
27
|
+
<RequiredRuntime Name="CSXS" Version="11.0" />
|
|
28
|
+
</RequiredRuntimeList>
|
|
29
|
+
</ExecutionEnvironment>
|
|
30
|
+
|
|
31
|
+
<DispatchInfoList>
|
|
32
|
+
<Extension Id="com.kenkaiiii.gg-editor-premiere-panel">
|
|
33
|
+
<DispatchInfo>
|
|
34
|
+
<Resources>
|
|
35
|
+
<MainPath>./index.html</MainPath>
|
|
36
|
+
<ScriptPath>./jsx/runtime.jsx</ScriptPath>
|
|
37
|
+
<CEFCommandLine>
|
|
38
|
+
<Parameter>--enable-nodejs</Parameter>
|
|
39
|
+
<Parameter>--mixed-context</Parameter>
|
|
40
|
+
</CEFCommandLine>
|
|
41
|
+
</Resources>
|
|
42
|
+
<Lifecycle>
|
|
43
|
+
<AutoVisible>true</AutoVisible>
|
|
44
|
+
<StartOn>
|
|
45
|
+
<Event>com.adobe.csxs.events.ApplicationActivate</Event>
|
|
46
|
+
</StartOn>
|
|
47
|
+
</Lifecycle>
|
|
48
|
+
<UI>
|
|
49
|
+
<Type>Panel</Type>
|
|
50
|
+
<Menu>GG Editor</Menu>
|
|
51
|
+
<Geometry>
|
|
52
|
+
<Size><Height>240</Height><Width>320</Width></Size>
|
|
53
|
+
<MinSize><Height>180</Height><Width>240</Width></MinSize>
|
|
54
|
+
<MaxSize><Height>900</Height><Width>1200</Width></MaxSize>
|
|
55
|
+
</Geometry>
|
|
56
|
+
</UI>
|
|
57
|
+
</DispatchInfo>
|
|
58
|
+
</Extension>
|
|
59
|
+
</DispatchInfoList>
|
|
60
|
+
</ExtensionManifest>
|
package/panel/index.html
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<title>GG Editor — Premiere Panel</title>
|
|
6
|
+
<style>
|
|
7
|
+
body { background: #1f2937; color: #e5e7eb; font: 12px -apple-system, "Segoe UI", sans-serif; padding: 12px; margin: 0; }
|
|
8
|
+
h1 { font-size: 14px; font-weight: 700; color: #60a5fa; margin: 0 0 8px; }
|
|
9
|
+
.row { display: flex; justify-content: space-between; padding: 4px 0; border-bottom: 1px solid #374151; }
|
|
10
|
+
.row:last-child { border-bottom: none; }
|
|
11
|
+
.muted { color: #9ca3af; }
|
|
12
|
+
.ok { color: #4ade80; }
|
|
13
|
+
.err { color: #f87171; }
|
|
14
|
+
.pill { background: #374151; padding: 1px 6px; border-radius: 3px; font-size: 11px; }
|
|
15
|
+
code { background: #111827; padding: 1px 4px; border-radius: 2px; font-family: ui-monospace, monospace; }
|
|
16
|
+
</style>
|
|
17
|
+
</head>
|
|
18
|
+
<body>
|
|
19
|
+
<h1>GG Editor</h1>
|
|
20
|
+
<div class="row"><span class="muted">Status</span><span id="status" class="pill">starting…</span></div>
|
|
21
|
+
<div class="row"><span class="muted">Port</span><span id="port" class="pill">—</span></div>
|
|
22
|
+
<div class="row"><span class="muted">Requests</span><span id="reqs">0</span></div>
|
|
23
|
+
<div class="row"><span class="muted">Last error</span><span id="lastErr" class="muted">—</span></div>
|
|
24
|
+
<div class="row"><span class="muted">CLI</span><code>ggeditor --host premiere</code></div>
|
|
25
|
+
<script src="lib/cs-interface.js"></script>
|
|
26
|
+
<script src="lib/server.js"></script>
|
|
27
|
+
</body>
|
|
28
|
+
</html>
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSX runtime for the gg-editor Premiere panel.
|
|
3
|
+
*
|
|
4
|
+
* Exposes `gg_<method>(jsonString)` global functions. The Node-side panel
|
|
5
|
+
* server calls these via CSInterface.evalScript and parses the JSON result.
|
|
6
|
+
*
|
|
7
|
+
* Each method:
|
|
8
|
+
* - Receives a JSON-encoded params string
|
|
9
|
+
* - Wraps work in try/catch
|
|
10
|
+
* - Returns a JSON string of {ok: true, result: ...} or {ok: false, error: "..."}
|
|
11
|
+
*
|
|
12
|
+
* Modern Premiere (2018+) ships ECMAScript 5 with full JSON.
|
|
13
|
+
*
|
|
14
|
+
* Methods mirror the macOS bridge:
|
|
15
|
+
* ping, get_timeline, add_marker, append_clip, import_timeline
|
|
16
|
+
*
|
|
17
|
+
* Unsupported via live API (use write_edl + import_timeline on the gg-editor side):
|
|
18
|
+
* cut_at, ripple_delete, render
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
function _ok(v) { return JSON.stringify({ ok: true, result: v === undefined ? null : v }); }
|
|
22
|
+
function _fail(e) {
|
|
23
|
+
return JSON.stringify({ ok: false, error: (e && e.message) ? String(e.message) : String(e) });
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function _seq() {
|
|
27
|
+
if (!app.project) throw new Error("No project open in Premiere.");
|
|
28
|
+
var s = app.project.activeSequence;
|
|
29
|
+
if (!s) throw new Error("No active sequence in Premiere.");
|
|
30
|
+
return s;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function _fps(seq) {
|
|
34
|
+
var fd = seq.getSettings().videoFrameRate.seconds;
|
|
35
|
+
return fd > 0 ? 1 / fd : 30;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function _frames(time, seq) {
|
|
39
|
+
var tb = parseInt(seq.timebase, 10);
|
|
40
|
+
if (!tb || isNaN(tb)) tb = 1;
|
|
41
|
+
return Math.round(parseInt(time.ticks, 10) / tb);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function _markerColor(name) {
|
|
45
|
+
var m = { green:0, red:1, purple:2, orange:3, yellow:4, white:5, blue:6, cyan:7 };
|
|
46
|
+
var k = (name || "blue").toLowerCase();
|
|
47
|
+
return m[k] !== undefined ? m[k] : 6;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function _findClipBin(name) {
|
|
51
|
+
var stack = [app.project.rootItem];
|
|
52
|
+
while (stack.length) {
|
|
53
|
+
var item = stack.pop();
|
|
54
|
+
for (var i = 0; i < item.children.numItems; i++) {
|
|
55
|
+
var child = item.children[i];
|
|
56
|
+
if (child.name === name) return child;
|
|
57
|
+
if (child.type === 2) stack.push(child); // BIN
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// ── Method implementations ──────────────────────────────────
|
|
64
|
+
|
|
65
|
+
function gg_ping(_jsonParams) {
|
|
66
|
+
try {
|
|
67
|
+
return _ok({ product: "Premiere Pro", version: app.version || "?" });
|
|
68
|
+
} catch (e) { return _fail(e); }
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function gg_get_timeline(_jsonParams) {
|
|
72
|
+
try {
|
|
73
|
+
var seq = _seq();
|
|
74
|
+
var fps = _fps(seq);
|
|
75
|
+
var clips = [];
|
|
76
|
+
function collect(tracks, kind) {
|
|
77
|
+
for (var ti = 0; ti < tracks.numTracks; ti++) {
|
|
78
|
+
var tr = tracks[ti];
|
|
79
|
+
for (var ci = 0; ci < tr.clips.numItems; ci++) {
|
|
80
|
+
var c = tr.clips[ci];
|
|
81
|
+
try {
|
|
82
|
+
clips.push({
|
|
83
|
+
id: String(c.nodeId || c.name + ":" + ci),
|
|
84
|
+
track: ti + 1,
|
|
85
|
+
trackKind: kind,
|
|
86
|
+
startFrame: _frames(c.start, seq),
|
|
87
|
+
endFrame: _frames(c.end, seq),
|
|
88
|
+
name: c.name
|
|
89
|
+
});
|
|
90
|
+
} catch (_) { /* skip uninspectable */ }
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
collect(seq.videoTracks, "video");
|
|
95
|
+
collect(seq.audioTracks, "audio");
|
|
96
|
+
|
|
97
|
+
var markers = [];
|
|
98
|
+
var mc = seq.markers;
|
|
99
|
+
var m = mc.getFirstMarker();
|
|
100
|
+
while (m) {
|
|
101
|
+
markers.push({
|
|
102
|
+
frame: _frames(m.start, seq),
|
|
103
|
+
note: (m.comments || m.name || ""),
|
|
104
|
+
color: m.colorIndex,
|
|
105
|
+
durationFrames: _frames(m.end, seq) - _frames(m.start, seq)
|
|
106
|
+
});
|
|
107
|
+
m = mc.getNextMarker(m);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
var dur = (seq.end ? _frames({ ticks: seq.end }, seq) : 0);
|
|
111
|
+
return _ok({ name: seq.name, frameRate: fps, durationFrames: dur, clips: clips, markers: markers });
|
|
112
|
+
} catch (e) { return _fail(e); }
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function gg_add_marker(jsonParams) {
|
|
116
|
+
try {
|
|
117
|
+
var P = JSON.parse(jsonParams || "{}");
|
|
118
|
+
var seq = _seq();
|
|
119
|
+
var fps = _fps(seq);
|
|
120
|
+
var m = seq.markers.createMarker(P.frame / fps);
|
|
121
|
+
m.name = (P.note || "").substring(0, 60);
|
|
122
|
+
m.comments = P.note || "";
|
|
123
|
+
if (P.durationFrames && P.durationFrames > 1) {
|
|
124
|
+
m.end = m.start + (P.durationFrames / fps);
|
|
125
|
+
}
|
|
126
|
+
try { m.setColorByIndex(_markerColor(P.color)); } catch (_) {}
|
|
127
|
+
return _ok(null);
|
|
128
|
+
} catch (e) { return _fail(e); }
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function gg_append_clip(jsonParams) {
|
|
132
|
+
try {
|
|
133
|
+
var P = JSON.parse(jsonParams || "{}");
|
|
134
|
+
var seq = _seq();
|
|
135
|
+
var ok = app.project.importFiles([P.mediaPath], true, app.project.rootItem, false);
|
|
136
|
+
if (!ok) throw new Error("importFiles returned false for " + P.mediaPath);
|
|
137
|
+
var base = String(P.mediaPath).replace(/\\/g, "/").split("/").pop();
|
|
138
|
+
var pi = _findClipBin(base);
|
|
139
|
+
if (!pi) throw new Error("Imported item not found in project bin: " + base);
|
|
140
|
+
var track = seq.videoTracks[(P.track || 1) - 1];
|
|
141
|
+
if (!track) throw new Error("Track " + P.track + " does not exist on active sequence.");
|
|
142
|
+
var endSec = seq.end ? (parseInt(seq.end, 10) / 254016000000) : 0;
|
|
143
|
+
track.insertClip(pi, endSec);
|
|
144
|
+
var inserted = track.clips[track.clips.numItems - 1];
|
|
145
|
+
return _ok({
|
|
146
|
+
id: String(inserted.nodeId || inserted.name),
|
|
147
|
+
track: P.track || 1,
|
|
148
|
+
trackKind: "video",
|
|
149
|
+
startFrame: _frames(inserted.start, seq),
|
|
150
|
+
endFrame: _frames(inserted.end, seq),
|
|
151
|
+
name: inserted.name
|
|
152
|
+
});
|
|
153
|
+
} catch (e) { return _fail(e); }
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function gg_import_timeline(jsonParams) {
|
|
157
|
+
try {
|
|
158
|
+
var P = JSON.parse(jsonParams || "{}");
|
|
159
|
+
var ok = app.project.importFiles([P.filePath], true, app.project.rootItem, false);
|
|
160
|
+
if (!ok) throw new Error("importFiles returned false for " + P.filePath);
|
|
161
|
+
return _ok(null);
|
|
162
|
+
} catch (e) { return _fail(e); }
|
|
163
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
/**
|
|
3
|
+
* Minimal CSInterface stub. Adobe ships a much larger CSInterface.js with
|
|
4
|
+
* dozens of helpers; we only need evalScript() to run JSX in the host. The
|
|
5
|
+
* extension API global `__adobe_cep__` is provided by the CEF runtime.
|
|
6
|
+
*/
|
|
7
|
+
(function (global) {
|
|
8
|
+
function CSInterface() {}
|
|
9
|
+
|
|
10
|
+
CSInterface.prototype.evalScript = function (script, callback) {
|
|
11
|
+
var cb = callback || function () {};
|
|
12
|
+
if (typeof global.__adobe_cep__ !== "undefined" && global.__adobe_cep__.evalScript) {
|
|
13
|
+
global.__adobe_cep__.evalScript(script, cb);
|
|
14
|
+
} else {
|
|
15
|
+
// Outside the CEP host (browser dev): no-op.
|
|
16
|
+
setTimeout(function () {
|
|
17
|
+
cb("CSInterface not available outside CEP host");
|
|
18
|
+
}, 0);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
CSInterface.prototype.getHostEnvironment = function () {
|
|
23
|
+
if (typeof global.__adobe_cep__ !== "undefined" && global.__adobe_cep__.getHostEnvironment) {
|
|
24
|
+
try { return JSON.parse(global.__adobe_cep__.getHostEnvironment()); }
|
|
25
|
+
catch (_) { return {}; }
|
|
26
|
+
}
|
|
27
|
+
return {};
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
global.CSInterface = CSInterface;
|
|
31
|
+
})(this);
|