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
+126
View File
@@ -0,0 +1,126 @@
import { createRequire } from "node:module";
import { describe, expect, it, vi } from "vitest";
const require = createRequire(import.meta.url);
const Commands = require("../../uxp-plugin/commands.cjs");
const Protocol = require("../../uxp-plugin/protocol.cjs");
type Options = {
replaceItemOnSecondRootRead?: boolean;
getRootItem?: boolean;
};
function nativeGuid(value: string) {
return { toString: vi.fn(() => value) };
}
function uniqueIdentityHost(options: Options = {}) {
const originalItem = { uniqueId: "unique-item-1", getId: vi.fn(async () => "item-1") };
const replacementItem = { uniqueId: "unique-item-2", getId: vi.fn(async () => "item-1") };
let currentItem = originalItem;
const root = {
getId: vi.fn(async () => "root"),
getItems: vi.fn(async () => [currentItem]),
};
const sequence = { guid: nativeGuid("sequence-1"), uniqueId: "unique-sequence-1" };
let rootReads = 0;
const project = {
guid: nativeGuid("project-1"),
getActiveSequence: vi.fn(async () => null),
getRootItem: vi.fn(async () => {
rootReads += 1;
if (options.replaceItemOnSecondRootRead && rootReads > 1) currentItem = replacementItem;
return root;
}),
getSequence: vi.fn(async (guid: { toString: () => string }) =>
guid.toString() === "sequence-1" ? sequence : null),
};
const ppro = {
Project: { getActiveProject: vi.fn(async () => project) },
Guid: { fromString: vi.fn((value: string) => nativeGuid(value)) },
UniqueSerializeable: {
cast: vi.fn((target: { uniqueId?: string }) => ({
getUniqueID: vi.fn(async () => nativeGuid(target.uniqueId || "")),
})),
},
};
return {
root,
project,
ppro,
registry: Commands.createCommandRegistry({ ppro, Protocol }),
};
}
describe("bounded documented UXP unique serializable identity inspection", () => {
it("advertises a read-only target-probed command and double-reads one project-item identity", async () => {
const value = uniqueIdentityHost();
await expect(value.registry.capabilities()).resolves.toMatchObject({ commands: {
"object.uniqueIdentity.inspect": {
supported: true,
readOnly: true,
minHostVersion: "25.6.0",
targetCapabilityProbe: "invocation",
},
} });
await expect(value.registry.dispatch("object.uniqueIdentity.inspect", {
projectItemId: "item-1",
expectedProjectGuid: "project-1",
expectedUniqueId: "unique-item-1",
})).resolves.toEqual({
projectGuid: "project-1",
target: { kind: "project_item", projectItemId: "item-1", uniqueId: "unique-item-1" },
verificationBoundary: "bounded_unique_serializable_double_readback",
});
expect(value.project.getRootItem).toHaveBeenCalledTimes(2);
expect(value.ppro.UniqueSerializeable.cast).toHaveBeenCalledTimes(2);
});
it("resolves an exact sequence GUID without traversing the project tree", async () => {
const value = uniqueIdentityHost();
await expect(value.registry.dispatch("object.uniqueIdentity.inspect", {
sequenceGuid: "sequence-1",
})).resolves.toMatchObject({
projectGuid: "project-1",
target: { kind: "sequence", sequenceGuid: "sequence-1", uniqueId: "unique-sequence-1" },
});
expect(value.project.getRootItem).not.toHaveBeenCalled();
expect(value.project.getSequence).toHaveBeenCalledTimes(2);
expect(value.ppro.Guid.fromString).toHaveBeenCalledTimes(2);
});
it("rejects ambiguous, stale, unsupported, and oversized requests", async () => {
const value = uniqueIdentityHost();
await expect(value.registry.dispatch("object.uniqueIdentity.inspect", {}))
.rejects.toMatchObject({ code: "UXP_INVALID_ARGUMENT" });
await expect(value.registry.dispatch("object.uniqueIdentity.inspect", {
projectItemId: "item-1", sequenceGuid: "sequence-1",
})).rejects.toMatchObject({ code: "UXP_INVALID_ARGUMENT" });
await expect(value.registry.dispatch("object.uniqueIdentity.inspect", {
projectItemId: "item-1", expectedUniqueId: "different",
})).rejects.toMatchObject({ code: "UXP_STALE_UNIQUE_IDENTITY" });
const tooLarge = uniqueIdentityHost();
tooLarge.root.getItems.mockResolvedValueOnce(Array.from({ length: 512 }, (_, index) => ({
getId: vi.fn(async () => `item-${index}`),
})));
await expect(tooLarge.registry.dispatch("object.uniqueIdentity.inspect", { projectItemId: "missing" }))
.rejects.toMatchObject({ code: "UXP_PROJECT_TOO_LARGE" });
});
it("fails closed when a retained project-item ID resolves to a replacement during the second read", async () => {
const value = uniqueIdentityHost({ replaceItemOnSecondRootRead: true });
await expect(value.registry.dispatch("object.uniqueIdentity.inspect", { projectItemId: "item-1" }))
.rejects.toMatchObject({ code: "UXP_STALE_UNIQUE_IDENTITY" });
});
it("does not advertise compatibility when the documented unique serializable static API is absent", async () => {
const value = uniqueIdentityHost();
delete (value.ppro as { UniqueSerializeable?: unknown }).UniqueSerializeable;
const registry = Commands.createCommandRegistry({ ppro: value.ppro, Protocol });
await expect(registry.capabilities()).resolves.toMatchObject({ commands: {
"object.uniqueIdentity.inspect": { supported: false, reason: expect.any(String) },
} });
});
});