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
+433
View File
@@ -0,0 +1,433 @@
import { createRequire } from "node:module";
import { tmpdir } from "node:os";
import { join } from "node:path";
import type { Capability, CapabilityConfig } from "./security/capabilities.js";
import {
buildToolCapabilityReport,
type CatalogToolDefinition,
} from "./tool-capability-report.js";
import type { ToolPackReport } from "./workflows/tool-packs.js";
export const SUPPORTED_HOST_PLATFORMS = ["darwin", "win32"] as const;
const ALL_CAPABILITIES: Capability[] = ["inspect", "edit", "export", "filesystem", "unsafe-script"];
const require = createRequire(import.meta.url);
const adobeUxpCoverage: unknown = require("./resources/adobe-uxp-coverage.json");
export type SupportedHostPlatform = (typeof SUPPORTED_HOST_PLATFORMS)[number];
export type AdobeUxpCoverageAvailability = "current" | "planned";
export type AdobeUxpCoverageImplementationStatus = "implemented" | "planned";
export type AdobeUxpCoverageVerificationStatus =
| "automated_contract_verified"
| "committed_unverified"
| "not_started";
export type AdobeUxpCoverageLiveHostVerificationStatus = "not_run" | "verified";
export interface AdobeUxpCoverageEntry {
id: string;
adobeApi: string[];
documentationUrls: string[];
minimumPremiereVersion: string;
backend: "uxp";
uxpCommand: string | null;
mcpTools: string[];
availability: AdobeUxpCoverageAvailability;
implementationStatus: AdobeUxpCoverageImplementationStatus;
verificationStatus: AdobeUxpCoverageVerificationStatus;
liveHostVerificationStatus: AdobeUxpCoverageLiveHostVerificationStatus;
mutatesProject: boolean;
undoable: boolean;
idempotency: "operation_id" | "operation_id_when_supported" | "not_applicable";
verificationBoundary: string;
}
export interface AdobeUxpCoverageManifest {
schemaVersion: 1;
source: {
apiPackage: "@adobe/premierepro";
apiVersion: string;
changelogUrl: string;
};
entries: AdobeUxpCoverageEntry[];
}
export interface AdobeUxpCoverageReport extends AdobeUxpCoverageManifest {
summary: {
total: number;
current: number;
planned: number;
implemented: number;
committedUnverified: number;
automatedContractVerified: number;
liveHostVerified: number;
};
}
function asRecord(value: unknown, label: string): Record<string, unknown> {
if (!value || typeof value !== "object" || Array.isArray(value)) {
throw new Error(`${label} must be an object`);
}
return value as Record<string, unknown>;
}
function stringArray(value: unknown, label: string): string[] {
if (!Array.isArray(value) || value.length === 0 || value.some((item) => typeof item !== "string" || !item)) {
throw new Error(`${label} must be a non-empty string array`);
}
return value;
}
function stringValue(value: unknown, label: string): string {
if (typeof value !== "string" || !value) throw new Error(`${label} must be a non-empty string`);
return value;
}
function validateDocumentationUrl(value: string, label: string): void {
let url: URL;
try {
url = new URL(value);
} catch {
throw new Error(`${label} must be a valid URL`);
}
if (url.protocol !== "https:" || url.hostname !== "developer.adobe.com" || !url.pathname.startsWith("/premiere-pro/uxp/")) {
throw new Error(`${label} must point to the official Premiere Pro UXP documentation`);
}
}
function validateAdobeUxpCoverageManifest(value: unknown): AdobeUxpCoverageManifest {
const manifest = asRecord(value, "Adobe UXP coverage manifest");
if (manifest.schemaVersion !== 1) throw new Error("Adobe UXP coverage manifest schemaVersion must be 1");
const source = asRecord(manifest.source, "Adobe UXP coverage manifest source");
if (source.apiPackage !== "@adobe/premierepro") {
throw new Error("Adobe UXP coverage manifest must identify @adobe/premierepro as its source package");
}
const apiVersion = stringValue(source.apiVersion, "Adobe UXP coverage manifest source.apiVersion");
const changelogUrl = stringValue(source.changelogUrl, "Adobe UXP coverage manifest source.changelogUrl");
validateDocumentationUrl(changelogUrl, "Adobe UXP coverage manifest source.changelogUrl");
if (!Array.isArray(manifest.entries) || manifest.entries.length === 0) {
throw new Error("Adobe UXP coverage manifest entries must be a non-empty array");
}
const ids = new Set<string>();
const entries = manifest.entries.map((rawEntry, index): AdobeUxpCoverageEntry => {
const label = `Adobe UXP coverage manifest entry ${index}`;
const entry = asRecord(rawEntry, label);
const id = stringValue(entry.id, `${label}.id`);
if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(id) || ids.has(id)) {
throw new Error(`${label}.id must be a unique kebab-case identifier`);
}
ids.add(id);
const documentationUrls = stringArray(entry.documentationUrls, `${label}.documentationUrls`);
documentationUrls.forEach((url) => validateDocumentationUrl(url, `${label}.documentationUrls`));
const availability = entry.availability;
if (availability !== "current" && availability !== "planned") {
throw new Error(`${label}.availability must be current or planned`);
}
const implementationStatus = entry.implementationStatus;
if (implementationStatus !== "implemented" && implementationStatus !== "planned") {
throw new Error(`${label}.implementationStatus must be implemented or planned`);
}
const verificationStatus = entry.verificationStatus;
if (
verificationStatus !== "automated_contract_verified"
&& verificationStatus !== "committed_unverified"
&& verificationStatus !== "not_started"
) {
throw new Error(`${label}.verificationStatus is not supported`);
}
const liveHostVerificationStatus = entry.liveHostVerificationStatus;
if (liveHostVerificationStatus !== "not_run" && liveHostVerificationStatus !== "verified") {
throw new Error(`${label}.liveHostVerificationStatus is not supported`);
}
const idempotency = entry.idempotency;
if (idempotency !== "operation_id" && idempotency !== "operation_id_when_supported" && idempotency !== "not_applicable") {
throw new Error(`${label}.idempotency is not supported`);
}
if (entry.backend !== "uxp") throw new Error(`${label}.backend must be uxp`);
if (entry.uxpCommand !== null && typeof entry.uxpCommand !== "string") {
throw new Error(`${label}.uxpCommand must be a string or null`);
}
if (typeof entry.mutatesProject !== "boolean" || typeof entry.undoable !== "boolean") {
throw new Error(`${label} mutation metadata must be boolean`);
}
return {
id,
adobeApi: stringArray(entry.adobeApi, `${label}.adobeApi`),
documentationUrls,
minimumPremiereVersion: stringValue(entry.minimumPremiereVersion, `${label}.minimumPremiereVersion`),
backend: "uxp",
uxpCommand: entry.uxpCommand,
mcpTools: stringArray(entry.mcpTools, `${label}.mcpTools`),
availability,
implementationStatus,
verificationStatus,
liveHostVerificationStatus,
mutatesProject: entry.mutatesProject,
undoable: entry.undoable,
idempotency,
verificationBoundary: stringValue(entry.verificationBoundary, `${label}.verificationBoundary`),
};
});
return {
schemaVersion: 1,
source: {
apiPackage: "@adobe/premierepro",
apiVersion,
changelogUrl,
},
entries,
};
}
export const ADOBE_UXP_COVERAGE_MANIFEST = validateAdobeUxpCoverageManifest(adobeUxpCoverage);
export function buildAdobeUxpCoverageReport(): AdobeUxpCoverageReport {
const entries = ADOBE_UXP_COVERAGE_MANIFEST.entries.map((entry) => ({
...entry,
adobeApi: [...entry.adobeApi],
documentationUrls: [...entry.documentationUrls],
mcpTools: [...entry.mcpTools],
}));
return {
schemaVersion: ADOBE_UXP_COVERAGE_MANIFEST.schemaVersion,
source: { ...ADOBE_UXP_COVERAGE_MANIFEST.source },
entries,
summary: {
total: entries.length,
current: entries.filter((entry) => entry.availability === "current").length,
planned: entries.filter((entry) => entry.availability === "planned").length,
implemented: entries.filter((entry) => entry.implementationStatus === "implemented").length,
committedUnverified: entries.filter((entry) => entry.verificationStatus === "committed_unverified").length,
automatedContractVerified: entries.filter((entry) => entry.verificationStatus === "automated_contract_verified").length,
liveHostVerified: entries.filter((entry) => entry.liveHostVerificationStatus === "verified").length,
},
};
}
export function platformName(platform: NodeJS.Platform): string {
if (platform === "darwin") return "macOS";
if (platform === "win32") return "Windows";
return platform;
}
export function buildPlatformCapabilityReport(
capabilities: CapabilityConfig,
platform: NodeJS.Platform = process.platform,
tempDirectory: string = join(tmpdir(), "premiere-mcp-bridge"),
toolCatalog: Record<string, CatalogToolDefinition> = {},
toolPacks?: ToolPackReport,
) {
const supported = SUPPORTED_HOST_PLATFORMS.includes(platform as SupportedHostPlatform);
return {
schemaVersion: 1,
mcp: {
sdk: {
generation: 2,
packages: [
"@modelcontextprotocol/server",
"@modelcontextprotocol/client",
"@modelcontextprotocol/node",
],
},
protocol: {
modernRevision: "2026-07-28",
legacyRevisions: "2024-10-07 through 2025-11-25",
dualEra: true,
},
features: {
statelessRequests: "supported",
serverDiscovery: "supported",
requestMetadataEnvelope: "supported",
headerBasedRouting: "supported",
deterministicCacheableLists: "supported",
resultTypeDiscriminator: "supported",
cancellation: "supported_by_protocol_host_limited",
progressNotifications: "protocol_supported_not_emitted",
traceContext: "transport_passthrough",
jsonSchema202012: "supported",
cursorPagination: "supported_single_page_catalogs",
resourceTemplates: "not_exposed_no_parameterized_resource_family",
completions: "not_exposed_no_bounded_completion_domain",
embeddedResourcesAndLinks: "supported_selective_use",
multiRoundTripRequests: "sdk_supported_no_current_workflow",
subscriptionsListen: "supported",
extensionCapabilities: "supported",
tasksExtension: "not_implemented",
mcpAppsExtension: "not_implemented",
skillsOverMcp: "experimental_not_advertised",
serverCard: "experimental_not_advertised",
oauthClientMetadataDocuments: "external_authorization_boundary",
deprecatedSamplingRootsLogging: "not_advertised",
},
cachePolicy: {
toolsList: { ttlMs: 30_000, cacheScope: "private" },
promptsList: { ttlMs: 300_000, cacheScope: "public" },
resourcesList: { ttlMs: 60_000, cacheScope: "private" },
resourcesRead: { ttlMs: 0, cacheScope: "private" },
},
},
runtime: {
platform,
platformName: platformName(platform),
supported,
tempDirectory,
nodeVersion: process.version,
},
premiere: {
supportedVersions: "2020–2026",
hostVerificationRequired: true,
note: supported
? "Static compatibility is supported; call ping with Premiere Pro running to verify the current host session."
: "The MCP server can run here, but the Adobe Premiere Pro bridge and installer are supported only on macOS and Windows.",
},
backends: {
cep: {
status: "production",
platforms: ["macOS", "Windows"],
premiereVersions: "2020–2026",
transport: "local file bridge",
capabilities: ALL_CAPABILITIES,
delivery: {
interchange: ["FCP XML export", "AAF export", "OMF export"],
presetValidation: true,
postExportChecksum: ["sha256", "sha512"],
unsupported: {
otio: "No documented Premiere ExtendScript or UXP OTIO import/export API.",
edl: "No documented Premiere ExtendScript or UXP EDL import/export API.",
cloudPublish: "No documented Premiere automation API for publishing to cloud destinations.",
contentCredentials: "No documented Premiere automation API for configuring Content Credentials.",
renderAndReplace: "No documented Premiere ExtendScript or UXP Render and Replace API.",
},
},
},
uxp: {
status: "preview",
platforms: ["macOS", "Windows"],
premiereVersions: "25.6+",
transport: "loopback WebSocket",
apiCoverage: buildAdobeUxpCoverageReport(),
commands: [
"capabilities.get",
"state.get",
"operation.cancel",
"frame.export",
"sequence.playhead.inspect",
"sequence.playhead.set",
"sequence.timing.inspect",
"graphics.mogrtPath.inspect",
"timeline.selection.lift",
"transition.video.list",
"transition.video.inspect",
"transition.video.add",
"transition.video.remove",
"transcript.export",
"transcript.search",
"transcript.has",
"transcript.import",
"captions.inspect",
"effects.catalog",
"effects.chain.get",
"trackItem.identity.inspect",
"effects.chain.add",
"effects.chain.remove",
"selection.inspect",
"selection.fingerprints.inspect",
"selection.targets.inspect",
"selection.update",
"effects.selection.add",
"effects.selection.remove",
"sceneEdit.detect",
"proxy.inspect",
"proxy.attach",
"ingest.get",
"ingest.configure",
"media.relink",
"metadata.get",
"metadata.update",
"color.preflight",
"environment.inspect",
"footage.conform",
"sourceMonitor.state",
"sourceMonitor.open",
"sourceMonitor.play",
"sourceMonitor.close",
"storage.preflight",
"scratch.configure",
"workspace.status",
"projectSelection.views",
"projectSelection.inspect",
"markers.inspect",
"markers.add",
"markers.addBeatGrid",
"markers.update",
"markers.remove",
"markers.removeMany",
"bins.inspect",
"bins.create",
"bins.createSmart",
"bins.rename",
"bins.move",
"bins.color",
"bins.remove",
"sequenceSettings.get",
"sequenceSettings.update",
"project.import",
"parameters.inspect",
"parameters.set",
"parameters.keyframeAdd",
"parameters.keyframeRemove",
"parameters.keyframeRemoveRange",
"parameters.keyframeInterpolation",
"trackItem.inspect",
"trackItem.update",
"timeline.insert",
"timeline.overwrite",
"timeline.cloneSelection",
"timeline.removeSelection",
"timeline.mogrtPath",
"timeline.mogrtLibrary",
"sequences.inspect",
"sequences.createFromMedia",
"silence.deriveSequence",
"sequences.clone",
"sequences.subsequence",
"sequences.activate",
"sequences.open",
"sequences.close",
"sequences.delete",
"encoder.preflight",
"encoder.sequence",
"encoder.projectItem",
"encoder.file",
],
unsupportedCommands: {
"captions.create": "No documented Premiere UXP caption creation API.",
"captions.update": "No documented Premiere UXP caption text/timing mutation API.",
"captions.delete": "No documented Premiere UXP caption deletion API.",
},
events: [
"premiere.state.changed",
"premiere.operation.started",
"premiere.operation.progress",
"premiere.operation.completed",
"premiere.operation.failed",
"premiere.operation.cancelled",
],
operationSemantics: {
cancellation: "cooperative preflight only",
atomicRollback: false,
undo: "only action-based mutations executed through Project.executeTransaction",
},
hostVerificationRequired: true,
},
},
authority: {
source: capabilities.source,
enabled: [...capabilities.capabilities].sort(),
disabled: ALL_CAPABILITIES.filter((capability) => !capabilities.capabilities.has(capability)),
},
...(toolPacks === undefined ? {} : { toolPacks }),
tools: buildToolCapabilityReport(toolCatalog, capabilities),
};
}