@spark-apps/quickpeek 1.2.4 → 1.2.5

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.
@@ -3,7 +3,7 @@ import { Page } from 'playwright';
3
3
  /**
4
4
  * Configuration types and defaults for QuickPeek
5
5
  */
6
- declare const VERSION = "1.2.3";
6
+ declare const VERSION = "1.2.5";
7
7
  declare const CONFIG_FILE = "quickpeek.config.json";
8
8
  type UserTier = 'free' | 'pro' | 'elite';
9
9
  /** The one dimension knob users see: wide (16:9) or short (9:16). */
@@ -63,6 +63,12 @@ interface Config {
63
63
  contrast: number;
64
64
  tempo: number;
65
65
  stepDelay: number;
66
+ watermark?: {
67
+ name: string;
68
+ iconPath?: string;
69
+ position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
70
+ opacity?: number;
71
+ };
66
72
  outro?: string;
67
73
  outroCard?: {
68
74
  /** The app the video is about - the card's headline. */
@@ -71,6 +77,8 @@ interface Config {
71
77
  tagline?: string;
72
78
  domain?: string;
73
79
  iconPath?: string;
80
+ /** Play the mark rather than show a still of it. See OutroSubject. */
81
+ animatedMark?: 'vidlet';
74
82
  };
75
83
  /** Tools that made the video, shown small in the corner. */
76
84
  credits?: Array<{
@@ -123,10 +131,25 @@ interface Config {
123
131
  /**
124
132
  * Which bundled CC0 bed to score with when no `path` is given.
125
133
  *
126
- * 'calm' | 'gentle' | 'lofi' - see assets/music/manifest.json. An unknown
134
+ * 'corporate' | 'calm' | 'lofi' - see assets/music/manifest.json. An unknown
127
135
  * mood falls back to the default rather than dropping the music.
128
136
  */
129
137
  mood?: string;
138
+ /**
139
+ * Hold the music back until the closing card.
140
+ *
141
+ * A track written FOR the product is not a bed: ducked under a narrator
142
+ * for a minute it is inaudible, and it is the thing people are meant to
143
+ * hear. With this on, the demo plays dry and the song fades in exactly as
144
+ * the closing card arrives, with the rest of the video silent underneath
145
+ * the voice.
146
+ *
147
+ * ON by default. Music under narration was the single most disliked thing
148
+ * about the output: ducked it is mud, unducked it fights the voice, and
149
+ * either way it makes a 17 second demo sound like a stock video. Set
150
+ * false in quickpeek.config.json to score the whole video.
151
+ */
152
+ outroOnly?: boolean;
130
153
  };
131
154
  timing: {
132
155
  minStepDuration: number;
@@ -299,6 +322,11 @@ declare const SERVER_BACKOFF_MS: number[];
299
322
  * 16 Aug 2026). Only safe where a human is waiting on a spinner.
300
323
  */
301
324
  declare const CLI_BACKOFF_MS: number[];
325
+ declare const RELAY_BASE: string;
326
+ /**
327
+ * Relay mode: exchange the signed-in email for a short-lived relay token (cached)
328
+ */
329
+ declare function getOrRefreshRelayToken(email: string): Promise<string>;
302
330
  /**
303
331
  * Direct Spark AI call using the runtime SPARK_AI_KEY (dev + server-side use).
304
332
  */
@@ -373,6 +401,12 @@ interface Step {
373
401
  highlight?: HighlightMode;
374
402
  mediaFile?: string;
375
403
  mediaType?: 'image' | 'video';
404
+ /**
405
+ * A small JPEG data URL of the file `value` names, attached only when a plan
406
+ * is handed to the browser editor, which cannot read a path on disk. Never
407
+ * written to a plan file; see plan-thumbs.ts.
408
+ */
409
+ thumb?: string;
376
410
  /**
377
411
  * Speak this step's caption but do not burn it.
378
412
  *
@@ -610,4 +644,4 @@ declare function hasVoice(lang: string): boolean;
610
644
  */
611
645
  declare function voiceFor(lang: string, gender?: VoiceGender): string | null;
612
646
 
613
- export { getTierByEmail as $, type AIError as A, type VoiceGender as B, type CaptionStyle as C, DEFAULT_CAPTIONS as D, EXCLUDED_LINK_PATTERNS as E, applyProfile as F, ariaLabelSelector as G, type HighlightMode as H, INTERACTIVE_SELECTORS as I, buildSystemPrompt as J, buildUserPrompt as K, callAI as L, callAIViaRelay as M, NO_CLIP_OUTRO as N, crawlPage as O, PLAN_MAX_TOKENS as P, deStock as Q, RATE_FACTOR as R, SERVER_BACKOFF_MS as S, type Tier as T, type UserTier as U, type VoiceRate as V, defaultCaptionsFor as W, getErrorMessage as X, getLanguageName as Y, getStatus as Z, getStatusCached as _, type CaptionPosition as a, gotoSettled as a0, hasTrialRemaining as a1, hasVoice as a2, idSelector as a3, internationalVoiceFor as a4, isCanceling as a5, isExcludedLink as a6, isPaid as a7, isVerified as a8, normalizeUrl as a9, parseAIPlanResponse as aa, parsePartial as ab, pricingUrl as ac, rgbaToHex as ad, runPooled as ae, shouldSkipLink as af, showPaywall as ag, stripLongDashes as ah, toTitleCase as ai, voiceFor as aj, waitForPlaceholdersGone as ak, getTier as al, type Config as b, type AIResponse as c, type AIResult as d, CLI_BACKOFF_MS as e, CONFIG_FILE as f, type CaptionPreset as g, type CaptionWordStyle as h, type ChatOptions as i, DEFAULT_CONFIG as j, type ElementInfo as k, type ElementType as l, INTERNATIONAL_VOICE as m, type Plan as n, type RateLimitInfo as o, type RetryNotice as p, SIZE_PRESETS as q, type SparkStatus as r, type SparkSubscription as s, type SparkTrial as t, type Step as u, type SuggestedAction as v, VERSION as w, VIDEO_PROFILES as x, type VideoProfileName as y, type VideoSize as z };
647
+ export { getStatus as $, type AIError as A, type VideoSize as B, type CaptionStyle as C, DEFAULT_CAPTIONS as D, EXCLUDED_LINK_PATTERNS as E, type VoiceGender as F, applyProfile as G, type HighlightMode as H, INTERACTIVE_SELECTORS as I, ariaLabelSelector as J, buildSystemPrompt as K, buildUserPrompt as L, callAI as M, NO_CLIP_OUTRO as N, callAIViaRelay as O, PLAN_MAX_TOKENS as P, crawlPage as Q, RATE_FACTOR as R, SERVER_BACKOFF_MS as S, type Tier as T, type UserTier as U, type VoiceRate as V, deStock as W, defaultCaptionsFor as X, getErrorMessage as Y, getLanguageName as Z, getOrRefreshRelayToken as _, type CaptionPosition as a, getStatusCached as a0, getTierByEmail as a1, gotoSettled as a2, hasTrialRemaining as a3, hasVoice as a4, idSelector as a5, internationalVoiceFor as a6, isCanceling as a7, isExcludedLink as a8, isPaid as a9, isVerified as aa, normalizeUrl as ab, parseAIPlanResponse as ac, parsePartial as ad, pricingUrl as ae, rgbaToHex as af, runPooled as ag, shouldSkipLink as ah, showPaywall as ai, stripLongDashes as aj, toTitleCase as ak, voiceFor as al, waitForPlaceholdersGone as am, getTier as an, type Config as b, type AIResponse as c, type AIResult as d, CLI_BACKOFF_MS as e, CONFIG_FILE as f, type CaptionPreset as g, type CaptionWordStyle as h, type ChatOptions as i, DEFAULT_CONFIG as j, type ElementInfo as k, type ElementType as l, INTERNATIONAL_VOICE as m, type Plan as n, RELAY_BASE as o, type RateLimitInfo as p, type RetryNotice as q, SIZE_PRESETS as r, type SparkStatus as s, type SparkSubscription as t, type SparkTrial as u, type Step as v, type SuggestedAction as w, VERSION as x, VIDEO_PROFILES as y, type VideoProfileName as z };
package/dist/web.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { n as Plan } from './voices-CPpnWn39.mjs';
2
- export { A as AIError, c as AIResponse, d as AIResult, i as ChatOptions, E as EXCLUDED_LINK_PATTERNS, k as ElementInfo, l as ElementType, H as HighlightMode, I as INTERACTIVE_SELECTORS, m as INTERNATIONAL_VOICE, P as PLAN_MAX_TOKENS, o as RateLimitInfo, r as SparkStatus, s as SparkSubscription, t as SparkTrial, u as Step, v as SuggestedAction, T as Tier, J as buildSystemPrompt, K as buildUserPrompt, L as callAI, O as crawlPage, Q as deStock, X as getErrorMessage, Y as getLanguageName, Z as getStatus, _ as getStatusCached, al as getTier, $ as getTierByEmail, a1 as hasTrialRemaining, a2 as hasVoice, a4 as internationalVoiceFor, a5 as isCanceling, a6 as isExcludedLink, a7 as isPaid, a8 as isVerified, a9 as normalizeUrl, aa as parseAIPlanResponse, ab as parsePartial, ac as pricingUrl, ad as rgbaToHex, ae as runPooled, af as shouldSkipLink, ag as showPaywall, ah as stripLongDashes, ai as toTitleCase, aj as voiceFor } from './voices-CPpnWn39.mjs';
1
+ import { n as Plan } from './voices-ufga0oOn.mjs';
2
+ export { A as AIError, c as AIResponse, d as AIResult, i as ChatOptions, E as EXCLUDED_LINK_PATTERNS, k as ElementInfo, l as ElementType, H as HighlightMode, I as INTERACTIVE_SELECTORS, m as INTERNATIONAL_VOICE, P as PLAN_MAX_TOKENS, p as RateLimitInfo, s as SparkStatus, t as SparkSubscription, u as SparkTrial, v as Step, w as SuggestedAction, T as Tier, K as buildSystemPrompt, L as buildUserPrompt, M as callAI, Q as crawlPage, W as deStock, Y as getErrorMessage, Z as getLanguageName, $ as getStatus, a0 as getStatusCached, an as getTier, a1 as getTierByEmail, a3 as hasTrialRemaining, a4 as hasVoice, a6 as internationalVoiceFor, a7 as isCanceling, a8 as isExcludedLink, a9 as isPaid, aa as isVerified, ab as normalizeUrl, ac as parseAIPlanResponse, ad as parsePartial, ae as pricingUrl, af as rgbaToHex, ag as runPooled, ah as shouldSkipLink, ai as showPaywall, aj as stripLongDashes, ak as toTitleCase, al as voiceFor } from './voices-ufga0oOn.mjs';
3
3
  export { MALE_VOICES, MULTILINGUAL_VOICES, WIDE_VOICES, hexToAss as hexToASS, windowsDrivePathToWsl as windowsPathToWSL } from '@spark-apps/video-kit';
4
4
  import 'playwright';
5
5
 
package/dist/web.mjs CHANGED
@@ -423,6 +423,7 @@ async function waitForDomStable(page, cap = SETTLE_CAP_MS) {
423
423
  var PLACEHOLDER_POLL_MS = 250;
424
424
  var PLACEHOLDER_CAP_MS = 8e3;
425
425
  var PLACEHOLDER_STATIC_POLLS = 4;
426
+ var PLACEHOLDER_CLEAR_POLLS = 3;
426
427
  var PLACEHOLDER_SELECTOR = [
427
428
  '[aria-busy="true"]',
428
429
  '[role="progressbar"]',
@@ -435,6 +436,7 @@ async function waitForPlaceholdersGone(page, cap = PLACEHOLDER_CAP_MS) {
435
436
  const deadline = Date.now() + cap;
436
437
  let previous = -1;
437
438
  let unchanged = 0;
439
+ let clear = 0;
438
440
  while (Date.now() < deadline) {
439
441
  const count = await page.evaluate((selector) => {
440
442
  let visible = 0;
@@ -444,7 +446,12 @@ async function waitForPlaceholdersGone(page, cap = PLACEHOLDER_CAP_MS) {
444
446
  }
445
447
  return visible;
446
448
  }, PLACEHOLDER_SELECTOR).catch(() => 0);
447
- if (count === 0) return;
449
+ if (count === 0) {
450
+ if (++clear >= PLACEHOLDER_CLEAR_POLLS) return;
451
+ await page.waitForTimeout(PLACEHOLDER_POLL_MS);
452
+ continue;
453
+ }
454
+ clear = 0;
448
455
  if (count === previous) {
449
456
  if (++unchanged >= PLACEHOLDER_STATIC_POLLS) return;
450
457
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spark-apps/quickpeek",
3
- "version": "1.2.4",
3
+ "version": "1.2.5",
4
4
  "description": "Auto-generate demo videos for your web app with AI",
5
5
  "mcpName": "co.quickpeek/quickpeek",
6
6
  "main": "dist/qp.js",
@@ -48,8 +48,18 @@
48
48
  "voiceover",
49
49
  "automation",
50
50
  "cli",
51
- "documentation"
51
+ "documentation",
52
+ "mcp",
53
+ "model-context-protocol"
52
54
  ],
55
+ "repository": {
56
+ "type": "git",
57
+ "url": "git+https://github.com/muammar-yacoob/QuickPeek.git"
58
+ },
59
+ "homepage": "https://quickpeek.co",
60
+ "bugs": {
61
+ "url": "https://discord.gg/mAjHWE3mSp"
62
+ },
53
63
  "license": "MIT",
54
64
  "dependencies": {
55
65
  "@modelcontextprotocol/sdk": "^1.29.0",