@xopcai/xopc 0.0.66 → 0.0.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/dist/extensions/telegram/xopc.extension.json +1 -1
  2. package/dist/gateway/static/root/assets/{agents-JiJR38n1.js → agents-CmhOU0fB.js} +2 -2
  3. package/dist/gateway/static/root/assets/{agents-JiJR38n1.js.map → agents-CmhOU0fB.js.map} +1 -1
  4. package/dist/gateway/static/root/assets/{apps-page-aBDyr7Im.js → apps-page-CzS9A_6L.js} +2 -2
  5. package/dist/gateway/static/root/assets/{apps-page-aBDyr7Im.js.map → apps-page-CzS9A_6L.js.map} +1 -1
  6. package/dist/gateway/static/root/assets/{channels-settings-DXxfgG4N.js → channels-settings-Bn0YSztA.js} +2 -2
  7. package/dist/gateway/static/root/assets/{channels-settings-DXxfgG4N.js.map → channels-settings-Bn0YSztA.js.map} +1 -1
  8. package/dist/gateway/static/root/assets/{cron-dreaming-jobs-3--QJSP5.js → cron-dreaming-jobs-bAYsiHdF.js} +2 -2
  9. package/dist/gateway/static/root/assets/{cron-dreaming-jobs-3--QJSP5.js.map → cron-dreaming-jobs-bAYsiHdF.js.map} +1 -1
  10. package/dist/gateway/static/root/assets/{cron-page-CCn-JwBy.js → cron-page-CKqDtScu.js} +2 -2
  11. package/dist/gateway/static/root/assets/{cron-page-CCn-JwBy.js.map → cron-page-CKqDtScu.js.map} +1 -1
  12. package/dist/gateway/static/root/assets/{dist-BS-cwfHQ.js → dist-CUMhnSuX.js} +2 -2
  13. package/dist/gateway/static/root/assets/{dist-BS-cwfHQ.js.map → dist-CUMhnSuX.js.map} +1 -1
  14. package/dist/gateway/static/root/assets/{extension-debug-page-M8JS4Jid.js → extension-debug-page-BDls5xp3.js} +2 -2
  15. package/dist/gateway/static/root/assets/{extension-debug-page-M8JS4Jid.js.map → extension-debug-page-BDls5xp3.js.map} +1 -1
  16. package/dist/gateway/static/root/assets/{extension-page-C8gjVE_t.js → extension-page-BSfv53OO.js} +2 -2
  17. package/dist/gateway/static/root/assets/{extension-page-C8gjVE_t.js.map → extension-page-BSfv53OO.js.map} +1 -1
  18. package/dist/gateway/static/root/assets/{extension-settings-page-DeY2M2di.js → extension-settings-page-B0nkVsLi.js} +2 -2
  19. package/dist/gateway/static/root/assets/{extension-settings-page-DeY2M2di.js.map → extension-settings-page-B0nkVsLi.js.map} +1 -1
  20. package/dist/gateway/static/root/assets/{heartbeat-config-api-DWmeyjyR.js → heartbeat-config-api-P5zdbIBw.js} +2 -2
  21. package/dist/gateway/static/root/assets/{heartbeat-config-api-DWmeyjyR.js.map → heartbeat-config-api-P5zdbIBw.js.map} +1 -1
  22. package/dist/gateway/static/root/assets/{index-Cc57jhuG.js → index-DAglRwh4.js} +5 -5
  23. package/dist/gateway/static/root/assets/{index-Cc57jhuG.js.map → index-DAglRwh4.js.map} +1 -1
  24. package/dist/gateway/static/root/assets/index-DHj3Cf9B.css +1 -0
  25. package/dist/gateway/static/root/assets/{logs-page-kIsSDMqb.js → logs-page-CfGDv4k7.js} +2 -2
  26. package/dist/gateway/static/root/assets/{logs-page-kIsSDMqb.js.map → logs-page-CfGDv4k7.js.map} +1 -1
  27. package/dist/gateway/static/root/assets/{sessions-page-Da9gjMh7.js → sessions-page-DoGE8N-O.js} +2 -2
  28. package/dist/gateway/static/root/assets/{sessions-page-Da9gjMh7.js.map → sessions-page-DoGE8N-O.js.map} +1 -1
  29. package/dist/gateway/static/root/assets/settings-page-C5VrwDoO.js +3 -0
  30. package/dist/gateway/static/root/assets/settings-page-C5VrwDoO.js.map +1 -0
  31. package/dist/gateway/static/root/assets/{skills-page-B_msZcLx.js → skills-page-ADUi69Fa.js} +2 -2
  32. package/dist/gateway/static/root/assets/{skills-page-B_msZcLx.js.map → skills-page-ADUi69Fa.js.map} +1 -1
  33. package/dist/gateway/static/root/assets/{use-image-provider-credentials-Bs8xl2E3.js → use-image-provider-credentials-C4x4dNv2.js} +2 -2
  34. package/dist/gateway/static/root/assets/{use-image-provider-credentials-Bs8xl2E3.js.map → use-image-provider-credentials-C4x4dNv2.js.map} +1 -1
  35. package/dist/gateway/static/root/index.html +2 -2
  36. package/dist/package.js +1 -1
  37. package/dist/src/cli/commands/tunnel.js +69 -8
  38. package/dist/src/cli/commands/tunnel.js.map +1 -1
  39. package/dist/src/config/schema.d.ts +2 -0
  40. package/dist/src/config/schema.js +2 -0
  41. package/dist/src/config/schema.js.map +1 -1
  42. package/dist/src/gateway/hono/lib/config-payload.d.ts +2 -5
  43. package/dist/src/gateway/hono/lib/config-payload.js +3 -5
  44. package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
  45. package/dist/src/gateway/hono/routes/tunnel.js +12 -10
  46. package/dist/src/gateway/hono/routes/tunnel.js.map +1 -1
  47. package/dist/src/tunnel/acme-client.d.ts +11 -0
  48. package/dist/src/tunnel/acme-client.js +54 -10
  49. package/dist/src/tunnel/acme-client.js.map +1 -1
  50. package/dist/src/tunnel/env.d.ts +14 -3
  51. package/dist/src/tunnel/env.js +34 -5
  52. package/dist/src/tunnel/env.js.map +1 -1
  53. package/dist/src/tunnel/frpc-binary.d.ts +6 -1
  54. package/dist/src/tunnel/frpc-binary.js +66 -40
  55. package/dist/src/tunnel/frpc-binary.js.map +1 -1
  56. package/dist/src/tunnel/frpc-extract.d.ts +10 -0
  57. package/dist/src/tunnel/frpc-extract.js +129 -0
  58. package/dist/src/tunnel/frpc-extract.js.map +1 -0
  59. package/dist/src/tunnel/gateway-lifecycle.d.ts +3 -1
  60. package/dist/src/tunnel/gateway-lifecycle.js +6 -4
  61. package/dist/src/tunnel/gateway-lifecycle.js.map +1 -1
  62. package/dist/src/tunnel/index.d.ts +3 -1
  63. package/dist/src/tunnel/index.js +2 -2
  64. package/dist/src/tunnel/tls-server.js +5 -0
  65. package/dist/src/tunnel/tls-server.js.map +1 -1
  66. package/dist/src/tunnel/tunnel-config.js +11 -1
  67. package/dist/src/tunnel/tunnel-config.js.map +1 -1
  68. package/dist/src/tunnel/tunnel-e2e-config.d.ts +4 -1
  69. package/dist/src/tunnel/tunnel-e2e-config.js +10 -3
  70. package/dist/src/tunnel/tunnel-e2e-config.js.map +1 -1
  71. package/dist/src/tunnel/tunnel-service.d.ts +4 -0
  72. package/dist/src/tunnel/tunnel-service.js +66 -5
  73. package/dist/src/tunnel/tunnel-service.js.map +1 -1
  74. package/dist/src/tunnel/tunnel-types.d.ts +16 -0
  75. package/package.json +3 -3
  76. package/dist/gateway/static/root/assets/index-B5gp15_q.css +0 -1
  77. package/dist/gateway/static/root/assets/settings-page-B0spIRVS.js +0 -3
  78. package/dist/gateway/static/root/assets/settings-page-B0spIRVS.js.map +0 -1
@@ -700,6 +700,7 @@ export declare const TunnelE2eSchema: z.ZodDefault<z.ZodObject<{
700
700
  export declare const TunnelConfigSchema: z.ZodDefault<z.ZodObject<{
701
701
  enabled: z.ZodDefault<z.ZodBoolean>;
702
702
  brokerUrl: z.ZodDefault<z.ZodString>;
703
+ registrationSecret: z.ZodOptional<z.ZodString>;
703
704
  autoStart: z.ZodDefault<z.ZodBoolean>;
704
705
  subdomain: z.ZodOptional<z.ZodString>;
705
706
  consent: z.ZodOptional<z.ZodObject<{
@@ -1487,6 +1488,7 @@ export declare const ConfigSchema: z.ZodDefault<z.ZodObject<{
1487
1488
  tunnel: z.ZodOptional<z.ZodDefault<z.ZodObject<{
1488
1489
  enabled: z.ZodDefault<z.ZodBoolean>;
1489
1490
  brokerUrl: z.ZodDefault<z.ZodString>;
1491
+ registrationSecret: z.ZodOptional<z.ZodString>;
1490
1492
  autoStart: z.ZodDefault<z.ZodBoolean>;
1491
1493
  subdomain: z.ZodOptional<z.ZodString>;
1492
1494
  consent: z.ZodOptional<z.ZodObject<{
@@ -497,6 +497,8 @@ summaryModel: z.string().optional() }).optional(),
497
497
  TunnelConfigSchema = z.object({
498
498
  enabled: z.boolean().default(false),
499
499
  brokerUrl: z.string().url().default("https://frp.xopc.ai/api"),
500
+ /** Broker register API secret (env `XOPC_TUNNEL_REGISTRATION_SECRET` overrides when set). */
501
+ registrationSecret: z.string().min(1).optional(),
500
502
  autoStart: z.boolean().default(false),
501
503
  subdomain: z.string().optional(),
502
504
  consent: TunnelConsentSchema.optional(),
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","names":[],"sources":["../../../src/config/schema.ts"],"sourcesContent":["import { z } from 'zod';\n\nimport { getDefaultWorkspacePath } from '../agent/agent-scope.js';\n\n// ============================================\n// Agent Configs\n// ============================================\n\nexport const AgentModelRefSchema = z.union([\n z.string(),\n z\n .object({\n primary: z.string().optional(),\n fallbacks: z.array(z.string()).optional(),\n })\n .strict(),\n]);\n\nexport type AgentModelConfig = z.infer<typeof AgentModelRefSchema>;\n\n/**\n * Image-generation model ref. Superset of {@link AgentModelRefSchema} with\n * runtime knobs (`timeoutMs`, `autoProviderFallback`) used by the\n * image-generation runtime; falls back to a plain string for backward\n * compatibility with old configs.\n */\nexport const AgentImageGenerationModelSchema = z.union([\n z.string(),\n z\n .object({\n primary: z.string().optional(),\n fallbacks: z.array(z.string()).optional(),\n /** Hard cap for the whole generation attempt (ms). */\n timeoutMs: z.number().int().positive().optional(),\n /**\n * When all `primary + fallbacks` candidates fail, sweep every other\n * configured provider before giving up.\n */\n autoProviderFallback: z.boolean().optional(),\n })\n .strict(),\n]);\n\nexport type AgentImageGenerationModelConfig = z.infer<typeof AgentImageGenerationModelSchema>;\n\nexport const AgentDefaultsSchema = z.object({\n /** Parent directory: each agent’s Markdown root is `<expanded>/<agentId>/` (e.g. `.../workspace/main`). */\n workspace: z.string().default('~/.xopc/workspace'),\n model: z.union([\n z.string(),\n z.object({\n primary: z.string().optional(),\n fallbacks: z.array(z.string()).optional(),\n }).strict(),\n ]).default(''), // Empty default - will be resolved dynamically at runtime\n /** Vision / image understanding model (provider/model). Falls back to heuristics when unset. */\n imageModel: AgentModelRefSchema.optional(),\n /** Image generation model (provider/model), e.g. openai/gpt-image-1. Supports plugin-based providers (OpenAI / DashScope / MiniMax / Google / Fal). */\n imageGenerationModel: AgentImageGenerationModelSchema.optional(),\n /** Max image size for image tool loads (MB). */\n mediaMaxMb: z.number().positive().optional(),\n maxTokens: z.number().default(8192),\n temperature: z.number().default(0.7),\n maxToolIterations: z.number().default(20),\n // Wall-clock limit for one user turn (LLM + tools). Default 30m if unset; cap 4h.\n maxTaskDurationMs: z.number().min(60000).max(14_400_000).optional(),\n // Reliability settings\n maxRequestsPerTurn: z.number().min(10).max(200).default(50),\n maxToolFailuresPerTurn: z.number().min(1).max(20).default(3),\n // Thinking ability settings\n thinkingDefault: z.enum(['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'adaptive']).optional(),\n reasoningDefault: z.enum(['off', 'on', 'stream']).optional(),\n verboseDefault: z.enum(['off', 'on', 'full']).optional(),\n bootstrapMaxChars: z.number().int().positive().optional(),\n bootstrapTotalMaxChars: z.number().int().positive().optional(),\n bootstrapPromptTruncationWarning: z.enum(['off', 'once', 'always']).optional(),\n startupContext: z\n .object({\n enabled: z.boolean().optional(),\n applyOn: z.array(z.enum(['new', 'reset'])).optional(),\n dailyMemoryDays: z.number().int().min(1).optional(),\n maxFileBytes: z.number().int().positive().optional(),\n maxFileChars: z.number().int().positive().optional(),\n maxTotalChars: z.number().int().positive().optional(),\n })\n .optional(),\n contextLimits: z\n .object({\n postCompactionMaxChars: z.number().int().positive().optional(),\n })\n .optional(),\n compaction: z.object({\n enabled: z.boolean().default(true),\n mode: z.enum(['default', 'safeguard']).default('default'),\n reserveTokens: z.number().default(8000),\n triggerThreshold: z.number().min(0.5).max(0.95).default(0.8),\n minMessagesBeforeCompact: z.number().default(10),\n keepRecentMessages: z.number().default(5),\n // Dual-strategy compaction\n evictionWindow: z.number().min(0.1).max(0.5).default(0.2),\n retentionWindow: z.number().min(3).max(20).default(6),\n postCompactionSections: z.array(z.string()).optional(),\n }).optional(),\n pruning: z.object({\n enabled: z.boolean().default(true),\n maxToolResultChars: z.number().default(10000),\n headKeepRatio: z.number().default(0.3),\n tailKeepRatio: z.number().default(0.3),\n }).optional(),\n /**\n * Curated memory (`agents/<id>/memories/`) + pluggable external provider.\n * Only one external provider at a time.\n */\n memory: z\n .object({\n /** Master switch: `curated_memory` tool, prefetch, and external provider. Default true. */\n enabled: z.boolean().optional(),\n /** When false, disable curated_memory tool and memory subsystem helpers. Default true. */\n useEnhancedSystem: z.boolean().optional(),\n /** Include USER.md in snapshot. Default true. */\n userProfileEnabled: z.boolean().optional(),\n memoryCharLimit: z.number().positive().optional(),\n userCharLimit: z.number().positive().optional(),\n provider: z.enum(['none', 'stub']).optional(),\n /** How often prefetched external memory is injected into the user message. */\n injectionFrequency: z.enum(['every-turn', 'first-turn']).optional(),\n /** Inject prefetch on turns 1, 1+N, 1+2N, … (only when injectionFrequency is every-turn). Min 1. */\n contextCadence: z.number().int().min(1).optional(),\n /** Reserved for future external “dialectic” sync cadence (not wired yet). */\n dialecticCadence: z.number().int().min(1).optional(),\n /**\n * Background memory consolidation (\"dreaming\"): three-phase sleep model that\n * promotes short-term recall signals into long-term memory (`MEMORY.md`).\n *\n * Phases:\n * - **light** — fast, frequent sweep (default every 6 h): dedup + signal collection.\n * - **deep** — daily deep promotion (default 3 AM): score-gated write to MEMORY.md.\n * - **rem** — weekly pattern discovery (default Sun 5 AM): cross-session insight mining.\n */\n dreaming: z\n .object({\n enabled: z.boolean().optional(),\n /** Default deep-phase cron when `phases.deep.cron` is omitted. */\n frequency: z.string().optional(),\n timezone: z.string().optional(),\n phases: z\n .object({\n light: z\n .object({\n enabled: z.boolean().optional(),\n cron: z.string().optional(),\n lookbackDays: z.number().int().min(1).optional(),\n limit: z.number().int().min(0).optional(),\n dedupeSimilarity: z.number().min(0).max(1).optional(),\n })\n .optional(),\n deep: z\n .object({\n enabled: z.boolean().optional(),\n cron: z.string().optional(),\n minScore: z.number().min(0).max(1).optional(),\n minRecallCount: z.number().int().min(1).optional(),\n minUniqueQueries: z.number().int().min(1).optional(),\n limit: z.number().int().min(0).optional(),\n recencyHalfLifeDays: z.number().min(1).optional(),\n maxAgeDays: z.number().int().min(1).optional(),\n })\n .optional(),\n rem: z\n .object({\n enabled: z.boolean().optional(),\n cron: z.string().optional(),\n lookbackDays: z.number().int().min(1).optional(),\n limit: z.number().int().min(0).optional(),\n minPatternStrength: z.number().min(0).max(1).optional(),\n })\n .optional(),\n })\n .optional(),\n })\n .optional(),\n })\n .optional(),\n /** Cross-session transcript search (`session_search` tool). */\n sessionSearch: z\n .object({\n /** Model ref for per-session summaries (e.g. openai/gpt-4o-mini). */\n summaryModel: z.string().optional(),\n })\n .optional(),\n /**\n * Post-turn background review (Hermes-style): optional quiet follow-up that may call\n * `curated_memory` / `skill_manage` so durable facts and reusable workflows persist\n * without bloating the main user-visible turn.\n */\n backgroundReview: z\n .object({\n /** When true, nudges may run after successful turns. Default false (opt-in). */\n enabled: z.boolean().optional(),\n /** User-turn cadence for memory review. 0 disables the memory channel. Default 10. */\n memoryNudgeInterval: z.number().int().min(0).optional(),\n /** LLM rounds without `skill_manage` before a skill review. 0 disables the skill channel. Default 10. */\n skillNudgeInterval: z.number().int().min(0).optional(),\n /** Max tool executions for the review agent. Default 8. */\n maxToolRounds: z.number().int().min(1).max(32).optional(),\n /** Max prior messages passed into the review context (tail). Default 80. */\n maxHistoryMessages: z.number().int().min(10).max(200).optional(),\n /** Wall-clock cap for the review run (ms). Default 120000. */\n maxDurationMs: z.number().int().min(30_000).max(600_000).optional(),\n })\n .optional(),\n /** LLM pass for `web_extract` (markdown-focused extraction). */\n webExtract: z\n .object({\n model: z.string().optional(),\n maxLength: z.number().positive().optional(),\n })\n .optional(),\n /**\n * Browser capability via unified `browser_use` tool. Enabled by default (set `enabled: false` to disable).\n * Install browsers once: `npx playwright install chromium`.\n */\n browser: z\n .object({\n enabled: z.boolean().optional(),\n /** Run browser in headless mode (default: false — visible window). */\n headless: z.boolean().optional(),\n /** When true, skip private-IP blocking for browser navigation (cloud metadata endpoints are always blocked). */\n allowPrivateUrls: z.boolean().optional(),\n /** Browser command timeout in seconds (default: 30). */\n commandTimeout: z.number().min(5).optional(),\n /** Browser backend mode: 'local' (Playwright), 'cdp', 'cloud', or 'extension' (Chrome Extension bridge). */\n backend: z.enum(['local', 'cdp', 'cloud', 'extension']).optional(),\n /** Cloud browser backend: 'local' (default Playwright), 'browserbase', or 'browser-use'. */\n cloudProvider: z.enum(['local', 'browserbase', 'browser-use']).optional(),\n /** Direct CDP WebSocket endpoint URL (bypasses cloud provider). */\n cdpUrl: z.string().optional(),\n /** Chrome Extension bridge settings (only used when backend = 'extension'). */\n extension: z.object({\n /** WebSocket server port. Default: 19820. */\n port: z.number().min(1024).max(65535).optional(),\n /** Host to bind. Default: 127.0.0.1. */\n host: z.string().optional(),\n /** Timeout waiting for extension connection (ms). Default: 30000. */\n connectionTimeout: z.number().min(1000).optional(),\n }).optional(),\n /** JS dialog handling policy: 'must_respond' (agent must act), 'auto_dismiss', or 'auto_accept'. */\n dialogPolicy: z.enum(['must_respond', 'auto_dismiss', 'auto_accept']).optional(),\n /** Dialog auto-dismiss/accept timeout in seconds (default: 300). */\n dialogTimeoutSeconds: z.number().min(1).optional(),\n })\n .optional(),\n /** Sub-agent delegation (`delegate_task`). Opt-in. */\n delegate: z\n .object({\n enabled: z.boolean().optional(),\n })\n .optional(),\n /** Sandboxed `execute_code` (programmatic tool calls). Opt-in. */\n executeCode: z\n .object({\n enabled: z.boolean().optional(),\n })\n .optional(),\n /** Optional full system prompt replacement (merged with per-agent entry; entry wins). */\n systemPromptOverride: z.string().optional(),\n /** Optional allowlist of skill names for `<available_skills>`; when set, replaces unfiltered list. */\n skills: z.array(z.string()).optional(),\n /** Disable built-in tools by name (e.g. `shell`, `web_search`). */\n tools: z\n .object({\n disable: z.array(z.string()).optional(),\n })\n .optional(),\n /** Opaque per-process params (reserved for extensions / future use). */\n params: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport const AgentConfigSchema = z.object({\n id: z.string(),\n /** When true, this entry is the default routing agent. */\n default: z.boolean().optional(),\n name: z.string().optional(),\n /** Short human-readable summary for UIs (gateway console, pickers). */\n description: z.string().max(4000).optional(),\n enabled: z.boolean().default(true),\n /** Per-agent workspace root (`~` expanded at runtime). */\n workspace: z.string().optional(),\n /**\n * Internal agent state directory (`…/credentials`, `agent.json`, pid, inbox).\n * Default: `<stateDir>/agents/<id>/agent`.\n */\n agentDir: z.string().optional(),\n model: AgentModelRefSchema.optional(),\n thinkingDefault: z.enum(['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'adaptive']).optional(),\n reasoningDefault: z.enum(['off', 'on', 'stream']).optional(),\n verboseDefault: z.enum(['off', 'on', 'full']).optional(),\n systemPromptOverride: z.string().optional(),\n skills: z.array(z.string()).optional(),\n tools: z\n .object({\n disable: z.array(z.string()).optional(),\n })\n .optional(),\n params: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport const AgentsConfigSchema = z.object({\n /** Default agent id when not specified (routing / session creation). */\n default: z.string().optional(),\n defaults: AgentDefaultsSchema.optional(),\n list: z.array(AgentConfigSchema).optional(),\n}).default({\n defaults: {\n workspace: '~/.xopc/workspace',\n model: '', // Empty default - will be resolved dynamically at runtime\n maxTokens: 8192,\n temperature: 0.7,\n maxToolIterations: 20,\n maxRequestsPerTurn: 50,\n maxToolFailuresPerTurn: 3,\n thinkingDefault: 'medium',\n reasoningDefault: 'stream',\n verboseDefault: 'full',\n compaction: {\n enabled: true,\n mode: 'default',\n reserveTokens: 8000,\n triggerThreshold: 0.8,\n minMessagesBeforeCompact: 10,\n keepRecentMessages: 5,\n evictionWindow: 0.2,\n retentionWindow: 6,\n },\n pruning: {\n enabled: true,\n maxToolResultChars: 10000,\n headKeepRatio: 0.3,\n tailKeepRatio: 0.3,\n },\n },\n} as any);\n\n// ============================================\n// Channel Configs (per-channel Zod lives in bundled extensions; root schema is open)\n// ============================================\n\nexport {\n TelegramTopicConfigSchema,\n TelegramGroupConfigSchema,\n TelegramAccountConfigSchema,\n TelegramConfigSchema,\n} from '../../extensions/telegram/src/config-schema.js';\nexport type { TelegramConfig } from '../../extensions/telegram/src/config-schema.js';\nexport { WeixinAccountConfigSchema, WeixinConfigSchema } from '../../extensions/weixin/src/config-schema.js';\nexport type { WeixinConfig } from '../../extensions/weixin/src/config-schema.js';\n// ============================================\n// Session Routing Configuration\n// ============================================\n\nexport const BindingMatchSchema = z.object({\n channel: z.string(),\n accountId: z.string().optional(),\n peerKind: z.string().optional(),\n peerId: z.string().optional(),\n guildId: z.string().optional(),\n teamId: z.string().optional(),\n memberRoleIds: z.array(z.string()).optional(),\n});\n\nexport const BindingRuleSchema = z.object({\n id: z.string().optional(),\n agentId: z.string(),\n priority: z.number().default(100),\n match: BindingMatchSchema,\n enabled: z.boolean().default(true),\n});\n\nexport const BindingsConfigSchema = z.array(BindingRuleSchema).default([]);\n\nexport const SessionDmScopeSchema = z.enum([\n 'main',\n 'per-peer',\n 'per-channel-peer',\n 'per-account-channel-peer',\n]);\n\nexport const SessionStorageConfigSchema = z.object({\n pruneAfterMs: z.number().optional(),\n maxEntries: z.number().optional(),\n});\n\nexport const SessionConfigSchema = z.object({\n dmScope: SessionDmScopeSchema.default('main'),\n identityLinks: z.record(z.string(), z.array(z.string())).optional(),\n storage: SessionStorageConfigSchema.optional(),\n}).default({\n dmScope: 'main',\n});\n\n/** Channel buckets — shapes validated post-parse by registered channel plugins. */\nexport const ChannelsConfigSchema = z.record(z.string(), z.unknown()).default({\n telegram: {\n enabled: false,\n allowFrom: [],\n groupAllowFrom: [],\n debug: false,\n accounts: {\n default: {\n accountId: 'default',\n enabled: true,\n botToken: '',\n allowFrom: [],\n dmPolicy: 'pairing' as const,\n groupPolicy: 'open' as const,\n replyToMode: 'off' as const,\n historyLimit: 50,\n textChunkLimit: 4000,\n streamMode: 'partial' as const,\n },\n },\n dmPolicy: 'pairing' as const,\n groupPolicy: 'open' as const,\n replyToMode: 'off' as const,\n historyLimit: 50,\n textChunkLimit: 4000,\n },\n});\n\nexport const SearchProviderEntrySchema = z.object({\n type: z.enum(['brave', 'tavily', 'bing', 'searxng']),\n apiKey: z.string().optional(),\n /** SearXNG instance base URL (e.g. http://localhost:8080) */\n url: z.string().optional(),\n disabled: z.boolean().optional(),\n});\n\nexport type SearchProviderEntry = z.infer<typeof SearchProviderEntrySchema>;\n\nexport const WebSearchConfigSchema = z.object({\n maxResults: z.number().default(5),\n /** Ordered API providers; empty → HTML fallback only */\n providers: z.array(SearchProviderEntrySchema).default([]),\n});\n\nexport type WebSearchConfig = z.infer<typeof WebSearchConfigSchema>;\n\nexport const WebsiteBlocklistSchema = z.object({\n /** Master switch. Default false (no blocking). */\n enabled: z.boolean().default(false),\n /** Domain patterns to block (e.g. \"example.com\", \"*.evil.org\"). */\n domains: z.array(z.string()).default([]),\n});\n\nexport type WebsiteBlocklistConfig = z.infer<typeof WebsiteBlocklistSchema>;\n\nexport const WebToolsConfigSchema = z.object({\n /** Search result HTML fallback: cn → Bing, otherwise DuckDuckGo */\n region: z.enum(['cn', 'global']).optional(),\n search: WebSearchConfigSchema.optional(),\n /** Domain blocklist for web_fetch / web_extract / browser tools. */\n blocklist: WebsiteBlocklistSchema.optional(),\n});\n\nexport type WebToolsConfig = z.infer<typeof WebToolsConfigSchema>;\n\nexport const ToolsConfigSchema = z.object({\n web: WebToolsConfigSchema.optional(),\n /**\n * Per-capability media providers. Currently only `audio` (STT) is wired;\n * `image` / `video` slots are reserved for future capabilities.\n */\n media: z.lazy(() => ToolsMediaConfigSchema),\n}).default({\n web: {\n search: {\n maxResults: 5,\n providers: [],\n },\n },\n});\n\n// ============================================\n// Gateway Configuration\n// ============================================\n\nexport const GatewayAuthRateLimitSchema = z\n .object({\n enabled: z.boolean().default(true),\n maxAttempts: z.number().int().min(1).default(5),\n windowMs: z.number().default(900_000),\n blockDurationMs: z.number().default(300_000),\n })\n .optional();\n\nexport const GatewayAuthSchema = z\n .object({\n mode: z.enum(['none', 'token', 'password']).default('token'),\n token: z.string().optional(),\n password: z.string().optional(),\n rateLimit: GatewayAuthRateLimitSchema,\n })\n .default({\n mode: 'token',\n });\n\nexport const HeartbeatConfigSchema = z\n .object({\n enabled: z.boolean(),\n intervalMs: z.number(),\n /** When false, heartbeat instructions are only sent during heartbeat polling turns (not in every chat system prompt). */\n includeSystemPromptSection: z.boolean().optional().default(false),\n target: z.string().optional(),\n targetChatId: z.string().optional(),\n prompt: z.string().optional(),\n ackMaxChars: z.number().optional(),\n isolatedSession: z.boolean().optional(),\n activeHours: z\n .object({\n start: z.string(),\n end: z.string(),\n timezone: z.string().optional(),\n })\n .optional(),\n })\n .default({\n enabled: true,\n intervalMs: 1_800_000,\n includeSystemPromptSection: false,\n });\n\nexport const GatewayChannelConnectDeferModeSchema = z.enum(['auto', 'off', 'explicit']);\n\nexport const TunnelConsentSchema = z.object({\n version: z.string().min(1),\n acceptedAt: z.string().min(1),\n});\n\nexport const TunnelE2eSchema = z\n .object({\n enabled: z.boolean().default(true),\n tlsPort: z.number().int().min(1024).max(65535).default(18791),\n staging: z.boolean().default(false),\n })\n .default({\n enabled: true,\n tlsPort: 18791,\n staging: false,\n });\n\nexport const TunnelConfigSchema = z\n .object({\n enabled: z.boolean().default(false),\n brokerUrl: z.string().url().default('https://frp.xopc.ai/api'),\n autoStart: z.boolean().default(false),\n subdomain: z.string().optional(),\n consent: TunnelConsentSchema.optional(),\n e2e: TunnelE2eSchema.optional(),\n })\n .default({\n enabled: false,\n brokerUrl: 'https://frp.xopc.ai/api',\n autoStart: false,\n });\n\nexport type TunnelConfig = z.infer<typeof TunnelConfigSchema>;\n\nexport const GatewayConfigSchema = z.object({\n host: z.string().optional(),\n port: z.number().optional(),\n auth: GatewayAuthSchema.optional(),\n heartbeat: HeartbeatConfigSchema.optional(),\n maxSseConnections: z.number().optional(),\n corsOrigins: z.array(z.string()).optional(),\n /**\n * How channel `start()` is split around HTTP listen when using `GatewayServer`.\n * - `auto` (default): defer ids come from channel plugin `meta.deferConnectUntilAfterListen` + enabled config.\n * - `off`: always start all channels in phase1 (troubleshooting / strict ordering).\n * - `explicit`: defer only `channelConnectDeferIds` (empty = defer none).\n */\n channelConnectDeferMode: GatewayChannelConnectDeferModeSchema.optional(),\n /** When `channelConnectDeferMode` is `explicit`, these channel plugin ids are deferred until after listen. */\n channelConnectDeferIds: z.array(z.string().min(1)).max(24).optional(),\n /** Removed from the defer set (applied after `auto` or `explicit` resolution). */\n channelConnectDeferSkipIds: z.array(z.string().min(1)).max(24).optional(),\n /** Default skills marketplace provider id. Built-in: 'store', 'skillhub', 'clawhub'. Extensions may register more. */\n skillsMarketplaceProvider: z.string().optional(),\n /** Base URL for the xopc skills marketplace (public REST API). */\n skillsStoreBaseUrl: z.string().url().optional(),\n /** File sharing configuration (temporary public download links for workspace files). */\n share: z.object({\n enabled: z.boolean().default(true),\n /** Default TTL in ms (default 24h). */\n defaultTtlMs: z.number().min(60_000).max(604_800_000).default(86_400_000),\n /** Maximum TTL in ms (default 7 days). */\n maxTtlMs: z.number().min(60_000).max(2_592_000_000).default(604_800_000),\n /** Maximum concurrent active shares (default 100). */\n maxActiveShares: z.number().min(1).max(10_000).default(100),\n /** Maximum shareable file size in bytes (default 100MB). */\n maxFileSize: z.number().min(1_048_576).max(10_737_418_240).default(104_857_600),\n /** MIME types allowed for inline preview (?inline=1). */\n inlinePreviewMimes: z.array(z.string()).default([\n 'image/png', 'image/jpeg', 'image/gif', 'image/webp', 'application/pdf',\n ]),\n }).optional(),\n}).default({\n host: '127.0.0.1',\n port: 18790,\n auth: {\n mode: 'token',\n },\n heartbeat: {\n enabled: true,\n intervalMs: 1_800_000,\n includeSystemPromptSection: false,\n },\n maxSseConnections: 100,\n corsOrigins: [],\n skillsMarketplaceProvider: 'skillhub',\n skillsStoreBaseUrl: 'https://store.xopc.ai',\n});\n\nexport const CronConfigSchema = z.object({\n enabled: z.boolean().optional(),\n maxConcurrentJobs: z.number().optional(),\n defaultTimezone: z.string().optional(),\n historyRetentionDays: z.number().optional(),\n enableMetrics: z.boolean().optional(),\n}).default({\n enabled: true,\n maxConcurrentJobs: 5,\n defaultTimezone: 'UTC',\n historyRetentionDays: 7,\n enableMetrics: true,\n});\n\nexport const ModelsDevConfigSchema = z.object({\n enabled: z.boolean().default(true),\n}).default({\n enabled: true,\n});\n\n// ============================================\n// STT (Speech-to-Text) Config\n// ============================================\n\nexport const STTProviderConfigSchema = z.object({\n apiKey: z.string().optional(),\n model: z.string().optional(),\n});\n\nexport const STTFallbackConfigSchema = z.object({\n enabled: z.boolean().default(true),\n order: z.array(z.enum(['alibaba', 'openai'])).default(['alibaba', 'openai']),\n});\n\nexport const STTConfigSchema = z.object({\n enabled: z.boolean().default(false),\n provider: z.enum(['alibaba', 'openai']).default('alibaba'),\n alibaba: STTProviderConfigSchema.optional(),\n openai: STTProviderConfigSchema.optional(),\n fallback: STTFallbackConfigSchema.optional(),\n});\n\n// ============================================\n// TTS (Text-to-Speech) Config\n// ============================================\n\nexport const TTSProviderConfigSchema = z.object({\n apiKey: z.string().optional(),\n model: z.string().optional(),\n voice: z.string().optional(),\n});\n\nexport const TTSFallbackConfigSchema = z.object({\n enabled: z.boolean().default(true),\n order: z\n .array(z.enum(['openai', 'alibaba', 'edge', 'minimax']))\n .default(['openai', 'alibaba', 'minimax', 'edge']),\n});\n\nexport const TTSModelOverridesConfigSchema = z.object({\n enabled: z.boolean().default(true),\n allowText: z.boolean().default(true),\n allowProvider: z.boolean().default(false),\n allowVoice: z.boolean().default(true),\n allowModelId: z.boolean().default(true),\n allowVoiceSettings: z.boolean().default(false),\n allowNormalization: z.boolean().default(false),\n allowSeed: z.boolean().default(false),\n});\n\nexport const TTSEdgeConfigSchema = z.object({\n enabled: z.boolean().default(true),\n voice: z.string().optional(),\n lang: z.string().optional(),\n outputFormat: z.string().optional(),\n pitch: z.string().optional(),\n rate: z.string().optional(),\n volume: z.string().optional(),\n proxy: z.string().optional(),\n timeoutMs: z.number().int().min(1000).max(120000).optional(),\n});\n\nexport const TTSSummarizationConfigSchema = z.object({\n enabled: z.boolean().optional(),\n targetLength: z.number().int().min(1).optional(),\n threshold: z.number().int().min(1).optional(),\n model: z.string().optional(),\n});\n\nexport const TTSConfigSchema = z.object({\n enabled: z.boolean().default(false),\n provider: z.enum(['openai', 'alibaba', 'edge', 'minimax']).default('openai'),\n trigger: z.enum(['off', 'always', 'inbound', 'tagged']).default('always'),\n fallback: TTSFallbackConfigSchema.optional(),\n maxTextLength: z.number().int().min(1).default(512), // Conservative default to accommodate all providers (Alibaba limit is 512)\n timeoutMs: z.number().int().min(1000).max(180000).default(60000),\n summarization: TTSSummarizationConfigSchema.optional(),\n modelOverrides: TTSModelOverridesConfigSchema.optional(),\n alibaba: TTSProviderConfigSchema.optional(),\n openai: TTSProviderConfigSchema.optional(),\n edge: TTSEdgeConfigSchema.optional(),\n minimax: TTSProviderConfigSchema.optional(),\n});\n\n// ============================================\n// messages.* — delivery / presentation concerns\n// ============================================\n\nexport const MessagesConfigSchema = z.object({\n /** Voice (text-to-speech) output configuration. */\n tts: TTSConfigSchema.optional(),\n}).optional();\n\nexport const ToolsMediaAudioConfigSchema = STTConfigSchema;\n\nexport const ToolsMediaConfigSchema = z.object({\n /** Audio (speech-to-text) capability provider config. */\n audio: ToolsMediaAudioConfigSchema.optional(),\n}).optional();\n\n// ============================================\n// Provider Configs (capability providers: image / audio / video)\n// ============================================\n\n/**\n * Optional Azure OpenAI overrides used when an OpenAI image-generation\n * request should hit an Azure deployment instead of `api.openai.com`.\n *\n * URL template (when present):\n * `https://<resource>.openai.azure.com/openai/deployments/<deployment>/images/generations?api-version=<apiVersion>`\n */\nexport const ProviderAzureConfigSchema = z\n .object({\n /** Azure resource name (subdomain before `.openai.azure.com`). */\n resource: z.string().min(1).optional(),\n /** Azure deployment id (configured per model). */\n deployment: z.string().min(1).optional(),\n /** Azure REST API version, e.g. `2024-08-01-preview`. */\n apiVersion: z.string().min(1).optional(),\n })\n .strict();\n\n/** Per-vendor request overrides applied by the provider HTTP layer. */\nexport const ProviderRequestOverridesSchema = z\n .object({\n /** Hard cap for a single HTTP call (ms). */\n timeoutMs: z.number().int().positive().optional(),\n /** Extra headers merged into every outbound request. */\n headers: z.record(z.string(), z.string()).optional(),\n })\n .strict();\n\n/**\n * Generic per-vendor provider config — used by image / audio / video\n * capability providers via `cfg.providers.<id>`. Kept loose (`.strict()` but\n * everything optional) so adding a new vendor never requires a config\n * migration.\n */\nexport const ProviderAuthConfigSchema = z\n .object({\n /** Static API key (api-key / azure-key modes). */\n apiKey: z.string().optional(),\n /** Override the default REST base URL. */\n baseUrl: z.string().url().optional(),\n /** Vendor region (DashScope: `beijing` / `singapore`; AWS: region id). */\n region: z.string().optional(),\n /** Image-only base URL override (DashScope splits image vs LLM). */\n imageBaseUrl: z.string().url().optional(),\n /** Per-vendor request overrides. */\n request: ProviderRequestOverridesSchema.optional(),\n /** Azure OpenAI deployment overrides; only consumed by OpenAI image provider. */\n azure: ProviderAzureConfigSchema.optional(),\n })\n .strict();\n\nexport type ProviderAuthConfig = z.infer<typeof ProviderAuthConfigSchema>;\n\n/**\n * `cfg.providers.<id>` is keyed by provider id (`openai`, `dashscope`,\n * `minimax`, `google`, `fal`, …). Every entry is optional and validated by\n * {@link ProviderAuthConfigSchema}.\n */\nexport const ProvidersConfigSchema = z.record(z.string(), ProviderAuthConfigSchema);\n\nexport type ProvidersConfig = z.infer<typeof ProvidersConfigSchema>;\n\n// ============================================\n// Extension Configs \n// ============================================\n\n// Security config for extensions \nexport const ExtensionSecurityConfigSchema = z.object({\n checkPermissions: z.boolean().default(true),\n allowUntrusted: z.boolean().default(false),\n allow: z.array(z.string()).default([]),\n trackProvenance: z.boolean().default(true),\n allowPromptInjection: z.boolean().default(false),\n});\n\n// Slot config for extensions \nexport const ExtensionSlotsConfigSchema = z.object({\n memory: z.string().optional(),\n tts: z.string().optional(),\n imageGeneration: z.string().optional(),\n webSearch: z.string().optional(),\n});\n\n// Complete extensions config\n// Extension config allows both known fields AND arbitrary extension-specific config\n// Known fields: enabled (array), allow (array), security (object), slots (object)\n// Arbitrary: any other key is extension-specific config (e.g., extensions.hello.greeting)\nexport const ExtensionsConfigSchema: z.ZodType<Record<string, unknown>> = z.record(z.string(), z.unknown());\n\n// ============================================\n// Update Config\n// ============================================\n\nexport const UpdateAutoConfigSchema = z\n .object({\n /** Enable automatic update installation. Default false. */\n enabled: z.boolean().default(false),\n /** Hours to wait before applying a stable update after first detection. */\n stableDelayHours: z.number().min(0).default(6),\n /** Additional random jitter hours for stable rollout (avoids thundering herd). */\n stableJitterHours: z.number().min(0).default(12),\n /** How often to re-check for beta updates (hours). Min 0.25. */\n betaCheckIntervalHours: z.number().min(0.25).default(1),\n })\n .strict()\n .optional();\n\n/** Persistent `/goal` (Ralph loop) — Hermes-aligned defaults. */\nexport const GoalsConfigSchema = z\n .object({\n /** Max continuation turns before auto-pause (Hermes default 20). */\n maxTurns: z.number().int().min(1).max(500).default(20),\n /** Optional judge model ref; defaults to `agents.defaults.model`. */\n judgeModelRef: z.string().optional(),\n /**\n * When true (default), first post-turn runs a decomposition judge to build a checklist;\n * subsequent turns evaluate progress per item (Hermes-style). When false, use legacy freeform judge only.\n */\n checklistMode: z.boolean().default(true),\n /** Auto-pause after this many consecutive judge JSON/tool parse failures (Hermes default 3). */\n maxConsecutiveParseFailures: z.number().int().min(1).max(20).default(3),\n /** Judge LLM call timeout in ms (Hermes uses 60s). */\n judgeTimeoutMs: z.number().int().min(5_000).max(120_000).default(60_000),\n /** Max characters of recent transcript JSON passed to the checklist judge as extra context. */\n checklistHistoryChars: z.number().int().min(0).max(100_000).default(24_000),\n })\n .strict();\n\nexport type GoalsConfig = z.infer<typeof GoalsConfigSchema>;\n\nexport const UpdateConfigSchema = z\n .object({\n /** Check for updates on gateway startup. Default true. */\n checkOnStart: z.boolean().default(true),\n /** Update channel: stable (default), beta, or dev. */\n channel: z.enum(['stable', 'beta', 'dev']).default('stable'),\n /** Automatic update policy. */\n auto: UpdateAutoConfigSchema,\n })\n .strict()\n .optional();\n\nexport type UpdateConfig = z.infer<typeof UpdateConfigSchema>;\n\n// ============================================\n// MCP (Model Context Protocol)\n// ============================================\n\nconst McpHttpUrlSchema = z\n .string()\n .url()\n .refine((value) => {\n try {\n const protocol = new URL(value).protocol;\n return protocol === 'http:' || protocol === 'https:';\n } catch {\n return false;\n }\n }, 'MCP server URL must use http or https');\n\nexport const McpServerSchema = z\n .object({\n command: z.string().optional(),\n args: z.array(z.string()).optional(),\n env: z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])).optional(),\n cwd: z.string().optional(),\n workingDirectory: z.string().optional(),\n url: McpHttpUrlSchema.optional(),\n transport: z.enum(['sse', 'streamable-http']).optional(),\n headers: z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])).optional(),\n connectionTimeoutMs: z.number().finite().positive().optional(),\n })\n .catchall(z.unknown())\n .superRefine((value, ctx) => {\n const hasCommand = typeof value.command === 'string' && value.command.trim().length > 0;\n const hasUrl = typeof value.url === 'string' && value.url.trim().length > 0;\n if (hasCommand && hasUrl) {\n ctx.addIssue({\n code: 'custom',\n message: 'MCP server cannot define both command and url',\n });\n }\n });\n\nexport const McpConfigSchema = z\n .object({\n servers: z.record(z.string(), McpServerSchema).optional(),\n sessionIdleTtlMs: z.number().finite().min(0).optional(),\n })\n .strict()\n .optional();\n\nexport type McpServerConfig = z.infer<typeof McpServerSchema>;\nexport type McpConfig = z.infer<typeof McpConfigSchema>;\n\n// ============================================\n// Root Config\n// ============================================\n\nexport const ConfigSchema = z.object({\n agents: AgentsConfigSchema,\n bindings: BindingsConfigSchema,\n session: SessionConfigSchema,\n channels: ChannelsConfigSchema,\n gateway: GatewayConfigSchema,\n tunnel: TunnelConfigSchema.optional(),\n tools: ToolsConfigSchema,\n mcp: McpConfigSchema,\n cron: CronConfigSchema,\n goals: GoalsConfigSchema.optional(),\n extensions: ExtensionsConfigSchema.default({}),\n /** Per-vendor capability provider config (image / audio / video). */\n providers: ProvidersConfigSchema.optional(),\n modelsDev: ModelsDevConfigSchema,\n /** Delivery / presentation concerns (currently `tts`). */\n messages: MessagesConfigSchema,\n update: UpdateConfigSchema,\n}).default({\n agents: {\n defaults: {\n workspace: '~/.xopc/workspace',\n model: '', // Empty default - will be resolved dynamically at runtime\n maxTokens: 8192,\n temperature: 0.7,\n maxToolIterations: 20,\n maxRequestsPerTurn: 50,\n maxToolFailuresPerTurn: 3,\n thinkingDefault: 'medium',\n reasoningDefault: 'stream',\n verboseDefault: 'full',\n compaction: {\n enabled: true,\n mode: 'default',\n reserveTokens: 8000,\n triggerThreshold: 0.8,\n minMessagesBeforeCompact: 10,\n keepRecentMessages: 5,\n evictionWindow: 0.2,\n retentionWindow: 6,\n },\n pruning: {\n enabled: true,\n maxToolResultChars: 10000,\n headKeepRatio: 0.3,\n tailKeepRatio: 0.3,\n },\n },\n },\n bindings: [],\n session: {\n dmScope: 'main' as const,\n },\n channels: {\n telegram: {\n enabled: false,\n allowFrom: [],\n groupAllowFrom: [],\n debug: false,\n accounts: {\n default: {\n accountId: 'default',\n enabled: true,\n botToken: '',\n allowFrom: [],\n dmPolicy: 'pairing' as const,\n groupPolicy: 'open' as const,\n replyToMode: 'off' as const,\n historyLimit: 50,\n textChunkLimit: 4000,\n streamMode: 'partial' as const,\n },\n },\n dmPolicy: 'pairing' as const,\n groupPolicy: 'open' as const,\n replyToMode: 'off' as const,\n historyLimit: 50,\n textChunkLimit: 4000,\n },\n },\n gateway: {\n host: '127.0.0.1',\n port: 18790,\n auth: {\n mode: 'token',\n },\n heartbeat: {\n enabled: true,\n intervalMs: 1_800_000,\n includeSystemPromptSection: false,\n },\n maxSseConnections: 100,\n corsOrigins: [],\n skillsMarketplaceProvider: 'skillhub',\n skillsStoreBaseUrl: 'https://store.xopc.ai',\n },\n tools: {\n web: {\n search: {\n maxResults: 5,\n providers: [],\n },\n },\n },\n cron: {\n enabled: true,\n maxConcurrentJobs: 5,\n defaultTimezone: 'UTC',\n historyRetentionDays: 7,\n enableMetrics: true,\n },\n goals: {\n maxTurns: 20,\n checklistMode: true,\n maxConsecutiveParseFailures: 3,\n judgeTimeoutMs: 60_000,\n checklistHistoryChars: 24_000,\n },\n extensions: {\n allow: [],\n security: {\n checkPermissions: true,\n allowUntrusted: false,\n allow: [],\n trackProvenance: true,\n allowPromptInjection: false,\n },\n slots: {},\n },\n modelsDev: {\n enabled: true,\n },\n // messages.tts / tools.media.audio start undefined; the factory layer fills\n // in provider-level defaults (model/voice) on demand. Fresh configs don't\n // ship with enabled providers so they never make surprise STT/TTS calls.\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\nexport type AgentDefaults = z.infer<typeof AgentDefaultsSchema>;\nexport type GatewayAuthConfig = z.infer<typeof GatewayAuthSchema>;\nexport type GatewayAuthRateLimitConfig = z.infer<typeof GatewayAuthRateLimitSchema>;\nexport type STTConfig = z.infer<typeof STTConfigSchema>;\nexport type TTSConfig = z.infer<typeof TTSConfigSchema>;\n\n// ============================================\n// Helper Functions\n// ============================================\n\n/**\n * Parse a model reference string.\n */\nexport interface ParsedModelRef {\n provider: string;\n model: string;\n}\n\n/**\n * Default agent’s resolved Markdown workspace root (`resolveAgentWorkspaceDir` for the default agent id).\n */\nexport function getWorkspacePath(config: Config): string {\n return getDefaultWorkspacePath(config);\n}\n\n/**\n * Primary model ref from `agents.defaults.model` (string or `{ primary }`).\n * Returns undefined when unset or empty.\n */\nexport function getAgentDefaultModelRef(config: Config): string | undefined {\n const raw = config.agents?.defaults?.model;\n if (raw === undefined || raw === null) return undefined;\n const ref = typeof raw === 'string' ? raw : raw.primary;\n if (ref === undefined || ref === null) return undefined;\n const s = String(ref).trim();\n return s ? s : undefined;\n}\n\n/** `provider/model` or null when invalid. */\nexport function parseModelRef(ref: string): ParsedModelRef | null {\n const trimmed = ref.trim();\n const idx = trimmed.indexOf('/');\n if (idx <= 0 || idx === trimmed.length - 1) {\n return null;\n }\n return { provider: trimmed.slice(0, idx).trim(), model: trimmed.slice(idx + 1).trim() };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","names":[],"sources":["../../../src/config/schema.ts"],"sourcesContent":["import { z } from 'zod';\n\nimport { getDefaultWorkspacePath } from '../agent/agent-scope.js';\n\n// ============================================\n// Agent Configs\n// ============================================\n\nexport const AgentModelRefSchema = z.union([\n z.string(),\n z\n .object({\n primary: z.string().optional(),\n fallbacks: z.array(z.string()).optional(),\n })\n .strict(),\n]);\n\nexport type AgentModelConfig = z.infer<typeof AgentModelRefSchema>;\n\n/**\n * Image-generation model ref. Superset of {@link AgentModelRefSchema} with\n * runtime knobs (`timeoutMs`, `autoProviderFallback`) used by the\n * image-generation runtime; falls back to a plain string for backward\n * compatibility with old configs.\n */\nexport const AgentImageGenerationModelSchema = z.union([\n z.string(),\n z\n .object({\n primary: z.string().optional(),\n fallbacks: z.array(z.string()).optional(),\n /** Hard cap for the whole generation attempt (ms). */\n timeoutMs: z.number().int().positive().optional(),\n /**\n * When all `primary + fallbacks` candidates fail, sweep every other\n * configured provider before giving up.\n */\n autoProviderFallback: z.boolean().optional(),\n })\n .strict(),\n]);\n\nexport type AgentImageGenerationModelConfig = z.infer<typeof AgentImageGenerationModelSchema>;\n\nexport const AgentDefaultsSchema = z.object({\n /** Parent directory: each agent’s Markdown root is `<expanded>/<agentId>/` (e.g. `.../workspace/main`). */\n workspace: z.string().default('~/.xopc/workspace'),\n model: z.union([\n z.string(),\n z.object({\n primary: z.string().optional(),\n fallbacks: z.array(z.string()).optional(),\n }).strict(),\n ]).default(''), // Empty default - will be resolved dynamically at runtime\n /** Vision / image understanding model (provider/model). Falls back to heuristics when unset. */\n imageModel: AgentModelRefSchema.optional(),\n /** Image generation model (provider/model), e.g. openai/gpt-image-1. Supports plugin-based providers (OpenAI / DashScope / MiniMax / Google / Fal). */\n imageGenerationModel: AgentImageGenerationModelSchema.optional(),\n /** Max image size for image tool loads (MB). */\n mediaMaxMb: z.number().positive().optional(),\n maxTokens: z.number().default(8192),\n temperature: z.number().default(0.7),\n maxToolIterations: z.number().default(20),\n // Wall-clock limit for one user turn (LLM + tools). Default 30m if unset; cap 4h.\n maxTaskDurationMs: z.number().min(60000).max(14_400_000).optional(),\n // Reliability settings\n maxRequestsPerTurn: z.number().min(10).max(200).default(50),\n maxToolFailuresPerTurn: z.number().min(1).max(20).default(3),\n // Thinking ability settings\n thinkingDefault: z.enum(['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'adaptive']).optional(),\n reasoningDefault: z.enum(['off', 'on', 'stream']).optional(),\n verboseDefault: z.enum(['off', 'on', 'full']).optional(),\n bootstrapMaxChars: z.number().int().positive().optional(),\n bootstrapTotalMaxChars: z.number().int().positive().optional(),\n bootstrapPromptTruncationWarning: z.enum(['off', 'once', 'always']).optional(),\n startupContext: z\n .object({\n enabled: z.boolean().optional(),\n applyOn: z.array(z.enum(['new', 'reset'])).optional(),\n dailyMemoryDays: z.number().int().min(1).optional(),\n maxFileBytes: z.number().int().positive().optional(),\n maxFileChars: z.number().int().positive().optional(),\n maxTotalChars: z.number().int().positive().optional(),\n })\n .optional(),\n contextLimits: z\n .object({\n postCompactionMaxChars: z.number().int().positive().optional(),\n })\n .optional(),\n compaction: z.object({\n enabled: z.boolean().default(true),\n mode: z.enum(['default', 'safeguard']).default('default'),\n reserveTokens: z.number().default(8000),\n triggerThreshold: z.number().min(0.5).max(0.95).default(0.8),\n minMessagesBeforeCompact: z.number().default(10),\n keepRecentMessages: z.number().default(5),\n // Dual-strategy compaction\n evictionWindow: z.number().min(0.1).max(0.5).default(0.2),\n retentionWindow: z.number().min(3).max(20).default(6),\n postCompactionSections: z.array(z.string()).optional(),\n }).optional(),\n pruning: z.object({\n enabled: z.boolean().default(true),\n maxToolResultChars: z.number().default(10000),\n headKeepRatio: z.number().default(0.3),\n tailKeepRatio: z.number().default(0.3),\n }).optional(),\n /**\n * Curated memory (`agents/<id>/memories/`) + pluggable external provider.\n * Only one external provider at a time.\n */\n memory: z\n .object({\n /** Master switch: `curated_memory` tool, prefetch, and external provider. Default true. */\n enabled: z.boolean().optional(),\n /** When false, disable curated_memory tool and memory subsystem helpers. Default true. */\n useEnhancedSystem: z.boolean().optional(),\n /** Include USER.md in snapshot. Default true. */\n userProfileEnabled: z.boolean().optional(),\n memoryCharLimit: z.number().positive().optional(),\n userCharLimit: z.number().positive().optional(),\n provider: z.enum(['none', 'stub']).optional(),\n /** How often prefetched external memory is injected into the user message. */\n injectionFrequency: z.enum(['every-turn', 'first-turn']).optional(),\n /** Inject prefetch on turns 1, 1+N, 1+2N, … (only when injectionFrequency is every-turn). Min 1. */\n contextCadence: z.number().int().min(1).optional(),\n /** Reserved for future external “dialectic” sync cadence (not wired yet). */\n dialecticCadence: z.number().int().min(1).optional(),\n /**\n * Background memory consolidation (\"dreaming\"): three-phase sleep model that\n * promotes short-term recall signals into long-term memory (`MEMORY.md`).\n *\n * Phases:\n * - **light** — fast, frequent sweep (default every 6 h): dedup + signal collection.\n * - **deep** — daily deep promotion (default 3 AM): score-gated write to MEMORY.md.\n * - **rem** — weekly pattern discovery (default Sun 5 AM): cross-session insight mining.\n */\n dreaming: z\n .object({\n enabled: z.boolean().optional(),\n /** Default deep-phase cron when `phases.deep.cron` is omitted. */\n frequency: z.string().optional(),\n timezone: z.string().optional(),\n phases: z\n .object({\n light: z\n .object({\n enabled: z.boolean().optional(),\n cron: z.string().optional(),\n lookbackDays: z.number().int().min(1).optional(),\n limit: z.number().int().min(0).optional(),\n dedupeSimilarity: z.number().min(0).max(1).optional(),\n })\n .optional(),\n deep: z\n .object({\n enabled: z.boolean().optional(),\n cron: z.string().optional(),\n minScore: z.number().min(0).max(1).optional(),\n minRecallCount: z.number().int().min(1).optional(),\n minUniqueQueries: z.number().int().min(1).optional(),\n limit: z.number().int().min(0).optional(),\n recencyHalfLifeDays: z.number().min(1).optional(),\n maxAgeDays: z.number().int().min(1).optional(),\n })\n .optional(),\n rem: z\n .object({\n enabled: z.boolean().optional(),\n cron: z.string().optional(),\n lookbackDays: z.number().int().min(1).optional(),\n limit: z.number().int().min(0).optional(),\n minPatternStrength: z.number().min(0).max(1).optional(),\n })\n .optional(),\n })\n .optional(),\n })\n .optional(),\n })\n .optional(),\n /** Cross-session transcript search (`session_search` tool). */\n sessionSearch: z\n .object({\n /** Model ref for per-session summaries (e.g. openai/gpt-4o-mini). */\n summaryModel: z.string().optional(),\n })\n .optional(),\n /**\n * Post-turn background review (Hermes-style): optional quiet follow-up that may call\n * `curated_memory` / `skill_manage` so durable facts and reusable workflows persist\n * without bloating the main user-visible turn.\n */\n backgroundReview: z\n .object({\n /** When true, nudges may run after successful turns. Default false (opt-in). */\n enabled: z.boolean().optional(),\n /** User-turn cadence for memory review. 0 disables the memory channel. Default 10. */\n memoryNudgeInterval: z.number().int().min(0).optional(),\n /** LLM rounds without `skill_manage` before a skill review. 0 disables the skill channel. Default 10. */\n skillNudgeInterval: z.number().int().min(0).optional(),\n /** Max tool executions for the review agent. Default 8. */\n maxToolRounds: z.number().int().min(1).max(32).optional(),\n /** Max prior messages passed into the review context (tail). Default 80. */\n maxHistoryMessages: z.number().int().min(10).max(200).optional(),\n /** Wall-clock cap for the review run (ms). Default 120000. */\n maxDurationMs: z.number().int().min(30_000).max(600_000).optional(),\n })\n .optional(),\n /** LLM pass for `web_extract` (markdown-focused extraction). */\n webExtract: z\n .object({\n model: z.string().optional(),\n maxLength: z.number().positive().optional(),\n })\n .optional(),\n /**\n * Browser capability via unified `browser_use` tool. Enabled by default (set `enabled: false` to disable).\n * Install browsers once: `npx playwright install chromium`.\n */\n browser: z\n .object({\n enabled: z.boolean().optional(),\n /** Run browser in headless mode (default: false — visible window). */\n headless: z.boolean().optional(),\n /** When true, skip private-IP blocking for browser navigation (cloud metadata endpoints are always blocked). */\n allowPrivateUrls: z.boolean().optional(),\n /** Browser command timeout in seconds (default: 30). */\n commandTimeout: z.number().min(5).optional(),\n /** Browser backend mode: 'local' (Playwright), 'cdp', 'cloud', or 'extension' (Chrome Extension bridge). */\n backend: z.enum(['local', 'cdp', 'cloud', 'extension']).optional(),\n /** Cloud browser backend: 'local' (default Playwright), 'browserbase', or 'browser-use'. */\n cloudProvider: z.enum(['local', 'browserbase', 'browser-use']).optional(),\n /** Direct CDP WebSocket endpoint URL (bypasses cloud provider). */\n cdpUrl: z.string().optional(),\n /** Chrome Extension bridge settings (only used when backend = 'extension'). */\n extension: z.object({\n /** WebSocket server port. Default: 19820. */\n port: z.number().min(1024).max(65535).optional(),\n /** Host to bind. Default: 127.0.0.1. */\n host: z.string().optional(),\n /** Timeout waiting for extension connection (ms). Default: 30000. */\n connectionTimeout: z.number().min(1000).optional(),\n }).optional(),\n /** JS dialog handling policy: 'must_respond' (agent must act), 'auto_dismiss', or 'auto_accept'. */\n dialogPolicy: z.enum(['must_respond', 'auto_dismiss', 'auto_accept']).optional(),\n /** Dialog auto-dismiss/accept timeout in seconds (default: 300). */\n dialogTimeoutSeconds: z.number().min(1).optional(),\n })\n .optional(),\n /** Sub-agent delegation (`delegate_task`). Opt-in. */\n delegate: z\n .object({\n enabled: z.boolean().optional(),\n })\n .optional(),\n /** Sandboxed `execute_code` (programmatic tool calls). Opt-in. */\n executeCode: z\n .object({\n enabled: z.boolean().optional(),\n })\n .optional(),\n /** Optional full system prompt replacement (merged with per-agent entry; entry wins). */\n systemPromptOverride: z.string().optional(),\n /** Optional allowlist of skill names for `<available_skills>`; when set, replaces unfiltered list. */\n skills: z.array(z.string()).optional(),\n /** Disable built-in tools by name (e.g. `shell`, `web_search`). */\n tools: z\n .object({\n disable: z.array(z.string()).optional(),\n })\n .optional(),\n /** Opaque per-process params (reserved for extensions / future use). */\n params: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport const AgentConfigSchema = z.object({\n id: z.string(),\n /** When true, this entry is the default routing agent. */\n default: z.boolean().optional(),\n name: z.string().optional(),\n /** Short human-readable summary for UIs (gateway console, pickers). */\n description: z.string().max(4000).optional(),\n enabled: z.boolean().default(true),\n /** Per-agent workspace root (`~` expanded at runtime). */\n workspace: z.string().optional(),\n /**\n * Internal agent state directory (`…/credentials`, `agent.json`, pid, inbox).\n * Default: `<stateDir>/agents/<id>/agent`.\n */\n agentDir: z.string().optional(),\n model: AgentModelRefSchema.optional(),\n thinkingDefault: z.enum(['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'adaptive']).optional(),\n reasoningDefault: z.enum(['off', 'on', 'stream']).optional(),\n verboseDefault: z.enum(['off', 'on', 'full']).optional(),\n systemPromptOverride: z.string().optional(),\n skills: z.array(z.string()).optional(),\n tools: z\n .object({\n disable: z.array(z.string()).optional(),\n })\n .optional(),\n params: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport const AgentsConfigSchema = z.object({\n /** Default agent id when not specified (routing / session creation). */\n default: z.string().optional(),\n defaults: AgentDefaultsSchema.optional(),\n list: z.array(AgentConfigSchema).optional(),\n}).default({\n defaults: {\n workspace: '~/.xopc/workspace',\n model: '', // Empty default - will be resolved dynamically at runtime\n maxTokens: 8192,\n temperature: 0.7,\n maxToolIterations: 20,\n maxRequestsPerTurn: 50,\n maxToolFailuresPerTurn: 3,\n thinkingDefault: 'medium',\n reasoningDefault: 'stream',\n verboseDefault: 'full',\n compaction: {\n enabled: true,\n mode: 'default',\n reserveTokens: 8000,\n triggerThreshold: 0.8,\n minMessagesBeforeCompact: 10,\n keepRecentMessages: 5,\n evictionWindow: 0.2,\n retentionWindow: 6,\n },\n pruning: {\n enabled: true,\n maxToolResultChars: 10000,\n headKeepRatio: 0.3,\n tailKeepRatio: 0.3,\n },\n },\n} as any);\n\n// ============================================\n// Channel Configs (per-channel Zod lives in bundled extensions; root schema is open)\n// ============================================\n\nexport {\n TelegramTopicConfigSchema,\n TelegramGroupConfigSchema,\n TelegramAccountConfigSchema,\n TelegramConfigSchema,\n} from '../../extensions/telegram/src/config-schema.js';\nexport type { TelegramConfig } from '../../extensions/telegram/src/config-schema.js';\nexport { WeixinAccountConfigSchema, WeixinConfigSchema } from '../../extensions/weixin/src/config-schema.js';\nexport type { WeixinConfig } from '../../extensions/weixin/src/config-schema.js';\n// ============================================\n// Session Routing Configuration\n// ============================================\n\nexport const BindingMatchSchema = z.object({\n channel: z.string(),\n accountId: z.string().optional(),\n peerKind: z.string().optional(),\n peerId: z.string().optional(),\n guildId: z.string().optional(),\n teamId: z.string().optional(),\n memberRoleIds: z.array(z.string()).optional(),\n});\n\nexport const BindingRuleSchema = z.object({\n id: z.string().optional(),\n agentId: z.string(),\n priority: z.number().default(100),\n match: BindingMatchSchema,\n enabled: z.boolean().default(true),\n});\n\nexport const BindingsConfigSchema = z.array(BindingRuleSchema).default([]);\n\nexport const SessionDmScopeSchema = z.enum([\n 'main',\n 'per-peer',\n 'per-channel-peer',\n 'per-account-channel-peer',\n]);\n\nexport const SessionStorageConfigSchema = z.object({\n pruneAfterMs: z.number().optional(),\n maxEntries: z.number().optional(),\n});\n\nexport const SessionConfigSchema = z.object({\n dmScope: SessionDmScopeSchema.default('main'),\n identityLinks: z.record(z.string(), z.array(z.string())).optional(),\n storage: SessionStorageConfigSchema.optional(),\n}).default({\n dmScope: 'main',\n});\n\n/** Channel buckets — shapes validated post-parse by registered channel plugins. */\nexport const ChannelsConfigSchema = z.record(z.string(), z.unknown()).default({\n telegram: {\n enabled: false,\n allowFrom: [],\n groupAllowFrom: [],\n debug: false,\n accounts: {\n default: {\n accountId: 'default',\n enabled: true,\n botToken: '',\n allowFrom: [],\n dmPolicy: 'pairing' as const,\n groupPolicy: 'open' as const,\n replyToMode: 'off' as const,\n historyLimit: 50,\n textChunkLimit: 4000,\n streamMode: 'partial' as const,\n },\n },\n dmPolicy: 'pairing' as const,\n groupPolicy: 'open' as const,\n replyToMode: 'off' as const,\n historyLimit: 50,\n textChunkLimit: 4000,\n },\n});\n\nexport const SearchProviderEntrySchema = z.object({\n type: z.enum(['brave', 'tavily', 'bing', 'searxng']),\n apiKey: z.string().optional(),\n /** SearXNG instance base URL (e.g. http://localhost:8080) */\n url: z.string().optional(),\n disabled: z.boolean().optional(),\n});\n\nexport type SearchProviderEntry = z.infer<typeof SearchProviderEntrySchema>;\n\nexport const WebSearchConfigSchema = z.object({\n maxResults: z.number().default(5),\n /** Ordered API providers; empty → HTML fallback only */\n providers: z.array(SearchProviderEntrySchema).default([]),\n});\n\nexport type WebSearchConfig = z.infer<typeof WebSearchConfigSchema>;\n\nexport const WebsiteBlocklistSchema = z.object({\n /** Master switch. Default false (no blocking). */\n enabled: z.boolean().default(false),\n /** Domain patterns to block (e.g. \"example.com\", \"*.evil.org\"). */\n domains: z.array(z.string()).default([]),\n});\n\nexport type WebsiteBlocklistConfig = z.infer<typeof WebsiteBlocklistSchema>;\n\nexport const WebToolsConfigSchema = z.object({\n /** Search result HTML fallback: cn → Bing, otherwise DuckDuckGo */\n region: z.enum(['cn', 'global']).optional(),\n search: WebSearchConfigSchema.optional(),\n /** Domain blocklist for web_fetch / web_extract / browser tools. */\n blocklist: WebsiteBlocklistSchema.optional(),\n});\n\nexport type WebToolsConfig = z.infer<typeof WebToolsConfigSchema>;\n\nexport const ToolsConfigSchema = z.object({\n web: WebToolsConfigSchema.optional(),\n /**\n * Per-capability media providers. Currently only `audio` (STT) is wired;\n * `image` / `video` slots are reserved for future capabilities.\n */\n media: z.lazy(() => ToolsMediaConfigSchema),\n}).default({\n web: {\n search: {\n maxResults: 5,\n providers: [],\n },\n },\n});\n\n// ============================================\n// Gateway Configuration\n// ============================================\n\nexport const GatewayAuthRateLimitSchema = z\n .object({\n enabled: z.boolean().default(true),\n maxAttempts: z.number().int().min(1).default(5),\n windowMs: z.number().default(900_000),\n blockDurationMs: z.number().default(300_000),\n })\n .optional();\n\nexport const GatewayAuthSchema = z\n .object({\n mode: z.enum(['none', 'token', 'password']).default('token'),\n token: z.string().optional(),\n password: z.string().optional(),\n rateLimit: GatewayAuthRateLimitSchema,\n })\n .default({\n mode: 'token',\n });\n\nexport const HeartbeatConfigSchema = z\n .object({\n enabled: z.boolean(),\n intervalMs: z.number(),\n /** When false, heartbeat instructions are only sent during heartbeat polling turns (not in every chat system prompt). */\n includeSystemPromptSection: z.boolean().optional().default(false),\n target: z.string().optional(),\n targetChatId: z.string().optional(),\n prompt: z.string().optional(),\n ackMaxChars: z.number().optional(),\n isolatedSession: z.boolean().optional(),\n activeHours: z\n .object({\n start: z.string(),\n end: z.string(),\n timezone: z.string().optional(),\n })\n .optional(),\n })\n .default({\n enabled: true,\n intervalMs: 1_800_000,\n includeSystemPromptSection: false,\n });\n\nexport const GatewayChannelConnectDeferModeSchema = z.enum(['auto', 'off', 'explicit']);\n\nexport const TunnelConsentSchema = z.object({\n version: z.string().min(1),\n acceptedAt: z.string().min(1),\n});\n\nexport const TunnelE2eSchema = z\n .object({\n enabled: z.boolean().default(true),\n tlsPort: z.number().int().min(1024).max(65535).default(18791),\n staging: z.boolean().default(false),\n })\n .default({\n enabled: true,\n tlsPort: 18791,\n staging: false,\n });\n\nexport const TunnelConfigSchema = z\n .object({\n enabled: z.boolean().default(false),\n brokerUrl: z.string().url().default('https://frp.xopc.ai/api'),\n /** Broker register API secret (env `XOPC_TUNNEL_REGISTRATION_SECRET` overrides when set). */\n registrationSecret: z.string().min(1).optional(),\n autoStart: z.boolean().default(false),\n subdomain: z.string().optional(),\n consent: TunnelConsentSchema.optional(),\n e2e: TunnelE2eSchema.optional(),\n })\n .default({\n enabled: false,\n brokerUrl: 'https://frp.xopc.ai/api',\n autoStart: false,\n });\n\nexport type TunnelConfig = z.infer<typeof TunnelConfigSchema>;\n\nexport const GatewayConfigSchema = z.object({\n host: z.string().optional(),\n port: z.number().optional(),\n auth: GatewayAuthSchema.optional(),\n heartbeat: HeartbeatConfigSchema.optional(),\n maxSseConnections: z.number().optional(),\n corsOrigins: z.array(z.string()).optional(),\n /**\n * How channel `start()` is split around HTTP listen when using `GatewayServer`.\n * - `auto` (default): defer ids come from channel plugin `meta.deferConnectUntilAfterListen` + enabled config.\n * - `off`: always start all channels in phase1 (troubleshooting / strict ordering).\n * - `explicit`: defer only `channelConnectDeferIds` (empty = defer none).\n */\n channelConnectDeferMode: GatewayChannelConnectDeferModeSchema.optional(),\n /** When `channelConnectDeferMode` is `explicit`, these channel plugin ids are deferred until after listen. */\n channelConnectDeferIds: z.array(z.string().min(1)).max(24).optional(),\n /** Removed from the defer set (applied after `auto` or `explicit` resolution). */\n channelConnectDeferSkipIds: z.array(z.string().min(1)).max(24).optional(),\n /** Default skills marketplace provider id. Built-in: 'store', 'skillhub', 'clawhub'. Extensions may register more. */\n skillsMarketplaceProvider: z.string().optional(),\n /** Base URL for the xopc skills marketplace (public REST API). */\n skillsStoreBaseUrl: z.string().url().optional(),\n /** File sharing configuration (temporary public download links for workspace files). */\n share: z.object({\n enabled: z.boolean().default(true),\n /** Default TTL in ms (default 24h). */\n defaultTtlMs: z.number().min(60_000).max(604_800_000).default(86_400_000),\n /** Maximum TTL in ms (default 7 days). */\n maxTtlMs: z.number().min(60_000).max(2_592_000_000).default(604_800_000),\n /** Maximum concurrent active shares (default 100). */\n maxActiveShares: z.number().min(1).max(10_000).default(100),\n /** Maximum shareable file size in bytes (default 100MB). */\n maxFileSize: z.number().min(1_048_576).max(10_737_418_240).default(104_857_600),\n /** MIME types allowed for inline preview (?inline=1). */\n inlinePreviewMimes: z.array(z.string()).default([\n 'image/png', 'image/jpeg', 'image/gif', 'image/webp', 'application/pdf',\n ]),\n }).optional(),\n}).default({\n host: '127.0.0.1',\n port: 18790,\n auth: {\n mode: 'token',\n },\n heartbeat: {\n enabled: true,\n intervalMs: 1_800_000,\n includeSystemPromptSection: false,\n },\n maxSseConnections: 100,\n corsOrigins: [],\n skillsMarketplaceProvider: 'skillhub',\n skillsStoreBaseUrl: 'https://store.xopc.ai',\n});\n\nexport const CronConfigSchema = z.object({\n enabled: z.boolean().optional(),\n maxConcurrentJobs: z.number().optional(),\n defaultTimezone: z.string().optional(),\n historyRetentionDays: z.number().optional(),\n enableMetrics: z.boolean().optional(),\n}).default({\n enabled: true,\n maxConcurrentJobs: 5,\n defaultTimezone: 'UTC',\n historyRetentionDays: 7,\n enableMetrics: true,\n});\n\nexport const ModelsDevConfigSchema = z.object({\n enabled: z.boolean().default(true),\n}).default({\n enabled: true,\n});\n\n// ============================================\n// STT (Speech-to-Text) Config\n// ============================================\n\nexport const STTProviderConfigSchema = z.object({\n apiKey: z.string().optional(),\n model: z.string().optional(),\n});\n\nexport const STTFallbackConfigSchema = z.object({\n enabled: z.boolean().default(true),\n order: z.array(z.enum(['alibaba', 'openai'])).default(['alibaba', 'openai']),\n});\n\nexport const STTConfigSchema = z.object({\n enabled: z.boolean().default(false),\n provider: z.enum(['alibaba', 'openai']).default('alibaba'),\n alibaba: STTProviderConfigSchema.optional(),\n openai: STTProviderConfigSchema.optional(),\n fallback: STTFallbackConfigSchema.optional(),\n});\n\n// ============================================\n// TTS (Text-to-Speech) Config\n// ============================================\n\nexport const TTSProviderConfigSchema = z.object({\n apiKey: z.string().optional(),\n model: z.string().optional(),\n voice: z.string().optional(),\n});\n\nexport const TTSFallbackConfigSchema = z.object({\n enabled: z.boolean().default(true),\n order: z\n .array(z.enum(['openai', 'alibaba', 'edge', 'minimax']))\n .default(['openai', 'alibaba', 'minimax', 'edge']),\n});\n\nexport const TTSModelOverridesConfigSchema = z.object({\n enabled: z.boolean().default(true),\n allowText: z.boolean().default(true),\n allowProvider: z.boolean().default(false),\n allowVoice: z.boolean().default(true),\n allowModelId: z.boolean().default(true),\n allowVoiceSettings: z.boolean().default(false),\n allowNormalization: z.boolean().default(false),\n allowSeed: z.boolean().default(false),\n});\n\nexport const TTSEdgeConfigSchema = z.object({\n enabled: z.boolean().default(true),\n voice: z.string().optional(),\n lang: z.string().optional(),\n outputFormat: z.string().optional(),\n pitch: z.string().optional(),\n rate: z.string().optional(),\n volume: z.string().optional(),\n proxy: z.string().optional(),\n timeoutMs: z.number().int().min(1000).max(120000).optional(),\n});\n\nexport const TTSSummarizationConfigSchema = z.object({\n enabled: z.boolean().optional(),\n targetLength: z.number().int().min(1).optional(),\n threshold: z.number().int().min(1).optional(),\n model: z.string().optional(),\n});\n\nexport const TTSConfigSchema = z.object({\n enabled: z.boolean().default(false),\n provider: z.enum(['openai', 'alibaba', 'edge', 'minimax']).default('openai'),\n trigger: z.enum(['off', 'always', 'inbound', 'tagged']).default('always'),\n fallback: TTSFallbackConfigSchema.optional(),\n maxTextLength: z.number().int().min(1).default(512), // Conservative default to accommodate all providers (Alibaba limit is 512)\n timeoutMs: z.number().int().min(1000).max(180000).default(60000),\n summarization: TTSSummarizationConfigSchema.optional(),\n modelOverrides: TTSModelOverridesConfigSchema.optional(),\n alibaba: TTSProviderConfigSchema.optional(),\n openai: TTSProviderConfigSchema.optional(),\n edge: TTSEdgeConfigSchema.optional(),\n minimax: TTSProviderConfigSchema.optional(),\n});\n\n// ============================================\n// messages.* — delivery / presentation concerns\n// ============================================\n\nexport const MessagesConfigSchema = z.object({\n /** Voice (text-to-speech) output configuration. */\n tts: TTSConfigSchema.optional(),\n}).optional();\n\nexport const ToolsMediaAudioConfigSchema = STTConfigSchema;\n\nexport const ToolsMediaConfigSchema = z.object({\n /** Audio (speech-to-text) capability provider config. */\n audio: ToolsMediaAudioConfigSchema.optional(),\n}).optional();\n\n// ============================================\n// Provider Configs (capability providers: image / audio / video)\n// ============================================\n\n/**\n * Optional Azure OpenAI overrides used when an OpenAI image-generation\n * request should hit an Azure deployment instead of `api.openai.com`.\n *\n * URL template (when present):\n * `https://<resource>.openai.azure.com/openai/deployments/<deployment>/images/generations?api-version=<apiVersion>`\n */\nexport const ProviderAzureConfigSchema = z\n .object({\n /** Azure resource name (subdomain before `.openai.azure.com`). */\n resource: z.string().min(1).optional(),\n /** Azure deployment id (configured per model). */\n deployment: z.string().min(1).optional(),\n /** Azure REST API version, e.g. `2024-08-01-preview`. */\n apiVersion: z.string().min(1).optional(),\n })\n .strict();\n\n/** Per-vendor request overrides applied by the provider HTTP layer. */\nexport const ProviderRequestOverridesSchema = z\n .object({\n /** Hard cap for a single HTTP call (ms). */\n timeoutMs: z.number().int().positive().optional(),\n /** Extra headers merged into every outbound request. */\n headers: z.record(z.string(), z.string()).optional(),\n })\n .strict();\n\n/**\n * Generic per-vendor provider config — used by image / audio / video\n * capability providers via `cfg.providers.<id>`. Kept loose (`.strict()` but\n * everything optional) so adding a new vendor never requires a config\n * migration.\n */\nexport const ProviderAuthConfigSchema = z\n .object({\n /** Static API key (api-key / azure-key modes). */\n apiKey: z.string().optional(),\n /** Override the default REST base URL. */\n baseUrl: z.string().url().optional(),\n /** Vendor region (DashScope: `beijing` / `singapore`; AWS: region id). */\n region: z.string().optional(),\n /** Image-only base URL override (DashScope splits image vs LLM). */\n imageBaseUrl: z.string().url().optional(),\n /** Per-vendor request overrides. */\n request: ProviderRequestOverridesSchema.optional(),\n /** Azure OpenAI deployment overrides; only consumed by OpenAI image provider. */\n azure: ProviderAzureConfigSchema.optional(),\n })\n .strict();\n\nexport type ProviderAuthConfig = z.infer<typeof ProviderAuthConfigSchema>;\n\n/**\n * `cfg.providers.<id>` is keyed by provider id (`openai`, `dashscope`,\n * `minimax`, `google`, `fal`, …). Every entry is optional and validated by\n * {@link ProviderAuthConfigSchema}.\n */\nexport const ProvidersConfigSchema = z.record(z.string(), ProviderAuthConfigSchema);\n\nexport type ProvidersConfig = z.infer<typeof ProvidersConfigSchema>;\n\n// ============================================\n// Extension Configs \n// ============================================\n\n// Security config for extensions \nexport const ExtensionSecurityConfigSchema = z.object({\n checkPermissions: z.boolean().default(true),\n allowUntrusted: z.boolean().default(false),\n allow: z.array(z.string()).default([]),\n trackProvenance: z.boolean().default(true),\n allowPromptInjection: z.boolean().default(false),\n});\n\n// Slot config for extensions \nexport const ExtensionSlotsConfigSchema = z.object({\n memory: z.string().optional(),\n tts: z.string().optional(),\n imageGeneration: z.string().optional(),\n webSearch: z.string().optional(),\n});\n\n// Complete extensions config\n// Extension config allows both known fields AND arbitrary extension-specific config\n// Known fields: enabled (array), allow (array), security (object), slots (object)\n// Arbitrary: any other key is extension-specific config (e.g., extensions.hello.greeting)\nexport const ExtensionsConfigSchema: z.ZodType<Record<string, unknown>> = z.record(z.string(), z.unknown());\n\n// ============================================\n// Update Config\n// ============================================\n\nexport const UpdateAutoConfigSchema = z\n .object({\n /** Enable automatic update installation. Default false. */\n enabled: z.boolean().default(false),\n /** Hours to wait before applying a stable update after first detection. */\n stableDelayHours: z.number().min(0).default(6),\n /** Additional random jitter hours for stable rollout (avoids thundering herd). */\n stableJitterHours: z.number().min(0).default(12),\n /** How often to re-check for beta updates (hours). Min 0.25. */\n betaCheckIntervalHours: z.number().min(0.25).default(1),\n })\n .strict()\n .optional();\n\n/** Persistent `/goal` (Ralph loop) — Hermes-aligned defaults. */\nexport const GoalsConfigSchema = z\n .object({\n /** Max continuation turns before auto-pause (Hermes default 20). */\n maxTurns: z.number().int().min(1).max(500).default(20),\n /** Optional judge model ref; defaults to `agents.defaults.model`. */\n judgeModelRef: z.string().optional(),\n /**\n * When true (default), first post-turn runs a decomposition judge to build a checklist;\n * subsequent turns evaluate progress per item (Hermes-style). When false, use legacy freeform judge only.\n */\n checklistMode: z.boolean().default(true),\n /** Auto-pause after this many consecutive judge JSON/tool parse failures (Hermes default 3). */\n maxConsecutiveParseFailures: z.number().int().min(1).max(20).default(3),\n /** Judge LLM call timeout in ms (Hermes uses 60s). */\n judgeTimeoutMs: z.number().int().min(5_000).max(120_000).default(60_000),\n /** Max characters of recent transcript JSON passed to the checklist judge as extra context. */\n checklistHistoryChars: z.number().int().min(0).max(100_000).default(24_000),\n })\n .strict();\n\nexport type GoalsConfig = z.infer<typeof GoalsConfigSchema>;\n\nexport const UpdateConfigSchema = z\n .object({\n /** Check for updates on gateway startup. Default true. */\n checkOnStart: z.boolean().default(true),\n /** Update channel: stable (default), beta, or dev. */\n channel: z.enum(['stable', 'beta', 'dev']).default('stable'),\n /** Automatic update policy. */\n auto: UpdateAutoConfigSchema,\n })\n .strict()\n .optional();\n\nexport type UpdateConfig = z.infer<typeof UpdateConfigSchema>;\n\n// ============================================\n// MCP (Model Context Protocol)\n// ============================================\n\nconst McpHttpUrlSchema = z\n .string()\n .url()\n .refine((value) => {\n try {\n const protocol = new URL(value).protocol;\n return protocol === 'http:' || protocol === 'https:';\n } catch {\n return false;\n }\n }, 'MCP server URL must use http or https');\n\nexport const McpServerSchema = z\n .object({\n command: z.string().optional(),\n args: z.array(z.string()).optional(),\n env: z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])).optional(),\n cwd: z.string().optional(),\n workingDirectory: z.string().optional(),\n url: McpHttpUrlSchema.optional(),\n transport: z.enum(['sse', 'streamable-http']).optional(),\n headers: z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])).optional(),\n connectionTimeoutMs: z.number().finite().positive().optional(),\n })\n .catchall(z.unknown())\n .superRefine((value, ctx) => {\n const hasCommand = typeof value.command === 'string' && value.command.trim().length > 0;\n const hasUrl = typeof value.url === 'string' && value.url.trim().length > 0;\n if (hasCommand && hasUrl) {\n ctx.addIssue({\n code: 'custom',\n message: 'MCP server cannot define both command and url',\n });\n }\n });\n\nexport const McpConfigSchema = z\n .object({\n servers: z.record(z.string(), McpServerSchema).optional(),\n sessionIdleTtlMs: z.number().finite().min(0).optional(),\n })\n .strict()\n .optional();\n\nexport type McpServerConfig = z.infer<typeof McpServerSchema>;\nexport type McpConfig = z.infer<typeof McpConfigSchema>;\n\n// ============================================\n// Root Config\n// ============================================\n\nexport const ConfigSchema = z.object({\n agents: AgentsConfigSchema,\n bindings: BindingsConfigSchema,\n session: SessionConfigSchema,\n channels: ChannelsConfigSchema,\n gateway: GatewayConfigSchema,\n tunnel: TunnelConfigSchema.optional(),\n tools: ToolsConfigSchema,\n mcp: McpConfigSchema,\n cron: CronConfigSchema,\n goals: GoalsConfigSchema.optional(),\n extensions: ExtensionsConfigSchema.default({}),\n /** Per-vendor capability provider config (image / audio / video). */\n providers: ProvidersConfigSchema.optional(),\n modelsDev: ModelsDevConfigSchema,\n /** Delivery / presentation concerns (currently `tts`). */\n messages: MessagesConfigSchema,\n update: UpdateConfigSchema,\n}).default({\n agents: {\n defaults: {\n workspace: '~/.xopc/workspace',\n model: '', // Empty default - will be resolved dynamically at runtime\n maxTokens: 8192,\n temperature: 0.7,\n maxToolIterations: 20,\n maxRequestsPerTurn: 50,\n maxToolFailuresPerTurn: 3,\n thinkingDefault: 'medium',\n reasoningDefault: 'stream',\n verboseDefault: 'full',\n compaction: {\n enabled: true,\n mode: 'default',\n reserveTokens: 8000,\n triggerThreshold: 0.8,\n minMessagesBeforeCompact: 10,\n keepRecentMessages: 5,\n evictionWindow: 0.2,\n retentionWindow: 6,\n },\n pruning: {\n enabled: true,\n maxToolResultChars: 10000,\n headKeepRatio: 0.3,\n tailKeepRatio: 0.3,\n },\n },\n },\n bindings: [],\n session: {\n dmScope: 'main' as const,\n },\n channels: {\n telegram: {\n enabled: false,\n allowFrom: [],\n groupAllowFrom: [],\n debug: false,\n accounts: {\n default: {\n accountId: 'default',\n enabled: true,\n botToken: '',\n allowFrom: [],\n dmPolicy: 'pairing' as const,\n groupPolicy: 'open' as const,\n replyToMode: 'off' as const,\n historyLimit: 50,\n textChunkLimit: 4000,\n streamMode: 'partial' as const,\n },\n },\n dmPolicy: 'pairing' as const,\n groupPolicy: 'open' as const,\n replyToMode: 'off' as const,\n historyLimit: 50,\n textChunkLimit: 4000,\n },\n },\n gateway: {\n host: '127.0.0.1',\n port: 18790,\n auth: {\n mode: 'token',\n },\n heartbeat: {\n enabled: true,\n intervalMs: 1_800_000,\n includeSystemPromptSection: false,\n },\n maxSseConnections: 100,\n corsOrigins: [],\n skillsMarketplaceProvider: 'skillhub',\n skillsStoreBaseUrl: 'https://store.xopc.ai',\n },\n tools: {\n web: {\n search: {\n maxResults: 5,\n providers: [],\n },\n },\n },\n cron: {\n enabled: true,\n maxConcurrentJobs: 5,\n defaultTimezone: 'UTC',\n historyRetentionDays: 7,\n enableMetrics: true,\n },\n goals: {\n maxTurns: 20,\n checklistMode: true,\n maxConsecutiveParseFailures: 3,\n judgeTimeoutMs: 60_000,\n checklistHistoryChars: 24_000,\n },\n extensions: {\n allow: [],\n security: {\n checkPermissions: true,\n allowUntrusted: false,\n allow: [],\n trackProvenance: true,\n allowPromptInjection: false,\n },\n slots: {},\n },\n modelsDev: {\n enabled: true,\n },\n // messages.tts / tools.media.audio start undefined; the factory layer fills\n // in provider-level defaults (model/voice) on demand. Fresh configs don't\n // ship with enabled providers so they never make surprise STT/TTS calls.\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\nexport type AgentDefaults = z.infer<typeof AgentDefaultsSchema>;\nexport type GatewayAuthConfig = z.infer<typeof GatewayAuthSchema>;\nexport type GatewayAuthRateLimitConfig = z.infer<typeof GatewayAuthRateLimitSchema>;\nexport type STTConfig = z.infer<typeof STTConfigSchema>;\nexport type TTSConfig = z.infer<typeof TTSConfigSchema>;\n\n// ============================================\n// Helper Functions\n// ============================================\n\n/**\n * Parse a model reference string.\n */\nexport interface ParsedModelRef {\n provider: string;\n model: string;\n}\n\n/**\n * Default agent’s resolved Markdown workspace root (`resolveAgentWorkspaceDir` for the default agent id).\n */\nexport function getWorkspacePath(config: Config): string {\n return getDefaultWorkspacePath(config);\n}\n\n/**\n * Primary model ref from `agents.defaults.model` (string or `{ primary }`).\n * Returns undefined when unset or empty.\n */\nexport function getAgentDefaultModelRef(config: Config): string | undefined {\n const raw = config.agents?.defaults?.model;\n if (raw === undefined || raw === null) return undefined;\n const ref = typeof raw === 'string' ? raw : raw.primary;\n if (ref === undefined || ref === null) return undefined;\n const s = String(ref).trim();\n return s ? s : undefined;\n}\n\n/** `provider/model` or null when invalid. */\nexport function parseModelRef(ref: string): ParsedModelRef | null {\n const trimmed = ref.trim();\n const idx = trimmed.indexOf('/');\n if (idx <= 0 || idx === trimmed.length - 1) {\n return null;\n }\n return { provider: trimmed.slice(0, idx).trim(), model: trimmed.slice(idx + 1).trim() };\n}\n"],"mappings":";;;;;;;;;AAklCA,SAAgB,iBAAiB,QAAwB;AACvD,QAAO,wBAAwB,OAAO;;;;;;AAOxC,SAAgB,wBAAwB,QAAoC;CAC1E,MAAM,MAAM,OAAO,QAAQ,UAAU;AACrC,KAAI,QAAQ,KAAA,KAAa,QAAQ,KAAM,QAAO,KAAA;CAC9C,MAAM,MAAM,OAAO,QAAQ,WAAW,MAAM,IAAI;AAChD,KAAI,QAAQ,KAAA,KAAa,QAAQ,KAAM,QAAO,KAAA;CAC9C,MAAM,IAAI,OAAO,IAAI,CAAC,MAAM;AAC5B,QAAO,IAAI,IAAI,KAAA;;;AAIjB,SAAgB,cAAc,KAAoC;CAChE,MAAM,UAAU,IAAI,MAAM;CAC1B,MAAM,MAAM,QAAQ,QAAQ,IAAI;AAChC,KAAI,OAAO,KAAK,QAAQ,QAAQ,SAAS,EACvC,QAAO;AAET,QAAO;EAAE,UAAU,QAAQ,MAAM,GAAG,IAAI,CAAC,MAAM;EAAE,OAAO,QAAQ,MAAM,MAAM,EAAE,CAAC,MAAM;EAAE;;;;mBAxmCvB;qBA8VV;uBAEqD;AA1VhG,uBAAsB,EAAE,MAAM,CACzC,EAAE,QAAQ,EACV,EACG,OAAO;EACN,SAAS,EAAE,QAAQ,CAAC,UAAU;EAC9B,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,UAAU;EAC1C,CAAC,CACD,QAAQ,CACZ,CAAC;AAUW,mCAAkC,EAAE,MAAM,CACrD,EAAE,QAAQ,EACV,EACG,OAAO;EACN,SAAS,EAAE,QAAQ,CAAC,UAAU;EAC9B,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,UAAU;;EAEzC,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU;;;;;EAKjD,sBAAsB,EAAE,SAAS,CAAC,UAAU;EAC7C,CAAC,CACD,QAAQ,CACZ,CAAC;AAIW,uBAAsB,EAAE,OAAO;;EAE1C,WAAW,EAAE,QAAQ,CAAC,QAAQ,oBAAoB;EAClD,OAAO,EAAE,MAAM,CACb,EAAE,QAAQ,EACV,EAAE,OAAO;GACP,SAAS,EAAE,QAAQ,CAAC,UAAU;GAC9B,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,UAAU;GAC1C,CAAC,CAAC,QAAQ,CACZ,CAAC,CAAC,QAAQ,GAAG;;EAEd,YAAY,oBAAoB,UAAU;;EAE1C,sBAAsB,gCAAgC,UAAU;;EAEhE,YAAY,EAAE,QAAQ,CAAC,UAAU,CAAC,UAAU;EAC5C,WAAW,EAAE,QAAQ,CAAC,QAAQ,KAAK;EACnC,aAAa,EAAE,QAAQ,CAAC,QAAQ,GAAI;EACpC,mBAAmB,EAAE,QAAQ,CAAC,QAAQ,GAAG;EAEzC,mBAAmB,EAAE,QAAQ,CAAC,IAAI,IAAM,CAAC,IAAI,MAAW,CAAC,UAAU;EAEnE,oBAAoB,EAAE,QAAQ,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,GAAG;EAC3D,wBAAwB,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,GAAG,CAAC,QAAQ,EAAE;EAE5D,iBAAiB,EAAE,KAAK;GAAC;GAAO;GAAW;GAAO;GAAU;GAAQ;GAAS;GAAW,CAAC,CAAC,UAAU;EACpG,kBAAkB,EAAE,KAAK;GAAC;GAAO;GAAM;GAAS,CAAC,CAAC,UAAU;EAC5D,gBAAgB,EAAE,KAAK;GAAC;GAAO;GAAM;GAAO,CAAC,CAAC,UAAU;EACxD,mBAAmB,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU;EACzD,wBAAwB,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU;EAC9D,kCAAkC,EAAE,KAAK;GAAC;GAAO;GAAQ;GAAS,CAAC,CAAC,UAAU;EAC9E,gBAAgB,EACb,OAAO;GACN,SAAS,EAAE,SAAS,CAAC,UAAU;GAC/B,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,UAAU;GACrD,iBAAiB,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU;GACnD,cAAc,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU;GACpD,cAAc,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU;GACpD,eAAe,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU;GACtD,CAAC,CACD,UAAU;EACb,eAAe,EACZ,OAAO,EACN,wBAAwB,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU,EAC/D,CAAC,CACD,UAAU;EACb,YAAY,EAAE,OAAO;GACnB,SAAS,EAAE,SAAS,CAAC,QAAQ,KAAK;GAClC,MAAM,EAAE,KAAK,CAAC,WAAW,YAAY,CAAC,CAAC,QAAQ,UAAU;GACzD,eAAe,EAAE,QAAQ,CAAC,QAAQ,IAAK;GACvC,kBAAkB,EAAE,QAAQ,CAAC,IAAI,GAAI,CAAC,IAAI,IAAK,CAAC,QAAQ,GAAI;GAC5D,0BAA0B,EAAE,QAAQ,CAAC,QAAQ,GAAG;GAChD,oBAAoB,EAAE,QAAQ,CAAC,QAAQ,EAAE;GAEzC,gBAAgB,EAAE,QAAQ,CAAC,IAAI,GAAI,CAAC,IAAI,GAAI,CAAC,QAAQ,GAAI;GACzD,iBAAiB,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,GAAG,CAAC,QAAQ,EAAE;GACrD,wBAAwB,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,UAAU;GACvD,CAAC,CAAC,UAAU;EACb,SAAS,EAAE,OAAO;GAChB,SAAS,EAAE,SAAS,CAAC,QAAQ,KAAK;GAClC,oBAAoB,EAAE,QAAQ,CAAC,QAAQ,IAAM;GAC7C,eAAe,EAAE,QAAQ,CAAC,QAAQ,GAAI;GACtC,eAAe,EAAE,QAAQ,CAAC,QAAQ,GAAI;GACvC,CAAC,CAAC,UAAU;;;;;EAKb,QAAQ,EACL,OAAO;;GAEN,SAAS,EAAE,SAAS,CAAC,UAAU;;GAE/B,mBAAmB,EAAE,SAAS,CAAC,UAAU;;GAEzC,oBAAoB,EAAE,SAAS,CAAC,UAAU;GAC1C,iBAAiB,EAAE,QAAQ,CAAC,UAAU,CAAC,UAAU;GACjD,eAAe,EAAE,QAAQ,CAAC,UAAU,CAAC,UAAU;GAC/C,UAAU,EAAE,KAAK,CAAC,QAAQ,OAAO,CAAC,CAAC,UAAU;;GAE7C,oBAAoB,EAAE,KAAK,CAAC,cAAc,aAAa,CAAC,CAAC,UAAU;;GAEnE,gBAAgB,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU;;GAElD,kBAAkB,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU;;;;;;;;;;GAUpD,UAAU,EACP,OAAO;IACN,SAAS,EAAE,SAAS,CAAC,UAAU;;IAE/B,WAAW,EAAE,QAAQ,CAAC,UAAU;IAChC,UAAU,EAAE,QAAQ,CAAC,UAAU;IAC/B,QAAQ,EACL,OAAO;KACN,OAAO,EACJ,OAAO;MACN,SAAS,EAAE,SAAS,CAAC,UAAU;MAC/B,MAAM,EAAE,QAAQ,CAAC,UAAU;MAC3B,cAAc,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU;MAChD,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU;MACzC,kBAAkB,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,UAAU;MACtD,CAAC,CACD,UAAU;KACb,MAAM,EACH,OAAO;MACN,SAAS,EAAE,SAAS,CAAC,UAAU;MAC/B,MAAM,EAAE,QAAQ,CAAC,UAAU;MAC3B,UAAU,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,UAAU;MAC7C,gBAAgB,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU;MAClD,kBAAkB,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU;MACpD,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU;MACzC,qBAAqB,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,UAAU;MACjD,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU;MAC/C,CAAC,CACD,UAAU;KACb,KAAK,EACF,OAAO;MACN,SAAS,EAAE,SAAS,CAAC,UAAU;MAC/B,MAAM,EAAE,QAAQ,CAAC,UAAU;MAC3B,cAAc,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU;MAChD,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU;MACzC,oBAAoB,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,UAAU;MACxD,CAAC,CACD,UAAU;KACd,CAAC,CACD,UAAU;IACd,CAAC,CACD,UAAU;GACd,CAAC,CACD,UAAU;;EAEb,eAAe,EACZ,OAAO;;AAEN,cAAc,EAAE,QAAQ,CAAC,UAAU,EACpC,CAAC,CACD,UAAU;;;;;;EAMb,kBAAkB,EACf,OAAO;;GAEN,SAAS,EAAE,SAAS,CAAC,UAAU;;GAE/B,qBAAqB,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU;;GAEvD,oBAAoB,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU;;GAEtD,eAAe,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,GAAG,CAAC,UAAU;;GAEzD,oBAAoB,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU;;GAEhE,eAAe,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAO,CAAC,IAAI,IAAQ,CAAC,UAAU;GACpE,CAAC,CACD,UAAU;;EAEb,YAAY,EACT,OAAO;GACN,OAAO,EAAE,QAAQ,CAAC,UAAU;GAC5B,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,UAAU;GAC5C,CAAC,CACD,UAAU;;;;;EAKb,SAAS,EACN,OAAO;GACN,SAAS,EAAE,SAAS,CAAC,UAAU;;GAE/B,UAAU,EAAE,SAAS,CAAC,UAAU;;GAEhC,kBAAkB,EAAE,SAAS,CAAC,UAAU;;GAExC,gBAAgB,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,UAAU;;GAE5C,SAAS,EAAE,KAAK;IAAC;IAAS;IAAO;IAAS;IAAY,CAAC,CAAC,UAAU;;GAElE,eAAe,EAAE,KAAK;IAAC;IAAS;IAAe;IAAc,CAAC,CAAC,UAAU;;GAEzE,QAAQ,EAAE,QAAQ,CAAC,UAAU;;GAE7B,WAAW,EAAE,OAAO;;IAElB,MAAM,EAAE,QAAQ,CAAC,IAAI,KAAK,CAAC,IAAI,MAAM,CAAC,UAAU;;IAEhD,MAAM,EAAE,QAAQ,CAAC,UAAU;;IAE3B,mBAAmB,EAAE,QAAQ,CAAC,IAAI,IAAK,CAAC,UAAU;IACnD,CAAC,CAAC,UAAU;;GAEb,cAAc,EAAE,KAAK;IAAC;IAAgB;IAAgB;IAAc,CAAC,CAAC,UAAU;;GAEhF,sBAAsB,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,UAAU;GACnD,CAAC,CACD,UAAU;;EAEb,UAAU,EACP,OAAO,EACN,SAAS,EAAE,SAAS,CAAC,UAAU,EAChC,CAAC,CACD,UAAU;;EAEb,aAAa,EACV,OAAO,EACN,SAAS,EAAE,SAAS,CAAC,UAAU,EAChC,CAAC,CACD,UAAU;;EAEb,sBAAsB,EAAE,QAAQ,CAAC,UAAU;;EAE3C,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,UAAU;;EAEtC,OAAO,EACJ,OAAO,EACN,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,UAAU,EACxC,CAAC,CACD,UAAU;;EAEb,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,SAAS,CAAC,CAAC,UAAU;EACrD,CAAC;AAEW,qBAAoB,EAAE,OAAO;EACxC,IAAI,EAAE,QAAQ;;EAEd,SAAS,EAAE,SAAS,CAAC,UAAU;EAC/B,MAAM,EAAE,QAAQ,CAAC,UAAU;;EAE3B,aAAa,EAAE,QAAQ,CAAC,IAAI,IAAK,CAAC,UAAU;EAC5C,SAAS,EAAE,SAAS,CAAC,QAAQ,KAAK;;EAElC,WAAW,EAAE,QAAQ,CAAC,UAAU;;;;;EAKhC,UAAU,EAAE,QAAQ,CAAC,UAAU;EAC/B,OAAO,oBAAoB,UAAU;EACrC,iBAAiB,EAAE,KAAK;GAAC;GAAO;GAAW;GAAO;GAAU;GAAQ;GAAS;GAAW,CAAC,CAAC,UAAU;EACpG,kBAAkB,EAAE,KAAK;GAAC;GAAO;GAAM;GAAS,CAAC,CAAC,UAAU;EAC5D,gBAAgB,EAAE,KAAK;GAAC;GAAO;GAAM;GAAO,CAAC,CAAC,UAAU;EACxD,sBAAsB,EAAE,QAAQ,CAAC,UAAU;EAC3C,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,UAAU;EACtC,OAAO,EACJ,OAAO,EACN,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,UAAU,EACxC,CAAC,CACD,UAAU;EACb,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,SAAS,CAAC,CAAC,UAAU;EACrD,CAAC;AAEW,sBAAqB,EAAE,OAAO;;EAEzC,SAAS,EAAE,QAAQ,CAAC,UAAU;EAC9B,UAAU,oBAAoB,UAAU;EACxC,MAAM,EAAE,MAAM,kBAAkB,CAAC,UAAU;EAC5C,CAAC,CAAC,QAAQ,EACT,UAAU;EACR,WAAW;EACX,OAAO;EACP,WAAW;EACX,aAAa;EACb,mBAAmB;EACnB,oBAAoB;EACpB,wBAAwB;EACxB,iBAAiB;EACjB,kBAAkB;EAClB,gBAAgB;EAChB,YAAY;GACV,SAAS;GACT,MAAM;GACN,eAAe;GACf,kBAAkB;GAClB,0BAA0B;GAC1B,oBAAoB;GACpB,gBAAgB;GAChB,iBAAiB;GAClB;EACD,SAAS;GACP,SAAS;GACT,oBAAoB;GACpB,eAAe;GACf,eAAe;GAChB;EACF,EACF,CAAQ;AAmBI,sBAAqB,EAAE,OAAO;EACzC,SAAS,EAAE,QAAQ;EACnB,WAAW,EAAE,QAAQ,CAAC,UAAU;EAChC,UAAU,EAAE,QAAQ,CAAC,UAAU;EAC/B,QAAQ,EAAE,QAAQ,CAAC,UAAU;EAC7B,SAAS,EAAE,QAAQ,CAAC,UAAU;EAC9B,QAAQ,EAAE,QAAQ,CAAC,UAAU;EAC7B,eAAe,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,UAAU;EAC9C,CAAC;AAEW,qBAAoB,EAAE,OAAO;EACxC,IAAI,EAAE,QAAQ,CAAC,UAAU;EACzB,SAAS,EAAE,QAAQ;EACnB,UAAU,EAAE,QAAQ,CAAC,QAAQ,IAAI;EACjC,OAAO;EACP,SAAS,EAAE,SAAS,CAAC,QAAQ,KAAK;EACnC,CAAC;AAEW,wBAAuB,EAAE,MAAM,kBAAkB,CAAC,QAAQ,EAAE,CAAC;AAE7D,wBAAuB,EAAE,KAAK;EACzC;EACA;EACA;EACA;EACD,CAAC;AAEW,8BAA6B,EAAE,OAAO;EACjD,cAAc,EAAE,QAAQ,CAAC,UAAU;EACnC,YAAY,EAAE,QAAQ,CAAC,UAAU;EAClC,CAAC;AAEW,uBAAsB,EAAE,OAAO;EAC1C,SAAS,qBAAqB,QAAQ,OAAO;EAC7C,eAAe,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,UAAU;EACnE,SAAS,2BAA2B,UAAU;EAC/C,CAAC,CAAC,QAAQ,EACT,SAAS,QACV,CAAC;AAGW,wBAAuB,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,SAAS,CAAC,CAAC,QAAQ,EAC5E,UAAU;EACR,SAAS;EACT,WAAW,EAAE;EACb,gBAAgB,EAAE;EAClB,OAAO;EACP,UAAU,EACR,SAAS;GACP,WAAW;GACX,SAAS;GACT,UAAU;GACV,WAAW,EAAE;GACb,UAAU;GACV,aAAa;GACb,aAAa;GACb,cAAc;GACd,gBAAgB;GAChB,YAAY;GACb,EACF;EACD,UAAU;EACV,aAAa;EACb,aAAa;EACb,cAAc;EACd,gBAAgB;EACjB,EACF,CAAC;AAEW,6BAA4B,EAAE,OAAO;EAChD,MAAM,EAAE,KAAK;GAAC;GAAS;GAAU;GAAQ;GAAU,CAAC;EACpD,QAAQ,EAAE,QAAQ,CAAC,UAAU;;EAE7B,KAAK,EAAE,QAAQ,CAAC,UAAU;EAC1B,UAAU,EAAE,SAAS,CAAC,UAAU;EACjC,CAAC;AAIW,yBAAwB,EAAE,OAAO;EAC5C,YAAY,EAAE,QAAQ,CAAC,QAAQ,EAAE;;EAEjC,WAAW,EAAE,MAAM,0BAA0B,CAAC,QAAQ,EAAE,CAAC;EAC1D,CAAC;AAIW,0BAAyB,EAAE,OAAO;;EAE7C,SAAS,EAAE,SAAS,CAAC,QAAQ,MAAM;;EAEnC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC;EACzC,CAAC;AAIW,wBAAuB,EAAE,OAAO;;EAE3C,QAAQ,EAAE,KAAK,CAAC,MAAM,SAAS,CAAC,CAAC,UAAU;EAC3C,QAAQ,sBAAsB,UAAU;;EAExC,WAAW,uBAAuB,UAAU;EAC7C,CAAC;AAIW,qBAAoB,EAAE,OAAO;EACxC,KAAK,qBAAqB,UAAU;;;;;EAKpC,OAAO,EAAE,WAAW,uBAAuB;EAC5C,CAAC,CAAC,QAAQ,EACT,KAAK,EACH,QAAQ;EACN,YAAY;EACZ,WAAW,EAAE;EACd,EACF,EACF,CAAC;AAMW,8BAA6B,EACvC,OAAO;EACN,SAAS,EAAE,SAAS,CAAC,QAAQ,KAAK;EAClC,aAAa,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;EAC/C,UAAU,EAAE,QAAQ,CAAC,QAAQ,IAAQ;EACrC,iBAAiB,EAAE,QAAQ,CAAC,QAAQ,IAAQ;EAC7C,CAAC,CACD,UAAU;AAEA,qBAAoB,EAC9B,OAAO;EACN,MAAM,EAAE,KAAK;GAAC;GAAQ;GAAS;GAAW,CAAC,CAAC,QAAQ,QAAQ;EAC5D,OAAO,EAAE,QAAQ,CAAC,UAAU;EAC5B,UAAU,EAAE,QAAQ,CAAC,UAAU;EAC/B,WAAW;EACZ,CAAC,CACD,QAAQ,EACP,MAAM,SACP,CAAC;AAES,yBAAwB,EAClC,OAAO;EACN,SAAS,EAAE,SAAS;EACpB,YAAY,EAAE,QAAQ;;EAEtB,4BAA4B,EAAE,SAAS,CAAC,UAAU,CAAC,QAAQ,MAAM;EACjE,QAAQ,EAAE,QAAQ,CAAC,UAAU;EAC7B,cAAc,EAAE,QAAQ,CAAC,UAAU;EACnC,QAAQ,EAAE,QAAQ,CAAC,UAAU;EAC7B,aAAa,EAAE,QAAQ,CAAC,UAAU;EAClC,iBAAiB,EAAE,SAAS,CAAC,UAAU;EACvC,aAAa,EACV,OAAO;GACN,OAAO,EAAE,QAAQ;GACjB,KAAK,EAAE,QAAQ;GACf,UAAU,EAAE,QAAQ,CAAC,UAAU;GAChC,CAAC,CACD,UAAU;EACd,CAAC,CACD,QAAQ;EACP,SAAS;EACT,YAAY;EACZ,4BAA4B;EAC7B,CAAC;AAES,wCAAuC,EAAE,KAAK;EAAC;EAAQ;EAAO;EAAW,CAAC;AAE1E,uBAAsB,EAAE,OAAO;EAC1C,SAAS,EAAE,QAAQ,CAAC,IAAI,EAAE;EAC1B,YAAY,EAAE,QAAQ,CAAC,IAAI,EAAE;EAC9B,CAAC;AAEW,mBAAkB,EAC5B,OAAO;EACN,SAAS,EAAE,SAAS,CAAC,QAAQ,KAAK;EAClC,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,MAAM,CAAC,QAAQ,MAAM;EAC7D,SAAS,EAAE,SAAS,CAAC,QAAQ,MAAM;EACpC,CAAC,CACD,QAAQ;EACP,SAAS;EACT,SAAS;EACT,SAAS;EACV,CAAC;AAES,sBAAqB,EAC/B,OAAO;EACN,SAAS,EAAE,SAAS,CAAC,QAAQ,MAAM;EACnC,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,0BAA0B;;EAE9D,oBAAoB,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,UAAU;EAChD,WAAW,EAAE,SAAS,CAAC,QAAQ,MAAM;EACrC,WAAW,EAAE,QAAQ,CAAC,UAAU;EAChC,SAAS,oBAAoB,UAAU;EACvC,KAAK,gBAAgB,UAAU;EAChC,CAAC,CACD,QAAQ;EACP,SAAS;EACT,WAAW;EACX,WAAW;EACZ,CAAC;AAIS,uBAAsB,EAAE,OAAO;EAC1C,MAAM,EAAE,QAAQ,CAAC,UAAU;EAC3B,MAAM,EAAE,QAAQ,CAAC,UAAU;EAC3B,MAAM,kBAAkB,UAAU;EAClC,WAAW,sBAAsB,UAAU;EAC3C,mBAAmB,EAAE,QAAQ,CAAC,UAAU;EACxC,aAAa,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,UAAU;;;;;;;EAO3C,yBAAyB,qCAAqC,UAAU;;EAExE,wBAAwB,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,UAAU;;EAErE,4BAA4B,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,UAAU;;EAEzE,2BAA2B,EAAE,QAAQ,CAAC,UAAU;;EAEhD,oBAAoB,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU;;EAE/C,OAAO,EAAE,OAAO;GACd,SAAS,EAAE,SAAS,CAAC,QAAQ,KAAK;;GAElC,cAAc,EAAE,QAAQ,CAAC,IAAI,IAAO,CAAC,IAAI,OAAY,CAAC,QAAQ,MAAW;;GAEzE,UAAU,EAAE,QAAQ,CAAC,IAAI,IAAO,CAAC,IAAI,OAAc,CAAC,QAAQ,OAAY;;GAExE,iBAAiB,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,IAAO,CAAC,QAAQ,IAAI;;GAE3D,aAAa,EAAE,QAAQ,CAAC,IAAI,QAAU,CAAC,IAAI,YAAe,CAAC,QAAQ,UAAY;;GAE/E,oBAAoB,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ;IAC9C;IAAa;IAAc;IAAa;IAAc;IACvD,CAAC;GACH,CAAC,CAAC,UAAU;EACd,CAAC,CAAC,QAAQ;EACT,MAAM;EACN,MAAM;EACN,MAAM,EACJ,MAAM,SACP;EACD,WAAW;GACT,SAAS;GACT,YAAY;GACZ,4BAA4B;GAC7B;EACD,mBAAmB;EACnB,aAAa,EAAE;EACf,2BAA2B;EAC3B,oBAAoB;EACrB,CAAC;AAEW,oBAAmB,EAAE,OAAO;EACvC,SAAS,EAAE,SAAS,CAAC,UAAU;EAC/B,mBAAmB,EAAE,QAAQ,CAAC,UAAU;EACxC,iBAAiB,EAAE,QAAQ,CAAC,UAAU;EACtC,sBAAsB,EAAE,QAAQ,CAAC,UAAU;EAC3C,eAAe,EAAE,SAAS,CAAC,UAAU;EACtC,CAAC,CAAC,QAAQ;EACT,SAAS;EACT,mBAAmB;EACnB,iBAAiB;EACjB,sBAAsB;EACtB,eAAe;EAChB,CAAC;AAEW,yBAAwB,EAAE,OAAO,EAC5C,SAAS,EAAE,SAAS,CAAC,QAAQ,KAAK,EACnC,CAAC,CAAC,QAAQ,EACT,SAAS,MACV,CAAC;AAMW,2BAA0B,EAAE,OAAO;EAC9C,QAAQ,EAAE,QAAQ,CAAC,UAAU;EAC7B,OAAO,EAAE,QAAQ,CAAC,UAAU;EAC7B,CAAC;AAEW,2BAA0B,EAAE,OAAO;EAC9C,SAAS,EAAE,SAAS,CAAC,QAAQ,KAAK;EAClC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,WAAW,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,SAAS,CAAC;EAC7E,CAAC;AAEW,mBAAkB,EAAE,OAAO;EACtC,SAAS,EAAE,SAAS,CAAC,QAAQ,MAAM;EACnC,UAAU,EAAE,KAAK,CAAC,WAAW,SAAS,CAAC,CAAC,QAAQ,UAAU;EAC1D,SAAS,wBAAwB,UAAU;EAC3C,QAAQ,wBAAwB,UAAU;EAC1C,UAAU,wBAAwB,UAAU;EAC7C,CAAC;AAMW,2BAA0B,EAAE,OAAO;EAC9C,QAAQ,EAAE,QAAQ,CAAC,UAAU;EAC7B,OAAO,EAAE,QAAQ,CAAC,UAAU;EAC5B,OAAO,EAAE,QAAQ,CAAC,UAAU;EAC7B,CAAC;AAEW,2BAA0B,EAAE,OAAO;EAC9C,SAAS,EAAE,SAAS,CAAC,QAAQ,KAAK;EAClC,OAAO,EACJ,MAAM,EAAE,KAAK;GAAC;GAAU;GAAW;GAAQ;GAAU,CAAC,CAAC,CACvD,QAAQ;GAAC;GAAU;GAAW;GAAW;GAAO,CAAC;EACrD,CAAC;AAEW,iCAAgC,EAAE,OAAO;EACpD,SAAS,EAAE,SAAS,CAAC,QAAQ,KAAK;EAClC,WAAW,EAAE,SAAS,CAAC,QAAQ,KAAK;EACpC,eAAe,EAAE,SAAS,CAAC,QAAQ,MAAM;EACzC,YAAY,EAAE,SAAS,CAAC,QAAQ,KAAK;EACrC,cAAc,EAAE,SAAS,CAAC,QAAQ,KAAK;EACvC,oBAAoB,EAAE,SAAS,CAAC,QAAQ,MAAM;EAC9C,oBAAoB,EAAE,SAAS,CAAC,QAAQ,MAAM;EAC9C,WAAW,EAAE,SAAS,CAAC,QAAQ,MAAM;EACtC,CAAC;AAEW,uBAAsB,EAAE,OAAO;EAC1C,SAAS,EAAE,SAAS,CAAC,QAAQ,KAAK;EAClC,OAAO,EAAE,QAAQ,CAAC,UAAU;EAC5B,MAAM,EAAE,QAAQ,CAAC,UAAU;EAC3B,cAAc,EAAE,QAAQ,CAAC,UAAU;EACnC,OAAO,EAAE,QAAQ,CAAC,UAAU;EAC5B,MAAM,EAAE,QAAQ,CAAC,UAAU;EAC3B,QAAQ,EAAE,QAAQ,CAAC,UAAU;EAC7B,OAAO,EAAE,QAAQ,CAAC,UAAU;EAC5B,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAK,CAAC,IAAI,KAAO,CAAC,UAAU;EAC7D,CAAC;AAEW,gCAA+B,EAAE,OAAO;EACnD,SAAS,EAAE,SAAS,CAAC,UAAU;EAC/B,cAAc,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU;EAChD,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU;EAC7C,OAAO,EAAE,QAAQ,CAAC,UAAU;EAC7B,CAAC;AAEW,mBAAkB,EAAE,OAAO;EACtC,SAAS,EAAE,SAAS,CAAC,QAAQ,MAAM;EACnC,UAAU,EAAE,KAAK;GAAC;GAAU;GAAW;GAAQ;GAAU,CAAC,CAAC,QAAQ,SAAS;EAC5E,SAAS,EAAE,KAAK;GAAC;GAAO;GAAU;GAAW;GAAS,CAAC,CAAC,QAAQ,SAAS;EACzE,UAAU,wBAAwB,UAAU;EAC5C,eAAe,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,QAAQ,IAAI;EACnD,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAK,CAAC,IAAI,KAAO,CAAC,QAAQ,IAAM;EAChE,eAAe,6BAA6B,UAAU;EACtD,gBAAgB,8BAA8B,UAAU;EACxD,SAAS,wBAAwB,UAAU;EAC3C,QAAQ,wBAAwB,UAAU;EAC1C,MAAM,oBAAoB,UAAU;EACpC,SAAS,wBAAwB,UAAU;EAC5C,CAAC;AAMW,wBAAuB,EAAE,OAAO;;AAE3C,KAAK,gBAAgB,UAAU,EAChC,CAAC,CAAC,UAAU;AAEA,+BAA8B;AAE9B,0BAAyB,EAAE,OAAO;;AAE7C,OAAO,4BAA4B,UAAU,EAC9C,CAAC,CAAC,UAAU;AAaA,6BAA4B,EACtC,OAAO;;EAEN,UAAU,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,UAAU;;EAEtC,YAAY,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,UAAU;;EAExC,YAAY,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,UAAU;EACzC,CAAC,CACD,QAAQ;AAGE,kCAAiC,EAC3C,OAAO;;EAEN,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU;;EAEjD,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,QAAQ,CAAC,CAAC,UAAU;EACrD,CAAC,CACD,QAAQ;AAQE,4BAA2B,EACrC,OAAO;;EAEN,QAAQ,EAAE,QAAQ,CAAC,UAAU;;EAE7B,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU;;EAEpC,QAAQ,EAAE,QAAQ,CAAC,UAAU;;EAE7B,cAAc,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU;;EAEzC,SAAS,+BAA+B,UAAU;;EAElD,OAAO,0BAA0B,UAAU;EAC5C,CAAC,CACD,QAAQ;AASE,yBAAwB,EAAE,OAAO,EAAE,QAAQ,EAAE,yBAAyB;AAStE,iCAAgC,EAAE,OAAO;EACpD,kBAAkB,EAAE,SAAS,CAAC,QAAQ,KAAK;EAC3C,gBAAgB,EAAE,SAAS,CAAC,QAAQ,MAAM;EAC1C,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC;EACtC,iBAAiB,EAAE,SAAS,CAAC,QAAQ,KAAK;EAC1C,sBAAsB,EAAE,SAAS,CAAC,QAAQ,MAAM;EACjD,CAAC;AAGW,8BAA6B,EAAE,OAAO;EACjD,QAAQ,EAAE,QAAQ,CAAC,UAAU;EAC7B,KAAK,EAAE,QAAQ,CAAC,UAAU;EAC1B,iBAAiB,EAAE,QAAQ,CAAC,UAAU;EACtC,WAAW,EAAE,QAAQ,CAAC,UAAU;EACjC,CAAC;AAMW,0BAA6D,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,SAAS,CAAC;AAM9F,0BAAyB,EACnC,OAAO;;EAEN,SAAS,EAAE,SAAS,CAAC,QAAQ,MAAM;;EAEnC,kBAAkB,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;;EAE9C,mBAAmB,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,QAAQ,GAAG;;EAEhD,wBAAwB,EAAE,QAAQ,CAAC,IAAI,IAAK,CAAC,QAAQ,EAAE;EACxD,CAAC,CACD,QAAQ,CACR,UAAU;AAGA,qBAAoB,EAC9B,OAAO;;EAEN,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI,CAAC,QAAQ,GAAG;;EAEtD,eAAe,EAAE,QAAQ,CAAC,UAAU;;;;;EAKpC,eAAe,EAAE,SAAS,CAAC,QAAQ,KAAK;;EAExC,6BAA6B,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,GAAG,CAAC,QAAQ,EAAE;;EAEvE,gBAAgB,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAM,CAAC,IAAI,KAAQ,CAAC,QAAQ,IAAO;;EAExE,uBAAuB,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,IAAQ,CAAC,QAAQ,KAAO;EAC5E,CAAC,CACD,QAAQ;AAIE,sBAAqB,EAC/B,OAAO;;EAEN,cAAc,EAAE,SAAS,CAAC,QAAQ,KAAK;;EAEvC,SAAS,EAAE,KAAK;GAAC;GAAU;GAAQ;GAAM,CAAC,CAAC,QAAQ,SAAS;;EAE5D,MAAM;EACP,CAAC,CACD,QAAQ,CACR,UAAU;AAQP,oBAAmB,EACtB,QAAQ,CACR,KAAK,CACL,QAAQ,UAAU;AACjB,MAAI;GACF,MAAM,WAAW,IAAI,IAAI,MAAM,CAAC;AAChC,UAAO,aAAa,WAAW,aAAa;UACtC;AACN,UAAO;;IAER,wCAAwC;AAEhC,mBAAkB,EAC5B,OAAO;EACN,SAAS,EAAE,QAAQ,CAAC,UAAU;EAC9B,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,UAAU;EACpC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,MAAM;GAAC,EAAE,QAAQ;GAAE,EAAE,QAAQ;GAAE,EAAE,SAAS;GAAC,CAAC,CAAC,CAAC,UAAU;EACpF,KAAK,EAAE,QAAQ,CAAC,UAAU;EAC1B,kBAAkB,EAAE,QAAQ,CAAC,UAAU;EACvC,KAAK,iBAAiB,UAAU;EAChC,WAAW,EAAE,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC,UAAU;EACxD,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,MAAM;GAAC,EAAE,QAAQ;GAAE,EAAE,QAAQ;GAAE,EAAE,SAAS;GAAC,CAAC,CAAC,CAAC,UAAU;EACxF,qBAAqB,EAAE,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,UAAU;EAC/D,CAAC,CACD,SAAS,EAAE,SAAS,CAAC,CACrB,aAAa,OAAO,QAAQ;EAC3B,MAAM,aAAa,OAAO,MAAM,YAAY,YAAY,MAAM,QAAQ,MAAM,CAAC,SAAS;EACtF,MAAM,SAAS,OAAO,MAAM,QAAQ,YAAY,MAAM,IAAI,MAAM,CAAC,SAAS;AAC1E,MAAI,cAAc,OAChB,KAAI,SAAS;GACX,MAAM;GACN,SAAS;GACV,CAAC;GAEJ;AAES,mBAAkB,EAC5B,OAAO;EACN,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,gBAAgB,CAAC,UAAU;EACzD,kBAAkB,EAAE,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,UAAU;EACxD,CAAC,CACD,QAAQ,CACR,UAAU;AASA,gBAAe,EAAE,OAAO;EACnC,QAAQ;EACR,UAAU;EACV,SAAS;EACT,UAAU;EACV,SAAS;EACT,QAAQ,mBAAmB,UAAU;EACrC,OAAO;EACP,KAAK;EACL,MAAM;EACN,OAAO,kBAAkB,UAAU;EACnC,YAAY,uBAAuB,QAAQ,EAAE,CAAC;;EAE9C,WAAW,sBAAsB,UAAU;EAC3C,WAAW;;EAEX,UAAU;EACV,QAAQ;EACT,CAAC,CAAC,QAAQ;EACT,QAAQ,EACN,UAAU;GACR,WAAW;GACX,OAAO;GACP,WAAW;GACX,aAAa;GACb,mBAAmB;GACnB,oBAAoB;GACpB,wBAAwB;GACxB,iBAAiB;GACjB,kBAAkB;GAClB,gBAAgB;GAChB,YAAY;IACV,SAAS;IACT,MAAM;IACN,eAAe;IACf,kBAAkB;IAClB,0BAA0B;IAC1B,oBAAoB;IACpB,gBAAgB;IAChB,iBAAiB;IAClB;GACD,SAAS;IACP,SAAS;IACT,oBAAoB;IACpB,eAAe;IACf,eAAe;IAChB;GACF,EACF;EACD,UAAU,EAAE;EACZ,SAAS,EACP,SAAS,QACV;EACD,UAAU,EACR,UAAU;GACR,SAAS;GACT,WAAW,EAAE;GACb,gBAAgB,EAAE;GAClB,OAAO;GACP,UAAU,EACR,SAAS;IACP,WAAW;IACX,SAAS;IACT,UAAU;IACV,WAAW,EAAE;IACb,UAAU;IACV,aAAa;IACb,aAAa;IACb,cAAc;IACd,gBAAgB;IAChB,YAAY;IACb,EACF;GACD,UAAU;GACV,aAAa;GACb,aAAa;GACb,cAAc;GACd,gBAAgB;GACjB,EACF;EACD,SAAS;GACP,MAAM;GACN,MAAM;GACN,MAAM,EACJ,MAAM,SACP;GACD,WAAW;IACT,SAAS;IACT,YAAY;IACZ,4BAA4B;IAC7B;GACD,mBAAmB;GACnB,aAAa,EAAE;GACf,2BAA2B;GAC3B,oBAAoB;GACrB;EACD,OAAO,EACL,KAAK,EACH,QAAQ;GACN,YAAY;GACZ,WAAW,EAAE;GACd,EACF,EACF;EACD,MAAM;GACJ,SAAS;GACT,mBAAmB;GACnB,iBAAiB;GACjB,sBAAsB;GACtB,eAAe;GAChB;EACD,OAAO;GACL,UAAU;GACV,eAAe;GACf,6BAA6B;GAC7B,gBAAgB;GAChB,uBAAuB;GACxB;EACD,YAAY;GACV,OAAO,EAAE;GACT,UAAU;IACR,kBAAkB;IAClB,gBAAgB;IAChB,OAAO,EAAE;IACT,iBAAiB;IACjB,sBAAsB;IACvB;GACD,OAAO,EAAE;GACV;EACD,WAAW,EACT,SAAS,MACV;EAIF,CAAC"}
@@ -196,15 +196,12 @@ export declare function buildSafeWebConfigPayload(service: GatewayService): Prom
196
196
  enabled: boolean;
197
197
  autoStart: boolean;
198
198
  brokerUrl: string;
199
+ registrationSecret: string;
199
200
  consent: {
200
201
  version: string;
201
202
  acceptedAt: string;
202
203
  };
203
- e2e: {
204
- enabled: boolean;
205
- tlsPort: number;
206
- staging: boolean;
207
- };
204
+ e2e: import("../../../tunnel/tunnel-e2e-config.js").ResolvedTunnelE2eConfig;
208
205
  };
209
206
  update: {
210
207
  channel: "stable" | "beta" | "dev";
@@ -4,6 +4,7 @@ import { normalizeConfiguredMcpServers } from "../../../config/mcp-config-normal
4
4
  import { bundledChannelPlugins } from "../../../generated/bundled-channel-plugins.js";
5
5
  import { listChannelPlugins, syncChannelPluginsFromManager } from "../../../channels/plugins/registry.js";
6
6
  import { safeToolsWebForGet } from "../../config-tools-web.js";
7
+ import { resolveTunnelE2eConfig } from "../../../tunnel/tunnel-e2e-config.js";
7
8
  import { agentImageGenerationModelAutoProviderFallback, agentImageGenerationModelTimeoutMs, agentModelFallbacksToArray, agentModelRefToString } from "./agent-model.js";
8
9
  import { buildSafeProvidersConfigForWeb } from "./safe-providers-config.js";
9
10
  //#region src/gateway/hono/lib/config-payload.ts
@@ -136,15 +137,12 @@ async function buildSafeWebConfigPayload(service) {
136
137
  enabled: config.tunnel?.enabled === true,
137
138
  autoStart: config.tunnel?.autoStart === true,
138
139
  brokerUrl: config.tunnel?.brokerUrl ?? "https://frp.xopc.ai/api",
140
+ registrationSecret: config.tunnel?.registrationSecret ? "••••••••••••" : "",
139
141
  consent: config.tunnel?.consent ? {
140
142
  version: config.tunnel.consent.version,
141
143
  acceptedAt: config.tunnel.consent.acceptedAt
142
144
  } : void 0,
143
- e2e: {
144
- enabled: config.tunnel?.e2e?.enabled ?? true,
145
- tlsPort: config.tunnel?.e2e?.tlsPort ?? 18791,
146
- staging: config.tunnel?.e2e?.staging ?? false
147
- }
145
+ e2e: resolveTunnelE2eConfig(config.tunnel, config.gateway?.port ?? 18790)
148
146
  },
149
147
  update: { channel: config.update?.channel ?? "stable" },
150
148
  stt: config.tools?.media?.audio,
@@ -1 +1 @@
1
- {"version":3,"file":"config-payload.js","names":[],"sources":["../../../../../src/gateway/hono/lib/config-payload.ts"],"sourcesContent":["import {\n listAgentEntries,\n normalizeAgentId,\n resolveDefaultAgentId,\n} from '../../../agent/agent-scope.js';\nimport {\n listChannelPlugins,\n syncChannelPluginsFromManager,\n} from '../../../channels/plugins/registry.js';\nimport { normalizeConfiguredMcpServers } from '../../../config/mcp-config-normalize.js';\nimport type { Config } from '../../../config/schema.js';\nimport { bundledChannelPlugins } from '../../../generated/bundled-channel-plugins.js';\nimport { getAllProviders, isProviderConfigured } from '../../../providers/index.js';\nimport type { GatewayService } from '../../service.js';\nimport { safeToolsWebForGet } from '../../config-tools-web.js';\nimport {\n agentImageGenerationModelAutoProviderFallback,\n agentImageGenerationModelTimeoutMs,\n agentModelFallbacksToArray,\n agentModelRefToString,\n} from './agent-model.js';\nimport { buildSafeProvidersConfigForWeb } from './safe-providers-config.js';\n\n/** MCP block for GET/PATCH `/api/config` (authenticated console editing). */\nexport function buildSafeMcpConfigForWeb(config: Config) {\n const mcp = config.mcp;\n if (!mcp) {\n return { servers: {} as Record<string, Record<string, unknown>> };\n }\n return {\n ...(mcp.sessionIdleTtlMs !== undefined ? { sessionIdleTtlMs: mcp.sessionIdleTtlMs } : {}),\n servers: normalizeConfiguredMcpServers(mcp.servers),\n };\n}\n\n/** Sanitized config snapshot for GET/PATCH `/api/config` (matches persisted `service.currentConfig`). */\nexport async function buildSafeWebConfigPayload(service: GatewayService) {\n const config = service.currentConfig;\n if (listChannelPlugins().length === 0) {\n syncChannelPluginsFromManager(bundledChannelPlugins);\n }\n const channelsPayload = Object.fromEntries(\n listChannelPlugins().map((plugin) => {\n if (plugin.configSurface) {\n return [plugin.id, plugin.configSurface.buildConfigSurface(config)];\n }\n const channelCfg = config.channels?.[plugin.id] as Record<string, unknown> | undefined;\n return [\n plugin.id,\n {\n enabled: channelCfg?.enabled ?? false,\n configured: plugin.config.listAccountIds(config).length > 0,\n },\n ];\n }),\n );\n return {\n agents: {\n defaultId: resolveDefaultAgentId(config),\n list: listAgentEntries(config)\n .filter((e) => e.enabled !== false)\n .map((e) => ({\n id: normalizeAgentId(e.id),\n ...(typeof e.name === 'string' && e.name.trim() ? { name: e.name.trim() } : {}),\n })),\n defaults: {\n model: agentModelRefToString(config.agents?.defaults?.model) ?? '',\n modelFallbacks: agentModelFallbacksToArray(config.agents?.defaults?.model),\n imageModel: agentModelRefToString(config.agents?.defaults?.imageModel) ?? null,\n imageModelFallbacks: agentModelFallbacksToArray(config.agents?.defaults?.imageModel),\n imageGenerationModel: agentModelRefToString(config.agents?.defaults?.imageGenerationModel) ?? null,\n imageGenerationModelFallbacks: agentModelFallbacksToArray(\n config.agents?.defaults?.imageGenerationModel,\n ),\n imageGenerationModelTimeoutMs: agentImageGenerationModelTimeoutMs(\n config.agents?.defaults?.imageGenerationModel,\n ),\n imageGenerationModelAutoProviderFallback: agentImageGenerationModelAutoProviderFallback(\n config.agents?.defaults?.imageGenerationModel,\n ),\n mediaMaxMb: config.agents?.defaults?.mediaMaxMb,\n maxTokens: config.agents?.defaults?.maxTokens,\n temperature: config.agents?.defaults?.temperature,\n maxToolIterations: config.agents?.defaults?.maxToolIterations,\n workspace: config.agents?.defaults?.workspace,\n thinkingDefault: config.agents?.defaults?.thinkingDefault,\n reasoningDefault: config.agents?.defaults?.reasoningDefault,\n verboseDefault: config.agents?.defaults?.verboseDefault,\n browser: (() => {\n const br = config.agents?.defaults?.browser;\n if (!br || typeof br !== 'object') {\n return {\n enabled: false,\n headless: false,\n allowPrivateUrls: false,\n commandTimeout: null,\n cloudProvider: null,\n cdpUrl: null,\n dialogPolicy: null,\n dialogTimeoutSeconds: null,\n };\n }\n return {\n enabled: br.enabled === true,\n headless: br.headless === true,\n allowPrivateUrls: br.allowPrivateUrls === true,\n commandTimeout:\n typeof br.commandTimeout === 'number' && Number.isFinite(br.commandTimeout)\n ? Math.floor(br.commandTimeout)\n : null,\n backend:\n br.backend === 'cdp' || br.backend === 'cloud' || br.backend === 'extension'\n ? br.backend\n : null,\n cloudProvider:\n br.cloudProvider === 'browserbase' || br.cloudProvider === 'browser-use' ? br.cloudProvider : null,\n cdpUrl: typeof br.cdpUrl === 'string' && br.cdpUrl.trim() ? br.cdpUrl.trim() : null,\n extension: br.extension && typeof br.extension === 'object' && !Array.isArray(br.extension)\n ? br.extension\n : null,\n dialogPolicy:\n br.dialogPolicy === 'must_respond' ||\n br.dialogPolicy === 'auto_accept' ||\n br.dialogPolicy === 'auto_dismiss'\n ? br.dialogPolicy\n : null,\n dialogTimeoutSeconds:\n typeof br.dialogTimeoutSeconds === 'number' && Number.isFinite(br.dialogTimeoutSeconds)\n ? Math.floor(br.dialogTimeoutSeconds)\n : null,\n };\n })(),\n maxTaskDurationMs: config.agents?.defaults?.maxTaskDurationMs,\n maxRequestsPerTurn: config.agents?.defaults?.maxRequestsPerTurn,\n maxToolFailuresPerTurn: config.agents?.defaults?.maxToolFailuresPerTurn,\n compaction: config.agents?.defaults?.compaction,\n pruning: config.agents?.defaults?.pruning,\n memory: config.agents?.defaults?.memory,\n sessionSearch: config.agents?.defaults?.sessionSearch,\n backgroundReview: config.agents?.defaults?.backgroundReview,\n webExtract: config.agents?.defaults?.webExtract,\n delegate: config.agents?.defaults?.delegate,\n executeCode: config.agents?.defaults?.executeCode,\n systemPromptOverride: config.agents?.defaults?.systemPromptOverride,\n skills: config.agents?.defaults?.skills,\n tools: config.agents?.defaults?.tools,\n params: config.agents?.defaults?.params,\n },\n },\n channels: channelsPayload,\n providers: Object.fromEntries(\n await Promise.all(\n getAllProviders().map(async (provider) => [\n provider,\n (await isProviderConfigured(provider)) ? '***' : '',\n ]),\n ),\n ),\n /** Masked `cfg.providers` for capability keys (image / STT / etc.). */\n providersConfig: buildSafeProvidersConfigForWeb(config.providers),\n gateway: {\n host: config.gateway?.host,\n port: config.gateway?.port,\n corsOrigins: Array.isArray(config.gateway?.corsOrigins) ? config.gateway.corsOrigins : [],\n auth: {\n mode: config.gateway?.auth?.mode || 'token',\n token: config.gateway?.auth?.token || '',\n password: config.gateway?.auth?.password ? '••••••••••••' : '',\n rateLimit: {\n enabled: config.gateway?.auth?.rateLimit?.enabled !== false,\n maxAttempts:\n typeof config.gateway?.auth?.rateLimit?.maxAttempts === 'number'\n ? config.gateway.auth.rateLimit.maxAttempts\n : 5,\n windowMs:\n typeof config.gateway?.auth?.rateLimit?.windowMs === 'number'\n ? config.gateway.auth.rateLimit.windowMs\n : 900_000,\n blockDurationMs:\n typeof config.gateway?.auth?.rateLimit?.blockDurationMs === 'number'\n ? config.gateway.auth.rateLimit.blockDurationMs\n : 300_000,\n },\n },\n heartbeat: {\n enabled: config.gateway?.heartbeat?.enabled,\n intervalMs: config.gateway?.heartbeat?.intervalMs,\n includeSystemPromptSection: config.gateway?.heartbeat?.includeSystemPromptSection === true,\n target: config.gateway?.heartbeat?.target,\n targetChatId: config.gateway?.heartbeat?.targetChatId,\n prompt: config.gateway?.heartbeat?.prompt,\n ackMaxChars: config.gateway?.heartbeat?.ackMaxChars,\n isolatedSession: config.gateway?.heartbeat?.isolatedSession,\n activeHours: config.gateway?.heartbeat?.activeHours,\n },\n maxSseConnections:\n typeof config.gateway?.maxSseConnections === 'number'\n ? config.gateway.maxSseConnections\n : 100,\n channelConnectDeferMode: config.gateway?.channelConnectDeferMode ?? 'auto',\n channelConnectDeferIds: Array.isArray(config.gateway?.channelConnectDeferIds)\n ? config.gateway.channelConnectDeferIds\n : [],\n channelConnectDeferSkipIds: Array.isArray(config.gateway?.channelConnectDeferSkipIds)\n ? config.gateway.channelConnectDeferSkipIds\n : [],\n },\n cron: { enabled: config.cron?.enabled },\n tunnel: {\n enabled: config.tunnel?.enabled === true,\n autoStart: config.tunnel?.autoStart === true,\n brokerUrl: config.tunnel?.brokerUrl ?? 'https://frp.xopc.ai/api',\n consent: config.tunnel?.consent\n ? {\n version: config.tunnel.consent.version,\n acceptedAt: config.tunnel.consent.acceptedAt,\n }\n : undefined,\n e2e: {\n enabled: config.tunnel?.e2e?.enabled ?? true,\n tlsPort: config.tunnel?.e2e?.tlsPort ?? 18791,\n staging: config.tunnel?.e2e?.staging ?? false,\n },\n },\n update: {\n channel: config.update?.channel ?? 'stable',\n },\n stt: config.tools?.media?.audio,\n tts: config.messages?.tts,\n tools: safeToolsWebForGet(config),\n bindings: Array.isArray(config.bindings) ? config.bindings : [],\n mcp: buildSafeMcpConfigForWeb(config),\n };\n}\n"],"mappings":";;;;;;;;;kBAIuC;gBAQ6C;;AAYpF,SAAgB,yBAAyB,QAAgB;CACvD,MAAM,MAAM,OAAO;AACnB,KAAI,CAAC,IACH,QAAO,EAAE,SAAS,EAAE,EAA6C;AAEnE,QAAO;EACL,GAAI,IAAI,qBAAqB,KAAA,IAAY,EAAE,kBAAkB,IAAI,kBAAkB,GAAG,EAAE;EACxF,SAAS,8BAA8B,IAAI,QAAQ;EACpD;;;AAIH,eAAsB,0BAA0B,SAAyB;CACvE,MAAM,SAAS,QAAQ;AACvB,KAAI,oBAAoB,CAAC,WAAW,EAClC,+BAA8B,sBAAsB;CAEtD,MAAM,kBAAkB,OAAO,YAC7B,oBAAoB,CAAC,KAAK,WAAW;AACnC,MAAI,OAAO,cACT,QAAO,CAAC,OAAO,IAAI,OAAO,cAAc,mBAAmB,OAAO,CAAC;EAErE,MAAM,aAAa,OAAO,WAAW,OAAO;AAC5C,SAAO,CACL,OAAO,IACP;GACE,SAAS,YAAY,WAAW;GAChC,YAAY,OAAO,OAAO,eAAe,OAAO,CAAC,SAAS;GAC3D,CACF;GACD,CACH;AACD,QAAO;EACL,QAAQ;GACN,WAAW,sBAAsB,OAAO;GACxC,MAAM,iBAAiB,OAAO,CAC3B,QAAQ,MAAM,EAAE,YAAY,MAAM,CAClC,KAAK,OAAO;IACX,IAAI,iBAAiB,EAAE,GAAG;IAC1B,GAAI,OAAO,EAAE,SAAS,YAAY,EAAE,KAAK,MAAM,GAAG,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,GAAG,EAAE;IAC/E,EAAE;GACL,UAAU;IACR,OAAO,sBAAsB,OAAO,QAAQ,UAAU,MAAM,IAAI;IAChE,gBAAgB,2BAA2B,OAAO,QAAQ,UAAU,MAAM;IAC1E,YAAY,sBAAsB,OAAO,QAAQ,UAAU,WAAW,IAAI;IAC1E,qBAAqB,2BAA2B,OAAO,QAAQ,UAAU,WAAW;IACpF,sBAAsB,sBAAsB,OAAO,QAAQ,UAAU,qBAAqB,IAAI;IAC9F,+BAA+B,2BAC7B,OAAO,QAAQ,UAAU,qBAC1B;IACD,+BAA+B,mCAC7B,OAAO,QAAQ,UAAU,qBAC1B;IACD,0CAA0C,8CACxC,OAAO,QAAQ,UAAU,qBAC1B;IACD,YAAY,OAAO,QAAQ,UAAU;IACrC,WAAW,OAAO,QAAQ,UAAU;IACpC,aAAa,OAAO,QAAQ,UAAU;IACtC,mBAAmB,OAAO,QAAQ,UAAU;IAC5C,WAAW,OAAO,QAAQ,UAAU;IACpC,iBAAiB,OAAO,QAAQ,UAAU;IAC1C,kBAAkB,OAAO,QAAQ,UAAU;IAC3C,gBAAgB,OAAO,QAAQ,UAAU;IACzC,gBAAgB;KACd,MAAM,KAAK,OAAO,QAAQ,UAAU;AACpC,SAAI,CAAC,MAAM,OAAO,OAAO,SACvB,QAAO;MACL,SAAS;MACT,UAAU;MACV,kBAAkB;MAClB,gBAAgB;MAChB,eAAe;MACf,QAAQ;MACR,cAAc;MACd,sBAAsB;MACvB;AAEH,YAAO;MACL,SAAS,GAAG,YAAY;MACxB,UAAU,GAAG,aAAa;MAC1B,kBAAkB,GAAG,qBAAqB;MAC1C,gBACE,OAAO,GAAG,mBAAmB,YAAY,OAAO,SAAS,GAAG,eAAe,GACvE,KAAK,MAAM,GAAG,eAAe,GAC7B;MACN,SACE,GAAG,YAAY,SAAS,GAAG,YAAY,WAAW,GAAG,YAAY,cAC7D,GAAG,UACH;MACN,eACE,GAAG,kBAAkB,iBAAiB,GAAG,kBAAkB,gBAAgB,GAAG,gBAAgB;MAChG,QAAQ,OAAO,GAAG,WAAW,YAAY,GAAG,OAAO,MAAM,GAAG,GAAG,OAAO,MAAM,GAAG;MAC/E,WAAW,GAAG,aAAa,OAAO,GAAG,cAAc,YAAY,CAAC,MAAM,QAAQ,GAAG,UAAU,GACvF,GAAG,YACH;MACJ,cACE,GAAG,iBAAiB,kBACpB,GAAG,iBAAiB,iBACpB,GAAG,iBAAiB,iBAChB,GAAG,eACH;MACN,sBACE,OAAO,GAAG,yBAAyB,YAAY,OAAO,SAAS,GAAG,qBAAqB,GACnF,KAAK,MAAM,GAAG,qBAAqB,GACnC;MACP;QACC;IACJ,mBAAmB,OAAO,QAAQ,UAAU;IAC5C,oBAAoB,OAAO,QAAQ,UAAU;IAC7C,wBAAwB,OAAO,QAAQ,UAAU;IACjD,YAAY,OAAO,QAAQ,UAAU;IACrC,SAAS,OAAO,QAAQ,UAAU;IAClC,QAAQ,OAAO,QAAQ,UAAU;IACjC,eAAe,OAAO,QAAQ,UAAU;IACxC,kBAAkB,OAAO,QAAQ,UAAU;IAC3C,YAAY,OAAO,QAAQ,UAAU;IACrC,UAAU,OAAO,QAAQ,UAAU;IACnC,aAAa,OAAO,QAAQ,UAAU;IACtC,sBAAsB,OAAO,QAAQ,UAAU;IAC/C,QAAQ,OAAO,QAAQ,UAAU;IACjC,OAAO,OAAO,QAAQ,UAAU;IAChC,QAAQ,OAAO,QAAQ,UAAU;IAClC;GACF;EACD,UAAU;EACV,WAAW,OAAO,YAChB,MAAM,QAAQ,IACZ,iBAAiB,CAAC,IAAI,OAAO,aAAa,CACxC,UACC,MAAM,qBAAqB,SAAS,GAAI,QAAQ,GAClD,CAAC,CACH,CACF;;EAED,iBAAiB,+BAA+B,OAAO,UAAU;EACjE,SAAS;GACP,MAAM,OAAO,SAAS;GACtB,MAAM,OAAO,SAAS;GACtB,aAAa,MAAM,QAAQ,OAAO,SAAS,YAAY,GAAG,OAAO,QAAQ,cAAc,EAAE;GACzF,MAAM;IACJ,MAAM,OAAO,SAAS,MAAM,QAAQ;IACpC,OAAO,OAAO,SAAS,MAAM,SAAS;IACtC,UAAU,OAAO,SAAS,MAAM,WAAW,iBAAiB;IAC5D,WAAW;KACT,SAAS,OAAO,SAAS,MAAM,WAAW,YAAY;KACtD,aACE,OAAO,OAAO,SAAS,MAAM,WAAW,gBAAgB,WACpD,OAAO,QAAQ,KAAK,UAAU,cAC9B;KACN,UACE,OAAO,OAAO,SAAS,MAAM,WAAW,aAAa,WACjD,OAAO,QAAQ,KAAK,UAAU,WAC9B;KACN,iBACE,OAAO,OAAO,SAAS,MAAM,WAAW,oBAAoB,WACxD,OAAO,QAAQ,KAAK,UAAU,kBAC9B;KACP;IACF;GACD,WAAW;IACT,SAAS,OAAO,SAAS,WAAW;IACpC,YAAY,OAAO,SAAS,WAAW;IACvC,4BAA4B,OAAO,SAAS,WAAW,+BAA+B;IACtF,QAAQ,OAAO,SAAS,WAAW;IACnC,cAAc,OAAO,SAAS,WAAW;IACzC,QAAQ,OAAO,SAAS,WAAW;IACnC,aAAa,OAAO,SAAS,WAAW;IACxC,iBAAiB,OAAO,SAAS,WAAW;IAC5C,aAAa,OAAO,SAAS,WAAW;IACzC;GACD,mBACE,OAAO,OAAO,SAAS,sBAAsB,WACzC,OAAO,QAAQ,oBACf;GACN,yBAAyB,OAAO,SAAS,2BAA2B;GACpE,wBAAwB,MAAM,QAAQ,OAAO,SAAS,uBAAuB,GACzE,OAAO,QAAQ,yBACf,EAAE;GACN,4BAA4B,MAAM,QAAQ,OAAO,SAAS,2BAA2B,GACjF,OAAO,QAAQ,6BACf,EAAE;GACP;EACD,MAAM,EAAE,SAAS,OAAO,MAAM,SAAS;EACvC,QAAQ;GACN,SAAS,OAAO,QAAQ,YAAY;GACpC,WAAW,OAAO,QAAQ,cAAc;GACxC,WAAW,OAAO,QAAQ,aAAa;GACvC,SAAS,OAAO,QAAQ,UACpB;IACE,SAAS,OAAO,OAAO,QAAQ;IAC/B,YAAY,OAAO,OAAO,QAAQ;IACnC,GACD,KAAA;GACJ,KAAK;IACH,SAAS,OAAO,QAAQ,KAAK,WAAW;IACxC,SAAS,OAAO,QAAQ,KAAK,WAAW;IACxC,SAAS,OAAO,QAAQ,KAAK,WAAW;IACzC;GACF;EACD,QAAQ,EACN,SAAS,OAAO,QAAQ,WAAW,UACpC;EACD,KAAK,OAAO,OAAO,OAAO;EAC1B,KAAK,OAAO,UAAU;EACtB,OAAO,mBAAmB,OAAO;EACjC,UAAU,MAAM,QAAQ,OAAO,SAAS,GAAG,OAAO,WAAW,EAAE;EAC/D,KAAK,yBAAyB,OAAO;EACtC"}
1
+ {"version":3,"file":"config-payload.js","names":[],"sources":["../../../../../src/gateway/hono/lib/config-payload.ts"],"sourcesContent":["import {\n listAgentEntries,\n normalizeAgentId,\n resolveDefaultAgentId,\n} from '../../../agent/agent-scope.js';\nimport {\n listChannelPlugins,\n syncChannelPluginsFromManager,\n} from '../../../channels/plugins/registry.js';\nimport { normalizeConfiguredMcpServers } from '../../../config/mcp-config-normalize.js';\nimport type { Config } from '../../../config/schema.js';\nimport { resolveTunnelE2eConfig } from '../../../tunnel/tunnel-e2e-config.js';\nimport { bundledChannelPlugins } from '../../../generated/bundled-channel-plugins.js';\nimport { getAllProviders, isProviderConfigured } from '../../../providers/index.js';\nimport type { GatewayService } from '../../service.js';\nimport { safeToolsWebForGet } from '../../config-tools-web.js';\nimport {\n agentImageGenerationModelAutoProviderFallback,\n agentImageGenerationModelTimeoutMs,\n agentModelFallbacksToArray,\n agentModelRefToString,\n} from './agent-model.js';\nimport { buildSafeProvidersConfigForWeb } from './safe-providers-config.js';\n\n/** MCP block for GET/PATCH `/api/config` (authenticated console editing). */\nexport function buildSafeMcpConfigForWeb(config: Config) {\n const mcp = config.mcp;\n if (!mcp) {\n return { servers: {} as Record<string, Record<string, unknown>> };\n }\n return {\n ...(mcp.sessionIdleTtlMs !== undefined ? { sessionIdleTtlMs: mcp.sessionIdleTtlMs } : {}),\n servers: normalizeConfiguredMcpServers(mcp.servers),\n };\n}\n\n/** Sanitized config snapshot for GET/PATCH `/api/config` (matches persisted `service.currentConfig`). */\nexport async function buildSafeWebConfigPayload(service: GatewayService) {\n const config = service.currentConfig;\n if (listChannelPlugins().length === 0) {\n syncChannelPluginsFromManager(bundledChannelPlugins);\n }\n const channelsPayload = Object.fromEntries(\n listChannelPlugins().map((plugin) => {\n if (plugin.configSurface) {\n return [plugin.id, plugin.configSurface.buildConfigSurface(config)];\n }\n const channelCfg = config.channels?.[plugin.id] as Record<string, unknown> | undefined;\n return [\n plugin.id,\n {\n enabled: channelCfg?.enabled ?? false,\n configured: plugin.config.listAccountIds(config).length > 0,\n },\n ];\n }),\n );\n return {\n agents: {\n defaultId: resolveDefaultAgentId(config),\n list: listAgentEntries(config)\n .filter((e) => e.enabled !== false)\n .map((e) => ({\n id: normalizeAgentId(e.id),\n ...(typeof e.name === 'string' && e.name.trim() ? { name: e.name.trim() } : {}),\n })),\n defaults: {\n model: agentModelRefToString(config.agents?.defaults?.model) ?? '',\n modelFallbacks: agentModelFallbacksToArray(config.agents?.defaults?.model),\n imageModel: agentModelRefToString(config.agents?.defaults?.imageModel) ?? null,\n imageModelFallbacks: agentModelFallbacksToArray(config.agents?.defaults?.imageModel),\n imageGenerationModel: agentModelRefToString(config.agents?.defaults?.imageGenerationModel) ?? null,\n imageGenerationModelFallbacks: agentModelFallbacksToArray(\n config.agents?.defaults?.imageGenerationModel,\n ),\n imageGenerationModelTimeoutMs: agentImageGenerationModelTimeoutMs(\n config.agents?.defaults?.imageGenerationModel,\n ),\n imageGenerationModelAutoProviderFallback: agentImageGenerationModelAutoProviderFallback(\n config.agents?.defaults?.imageGenerationModel,\n ),\n mediaMaxMb: config.agents?.defaults?.mediaMaxMb,\n maxTokens: config.agents?.defaults?.maxTokens,\n temperature: config.agents?.defaults?.temperature,\n maxToolIterations: config.agents?.defaults?.maxToolIterations,\n workspace: config.agents?.defaults?.workspace,\n thinkingDefault: config.agents?.defaults?.thinkingDefault,\n reasoningDefault: config.agents?.defaults?.reasoningDefault,\n verboseDefault: config.agents?.defaults?.verboseDefault,\n browser: (() => {\n const br = config.agents?.defaults?.browser;\n if (!br || typeof br !== 'object') {\n return {\n enabled: false,\n headless: false,\n allowPrivateUrls: false,\n commandTimeout: null,\n cloudProvider: null,\n cdpUrl: null,\n dialogPolicy: null,\n dialogTimeoutSeconds: null,\n };\n }\n return {\n enabled: br.enabled === true,\n headless: br.headless === true,\n allowPrivateUrls: br.allowPrivateUrls === true,\n commandTimeout:\n typeof br.commandTimeout === 'number' && Number.isFinite(br.commandTimeout)\n ? Math.floor(br.commandTimeout)\n : null,\n backend:\n br.backend === 'cdp' || br.backend === 'cloud' || br.backend === 'extension'\n ? br.backend\n : null,\n cloudProvider:\n br.cloudProvider === 'browserbase' || br.cloudProvider === 'browser-use' ? br.cloudProvider : null,\n cdpUrl: typeof br.cdpUrl === 'string' && br.cdpUrl.trim() ? br.cdpUrl.trim() : null,\n extension: br.extension && typeof br.extension === 'object' && !Array.isArray(br.extension)\n ? br.extension\n : null,\n dialogPolicy:\n br.dialogPolicy === 'must_respond' ||\n br.dialogPolicy === 'auto_accept' ||\n br.dialogPolicy === 'auto_dismiss'\n ? br.dialogPolicy\n : null,\n dialogTimeoutSeconds:\n typeof br.dialogTimeoutSeconds === 'number' && Number.isFinite(br.dialogTimeoutSeconds)\n ? Math.floor(br.dialogTimeoutSeconds)\n : null,\n };\n })(),\n maxTaskDurationMs: config.agents?.defaults?.maxTaskDurationMs,\n maxRequestsPerTurn: config.agents?.defaults?.maxRequestsPerTurn,\n maxToolFailuresPerTurn: config.agents?.defaults?.maxToolFailuresPerTurn,\n compaction: config.agents?.defaults?.compaction,\n pruning: config.agents?.defaults?.pruning,\n memory: config.agents?.defaults?.memory,\n sessionSearch: config.agents?.defaults?.sessionSearch,\n backgroundReview: config.agents?.defaults?.backgroundReview,\n webExtract: config.agents?.defaults?.webExtract,\n delegate: config.agents?.defaults?.delegate,\n executeCode: config.agents?.defaults?.executeCode,\n systemPromptOverride: config.agents?.defaults?.systemPromptOverride,\n skills: config.agents?.defaults?.skills,\n tools: config.agents?.defaults?.tools,\n params: config.agents?.defaults?.params,\n },\n },\n channels: channelsPayload,\n providers: Object.fromEntries(\n await Promise.all(\n getAllProviders().map(async (provider) => [\n provider,\n (await isProviderConfigured(provider)) ? '***' : '',\n ]),\n ),\n ),\n /** Masked `cfg.providers` for capability keys (image / STT / etc.). */\n providersConfig: buildSafeProvidersConfigForWeb(config.providers),\n gateway: {\n host: config.gateway?.host,\n port: config.gateway?.port,\n corsOrigins: Array.isArray(config.gateway?.corsOrigins) ? config.gateway.corsOrigins : [],\n auth: {\n mode: config.gateway?.auth?.mode || 'token',\n token: config.gateway?.auth?.token || '',\n password: config.gateway?.auth?.password ? '••••••••••••' : '',\n rateLimit: {\n enabled: config.gateway?.auth?.rateLimit?.enabled !== false,\n maxAttempts:\n typeof config.gateway?.auth?.rateLimit?.maxAttempts === 'number'\n ? config.gateway.auth.rateLimit.maxAttempts\n : 5,\n windowMs:\n typeof config.gateway?.auth?.rateLimit?.windowMs === 'number'\n ? config.gateway.auth.rateLimit.windowMs\n : 900_000,\n blockDurationMs:\n typeof config.gateway?.auth?.rateLimit?.blockDurationMs === 'number'\n ? config.gateway.auth.rateLimit.blockDurationMs\n : 300_000,\n },\n },\n heartbeat: {\n enabled: config.gateway?.heartbeat?.enabled,\n intervalMs: config.gateway?.heartbeat?.intervalMs,\n includeSystemPromptSection: config.gateway?.heartbeat?.includeSystemPromptSection === true,\n target: config.gateway?.heartbeat?.target,\n targetChatId: config.gateway?.heartbeat?.targetChatId,\n prompt: config.gateway?.heartbeat?.prompt,\n ackMaxChars: config.gateway?.heartbeat?.ackMaxChars,\n isolatedSession: config.gateway?.heartbeat?.isolatedSession,\n activeHours: config.gateway?.heartbeat?.activeHours,\n },\n maxSseConnections:\n typeof config.gateway?.maxSseConnections === 'number'\n ? config.gateway.maxSseConnections\n : 100,\n channelConnectDeferMode: config.gateway?.channelConnectDeferMode ?? 'auto',\n channelConnectDeferIds: Array.isArray(config.gateway?.channelConnectDeferIds)\n ? config.gateway.channelConnectDeferIds\n : [],\n channelConnectDeferSkipIds: Array.isArray(config.gateway?.channelConnectDeferSkipIds)\n ? config.gateway.channelConnectDeferSkipIds\n : [],\n },\n cron: { enabled: config.cron?.enabled },\n tunnel: {\n enabled: config.tunnel?.enabled === true,\n autoStart: config.tunnel?.autoStart === true,\n brokerUrl: config.tunnel?.brokerUrl ?? 'https://frp.xopc.ai/api',\n registrationSecret: config.tunnel?.registrationSecret ? '••••••••••••' : '',\n consent: config.tunnel?.consent\n ? {\n version: config.tunnel.consent.version,\n acceptedAt: config.tunnel.consent.acceptedAt,\n }\n : undefined,\n e2e: resolveTunnelE2eConfig(config.tunnel, config.gateway?.port ?? 18790),\n },\n update: {\n channel: config.update?.channel ?? 'stable',\n },\n stt: config.tools?.media?.audio,\n tts: config.messages?.tts,\n tools: safeToolsWebForGet(config),\n bindings: Array.isArray(config.bindings) ? config.bindings : [],\n mcp: buildSafeMcpConfigForWeb(config),\n };\n}\n"],"mappings":"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"}
@@ -2,21 +2,25 @@ import { getClientIpFromHeaders } from "../../auth-rate-limit.js";
2
2
  import { extractToken } from "../../auth.js";
3
3
  import { TUNNEL_CONSENT_REQUIRED_CODE, TunnelConsentError, assertTunnelMayStart, getTunnelConsentState } from "../../../tunnel/consent.js";
4
4
  import { getCertStatusSummary } from "../../../tunnel/acme-cert-store.js";
5
+ import { getTunnelRegistrationSecretMeta, resolveTunnelBrokerUrl } from "../../../tunnel/env.js";
5
6
  import { consumePairingSecret, createPairingSecret } from "../../../tunnel/pairing.js";
6
7
  import { loadTunnelState } from "../../../tunnel/tunnel-state.js";
7
8
  import { logTunnelAudit } from "../../../tunnel/tunnel-audit.js";
8
9
  import { getTunnelService, hashGatewayToken } from "../../../tunnel/tunnel-service.js";
10
+ import { resolveTunnelE2eConfig } from "../../../tunnel/tunnel-e2e-config.js";
9
11
  import { configureTunnelFromGatewayConfig } from "../../../tunnel/gateway-lifecycle.js";
10
12
  import { applyTunnelConsentToConfig, setTunnelEnabledInConfig } from "../../../tunnel/tunnel-config.js";
11
13
  import { consumeTunnelMutationLimit } from "../../../tunnel/tunnel-rate-limit.js";
12
14
  import "../../../tunnel/index.js";
13
15
  import { consumePairingExchangeFailLimit } from "../../../tunnel/pairing-rate-limit.js";
14
16
  //#region src/gateway/hono/routes/tunnel.ts
15
- async function configureTunnelFromService(deps) {
16
- await configureTunnelFromGatewayConfig(deps.service.currentConfig);
17
+ async function configureTunnelFromService(deps, opts) {
18
+ await configureTunnelFromGatewayConfig(deps.service.currentConfig, opts);
17
19
  }
18
20
  function enrichTunnelStatus(config, status) {
19
21
  const consent = getTunnelConsentState(config);
22
+ const brokerUrl = resolveTunnelBrokerUrl(config.tunnel?.brokerUrl);
23
+ const registrationSecret = getTunnelRegistrationSecretMeta(config, process.env, brokerUrl);
20
24
  return {
21
25
  ...status,
22
26
  consentRequired: consent.consentRequired,
@@ -26,7 +30,8 @@ function enrichTunnelStatus(config, status) {
26
30
  acceptedAt: consent.acceptedAt,
27
31
  valid: consent.valid
28
32
  },
29
- canAutoStart: consent.canAutoStart
33
+ canAutoStart: consent.canAutoStart,
34
+ registrationSecret
30
35
  };
31
36
  }
32
37
  function requireGatewayToken(c) {
@@ -141,7 +146,7 @@ function registerTunnelRoutes(authenticated, deps) {
141
146
  });
142
147
  });
143
148
  authenticated.post("/api/tunnel/start", tunnelMutationLimit, async (c) => {
144
- await configureTunnelFromService(deps);
149
+ await configureTunnelFromService(deps, { force: true });
145
150
  const config = deps.service.currentConfig;
146
151
  const token = requireGatewayToken(c);
147
152
  if (!token) return c.json({ error: "Gateway token required" }, 401);
@@ -207,14 +212,11 @@ function registerTunnelRoutes(authenticated, deps) {
207
212
  await configureTunnelFromService(deps);
208
213
  const config = deps.service.currentConfig;
209
214
  const cert = getCertStatusSummary();
210
- const e2e = config.tunnel?.e2e;
215
+ const gatewayPort = config.gateway?.port ?? 18790;
216
+ const e2e = resolveTunnelE2eConfig(config.tunnel, gatewayPort);
211
217
  return c.json({
212
218
  ...cert,
213
- e2e: {
214
- enabled: e2e?.enabled ?? true,
215
- tlsPort: e2e?.tlsPort ?? 18791,
216
- staging: e2e?.staging ?? false
217
- }
219
+ e2e
218
220
  });
219
221
  });
220
222
  }
@@ -1 +1 @@
1
- {"version":3,"file":"tunnel.js","names":[],"sources":["../../../../../src/gateway/hono/routes/tunnel.ts"],"sourcesContent":["import type { Hono, MiddlewareHandler } from 'hono';\n\nimport type { Config } from '../../../config/schema.js';\nimport { extractToken } from '../../auth.js';\nimport {\n assertTunnelMayStart,\n getTunnelConsentState,\n TUNNEL_CONSENT_REQUIRED_CODE,\n TunnelConsentError,\n} from '../../../tunnel/consent.js';\nimport { hashGatewayToken } from '../../../tunnel/tunnel-service.js';\nimport { configureTunnelFromGatewayConfig } from '../../../tunnel/gateway-lifecycle.js';\nimport { getTunnelService } from '../../../tunnel/index.js';\nimport { getCertStatusSummary } from '../../../tunnel/acme-cert-store.js';\nimport { createPairingSecret, consumePairingSecret } from '../../../tunnel/pairing.js';\nimport { consumePairingExchangeFailLimit } from '../../../tunnel/pairing-rate-limit.js';\nimport { loadTunnelState } from '../../../tunnel/tunnel-state.js';\nimport { logTunnelAudit } from '../../../tunnel/tunnel-audit.js';\nimport {\n applyTunnelConsentToConfig,\n setTunnelEnabledInConfig,\n} from '../../../tunnel/tunnel-config.js';\nimport { consumeTunnelMutationLimit } from '../../../tunnel/tunnel-rate-limit.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\nimport type { GatewayService } from '../../service.js';\nimport { getClientIpFromHeaders } from '../../auth-rate-limit.js';\n\nasync function configureTunnelFromService(deps: AuthenticatedRouteDeps): Promise<void> {\n await configureTunnelFromGatewayConfig(deps.service.currentConfig);\n}\n\nfunction enrichTunnelStatus(config: Config, status: ReturnType<ReturnType<typeof getTunnelService>['getStatus']>) {\n const consent = getTunnelConsentState(config);\n return {\n ...status,\n consentRequired: consent.consentRequired,\n consent: {\n currentVersion: consent.currentVersion,\n acceptedVersion: consent.acceptedVersion,\n acceptedAt: consent.acceptedAt,\n valid: consent.valid,\n },\n canAutoStart: consent.canAutoStart,\n };\n}\n\nfunction requireGatewayToken(c: { req: { header: (name: string) => string | undefined } }): string | null {\n return (\n extractToken({\n authorization: c.req.header('authorization') ?? undefined,\n }) ?? null\n );\n}\n\nfunction createTunnelMutationRateLimitMiddleware(): MiddlewareHandler {\n return async (c, next) => {\n const token = requireGatewayToken(c);\n if (!token) {\n return c.json({ error: 'Gateway token required' }, 401);\n }\n const result = consumeTunnelMutationLimit(token);\n if (!result.allowed) {\n c.header('Retry-After', String(Math.ceil(result.retryAfterMs / 1000)));\n return c.json(\n {\n error: 'Too many tunnel operations. Try again later.',\n code: 'TUNNEL_RATE_LIMITED',\n retryAfterMs: result.retryAfterMs,\n },\n 429,\n );\n }\n await next();\n };\n}\n\nexport function registerTunnelPublicRoutes(app: Hono, service: GatewayService): void {\n app.post('/api/tunnel/exchange-token', async (c) => {\n const clientIp =\n getClientIpFromHeaders({\n get: (name: string) => c.req.header(name) ?? undefined,\n }) ?? 'unknown';\n\n let body: { pairingSecret?: unknown };\n try {\n body = (await c.req.json()) as { pairingSecret?: unknown };\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n\n const pairingSecret = typeof body.pairingSecret === 'string' ? body.pairingSecret.trim() : '';\n if (!pairingSecret) {\n return c.json({ error: 'pairingSecret required' }, 400);\n }\n\n if (!consumePairingSecret(pairingSecret)) {\n const limited = consumePairingExchangeFailLimit(clientIp);\n if (!limited.allowed) {\n c.header('Retry-After', String(Math.ceil(limited.retryAfterMs / 1000)));\n }\n logTunnelAudit(\n 'tunnel.exchange_token',\n { ok: false, clientIp, phase: 'pairing_exchange' },\n 'Pairing exchange denied: invalid or expired secret',\n );\n return c.json({ error: 'Invalid or expired pairing secret', code: 'PAIRING_INVALID' }, 401);\n }\n\n const token = service.getAuthToken();\n if (!token) {\n return c.json({ error: 'Gateway token not configured' }, 500);\n }\n\n const persisted = loadTunnelState();\n const gateway = service.currentConfig.gateway;\n const host = gateway.host ?? '127.0.0.1';\n const port = gateway.port ?? 18790;\n const lanHost = host === '0.0.0.0' || host === '::' ? '127.0.0.1' : host;\n const lanUrl =\n lanHost === '127.0.0.1' || lanHost === 'localhost' ? null : `http://${lanHost}:${port}`.replace(/\\/+$/, '');\n\n logTunnelAudit(\n 'tunnel.exchange_token',\n { ok: true, clientIp, subdomain: persisted?.subdomain ?? null, phase: 'pairing_exchange' },\n 'Pairing secret exchanged for gateway token',\n );\n\n return c.json({\n token,\n baseUrl: persisted?.publicUrl ?? null,\n lanUrl,\n });\n });\n}\n\nexport function registerTunnelRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const tunnel = getTunnelService();\n const tunnelMutationLimit = createTunnelMutationRateLimitMiddleware();\n\n authenticated.post('/api/tunnel/pair', tunnelMutationLimit, async (c) => {\n await configureTunnelFromService(deps);\n const token = requireGatewayToken(c);\n if (!token) return c.json({ error: 'Gateway token required' }, 401);\n\n const { secret, expiresAt } = createPairingSecret();\n logTunnelAudit(\n 'tunnel.pair',\n {\n expiresAt: expiresAt.toISOString(),\n gatewayTokenHash: hashGatewayToken(token).slice(0, 12),\n },\n 'Mobile pairing session created',\n );\n return c.json({ pairingSecret: secret, expiresAt: expiresAt.toISOString() });\n });\n\n authenticated.get('/api/tunnel/status', async (c) => {\n await configureTunnelFromService(deps);\n const config = deps.service.currentConfig as Config;\n return c.json(enrichTunnelStatus(config, tunnel.getStatus()));\n });\n\n authenticated.post('/api/tunnel/consent', tunnelMutationLimit, async (c) => {\n const token = requireGatewayToken(c);\n if (!token) return c.json({ error: 'Gateway token required' }, 401);\n\n const config = deps.service.currentConfig as Config;\n applyTunnelConsentToConfig(config);\n const result = await deps.service.saveConfig(config);\n if (!result.saved) {\n return c.json({ ok: false, error: result.error ?? 'Failed to save config' }, 500);\n }\n const consent = getTunnelConsentState(config);\n logTunnelAudit(\n 'tunnel.consent',\n {\n consentVersion: consent.currentVersion,\n gatewayTokenHash: hashGatewayToken(token).slice(0, 12),\n },\n 'Remote access security consent recorded',\n );\n return c.json({\n ok: true,\n consent: {\n currentVersion: consent.currentVersion,\n acceptedVersion: consent.acceptedVersion,\n acceptedAt: consent.acceptedAt,\n valid: consent.valid,\n },\n });\n });\n\n authenticated.post('/api/tunnel/start', tunnelMutationLimit, async (c) => {\n await configureTunnelFromService(deps);\n const config = deps.service.currentConfig as Config;\n const token = requireGatewayToken(c);\n if (!token) return c.json({ error: 'Gateway token required' }, 401);\n\n try {\n assertTunnelMayStart(config);\n } catch (err) {\n if (err instanceof TunnelConsentError) {\n logTunnelAudit(\n 'tunnel.start_denied',\n { reason: TUNNEL_CONSENT_REQUIRED_CODE, gatewayTokenHash: hashGatewayToken(token).slice(0, 12) },\n 'Tunnel start denied: consent required',\n );\n return c.json({ error: err.message, code: TUNNEL_CONSENT_REQUIRED_CODE }, 403);\n }\n throw err;\n }\n\n const gateway = config.gateway;\n const port = gateway.port ?? 18790;\n try {\n const qr = await tunnel.start(port, token);\n setTunnelEnabledInConfig(config, true);\n await deps.service.saveConfig(config);\n const status = tunnel.getStatus();\n return c.json({\n publicUrl: qr.publicUrl,\n subdomain: status.subdomain,\n qrPayload: qr.qrPayload,\n lanUrl: qr.lanUrl,\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return c.json({ error: message }, 500);\n }\n });\n\n authenticated.post('/api/tunnel/stop', tunnelMutationLimit, async (c) => {\n await configureTunnelFromService(deps);\n const config = deps.service.currentConfig as Config;\n let release = false;\n try {\n const body = (await c.req.json().catch(() => ({}))) as { release?: unknown };\n release = body.release === true;\n } catch {\n release = false;\n }\n const { released } = await tunnel.stop({ release });\n setTunnelEnabledInConfig(config, false);\n await deps.service.saveConfig(config);\n return c.json({ ok: true, released });\n });\n\n authenticated.get('/api/tunnel/qr', async (c) => {\n await configureTunnelFromService(deps);\n const gateway = deps.service.currentConfig.gateway;\n const port = gateway.port ?? 18790;\n const host = gateway.host ?? '127.0.0.1';\n const token = requireGatewayToken(c);\n if (!token) return c.json({ error: 'Gateway token required' }, 401);\n const qr = tunnel.buildQr(port, host);\n return c.json(qr);\n });\n\n authenticated.get('/api/tunnel/cert-status', async (c) => {\n await configureTunnelFromService(deps);\n const config = deps.service.currentConfig as Config;\n const cert = getCertStatusSummary();\n const e2e = config.tunnel?.e2e;\n return c.json({\n ...cert,\n e2e: {\n enabled: e2e?.enabled ?? true,\n tlsPort: e2e?.tlsPort ?? 18791,\n staging: e2e?.staging ?? false,\n },\n });\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"tunnel.js","names":[],"sources":["../../../../../src/gateway/hono/routes/tunnel.ts"],"sourcesContent":["import type { Hono, MiddlewareHandler } from 'hono';\n\nimport { resolveTunnelE2eConfig } from '../../../tunnel/tunnel-e2e-config.js';\nimport type { Config } from '../../../config/schema.js';\nimport { extractToken } from '../../auth.js';\nimport {\n assertTunnelMayStart,\n getTunnelConsentState,\n TUNNEL_CONSENT_REQUIRED_CODE,\n TunnelConsentError,\n} from '../../../tunnel/consent.js';\nimport { hashGatewayToken } from '../../../tunnel/tunnel-service.js';\nimport { configureTunnelFromGatewayConfig } from '../../../tunnel/gateway-lifecycle.js';\nimport { getTunnelRegistrationSecretMeta, resolveTunnelBrokerUrl } from '../../../tunnel/env.js';\nimport { getTunnelService } from '../../../tunnel/index.js';\nimport { getCertStatusSummary } from '../../../tunnel/acme-cert-store.js';\nimport { createPairingSecret, consumePairingSecret } from '../../../tunnel/pairing.js';\nimport { consumePairingExchangeFailLimit } from '../../../tunnel/pairing-rate-limit.js';\nimport { loadTunnelState } from '../../../tunnel/tunnel-state.js';\nimport { logTunnelAudit } from '../../../tunnel/tunnel-audit.js';\nimport {\n applyTunnelConsentToConfig,\n setTunnelEnabledInConfig,\n} from '../../../tunnel/tunnel-config.js';\nimport { consumeTunnelMutationLimit } from '../../../tunnel/tunnel-rate-limit.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\nimport type { GatewayService } from '../../service.js';\nimport { getClientIpFromHeaders } from '../../auth-rate-limit.js';\n\nasync function configureTunnelFromService(\n deps: AuthenticatedRouteDeps,\n opts?: { force?: boolean },\n): Promise<void> {\n await configureTunnelFromGatewayConfig(deps.service.currentConfig, opts);\n}\n\nfunction enrichTunnelStatus(config: Config, status: ReturnType<ReturnType<typeof getTunnelService>['getStatus']>) {\n const consent = getTunnelConsentState(config);\n const brokerUrl = resolveTunnelBrokerUrl(config.tunnel?.brokerUrl);\n const registrationSecret = getTunnelRegistrationSecretMeta(config, process.env, brokerUrl);\n return {\n ...status,\n consentRequired: consent.consentRequired,\n consent: {\n currentVersion: consent.currentVersion,\n acceptedVersion: consent.acceptedVersion,\n acceptedAt: consent.acceptedAt,\n valid: consent.valid,\n },\n canAutoStart: consent.canAutoStart,\n registrationSecret,\n };\n}\n\nfunction requireGatewayToken(c: { req: { header: (name: string) => string | undefined } }): string | null {\n return (\n extractToken({\n authorization: c.req.header('authorization') ?? undefined,\n }) ?? null\n );\n}\n\nfunction createTunnelMutationRateLimitMiddleware(): MiddlewareHandler {\n return async (c, next) => {\n const token = requireGatewayToken(c);\n if (!token) {\n return c.json({ error: 'Gateway token required' }, 401);\n }\n const result = consumeTunnelMutationLimit(token);\n if (!result.allowed) {\n c.header('Retry-After', String(Math.ceil(result.retryAfterMs / 1000)));\n return c.json(\n {\n error: 'Too many tunnel operations. Try again later.',\n code: 'TUNNEL_RATE_LIMITED',\n retryAfterMs: result.retryAfterMs,\n },\n 429,\n );\n }\n await next();\n };\n}\n\nexport function registerTunnelPublicRoutes(app: Hono, service: GatewayService): void {\n app.post('/api/tunnel/exchange-token', async (c) => {\n const clientIp =\n getClientIpFromHeaders({\n get: (name: string) => c.req.header(name) ?? undefined,\n }) ?? 'unknown';\n\n let body: { pairingSecret?: unknown };\n try {\n body = (await c.req.json()) as { pairingSecret?: unknown };\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n\n const pairingSecret = typeof body.pairingSecret === 'string' ? body.pairingSecret.trim() : '';\n if (!pairingSecret) {\n return c.json({ error: 'pairingSecret required' }, 400);\n }\n\n if (!consumePairingSecret(pairingSecret)) {\n const limited = consumePairingExchangeFailLimit(clientIp);\n if (!limited.allowed) {\n c.header('Retry-After', String(Math.ceil(limited.retryAfterMs / 1000)));\n }\n logTunnelAudit(\n 'tunnel.exchange_token',\n { ok: false, clientIp, phase: 'pairing_exchange' },\n 'Pairing exchange denied: invalid or expired secret',\n );\n return c.json({ error: 'Invalid or expired pairing secret', code: 'PAIRING_INVALID' }, 401);\n }\n\n const token = service.getAuthToken();\n if (!token) {\n return c.json({ error: 'Gateway token not configured' }, 500);\n }\n\n const persisted = loadTunnelState();\n const gateway = service.currentConfig.gateway;\n const host = gateway.host ?? '127.0.0.1';\n const port = gateway.port ?? 18790;\n const lanHost = host === '0.0.0.0' || host === '::' ? '127.0.0.1' : host;\n const lanUrl =\n lanHost === '127.0.0.1' || lanHost === 'localhost' ? null : `http://${lanHost}:${port}`.replace(/\\/+$/, '');\n\n logTunnelAudit(\n 'tunnel.exchange_token',\n { ok: true, clientIp, subdomain: persisted?.subdomain ?? null, phase: 'pairing_exchange' },\n 'Pairing secret exchanged for gateway token',\n );\n\n return c.json({\n token,\n baseUrl: persisted?.publicUrl ?? null,\n lanUrl,\n });\n });\n}\n\nexport function registerTunnelRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const tunnel = getTunnelService();\n const tunnelMutationLimit = createTunnelMutationRateLimitMiddleware();\n\n authenticated.post('/api/tunnel/pair', tunnelMutationLimit, async (c) => {\n await configureTunnelFromService(deps);\n const token = requireGatewayToken(c);\n if (!token) return c.json({ error: 'Gateway token required' }, 401);\n\n const { secret, expiresAt } = createPairingSecret();\n logTunnelAudit(\n 'tunnel.pair',\n {\n expiresAt: expiresAt.toISOString(),\n gatewayTokenHash: hashGatewayToken(token).slice(0, 12),\n },\n 'Mobile pairing session created',\n );\n return c.json({ pairingSecret: secret, expiresAt: expiresAt.toISOString() });\n });\n\n authenticated.get('/api/tunnel/status', async (c) => {\n await configureTunnelFromService(deps);\n const config = deps.service.currentConfig as Config;\n return c.json(enrichTunnelStatus(config, tunnel.getStatus()));\n });\n\n authenticated.post('/api/tunnel/consent', tunnelMutationLimit, async (c) => {\n const token = requireGatewayToken(c);\n if (!token) return c.json({ error: 'Gateway token required' }, 401);\n\n const config = deps.service.currentConfig as Config;\n applyTunnelConsentToConfig(config);\n const result = await deps.service.saveConfig(config);\n if (!result.saved) {\n return c.json({ ok: false, error: result.error ?? 'Failed to save config' }, 500);\n }\n const consent = getTunnelConsentState(config);\n logTunnelAudit(\n 'tunnel.consent',\n {\n consentVersion: consent.currentVersion,\n gatewayTokenHash: hashGatewayToken(token).slice(0, 12),\n },\n 'Remote access security consent recorded',\n );\n return c.json({\n ok: true,\n consent: {\n currentVersion: consent.currentVersion,\n acceptedVersion: consent.acceptedVersion,\n acceptedAt: consent.acceptedAt,\n valid: consent.valid,\n },\n });\n });\n\n authenticated.post('/api/tunnel/start', tunnelMutationLimit, async (c) => {\n await configureTunnelFromService(deps, { force: true });\n const config = deps.service.currentConfig as Config;\n const token = requireGatewayToken(c);\n if (!token) return c.json({ error: 'Gateway token required' }, 401);\n\n try {\n assertTunnelMayStart(config);\n } catch (err) {\n if (err instanceof TunnelConsentError) {\n logTunnelAudit(\n 'tunnel.start_denied',\n { reason: TUNNEL_CONSENT_REQUIRED_CODE, gatewayTokenHash: hashGatewayToken(token).slice(0, 12) },\n 'Tunnel start denied: consent required',\n );\n return c.json({ error: err.message, code: TUNNEL_CONSENT_REQUIRED_CODE }, 403);\n }\n throw err;\n }\n\n const gateway = config.gateway;\n const port = gateway.port ?? 18790;\n try {\n const qr = await tunnel.start(port, token);\n setTunnelEnabledInConfig(config, true);\n await deps.service.saveConfig(config);\n const status = tunnel.getStatus();\n return c.json({\n publicUrl: qr.publicUrl,\n subdomain: status.subdomain,\n qrPayload: qr.qrPayload,\n lanUrl: qr.lanUrl,\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return c.json({ error: message }, 500);\n }\n });\n\n authenticated.post('/api/tunnel/stop', tunnelMutationLimit, async (c) => {\n await configureTunnelFromService(deps);\n const config = deps.service.currentConfig as Config;\n let release = false;\n try {\n const body = (await c.req.json().catch(() => ({}))) as { release?: unknown };\n release = body.release === true;\n } catch {\n release = false;\n }\n const { released } = await tunnel.stop({ release });\n setTunnelEnabledInConfig(config, false);\n await deps.service.saveConfig(config);\n return c.json({ ok: true, released });\n });\n\n authenticated.get('/api/tunnel/qr', async (c) => {\n await configureTunnelFromService(deps);\n const gateway = deps.service.currentConfig.gateway;\n const port = gateway.port ?? 18790;\n const host = gateway.host ?? '127.0.0.1';\n const token = requireGatewayToken(c);\n if (!token) return c.json({ error: 'Gateway token required' }, 401);\n const qr = tunnel.buildQr(port, host);\n return c.json(qr);\n });\n\n authenticated.get('/api/tunnel/cert-status', async (c) => {\n await configureTunnelFromService(deps);\n const config = deps.service.currentConfig as Config;\n const cert = getCertStatusSummary();\n const gatewayPort = config.gateway?.port ?? 18790;\n const e2e = resolveTunnelE2eConfig(config.tunnel, gatewayPort);\n return c.json({\n ...cert,\n e2e,\n });\n });\n}\n"],"mappings":"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"}