feat: initial commit - Jhonny Editor

- Adicionado estrutura completa do projeto
- Configurado MCP server para Premiere Pro
- Adicionado documentação e skills
- Configurado Gitignore para o projeto
This commit is contained in:
João Henrique
2026-09-08 09:59:31 -04:00
commit b541f502ba
1507 changed files with 387650 additions and 0 deletions
+652
View File
@@ -0,0 +1,652 @@
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import { mkdir } from "node:fs/promises";
import { spawnSync } from "node:child_process";
import { join } from "node:path";
import { tmpdir } from "node:os";
import { deflateRawSync } from "node:zlib";
import { describe, expect, it } from "vitest";
import { NATIVE_SDK_HEADER_INVENTORY_SEMANTICS } from "../scripts/native-sdk-header-inventory-contract.mjs";
import { UXP_HYBRID_CCX_RECEIPT_LEGACY_SEMANTICS } from "../scripts/uxp-hybrid-ccx-receipt-contract.mjs";
import {
buildUxpHybridCcxReceipt,
canonicalUxpHybridCcxReceiptSha256,
verifyUxpHybridCcxReceipt,
} from "../scripts/uxp-hybrid-ccx-receipt-core.mjs";
import { generateUxpHybridAddonReceipt } from "../scripts/generate-uxp-hybrid-addon-receipt.mjs";
import { canonicalUxpHybridAddonReceiptSha256 } from "../scripts/verify-uxp-hybrid-addon-receipt.mjs";
import { canonicalNativeSdkHeaderInventorySha256 } from "../scripts/verify-native-sdk-header-inventory.mjs";
import { verifyHybridBenchmarkEvidenceWithLocalCcx } from "../scripts/verify-uxp-hybrid-benchmark.mjs";
const hash = (value: string) => value.repeat(64);
function sdkHeaderReceipt() {
return {
schemaVersion: 1,
source: {
sdk: "uxp-hybrid",
sdkVersion: "fixture-sdk",
authorityUrl: "https://developer.adobe.com/premiere-pro/uxp/plugins/hybrid-plugins/",
archiveSha256: hash("a"),
inventoryScope: "header_files_only",
includeDirectories: ["src/api", "src/utilities"],
},
semantics: NATIVE_SDK_HEADER_INVENTORY_SEMANTICS,
stats: { headers: 3, bytes: 24 },
headers: [
{ path: "src/api/UxpAddonShared.h", bytes: 7, sha256: hash("b") },
{ path: "src/api/UxpAddonTypes.h", bytes: 8, sha256: hash("c") },
{ path: "src/utilities/UxpAddon.h", bytes: 9, sha256: hash("d") },
],
};
}
async function writeDevelopmentBundle(root: string, additions: Record<string, unknown> = {}) {
const name = "fixture-addon.uxpaddon";
writeFileSync(join(root, "manifest.json"), `${JSON.stringify({
id: "fixture-hybrid-plugin",
manifestVersion: 6,
host: { app: "premierepro", minVersion: "25.6.0" },
addon: { name },
requiredPermissions: { enableAddon: true },
...additions,
}, null, 2)}\n`);
writeFileSync(join(root, "main.js"), "const addon = require(\"fixture-addon.uxpaddon\");\n");
for (const [path, contents] of [
[`mac/x64/${name}`, "mac intel fixture"],
[`mac/arm64/${name}`, "mac arm fixture"],
[`win/x64/${name}`, "windows fixture"],
]) {
const target = join(root, ...path.split("/"));
await mkdir(join(target, ".."), { recursive: true });
writeFileSync(target, contents);
}
}
function crc32(buffer: Buffer) {
let value = 0xffff_ffff;
for (const byte of buffer) {
value ^= byte;
for (let bit = 0; bit < 8; bit += 1) value = (value >>> 1) ^ (value & 1 ? 0xedb8_8320 : 0);
}
return (value ^ 0xffff_ffff) >>> 0;
}
type DataDescriptorMetadata = false | { signature?: boolean; crc32?: number; compressedBytes?: number; uncompressedBytes?: number };
type ZipOptions = {
flags?: number;
method?: number;
localPreamble?: Buffer;
localSuffix?: Buffer;
centralSuffix?: Buffer;
localNames?: Record<string, string>;
localExtraFields?: Record<string, Buffer>;
centralExtraFields?: Record<string, Buffer>;
centralComments?: Record<string, Buffer>;
localMetadata?: Record<string, { versionNeeded?: number; flags?: number; method?: number; crc32?: number; compressedBytes?: number; uncompressedBytes?: number }>;
centralMetadata?: Record<string, { versionMadeBy?: number; versionNeeded?: number; flags?: number; compressedBytes?: number; uncompressedBytes?: number; externalAttributes?: number; localOffset?: number }>;
crc32Adjustments?: Record<string, number>;
compressedDataSuffixes?: Record<string, Buffer>;
compressedByteAdjustments?: Record<string, number>;
dataDescriptors?: Record<string, DataDescriptorMetadata>;
};
function createZip(entries: Array<{ path: string; contents: Buffer }>, prefix = "", deflate = true, localNameOverride?: string, options: ZipOptions = {}) {
const locals: Buffer[] = options.localPreamble ? [options.localPreamble] : [];
const centrals: Buffer[] = [];
let localOffset = options.localPreamble?.length ?? 0;
for (const entry of entries) {
const name = Buffer.from(`${prefix}${entry.path}`, "utf8");
const method = options.method ?? (deflate ? 8 : 0);
const compressed = method === 8 ? deflateRawSync(entry.contents) : entry.contents;
const compressedPayload = options.compressedDataSuffixes?.[entry.path]
? Buffer.concat([compressed, options.compressedDataSuffixes[entry.path]])
: compressed;
const flags = 0x800 | (options.flags ?? 0);
const declaredCrc32 = (crc32(entry.contents) + (options.crc32Adjustments?.[entry.path] ?? 0)) >>> 0;
const declaredCompressedBytes = compressedPayload.length + (options.compressedByteAdjustments?.[entry.path] ?? 0);
const localMetadata = options.localMetadata?.[entry.path] ?? {};
const localExtraFields = options.localExtraFields?.[entry.path] ?? Buffer.alloc(0);
const local = Buffer.alloc(30);
local.writeUInt32LE(0x04034b50, 0);
local.writeUInt16LE(localMetadata.versionNeeded ?? 20, 4);
local.writeUInt16LE(localMetadata.flags ?? flags, 6);
local.writeUInt16LE(localMetadata.method ?? method, 8);
local.writeUInt32LE(localMetadata.crc32 ?? declaredCrc32, 14);
local.writeUInt32LE(localMetadata.compressedBytes ?? declaredCompressedBytes, 18);
local.writeUInt32LE(localMetadata.uncompressedBytes ?? entry.contents.length, 22);
local.writeUInt16LE(name.length, 26);
const localNamePath = options.localNames?.[entry.path] ?? (localNameOverride && entry.path === "main.js" ? localNameOverride : entry.path);
const localName = Buffer.from(`${prefix}${localNamePath}`, "utf8");
local.writeUInt16LE(localName.length, 26);
local.writeUInt16LE(localExtraFields.length, 28);
locals.push(local, localName, localExtraFields, compressedPayload);
const descriptorMetadata = flags & 0x8 ? options.dataDescriptors?.[entry.path] ?? {} : false;
const descriptor = descriptorMetadata === false ? undefined : Buffer.alloc(descriptorMetadata.signature === false ? 12 : 16);
if (descriptor) {
const offset = descriptor.length === 16 ? 4 : 0;
if (offset) descriptor.writeUInt32LE(0x08074b50, 0);
descriptor.writeUInt32LE(descriptorMetadata.crc32 ?? declaredCrc32, offset);
descriptor.writeUInt32LE(descriptorMetadata.compressedBytes ?? declaredCompressedBytes, offset + 4);
descriptor.writeUInt32LE(descriptorMetadata.uncompressedBytes ?? entry.contents.length, offset + 8);
locals.push(descriptor);
}
const central = Buffer.alloc(46);
const centralMetadata = options.centralMetadata?.[entry.path] ?? {};
const centralExtraFields = options.centralExtraFields?.[entry.path] ?? Buffer.alloc(0);
const centralComment = options.centralComments?.[entry.path] ?? Buffer.alloc(0);
central.writeUInt32LE(0x02014b50, 0);
central.writeUInt16LE(centralMetadata.versionMadeBy ?? 20, 4);
central.writeUInt16LE(centralMetadata.versionNeeded ?? 20, 6);
central.writeUInt16LE(centralMetadata.flags ?? flags, 8);
central.writeUInt16LE(method, 10);
central.writeUInt32LE(declaredCrc32, 16);
central.writeUInt32LE(centralMetadata.compressedBytes ?? declaredCompressedBytes, 20);
central.writeUInt32LE(centralMetadata.uncompressedBytes ?? entry.contents.length, 24);
central.writeUInt16LE(name.length, 28);
central.writeUInt16LE(centralExtraFields.length, 30);
central.writeUInt16LE(centralComment.length, 32);
central.writeUInt32LE(centralMetadata.externalAttributes ?? 0, 38);
central.writeUInt32LE(centralMetadata.localOffset ?? localOffset, 42);
centrals.push(central, name, centralExtraFields, centralComment);
localOffset += local.length + localName.length + localExtraFields.length + compressedPayload.length + (descriptor?.length ?? 0);
}
if (options.localSuffix) {
locals.push(options.localSuffix);
localOffset += options.localSuffix.length;
}
const central = Buffer.concat(centrals);
const centralSuffix = options.centralSuffix ?? Buffer.alloc(0);
const end = Buffer.alloc(22);
end.writeUInt32LE(0x06054b50, 0);
end.writeUInt16LE(entries.length, 8);
end.writeUInt16LE(entries.length, 10);
end.writeUInt32LE(central.length, 12);
end.writeUInt32LE(localOffset, 16);
return Buffer.concat([...locals, central, centralSuffix, end]);
}
function writeCcx(bundle: string, archive: string, options: { prefix?: string; deflate?: boolean; main?: string; manifest?: Record<string, unknown>; duplicateMain?: boolean; localMainName?: string; extra?: Array<{ path: string; contents: Buffer }>; zipFlags?: number; compressionMethod?: number; localPreamble?: Buffer; localSuffix?: Buffer; centralSuffix?: Buffer; localNames?: Record<string, string>; localExtraFields?: Record<string, Buffer>; centralExtraFields?: Record<string, Buffer>; centralComments?: Record<string, Buffer>; localMetadata?: Record<string, { versionNeeded?: number; flags?: number; method?: number; crc32?: number; compressedBytes?: number; uncompressedBytes?: number }>; centralMetadata?: Record<string, { versionMadeBy?: number; versionNeeded?: number; flags?: number; compressedBytes?: number; uncompressedBytes?: number; externalAttributes?: number; localOffset?: number }>; crc32Adjustments?: Record<string, number>; compressedDataSuffixes?: Record<string, Buffer>; compressedByteAdjustments?: Record<string, number>; dataDescriptors?: Record<string, DataDescriptorMetadata> } = {}) {
const name = "fixture-addon.uxpaddon";
const manifest = { ...JSON.parse(readFileSync(join(bundle, "manifest.json"), "utf8")), ...(options.manifest ?? {}) };
const entries = [
{ path: "manifest.json", contents: Buffer.from(`${JSON.stringify(manifest, null, 2)}\n`) },
{ path: "main.js", contents: Buffer.from(options.main ?? readFileSync(join(bundle, "main.js"))) },
{ path: `mac/x64/${name}`, contents: readFileSync(join(bundle, "mac", "x64", name)) },
{ path: `mac/arm64/${name}`, contents: readFileSync(join(bundle, "mac", "arm64", name)) },
{ path: `win/x64/${name}`, contents: readFileSync(join(bundle, "win", "x64", name)) },
];
entries.push(...(options.extra ?? []));
if (options.duplicateMain) entries.push({ path: "main.js", contents: Buffer.from("duplicate") });
writeFileSync(archive, createZip(entries, options.prefix ?? "", options.deflate ?? true, options.localMainName, {
flags: options.zipFlags,
method: options.compressionMethod,
localPreamble: options.localPreamble,
localSuffix: options.localSuffix,
centralSuffix: options.centralSuffix,
localNames: options.localNames,
localExtraFields: options.localExtraFields,
centralExtraFields: options.centralExtraFields,
centralComments: options.centralComments,
localMetadata: options.localMetadata,
centralMetadata: options.centralMetadata,
crc32Adjustments: options.crc32Adjustments,
compressedDataSuffixes: options.compressedDataSuffixes,
compressedByteAdjustments: options.compressedByteAdjustments,
dataDescriptors: options.dataDescriptors,
}));
}
describe("UXP Hybrid CCX receipt", () => {
it("binds a wrapped, deflated CCX ZIP to a v2 addon receipt without copying archive contents", async () => {
const directory = mkdtempSync(join(tmpdir(), "premiere-hybrid-ccx-receipt-"));
const bundle = join(directory, "bundle");
const archive = join(directory, "fixture.ccx");
const headers = sdkHeaderReceipt();
try {
await mkdir(bundle, { recursive: true });
await writeDevelopmentBundle(bundle);
const addonReceipt = await generateUxpHybridAddonReceipt({ pluginRoot: bundle, sdkHeaderReceipt: headers });
writeCcx(bundle, archive, {
prefix: "fixture-hybrid-plugin/",
zipFlags: 0x8,
dataDescriptors: { "main.js": { signature: false } },
});
const receipt = await buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers });
expect(receipt).toMatchObject({
schemaVersion: 2,
source: { sdk: "uxp-hybrid", addonReceiptSha256: expect.stringMatching(/^[a-f0-9]{64}$/) },
archive: { format: "zip", bytes: expect.any(Number), sha256: expect.stringMatching(/^[a-f0-9]{64}$/) },
contents: { entries: 5, files: 5, directories: 0, pathSetSha256: expect.stringMatching(/^[a-f0-9]{64}$/) },
manifest: { idLength: "fixture-hybrid-plugin".length, idSha256: expect.stringMatching(/^[a-f0-9]{64}$/), addonName: "fixture-addon.uxpaddon" },
stats: { artifacts: 3, entrypoints: 1 },
});
expect(verifyUxpHybridCcxReceipt(receipt, { addonReceipt, sdkHeaderReceipt: headers })).toEqual({
artifacts: 3,
addonBytes: addonReceipt.stats.addonBytes,
entrypoints: 1,
entrypointBytes: addonReceipt.stats.entrypointBytes,
});
const { contents: ignoredContents, ...legacyReceipt } = receipt;
expect(ignoredContents).toBeDefined();
expect(verifyUxpHybridCcxReceipt({
...legacyReceipt,
schemaVersion: 1,
semantics: UXP_HYBRID_CCX_RECEIPT_LEGACY_SEMANTICS,
}, { addonReceipt, sdkHeaderReceipt: headers })).toEqual({
artifacts: 3,
addonBytes: addonReceipt.stats.addonBytes,
entrypoints: 1,
entrypointBytes: addonReceipt.stats.entrypointBytes,
});
const legacyPath = join(directory, "legacy-ccx-receipt.json");
const legacyHeadersPath = join(directory, "legacy-headers.json");
const legacyAddonPath = join(directory, "legacy-addon-receipt.json");
writeFileSync(legacyPath, `${JSON.stringify({
...legacyReceipt,
schemaVersion: 1,
semantics: UXP_HYBRID_CCX_RECEIPT_LEGACY_SEMANTICS,
}, null, 2)}\n`);
writeFileSync(legacyHeadersPath, `${JSON.stringify(headers, null, 2)}\n`);
writeFileSync(legacyAddonPath, `${JSON.stringify(addonReceipt, null, 2)}\n`);
const legacyVerified = spawnSync(process.execPath, [
"scripts/verify-uxp-hybrid-ccx-receipt.mjs",
"--input", legacyPath,
"--ccx", archive,
"--addon-receipt", legacyAddonPath,
"--sdk-header-receipt", legacyHeadersPath,
], { encoding: "utf8" });
expect(legacyVerified.status).toBe(0);
expect(legacyVerified.stdout).toContain("UXP Hybrid CCX receipt is valid");
expect(() => verifyUxpHybridCcxReceipt({
...receipt,
contents: { ...receipt.contents, files: receipt.contents.files - 1 },
})).toThrow("contents file and directory totals must match entries");
expect(canonicalUxpHybridCcxReceiptSha256(receipt)).toMatch(/^[a-f0-9]{64}$/);
expect(JSON.stringify(receipt)).not.toContain("fixture-hybrid-plugin");
expect(JSON.stringify(receipt)).not.toContain("mac/x64");
expect(JSON.stringify(receipt)).not.toContain("const addon");
expect(JSON.stringify(receipt)).not.toContain("mac intel fixture");
expect(JSON.stringify(receipt)).not.toContain(directory);
const benchmarkEvidence = {
schemaVersion: 3,
workloadId: "weighted-energy-v1",
configuration: { sampleCount: 30, warmupCount: 3, iterations: 4, inputLength: 131072, seed: 1337 },
memoryMeasurement: "fixture process monitor",
sdkHeaderReceiptSha256: canonicalNativeSdkHeaderInventorySha256(headers),
addonReceiptSha256: canonicalUxpHybridAddonReceiptSha256(addonReceipt),
ccxReceiptSha256: canonicalUxpHybridCcxReceiptSha256(receipt),
runs: addonReceipt.artifacts.map((artifact) => {
const [platform, arch] = artifact.target.split("-");
return {
platform,
arch,
hostVersion: "26.3.0",
sdkVersion: "fixture-sdk",
buildMode: "Release",
addonLoaded: true,
addonSha256: artifact.sha256,
sourceCommit: "a".repeat(40),
checksumMatch: true,
codeSigned: platform === "mac",
notarized: platform === "mac",
javascript: { sampleCount: 30, p50Ms: 100, p95Ms: 140, peakWorkingSetBytes: 1000 },
native: { sampleCount: 30, p50Ms: 60, p95Ms: 80, peakWorkingSetBytes: 1050 },
};
}),
};
await expect(verifyHybridBenchmarkEvidenceWithLocalCcx(benchmarkEvidence, {
ccxPath: archive,
addonReceipt,
sdkHeaderReceipt: headers,
ccxReceipt: receipt,
})).resolves.toMatchObject({ promotionEligible: true, errors: [] });
const evidencePath = join(directory, "benchmark-evidence.json");
const headersPath = join(directory, "headers.json");
const addonPath = join(directory, "addon-receipt.json");
const ccxReceiptPath = join(directory, "ccx-receipt.json");
writeFileSync(evidencePath, `${JSON.stringify(benchmarkEvidence, null, 2)}\n`);
writeFileSync(headersPath, `${JSON.stringify(headers, null, 2)}\n`);
writeFileSync(addonPath, `${JSON.stringify(addonReceipt, null, 2)}\n`);
writeFileSync(ccxReceiptPath, `${JSON.stringify(receipt, null, 2)}\n`);
const benchmarkVerified = spawnSync(process.execPath, [
"scripts/verify-uxp-hybrid-benchmark.mjs",
"--input", evidencePath,
"--sdk-header-receipt", headersPath,
"--addon-receipt", addonPath,
"--ccx-receipt", ccxReceiptPath,
"--ccx", archive,
], { encoding: "utf8" });
expect(benchmarkVerified.status).toBe(0);
expect(benchmarkVerified.stdout).toContain('"promotionEligible": true');
expect(benchmarkVerified.stdout).not.toContain(directory);
} finally {
rmSync(directory, { recursive: true, force: true });
}
});
it("fails closed for malformed manifest, ZIP, entrypoint, and addon content", async () => {
const directory = mkdtempSync(join(tmpdir(), "premiere-hybrid-ccx-receipt-invalid-"));
const bundle = join(directory, "bundle");
const archive = join(directory, "fixture.ccx");
const headers = sdkHeaderReceipt();
try {
await mkdir(bundle, { recursive: true });
await writeDevelopmentBundle(bundle);
const addonReceipt = await generateUxpHybridAddonReceipt({ pluginRoot: bundle, sdkHeaderReceipt: headers });
writeCcx(bundle, archive, { manifest: { id: "" } });
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("manifest.json id must be a non-empty string");
writeCcx(bundle, archive, { duplicateMain: true });
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("duplicate ZIP entry names");
writeCcx(bundle, archive, { localMainName: "renamed-main.js" });
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("local entry name is inconsistent");
writeCcx(bundle, archive, {
extra: [{ path: "docs/readme.txt", contents: Buffer.from("unselected entry") }],
localMetadata: { "docs/readme.txt": { compressedBytes: 1 } },
});
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("local entry metadata is inconsistent");
writeCcx(bundle, archive, {
extra: [{ path: "docs/readme.txt", contents: Buffer.from("unselected entry") }],
centralMetadata: { "docs/readme.txt": { versionNeeded: 45 } },
});
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("local entry metadata is inconsistent");
const storedV10Path = "docs/stored-v10.txt";
writeCcx(bundle, archive, {
deflate: false,
extra: [{ path: storedV10Path, contents: Buffer.from("stored ZIP 1.0 entry") }],
localMetadata: { [storedV10Path]: { versionNeeded: 10 } },
centralMetadata: { [storedV10Path]: { versionNeeded: 10 } },
});
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).resolves.toMatchObject({
contents: { entries: 6 },
});
const invalidV09Path = "docs/stored-v09.txt";
writeCcx(bundle, archive, {
deflate: false,
extra: [{ path: invalidV09Path, contents: Buffer.from("invalid ZIP version") }],
localMetadata: { [invalidV09Path]: { versionNeeded: 9 } },
centralMetadata: { [invalidV09Path]: { versionNeeded: 9 } },
});
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("version-needed does not support its ZIP features");
const deflatedV10Path = "docs/deflated-v10.txt";
writeCcx(bundle, archive, {
extra: [{ path: deflatedV10Path, contents: Buffer.from("Deflate requires ZIP 2.0") }],
localMetadata: { [deflatedV10Path]: { versionNeeded: 10 } },
centralMetadata: { [deflatedV10Path]: { versionNeeded: 10 } },
});
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("version-needed does not support its ZIP features");
const directoryV10Path = "docs/directory-v10/";
writeCcx(bundle, archive, {
deflate: false,
extra: [{ path: directoryV10Path, contents: Buffer.alloc(0) }],
localMetadata: { [directoryV10Path]: { versionNeeded: 10 } },
centralMetadata: { [directoryV10Path]: { versionNeeded: 10 } },
});
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("version-needed does not support its ZIP features");
writeCcx(bundle, archive, {
extra: [{ path: "docs/readme.txt", contents: Buffer.from("unselected entry") }],
localMetadata: { "docs/readme.txt": { flags: 0x810 } },
centralMetadata: { "docs/readme.txt": { flags: 0x810 } },
});
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("entries use unsupported ZIP flags");
writeCcx(bundle, archive, { deflate: false, zipFlags: 0x6 });
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("compression option flags require deflate");
writeCcx(bundle, archive, { zipFlags: 0x6 });
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).resolves.toMatchObject({
contents: { entries: 5 },
});
const asciiPath = "docs/legacy.txt";
writeCcx(bundle, archive, {
extra: [{ path: asciiPath, contents: Buffer.from("unflagged ASCII entry") }],
localMetadata: { [asciiPath]: { flags: 0 } },
centralMetadata: { [asciiPath]: { flags: 0 } },
});
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).resolves.toMatchObject({
contents: { entries: 6 },
});
const nonAsciiPath = "docs/résumé.txt";
writeCcx(bundle, archive, { extra: [{ path: nonAsciiPath, contents: Buffer.from("declared UTF-8 entry") }] });
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).resolves.toMatchObject({
contents: { entries: 6 },
});
writeCcx(bundle, archive, {
extra: [{ path: nonAsciiPath, contents: Buffer.from("undeclared legacy entry") }],
localMetadata: { [nonAsciiPath]: { flags: 0 } },
centralMetadata: { [nonAsciiPath]: { flags: 0 } },
});
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("non-ASCII ZIP entry names must declare UTF-8");
const commentPath = "docs/comment.txt";
writeCcx(bundle, archive, {
extra: [{ path: commentPath, contents: Buffer.from("declared UTF-8 ZIP comment") }],
centralComments: { [commentPath]: Buffer.from("Résumé", "utf8") },
});
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).resolves.toMatchObject({
contents: { entries: 6 },
});
writeCcx(bundle, archive, {
extra: [{ path: commentPath, contents: Buffer.from("invalid UTF-8 ZIP comment") }],
centralComments: { [commentPath]: Buffer.from([0xc3, 0x28]) },
});
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("UTF-8 ZIP entry comment is invalid");
writeCcx(bundle, archive, {
extra: [{ path: commentPath, contents: Buffer.from("legacy ZIP comment") }],
zipFlags: 0,
localMetadata: { [commentPath]: { flags: 0 } },
centralMetadata: { [commentPath]: { flags: 0 } },
centralComments: { [commentPath]: Buffer.from([0xc3, 0x28]) },
});
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).resolves.toMatchObject({
contents: { entries: 6 },
});
const unixVersionMadeBy = 0x0314;
const unixFileAttributes = (fileType: number) => (fileType << 16) >>> 0;
const regularPath = "docs/regular.txt";
writeCcx(bundle, archive, {
extra: [{ path: regularPath, contents: Buffer.from("declared Unix regular file") }],
centralMetadata: { [regularPath]: { versionMadeBy: unixVersionMadeBy, externalAttributes: unixFileAttributes(0o100000) } },
});
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).resolves.toMatchObject({
contents: { entries: 6 },
});
const directoryPath = "docs/unix-directory/";
writeCcx(bundle, archive, {
deflate: false,
extra: [{ path: directoryPath, contents: Buffer.alloc(0) }],
centralMetadata: { [directoryPath]: { versionMadeBy: unixVersionMadeBy, externalAttributes: unixFileAttributes(0o040000) } },
});
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).resolves.toMatchObject({
contents: { entries: 6, directories: 1 },
});
writeCcx(bundle, archive, { extra: [{ path: "docs/nonempty-directory/", contents: Buffer.from("unexpected directory data") }] });
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("directory entries must not contain file data");
const nonzeroCrcDirectoryPath = "docs/nonzero-crc-directory/";
writeCcx(bundle, archive, {
deflate: false,
extra: [{ path: nonzeroCrcDirectoryPath, contents: Buffer.alloc(0) }],
crc32Adjustments: { [nonzeroCrcDirectoryPath]: 1 },
});
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("directory entries must use a zero CRC-32");
for (const unixSpecialFileType of [0o010000, 0o020000, 0o060000, 0o120000, 0o140000]) {
writeCcx(bundle, archive, {
extra: [{ path: "docs/unsupported-type", contents: Buffer.from("declared Unix special file") }],
centralMetadata: { "docs/unsupported-type": { versionMadeBy: unixVersionMadeBy, externalAttributes: unixFileAttributes(unixSpecialFileType) } },
});
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("Unix entries must be regular files or directories");
}
writeCcx(bundle, archive, {
zipFlags: 0x8,
dataDescriptors: { "main.js": false },
});
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("data descriptor is missing or truncated");
writeCcx(bundle, archive, {
extra: [{ path: "docs/readme.txt", contents: Buffer.from("unselected entry") }],
zipFlags: 0x8,
dataDescriptors: { "docs/readme.txt": { crc32: 0 } },
});
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("data descriptor is inconsistent");
writeCcx(bundle, archive, { crc32Adjustments: { "main.js": 1 } });
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("required entry checksum is inconsistent");
writeCcx(bundle, archive, { compressedDataSuffixes: { "main.js": Buffer.from([0x00]) } });
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("required entry has trailing compressed data");
writeCcx(bundle, archive, { compressedByteAdjustments: { "manifest.json": 1 } });
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("local entries overlap");
writeCcx(bundle, archive, { localPreamble: Buffer.from("unexpected ZIP prefix") });
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("local records have unaccounted bytes");
const orphanName = Buffer.from("unreferenced-local-entry.txt");
const orphanLocal = Buffer.alloc(30);
orphanLocal.writeUInt32LE(0x04034b50, 0);
orphanLocal.writeUInt16LE(20, 4);
orphanLocal.writeUInt16LE(0x800, 6);
orphanLocal.writeUInt16LE(orphanName.length, 26);
writeCcx(bundle, archive, { localSuffix: Buffer.concat([orphanLocal, orphanName]) });
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("local records have unaccounted bytes");
writeCcx(bundle, archive, { centralSuffix: Buffer.from("unexpected central-directory suffix") });
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("unaccounted bytes between the central directory and ZIP end record");
writeCcx(bundle, archive, {
extra: [{ path: "docs/readme.txt", contents: Buffer.from("unselected entry") }],
localNames: { "docs/readme.txt": "docs/renamed.txt" },
});
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("local entry name is inconsistent");
writeCcx(bundle, archive, { main: "changed entrypoint" });
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("CCX archive main.js must match the addon-layout receipt");
writeCcx(bundle, archive, { extra: [{ path: "C:Headers", contents: Buffer.from("unsafe") }] });
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("unsafe ZIP entry name");
writeCcx(bundle, archive, { zipFlags: 0x1 });
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("entries must not be encrypted");
writeCcx(bundle, archive, { zipFlags: 0x2000 });
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("entries must not be encrypted");
writeCcx(bundle, archive, { compressionMethod: 12 });
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("stored or deflate compression");
for (const zip64Metadata of [
{ compressedBytes: 0xffff_ffff },
{ uncompressedBytes: 0xffff_ffff },
{ localOffset: 0xffff_ffff },
]) {
writeCcx(bundle, archive, {
extra: [{ path: "docs/readme.txt", contents: Buffer.from("unselected ZIP64 sentinel") }],
centralMetadata: { "docs/readme.txt": zip64Metadata },
});
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("ZIP64 entry metadata is not supported");
}
const vendorExtraField = Buffer.from([0xfe, 0xca, 0x00, 0x00]);
writeCcx(bundle, archive, {
extra: [{ path: "docs/vendor-extra.txt", contents: Buffer.from("well-formed non-ZIP64 extra field") }],
localExtraFields: { "docs/vendor-extra.txt": vendorExtraField },
centralExtraFields: { "docs/vendor-extra.txt": vendorExtraField },
});
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).resolves.toMatchObject({
contents: { entries: 6 },
});
const zip64ExtraField = Buffer.from([0x01, 0x00, 0x00, 0x00]);
writeCcx(bundle, archive, {
extra: [{ path: "docs/central-zip64-extra.txt", contents: Buffer.from("central ZIP64 extra field") }],
centralExtraFields: { "docs/central-zip64-extra.txt": zip64ExtraField },
});
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("ZIP64 extra fields are not supported");
writeCcx(bundle, archive, {
extra: [{ path: "docs/local-zip64-extra.txt", contents: Buffer.from("local ZIP64 extra field") }],
localExtraFields: { "docs/local-zip64-extra.txt": zip64ExtraField },
});
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("ZIP64 extra fields are not supported");
const malformedExtraField = Buffer.from([0x55, 0x54, 0x01, 0x00]);
writeCcx(bundle, archive, {
extra: [{ path: "docs/malformed-central-extra.txt", contents: Buffer.from("malformed central extra field") }],
centralExtraFields: { "docs/malformed-central-extra.txt": malformedExtraField },
});
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("ZIP extra fields are malformed");
writeCcx(bundle, archive, {
extra: [{ path: "docs/malformed-local-extra.txt", contents: Buffer.from("malformed local extra field") }],
localExtraFields: { "docs/malformed-local-extra.txt": malformedExtraField },
});
await expect(buildUxpHybridCcxReceipt({ ccxPath: archive, addonReceipt, sdkHeaderReceipt: headers })).rejects.toThrow("ZIP extra fields are malformed");
} finally {
rmSync(directory, { recursive: true, force: true });
}
});
it("supports deterministic CLI generation, archive re-verification, and stale checks without printing local paths", async () => {
const directory = mkdtempSync(join(tmpdir(), "premiere-hybrid-ccx-receipt-cli-"));
const bundle = join(directory, "bundle");
const archive = join(directory, "fixture.ccx");
const headersPath = join(directory, "headers.json");
const addonPath = join(directory, "addon.json");
const output = join(directory, "ccx-receipt.json");
const headers = sdkHeaderReceipt();
try {
await mkdir(bundle, { recursive: true });
await writeDevelopmentBundle(bundle);
const addonReceipt = await generateUxpHybridAddonReceipt({ pluginRoot: bundle, sdkHeaderReceipt: headers });
writeFileSync(headersPath, `${JSON.stringify(headers, null, 2)}\n`);
writeFileSync(addonPath, `${JSON.stringify(addonReceipt, null, 2)}\n`);
writeCcx(bundle, archive, { deflate: true });
const args = ["scripts/generate-uxp-hybrid-ccx-receipt.mjs", "--ccx", archive, "--addon-receipt", addonPath, "--sdk-header-receipt", headersPath, "--output", output];
const generated = spawnSync(process.execPath, args, { encoding: "utf8" });
expect(generated.status).toBe(0);
expect(generated.stdout).toContain("Wrote UXP Hybrid CCX receipt: 3 artifacts and 1 entrypoint.");
expect(generated.stdout).not.toContain(directory);
expect(spawnSync(process.execPath, [...args, "--check"], { encoding: "utf8" }).status).toBe(0);
const verified = spawnSync(process.execPath, ["scripts/verify-uxp-hybrid-ccx-receipt.mjs", "--input", output, "--ccx", archive, "--addon-receipt", addonPath, "--sdk-header-receipt", headersPath, "--print-canonical-sha256"], { encoding: "utf8" });
expect(verified.status).toBe(0);
expect(verified.stdout).toContain("UXP Hybrid CCX receipt is valid: 3 addon artifacts and 1 entrypoint.");
expect(verified.stdout).toContain("Canonical receipt SHA-256:");
expect(verified.stdout).not.toContain(directory);
writeCcx(bundle, archive, { deflate: false });
const stale = spawnSync(process.execPath, [...args, "--check"], { encoding: "utf8" });
expect(stale.status).not.toBe(0);
expect(stale.stderr).toContain("UXP Hybrid CCX receipt is stale");
expect(stale.stderr).not.toContain(directory);
expect(JSON.parse(readFileSync(output, "utf8")).manifest).not.toHaveProperty("id");
} finally {
rmSync(directory, { recursive: true, force: true });
}
});
});