UNPKG

consortium

Version:

Remote control and session sharing CLI for AI coding agents

2,679 lines • 102 kB
import { z } from 'zod';
import { EventEmitter } from 'node:events';
import { Socket } from 'socket.io-client';
import { ExpoPushMessage } from 'expo-server-sdk';

/**
 * Simplified schema that only validates fields actually used in the codebase
 * while preserving all other fields through passthrough()
 */

declare const UsageSchema: z.ZodObject<{
    input_tokens: z.ZodNumber;
    cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
    cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
    output_tokens: z.ZodNumber;
    service_tier: z.ZodOptional<z.ZodString>;
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
    input_tokens: z.ZodNumber;
    cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
    cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
    output_tokens: z.ZodNumber;
    service_tier: z.ZodOptional<z.ZodString>;
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
    input_tokens: z.ZodNumber;
    cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
    cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
    output_tokens: z.ZodNumber;
    service_tier: z.ZodOptional<z.ZodString>;
}, z.ZodTypeAny, "passthrough">>;
declare const RawJSONLinesSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
    type: z.ZodLiteral<"user">;
    isSidechain: z.ZodOptional<z.ZodBoolean>;
    isMeta: z.ZodOptional<z.ZodBoolean>;
    uuid: z.ZodString;
    message: z.ZodObject<{
        content: z.ZodUnion<[z.ZodString, z.ZodAny]>;
    }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
        content: z.ZodUnion<[z.ZodString, z.ZodAny]>;
    }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
        content: z.ZodUnion<[z.ZodString, z.ZodAny]>;
    }, z.ZodTypeAny, "passthrough">>;
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
    type: z.ZodLiteral<"user">;
    isSidechain: z.ZodOptional<z.ZodBoolean>;
    isMeta: z.ZodOptional<z.ZodBoolean>;
    uuid: z.ZodString;
    message: z.ZodObject<{
        content: z.ZodUnion<[z.ZodString, z.ZodAny]>;
    }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
        content: z.ZodUnion<[z.ZodString, z.ZodAny]>;
    }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
        content: z.ZodUnion<[z.ZodString, z.ZodAny]>;
    }, z.ZodTypeAny, "passthrough">>;
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
    type: z.ZodLiteral<"user">;
    isSidechain: z.ZodOptional<z.ZodBoolean>;
    isMeta: z.ZodOptional<z.ZodBoolean>;
    uuid: z.ZodString;
    message: z.ZodObject<{
        content: z.ZodUnion<[z.ZodString, z.ZodAny]>;
    }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
        content: z.ZodUnion<[z.ZodString, z.ZodAny]>;
    }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
        content: z.ZodUnion<[z.ZodString, z.ZodAny]>;
    }, z.ZodTypeAny, "passthrough">>;
}, z.ZodTypeAny, "passthrough">>, z.ZodObject<{
    uuid: z.ZodString;
    type: z.ZodLiteral<"assistant">;
    message: z.ZodOptional<z.ZodObject<{
        usage: z.ZodOptional<z.ZodObject<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, z.ZodTypeAny, "passthrough">>>;
        model: z.ZodOptional<z.ZodString>;
    }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
        usage: z.ZodOptional<z.ZodObject<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, z.ZodTypeAny, "passthrough">>>;
        model: z.ZodOptional<z.ZodString>;
    }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
        usage: z.ZodOptional<z.ZodObject<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, z.ZodTypeAny, "passthrough">>>;
        model: z.ZodOptional<z.ZodString>;
    }, z.ZodTypeAny, "passthrough">>>;
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
    uuid: z.ZodString;
    type: z.ZodLiteral<"assistant">;
    message: z.ZodOptional<z.ZodObject<{
        usage: z.ZodOptional<z.ZodObject<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, z.ZodTypeAny, "passthrough">>>;
        model: z.ZodOptional<z.ZodString>;
    }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
        usage: z.ZodOptional<z.ZodObject<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, z.ZodTypeAny, "passthrough">>>;
        model: z.ZodOptional<z.ZodString>;
    }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
        usage: z.ZodOptional<z.ZodObject<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, z.ZodTypeAny, "passthrough">>>;
        model: z.ZodOptional<z.ZodString>;
    }, z.ZodTypeAny, "passthrough">>>;
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
    uuid: z.ZodString;
    type: z.ZodLiteral<"assistant">;
    message: z.ZodOptional<z.ZodObject<{
        usage: z.ZodOptional<z.ZodObject<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, z.ZodTypeAny, "passthrough">>>;
        model: z.ZodOptional<z.ZodString>;
    }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
        usage: z.ZodOptional<z.ZodObject<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, z.ZodTypeAny, "passthrough">>>;
        model: z.ZodOptional<z.ZodString>;
    }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
        usage: z.ZodOptional<z.ZodObject<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
            input_tokens: z.ZodNumber;
            cache_creation_input_tokens: z.ZodOptional<z.ZodNumber>;
            cache_read_input_tokens: z.ZodOptional<z.ZodNumber>;
            output_tokens: z.ZodNumber;
            service_tier: z.ZodOptional<z.ZodString>;
        }, z.ZodTypeAny, "passthrough">>>;
        model: z.ZodOptional<z.ZodString>;
    }, z.ZodTypeAny, "passthrough">>>;
}, z.ZodTypeAny, "passthrough">>, z.ZodObject<{
    type: z.ZodLiteral<"summary">;
    summary: z.ZodString;
    leafUuid: z.ZodString;
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
    type: z.ZodLiteral<"summary">;
    summary: z.ZodString;
    leafUuid: z.ZodString;
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
    type: z.ZodLiteral<"summary">;
    summary: z.ZodString;
    leafUuid: z.ZodString;
}, z.ZodTypeAny, "passthrough">>, z.ZodObject<{
    type: z.ZodLiteral<"system">;
    uuid: z.ZodString;
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
    type: z.ZodLiteral<"system">;
    uuid: z.ZodString;
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
    type: z.ZodLiteral<"system">;
    uuid: z.ZodString;
}, z.ZodTypeAny, "passthrough">>]>;
type RawJSONLines = z.infer<typeof RawJSONLinesSchema>;

/**
 * Permission mode type - includes both Claude and Codex modes
 * Must match MessageMetaSchema.permissionMode enum values
 *
 * Claude modes: default, acceptEdits, bypassPermissions, plan
 * Codex modes: read-only, safe-yolo, yolo
 *
 * When calling Claude SDK, Codex modes are mapped at the SDK boundary:
 * - yolo → bypassPermissions
 * - safe-yolo → default
 * - read-only → default
 */
type PermissionMode = 'default' | 'acceptEdits' | 'bypassPermissions' | 'plan' | 'read-only' | 'safe-yolo' | 'yolo';
/**
 * Usage data type from Claude
 */
type Usage = z.infer<typeof UsageSchema>;
/**
 * Update event from server
 */
declare const UpdateSchema: z.ZodObject<{
    id: z.ZodString;
    seq: z.ZodNumber;
    body: z.ZodUnion<[z.ZodObject<{
        message: z.ZodObject<{
            id: z.ZodString;
            seq: z.ZodNumber;
            content: z.ZodObject<{
                c: z.ZodString;
                t: z.ZodLiteral<"encrypted">;
            }, "strip", z.ZodTypeAny, {
                c: string;
                t: "encrypted";
            }, {
                c: string;
                t: "encrypted";
            }>;
        }, "strip", z.ZodTypeAny, {
            content: {
                c: string;
                t: "encrypted";
            };
            id: string;
            seq: number;
        }, {
            content: {
                c: string;
                t: "encrypted";
            };
            id: string;
            seq: number;
        }>;
        sid: z.ZodString;
        t: z.ZodLiteral<"new-message">;
    }, "strip", z.ZodTypeAny, {
        message: {
            content: {
                c: string;
                t: "encrypted";
            };
            id: string;
            seq: number;
        };
        t: "new-message";
        sid: string;
    }, {
        message: {
            content: {
                c: string;
                t: "encrypted";
            };
            id: string;
            seq: number;
        };
        t: "new-message";
        sid: string;
    }>, z.ZodObject<{
        t: z.ZodLiteral<"update-session">;
        sid: z.ZodString;
        metadata: z.ZodOptional<z.ZodNullable<z.ZodObject<{
            version: z.ZodNumber;
            value: z.ZodString;
        }, "strip", z.ZodTypeAny, {
            value: string;
            version: number;
        }, {
            value: string;
            version: number;
        }>>>;
        agentState: z.ZodOptional<z.ZodNullable<z.ZodObject<{
            version: z.ZodNumber;
            value: z.ZodString;
        }, "strip", z.ZodTypeAny, {
            value: string;
            version: number;
        }, {
            value: string;
            version: number;
        }>>>;
    }, "strip", z.ZodTypeAny, {
        t: "update-session";
        sid: string;
        metadata?: {
            value: string;
            version: number;
        } | null | undefined;
        agentState?: {
            value: string;
            version: number;
        } | null | undefined;
    }, {
        t: "update-session";
        sid: string;
        metadata?: {
            value: string;
            version: number;
        } | null | undefined;
        agentState?: {
            value: string;
            version: number;
        } | null | undefined;
    }>, z.ZodObject<{
        t: z.ZodLiteral<"update-machine">;
        machineId: z.ZodString;
        metadata: z.ZodOptional<z.ZodNullable<z.ZodObject<{
            version: z.ZodNumber;
            value: z.ZodString;
        }, "strip", z.ZodTypeAny, {
            value: string;
            version: number;
        }, {
            value: string;
            version: number;
        }>>>;
        daemonState: z.ZodOptional<z.ZodNullable<z.ZodObject<{
            version: z.ZodNumber;
            value: z.ZodString;
        }, "strip", z.ZodTypeAny, {
            value: string;
            version: number;
        }, {
            value: string;
            version: number;
        }>>>;
    }, "strip", z.ZodTypeAny, {
        t: "update-machine";
        machineId: string;
        metadata?: {
            value: string;
            version: number;
        } | null | undefined;
        daemonState?: {
            value: string;
            version: number;
        } | null | undefined;
    }, {
        t: "update-machine";
        machineId: string;
        metadata?: {
            value: string;
            version: number;
        } | null | undefined;
        daemonState?: {
            value: string;
            version: number;
        } | null | undefined;
    }>]>;
    createdAt: z.ZodNumber;
}, "strip", z.ZodTypeAny, {
    id: string;
    seq: number;
    body: {
        message: {
            content: {
                c: string;
                t: "encrypted";
            };
            id: string;
            seq: number;
        };
        t: "new-message";
        sid: string;
    } | {
        t: "update-session";
        sid: string;
        metadata?: {
            value: string;
            version: number;
        } | null | undefined;
        agentState?: {
            value: string;
            version: number;
        } | null | undefined;
    } | {
        t: "update-machine";
        machineId: string;
        metadata?: {
            value: string;
            version: number;
        } | null | undefined;
        daemonState?: {
            value: string;
            version: number;
        } | null | undefined;
    };
    createdAt: number;
}, {
    id: string;
    seq: number;
    body: {
        message: {
            content: {
                c: string;
                t: "encrypted";
            };
            id: string;
            seq: number;
        };
        t: "new-message";
        sid: string;
    } | {
        t: "update-session";
        sid: string;
        metadata?: {
            value: string;
            version: number;
        } | null | undefined;
        agentState?: {
            value: string;
            version: number;
        } | null | undefined;
    } | {
        t: "update-machine";
        machineId: string;
        metadata?: {
            value: string;
            version: number;
        } | null | undefined;
        daemonState?: {
            value: string;
            version: number;
        } | null | undefined;
    };
    createdAt: number;
}>;
type Update = z.infer<typeof UpdateSchema>;
/**
 * Session information
 */
type Session = {
    id: string;
    /**
     * Server-side idempotency tag for this session. Two `getOrCreateSession`
     * calls with the same `tag` return the same row, so callers who want
     * to resume an existing session (e.g. `consortium code --resume <id>`)
     * must pass the original tag — not a fresh random one. Surfacing it
     * here so the TUI wizard can hand it to the spawned agent process.
     */
    tag: string;
    seq: number;
    encryptionKey: Uint8Array;
    encryptionVariant: 'legacy' | 'dataKey';
    /**
     * The user's content X25519 public key (from `credential.encryption` when
     * type is 'dataKey'). Used to wrap per-artifact DEKs when the CLI creates
     * library artifacts via /v1/artifacts. Undefined for legacy-encryption
     * accounts (which cannot create interactive artifacts).
     */
    userContentPublicKey?: Uint8Array;
    metadata: Metadata;
    metadataVersion: number;
    agentState: AgentState | null;
    agentStateVersion: number;
};
declare const MachineMetadataSchema: z.ZodObject<{
    host: z.ZodString;
    platform: z.ZodString;
    consortiumCliVersion: z.ZodString;
    homeDir: z.ZodString;
    consortiumHomeDir: z.ZodString;
    consortiumLibDir: z.ZodString;
    cpuCount: z.ZodOptional<z.ZodNumber>;
    memoryTotalMb: z.ZodOptional<z.ZodNumber>;
    hardware: z.ZodOptional<z.ZodObject<{
        schemaVersion: z.ZodLiteral<1>;
        platform: z.ZodString;
        arch: z.ZodString;
        cpuModel: z.ZodString;
        cpuCoresPhysical: z.ZodNumber;
        cpuThreads: z.ZodNumber;
        ramTotalBytes: z.ZodNumber;
        gpus: z.ZodArray<z.ZodObject<{
            vendor: z.ZodEnum<["apple", "nvidia", "amd", "intel", "unknown"]>;
            name: z.ZodString;
            vramBytes: z.ZodOptional<z.ZodNumber>;
            driver: z.ZodOptional<z.ZodString>;
            computeCapability: z.ZodOptional<z.ZodString>;
        }, "strip", z.ZodTypeAny, {
            vendor: "unknown" | "apple" | "nvidia" | "amd" | "intel";
            name: string;
            vramBytes?: number | undefined;
            driver?: string | undefined;
            computeCapability?: string | undefined;
        }, {
            vendor: "unknown" | "apple" | "nvidia" | "amd" | "intel";
            name: string;
            vramBytes?: number | undefined;
            driver?: string | undefined;
            computeCapability?: string | undefined;
        }>, "many">;
        unifiedMemory: z.ZodBoolean;
        usableModelBytes: z.ZodNumber;
        memBandwidthGBs: z.ZodOptional<z.ZodNumber>;
        bandwidthSource: z.ZodEnum<["measured", "chip-table", "unknown"]>;
        diskFreeBytes: z.ZodNumber;
        detectedAt: z.ZodNumber;
        warnings: z.ZodArray<z.ZodString, "many">;
    }, "strip", z.ZodTypeAny, {
        schemaVersion: 1;
        platform: string;
        arch: string;
        cpuModel: string;
        cpuCoresPhysical: number;
        cpuThreads: number;
        ramTotalBytes: number;
        gpus: {
            vendor: "unknown" | "apple" | "nvidia" | "amd" | "intel";
            name: string;
            vramBytes?: number | undefined;
            driver?: string | undefined;
            computeCapability?: string | undefined;
        }[];
        unifiedMemory: boolean;
        usableModelBytes: number;
        bandwidthSource: "unknown" | "measured" | "chip-table";
        diskFreeBytes: number;
        detectedAt: number;
        warnings: string[];
        memBandwidthGBs?: number | undefined;
    }, {
        schemaVersion: 1;
        platform: string;
        arch: string;
        cpuModel: string;
        cpuCoresPhysical: number;
        cpuThreads: number;
        ramTotalBytes: number;
        gpus: {
            vendor: "unknown" | "apple" | "nvidia" | "amd" | "intel";
            name: string;
            vramBytes?: number | undefined;
            driver?: string | undefined;
            computeCapability?: string | undefined;
        }[];
        unifiedMemory: boolean;
        usableModelBytes: number;
        bandwidthSource: "unknown" | "measured" | "chip-table";
        diskFreeBytes: number;
        detectedAt: number;
        warnings: string[];
        memBandwidthGBs?: number | undefined;
    }>>;
    openclawInstalled: z.ZodOptional<z.ZodBoolean>;
    openclawVersion: z.ZodOptional<z.ZodNullable<z.ZodString>>;
    openclawWorkspaceExists: z.ZodOptional<z.ZodBoolean>;
    openclawGatewayRunning: z.ZodOptional<z.ZodBoolean>;
    openclawGatewayPort: z.ZodOptional<z.ZodNumber>;
    openclawChannels: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
    openclawAgentCount: z.ZodOptional<z.ZodNumber>;
    openclawAgents: z.ZodOptional<z.ZodArray<z.ZodObject<{
        name: z.ZodString;
        workspace: z.ZodString;
        agentDir: z.ZodString;
        model: z.ZodString;
        routingRules: z.ZodNumber;
        isDefault: z.ZodBoolean;
    }, "strip", z.ZodTypeAny, {
        model: string;
        name: string;
        workspace: string;
        agentDir: string;
        routingRules: number;
        isDefault: boolean;
    }, {
        model: string;
        name: string;
        workspace: string;
        agentDir: string;
        routingRules: number;
        isDefault: boolean;
    }>, "many">>;
    harnessInstances: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
        type: z.ZodString;
        family: z.ZodOptional<z.ZodString>;
        installed: z.ZodBoolean;
        version: z.ZodOptional<z.ZodNullable<z.ZodString>>;
        workspaceExists: z.ZodOptional<z.ZodBoolean>;
        gatewayRunning: z.ZodOptional<z.ZodBoolean>;
        gatewayPort: z.ZodOptional<z.ZodNumber>;
        channels: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
        agentCount: z.ZodOptional<z.ZodNumber>;
        agents: z.ZodOptional<z.ZodArray<z.ZodObject<{
            id: z.ZodOptional<z.ZodString>;
            name: z.ZodString;
            status: z.ZodOptional<z.ZodString>;
            port: z.ZodOptional<z.ZodNumber>;
            workspace: z.ZodOptional<z.ZodString>;
            agentDir: z.ZodOptional<z.ZodString>;
            model: z.ZodOptional<z.ZodString>;
            routingRules: z.ZodOptional<z.ZodNumber>;
            isDefault: z.ZodOptional<z.ZodBoolean>;
        }, "strip", z.ZodTypeAny, {
            name: string;
            status?: string | undefined;
            model?: string | undefined;
            id?: string | undefined;
            workspace?: string | undefined;
            agentDir?: string | undefined;
            routingRules?: number | undefined;
            isDefault?: boolean | undefined;
            port?: number | undefined;
        }, {
            name: string;
            status?: string | undefined;
            model?: string | undefined;
            id?: string | undefined;
            workspace?: string | undefined;
            agentDir?: string | undefined;
            routingRules?: number | undefined;
            isDefault?: boolean | undefined;
            port?: number | undefined;
        }>, "many">>;
    }, "strip", z.ZodTypeAny, {
        type: string;
        installed: boolean;
        version?: string | null | undefined;
        family?: string | undefined;
        workspaceExists?: boolean | undefined;
        gatewayRunning?: boolean | undefined;
        gatewayPort?: number | undefined;
        channels?: string[] | undefined;
        agentCount?: number | undefined;
        agents?: {
            name: string;
            status?: string | undefined;
            model?: string | undefined;
            id?: string | undefined;
            workspace?: string | undefined;
            agentDir?: string | undefined;
            routingRules?: number | undefined;
            isDefault?: boolean | undefined;
            port?: number | undefined;
        }[] | undefined;
    }, {
        type: string;
        installed: boolean;
        version?: string | null | undefined;
        family?: string | undefined;
        workspaceExists?: boolean | undefined;
        gatewayRunning?: boolean | undefined;
        gatewayPort?: number | undefined;
        channels?: string[] | undefined;
        agentCount?: number | undefined;
        agents?: {
            name: string;
            status?: string | undefined;
            model?: string | undefined;
            id?: string | undefined;
            workspace?: string | undefined;
            agentDir?: string | undefined;
            routingRules?: number | undefined;
            isDefault?: boolean | undefined;
            port?: number | undefined;
        }[] | undefined;
    }>>>;
    terminalCapabilities: z.ZodOptional<z.ZodObject<{
        tmux: z.ZodBoolean;
        zellij: z.ZodBoolean;
    }, "strip", z.ZodTypeAny, {
        tmux: boolean;
        zellij: boolean;
    }, {
        tmux: boolean;
        zellij: boolean;
    }>>;
}, "strip", z.ZodTypeAny, {
    platform: string;
    host: string;
    consortiumCliVersion: string;
    homeDir: string;
    consortiumHomeDir: string;
    consortiumLibDir: string;
    cpuCount?: number | undefined;
    memoryTotalMb?: number | undefined;
    hardware?: {
        schemaVersion: 1;
        platform: string;
        arch: string;
        cpuModel: string;
        cpuCoresPhysical: number;
        cpuThreads: number;
        ramTotalBytes: number;
        gpus: {
            vendor: "unknown" | "apple" | "nvidia" | "amd" | "intel";
            name: string;
            vramBytes?: number | undefined;
            driver?: string | undefined;
            computeCapability?: string | undefined;
        }[];
        unifiedMemory: boolean;
        usableModelBytes: number;
        bandwidthSource: "unknown" | "measured" | "chip-table";
        diskFreeBytes: number;
        detectedAt: number;
        warnings: string[];
        memBandwidthGBs?: number | undefined;
    } | undefined;
    openclawInstalled?: boolean | undefined;
    openclawVersion?: string | null | undefined;
    openclawWorkspaceExists?: boolean | undefined;
    openclawGatewayRunning?: boolean | undefined;
    openclawGatewayPort?: number | undefined;
    openclawChannels?: string[] | undefined;
    openclawAgentCount?: number | undefined;
    openclawAgents?: {
        model: string;
        name: string;
        workspace: string;
        agentDir: string;
        routingRules: number;
        isDefault: boolean;
    }[] | undefined;
    harnessInstances?: Record<string, {
        type: string;
        installed: boolean;
        version?: string | null | undefined;
        family?: string | undefined;
        workspaceExists?: boolean | undefined;
        gatewayRunning?: boolean | undefined;
        gatewayPort?: number | undefined;
        channels?: string[] | undefined;
        agentCount?: number | undefined;
        agents?: {
            name: string;
            status?: string | undefined;
            model?: string | undefined;
            id?: string | undefined;
            workspace?: string | undefined;
            agentDir?: string | undefined;
            routingRules?: number | undefined;
            isDefault?: boolean | undefined;
            port?: number | undefined;
        }[] | undefined;
    }> | undefined;
    terminalCapabilities?: {
        tmux: boolean;
        zellij: boolean;
    } | undefined;
}, {
    platform: string;
    host: string;
    consortiumCliVersion: string;
    homeDir: string;
    consortiumHomeDir: string;
    consortiumLibDir: string;
    cpuCount?: number | undefined;
    memoryTotalMb?: number | undefined;
    hardware?: {
        schemaVersion: 1;
        platform: string;
        arch: string;
        cpuModel: string;
        cpuCoresPhysical: number;
        cpuThreads: number;
        ramTotalBytes: number;
        gpus: {
            vendor: "unknown" | "apple" | "nvidia" | "amd" | "intel";
            name: string;
            vramBytes?: number | undefined;
            driver?: string | undefined;
            computeCapability?: string | undefined;
        }[];
        unifiedMemory: boolean;
        usableModelBytes: number;
        bandwidthSource: "unknown" | "measured" | "chip-table";
        diskFreeBytes: number;
        detectedAt: number;
        warnings: string[];
        memBandwidthGBs?: number | undefined;
    } | undefined;
    openclawInstalled?: boolean | undefined;
    openclawVersion?: string | null | undefined;
    openclawWorkspaceExists?: boolean | undefined;
    openclawGatewayRunning?: boolean | undefined;
    openclawGatewayPort?: number | undefined;
    openclawChannels?: string[] | undefined;
    openclawAgentCount?: number | undefined;
    openclawAgents?: {
        model: string;
        name: string;
        workspace: string;
        agentDir: string;
        routingRules: number;
        isDefault: boolean;
    }[] | undefined;
    harnessInstances?: Record<string, {
        type: string;
        installed: boolean;
        version?: string | null | undefined;
        family?: string | undefined;
        workspaceExists?: boolean | undefined;
        gatewayRunning?: boolean | undefined;
        gatewayPort?: number | undefined;
        channels?: string[] | undefined;
        agentCount?: number | undefined;
        agents?: {
            name: string;
            status?: string | undefined;
            model?: string | undefined;
            id?: string | undefined;
            workspace?: string | undefined;
            agentDir?: string | undefined;
            routingRules?: number | undefined;
            isDefault?: boolean | undefined;
            port?: number | undefined;
        }[] | undefined;
    }> | undefined;
    terminalCapabilities?: {
        tmux: boolean;
        zellij: boolean;
    } | undefined;
}>;
type MachineMetadata = z.infer<typeof MachineMetadataSchema>;
/**
 * Daemon state - dynamic runtime information (frequently updated)
 */
declare const DaemonStateSchema: z.ZodObject<{
    status: z.ZodUnion<[z.ZodEnum<["running", "shutting-down"]>, z.ZodString]>;
    pid: z.ZodOptional<z.ZodNumber>;
    httpPort: z.ZodOptional<z.ZodNumber>;
    startedAt: z.ZodOptional<z.ZodNumber>;
    shutdownRequestedAt: z.ZodOptional<z.ZodNumber>;
    shutdownSource: z.ZodOptional<z.ZodUnion<[z.ZodEnum<["mobile-app", "cli", "os-signal", "unknown"]>, z.ZodString]>>;
}, "strip", z.ZodTypeAny, {
    status: string;
    pid?: number | undefined;
    httpPort?: number | undefined;
    startedAt?: number | undefined;
    shutdownRequestedAt?: number | undefined;
    shutdownSource?: string | undefined;
}, {
    status: string;
    pid?: number | undefined;
    httpPort?: number | undefined;
    startedAt?: number | undefined;
    shutdownRequestedAt?: number | undefined;
    shutdownSource?: string | undefined;
}>;
type DaemonState = z.infer<typeof DaemonStateSchema>;
type Machine = {
    id: string;
    encryptionKey: Uint8Array;
    encryptionVariant: 'legacy' | 'dataKey';
    metadata: MachineMetadata;
    metadataVersion: number;
    daemonState: DaemonState | null;
    daemonStateVersion: number;
    /**
     * False when this object is the offline fallback fabricated by
     * getOrCreateMachine after a failed POST /v1/machines — the server has
     * NOT accepted this machine and will silently drop its heartbeats.
     * Callers must not present the daemon as fully connected until a real
     * registration succeeds. Absent/true = server-confirmed.
     */
    registered?: boolean;
};
declare const UserMessageSchema: z.ZodObject<{
    role: z.ZodLiteral<"user">;
    content: z.ZodObject<{
        type: z.ZodLiteral<"text">;
        text: z.ZodString;
        attachmentIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
        localId: z.ZodOptional<z.ZodString>;
        driveId: z.ZodOptional<z.ZodString>;
        driveNodeIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
        driveDek: z.ZodOptional<z.ZodString>;
        attachments: z.ZodOptional<z.ZodArray<z.ZodObject<{
            nodeId: z.ZodString;
            driveId: z.ZodString;
            kind: z.ZodString;
            key: z.ZodOptional<z.ZodString>;
            name: z.ZodOptional<z.ZodString>;
            mime: z.ZodOptional<z.ZodString>;
            size: z.ZodOptional<z.ZodNumber>;
            linkUri: z.ZodOptional<z.ZodString>;
        }, "strip", z.ZodTypeAny, {
            driveId: string;
            nodeId: string;
            kind: string;
            name?: string | undefined;
            key?: string | undefined;
            mime?: string | undefined;
            size?: number | undefined;
            linkUri?: string | undefined;
        }, {
            driveId: string;
            nodeId: string;
            kind: string;
            name?: string | undefined;
            key?: string | undefined;
            mime?: string | undefined;
            size?: number | undefined;
            linkUri?: string | undefined;
        }>, "many">>;
    }, "strip", z.ZodTypeAny, {
        type: "text";
        text: string;
        attachmentIds?: string[] | undefined;
        localId?: string | undefined;
        driveId?: string | undefined;
        driveNodeIds?: string[] | undefined;
        driveDek?: string | undefined;
        attachments?: {
            driveId: string;
            nodeId: string;
            kind: string;
            name?: string | undefined;
            key?: string | undefined;
            mime?: string | undefined;
            size?: number | undefined;
            linkUri?: string | undefined;
        }[] | undefined;
    }, {
        type: "text";
        text: string;
        attachmentIds?: string[] | undefined;
        localId?: string | undefined;
        driveId?: string | undefined;
        driveNodeIds?: string[] | undefined;
        driveDek?: string | undefined;
        attachments?: {
            driveId: string;
            nodeId: string;
            kind: string;
            name?: string | undefined;
            key?: string | undefined;
            mime?: string | undefined;
            size?: number | undefined;
            linkUri?: string | undefined;
        }[] | undefined;
    }>;
    localKey: z.ZodOptional<z.ZodString>;
    meta: z.ZodOptional<z.ZodObject<{
        sentFrom: z.ZodOptional<z.ZodString>;
        permissionMode: z.ZodOptional<z.ZodEnum<["default", "acceptEdits", "bypassPermissions", "plan", "read-only", "safe-yolo", "yolo"]>>;
        model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
        fallbackModel: z.ZodOptional<z.ZodNullable<z.ZodString>>;
        customSystemPrompt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
        appendSystemPrompt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
        allowedTools: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString, "many">>>;
        disallowedTools: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString, "many">>>;
    }, "strip", z.ZodTypeAny, {
        model?: string | null | undefined;
        sentFrom?: string | undefined;
        permissionMode?: "default" | "acceptEdits" | "bypassPermissions" | "plan" | "read-only" | "safe-yolo" | "yolo" | undefined;
        fallbackModel?: string | null | undefined;
        customSystemPrompt?: string | null | undefined;
        appendSystemPrompt?: string | null | undefined;
        allowedTools?: string[] | null | undefined;
        disallowedTools?: string[] | null | undefined;
    }, {
        model?: string | null | undefined;
        sentFrom?: string | undefined;
        permissionMode?: "default" | "acceptEdits" | "bypassPermissions" | "plan" | "read-only" | "safe-yolo" | "yolo" | undefined;
        fallbackModel?: string | null | undefined;
        customSystemPrompt?: string | null | undefined;
        appendSystemPrompt?: string | null | undefined;
        allowedTools?: string[] | null | undefined;
        disallowedTools?: string[] | null | undefined;
    }>>;
    attachmentIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
    localId: z.ZodOptional<z.ZodString>;
    driveId: z.ZodOptional<z.ZodString>;
    driveDek: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
    content: {
        type: "text";
        text: string;
        attachmentIds?: string[] | undefined;
        localId?: string | undefined;
        driveId?: string | undefined;
        driveNodeIds?: string[] | undefined;
        driveDek?: string | undefined;
        attachments?: {
            driveId: string;
            nodeId: string;
            kind: string;
            name?: string | undefined;
            key?: string | undefined;
            mime?: string | undefined;
            size?: number | undefined;
            linkUri?: string | undefined;
        }[] | undefined;
    };
    role: "user";
    attachmentIds?: string[] | undefined;
    localId?: string | undefined;
    driveId?: string | undefined;
    driveDek?: string | undefined;
    localKey?: string | undefined;
    meta?: {
        model?: string | null | undefined;
        sentFrom?: string | undefined;
        permissionMode?: "default" | "acceptEdits" | "bypassPermissions" | "plan" | "read-only" | "safe-yolo" | "yolo" | undefined;
        fallbackModel?: string | null | undefined;
        customSystemPrompt?: string | null | undefined;
        appendSystemPrompt?: string | null | undefined;
        allowedTools?: string[] | null | undefined;
        disallowedTools?: string[] | null | undefined;
    } | undefined;
}, {
    content: {
        type: "text";
        text: string;
        attachmentIds?: string[] | undefined;
        localId?: string | undefined;
        driveId?: string | undefined;
        driveNodeIds?: string[] | undefined;
        driveDek?: string | undefined;
        attachments?: {
            driveId: string;
            nodeId: string;
            kind: string;
            name?: string | undefined;
            key?: string | undefined;
            mime?: string | undefined;
            size?: number | undefined;
            linkUri?: string | undefined;
        }[] | undefined;
    };
    role: "user";
    attachmentIds?: string[] | undefined;
    localId?: string | undefined;
    driveId?: string | undefined;
    driveDek?: string | undefined;
    localKey?: string | undefined;
    meta?: {
        model?: string | null | undefined;
        sentFrom?: string | undefined;
        permissionMode?: "default" | "acceptEdits" | "bypassPermissions" | "plan" | "read-only" | "safe-yolo" | "yolo" | undefined;
        fallbackModel?: string | null | undefined;
        customSystemPrompt?: string | null | undefined;
        appendSystemPrompt?: string | null | undefined;
        allowedTools?: string[] | null | undefined;
        disallowedTools?: string[] | null | undefined;
    } | undefined;
}>;
type UserMessage = z.infer<typeof UserMessageSchema>;
type Metadata = {
    path: string;
    host: string;
    version?: string;
    name?: string;
    os?: string;
    summary?: {
        text: string;
        updatedAt: number;
    };
    machineId?: string;
    claudeSessionId?: string;
    agentSessionId?: string;
    codexRolloutPath?: string;
    tools?: string[];
    slashCommands?: string[];
    homeDir: string;
    consortiumHomeDir: string;
    consortiumLibDir: string;
    consortiumToolsDir: string;
    startedFromDaemon?: boolean;
    hostPid?: number;
    startedBy?: 'daemon' | 'terminal';
    /**
     * Daemon-hosted PTY this session's process runs in (a tmux session named
     * `consortium-<terminalId>` managed by the daemon's TerminalManager). The
     * app attaches to it with `pty:open { persistentTerminalId }` to render the
     * raw terminal view. Absent when the session has no capturable PTY (plain
     * daemon spawn, or started by hand in a user's terminal).
     */
    terminalId?: string;
    /** Multiplexer hosting `terminalId` ('tmux' today). */
    terminalMode?: string;
    lifecycleState?: 'running' | 'archiveRequested' | 'archived' | string;
    lifecycleStateSince?: number;
    archivedBy?: string;
    archiveReason?: string;
    flavor?: string;
    firstMessage?: string;
    /** Resolved model id (cli-set; Pi updates per message_start). */
    model?: string;
    /** Resolved provider id (cli-set alongside `model`). */
    provider?: string;
    /**
     * Startup latency breakdown in milliseconds (label → elapsed), pushed once
     * when the runner is ready. Makes slow session starts measurable from the
     * app instead of requiring daemon debug logs.
     */
    startupTimings?: Record<string, number>;
};
type AgentState = {
    controlledByUser?: boolean | null | undefined;
    requests?: {
        [id: string]: {
            tool: string;
            arguments: any;
            createdAt: number;
        };
    };
    completedRequests?: {
        [id: string]: {
            tool: string;
            arguments: any;
            createdAt: number;
            completedAt: number;
            status: 'canceled' | 'denied' | 'approved';
            reason?: string;
            mode?: PermissionMode;
            decision?: 'approved' | 'approved_for_session' | 'denied' | 'abort';
            allowTools?: string[];
        };
    };
};

/**
 * Common RPC types and interfaces for both session and machine clients
 */
/**
 * Generic RPC handler function type
 * @template TRequest - The request data type
 * @template TResponse - The response data type
 */
type RpcHandler<TRequest = any, TResponse = any> = (data: TRequest) => TResponse | Promise<TResponse>;
/**
 * RPC request data from server
 */
interface RpcRequest {
    method: string;
    params: string;
}
/**
 * Configuration for RPC handler manager
 */
interface RpcHandlerConfig {
    scopePrefix: string;
    encryptionKey: Uint8Array;
    encryptionVariant: 'legacy' | 'dataKey';
    logger?: (message: string, data?: any) => void;
    /**
     * Called for every failed request (decryption failure or handler throw)
     * with the error and structured context. Wire this to crash reporting
     * (observability.captureError) — the manager itself stays transport-only.
     */
    onError?: (error: unknown, context: Record<string, unknown>) => void;
}

/**
 * Generic RPC handler manager for session and machine clients
 * Manages RPC method registration, encryption/decryption, and handler execution
 */

declare class RpcHandlerManager {
    private handlers;
    private readonly scopePrefix;
    private readonly encryptionKey;
    private readonly encryptionVariant;
    private readonly logger;
    private readonly onError?;
    private socket;
    constructor(config: RpcHandlerConfig);
    /**
     * Register an RPC handler for a specific method
     * @param method - The method name (without prefix)
     * @param handler - The handler function
     */
    registerHandler<TRequest = any, TResponse = any>(method: string, handler: RpcHandler<TRequest, TResponse>): void;
    /**
     * Handle an incoming RPC request
     * @param request - The RPC request data
     * @param callback - The response callback
     */
    handleRequest(request: RpcRequest): Promise<any>;
    onSocketConnect(socket: Socket): Promise<void>;
    onSocketDisconnect(): void;
    /**
     * Get the number of registered handlers
     */
    getHandlerCount(): number;
    /**
     * Check if a handler is registered
     * @param method - The method name (without prefix)
     */
    hasHandler(method: string): boolean;
    /**
     * Invoke a registered handler in-process with already-decrypted params.
     * Used by the generic harness dispatcher to fall through to a legacy
     * per-harness RPC (e.g. `openclaw-agent-add`) when the harness provider
     * doesn't expose the dispatcher-facing method directly.
     */
    callLocal<TRequest = any, TResponse = any>(method: string, params: TRequest): Promise<TResponse | undefined>;
    /**
     * Clear all handlers
     */
    clearHandlers(): void;
    /**
     * Get the prefixed method name
     * @param method - The method name
     */
    private getPrefixedMethod;
}

/**
 * The shared vocabulary for agent-CLI *operational* failures — not authed,
 * out of plan usage, out of credits, rate limited, CLI missing.
 *
 * These are the errors Consortium used to lose. Before this module an error
 * was a `string` produced at the end of the pipeline and recovered by regex
 * over chat prose; every failure the user could actually act on collapsed to
 * `'Process exited unexpectedly'`.
 *
 * The contract here is deliberately narrow:
 *
 *  - The CLI emits a `code` plus structured params. It does NOT own the copy.
 *    User-facing wording lives in the app (`sources/text/_default.ts`), which
 *    ships ten locales behind a compile-time structural check and is
 *    OTA-updatable — CLI strings are English-only and gated behind a dist sync
 *    plus a daemon restart. `message` here is a LEGACY FALLBACK, rendered only
 *    by clients too old to understand `code`.
 *  - Every code maps to exactly one `action`, so the app never has to infer
 *    what button to draw.
 *  - `retryable` is a property of the code, not of the call site, so two
 *    runners can't disagree about whether the same failure is worth retrying.
 */

/**
 * What went wrong, at the granularity the user can act on.
 *
 * Ordering note: this is a closed set on purpose. A failure that doesn't map
 * cleanly is `unknown` (retryable) rather than a new code invented at a call
 * site — otherwise the app's action table silently falls out of sync.
 */
type AgentErrorCode = 'not_authenticated' | 'auth_expired' | 'plan_limit' | 'rate_limit' | 'insufficient_credits' | 'model_unavailable' | 'cli_missing' | 'cli_incompatible' | 'context_exceeded' | 'network' | 'crashed' | 'unknown';
/** The single UI affordance a code earns. One code → one button. */
type AgentErrorAction = 'login' | 'retry' | 'switch_model' | 'add_credits' | 'install_cli' | 'update_cli' | 'compact' | 'wait_or_switch';

/**
 * ACP (Agent Communication Protocol) message data types.
 * This is the unified format for all agent messages - CLI adapts each provider's format to ACP.
 */
type ACPMessageData = {
    type: 'message';
    message: string;
} | {
    type: 'reasoning';
    message: string;
} | {
    type: 'thinking';
    text: string;
} | {
    type: 'tool-call';
    callId: string;
    name: string;
    input: unknown;
    id: string;
} | {
    type: 'tool-result';
    callId: string;
    output: unknown;
    id: string;
    isError?: boolean;
} | {
    type: 'file-edit';
    description: string;
    filePath: string;
    diff?: string;
    oldContent?: string;
    newContent?: string;
    id: string;
} | {
    type: 'terminal-output';
    data: string;
    callId: string;
} | {
    type: 'task_started';
    id: string;
} | {
    type: 'task_complete';
    id: string;
} | {
    type: 'turn_aborted';
    id: string;
} | {
    type: 'permission-request';
    permissionId: string;
    toolName: string;
    description: string;
    options?: unknown;
} | {
    type: 'artifact';
    artifactId: string;
    mime: string;
    name?: string;
    sizeBytes?: number;
} | {
    type: 'artifact-ref';
    artifactId: string;
    title: string;
    artifactKind: ArtifactKind;
    versionHint?: number;
    id: string;
} | {
    type: 'token_count';
    [key: string]: unknown;
};
/** Interactive artifact kinds (mirrors the app's ArtifactKind). */
type ArtifactKind = 'code' | 'html' | 'react' | 'svg' | 'mermaid' | 'markdown' | 'document';
type ACPProvider = 'gemini' | 'grok' | 'pi' | 'codex' | 'claude' | 'consortium-code';
declare class ApiSessionClient extends EventEmitter {
    private readonly token;
    readonly sessionId: string;
    private metadata;
    private metadataVersion;
    private agentState;
    private agentStateVersion;
    private socket;
    private pendingMessages;
    private pendingMessageCallback;
    private modelChangeCallback;
    readonly rpcHandlerManager: RpcHandlerManager;
    private agentStateLock;
    private metadataLock;
    private encryptionKey;
    private encryptionVariant;
    private readonly userContentPublicKey?;
    private artifactStates;
    private lastClaudeModel;
    private pendingEmits;
    private static readonly MAX_PENDING_EMITS;
    private reconnectTimer;
    private manualReconnectAttempts;
    private destroyed;
    private flushWatchdog;
    private static readonly FLUSH_WATCHDOG_MS;
    /** Get encryption details for passing to child processes. */
    getEncryptionDetails(): {
        key: Uint8Array;
        variant: 'legacy' | 'dataKey';
    };
    /**
     * Upload an agent-produced media blob to the server as a SessionArtifact.
     *
     * Phase 1.5 (E2EE): when the session content key is available (it always
     * is for a live ApiSessionClient — both 'legacy' and 'dataKey' variants
     * carry a 32-byte symmetric key that the app derives for the same
     * session), the bytes are encrypted client-side with libsodium secretbox
     * as `nonce || ciphertext` — the exact Drive-content primitive, so the
     * app decrypts with the code path it already ships — and the POST carries
     * `encVersion: 1`. If the key is missing/malformed (defensive: should not
     * happen), we fall back to the Phase-1 plaintext upload with no
     * `encVersion`, which the private-prefix + presigned-URL model still
     * gates. Server-side size caps apply to the CIPHERTEXT (secretbox adds
     * only 24-byte nonce + 16-byte MAC).
     *
     * Returns the artifact id and metadata so the caller can immediately
     * reference it in an outgoing agent message
     * (`{ type: 'artifact', artifactId, mime }`).
     */
    uploadArtifact(args: {
        bytes: Uint8Array;
        mime: string;
    }): Promise<{
        id: string;
        mime: string;
        sizeBytes: number;
    }>;
    /** True when this session can create interactive library artifacts. */
    canCreateLibraryArtifacts(): boolean;
    /**
     * Create a versioned interactive artifact (the /v1/artifacts entity),
     * linked to this session. Encrypts header+body with a fresh per-artifact
     * DEK wrapped to the user's content public key — byte-compatible with the
     * mobile app's ArtifactEncryption, so the artifact opens in the app's
     * slide-in panel and library. Returns the new artifact id.
     */
    createLibraryArtifact(input: {
        title: string;
        kind: ArtifactKind;
        content: string;
        language?: string;
        mime?: string;
    }): Promise<{
        id: string;
    }>;
    /**
     * Update an artifact previously created in this session, producing a new
     * body version and appending the prior body to the inline version history
     * (capped). Requires the artifact to exist in this session's in-memory
     * state (i.e. created in the same run) — otherwise the DEK is unavailable
     * and the caller should create a new artifact instead.
     */
    updateLibraryArtifact(input: {
        id: string;
        content: string;
        title?: string;
        summary?: string;
    }): Promise<{
        bodyVersion: number;
        title: string;
        kind: ArtifactKind;
    }>;
    constructor(token: string, session: Session);
    onUserMessage(callback: (data: UserMessage) => void): void;
    /**
     * EPHEMERAL-1: subscribe to server-broadcast model-change events
     * (emitted on Path A set AND clear — CONTRACT A). The server fans these
     * out so every live client/session reconciles the active model
     * immediately instead of only learning on the next request. Runners use
     * this to update their in-memory model + repaint the model pill.
     *
     * `modelId === null` means the override was cleared (reset to default).
     * `sessionId` is present for session-scoped changes and absent for
     * account-level (default-for-new-sessions) changes.
     */
    onModelChange(callback: (change: {
        providerId: string;
        modelId: string | null;
        sessionId?: string;
    }) => void): void;
    /**
     * Parse + dispatch a model-change ephemeral. Defensive: tolerates the
     * broadcast arriving as either `model-change` or `model-changed` and
     * silently ignores anything that isn't a well-formed model-change event
     * (the same socket carries relay + rotate ephemerals).
     */
    private onModelChangeEphemeral;
    /**
     * Emit a 'message' payload, buffering it if the socket is currently
     * disconnected. Drained on the next 'connect' event.
     */
    private reliableEmitMessage;
    private flushPendingEmits;
    /**
     * Send message to session
     * @param body - Message body (can be MessageContent or raw content for agent messages)
     */
    sendClaudeSessionMessage(body: RawJSONLines): void;
    sendCodexMessage(body: any): void;
    /**
     * Send a generic agent message to the session using ACP (Agent Communication Protocol) format.
     * Works for any agent type (Gemini, Codex, Claude, etc.) - CLI normalizes to unified ACP format.
     *
     * @param provider - The agent provider sending the message (e.g., 'gemini', 'codex', 'claude')
     * @param body - The message payload (type: 'message' | 'reasoning' | 'tool-call' | 'tool-result')
     */
    /**
     * Send a user message to the session, rendered as a chat bubble on the web client.
     * Used to mirror terminal TUI input to the web session.
     */
    sendUserChatMessage(text: string): void;
    sendAgentMessage(provider: ACPProvider, body: ACPMessageData): void;
    private pendingWriteCalls;
    private fileArtifactIds;
    private autoArtifactSeen;
    private artifactDedupeKey;
    /**
     * Scan agent text for substantial fenced blocks and promote them to
     * interactive artifacts — the safety net for agents that print a code
     * block instead of calling create_artifact. Works for ALL agents: full-
     * message agents (gemini/grok/pi/claude) are scanned per outgoing message
     * from sendAgentMessage; streaming agents (consortium-code) call this once
     * with the whole turn's text. Best-effort and fire-and-forget.
     *
     * Default ON; set CONSORTIUM_ARTIFACTS_AUTODETECT=0 to disable.
     */
    autoDetectArtifactsFromText(provider: ACPProvider, text: string): Promise<void>;
    private extractWritePath;
    private fileArtifactKind;
    /**
     * Promote a written file to an interactive artifact: read it, infer the
     * kind from its extension, and create (or, for a re-write of the same path,
     * version) the artifact + drop a chat card. This is what makes coding
     * agents behave like Claude artifacts — they write files, not fences.
     *
     * `content` may be passed when the caller already has it in hand (e.g.
     * Claude's Write tool input, Codex add patches); otherwise the file is read
     * from disk (it exists by the time the write tool-result fires). Best-effort
     * and fire-and-forget. Honours CONSORTIUM_ARTIFACTS_AUTODETECT.
     */
    promoteFileWriteArtifact(provider: ACPProvider, filePath: string, content?: string): Promise<void>;
    sendSessionEvent(event: {
        type: 'switch';
        mode: 'local' | 'remote';
    } | {
        /**
         * The `message` arm doubles as the error channel. It is the SAME event
         * the cloud path already emits, so both surfaces speak one language
         * and clients too old to understand `code` still render `message` as a
         * plain line.
         *
         * `message` is a LEGACY English fallback — the app renders from `code`,
         * because the app ships ten locales and is OTA-updatable while CLI
         * strings are English-only and gated behind a dist sync.
         */
        type: 'message';
        message: string;
        isError?: boolean;
        code?: AgentErrorCode;
        retryable?: boolean;
        action?: AgentErrorAction;
        /** Epoch ms when a limit lifts. Only set when the CLI actually said so. */
        resetsAt?: number;
        agent?: string;
        providerId?: string;
        providerAccountId?: string;
        /** Raw CLI text, truncated, for the details toggle. */
        detail?: string;
    } | {
        type: 'permission-mode-changed';
        mode: 'default' | 'acceptEdits' | 'bypassPermissions' | 'plan';
    } | {
        type: 'ready';
    }, id?: string): void;
    /**
     * Emit a live token-stream delta over the ephemeral `session-stream`
     * channel. Unlike `sendAgentMessage`, this is NOT persisted — the
     * server relays it to clients currently viewing the session and drops
     * it otherwise. The durable, authoritative message still flows through
     * `sendAgentMessage` at turn end; this only powers the live "typing"
     * feed. Deltas are best-effort (`volatile`): if the socket is
     * congested a dropped delta is harmless because the final message
     * reconciles the text.
     *
     * The `textDelta` is encrypted with the session key exactly like a
     * durable message body, so the relay server never sees plaintext.
     *
     * @param provider  agent id ('grok' | 'gemini' | 'codex' | 'claude' | 'pi' | …)
     * @param streamId  stable id for one assistant turn (answer+reasoning share it)
     * @param channel   'answer' for response text, 'reasoning' for thinking
     * @param seq       monotonically increasing index within the stream (ordering)
     * @param textDelta the incremental chunk (omit on the terminal frame)
     * @param done      true to signal the stream is finished (clears the buffer)
     */
    sendStreamDelta(provider: string, streamId: string, channel: 'answer' | 'reasoning', seq: number, textDelta: string, done?: boolean): void;
    /**
     * Optional provider for message-queue observability. When set, every
     * keepAlive heartbeat carries `queued`/`queuedIds` so clients can render
     * exact queue state (level-triggered: re-sent every ~2s on a volatile
     * emit, so a dropped frame self-heals on the next tick — no ack contract).
     * Old servers/clients simply ignore the extra fields.
     */
    private queueStatsProvider;
    setQueueStatsProvider(provider: (() => {
        queued: number;
        queuedIds: string[];
    }) | null): void;
    /**
     * Send a ping message to keep the connection alive
     */
    keepAlive(thinking: boolean, mode: 'local' | 'remote'): void;
    /**
     * Send session death message
     */
    sendSessionDeath(): void;
    /**
     * Infers the LLM provider ID from a model name string.
     */
    private inferProvider;
    /**
     * Detects the usage mode based on environment variables (B-8).
     *
     *  · 'managed' — the agent's traffic is rewritten through the Consortium
     *    proxy, so the SERVER already metered and billed this call and the
     *    report is supplementary analytics. This used to check only
     *    `ANTHROPIC_BASE_URL`, so a managed OpenAI or Google session was
     *    mislabeled 'wrapped' and got billed a SECOND time from the
     *    client-reported cost. All three vendor base-URL vars are checked now.
     *  · 'byok' — the daemon injected the user's OWN credential for this spawn
     *    (custom base URL and/or a vendor API-key env var it set). The user
     *    pays their vendor directly, so the server must not bill the wallet.
     *  · 'wrapped' — everything else; the server bills the client-reported cost.
     *
     * The BYOK signals are deliberately restricted to variables the DAEMON
     * sets (`daemon/run.ts` — `CONSORTIUM_CODE_BYOK_BASE_URL` /
     * `CONSORTIUM_CODE_BYOK_ENV_VAR` / `CONSORTIUM_CODE_BYOK_PROVIDER`). A bare
     * `ANTHROPIC_API_KEY` inherited from the user's shell is NOT treated as
     * BYOK: that would silently stop billing existing wrapped sessions, which
     * is a revenue change, not an accounting fix.
     */
    private detectUsageMode;
    /**
     * Send usage data to the server
     *
     * `opts` (L4.2 — non-claude agents + sub-agent rollup):
     *  · `keyPrefix` — report-key namespace. Defaults to the legacy
     *    'claude-session' so existing claude rows keep upserting under their
     *    historical keys; codex/gemini/grok pass their agent name so the
     *    ledger can tell who reported.
     *  · `providerId` — explicit provider when the model id alone can't infer
     *    it (e.g. codex running its default model: the CLI never learns the
     *    model string, but the vendor is definitionally openai).
     *  · `zeroCost` — report tokens only, cost 0. REQUIRED for the non-claude
     *    agent self-reports: `calculateCost` falls back to Anthropic Sonnet
     *    pricing for unknown model ids, and the server debits the wallet for
     *    any wrapped-mode report with cost > 0 — a codex/gemini/grok session
     *    running on the user's OWN vendor account must never create a wallet
     *    charge. Vendor-true cost adoption is lane L4.4's scope, not ours.
     */
    sendUsageData(usage: Usage, model?: string, turnKey?: string, opts?: {
        keyPrefix?: string;
        providerId?: string;
        zeroCost?: boolean;
    }): void;
    /**
     * Update session metadata
     * @param handler - Handler function that returns the updated metadata
     */
    updateMetadata(handler: (metadata: Metadata) => Metadata): void;
    /**
     * Update session agent state
     * @param handler - Handler function that returns the updated agent state
     */
    updateAgentState(handler: (metadata: AgentState) => AgentState): void;
    /**
     * Wait for socket buffer to flush
     */
    flush(): Promise<void>;
    close(): Promise<void>;
    /**
     * Schedule a manual reconnect after a connect_error. Mirrors
     * ApiMachineClient.scheduleManualReconnect; see comment there for the
     * Socket.IO middleware-rejection rationale. Session sockets don't
     * carry their own refresh path — the session token comes from the
     * parent process, so the only thing we can do here is retry with
     * the existing token until it works (or until close() is called).
     */
    private scheduleManualReconnect;
}

/**
 * Shared types for the persistent terminal multiplexer subsystem.
 *
 * TerminalBackend is the common interface implemented by tmux, zellij, and
 * the fallback ephemeral (node-pty) backend. TerminalManager owns backend
 * instances and dispatches I/O through them.
 */
type TerminalMode = 'tmux' | 'zellij' | 'ephemeral' | 'external';
type TerminalStatus = 'running' | 'exited';
interface TerminalDescriptor {
    id: string;
    mode: TerminalMode;
    status: TerminalStatus;
    /** Epoch ms; best-effort, may be 0 if unknown post-restart */
    createdAt: number;
}

interface SpawnSessionOptions {
    machineId?: string;
    directory: string;
    sessionId?: string;
    /**
     * Correlation ID from the originating RPC (`_reqId` in the encrypted
     * params). Propagated into the spawned session's environment as
     * CONSORTIUM_REQUEST_ID so the session's logs link back to the request
     * that spawned it.
     */
    requestId?: string;
    approvedNewDirectoryCreation?: boolean;
    agent?: 'claude' | 'codex' | 'gemini' | 'grok' | 'pi' | 'consortium-code';
    token?: string;
    /** Start as Project Manager agent with session orchestration tools */
    pmMode?: boolean;
    /** When true, create a worktree before spawning the agent process */
    worktreeMode?: boolean;
    /** Card ID for worktree branch naming */
    cardId?: string;
    /** Card slug for worktree directory naming */
    cardSlug?: string;
    /**
     * Project the session is started under. Forwarded to the spawned agent
     * child process as CONSORTIUM_PROJECT_ID so the created session is
     * persisted with Session.projectId. Optional — machine sessions with no
     * project are unaffected.
     */
    projectId?: string;
    /**
     * Automations: first user message, injected LOCALLY by the spawned agent
     * (forwarded as CONSORTIUM_INITIAL_PROMPT). Used by server-scheduled runs
     * where no app is online to send the opening message. Consumed today by
     * the claude and consortium-code runners.
     */
    initialPrompt?: string;
    /**
     * Automations: initial permission mode for the spawned agent (forwarded
     * as CONSORTIUM_PERMISSION_MODE; same values as the app's per-session
     * permission mode, e.g. 'read-only', 'default', 'safe-yolo').
     */
    permissionMode?: string;
    /** Base branch for worktree (defaults to 'main') */
    repoBaseBranch?: string;
    /**
     * Legacy: Claude session ID to resume (uses `claude --resume <id>`).
     * Still honored for claude agents when `resume` is not set. Prefer `resume`
     * below for all new callers — it carries agent-specific resume data.
     */
    resumeSessionId?: string;
    /**
     * Agent-specific resume hint. Only one of these is consulted, based on
     * `agent`:
     *   - claude            → uses `sessionId` as `--resume <id>`
     *   - codex             → uses `rolloutPath` via `experimental_resume`
     *                         config (daemon writes it to a --config arg)
     *                         and passes `sessionId` for logging.
     *   - consortium-code   → uses `--continue` (no id). `sessionId` carried
     *                         for logging only; actual resume is last-session.
     *   - gemini            → resume not supported; daemon rejects with a
     *                         user-visible error if this is set.
     */
    resume?: {
        sessionId?: string;
        rolloutPath?: string;
    };
    environmentVariables?: {
        ANTHROPIC_BASE_URL?: string;
        ANTHROPIC_AUTH_TOKEN?: string;
        ANTHROPIC_MODEL?: string;
        TMUX_SESSION_NAME?: string;
        TMUX_TMPDIR?: string;
    };
    /** Per-provider key mode from profile: managed, byok, or none */
    profileKeyMode?: Record<string, 'managed' | 'byok' | 'none'>;
    /**
     * How auth credentials should be sourced for this session. Mirrors
     * `AuthSource` in `src/auth/types.ts` — duplicated as a string-literal
     * union here to avoid a circular import between the common RPC layer
     * and the auth module. Defaults to `'auto'` server-side: prefer
     * machine creds if the probe finds them, else fall back to managed
     * proxy if the user has credits, else error.
     */
    authSource?: 'machine' | 'managed' | 'byok' | 'auto';
    /**
     * Optional expectation about the resolved identity. When supplied,
     * the daemon verifies the probe's identity matches before spawning;
     * a mismatch surfaces a clear error rather than silently using the
     * wrong account.
     */
    authIdentity?: {
        agent: 'claude' | 'codex' | 'gemini' | 'consortium';
        email?: string;
    };
    /**
     * Provider id picked in the mobile Provider button (W3A). When set and
     * non-`consortium`, the daemon injects this provider's keyEnvVar from
     * the encrypted BYOK keystore so the agent CLI talks directly to the
     * native upstream instead of routing through the Consortium proxy.
     * Higher precedence than `profileKeyMode` for choosing the BYOK
     * provider id.
     */
    providerId?: string;
    /**
     * Selected model id (W3A). Currently advisory — the agent CLI reads
     * the model from its own per-agent flags or environment. Carried so
     * future telemetry / provider-routing decisions can avoid re-parsing
     * provider:model strings.
     */
    modelId?: string;
    /**
     * Linked provider account to authenticate this session with (M3).
     * Pins spawn-time resolution to a specific account in the daemon's
     * encrypted keystore (e.g. one of two claude.ai subscriptions);
     * absent → the keystore's provider default is used. Ignored when an
     * explicit `token` is supplied or `authSource === 'machine'`.
     */
    accountKeyId?: string;
    /**
     * Explicit environment variable name to bind the BYOK key under when
     * the daemon can't infer it from its catalogs (custom providers).
     * Mobile supplies this for `customProviders` entries; the daemon uses
     * it verbatim instead of looking up via AGENT_PROVIDERS or
     * OPENCODE_PROVIDERS. Ignored when the daemon already knows the
     * provider.
     */
    byokEnvVar?: string;
    /**
     * Optional OpenAI-compatible base URL for the custom provider. When
     * present the daemon exports `OPENCODE_CUSTOM_BASE_URL` so users can
     * reference it from their opencode.json provider config.
     */
    byokBaseURL?: string;
}
type SpawnSessionResult = {
    type: 'success';
    sessionId: string;
} | {
    type: 'requestToApproveDirectoryCreation';
    directory: string;
} | {
    type: 'error';
    errorMessage: string;
}
/**
 * Proxy-token mint failed for a required scope. Distinct from the
 * generic 'error' so the app can route to billing/upgrade UI instead
 * of a generic "Failed to spawn" alert. `errorCode` mirrors the
 * structured server response (`spending_cap_required`,
 * `subscription_canceled`, `daily_limit_hit`, `insufficient_credits`,
 * etc.). The CLI never silently downgrades to direct upstream — a
 * failed mint is a hard spawn refusal.
 */
 | {
    type: 'mint_failed';
    errorCode: string;
    message: string;
    scope: 'consortium' | 'anthropic' | 'openai' | 'google' | 'zai';
};

declare const DeviceFrameSchema: z.ZodObject<{
    deviceId: z.ZodString;
    seq: z.ZodNumber;
    codec: z.ZodEnum<["jpeg", "h264"]>;
    keyframe: z.ZodOptional<z.ZodBoolean>;
    w: z.ZodNumber;
    h: z.ZodNumber;
    ctMs: z.ZodNumber;
    sealed: z.ZodString;
}, "strip", z.ZodTypeAny, {
    w: number;
    h: number;
    deviceId: string;
    seq: number;
    codec: "jpeg" | "h264";
    ctMs: number;
    sealed: string;
    keyframe?: boolean | undefined;
}, {
    w: number;
    h: number;
    deviceId: string;
    seq: number;
    codec: "jpeg" | "h264";
    ctMs: number;
    sealed: string;
    keyframe?: boolean | undefined;
}>;
type DeviceFrame = z.infer<typeof DeviceFrameSchema>;
/** An input event as it crosses the relay: the event is sealed under the
 *  session DEK and carries a monotonic nonce so a compromised relay can neither
 *  read nor replay/forge taps. deviceHost rejects anything that fails to
 *  decrypt or whose nonce is <= the last accepted nonce. */
declare const SealedInputSchema: z.ZodObject<{
    deviceId: z.ZodString;
    nonce: z.ZodNumber;
    sealed: z.ZodString;
}, "strip", z.ZodTypeAny, {
    deviceId: string;
    sealed: string;
    nonce: number;
}, {
    deviceId: string;
    sealed: string;
    nonce: number;
}>;
type SealedInput = z.infer<typeof SealedInputSchema>;
/** A control request. `id` correlates the matching DeviceControlResult. `params`
 *  is validated by the matching *InputSchema for `method`. */
declare const DeviceControlRequestSchema: z.ZodObject<{
    type: z.ZodLiteral<"control">;
    id: z.ZodString;
    deviceId: z.ZodOptional<z.ZodString>;
    method: z.ZodEnum<["listDevices", "boot", "attach", "detach", "screenshot", "install", "launch", "openUrl", "build", "buildStatus", "shutdown"]>;
    params: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
}, "strip", z.ZodTypeAny, {
    type: "control";
    id: string;
    method: "listDevices" | "boot" | "attach" | "detach" | "screenshot" | "install" | "launch" | "openUrl" | "build" | "buildStatus" | "shutdown";
    params?: Record<string, unknown> | undefined;
    deviceId?: string | undefined;
}, {
    type: "control";
    id: string;
    method: "listDevices" | "boot" | "attach" | "detach" | "screenshot" | "install" | "launch" | "openUrl" | "build" | "buildStatus" | "shutdown";
    params?: Record<string, unknown> | undefined;
    deviceId?: string | undefined;
}>;
type DeviceControlRequest = z.infer<typeof DeviceControlRequestSchema>;
declare const DeviceControlResultSchema: z.ZodUnion<[z.ZodObject<{
    type: z.ZodLiteral<"control-result">;
    id: z.ZodString;
    ok: z.ZodLiteral<true>;
    result: z.ZodOptional<z.ZodUnknown>;
}, "strip", z.ZodTypeAny, {
    type: "control-result";
    id: string;
    ok: true;
    result?: unknown;
}, {
    type: "control-result";
    id: string;
    ok: true;
    result?: unknown;
}>, z.ZodObject<{
    type: z.ZodLiteral<"control-result">;
    id: z.ZodString;
    ok: z.ZodLiteral<false>;
    error: z.ZodString;
}, "strip", z.ZodTypeAny, {
    type: "control-result";
    id: string;
    error: string;
    ok: false;
}, {
    type: "control-result";
    id: string;
    error: string;
    ok: false;
}>]>;
type DeviceControlResult = z.infer<typeof DeviceControlResultSchema>;
declare const DeviceLifecycleEventSchema: z.ZodObject<{
    type: z.ZodLiteral<"event">;
    deviceId: z.ZodString;
    event: z.ZodEnum<["booted", "attached", "detached", "shutdown", "driver-changed", "error"]>;
    driver: z.ZodOptional<z.ZodEnum<["agent", "human", "shared"]>>;
    message: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
    type: "event";
    deviceId: string;
    event: "error" | "shutdown" | "booted" | "attached" | "detached" | "driver-changed";
    message?: string | undefined;
    driver?: "agent" | "human" | "shared" | undefined;
}, {
    type: "event";
    deviceId: string;
    event: "error" | "shutdown" | "booted" | "attached" | "detached" | "driver-changed";
    message?: string | undefined;
    driver?: "agent" | "human" | "shared" | undefined;
}>;
type DeviceLifecycleEvent = z.infer<typeof DeviceLifecycleEventSchema>;

interface ServerToDaemonEvents {
    update: (data: Update) => void;
    'rpc-request': (data: {
        method: string;
        params: string;
    }, callback: (response: string) => void) => void;
    'rpc-registered': (data: {
        method: string;
    }) => void;
    'rpc-unregistered': (data: {
        method: string;
    }) => void;
    'rpc-error': (data: {
        type: string;
        error: string;
    }) => void;
    auth: (data: {
        success: boolean;
        user: string;
    }) => void;
    error: (data: {
        message: string;
    }) => void;
    'pty:open': (data: {
        terminalId: string;
        cols: number;
        rows: number;
        persistentTerminalId?: string;
    }, callback: (response: {
        ok: boolean;
        error?: string;
    }) => void) => void;
    'pty:data': (data: {
        terminalId: string;
        data: string;
    }) => void;
    'pty:resize': (data: {
        terminalId: string;
        cols: number;
        rows: number;
    }) => void;
    'pty:close': (data: {
        terminalId: string;
    }) => void;
    'terminal:create': (data: {
        terminalId: string;
        persistenceMode?: string;
        cols?: number;
        rows?: number;
        cwd?: string;
        shell?: string;
    }, callback: (response: {
        ok: boolean;
        mode: string;
        error?: string;
    }) => void) => void;
    'terminal:list': (data: unknown, callback: (response: {
        ok: boolean;
        terminals: TerminalDescriptor[];
    }) => void) => void;
    'terminal:destroy': (data: {
        terminalId: string;
    }, callback: (response: {
        ok: boolean;
        error?: string;
    }) => void) => void;
    'server-shutting-down': (data: {
        reason: string;
        timestamp: number;
    }) => void;
    'machine:fs-readdir': (data: {
        machineId: string;
        path: string;
        requestId: string;
    }) => void;
    'machine:fs-stat': (data: {
        machineId: string;
        path: string;
        requestId: string;
    }) => void;
    'device:control': (data: {
        machineId: string;
        sessionId: string;
    } & DeviceControlRequest) => void;
    'device:input': (data: {
        machineId: string;
        sessionId: string;
    } & SealedInput) => void;
}
interface DaemonToServerEvents {
    'machine-alive': (data: {
        machineId: string;
        time: number;
    }) => void;
    'machine-update-metadata': (data: {
        machineId: string;
        metadata: string;
        expectedVersion: number;
    }, cb: (answer: {
        result: 'error';
    } | {
        result: 'version-mismatch';
        version: number;
        metadata: string;
    } | {
        result: 'success';
        version: number;
        metadata: string;
    }) => void) => void;
    'machine-update-state': (data: {
        machineId: string;
        daemonState: string;
        expectedVersion: number;
    }, cb: (answer: {
        result: 'error';
    } | {
        result: 'version-mismatch';
        version: number;
        daemonState: string;
    } | {
        result: 'success';
        version: number;
        daemonState: string;
    }) => void) => void;
    'openclaw:activity': (data: {
        machineId: string;
        eventType: string;
        agentId: string | null;
        encryptedPayload: string;
        timestamp: number;
    }) => void;
    'openclaw:status': (data: {
        machineId: string;
        status: string;
        version: string | null;
        gatewayPort: number;
        channels: string[];
        agentCount: number;
        timestamp: number;
    }) => void;
    'harness:agent-chat-frame': (data: {
        machineId: string;
        requestId: string;
        agentId: string | null;
        seq: number;
        encryptedPayload: string;
        done: boolean;
        timestamp: number;
    }) => void;
    'rpc-register': (data: {
        method: string;
    }, callback: (response: {
        ok: boolean;
        method: string;
    }) => void) => void;
    'rpc-unregister': (data: {
        method: string;
    }) => void;
    'rpc-ready': () => void;
    'rpc-call': (data: {
        method: string;
        params: any;
    }, callback: (response: {
        ok: boolean;
        result?: any;
        error?: string;
    }) => void) => void;
    'pty:data': (data: {
        machineId: string;
        terminalId: string;
        data: string;
    }) => void;
    'pty:exit': (data: {
        machineId: string;
        terminalId: string;
    }) => void;
    'codrive:frame': (data: {
        machineId: string;
        sessionId: string;
        jpegBase64: string;
        w: number;
        h: number;
        seq: number;
    }) => void;
    'terminal:list': (data: {
        machineId: string;
        terminals: TerminalDescriptor[];
    }) => void;
    'machine:fs-readdir-result': (data: {
        requestId: string;
        payload: string;
    }) => void;
    'machine:fs-stat-result': (data: {
        requestId: string;
        payload: string;
    }) => void;
    'device:frame': (data: {
        machineId: string;
        sessionId: string;
    } & DeviceFrame) => void;
    'device:control-result': (data: {
        machineId: string;
        sessionId: string;
    } & DeviceControlResult) => void;
    'device:event': (data: {
        machineId: string;
        sessionId: string;
    } & DeviceLifecycleEvent) => void;
}
type MachineRpcHandlers = {
    spawnSession: (options: SpawnSessionOptions) => Promise<SpawnSessionResult>;
    stopSession: (sessionId: string) => boolean;
    /**
     * Live-apply a marketplace connector change to a running session: stop the
     * agent process and re-spawn it with a resume hint so the conversation
     * survives and provisioning re-runs on launch. `resume` carries the
     * freshest agent-native resume data the caller holds (agent session id or
     * codex rollout path); when omitted the daemon falls back to the session's
     * tracked metadata.
     */
    reprovisionSession: (sessionId: string, resume?: {
        sessionId?: string;
        rolloutPath?: string;
    }) => Promise<SpawnSessionResult>;
    requestShutdown: () => void;
};
interface ApiMachineConnectOptions {
    onReconnect?: () => Promise<Machine>;
    organizationId?: string;
    onAuthFailure?: () => void;
    /**
     * Called when the websocket handshake is rejected (typically auth-related,
     * but can fire for any connect_error). Should return a fresh token if one
     * is available, or null if refresh failed/isn't possible. The new token,
     * if returned, is swapped into the socket auth before the next reconnect
     * attempt. See connect_error handler for the back-off schedule.
     *
     * Why this exists: Socket.IO v4 does not auto-retry middleware-level
     * handshake rejections (the path the server takes for "Invalid
     * authentication token"). Without explicit refresh + manual reconnect,
     * a single transient auth blip permanently disconnects the daemon.
     */
    refreshToken?: () => Promise<string | null>;
}
declare class ApiMachineClient {
    private token;
    private machine;
    private socket;
    /**
     * Escape hatch for subsystems (e.g. harness profile-sync) that need to
     * register custom events on the machine-scoped socket. Returns the live
     * Socket.IO client; may be undefined before connect() is called.
     */
    getRawSocket(): Socket<ServerToDaemonEvents, DaemonToServerEvents> | undefined;
    /** Initialised async in connect(); guarded by the null check in handlers */
    private terminalManager;
    private keepAliveInterval;
    private rpcHandlerManager;
    /**
     * Single shared device-code flow runner per daemon process. Wave 2
     * of agent-auth-foundation. Handles `claude login` / `gcloud auth
     * login --no-browser` and any future RFC 8628 device-code flow.
     */
    private deviceCodeFlow;
    private pasteFlow;
    /** Claude subscription paste-code (OOB OAuth) flow. */
    private claudePasteCodeFlow;
    /**
     * Drives an agent's OWN `login` command (see auth/flows/cliLogin.ts). This
     * is preferred over every daemon-implemented OAuth path when the binary is
     * installed, because the CLI holds its own PKCE verifier, talks to its own
     * (current) endpoints, and writes its own credential file.
     */
    private cliLoginFlow;
    /**
     * Single shared agent-CLI install runner (start → poll → cancel). Gated
     * daemon-side by CONSORTIUM_AGENT_INSTALL=0. See cli-install/installFlow.ts.
     */
    private installFlow;
    private hasConnectedOnce;
    private consecutiveAuthErrors;
    private disconnectedAt;
    private reconnectTimer;
    private manualReconnectAttempts;
    private destroyed;
    /**
     * L3.3 — drains the durable machine-origin UsageEvent queue to
     * `POST /v1/usage-events`. The daemon owns it because the daemon owns the
     * server credential; the per-session LMP only ever writes to the queue.
     * Created lazily on first successful connect (see `startUsageUploader`).
     */
    private usageUploader;
    constructor(token: string, machine: Machine);
    setRPCHandlers({ spawnSession, stopSession, reprovisionSession, requestShutdown }: MachineRpcHandlers): void;
    /**
     * Update machine metadata
     * Currently unused, changes from the mobile client are more likely
     * for example to set a custom name.
     */
    updateMachineMetadata(handler: (metadata: MachineMetadata | null) => MachineMetadata): Promise<void>;
    /**
     * Update daemon state (runtime info) - similar to session updateAgentState
     * Simplified without lock - relies on backoff for retry
     */
    updateDaemonState(handler: (state: DaemonState | null) => DaemonState): Promise<void>;
    connect(options?: ApiMachineConnectOptions): void;
    /**
     * Recovery for a socket that was ESTABLISHED and then dropped.
     *
     * `scheduleManualReconnect` covers handshake failures (`connect_error`).
     * Nothing covered a *post-connect* drop: the disconnect handler only
     * stopped the keep-alive and trusted `reconnection: true` to bring the
     * socket back. That trust is misplaced for two of Socket.IO v4's
     * disconnect reasons, and the gap is a real outage — on 2026-08-16
     * Station 1 logged `Disconnected from server` and then went silent for
     * hours: process alive, log still writing, zero sockets open, machine
     * reading offline. `Restart=always` cannot help because nothing exits.
     *
     * Reasons and who owns recovery:
     *   `io client disconnect` — we called disconnect(). Intentional; do
     *                            nothing, or shutdown() would reopen itself.
     *   `io server disconnect` — the server called socket.disconnect(). The
     *                            Manager treats this as terminal and will
     *                            NOT retry. We must reconnect ourselves.
     *   everything else        — transport close/error, ping timeout, parse
     *                            error. The Manager does retry these, so
     *                            arm a watchdog instead of racing it, and
     *                            take over only if it has not recovered.
     *
     * The watchdog shares `reconnectTimer` with the manual scheduler on
     * purpose: a successful `connect` clears that timer, so recovering by
     * either route disarms the other automatically.
     */
    private scheduleRecoveryFromDisconnect;
    /**
     * Schedule a manual reconnect with exponential backoff + jitter. Called
     * from the connect_error handler because Socket.IO v4 does not retry
     * middleware-rejected handshakes on its own (see comment in the handler).
     *
     * If a refreshToken callback is provided and the rejection looked like
     * an auth error, the new token is swapped into socket.auth before the
     * next attempt. Backoff: 1s, 2s, 4s, 8s, 10s (cap), with up to 1s of
     * random jitter on top. The 10s cap matches socket.io's
     * reconnectionDelayMax and keeps the worst-case heartbeat gap under the
     * app's 60s offline threshold so a reconnecting daemon never reads as
     * offline. Reset to 0 on successful connect.
     */
    private scheduleManualReconnect;
    /**
     * L3.3 — start the durable usage-queue drain.
     *
     * Idempotent: the uploader is created once per client and `start()` is a
     * no-op while it is already running, so reconnect storms cannot stack
     * timers. `getToken` is read lazily on every batch so a token refreshed by
     * `scheduleManualReconnect` is picked up without recreating anything.
     *
     * Never fatal: a queue that cannot be opened (read-only home dir) must not
     * stop the daemon from serving sessions — metering is telemetry, not the
     * product.
     */
    private startUsageUploader;
    private startKeepAlive;
    private stopKeepAlive;
    /**
     * Emit an encrypted OpenClaw activity event to be relayed to the mobile app.
     * The encryptedPayload should already be base64(encrypted(event data)).
     */
    emitOpenClawActivity(eventType: string, agentId: string | null, encryptedPayload: string): void;
    /**
     * Emit one streaming agent-chat frame. The payload is encrypted here
     * with the machine key so the server relays ciphertext only; the app
     * decrypts with the same machine key it already holds.
     */
    emitAgentChatFrame(frame: {
        requestId: string;
        agentId: string | null;
        seq: number;
        payload: {
            delta?: string;
            reply?: string;
            error?: string;
        };
        done: boolean;
    }): void;
    /**
     * Emit an OpenClaw status update (unencrypted, for quick display).
     */
    emitOpenClawStatus(status: string, version: string | null, gatewayPort: number, channels: string[], agentCount: number): void;
    /**
     * Emit a deployment health status event to the server for mobile app display.
     *
     * Accepts the full set of deployment lifecycle statuses (health, container,
     * deploy/stop/remove) plus optional metadata fields used by the deployment
     * RPC handlers in daemon/run.ts.
     */
    emitDeploymentStatus(data: {
        deploymentId: string;
        status: 'healthy' | 'unhealthy' | 'running' | 'stopped' | 'pulling' | 'failed' | 'removing' | string;
        healthStatus?: 'healthy' | 'unhealthy' | 'unknown';
        statusMessage?: string;
        containerName?: string;
        url?: string;
        timestamp?: number;
        [extra: string]: unknown;
    }): void;
    /** Exposes the RPC handler manager for registering additional handlers (e.g. OpenClaw) */
    get rpcHandlers(): RpcHandlerManager;
    /** Exposes the machine's encryption key for the bridge to encrypt activity payloads */
    get encryptionKey(): Uint8Array;
    /** Exposes the encryption variant */
    get encryptionVariant(): 'legacy' | 'dataKey';
    shutdown(): void;
}

interface PushToken {
    id: string;
    token: string;
    createdAt: number;
    updatedAt: number;
}
declare class PushNotificationClient {
    private readonly token;
    private readonly baseUrl;
    private readonly expo;
    constructor(token: string, baseUrl?: string);
    /**
     * Fetch all push tokens for the authenticated user
     */
    fetchPushTokens(): Promise<PushToken[]>;
    /**
     * Send push notification via Expo Push API with retry
     * @param messages - Array of push messages to send
     */
    sendPushNotifications(messages: ExpoPushMessage[]): Promise<void>;
    /**
     * Send a push notification to all registered devices for the user
     * @param title - Notification title
     * @param body - Notification body
     * @param data - Additional data to send with the notification
     */
    sendToAllDevices(title: string, body: string, data?: Record<string, any>): void;
}

/**
 * Minimal persistence functions for consortium CLI
 *
 * Handles settings and private key storage in ~/.consortium/ or local .consortium/
 */

type Credentials = {
    token: string;
    encryption: {
        type: 'legacy';
        secret: Uint8Array;
    } | {
        type: 'dataKey';
        publicKey: Uint8Array;
        machineKey: Uint8Array;
    } | null;
};

declare class ApiClient {
    static create(credential: Credentials): Promise<ApiClient>;
    private readonly credential;
    private readonly pushClient;
    private constructor();
    /**
     * Create a new session or load existing one with the given tag
     */
    getOrCreateSession(opts: {
        tag: string;
        metadata: Metadata;
        state: AgentState | null;
        organizationId?: string;
        projectId?: string;
    }): Promise<Session | null>;
    /**
     * Register or update machine with the server
     * Returns the current machine state from the server with decrypted metadata and daemonState
     */
    getOrCreateMachine(opts: {
        machineId: string;
        metadata: MachineMetadata;
        daemonState?: DaemonState;
        vpsInstanceId?: string;
        organizationId?: string;
    }): Promise<Machine>;
    sessionSyncClient(session: Session): ApiSessionClient;
    machineSyncClient(machine: Machine): ApiMachineClient;
    push(): PushNotificationClient;
    /**
     * Register a vendor API token with the server
     * The token is sent as a JSON string - server handles encryption
     */
    registerVendorToken(vendor: 'openai' | 'anthropic' | 'gemini' | 'xai', apiKey: any): Promise<void>;
    /**
     * Get vendor API token from the server
     * Returns the token if it exists, null otherwise
     */
    getVendorToken(vendor: 'openai' | 'anthropic' | 'gemini' | 'xai'): Promise<any | null>;
    /**
     * Fetches the list of organizations the user belongs to.
     * Used for the interactive org picker on CLI startup.
     *
     * THROWS on failure (network / 5xx / auth). Previously this swallowed
     * errors and returned `[]`, which conflated "the user has no orgs" with
     * "we couldn't reach the server". The daemon path used that empty array to
     * register the machine UNSCOPED, so a transient 5xx during startup
     * orphaned the machine outside any org. Callers must now distinguish the
     * two: a real empty list returns `[]`, an error rejects. Interactive
     * callers (`auth`) already wrap this in try/catch and degrade gracefully;
     * the daemon falls back to the persisted org or refuses to register
     * unscoped on a fetch failure.
     */
    fetchOrgs(): Promise<Array<{
        id: string;
        name: string;
        slug: string;
        type: 'personal' | 'team';
        tier: string;
        memberCount: number;
    }>>;
}

/**
 * serializeError — convert unknown thrown values into a JSON-safe shape.
 *
 * Error objects have non-enumerable `name`/`message`/`stack`, so a plain
 * JSON.stringify(err) — or embedding an error inside a context object like
 * `{ error }` — yields `{}` and destroys the diagnostics. This is exactly how
 * the daemon used to log `[RPC] [ERROR] Error handling request {"error":{}}`.
 * Any code that puts an error inside a log/context object must go through
 * this helper.
 */
interface SerializedError {
    name: string;
    message: string;
    stack?: string;
    /** Node ErrnoException code (ENOENT, ECONNREFUSED, EADDRINUSE, ...) when present */
    code?: string;
    cause?: SerializedError;
}

/**
 * Design decisions:
 * - Logging should be done only through file for debugging, otherwise we might disturb the claude session when in interactive mode
 * - Use info for logs that are useful to the user - this is our UI
 * - File output location: ~/.consortium/logs/<date time in local timezone>.log
 * - Every entry is mirrored as a structured JSONL line to a sibling `.jsonl`
 *   file ({ts, level, msg, err?, ctx?, reqId?}) so tooling and the log
 *   watchdog can parse logs without regexes. The plaintext file format is
 *   unchanged for humans and existing tools.
 * - A ring buffer of recent lines feeds last-exit.json (crash forensics), and
 *   subscribers (daemon/logWatchdog.ts) get every structured entry in-process.
 */

type LogLevel = 'debug' | 'info' | 'warn' | 'error';
/** One structured log entry — the JSONL line shape. */
interface StructuredLogEntry {
    ts: string;
    level: LogLevel;
    msg: string;
    /** Serialized error when the entry carries one */
    err?: SerializedError;
    /** Additional structured context */
    ctx?: Record<string, unknown>;
    /** Correlation ID linking this entry to the originating RPC/request */
    reqId?: string;
}
declare class Logger {
    readonly logFilePath: string;
    private dangerouslyUnencryptedServerLoggingUrl;
    /** Sibling structured log: same path with .jsonl extension */
    readonly structuredLogFilePath: string;
    private recentLines;
    private subscribers;
    /** Correlation ID inherited from the spawning daemon, if any */
    private readonly inheritedReqId;
    constructor(logFilePath?: string);
    /**
     * Subscribe to every structured entry (in-process). Used by the daemon log
     * watchdog. Subscribers must never throw — exceptions are swallowed so a
     * broken subscriber can't take down logging.
     */
    subscribe(fn: (entry: StructuredLogEntry) => void): () => void;
    /** Last N plaintext log lines, oldest first. Feeds last-exit.json forensics. */
    getRecentLines(): string[];
    /**
     * Structured logging entry point: writes both the plaintext line (for
     * humans) and the JSONL line (for tooling), with an explicit level and
     * optional error / context / correlation ID.
     */
    event(level: LogLevel, message: string, opts?: {
        err?: unknown;
        ctx?: Record<string, unknown>;
        reqId?: string;
    }): void;
    /**
     * Unified sink: one call produces exactly one plaintext line and one JSONL
     * line, updates the ring buffer, and notifies subscribers. All public log
     * methods route through here.
     */
    private write;
    localTimezoneTimestamp(): string;
    debug(message: string, ...args: unknown[]): void;
    debugLargeJson(message: string, object: unknown, maxStringLength?: number, maxArrayLength?: number): void;
    info(message: string, ...args: unknown[]): void;
    infoDeveloper(message: string, ...args: unknown[]): void;
    warn(message: string, ...args: unknown[]): void;
    error(message: string, ...args: unknown[]): void;
    getLogPath(): string;
    private logToConsole;
    private sendToRemoteServer;
    private logToFile;
}
declare let logger: Logger;

/**
 * Global configuration for consortium CLI
 *
 * Centralizes all configuration including environment variables and paths
 * Environment files should be loaded using Node's --env-file flag
 */
declare class Configuration {
    readonly serverUrl: string;
    readonly webappUrl: string;
    readonly isDaemonProcess: boolean;
    readonly consortiumHomeDir: string;
    readonly logsDir: string;
    readonly settingsFile: string;
    readonly privateKeyFile: string;
    readonly daemonStateFile: string;
    readonly daemonLockFile: string;
    readonly currentCliVersion: string;
    readonly isExperimentalEnabled: boolean;
    readonly disableCaffeinate: boolean;
    readonly authToken: string | undefined;
    constructor();
}
declare const configuration: Configuration;

export { ApiClient, ApiSessionClient, RawJSONLinesSchema, configuration, logger };
export type { RawJSONLines };