@writepanda/mcp 1.56.0 → 1.58.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/server.mjs +60 -6
  2. package/package.json +1 -1
package/bin/server.mjs CHANGED
@@ -986,7 +986,7 @@ const TOOLS = [
986
986
  {
987
987
  name: "project_add_clip_transform_region",
988
988
  description:
989
- "Time-bounded transform on the main video clip — between startMs and endMs the clip renders inside a sub-rect of the canvas (per the chosen preset), freeing the rest for motion graphics. Outside the region, the clip renders full-frame. Renderer interpolates over `transitionMs` (default 320ms) at each boundary so the camera smoothly slides + scales. **Use ONLY on camera-only / user-uploaded recordings — for screen recordings, use cursor-telemetry zooms instead.** Typical pattern: agent finds an emphasis moment in the transcript, places a `cam-bottom-half` (9:16) or `cam-right-portrait` (16:9) transform region, and adds a motion graphic in the freed space. When the region ends, the camera returns to full-frame.",
989
+ "Time-bounded transform on the main video clip between startMs and endMs. TWO families of preset: (1) cam-* render the single clip inside a sub-rect of the canvas, freeing the rest for motion graphics (use ONLY on camera-only / user-uploaded recordings; for screen recordings use cursor-telemetry zooms). (2) layout-* swap the WHOLE podcast composite for the window — this is how you change a PODCAST's layout over time WITHIN ONE recording (e.g. side-by-side intro, then host-only while they talk, then back). Outside the region the clip renders with its natural layout. Renderer interpolates over `transitionMs` (default 320ms) at each boundary so the camera/tiles smoothly resize.",
990
990
  inputSchema: {
991
991
  type: "object",
992
992
  required: ["startMs", "endMs", "preset"],
@@ -1004,9 +1004,17 @@ const TOOLS = [
1004
1004
  "cam-left-portrait",
1005
1005
  "cam-bottom-right-quarter",
1006
1006
  "cam-bottom-left-quarter",
1007
+ "cam-right-55",
1008
+ "cam-left-55",
1009
+ "cam-right-50",
1010
+ "cam-left-50",
1011
+ "layout-side-by-side",
1012
+ "layout-podcast",
1013
+ "layout-host-full",
1014
+ "layout-guest-full",
1007
1015
  ],
1008
1016
  description:
1009
- "cam-bottom-half / cam-top-half — for 9:16 (camera fills half, other half open for motion graphics). cam-right-portrait / cam-left-portrait — for 16:9 (camera ~35% of canvas in a portrait card on the chosen side, other ~65% open). cam-bottom-right-quarter / cam-bottom-left-quarter — small corner card; rest of canvas open.",
1017
+ "cam-* (camera reposition into a sub-rect): cam-bottom-half / cam-top-half (9:16); cam-right-portrait / cam-left-portrait (16:9 ~35% card); cam-bottom-right-quarter / cam-bottom-left-quarter (corner card); cam-right-55/left-55/right-50/left-50 (designed splits). layout-* (PODCAST ONLY — whole-composite swap over time): layout-side-by-side, layout-podcast (two equal tiles), layout-host-full (speaker 1 only), layout-guest-full (speaker 2 only). IMPORTANT: layout-* presets only do anything on a PODCAST clip (kind='podcast' — a clip with BOTH a host and a guest source). On any other clip there is no second speaker, so they are a no-op; use cam-* there. Check clip.kind via project_read before using layout-*.",
1010
1018
  },
1011
1019
  transitionMs: {
1012
1020
  type: "number",
@@ -1193,7 +1201,7 @@ const TOOLS = [
1193
1201
  {
1194
1202
  name: "project_set_webcam_layout",
1195
1203
  description:
1196
- "Set the webcam layout preset and optional position/scale for the current project. Use 'none' to hide the webcam overlay entirely. Use 'podcast' for a two-speaker composite (host + guest as co-equal tiles).",
1204
+ "Set the PROJECT-LEVEL webcam layout preset and optional position/scale. Use 'none' to hide the webcam. 'podcast' = two co-equal speaker tiles (host + guest). 'podcast-host-full'/'podcast-guest-full' = a single speaker full-frame (host=mediaPath/speaker 1, guest=webcamPath/speaker 2). To vary the layout PER SECTION of a podcast, split the clip and use project_set_clip_layout instead.",
1197
1205
  inputSchema: {
1198
1206
  type: "object",
1199
1207
  properties: {
@@ -1202,7 +1210,7 @@ const TOOLS = [
1202
1210
  preset: {
1203
1211
  type: "string",
1204
1212
  description:
1205
- "picture-in-picture | vertical-stack | side-by-side | podcast | none. 'podcast' shows two co-equal speaker tiles; 'none' hides the webcam.",
1213
+ "picture-in-picture | vertical-stack | side-by-side | podcast | podcast-host-full | podcast-guest-full | none",
1206
1214
  },
1207
1215
  cx: {
1208
1216
  type: "number",
@@ -1477,6 +1485,52 @@ const TOOLS = [
1477
1485
  },
1478
1486
  command: "project.set-webcam-offset",
1479
1487
  },
1488
+ {
1489
+ name: "project_set_clip_layout",
1490
+ description:
1491
+ "Set ONE clip's webcam layout — the per-section override for a podcast. preset: podcast | podcast-host-full | podcast-guest-full | picture-in-picture | side-by-side | vertical-stack | none (none clears the override so the clip inherits the project layout). 'podcast-host-full' shows only speaker 1 (host=mediaPath) full-frame; 'podcast-guest-full' shows only speaker 2 (guest=webcamPath). Speaker-driven editing flow: transcript_get returns each word's `speaker` ('host'/'guest') for podcast clips; project_split_clip at the points where the active speaker changes; then call this per section to cut to whoever is talking. Honored in preview + export.",
1492
+ inputSchema: {
1493
+ type: "object",
1494
+ properties: {
1495
+ id: { type: "string" },
1496
+ path: { type: "string" },
1497
+ clipId: { type: "string", description: "Clip id of the section to set" },
1498
+ preset: {
1499
+ type: "string",
1500
+ description:
1501
+ "podcast | podcast-host-full | podcast-guest-full | picture-in-picture | side-by-side | vertical-stack | none",
1502
+ },
1503
+ expectedRevision: { type: "number" },
1504
+ },
1505
+ required: ["clipId", "preset"],
1506
+ },
1507
+ command: "project.set-clip-layout",
1508
+ },
1509
+ {
1510
+ name: "project_set_clip_style",
1511
+ description:
1512
+ "Set ONE clip's framing style — padding, borderRadius (roundness), and/or shadowIntensity (each 0–100) — overriding the project-level values for just that clip. Use in a multi-clip project to frame sources differently: e.g. a full-bleed camera clip (padding 0, borderRadius 0, shadowIntensity 0) next to a padded, rounded podcast clip. Pass a field as null to CLEAR its override (inherit project); omit a field to leave it unchanged. Project-level equivalents are project_set_style. Honored in preview + export.",
1513
+ inputSchema: {
1514
+ type: "object",
1515
+ properties: {
1516
+ id: { type: "string" },
1517
+ path: { type: "string" },
1518
+ clipId: { type: "string", description: "Clip id to style" },
1519
+ padding: { type: "number", description: "Padding 0–100; null clears, omit leaves as-is." },
1520
+ borderRadius: {
1521
+ type: "number",
1522
+ description: "Roundness 0–100; null clears, omit leaves as-is.",
1523
+ },
1524
+ shadowIntensity: {
1525
+ type: "number",
1526
+ description: "Shadow 0–100; null clears, omit leaves as-is.",
1527
+ },
1528
+ expectedRevision: { type: "number" },
1529
+ },
1530
+ required: ["clipId"],
1531
+ },
1532
+ command: "project.set-clip-style",
1533
+ },
1480
1534
 
1481
1535
  // ── transcript-based editing ────────────────────────────────────
1482
1536
  {
@@ -1496,7 +1550,7 @@ const TOOLS = [
1496
1550
  {
1497
1551
  name: "transcript_get",
1498
1552
  description:
1499
- "Return the merged edited-time transcript: every word with id, text, startMs, endMs in EDITED-TIMELINE coordinates. Use word IDs as input to transcript_delete_words.",
1553
+ "Return the merged edited-time transcript: every word with id, text, startMs, endMs in EDITED-TIMELINE coordinates. Use word IDs as input to transcript_delete_words. For a PODCAST composite, each word also carries `speaker` ('host' = speaker 1 / mediaPath, 'guest' = speaker 2 / webcamPath) — use these spans to drive project_set_clip_layout (cut to whoever is talking).",
1500
1554
  inputSchema: {
1501
1555
  type: "object",
1502
1556
  properties: {
@@ -2250,7 +2304,7 @@ const TOOLS = [
2250
2304
  const server = new Server(
2251
2305
  {
2252
2306
  name: "pandastudio",
2253
- version: "1.56.0",
2307
+ version: "1.58.0",
2254
2308
  },
2255
2309
  {
2256
2310
  capabilities: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@writepanda/mcp",
3
- "version": "1.56.0",
3
+ "version": "1.58.0",
4
4
  "description": "Model Context Protocol server for PandaStudio. Exposes the desktop video editor's automation surface to Cursor, Continue, Cline, Claude Desktop, and any MCP-compliant client.",
5
5
  "keywords": [
6
6
  "pandastudio",