@writepanda/mcp 1.198.0 → 1.201.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 -11
  2. package/package.json +1 -1
package/bin/server.mjs CHANGED
@@ -567,13 +567,16 @@ const MOTION_ELEMENT_TYPES = [
567
567
  "iconPop",
568
568
  "frame",
569
569
  "sticker",
570
+ "ticker",
571
+ "credits",
572
+ "crawl",
570
573
  ];
571
574
  const MOTION_ELEMENT_PROPS = {
572
575
  type: { type: "string", enum: MOTION_ELEMENT_TYPES },
573
576
  content: {
574
577
  type: ["object", "string", "array"],
575
578
  description:
576
- 'keyword/chip/stamp/slam/behind/highlight { text } (or a bare string); count { value, to?, prefix?, suffix?, label?, decimals? } (value "20-30" = range); steps { items[], cues? (ms offsets from start) }; lowerThird { title, subtitle? }; endCard { lines: [a, b] }; progress { label?, fromMs?, toMs? }; iconPop { emoji } | { icon }; frame { look: viewfinder | selection | corners, label? }; sticker { image: transparent PNG path, label? }. Latin script only.',
579
+ 'keyword/chip/stamp/slam/behind/highlight { text } (or a bare string); count { value, to?, prefix?, suffix?, label?, decimals? } (value "20-30" = range); steps { items[], cues? (ms offsets from start) }; lowerThird { title, subtitle? (<=320 chars, wraps), look?: plate|plain|typewriter }; endCard { lines: [a, b] }; progress { label?, fromMs?, toMs? }; iconPop { emoji } | { icon }; frame { look: viewfinder | selection | corners, label? }; sticker { image: transparent PNG path, label? }; ticker { text (one story per line, <=2000 chars), label?, speed? (40-600 px/s) }; credits { title?, entries: [{ role?, name }] | "Role: Name" strings (<=200) }; crawl { title?, text (<=6000 chars), tilt? (0-80), turn? (-60..60) }. Any script, symbols and emoji draw.',
577
580
  },
578
581
  atMs: { type: "number", description: "Start, edited ms. Or wordId." },
579
582
  wordId: {
@@ -596,8 +599,19 @@ const MOTION_ELEMENT_PROPS = {
596
599
  highlight: { type: "string" },
597
600
  text: { type: "string" },
598
601
  font: { type: "string" },
599
- size: { type: "string", enum: ["s", "m", "l", "xl"] },
602
+ size: { type: "string", enum: ["xs", "s", "m", "l", "xl"] },
600
603
  outline: { type: "boolean" },
604
+ opacity: { type: "number", minimum: 0, maximum: 1, description: "Main text opacity." },
605
+ secondary: {
606
+ type: "object",
607
+ description:
608
+ "The smaller line (count label, lower-third subtitle, ticker label box, credits roles).",
609
+ properties: {
610
+ size: { type: "number", minimum: 0.4, maximum: 2.5, description: "1 = default." },
611
+ opacity: { type: "number", minimum: 0, maximum: 1 },
612
+ color: { type: "string" },
613
+ },
614
+ },
601
615
  },
602
616
  description: "Default: the brand kit.",
603
617
  },
@@ -2112,10 +2126,34 @@ const TOOLS = [
2112
2126
  },
2113
2127
  command: "project.remove-bleep",
2114
2128
  },
2129
+ {
2130
+ name: "project_follow_speaker",
2131
+ description:
2132
+ "Podcast recordings (each person on their own camera): cut the frame to whoever is talking from the transcript's speaker tags. podcast-solo per turn, podcast-pair (both) in quick back-and-forth, no cut for short interjections. Anchored, re-runnable; run after the cuts. One wide shot of several people: project_auto_reframe instead.",
2133
+ inputSchema: {
2134
+ type: "object",
2135
+ properties: {
2136
+ id: { type: "string" },
2137
+ path: { type: "string" },
2138
+ minTurnMs: { type: "number", description: "Shorter turns don't cut away (default 1200)." },
2139
+ pair: {
2140
+ type: "boolean",
2141
+ description: "Both people during quick exchanges (default true).",
2142
+ },
2143
+ exchangeTurnMs: {
2144
+ type: "number",
2145
+ description: "Turn length that counts as quick (default 2600).",
2146
+ },
2147
+ dryRun: { type: "boolean" },
2148
+ expectedRevision: { type: "number" },
2149
+ },
2150
+ },
2151
+ command: "project.follow-speaker",
2152
+ },
2115
2153
  {
2116
2154
  name: "project_check_broll",
2117
2155
  description:
2118
- "B-roll, the LAST step of an edit. YOU pick the moments from what's said (transcript_get; any language, any topic; ~1 per 10-15 s) and what each picture shows; this checks them: span, clashes with the steps list / end card / other pictures, spacing, a nearby suggestion when blocked, insetSide (card away from the face). No moments: free stretches. Returns imageConnector. Never makes images: show the user your moments and ASK: their own images, generate on their connector (uses credits), or none. No one to ask: skip it and say so.",
2156
+ "B-roll, the LAST step of an edit. YOU pick the moments from what's said (transcript_get; any language, any topic; in a Short ~1 per 6-8 s with the first right after the opening line, in long-form ~1 per 10-15 s) and what each picture shows; this checks them: span, clashes with the steps list / end card / other pictures, spacing, a nearby suggestion when blocked, insetSide (card away from the face). No moments: free stretches. Returns imageConnector. Never makes images: show the user your moments and ASK: their own images, generate on their connector (uses credits), or none. No one to ask: skip it and say so.",
2119
2157
  inputSchema: {
2120
2158
  type: "object",
2121
2159
  properties: {
@@ -4476,6 +4514,21 @@ const TOOLS = [
4476
4514
  },
4477
4515
  command: "recipe.list",
4478
4516
  },
4517
+ {
4518
+ name: "recipe_pick",
4519
+ description:
4520
+ "No style named ('edit my video', 'make this a Short')? The recipes that fit this project's format and footage, each with pickWhen, plus defaultId. Choose by what's said, then recipe_apply_style + recipe_render.",
4521
+ inputSchema: {
4522
+ type: "object",
4523
+ properties: {
4524
+ id: { type: "string", description: "Project id (default: the open project)." },
4525
+ path: { type: "string" },
4526
+ format: { type: "string", enum: ["short", "long"] },
4527
+ footage: { type: "string", enum: ["camera", "screen", "podcast", "none"] },
4528
+ },
4529
+ },
4530
+ command: "recipe.pick",
4531
+ },
4479
4532
  {
4480
4533
  name: "recipe_get",
4481
4534
  description: "Read one recipe in full.",
@@ -5270,22 +5323,18 @@ Start with system_status. Unknown arguments are rejected. Verbs without a tool o
5270
5323
 
5271
5324
  Before an editing pass, read the skill's "Which tool for which moment" section (skill_read section="Which tool for which moment").
5272
5325
 
5273
- "Edit my video" with no specifics = this pipeline, in order. Confirm scope once ("full polish, or just part of it?"), then run it all:
5326
+ "Edit my video" / "make this a Short" with no specifics = this pipeline, in order. Confirm scope once ("full polish, or just part of it?"), then run it all:
5274
5327
  1. transcript_transcribe clips not yet transcribed (project_read clipStates).
5275
5328
  2. transcript_remove_fillers.
5276
5329
  3. Fix misheard names / brands with transcript_find_replace (transcript_insert_words for dropped words).
5277
5330
  4. transcript_find_issues, then transcript_delete_words on each duplicate take / false start (keep the LAST take; keep severity "low" ones).
5278
5331
  5. transcript_remove_silences.
5279
5332
  6. audio_clean clips not yet cleaned.
5280
- 7. Captions (caption_toggle; template glowStack unless a recipe says otherwise), motion graphics, emphasis zooms: only after steps 2-5, which shift the timeline.
5333
+ 7. The style, after steps 2-5 (they shift the timeline). The user's named style, recipe, creator or a saved memory wins. Otherwise call recipe_pick: it returns the recipes that fit this project's format and footage, each with pickWhen, plus defaultId. Read the transcript, choose the ONE candidate whose pickWhen matches what is said (defaultId when none clearly fits), do its "before" step if any, then recipe_apply_style + recipe_render and follow the prompt: the recipe decides captions, graphics, zooms, music and transitions. (An app without recipe_pick, 2.0.5 and older: recipe_list with format short or long, and choose by description and footage.) Tell the user which recipe and why in one line and name one or two alternatives. Only when no candidate exists or the user asked for a plain clean-up: captions (caption_toggle, template glowStack), a few motion graphics, emphasis zooms.
5281
5334
  8. B-roll, last: pick the moments yourself from what's said (any language), check them with project_check_broll, show the user your moments and ASK: their own images, generated on their image connector (only if one is connected; it uses their credits), or no B-roll. Never generate or invent images without their answer. Place what they give with project_add_broll. Nobody to ask: skip it and say so.
5282
5335
  9. llm_generate_title / description / timestamps, then preview_show and ask before export_start. Never export before the user has seen the preview.
5283
- Report the real count each step returned. Never add music, intro/outro cards or FX overlays unless asked.
5284
-
5285
- Style defaults when the user names no style, recipe or creator (their choice or a saved memory wins):
5286
- - Long-form 16:9 with the speaker on camera: the Ali style recipe, id educator-talking-head-chapters (recipe_apply_style, then recipe_render and follow its prompt). It keeps burned-in captions OFF (keyword pops instead). Not for camera-less screen recordings or Loom-style internal videos.
5287
- - Shorts / Reels / TikTok (9:16): the Shorts recipe that fits: hard-truth-one-liner-short (one blunt claim), rules-listicle-cutaways-short (numbered tips), rapid-fire-list-short (many one-line items), storytime-turn-short (story with a twist), framework-explainer-short (one concept), split-screen-short-broll (showable things), social-ad-hook-variants (selling an offer), faceless-short (no footage), else warm-educator-short.
5288
- A Short from a SCREEN RECORDING first gets project_set_vertical_screen_layout, then the recipe. Say which recipe you used and why, and offer others (recipe_list).
5336
+ Report the real count each step returned. No music, intro/outro cards or FX overlays unless the recipe or the user asks for them.
5337
+ A single named operation ("just add captions", "remove the silences") is exactly that: no recipe.
5289
5338
 
5290
5339
  Destructive actions need the user's own confirmation: project_delete, workspace_delete, recipe_delete, memory_forget, export_delete, export_clear_thumbnail, youtube_disconnect, social_disconnect. Ask plainly in chat first ("Delete project 'Demo'? This can't be undone.") and call only after they agree. PandaStudio then confirms with them itself: in its own chat the call returns confirmation_required and changes nothing while a Delete / Cancel card waits (tell them to press it; don't call again; the outcome arrives as their next message); from other apps a dialog asks, and the call is refused when nobody is at the app. Nothing you send can approve it.
5291
5340
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@writepanda/mcp",
3
- "version": "1.198.0",
3
+ "version": "1.201.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",