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
@@ -0,0 +1,235 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { BridgeOptions } from "../../src/bridge/file-bridge.js";
vi.mock("../../src/bridge/file-bridge.js", () => ({
sendCommand: vi.fn().mockResolvedValue({ success: true, data: {} }),
}));
import { sendCommand } from "../../src/bridge/file-bridge.js";
import { getCompetitorGapTools } from "../../src/tools/competitor-gaps.js";
const bridgeOptions: BridgeOptions = { tempDir: "/tmp/competitor-gap-tests", timeoutMs: 5000 };
const mockedSendCommand = vi.mocked(sendCommand);
describe("competitor-gap default-profile tools", () => {
beforeEach(() => vi.clearAllMocks());
it("exposes the requested competitor-parity names", () => {
const tools = getCompetitorGapTools(bridgeOptions);
expect(Object.keys(tools)).toEqual(expect.arrayContaining([
"import_edl",
"add_to_timeline_batch",
"crop_clip",
"setup_ducking",
"validate_project_for_export",
"read_sequence_captions",
"set_clip_properties_batch",
"detect_scene_edits",
]));
});
it("does not attempt an unattended EDL import", async () => {
const result = await getCompetitorGapTools(bridgeOptions).import_edl.handler({ file_path: "D:/cuts/spot.edl" });
expect(result.success).toBe(false);
expect(result.error).toContain("No mutation was attempted");
expect(mockedSendCommand).not.toHaveBeenCalled();
});
it("rejects ambiguous batch insert positions before writing", async () => {
const result = await getCompetitorGapTools(bridgeOptions).add_to_timeline_batch.handler({
clips: [
{ item_id: "a", track_index: 0, start_seconds: 4 },
{ item_id: "b", track_index: 0, start_seconds: 4 },
],
});
expect(result.success).toBe(false);
expect(result.error).toContain("shares video track");
expect(mockedSendCommand).not.toHaveBeenCalled();
});
it("preflights and reads back batch insertions", async () => {
await getCompetitorGapTools(bridgeOptions).add_to_timeline_batch.handler({
clips: [
{ item_id: "later", track_index: 1, start_seconds: 10, audio_track_index: 0 },
{ item_id: "first", track_index: 0, start_seconds: 2, audio_track_index: 0 },
],
});
const script = mockedSendCommand.mock.calls[0][0];
expect(script).toContain("Preflight every mutable dependency");
expect(script).toContain("seq.insertClip");
expect(script).toContain("actualStart");
expect(script.indexOf('itemId: "first"')).toBeLessThan(script.indexOf('itemId: "later"'));
});
it("requires a meaningful crop change before adding an effect", async () => {
const result = await getCompetitorGapTools(bridgeOptions).crop_clip.handler({ node_id: "video-1" });
expect(result.success).toBe(false);
expect(result.error).toContain("requires at least one");
expect(mockedSendCommand).not.toHaveBeenCalled();
});
it("uses the QE crop catalog only when needed and verifies requested values", async () => {
await getCompetitorGapTools(bridgeOptions).crop_clip.handler({ node_id: "video-1", left: 12, zoom: true });
const script = mockedSendCommand.mock.calls[0][0];
expect(script).toContain('__getQeEffectCatalog("video")');
expect(script).toContain("addVideoEffect");
expect(script).toContain('name: "Left"');
expect(script).toContain("getValue");
});
it("rejects overlapping ducking windows before writing automation", async () => {
const result = await getCompetitorGapTools(bridgeOptions).setup_ducking.handler({
node_id: "music-1",
ducking_windows: [
{ start_seconds: 1, end_seconds: 3, ducked_db: -20 },
{ start_seconds: 2, end_seconds: 4, ducked_db: -24 },
],
});
expect(result.success).toBe(false);
expect(result.error).toContain("must not overlap");
expect(mockedSendCommand).not.toHaveBeenCalled();
});
it("generates verified relative audio keyframes for non-overlapping windows", async () => {
await getCompetitorGapTools(bridgeOptions).setup_ducking.handler({
node_id: "music-1",
base_db: -4,
fade_seconds: 0.25,
ducking_windows: [{ start_seconds: 2, end_seconds: 4, ducked_db: -28 }],
});
const script = mockedSendCommand.mock.calls[0][0];
expect(script).toContain("setup_ducking only supports audio");
expect(script).toContain("setTimeVarying");
expect(script).toContain("getValueAtTime");
expect(script).toContain("duckingWindowCount");
});
it("generates a non-mutating export readiness audit", async () => {
await getCompetitorGapTools(bridgeOptions).validate_project_for_export.handler({
sequence_id: "edit-1",
output_path: "D:/exports/final.mp4",
preset_path: "D:/presets/h264.epr",
});
const script = mockedSendCommand.mock.calls[0][0];
expect(script).toContain("OFFLINE_MEDIA");
expect(script).toContain("TIMELINE_GAPS");
expect(script).toContain("readyForExport");
expect(script).not.toContain("encodeSequence");
});
it("makes caption-read limitations explicit instead of treating no tracks as no captions", async () => {
await getCompetitorGapTools(bridgeOptions).read_sequence_captions.handler({});
const script = mockedSendCommand.mock.calls[0][0];
expect(script).toContain("captionReadSupported");
expect(script).toContain("do not prove this sequence has no captions");
});
it("fails property batch speed requests before touching any clip", async () => {
const result = await getCompetitorGapTools(bridgeOptions).set_clip_properties_batch.handler({
items: [{ node_id: "clip-1", speed: 150 }],
});
expect(result.success).toBe(false);
expect(result.error).toContain("speed");
expect(mockedSendCommand).not.toHaveBeenCalled();
});
it("preflights, verifies, and restores batch clip properties on mismatch", async () => {
await getCompetitorGapTools(bridgeOptions).set_clip_properties_batch.handler({
items: [{ node_id: "clip-1", opacity: 80, scale: 110, position_x: 400, rotation: 12 }],
});
const script = mockedSendCommand.mock.calls[0][0];
expect(script).toContain("No batch mutation was attempted");
expect(script).toContain("restoreAll");
expect(script).toContain("No partial batch is reported as verified");
});
it("withholds unsafe CEP scene detection without an authenticated UXP bridge", async () => {
const result = await getCompetitorGapTools(bridgeOptions).detect_scene_edits.handler({
mode: "create_markers",
confirm_non_undoable: true,
});
expect(result.success).toBe(false);
expect(result.error).toContain("authenticated Premiere UXP bridge");
expect(mockedSendCommand).not.toHaveBeenCalled();
});
it("routes confirmed scene detection through UXP with a stable mode mapping", async () => {
const request = vi.fn().mockResolvedValue({ detected: true });
const bridge = { request } as any;
const result = await getCompetitorGapTools(bridgeOptions, bridge).detect_scene_edits.handler({
mode: "create_subclips",
confirm_non_undoable: true,
operation_id: "scene-42",
});
expect(result).toMatchObject({ success: true, data: { backend: "uxp" } });
expect(request).toHaveBeenCalledWith("sceneEdit.detect", { mode: "createSubclips", operationId: "scene-42" });
});
it("rejects malformed or unsafe inputs before generating a CEP command", async () => {
const tools = getCompetitorGapTools(bridgeOptions);
await expect(tools.add_to_timeline_batch.handler({ clips: [] })).resolves.toMatchObject({
success: false,
error: expect.stringContaining("clips must contain"),
});
await expect(tools.add_to_timeline_batch.handler({
clips: Array.from({ length: 33 }, (_, index) => ({ item_id: `clip-${index}` })),
})).resolves.toMatchObject({ success: false, error: expect.stringContaining("between 1 and 32") });
await expect(tools.add_to_timeline_batch.handler({ clips: [{ item_id: "" }] })).resolves
.toMatchObject({ success: false, error: expect.stringContaining("item_id") });
await expect(tools.add_to_timeline_batch.handler({
clips: [{ item_id: "clip", track_index: -1 }],
})).resolves.toMatchObject({ success: false, error: expect.stringContaining("non-negative integer") });
await expect(tools.crop_clip.handler({ node_id: "clip", right: 101 })).resolves.toMatchObject({ success: false, error: expect.stringContaining("percentages") });
await expect(tools.setup_ducking.handler({
node_id: "music", fade_seconds: 0, ducking_windows: [],
})).resolves.toMatchObject({ success: false, error: expect.stringContaining("positive fade_seconds") });
await expect(tools.setup_ducking.handler({
node_id: "music", ducking_windows: Array.from({ length: 33 }, () => ({ start_seconds: 0, end_seconds: 1, ducked_db: -12 })),
})).resolves.toMatchObject({ success: false, error: expect.stringContaining("0–32 ducking windows") });
await expect(tools.setup_ducking.handler({
node_id: "music", ducking_windows: [{ start_seconds: 3, end_seconds: 3, ducked_db: -12 }],
})).resolves.toMatchObject({ success: false, error: expect.stringContaining("greater than start_seconds") });
await expect(tools.set_clip_properties_batch.handler({ items: [] })).resolves.toMatchObject({ success: false, error: expect.stringContaining("between 1 and 16") });
await expect(tools.set_clip_properties_batch.handler({ items: [{ node_id: "" }] })).resolves
.toMatchObject({ success: false, error: expect.stringContaining("node_id") });
await expect(tools.set_clip_properties_batch.handler({
items: [{ node_id: "clip" }, { node_id: "clip", opacity: 80 }],
})).resolves.toMatchObject({ success: false, error: expect.stringContaining("must specify at least one") });
await expect(tools.set_clip_properties_batch.handler({
items: [{ node_id: "clip", opacity: -1 }],
})).resolves.toMatchObject({ success: false, error: expect.stringContaining("invalid property") });
await expect(tools.set_clip_properties_batch.handler({
items: [{ node_id: "clip", opacity: 80 }, { node_id: "clip", opacity: 60 }],
})).resolves.toMatchObject({ success: false, error: expect.stringContaining("duplicate node_id") });
await expect(tools.detect_scene_edits.handler({ mode: "create_markers", confirm_non_undoable: false })).resolves
.toMatchObject({ success: false, error: expect.stringContaining("confirm_non_undoable") });
expect(mockedSendCommand).not.toHaveBeenCalled();
});
it("covers optional export, caption, and UXP-scene request variants", async () => {
const tools = getCompetitorGapTools(bridgeOptions);
await tools.validate_project_for_export.handler({ require_non_empty_timeline: false, check_gaps: false });
expect(String(mockedSendCommand.mock.calls[0][0])).toContain("requireNonEmptyTimeline: false");
expect(String(mockedSendCommand.mock.calls[0][0])).toContain("PRESET_NOT_PROVIDED");
vi.clearAllMocks();
await tools.read_sequence_captions.handler({ sequence_id: "sequence-1" });
expect(String(mockedSendCommand.mock.calls[0][0])).toContain('__findSequence("sequence-1")');
const rejectedBridge = { request: vi.fn().mockRejectedValue(new Error("UXP disconnected")) } as any;
await expect(getCompetitorGapTools(bridgeOptions, rejectedBridge).detect_scene_edits.handler({
mode: "apply_cuts", confirm_non_undoable: true,
})).resolves.toMatchObject({ success: false, error: expect.stringContaining("UXP disconnected") });
await expect(getCompetitorGapTools(bridgeOptions, { request: vi.fn() } as any).detect_scene_edits.handler({
mode: "not-supported" as any, confirm_non_undoable: true,
})).resolves.toMatchObject({ success: false, error: expect.stringContaining("Unsupported scene-edit mode") });
const bridge = { request: vi.fn().mockResolvedValue({ applied: true }) } as any;
await getCompetitorGapTools(bridgeOptions, bridge).detect_scene_edits.handler({
mode: "create_markers", confirm_non_undoable: true,
});
expect(bridge.request).toHaveBeenCalledWith("sceneEdit.detect", { mode: "createMarkers" });
});
});