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
+76
View File
@@ -0,0 +1,76 @@
import { mkdtempSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { beforeEach, describe, expect, it, vi } from "vitest";
const { mockedExecFile, mockedExecFileAsync } = vi.hoisted(() => {
const mockedExecFileAsync = vi.fn();
const mockedExecFile = vi.fn();
mockedExecFile[Symbol.for("nodejs.util.promisify.custom")] = mockedExecFileAsync;
return { mockedExecFile, mockedExecFileAsync };
});
vi.mock("node:child_process", () => ({ execFile: mockedExecFile }));
import { getExportTools, parseSceneChangeOutput } from "../../src/tools/export.js";
describe("parseSceneChangeOutput", () => {
it("pairs times with scores and keeps the strongest nearby event", () => {
const output = [
"n:1 pts:100 pts_time:1.00",
"lavfi.scene_score=0.40",
"n:2 pts:110 pts_time:1.10",
"lavfi.scene_score=0.75",
"n:3 pts:300 pts_time:3.00",
"lavfi.scene_score=0.55",
].join("\n");
expect(parseSceneChangeOutput(output, 0.25)).toEqual([
{ timeSeconds: 1.1, score: 0.75 },
{ timeSeconds: 3, score: 0.55 },
]);
});
});
describe("detect_source_scene_changes boundary", () => {
const tool = getExportTools({ tempDir: "/tmp/test" }).detect_source_scene_changes;
beforeEach(() => vi.clearAllMocks());
it("rejects invalid thresholds and missing files", async () => {
await expect(tool.handler({ media_path: "missing.mp4", threshold: 2 })).resolves.toMatchObject({ success: false });
await expect(tool.handler({ media_path: "missing.mp4", minimum_interval_seconds: -1 })).resolves.toMatchObject({ success: false });
await expect(tool.handler({ media_path: "missing.mp4", maximum_events: 0 })).resolves.toMatchObject({ success: false });
await expect(tool.handler({ media_path: "missing.mp4" })).resolves.toMatchObject({ success: false, error: expect.stringContaining("not found") });
});
it("returns bounded source-relative scene candidates from one local FFmpeg pass", async () => {
const directory = mkdtempSync(join(tmpdir(), "premiere-scene-detect-"));
const mediaPath = join(directory, "source.mp4");
writeFileSync(mediaPath, "video-fixture");
mockedExecFileAsync.mockResolvedValueOnce({
stdout: "n:1 pts:100 pts_time:1.00\nlavfi.scene_score=0.40\nn:2 pts:300 pts_time:3.00\nlavfi.scene_score=0.55",
stderr: "",
});
await expect(tool.handler({ media_path: mediaPath, threshold: 0.3, minimum_interval_seconds: 0.25, maximum_events: 1 }))
.resolves.toMatchObject({
success: true,
data: {
mediaPath,
totalDetected: 2,
truncated: true,
sceneChanges: [{ timeSeconds: 1, score: 0.4 }],
},
});
expect(mockedExecFileAsync).toHaveBeenCalledTimes(1);
});
it("keeps an FFmpeg scene-detection failure explicit", async () => {
const directory = mkdtempSync(join(tmpdir(), "premiere-scene-error-"));
const mediaPath = join(directory, "source.mp4");
writeFileSync(mediaPath, "video-fixture");
mockedExecFileAsync.mockRejectedValueOnce(Object.assign(new Error("decode failed"), { stderr: "bad video stream" }));
await expect(tool.handler({ media_path: mediaPath }))
.resolves.toMatchObject({ success: false, error: expect.stringContaining("bad video stream") });
});
});