@clipform/mcp-server 1.34.0 → 1.36.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.
- package/README.md +1 -1
- package/dist/{chunk-JID43EDM.js → chunk-2AJMWM5W.js} +67 -4
- package/dist/chunk-2AJMWM5W.js.map +1 -0
- package/dist/{chunk-JOJJ2XFL.js → chunk-6MLZZSNM.js} +61 -3
- package/dist/{chunk-JOJJ2XFL.js.map → chunk-6MLZZSNM.js.map} +1 -1
- package/dist/{chunk-KWEBCAPF.js → chunk-BYJMRIB6.js} +10 -4
- package/dist/chunk-BYJMRIB6.js.map +1 -0
- package/dist/{chunk-ZVHI2V7B.js → chunk-CN4XBVFD.js} +133 -108
- package/dist/{chunk-ZVHI2V7B.js.map → chunk-CN4XBVFD.js.map} +1 -1
- package/dist/index.js +4 -4
- package/dist/prompts.js +2 -2
- package/dist/resources.js +2 -2
- package/dist/server.js +4 -4
- package/package.json +1 -1
- package/dist/chunk-JID43EDM.js.map +0 -1
- package/dist/chunk-KWEBCAPF.js.map +0 -1
package/README.md
CHANGED
|
@@ -84,7 +84,7 @@ You can also pass the key as a CLI flag: `npx -y @clipform/mcp-server --api-key=
|
|
|
84
84
|
|
|
85
85
|
| Tool | Description |
|
|
86
86
|
|------|-------------|
|
|
87
|
-
| `clipform_render_composition` | Render a video composition to MP4 or PNG
|
|
87
|
+
| `clipform_render_composition` | Render a video composition to MP4 or PNG - flag reveals, emoji puzzles, grids, timelines, map motion and more. Pass `wait: false` to fire renders in parallel and poll for results |
|
|
88
88
|
| `clipform_generate_tts` | Generate narration audio with word-level captions |
|
|
89
89
|
| `clipform_generate_slideshow` | Create slideshow videos from images + audio (waits, returns URL) |
|
|
90
90
|
| `clipform_generate_video` | Generate video from images, clips, or both synced to audio. Pass `wait: false` to fire renders in parallel and poll for results |
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
ALL_VARIANTS,
|
|
3
3
|
FORM_TYPE_KEYS,
|
|
4
4
|
getSessionContext
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-BYJMRIB6.js";
|
|
6
6
|
|
|
7
7
|
// src/resources.ts
|
|
8
8
|
var GUIDE_TYPES = FORM_TYPE_KEYS;
|
|
@@ -58,7 +58,8 @@ var GUIDE_DESCRIPTIONS = {
|
|
|
58
58
|
};
|
|
59
59
|
var QUIZ_VARIANT_DESCRIPTIONS = {
|
|
60
60
|
"personality": "Addendum for personality quizzes - category design, option weighting, outcome writing, no right/wrong answers",
|
|
61
|
-
"comprehension": "Addendum for YouTube comprehension quizzes - extracting questions from transcripts, distractor design, audience adaptation"
|
|
61
|
+
"comprehension": "Addendum for YouTube comprehension quizzes - extracting questions from transcripts, distractor design, audience adaptation",
|
|
62
|
+
"composition": "Addendum for composition quizzes - guess-and-reveal formats built from rendered compositions: mechanic selection, the clue/reveal node pair, difficulty design"
|
|
62
63
|
};
|
|
63
64
|
var GUIDE_CONTENT = {
|
|
64
65
|
"quiz": `# Quiz Writing Guide
|
|
@@ -119,6 +120,14 @@ Inspired by the Color Brain board game - every answer is identified by its colou
|
|
|
119
120
|
- show_step_counter: true
|
|
120
121
|
- disable_back_navigation: true (prevent going back to change answers after seeing feedback)
|
|
121
122
|
|
|
123
|
+
## End Screen Copy
|
|
124
|
+
|
|
125
|
+
The end screen is the payoff - it must reward the respondent and drive sharing and retakes.
|
|
126
|
+
|
|
127
|
+
- Title and message in the quiz's voice: short, punchy, specific to the topic. Never generic "Good job!"
|
|
128
|
+
- When per-tier messages ship (score_ranges), each tier should feel like a character, not a grade - "Lost Tourist" beats "Low Score"
|
|
129
|
+
- Always pair the retake CTA ("Beat your score?") with the share button - "I got X, what did you get?" is the viral loop
|
|
130
|
+
|
|
122
131
|
## Narration Style
|
|
123
132
|
|
|
124
133
|
You're a quiz master, not a question reader. Each question's narration should:
|
|
@@ -453,7 +462,61 @@ Reference the video naturally but don't spoil:
|
|
|
453
462
|
|
|
454
463
|
- "If you were paying attention during the bit about..."
|
|
455
464
|
- "This is one of those details most people miss..."
|
|
456
|
-
- "The presenter made a really specific claim here..."
|
|
465
|
+
- "The presenter made a really specific claim here..."`,
|
|
466
|
+
"composition": `---
|
|
467
|
+
|
|
468
|
+
# Composition Quiz Addendum
|
|
469
|
+
|
|
470
|
+
> The following sections supplement the base quiz guide above. A composition quiz replaces stock-image slideshows with RENDERED compositions: the clue is a designed visual (a flag sweeping in, an emoji rebus, a blurred photo resolving) and the answer gets its own reveal clip. Scoring and settings match the base quiz - only the media pipeline differs.
|
|
471
|
+
|
|
472
|
+
## The Clue \u2192 Reveal Node Pair
|
|
473
|
+
|
|
474
|
+
Every composition question is a PAIR of nodes:
|
|
475
|
+
|
|
476
|
+
1. **Clue node** (type "choice"): the rendered clue clip is the node's background media, the question text is the prompt, options are text answers (score 1 correct / 0 wrong as usual).
|
|
477
|
+
2. **Reveal node** (type "button"): the answer lives in the prompt ("It was Japan!"), the rendered reveal clip plays behind it, button_text is a short beat like "Next one". The reveal is the payoff - never skip it.
|
|
478
|
+
|
|
479
|
+
Rules:
|
|
480
|
+
- Compositions are plain visuals. The clue clip must NOT contain the question text, options, or any UI - the viewer renders prompt, options, and captions on top.
|
|
481
|
+
- **Clue-based formats deliberately let the media BE the hint** (emoji rebus, flag, colour chips, silhouette). That is the mechanic, not an answer leak - the base guide's "media must not reveal the answer" rule applies to incidental media, not to the clue itself.
|
|
482
|
+
- Many compositions have chain states: render the clue clip with animate: true and the reveal clip with animate: false plus the answer props, so the pair feels like one continuous scene.
|
|
483
|
+
- A composition quiz of N questions uses about 2N+1 nodes. Check the plan's node limit first - 5-6 questions is the sweet spot.
|
|
484
|
+
|
|
485
|
+
## Picking a Mechanic
|
|
486
|
+
|
|
487
|
+
Composition availability varies by session: call clipform_list_compositions FIRST and choose only from what it returns (each entry carries its props schema). If no listed composition fits a question, fall back to the base guide's Ken Burns pipeline for that question - mixing treatments within one quiz is fine and keeps pacing fresh.
|
|
488
|
+
|
|
489
|
+
| Mechanic | The question feels like | Composition family |
|
|
490
|
+
|---|---|---|
|
|
491
|
+
| Guess the flag | a flag sweeps onto the screen | FlagReveal* |
|
|
492
|
+
| What has these colours? | flat colour chips, name the subject | ColorCards (pair with a reveal clip) |
|
|
493
|
+
| Guess the country | an outline draws itself | CountrySilhouetteClip |
|
|
494
|
+
| Emoji puzzle | emoji rebus \u2192 movie/phrase/place | EmojiPuzzle |
|
|
495
|
+
| Guess before it resolves | blurred / pixelated / extreme close-up sharpens | ObscuredReveal |
|
|
496
|
+
| Odd one out / what connects | grid of images or statements | Grid, GridList |
|
|
497
|
+
| Order the events | timeline entries reveal in sequence | Timeline |
|
|
498
|
+
| Number guess / higher-lower | a marker sweeps a scale to the answer | NumberLine |
|
|
499
|
+
| Where is it? | map or globe motion toward the place | MapPin, GlobeToCity, CityToGlobe |
|
|
500
|
+
| What changed? | before/after slide | BeforeAfter |
|
|
501
|
+
| Missing words | headline or quote with blanked tokens | TextReveal |
|
|
502
|
+
|
|
503
|
+
Principles, not recipes:
|
|
504
|
+
- One mechanic per question; 2-3 mechanics per quiz. Repeating one mechanic 6 times reads as a template, not a craft choice.
|
|
505
|
+
- The grid mechanics fake "tap the image" with positional labels (A/B/C/D chips on cells matching the text options) - image-as-options is not yet supported.
|
|
506
|
+
- Urgency dressing (CountdownRing) changes feel, not function - there is no real timed auto-advance yet.
|
|
507
|
+
|
|
508
|
+
## Difficulty Design
|
|
509
|
+
|
|
510
|
+
Difficulty comes from **subject obscurity, not clue degradation**. An easy flag question is Japan; a hard one is Kiribati - both get the same crisp reveal. Follow the base guide's difficulty curve with mechanic-aware ordering: open with the most readable mechanic (flags, emoji), put high-cognition mechanics (order-the-events, what-connects) in the middle, end on a satisfying reveal (ObscuredReveal or BeforeAfter land well as closers).
|
|
511
|
+
|
|
512
|
+
## Composition Narration Style
|
|
513
|
+
|
|
514
|
+
The visual does the teasing, so narration frames rather than describes:
|
|
515
|
+
|
|
516
|
+
- DO set the stakes: "Only 8% of people get this one..."
|
|
517
|
+
- DO NOT describe what is on screen ("here you can see four pictures...") - they can see it
|
|
518
|
+
- DO NOT read the emoji, colours, or grid cells aloud - decoding them IS the game
|
|
519
|
+
- Reveal narration can celebrate: "Of course - it was Brazil all along."`
|
|
457
520
|
};
|
|
458
521
|
function getGuideContent(type, variant) {
|
|
459
522
|
const base = GUIDE_CONTENT[type];
|
|
@@ -535,4 +598,4 @@ export {
|
|
|
535
598
|
getGuideUri,
|
|
536
599
|
registerResources
|
|
537
600
|
};
|
|
538
|
-
//# sourceMappingURL=chunk-
|
|
601
|
+
//# sourceMappingURL=chunk-2AJMWM5W.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/resources.ts"],"sourcesContent":["import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { getSessionContext } from \"./lib/session-context.js\";\nimport { FORM_TYPE_KEYS, FORM_TYPES, ALL_VARIANTS } from \"@vid-master/config\";\n\nexport const GUIDE_TYPES = FORM_TYPE_KEYS as readonly string[] as readonly [string, ...string[]];\nexport type GuideType = (typeof FORM_TYPE_KEYS)[number];\n\nexport const QUIZ_VARIANTS = ALL_VARIANTS as readonly string[] as readonly [string, ...string[]];\nexport type QuizVariant = (typeof ALL_VARIANTS)[number];\n\nconst WRITING_PRINCIPLES = `## Writing Principles\n\n- **Write for the ear.** Narration is spoken aloud. Short sentences. Natural rhythm.\n- **Research before writing.** Find 2-3 genuinely interesting facts per topic. Generic content doesn't hold attention.\n- **Conversational, not encyclopaedic.** \"Here's what's wild about this...\" not \"The subject is characterized by...\"\n- **Cut ruthlessly.** Every word must earn its place.\n- **Never reveal answers in narration.** The user picks from options - narration teases and builds intrigue.\n- **Don't read answer options aloud.** The viewer can see them on screen.\n\n## Narration Tips\n\n- Tease the topic, don't summarise it\n- Give one interesting fact that makes the user curious\n- 5-15 seconds per question narration\n- If TTS comes back too long, trim the copy and regenerate\n\n## Research\n\nSearch for the specific subject, not generic terms (\"komodo dragon habitat\" not \"reptile\"). Cross-reference facts - quiz answers must be correct. Look for the surprising angle: what would make someone say \"wait, really?\"\n\nFor timeless topics (history, geography, science), write from your own knowledge. For anything recent or uncertain, use web search or clipform_search_news. If neither is available, refuse rather than fabricate.`;\n\nconst MEDIA_WORKFLOW = `## Media Workflow\n\n1. **clipform_generate_tts** - narration audio (returns word-level captions) - batch ALL items in one call\n2. **clipform_search_media** (kind: \"image\") - find 3 images per question - batch ALL queries in one call\n3. **clipform_generate_video** - Ken Burns video from images + audio. Rendering more than one video? Pass wait: false on EVERY call (each returns a job ID immediately, renders run in parallel), then collect URLs with clipform_check_render.\n4. **clipform_upload_node_media** - attach video with captions (set show_captions: true) - batch all uploads in one call\n\n**Image selection:**\n- ONLY use URLs from clipform_search_media results\n- ALL returned images are pre-cleared for commercial use - pick by visual quality, not by provider or license\n- **Question media must not accidentally reveal the answer.** Unless the media IS the clue (emoji quiz, guess-the-flag - then choose it deliberately for difficulty), search the question's category or scene-setting context, not the answer. Answer-specific media belongs on the reveal. Test: could someone who knows nothing pick the right option just from the media?\n- For non-question media (intros, reveals, surveys), search the specific subject, not generic terms\n- Pick visually distinct images (different angles, colors, subjects) - use each result's description/alt text to judge\n- Portrait images fill the 9:16 frame best and results come portrait-first by default; landscape images get automatic blur-pad framing. Request orientation: \"landscape\" only when you specifically want wide shots.\n\n**Slideshow defaults:**\n- 3 images per question, random_effects: true\n- transition: { type: \"fade\", duration: 1 }\n- Auto focal point detection, eased motion, and cinematic vignette are built in`;\n\nconst GUIDE_DESCRIPTIONS: Record<GuideType, string> = {\n \"quiz\": \"Craft knowledge for writing engaging quizzes - difficulty curves, question psychology, narration style, scoring\",\n \"survey\": \"Craft knowledge for feedback surveys, NPS, and research forms - brevity, rating scales, respondent fatigue\",\n \"interview\": \"Craft knowledge for building interview forms - warm-up pacing, open questions, consent, video responses\",\n \"funnel\": \"Craft knowledge for lead qualification funnels - planned feature, conditional routing coming soon\",\n \"testimonial\": \"Craft knowledge for collecting testimonials and customer stories on video - storytelling prompts, comfort techniques, consent\",\n \"application\": \"Craft knowledge for application and evaluation forms - multi-section structure, video responses for behavioural questions, screening\",\n \"booking\": \"Craft knowledge for event registration and booking forms - minimal friction, video welcome, confirmation flow\",\n};\n\nconst QUIZ_VARIANT_DESCRIPTIONS: Record<QuizVariant, string> = {\n \"personality\": \"Addendum for personality quizzes - category design, option weighting, outcome writing, no right/wrong answers\",\n \"comprehension\": \"Addendum for YouTube comprehension quizzes - extracting questions from transcripts, distractor design, audience adaptation\",\n \"composition\": \"Addendum for composition quizzes - guess-and-reveal formats built from rendered compositions: mechanic selection, the clue/reveal node pair, difficulty design\",\n};\n\nconst GUIDE_CONTENT: Record<GuideType, string> = {\n \"quiz\": `# Quiz Writing Guide\n\n## Psychology\n\nEach question is a micro variable-reward event - the same dopamine loop that keeps people watching. Once someone answers 2-3 questions, sunk cost kicks in and they finish. Viewers mentally compete, then want to compare scores.\n\n**Target 50-60% correct.** Too easy = no challenge. Too hard = people feel stupid and won't share.\n\n## Difficulty Curve\n\n| Position | Difficulty | Purpose |\n|----------|-----------|---------|\n| Q1-Q2 | Easy (80%+ get right) | Build confidence and commitment |\n| Q3-Q5 | Medium | Peak engagement |\n| Q6-Q8 | Hard (include one \"gotcha\") | The \"everyone gets this wrong\" moment |\n| Q9-Q10 | One hard, one satisfying medium | End on a smart feeling, not defeat |\n\n## Question Design\n\n- **No guessable answer pattern** - set randomise_options: true and the viewer shuffles options at render time. Do NOT hand-vary correct answer positions; it has no effect once options shuffle.\n- **Myth-busters**: \"Sushi means raw fish - True or False?\" (False - it means seasoned rice)\n- **Sounds fake but true**: counterintuitive correct answers make people rewatch\n- **Common misconceptions**: \"Capital of Australia?\" (not Sydney - Canberra)\n- Under 12-15 words per question for mobile readability\n- Trigger gut reactions, not deep thinking\n\n## Wrong Answer Generation\n\nFor numeric questions (population, speed, weight), scale the real answer by random multipliers (0.3x to 3x) rounded to the same magnitude. Makes wrong answers plausible but clearly different.\n\n## Color Brain Questions (ColorCards composition)\n\nInspired by the Color Brain board game - every answer is identified by its colours. Show flat colour chips, ask \"what has these colours?\". Use the \\`ColorCards\\` composition for the question card.\n\n**Colour palette constraint:** Swatches are solid flat chips. Only use clearly distinguishable basic colours: red, blue, green, yellow, white, black, orange, purple, pink, brown, grey. No navy vs blue, no teal vs cyan - they look the same as flat chips. The skill is picking subjects where a combo of basic colours is unique enough to identify.\n\n**Question categories:**\n- Flags: \"Which country's flag has these colours?\" (pair with FlagReveal for answer)\n- Brand logos: red + yellow = McDonald's, red + white = Coca-Cola\n- Sports teams: red + white = Arsenal, red + blue + white = Barcelona\n- Superheroes/characters: red + blue = Spider-Man, yellow + black = Batman\n- Food: red + green = watermelon, yellow + brown = banana\n\n**Difficulty scaling:**\n- Easy: iconic subjects with unique colour combos (Japan flag: red + white)\n- Medium: common subjects but colours shared with others (Italy vs Ireland: both green + white + one more)\n- Hard: obscure subjects or very common colour combos that fit many answers\n\n**Design rules:**\n- 2-4 colours per question works best. 5+ gets messy and hard to distinguish.\n- If two answer options would produce identical swatches, don't use that question.\n- Pair with a reveal composition (FlagReveal, image, or text) for the answer.\n\n## Settings\n\n- show_step_counter: true\n- disable_back_navigation: true (prevent going back to change answers after seeing feedback)\n\n## End Screen Copy\n\nThe end screen is the payoff - it must reward the respondent and drive sharing and retakes.\n\n- Title and message in the quiz's voice: short, punchy, specific to the topic. Never generic \"Good job!\"\n- When per-tier messages ship (score_ranges), each tier should feel like a character, not a grade - \"Lost Tourist\" beats \"Low Score\"\n- Always pair the retake CTA (\"Beat your score?\") with the share button - \"I got X, what did you get?\" is the viral loop\n\n## Narration Style\n\nYou're a quiz master, not a question reader. Each question's narration should:\n\n1. **Tease** - set the scene, build intrigue (\"This one catches everyone out\")\n2. **Give context** - one interesting fact that makes the question richer\n3. **Pose the question** - \"So here's the question...\"\n\n**Don't say:**\n- \"You either know it or you don't\" (meaningless filler)\n- \"This is a really hard one\" on every question (loses impact)\n- \"Welcome to my quiz\" / \"Hey guys\" (wastes time, skip to Q1)\n\n${WRITING_PRINCIPLES}\n\n${MEDIA_WORKFLOW}`,\n\n \"survey\": `# Survey & Feedback Guide\n\n## Purpose\n\nCollect structured feedback - NPS, customer satisfaction, product research, post-event feedback. The goal is clean, analysable data with minimal respondent fatigue.\n\n## Structure\n\nSurveys should be ruthlessly short. Every extra question costs you completions.\n\n1. **Key metric** - the one number you care about (NPS, satisfaction rating, likelihood to recommend). Put it first while attention is highest.\n2. **Follow-up** - one open-ended \"why?\" question. \"What's the main reason for your score?\" This is where the insight lives.\n3. **Specific questions** (optional) - 2-3 targeted choice questions on specific areas. Don't fish - only ask what you'll act on.\n4. **Contact** (optional) - only if you need to follow up. Many surveys are better anonymous.\n5. **End screen** - \"Thanks for your feedback!\" Keep it simple.\n\n## Question Design\n\n- **Choice questions for data, open questions for insight.** Don't use open-ended where a rating scale would do, and don't use ratings where you need to understand why.\n- **Balanced scales.** Equal positive and negative options. \"Excellent / Good / Fair / Poor\" not \"Amazing / Great / Good / OK / Bad.\"\n- **No leading questions.** \"How much did you enjoy...?\" assumes they enjoyed it.\n- **5 questions max.** If you need more, you're running research, not a survey - split it up.\n\n## Narration for Surveys\n\nOptional - many surveys work fine as text only. If using narration:\n\n- Keep it brief (5-8 seconds). \"We'd love your quick feedback on...\"\n- Don't narrate every question - just the opener to set the tone\n- Friendly but efficient. Respect their time.\n\n## Settings\n\n- disable_back_navigation: false\n- show_step_counter: true (shows progress, reduces abandonment)\n\n${WRITING_PRINCIPLES}`,\n\n \"interview\": `# Interview Guide\n\n## Purpose\n\nCollect responses through structured conversations - journalist callouts, async video interviews, expert input, case study interviews. You're guiding someone through questions, with their answers as structured data or video responses.\n\n## Structure\n\n1. **Warm-up question** - something easy and low-stakes to get them comfortable. \"Tell us your name and what you do\" or \"What's your role?\"\n2. **Core questions** - the real ask. Open-ended, one topic per question. Don't over-split - 2-3 core questions max.\n3. **Follow-up** (optional) - \"Anything else you'd like to add?\" catches things you didn't think to ask.\n4. **Contact collection** - first name + email minimum. Add phone/company if relevant.\n5. **Consent** - \"I agree that my response may be used in [context].\" Always include for media use.\n6. **End screen** - set expectations: \"Thanks! We'll be in touch if we'd like to take things further.\"\n\n## Question Design\n\n- **Open-ended by default.** Use \"open\" type with text + audio + video response enabled. Let the respondent choose their format.\n- **One topic per question.** \"Tell us about your experience AND what you'd change\" is two questions.\n- **Prompt, don't interrogate.** \"What surprised you most about working with us?\" beats \"Rate your satisfaction.\"\n- **Keep it short.** 3-5 questions total. Every extra question loses respondents.\n\n## Narration for Interviews\n\nWarmer and more personal than quiz narration. You're inviting someone to share, not testing them.\n\n- \"We'd love to hear your perspective...\"\n- \"Take your time with this one - there's no wrong answer\"\n- Keep narration under 10 seconds - the respondent's answer is the content, not yours\n\n## Settings\n\n- disable_back_navigation: false (let people review their answers)\n- show_step_counter: true (so they know how much is left)\n\n${WRITING_PRINCIPLES}\n\n${MEDIA_WORKFLOW}`,\n\n \"funnel\": `# Lead Qualification Funnel - Coming Soon\n\nFunnel capabilities with conditional routing and branching logic are planned but not yet available. This guide will be expanded when the branching feature launches.\n\nIn the meantime, you can build a simple linear qualification form using the survey or quiz workflows.`,\n\n \"testimonial\": `# Testimonial & Story Collection Guide\n\n## Purpose\n\nCapture authentic stories from customers, users, or participants on camera. The respondent's video IS the deliverable - you're producing content, not collecting data. The questions are storytelling prompts designed to elicit a compelling narrative arc.\n\n## Storytelling Arc\n\nThe best testimonials follow a three-part structure. Each prompt maps to one part:\n\n1. **Before** - \"What was your situation before?\" (establishes the problem)\n2. **During** - \"What was the experience like?\" (the journey)\n3. **After** - \"What's different now?\" (the transformation/result)\n\nThis gives you a complete story you can edit into marketing content.\n\n## Prompt Design\n\n- **Open-ended, video-first.** Every core question should be type \"open\" with video response enabled.\n- **One idea per prompt.** \"Tell us about your experience and what you'd recommend\" is two prompts.\n- **Warm and specific.** \"What surprised you most about working with us?\" beats \"Tell us about your experience.\"\n- **3-5 prompts max.** Fewer = higher completion. The best testimonials come from 3 focused questions.\n- **Don't ask for ratings.** This isn't a survey. You want stories, not numbers.\n\n## Making Respondents Comfortable\n\n- Start with something easy: name, role, how long they've been a customer\n- Narration should feel like a friendly conversation, not a formal interview\n- \"Take your time - there's no rush and no wrong answer\"\n- Keep narration under 8 seconds per prompt - the respondent's answer is the content\n\n## Consent\n\nAlways include a consent node for testimonials. The response will be used in marketing, on your website, or in sales materials. Be explicit about where it may appear.\n\n## Settings\n\n- disable_back_navigation: false (let people re-record if they weren't happy)\n- show_step_counter: true (shows progress, reduces surprise)\n\n## Narration Style\n\nWarm, appreciative, and encouraging:\n- \"We'd love to hear your story...\"\n- \"What you share will help others just like you\"\n- \"There's no script - just speak from the heart\"\n\nDo NOT say \"this will only take a minute\" (it won't) or \"just a quick video\" (undermines the ask).\n\n${WRITING_PRINCIPLES}\n\n${MEDIA_WORKFLOW}`,\n\n \"application\": `# Application & Evaluation Guide\n\n## Purpose\n\nCollect structured applications - job applications, programme admissions, grant proposals, course enrolments. Applications mix structured data (contact, qualifications) with open-ended responses (motivation, experience). Video responses reveal personality and communication skills that text can't capture.\n\n## Structure\n\nApplications have a natural multi-section flow:\n\n1. **Identity** - name, email, phone. Get this first while motivation is highest.\n2. **Qualifications** - role-specific structured questions (experience level, skills, availability). Choice or short text.\n3. **Open responses** - \"Tell us about a time when...\" or \"Why are you interested?\" Video encouraged for behavioural questions.\n4. **Supporting material** (optional) - \"Anything else you'd like to share?\"\n5. **Confirmation** - clear next steps. \"We'll review your application and get back to you within X days.\"\n\n## Question Design\n\n- **Structured for screening, open for depth.** Use choice questions to filter (experience level, availability), open questions to understand (motivation, fit).\n- **Video for behavioural questions.** \"Walk us through how you'd approach...\" is far more revealing on video than in text.\n- **One question per screen.** Applications feel long - keep each step focused.\n- **8-10 questions max.** Even for detailed applications. Every extra question increases abandonment.\n- **Don't duplicate the CV.** Ask for what a resume doesn't show: motivation, culture fit, communication style.\n\n## Narration for Applications\n\nProfessional and welcoming. You're the organisation's first impression.\n\n- \"Thanks for your interest - let's get to know you\"\n- \"Take your time with this one\"\n- Keep narration factual and brief - applicants want to know what's expected, not be entertained\n\n## Settings\n\n- disable_back_navigation: false (applicants need to review and revise)\n- show_step_counter: true (essential - applicants need to know how much is left)\n\n${WRITING_PRINCIPLES}\n\n${MEDIA_WORKFLOW}`,\n\n \"booking\": `# Booking & Registration Guide\n\n## Purpose\n\nEvent registration, course signup, workshop booking, consultation scheduling. The goal is minimal friction to confirmed attendance. Video makes registrations feel personal - a welcome video from the host builds anticipation and reduces no-shows.\n\n## Structure\n\nRegistrations should be fast. Every field you add costs completions.\n\n1. **Welcome** - a short video or narrated intro that sells the event and sets expectations. This is where video adds the most value.\n2. **Essential info** - name, email. Absolute minimum.\n3. **Event-specific details** (if needed) - dietary requirements, session preferences, t-shirt size. Only ask what you'll actually use.\n4. **Confirmation** - \"You're registered! Here's what to expect.\" Include date, time, location/link.\n\n## Question Design\n\n- **3-5 fields maximum.** Name + email + 1-3 event-specific fields. That's it.\n- **Choice questions over open-ended.** \"Which session interests you most?\" not \"What are you hoping to learn?\" You need structured data for logistics.\n- **Contact is mandatory.** This isn't anonymous - you need to confirm their spot.\n- **Don't over-collect.** Phone number, company, job title - only if you genuinely need them for the event.\n\n## Video Welcome\n\nThe registration's killer feature. A 15-30 second video from the host:\n- Who you are and what the event is about\n- What attendees will get out of it\n- Why you're excited about it\n\nThis turns a boring form into a personal invitation. Completion rates go up when people feel welcomed.\n\n## Narration Style\n\nEnthusiastic but efficient. Respect their time.\n- \"We're excited to have you!\"\n- \"Just a few quick details and you're in\"\n- Keep total narration under 20 seconds across the whole form (excluding the welcome video)\n\n## Settings\n\n- disable_back_navigation: false\n- show_step_counter: false (it's so short, a counter adds unnecessary UI)\n\n${WRITING_PRINCIPLES}`,\n};\n\nconst QUIZ_VARIANT_ADDONS: Record<QuizVariant, string> = {\n \"personality\": `---\n\n# Personality Quiz Addendum\n\n> The following sections supplement the base quiz guide above. For personality quizzes, scoring works differently (categories, not right/wrong) and there is no answer feedback. Where guidance below conflicts with the base (e.g., narration style), follow the personality-specific version.\n\n## How Personality Quizzes Work\n\nPersonality quizzes have NO correct answers. Each option should feel equally valid and appealing. The experience is about self-expression and fun, not testing knowledge. Always set show_answer_feedback: false.\n\n**NOTE:** Full category-based scoring (where each option maps to outcome categories via the \\`scores\\` field and the winning category determines a personalised result screen) is coming soon. For now, design personality quizzes as engaging choice-based forms with a single end screen. The questions themselves are the experience.\n\n## Category Design (Conceptual)\n\nEven without automated scoring, design your questions around 3-5 outcome categories:\n\n- **3-5 categories** is the sweet spot. Fewer feels too binary, more feels random.\n- Categories should be **distinct but equally appealing**. Nobody wants to get the \"bad\" result.\n- Name them after the outcome, not the trait: \"Explorer\" not \"Adventurous\", \"The Architect\" not \"Organised\".\n- Use categories to guide question and option design, even though automated scoring is not yet available.\n\n## Personality Question Design\n\n- Questions should feel **personally revealing** but low-stakes: \"Pick your ideal Saturday morning\" not \"What's your biggest weakness?\"\n- Scenario-based questions work better than abstract preference questions\n- Each question should meaningfully differentiate between categories\n- Avoid questions where all options clearly map to one obvious personality\n\n## End Screen\n\nWrite a single end screen that feels personal and shareable:\n\n- **Title**: Something warm and inviting, like \"Thanks for playing!\" or \"That was fun!\"\n- **Message**: Encourage sharing - \"Compare your answers with friends!\" Personality quizzes are inherently social.\n- show_score: false (there is no score to show)\n- show_share_button: true (personality results are inherently shareable)\n- NOTE: Automated result screens per category (scoring_results) are coming soon.\n\n## Personality Narration Style\n\nReflective and curious, not quizmaster-y:\n- \"This one says a lot about you...\"\n- \"There's no wrong answer here - go with your gut\"\n- \"What does your choice reveal?\"\n\nDo NOT say \"let's see if you get this right\" - there is no right answer.`,\n\n \"comprehension\": `---\n\n# Comprehension Quiz Addendum\n\n> The following sections supplement the base quiz guide above. Comprehension quizzes test whether someone watched a specific piece of content, not general knowledge. Scoring and settings match the base quiz, but question sourcing and distractor design are completely different.\n\n## How Comprehension Differs from Trivia\n\nA trivia quiz tests general knowledge. A comprehension quiz tests whether someone watched a specific piece of content. The questions should be **unfair to non-watchers and fair to watchers**.\n\n| | Trivia Quiz | Comprehension Quiz |\n|---|---|---|\n| Source | Research + your knowledge | The video transcript |\n| Questions | General facts | Specific claims from the video |\n| Wrong answers | Common misconceptions | Things you'd guess without watching |\n| Goal | Entertainment + learning | Proof of watching + retention |\n\n## Extracting Questions from Transcripts\n\nRead the transcript looking for:\n\n1. **Specific numbers or data** - \"The presenter says it takes X days to...\" (detail recall)\n2. **Causal claims** - \"According to the video, this happens because...\" (comprehension)\n3. **Examples used** - \"What example does the presenter use to explain...?\" (attention)\n4. **Sequence of topics** - \"What does the presenter discuss right after...?\" (structure following)\n5. **The main argument** - \"What is the presenter's main point about...?\" (thesis comprehension)\n6. **Counterintuitive points** - anything the presenter says is surprising or commonly misunderstood\n\n## Distractor Design (Wrong Answers)\n\nMake wrong answers plausible to someone who **didn't watch**:\n\n- Use correct facts from other sources about the same topic (tests whether they watched THIS video)\n- Include things that sound likely based on the title alone\n- For number questions, use nearby values that seem reasonable\n- Never include obviously joke answers - every option should feel possible\n\n## Audience Adaptation\n\n| Audience | Question style | Language | Count |\n|----------|---------------|----------|-------|\n| Young children (5-8) | Concrete details, visual moments | Simple, short sentences | 4-6 |\n| Older children (9-12) | Details + basic inference | Clear, direct | 6-8 |\n| Teens (13-17) | Inference + sequence + argument | Natural, conversational | 6-10 |\n| Adults | Full range including critical analysis | Match the video's register | 6-10 |\n\nFor young children: focus on \"What did you SEE?\" and \"Who did what?\" rather than abstract arguments.\n\n## Comprehension Narration Style\n\nReference the video naturally but don't spoil:\n\n- \"If you were paying attention during the bit about...\"\n- \"This is one of those details most people miss...\"\n- \"The presenter made a really specific claim here...\"`,\n\n \"composition\": `---\n\n# Composition Quiz Addendum\n\n> The following sections supplement the base quiz guide above. A composition quiz replaces stock-image slideshows with RENDERED compositions: the clue is a designed visual (a flag sweeping in, an emoji rebus, a blurred photo resolving) and the answer gets its own reveal clip. Scoring and settings match the base quiz - only the media pipeline differs.\n\n## The Clue → Reveal Node Pair\n\nEvery composition question is a PAIR of nodes:\n\n1. **Clue node** (type \"choice\"): the rendered clue clip is the node's background media, the question text is the prompt, options are text answers (score 1 correct / 0 wrong as usual).\n2. **Reveal node** (type \"button\"): the answer lives in the prompt (\"It was Japan!\"), the rendered reveal clip plays behind it, button_text is a short beat like \"Next one\". The reveal is the payoff - never skip it.\n\nRules:\n- Compositions are plain visuals. The clue clip must NOT contain the question text, options, or any UI - the viewer renders prompt, options, and captions on top.\n- **Clue-based formats deliberately let the media BE the hint** (emoji rebus, flag, colour chips, silhouette). That is the mechanic, not an answer leak - the base guide's \"media must not reveal the answer\" rule applies to incidental media, not to the clue itself.\n- Many compositions have chain states: render the clue clip with animate: true and the reveal clip with animate: false plus the answer props, so the pair feels like one continuous scene.\n- A composition quiz of N questions uses about 2N+1 nodes. Check the plan's node limit first - 5-6 questions is the sweet spot.\n\n## Picking a Mechanic\n\nComposition availability varies by session: call clipform_list_compositions FIRST and choose only from what it returns (each entry carries its props schema). If no listed composition fits a question, fall back to the base guide's Ken Burns pipeline for that question - mixing treatments within one quiz is fine and keeps pacing fresh.\n\n| Mechanic | The question feels like | Composition family |\n|---|---|---|\n| Guess the flag | a flag sweeps onto the screen | FlagReveal* |\n| What has these colours? | flat colour chips, name the subject | ColorCards (pair with a reveal clip) |\n| Guess the country | an outline draws itself | CountrySilhouetteClip |\n| Emoji puzzle | emoji rebus → movie/phrase/place | EmojiPuzzle |\n| Guess before it resolves | blurred / pixelated / extreme close-up sharpens | ObscuredReveal |\n| Odd one out / what connects | grid of images or statements | Grid, GridList |\n| Order the events | timeline entries reveal in sequence | Timeline |\n| Number guess / higher-lower | a marker sweeps a scale to the answer | NumberLine |\n| Where is it? | map or globe motion toward the place | MapPin, GlobeToCity, CityToGlobe |\n| What changed? | before/after slide | BeforeAfter |\n| Missing words | headline or quote with blanked tokens | TextReveal |\n\nPrinciples, not recipes:\n- One mechanic per question; 2-3 mechanics per quiz. Repeating one mechanic 6 times reads as a template, not a craft choice.\n- The grid mechanics fake \"tap the image\" with positional labels (A/B/C/D chips on cells matching the text options) - image-as-options is not yet supported.\n- Urgency dressing (CountdownRing) changes feel, not function - there is no real timed auto-advance yet.\n\n## Difficulty Design\n\nDifficulty comes from **subject obscurity, not clue degradation**. An easy flag question is Japan; a hard one is Kiribati - both get the same crisp reveal. Follow the base guide's difficulty curve with mechanic-aware ordering: open with the most readable mechanic (flags, emoji), put high-cognition mechanics (order-the-events, what-connects) in the middle, end on a satisfying reveal (ObscuredReveal or BeforeAfter land well as closers).\n\n## Composition Narration Style\n\nThe visual does the teasing, so narration frames rather than describes:\n\n- DO set the stakes: \"Only 8% of people get this one...\"\n- DO NOT describe what is on screen (\"here you can see four pictures...\") - they can see it\n- DO NOT read the emoji, colours, or grid cells aloud - decoding them IS the game\n- Reveal narration can celebrate: \"Of course - it was Brazil all along.\"`,\n};\n\nexport function getGuideContent(type: GuideType, variant?: QuizVariant): string {\n const base = GUIDE_CONTENT[type];\n if (type === \"quiz\" && variant) {\n return base + \"\\n\\n\" + QUIZ_VARIANT_ADDONS[variant];\n }\n return base;\n}\n\nexport function getGuideUri(type: GuideType, variant?: QuizVariant): string {\n if (type === \"quiz\" && variant) {\n return `clipform://guides/quiz/${variant}`;\n }\n return `clipform://guides/${type}`;\n}\n\nexport function registerResources(server: McpServer) {\n for (const type of GUIDE_TYPES) {\n server.registerResource(\n `guide-${type}`,\n getGuideUri(type),\n {\n description: GUIDE_DESCRIPTIONS[type],\n mimeType: \"text/markdown\",\n annotations: { audience: [\"assistant\" as const], priority: 0.8 },\n },\n async () => ({\n contents: [{\n uri: getGuideUri(type),\n mimeType: \"text/markdown\",\n text: getGuideContent(type),\n }],\n }),\n );\n }\n\n for (const variant of QUIZ_VARIANTS) {\n server.registerResource(\n `guide-quiz-${variant}`,\n getGuideUri(\"quiz\", variant),\n {\n description: QUIZ_VARIANT_DESCRIPTIONS[variant],\n mimeType: \"text/markdown\",\n annotations: { audience: [\"assistant\" as const], priority: 0.8 },\n },\n async () => ({\n contents: [{\n uri: getGuideUri(\"quiz\", variant),\n mimeType: \"text/markdown\",\n text: getGuideContent(\"quiz\", variant),\n }],\n }),\n );\n }\n\n server.registerResource(\n \"context-session\",\n \"clipform://context/session\",\n {\n description:\n \"Current session info: auth mode, workspace, plan tier, node limits, feature flags. Read this before planning content to know your constraints.\",\n mimeType: \"text/markdown\",\n annotations: { audience: [\"assistant\"], priority: 1.0 },\n },\n async () => {\n const text = await getSessionContext();\n return {\n contents: [\n {\n uri: \"clipform://context/session\",\n mimeType: \"text/markdown\",\n text: text || \"Session context unavailable - API may not be reachable.\",\n },\n ],\n };\n }\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
WORKFLOW_TYPES,
|
|
3
3
|
getDiscoveryParams,
|
|
4
4
|
getSessionContextWithAuth
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-BYJMRIB6.js";
|
|
6
6
|
import {
|
|
7
7
|
__export
|
|
8
8
|
} from "./chunk-HCZI2UJ5.js";
|
|
@@ -4212,6 +4212,29 @@ Wrong answers should sound right to someone who didn't watch but googled the top
|
|
|
4212
4212
|
|
|
4213
4213
|
> **Text-only override:** If the user explicitly asked for text-only (no video), skip steps 7-8 (video production and media attachment). Still generate narration in step 6.`;
|
|
4214
4214
|
}
|
|
4215
|
+
function compositionQuizWorkflow(args, sessionContext, authMode = "authenticated") {
|
|
4216
|
+
const topic = args.topic ? ` about "${args.topic}"` : "";
|
|
4217
|
+
const count = args.question_count ?? 5;
|
|
4218
|
+
const discovery = buildDiscovery(getDiscoveryParams("quiz", "composition", authMode === "anonymous" ? "demo" : "full"), args, authMode);
|
|
4219
|
+
return `${sessionContext ? sessionContext + "\n\n" : ""}${discovery}Here's how to build a ${count}-question composition quiz${topic} with Clipform - a guess-and-reveal quiz where each question is a rendered composition (flag sweep, emoji rebus, blurred photo resolving) instead of a stock-image slideshow. Read the attached quiz and composition guides for the mechanic matrix, the clue \u2192 reveal node pattern, and difficulty design.
|
|
4220
|
+
|
|
4221
|
+
## Composition Quiz Workflow
|
|
4222
|
+
|
|
4223
|
+
1. **Discover what's renderable** - call clipform_list_compositions. Availability varies by session; choose mechanics ONLY from what it returns. Match each question to a mechanic via the composition guide's matrix. Mix 2-3 mechanics across the quiz; for questions with no fitting composition, use the base quiz's Ken Burns pipeline instead.
|
|
4224
|
+
2. **Write questions** - difficulty curve as in the base guide. Difficulty = subject obscurity (Japan's flag vs Kiribati's), never clue degradation. ${count} questions \u2248 ${count * 2 + 1} nodes (each question is a clue + reveal pair) - check the plan's node limit.
|
|
4225
|
+
3. **Render all clips** with clipform_render_composition, wait: false on EVERY call - fire the full batch (clue clip + reveal clip per question), then collect URLs with clipform_check_render. Chain-state compositions: clue clip animate: true, reveal clip animate: false + answer props.
|
|
4226
|
+
4. **Build the whole form in ONE clipform_create_form call** - pass nodes, settings, and tags together; do NOT create an empty form and add nodes one by one:
|
|
4227
|
+
- Settings: show_step_counter: true, disable_back_navigation: true
|
|
4228
|
+
- Per question, a PAIR of nodes:
|
|
4229
|
+
- Clue node (type: "choice"): question as prompt, config { choice: { show_answer_feedback: true }, randomise_options: true }, options with score: 1 on the correct answer and score: 0 on 2-3 wrong ones. Scored options enable correct-answer marking automatically.
|
|
4230
|
+
- Reveal node (type: "button"): the answer in the prompt ("It was Japan!"), config { button_text: "Next one" }
|
|
4231
|
+
- Final end_screen node: show_score: true, icon: "trophy", show_share_button: true, cta_type: "restart", cta_text: a short challenge. NOTE: per-tier messages (score_ranges) are coming soon - write one great message.
|
|
4232
|
+
- tags: format "quiz", genre "trivia", and 2-3 topic words
|
|
4233
|
+
5. **Generate narration** with clipform_generate_tts - batch ALL items in one call. The visual does the teasing: set stakes, never describe what's on screen or read the clue aloud. Reveal narration can celebrate.
|
|
4234
|
+
6. **Attach media** with clipform_upload_node_media (batch all uploads in one call) - clue clip on each choice node, reveal clip on each button node. Include captions, set show_captions: true.
|
|
4235
|
+
7. **Publish** with clipform_update_form
|
|
4236
|
+
8. **Log** with clipform_log_generation - record the composition IDs used per question alongside sources and attributions`;
|
|
4237
|
+
}
|
|
4215
4238
|
function interviewWorkflow(args, sessionContext, authMode = "authenticated") {
|
|
4216
4239
|
const purpose = args.purpose ?? "responses";
|
|
4217
4240
|
const format = args.response_format ?? "all";
|
|
@@ -4339,7 +4362,8 @@ var WORKFLOW_BUILDERS = {
|
|
|
4339
4362
|
};
|
|
4340
4363
|
var QUIZ_VARIANT_BUILDERS = {
|
|
4341
4364
|
"personality": personalityQuizWorkflow,
|
|
4342
|
-
"comprehension": comprehensionQuizWorkflow
|
|
4365
|
+
"comprehension": comprehensionQuizWorkflow,
|
|
4366
|
+
"composition": compositionQuizWorkflow
|
|
4343
4367
|
};
|
|
4344
4368
|
async function getWorkflowText(type, args = {}, variant) {
|
|
4345
4369
|
const { text: sessionContext, authMode } = await getSessionContextWithAuth();
|
|
@@ -4527,6 +4551,40 @@ Outcome categories: ${args.categories}` : "";
|
|
|
4527
4551
|
};
|
|
4528
4552
|
}
|
|
4529
4553
|
);
|
|
4554
|
+
server.registerPrompt(
|
|
4555
|
+
"create-composition-quiz",
|
|
4556
|
+
{
|
|
4557
|
+
title: "Create a Composition Quiz",
|
|
4558
|
+
description: "Build a guess-and-reveal quiz from rendered compositions - flag sweeps, emoji puzzles, blur reveals, odd-one-out grids - instead of stock-image slideshows",
|
|
4559
|
+
argsSchema: {
|
|
4560
|
+
topic: external_exports.string().optional().describe("Quiz topic (e.g. 'world flags', 'movie emoji', '90s music')"),
|
|
4561
|
+
question_count: external_exports.string().optional().default("5").describe("Number of questions (default: 5 - each question is a clue + reveal node pair)")
|
|
4562
|
+
}
|
|
4563
|
+
},
|
|
4564
|
+
async (rawArgs) => {
|
|
4565
|
+
const args = coercePromptArgs(rawArgs);
|
|
4566
|
+
return {
|
|
4567
|
+
messages: [
|
|
4568
|
+
{
|
|
4569
|
+
role: "user",
|
|
4570
|
+
content: {
|
|
4571
|
+
type: "text",
|
|
4572
|
+
text: `I want to create a composition quiz${args.topic ? ` about "${args.topic}"` : ""}. ${args.question_count ?? 5} questions, guess-and-reveal style.`
|
|
4573
|
+
}
|
|
4574
|
+
},
|
|
4575
|
+
resourceLink("guide-quiz", "clipform://guides/quiz", "Quiz Writing Guide"),
|
|
4576
|
+
resourceLink("guide-quiz-composition", "clipform://guides/quiz/composition", "Composition Quiz Addendum"),
|
|
4577
|
+
{
|
|
4578
|
+
role: "assistant",
|
|
4579
|
+
content: {
|
|
4580
|
+
type: "text",
|
|
4581
|
+
text: await getWorkflowText("quiz", args, "composition")
|
|
4582
|
+
}
|
|
4583
|
+
}
|
|
4584
|
+
]
|
|
4585
|
+
};
|
|
4586
|
+
}
|
|
4587
|
+
);
|
|
4530
4588
|
server.registerPrompt(
|
|
4531
4589
|
"create-funnel",
|
|
4532
4590
|
{
|
|
@@ -4647,4 +4705,4 @@ export {
|
|
|
4647
4705
|
getWorkflowText,
|
|
4648
4706
|
registerPrompts
|
|
4649
4707
|
};
|
|
4650
|
-
//# sourceMappingURL=chunk-
|
|
4708
|
+
//# sourceMappingURL=chunk-6MLZZSNM.js.map
|