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:
Executable
+474
@@ -0,0 +1,474 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { getUxpTools } from "../../src/tools/uxp.js";
|
||||
import type { UxpWebSocketBridge } from "../../src/bridge/uxp-websocket-bridge.js";
|
||||
import { createServer } from "../../src/server.js";
|
||||
import { Client, InMemoryTransport } from "@modelcontextprotocol/client";
|
||||
|
||||
describe("UXP MCP tools", () => {
|
||||
it("maps MCP arguments to the supported frame export command", async () => {
|
||||
const request = vi.fn().mockResolvedValue({ path: "/tmp/frame.png" });
|
||||
const bridge = {
|
||||
request,
|
||||
getState: vi.fn(),
|
||||
} as unknown as UxpWebSocketBridge;
|
||||
const tools = getUxpTools(bridge);
|
||||
const result = await tools.export_frame_uxp.handler({
|
||||
output_directory: "/tmp",
|
||||
filename: "frame.png",
|
||||
seconds: 2.5,
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
});
|
||||
expect(request).toHaveBeenCalledWith("frame.export", {
|
||||
outputDirectory: "/tmp",
|
||||
filename: "frame.png",
|
||||
seconds: 2.5,
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
});
|
||||
expect(result).toEqual({
|
||||
success: true,
|
||||
data: { backend: "uxp", result: { path: "/tmp/frame.png" } },
|
||||
});
|
||||
});
|
||||
|
||||
it("exposes connection discovery without requiring a host request", async () => {
|
||||
const state = { status: "listening", connected: false } as const;
|
||||
const bridge = {
|
||||
request: vi.fn(),
|
||||
getState: vi.fn(() => state),
|
||||
} as unknown as UxpWebSocketBridge;
|
||||
const result = await getUxpTools(bridge).get_uxp_capabilities.handler();
|
||||
expect(result).toEqual({ success: true, data: state });
|
||||
expect(bridge.request).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("maps verified project and interchange workflows to versioned UXP commands", async () => {
|
||||
const request = vi.fn().mockResolvedValue({ outcome: "verified" });
|
||||
const bridge = { request, getState: vi.fn() } as unknown as UxpWebSocketBridge;
|
||||
const tools = getUxpTools(bridge);
|
||||
await tools.create_sequence_with_preset_uxp.handler({
|
||||
name: "Delivery",
|
||||
preset_path: "/presets/hd.sqpreset",
|
||||
operation_id: "sequence-1",
|
||||
});
|
||||
await tools.export_interchange_uxp.handler({
|
||||
format: "otio",
|
||||
output_file_path: "/exports/edit.otio",
|
||||
operation_id: "export-1",
|
||||
});
|
||||
expect(request).toHaveBeenNthCalledWith(1, "sequence.createPreset", {
|
||||
name: "Delivery", presetPath: "/presets/hd.sqpreset", operationId: "sequence-1",
|
||||
});
|
||||
expect(request).toHaveBeenNthCalledWith(2, "interchange.export", {
|
||||
format: "otio", outputFilePath: "/exports/edit.otio", operationId: "export-1",
|
||||
});
|
||||
});
|
||||
|
||||
it("maps guarded empty sequence creation only after confirmation and with a replay key", async () => {
|
||||
const request = vi.fn().mockResolvedValue({ outcome: "verified" });
|
||||
const bridge = { request, getState: vi.fn() } as unknown as UxpWebSocketBridge;
|
||||
const tool = getUxpTools(bridge).create_empty_sequence_uxp;
|
||||
await expect(tool.handler({
|
||||
name: "Empty Assembly", confirm_non_undoable: false, operation_id: "empty-1",
|
||||
})).resolves.toEqual({ success: false, error: "create_empty_sequence_uxp requires confirm_non_undoable: true" });
|
||||
await expect(tool.handler({
|
||||
name: "Empty Assembly", confirm_non_undoable: true, operation_id: "",
|
||||
})).resolves.toEqual({ success: false, error: "create_empty_sequence_uxp requires operation_id for safe replay" });
|
||||
expect(request).not.toHaveBeenCalled();
|
||||
await expect(tool.handler({
|
||||
name: "Empty Assembly", confirm_non_undoable: true, operation_id: "empty-1",
|
||||
})).resolves.toEqual({ success: true, data: { backend: "uxp", result: { outcome: "verified" } } });
|
||||
expect(request).toHaveBeenCalledWith("sequences.createEmpty", {
|
||||
name: "Empty Assembly", confirmNonUndoable: true, operationId: "empty-1",
|
||||
});
|
||||
expect(tool.parameters).toMatchObject({
|
||||
additionalProperties: false,
|
||||
required: ["name", "confirm_non_undoable", "operation_id"],
|
||||
});
|
||||
});
|
||||
|
||||
it("maps native caption-track inspection to its documented UXP command", async () => {
|
||||
const request = vi.fn().mockResolvedValue({ trackCount: 0, tracks: [] });
|
||||
const bridge = { request, getState: vi.fn() } as unknown as UxpWebSocketBridge;
|
||||
await expect(getUxpTools(bridge).inspect_caption_tracks_uxp.handler()).resolves.toEqual({
|
||||
success: true,
|
||||
data: { backend: "uxp", result: { trackCount: 0, tracks: [] } },
|
||||
});
|
||||
expect(request).toHaveBeenCalledWith("captions.inspect", {});
|
||||
});
|
||||
|
||||
it("maps guarded native Project-panel insertion-bin inspection to its documented UXP command", async () => {
|
||||
const request = vi.fn().mockResolvedValue({ projectGuid: "project-1" });
|
||||
const bridge = { request, getState: vi.fn() } as unknown as UxpWebSocketBridge;
|
||||
const tool = getUxpTools(bridge).inspect_project_insertion_bin_uxp;
|
||||
await expect(tool.handler()).resolves.toEqual({
|
||||
success: true,
|
||||
data: { backend: "uxp", result: { projectGuid: "project-1" } },
|
||||
});
|
||||
expect(request).toHaveBeenCalledWith("project.insertionBin.inspect", {});
|
||||
expect(tool.parameters).toMatchObject({
|
||||
type: "object",
|
||||
additionalProperties: false,
|
||||
properties: {},
|
||||
});
|
||||
});
|
||||
|
||||
it("maps opt-in installed MOGRT-directory disclosure to its documented UXP command", async () => {
|
||||
const request = vi.fn().mockResolvedValue({ pathDisclosure: "requested" });
|
||||
const bridge = { request, getState: vi.fn() } as unknown as UxpWebSocketBridge;
|
||||
const tool = getUxpTools(bridge).inspect_installed_mogrt_directory_uxp;
|
||||
await expect(tool.handler()).resolves.toEqual({
|
||||
success: true,
|
||||
data: { backend: "uxp", result: { pathDisclosure: "requested" } },
|
||||
});
|
||||
await tool.handler({ include_path: true });
|
||||
expect(request).toHaveBeenNthCalledWith(1, "graphics.mogrtPath.inspect", {});
|
||||
expect(request).toHaveBeenNthCalledWith(2, "graphics.mogrtPath.inspect", { includePath: true });
|
||||
expect(tool.parameters).toMatchObject({
|
||||
type: "object",
|
||||
additionalProperties: false,
|
||||
properties: { include_path: { type: "boolean" } },
|
||||
});
|
||||
});
|
||||
|
||||
it("maps guarded sequence-range inspection and updates to documented UXP commands", async () => {
|
||||
const request = vi.fn().mockResolvedValue({ outcome: "verified" });
|
||||
const bridge = { request, getState: vi.fn() } as unknown as UxpWebSocketBridge;
|
||||
const tools = getUxpTools(bridge);
|
||||
await tools.manage_sequence_range_uxp.handler({ action: "inspect" });
|
||||
await tools.manage_sequence_range_uxp.handler({
|
||||
action: "update",
|
||||
expected_sequence_guid: "sequence-1",
|
||||
expected_range: { in_seconds: 1, out_seconds: 10, zero_point_seconds: 3600, end_seconds: 120 },
|
||||
updates: { in_seconds: 2, zero_point_seconds: 7200 },
|
||||
operation_id: "range-1",
|
||||
});
|
||||
expect(request).toHaveBeenNthCalledWith(1, "sequence.range.inspect", {});
|
||||
expect(request).toHaveBeenNthCalledWith(2, "sequence.range.update", {
|
||||
expectedSequenceGuid: "sequence-1",
|
||||
expectedRange: { inSeconds: 1, outSeconds: 10, zeroPointSeconds: 3600, endSeconds: 120 },
|
||||
updates: { inSeconds: 2, zeroPointSeconds: 7200 },
|
||||
operationId: "range-1",
|
||||
});
|
||||
expect(tools.manage_sequence_range_uxp.parameters).toMatchObject({
|
||||
type: "object",
|
||||
additionalProperties: false,
|
||||
required: ["action"],
|
||||
properties: {
|
||||
action: { type: "string", enum: ["inspect", "update"] },
|
||||
expected_sequence_guid: { type: "string" },
|
||||
expected_range: {
|
||||
type: "object",
|
||||
additionalProperties: false,
|
||||
required: ["in_seconds", "out_seconds", "zero_point_seconds", "end_seconds"],
|
||||
},
|
||||
updates: { type: "object", additionalProperties: false },
|
||||
operation_id: { type: "string" },
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("maps guarded sequence-playhead inspection and settings to documented UXP commands", async () => {
|
||||
const request = vi.fn().mockResolvedValue({ outcome: "verified" });
|
||||
const bridge = { request, getState: vi.fn() } as unknown as UxpWebSocketBridge;
|
||||
const tools = getUxpTools(bridge);
|
||||
await tools.manage_sequence_playhead_uxp.handler({ action: "inspect" });
|
||||
await tools.manage_sequence_playhead_uxp.handler({
|
||||
action: "set",
|
||||
expected_sequence_guid: "sequence-1",
|
||||
expected_position_seconds: 3,
|
||||
position_seconds: 8,
|
||||
operation_id: "playhead-1",
|
||||
});
|
||||
expect(request).toHaveBeenNthCalledWith(1, "sequence.playhead.inspect", {});
|
||||
expect(request).toHaveBeenNthCalledWith(2, "sequence.playhead.set", {
|
||||
expectedSequenceGuid: "sequence-1",
|
||||
expectedPositionSeconds: 3,
|
||||
positionSeconds: 8,
|
||||
operationId: "playhead-1",
|
||||
});
|
||||
expect(tools.manage_sequence_playhead_uxp.parameters).toMatchObject({
|
||||
type: "object",
|
||||
additionalProperties: false,
|
||||
required: ["action"],
|
||||
properties: {
|
||||
action: { type: "string", enum: ["inspect", "set"] },
|
||||
expected_sequence_guid: { type: "string" },
|
||||
expected_position_seconds: { type: "number", minimum: 0, maximum: 86400 },
|
||||
position_seconds: { type: "number", minimum: 0, maximum: 86400 },
|
||||
operation_id: { type: "string" },
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("maps bounded guarded app-preference inspection and direct writes to documented UXP commands", async () => {
|
||||
const request = vi.fn().mockResolvedValue({ outcome: "verified" });
|
||||
const bridge = { request, getState: vi.fn() } as unknown as UxpWebSocketBridge;
|
||||
const tools = getUxpTools(bridge);
|
||||
await tools.manage_app_preferences_uxp.handler({ action: "inspect" });
|
||||
await tools.manage_app_preferences_uxp.handler({
|
||||
action: "set",
|
||||
preference: "auto_peak_generation",
|
||||
expected_value: "0",
|
||||
value: "1",
|
||||
persistence: "persistent",
|
||||
confirm_preference_change: true,
|
||||
operation_id: "app-preference-1",
|
||||
});
|
||||
expect(request).toHaveBeenNthCalledWith(1, "preferences.inspect", {});
|
||||
expect(request).toHaveBeenNthCalledWith(2, "preferences.set", {
|
||||
preference: "auto_peak_generation",
|
||||
expectedValue: "0",
|
||||
value: "1",
|
||||
persistence: "persistent",
|
||||
confirmPreferenceChange: true,
|
||||
operationId: "app-preference-1",
|
||||
});
|
||||
expect(tools.manage_app_preferences_uxp.parameters).toMatchObject({
|
||||
type: "object",
|
||||
additionalProperties: false,
|
||||
required: ["action"],
|
||||
properties: {
|
||||
action: { type: "string", enum: ["inspect", "set"] },
|
||||
preference: { enum: ["auto_peak_generation", "import_workspace", "show_quickstart_dialog"] },
|
||||
expected_value: { type: "string", maxLength: 1024 },
|
||||
value: { type: "string", maxLength: 1024 },
|
||||
persistence: { enum: ["persistent", "non_persistent"] },
|
||||
confirm_preference_change: { type: "boolean" },
|
||||
operation_id: { type: "string", minLength: 1, maxLength: 128 },
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("rejects incomplete or unconfirmed app-preference writes before bridge access", async () => {
|
||||
const request = vi.fn();
|
||||
const bridge = { request, getState: vi.fn() } as unknown as UxpWebSocketBridge;
|
||||
const tool = getUxpTools(bridge).manage_app_preferences_uxp;
|
||||
await expect(tool.handler({ action: "set", preference: "import_workspace" }))
|
||||
.resolves.toMatchObject({ success: false, error: expect.stringContaining("requires preference") });
|
||||
await expect(tool.handler({
|
||||
action: "set", preference: "import_workspace", expected_value: "1", value: "0", persistence: "persistent", operation_id: "app-preference-unconfirmed",
|
||||
})).resolves.toMatchObject({ success: false, error: expect.stringContaining("confirm_preference_change") });
|
||||
expect(request).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("maps bounded native sequence-timing inspection to its documented UXP command", async () => {
|
||||
const request = vi.fn().mockResolvedValue({ outcome: "verified" });
|
||||
const bridge = { request, getState: vi.fn() } as unknown as UxpWebSocketBridge;
|
||||
const tools = getUxpTools(bridge);
|
||||
await tools.inspect_sequence_timing_uxp.handler({});
|
||||
expect(request).toHaveBeenCalledWith("sequence.timing.inspect", {});
|
||||
expect(tools.inspect_sequence_timing_uxp.parameters).toMatchObject({
|
||||
type: "object",
|
||||
additionalProperties: false,
|
||||
properties: {},
|
||||
});
|
||||
});
|
||||
|
||||
it("maps native frame alignment with a closed action-specific argument contract", async () => {
|
||||
const request = vi.fn().mockResolvedValue({ verificationBoundary: "native_ticktime_value_readback" });
|
||||
const bridge = { request, getState: vi.fn() } as unknown as UxpWebSocketBridge;
|
||||
const tools = getUxpTools(bridge);
|
||||
await tools.inspect_frame_alignment_uxp.handler({ action: "align", frame_rate: 30000 / 1001, seconds: 1.03 });
|
||||
await tools.inspect_frame_alignment_uxp.handler({ action: "frame", frame_rate: 24, frame_count: 42 });
|
||||
expect(request).toHaveBeenNthCalledWith(1, "time.frameAlignment.inspect", { action: "align", frameRate: 30000 / 1001, seconds: 1.03 });
|
||||
expect(request).toHaveBeenNthCalledWith(2, "time.frameAlignment.inspect", { action: "frame", frameRate: 24, frameCount: 42 });
|
||||
expect(tools.inspect_frame_alignment_uxp.parameters).toMatchObject({
|
||||
type: "object", additionalProperties: false, required: ["action", "frame_rate"],
|
||||
properties: {
|
||||
action: { enum: ["align", "frame"] },
|
||||
frame_rate: { minimum: 1, maximum: 240 },
|
||||
seconds: { minimum: 0, maximum: 86400 },
|
||||
frame_count: { minimum: 0, maximum: 20736000 },
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("maps non-active native sequence timing inspection to its guarded GUID command", async () => {
|
||||
const request = vi.fn().mockResolvedValue({ outcome: "verified" });
|
||||
const bridge = { request, getState: vi.fn() } as unknown as UxpWebSocketBridge;
|
||||
const tools = getUxpTools(bridge);
|
||||
await tools.inspect_sequence_timing_by_guid_uxp.handler({ sequence_guid: "sequence-2" });
|
||||
expect(request).toHaveBeenCalledWith("sequence.timingByGuid.inspect", { sequenceGuid: "sequence-2" });
|
||||
expect(tools.inspect_sequence_timing_by_guid_uxp.parameters).toMatchObject({
|
||||
type: "object", additionalProperties: false, required: ["sequence_guid"],
|
||||
properties: { sequence_guid: { minLength: 1, maxLength: 512 } },
|
||||
});
|
||||
});
|
||||
|
||||
it("maps bounded native timeline-structure inspection and documents scoped track counts", async () => {
|
||||
const request = vi.fn().mockResolvedValue({ outcome: "verified" });
|
||||
const bridge = { request, getState: vi.fn() } as unknown as UxpWebSocketBridge;
|
||||
const tools = getUxpTools(bridge);
|
||||
await tools.inspect_sequence_structure_uxp.handler({
|
||||
sequence_id: "sequence-1", expected_sequence_id: "sequence-1", media_type: "video",
|
||||
track_indices: [1, 0], include_empty_tracks: true, include_source_project_items: true,
|
||||
include_source_project_item_classification: true, include_source_project_item_content_type: true,
|
||||
include_source_nested_sequence_identity: true, max_items: 8,
|
||||
});
|
||||
expect(request).toHaveBeenCalledWith("timeline.structure.inspect", {
|
||||
sequenceId: "sequence-1", expectedSequenceId: "sequence-1", mediaType: "video",
|
||||
trackIndices: [1, 0], includeEmptyTracks: true, includeSourceProjectItems: true,
|
||||
includeSourceProjectItemClassification: true, includeSourceProjectItemContentType: true,
|
||||
includeSourceNestedSequenceIdentity: true, maxItems: 8,
|
||||
});
|
||||
expect(tools.inspect_sequence_structure_uxp.description).toContain(
|
||||
"track_counts contains only the requested media types",
|
||||
);
|
||||
expect(tools.inspect_sequence_structure_uxp.parameters).toMatchObject({
|
||||
type: "object",
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
sequence_id: { type: "string", minLength: 1, maxLength: 128 },
|
||||
expected_sequence_id: { type: "string", minLength: 1, maxLength: 128 },
|
||||
media_type: { type: "string", enum: ["all", "video", "audio"] },
|
||||
track_indices: { type: "array", minItems: 1, maxItems: 64, uniqueItems: true },
|
||||
include_empty_tracks: { type: "boolean" },
|
||||
include_source_project_items: { type: "boolean" },
|
||||
include_source_project_item_classification: { type: "boolean" },
|
||||
include_source_project_item_content_type: { type: "boolean" },
|
||||
include_source_nested_sequence_identity: { type: "boolean" },
|
||||
max_items: { type: "integer", minimum: 1, maximum: 512 },
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("maps guarded native transition inspection and mutation arguments to documented UXP commands", async () => {
|
||||
const request = vi.fn().mockResolvedValue({ outcome: "committed_unverified" });
|
||||
const bridge = { request, getState: vi.fn() } as unknown as UxpWebSocketBridge;
|
||||
const tools = getUxpTools(bridge);
|
||||
const expectedTarget = {
|
||||
sequence_guid: "sequence-1", video_track_index: 2, clip_index: 3, project_item_id: "project-item-1",
|
||||
start_seconds: 10, end_seconds: 20, position: "end" as const, transition_present: false,
|
||||
};
|
||||
await tools.lift_selection_uxp.handler({ expected_sequence_guid: "sequence-1", operation_id: "lift-1" });
|
||||
await tools.list_video_transitions_uxp.handler();
|
||||
await tools.inspect_video_transition_uxp.handler({ video_track_index: 2, clip_index: 3, position: "end" });
|
||||
await tools.add_video_transition_uxp.handler({
|
||||
video_track_index: 2, clip_index: 3, match_name: "CrossDissolve", position: "end",
|
||||
duration_seconds: 0.5, force_single_sided: true, transition_alignment: 1, expected_target: expectedTarget, operation_id: "transition-add-1",
|
||||
});
|
||||
await tools.remove_video_transition_uxp.handler({
|
||||
video_track_index: 2, clip_index: 3, position: "end", expected_target: { ...expectedTarget, transition_present: true }, operation_id: "transition-remove-1",
|
||||
});
|
||||
expect(request).toHaveBeenNthCalledWith(1, "timeline.selection.lift", { expectedSequenceGuid: "sequence-1", operationId: "lift-1" });
|
||||
expect(request).toHaveBeenNthCalledWith(2, "transition.video.list", {});
|
||||
expect(request).toHaveBeenNthCalledWith(3, "transition.video.inspect", {
|
||||
videoTrackIndex: 2, clipIndex: 3, position: "end",
|
||||
});
|
||||
expect(request).toHaveBeenNthCalledWith(4, "transition.video.add", {
|
||||
videoTrackIndex: 2, clipIndex: 3, matchName: "CrossDissolve", position: "end", durationSeconds: 0.5,
|
||||
forceSingleSided: true, transitionAlignment: 1,
|
||||
expectedTarget: {
|
||||
sequenceGuid: "sequence-1", videoTrackIndex: 2, clipIndex: 3, projectItemId: "project-item-1",
|
||||
startSeconds: 10, endSeconds: 20, position: "end", transitionPresent: false,
|
||||
},
|
||||
operationId: "transition-add-1",
|
||||
});
|
||||
expect(request).toHaveBeenNthCalledWith(5, "transition.video.remove", {
|
||||
videoTrackIndex: 2, clipIndex: 3, position: "end", operationId: "transition-remove-1",
|
||||
expectedTarget: {
|
||||
sequenceGuid: "sequence-1", videoTrackIndex: 2, clipIndex: 3, projectItemId: "project-item-1",
|
||||
startSeconds: 10, endSeconds: 20, position: "end", transitionPresent: true,
|
||||
},
|
||||
});
|
||||
expect(tools.add_video_transition_uxp.parameters).toMatchObject({ required: expect.arrayContaining(["expected_target"]) });
|
||||
expect(tools.remove_video_transition_uxp.parameters).toMatchObject({ required: expect.arrayContaining(["expected_target"]) });
|
||||
});
|
||||
|
||||
it("returns transport errors through the normal tool envelope", async () => {
|
||||
const bridge = {
|
||||
request: vi.fn().mockRejectedValue(new Error("UXP bridge is not connected")),
|
||||
getState: vi.fn(),
|
||||
} as unknown as UxpWebSocketBridge;
|
||||
const result = await getUxpTools(bridge).get_uxp_state.handler();
|
||||
expect(result).toEqual({
|
||||
success: false,
|
||||
error: "UXP bridge is not connected",
|
||||
});
|
||||
});
|
||||
|
||||
it("registers UXP tools only when an adapter is supplied", async () => {
|
||||
const bridge = {
|
||||
request: vi.fn(),
|
||||
getState: vi.fn(() => ({ status: "listening", connected: false })),
|
||||
} as unknown as UxpWebSocketBridge;
|
||||
const server = createServer({}, { uxpBridge: bridge });
|
||||
const client = new Client({ name: "uxp-tool-test", version: "1.0.0" });
|
||||
const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
|
||||
await Promise.all([server.connect(serverTransport), client.connect(clientTransport)]);
|
||||
try {
|
||||
const tools = await client.listTools();
|
||||
expect(tools.tools.map((tool) => tool.name)).toEqual(
|
||||
expect.arrayContaining([
|
||||
"get_uxp_capabilities",
|
||||
"get_uxp_state",
|
||||
"inspect_project_uxp",
|
||||
"inspect_project_insertion_bin_uxp",
|
||||
"inspect_installed_mogrt_directory_uxp",
|
||||
"inspect_sequence_timing_uxp",
|
||||
"inspect_frame_alignment_uxp",
|
||||
"calculate_tick_time_uxp",
|
||||
"inspect_sequence_timing_by_guid_uxp",
|
||||
"inspect_caption_tracks_uxp",
|
||||
"manage_sequence_display_format_uxp",
|
||||
"manage_sequence_range_uxp",
|
||||
"manage_sequence_playhead_uxp",
|
||||
"manage_app_preferences_uxp",
|
||||
"save_project_uxp",
|
||||
"create_sequence_with_preset_uxp",
|
||||
"create_empty_sequence_uxp",
|
||||
"export_interchange_uxp",
|
||||
"get_transcript_languages_uxp",
|
||||
"get_clip_transcript_uxp",
|
||||
"search_clip_transcript_uxp",
|
||||
"preview_transcript_edit_uxp",
|
||||
"plan_transcript_rough_cut_uxp",
|
||||
"detect_object_masks_uxp",
|
||||
"audit_object_masks_uxp",
|
||||
"configure_encoder_uxp",
|
||||
"rename_track_uxp",
|
||||
"create_subclip_uxp",
|
||||
"list_markers_uxp",
|
||||
"set_source_monitor_position_uxp",
|
||||
"has_transcript_uxp",
|
||||
"export_aaf_uxp",
|
||||
"export_frame_uxp",
|
||||
"lift_selection_uxp",
|
||||
"list_video_transitions_uxp",
|
||||
"inspect_video_transition_uxp",
|
||||
"add_video_transition_uxp",
|
||||
"remove_video_transition_uxp",
|
||||
"inspect_project_panel_metadata_uxp",
|
||||
"slide_track_item_uxp",
|
||||
"duplicate_track_item_uxp",
|
||||
"ripple_delete_track_item_uxp",
|
||||
"manage_timeline_source_label_uxp",
|
||||
"apply_editorial_organization_plan",
|
||||
]),
|
||||
);
|
||||
// The default profile excludes two unsafe-script tools. The native
|
||||
// transcript workflow and documented Premiere 26.3 tools add nineteen. The
|
||||
// two stable workflow expansions, confirmed organization application, four
|
||||
// bounded native migration adapters, beat-grid marker application, and
|
||||
// guarded sequence-playhead control, native sequence-timing inspection, and
|
||||
// guarded sequence-display-format updates and guarded Project-panel
|
||||
// insertion-bin inspection, guarded empty-sequence creation, marker web-link
|
||||
// inspection, Project-panel metadata inspection and guarded replacement,
|
||||
// guarded app-preference control, source-media interpretation overrides,
|
||||
// direct track-item identity inspection, targeted sequence timing, guarded
|
||||
// three-item slides, append-only timeline duplication, guarded Project metadata
|
||||
// schema-field creation, guarded contiguous ripple deletes, and guarded
|
||||
// source-label updates, opt-in installed-MOGRT directory inspection, and
|
||||
// bounded Object Mask audits, native TickTime arithmetic, and guarded
|
||||
// explicit-sequence preview-frame updates plus unique serializable identity
|
||||
// inspection add fifty consolidated UXP tools;
|
||||
// connection verification and delivery conformance add two default-profile core tools.
|
||||
expect(tools.tools).toHaveLength(440);
|
||||
} finally {
|
||||
await client.close();
|
||||
await server.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user