import { z } from "zod/v4";
export const LlmProtocol = z.enum(["openai", "claude"]);
export const BrowserConnectionMode = z.enum(["remote-debug", "extension-relay"]);
export const ProxyConfig = z.object({
    protocol: z.enum(["socks5", "socks4", "http", "https"]),
    host: z.string().min(1),
    port: z.number().int().positive(),
    username: z.string().optional(),
    password: z.string().optional(),
});
/** Validate an IANA timezone name via Intl. Returns true for valid zones (e.g. "UTC", "Asia/Shanghai"). */
export function isValidTimezone(tz) {
    try {
        new Intl.DateTimeFormat(undefined, { timeZone: tz });
        return true;
    }
    catch {
        return false;
    }
}
/** Build a proxy URL string from structured config */
export function proxyConfigToUrl(proxy) {
    const auth = proxy.username && proxy.password
        ? `${encodeURIComponent(proxy.username)}:${encodeURIComponent(proxy.password)}@`
        : "";
    return `${proxy.protocol}://${auth}${proxy.host}:${proxy.port}`;
}
export const DipclawConfig = z.object({
    name: z.string().min(1),
    workspace: z.string().min(1),
    llm: z.object({
        protocol: LlmProtocol,
        baseUrl: z.string().min(1),
        apiKey: z.string().min(1),
        model: z.string().min(1),
        maxTokens: z.number().int().positive().optional(),
        /** Optional OpenAI-compatible image generation on the same baseUrl. */
        imageGeneration: z
            .object({
            apiKey: z.string().min(1),
            model: z.string().min(1),
            size: z.string().default("1024x1024"),
            timeoutMs: z.number().int().positive().default(120000),
        })
            .optional(),
    }),
    telegram: z
        .object({
        botToken: z.string().min(1),
        allowedUsers: z.array(z.number().int()),
    })
        .optional(),
    maxIterations: z.number().int().positive().default(90),
    debug: z.boolean().default(false),
    tui: z.boolean().default(false),
    scheduler: z
        .object({
        /** Default IANA timezone for cron tasks (e.g. "UTC", "Asia/Shanghai"). Falls back to system timezone if unset. */
        timezone: z
            .string()
            .refine(isValidTimezone, { message: "Invalid IANA timezone" })
            .optional(),
        /** Max wall-clock time for a scheduled task before Chrome is restarted. */
        taskTimeoutMs: z.number().int().positive().default(30 * 60 * 1000),
        /** Restart Chrome after this much uptime, but only while idle. */
        chromeMaxRuntimeMs: z.number().int().positive().default(24 * 60 * 60 * 1000),
        /** How often to check whether Chrome is old enough to restart. */
        chromeRestartCheckIntervalMs: z
            .number()
            .int()
            .positive()
            .default(10 * 60 * 1000),
        /** Do not perform an age-based restart when a cron run is this close. */
        chromeRestartMinLeadMs: z.number().int().positive().default(10 * 60 * 1000),
        /**
         * Close Chrome when it has been idle for this long (ms). Workspace
         * ownership is retained so the next browser action relaunches Chrome
         * in-place without re-claiming the lock. Set to a very large value to
         * effectively disable idle-close.
         */
        chromeIdleCloseMs: z.number().int().positive().default(5 * 60 * 1000),
        /** Do not perform an idle-close when a cron run is this close. */
        chromeIdleCloseMinLeadMs: z
            .number()
            .int()
            .positive()
            .default(2 * 60 * 1000),
        /** How often to check whether Chrome has been idle long enough to close. */
        chromeIdleCloseCheckIntervalMs: z
            .number()
            .int()
            .positive()
            .default(60 * 1000),
    })
        .optional(),
    browser: z
        .object({
        connectionMode: BrowserConnectionMode.default("extension-relay"),
        headless: z.boolean().default(false),
        /**
         * Browser automation backend. "chrome" (default) spawns real Google
         * Chrome + CDP attach with the OmniFlow extension. "cloakbrowser" launches
         * the C++-patched stealth Chromium via the cloakbrowser package. cs-only:
         * standalone always uses "chrome".
         */
        backend: z.enum(["chrome", "cloakbrowser"]).default("chrome"),
        /**
         * Stable, immutable anchor for the cloakbrowser per-worker fingerprint
         * seed. Set to the worker_id in center mode (survives renames/redeploys);
         * falls back to the worker name when absent. cs-only effect.
         */
        fingerprintKey: z.string().optional(),
        /**
         * Unsafe compatibility switch for JS/DOM-based interaction fallbacks
         * such as act:evaluate, dispatch="dom", DOM key/hover fallbacks, and
         * synthetic paste/clear paths. Keep false by default.
         */
        allowEvaluateFallbacks: z.boolean().default(false),
        proxy: ProxyConfig.optional(),
        viewport: z
            .object({
            width: z.number().int().positive(),
            height: z.number().int().positive(),
        })
            .optional(),
        timezone: z.string().optional(),
        /** Random delay between browser actions for human simulation (ms) */
        actionDelay: z
            .object({
            min: z.number().int().nonnegative().default(800),
            max: z.number().int().nonnegative().default(3000),
        })
            .optional(),
        relay: z
            .object({
            connectTimeoutMs: z.number().int().positive().default(20_000),
            autoApprove: z.boolean().default(true),
        })
            .optional(),
    })
        .default({
        connectionMode: "extension-relay",
        headless: false,
        backend: "chrome",
        allowEvaluateFallbacks: false,
    }),
    org: z
        .object({
        /**
         * 组织中心根目录 (必须是所有 Agent 都能访问的共享路径，用于存放注册表和收件箱)
         * 例如：/Users/shared/org-center 或 /Volumes/挂载的云盘/org-center
         */
        root: z.string().min(1),
        /**
         * 该 Agent 所属或管理的部门名称。
         * 1. 员工 (worker)：只能填写一个部门名，如 "推广部"。
         * 2. 部门老板 (boss)：填写自己管理的部门，如 "推广部" 或 ["推广部", "客服部"]。
         * 3. 超级老板 (boss)：填写 "*" 代表拥有全公司的管理视角。
         */
        department: z.union([z.string(), z.array(z.string())]).default("*"),
        /**
         * 角色定位：
         * - "boss": 拥有管理权限，可以调用 org.assign 分发任务，查看团队。
         * - "worker": 基层员工，只会默默轮询收件箱并执行被分发的任务。
         */
        role: z.enum(["boss", "worker"]).default("worker"),
    })
        .optional(),
});
//# sourceMappingURL=types.js.map