@nodaro/prompts 1.21.0 → 1.23.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/dist/index.cjs CHANGED
@@ -166,8 +166,11 @@ function applyExtend(c, pack) {
166
166
  }
167
167
  function applyDeny(c, denyIds) {
168
168
  const deny = new Set(denyIds);
169
- if (c.kind === "single") return { ...c, options: (c.options ?? []).filter((o) => !deny.has(o.id)) };
170
- return { ...c, dimensions: (c.dimensions ?? []).map((d) => ({ ...d, options: d.options.filter((o) => !deny.has(o.id)) })) };
169
+ return {
170
+ ...c,
171
+ options: c.options?.filter((o) => !deny.has(o.id)),
172
+ dimensions: c.dimensions?.map((d) => ({ ...d, options: d.options.filter((o) => !deny.has(o.id)) }))
173
+ };
171
174
  }
172
175
  function composePickerCatalogs(base, activePacks) {
173
176
  const known = new Set(base.map((c) => c.catalogId));
@@ -182,6 +185,12 @@ function composePickerCatalogs(base, activePacks) {
182
185
  else if (pack.mode === "extend") out = applyExtend(out, pack);
183
186
  else if (pack.mode === "deny") out = applyDeny(out, pack.denyIds ?? []);
184
187
  }
188
+ if (activePacks.some((p) => p.catalogId === c.catalogId) && out.defaultValue) {
189
+ const options = [...out.options ?? [], ...(out.dimensions ?? []).flatMap((d) => d.options)];
190
+ if (!options.some((o) => o.id === out.defaultValue)) {
191
+ out = { ...out, defaultValue: out.options?.[0]?.id };
192
+ }
193
+ }
185
194
  return out;
186
195
  });
187
196
  }
@@ -4864,7 +4873,8 @@ var TRANSITIONS = [
4864
4873
  category: "standard",
4865
4874
  description: "Instantaneous switch, no transition",
4866
4875
  promptHint: "no transition, hard cut, instantaneous switch from first shot to second shot",
4867
- term: "hard cut"
4876
+ term: "hard cut",
4877
+ instant: true
4868
4878
  },
4869
4879
  {
4870
4880
  id: "cross-dissolve",
@@ -4893,21 +4903,24 @@ var TRANSITIONS = [
4893
4903
  category: "standard",
4894
4904
  description: "Instant cut to full black for a beat, then the next shot",
4895
4905
  promptHint: "snap to black: the first shot cuts instantly to full black with no fade, the frame holds pure black for a single beat, then the second shot cuts in at full brightness",
4896
- term: "snap to black"
4906
+ term: "snap to black",
4907
+ instant: true
4897
4908
  },
4898
4909
  {
4899
4910
  id: "match-cut",
4900
4911
  label: "Match Cut",
4901
4912
  category: "standard",
4902
4913
  description: "Shape or motion match across shots",
4903
- promptHint: "match cut: the final composition of the first shot matches the opening composition of the second shot in shape, color, and motion, so the cut feels like a visual rhyme"
4914
+ promptHint: "match cut: the final composition of the first shot matches the opening composition of the second shot in shape, color, and motion, so the cut feels like a visual rhyme",
4915
+ instant: true
4904
4916
  },
4905
4917
  {
4906
4918
  id: "smash-cut",
4907
4919
  label: "Smash Cut",
4908
4920
  category: "standard",
4909
4921
  description: "Jarring abrupt cut between contrasting shots",
4910
- promptHint: "smash cut: an abrupt jarring transition between two visually or tonally contrasting shots with no fade, on a beat"
4922
+ promptHint: "smash cut: an abrupt jarring transition between two visually or tonally contrasting shots with no fade, on a beat",
4923
+ instant: true
4911
4924
  },
4912
4925
  {
4913
4926
  id: "iris",
@@ -4939,7 +4952,8 @@ var TRANSITIONS = [
4939
4952
  category: "standard",
4940
4953
  description: "Hidden cut disguised by matched motion and color",
4941
4954
  promptHint: "hidden seamless transition: the camera motion, color palette, and on-screen motion at the end of the first shot continue exactly across the cut into the second shot, so the boundary is invisible and the two shots feel like one unbroken take",
4942
- term: "invisible cut"
4955
+ term: "invisible cut",
4956
+ instant: true
4943
4957
  },
4944
4958
  {
4945
4959
  id: "whip-pan",
@@ -4955,7 +4969,8 @@ var TRANSITIONS = [
4955
4969
  category: "standard",
4956
4970
  description: "Same framing, time skips forward",
4957
4971
  promptHint: "jump cut: the framing, lens, and camera position stay identical across the cut while time skips abruptly forward, so the subject snaps to a new position inside what still reads as one continuous shot",
4958
- term: "jump cut"
4972
+ term: "jump cut",
4973
+ instant: true
4959
4974
  },
4960
4975
  // ============================================================================
4961
4976
  // TIME — 8 entries — temporal shifts (same or related scene, different time, or memory)
@@ -5344,7 +5359,8 @@ var TRANSITIONS = [
5344
5359
  category: "physics",
5345
5360
  description: "Subject jumps, landing matches into new scene",
5346
5361
  promptHint: "the subject jumps upward and out of frame at the end of the first shot, with matched velocity the camera follows the arc, and on landing the subject is in a new location seamlessly continuing the same jump",
5347
- term: "match cut on a jump"
5362
+ term: "match cut on a jump",
5363
+ instant: true
5348
5364
  },
5349
5365
  {
5350
5366
  id: "hand-swipe",
@@ -5359,7 +5375,8 @@ var TRANSITIONS = [
5359
5375
  category: "physics",
5360
5376
  description: "Subject exits on an action and lands in the new scene mid-move",
5361
5377
  promptHint: "match cut on action: the subject exits the frame on a committed action \u2014 a stride, a throw, a turn \u2014 and enters the new scene on the same beat continuing that movement at matched speed and direction, so the action carries unbroken across the cut",
5362
- term: "match cut on action"
5378
+ term: "match cut on action",
5379
+ instant: true
5363
5380
  },
5364
5381
  // ============================================================================
5365
5382
  // LIGHT — 8 entries — flash and lens FX
@@ -5515,6 +5532,11 @@ function getTransitionTerm(id) {
5515
5532
  return resolveTerm(getTransition(id));
5516
5533
  }
5517
5534
  var TRANSITION_IDS = TRANSITIONS.map((t) => t.id);
5535
+ function isInstantTransition(id) {
5536
+ const ids = typeof id === "string" ? [id] : id ? [...id] : [];
5537
+ if (ids.length === 0) return false;
5538
+ return ids.every((one) => getTransition(one)?.instant === true);
5539
+ }
5518
5540
  var TRANSITION_POSITIONS = [
5519
5541
  { id: "auto", label: "Auto", description: "Let the model place it", promptHint: "", term: "" },
5520
5542
  { id: "start", label: "Start", description: "At the opening of the clip", promptHint: "the transition occurs at the opening of the clip", term: "at the opening of the clip" },
@@ -5547,14 +5569,15 @@ var INTENSITY_CLAUSES = clausesOf(TRANSITION_INTENSITIES);
5547
5569
  function composeTransitionHintFromConnections(transitionId, startHints, endHints, timing, mode = "full") {
5548
5570
  const ids = Array.isArray(transitionId) ? Array.from(new Set(transitionId)).slice(0, 2) : transitionId ? [transitionId] : [];
5549
5571
  const resolveBase = mode === "compact" ? getTransitionTerm : getTransitionPromptHint;
5550
- const baseHints = ids.map(resolveBase).filter((h) => h.length > 0);
5572
+ const picked = ids.filter((id) => resolveBase(id).length > 0);
5573
+ const baseHints = picked.map(resolveBase);
5551
5574
  if (baseHints.length === 0) return "";
5552
5575
  const combinedBase = baseHints.join(", and ");
5553
5576
  const parts = [combinedBase];
5554
5577
  if (timing?.position && timing.position !== "auto") {
5555
5578
  parts.push(POSITION_CLAUSES[timing.position]);
5556
5579
  }
5557
- if (timing?.duration && timing.duration !== "auto") {
5580
+ if (timing?.duration && timing.duration !== "auto" && !isInstantTransition(picked)) {
5558
5581
  parts.push(DURATION_CLAUSES[timing.duration]);
5559
5582
  }
5560
5583
  if (timing?.intensity && timing.intensity !== "auto") {
@@ -18607,6 +18630,7 @@ function toOptions(arr, categoryField) {
18607
18630
  if (e.description) opt.description = e.description;
18608
18631
  if (categoryField) opt.category = e[categoryField];
18609
18632
  if (e.adultOnly) opt.adultOnly = true;
18633
+ if (e.instant) opt.instant = true;
18610
18634
  return opt;
18611
18635
  });
18612
18636
  }
@@ -21881,6 +21905,12 @@ var REF_BINDING = {
21881
21905
  ordinal: (n) => `@image_${n}`,
21882
21906
  frame: (n, role) => `Use @image_${n} as the ${role} (${role === "opening" ? "first" : "last"}) frame of the video.`
21883
21907
  };
21908
+ var SEEDANCE_VIDEO_EDIT_PREFIX = "edit {video:1} as follows:\n";
21909
+ function buildSeedanceVideoEditPrompt(prompt) {
21910
+ const body = (prompt ?? "").trim();
21911
+ if (/^edit\s+(?:\{video:1(?::[^}]*)?\}|@video_1(?!\w))/i.test(body)) return body;
21912
+ return `${SEEDANCE_VIDEO_EDIT_PREFIX}${body}`;
21913
+ }
21884
21914
 
21885
21915
  // src/ref-id-tokens.ts
21886
21916
  var REF_TOKEN_LABEL_RE = /^[a-zA-Z0-9_ -]+$/;
@@ -38911,7 +38941,11 @@ var NODE_PROMPT_FIELDS = {
38911
38941
  "forced-alignment": { prompt: "transcript", promptLabel: "Transcript", media: "audio", inline: false },
38912
38942
  // Video Analysis — its focus hint is the editable prompt (renders a JSON scene
38913
38943
  // table, not a media preview → no inline editor).
38914
- "video-analysis": { prompt: "analysisFocus", promptLabel: "Analysis focus", media: "video", inline: false }
38944
+ "video-analysis": { prompt: "analysisFocus", promptLabel: "Analysis focus", media: "video", inline: false },
38945
+ // Edit Plan (podcast editing) — its free-text editing instructions are the
38946
+ // editable prompt; the affixes wrap them. Emits an EDL (JSON), not a media
38947
+ // preview, so no inline editor.
38948
+ "edit-plan": { prompt: "instructions", promptLabel: "Editing instructions", media: "video", inline: false }
38915
38949
  };
38916
38950
  function getPromptFields(nodeType) {
38917
38951
  return nodeType ? NODE_PROMPT_FIELDS[nodeType] : void 0;
@@ -41691,6 +41725,27 @@ var GENERATE_VIDEO_PRESETS = [
41691
41725
  generateAudio: true,
41692
41726
  prompt: "{creature || A monstrous yeti with the physique and bone structure of a giant silverback gorilla}, {texture || thick matted white fur with snow crusted on the shoulders}, charges forward and smashes both fists into the ground. Low-angle ground shot looking up to emphasize its scale, heavy camera shake on impact, snow and debris bursting toward the lens. Overcast mountain light, volumetric breath mist around its muzzle. <deep guttural roar, the crunch of impact, debris scattering>\uFF08low ominous brass drone\uFF09Biologically accurate anatomy, epic cinematic scale. HD, sharp micro-details, stable picture, keep it subtitle-free, do not generate a watermark."
41693
41727
  }
41728
+ },
41729
+ // ── Video Editing ─────────────────────────────────────────────────────────
41730
+ // Seedance 2.5 EDITS a wired reference clip when the prompt reads as an edit
41731
+ // instruction. Edit mode takes the source clip's own ratio and length, so the
41732
+ // preset ships the exact shape the provider requires — Adaptive + Auto
41733
+ // (duration -1) — and the run goes through on the first submit. The user's
41734
+ // own sentence is the whole prompt: the preset only supplies the pre & post
41735
+ // text, with the clip bound as {video:1} (wire it into Video Refs).
41736
+ {
41737
+ id: "generate-video/edit-video",
41738
+ name: "Edit Video",
41739
+ description: "Change a wired clip by instruction \u2014 keeps its length, ratio and everything you don't mention.",
41740
+ group: "Video Editing",
41741
+ data: {
41742
+ provider: "seedance-2-5",
41743
+ aspectRatio: "adaptive",
41744
+ duration: -1,
41745
+ generateAudio: true,
41746
+ promptPrefix: "edit {video:1} as follows:\n",
41747
+ promptSuffix: "Keep everything else in the clip unchanged: the same people, motion, framing and timing. Keep it subtitle-free, do not generate a watermark."
41748
+ }
41694
41749
  }
41695
41750
  ];
41696
41751
 
@@ -44257,6 +44312,63 @@ function getCharacterMotionDiagnostics(value, timing, bindings = {}) {
44257
44312
  return result;
44258
44313
  }
44259
44314
 
44315
+ // src/ad-creative-analysis.ts
44316
+ var AD_CREATIVE_ANALYSIS_FIELDS = [
44317
+ "assetType",
44318
+ "format",
44319
+ "visualHooks",
44320
+ "audiences",
44321
+ "graphicIdentity",
44322
+ "copywritingHooks",
44323
+ "usps",
44324
+ "cta",
44325
+ "summary"
44326
+ ];
44327
+ var AD_CREATIVE_ANALYSIS_SYSTEM_PROMPT = `You are an expert competitor ad analyst. You look at a competitor's ad \u2014 its creative (image or video poster frame) and its copy \u2014 and extract the relevant ad information into a structured summary a marketing team can act on.
44328
+
44329
+ Judge from what is actually in the creative and copy; never invent claims that are not visible or written. Be concrete and specific (name the objects, colors, people, layouts, words), not generic ("eye-catching visuals"). Write in the language of the ad copy when it is not English, otherwise in English.
44330
+
44331
+ Fill every field:
44332
+ - assetType: "static" (a still image), "motion" (a video \u2014 you see its poster frame), "carousel" (several creatives in one ad), or "unknown".
44333
+ - format: the placement the creative is built for \u2014 e.g. "in-feed", "story / reel (9:16)", "square feed", "banner / web", judged from its shape and framing.
44334
+ - visualHooks: the key visuals and visual angles used to stop the scroll (product close-up, before/after, face + eye contact, big number, screenshot, meme style, UGC selfie, text-on-image\u2026). 2\u20136 short items.
44335
+ - audiences: who the ad represents or addresses (age band, gender, life situation, profession, interest, geography, pain point). 1\u20135 short items.
44336
+ - graphicIdentity: the graphic components \u2014 color palette, typography style, logo placement, layout system, illustration vs photo, brand consistency cues. One or two sentences.
44337
+ - copywritingHooks: the copywriting angles used in the visual text and in the body (curiosity, urgency, social proof, question, offer, fear of missing out, authority, humor\u2026). 1\u20136 short items, each naming the angle and quoting or paraphrasing the line that carries it.
44338
+ - usps: the unique selling points the ad claims (price, speed, exclusivity, guarantee, results, features). 1\u20135 short items.
44339
+ - cta: the call to action \u2014 the button label and/or the closing line that tells the viewer what to do.
44340
+ - summary: two to four sentences: what the ad sells, to whom, with what hook, and why it likely works (or does not).`;
44341
+ var POST_CONTENT_ANALYSIS_SYSTEM_PROMPT = `You are an expert social-media content analyst. You look at a single organic post \u2014 its creative (image or video cover frame) and its caption \u2014 and extract what a marketing team can learn from it into a structured summary.
44342
+
44343
+ Judge from what is actually in the creative and caption; never invent claims that are not visible or written. Be concrete and specific (name the objects, colors, people, layouts, words), not generic ("engaging content"). Write in the language of the caption when it is not English, otherwise in English.
44344
+
44345
+ Fill every field:
44346
+ - assetType: "static" (a still image), "motion" (a video / reel \u2014 you see its cover frame), "carousel" (a multi-image post), or "unknown".
44347
+ - format: the format the post is built for \u2014 e.g. "reel (9:16)", "square feed photo", "carousel", "portrait (4:5)", judged from its shape and framing.
44348
+ - visualHooks: the key visuals and visual angles used to stop the scroll (product close-up, before/after, face + eye contact, big text overlay, meme style, UGC selfie, trend/format\u2026). 2\u20136 short items.
44349
+ - audiences: who the post represents or speaks to (age band, gender, life situation, profession, interest, geography, community). 1\u20135 short items.
44350
+ - graphicIdentity: the graphic components \u2014 color palette, typography style, logo / handle placement, layout, illustration vs photo, brand consistency cues. One or two sentences.
44351
+ - copywritingHooks: the caption / content angles (curiosity, storytelling, question, trend, humor, social proof, education, behind-the-scenes\u2026). 1\u20136 short items, each naming the angle and quoting or paraphrasing the line that carries it.
44352
+ - usps: the value or benefit the post conveys to the viewer (entertainment, education, inspiration, a product benefit, a deal). 1\u20135 short items.
44353
+ - cta: the ask \u2014 the caption's call to action ("link in bio", "shop now", "follow", "comment below"), or "none" if the post makes none.
44354
+ - summary: two to four sentences: what the post is about, who it speaks to, with what hook, and why it likely performs (or does not).`;
44355
+ function buildAdCreativeAnalysisUserText(input) {
44356
+ const lines = [];
44357
+ if (input.advertiser) lines.push(`Account / advertiser: ${input.advertiser}`);
44358
+ if (input.headline) lines.push(`Headline: ${input.headline}`);
44359
+ if (input.body) lines.push(`Body copy:
44360
+ ${input.body}`);
44361
+ if (input.ctaLabel) lines.push(`CTA button: ${input.ctaLabel}`);
44362
+ if (input.landing) lines.push(`Landing: ${input.landing}`);
44363
+ if (input.platforms && input.platforms.length > 0) lines.push(`Placements: ${input.platforms.join(", ")}`);
44364
+ if (input.creativeFormat) lines.push(`Creative shape: ${input.creativeFormat}`);
44365
+ if (input.mediaSummary) lines.push(`Media: ${input.mediaSummary}`);
44366
+ lines.push("The attached image is the ad's creative (for a video, its poster frame).");
44367
+ if (input.focus) lines.push(`
44368
+ Analyst focus from the user: ${input.focus}`);
44369
+ return lines.join("\n");
44370
+ }
44371
+
44260
44372
  exports.ACTION_FX = ACTION_FX;
44261
44373
  exports.ACTION_FX_CATEGORY_LABELS = ACTION_FX_CATEGORY_LABELS;
44262
44374
  exports.ACTION_FX_CATEGORY_ORDER = ACTION_FX_CATEGORY_ORDER;
@@ -44264,6 +44376,8 @@ exports.ACTION_FX_IDS = ACTION_FX_IDS;
44264
44376
  exports.ADULT_AGE_IDS = ADULT_AGE_IDS;
44265
44377
  exports.ADULT_ONLY_FLAG = ADULT_ONLY_FLAG;
44266
44378
  exports.ADULT_SWEPT_CATALOG_IDS = ADULT_SWEPT_CATALOG_IDS;
44379
+ exports.AD_CREATIVE_ANALYSIS_FIELDS = AD_CREATIVE_ANALYSIS_FIELDS;
44380
+ exports.AD_CREATIVE_ANALYSIS_SYSTEM_PROMPT = AD_CREATIVE_ANALYSIS_SYSTEM_PROMPT;
44267
44381
  exports.AESTHETICS = AESTHETICS;
44268
44382
  exports.AESTHETIC_CATEGORY_LABELS = AESTHETIC_CATEGORY_LABELS;
44269
44383
  exports.AESTHETIC_CATEGORY_ORDER = AESTHETIC_CATEGORY_ORDER;
@@ -44414,6 +44528,7 @@ exports.POSES = POSES;
44414
44528
  exports.POSE_CATEGORY_LABELS = POSE_CATEGORY_LABELS;
44415
44529
  exports.POSE_CATEGORY_ORDER = POSE_CATEGORY_ORDER;
44416
44530
  exports.POSE_IDS = POSE_IDS;
44531
+ exports.POST_CONTENT_ANALYSIS_SYSTEM_PROMPT = POST_CONTENT_ANALYSIS_SYSTEM_PROMPT;
44417
44532
  exports.POST_PROCESS_EFFECTS = POST_PROCESS_EFFECTS;
44418
44533
  exports.POST_PROCESS_EFFECT_IDS = POST_PROCESS_EFFECT_IDS;
44419
44534
  exports.PRODUCTION_STYLES = PRODUCTION_STYLES;
@@ -44440,6 +44555,7 @@ exports.SCENE3D_LAYOUT_SCOPING_MARKER = SCENE3D_LAYOUT_SCOPING_MARKER;
44440
44555
  exports.SCENE3D_UNREFERENCED_FIGURES_WARNING_CODE = SCENE3D_UNREFERENCED_FIGURES_WARNING_CODE;
44441
44556
  exports.SCENE_FRAME_RULE = SCENE_FRAME_RULE;
44442
44557
  exports.SCENE_PROMPT_MAX_LENGTH = SCENE_PROMPT_MAX_LENGTH;
44558
+ exports.SEEDANCE_VIDEO_EDIT_PREFIX = SEEDANCE_VIDEO_EDIT_PREFIX;
44443
44559
  exports.SETTINGS = SETTINGS;
44444
44560
  exports.SETTING_CATEGORY_LABELS = SETTING_CATEGORY_LABELS;
44445
44561
  exports.SETTING_IDS = SETTING_IDS;
@@ -44513,6 +44629,7 @@ exports.assembleImageInput = assembleImageInput;
44513
44629
  exports.assembleSunoInput = assembleSunoInput;
44514
44630
  exports.buildActionFxHints = buildActionFxHints;
44515
44631
  exports.buildActionFxTerms = buildActionFxTerms;
44632
+ exports.buildAdCreativeAnalysisUserText = buildAdCreativeAnalysisUserText;
44516
44633
  exports.buildAestheticHints = buildAestheticHints;
44517
44634
  exports.buildAestheticTerms = buildAestheticTerms;
44518
44635
  exports.buildAgeHint = buildAgeHint;
@@ -44567,6 +44684,7 @@ exports.buildReferenceBlocks = buildReferenceBlocks;
44567
44684
  exports.buildScene3DLayoutScopingLine = buildScene3DLayoutScopingLine;
44568
44685
  exports.buildScene3DUnreferencedFiguresWarning = buildScene3DUnreferencedFiguresWarning;
44569
44686
  exports.buildScenePrompt = buildScenePrompt;
44687
+ exports.buildSeedanceVideoEditPrompt = buildSeedanceVideoEditPrompt;
44570
44688
  exports.buildStylingHints = buildStylingHints;
44571
44689
  exports.buildStylingTerms = buildStylingTerms;
44572
44690
  exports.buildSurroundFillPrompt = buildSurroundFillPrompt;
@@ -44811,6 +44929,7 @@ exports.identityRefsSentence = identityRefsSentence;
44811
44929
  exports.insertBeforeStyleSection = insertBeforeStyleSection;
44812
44930
  exports.isAnalyzablePicker = isAnalyzablePicker;
44813
44931
  exports.isDeniedStyleId = isDeniedStyleId;
44932
+ exports.isInstantTransition = isInstantTransition;
44814
44933
  exports.isInstrumentalVocal = isInstrumentalVocal;
44815
44934
  exports.isMinorAge = isMinorAge;
44816
44935
  exports.isSuspiciousDerivedTerm = isSuspiciousDerivedTerm;