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
+489
View File
@@ -0,0 +1,489 @@
import { buildToolScript, escapeForExtendScript } from "../bridge/script-builder.js";
import { sendCommand, BridgeOptions } from "../bridge/file-bridge.js";
export function getMediaTools(bridgeOptions: BridgeOptions) {
return {
import_media: {
description: "Import media files into the project",
parameters: {
type: "object" as const,
properties: {
file_paths: {
type: "array",
items: { type: "string" },
description: "Array of file paths to import",
},
target_bin: {
type: "string",
description: "Optional bin name or node ID to import into. Imports to root if omitted.",
},
suppress_ui: {
type: "boolean",
description: "Suppress import dialogs (default: true)",
},
},
required: ["file_paths"],
},
handler: async (args: { file_paths: string[]; target_bin?: string; suppress_ui?: boolean }) => {
const paths = args.file_paths.map((p) => `"${escapeForExtendScript(p)}"`).join(", ");
const suppress = args.suppress_ui !== false ? "true" : "false";
const binLookup = args.target_bin
? `var targetBin = __findProjectItem("${escapeForExtendScript(args.target_bin)}");
if (!targetBin) return __error("Bin not found: ${escapeForExtendScript(args.target_bin)}");`
: `var targetBin = app.project.rootItem;`;
const script = buildToolScript(`
${binLookup}
var filePaths = [${paths}];
var importSuccess = app.project.importFiles(filePaths, ${suppress}, targetBin, false);
if (!importSuccess) return __error("Import failed");
return __result({ imported: filePaths.length, files: filePaths });
`);
return sendCommand(script, bridgeOptions);
},
},
import_folder: {
description: "Import an entire folder of media into the project",
parameters: {
type: "object" as const,
properties: {
folder_path: {
type: "string",
description: "Path to the folder to import",
},
},
required: ["folder_path"],
},
handler: async (args: { folder_path: string }) => {
const script = buildToolScript(`
var folder = new Folder("${escapeForExtendScript(args.folder_path)}");
if (!folder.exists) return __error("Folder not found: ${escapeForExtendScript(args.folder_path)}");
var files = folder.getFiles();
var filePaths = [];
for (var i = 0; i < files.length; i++) {
if (files[i] instanceof File) {
filePaths.push(files[i].fsName);
}
}
if (filePaths.length === 0) return __error("No files found in folder");
var importSuccess = app.project.importFiles(filePaths, true, app.project.rootItem, false);
if (!importSuccess) return __error("Import failed");
return __result({ imported: filePaths.length, folder: "${escapeForExtendScript(args.folder_path)}" });
`);
return sendCommand(script, bridgeOptions);
},
},
create_bin: {
description: "Create a new bin (folder) in the project panel",
parameters: {
type: "object" as const,
properties: {
name: {
type: "string",
description: "Name of the new bin",
},
parent_bin: {
type: "string",
description: "Optional parent bin name or node ID. Creates in root if omitted.",
},
},
required: ["name"],
},
handler: async (args: { name: string; parent_bin?: string }) => {
const parentLookup = args.parent_bin
? `var parent = __findProjectItem("${escapeForExtendScript(args.parent_bin)}");
if (!parent) return __error("Parent bin not found");`
: `var parent = app.project.rootItem;`;
const script = buildToolScript(`
${parentLookup}
var newBin = parent.createBin("${escapeForExtendScript(args.name)}");
return __result({ created: true, name: "${escapeForExtendScript(args.name)}", nodeId: newBin.nodeId });
`);
return sendCommand(script, bridgeOptions);
},
},
move_item_to_bin: {
description: "Move a project item to a different bin",
parameters: {
type: "object" as const,
properties: {
item_id: {
type: "string",
description: "Node ID or name of the item to move",
},
target_bin: {
type: "string",
description: "Name or node ID of the target bin",
},
},
required: ["item_id", "target_bin"],
},
handler: async (args: { item_id: string; target_bin: string }) => {
const script = buildToolScript(`
var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
if (!item) return __error("Item not found: ${escapeForExtendScript(args.item_id)}");
var targetBin = __findProjectItem("${escapeForExtendScript(args.target_bin)}");
if (!targetBin) return __error("Target bin not found: ${escapeForExtendScript(args.target_bin)}");
item.moveBin(targetBin);
return __result({ moved: true, item: item.name, toBin: targetBin.name });
`);
return sendCommand(script, bridgeOptions);
},
},
relink_media: {
description: "Relink an offline media item to a new file path",
parameters: {
type: "object" as const,
properties: {
item_id: {
type: "string",
description: "Node ID or name of the item to relink",
},
new_path: {
type: "string",
description: "New file path for the media",
},
},
required: ["item_id", "new_path"],
},
handler: async (args: { item_id: string; new_path: string }) => {
const script = buildToolScript(`
var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
if (!item) return __error("Item not found: ${escapeForExtendScript(args.item_id)}");
var success = item.changeMediaPath("${escapeForExtendScript(args.new_path)}", true);
return __result({ relinked: success, item: item.name, newPath: "${escapeForExtendScript(args.new_path)}" });
`);
return sendCommand(script, bridgeOptions);
},
},
refresh_media: {
description: "Refresh a project item to pick up changes to the source file",
parameters: {
type: "object" as const,
properties: {
item_id: {
type: "string",
description: "Node ID or name of the item to refresh",
},
},
required: ["item_id"],
},
handler: async (args: { item_id: string }) => {
const script = buildToolScript(`
var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
if (!item) return __error("Item not found: ${escapeForExtendScript(args.item_id)}");
item.refreshMedia();
return __result({ refreshed: true, item: item.name });
`);
return sendCommand(script, bridgeOptions);
},
},
check_offline_media: {
description: "Check for offline (missing) media in the project",
parameters: {},
handler: async () => {
const script = buildToolScript(`
var offlineItems = [];
function checkItem(item) {
if (item.type === 1) {
try {
if (item.isOffline && item.isOffline()) {
offlineItems.push({
nodeId: item.nodeId,
name: item.name,
mediaPath: item.getMediaPath ? item.getMediaPath() : ""
});
}
} catch(e) {}
}
if (item.type === 2 && item.children) {
for (var i = 0; i < item.children.numItems; i++) {
checkItem(item.children[i]);
}
}
}
var root = app.project.rootItem;
for (var i = 0; i < root.children.numItems; i++) {
checkItem(root.children[i]);
}
return __result({ offlineCount: offlineItems.length, items: offlineItems });
`);
return sendCommand(script, bridgeOptions);
},
},
set_offline: {
description: "Set a project item offline, or ask Premiere to refresh it back online when offline is false.",
parameters: {
type: "object" as const,
properties: {
item_id: {
type: "string",
description: "Node ID or name of the project item",
},
offline: {
type: "boolean",
description: "true to take media offline (default); false to refresh an existing offline item",
},
},
required: ["item_id"],
},
handler: async (args: { item_id: string; offline?: boolean }) => {
const offline = args.offline !== false;
const script = buildToolScript(`
var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
if (!item) return __error("Item not found: ${escapeForExtendScript(args.item_id)}");
${offline
? `item.setOffline();`
: `item.refreshMedia();`
}
var observedOffline = !!item.isOffline();
if (observedOffline !== ${offline}) {
return __error(${offline
? `"Premiere did not take the project item offline."`
: `"Premiere could not refresh this item online. Use relink_media with the known media path if the source has moved."`
});
}
return __result({ offline: observedOffline, item: item.name, verified: true });
`);
return sendCommand(script, bridgeOptions);
},
},
has_proxy: {
description: "Check if a project item has a proxy attached",
parameters: {
type: "object" as const,
properties: {
item_id: {
type: "string",
description: "Node ID or name of the project item",
},
},
required: ["item_id"],
},
handler: async (args: { item_id: string }) => {
const script = buildToolScript(`
var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
if (!item) return __error("Item not found");
var info = { item: item.name };
try { info.hasProxy = item.hasProxy(); } catch(e) { info.hasProxy = false; }
try { info.canProxy = item.canProxy(); } catch(e) { info.canProxy = false; }
try { info.proxyPath = item.getProxyPath(); } catch(e) {}
return __result(info);
`);
return sendCommand(script, bridgeOptions);
},
},
detach_proxy: {
description: "Detach/remove the proxy from a project item",
parameters: {
type: "object" as const,
properties: {
item_id: {
type: "string",
description: "Node ID or name of the project item",
},
},
required: ["item_id"],
},
handler: async (args: { item_id: string }) => {
const script = buildToolScript(`
var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
if (!item) return __error("Item not found");
item.detachProxy();
return __result({ detached: true, item: item.name });
`);
return sendCommand(script, bridgeOptions);
},
},
set_override_frame_rate: {
description: "Override the frame rate of a project item (useful for image sequences or misinterpreted media)",
parameters: {
type: "object" as const,
properties: {
item_id: {
type: "string",
description: "Node ID or name of the project item",
},
frame_rate: {
type: "number",
description: "Frame rate to set (e.g., 23.976, 24, 29.97, 30, 60)",
},
},
required: ["item_id", "frame_rate"],
},
handler: async (args: { item_id: string; frame_rate: number }) => {
const script = buildToolScript(`
var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
if (!item) return __error("Item not found");
item.setOverrideFrameRate(${args.frame_rate});
return __result({ set: true, item: item.name, frameRate: ${args.frame_rate} });
`);
return sendCommand(script, bridgeOptions);
},
},
set_override_pixel_aspect_ratio: {
description: "Override the pixel aspect ratio of a project item",
parameters: {
type: "object" as const,
properties: {
item_id: {
type: "string",
description: "Node ID or name of the project item",
},
numerator: {
type: "number",
description: "PAR numerator (e.g., 1 for square pixels)",
},
denominator: {
type: "number",
description: "PAR denominator (e.g., 1 for square pixels)",
},
},
required: ["item_id", "numerator", "denominator"],
},
handler: async (args: { item_id: string; numerator: number; denominator: number }) => {
const script = buildToolScript(`
var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
if (!item) return __error("Item not found");
item.setOverridePixelAspectRatio(${args.numerator}, ${args.denominator});
return __result({ set: true, item: item.name, par: "${args.numerator}:${args.denominator}" });
`);
return sendCommand(script, bridgeOptions);
},
},
set_scale_to_frame_size: {
description: "Enable 'Scale to Frame Size' on a project item so it fills the sequence frame",
parameters: {
type: "object" as const,
properties: {
item_id: {
type: "string",
description: "Node ID or name of the project item",
},
},
required: ["item_id"],
},
handler: async (args: { item_id: string }) => {
const script = buildToolScript(`
var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
if (!item) return __error("Item not found");
item.setScaleToFrameSize();
return __result({ set: true, item: item.name });
`);
return sendCommand(script, bridgeOptions);
},
},
get_item_info: {
description: "Get detailed type info about a project item (is it a sequence, multicam, merged clip, etc.)",
parameters: {
type: "object" as const,
properties: {
item_id: {
type: "string",
description: "Node ID or name of the project item",
},
},
required: ["item_id"],
},
handler: async (args: { item_id: string }) => {
const script = buildToolScript(`
var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
if (!item) return __error("Item not found");
var info = {
name: item.name,
nodeId: item.nodeId,
type: item.type === 1 ? "clip" : item.type === 2 ? "bin" : item.type === 3 ? "sequence" : "unknown",
treePath: item.treePath
};
try { info.isSequence = item.isSequence(); } catch(e) {}
try { info.isMulticamClip = item.isMulticamClip(); } catch(e) {}
try { info.isMergedClip = item.isMergedClip(); } catch(e) {}
try { info.isOffline = item.isOffline(); } catch(e) {}
try { info.mediaPath = item.getMediaPath(); } catch(e) {}
try { info.hasProxy = item.hasProxy(); } catch(e) {}
try { info.canProxy = item.canProxy(); } catch(e) {}
return __result(info);
`);
return sendCommand(script, bridgeOptions);
},
},
select_item: {
description: "Select a project item in the Project panel",
parameters: {
type: "object" as const,
properties: {
item_id: {
type: "string",
description: "Node ID or name of the project item to select",
},
},
required: ["item_id"],
},
handler: async (args: { item_id: string }) => {
const script = buildToolScript(`
var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
if (!item) return __error("Item not found");
item.select();
return __result({ selected: true, item: item.name });
`);
return sendCommand(script, bridgeOptions);
},
},
set_start_time: {
description: "Set the start time (timecode offset) for a project item",
parameters: {
type: "object" as const,
properties: {
item_id: {
type: "string",
description: "Node ID or name of the project item",
},
start_seconds: {
type: "number",
description: "Start time in seconds",
},
},
required: ["item_id", "start_seconds"],
},
handler: async (args: { item_id: string; start_seconds: number }) => {
const script = buildToolScript(`
var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
if (!item) return __error("Item not found");
var ticks = __secondsToTicks(${args.start_seconds}).toString();
item.setStartTime(ticks);
return __result({ set: true, item: item.name, startSeconds: ${args.start_seconds} });
`);
return sendCommand(script, bridgeOptions);
},
},
};
}