import type { VoiceInstallProgressSnapshot } from './install-progress.js'; import { type PiperEngineManifest, type PiperVoiceManifest, type WhisperEngineManifest, type WhisperModelManifest, type VoicePlatform } from './manifest.js'; /** What the last successful install put on disk (versions) and wrote to config. */ export interface VoiceInstallStamp { readonly engineVersion: string; readonly voiceId: string; /** Installed whisper engine version (absent when STT is not provisioned). */ readonly sttEngineVersion?: string | undefined; /** Installed whisper model id (absent when STT is not provisioned). */ readonly sttModelId?: string | undefined; /** The exact voice.local.* values THIS installer wrote (ownership marker). */ readonly configWrites: Record; } export interface ManagedVoicePaths { readonly managedRoot: string; readonly enginesDir: string; readonly modelsDir: string; readonly piperArchive: string; readonly piperBinary: string; readonly defaultVoiceOnnx: string; readonly defaultVoiceJson: string; /** The whisper bundle archive path, ALSO the sideload drop location. */ readonly whisperArchive: string; readonly whisperBinary: string; readonly whisperModel: string; } export declare function resolveManagedVoicePaths(managedRoot: string, platform?: VoicePlatform | null): ManagedVoicePaths; /** Read the install stamp, or null when absent/corrupt. */ export declare function readVoiceInstallStamp(managedRoot: string): VoiceInstallStamp | null; /** Persist the install stamp (best effort, a failed stamp write is logged, not fatal). */ export declare function writeVoiceInstallStamp(managedRoot: string, stamp: VoiceInstallStamp): void; export type ProvisionPhase = 'skip' | 'download' | 'verify' | 'extract' | 'done' | 'error'; export interface VoiceProvisionProgress { readonly component: string; readonly phase: ProvisionPhase; readonly message?: string | undefined; /** The component's pinned size in bytes, where the manifest knows it. */ readonly bytesTotal?: number | undefined; /** * Bytes landed on disk, where known. Downloads verify whole-file (atomic * temp+rename), so this is reported at completion boundaries (done/skip), * not incrementally mid-transfer. */ readonly bytesDone?: number | undefined; } export type TtsProvisionState = 'provisioned' | 'unsupported-platform' | 'download-failed' | 'checksum-mismatch'; /** * STT terminal states. `bundle-unavailable`: no hosted URL and no sideloaded * archive (and no usable binary). `sideload-mismatch`: an archive IS present at * the sideload path but fails the current pin, so it is refused rather than * extracted, reported explicitly so the user knows to rebuild/replace it. */ export type SttProvisionState = TtsProvisionState | 'bundle-unavailable' | 'sideload-mismatch'; export interface VoiceComponentOutcome { readonly id: string; readonly state: 'installed' | 'skipped' | 'failed'; readonly bytes?: number | undefined; readonly error?: string | undefined; } export interface VoiceProvisionResult { readonly platform: VoicePlatform | null; readonly tts: { readonly engine: 'piper'; readonly state: TtsProvisionState; readonly binaryPath?: string | undefined; readonly modelPath?: string | undefined; readonly reason?: string | undefined; }; readonly stt: { readonly engine: 'whisper-cpp'; readonly state: SttProvisionState; readonly binaryPath?: string | undefined; readonly modelPath?: string | undefined; readonly reason?: string | undefined; }; readonly components: readonly VoiceComponentOutcome[]; } export type ArchiveExtractor = (archivePath: string, destDir: string) => Promise; export interface VoiceProvisionOptions { readonly managedRoot: string; readonly fetchImpl?: typeof fetch | undefined; readonly onProgress?: ((progress: VoiceProvisionProgress) => void) | undefined; readonly extractArchive?: ArchiveExtractor | undefined; /** Override the detected platform (tests). */ readonly platform?: VoicePlatform | null | undefined; /** Override the pinned engine manifest (tests / staged rollouts). */ readonly engineOverride?: PiperEngineManifest | undefined; /** Override the pinned default voice manifest (tests / staged rollouts). */ readonly voiceOverride?: PiperVoiceManifest | undefined; /** Override the pinned whisper engine manifest (tests / staged rollouts). */ readonly whisperOverride?: WhisperEngineManifest | undefined; /** Override the pinned whisper model manifest (tests / staged rollouts). */ readonly whisperModelOverride?: WhisperModelManifest | undefined; } /** Provision the managed local voice runtime (piper TTS + default voice). */ export declare function provisionLocalVoiceRuntime(options: VoiceProvisionOptions): Promise; export type VoiceRuntimeState = 'not-provisioned' | 'partial' | 'provisioned' | 'unsupported-platform'; export interface VoiceRuntimeStatus { readonly platform: VoicePlatform | null; readonly state: VoiceRuntimeState; readonly tts: { readonly engine: 'piper'; readonly binaryPresent: boolean; readonly voicePresent: boolean; readonly binaryPath: string; readonly modelPath: string; }; readonly stt: { readonly engine: 'whisper-cpp'; /** A pinned goodvibes whisper bundle exists for this platform. */ readonly supported: boolean; readonly state: 'not-provisioned' | 'partial' | 'provisioned' | 'unsupported-platform'; readonly binaryPresent: boolean; readonly modelPresent: boolean; readonly binaryPath: string; readonly modelPath: string; readonly reason?: string | undefined; }; /** Total download size of a fresh provision, in bytes (null on unsupported platforms). */ readonly offerBytes: number | null; /** * Present ONLY while a voice.local.install run is active: the live * per-component progress of that run (the daemon composition merges it in, * see install-progress.ts). Surfaces poll status during install to render * real progress instead of busy→receipt. */ readonly installInProgress?: VoiceInstallProgressSnapshot | undefined; } /** Report whether the managed voice runtime is installed, without touching the network. */ export declare function localVoiceRuntimeStatus(options: { managedRoot: string; platform?: VoicePlatform | null | undefined; }): VoiceRuntimeStatus; /** * Resolve managed engine binary + model for a config prefix, when the managed * install is present. Only TTS (piper) is managed; STT returns null (unsupported). */ export declare function resolveManagedEngine(prefix: 'stt' | 'tts', managedRoot: string, fileExists?: (path: string) => boolean): { engine: string; binary: string; modelPath: string; } | null; //# sourceMappingURL=provisioner.d.ts.map