@spark-apps/quickpeek 1.1.1 → 1.1.3

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.
@@ -0,0 +1,287 @@
1
+ /**
2
+ * Configuration types and defaults for QuickPeek
3
+ */
4
+ declare const VERSION = "1.1.1";
5
+ declare const CONFIG_FILE = "quickpeek.config.json";
6
+ type UserTier = 'free' | 'pro';
7
+ interface Config {
8
+ lang?: string;
9
+ plan?: {
10
+ maxSteps: number;
11
+ };
12
+ browser?: {
13
+ extension?: string;
14
+ };
15
+ video: {
16
+ width: number;
17
+ height: number;
18
+ format: string;
19
+ preset: 'ultrafast' | 'superfast' | 'veryfast' | 'faster' | 'fast' | 'medium' | 'slow' | 'slower' | 'veryslow';
20
+ quality: number;
21
+ fps: number;
22
+ cursor: boolean;
23
+ highlight: false | 'outline' | 'full';
24
+ fadeIn: number;
25
+ fadeOut: number;
26
+ transitions: 'none' | 'fade' | 'blend';
27
+ contrast: number;
28
+ tempo: number;
29
+ stepDelay: number;
30
+ };
31
+ audio?: {
32
+ voice?: string;
33
+ format: string;
34
+ bitrate: string;
35
+ };
36
+ music?: {
37
+ path: string;
38
+ volume: number;
39
+ };
40
+ timing: {
41
+ minStepDuration: number;
42
+ };
43
+ output: {
44
+ dir: string;
45
+ };
46
+ }
47
+ interface CaptionWordStyle {
48
+ color: string;
49
+ size: number;
50
+ bold: boolean;
51
+ }
52
+ interface CaptionStyle {
53
+ font: string;
54
+ outline: string;
55
+ outlineWidth: number;
56
+ shadow: number;
57
+ marginBottom: number;
58
+ regular: CaptionWordStyle;
59
+ highlight: CaptionWordStyle;
60
+ }
61
+ declare const DEFAULT_CONFIG: Config;
62
+ declare const DEFAULT_CAPTIONS: CaptionStyle;
63
+
64
+ /**
65
+ * AI API client — Spark AI communication
66
+ * Handles token management, rate limiting, and retries
67
+ *
68
+ * The API key is embedded at build time via tsup `define`.
69
+ * Per-user rate limiting is handled server-side via email.
70
+ */
71
+
72
+ interface RateLimitInfo {
73
+ used: number;
74
+ limit: number;
75
+ tier: UserTier;
76
+ resetAt?: string;
77
+ }
78
+ interface AIResponse {
79
+ success: true;
80
+ content: string;
81
+ limits: RateLimitInfo;
82
+ }
83
+ interface AIError {
84
+ success: false;
85
+ error: string;
86
+ isRateLimit?: boolean;
87
+ isAuthError?: boolean;
88
+ retryAfterSeconds?: number;
89
+ }
90
+ type AIResult = AIResponse | AIError;
91
+ /**
92
+ * Call Spark AI chat endpoint. Automatically retries on rate limit using Retry-After header.
93
+ */
94
+ declare function callAI(systemPrompt: string, userPrompt: string, tier?: UserTier): Promise<AIResult>;
95
+ /**
96
+ * Parse AI-generated plan JSON from response text
97
+ */
98
+ declare function parseAIPlanResponse(content: string): {
99
+ success: true;
100
+ plan: {
101
+ title?: string;
102
+ description?: string;
103
+ steps: Array<{
104
+ id?: number;
105
+ action?: string;
106
+ caption?: string;
107
+ target?: string;
108
+ value?: string;
109
+ }>;
110
+ };
111
+ } | {
112
+ success: false;
113
+ error: string;
114
+ };
115
+ /**
116
+ * Normalize a URL by adding https:// and stripping www prefix
117
+ */
118
+ declare function normalizeUrl(input: string): string;
119
+
120
+ /**
121
+ * Shared types for QuickPeek core
122
+ */
123
+ /** Action type suggested for an element based on its type */
124
+ type SuggestedAction = 'click' | 'type' | 'upload' | 'drag' | 'select' | 'check';
125
+ /** Element type discovered on a page */
126
+ type ElementType = 'button' | 'input' | 'link' | 'text' | 'file' | 'select' | 'range' | 'checkbox';
127
+ /** Discovered element from page crawl */
128
+ interface ElementInfo {
129
+ /** Element type */
130
+ type: ElementType | string;
131
+ /** Display text/label for the element */
132
+ text: string;
133
+ /** CSS selector to target the element */
134
+ selector: string;
135
+ /** Suggested action for this element */
136
+ action?: SuggestedAction;
137
+ /** Simplified target name (just the text, for AI use) */
138
+ target?: string;
139
+ }
140
+ /** Highlight mode for UI elements */
141
+ type HighlightMode = false | 'outline' | 'full';
142
+ /** Step in a demo plan */
143
+ interface Step {
144
+ id: number | string;
145
+ action: string;
146
+ target?: string;
147
+ value?: string;
148
+ caption?: string;
149
+ description?: string;
150
+ duration?: number;
151
+ zoom?: number | string;
152
+ partial?: string;
153
+ transition?: 'fade' | 'blend';
154
+ highlight?: HighlightMode;
155
+ mediaFile?: string;
156
+ mediaType?: 'image' | 'video';
157
+ }
158
+ /** Demo plan structure */
159
+ interface Plan {
160
+ url: string;
161
+ title: string;
162
+ description: string;
163
+ lang?: string;
164
+ steps: Step[];
165
+ }
166
+
167
+ /**
168
+ * Page crawling and interactive element extraction
169
+ */
170
+
171
+ /**
172
+ * Crawl a page and extract interactive elements with smart selectors
173
+ * @param url - URL to crawl
174
+ * @param task - Optional progress reporter (CLI uses ora spinners, web can omit)
175
+ */
176
+ declare function crawlPage(url: string, task?: (text: string) => {
177
+ succeed: (text?: string) => void;
178
+ }): Promise<{
179
+ title: string;
180
+ elements: ElementInfo[];
181
+ }>;
182
+
183
+ /**
184
+ * Utility functions for QuickPeek
185
+ */
186
+ /**
187
+ * Get full language name from ISO code
188
+ */
189
+ declare function getLanguageName(lang?: string): string | null;
190
+ /**
191
+ * Convert hex color (#RRGGBB) to ASS subtitle format (&HAABBGGRR)
192
+ */
193
+ declare function hexToASS(hex: string, alpha?: number): string;
194
+ /**
195
+ * Convert rgba() or rgb() color string to hex
196
+ */
197
+ declare function rgbaToHex(color: string): string;
198
+ /**
199
+ * Convert a Windows absolute path (D:\...) to WSL mount format (/mnt/d/...).
200
+ * Returns null if the path is not a Windows drive-letter path.
201
+ */
202
+ declare function windowsPathToWSL(path: string): string | null;
203
+ /**
204
+ * Parse partial field "start-end" into trim values
205
+ * e.g., "0-3.5" -> { trimStart: 0, trimEnd: 3.5 }
206
+ * e.g., "2-" -> { trimStart: 2, trimEnd: undefined }
207
+ */
208
+ declare function parsePartial(partial: string | undefined): {
209
+ trimStart?: number;
210
+ trimEnd?: number;
211
+ };
212
+ /**
213
+ * Extract a message string from an unknown error value
214
+ */
215
+ declare function getErrorMessage(err: unknown): string;
216
+ /**
217
+ * Convert text to Title Case, keeping prepositions/articles lowercase
218
+ * First word is always capitalized
219
+ */
220
+ declare function toTitleCase(text: string): string;
221
+
222
+ /**
223
+ * AI prompts for demo plan generation
224
+ */
225
+
226
+ declare function buildSystemPrompt(maxSteps: number): string;
227
+ declare function buildUserPrompt(url: string, title: string, elements: ElementInfo[], langName: string | null, description: string | undefined, maxSteps: number): string;
228
+
229
+ /**
230
+ * Shared constants for page scraping and element filtering
231
+ * Used by both CLI and web versions
232
+ */
233
+ declare const EXCLUDED_LINK_PATTERNS: string[];
234
+ /** CSS selectors for interactive page elements */
235
+ declare const INTERACTIVE_SELECTORS: string[];
236
+ /** Check if link text or href matches an excluded pattern */
237
+ declare function isExcludedLink(text: string, href?: string): boolean;
238
+ /** Check if a link should be skipped during crawling */
239
+ declare function shouldSkipLink(text: string, href: string, currentPath: string): boolean;
240
+
241
+ type Tier = 'free' | 'pro';
242
+ declare const FEATURES: Record<string, string[]>;
243
+ interface SparkSubscription {
244
+ payment_type: 'subscription' | 'one_time';
245
+ status: 'active' | 'trialing' | 'past_due' | 'canceled' | 'lifetime';
246
+ is_lifetime: boolean;
247
+ current_period_end: string;
248
+ cancel_at_period_end: boolean;
249
+ billing_interval: 'monthly' | 'yearly' | 'one_time';
250
+ price_id: string;
251
+ created_at: string;
252
+ }
253
+ interface SparkTrial {
254
+ is_expired: boolean;
255
+ days_remaining: number;
256
+ uses_remaining: number;
257
+ max_days: number;
258
+ max_uses: number;
259
+ }
260
+ interface SparkStatus {
261
+ subscription: SparkSubscription | null;
262
+ verified: boolean;
263
+ registered: boolean;
264
+ usage_count: number;
265
+ trial: SparkTrial | null;
266
+ message?: string;
267
+ }
268
+ declare const getStatus: (email: string) => Promise<SparkStatus>;
269
+ declare function getStatusCached(email: string): Promise<SparkStatus>;
270
+ declare function getTier(d: SparkStatus): Tier;
271
+ declare const isPaid: (d: SparkStatus) => boolean;
272
+ declare const hasAccess: (d: SparkStatus, min: Tier) => boolean;
273
+ declare const hasTrialRemaining: (d: SparkStatus) => boolean;
274
+ declare const showPaywall: (d: SparkStatus) => boolean;
275
+ declare const isCanceling: (d: SparkStatus) => boolean;
276
+ /** Resolve tier directly from an email — the most common consumer call. Falls back to 'free' on error. */
277
+ declare function getTierByEmail(email: string): Promise<Tier>;
278
+ /** Check whether an email is verified. Falls back to false on error. */
279
+ declare function isVerified(email: string): Promise<boolean>;
280
+ declare function pricingUrl(opts?: {
281
+ email?: string;
282
+ returnUrl?: string;
283
+ }): string;
284
+
285
+ declare const LANGUAGE_VOICES: Record<string, string>;
286
+
287
+ export { type AIError as A, isPaid as B, type Config as C, DEFAULT_CAPTIONS as D, EXCLUDED_LINK_PATTERNS as E, FEATURES as F, isVerified as G, type HighlightMode as H, INTERACTIVE_SELECTORS as I, normalizeUrl as J, parseAIPlanResponse as K, LANGUAGE_VOICES as L, parsePartial as M, pricingUrl as N, rgbaToHex as O, type Plan as P, shouldSkipLink as Q, type RateLimitInfo as R, type SparkStatus as S, type Tier as T, type UserTier as U, VERSION as V, showPaywall as W, toTitleCase as X, windowsPathToWSL as Y, getTier as Z, type AIResponse as a, type AIResult as b, CONFIG_FILE as c, type CaptionStyle as d, type CaptionWordStyle as e, DEFAULT_CONFIG as f, type ElementInfo as g, type ElementType as h, type SparkSubscription as i, type SparkTrial as j, type Step as k, type SuggestedAction as l, buildSystemPrompt as m, buildUserPrompt as n, callAI as o, crawlPage as p, getErrorMessage as q, getLanguageName as r, getStatus as s, getStatusCached as t, getTierByEmail as u, hasAccess as v, hasTrialRemaining as w, hexToASS as x, isCanceling as y, isExcludedLink as z };
package/dist/web.d.mts ADDED
@@ -0,0 +1,102 @@
1
+ export { A as AIError, a as AIResponse, b as AIResult, E as EXCLUDED_LINK_PATTERNS, g as ElementInfo, h as ElementType, F as FEATURES, H as HighlightMode, I as INTERACTIVE_SELECTORS, L as LANGUAGE_VOICES, P as Plan, R as RateLimitInfo, S as SparkStatus, i as SparkSubscription, j as SparkTrial, k as Step, l as SuggestedAction, T as Tier, m as buildSystemPrompt, n as buildUserPrompt, o as callAI, p as crawlPage, q as getErrorMessage, r as getLanguageName, s as getStatus, t as getStatusCached, Z as getTier, u as getTierByEmail, v as hasAccess, w as hasTrialRemaining, x as hexToASS, y as isCanceling, z as isExcludedLink, B as isPaid, G as isVerified, J as normalizeUrl, K as parseAIPlanResponse, M as parsePartial, N as pricingUrl, O as rgbaToHex, Q as shouldSkipLink, W as showPaywall, X as toTitleCase, Y as windowsPathToWSL } from './voices-BtYZey4Y.mjs';
2
+
3
+ /**
4
+ * Plan Validation - Shared between CLI and Web
5
+ * Contains validation logic, prompts, and value preservation utilities
6
+ */
7
+ /** Action types supported by QuickPeek */
8
+ type StepAction = 'navigate' | 'click' | 'type' | 'select' | 'check' | 'wait' | 'scroll' | 'upload' | 'drag' | 'media' | 'showDownload';
9
+ /** Base step structure - shared between CLI and Web */
10
+ interface BaseStep {
11
+ action: StepAction | string;
12
+ target?: string;
13
+ value?: string;
14
+ caption?: string;
15
+ description?: string;
16
+ }
17
+ /** CLI step format */
18
+ interface CLIStep extends BaseStep {
19
+ id: number;
20
+ caption: string;
21
+ duration?: number;
22
+ zoom?: number;
23
+ }
24
+ /** CLI plan format */
25
+ interface CLIPlan {
26
+ url: string;
27
+ title: string;
28
+ description: string;
29
+ steps: CLIStep[];
30
+ }
31
+ /** Validation failure info */
32
+ interface StepFailure {
33
+ stepIndex: number;
34
+ step: BaseStep;
35
+ error: string;
36
+ suggestion?: string;
37
+ }
38
+ /** Invalid target patterns - only filter out clearly wrong targets (file paths, generic terms) */
39
+ declare const INVALID_TARGETS: RegExp[];
40
+ /** Actions that require a target element */
41
+ declare const ACTIONS_REQUIRING_TARGET: string[];
42
+ /**
43
+ * Check if a step target is invalid (matches known bad patterns)
44
+ */
45
+ declare function isInvalidTarget(target: string): boolean;
46
+ /**
47
+ * Validate a single plan step
48
+ * Returns null if valid, error message if invalid
49
+ */
50
+ declare function validateStep(step: BaseStep & {
51
+ mediaFile?: string;
52
+ }): string | null;
53
+ /**
54
+ * Check if a step is valid (returns boolean for filter operations)
55
+ */
56
+ declare function isValidStep(step: BaseStep): boolean;
57
+ /**
58
+ * Filter and validate plan steps, returning only valid ones
59
+ */
60
+ declare function filterValidSteps<T extends BaseStep>(steps: T[]): T[];
61
+ /** System prompt for refining plans based on user feedback */
62
+ declare const REFINE_PLAN_SYSTEM_PROMPT = "You refine demo video plans based on user feedback.\n\nAVAILABLE ACTIONS (use these exact formats):\n\n1. WAIT - Pause for narration (intro/outro/explanations)\n Format: { \"action\": \"wait\", \"caption\": \"Your narration text...\" }\n Use when: Starting intro, ending outro, explaining something without interaction\n NO target needed\n\n2. CLICK - Click buttons, links, or interactive elements\n Format: { \"action\": \"click\", \"target\": \"button text\", \"caption\": \"Click description...\" }\n Target: Just the button/link text (case insensitive, partial match OK)\n Examples: \"extract frame\", \"download\", \"submit\", \"next\"\n Use when: User says \"click\", \"press\", \"tap\", \"select button\", \"open\", \"close\"\n\n3. TYPE - Enter text into input fields\n Format: { \"action\": \"type\", \"target\": \"input[name=\\\"field\\\"]\", \"value\": \"text to type\", \"caption\": \"...\" }\n Selectors: input[type=\"text\"], input[name=\"...\"], textarea, #id\n Use when: User says \"type\", \"enter\", \"input\", \"fill in\", \"write\"\n CRITICAL: PRESERVE existing value - never change what's being typed\n\n4. UPLOAD - Upload a file to a web form's file input element\n Format: { \"action\": \"upload\", \"target\": \"input[type=\\\"file\\\"]\", \"value\": \"path/to/file\", \"caption\": \"...\" }\n Target: REQUIRED - CSS selector for file input, usually input[type=\"file\"]\n Value: Path to file being uploaded\n Use when: Uploading a file TO a website's form (the page has a file picker)\n CRITICAL: PRESERVE existing value - never change the file path\n\n5. SCROLL - Scroll page or zoom camera\n Format: { \"action\": \"scroll\", \"value\": \"direction\", \"caption\": \"...\" }\n Values: \"up\", \"down\", \"bottom\", \"80%\" (page scroll) OR \"-10\", \"10\" (zoom: negative=out, positive=in)\n Use when: User says \"scroll\", \"zoom in\", \"zoom out\", \"show more\", \"go to bottom\"\n NO target needed\n\n6. DRAG - Drag sliders or rotate 3D objects\n Format: { \"action\": \"drag\", \"target\": \"input[type=\\\"range\\\"]\", \"value\": \"50\", \"caption\": \"...\" }\n Values: \"0\"-\"100\" for sliders, \"rotate\" for 3D rotation (stays at new angle), \"around\" for full 360\u00B0 (returns to start)\n Selectors: input[type=\"range\"], canvas, .slider\n Use when: User says \"drag\", \"slide\", \"adjust slider\", \"rotate\", \"spin\", \"move\"\n NOTE: Use \"rotate\" (not \"around\") for showcasing 3D models - it rotates ~270\u00B0 and stays at the new position\n\n7. SELECT - Choose option from dropdown\n Format: { \"action\": \"select\", \"target\": \"select[name=\\\"..\\\"]\", \"value\": \"option text\", \"caption\": \"...\" }\n Selector: select, select[name=\"...\"], #id\n Use when: User says \"select\", \"choose\", \"pick from dropdown\", \"change option\"\n\n8. CHECK - Toggle checkbox\n Format: { \"action\": \"check\", \"target\": \"input[type=\\\"checkbox\\\"]\", \"caption\": \"...\" }\n Selector: input[type=\"checkbox\"], [role=\"checkbox\"]\n Use when: User says \"check\", \"uncheck\", \"toggle\", \"enable\", \"disable\"\n\n9. MEDIA - Display a media file fullscreen (NOT for uploading to a form!)\n Format: { \"action\": \"media\", \"value\": \"path/to/file.png\", \"caption\": \"...\" }\n Target: OPTIONAL - \"scale\" (fill viewport) or \"center\" (original size). Defaults to center.\n Value: REQUIRED - File path to display\n Supported: .png, .jpg, .jpeg, .gif, .webp, .mp4, .webm, .mov, .glb\n Use when: Showing a file directly in the demo (screenshot, 3D model, video clip)\n NOT for uploading - use UPLOAD action if page has a file input\n CRITICAL: PRESERVE existing value - never change the file path\n\n10. SHOW_DOWNLOAD - Display a download animation/result\n Format: { \"action\": \"showDownload\", \"caption\": \"...\" }\n Use when: Showing the final result after a download action\n NO target needed\n\nIMPORTANT - UPLOAD vs MEDIA:\n\u2022 UPLOAD: File goes INTO a web form (page has <input type=\"file\">). Requires target selector.\n\u2022 MEDIA: File is DISPLAYED fullscreen in demo (no web interaction). No target needed.\nExample: \"Show the 3D model\" \u2192 use MEDIA action\nExample: \"Upload a file to the converter\" \u2192 use UPLOAD action\n\nTARGET SYNTAX (simplified):\n\u2022 Buttons/Links: Just use the text! \"extract frame\", \"download\", \"submit\" (case insensitive)\n\u2022 Inputs: input[type=\"text\"], input[name=\"field\"], input[type=\"file\"], input[type=\"range\"]\n\u2022 By ID: #elementId (only if text won't work)\n\u2022 By class: .className (only if text won't work)\n\nPREFER SIMPLE TEXT for buttons: \"download\" instead of button:has-text(\"Download\")\n\nDETECTING USER INTENT:\n\u2022 \"add intro/outro\" \u2192 add wait step at start/end\n\u2022 \"remove step X\" \u2192 delete that step\n\u2022 \"change caption\" \u2192 update the caption text only\n\u2022 \"click X instead\" \u2192 change target to X\n\u2022 \"add a click on X\" \u2192 insert new click step\n\u2022 \"show the slider\" \u2192 add drag step for input[type=\"range\"]\n\u2022 \"zoom in/out\" \u2192 add scroll with numeric value\n\u2022 \"reorder\" \u2192 rearrange step sequence\n\nRULES:\n\u2022 Return ONLY valid JSON\n\u2022 Keep step ids sequential (1, 2, 3...)\n\u2022 PRESERVE upload/type values EXACTLY - copy from input unchanged\n\u2022 Only modify steps mentioned in feedback\n\u2022 Use available elements list when provided to find correct selectors\n\nReturn ONLY the modified JSON plan:\n{\n \"steps\": [\n { \"id\": 1, \"action\": \"wait\", \"caption\": \"intro text\" },\n { \"id\": 2, \"action\": \"click\", \"target\": \"start\", \"caption\": \"Click to begin\" },\n { \"id\": 3, \"action\": \"upload\", \"target\": \"input[type=\\\"file\\\"]\", \"value\": \"path/to/file.png\", \"caption\": \"Upload the file\" },\n { \"id\": 4, \"action\": \"click\", \"target\": \"extract\", \"caption\": \"Process the file\" },\n { \"id\": 5, \"action\": \"media\", \"value\": \"path/to/result.png\", \"caption\": \"Here's the result\" },\n ...\n ]\n}";
63
+ /** System prompt for fixing failed steps using AI */
64
+ declare const FIX_PLAN_SYSTEM_PROMPT = "You are a web automation expert. Fix demo plan steps that failed validation.\n\nRULES:\n\u2022 Return ONLY valid JSON with the complete plan structure\n\u2022 Fix ONLY the failed steps - keep working steps unchanged\n\u2022 Use the available page elements to find correct selectors\n\u2022 For click targets: use simplified button text like \"extract frame\", \"download\" (case insensitive)\n\u2022 For elements not found, check if a similar element exists in the page elements list\n\u2022 If an element truly doesn't exist, remove the step or change the action\n\u2022 Preserve file paths in \"value\" fields\n\u2022 Keep step ids sequential starting from 1\n\nTARGET PATTERNS:\n\u2022 Buttons/Links: Just the text! \"extract frame\", \"download\", \"submit\" (case insensitive)\n\u2022 File inputs: input[type=\"file\"]\n\u2022 Sliders: input[type=\"range\"]\n\u2022 Text inputs: input[name=\"field\"], #id, [placeholder=\"...\"]\n\nACTION FORMATS:\n\u2022 click: { \"target\": \"download\" } - use simplified button text\n\u2022 scroll: { \"value\": \"up|down\" } for page, { \"value\": \"10|-10\" } for zoom (positive=in, negative=out)\n\u2022 drag: { \"target\": \"input[type=\\\"range\\\"]\", \"value\": \"10\" } for sliders, { \"value\": \"rotate\" } for 3D rotation (auto-targets canvas)\n\u2022 media: { \"value\": \"path/to/file.png\" } - display file fullscreen (NOT upload!)\n\u2022 upload: { \"target\": \"input[type=\\\"file\\\"]\", \"value\": \"path/to/file\" } - upload to form\n\nIMPORTANT: Only use elements that actually exist on the page based on the provided list.";
65
+ /** Collected values from original plan steps for preservation */
66
+ interface PreservedValues {
67
+ uploadSteps: Array<{
68
+ value: string | undefined;
69
+ target: string | undefined;
70
+ mediaFile: string | undefined;
71
+ mediaType: string | undefined;
72
+ }>;
73
+ mediaSteps: Array<{
74
+ mediaFile: string | undefined;
75
+ mediaType: string | undefined;
76
+ target: string | undefined;
77
+ }>;
78
+ otherValues: Map<string, string>;
79
+ }
80
+ /**
81
+ * Collect values from original plan that need to be preserved through AI modifications
82
+ */
83
+ declare function collectPreservedValues<T extends BaseStep & {
84
+ mediaFile?: string;
85
+ mediaType?: string;
86
+ }>(steps: T[]): PreservedValues;
87
+ /**
88
+ * Restore preserved values to AI-modified steps
89
+ * Returns indices of how many upload/media steps were restored
90
+ */
91
+ declare function restorePreservedValues<T extends BaseStep & {
92
+ mediaFile?: string;
93
+ mediaType?: string;
94
+ }>(step: T, preserved: PreservedValues, indices: {
95
+ uploadIdx: number;
96
+ mediaIdx: number;
97
+ }): {
98
+ uploadIdx: number;
99
+ mediaIdx: number;
100
+ };
101
+
102
+ export { ACTIONS_REQUIRING_TARGET, type BaseStep, type CLIPlan, type CLIStep, FIX_PLAN_SYSTEM_PROMPT, INVALID_TARGETS, type PreservedValues, REFINE_PLAN_SYSTEM_PROMPT, type StepAction, type StepFailure, collectPreservedValues, filterValidSteps, isInvalidTarget, isValidStep, restorePreservedValues, validateStep };