interface FetchLikeResponse { ok: boolean; status: number; text(): Promise; json(): Promise; } export type FetchLike = (input: string, init?: { method?: string; headers?: Record; body?: string | Uint8Array; }) => Promise; /** * The 30 Google Flow system base-voice presets accepted by POST /voices `voice` * (case-sensitive). `createVoice` validates against this list so a typo'd preset * fails fast before the network rather than 400ing at the provider. */ export declare const FLOW_VOICE_PRESETS: readonly ["Achernar", "Achird", "Algenib", "Algieba", "Alnilam", "Aoede", "Autonoe", "Callirrhoe", "Charon", "Despina", "Enceladus", "Erinome", "Fenrir", "Gacrux", "Iapetus", "Kore", "Laomedeia", "Leda", "Orus", "Puck", "Pulcherrima", "Rasalgethi", "Sadachbia", "Sadaltager", "Schedar", "Sulafat", "Umbriel", "Vindemiatrix", "Zephyr", "Zubenelgenubi"]; export type FlowVoicePreset = typeof FLOW_VOICE_PRESETS[number]; export interface FlowLibraryClientOptions { apiToken: string; accountEmail: string; baseUrl?: string; /** Injectable fetch so tests run offline. Defaults to global fetch. */ fetchImpl?: FetchLike; /** Injectable file reader (returns raw image bytes). Defaults to fs.readFile. */ readFileImpl?: (path: string) => Promise; /** * captcha-retry auto-solve count sent on POST /voices (`captchaRetry`). Omit * (or 0) to send no field; the handler resolves it from VCLAW_FLOW_CAPTCHA_RETRY. */ captchaRetry?: number; } /** * Thin client for the Google Flow v1 Characters/Voices + asset-upload endpoints. * Pure transport — no fs/project knowledge beyond reading an image to upload. */ export declare class FlowLibraryClient { private readonly apiToken; private readonly accountEmail; private readonly baseUrl; private readonly fetchImpl; private readonly readFileImpl; private readonly captchaRetry?; constructor(options: FlowLibraryClientOptions); private authHeaders; private parse; /** Upload a local PNG/JPEG → returns its mediaGenerationId (for imageReference_*). */ uploadImage(imagePath: string): Promise; /** * POST /google-flow/characters — NO email in body (account from token). * Returns the saved character with its `character` ref string. */ createCharacter(params: { displayName: string; imageReference_1: string; imageReference_2?: string; voice?: string; personalityNotes?: string; }): Promise<{ entityId: string; character: string; voice?: string; }>; /** * POST /google-flow/voices — REQUIRES email in body. Returns the saved voice * with its `voice` ref string (usable as referenceAudio or a character voice). */ createVoice(params: { voice: string; displayName: string; dialog: string; voicePerformance: string; }): Promise<{ voice: string; baseVoice?: string; displayName?: string; }>; } /** One registered character in `flow-characters.json`. */ export interface FlowCharacterEntry { name: string; entityId: string; characterRef: string; voice?: string; } export interface FlowCharactersArtifact { schemaVersion: 1; projectSlug: string; generatedAt: string; characters: FlowCharacterEntry[]; } /** One registered custom voice in `flow-voices.json`. */ export interface FlowVoiceEntry { name: string; voiceRef: string; baseVoice?: string; } export interface FlowVoicesArtifact { schemaVersion: 1; projectSlug: string; generatedAt: string; voices: FlowVoiceEntry[]; } export interface FlowCharactersLookup { characters: FlowCharacterEntry[]; characterRefByName: Map; } /** * Read `artifacts/flow-characters.json`. Returns an empty lookup when absent so * the execution layer degrades gracefully (no `--character` flags) rather than * failing. A present-but-malformed file is NOT swallowed (JSON.parse surfaces it). */ export declare function readFlowCharacters(workspaceRoot: string, slug: string): Promise; /** Read `artifacts/flow-voices.json` → name -> voice ref (empty when absent). */ export declare function readFlowVoices(workspaceRoot: string, slug: string): Promise>; export interface FlowCharacterInput { /** Project-facing character name (matches a storyboard scene's `characters`). */ name: string; /** 1-2 local image paths to upload, OR already-uploaded mediaGenerationIds. */ images: string[]; /** Optional voice: a system preset (e.g. "Charon") or a user voice ref. */ voice?: string; /** Optional personality notes (≤2000 chars). */ personalityNotes?: string; /** Optional display name override (defaults to `name`). */ displayName?: string; } /** * Register characters with Google Flow and write `flow-characters.json`. Each * input's images are uploaded (local paths) or used directly (existing refs), * then bundled into a saved character. `generatedAt` is injected (callers stamp * it) so this stays deterministic/testable. */ export declare function registerFlowCharacters(opts: { workspaceRoot: string; slug: string; characters: FlowCharacterInput[]; client: FlowLibraryClient; generatedAt: string; }): Promise; export interface FlowVoiceInput { name: string; basePreset: string; dialog: string; voicePerformance: string; } /** Register custom voices with Google Flow and write `flow-voices.json`. */ export declare function registerFlowVoices(opts: { workspaceRoot: string; slug: string; voices: FlowVoiceInput[]; client: FlowLibraryClient; generatedAt: string; }): Promise; export {}; //# sourceMappingURL=flow-character-library.d.ts.map