@mobvibe/cli 0.1.4 → 0.1.7

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.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/auth/login.ts","../src/lib/logger.ts","../src/auth/credentials.ts","../src/config.ts","../src/config-loader.ts","../src/daemon/daemon.ts","../src/acp/session-manager.ts","../../../packages/shared/dist/types/errors.js","../src/acp/acp-connection.ts","../src/daemon/socket-client.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { login, loginStatus, logout } from \"./auth/login.js\";\nimport { getCliConfig } from \"./config.js\";\nimport { DaemonManager } from \"./daemon/daemon.js\";\nimport { logger } from \"./lib/logger.js\";\n\nconst program = new Command();\n\nprogram\n\t.name(\"mobvibe\")\n\t.description(\"Mobvibe CLI - Connect local ACP backends to the gateway\")\n\t.version(\"0.0.0\");\n\nprogram\n\t.command(\"start\")\n\t.description(\"Start the mobvibe daemon\")\n\t.option(\"--gateway <url>\", \"Gateway URL\", process.env.MOBVIBE_GATEWAY_URL)\n\t.option(\"--foreground\", \"Run in foreground instead of detaching\")\n\t.action(async (options) => {\n\t\tif (options.gateway) {\n\t\t\tprocess.env.MOBVIBE_GATEWAY_URL = options.gateway;\n\t\t}\n\t\tconst config = await getCliConfig();\n\t\tconst daemon = new DaemonManager(config);\n\t\tawait daemon.start({ foreground: options.foreground });\n\t});\n\nprogram\n\t.command(\"stop\")\n\t.description(\"Stop the mobvibe daemon\")\n\t.action(async () => {\n\t\tconst config = await getCliConfig();\n\t\tconst daemon = new DaemonManager(config);\n\t\tawait daemon.stop();\n\t});\n\nprogram\n\t.command(\"status\")\n\t.description(\"Show daemon status\")\n\t.action(async () => {\n\t\tconst config = await getCliConfig();\n\t\tconst daemon = new DaemonManager(config);\n\t\tconst status = await daemon.status();\n\t\tif (status.running) {\n\t\t\tlogger.info({ pid: status.pid }, \"daemon_status_running\");\n\t\t\tconsole.log(`Daemon is running (PID ${status.pid})`);\n\t\t\tif (status.connected !== undefined) {\n\t\t\t\tconsole.log(`Connected to gateway: ${status.connected ? \"yes\" : \"no\"}`);\n\t\t\t}\n\t\t\tif (status.sessionCount !== undefined) {\n\t\t\t\tconsole.log(`Active sessions: ${status.sessionCount}`);\n\t\t\t}\n\t\t} else {\n\t\t\tlogger.info(\"daemon_status_not_running\");\n\t\t\tconsole.log(\"Daemon is not running\");\n\t\t}\n\t});\n\nprogram\n\t.command(\"logs\")\n\t.description(\"Show daemon logs\")\n\t.option(\"-f, --follow\", \"Follow log output\")\n\t.option(\"-n, --lines <number>\", \"Number of lines to show\", \"50\")\n\t.action(async (options) => {\n\t\tconst config = await getCliConfig();\n\t\tconst daemon = new DaemonManager(config);\n\t\tawait daemon.logs({\n\t\t\tfollow: options.follow,\n\t\t\tlines: Number.parseInt(options.lines, 10),\n\t\t});\n\t});\n\nprogram\n\t.command(\"login\")\n\t.description(\"Authenticate with an API key from the WebUI\")\n\t.action(async () => {\n\t\tconst result = await login();\n\t\tif (!result.success) {\n\t\t\tlogger.error({ err: result.error }, \"login_failed\");\n\t\t\tconsole.error(`Login failed: ${result.error}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command(\"logout\")\n\t.description(\"Remove stored credentials\")\n\t.action(async () => {\n\t\tawait logout();\n\t});\n\nprogram\n\t.command(\"auth-status\")\n\t.description(\"Show authentication status\")\n\t.action(async () => {\n\t\tawait loginStatus();\n\t});\n\nexport async function run() {\n\tawait program.parseAsync(process.argv);\n}\n\nrun().catch((error) => {\n\tlogger.error({ err: error }, \"cli_run_error\");\n\tconsole.error(\"Error:\", error.message);\n\tprocess.exit(1);\n});\n","/**\n * Login command for CLI authentication.\n * Prompts user to paste an API key generated from the WebUI.\n */\n\nimport * as readline from \"node:readline/promises\";\nimport { logger } from \"../lib/logger.js\";\nimport {\n\ttype Credentials,\n\tdeleteCredentials,\n\tloadCredentials,\n\tsaveCredentials,\n} from \"./credentials.js\";\n\nexport interface LoginResult {\n\tsuccess: boolean;\n\terror?: string;\n}\n\n/**\n * Start the login flow.\n * Prompts user to paste an API key from the WebUI.\n */\nexport async function login(): Promise<LoginResult> {\n\tlogger.info(\"login_prompt_start\");\n\tconsole.log(\"To get an API key:\");\n\tconsole.log(\" 1. Open the Mobvibe WebUI in your browser\");\n\tconsole.log(\" 2. Go to Settings (gear icon) -> API Keys\");\n\tconsole.log(\" 3. Click 'Create API Key' and copy it\");\n\tconsole.log(\" 4. Paste the API key below\\n\");\n\n\tconst rl = readline.createInterface({\n\t\tinput: process.stdin,\n\t\toutput: process.stdout,\n\t});\n\n\ttry {\n\t\tconst apiKey = await rl.question(\"Paste your API key: \");\n\n\t\tif (!apiKey.trim()) {\n\t\t\tlogger.warn(\"login_missing_api_key\");\n\t\t\treturn { success: false, error: \"No API key provided\" };\n\t\t}\n\n\t\t// Basic format check\n\t\tif (!apiKey.trim().startsWith(\"mbk_\")) {\n\t\t\tlogger.warn(\"login_invalid_api_key_format\");\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: \"Invalid API key format (should start with mbk_)\",\n\t\t\t};\n\t\t}\n\n\t\t// Store credentials - gateway validates on connection\n\t\tconst credentials: Credentials = {\n\t\t\tapiKey: apiKey.trim(),\n\t\t\tcreatedAt: Date.now(),\n\t\t};\n\t\tawait saveCredentials(credentials);\n\t\tlogger.info(\"login_credentials_saved\");\n\n\t\tconsole.log(\"\\nAPI key saved!\");\n\t\tconsole.log(\"Run 'mobvibe start' to connect to the gateway.\");\n\n\t\treturn { success: true };\n\t} finally {\n\t\trl.close();\n\t}\n}\n\n/**\n * Logout - delete stored credentials.\n */\nexport async function logout(): Promise<void> {\n\tawait deleteCredentials();\n\tlogger.info(\"logout_complete\");\n\tconsole.log(\"Logged out successfully. Credentials deleted.\");\n}\n\n/**\n * Show current login status.\n */\nexport async function loginStatus(): Promise<void> {\n\tconst credentials = await loadCredentials();\n\tif (credentials) {\n\t\tlogger.info(\"login_status_logged_in\");\n\t\tconsole.log(\"Status: Logged in\");\n\t\tconsole.log(`API key: ${credentials.apiKey.slice(0, 12)}...`);\n\t\tconsole.log(`Saved: ${new Date(credentials.createdAt).toLocaleString()}`);\n\t} else {\n\t\tlogger.info(\"login_status_logged_out\");\n\t\tconsole.log(\"Status: Not logged in\");\n\t\tconsole.log(\"Run 'mobvibe login' to authenticate.\");\n\t}\n}\n","import pino from \"pino\";\n\nconst LOG_LEVEL = process.env.LOG_LEVEL ?? \"info\";\nconst isPretty = process.env.NODE_ENV !== \"production\";\n\nconst redact = {\n\tpaths: [\n\t\t\"req.headers.authorization\",\n\t\t\"req.headers.cookie\",\n\t\t\"req.headers['x-api-key']\",\n\t\t\"headers.authorization\",\n\t\t\"headers.cookie\",\n\t\t\"headers['x-api-key']\",\n\t\t\"apiKey\",\n\t\t\"token\",\n\t],\n\tcensor: \"[redacted]\",\n};\n\nconst transport = isPretty\n\t? {\n\t\t\ttarget: \"pino-pretty\",\n\t\t\toptions: {\n\t\t\t\tcolorize: true,\n\t\t\t\ttranslateTime: \"SYS:standard\",\n\t\t\t\tignore: \"pid,hostname\",\n\t\t\t},\n\t\t}\n\t: undefined;\n\nexport const logger = pino(\n\t{\n\t\tlevel: LOG_LEVEL,\n\t\tredact,\n\t\tbase: { service: \"mobvibe-cli\" },\n\t\tserializers: {\n\t\t\terr: pino.stdSerializers.err,\n\t\t\terror: pino.stdSerializers.err,\n\t\t},\n\t},\n\ttransport ? pino.transport(transport) : undefined,\n);\n","/**\n * Credentials management for CLI authentication.\n * Stores API key in ~/.mobvibe/credentials.json\n */\n\nimport fs from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nexport interface Credentials {\n\t/** API key for gateway authentication */\n\tapiKey: string;\n\t/** When the credentials were created */\n\tcreatedAt: number;\n\t/** Optional: custom gateway URL (user can manually set this) */\n\tgatewayUrl?: string;\n}\n\nconst MOBVIBE_DIR =\n\tprocess.env.MOBVIBE_HOME ?? path.join(os.homedir(), \".mobvibe\");\nconst CREDENTIALS_FILE = path.join(MOBVIBE_DIR, \"credentials.json\");\n\n/**\n * Ensure the mobvibe directory exists.\n */\nasync function ensureMobvibeDir(): Promise<void> {\n\tawait fs.mkdir(MOBVIBE_DIR, { recursive: true });\n}\n\n/**\n * Load credentials from the credentials file.\n * Returns null if no credentials exist.\n */\nexport async function loadCredentials(): Promise<Credentials | null> {\n\ttry {\n\t\tconst data = await fs.readFile(CREDENTIALS_FILE, \"utf8\");\n\t\tconst credentials = JSON.parse(data) as Credentials;\n\n\t\t// Validate required fields\n\t\tif (!credentials.apiKey) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn credentials;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Save credentials to the credentials file.\n */\nexport async function saveCredentials(credentials: Credentials): Promise<void> {\n\tawait ensureMobvibeDir();\n\tawait fs.writeFile(\n\t\tCREDENTIALS_FILE,\n\t\tJSON.stringify(credentials, null, 2),\n\t\t{ mode: 0o600 }, // Read/write only for owner\n\t);\n}\n\n/**\n * Delete the credentials file.\n */\nexport async function deleteCredentials(): Promise<void> {\n\ttry {\n\t\tawait fs.unlink(CREDENTIALS_FILE);\n\t} catch {\n\t\t// Ignore if file doesn't exist\n\t}\n}\n\n/**\n * Check if credentials exist.\n */\nexport async function hasCredentials(): Promise<boolean> {\n\tconst credentials = await loadCredentials();\n\treturn credentials !== null;\n}\n\n/**\n * Get the API key from credentials.\n * Also checks MOBVIBE_API_KEY env var as override.\n */\nexport async function getApiKey(): Promise<string | undefined> {\n\t// Environment variable takes precedence\n\tif (process.env.MOBVIBE_API_KEY) {\n\t\treturn process.env.MOBVIBE_API_KEY;\n\t}\n\n\tconst credentials = await loadCredentials();\n\treturn credentials?.apiKey;\n}\n\n/** Default production gateway URL */\nconst DEFAULT_GATEWAY_URL = \"https://mobvibe.zeabur.app\";\n\n/**\n * Get the gateway URL with the following priority:\n * 1. MOBVIBE_GATEWAY_URL env var\n * 2. gatewayUrl in credentials file\n * 3. Default production URL\n */\nexport async function getGatewayUrl(): Promise<string> {\n\t// Environment variable takes precedence\n\tif (process.env.MOBVIBE_GATEWAY_URL) {\n\t\treturn process.env.MOBVIBE_GATEWAY_URL;\n\t}\n\n\t// Check credentials file for custom gateway URL\n\tconst credentials = await loadCredentials();\n\tif (credentials?.gatewayUrl) {\n\t\treturn credentials.gatewayUrl;\n\t}\n\n\t// Default to production\n\treturn DEFAULT_GATEWAY_URL;\n}\n","import os from \"node:os\";\nimport path from \"node:path\";\nimport type { AcpBackendId, UserAgentConfig } from \"@mobvibe/shared\";\nimport { getGatewayUrl } from \"./auth/credentials.js\";\nimport { loadUserConfig } from \"./config-loader.js\";\nimport { logger } from \"./lib/logger.js\";\n\nexport type AcpBackendConfig = {\n\tid: AcpBackendId;\n\tlabel: string;\n\tcommand: string;\n\targs: string[];\n\tenvOverrides?: Record<string, string>;\n};\n\nexport type CliConfig = {\n\tgatewayUrl: string;\n\tacpBackends: AcpBackendConfig[];\n\tdefaultAcpBackendId: AcpBackendId;\n\tclientName: string;\n\tclientVersion: string;\n\thomePath: string;\n\tlogPath: string;\n\tpidFile: string;\n\tmachineId: string;\n\thostname: string;\n\tplatform: string;\n\tuserConfigPath?: string;\n\tuserConfigErrors?: string[];\n};\n\n// Default opencode backend\nconst DEFAULT_OPENCODE_BACKEND: AcpBackendConfig = {\n\tid: \"opencode\",\n\tlabel: \"opencode\",\n\tcommand: \"opencode\",\n\targs: [\"acp\"],\n};\n\nconst generateMachineId = (): string => {\n\tconst hostname = os.hostname();\n\tconst platform = os.platform();\n\tconst arch = os.arch();\n\tconst username = os.userInfo().username;\n\treturn `${hostname}-${platform}-${arch}-${username}`;\n};\n\nconst userAgentToBackendConfig = (\n\tagent: UserAgentConfig,\n): AcpBackendConfig => ({\n\tid: agent.id,\n\tlabel: agent.label ?? agent.id,\n\tcommand: agent.command,\n\targs: agent.args ?? [],\n\tenvOverrides: agent.env,\n});\n\nconst mergeBackends = (\n\tdefaultBackend: AcpBackendConfig,\n\tuserAgents: UserAgentConfig[] | undefined,\n): { backends: AcpBackendConfig[]; defaultId: AcpBackendId } => {\n\t// No user agents: use default opencode only\n\tif (!userAgents || userAgents.length === 0) {\n\t\treturn { backends: [defaultBackend], defaultId: defaultBackend.id };\n\t}\n\n\t// Check if user defined opencode (override case)\n\tconst userOpencode = userAgents.find((a) => a.id === \"opencode\");\n\n\tif (userOpencode) {\n\t\t// User overrides opencode - use only user-defined agents\n\t\treturn {\n\t\t\tbackends: userAgents.map(userAgentToBackendConfig),\n\t\t\tdefaultId: userAgents[0].id,\n\t\t};\n\t}\n\n\t// User didn't define opencode - prepend default opencode to user agents\n\treturn {\n\t\tbackends: [defaultBackend, ...userAgents.map(userAgentToBackendConfig)],\n\t\tdefaultId: defaultBackend.id,\n\t};\n};\n\nexport const getCliConfig = async (): Promise<CliConfig> => {\n\tconst env = process.env;\n\tconst homePath = env.MOBVIBE_HOME ?? path.join(os.homedir(), \".mobvibe\");\n\n\t// Load user configuration\n\tconst userConfigResult = await loadUserConfig(homePath);\n\n\t// Log any config errors as warnings\n\tif (userConfigResult.errors.length > 0) {\n\t\tfor (const error of userConfigResult.errors) {\n\t\t\tlogger.warn({ configPath: userConfigResult.path, error }, \"config_error\");\n\t\t}\n\t}\n\n\t// Merge backends\n\tconst { backends, defaultId } = mergeBackends(\n\t\tDEFAULT_OPENCODE_BACKEND,\n\t\tuserConfigResult.config?.agents,\n\t);\n\n\t// Override default if user specified one\n\tconst resolvedDefaultId =\n\t\tuserConfigResult.config?.defaultAgentId &&\n\t\tbackends.some((b) => b.id === userConfigResult.config?.defaultAgentId)\n\t\t\t? userConfigResult.config.defaultAgentId\n\t\t\t: defaultId;\n\n\t// Get gateway URL (env var > credentials file > default production URL)\n\tconst gatewayUrl = await getGatewayUrl();\n\n\treturn {\n\t\tgatewayUrl,\n\t\tacpBackends: backends,\n\t\tdefaultAcpBackendId: resolvedDefaultId,\n\t\tclientName: env.MOBVIBE_ACP_CLIENT_NAME ?? \"mobvibe-cli\",\n\t\tclientVersion: env.MOBVIBE_ACP_CLIENT_VERSION ?? \"0.0.0\",\n\t\thomePath,\n\t\tlogPath: path.join(homePath, \"logs\"),\n\t\tpidFile: path.join(homePath, \"daemon.pid\"),\n\t\tmachineId: env.MOBVIBE_MACHINE_ID ?? generateMachineId(),\n\t\thostname: os.hostname(),\n\t\tplatform: os.platform(),\n\t\tuserConfigPath: userConfigResult.path,\n\t\tuserConfigErrors:\n\t\t\tuserConfigResult.errors.length > 0 ? userConfigResult.errors : undefined,\n\t};\n};\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { MobvibeUserConfig, UserAgentConfig } from \"@mobvibe/shared\";\n\nexport type ConfigLoadResult = {\n\tconfig: MobvibeUserConfig | null;\n\terrors: string[];\n\tpath: string;\n};\n\nconst CONFIG_FILENAME = \".config.json\";\n\nconst validateAgentConfig = (\n\tagent: unknown,\n\tindex: number,\n): { valid: UserAgentConfig | null; errors: string[] } => {\n\tconst errors: string[] = [];\n\tconst prefix = `agents[${index}]`;\n\n\tif (typeof agent !== \"object\" || agent === null) {\n\t\terrors.push(`${prefix}: must be an object`);\n\t\treturn { valid: null, errors };\n\t}\n\n\tconst record = agent as Record<string, unknown>;\n\n\t// Validate id (required)\n\tif (typeof record.id !== \"string\" || record.id.trim().length === 0) {\n\t\terrors.push(`${prefix}.id: must be a non-empty string`);\n\t\treturn { valid: null, errors };\n\t}\n\n\t// Validate command (required)\n\tif (\n\t\ttypeof record.command !== \"string\" ||\n\t\trecord.command.trim().length === 0\n\t) {\n\t\terrors.push(`${prefix}.command: must be a non-empty string`);\n\t\treturn { valid: null, errors };\n\t}\n\n\tconst validated: UserAgentConfig = {\n\t\tid: record.id.trim(),\n\t\tcommand: record.command.trim(),\n\t};\n\n\t// Validate label (optional string)\n\tif (record.label !== undefined) {\n\t\tif (typeof record.label !== \"string\") {\n\t\t\terrors.push(`${prefix}.label: must be a string`);\n\t\t} else if (record.label.trim().length > 0) {\n\t\t\tvalidated.label = record.label.trim();\n\t\t}\n\t}\n\n\t// Validate args (optional string array)\n\tif (record.args !== undefined) {\n\t\tif (!Array.isArray(record.args)) {\n\t\t\terrors.push(`${prefix}.args: must be an array of strings`);\n\t\t} else {\n\t\t\tconst validArgs = record.args.filter((arg): arg is string => {\n\t\t\t\tif (typeof arg !== \"string\") {\n\t\t\t\t\terrors.push(`${prefix}.args: all elements must be strings`);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t});\n\t\t\tif (validArgs.length > 0) {\n\t\t\t\tvalidated.args = validArgs;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Validate env (optional object with string values)\n\tif (record.env !== undefined) {\n\t\tif (typeof record.env !== \"object\" || record.env === null) {\n\t\t\terrors.push(`${prefix}.env: must be an object`);\n\t\t} else {\n\t\t\tconst envRecord = record.env as Record<string, unknown>;\n\t\t\tconst validEnv: Record<string, string> = {};\n\t\t\tlet hasEnv = false;\n\t\t\tfor (const [key, value] of Object.entries(envRecord)) {\n\t\t\t\tif (typeof value !== \"string\") {\n\t\t\t\t\terrors.push(`${prefix}.env.${key}: must be a string`);\n\t\t\t\t} else {\n\t\t\t\t\tvalidEnv[key] = value;\n\t\t\t\t\thasEnv = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (hasEnv) {\n\t\t\t\tvalidated.env = validEnv;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return null if there were any errors after id/command validation\n\tif (errors.length > 0) {\n\t\treturn { valid: null, errors };\n\t}\n\n\treturn { valid: validated, errors: [] };\n};\n\nconst validateUserConfig = (\n\tdata: unknown,\n): { config: MobvibeUserConfig | null; errors: string[] } => {\n\tconst errors: string[] = [];\n\n\tif (typeof data !== \"object\" || data === null) {\n\t\terrors.push(\"config: must be an object\");\n\t\treturn { config: null, errors };\n\t}\n\n\tconst record = data as Record<string, unknown>;\n\tconst config: MobvibeUserConfig = {};\n\n\t// Validate agents array\n\tif (record.agents !== undefined) {\n\t\tif (!Array.isArray(record.agents)) {\n\t\t\terrors.push(\"agents: must be an array\");\n\t\t} else {\n\t\t\tconst validAgents: UserAgentConfig[] = [];\n\t\t\tconst seenIds = new Set<string>();\n\n\t\t\tfor (let i = 0; i < record.agents.length; i++) {\n\t\t\t\tconst result = validateAgentConfig(record.agents[i], i);\n\t\t\t\terrors.push(...result.errors);\n\n\t\t\t\tif (result.valid) {\n\t\t\t\t\tif (seenIds.has(result.valid.id)) {\n\t\t\t\t\t\terrors.push(`agents[${i}].id: duplicate id \"${result.valid.id}\"`);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tseenIds.add(result.valid.id);\n\t\t\t\t\t\tvalidAgents.push(result.valid);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (validAgents.length > 0) {\n\t\t\t\tconfig.agents = validAgents;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Validate defaultAgentId\n\tif (record.defaultAgentId !== undefined) {\n\t\tif (typeof record.defaultAgentId !== \"string\") {\n\t\t\terrors.push(\"defaultAgentId: must be a string\");\n\t\t} else if (record.defaultAgentId.trim().length > 0) {\n\t\t\tconfig.defaultAgentId = record.defaultAgentId.trim();\n\t\t}\n\t}\n\n\tif (errors.length > 0) {\n\t\treturn { config: null, errors };\n\t}\n\n\treturn { config, errors: [] };\n};\n\nexport const loadUserConfig = async (\n\thomePath: string,\n): Promise<ConfigLoadResult> => {\n\tconst configPath = path.join(homePath, CONFIG_FILENAME);\n\tconsole.log(`[config] Loading config from: ${configPath}`);\n\n\ttry {\n\t\tconst content = await fs.readFile(configPath, \"utf-8\");\n\t\tlet parsed: unknown;\n\n\t\ttry {\n\t\t\tparsed = JSON.parse(content);\n\t\t} catch {\n\t\t\tconsole.log(`[config] Invalid JSON in config file: ${configPath}`);\n\t\t\treturn {\n\t\t\t\tconfig: null,\n\t\t\t\terrors: [\"Invalid JSON in config file\"],\n\t\t\t\tpath: configPath,\n\t\t\t};\n\t\t}\n\n\t\tconst { config, errors } = validateUserConfig(parsed);\n\n\t\tif (errors.length > 0) {\n\t\t\tconsole.log(\"[config] Validation errors:\", errors);\n\t\t}\n\n\t\tif (config) {\n\t\t\tconsole.log(\"[config] Loaded config:\", JSON.stringify(config, null, 2));\n\t\t}\n\n\t\treturn { config, errors, path: configPath };\n\t} catch (error) {\n\t\t// File not found is not an error, just return null config\n\t\tif (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") {\n\t\t\tconsole.log(`[config] No config file found at: ${configPath}`);\n\t\t\treturn { config: null, errors: [], path: configPath };\n\t\t}\n\n\t\t// Other errors (permissions, etc.)\n\t\tconst message =\n\t\t\terror instanceof Error ? error.message : \"Unknown error reading config\";\n\t\tconsole.log(`[config] Error reading config: ${message}`);\n\t\treturn { config: null, errors: [message], path: configPath };\n\t}\n};\n","import { spawn } from \"node:child_process\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { SessionManager } from \"../acp/session-manager.js\";\nimport { getApiKey } from \"../auth/credentials.js\";\nimport type { CliConfig } from \"../config.js\";\nimport { logger } from \"../lib/logger.js\";\nimport { SocketClient } from \"./socket-client.js\";\n\ntype DaemonStatus = {\n\trunning: boolean;\n\tpid?: number;\n\tconnected?: boolean;\n\tsessionCount?: number;\n};\n\nexport class DaemonManager {\n\tconstructor(private readonly config: CliConfig) {}\n\n\tasync ensureHomeDirectory(): Promise<void> {\n\t\tawait fs.mkdir(this.config.homePath, { recursive: true });\n\t\tawait fs.mkdir(this.config.logPath, { recursive: true });\n\t}\n\n\tasync getPid(): Promise<number | null> {\n\t\ttry {\n\t\t\tconst content = await fs.readFile(this.config.pidFile, \"utf8\");\n\t\t\tconst pid = Number.parseInt(content.trim(), 10);\n\t\t\tif (Number.isNaN(pid)) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\t// Check if process is running\n\t\t\ttry {\n\t\t\t\tprocess.kill(pid, 0);\n\t\t\t\treturn pid;\n\t\t\t} catch {\n\t\t\t\t// Process not running, clean up stale PID file\n\t\t\t\tawait this.removePidFile();\n\t\t\t\treturn null;\n\t\t\t}\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tasync writePidFile(pid: number): Promise<void> {\n\t\tawait fs.writeFile(this.config.pidFile, String(pid), \"utf8\");\n\t}\n\n\tasync removePidFile(): Promise<void> {\n\t\ttry {\n\t\t\tawait fs.unlink(this.config.pidFile);\n\t\t} catch {\n\t\t\t// Ignore errors\n\t\t}\n\t}\n\n\tasync status(): Promise<DaemonStatus> {\n\t\tconst pid = await this.getPid();\n\t\tif (!pid) {\n\t\t\treturn { running: false };\n\t\t}\n\t\treturn { running: true, pid };\n\t}\n\n\tasync start(options?: { foreground?: boolean }): Promise<void> {\n\t\tconst existingPid = await this.getPid();\n\t\tif (existingPid) {\n\t\t\tlogger.info({ pid: existingPid }, \"daemon_already_running\");\n\t\t\treturn;\n\t\t}\n\n\t\tawait this.ensureHomeDirectory();\n\n\t\tif (options?.foreground) {\n\t\t\tawait this.runForeground();\n\t\t} else {\n\t\t\tawait this.spawnBackground();\n\t\t}\n\t}\n\n\tasync stop(): Promise<void> {\n\t\tconst pid = await this.getPid();\n\t\tif (!pid) {\n\t\t\tlogger.info(\"daemon_not_running\");\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if process actually exists\n\t\ttry {\n\t\t\tprocess.kill(pid, 0);\n\t\t} catch {\n\t\t\tlogger.warn(\"daemon_pid_missing_cleanup\");\n\t\t\tawait this.removePidFile();\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tlogger.info({ pid }, \"daemon_stop_sigterm\");\n\t\t\tprocess.kill(pid, \"SIGTERM\");\n\n\t\t\t// Wait for process to exit (up to 5 seconds)\n\t\t\tconst startTime = Date.now();\n\t\t\tconst timeout = 5000;\n\n\t\t\twhile (Date.now() - startTime < timeout) {\n\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, 100));\n\t\t\t\ttry {\n\t\t\t\t\tprocess.kill(pid, 0);\n\t\t\t\t\t// Process still running\n\t\t\t\t} catch {\n\t\t\t\t\t// Process exited\n\t\t\t\t\tlogger.info({ pid }, \"daemon_stopped_gracefully\");\n\t\t\t\t\tawait this.removePidFile();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Process didn't exit gracefully, force kill\n\t\t\tlogger.warn({ pid }, \"daemon_force_kill_start\");\n\t\t\ttry {\n\t\t\t\tprocess.kill(pid, \"SIGKILL\");\n\t\t\t\t// Wait a bit for SIGKILL to take effect\n\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, 500));\n\t\t\t\tlogger.warn({ pid }, \"daemon_force_kill_complete\");\n\t\t\t} catch {\n\t\t\t\t// Already dead\n\t\t\t\tlogger.info({ pid }, \"daemon_already_stopped\");\n\t\t\t}\n\t\t\tawait this.removePidFile();\n\t\t} catch (error) {\n\t\t\tlogger.error({ err: error }, \"daemon_stop_error\");\n\t\t\tawait this.removePidFile();\n\t\t}\n\t}\n\n\tprivate async spawnBackground(): Promise<void> {\n\t\tconst logFile = path.join(\n\t\t\tthis.config.logPath,\n\t\t\t`${new Date().toISOString().replace(/[:.]/g, \"-\")}-daemon.log`,\n\t\t);\n\n\t\t// Filter out --foreground if already present, then add it\n\t\tconst args = process.argv\n\t\t\t.slice(1)\n\t\t\t.filter((arg) => arg !== \"--foreground\" && arg !== \"-f\");\n\t\targs.push(\"--foreground\");\n\n\t\tconst child = spawn(process.argv[0], args, {\n\t\t\tdetached: true,\n\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t\tenv: {\n\t\t\t\t...process.env,\n\t\t\t\tMOBVIBE_GATEWAY_URL: this.config.gatewayUrl,\n\t\t\t},\n\t\t});\n\n\t\tif (!child.pid) {\n\t\t\tlogger.error(\"daemon_spawn_failed\");\n\t\t\tthrow new Error(\"Failed to spawn daemon process\");\n\t\t}\n\n\t\t// Create log file stream before writing PID\n\t\tconst logStream = await fs.open(logFile, \"a\");\n\t\tconst fileHandle = logStream;\n\n\t\tchild.stdout?.on(\"data\", (data: Buffer) => {\n\t\t\tfileHandle.write(`[stdout] ${data.toString()}`).catch(() => {});\n\t\t});\n\n\t\tchild.stderr?.on(\"data\", (data: Buffer) => {\n\t\t\tfileHandle.write(`[stderr] ${data.toString()}`).catch(() => {});\n\t\t});\n\n\t\t// Handle child exit to clean up\n\t\tchild.on(\"exit\", (code, signal) => {\n\t\t\tfileHandle\n\t\t\t\t.write(`[exit] Process exited with code ${code}, signal ${signal}\\n`)\n\t\t\t\t.catch(() => {});\n\t\t\tfileHandle.close().catch(() => {});\n\t\t});\n\n\t\t// Detach from parent\n\t\t// Note: The child process writes its own PID file in runForeground()\n\t\tchild.unref();\n\n\t\tlogger.info({ pid: child.pid }, \"daemon_started\");\n\t\tconsole.log(`Logs: ${logFile}`);\n\t\tlogger.info({ logFile }, \"daemon_log_path\");\n\t}\n\n\tasync runForeground(): Promise<void> {\n\t\tconst pid = process.pid;\n\t\tawait this.writePidFile(pid);\n\n\t\tlogger.info({ pid }, \"daemon_starting\");\n\t\tlogger.info({ gatewayUrl: this.config.gatewayUrl }, \"daemon_gateway_url\");\n\t\tlogger.info({ machineId: this.config.machineId }, \"daemon_machine_id\");\n\n\t\t// Load API key for authentication\n\t\tconst apiKey = await getApiKey();\n\t\tif (!apiKey) {\n\t\t\tlogger.error(\"daemon_api_key_missing\");\n\t\t\tconsole.error(\n\t\t\t\t`[mobvibe-cli] No API key found. Run 'mobvibe login' to authenticate.`,\n\t\t\t);\n\t\t\tlogger.warn(\"daemon_exit_missing_api_key\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tlogger.info(\"daemon_api_key_loaded\");\n\n\t\tconst sessionManager = new SessionManager(this.config);\n\t\tconst socketClient = new SocketClient({\n\t\t\tconfig: this.config,\n\t\t\tsessionManager,\n\t\t\tapiKey,\n\t\t});\n\n\t\tlet shuttingDown = false;\n\n\t\tconst shutdown = async (signal: string) => {\n\t\t\tif (shuttingDown) {\n\t\t\t\tlogger.warn({ signal }, \"daemon_shutdown_already_running\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tshuttingDown = true;\n\n\t\t\tlogger.info({ signal }, \"daemon_shutdown_start\");\n\n\t\t\ttry {\n\t\t\t\tsocketClient.disconnect();\n\t\t\t\tawait sessionManager.closeAll();\n\t\t\t\tawait this.removePidFile();\n\t\t\t\tlogger.info({ signal }, \"daemon_shutdown_complete\");\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error({ err: error, signal }, \"daemon_shutdown_error\");\n\t\t\t}\n\t\t};\n\n\t\tprocess.on(\"SIGINT\", () => {\n\t\t\tshutdown(\"SIGINT\").catch((error) => {\n\t\t\t\tlogger.error({ err: error }, \"daemon_shutdown_sigint_error\");\n\t\t\t});\n\t\t});\n\t\tprocess.on(\"SIGTERM\", () => {\n\t\t\tshutdown(\"SIGTERM\").catch((error) => {\n\t\t\t\tlogger.error({ err: error }, \"daemon_shutdown_sigterm_error\");\n\t\t\t});\n\t\t});\n\n\t\tsocketClient.connect();\n\n\t\t// Keep process alive\n\t\tawait new Promise(() => {});\n\t}\n\n\tasync logs(options?: { follow?: boolean; lines?: number }): Promise<void> {\n\t\tconst files = await fs.readdir(this.config.logPath);\n\t\tconst logFiles = files\n\t\t\t.filter((f) => f.endsWith(\"-daemon.log\"))\n\t\t\t.sort()\n\t\t\t.reverse();\n\n\t\tif (logFiles.length === 0) {\n\t\t\tlogger.warn(\"daemon_logs_empty\");\n\t\t\tconsole.log(\"No log files found\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst latestLog = path.join(this.config.logPath, logFiles[0]);\n\t\tlogger.info({ logFile: latestLog }, \"daemon_logs_latest\");\n\t\tconsole.log(`Log file: ${latestLog}\\n`);\n\n\t\tif (options?.follow) {\n\t\t\t// Use tail -f\n\t\t\tconst tail = spawn(\"tail\", [\"-f\", latestLog], {\n\t\t\t\tstdio: \"inherit\",\n\t\t\t});\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\ttail.on(\"close\", () => resolve());\n\t\t\t});\n\t\t} else {\n\t\t\tconst content = await fs.readFile(latestLog, \"utf8\");\n\t\t\tconst lines = content.split(\"\\n\");\n\t\t\tconst count = options?.lines ?? 50;\n\t\t\tconsole.log(lines.slice(-count).join(\"\\n\"));\n\t\t}\n\t}\n}\n","import { randomUUID } from \"node:crypto\";\nimport { EventEmitter } from \"node:events\";\nimport type {\n\tAvailableCommand,\n\tRequestPermissionRequest,\n\tRequestPermissionResponse,\n\tSessionModelState,\n\tSessionModeState,\n\tSessionNotification,\n} from \"@agentclientprotocol/sdk\";\nimport {\n\ttype AcpSessionInfo,\n\tAppError,\n\tcreateErrorDetail,\n\ttype DiscoverSessionsRpcResult,\n\ttype ErrorDetail,\n\ttype PermissionDecisionPayload,\n\ttype PermissionRequestPayload,\n\ttype SessionSummary,\n\ttype SessionsChangedPayload,\n\ttype TerminalOutputEvent,\n} from \"@mobvibe/shared\";\nimport type { AcpBackendConfig, CliConfig } from \"../config.js\";\nimport { logger } from \"../lib/logger.js\";\nimport { AcpConnection } from \"./acp-connection.js\";\n\ntype SessionRecord = {\n\tsessionId: string;\n\ttitle: string;\n\tbackendId: string;\n\tbackendLabel: string;\n\tconnection: AcpConnection;\n\tcreatedAt: Date;\n\tupdatedAt: Date;\n\tcwd?: string;\n\tagentName?: string;\n\tmodelId?: string;\n\tmodelName?: string;\n\tmodeId?: string;\n\tmodeName?: string;\n\tavailableModes?: Array<{ id: string; name: string }>;\n\tavailableModels?: Array<{\n\t\tid: string;\n\t\tname: string;\n\t\tdescription?: string | null;\n\t}>;\n\tavailableCommands?: AvailableCommand[];\n\tunsubscribe?: () => void;\n\tunsubscribeTerminal?: () => void;\n};\n\ntype PermissionRequestRecord = {\n\tsessionId: string;\n\trequestId: string;\n\tparams: RequestPermissionRequest;\n\tpromise: Promise<RequestPermissionResponse>;\n\tresolve: (response: RequestPermissionResponse) => void;\n};\n\nconst buildPermissionKey = (sessionId: string, requestId: string) =>\n\t`${sessionId}:${requestId}`;\n\nconst resolveModelState = (models?: SessionModelState | null) => {\n\tif (!models) {\n\t\treturn {\n\t\t\tmodelId: undefined,\n\t\t\tmodelName: undefined,\n\t\t\tavailableModels: undefined,\n\t\t};\n\t}\n\tconst availableModels = models.availableModels?.map((model) => ({\n\t\tid: model.modelId,\n\t\tname: model.name,\n\t\tdescription: model.description ?? undefined,\n\t}));\n\tconst modelId = models.currentModelId ?? undefined;\n\tconst modelName = availableModels?.find(\n\t\t(model) => model.id === modelId,\n\t)?.name;\n\treturn { modelId, modelName, availableModels };\n};\n\nconst resolveModeState = (modes?: SessionModeState | null) => {\n\tif (!modes) {\n\t\treturn {\n\t\t\tmodeId: undefined,\n\t\t\tmodeName: undefined,\n\t\t\tavailableModes: undefined,\n\t\t};\n\t}\n\tconst modeId = modes.currentModeId ?? undefined;\n\tconst modeName = modes.availableModes?.find(\n\t\t(mode) => mode.id === modeId,\n\t)?.name;\n\treturn {\n\t\tmodeId,\n\t\tmodeName,\n\t\tavailableModes: modes.availableModes?.map((mode) => ({\n\t\t\tid: mode.id,\n\t\t\tname: mode.name,\n\t\t})),\n\t};\n};\n\nconst createCapabilityNotSupportedError = (message: string) =>\n\tnew AppError(\n\t\tcreateErrorDetail({\n\t\t\tcode: \"CAPABILITY_NOT_SUPPORTED\",\n\t\t\tmessage,\n\t\t\tretryable: false,\n\t\t\tscope: \"session\",\n\t\t}),\n\t\t409,\n\t);\n\nexport class SessionManager {\n\tprivate sessions = new Map<string, SessionRecord>();\n\tprivate backendById: Map<string, AcpBackendConfig>;\n\tprivate defaultBackendId: string;\n\tprivate permissionRequests = new Map<string, PermissionRequestRecord>();\n\tprivate readonly sessionUpdateEmitter = new EventEmitter();\n\tprivate readonly sessionErrorEmitter = new EventEmitter();\n\tprivate readonly permissionRequestEmitter = new EventEmitter();\n\tprivate readonly permissionResultEmitter = new EventEmitter();\n\tprivate readonly terminalOutputEmitter = new EventEmitter();\n\tprivate readonly sessionsChangedEmitter = new EventEmitter();\n\n\tconstructor(private readonly config: CliConfig) {\n\t\tthis.backendById = new Map(\n\t\t\tconfig.acpBackends.map((backend) => [backend.id, backend]),\n\t\t);\n\t\tthis.defaultBackendId = config.defaultAcpBackendId;\n\t}\n\n\tlistSessions(): SessionSummary[] {\n\t\treturn Array.from(this.sessions.values()).map((record) =>\n\t\t\tthis.buildSummary(record),\n\t\t);\n\t}\n\n\tgetSession(sessionId: string): SessionRecord | undefined {\n\t\treturn this.sessions.get(sessionId);\n\t}\n\n\tonSessionUpdate(listener: (notification: SessionNotification) => void) {\n\t\tthis.sessionUpdateEmitter.on(\"update\", listener);\n\t\treturn () => {\n\t\t\tthis.sessionUpdateEmitter.off(\"update\", listener);\n\t\t};\n\t}\n\n\tonSessionError(\n\t\tlistener: (payload: { sessionId: string; error: ErrorDetail }) => void,\n\t) {\n\t\tthis.sessionErrorEmitter.on(\"error\", listener);\n\t\treturn () => {\n\t\t\tthis.sessionErrorEmitter.off(\"error\", listener);\n\t\t};\n\t}\n\n\tonPermissionRequest(listener: (payload: PermissionRequestPayload) => void) {\n\t\tthis.permissionRequestEmitter.on(\"request\", listener);\n\t\treturn () => {\n\t\t\tthis.permissionRequestEmitter.off(\"request\", listener);\n\t\t};\n\t}\n\n\tonPermissionResult(listener: (payload: PermissionDecisionPayload) => void) {\n\t\tthis.permissionResultEmitter.on(\"result\", listener);\n\t\treturn () => {\n\t\t\tthis.permissionResultEmitter.off(\"result\", listener);\n\t\t};\n\t}\n\n\tonTerminalOutput(listener: (event: TerminalOutputEvent) => void) {\n\t\tthis.terminalOutputEmitter.on(\"output\", listener);\n\t\treturn () => {\n\t\t\tthis.terminalOutputEmitter.off(\"output\", listener);\n\t\t};\n\t}\n\n\tonSessionsChanged(listener: (payload: SessionsChangedPayload) => void) {\n\t\tthis.sessionsChangedEmitter.on(\"changed\", listener);\n\t\treturn () => {\n\t\t\tthis.sessionsChangedEmitter.off(\"changed\", listener);\n\t\t};\n\t}\n\n\tprivate emitSessionsChanged(payload: SessionsChangedPayload) {\n\t\tthis.sessionsChangedEmitter.emit(\"changed\", payload);\n\t}\n\n\tlistPendingPermissions(sessionId: string): PermissionRequestPayload[] {\n\t\treturn Array.from(this.permissionRequests.values())\n\t\t\t.filter((record) => record.sessionId === sessionId)\n\t\t\t.map((record) => this.buildPermissionRequestPayload(record));\n\t}\n\n\tresolvePermissionRequest(\n\t\tsessionId: string,\n\t\trequestId: string,\n\t\toutcome: RequestPermissionResponse[\"outcome\"],\n\t): PermissionDecisionPayload {\n\t\tconst key = buildPermissionKey(sessionId, requestId);\n\t\tconst record = this.permissionRequests.get(key);\n\t\tif (!record) {\n\t\t\tthrow new AppError(\n\t\t\t\tcreateErrorDetail({\n\t\t\t\t\tcode: \"REQUEST_VALIDATION_FAILED\",\n\t\t\t\t\tmessage: \"Permission request not found\",\n\t\t\t\t\tretryable: false,\n\t\t\t\t\tscope: \"request\",\n\t\t\t\t}),\n\t\t\t\t404,\n\t\t\t);\n\t\t}\n\t\tconst response: RequestPermissionResponse = { outcome };\n\t\trecord.resolve(response);\n\t\tthis.permissionRequests.delete(key);\n\t\tconst payload: PermissionDecisionPayload = {\n\t\t\tsessionId,\n\t\t\trequestId,\n\t\t\toutcome,\n\t\t};\n\t\tthis.permissionResultEmitter.emit(\"result\", payload);\n\t\treturn payload;\n\t}\n\n\tprivate resolveBackend(backendId?: string) {\n\t\tconst normalized = backendId?.trim();\n\t\tconst resolvedId =\n\t\t\tnormalized && normalized.length > 0 ? normalized : this.defaultBackendId;\n\t\tconst backend = this.backendById.get(resolvedId);\n\t\tif (!backend) {\n\t\t\tthrow new AppError(\n\t\t\t\tcreateErrorDetail({\n\t\t\t\t\tcode: \"REQUEST_VALIDATION_FAILED\",\n\t\t\t\t\tmessage: \"Invalid backend ID\",\n\t\t\t\t\tretryable: false,\n\t\t\t\t\tscope: \"request\",\n\t\t\t\t}),\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\t\treturn backend;\n\t}\n\n\tasync createSession(options?: {\n\t\tcwd?: string;\n\t\ttitle?: string;\n\t\tbackendId?: string;\n\t}): Promise<SessionSummary> {\n\t\tconst backend = this.resolveBackend(options?.backendId);\n\t\tconst connection = new AcpConnection({\n\t\t\tbackend,\n\t\t\tclient: {\n\t\t\t\tname: this.config.clientName,\n\t\t\t\tversion: this.config.clientVersion,\n\t\t\t},\n\t\t});\n\t\ttry {\n\t\t\tawait connection.connect();\n\t\t\tconst session = await connection.createSession({ cwd: options?.cwd });\n\t\t\tconnection.setPermissionHandler((params) =>\n\t\t\t\tthis.handlePermissionRequest(session.sessionId, params),\n\t\t\t);\n\t\t\tconst now = new Date();\n\t\t\tconst agentInfo = connection.getAgentInfo();\n\t\t\tconst { modelId, modelName, availableModels } = resolveModelState(\n\t\t\t\tsession.models,\n\t\t\t);\n\t\t\tconst { modeId, modeName, availableModes } = resolveModeState(\n\t\t\t\tsession.modes,\n\t\t\t);\n\t\t\tconst record: SessionRecord = {\n\t\t\t\tsessionId: session.sessionId,\n\t\t\t\ttitle: options?.title ?? `Session ${this.sessions.size + 1}`,\n\t\t\t\tbackendId: backend.id,\n\t\t\t\tbackendLabel: backend.label,\n\t\t\t\tconnection,\n\t\t\t\tcreatedAt: now,\n\t\t\t\tupdatedAt: now,\n\t\t\t\tcwd: options?.cwd,\n\t\t\t\tagentName: agentInfo?.title ?? agentInfo?.name,\n\t\t\t\tmodelId,\n\t\t\t\tmodelName,\n\t\t\t\tmodeId,\n\t\t\t\tmodeName,\n\t\t\t\tavailableModes,\n\t\t\t\tavailableModels,\n\t\t\t\tavailableCommands: undefined,\n\t\t\t};\n\t\t\trecord.unsubscribe = connection.onSessionUpdate(\n\t\t\t\t(notification: SessionNotification) => {\n\t\t\t\t\tthis.touchSession(session.sessionId);\n\t\t\t\t\tthis.sessionUpdateEmitter.emit(\"update\", notification);\n\n\t\t\t\t\tconst update = notification.update;\n\t\t\t\t\tif (update.sessionUpdate === \"current_mode_update\") {\n\t\t\t\t\t\trecord.modeId = update.currentModeId;\n\t\t\t\t\t\trecord.modeName =\n\t\t\t\t\t\t\trecord.availableModes?.find(\n\t\t\t\t\t\t\t\t(mode) => mode.id === update.currentModeId,\n\t\t\t\t\t\t\t)?.name ?? record.modeName;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (update.sessionUpdate === \"session_info_update\") {\n\t\t\t\t\t\tif (typeof update.title === \"string\") {\n\t\t\t\t\t\t\trecord.title = update.title;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (typeof update.updatedAt === \"string\") {\n\t\t\t\t\t\t\trecord.updatedAt = new Date(update.updatedAt);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (update.sessionUpdate === \"available_commands_update\") {\n\t\t\t\t\t\tif (update.availableCommands) {\n\t\t\t\t\t\t\trecord.availableCommands = update.availableCommands;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\t\t\trecord.unsubscribeTerminal = connection.onTerminalOutput((event) => {\n\t\t\t\tthis.terminalOutputEmitter.emit(\"output\", event);\n\t\t\t});\n\t\t\tconnection.onStatusChange((status) => {\n\t\t\t\tif (status.error) {\n\t\t\t\t\tthis.sessionErrorEmitter.emit(\"error\", {\n\t\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\t\terror: status.error,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis.sessions.set(session.sessionId, record);\n\t\t\tconst summary = this.buildSummary(record);\n\t\t\tthis.emitSessionsChanged({\n\t\t\t\tadded: [summary],\n\t\t\t\tupdated: [],\n\t\t\t\tremoved: [],\n\t\t\t});\n\t\t\treturn summary;\n\t\t} catch (error) {\n\t\t\tconst status = connection.getStatus();\n\t\t\tawait connection.disconnect();\n\t\t\tif (status.error) {\n\t\t\t\tthrow new AppError(status.error, 500);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate buildPermissionRequestPayload(\n\t\trecord: PermissionRequestRecord,\n\t): PermissionRequestPayload {\n\t\tconst toolCall = record.params.toolCall;\n\t\treturn {\n\t\t\tsessionId: record.sessionId,\n\t\t\trequestId: record.requestId,\n\t\t\toptions: record.params.options.map((option) => ({\n\t\t\t\toptionId: option.optionId,\n\t\t\t\t// SDK uses 'name', our shared type uses 'label'\n\t\t\t\tlabel: option.name,\n\t\t\t\tdescription: (option._meta?.description as string) ?? null,\n\t\t\t})),\n\t\t\ttoolCall: {\n\t\t\t\ttoolCallId: toolCall.toolCallId,\n\t\t\t\tname: (toolCall._meta?.name as string) ?? null,\n\t\t\t\ttitle: toolCall.title,\n\t\t\t\tcommand: (toolCall._meta?.command as string) ?? null,\n\t\t\t\targs: (toolCall._meta?.args as string[]) ?? null,\n\t\t\t},\n\t\t};\n\t}\n\n\tprivate handlePermissionRequest(\n\t\tsessionId: string,\n\t\tparams: RequestPermissionRequest,\n\t): Promise<RequestPermissionResponse> {\n\t\tconst requestId = params.toolCall?.toolCallId ?? randomUUID();\n\t\tconst key = buildPermissionKey(sessionId, requestId);\n\t\tconst existing = this.permissionRequests.get(key);\n\t\tif (existing) {\n\t\t\treturn existing.promise;\n\t\t}\n\t\tlet resolver: (response: RequestPermissionResponse) => void = () => {};\n\t\tconst promise = new Promise<RequestPermissionResponse>((resolve) => {\n\t\t\tresolver = resolve;\n\t\t});\n\t\tconst record: PermissionRequestRecord = {\n\t\t\tsessionId,\n\t\t\trequestId,\n\t\t\tparams,\n\t\t\tpromise,\n\t\t\tresolve: resolver,\n\t\t};\n\t\tthis.permissionRequests.set(key, record);\n\t\tthis.permissionRequestEmitter.emit(\n\t\t\t\"request\",\n\t\t\tthis.buildPermissionRequestPayload(record),\n\t\t);\n\t\treturn promise;\n\t}\n\n\tprivate cancelPermissionRequests(sessionId: string) {\n\t\tconst cancelledOutcome: RequestPermissionResponse[\"outcome\"] = {\n\t\t\toutcome: \"cancelled\",\n\t\t};\n\t\tfor (const [key, record] of this.permissionRequests.entries()) {\n\t\t\tif (record.sessionId !== sessionId) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\trecord.resolve({ outcome: cancelledOutcome });\n\t\t\tthis.permissionRequests.delete(key);\n\t\t\tthis.permissionResultEmitter.emit(\"result\", {\n\t\t\t\tsessionId,\n\t\t\t\trequestId: record.requestId,\n\t\t\t\toutcome: cancelledOutcome,\n\t\t\t});\n\t\t}\n\t}\n\n\tupdateTitle(sessionId: string, title: string): SessionSummary {\n\t\tconst record = this.sessions.get(sessionId);\n\t\tif (!record) {\n\t\t\tthrow new AppError(\n\t\t\t\tcreateErrorDetail({\n\t\t\t\t\tcode: \"SESSION_NOT_FOUND\",\n\t\t\t\t\tmessage: \"Session not found\",\n\t\t\t\t\tretryable: false,\n\t\t\t\t\tscope: \"session\",\n\t\t\t\t}),\n\t\t\t\t404,\n\t\t\t);\n\t\t}\n\t\trecord.title = title;\n\t\trecord.updatedAt = new Date();\n\t\tconst summary = this.buildSummary(record);\n\t\tthis.emitSessionsChanged({\n\t\t\tadded: [],\n\t\t\tupdated: [summary],\n\t\t\tremoved: [],\n\t\t});\n\t\treturn summary;\n\t}\n\n\ttouchSession(sessionId: string) {\n\t\tconst record = this.sessions.get(sessionId);\n\t\tif (!record) {\n\t\t\treturn;\n\t\t}\n\t\trecord.updatedAt = new Date();\n\t}\n\n\tasync setSessionMode(\n\t\tsessionId: string,\n\t\tmodeId: string,\n\t): Promise<SessionSummary> {\n\t\tconst record = this.sessions.get(sessionId);\n\t\tif (!record) {\n\t\t\tthrow new AppError(\n\t\t\t\tcreateErrorDetail({\n\t\t\t\t\tcode: \"SESSION_NOT_FOUND\",\n\t\t\t\t\tmessage: \"Session not found\",\n\t\t\t\t\tretryable: false,\n\t\t\t\t\tscope: \"session\",\n\t\t\t\t}),\n\t\t\t\t404,\n\t\t\t);\n\t\t}\n\t\tif (!record.availableModes || record.availableModes.length === 0) {\n\t\t\tthrow createCapabilityNotSupportedError(\n\t\t\t\t\"Current agent does not support mode switching\",\n\t\t\t);\n\t\t}\n\t\tconst selected = record.availableModes.find((mode) => mode.id === modeId);\n\t\tif (!selected) {\n\t\t\tthrow new AppError(\n\t\t\t\tcreateErrorDetail({\n\t\t\t\t\tcode: \"REQUEST_VALIDATION_FAILED\",\n\t\t\t\t\tmessage: \"Invalid mode ID\",\n\t\t\t\t\tretryable: false,\n\t\t\t\t\tscope: \"request\",\n\t\t\t\t}),\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\t\tawait record.connection.setSessionMode(sessionId, modeId);\n\t\trecord.modeId = selected.id;\n\t\trecord.modeName = selected.name;\n\t\trecord.updatedAt = new Date();\n\t\tconst summary = this.buildSummary(record);\n\t\tthis.emitSessionsChanged({\n\t\t\tadded: [],\n\t\t\tupdated: [summary],\n\t\t\tremoved: [],\n\t\t});\n\t\treturn summary;\n\t}\n\n\tasync setSessionModel(\n\t\tsessionId: string,\n\t\tmodelId: string,\n\t): Promise<SessionSummary> {\n\t\tconst record = this.sessions.get(sessionId);\n\t\tif (!record) {\n\t\t\tthrow new AppError(\n\t\t\t\tcreateErrorDetail({\n\t\t\t\t\tcode: \"SESSION_NOT_FOUND\",\n\t\t\t\t\tmessage: \"Session not found\",\n\t\t\t\t\tretryable: false,\n\t\t\t\t\tscope: \"session\",\n\t\t\t\t}),\n\t\t\t\t404,\n\t\t\t);\n\t\t}\n\t\tif (!record.availableModels || record.availableModels.length === 0) {\n\t\t\tthrow createCapabilityNotSupportedError(\n\t\t\t\t\"Current agent does not support model switching\",\n\t\t\t);\n\t\t}\n\t\tconst selected = record.availableModels.find(\n\t\t\t(model) => model.id === modelId,\n\t\t);\n\t\tif (!selected) {\n\t\t\tthrow new AppError(\n\t\t\t\tcreateErrorDetail({\n\t\t\t\t\tcode: \"REQUEST_VALIDATION_FAILED\",\n\t\t\t\t\tmessage: \"Invalid model ID\",\n\t\t\t\t\tretryable: false,\n\t\t\t\t\tscope: \"request\",\n\t\t\t\t}),\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\t\tawait record.connection.setSessionModel(sessionId, modelId);\n\t\trecord.modelId = selected.id;\n\t\trecord.modelName = selected.name;\n\t\trecord.updatedAt = new Date();\n\t\tconst summary = this.buildSummary(record);\n\t\tthis.emitSessionsChanged({\n\t\t\tadded: [],\n\t\t\tupdated: [summary],\n\t\t\tremoved: [],\n\t\t});\n\t\treturn summary;\n\t}\n\n\tasync cancelSession(sessionId: string): Promise<boolean> {\n\t\tconst record = this.sessions.get(sessionId);\n\t\tif (!record) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.cancelPermissionRequests(sessionId);\n\t\tawait record.connection.cancel(sessionId);\n\t\tthis.touchSession(sessionId);\n\t\treturn true;\n\t}\n\n\tasync closeSession(sessionId: string): Promise<boolean> {\n\t\tconst record = this.sessions.get(sessionId);\n\t\tif (!record) {\n\t\t\treturn false;\n\t\t}\n\t\ttry {\n\t\t\trecord.unsubscribe?.();\n\t\t\trecord.unsubscribeTerminal?.();\n\t\t} catch (error) {\n\t\t\tlogger.error({ err: error, sessionId }, \"session_unsubscribe_failed\");\n\t\t}\n\t\tthis.cancelPermissionRequests(sessionId);\n\t\ttry {\n\t\t\tawait record.connection.disconnect();\n\t\t} catch (error) {\n\t\t\tlogger.error({ err: error, sessionId }, \"session_disconnect_failed\");\n\t\t}\n\t\tthis.sessions.delete(sessionId);\n\t\tthis.emitSessionsChanged({\n\t\t\tadded: [],\n\t\t\tupdated: [],\n\t\t\tremoved: [sessionId],\n\t\t});\n\t\treturn true;\n\t}\n\n\tasync closeAll(): Promise<void> {\n\t\tconst sessionIds = Array.from(this.sessions.keys());\n\t\tawait Promise.all(\n\t\t\tsessionIds.map((sessionId) => this.closeSession(sessionId)),\n\t\t);\n\t}\n\n\t/**\n\t * Discover sessions persisted by the ACP agent.\n\t * Creates a temporary connection to query sessions.\n\t * @param options Optional parameters for discovery\n\t * @returns List of discovered sessions and agent capabilities\n\t */\n\tasync discoverSessions(options?: {\n\t\tcwd?: string;\n\t\tbackendId?: string;\n\t}): Promise<DiscoverSessionsRpcResult> {\n\t\tconst backend = this.resolveBackend(options?.backendId);\n\t\tconst connection = new AcpConnection({\n\t\t\tbackend,\n\t\t\tclient: {\n\t\t\t\tname: this.config.clientName,\n\t\t\t\tversion: this.config.clientVersion,\n\t\t\t},\n\t\t});\n\n\t\ttry {\n\t\t\tawait connection.connect();\n\t\t\tconst capabilities = connection.getSessionCapabilities();\n\t\t\tconst sessions: AcpSessionInfo[] = [];\n\n\t\t\tif (capabilities.list) {\n\t\t\t\tconst agentSessions = await connection.listSessions({\n\t\t\t\t\tcwd: options?.cwd,\n\t\t\t\t});\n\t\t\t\tfor (const session of agentSessions) {\n\t\t\t\t\tsessions.push({\n\t\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\t\tcwd: session.cwd,\n\t\t\t\t\t\ttitle: session.title ?? undefined,\n\t\t\t\t\t\tupdatedAt: session.updatedAt ?? undefined,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlogger.info(\n\t\t\t\t{\n\t\t\t\t\tbackendId: backend.id,\n\t\t\t\t\tsessionCount: sessions.length,\n\t\t\t\t\tcapabilities,\n\t\t\t\t},\n\t\t\t\t\"sessions_discovered\",\n\t\t\t);\n\n\t\t\treturn { sessions, capabilities };\n\t\t} finally {\n\t\t\tawait connection.disconnect();\n\t\t}\n\t}\n\n\t/**\n\t * Load a historical session from the ACP agent.\n\t * This will replay the session's message history.\n\t * @param sessionId The session ID to load\n\t * @param cwd The working directory\n\t * @param backendId Optional backend ID\n\t * @returns The loaded session summary\n\t */\n\tasync loadSession(\n\t\tsessionId: string,\n\t\tcwd: string,\n\t\tbackendId?: string,\n\t): Promise<SessionSummary> {\n\t\t// Check if session is already loaded\n\t\tconst existing = this.sessions.get(sessionId);\n\t\tif (existing) {\n\t\t\treturn this.buildSummary(existing);\n\t\t}\n\n\t\tconst backend = this.resolveBackend(backendId);\n\t\tconst connection = new AcpConnection({\n\t\t\tbackend,\n\t\t\tclient: {\n\t\t\t\tname: this.config.clientName,\n\t\t\t\tversion: this.config.clientVersion,\n\t\t\t},\n\t\t});\n\n\t\ttry {\n\t\t\tawait connection.connect();\n\n\t\t\tif (!connection.supportsSessionLoad()) {\n\t\t\t\tthrow createCapabilityNotSupportedError(\n\t\t\t\t\t\"Agent does not support session loading\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst response = await connection.loadSession(sessionId, cwd);\n\t\t\tconnection.setPermissionHandler((params) =>\n\t\t\t\tthis.handlePermissionRequest(sessionId, params),\n\t\t\t);\n\n\t\t\tconst now = new Date();\n\t\t\tconst agentInfo = connection.getAgentInfo();\n\t\t\tconst { modelId, modelName, availableModels } = resolveModelState(\n\t\t\t\tresponse.models,\n\t\t\t);\n\t\t\tconst { modeId, modeName, availableModes } = resolveModeState(\n\t\t\t\tresponse.modes,\n\t\t\t);\n\n\t\t\tconst record: SessionRecord = {\n\t\t\t\tsessionId,\n\t\t\t\ttitle: `Loaded Session`,\n\t\t\t\tbackendId: backend.id,\n\t\t\t\tbackendLabel: backend.label,\n\t\t\t\tconnection,\n\t\t\t\tcreatedAt: now,\n\t\t\t\tupdatedAt: now,\n\t\t\t\tcwd,\n\t\t\t\tagentName: agentInfo?.title ?? agentInfo?.name,\n\t\t\t\tmodelId,\n\t\t\t\tmodelName,\n\t\t\t\tmodeId,\n\t\t\t\tmodeName,\n\t\t\t\tavailableModes,\n\t\t\t\tavailableModels,\n\t\t\t\tavailableCommands: undefined,\n\t\t\t};\n\n\t\t\tthis.setupSessionSubscriptions(record);\n\t\t\tthis.sessions.set(sessionId, record);\n\n\t\t\tconst summary = this.buildSummary(record);\n\t\t\tthis.emitSessionsChanged({\n\t\t\t\tadded: [summary],\n\t\t\t\tupdated: [],\n\t\t\t\tremoved: [],\n\t\t\t});\n\n\t\t\tlogger.info({ sessionId, backendId: backend.id }, \"session_loaded\");\n\n\t\t\treturn summary;\n\t\t} catch (error) {\n\t\t\tawait connection.disconnect();\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Resume an active session from the ACP agent.\n\t * This does not replay message history.\n\t * @param sessionId The session ID to resume\n\t * @param cwd The working directory\n\t * @param backendId Optional backend ID\n\t * @returns The resumed session summary\n\t */\n\tasync resumeSession(\n\t\tsessionId: string,\n\t\tcwd: string,\n\t\tbackendId?: string,\n\t): Promise<SessionSummary> {\n\t\t// Check if session is already loaded\n\t\tconst existing = this.sessions.get(sessionId);\n\t\tif (existing) {\n\t\t\treturn this.buildSummary(existing);\n\t\t}\n\n\t\tconst backend = this.resolveBackend(backendId);\n\t\tconst connection = new AcpConnection({\n\t\t\tbackend,\n\t\t\tclient: {\n\t\t\t\tname: this.config.clientName,\n\t\t\t\tversion: this.config.clientVersion,\n\t\t\t},\n\t\t});\n\n\t\ttry {\n\t\t\tawait connection.connect();\n\n\t\t\tif (!connection.supportsSessionResume()) {\n\t\t\t\tthrow createCapabilityNotSupportedError(\n\t\t\t\t\t\"Agent does not support session resuming\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst response = await connection.resumeSession(sessionId, cwd);\n\t\t\tconnection.setPermissionHandler((params) =>\n\t\t\t\tthis.handlePermissionRequest(sessionId, params),\n\t\t\t);\n\n\t\t\tconst now = new Date();\n\t\t\tconst agentInfo = connection.getAgentInfo();\n\t\t\tconst { modelId, modelName, availableModels } = resolveModelState(\n\t\t\t\tresponse.models,\n\t\t\t);\n\t\t\tconst { modeId, modeName, availableModes } = resolveModeState(\n\t\t\t\tresponse.modes,\n\t\t\t);\n\n\t\t\tconst record: SessionRecord = {\n\t\t\t\tsessionId,\n\t\t\t\ttitle: `Resumed Session`,\n\t\t\t\tbackendId: backend.id,\n\t\t\t\tbackendLabel: backend.label,\n\t\t\t\tconnection,\n\t\t\t\tcreatedAt: now,\n\t\t\t\tupdatedAt: now,\n\t\t\t\tcwd,\n\t\t\t\tagentName: agentInfo?.title ?? agentInfo?.name,\n\t\t\t\tmodelId,\n\t\t\t\tmodelName,\n\t\t\t\tmodeId,\n\t\t\t\tmodeName,\n\t\t\t\tavailableModes,\n\t\t\t\tavailableModels,\n\t\t\t\tavailableCommands: undefined,\n\t\t\t};\n\n\t\t\tthis.setupSessionSubscriptions(record);\n\t\t\tthis.sessions.set(sessionId, record);\n\n\t\t\tconst summary = this.buildSummary(record);\n\t\t\tthis.emitSessionsChanged({\n\t\t\t\tadded: [summary],\n\t\t\t\tupdated: [],\n\t\t\t\tremoved: [],\n\t\t\t});\n\n\t\t\tlogger.info({ sessionId, backendId: backend.id }, \"session_resumed\");\n\n\t\t\treturn summary;\n\t\t} catch (error) {\n\t\t\tawait connection.disconnect();\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Set up event subscriptions for a session record.\n\t */\n\tprivate setupSessionSubscriptions(record: SessionRecord): void {\n\t\tconst { sessionId, connection } = record;\n\n\t\trecord.unsubscribe = connection.onSessionUpdate(\n\t\t\t(notification: SessionNotification) => {\n\t\t\t\tthis.touchSession(sessionId);\n\t\t\t\tthis.sessionUpdateEmitter.emit(\"update\", notification);\n\n\t\t\t\tconst update = notification.update;\n\t\t\t\tif (update.sessionUpdate === \"current_mode_update\") {\n\t\t\t\t\trecord.modeId = update.currentModeId;\n\t\t\t\t\trecord.modeName =\n\t\t\t\t\t\trecord.availableModes?.find(\n\t\t\t\t\t\t\t(mode) => mode.id === update.currentModeId,\n\t\t\t\t\t\t)?.name ?? record.modeName;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (update.sessionUpdate === \"session_info_update\") {\n\t\t\t\t\tif (typeof update.title === \"string\") {\n\t\t\t\t\t\trecord.title = update.title;\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof update.updatedAt === \"string\") {\n\t\t\t\t\t\trecord.updatedAt = new Date(update.updatedAt);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (update.sessionUpdate === \"available_commands_update\") {\n\t\t\t\t\tif (update.availableCommands) {\n\t\t\t\t\t\trecord.availableCommands = update.availableCommands;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\n\t\trecord.unsubscribeTerminal = connection.onTerminalOutput((event) => {\n\t\t\tthis.terminalOutputEmitter.emit(\"output\", event);\n\t\t});\n\n\t\tconnection.onStatusChange((status) => {\n\t\t\tif (status.error) {\n\t\t\t\tthis.sessionErrorEmitter.emit(\"error\", {\n\t\t\t\t\tsessionId,\n\t\t\t\t\terror: status.error,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate buildSummary(record: SessionRecord): SessionSummary {\n\t\tconst status = record.connection.getStatus();\n\t\treturn {\n\t\t\tsessionId: record.sessionId,\n\t\t\ttitle: record.title,\n\t\t\tbackendId: record.backendId,\n\t\t\tbackendLabel: record.backendLabel,\n\t\t\tstate: status.state,\n\t\t\terror: status.error,\n\t\t\tpid: status.pid,\n\t\t\tcreatedAt: record.createdAt.toISOString(),\n\t\t\tupdatedAt: record.updatedAt.toISOString(),\n\t\t\tcwd: record.cwd,\n\t\t\tagentName: record.agentName,\n\t\t\tmodelId: record.modelId,\n\t\t\tmodelName: record.modelName,\n\t\t\tmodeId: record.modeId,\n\t\t\tmodeName: record.modeName,\n\t\t\tavailableModes: record.availableModes,\n\t\t\tavailableModels: record.availableModels,\n\t\t\tavailableCommands: record.availableCommands,\n\t\t};\n\t}\n}\n","export const createErrorDetail = (input) => ({\n ...input,\n});\nexport const withScope = (detail, scope) => createErrorDetail({\n ...detail,\n scope,\n});\nexport const createInternalError = (scope, detail) => createErrorDetail({\n code: \"INTERNAL_ERROR\",\n message: \"Internal server error\",\n retryable: true,\n scope,\n detail,\n});\nexport const isProtocolMismatch = (error) => {\n if (error instanceof Error) {\n return /protocol/i.test(error.message);\n }\n return false;\n};\nexport class AppError extends Error {\n detail;\n status;\n constructor(detail, status = 500) {\n super(detail.message);\n this.detail = detail;\n this.status = status;\n }\n}\nexport const isErrorDetail = (payload) => {\n if (!payload || typeof payload !== \"object\") {\n return false;\n }\n const detail = payload;\n return (typeof detail.code === \"string\" &&\n typeof detail.message === \"string\" &&\n typeof detail.retryable === \"boolean\" &&\n typeof detail.scope === \"string\");\n};\n","import { type ChildProcessWithoutNullStreams, spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { EventEmitter } from \"node:events\";\nimport { Readable, Writable } from \"node:stream\";\nimport {\n\ttype AgentCapabilities,\n\ttype Client,\n\tClientSideConnection,\n\ttype ContentBlock,\n\ttype CreateTerminalRequest,\n\ttype CreateTerminalResponse,\n\ttype Implementation,\n\ttype KillTerminalCommandRequest,\n\ttype KillTerminalCommandResponse,\n\ttype ListSessionsResponse,\n\ttype LoadSessionResponse,\n\ttype NewSessionResponse,\n\tndJsonStream,\n\tPROTOCOL_VERSION,\n\ttype PromptResponse,\n\ttype ReleaseTerminalRequest,\n\ttype ReleaseTerminalResponse,\n\ttype RequestPermissionRequest,\n\ttype RequestPermissionResponse,\n\ttype ResumeSessionResponse,\n\ttype SessionInfo,\n\ttype SessionNotification,\n\ttype TerminalExitStatus,\n\ttype TerminalOutputRequest,\n\ttype TerminalOutputResponse,\n\ttype WaitForTerminalExitRequest,\n\ttype WaitForTerminalExitResponse,\n} from \"@agentclientprotocol/sdk\";\nimport {\n\ttype AcpConnectionState,\n\ttype AgentSessionCapabilities,\n\tcreateErrorDetail,\n\ttype ErrorDetail,\n\tisProtocolMismatch,\n\ttype TerminalOutputEvent,\n} from \"@mobvibe/shared\";\nimport type { AcpBackendConfig } from \"../config.js\";\n\ntype ClientInfo = {\n\tname: string;\n\tversion: string;\n};\n\nexport type AcpBackendStatus = {\n\tbackendId: string;\n\tbackendLabel: string;\n\tstate: AcpConnectionState;\n\tcommand: string;\n\targs: string[];\n\tconnectedAt?: string;\n\terror?: ErrorDetail;\n\tsessionId?: string;\n\tpid?: number;\n};\n\nconst getErrorMessage = (error: unknown) => {\n\tif (error instanceof Error) {\n\t\treturn error.message;\n\t}\n\treturn String(error);\n};\n\ntype SessionUpdateListener = (notification: SessionNotification) => void;\n\ntype TerminalOutputSnapshot = {\n\toutput: string;\n\ttruncated: boolean;\n\texitStatus?: TerminalExitStatus | null;\n};\n\ntype TerminalRecord = {\n\tsessionId: string;\n\tcommand: string;\n\targs: string[];\n\toutputByteLimit: number;\n\toutput: TerminalOutputSnapshot;\n\tprocess?: ChildProcessWithoutNullStreams;\n\tonExit?: Promise<WaitForTerminalExitResponse>;\n\tresolveExit?: (response: WaitForTerminalExitResponse) => void;\n};\n\ntype ClientHandlers = {\n\tonSessionUpdate: (notification: SessionNotification) => void;\n\tonRequestPermission?: (\n\t\tparams: RequestPermissionRequest,\n\t) => Promise<RequestPermissionResponse>;\n\tonCreateTerminal?: (\n\t\tparams: CreateTerminalRequest,\n\t) => Promise<CreateTerminalResponse>;\n\tonTerminalOutput?: (\n\t\tparams: TerminalOutputRequest,\n\t) => Promise<TerminalOutputResponse>;\n\tonWaitForTerminalExit?: (\n\t\tparams: WaitForTerminalExitRequest,\n\t) => Promise<WaitForTerminalExitResponse>;\n\tonKillTerminal?: (\n\t\tparams: KillTerminalCommandRequest,\n\t) => Promise<KillTerminalCommandResponse>;\n\tonReleaseTerminal?: (\n\t\tparams: ReleaseTerminalRequest,\n\t) => Promise<ReleaseTerminalResponse>;\n};\n\nconst buildClient = (handlers: ClientHandlers): Client => ({\n\tasync requestPermission(params: RequestPermissionRequest) {\n\t\tif (handlers.onRequestPermission) {\n\t\t\treturn handlers.onRequestPermission(params);\n\t\t}\n\t\treturn { outcome: { outcome: \"cancelled\" } };\n\t},\n\tasync sessionUpdate(params: SessionNotification) {\n\t\thandlers.onSessionUpdate(params);\n\t},\n\tasync createTerminal(params: CreateTerminalRequest) {\n\t\tif (!handlers.onCreateTerminal) {\n\t\t\tthrow new Error(\"Terminal create handler not configured\");\n\t\t}\n\t\treturn handlers.onCreateTerminal(params);\n\t},\n\tasync terminalOutput(params: TerminalOutputRequest) {\n\t\tif (!handlers.onTerminalOutput) {\n\t\t\treturn { output: \"\", truncated: false };\n\t\t}\n\t\treturn handlers.onTerminalOutput(params);\n\t},\n\tasync waitForTerminalExit(params: WaitForTerminalExitRequest) {\n\t\tif (!handlers.onWaitForTerminalExit) {\n\t\t\treturn { exitCode: null, signal: null };\n\t\t}\n\t\treturn handlers.onWaitForTerminalExit(params);\n\t},\n\tasync killTerminal(params: KillTerminalCommandRequest) {\n\t\tif (!handlers.onKillTerminal) {\n\t\t\treturn {};\n\t\t}\n\t\treturn handlers.onKillTerminal(params);\n\t},\n\tasync releaseTerminal(params: ReleaseTerminalRequest) {\n\t\tif (!handlers.onReleaseTerminal) {\n\t\t\treturn {};\n\t\t}\n\t\treturn handlers.onReleaseTerminal(params);\n\t},\n});\n\nconst formatExitMessage = (\n\tcode: number | null,\n\tsignal: NodeJS.Signals | null,\n) => {\n\tif (signal) {\n\t\treturn `ACP process received signal ${signal}`;\n\t}\n\tif (code !== null) {\n\t\treturn `ACP process exited with code ${code}`;\n\t}\n\treturn \"ACP process exited\";\n};\n\nconst buildConnectError = (error: unknown): ErrorDetail => {\n\tconst detail = getErrorMessage(error);\n\tif (isProtocolMismatch(error)) {\n\t\treturn createErrorDetail({\n\t\t\tcode: \"ACP_PROTOCOL_MISMATCH\",\n\t\t\tmessage: \"ACP protocol version mismatch\",\n\t\t\tretryable: false,\n\t\t\tscope: \"service\",\n\t\t\tdetail,\n\t\t});\n\t}\n\treturn createErrorDetail({\n\t\tcode: \"ACP_CONNECT_FAILED\",\n\t\tmessage: \"Failed to connect to ACP backend process\",\n\t\tretryable: true,\n\t\tscope: \"service\",\n\t\tdetail,\n\t});\n};\n\nconst buildProcessExitError = (detail: string): ErrorDetail =>\n\tcreateErrorDetail({\n\t\tcode: \"ACP_PROCESS_EXITED\",\n\t\tmessage: \"ACP backend process exited unexpectedly\",\n\t\tretryable: true,\n\t\tscope: \"service\",\n\t\tdetail,\n\t});\n\nconst buildConnectionClosedError = (detail: string): ErrorDetail =>\n\tcreateErrorDetail({\n\t\tcode: \"ACP_CONNECTION_CLOSED\",\n\t\tmessage: \"ACP connection closed\",\n\t\tretryable: true,\n\t\tscope: \"service\",\n\t\tdetail,\n\t});\n\nconst normalizeOutputText = (value: string) => value.normalize(\"NFC\");\n\nconst isOutputOverLimit = (value: string, limit: number) =>\n\tBuffer.byteLength(value, \"utf8\") > limit;\n\nconst sliceOutputToLimit = (value: string, limit: number) => {\n\tconst buffer = Buffer.from(value, \"utf8\");\n\tif (buffer.byteLength <= limit) {\n\t\treturn value;\n\t}\n\tconst sliced = buffer.subarray(buffer.byteLength - limit);\n\tlet start = 0;\n\twhile (start < sliced.length && (sliced[start] & 0b11000000) === 0b10000000) {\n\t\tstart += 1;\n\t}\n\treturn sliced.subarray(start).toString(\"utf8\");\n};\n\nexport class AcpConnection {\n\tprivate connection?: ClientSideConnection;\n\tprivate process?: ChildProcessWithoutNullStreams;\n\tprivate closedPromise?: Promise<void>;\n\tprivate state: AcpConnectionState = \"idle\";\n\tprivate connectedAt?: Date;\n\tprivate error?: ErrorDetail;\n\tprivate sessionId?: string;\n\tprivate agentInfo?: Implementation;\n\tprivate agentCapabilities?: AgentCapabilities;\n\tprivate readonly sessionUpdateEmitter = new EventEmitter();\n\tprivate readonly statusEmitter = new EventEmitter();\n\tprivate readonly terminalOutputEmitter = new EventEmitter();\n\tprivate permissionHandler?: (\n\t\tparams: RequestPermissionRequest,\n\t) => Promise<RequestPermissionResponse>;\n\tprivate terminals = new Map<string, TerminalRecord>();\n\n\tconstructor(\n\t\tprivate readonly options: {\n\t\t\tbackend: AcpBackendConfig;\n\t\t\tclient: ClientInfo;\n\t\t},\n\t) {}\n\n\tgetStatus(): AcpBackendStatus {\n\t\treturn {\n\t\t\tbackendId: this.options.backend.id,\n\t\t\tbackendLabel: this.options.backend.label,\n\t\t\tstate: this.state,\n\t\t\tcommand: this.options.backend.command,\n\t\t\targs: [...this.options.backend.args],\n\t\t\tconnectedAt: this.connectedAt?.toISOString(),\n\t\t\terror: this.error,\n\t\t\tsessionId: this.sessionId,\n\t\t\tpid: this.process?.pid,\n\t\t};\n\t}\n\n\tgetAgentInfo(): Implementation | undefined {\n\t\treturn this.agentInfo;\n\t}\n\n\t/**\n\t * Get the agent's session capabilities.\n\t */\n\tgetSessionCapabilities(): AgentSessionCapabilities {\n\t\treturn {\n\t\t\tlist: this.agentCapabilities?.sessionCapabilities?.list != null,\n\t\t\tload: this.agentCapabilities?.loadSession === true,\n\t\t\tresume: this.agentCapabilities?.sessionCapabilities?.resume != null,\n\t\t};\n\t}\n\n\t/**\n\t * Check if the agent supports session/list.\n\t */\n\tsupportsSessionList(): boolean {\n\t\treturn this.agentCapabilities?.sessionCapabilities?.list != null;\n\t}\n\n\t/**\n\t * Check if the agent supports session/load.\n\t */\n\tsupportsSessionLoad(): boolean {\n\t\treturn this.agentCapabilities?.loadSession === true;\n\t}\n\n\t/**\n\t * Check if the agent supports session/resume.\n\t */\n\tsupportsSessionResume(): boolean {\n\t\treturn this.agentCapabilities?.sessionCapabilities?.resume != null;\n\t}\n\n\t/**\n\t * List sessions from the agent (session/list).\n\t * @param params Optional filter parameters\n\t * @returns List of session info from the agent\n\t */\n\tasync listSessions(params?: {\n\t\tcursor?: string;\n\t\tcwd?: string;\n\t}): Promise<SessionInfo[]> {\n\t\tif (!this.supportsSessionList()) {\n\t\t\treturn [];\n\t\t}\n\t\tconst connection = await this.ensureReady();\n\t\tconst response: ListSessionsResponse =\n\t\t\tawait connection.unstable_listSessions({\n\t\t\t\tcursor: params?.cursor ?? undefined,\n\t\t\t\tcwd: params?.cwd ?? undefined,\n\t\t\t});\n\t\treturn response.sessions;\n\t}\n\n\t/**\n\t * Load a historical session with message history replay (session/load).\n\t * @param sessionId The session ID to load\n\t * @param cwd The working directory\n\t * @returns Load session response with modes/models state\n\t */\n\tasync loadSession(\n\t\tsessionId: string,\n\t\tcwd: string,\n\t): Promise<LoadSessionResponse> {\n\t\tif (!this.supportsSessionLoad()) {\n\t\t\tthrow new Error(\"Agent does not support session/load capability\");\n\t\t}\n\t\tconst connection = await this.ensureReady();\n\t\tconst response = await connection.loadSession({\n\t\t\tsessionId,\n\t\t\tcwd,\n\t\t\tmcpServers: [],\n\t\t});\n\t\tthis.sessionId = sessionId;\n\t\treturn response;\n\t}\n\n\t/**\n\t * Resume an active session without message history replay (session/resume).\n\t * @param sessionId The session ID to resume\n\t * @param cwd The working directory\n\t * @returns Resume session response\n\t */\n\tasync resumeSession(\n\t\tsessionId: string,\n\t\tcwd: string,\n\t): Promise<ResumeSessionResponse> {\n\t\tif (!this.supportsSessionResume()) {\n\t\t\tthrow new Error(\"Agent does not support session/resume capability\");\n\t\t}\n\t\tconst connection = await this.ensureReady();\n\t\tconst response = await connection.unstable_resumeSession({\n\t\t\tsessionId,\n\t\t\tcwd,\n\t\t\tmcpServers: [],\n\t\t});\n\t\tthis.sessionId = sessionId;\n\t\treturn response;\n\t}\n\n\tsetPermissionHandler(\n\t\thandler?: (\n\t\t\tparams: RequestPermissionRequest,\n\t\t) => Promise<RequestPermissionResponse>,\n\t) {\n\t\tthis.permissionHandler = handler;\n\t}\n\n\tonTerminalOutput(listener: (payload: TerminalOutputEvent) => void) {\n\t\tthis.terminalOutputEmitter.on(\"output\", listener);\n\t\treturn () => {\n\t\t\tthis.terminalOutputEmitter.off(\"output\", listener);\n\t\t};\n\t}\n\n\tonSessionUpdate(listener: SessionUpdateListener) {\n\t\tthis.sessionUpdateEmitter.on(\"update\", listener);\n\t\treturn () => {\n\t\t\tthis.sessionUpdateEmitter.off(\"update\", listener);\n\t\t};\n\t}\n\n\tonStatusChange(listener: (status: AcpBackendStatus) => void) {\n\t\tthis.statusEmitter.on(\"status\", listener);\n\t\treturn () => {\n\t\t\tthis.statusEmitter.off(\"status\", listener);\n\t\t};\n\t}\n\n\tprivate updateStatus(state: AcpConnectionState, error?: ErrorDetail) {\n\t\tthis.state = state;\n\t\tthis.error = error;\n\t\tthis.statusEmitter.emit(\"status\", this.getStatus());\n\t}\n\n\tasync connect(): Promise<void> {\n\t\tif (this.state === \"connecting\" || this.state === \"ready\") {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.updateStatus(\"connecting\");\n\t\tthis.agentInfo = undefined;\n\n\t\ttry {\n\t\t\tconst env = this.options.backend.envOverrides\n\t\t\t\t? { ...process.env, ...this.options.backend.envOverrides }\n\t\t\t\t: process.env;\n\t\t\tconst child = spawn(\n\t\t\t\tthis.options.backend.command,\n\t\t\t\tthis.options.backend.args,\n\t\t\t\t{\n\t\t\t\t\tstdio: [\"pipe\", \"pipe\", \"pipe\"],\n\t\t\t\t\tenv,\n\t\t\t\t},\n\t\t\t);\n\t\t\tthis.process = child;\n\t\t\tthis.sessionId = undefined;\n\t\t\tchild.stderr.pipe(process.stderr);\n\n\t\t\tconst input = Writable.toWeb(child.stdin) as WritableStream<Uint8Array>;\n\t\t\tconst output = Readable.toWeb(child.stdout) as ReadableStream<Uint8Array>;\n\t\t\tconst stream = ndJsonStream(input, output);\n\t\t\tconst connection = new ClientSideConnection(\n\t\t\t\t() =>\n\t\t\t\t\tbuildClient({\n\t\t\t\t\t\tonSessionUpdate: (notification) =>\n\t\t\t\t\t\t\tthis.emitSessionUpdate(notification),\n\t\t\t\t\t\tonRequestPermission: (params) =>\n\t\t\t\t\t\t\tthis.handlePermissionRequest(params),\n\t\t\t\t\t\tonCreateTerminal: (params) => this.createTerminal(params),\n\t\t\t\t\t\tonTerminalOutput: (params) => this.getTerminalOutput(params),\n\t\t\t\t\t\tonWaitForTerminalExit: (params) => this.waitForTerminalExit(params),\n\t\t\t\t\t\tonKillTerminal: (params) => this.killTerminal(params),\n\t\t\t\t\t\tonReleaseTerminal: (params) => this.releaseTerminal(params),\n\t\t\t\t\t}),\n\t\t\t\tstream,\n\t\t\t);\n\t\t\tthis.connection = connection;\n\n\t\t\tchild.once(\"error\", (error) => {\n\t\t\t\tif (this.state === \"stopped\") {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.updateStatus(\"error\", buildConnectError(error));\n\t\t\t});\n\n\t\t\tchild.once(\"exit\", (code, signal) => {\n\t\t\t\tif (this.state === \"stopped\") {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.updateStatus(\n\t\t\t\t\t\"error\",\n\t\t\t\t\tbuildProcessExitError(formatExitMessage(code, signal)),\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tthis.closedPromise = connection.closed.catch((error) => {\n\t\t\t\tthis.updateStatus(\n\t\t\t\t\t\"error\",\n\t\t\t\t\tbuildConnectionClosedError(getErrorMessage(error)),\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tconst initializeResponse = await connection.initialize({\n\t\t\t\tprotocolVersion: PROTOCOL_VERSION,\n\t\t\t\tclientInfo: {\n\t\t\t\t\tname: this.options.client.name,\n\t\t\t\t\tversion: this.options.client.version,\n\t\t\t\t},\n\t\t\t\tclientCapabilities: { terminal: true },\n\t\t\t});\n\n\t\t\tthis.agentInfo = initializeResponse.agentInfo ?? undefined;\n\t\t\tthis.agentCapabilities =\n\t\t\t\tinitializeResponse.agentCapabilities ?? undefined;\n\t\t\tthis.connectedAt = new Date();\n\t\t\tthis.updateStatus(\"ready\");\n\t\t} catch (error) {\n\t\t\tthis.updateStatus(\"error\", buildConnectError(error));\n\t\t\tawait this.stopProcess();\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync createSession(options?: { cwd?: string }): Promise<NewSessionResponse> {\n\t\tconst connection = await this.ensureReady();\n\t\tconst response = await this.createSessionInternal(\n\t\t\tconnection,\n\t\t\toptions?.cwd ?? process.cwd(),\n\t\t);\n\t\tthis.sessionId = response.sessionId;\n\t\treturn response;\n\t}\n\n\tasync prompt(\n\t\tsessionId: string,\n\t\tprompt: ContentBlock[],\n\t): Promise<PromptResponse> {\n\t\tconst connection = await this.ensureReady();\n\t\treturn connection.prompt({ sessionId, prompt });\n\t}\n\n\tasync cancel(sessionId: string): Promise<void> {\n\t\tconst connection = await this.ensureReady();\n\t\tawait connection.cancel({ sessionId });\n\t}\n\n\tasync setSessionMode(sessionId: string, modeId: string): Promise<void> {\n\t\tconst connection = await this.ensureReady();\n\t\tawait connection.setSessionMode({ sessionId, modeId });\n\t}\n\n\tasync setSessionModel(sessionId: string, modelId: string): Promise<void> {\n\t\tconst connection = await this.ensureReady();\n\t\tawait connection.unstable_setSessionModel({ sessionId, modelId });\n\t}\n\n\tasync createTerminal(\n\t\tparams: CreateTerminalRequest,\n\t): Promise<CreateTerminalResponse> {\n\t\tconst outputLimit =\n\t\t\ttypeof params.outputByteLimit === \"number\" && params.outputByteLimit > 0\n\t\t\t\t? Math.floor(params.outputByteLimit)\n\t\t\t\t: 1024 * 1024;\n\t\tconst resolvedEnv = params.env\n\t\t\t? Object.fromEntries(\n\t\t\t\t\tparams.env.map((envVar) => [envVar.name, envVar.value]),\n\t\t\t\t)\n\t\t\t: undefined;\n\t\tconst terminalId = randomUUID();\n\t\tconst record: TerminalRecord = {\n\t\t\tsessionId: params.sessionId,\n\t\t\tcommand: params.command,\n\t\t\targs: params.args ?? [],\n\t\t\toutputByteLimit: outputLimit,\n\t\t\toutput: {\n\t\t\t\toutput: \"\",\n\t\t\t\ttruncated: false,\n\t\t\t\texitStatus: null,\n\t\t\t},\n\t\t};\n\t\tthis.terminals.set(terminalId, record);\n\n\t\tconst child = spawn(params.command, params.args ?? [], {\n\t\t\tcwd: params.cwd ?? undefined,\n\t\t\tenv: resolvedEnv ? { ...process.env, ...resolvedEnv } : process.env,\n\t\t});\n\t\tchild.once(\"error\", (error) => {\n\t\t\trecord.output.exitStatus = {\n\t\t\t\texitCode: null,\n\t\t\t\tsignal: null,\n\t\t\t};\n\t\t\trecord.resolveExit?.({ exitCode: null, signal: null });\n\t\t\tthis.terminalOutputEmitter.emit(\"output\", {\n\t\t\t\tsessionId: record.sessionId,\n\t\t\t\tterminalId,\n\t\t\t\tdelta: `\\n[terminal error] ${String(error)}`,\n\t\t\t\ttruncated: record.output.truncated,\n\t\t\t\toutput: record.output.output,\n\t\t\t\texitStatus: record.output.exitStatus,\n\t\t\t} satisfies TerminalOutputEvent);\n\t\t});\n\t\trecord.process = child;\n\t\tlet resolveExit: (response: WaitForTerminalExitResponse) => void = () => {};\n\t\trecord.onExit = new Promise<WaitForTerminalExitResponse>((resolve) => {\n\t\t\tresolveExit = resolve;\n\t\t});\n\t\trecord.resolveExit = resolveExit;\n\n\t\tconst handleChunk = (chunk: Buffer) => {\n\t\t\tconst delta = normalizeOutputText(chunk.toString(\"utf8\"));\n\t\t\tif (!delta) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst combinedOutput = record.output.output + delta;\n\t\t\trecord.output.truncated = isOutputOverLimit(\n\t\t\t\tcombinedOutput,\n\t\t\t\trecord.outputByteLimit,\n\t\t\t);\n\t\t\trecord.output.output = sliceOutputToLimit(\n\t\t\t\tcombinedOutput,\n\t\t\t\trecord.outputByteLimit,\n\t\t\t);\n\n\t\t\tthis.terminalOutputEmitter.emit(\"output\", {\n\t\t\t\tsessionId: record.sessionId,\n\t\t\t\tterminalId,\n\t\t\t\tdelta,\n\t\t\t\ttruncated: record.output.truncated,\n\t\t\t\toutput: record.output.truncated ? record.output.output : undefined,\n\t\t\t\texitStatus: record.output.exitStatus,\n\t\t\t} satisfies TerminalOutputEvent);\n\t\t};\n\n\t\tchild.stdout?.on(\"data\", handleChunk);\n\t\tchild.stderr?.on(\"data\", handleChunk);\n\t\tchild.on(\"exit\", (code, signal) => {\n\t\t\trecord.output.exitStatus = {\n\t\t\t\texitCode: code ?? null,\n\t\t\t\tsignal: signal ?? null,\n\t\t\t};\n\t\t\trecord.resolveExit?.({\n\t\t\t\texitCode: code ?? null,\n\t\t\t\tsignal: signal ?? null,\n\t\t\t});\n\t\t\tthis.terminalOutputEmitter.emit(\"output\", {\n\t\t\t\tsessionId: record.sessionId,\n\t\t\t\tterminalId,\n\t\t\t\tdelta: \"\",\n\t\t\t\ttruncated: record.output.truncated,\n\t\t\t\toutput: record.output.output,\n\t\t\t\texitStatus: record.output.exitStatus,\n\t\t\t} satisfies TerminalOutputEvent);\n\t\t});\n\n\t\treturn { terminalId };\n\t}\n\n\tasync getTerminalOutput(\n\t\tparams: TerminalOutputRequest,\n\t): Promise<TerminalOutputResponse> {\n\t\tconst record = this.terminals.get(params.terminalId);\n\t\tif (!record || record.sessionId !== params.sessionId) {\n\t\t\treturn { output: \"\", truncated: false };\n\t\t}\n\t\treturn record.output;\n\t}\n\n\tasync waitForTerminalExit(\n\t\tparams: WaitForTerminalExitRequest,\n\t): Promise<WaitForTerminalExitResponse> {\n\t\tconst record = this.terminals.get(params.terminalId);\n\t\tif (!record || record.sessionId !== params.sessionId) {\n\t\t\treturn Promise.resolve({ exitCode: null, signal: null });\n\t\t}\n\t\treturn record.onExit ?? Promise.resolve({ exitCode: null, signal: null });\n\t}\n\n\tasync killTerminal(\n\t\tparams: KillTerminalCommandRequest,\n\t): Promise<KillTerminalCommandResponse> {\n\t\tconst record = this.terminals.get(params.terminalId);\n\t\tif (!record || record.sessionId !== params.sessionId) {\n\t\t\treturn {};\n\t\t}\n\t\trecord.process?.kill(\"SIGTERM\");\n\t\treturn {};\n\t}\n\n\tasync releaseTerminal(\n\t\tparams: ReleaseTerminalRequest,\n\t): Promise<ReleaseTerminalResponse> {\n\t\tconst record = this.terminals.get(params.terminalId);\n\t\tif (record?.process && record.process.exitCode === null) {\n\t\t\trecord.process.kill(\"SIGTERM\");\n\t\t}\n\t\tthis.terminals.delete(params.terminalId);\n\t\treturn {};\n\t}\n\n\tasync disconnect(): Promise<void> {\n\t\tif (this.state === \"stopped\") {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.updateStatus(\"stopped\");\n\t\tthis.sessionId = undefined;\n\t\tthis.agentInfo = undefined;\n\t\tawait this.stopProcess();\n\t\tawait this.closedPromise;\n\t\tthis.connection = undefined;\n\t}\n\n\tprivate async ensureReady(): Promise<ClientSideConnection> {\n\t\tif (this.state !== \"ready\" || !this.connection) {\n\t\t\tawait this.connect();\n\t\t}\n\n\t\tif (!this.connection || this.state !== \"ready\") {\n\t\t\tthrow new Error(\"ACP connection not available\");\n\t\t}\n\n\t\treturn this.connection;\n\t}\n\n\tprivate async createSessionInternal(\n\t\tconnection: ClientSideConnection,\n\t\tcwd: string,\n\t): Promise<NewSessionResponse> {\n\t\tconst session = await connection.newSession({\n\t\t\tcwd,\n\t\t\tmcpServers: [],\n\t\t});\n\t\treturn session;\n\t}\n\n\tprivate emitSessionUpdate(notification: SessionNotification) {\n\t\tthis.sessionUpdateEmitter.emit(\"update\", notification);\n\t}\n\n\tprivate async handlePermissionRequest(\n\t\tparams: RequestPermissionRequest,\n\t): Promise<RequestPermissionResponse> {\n\t\tif (this.permissionHandler) {\n\t\t\treturn this.permissionHandler(params);\n\t\t}\n\t\treturn { outcome: { outcome: \"cancelled\" } };\n\t}\n\n\tprivate async stopProcess(): Promise<void> {\n\t\tconst child = this.process;\n\t\tif (!child) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.process = undefined;\n\t\tif (child.exitCode === null && !child.killed) {\n\t\t\tchild.kill(\"SIGTERM\");\n\t\t}\n\t}\n}\n","import { EventEmitter } from \"node:events\";\nimport fs from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport path from \"node:path\";\nimport type {\n\tCliToGatewayEvents,\n\tFsEntry,\n\tFsRoot,\n\tGatewayToCliEvents,\n\tHostFsRootsResponse,\n\tRpcResponse,\n\tSessionFsFilePreview,\n\tSessionFsResourceEntry,\n\tStopReason,\n} from \"@mobvibe/shared\";\nimport ignore, { type Ignore } from \"ignore\";\nimport { io, type Socket } from \"socket.io-client\";\nimport type { SessionManager } from \"../acp/session-manager.js\";\nimport type { CliConfig } from \"../config.js\";\nimport { logger } from \"../lib/logger.js\";\n\ntype SocketClientOptions = {\n\tconfig: CliConfig;\n\tsessionManager: SessionManager;\n\t/** API key for authentication (loaded from credentials) */\n\tapiKey: string;\n};\n\nconst SESSION_ROOT_NAME = \"Working Directory\";\nconst MAX_RESOURCE_FILES = 2000;\nconst DEFAULT_IGNORES = [\n\t\"node_modules\",\n\t\".git\",\n\t\"dist\",\n\t\"build\",\n\t\".next\",\n\t\".nuxt\",\n\t\".output\",\n\t\".cache\",\n\t\"__pycache__\",\n\t\".venv\",\n\t\"venv\",\n\t\"target\",\n];\n\nconst loadGitignore = async (rootPath: string): Promise<Ignore> => {\n\tconst ig = ignore().add(DEFAULT_IGNORES);\n\ttry {\n\t\tconst gitignorePath = path.join(rootPath, \".gitignore\");\n\t\tconst content = await fs.readFile(gitignorePath, \"utf8\");\n\t\tig.add(content);\n\t} catch {\n\t\t// No .gitignore file, use defaults only\n\t}\n\treturn ig;\n};\n\nconst resolveImageMimeType = (filePath: string) => {\n\tconst extension = path.extname(filePath).toLowerCase();\n\tswitch (extension) {\n\t\tcase \".apng\":\n\t\t\treturn \"image/apng\";\n\t\tcase \".avif\":\n\t\t\treturn \"image/avif\";\n\t\tcase \".gif\":\n\t\t\treturn \"image/gif\";\n\t\tcase \".jpeg\":\n\t\t\treturn \"image/jpeg\";\n\t\tcase \".jpg\":\n\t\t\treturn \"image/jpeg\";\n\t\tcase \".png\":\n\t\t\treturn \"image/png\";\n\t\tcase \".svg\":\n\t\t\treturn \"image/svg+xml\";\n\t\tcase \".webp\":\n\t\t\treturn \"image/webp\";\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n};\n\nconst readDirectoryEntries = async (dirPath: string): Promise<FsEntry[]> => {\n\tconst entries = await fs.readdir(dirPath, { withFileTypes: true });\n\tconst resolvedEntries = await Promise.all(\n\t\tentries.map(async (entry) => {\n\t\t\tconst entryPath = path.join(dirPath, entry.name);\n\t\t\tlet isDirectory = entry.isDirectory();\n\t\t\tif (!isDirectory && entry.isSymbolicLink()) {\n\t\t\t\ttry {\n\t\t\t\t\tconst stats = await fs.stat(entryPath);\n\t\t\t\t\tisDirectory = stats.isDirectory();\n\t\t\t\t} catch {\n\t\t\t\t\t// ignore broken symlink\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst entryType: FsEntry[\"type\"] = isDirectory ? \"directory\" : \"file\";\n\t\t\treturn {\n\t\t\t\tname: entry.name,\n\t\t\t\tpath: entryPath,\n\t\t\t\ttype: entryType,\n\t\t\t\thidden: entry.name.startsWith(\".\"),\n\t\t\t};\n\t\t}),\n\t);\n\treturn resolvedEntries.sort((left, right) => {\n\t\tif (left.type !== right.type) {\n\t\t\treturn left.type === \"directory\" ? -1 : 1;\n\t\t}\n\t\treturn left.name.localeCompare(right.name);\n\t});\n};\n\nconst filterVisibleEntries = (entries: FsEntry[]) =>\n\tentries.filter((entry) => !entry.hidden);\n\nconst buildHostFsRoots = async (): Promise<HostFsRootsResponse> => {\n\tconst homePath = homedir();\n\treturn {\n\t\thomePath,\n\t\troots: [{ name: \"Home\", path: homePath }],\n\t};\n};\n\nexport class SocketClient extends EventEmitter {\n\tprivate socket: Socket<GatewayToCliEvents, CliToGatewayEvents>;\n\tprivate connected = false;\n\tprivate reconnectAttempts = 0;\n\tprivate heartbeatInterval?: NodeJS.Timeout;\n\n\tconstructor(private readonly options: SocketClientOptions) {\n\t\tsuper();\n\t\tthis.socket = io(`${options.config.gatewayUrl}/cli`, {\n\t\t\tpath: \"/socket.io\",\n\t\t\treconnection: true,\n\t\t\treconnectionAttempts: Number.POSITIVE_INFINITY,\n\t\t\treconnectionDelay: 1000,\n\t\t\treconnectionDelayMax: 30000,\n\t\t\ttransports: [\"websocket\"],\n\t\t\tautoConnect: false,\n\t\t\textraHeaders: {\n\t\t\t\t\"x-api-key\": options.apiKey,\n\t\t\t},\n\t\t});\n\t\tthis.setupEventHandlers();\n\t\tthis.setupRpcHandlers();\n\t\tthis.setupSessionManagerListeners();\n\t}\n\n\tprivate setupEventHandlers() {\n\t\tthis.socket.on(\"connect\", () => {\n\t\t\tlogger.info(\n\t\t\t\t{ gatewayUrl: this.options.config.gatewayUrl },\n\t\t\t\t\"gateway_connected\",\n\t\t\t);\n\t\t\tthis.connected = true;\n\t\t\tthis.reconnectAttempts = 0;\n\t\t\tlogger.info(\"gateway_register_start\");\n\t\t\tthis.register();\n\t\t\tthis.startHeartbeat();\n\t\t\tthis.emit(\"connected\");\n\t\t});\n\n\t\tthis.socket.on(\"disconnect\", (reason) => {\n\t\t\tlogger.warn({ reason }, \"gateway_disconnected\");\n\t\t\tthis.connected = false;\n\t\t\tthis.stopHeartbeat();\n\t\t\tthis.emit(\"disconnected\", reason);\n\t\t});\n\n\t\tthis.socket.on(\"connect_error\", (error) => {\n\t\t\tthis.reconnectAttempts++;\n\t\t\tif (this.reconnectAttempts <= 3 || this.reconnectAttempts % 10 === 0) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{ attempt: this.reconnectAttempts, err: error },\n\t\t\t\t\t\"gateway_connect_error\",\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\n\t\tthis.socket.on(\"cli:registered\", async (info) => {\n\t\t\tlogger.info({ machineId: info.machineId }, \"gateway_registered\");\n\n\t\t\t// Auto-discover historical sessions from ACP agent\n\t\t\ttry {\n\t\t\t\tconst { sessions, capabilities } =\n\t\t\t\t\tawait this.options.sessionManager.discoverSessions();\n\n\t\t\t\tif (sessions.length > 0) {\n\t\t\t\t\tthis.socket.emit(\"sessions:discovered\", { sessions, capabilities });\n\t\t\t\t\tlogger.info(\n\t\t\t\t\t\t{ count: sessions.length, capabilities },\n\t\t\t\t\t\t\"historical_sessions_discovered\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tlogger.warn({ err: error }, \"session_discovery_failed\");\n\t\t\t}\n\t\t});\n\n\t\t// Handle authentication errors\n\t\tthis.socket.on(\"cli:error\", (error) => {\n\t\t\tlogger.error({ err: error }, \"gateway_auth_error\");\n\t\t\tthis.emit(\"auth_error\", error);\n\t\t});\n\t}\n\n\tprivate setupRpcHandlers() {\n\t\tconst { sessionManager } = this.options;\n\n\t\t// Session create\n\t\tthis.socket.on(\"rpc:session:create\", async (request) => {\n\t\t\ttry {\n\t\t\t\tlogger.info({ requestId: request.requestId }, \"rpc_session_create\");\n\t\t\t\tconst session = await sessionManager.createSession(request.params);\n\t\t\t\tthis.sendRpcResponse(request.requestId, session);\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{ err: error, requestId: request.requestId },\n\t\t\t\t\t\"rpc_session_create_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\t// Session close\n\t\tthis.socket.on(\"rpc:session:close\", async (request) => {\n\t\t\ttry {\n\t\t\t\tlogger.info(\n\t\t\t\t\t{ requestId: request.requestId, sessionId: request.params.sessionId },\n\t\t\t\t\t\"rpc_session_close\",\n\t\t\t\t);\n\t\t\t\tawait sessionManager.closeSession(request.params.sessionId);\n\t\t\t\tthis.sendRpcResponse(request.requestId, { ok: true });\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_session_close_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\t// Session cancel\n\t\tthis.socket.on(\"rpc:session:cancel\", async (request) => {\n\t\t\ttry {\n\t\t\t\tlogger.info(\n\t\t\t\t\t{ requestId: request.requestId, sessionId: request.params.sessionId },\n\t\t\t\t\t\"rpc_session_cancel\",\n\t\t\t\t);\n\t\t\t\tawait sessionManager.cancelSession(request.params.sessionId);\n\t\t\t\tthis.sendRpcResponse(request.requestId, { ok: true });\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_session_cancel_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\t// Session mode\n\t\tthis.socket.on(\"rpc:session:mode\", async (request) => {\n\t\t\ttry {\n\t\t\t\tlogger.info(\n\t\t\t\t\t{\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t\tmodeId: request.params.modeId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_session_mode\",\n\t\t\t\t);\n\t\t\t\tconst session = await sessionManager.setSessionMode(\n\t\t\t\t\trequest.params.sessionId,\n\t\t\t\t\trequest.params.modeId,\n\t\t\t\t);\n\t\t\t\tthis.sendRpcResponse(request.requestId, session);\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t\tmodeId: request.params.modeId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_session_mode_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\t// Session model\n\t\tthis.socket.on(\"rpc:session:model\", async (request) => {\n\t\t\ttry {\n\t\t\t\tlogger.info(\n\t\t\t\t\t{\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t\tmodelId: request.params.modelId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_session_model\",\n\t\t\t\t);\n\t\t\t\tconst session = await sessionManager.setSessionModel(\n\t\t\t\t\trequest.params.sessionId,\n\t\t\t\t\trequest.params.modelId,\n\t\t\t\t);\n\t\t\t\tthis.sendRpcResponse(request.requestId, session);\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t\tmodelId: request.params.modelId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_session_model_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\t// Send message\n\t\tthis.socket.on(\"rpc:message:send\", async (request) => {\n\t\t\tconst requestStart = process.hrtime.bigint();\n\t\t\ttry {\n\t\t\t\tconst { sessionId, prompt } = request.params;\n\t\t\t\tlogger.info(\n\t\t\t\t\t{\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId,\n\t\t\t\t\t\tpromptBlocks: prompt.length,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_message_send\",\n\t\t\t\t);\n\t\t\t\tlogger.debug(\n\t\t\t\t\t{\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId,\n\t\t\t\t\t\tpromptBlocks: prompt.length,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_message_send_start\",\n\t\t\t\t);\n\t\t\t\tconst record = sessionManager.getSession(sessionId);\n\t\t\t\tif (!record) {\n\t\t\t\t\tthrow new Error(\"Session not found\");\n\t\t\t\t}\n\t\t\t\tsessionManager.touchSession(sessionId);\n\t\t\t\t// Cast through unknown since SDK and shared ContentBlock types are structurally compatible\n\t\t\t\tconst result = await record.connection.prompt(\n\t\t\t\t\tsessionId,\n\t\t\t\t\tprompt as unknown as import(\"@agentclientprotocol/sdk\").ContentBlock[],\n\t\t\t\t);\n\t\t\t\tsessionManager.touchSession(sessionId);\n\t\t\t\tthis.sendRpcResponse<{ stopReason: StopReason }>(request.requestId, {\n\t\t\t\t\tstopReason: result.stopReason as StopReason,\n\t\t\t\t});\n\t\t\t\tconst durationMs =\n\t\t\t\t\tNumber(process.hrtime.bigint() - requestStart) / 1_000_000;\n\t\t\t\tlogger.info(\n\t\t\t\t\t{\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId,\n\t\t\t\t\t\tstopReason: result.stopReason,\n\t\t\t\t\t\tdurationMs,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_message_send_complete\",\n\t\t\t\t);\n\t\t\t\tlogger.debug(\n\t\t\t\t\t{\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId,\n\t\t\t\t\t\tdurationMs,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_message_send_finish\",\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\tconst durationMs =\n\t\t\t\t\tNumber(process.hrtime.bigint() - requestStart) / 1_000_000;\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t\tpromptBlocks: request.params.prompt.length,\n\t\t\t\t\t\tdurationMs,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_message_send_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\t// Permission decision\n\t\tthis.socket.on(\"rpc:permission:decision\", async (request) => {\n\t\t\ttry {\n\t\t\t\tconst { sessionId, requestId, outcome } = request.params;\n\t\t\t\tlogger.info(\n\t\t\t\t\t{ requestId: request.requestId, sessionId, outcome },\n\t\t\t\t\t\"rpc_permission_decision\",\n\t\t\t\t);\n\t\t\t\tsessionManager.resolvePermissionRequest(sessionId, requestId, outcome);\n\t\t\t\tthis.sendRpcResponse(request.requestId, { ok: true });\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t\tpermissionRequestId: request.params.requestId,\n\t\t\t\t\t\toutcome: request.params.outcome,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_permission_decision_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\t// File system handlers\n\t\tthis.socket.on(\"rpc:fs:roots\", async (request) => {\n\t\t\ttry {\n\t\t\t\tlogger.debug(\n\t\t\t\t\t{ requestId: request.requestId, sessionId: request.params.sessionId },\n\t\t\t\t\t\"rpc_fs_roots\",\n\t\t\t\t);\n\t\t\t\tconst record = sessionManager.getSession(request.params.sessionId);\n\t\t\t\tif (!record || !record.cwd) {\n\t\t\t\t\tthrow new Error(\"Session not found or no working directory\");\n\t\t\t\t}\n\t\t\t\tconst root: FsRoot = {\n\t\t\t\t\tname: SESSION_ROOT_NAME,\n\t\t\t\t\tpath: record.cwd,\n\t\t\t\t};\n\t\t\t\tthis.sendRpcResponse(request.requestId, { root });\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_fs_roots_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\tthis.socket.on(\"rpc:hostfs:roots\", async (request) => {\n\t\t\ttry {\n\t\t\t\tlogger.debug(\n\t\t\t\t\t{\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tmachineId: request.params.machineId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_hostfs_roots\",\n\t\t\t\t);\n\t\t\t\tconst result = await buildHostFsRoots();\n\t\t\t\tthis.sendRpcResponse(request.requestId, result);\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tmachineId: request.params.machineId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_hostfs_roots_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\tthis.socket.on(\"rpc:hostfs:entries\", async (request) => {\n\t\t\ttry {\n\t\t\t\tconst { path: requestPath, machineId } = request.params;\n\t\t\t\tlogger.debug(\n\t\t\t\t\t{ requestId: request.requestId, machineId, path: requestPath },\n\t\t\t\t\t\"rpc_hostfs_entries\",\n\t\t\t\t);\n\t\t\t\tconst entries = await readDirectoryEntries(requestPath);\n\t\t\t\tthis.sendRpcResponse(request.requestId, {\n\t\t\t\t\tpath: requestPath,\n\t\t\t\t\tentries: filterVisibleEntries(entries),\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tmachineId: request.params.machineId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_hostfs_entries_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\tthis.socket.on(\"rpc:fs:entries\", async (request) => {\n\t\t\ttry {\n\t\t\t\tconst { sessionId, path: requestPath } = request.params;\n\t\t\t\tlogger.debug(\n\t\t\t\t\t{ requestId: request.requestId, sessionId, path: requestPath },\n\t\t\t\t\t\"rpc_fs_entries\",\n\t\t\t\t);\n\t\t\t\tconst record = sessionManager.getSession(sessionId);\n\t\t\t\tif (!record || !record.cwd) {\n\t\t\t\t\tthrow new Error(\"Session not found or no working directory\");\n\t\t\t\t}\n\t\t\t\tconst resolved = requestPath\n\t\t\t\t\t? path.isAbsolute(requestPath)\n\t\t\t\t\t\t? requestPath\n\t\t\t\t\t\t: path.join(record.cwd, requestPath)\n\t\t\t\t\t: record.cwd;\n\t\t\t\tconst entries = await readDirectoryEntries(resolved);\n\t\t\t\tthis.sendRpcResponse(request.requestId, { path: resolved, entries });\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_fs_entries_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\tthis.socket.on(\"rpc:fs:file\", async (request) => {\n\t\t\ttry {\n\t\t\t\tconst { sessionId, path: requestPath } = request.params;\n\t\t\t\tlogger.debug(\n\t\t\t\t\t{ requestId: request.requestId, sessionId, path: requestPath },\n\t\t\t\t\t\"rpc_fs_file\",\n\t\t\t\t);\n\t\t\t\tconst record = sessionManager.getSession(sessionId);\n\t\t\t\tif (!record || !record.cwd) {\n\t\t\t\t\tthrow new Error(\"Session not found or no working directory\");\n\t\t\t\t}\n\t\t\t\tconst resolved = path.isAbsolute(requestPath)\n\t\t\t\t\t? requestPath\n\t\t\t\t\t: path.join(record.cwd, requestPath);\n\t\t\t\tconst mimeType = resolveImageMimeType(resolved);\n\t\t\t\tif (mimeType) {\n\t\t\t\t\tconst buffer = await fs.readFile(resolved);\n\t\t\t\t\tconst preview: SessionFsFilePreview = {\n\t\t\t\t\t\tpath: resolved,\n\t\t\t\t\t\tpreviewType: \"image\",\n\t\t\t\t\t\tcontent: `data:${mimeType};base64,${buffer.toString(\"base64\")}`,\n\t\t\t\t\t\tmimeType,\n\t\t\t\t\t};\n\t\t\t\t\tthis.sendRpcResponse(request.requestId, preview);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst content = await fs.readFile(resolved, \"utf8\");\n\t\t\t\tconst preview: SessionFsFilePreview = {\n\t\t\t\t\tpath: resolved,\n\t\t\t\t\tpreviewType: \"code\",\n\t\t\t\t\tcontent,\n\t\t\t\t};\n\t\t\t\tthis.sendRpcResponse(request.requestId, preview);\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_fs_file_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\tthis.socket.on(\"rpc:fs:resources\", async (request) => {\n\t\t\ttry {\n\t\t\t\tconst { sessionId } = request.params;\n\t\t\t\tlogger.debug(\n\t\t\t\t\t{ requestId: request.requestId, sessionId },\n\t\t\t\t\t\"rpc_fs_resources\",\n\t\t\t\t);\n\t\t\t\tconst record = sessionManager.getSession(sessionId);\n\t\t\t\tif (!record || !record.cwd) {\n\t\t\t\t\tthrow new Error(\"Session not found or no working directory\");\n\t\t\t\t}\n\t\t\t\tconst entries = await this.listSessionResources(record.cwd);\n\t\t\t\tthis.sendRpcResponse(request.requestId, {\n\t\t\t\t\trootPath: record.cwd,\n\t\t\t\t\tentries,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_fs_resources_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\t// Session discovery - list sessions from ACP agent\n\t\tthis.socket.on(\"rpc:sessions:discover\", async (request) => {\n\t\t\ttry {\n\t\t\t\tconst { cwd, backendId } = request.params;\n\t\t\t\tlogger.info(\n\t\t\t\t\t{ requestId: request.requestId, cwd, backendId },\n\t\t\t\t\t\"rpc_sessions_discover\",\n\t\t\t\t);\n\t\t\t\tconst result = await sessionManager.discoverSessions({\n\t\t\t\t\tcwd,\n\t\t\t\t\tbackendId,\n\t\t\t\t});\n\t\t\t\tthis.sendRpcResponse(request.requestId, result);\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_sessions_discover_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\t// Load historical session from ACP agent\n\t\tthis.socket.on(\"rpc:session:load\", async (request) => {\n\t\t\ttry {\n\t\t\t\tconst { sessionId, cwd } = request.params;\n\t\t\t\tlogger.info(\n\t\t\t\t\t{ requestId: request.requestId, sessionId, cwd },\n\t\t\t\t\t\"rpc_session_load\",\n\t\t\t\t);\n\t\t\t\tconst session = await sessionManager.loadSession(sessionId, cwd);\n\t\t\t\tthis.sendRpcResponse(request.requestId, session);\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_session_load_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\t// Resume active session from ACP agent\n\t\tthis.socket.on(\"rpc:session:resume\", async (request) => {\n\t\t\ttry {\n\t\t\t\tconst { sessionId, cwd } = request.params;\n\t\t\t\tlogger.info(\n\t\t\t\t\t{ requestId: request.requestId, sessionId, cwd },\n\t\t\t\t\t\"rpc_session_resume\",\n\t\t\t\t);\n\t\t\t\tconst session = await sessionManager.resumeSession(sessionId, cwd);\n\t\t\t\tthis.sendRpcResponse(request.requestId, session);\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_session_resume_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate setupSessionManagerListeners() {\n\t\tconst { sessionManager } = this.options;\n\n\t\tsessionManager.onSessionUpdate((notification) => {\n\t\t\tif (this.connected) {\n\t\t\t\t// Cast through unknown since SDK and shared SessionNotification types are structurally compatible\n\t\t\t\tthis.socket.emit(\n\t\t\t\t\t\"session:update\",\n\t\t\t\t\tnotification as unknown as import(\"@mobvibe/shared\").SessionNotification,\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\n\t\tsessionManager.onSessionError((payload) => {\n\t\t\tif (this.connected) {\n\t\t\t\tthis.socket.emit(\"session:error\", payload);\n\t\t\t}\n\t\t});\n\n\t\tsessionManager.onPermissionRequest((payload) => {\n\t\t\tif (this.connected) {\n\t\t\t\tthis.socket.emit(\"permission:request\", payload);\n\t\t\t}\n\t\t});\n\n\t\tsessionManager.onPermissionResult((payload) => {\n\t\t\tif (this.connected) {\n\t\t\t\tthis.socket.emit(\"permission:result\", payload);\n\t\t\t}\n\t\t});\n\n\t\tsessionManager.onTerminalOutput((event) => {\n\t\t\tif (this.connected) {\n\t\t\t\tthis.socket.emit(\"terminal:output\", event);\n\t\t\t}\n\t\t});\n\n\t\tsessionManager.onSessionsChanged((payload) => {\n\t\t\tif (this.connected) {\n\t\t\t\tlogger.info(\n\t\t\t\t\t{\n\t\t\t\t\t\tadded: payload.added.length,\n\t\t\t\t\t\tupdated: payload.updated.length,\n\t\t\t\t\t\tremoved: payload.removed.length,\n\t\t\t\t\t},\n\t\t\t\t\t\"sessions_changed_emit\",\n\t\t\t\t);\n\t\t\t\tthis.socket.emit(\"sessions:changed\", payload);\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate async listSessionResources(\n\t\trootPath: string,\n\t): Promise<SessionFsResourceEntry[]> {\n\t\tconst ig = await loadGitignore(rootPath);\n\t\tconst allFiles = await this.listAllFiles(rootPath, ig, rootPath, []);\n\t\treturn allFiles.map((filePath) => ({\n\t\t\tname: path.basename(filePath),\n\t\t\trelativePath: path.relative(rootPath, filePath),\n\t\t\tpath: filePath,\n\t\t}));\n\t}\n\n\tprivate async listAllFiles(\n\t\trootPath: string,\n\t\tig: Ignore,\n\t\tbaseDir: string,\n\t\tcollected: string[] = [],\n\t): Promise<string[]> {\n\t\tif (collected.length >= MAX_RESOURCE_FILES) {\n\t\t\treturn collected;\n\t\t}\n\t\tconst entries = await fs.readdir(rootPath, { withFileTypes: true });\n\t\tfor (const entry of entries) {\n\t\t\tif (collected.length >= MAX_RESOURCE_FILES) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tconst entryPath = path.join(rootPath, entry.name);\n\t\t\tconst relativePath = path.relative(baseDir, entryPath);\n\n\t\t\t// Check gitignore (add trailing slash for directories)\n\t\t\tconst checkPath = entry.isDirectory() ? `${relativePath}/` : relativePath;\n\t\t\tif (ig.ignores(checkPath)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tawait this.listAllFiles(entryPath, ig, baseDir, collected);\n\t\t\t} else if (entry.isFile()) {\n\t\t\t\tcollected.push(entryPath);\n\t\t\t}\n\t\t}\n\t\treturn collected;\n\t}\n\n\tprivate sendRpcResponse<T>(requestId: string, result: T) {\n\t\tconst response: RpcResponse<T> = { requestId, result };\n\t\tthis.socket.emit(\"rpc:response\", response);\n\t\tlogger.debug({ requestId }, \"rpc_response_sent\");\n\t}\n\n\tprivate sendRpcError(requestId: string, error: unknown) {\n\t\tconst message = error instanceof Error ? error.message : \"Unknown error\";\n\t\tconst detail = error instanceof Error ? error.stack : undefined;\n\t\tlogger.error(\n\t\t\t{\n\t\t\t\trequestId,\n\t\t\t\terr: error,\n\t\t\t\tmessage,\n\t\t\t\tdetail,\n\t\t\t},\n\t\t\t\"rpc_response_error_sent\",\n\t\t);\n\t\tconst response: RpcResponse<unknown> = {\n\t\t\trequestId,\n\t\t\terror: {\n\t\t\t\tcode: \"INTERNAL_ERROR\",\n\t\t\t\tmessage,\n\t\t\t\tretryable: true,\n\t\t\t\tscope: \"request\",\n\t\t\t\tdetail,\n\t\t\t},\n\t\t};\n\t\tthis.socket.emit(\"rpc:response\", response);\n\t}\n\n\tprivate register() {\n\t\tconst { config, sessionManager } = this.options;\n\t\tlogger.info({ machineId: config.machineId }, \"cli_register_emit\");\n\t\tthis.socket.emit(\"cli:register\", {\n\t\t\tmachineId: config.machineId,\n\t\t\thostname: config.hostname,\n\t\t\tversion: config.clientVersion,\n\t\t\tbackends: config.acpBackends.map((backend) => ({\n\t\t\t\tbackendId: backend.id,\n\t\t\t\tbackendLabel: backend.label,\n\t\t\t})),\n\t\t\tdefaultBackendId: config.defaultAcpBackendId,\n\t\t});\n\t\tlogger.info({ machineId: config.machineId }, \"cli_register_sessions_list\");\n\t\t// Send current sessions list\n\t\tthis.socket.emit(\"sessions:list\", sessionManager.listSessions());\n\t}\n\n\tprivate startHeartbeat() {\n\t\tthis.stopHeartbeat();\n\t\tthis.heartbeatInterval = setInterval(() => {\n\t\t\tif (this.connected) {\n\t\t\t\tthis.socket.emit(\"cli:heartbeat\");\n\t\t\t\tthis.socket.emit(\n\t\t\t\t\t\"sessions:list\",\n\t\t\t\t\tthis.options.sessionManager.listSessions(),\n\t\t\t\t);\n\t\t\t}\n\t\t}, 30000);\n\t}\n\n\tprivate stopHeartbeat() {\n\t\tif (this.heartbeatInterval) {\n\t\t\tclearInterval(this.heartbeatInterval);\n\t\t\tthis.heartbeatInterval = undefined;\n\t\t}\n\t}\n\n\tconnect() {\n\t\tthis.socket.connect();\n\t}\n\n\tdisconnect() {\n\t\tthis.stopHeartbeat();\n\t\tthis.socket.disconnect();\n\t}\n\n\tisConnected() {\n\t\treturn this.connected;\n\t}\n}\n"],"mappings":";AAAA,SAAS,eAAe;;;ACKxB,YAAY,cAAc;;;ACL1B,OAAO,UAAU;AAEjB,IAAM,YAAY,QAAQ,IAAI,aAAa;AAC3C,IAAM,WAAW,QAAQ,IAAI,aAAa;AAE1C,IAAM,SAAS;AAAA,EACd,OAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AAAA,EACA,QAAQ;AACT;AAEA,IAAM,YAAY,WACf;AAAA,EACA,QAAQ;AAAA,EACR,SAAS;AAAA,IACR,UAAU;AAAA,IACV,eAAe;AAAA,IACf,QAAQ;AAAA,EACT;AACD,IACC;AAEI,IAAM,SAAS;AAAA,EACrB;AAAA,IACC,OAAO;AAAA,IACP;AAAA,IACA,MAAM,EAAE,SAAS,cAAc;AAAA,IAC/B,aAAa;AAAA,MACZ,KAAK,KAAK,eAAe;AAAA,MACzB,OAAO,KAAK,eAAe;AAAA,IAC5B;AAAA,EACD;AAAA,EACA,YAAY,KAAK,UAAU,SAAS,IAAI;AACzC;;;ACpCA,OAAO,QAAQ;AACf,OAAO,QAAQ;AACf,OAAO,UAAU;AAWjB,IAAM,cACL,QAAQ,IAAI,gBAAgB,KAAK,KAAK,GAAG,QAAQ,GAAG,UAAU;AAC/D,IAAM,mBAAmB,KAAK,KAAK,aAAa,kBAAkB;AAKlE,eAAe,mBAAkC;AAChD,QAAM,GAAG,MAAM,aAAa,EAAE,WAAW,KAAK,CAAC;AAChD;AAMA,eAAsB,kBAA+C;AACpE,MAAI;AACH,UAAM,OAAO,MAAM,GAAG,SAAS,kBAAkB,MAAM;AACvD,UAAM,cAAc,KAAK,MAAM,IAAI;AAGnC,QAAI,CAAC,YAAY,QAAQ;AACxB,aAAO;AAAA,IACR;AAEA,WAAO;AAAA,EACR,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAKA,eAAsB,gBAAgB,aAAyC;AAC9E,QAAM,iBAAiB;AACvB,QAAM,GAAG;AAAA,IACR;AAAA,IACA,KAAK,UAAU,aAAa,MAAM,CAAC;AAAA,IACnC,EAAE,MAAM,IAAM;AAAA;AAAA,EACf;AACD;AAKA,eAAsB,oBAAmC;AACxD,MAAI;AACH,UAAM,GAAG,OAAO,gBAAgB;AAAA,EACjC,QAAQ;AAAA,EAER;AACD;AAcA,eAAsB,YAAyC;AAE9D,MAAI,QAAQ,IAAI,iBAAiB;AAChC,WAAO,QAAQ,IAAI;AAAA,EACpB;AAEA,QAAM,cAAc,MAAM,gBAAgB;AAC1C,SAAO,aAAa;AACrB;AAGA,IAAM,sBAAsB;AAQ5B,eAAsB,gBAAiC;AAEtD,MAAI,QAAQ,IAAI,qBAAqB;AACpC,WAAO,QAAQ,IAAI;AAAA,EACpB;AAGA,QAAM,cAAc,MAAM,gBAAgB;AAC1C,MAAI,aAAa,YAAY;AAC5B,WAAO,YAAY;AAAA,EACpB;AAGA,SAAO;AACR;;;AF9FA,eAAsB,QAA8B;AACnD,SAAO,KAAK,oBAAoB;AAChC,UAAQ,IAAI,oBAAoB;AAChC,UAAQ,IAAI,6CAA6C;AACzD,UAAQ,IAAI,6CAA6C;AACzD,UAAQ,IAAI,yCAAyC;AACrD,UAAQ,IAAI,gCAAgC;AAE5C,QAAM,KAAc,yBAAgB;AAAA,IACnC,OAAO,QAAQ;AAAA,IACf,QAAQ,QAAQ;AAAA,EACjB,CAAC;AAED,MAAI;AACH,UAAM,SAAS,MAAM,GAAG,SAAS,sBAAsB;AAEvD,QAAI,CAAC,OAAO,KAAK,GAAG;AACnB,aAAO,KAAK,uBAAuB;AACnC,aAAO,EAAE,SAAS,OAAO,OAAO,sBAAsB;AAAA,IACvD;AAGA,QAAI,CAAC,OAAO,KAAK,EAAE,WAAW,MAAM,GAAG;AACtC,aAAO,KAAK,8BAA8B;AAC1C,aAAO;AAAA,QACN,SAAS;AAAA,QACT,OAAO;AAAA,MACR;AAAA,IACD;AAGA,UAAM,cAA2B;AAAA,MAChC,QAAQ,OAAO,KAAK;AAAA,MACpB,WAAW,KAAK,IAAI;AAAA,IACrB;AACA,UAAM,gBAAgB,WAAW;AACjC,WAAO,KAAK,yBAAyB;AAErC,YAAQ,IAAI,kBAAkB;AAC9B,YAAQ,IAAI,gDAAgD;AAE5D,WAAO,EAAE,SAAS,KAAK;AAAA,EACxB,UAAE;AACD,OAAG,MAAM;AAAA,EACV;AACD;AAKA,eAAsB,SAAwB;AAC7C,QAAM,kBAAkB;AACxB,SAAO,KAAK,iBAAiB;AAC7B,UAAQ,IAAI,+CAA+C;AAC5D;AAKA,eAAsB,cAA6B;AAClD,QAAM,cAAc,MAAM,gBAAgB;AAC1C,MAAI,aAAa;AAChB,WAAO,KAAK,wBAAwB;AACpC,YAAQ,IAAI,mBAAmB;AAC/B,YAAQ,IAAI,YAAY,YAAY,OAAO,MAAM,GAAG,EAAE,CAAC,KAAK;AAC5D,YAAQ,IAAI,UAAU,IAAI,KAAK,YAAY,SAAS,EAAE,eAAe,CAAC,EAAE;AAAA,EACzE,OAAO;AACN,WAAO,KAAK,yBAAyB;AACrC,YAAQ,IAAI,uBAAuB;AACnC,YAAQ,IAAI,sCAAsC;AAAA,EACnD;AACD;;;AG9FA,OAAOA,SAAQ;AACf,OAAOC,WAAU;;;ACDjB,OAAOC,SAAQ;AACf,OAAOC,WAAU;AASjB,IAAM,kBAAkB;AAExB,IAAM,sBAAsB,CAC3B,OACA,UACyD;AACzD,QAAM,SAAmB,CAAC;AAC1B,QAAM,SAAS,UAAU,KAAK;AAE9B,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAChD,WAAO,KAAK,GAAG,MAAM,qBAAqB;AAC1C,WAAO,EAAE,OAAO,MAAM,OAAO;AAAA,EAC9B;AAEA,QAAM,SAAS;AAGf,MAAI,OAAO,OAAO,OAAO,YAAY,OAAO,GAAG,KAAK,EAAE,WAAW,GAAG;AACnE,WAAO,KAAK,GAAG,MAAM,iCAAiC;AACtD,WAAO,EAAE,OAAO,MAAM,OAAO;AAAA,EAC9B;AAGA,MACC,OAAO,OAAO,YAAY,YAC1B,OAAO,QAAQ,KAAK,EAAE,WAAW,GAChC;AACD,WAAO,KAAK,GAAG,MAAM,sCAAsC;AAC3D,WAAO,EAAE,OAAO,MAAM,OAAO;AAAA,EAC9B;AAEA,QAAM,YAA6B;AAAA,IAClC,IAAI,OAAO,GAAG,KAAK;AAAA,IACnB,SAAS,OAAO,QAAQ,KAAK;AAAA,EAC9B;AAGA,MAAI,OAAO,UAAU,QAAW;AAC/B,QAAI,OAAO,OAAO,UAAU,UAAU;AACrC,aAAO,KAAK,GAAG,MAAM,0BAA0B;AAAA,IAChD,WAAW,OAAO,MAAM,KAAK,EAAE,SAAS,GAAG;AAC1C,gBAAU,QAAQ,OAAO,MAAM,KAAK;AAAA,IACrC;AAAA,EACD;AAGA,MAAI,OAAO,SAAS,QAAW;AAC9B,QAAI,CAAC,MAAM,QAAQ,OAAO,IAAI,GAAG;AAChC,aAAO,KAAK,GAAG,MAAM,oCAAoC;AAAA,IAC1D,OAAO;AACN,YAAM,YAAY,OAAO,KAAK,OAAO,CAAC,QAAuB;AAC5D,YAAI,OAAO,QAAQ,UAAU;AAC5B,iBAAO,KAAK,GAAG,MAAM,qCAAqC;AAC1D,iBAAO;AAAA,QACR;AACA,eAAO;AAAA,MACR,CAAC;AACD,UAAI,UAAU,SAAS,GAAG;AACzB,kBAAU,OAAO;AAAA,MAClB;AAAA,IACD;AAAA,EACD;AAGA,MAAI,OAAO,QAAQ,QAAW;AAC7B,QAAI,OAAO,OAAO,QAAQ,YAAY,OAAO,QAAQ,MAAM;AAC1D,aAAO,KAAK,GAAG,MAAM,yBAAyB;AAAA,IAC/C,OAAO;AACN,YAAM,YAAY,OAAO;AACzB,YAAM,WAAmC,CAAC;AAC1C,UAAI,SAAS;AACb,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,SAAS,GAAG;AACrD,YAAI,OAAO,UAAU,UAAU;AAC9B,iBAAO,KAAK,GAAG,MAAM,QAAQ,GAAG,oBAAoB;AAAA,QACrD,OAAO;AACN,mBAAS,GAAG,IAAI;AAChB,mBAAS;AAAA,QACV;AAAA,MACD;AACA,UAAI,QAAQ;AACX,kBAAU,MAAM;AAAA,MACjB;AAAA,IACD;AAAA,EACD;AAGA,MAAI,OAAO,SAAS,GAAG;AACtB,WAAO,EAAE,OAAO,MAAM,OAAO;AAAA,EAC9B;AAEA,SAAO,EAAE,OAAO,WAAW,QAAQ,CAAC,EAAE;AACvC;AAEA,IAAM,qBAAqB,CAC1B,SAC4D;AAC5D,QAAM,SAAmB,CAAC;AAE1B,MAAI,OAAO,SAAS,YAAY,SAAS,MAAM;AAC9C,WAAO,KAAK,2BAA2B;AACvC,WAAO,EAAE,QAAQ,MAAM,OAAO;AAAA,EAC/B;AAEA,QAAM,SAAS;AACf,QAAM,SAA4B,CAAC;AAGnC,MAAI,OAAO,WAAW,QAAW;AAChC,QAAI,CAAC,MAAM,QAAQ,OAAO,MAAM,GAAG;AAClC,aAAO,KAAK,0BAA0B;AAAA,IACvC,OAAO;AACN,YAAM,cAAiC,CAAC;AACxC,YAAM,UAAU,oBAAI,IAAY;AAEhC,eAAS,IAAI,GAAG,IAAI,OAAO,OAAO,QAAQ,KAAK;AAC9C,cAAM,SAAS,oBAAoB,OAAO,OAAO,CAAC,GAAG,CAAC;AACtD,eAAO,KAAK,GAAG,OAAO,MAAM;AAE5B,YAAI,OAAO,OAAO;AACjB,cAAI,QAAQ,IAAI,OAAO,MAAM,EAAE,GAAG;AACjC,mBAAO,KAAK,UAAU,CAAC,uBAAuB,OAAO,MAAM,EAAE,GAAG;AAAA,UACjE,OAAO;AACN,oBAAQ,IAAI,OAAO,MAAM,EAAE;AAC3B,wBAAY,KAAK,OAAO,KAAK;AAAA,UAC9B;AAAA,QACD;AAAA,MACD;AAEA,UAAI,YAAY,SAAS,GAAG;AAC3B,eAAO,SAAS;AAAA,MACjB;AAAA,IACD;AAAA,EACD;AAGA,MAAI,OAAO,mBAAmB,QAAW;AACxC,QAAI,OAAO,OAAO,mBAAmB,UAAU;AAC9C,aAAO,KAAK,kCAAkC;AAAA,IAC/C,WAAW,OAAO,eAAe,KAAK,EAAE,SAAS,GAAG;AACnD,aAAO,iBAAiB,OAAO,eAAe,KAAK;AAAA,IACpD;AAAA,EACD;AAEA,MAAI,OAAO,SAAS,GAAG;AACtB,WAAO,EAAE,QAAQ,MAAM,OAAO;AAAA,EAC/B;AAEA,SAAO,EAAE,QAAQ,QAAQ,CAAC,EAAE;AAC7B;AAEO,IAAM,iBAAiB,OAC7B,aAC+B;AAC/B,QAAM,aAAaA,MAAK,KAAK,UAAU,eAAe;AACtD,UAAQ,IAAI,iCAAiC,UAAU,EAAE;AAEzD,MAAI;AACH,UAAM,UAAU,MAAMD,IAAG,SAAS,YAAY,OAAO;AACrD,QAAI;AAEJ,QAAI;AACH,eAAS,KAAK,MAAM,OAAO;AAAA,IAC5B,QAAQ;AACP,cAAQ,IAAI,yCAAyC,UAAU,EAAE;AACjE,aAAO;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ,CAAC,6BAA6B;AAAA,QACtC,MAAM;AAAA,MACP;AAAA,IACD;AAEA,UAAM,EAAE,QAAQ,OAAO,IAAI,mBAAmB,MAAM;AAEpD,QAAI,OAAO,SAAS,GAAG;AACtB,cAAQ,IAAI,+BAA+B,MAAM;AAAA,IAClD;AAEA,QAAI,QAAQ;AACX,cAAQ,IAAI,2BAA2B,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,IACvE;AAEA,WAAO,EAAE,QAAQ,QAAQ,MAAM,WAAW;AAAA,EAC3C,SAAS,OAAO;AAEf,QAAI,iBAAiB,SAAS,UAAU,SAAS,MAAM,SAAS,UAAU;AACzE,cAAQ,IAAI,qCAAqC,UAAU,EAAE;AAC7D,aAAO,EAAE,QAAQ,MAAM,QAAQ,CAAC,GAAG,MAAM,WAAW;AAAA,IACrD;AAGA,UAAM,UACL,iBAAiB,QAAQ,MAAM,UAAU;AAC1C,YAAQ,IAAI,kCAAkC,OAAO,EAAE;AACvD,WAAO,EAAE,QAAQ,MAAM,QAAQ,CAAC,OAAO,GAAG,MAAM,WAAW;AAAA,EAC5D;AACD;;;AD7KA,IAAM,2BAA6C;AAAA,EAClD,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM,CAAC,KAAK;AACb;AAEA,IAAM,oBAAoB,MAAc;AACvC,QAAM,WAAWE,IAAG,SAAS;AAC7B,QAAM,WAAWA,IAAG,SAAS;AAC7B,QAAM,OAAOA,IAAG,KAAK;AACrB,QAAM,WAAWA,IAAG,SAAS,EAAE;AAC/B,SAAO,GAAG,QAAQ,IAAI,QAAQ,IAAI,IAAI,IAAI,QAAQ;AACnD;AAEA,IAAM,2BAA2B,CAChC,WACuB;AAAA,EACvB,IAAI,MAAM;AAAA,EACV,OAAO,MAAM,SAAS,MAAM;AAAA,EAC5B,SAAS,MAAM;AAAA,EACf,MAAM,MAAM,QAAQ,CAAC;AAAA,EACrB,cAAc,MAAM;AACrB;AAEA,IAAM,gBAAgB,CACrB,gBACA,eAC+D;AAE/D,MAAI,CAAC,cAAc,WAAW,WAAW,GAAG;AAC3C,WAAO,EAAE,UAAU,CAAC,cAAc,GAAG,WAAW,eAAe,GAAG;AAAA,EACnE;AAGA,QAAM,eAAe,WAAW,KAAK,CAAC,MAAM,EAAE,OAAO,UAAU;AAE/D,MAAI,cAAc;AAEjB,WAAO;AAAA,MACN,UAAU,WAAW,IAAI,wBAAwB;AAAA,MACjD,WAAW,WAAW,CAAC,EAAE;AAAA,IAC1B;AAAA,EACD;AAGA,SAAO;AAAA,IACN,UAAU,CAAC,gBAAgB,GAAG,WAAW,IAAI,wBAAwB,CAAC;AAAA,IACtE,WAAW,eAAe;AAAA,EAC3B;AACD;AAEO,IAAM,eAAe,YAAgC;AAC3D,QAAM,MAAM,QAAQ;AACpB,QAAM,WAAW,IAAI,gBAAgBC,MAAK,KAAKD,IAAG,QAAQ,GAAG,UAAU;AAGvE,QAAM,mBAAmB,MAAM,eAAe,QAAQ;AAGtD,MAAI,iBAAiB,OAAO,SAAS,GAAG;AACvC,eAAW,SAAS,iBAAiB,QAAQ;AAC5C,aAAO,KAAK,EAAE,YAAY,iBAAiB,MAAM,MAAM,GAAG,cAAc;AAAA,IACzE;AAAA,EACD;AAGA,QAAM,EAAE,UAAU,UAAU,IAAI;AAAA,IAC/B;AAAA,IACA,iBAAiB,QAAQ;AAAA,EAC1B;AAGA,QAAM,oBACL,iBAAiB,QAAQ,kBACzB,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,iBAAiB,QAAQ,cAAc,IAClE,iBAAiB,OAAO,iBACxB;AAGJ,QAAM,aAAa,MAAM,cAAc;AAEvC,SAAO;AAAA,IACN;AAAA,IACA,aAAa;AAAA,IACb,qBAAqB;AAAA,IACrB,YAAY,IAAI,2BAA2B;AAAA,IAC3C,eAAe,IAAI,8BAA8B;AAAA,IACjD;AAAA,IACA,SAASC,MAAK,KAAK,UAAU,MAAM;AAAA,IACnC,SAASA,MAAK,KAAK,UAAU,YAAY;AAAA,IACzC,WAAW,IAAI,sBAAsB,kBAAkB;AAAA,IACvD,UAAUD,IAAG,SAAS;AAAA,IACtB,UAAUA,IAAG,SAAS;AAAA,IACtB,gBAAgB,iBAAiB;AAAA,IACjC,kBACC,iBAAiB,OAAO,SAAS,IAAI,iBAAiB,SAAS;AAAA,EACjE;AACD;;;AElIA,SAAS,SAAAE,cAAa;AACtB,OAAOC,SAAQ;AACf,OAAOC,WAAU;;;ACFjB,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,gBAAAC,qBAAoB;;;ACDtB,IAAM,oBAAoB,CAAC,WAAW;AAAA,EACzC,GAAG;AACP;AAYO,IAAM,qBAAqB,CAAC,UAAU;AACzC,MAAI,iBAAiB,OAAO;AACxB,WAAO,YAAY,KAAK,MAAM,OAAO;AAAA,EACzC;AACA,SAAO;AACX;AACO,IAAM,WAAN,cAAuB,MAAM;AAAA,EAChC;AAAA,EACA;AAAA,EACA,YAAY,QAAQ,SAAS,KAAK;AAC9B,UAAM,OAAO,OAAO;AACpB,SAAK,SAAS;AACd,SAAK,SAAS;AAAA,EAClB;AACJ;;;AC5BA,SAA8C,aAAa;AAC3D,SAAS,kBAAkB;AAC3B,SAAS,oBAAoB;AAC7B,SAAS,UAAU,gBAAgB;AACnC;AAAA,EAGC;AAAA,EAUA;AAAA,EACA;AAAA,OAcM;AA4BP,IAAM,kBAAkB,CAAC,UAAmB;AAC3C,MAAI,iBAAiB,OAAO;AAC3B,WAAO,MAAM;AAAA,EACd;AACA,SAAO,OAAO,KAAK;AACpB;AA2CA,IAAM,cAAc,CAAC,cAAsC;AAAA,EAC1D,MAAM,kBAAkB,QAAkC;AACzD,QAAI,SAAS,qBAAqB;AACjC,aAAO,SAAS,oBAAoB,MAAM;AAAA,IAC3C;AACA,WAAO,EAAE,SAAS,EAAE,SAAS,YAAY,EAAE;AAAA,EAC5C;AAAA,EACA,MAAM,cAAc,QAA6B;AAChD,aAAS,gBAAgB,MAAM;AAAA,EAChC;AAAA,EACA,MAAM,eAAe,QAA+B;AACnD,QAAI,CAAC,SAAS,kBAAkB;AAC/B,YAAM,IAAI,MAAM,wCAAwC;AAAA,IACzD;AACA,WAAO,SAAS,iBAAiB,MAAM;AAAA,EACxC;AAAA,EACA,MAAM,eAAe,QAA+B;AACnD,QAAI,CAAC,SAAS,kBAAkB;AAC/B,aAAO,EAAE,QAAQ,IAAI,WAAW,MAAM;AAAA,IACvC;AACA,WAAO,SAAS,iBAAiB,MAAM;AAAA,EACxC;AAAA,EACA,MAAM,oBAAoB,QAAoC;AAC7D,QAAI,CAAC,SAAS,uBAAuB;AACpC,aAAO,EAAE,UAAU,MAAM,QAAQ,KAAK;AAAA,IACvC;AACA,WAAO,SAAS,sBAAsB,MAAM;AAAA,EAC7C;AAAA,EACA,MAAM,aAAa,QAAoC;AACtD,QAAI,CAAC,SAAS,gBAAgB;AAC7B,aAAO,CAAC;AAAA,IACT;AACA,WAAO,SAAS,eAAe,MAAM;AAAA,EACtC;AAAA,EACA,MAAM,gBAAgB,QAAgC;AACrD,QAAI,CAAC,SAAS,mBAAmB;AAChC,aAAO,CAAC;AAAA,IACT;AACA,WAAO,SAAS,kBAAkB,MAAM;AAAA,EACzC;AACD;AAEA,IAAM,oBAAoB,CACzB,MACA,WACI;AACJ,MAAI,QAAQ;AACX,WAAO,+BAA+B,MAAM;AAAA,EAC7C;AACA,MAAI,SAAS,MAAM;AAClB,WAAO,gCAAgC,IAAI;AAAA,EAC5C;AACA,SAAO;AACR;AAEA,IAAM,oBAAoB,CAAC,UAAgC;AAC1D,QAAM,SAAS,gBAAgB,KAAK;AACpC,MAAI,mBAAmB,KAAK,GAAG;AAC9B,WAAO,kBAAkB;AAAA,MACxB,MAAM;AAAA,MACN,SAAS;AAAA,MACT,WAAW;AAAA,MACX,OAAO;AAAA,MACP;AAAA,IACD,CAAC;AAAA,EACF;AACA,SAAO,kBAAkB;AAAA,IACxB,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,OAAO;AAAA,IACP;AAAA,EACD,CAAC;AACF;AAEA,IAAM,wBAAwB,CAAC,WAC9B,kBAAkB;AAAA,EACjB,MAAM;AAAA,EACN,SAAS;AAAA,EACT,WAAW;AAAA,EACX,OAAO;AAAA,EACP;AACD,CAAC;AAEF,IAAM,6BAA6B,CAAC,WACnC,kBAAkB;AAAA,EACjB,MAAM;AAAA,EACN,SAAS;AAAA,EACT,WAAW;AAAA,EACX,OAAO;AAAA,EACP;AACD,CAAC;AAEF,IAAM,sBAAsB,CAAC,UAAkB,MAAM,UAAU,KAAK;AAEpE,IAAM,oBAAoB,CAAC,OAAe,UACzC,OAAO,WAAW,OAAO,MAAM,IAAI;AAEpC,IAAM,qBAAqB,CAAC,OAAe,UAAkB;AAC5D,QAAM,SAAS,OAAO,KAAK,OAAO,MAAM;AACxC,MAAI,OAAO,cAAc,OAAO;AAC/B,WAAO;AAAA,EACR;AACA,QAAM,SAAS,OAAO,SAAS,OAAO,aAAa,KAAK;AACxD,MAAI,QAAQ;AACZ,SAAO,QAAQ,OAAO,WAAW,OAAO,KAAK,IAAI,SAAgB,KAAY;AAC5E,aAAS;AAAA,EACV;AACA,SAAO,OAAO,SAAS,KAAK,EAAE,SAAS,MAAM;AAC9C;AAEO,IAAM,gBAAN,MAAoB;AAAA,EAkB1B,YACkB,SAIhB;AAJgB;AAAA,EAIf;AAAA,EAtBK;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAA4B;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACS,uBAAuB,IAAI,aAAa;AAAA,EACxC,gBAAgB,IAAI,aAAa;AAAA,EACjC,wBAAwB,IAAI,aAAa;AAAA,EAClD;AAAA,EAGA,YAAY,oBAAI,IAA4B;AAAA,EASpD,YAA8B;AAC7B,WAAO;AAAA,MACN,WAAW,KAAK,QAAQ,QAAQ;AAAA,MAChC,cAAc,KAAK,QAAQ,QAAQ;AAAA,MACnC,OAAO,KAAK;AAAA,MACZ,SAAS,KAAK,QAAQ,QAAQ;AAAA,MAC9B,MAAM,CAAC,GAAG,KAAK,QAAQ,QAAQ,IAAI;AAAA,MACnC,aAAa,KAAK,aAAa,YAAY;AAAA,MAC3C,OAAO,KAAK;AAAA,MACZ,WAAW,KAAK;AAAA,MAChB,KAAK,KAAK,SAAS;AAAA,IACpB;AAAA,EACD;AAAA,EAEA,eAA2C;AAC1C,WAAO,KAAK;AAAA,EACb;AAAA;AAAA;AAAA;AAAA,EAKA,yBAAmD;AAClD,WAAO;AAAA,MACN,MAAM,KAAK,mBAAmB,qBAAqB,QAAQ;AAAA,MAC3D,MAAM,KAAK,mBAAmB,gBAAgB;AAAA,MAC9C,QAAQ,KAAK,mBAAmB,qBAAqB,UAAU;AAAA,IAChE;AAAA,EACD;AAAA;AAAA;AAAA;AAAA,EAKA,sBAA+B;AAC9B,WAAO,KAAK,mBAAmB,qBAAqB,QAAQ;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA,EAKA,sBAA+B;AAC9B,WAAO,KAAK,mBAAmB,gBAAgB;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA,EAKA,wBAAiC;AAChC,WAAO,KAAK,mBAAmB,qBAAqB,UAAU;AAAA,EAC/D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,aAAa,QAGQ;AAC1B,QAAI,CAAC,KAAK,oBAAoB,GAAG;AAChC,aAAO,CAAC;AAAA,IACT;AACA,UAAM,aAAa,MAAM,KAAK,YAAY;AAC1C,UAAM,WACL,MAAM,WAAW,sBAAsB;AAAA,MACtC,QAAQ,QAAQ,UAAU;AAAA,MAC1B,KAAK,QAAQ,OAAO;AAAA,IACrB,CAAC;AACF,WAAO,SAAS;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,YACL,WACA,KAC+B;AAC/B,QAAI,CAAC,KAAK,oBAAoB,GAAG;AAChC,YAAM,IAAI,MAAM,gDAAgD;AAAA,IACjE;AACA,UAAM,aAAa,MAAM,KAAK,YAAY;AAC1C,UAAM,WAAW,MAAM,WAAW,YAAY;AAAA,MAC7C;AAAA,MACA;AAAA,MACA,YAAY,CAAC;AAAA,IACd,CAAC;AACD,SAAK,YAAY;AACjB,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,cACL,WACA,KACiC;AACjC,QAAI,CAAC,KAAK,sBAAsB,GAAG;AAClC,YAAM,IAAI,MAAM,kDAAkD;AAAA,IACnE;AACA,UAAM,aAAa,MAAM,KAAK,YAAY;AAC1C,UAAM,WAAW,MAAM,WAAW,uBAAuB;AAAA,MACxD;AAAA,MACA;AAAA,MACA,YAAY,CAAC;AAAA,IACd,CAAC;AACD,SAAK,YAAY;AACjB,WAAO;AAAA,EACR;AAAA,EAEA,qBACC,SAGC;AACD,SAAK,oBAAoB;AAAA,EAC1B;AAAA,EAEA,iBAAiB,UAAkD;AAClE,SAAK,sBAAsB,GAAG,UAAU,QAAQ;AAChD,WAAO,MAAM;AACZ,WAAK,sBAAsB,IAAI,UAAU,QAAQ;AAAA,IAClD;AAAA,EACD;AAAA,EAEA,gBAAgB,UAAiC;AAChD,SAAK,qBAAqB,GAAG,UAAU,QAAQ;AAC/C,WAAO,MAAM;AACZ,WAAK,qBAAqB,IAAI,UAAU,QAAQ;AAAA,IACjD;AAAA,EACD;AAAA,EAEA,eAAe,UAA8C;AAC5D,SAAK,cAAc,GAAG,UAAU,QAAQ;AACxC,WAAO,MAAM;AACZ,WAAK,cAAc,IAAI,UAAU,QAAQ;AAAA,IAC1C;AAAA,EACD;AAAA,EAEQ,aAAa,OAA2B,OAAqB;AACpE,SAAK,QAAQ;AACb,SAAK,QAAQ;AACb,SAAK,cAAc,KAAK,UAAU,KAAK,UAAU,CAAC;AAAA,EACnD;AAAA,EAEA,MAAM,UAAyB;AAC9B,QAAI,KAAK,UAAU,gBAAgB,KAAK,UAAU,SAAS;AAC1D;AAAA,IACD;AAEA,SAAK,aAAa,YAAY;AAC9B,SAAK,YAAY;AAEjB,QAAI;AACH,YAAM,MAAM,KAAK,QAAQ,QAAQ,eAC9B,EAAE,GAAG,QAAQ,KAAK,GAAG,KAAK,QAAQ,QAAQ,aAAa,IACvD,QAAQ;AACX,YAAM,QAAQ;AAAA,QACb,KAAK,QAAQ,QAAQ;AAAA,QACrB,KAAK,QAAQ,QAAQ;AAAA,QACrB;AAAA,UACC,OAAO,CAAC,QAAQ,QAAQ,MAAM;AAAA,UAC9B;AAAA,QACD;AAAA,MACD;AACA,WAAK,UAAU;AACf,WAAK,YAAY;AACjB,YAAM,OAAO,KAAK,QAAQ,MAAM;AAEhC,YAAM,QAAQ,SAAS,MAAM,MAAM,KAAK;AACxC,YAAM,SAAS,SAAS,MAAM,MAAM,MAAM;AAC1C,YAAM,SAAS,aAAa,OAAO,MAAM;AACzC,YAAM,aAAa,IAAI;AAAA,QACtB,MACC,YAAY;AAAA,UACX,iBAAiB,CAAC,iBACjB,KAAK,kBAAkB,YAAY;AAAA,UACpC,qBAAqB,CAAC,WACrB,KAAK,wBAAwB,MAAM;AAAA,UACpC,kBAAkB,CAAC,WAAW,KAAK,eAAe,MAAM;AAAA,UACxD,kBAAkB,CAAC,WAAW,KAAK,kBAAkB,MAAM;AAAA,UAC3D,uBAAuB,CAAC,WAAW,KAAK,oBAAoB,MAAM;AAAA,UAClE,gBAAgB,CAAC,WAAW,KAAK,aAAa,MAAM;AAAA,UACpD,mBAAmB,CAAC,WAAW,KAAK,gBAAgB,MAAM;AAAA,QAC3D,CAAC;AAAA,QACF;AAAA,MACD;AACA,WAAK,aAAa;AAElB,YAAM,KAAK,SAAS,CAAC,UAAU;AAC9B,YAAI,KAAK,UAAU,WAAW;AAC7B;AAAA,QACD;AACA,aAAK,aAAa,SAAS,kBAAkB,KAAK,CAAC;AAAA,MACpD,CAAC;AAED,YAAM,KAAK,QAAQ,CAAC,MAAM,WAAW;AACpC,YAAI,KAAK,UAAU,WAAW;AAC7B;AAAA,QACD;AACA,aAAK;AAAA,UACJ;AAAA,UACA,sBAAsB,kBAAkB,MAAM,MAAM,CAAC;AAAA,QACtD;AAAA,MACD,CAAC;AAED,WAAK,gBAAgB,WAAW,OAAO,MAAM,CAAC,UAAU;AACvD,aAAK;AAAA,UACJ;AAAA,UACA,2BAA2B,gBAAgB,KAAK,CAAC;AAAA,QAClD;AAAA,MACD,CAAC;AAED,YAAM,qBAAqB,MAAM,WAAW,WAAW;AAAA,QACtD,iBAAiB;AAAA,QACjB,YAAY;AAAA,UACX,MAAM,KAAK,QAAQ,OAAO;AAAA,UAC1B,SAAS,KAAK,QAAQ,OAAO;AAAA,QAC9B;AAAA,QACA,oBAAoB,EAAE,UAAU,KAAK;AAAA,MACtC,CAAC;AAED,WAAK,YAAY,mBAAmB,aAAa;AACjD,WAAK,oBACJ,mBAAmB,qBAAqB;AACzC,WAAK,cAAc,oBAAI,KAAK;AAC5B,WAAK,aAAa,OAAO;AAAA,IAC1B,SAAS,OAAO;AACf,WAAK,aAAa,SAAS,kBAAkB,KAAK,CAAC;AACnD,YAAM,KAAK,YAAY;AACvB,YAAM;AAAA,IACP;AAAA,EACD;AAAA,EAEA,MAAM,cAAc,SAAyD;AAC5E,UAAM,aAAa,MAAM,KAAK,YAAY;AAC1C,UAAM,WAAW,MAAM,KAAK;AAAA,MAC3B;AAAA,MACA,SAAS,OAAO,QAAQ,IAAI;AAAA,IAC7B;AACA,SAAK,YAAY,SAAS;AAC1B,WAAO;AAAA,EACR;AAAA,EAEA,MAAM,OACL,WACA,QAC0B;AAC1B,UAAM,aAAa,MAAM,KAAK,YAAY;AAC1C,WAAO,WAAW,OAAO,EAAE,WAAW,OAAO,CAAC;AAAA,EAC/C;AAAA,EAEA,MAAM,OAAO,WAAkC;AAC9C,UAAM,aAAa,MAAM,KAAK,YAAY;AAC1C,UAAM,WAAW,OAAO,EAAE,UAAU,CAAC;AAAA,EACtC;AAAA,EAEA,MAAM,eAAe,WAAmB,QAA+B;AACtE,UAAM,aAAa,MAAM,KAAK,YAAY;AAC1C,UAAM,WAAW,eAAe,EAAE,WAAW,OAAO,CAAC;AAAA,EACtD;AAAA,EAEA,MAAM,gBAAgB,WAAmB,SAAgC;AACxE,UAAM,aAAa,MAAM,KAAK,YAAY;AAC1C,UAAM,WAAW,yBAAyB,EAAE,WAAW,QAAQ,CAAC;AAAA,EACjE;AAAA,EAEA,MAAM,eACL,QACkC;AAClC,UAAM,cACL,OAAO,OAAO,oBAAoB,YAAY,OAAO,kBAAkB,IACpE,KAAK,MAAM,OAAO,eAAe,IACjC,OAAO;AACX,UAAM,cAAc,OAAO,MACxB,OAAO;AAAA,MACP,OAAO,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,MAAM,OAAO,KAAK,CAAC;AAAA,IACvD,IACC;AACH,UAAM,aAAa,WAAW;AAC9B,UAAM,SAAyB;AAAA,MAC9B,WAAW,OAAO;AAAA,MAClB,SAAS,OAAO;AAAA,MAChB,MAAM,OAAO,QAAQ,CAAC;AAAA,MACtB,iBAAiB;AAAA,MACjB,QAAQ;AAAA,QACP,QAAQ;AAAA,QACR,WAAW;AAAA,QACX,YAAY;AAAA,MACb;AAAA,IACD;AACA,SAAK,UAAU,IAAI,YAAY,MAAM;AAErC,UAAM,QAAQ,MAAM,OAAO,SAAS,OAAO,QAAQ,CAAC,GAAG;AAAA,MACtD,KAAK,OAAO,OAAO;AAAA,MACnB,KAAK,cAAc,EAAE,GAAG,QAAQ,KAAK,GAAG,YAAY,IAAI,QAAQ;AAAA,IACjE,CAAC;AACD,UAAM,KAAK,SAAS,CAAC,UAAU;AAC9B,aAAO,OAAO,aAAa;AAAA,QAC1B,UAAU;AAAA,QACV,QAAQ;AAAA,MACT;AACA,aAAO,cAAc,EAAE,UAAU,MAAM,QAAQ,KAAK,CAAC;AACrD,WAAK,sBAAsB,KAAK,UAAU;AAAA,QACzC,WAAW,OAAO;AAAA,QAClB;AAAA,QACA,OAAO;AAAA,mBAAsB,OAAO,KAAK,CAAC;AAAA,QAC1C,WAAW,OAAO,OAAO;AAAA,QACzB,QAAQ,OAAO,OAAO;AAAA,QACtB,YAAY,OAAO,OAAO;AAAA,MAC3B,CAA+B;AAAA,IAChC,CAAC;AACD,WAAO,UAAU;AACjB,QAAI,cAA+D,MAAM;AAAA,IAAC;AAC1E,WAAO,SAAS,IAAI,QAAqC,CAAC,YAAY;AACrE,oBAAc;AAAA,IACf,CAAC;AACD,WAAO,cAAc;AAErB,UAAM,cAAc,CAAC,UAAkB;AACtC,YAAM,QAAQ,oBAAoB,MAAM,SAAS,MAAM,CAAC;AACxD,UAAI,CAAC,OAAO;AACX;AAAA,MACD;AACA,YAAM,iBAAiB,OAAO,OAAO,SAAS;AAC9C,aAAO,OAAO,YAAY;AAAA,QACzB;AAAA,QACA,OAAO;AAAA,MACR;AACA,aAAO,OAAO,SAAS;AAAA,QACtB;AAAA,QACA,OAAO;AAAA,MACR;AAEA,WAAK,sBAAsB,KAAK,UAAU;AAAA,QACzC,WAAW,OAAO;AAAA,QAClB;AAAA,QACA;AAAA,QACA,WAAW,OAAO,OAAO;AAAA,QACzB,QAAQ,OAAO,OAAO,YAAY,OAAO,OAAO,SAAS;AAAA,QACzD,YAAY,OAAO,OAAO;AAAA,MAC3B,CAA+B;AAAA,IAChC;AAEA,UAAM,QAAQ,GAAG,QAAQ,WAAW;AACpC,UAAM,QAAQ,GAAG,QAAQ,WAAW;AACpC,UAAM,GAAG,QAAQ,CAAC,MAAM,WAAW;AAClC,aAAO,OAAO,aAAa;AAAA,QAC1B,UAAU,QAAQ;AAAA,QAClB,QAAQ,UAAU;AAAA,MACnB;AACA,aAAO,cAAc;AAAA,QACpB,UAAU,QAAQ;AAAA,QAClB,QAAQ,UAAU;AAAA,MACnB,CAAC;AACD,WAAK,sBAAsB,KAAK,UAAU;AAAA,QACzC,WAAW,OAAO;AAAA,QAClB;AAAA,QACA,OAAO;AAAA,QACP,WAAW,OAAO,OAAO;AAAA,QACzB,QAAQ,OAAO,OAAO;AAAA,QACtB,YAAY,OAAO,OAAO;AAAA,MAC3B,CAA+B;AAAA,IAChC,CAAC;AAED,WAAO,EAAE,WAAW;AAAA,EACrB;AAAA,EAEA,MAAM,kBACL,QACkC;AAClC,UAAM,SAAS,KAAK,UAAU,IAAI,OAAO,UAAU;AACnD,QAAI,CAAC,UAAU,OAAO,cAAc,OAAO,WAAW;AACrD,aAAO,EAAE,QAAQ,IAAI,WAAW,MAAM;AAAA,IACvC;AACA,WAAO,OAAO;AAAA,EACf;AAAA,EAEA,MAAM,oBACL,QACuC;AACvC,UAAM,SAAS,KAAK,UAAU,IAAI,OAAO,UAAU;AACnD,QAAI,CAAC,UAAU,OAAO,cAAc,OAAO,WAAW;AACrD,aAAO,QAAQ,QAAQ,EAAE,UAAU,MAAM,QAAQ,KAAK,CAAC;AAAA,IACxD;AACA,WAAO,OAAO,UAAU,QAAQ,QAAQ,EAAE,UAAU,MAAM,QAAQ,KAAK,CAAC;AAAA,EACzE;AAAA,EAEA,MAAM,aACL,QACuC;AACvC,UAAM,SAAS,KAAK,UAAU,IAAI,OAAO,UAAU;AACnD,QAAI,CAAC,UAAU,OAAO,cAAc,OAAO,WAAW;AACrD,aAAO,CAAC;AAAA,IACT;AACA,WAAO,SAAS,KAAK,SAAS;AAC9B,WAAO,CAAC;AAAA,EACT;AAAA,EAEA,MAAM,gBACL,QACmC;AACnC,UAAM,SAAS,KAAK,UAAU,IAAI,OAAO,UAAU;AACnD,QAAI,QAAQ,WAAW,OAAO,QAAQ,aAAa,MAAM;AACxD,aAAO,QAAQ,KAAK,SAAS;AAAA,IAC9B;AACA,SAAK,UAAU,OAAO,OAAO,UAAU;AACvC,WAAO,CAAC;AAAA,EACT;AAAA,EAEA,MAAM,aAA4B;AACjC,QAAI,KAAK,UAAU,WAAW;AAC7B;AAAA,IACD;AAEA,SAAK,aAAa,SAAS;AAC3B,SAAK,YAAY;AACjB,SAAK,YAAY;AACjB,UAAM,KAAK,YAAY;AACvB,UAAM,KAAK;AACX,SAAK,aAAa;AAAA,EACnB;AAAA,EAEA,MAAc,cAA6C;AAC1D,QAAI,KAAK,UAAU,WAAW,CAAC,KAAK,YAAY;AAC/C,YAAM,KAAK,QAAQ;AAAA,IACpB;AAEA,QAAI,CAAC,KAAK,cAAc,KAAK,UAAU,SAAS;AAC/C,YAAM,IAAI,MAAM,8BAA8B;AAAA,IAC/C;AAEA,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,MAAc,sBACb,YACA,KAC8B;AAC9B,UAAM,UAAU,MAAM,WAAW,WAAW;AAAA,MAC3C;AAAA,MACA,YAAY,CAAC;AAAA,IACd,CAAC;AACD,WAAO;AAAA,EACR;AAAA,EAEQ,kBAAkB,cAAmC;AAC5D,SAAK,qBAAqB,KAAK,UAAU,YAAY;AAAA,EACtD;AAAA,EAEA,MAAc,wBACb,QACqC;AACrC,QAAI,KAAK,mBAAmB;AAC3B,aAAO,KAAK,kBAAkB,MAAM;AAAA,IACrC;AACA,WAAO,EAAE,SAAS,EAAE,SAAS,YAAY,EAAE;AAAA,EAC5C;AAAA,EAEA,MAAc,cAA6B;AAC1C,UAAM,QAAQ,KAAK;AACnB,QAAI,CAAC,OAAO;AACX;AAAA,IACD;AAEA,SAAK,UAAU;AACf,QAAI,MAAM,aAAa,QAAQ,CAAC,MAAM,QAAQ;AAC7C,YAAM,KAAK,SAAS;AAAA,IACrB;AAAA,EACD;AACD;;;AFtpBA,IAAM,qBAAqB,CAAC,WAAmB,cAC9C,GAAG,SAAS,IAAI,SAAS;AAE1B,IAAM,oBAAoB,CAAC,WAAsC;AAChE,MAAI,CAAC,QAAQ;AACZ,WAAO;AAAA,MACN,SAAS;AAAA,MACT,WAAW;AAAA,MACX,iBAAiB;AAAA,IAClB;AAAA,EACD;AACA,QAAM,kBAAkB,OAAO,iBAAiB,IAAI,CAAC,WAAW;AAAA,IAC/D,IAAI,MAAM;AAAA,IACV,MAAM,MAAM;AAAA,IACZ,aAAa,MAAM,eAAe;AAAA,EACnC,EAAE;AACF,QAAM,UAAU,OAAO,kBAAkB;AACzC,QAAM,YAAY,iBAAiB;AAAA,IAClC,CAAC,UAAU,MAAM,OAAO;AAAA,EACzB,GAAG;AACH,SAAO,EAAE,SAAS,WAAW,gBAAgB;AAC9C;AAEA,IAAM,mBAAmB,CAAC,UAAoC;AAC7D,MAAI,CAAC,OAAO;AACX,WAAO;AAAA,MACN,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,gBAAgB;AAAA,IACjB;AAAA,EACD;AACA,QAAM,SAAS,MAAM,iBAAiB;AACtC,QAAM,WAAW,MAAM,gBAAgB;AAAA,IACtC,CAAC,SAAS,KAAK,OAAO;AAAA,EACvB,GAAG;AACH,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA,gBAAgB,MAAM,gBAAgB,IAAI,CAAC,UAAU;AAAA,MACpD,IAAI,KAAK;AAAA,MACT,MAAM,KAAK;AAAA,IACZ,EAAE;AAAA,EACH;AACD;AAEA,IAAM,oCAAoC,CAAC,YAC1C,IAAI;AAAA,EACH,kBAAkB;AAAA,IACjB,MAAM;AAAA,IACN;AAAA,IACA,WAAW;AAAA,IACX,OAAO;AAAA,EACR,CAAC;AAAA,EACD;AACD;AAEM,IAAM,iBAAN,MAAqB;AAAA,EAY3B,YAA6B,QAAmB;AAAnB;AAC5B,SAAK,cAAc,IAAI;AAAA,MACtB,OAAO,YAAY,IAAI,CAAC,YAAY,CAAC,QAAQ,IAAI,OAAO,CAAC;AAAA,IAC1D;AACA,SAAK,mBAAmB,OAAO;AAAA,EAChC;AAAA,EAhBQ,WAAW,oBAAI,IAA2B;AAAA,EAC1C;AAAA,EACA;AAAA,EACA,qBAAqB,oBAAI,IAAqC;AAAA,EACrD,uBAAuB,IAAIC,cAAa;AAAA,EACxC,sBAAsB,IAAIA,cAAa;AAAA,EACvC,2BAA2B,IAAIA,cAAa;AAAA,EAC5C,0BAA0B,IAAIA,cAAa;AAAA,EAC3C,wBAAwB,IAAIA,cAAa;AAAA,EACzC,yBAAyB,IAAIA,cAAa;AAAA,EAS3D,eAAiC;AAChC,WAAO,MAAM,KAAK,KAAK,SAAS,OAAO,CAAC,EAAE;AAAA,MAAI,CAAC,WAC9C,KAAK,aAAa,MAAM;AAAA,IACzB;AAAA,EACD;AAAA,EAEA,WAAW,WAA8C;AACxD,WAAO,KAAK,SAAS,IAAI,SAAS;AAAA,EACnC;AAAA,EAEA,gBAAgB,UAAuD;AACtE,SAAK,qBAAqB,GAAG,UAAU,QAAQ;AAC/C,WAAO,MAAM;AACZ,WAAK,qBAAqB,IAAI,UAAU,QAAQ;AAAA,IACjD;AAAA,EACD;AAAA,EAEA,eACC,UACC;AACD,SAAK,oBAAoB,GAAG,SAAS,QAAQ;AAC7C,WAAO,MAAM;AACZ,WAAK,oBAAoB,IAAI,SAAS,QAAQ;AAAA,IAC/C;AAAA,EACD;AAAA,EAEA,oBAAoB,UAAuD;AAC1E,SAAK,yBAAyB,GAAG,WAAW,QAAQ;AACpD,WAAO,MAAM;AACZ,WAAK,yBAAyB,IAAI,WAAW,QAAQ;AAAA,IACtD;AAAA,EACD;AAAA,EAEA,mBAAmB,UAAwD;AAC1E,SAAK,wBAAwB,GAAG,UAAU,QAAQ;AAClD,WAAO,MAAM;AACZ,WAAK,wBAAwB,IAAI,UAAU,QAAQ;AAAA,IACpD;AAAA,EACD;AAAA,EAEA,iBAAiB,UAAgD;AAChE,SAAK,sBAAsB,GAAG,UAAU,QAAQ;AAChD,WAAO,MAAM;AACZ,WAAK,sBAAsB,IAAI,UAAU,QAAQ;AAAA,IAClD;AAAA,EACD;AAAA,EAEA,kBAAkB,UAAqD;AACtE,SAAK,uBAAuB,GAAG,WAAW,QAAQ;AAClD,WAAO,MAAM;AACZ,WAAK,uBAAuB,IAAI,WAAW,QAAQ;AAAA,IACpD;AAAA,EACD;AAAA,EAEQ,oBAAoB,SAAiC;AAC5D,SAAK,uBAAuB,KAAK,WAAW,OAAO;AAAA,EACpD;AAAA,EAEA,uBAAuB,WAA+C;AACrE,WAAO,MAAM,KAAK,KAAK,mBAAmB,OAAO,CAAC,EAChD,OAAO,CAAC,WAAW,OAAO,cAAc,SAAS,EACjD,IAAI,CAAC,WAAW,KAAK,8BAA8B,MAAM,CAAC;AAAA,EAC7D;AAAA,EAEA,yBACC,WACA,WACA,SAC4B;AAC5B,UAAM,MAAM,mBAAmB,WAAW,SAAS;AACnD,UAAM,SAAS,KAAK,mBAAmB,IAAI,GAAG;AAC9C,QAAI,CAAC,QAAQ;AACZ,YAAM,IAAI;AAAA,QACT,kBAAkB;AAAA,UACjB,MAAM;AAAA,UACN,SAAS;AAAA,UACT,WAAW;AAAA,UACX,OAAO;AAAA,QACR,CAAC;AAAA,QACD;AAAA,MACD;AAAA,IACD;AACA,UAAM,WAAsC,EAAE,QAAQ;AACtD,WAAO,QAAQ,QAAQ;AACvB,SAAK,mBAAmB,OAAO,GAAG;AAClC,UAAM,UAAqC;AAAA,MAC1C;AAAA,MACA;AAAA,MACA;AAAA,IACD;AACA,SAAK,wBAAwB,KAAK,UAAU,OAAO;AACnD,WAAO;AAAA,EACR;AAAA,EAEQ,eAAe,WAAoB;AAC1C,UAAM,aAAa,WAAW,KAAK;AACnC,UAAM,aACL,cAAc,WAAW,SAAS,IAAI,aAAa,KAAK;AACzD,UAAM,UAAU,KAAK,YAAY,IAAI,UAAU;AAC/C,QAAI,CAAC,SAAS;AACb,YAAM,IAAI;AAAA,QACT,kBAAkB;AAAA,UACjB,MAAM;AAAA,UACN,SAAS;AAAA,UACT,WAAW;AAAA,UACX,OAAO;AAAA,QACR,CAAC;AAAA,QACD;AAAA,MACD;AAAA,IACD;AACA,WAAO;AAAA,EACR;AAAA,EAEA,MAAM,cAAc,SAIQ;AAC3B,UAAM,UAAU,KAAK,eAAe,SAAS,SAAS;AACtD,UAAM,aAAa,IAAI,cAAc;AAAA,MACpC;AAAA,MACA,QAAQ;AAAA,QACP,MAAM,KAAK,OAAO;AAAA,QAClB,SAAS,KAAK,OAAO;AAAA,MACtB;AAAA,IACD,CAAC;AACD,QAAI;AACH,YAAM,WAAW,QAAQ;AACzB,YAAM,UAAU,MAAM,WAAW,cAAc,EAAE,KAAK,SAAS,IAAI,CAAC;AACpE,iBAAW;AAAA,QAAqB,CAAC,WAChC,KAAK,wBAAwB,QAAQ,WAAW,MAAM;AAAA,MACvD;AACA,YAAM,MAAM,oBAAI,KAAK;AACrB,YAAM,YAAY,WAAW,aAAa;AAC1C,YAAM,EAAE,SAAS,WAAW,gBAAgB,IAAI;AAAA,QAC/C,QAAQ;AAAA,MACT;AACA,YAAM,EAAE,QAAQ,UAAU,eAAe,IAAI;AAAA,QAC5C,QAAQ;AAAA,MACT;AACA,YAAM,SAAwB;AAAA,QAC7B,WAAW,QAAQ;AAAA,QACnB,OAAO,SAAS,SAAS,WAAW,KAAK,SAAS,OAAO,CAAC;AAAA,QAC1D,WAAW,QAAQ;AAAA,QACnB,cAAc,QAAQ;AAAA,QACtB;AAAA,QACA,WAAW;AAAA,QACX,WAAW;AAAA,QACX,KAAK,SAAS;AAAA,QACd,WAAW,WAAW,SAAS,WAAW;AAAA,QAC1C;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,mBAAmB;AAAA,MACpB;AACA,aAAO,cAAc,WAAW;AAAA,QAC/B,CAAC,iBAAsC;AACtC,eAAK,aAAa,QAAQ,SAAS;AACnC,eAAK,qBAAqB,KAAK,UAAU,YAAY;AAErD,gBAAM,SAAS,aAAa;AAC5B,cAAI,OAAO,kBAAkB,uBAAuB;AACnD,mBAAO,SAAS,OAAO;AACvB,mBAAO,WACN,OAAO,gBAAgB;AAAA,cACtB,CAAC,SAAS,KAAK,OAAO,OAAO;AAAA,YAC9B,GAAG,QAAQ,OAAO;AACnB;AAAA,UACD;AACA,cAAI,OAAO,kBAAkB,uBAAuB;AACnD,gBAAI,OAAO,OAAO,UAAU,UAAU;AACrC,qBAAO,QAAQ,OAAO;AAAA,YACvB;AACA,gBAAI,OAAO,OAAO,cAAc,UAAU;AACzC,qBAAO,YAAY,IAAI,KAAK,OAAO,SAAS;AAAA,YAC7C;AAAA,UACD;AACA,cAAI,OAAO,kBAAkB,6BAA6B;AACzD,gBAAI,OAAO,mBAAmB;AAC7B,qBAAO,oBAAoB,OAAO;AAAA,YACnC;AAAA,UACD;AAAA,QACD;AAAA,MACD;AACA,aAAO,sBAAsB,WAAW,iBAAiB,CAAC,UAAU;AACnE,aAAK,sBAAsB,KAAK,UAAU,KAAK;AAAA,MAChD,CAAC;AACD,iBAAW,eAAe,CAAC,WAAW;AACrC,YAAI,OAAO,OAAO;AACjB,eAAK,oBAAoB,KAAK,SAAS;AAAA,YACtC,WAAW,QAAQ;AAAA,YACnB,OAAO,OAAO;AAAA,UACf,CAAC;AAAA,QACF;AAAA,MACD,CAAC;AACD,WAAK,SAAS,IAAI,QAAQ,WAAW,MAAM;AAC3C,YAAM,UAAU,KAAK,aAAa,MAAM;AACxC,WAAK,oBAAoB;AAAA,QACxB,OAAO,CAAC,OAAO;AAAA,QACf,SAAS,CAAC;AAAA,QACV,SAAS,CAAC;AAAA,MACX,CAAC;AACD,aAAO;AAAA,IACR,SAAS,OAAO;AACf,YAAM,SAAS,WAAW,UAAU;AACpC,YAAM,WAAW,WAAW;AAC5B,UAAI,OAAO,OAAO;AACjB,cAAM,IAAI,SAAS,OAAO,OAAO,GAAG;AAAA,MACrC;AACA,YAAM;AAAA,IACP;AAAA,EACD;AAAA,EAEQ,8BACP,QAC2B;AAC3B,UAAM,WAAW,OAAO,OAAO;AAC/B,WAAO;AAAA,MACN,WAAW,OAAO;AAAA,MAClB,WAAW,OAAO;AAAA,MAClB,SAAS,OAAO,OAAO,QAAQ,IAAI,CAAC,YAAY;AAAA,QAC/C,UAAU,OAAO;AAAA;AAAA,QAEjB,OAAO,OAAO;AAAA,QACd,aAAc,OAAO,OAAO,eAA0B;AAAA,MACvD,EAAE;AAAA,MACF,UAAU;AAAA,QACT,YAAY,SAAS;AAAA,QACrB,MAAO,SAAS,OAAO,QAAmB;AAAA,QAC1C,OAAO,SAAS;AAAA,QAChB,SAAU,SAAS,OAAO,WAAsB;AAAA,QAChD,MAAO,SAAS,OAAO,QAAqB;AAAA,MAC7C;AAAA,IACD;AAAA,EACD;AAAA,EAEQ,wBACP,WACA,QACqC;AACrC,UAAM,YAAY,OAAO,UAAU,cAAcC,YAAW;AAC5D,UAAM,MAAM,mBAAmB,WAAW,SAAS;AACnD,UAAM,WAAW,KAAK,mBAAmB,IAAI,GAAG;AAChD,QAAI,UAAU;AACb,aAAO,SAAS;AAAA,IACjB;AACA,QAAI,WAA0D,MAAM;AAAA,IAAC;AACrE,UAAM,UAAU,IAAI,QAAmC,CAAC,YAAY;AACnE,iBAAW;AAAA,IACZ,CAAC;AACD,UAAM,SAAkC;AAAA,MACvC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS;AAAA,IACV;AACA,SAAK,mBAAmB,IAAI,KAAK,MAAM;AACvC,SAAK,yBAAyB;AAAA,MAC7B;AAAA,MACA,KAAK,8BAA8B,MAAM;AAAA,IAC1C;AACA,WAAO;AAAA,EACR;AAAA,EAEQ,yBAAyB,WAAmB;AACnD,UAAM,mBAAyD;AAAA,MAC9D,SAAS;AAAA,IACV;AACA,eAAW,CAAC,KAAK,MAAM,KAAK,KAAK,mBAAmB,QAAQ,GAAG;AAC9D,UAAI,OAAO,cAAc,WAAW;AACnC;AAAA,MACD;AACA,aAAO,QAAQ,EAAE,SAAS,iBAAiB,CAAC;AAC5C,WAAK,mBAAmB,OAAO,GAAG;AAClC,WAAK,wBAAwB,KAAK,UAAU;AAAA,QAC3C;AAAA,QACA,WAAW,OAAO;AAAA,QAClB,SAAS;AAAA,MACV,CAAC;AAAA,IACF;AAAA,EACD;AAAA,EAEA,YAAY,WAAmB,OAA+B;AAC7D,UAAM,SAAS,KAAK,SAAS,IAAI,SAAS;AAC1C,QAAI,CAAC,QAAQ;AACZ,YAAM,IAAI;AAAA,QACT,kBAAkB;AAAA,UACjB,MAAM;AAAA,UACN,SAAS;AAAA,UACT,WAAW;AAAA,UACX,OAAO;AAAA,QACR,CAAC;AAAA,QACD;AAAA,MACD;AAAA,IACD;AACA,WAAO,QAAQ;AACf,WAAO,YAAY,oBAAI,KAAK;AAC5B,UAAM,UAAU,KAAK,aAAa,MAAM;AACxC,SAAK,oBAAoB;AAAA,MACxB,OAAO,CAAC;AAAA,MACR,SAAS,CAAC,OAAO;AAAA,MACjB,SAAS,CAAC;AAAA,IACX,CAAC;AACD,WAAO;AAAA,EACR;AAAA,EAEA,aAAa,WAAmB;AAC/B,UAAM,SAAS,KAAK,SAAS,IAAI,SAAS;AAC1C,QAAI,CAAC,QAAQ;AACZ;AAAA,IACD;AACA,WAAO,YAAY,oBAAI,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,eACL,WACA,QAC0B;AAC1B,UAAM,SAAS,KAAK,SAAS,IAAI,SAAS;AAC1C,QAAI,CAAC,QAAQ;AACZ,YAAM,IAAI;AAAA,QACT,kBAAkB;AAAA,UACjB,MAAM;AAAA,UACN,SAAS;AAAA,UACT,WAAW;AAAA,UACX,OAAO;AAAA,QACR,CAAC;AAAA,QACD;AAAA,MACD;AAAA,IACD;AACA,QAAI,CAAC,OAAO,kBAAkB,OAAO,eAAe,WAAW,GAAG;AACjE,YAAM;AAAA,QACL;AAAA,MACD;AAAA,IACD;AACA,UAAM,WAAW,OAAO,eAAe,KAAK,CAAC,SAAS,KAAK,OAAO,MAAM;AACxE,QAAI,CAAC,UAAU;AACd,YAAM,IAAI;AAAA,QACT,kBAAkB;AAAA,UACjB,MAAM;AAAA,UACN,SAAS;AAAA,UACT,WAAW;AAAA,UACX,OAAO;AAAA,QACR,CAAC;AAAA,QACD;AAAA,MACD;AAAA,IACD;AACA,UAAM,OAAO,WAAW,eAAe,WAAW,MAAM;AACxD,WAAO,SAAS,SAAS;AACzB,WAAO,WAAW,SAAS;AAC3B,WAAO,YAAY,oBAAI,KAAK;AAC5B,UAAM,UAAU,KAAK,aAAa,MAAM;AACxC,SAAK,oBAAoB;AAAA,MACxB,OAAO,CAAC;AAAA,MACR,SAAS,CAAC,OAAO;AAAA,MACjB,SAAS,CAAC;AAAA,IACX,CAAC;AACD,WAAO;AAAA,EACR;AAAA,EAEA,MAAM,gBACL,WACA,SAC0B;AAC1B,UAAM,SAAS,KAAK,SAAS,IAAI,SAAS;AAC1C,QAAI,CAAC,QAAQ;AACZ,YAAM,IAAI;AAAA,QACT,kBAAkB;AAAA,UACjB,MAAM;AAAA,UACN,SAAS;AAAA,UACT,WAAW;AAAA,UACX,OAAO;AAAA,QACR,CAAC;AAAA,QACD;AAAA,MACD;AAAA,IACD;AACA,QAAI,CAAC,OAAO,mBAAmB,OAAO,gBAAgB,WAAW,GAAG;AACnE,YAAM;AAAA,QACL;AAAA,MACD;AAAA,IACD;AACA,UAAM,WAAW,OAAO,gBAAgB;AAAA,MACvC,CAAC,UAAU,MAAM,OAAO;AAAA,IACzB;AACA,QAAI,CAAC,UAAU;AACd,YAAM,IAAI;AAAA,QACT,kBAAkB;AAAA,UACjB,MAAM;AAAA,UACN,SAAS;AAAA,UACT,WAAW;AAAA,UACX,OAAO;AAAA,QACR,CAAC;AAAA,QACD;AAAA,MACD;AAAA,IACD;AACA,UAAM,OAAO,WAAW,gBAAgB,WAAW,OAAO;AAC1D,WAAO,UAAU,SAAS;AAC1B,WAAO,YAAY,SAAS;AAC5B,WAAO,YAAY,oBAAI,KAAK;AAC5B,UAAM,UAAU,KAAK,aAAa,MAAM;AACxC,SAAK,oBAAoB;AAAA,MACxB,OAAO,CAAC;AAAA,MACR,SAAS,CAAC,OAAO;AAAA,MACjB,SAAS,CAAC;AAAA,IACX,CAAC;AACD,WAAO;AAAA,EACR;AAAA,EAEA,MAAM,cAAc,WAAqC;AACxD,UAAM,SAAS,KAAK,SAAS,IAAI,SAAS;AAC1C,QAAI,CAAC,QAAQ;AACZ,aAAO;AAAA,IACR;AACA,SAAK,yBAAyB,SAAS;AACvC,UAAM,OAAO,WAAW,OAAO,SAAS;AACxC,SAAK,aAAa,SAAS;AAC3B,WAAO;AAAA,EACR;AAAA,EAEA,MAAM,aAAa,WAAqC;AACvD,UAAM,SAAS,KAAK,SAAS,IAAI,SAAS;AAC1C,QAAI,CAAC,QAAQ;AACZ,aAAO;AAAA,IACR;AACA,QAAI;AACH,aAAO,cAAc;AACrB,aAAO,sBAAsB;AAAA,IAC9B,SAAS,OAAO;AACf,aAAO,MAAM,EAAE,KAAK,OAAO,UAAU,GAAG,4BAA4B;AAAA,IACrE;AACA,SAAK,yBAAyB,SAAS;AACvC,QAAI;AACH,YAAM,OAAO,WAAW,WAAW;AAAA,IACpC,SAAS,OAAO;AACf,aAAO,MAAM,EAAE,KAAK,OAAO,UAAU,GAAG,2BAA2B;AAAA,IACpE;AACA,SAAK,SAAS,OAAO,SAAS;AAC9B,SAAK,oBAAoB;AAAA,MACxB,OAAO,CAAC;AAAA,MACR,SAAS,CAAC;AAAA,MACV,SAAS,CAAC,SAAS;AAAA,IACpB,CAAC;AACD,WAAO;AAAA,EACR;AAAA,EAEA,MAAM,WAA0B;AAC/B,UAAM,aAAa,MAAM,KAAK,KAAK,SAAS,KAAK,CAAC;AAClD,UAAM,QAAQ;AAAA,MACb,WAAW,IAAI,CAAC,cAAc,KAAK,aAAa,SAAS,CAAC;AAAA,IAC3D;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,iBAAiB,SAGgB;AACtC,UAAM,UAAU,KAAK,eAAe,SAAS,SAAS;AACtD,UAAM,aAAa,IAAI,cAAc;AAAA,MACpC;AAAA,MACA,QAAQ;AAAA,QACP,MAAM,KAAK,OAAO;AAAA,QAClB,SAAS,KAAK,OAAO;AAAA,MACtB;AAAA,IACD,CAAC;AAED,QAAI;AACH,YAAM,WAAW,QAAQ;AACzB,YAAM,eAAe,WAAW,uBAAuB;AACvD,YAAM,WAA6B,CAAC;AAEpC,UAAI,aAAa,MAAM;AACtB,cAAM,gBAAgB,MAAM,WAAW,aAAa;AAAA,UACnD,KAAK,SAAS;AAAA,QACf,CAAC;AACD,mBAAW,WAAW,eAAe;AACpC,mBAAS,KAAK;AAAA,YACb,WAAW,QAAQ;AAAA,YACnB,KAAK,QAAQ;AAAA,YACb,OAAO,QAAQ,SAAS;AAAA,YACxB,WAAW,QAAQ,aAAa;AAAA,UACjC,CAAC;AAAA,QACF;AAAA,MACD;AAEA,aAAO;AAAA,QACN;AAAA,UACC,WAAW,QAAQ;AAAA,UACnB,cAAc,SAAS;AAAA,UACvB;AAAA,QACD;AAAA,QACA;AAAA,MACD;AAEA,aAAO,EAAE,UAAU,aAAa;AAAA,IACjC,UAAE;AACD,YAAM,WAAW,WAAW;AAAA,IAC7B;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,YACL,WACA,KACA,WAC0B;AAE1B,UAAM,WAAW,KAAK,SAAS,IAAI,SAAS;AAC5C,QAAI,UAAU;AACb,aAAO,KAAK,aAAa,QAAQ;AAAA,IAClC;AAEA,UAAM,UAAU,KAAK,eAAe,SAAS;AAC7C,UAAM,aAAa,IAAI,cAAc;AAAA,MACpC;AAAA,MACA,QAAQ;AAAA,QACP,MAAM,KAAK,OAAO;AAAA,QAClB,SAAS,KAAK,OAAO;AAAA,MACtB;AAAA,IACD,CAAC;AAED,QAAI;AACH,YAAM,WAAW,QAAQ;AAEzB,UAAI,CAAC,WAAW,oBAAoB,GAAG;AACtC,cAAM;AAAA,UACL;AAAA,QACD;AAAA,MACD;AAEA,YAAM,WAAW,MAAM,WAAW,YAAY,WAAW,GAAG;AAC5D,iBAAW;AAAA,QAAqB,CAAC,WAChC,KAAK,wBAAwB,WAAW,MAAM;AAAA,MAC/C;AAEA,YAAM,MAAM,oBAAI,KAAK;AACrB,YAAM,YAAY,WAAW,aAAa;AAC1C,YAAM,EAAE,SAAS,WAAW,gBAAgB,IAAI;AAAA,QAC/C,SAAS;AAAA,MACV;AACA,YAAM,EAAE,QAAQ,UAAU,eAAe,IAAI;AAAA,QAC5C,SAAS;AAAA,MACV;AAEA,YAAM,SAAwB;AAAA,QAC7B;AAAA,QACA,OAAO;AAAA,QACP,WAAW,QAAQ;AAAA,QACnB,cAAc,QAAQ;AAAA,QACtB;AAAA,QACA,WAAW;AAAA,QACX,WAAW;AAAA,QACX;AAAA,QACA,WAAW,WAAW,SAAS,WAAW;AAAA,QAC1C;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,mBAAmB;AAAA,MACpB;AAEA,WAAK,0BAA0B,MAAM;AACrC,WAAK,SAAS,IAAI,WAAW,MAAM;AAEnC,YAAM,UAAU,KAAK,aAAa,MAAM;AACxC,WAAK,oBAAoB;AAAA,QACxB,OAAO,CAAC,OAAO;AAAA,QACf,SAAS,CAAC;AAAA,QACV,SAAS,CAAC;AAAA,MACX,CAAC;AAED,aAAO,KAAK,EAAE,WAAW,WAAW,QAAQ,GAAG,GAAG,gBAAgB;AAElE,aAAO;AAAA,IACR,SAAS,OAAO;AACf,YAAM,WAAW,WAAW;AAC5B,YAAM;AAAA,IACP;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,cACL,WACA,KACA,WAC0B;AAE1B,UAAM,WAAW,KAAK,SAAS,IAAI,SAAS;AAC5C,QAAI,UAAU;AACb,aAAO,KAAK,aAAa,QAAQ;AAAA,IAClC;AAEA,UAAM,UAAU,KAAK,eAAe,SAAS;AAC7C,UAAM,aAAa,IAAI,cAAc;AAAA,MACpC;AAAA,MACA,QAAQ;AAAA,QACP,MAAM,KAAK,OAAO;AAAA,QAClB,SAAS,KAAK,OAAO;AAAA,MACtB;AAAA,IACD,CAAC;AAED,QAAI;AACH,YAAM,WAAW,QAAQ;AAEzB,UAAI,CAAC,WAAW,sBAAsB,GAAG;AACxC,cAAM;AAAA,UACL;AAAA,QACD;AAAA,MACD;AAEA,YAAM,WAAW,MAAM,WAAW,cAAc,WAAW,GAAG;AAC9D,iBAAW;AAAA,QAAqB,CAAC,WAChC,KAAK,wBAAwB,WAAW,MAAM;AAAA,MAC/C;AAEA,YAAM,MAAM,oBAAI,KAAK;AACrB,YAAM,YAAY,WAAW,aAAa;AAC1C,YAAM,EAAE,SAAS,WAAW,gBAAgB,IAAI;AAAA,QAC/C,SAAS;AAAA,MACV;AACA,YAAM,EAAE,QAAQ,UAAU,eAAe,IAAI;AAAA,QAC5C,SAAS;AAAA,MACV;AAEA,YAAM,SAAwB;AAAA,QAC7B;AAAA,QACA,OAAO;AAAA,QACP,WAAW,QAAQ;AAAA,QACnB,cAAc,QAAQ;AAAA,QACtB;AAAA,QACA,WAAW;AAAA,QACX,WAAW;AAAA,QACX;AAAA,QACA,WAAW,WAAW,SAAS,WAAW;AAAA,QAC1C;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,mBAAmB;AAAA,MACpB;AAEA,WAAK,0BAA0B,MAAM;AACrC,WAAK,SAAS,IAAI,WAAW,MAAM;AAEnC,YAAM,UAAU,KAAK,aAAa,MAAM;AACxC,WAAK,oBAAoB;AAAA,QACxB,OAAO,CAAC,OAAO;AAAA,QACf,SAAS,CAAC;AAAA,QACV,SAAS,CAAC;AAAA,MACX,CAAC;AAED,aAAO,KAAK,EAAE,WAAW,WAAW,QAAQ,GAAG,GAAG,iBAAiB;AAEnE,aAAO;AAAA,IACR,SAAS,OAAO;AACf,YAAM,WAAW,WAAW;AAC5B,YAAM;AAAA,IACP;AAAA,EACD;AAAA;AAAA;AAAA;AAAA,EAKQ,0BAA0B,QAA6B;AAC9D,UAAM,EAAE,WAAW,WAAW,IAAI;AAElC,WAAO,cAAc,WAAW;AAAA,MAC/B,CAAC,iBAAsC;AACtC,aAAK,aAAa,SAAS;AAC3B,aAAK,qBAAqB,KAAK,UAAU,YAAY;AAErD,cAAM,SAAS,aAAa;AAC5B,YAAI,OAAO,kBAAkB,uBAAuB;AACnD,iBAAO,SAAS,OAAO;AACvB,iBAAO,WACN,OAAO,gBAAgB;AAAA,YACtB,CAAC,SAAS,KAAK,OAAO,OAAO;AAAA,UAC9B,GAAG,QAAQ,OAAO;AACnB;AAAA,QACD;AACA,YAAI,OAAO,kBAAkB,uBAAuB;AACnD,cAAI,OAAO,OAAO,UAAU,UAAU;AACrC,mBAAO,QAAQ,OAAO;AAAA,UACvB;AACA,cAAI,OAAO,OAAO,cAAc,UAAU;AACzC,mBAAO,YAAY,IAAI,KAAK,OAAO,SAAS;AAAA,UAC7C;AAAA,QACD;AACA,YAAI,OAAO,kBAAkB,6BAA6B;AACzD,cAAI,OAAO,mBAAmB;AAC7B,mBAAO,oBAAoB,OAAO;AAAA,UACnC;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAEA,WAAO,sBAAsB,WAAW,iBAAiB,CAAC,UAAU;AACnE,WAAK,sBAAsB,KAAK,UAAU,KAAK;AAAA,IAChD,CAAC;AAED,eAAW,eAAe,CAAC,WAAW;AACrC,UAAI,OAAO,OAAO;AACjB,aAAK,oBAAoB,KAAK,SAAS;AAAA,UACtC;AAAA,UACA,OAAO,OAAO;AAAA,QACf,CAAC;AAAA,MACF;AAAA,IACD,CAAC;AAAA,EACF;AAAA,EAEQ,aAAa,QAAuC;AAC3D,UAAM,SAAS,OAAO,WAAW,UAAU;AAC3C,WAAO;AAAA,MACN,WAAW,OAAO;AAAA,MAClB,OAAO,OAAO;AAAA,MACd,WAAW,OAAO;AAAA,MAClB,cAAc,OAAO;AAAA,MACrB,OAAO,OAAO;AAAA,MACd,OAAO,OAAO;AAAA,MACd,KAAK,OAAO;AAAA,MACZ,WAAW,OAAO,UAAU,YAAY;AAAA,MACxC,WAAW,OAAO,UAAU,YAAY;AAAA,MACxC,KAAK,OAAO;AAAA,MACZ,WAAW,OAAO;AAAA,MAClB,SAAS,OAAO;AAAA,MAChB,WAAW,OAAO;AAAA,MAClB,QAAQ,OAAO;AAAA,MACf,UAAU,OAAO;AAAA,MACjB,gBAAgB,OAAO;AAAA,MACvB,iBAAiB,OAAO;AAAA,MACxB,mBAAmB,OAAO;AAAA,IAC3B;AAAA,EACD;AACD;;;AG93BA,SAAS,gBAAAC,qBAAoB;AAC7B,OAAOC,SAAQ;AACf,SAAS,eAAe;AACxB,OAAOC,WAAU;AAYjB,OAAO,YAA6B;AACpC,SAAS,UAAuB;AAYhC,IAAM,oBAAoB;AAC1B,IAAM,qBAAqB;AAC3B,IAAM,kBAAkB;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD;AAEA,IAAM,gBAAgB,OAAO,aAAsC;AAClE,QAAM,KAAK,OAAO,EAAE,IAAI,eAAe;AACvC,MAAI;AACH,UAAM,gBAAgBC,MAAK,KAAK,UAAU,YAAY;AACtD,UAAM,UAAU,MAAMC,IAAG,SAAS,eAAe,MAAM;AACvD,OAAG,IAAI,OAAO;AAAA,EACf,QAAQ;AAAA,EAER;AACA,SAAO;AACR;AAEA,IAAM,uBAAuB,CAAC,aAAqB;AAClD,QAAM,YAAYD,MAAK,QAAQ,QAAQ,EAAE,YAAY;AACrD,UAAQ,WAAW;AAAA,IAClB,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR;AACC,aAAO;AAAA,EACT;AACD;AAEA,IAAM,uBAAuB,OAAO,YAAwC;AAC3E,QAAM,UAAU,MAAMC,IAAG,QAAQ,SAAS,EAAE,eAAe,KAAK,CAAC;AACjE,QAAM,kBAAkB,MAAM,QAAQ;AAAA,IACrC,QAAQ,IAAI,OAAO,UAAU;AAC5B,YAAM,YAAYD,MAAK,KAAK,SAAS,MAAM,IAAI;AAC/C,UAAI,cAAc,MAAM,YAAY;AACpC,UAAI,CAAC,eAAe,MAAM,eAAe,GAAG;AAC3C,YAAI;AACH,gBAAM,QAAQ,MAAMC,IAAG,KAAK,SAAS;AACrC,wBAAc,MAAM,YAAY;AAAA,QACjC,QAAQ;AAAA,QAER;AAAA,MACD;AACA,YAAM,YAA6B,cAAc,cAAc;AAC/D,aAAO;AAAA,QACN,MAAM,MAAM;AAAA,QACZ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,QAAQ,MAAM,KAAK,WAAW,GAAG;AAAA,MAClC;AAAA,IACD,CAAC;AAAA,EACF;AACA,SAAO,gBAAgB,KAAK,CAAC,MAAM,UAAU;AAC5C,QAAI,KAAK,SAAS,MAAM,MAAM;AAC7B,aAAO,KAAK,SAAS,cAAc,KAAK;AAAA,IACzC;AACA,WAAO,KAAK,KAAK,cAAc,MAAM,IAAI;AAAA,EAC1C,CAAC;AACF;AAEA,IAAM,uBAAuB,CAAC,YAC7B,QAAQ,OAAO,CAAC,UAAU,CAAC,MAAM,MAAM;AAExC,IAAM,mBAAmB,YAA0C;AAClE,QAAM,WAAW,QAAQ;AACzB,SAAO;AAAA,IACN;AAAA,IACA,OAAO,CAAC,EAAE,MAAM,QAAQ,MAAM,SAAS,CAAC;AAAA,EACzC;AACD;AAEO,IAAM,eAAN,cAA2BC,cAAa;AAAA,EAM9C,YAA6B,SAA8B;AAC1D,UAAM;AADsB;AAE5B,SAAK,SAAS,GAAG,GAAG,QAAQ,OAAO,UAAU,QAAQ;AAAA,MACpD,MAAM;AAAA,MACN,cAAc;AAAA,MACd,sBAAsB,OAAO;AAAA,MAC7B,mBAAmB;AAAA,MACnB,sBAAsB;AAAA,MACtB,YAAY,CAAC,WAAW;AAAA,MACxB,aAAa;AAAA,MACb,cAAc;AAAA,QACb,aAAa,QAAQ;AAAA,MACtB;AAAA,IACD,CAAC;AACD,SAAK,mBAAmB;AACxB,SAAK,iBAAiB;AACtB,SAAK,6BAA6B;AAAA,EACnC;AAAA,EAtBQ;AAAA,EACA,YAAY;AAAA,EACZ,oBAAoB;AAAA,EACpB;AAAA,EAqBA,qBAAqB;AAC5B,SAAK,OAAO,GAAG,WAAW,MAAM;AAC/B,aAAO;AAAA,QACN,EAAE,YAAY,KAAK,QAAQ,OAAO,WAAW;AAAA,QAC7C;AAAA,MACD;AACA,WAAK,YAAY;AACjB,WAAK,oBAAoB;AACzB,aAAO,KAAK,wBAAwB;AACpC,WAAK,SAAS;AACd,WAAK,eAAe;AACpB,WAAK,KAAK,WAAW;AAAA,IACtB,CAAC;AAED,SAAK,OAAO,GAAG,cAAc,CAAC,WAAW;AACxC,aAAO,KAAK,EAAE,OAAO,GAAG,sBAAsB;AAC9C,WAAK,YAAY;AACjB,WAAK,cAAc;AACnB,WAAK,KAAK,gBAAgB,MAAM;AAAA,IACjC,CAAC;AAED,SAAK,OAAO,GAAG,iBAAiB,CAAC,UAAU;AAC1C,WAAK;AACL,UAAI,KAAK,qBAAqB,KAAK,KAAK,oBAAoB,OAAO,GAAG;AACrE,eAAO;AAAA,UACN,EAAE,SAAS,KAAK,mBAAmB,KAAK,MAAM;AAAA,UAC9C;AAAA,QACD;AAAA,MACD;AAAA,IACD,CAAC;AAED,SAAK,OAAO,GAAG,kBAAkB,OAAO,SAAS;AAChD,aAAO,KAAK,EAAE,WAAW,KAAK,UAAU,GAAG,oBAAoB;AAG/D,UAAI;AACH,cAAM,EAAE,UAAU,aAAa,IAC9B,MAAM,KAAK,QAAQ,eAAe,iBAAiB;AAEpD,YAAI,SAAS,SAAS,GAAG;AACxB,eAAK,OAAO,KAAK,uBAAuB,EAAE,UAAU,aAAa,CAAC;AAClE,iBAAO;AAAA,YACN,EAAE,OAAO,SAAS,QAAQ,aAAa;AAAA,YACvC;AAAA,UACD;AAAA,QACD;AAAA,MACD,SAAS,OAAO;AACf,eAAO,KAAK,EAAE,KAAK,MAAM,GAAG,0BAA0B;AAAA,MACvD;AAAA,IACD,CAAC;AAGD,SAAK,OAAO,GAAG,aAAa,CAAC,UAAU;AACtC,aAAO,MAAM,EAAE,KAAK,MAAM,GAAG,oBAAoB;AACjD,WAAK,KAAK,cAAc,KAAK;AAAA,IAC9B,CAAC;AAAA,EACF;AAAA,EAEQ,mBAAmB;AAC1B,UAAM,EAAE,eAAe,IAAI,KAAK;AAGhC,SAAK,OAAO,GAAG,sBAAsB,OAAO,YAAY;AACvD,UAAI;AACH,eAAO,KAAK,EAAE,WAAW,QAAQ,UAAU,GAAG,oBAAoB;AAClE,cAAM,UAAU,MAAM,eAAe,cAAc,QAAQ,MAAM;AACjE,aAAK,gBAAgB,QAAQ,WAAW,OAAO;AAAA,MAChD,SAAS,OAAO;AACf,eAAO;AAAA,UACN,EAAE,KAAK,OAAO,WAAW,QAAQ,UAAU;AAAA,UAC3C;AAAA,QACD;AACA,aAAK,aAAa,QAAQ,WAAW,KAAK;AAAA,MAC3C;AAAA,IACD,CAAC;AAGD,SAAK,OAAO,GAAG,qBAAqB,OAAO,YAAY;AACtD,UAAI;AACH,eAAO;AAAA,UACN,EAAE,WAAW,QAAQ,WAAW,WAAW,QAAQ,OAAO,UAAU;AAAA,UACpE;AAAA,QACD;AACA,cAAM,eAAe,aAAa,QAAQ,OAAO,SAAS;AAC1D,aAAK,gBAAgB,QAAQ,WAAW,EAAE,IAAI,KAAK,CAAC;AAAA,MACrD,SAAS,OAAO;AACf,eAAO;AAAA,UACN;AAAA,YACC,KAAK;AAAA,YACL,WAAW,QAAQ;AAAA,YACnB,WAAW,QAAQ,OAAO;AAAA,UAC3B;AAAA,UACA;AAAA,QACD;AACA,aAAK,aAAa,QAAQ,WAAW,KAAK;AAAA,MAC3C;AAAA,IACD,CAAC;AAGD,SAAK,OAAO,GAAG,sBAAsB,OAAO,YAAY;AACvD,UAAI;AACH,eAAO;AAAA,UACN,EAAE,WAAW,QAAQ,WAAW,WAAW,QAAQ,OAAO,UAAU;AAAA,UACpE;AAAA,QACD;AACA,cAAM,eAAe,cAAc,QAAQ,OAAO,SAAS;AAC3D,aAAK,gBAAgB,QAAQ,WAAW,EAAE,IAAI,KAAK,CAAC;AAAA,MACrD,SAAS,OAAO;AACf,eAAO;AAAA,UACN;AAAA,YACC,KAAK;AAAA,YACL,WAAW,QAAQ;AAAA,YACnB,WAAW,QAAQ,OAAO;AAAA,UAC3B;AAAA,UACA;AAAA,QACD;AACA,aAAK,aAAa,QAAQ,WAAW,KAAK;AAAA,MAC3C;AAAA,IACD,CAAC;AAGD,SAAK,OAAO,GAAG,oBAAoB,OAAO,YAAY;AACrD,UAAI;AACH,eAAO;AAAA,UACN;AAAA,YACC,WAAW,QAAQ;AAAA,YACnB,WAAW,QAAQ,OAAO;AAAA,YAC1B,QAAQ,QAAQ,OAAO;AAAA,UACxB;AAAA,UACA;AAAA,QACD;AACA,cAAM,UAAU,MAAM,eAAe;AAAA,UACpC,QAAQ,OAAO;AAAA,UACf,QAAQ,OAAO;AAAA,QAChB;AACA,aAAK,gBAAgB,QAAQ,WAAW,OAAO;AAAA,MAChD,SAAS,OAAO;AACf,eAAO;AAAA,UACN;AAAA,YACC,KAAK;AAAA,YACL,WAAW,QAAQ;AAAA,YACnB,WAAW,QAAQ,OAAO;AAAA,YAC1B,QAAQ,QAAQ,OAAO;AAAA,UACxB;AAAA,UACA;AAAA,QACD;AACA,aAAK,aAAa,QAAQ,WAAW,KAAK;AAAA,MAC3C;AAAA,IACD,CAAC;AAGD,SAAK,OAAO,GAAG,qBAAqB,OAAO,YAAY;AACtD,UAAI;AACH,eAAO;AAAA,UACN;AAAA,YACC,WAAW,QAAQ;AAAA,YACnB,WAAW,QAAQ,OAAO;AAAA,YAC1B,SAAS,QAAQ,OAAO;AAAA,UACzB;AAAA,UACA;AAAA,QACD;AACA,cAAM,UAAU,MAAM,eAAe;AAAA,UACpC,QAAQ,OAAO;AAAA,UACf,QAAQ,OAAO;AAAA,QAChB;AACA,aAAK,gBAAgB,QAAQ,WAAW,OAAO;AAAA,MAChD,SAAS,OAAO;AACf,eAAO;AAAA,UACN;AAAA,YACC,KAAK;AAAA,YACL,WAAW,QAAQ;AAAA,YACnB,WAAW,QAAQ,OAAO;AAAA,YAC1B,SAAS,QAAQ,OAAO;AAAA,UACzB;AAAA,UACA;AAAA,QACD;AACA,aAAK,aAAa,QAAQ,WAAW,KAAK;AAAA,MAC3C;AAAA,IACD,CAAC;AAGD,SAAK,OAAO,GAAG,oBAAoB,OAAO,YAAY;AACrD,YAAM,eAAe,QAAQ,OAAO,OAAO;AAC3C,UAAI;AACH,cAAM,EAAE,WAAW,OAAO,IAAI,QAAQ;AACtC,eAAO;AAAA,UACN;AAAA,YACC,WAAW,QAAQ;AAAA,YACnB;AAAA,YACA,cAAc,OAAO;AAAA,UACtB;AAAA,UACA;AAAA,QACD;AACA,eAAO;AAAA,UACN;AAAA,YACC,WAAW,QAAQ;AAAA,YACnB;AAAA,YACA,cAAc,OAAO;AAAA,UACtB;AAAA,UACA;AAAA,QACD;AACA,cAAM,SAAS,eAAe,WAAW,SAAS;AAClD,YAAI,CAAC,QAAQ;AACZ,gBAAM,IAAI,MAAM,mBAAmB;AAAA,QACpC;AACA,uBAAe,aAAa,SAAS;AAErC,cAAM,SAAS,MAAM,OAAO,WAAW;AAAA,UACtC;AAAA,UACA;AAAA,QACD;AACA,uBAAe,aAAa,SAAS;AACrC,aAAK,gBAA4C,QAAQ,WAAW;AAAA,UACnE,YAAY,OAAO;AAAA,QACpB,CAAC;AACD,cAAM,aACL,OAAO,QAAQ,OAAO,OAAO,IAAI,YAAY,IAAI;AAClD,eAAO;AAAA,UACN;AAAA,YACC,WAAW,QAAQ;AAAA,YACnB;AAAA,YACA,YAAY,OAAO;AAAA,YACnB;AAAA,UACD;AAAA,UACA;AAAA,QACD;AACA,eAAO;AAAA,UACN;AAAA,YACC,WAAW,QAAQ;AAAA,YACnB;AAAA,YACA;AAAA,UACD;AAAA,UACA;AAAA,QACD;AAAA,MACD,SAAS,OAAO;AACf,cAAM,aACL,OAAO,QAAQ,OAAO,OAAO,IAAI,YAAY,IAAI;AAClD,eAAO;AAAA,UACN;AAAA,YACC,KAAK;AAAA,YACL,WAAW,QAAQ;AAAA,YACnB,WAAW,QAAQ,OAAO;AAAA,YAC1B,cAAc,QAAQ,OAAO,OAAO;AAAA,YACpC;AAAA,UACD;AAAA,UACA;AAAA,QACD;AACA,aAAK,aAAa,QAAQ,WAAW,KAAK;AAAA,MAC3C;AAAA,IACD,CAAC;AAGD,SAAK,OAAO,GAAG,2BAA2B,OAAO,YAAY;AAC5D,UAAI;AACH,cAAM,EAAE,WAAW,WAAW,QAAQ,IAAI,QAAQ;AAClD,eAAO;AAAA,UACN,EAAE,WAAW,QAAQ,WAAW,WAAW,QAAQ;AAAA,UACnD;AAAA,QACD;AACA,uBAAe,yBAAyB,WAAW,WAAW,OAAO;AACrE,aAAK,gBAAgB,QAAQ,WAAW,EAAE,IAAI,KAAK,CAAC;AAAA,MACrD,SAAS,OAAO;AACf,eAAO;AAAA,UACN;AAAA,YACC,KAAK;AAAA,YACL,WAAW,QAAQ;AAAA,YACnB,WAAW,QAAQ,OAAO;AAAA,YAC1B,qBAAqB,QAAQ,OAAO;AAAA,YACpC,SAAS,QAAQ,OAAO;AAAA,UACzB;AAAA,UACA;AAAA,QACD;AACA,aAAK,aAAa,QAAQ,WAAW,KAAK;AAAA,MAC3C;AAAA,IACD,CAAC;AAGD,SAAK,OAAO,GAAG,gBAAgB,OAAO,YAAY;AACjD,UAAI;AACH,eAAO;AAAA,UACN,EAAE,WAAW,QAAQ,WAAW,WAAW,QAAQ,OAAO,UAAU;AAAA,UACpE;AAAA,QACD;AACA,cAAM,SAAS,eAAe,WAAW,QAAQ,OAAO,SAAS;AACjE,YAAI,CAAC,UAAU,CAAC,OAAO,KAAK;AAC3B,gBAAM,IAAI,MAAM,2CAA2C;AAAA,QAC5D;AACA,cAAM,OAAe;AAAA,UACpB,MAAM;AAAA,UACN,MAAM,OAAO;AAAA,QACd;AACA,aAAK,gBAAgB,QAAQ,WAAW,EAAE,KAAK,CAAC;AAAA,MACjD,SAAS,OAAO;AACf,eAAO;AAAA,UACN;AAAA,YACC,KAAK;AAAA,YACL,WAAW,QAAQ;AAAA,YACnB,WAAW,QAAQ,OAAO;AAAA,UAC3B;AAAA,UACA;AAAA,QACD;AACA,aAAK,aAAa,QAAQ,WAAW,KAAK;AAAA,MAC3C;AAAA,IACD,CAAC;AAED,SAAK,OAAO,GAAG,oBAAoB,OAAO,YAAY;AACrD,UAAI;AACH,eAAO;AAAA,UACN;AAAA,YACC,WAAW,QAAQ;AAAA,YACnB,WAAW,QAAQ,OAAO;AAAA,UAC3B;AAAA,UACA;AAAA,QACD;AACA,cAAM,SAAS,MAAM,iBAAiB;AACtC,aAAK,gBAAgB,QAAQ,WAAW,MAAM;AAAA,MAC/C,SAAS,OAAO;AACf,eAAO;AAAA,UACN;AAAA,YACC,KAAK;AAAA,YACL,WAAW,QAAQ;AAAA,YACnB,WAAW,QAAQ,OAAO;AAAA,UAC3B;AAAA,UACA;AAAA,QACD;AACA,aAAK,aAAa,QAAQ,WAAW,KAAK;AAAA,MAC3C;AAAA,IACD,CAAC;AAED,SAAK,OAAO,GAAG,sBAAsB,OAAO,YAAY;AACvD,UAAI;AACH,cAAM,EAAE,MAAM,aAAa,UAAU,IAAI,QAAQ;AACjD,eAAO;AAAA,UACN,EAAE,WAAW,QAAQ,WAAW,WAAW,MAAM,YAAY;AAAA,UAC7D;AAAA,QACD;AACA,cAAM,UAAU,MAAM,qBAAqB,WAAW;AACtD,aAAK,gBAAgB,QAAQ,WAAW;AAAA,UACvC,MAAM;AAAA,UACN,SAAS,qBAAqB,OAAO;AAAA,QACtC,CAAC;AAAA,MACF,SAAS,OAAO;AACf,eAAO;AAAA,UACN;AAAA,YACC,KAAK;AAAA,YACL,WAAW,QAAQ;AAAA,YACnB,WAAW,QAAQ,OAAO;AAAA,UAC3B;AAAA,UACA;AAAA,QACD;AACA,aAAK,aAAa,QAAQ,WAAW,KAAK;AAAA,MAC3C;AAAA,IACD,CAAC;AAED,SAAK,OAAO,GAAG,kBAAkB,OAAO,YAAY;AACnD,UAAI;AACH,cAAM,EAAE,WAAW,MAAM,YAAY,IAAI,QAAQ;AACjD,eAAO;AAAA,UACN,EAAE,WAAW,QAAQ,WAAW,WAAW,MAAM,YAAY;AAAA,UAC7D;AAAA,QACD;AACA,cAAM,SAAS,eAAe,WAAW,SAAS;AAClD,YAAI,CAAC,UAAU,CAAC,OAAO,KAAK;AAC3B,gBAAM,IAAI,MAAM,2CAA2C;AAAA,QAC5D;AACA,cAAM,WAAW,cACdF,MAAK,WAAW,WAAW,IAC1B,cACAA,MAAK,KAAK,OAAO,KAAK,WAAW,IAClC,OAAO;AACV,cAAM,UAAU,MAAM,qBAAqB,QAAQ;AACnD,aAAK,gBAAgB,QAAQ,WAAW,EAAE,MAAM,UAAU,QAAQ,CAAC;AAAA,MACpE,SAAS,OAAO;AACf,eAAO;AAAA,UACN;AAAA,YACC,KAAK;AAAA,YACL,WAAW,QAAQ;AAAA,YACnB,WAAW,QAAQ,OAAO;AAAA,UAC3B;AAAA,UACA;AAAA,QACD;AACA,aAAK,aAAa,QAAQ,WAAW,KAAK;AAAA,MAC3C;AAAA,IACD,CAAC;AAED,SAAK,OAAO,GAAG,eAAe,OAAO,YAAY;AAChD,UAAI;AACH,cAAM,EAAE,WAAW,MAAM,YAAY,IAAI,QAAQ;AACjD,eAAO;AAAA,UACN,EAAE,WAAW,QAAQ,WAAW,WAAW,MAAM,YAAY;AAAA,UAC7D;AAAA,QACD;AACA,cAAM,SAAS,eAAe,WAAW,SAAS;AAClD,YAAI,CAAC,UAAU,CAAC,OAAO,KAAK;AAC3B,gBAAM,IAAI,MAAM,2CAA2C;AAAA,QAC5D;AACA,cAAM,WAAWA,MAAK,WAAW,WAAW,IACzC,cACAA,MAAK,KAAK,OAAO,KAAK,WAAW;AACpC,cAAM,WAAW,qBAAqB,QAAQ;AAC9C,YAAI,UAAU;AACb,gBAAM,SAAS,MAAMC,IAAG,SAAS,QAAQ;AACzC,gBAAME,WAAgC;AAAA,YACrC,MAAM;AAAA,YACN,aAAa;AAAA,YACb,SAAS,QAAQ,QAAQ,WAAW,OAAO,SAAS,QAAQ,CAAC;AAAA,YAC7D;AAAA,UACD;AACA,eAAK,gBAAgB,QAAQ,WAAWA,QAAO;AAC/C;AAAA,QACD;AACA,cAAM,UAAU,MAAMF,IAAG,SAAS,UAAU,MAAM;AAClD,cAAM,UAAgC;AAAA,UACrC,MAAM;AAAA,UACN,aAAa;AAAA,UACb;AAAA,QACD;AACA,aAAK,gBAAgB,QAAQ,WAAW,OAAO;AAAA,MAChD,SAAS,OAAO;AACf,eAAO;AAAA,UACN;AAAA,YACC,KAAK;AAAA,YACL,WAAW,QAAQ;AAAA,YACnB,WAAW,QAAQ,OAAO;AAAA,UAC3B;AAAA,UACA;AAAA,QACD;AACA,aAAK,aAAa,QAAQ,WAAW,KAAK;AAAA,MAC3C;AAAA,IACD,CAAC;AAED,SAAK,OAAO,GAAG,oBAAoB,OAAO,YAAY;AACrD,UAAI;AACH,cAAM,EAAE,UAAU,IAAI,QAAQ;AAC9B,eAAO;AAAA,UACN,EAAE,WAAW,QAAQ,WAAW,UAAU;AAAA,UAC1C;AAAA,QACD;AACA,cAAM,SAAS,eAAe,WAAW,SAAS;AAClD,YAAI,CAAC,UAAU,CAAC,OAAO,KAAK;AAC3B,gBAAM,IAAI,MAAM,2CAA2C;AAAA,QAC5D;AACA,cAAM,UAAU,MAAM,KAAK,qBAAqB,OAAO,GAAG;AAC1D,aAAK,gBAAgB,QAAQ,WAAW;AAAA,UACvC,UAAU,OAAO;AAAA,UACjB;AAAA,QACD,CAAC;AAAA,MACF,SAAS,OAAO;AACf,eAAO;AAAA,UACN;AAAA,YACC,KAAK;AAAA,YACL,WAAW,QAAQ;AAAA,YACnB,WAAW,QAAQ,OAAO;AAAA,UAC3B;AAAA,UACA;AAAA,QACD;AACA,aAAK,aAAa,QAAQ,WAAW,KAAK;AAAA,MAC3C;AAAA,IACD,CAAC;AAGD,SAAK,OAAO,GAAG,yBAAyB,OAAO,YAAY;AAC1D,UAAI;AACH,cAAM,EAAE,KAAK,UAAU,IAAI,QAAQ;AACnC,eAAO;AAAA,UACN,EAAE,WAAW,QAAQ,WAAW,KAAK,UAAU;AAAA,UAC/C;AAAA,QACD;AACA,cAAM,SAAS,MAAM,eAAe,iBAAiB;AAAA,UACpD;AAAA,UACA;AAAA,QACD,CAAC;AACD,aAAK,gBAAgB,QAAQ,WAAW,MAAM;AAAA,MAC/C,SAAS,OAAO;AACf,eAAO;AAAA,UACN;AAAA,YACC,KAAK;AAAA,YACL,WAAW,QAAQ;AAAA,UACpB;AAAA,UACA;AAAA,QACD;AACA,aAAK,aAAa,QAAQ,WAAW,KAAK;AAAA,MAC3C;AAAA,IACD,CAAC;AAGD,SAAK,OAAO,GAAG,oBAAoB,OAAO,YAAY;AACrD,UAAI;AACH,cAAM,EAAE,WAAW,IAAI,IAAI,QAAQ;AACnC,eAAO;AAAA,UACN,EAAE,WAAW,QAAQ,WAAW,WAAW,IAAI;AAAA,UAC/C;AAAA,QACD;AACA,cAAM,UAAU,MAAM,eAAe,YAAY,WAAW,GAAG;AAC/D,aAAK,gBAAgB,QAAQ,WAAW,OAAO;AAAA,MAChD,SAAS,OAAO;AACf,eAAO;AAAA,UACN;AAAA,YACC,KAAK;AAAA,YACL,WAAW,QAAQ;AAAA,YACnB,WAAW,QAAQ,OAAO;AAAA,UAC3B;AAAA,UACA;AAAA,QACD;AACA,aAAK,aAAa,QAAQ,WAAW,KAAK;AAAA,MAC3C;AAAA,IACD,CAAC;AAGD,SAAK,OAAO,GAAG,sBAAsB,OAAO,YAAY;AACvD,UAAI;AACH,cAAM,EAAE,WAAW,IAAI,IAAI,QAAQ;AACnC,eAAO;AAAA,UACN,EAAE,WAAW,QAAQ,WAAW,WAAW,IAAI;AAAA,UAC/C;AAAA,QACD;AACA,cAAM,UAAU,MAAM,eAAe,cAAc,WAAW,GAAG;AACjE,aAAK,gBAAgB,QAAQ,WAAW,OAAO;AAAA,MAChD,SAAS,OAAO;AACf,eAAO;AAAA,UACN;AAAA,YACC,KAAK;AAAA,YACL,WAAW,QAAQ;AAAA,YACnB,WAAW,QAAQ,OAAO;AAAA,UAC3B;AAAA,UACA;AAAA,QACD;AACA,aAAK,aAAa,QAAQ,WAAW,KAAK;AAAA,MAC3C;AAAA,IACD,CAAC;AAAA,EACF;AAAA,EAEQ,+BAA+B;AACtC,UAAM,EAAE,eAAe,IAAI,KAAK;AAEhC,mBAAe,gBAAgB,CAAC,iBAAiB;AAChD,UAAI,KAAK,WAAW;AAEnB,aAAK,OAAO;AAAA,UACX;AAAA,UACA;AAAA,QACD;AAAA,MACD;AAAA,IACD,CAAC;AAED,mBAAe,eAAe,CAAC,YAAY;AAC1C,UAAI,KAAK,WAAW;AACnB,aAAK,OAAO,KAAK,iBAAiB,OAAO;AAAA,MAC1C;AAAA,IACD,CAAC;AAED,mBAAe,oBAAoB,CAAC,YAAY;AAC/C,UAAI,KAAK,WAAW;AACnB,aAAK,OAAO,KAAK,sBAAsB,OAAO;AAAA,MAC/C;AAAA,IACD,CAAC;AAED,mBAAe,mBAAmB,CAAC,YAAY;AAC9C,UAAI,KAAK,WAAW;AACnB,aAAK,OAAO,KAAK,qBAAqB,OAAO;AAAA,MAC9C;AAAA,IACD,CAAC;AAED,mBAAe,iBAAiB,CAAC,UAAU;AAC1C,UAAI,KAAK,WAAW;AACnB,aAAK,OAAO,KAAK,mBAAmB,KAAK;AAAA,MAC1C;AAAA,IACD,CAAC;AAED,mBAAe,kBAAkB,CAAC,YAAY;AAC7C,UAAI,KAAK,WAAW;AACnB,eAAO;AAAA,UACN;AAAA,YACC,OAAO,QAAQ,MAAM;AAAA,YACrB,SAAS,QAAQ,QAAQ;AAAA,YACzB,SAAS,QAAQ,QAAQ;AAAA,UAC1B;AAAA,UACA;AAAA,QACD;AACA,aAAK,OAAO,KAAK,oBAAoB,OAAO;AAAA,MAC7C;AAAA,IACD,CAAC;AAAA,EACF;AAAA,EAEA,MAAc,qBACb,UACoC;AACpC,UAAM,KAAK,MAAM,cAAc,QAAQ;AACvC,UAAM,WAAW,MAAM,KAAK,aAAa,UAAU,IAAI,UAAU,CAAC,CAAC;AACnE,WAAO,SAAS,IAAI,CAAC,cAAc;AAAA,MAClC,MAAMD,MAAK,SAAS,QAAQ;AAAA,MAC5B,cAAcA,MAAK,SAAS,UAAU,QAAQ;AAAA,MAC9C,MAAM;AAAA,IACP,EAAE;AAAA,EACH;AAAA,EAEA,MAAc,aACb,UACA,IACA,SACA,YAAsB,CAAC,GACH;AACpB,QAAI,UAAU,UAAU,oBAAoB;AAC3C,aAAO;AAAA,IACR;AACA,UAAM,UAAU,MAAMC,IAAG,QAAQ,UAAU,EAAE,eAAe,KAAK,CAAC;AAClE,eAAW,SAAS,SAAS;AAC5B,UAAI,UAAU,UAAU,oBAAoB;AAC3C;AAAA,MACD;AACA,YAAM,YAAYD,MAAK,KAAK,UAAU,MAAM,IAAI;AAChD,YAAM,eAAeA,MAAK,SAAS,SAAS,SAAS;AAGrD,YAAM,YAAY,MAAM,YAAY,IAAI,GAAG,YAAY,MAAM;AAC7D,UAAI,GAAG,QAAQ,SAAS,GAAG;AAC1B;AAAA,MACD;AAEA,UAAI,MAAM,YAAY,GAAG;AACxB,cAAM,KAAK,aAAa,WAAW,IAAI,SAAS,SAAS;AAAA,MAC1D,WAAW,MAAM,OAAO,GAAG;AAC1B,kBAAU,KAAK,SAAS;AAAA,MACzB;AAAA,IACD;AACA,WAAO;AAAA,EACR;AAAA,EAEQ,gBAAmB,WAAmB,QAAW;AACxD,UAAM,WAA2B,EAAE,WAAW,OAAO;AACrD,SAAK,OAAO,KAAK,gBAAgB,QAAQ;AACzC,WAAO,MAAM,EAAE,UAAU,GAAG,mBAAmB;AAAA,EAChD;AAAA,EAEQ,aAAa,WAAmB,OAAgB;AACvD,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,UAAM,SAAS,iBAAiB,QAAQ,MAAM,QAAQ;AACtD,WAAO;AAAA,MACN;AAAA,QACC;AAAA,QACA,KAAK;AAAA,QACL;AAAA,QACA;AAAA,MACD;AAAA,MACA;AAAA,IACD;AACA,UAAM,WAAiC;AAAA,MACtC;AAAA,MACA,OAAO;AAAA,QACN,MAAM;AAAA,QACN;AAAA,QACA,WAAW;AAAA,QACX,OAAO;AAAA,QACP;AAAA,MACD;AAAA,IACD;AACA,SAAK,OAAO,KAAK,gBAAgB,QAAQ;AAAA,EAC1C;AAAA,EAEQ,WAAW;AAClB,UAAM,EAAE,QAAQ,eAAe,IAAI,KAAK;AACxC,WAAO,KAAK,EAAE,WAAW,OAAO,UAAU,GAAG,mBAAmB;AAChE,SAAK,OAAO,KAAK,gBAAgB;AAAA,MAChC,WAAW,OAAO;AAAA,MAClB,UAAU,OAAO;AAAA,MACjB,SAAS,OAAO;AAAA,MAChB,UAAU,OAAO,YAAY,IAAI,CAAC,aAAa;AAAA,QAC9C,WAAW,QAAQ;AAAA,QACnB,cAAc,QAAQ;AAAA,MACvB,EAAE;AAAA,MACF,kBAAkB,OAAO;AAAA,IAC1B,CAAC;AACD,WAAO,KAAK,EAAE,WAAW,OAAO,UAAU,GAAG,4BAA4B;AAEzE,SAAK,OAAO,KAAK,iBAAiB,eAAe,aAAa,CAAC;AAAA,EAChE;AAAA,EAEQ,iBAAiB;AACxB,SAAK,cAAc;AACnB,SAAK,oBAAoB,YAAY,MAAM;AAC1C,UAAI,KAAK,WAAW;AACnB,aAAK,OAAO,KAAK,eAAe;AAChC,aAAK,OAAO;AAAA,UACX;AAAA,UACA,KAAK,QAAQ,eAAe,aAAa;AAAA,QAC1C;AAAA,MACD;AAAA,IACD,GAAG,GAAK;AAAA,EACT;AAAA,EAEQ,gBAAgB;AACvB,QAAI,KAAK,mBAAmB;AAC3B,oBAAc,KAAK,iBAAiB;AACpC,WAAK,oBAAoB;AAAA,IAC1B;AAAA,EACD;AAAA,EAEA,UAAU;AACT,SAAK,OAAO,QAAQ;AAAA,EACrB;AAAA,EAEA,aAAa;AACZ,SAAK,cAAc;AACnB,SAAK,OAAO,WAAW;AAAA,EACxB;AAAA,EAEA,cAAc;AACb,WAAO,KAAK;AAAA,EACb;AACD;;;AJz0BO,IAAM,gBAAN,MAAoB;AAAA,EAC1B,YAA6B,QAAmB;AAAnB;AAAA,EAAoB;AAAA,EAEjD,MAAM,sBAAqC;AAC1C,UAAMI,IAAG,MAAM,KAAK,OAAO,UAAU,EAAE,WAAW,KAAK,CAAC;AACxD,UAAMA,IAAG,MAAM,KAAK,OAAO,SAAS,EAAE,WAAW,KAAK,CAAC;AAAA,EACxD;AAAA,EAEA,MAAM,SAAiC;AACtC,QAAI;AACH,YAAM,UAAU,MAAMA,IAAG,SAAS,KAAK,OAAO,SAAS,MAAM;AAC7D,YAAM,MAAM,OAAO,SAAS,QAAQ,KAAK,GAAG,EAAE;AAC9C,UAAI,OAAO,MAAM,GAAG,GAAG;AACtB,eAAO;AAAA,MACR;AAEA,UAAI;AACH,gBAAQ,KAAK,KAAK,CAAC;AACnB,eAAO;AAAA,MACR,QAAQ;AAEP,cAAM,KAAK,cAAc;AACzB,eAAO;AAAA,MACR;AAAA,IACD,QAAQ;AACP,aAAO;AAAA,IACR;AAAA,EACD;AAAA,EAEA,MAAM,aAAa,KAA4B;AAC9C,UAAMA,IAAG,UAAU,KAAK,OAAO,SAAS,OAAO,GAAG,GAAG,MAAM;AAAA,EAC5D;AAAA,EAEA,MAAM,gBAA+B;AACpC,QAAI;AACH,YAAMA,IAAG,OAAO,KAAK,OAAO,OAAO;AAAA,IACpC,QAAQ;AAAA,IAER;AAAA,EACD;AAAA,EAEA,MAAM,SAAgC;AACrC,UAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,QAAI,CAAC,KAAK;AACT,aAAO,EAAE,SAAS,MAAM;AAAA,IACzB;AACA,WAAO,EAAE,SAAS,MAAM,IAAI;AAAA,EAC7B;AAAA,EAEA,MAAM,MAAM,SAAmD;AAC9D,UAAM,cAAc,MAAM,KAAK,OAAO;AACtC,QAAI,aAAa;AAChB,aAAO,KAAK,EAAE,KAAK,YAAY,GAAG,wBAAwB;AAC1D;AAAA,IACD;AAEA,UAAM,KAAK,oBAAoB;AAE/B,QAAI,SAAS,YAAY;AACxB,YAAM,KAAK,cAAc;AAAA,IAC1B,OAAO;AACN,YAAM,KAAK,gBAAgB;AAAA,IAC5B;AAAA,EACD;AAAA,EAEA,MAAM,OAAsB;AAC3B,UAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,QAAI,CAAC,KAAK;AACT,aAAO,KAAK,oBAAoB;AAChC;AAAA,IACD;AAGA,QAAI;AACH,cAAQ,KAAK,KAAK,CAAC;AAAA,IACpB,QAAQ;AACP,aAAO,KAAK,4BAA4B;AACxC,YAAM,KAAK,cAAc;AACzB;AAAA,IACD;AAEA,QAAI;AACH,aAAO,KAAK,EAAE,IAAI,GAAG,qBAAqB;AAC1C,cAAQ,KAAK,KAAK,SAAS;AAG3B,YAAM,YAAY,KAAK,IAAI;AAC3B,YAAM,UAAU;AAEhB,aAAO,KAAK,IAAI,IAAI,YAAY,SAAS;AACxC,cAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,GAAG,CAAC;AACvD,YAAI;AACH,kBAAQ,KAAK,KAAK,CAAC;AAAA,QAEpB,QAAQ;AAEP,iBAAO,KAAK,EAAE,IAAI,GAAG,2BAA2B;AAChD,gBAAM,KAAK,cAAc;AACzB;AAAA,QACD;AAAA,MACD;AAGA,aAAO,KAAK,EAAE,IAAI,GAAG,yBAAyB;AAC9C,UAAI;AACH,gBAAQ,KAAK,KAAK,SAAS;AAE3B,cAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,GAAG,CAAC;AACvD,eAAO,KAAK,EAAE,IAAI,GAAG,4BAA4B;AAAA,MAClD,QAAQ;AAEP,eAAO,KAAK,EAAE,IAAI,GAAG,wBAAwB;AAAA,MAC9C;AACA,YAAM,KAAK,cAAc;AAAA,IAC1B,SAAS,OAAO;AACf,aAAO,MAAM,EAAE,KAAK,MAAM,GAAG,mBAAmB;AAChD,YAAM,KAAK,cAAc;AAAA,IAC1B;AAAA,EACD;AAAA,EAEA,MAAc,kBAAiC;AAC9C,UAAM,UAAUC,MAAK;AAAA,MACpB,KAAK,OAAO;AAAA,MACZ,IAAG,oBAAI,KAAK,GAAE,YAAY,EAAE,QAAQ,SAAS,GAAG,CAAC;AAAA,IAClD;AAGA,UAAM,OAAO,QAAQ,KACnB,MAAM,CAAC,EACP,OAAO,CAAC,QAAQ,QAAQ,kBAAkB,QAAQ,IAAI;AACxD,SAAK,KAAK,cAAc;AAExB,UAAM,QAAQC,OAAM,QAAQ,KAAK,CAAC,GAAG,MAAM;AAAA,MAC1C,UAAU;AAAA,MACV,OAAO,CAAC,UAAU,QAAQ,MAAM;AAAA,MAChC,KAAK;AAAA,QACJ,GAAG,QAAQ;AAAA,QACX,qBAAqB,KAAK,OAAO;AAAA,MAClC;AAAA,IACD,CAAC;AAED,QAAI,CAAC,MAAM,KAAK;AACf,aAAO,MAAM,qBAAqB;AAClC,YAAM,IAAI,MAAM,gCAAgC;AAAA,IACjD;AAGA,UAAM,YAAY,MAAMF,IAAG,KAAK,SAAS,GAAG;AAC5C,UAAM,aAAa;AAEnB,UAAM,QAAQ,GAAG,QAAQ,CAAC,SAAiB;AAC1C,iBAAW,MAAM,YAAY,KAAK,SAAS,CAAC,EAAE,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IAC/D,CAAC;AAED,UAAM,QAAQ,GAAG,QAAQ,CAAC,SAAiB;AAC1C,iBAAW,MAAM,YAAY,KAAK,SAAS,CAAC,EAAE,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IAC/D,CAAC;AAGD,UAAM,GAAG,QAAQ,CAAC,MAAM,WAAW;AAClC,iBACE,MAAM,mCAAmC,IAAI,YAAY,MAAM;AAAA,CAAI,EACnE,MAAM,MAAM;AAAA,MAAC,CAAC;AAChB,iBAAW,MAAM,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IAClC,CAAC;AAID,UAAM,MAAM;AAEZ,WAAO,KAAK,EAAE,KAAK,MAAM,IAAI,GAAG,gBAAgB;AAChD,YAAQ,IAAI,SAAS,OAAO,EAAE;AAC9B,WAAO,KAAK,EAAE,QAAQ,GAAG,iBAAiB;AAAA,EAC3C;AAAA,EAEA,MAAM,gBAA+B;AACpC,UAAM,MAAM,QAAQ;AACpB,UAAM,KAAK,aAAa,GAAG;AAE3B,WAAO,KAAK,EAAE,IAAI,GAAG,iBAAiB;AACtC,WAAO,KAAK,EAAE,YAAY,KAAK,OAAO,WAAW,GAAG,oBAAoB;AACxE,WAAO,KAAK,EAAE,WAAW,KAAK,OAAO,UAAU,GAAG,mBAAmB;AAGrE,UAAM,SAAS,MAAM,UAAU;AAC/B,QAAI,CAAC,QAAQ;AACZ,aAAO,MAAM,wBAAwB;AACrC,cAAQ;AAAA,QACP;AAAA,MACD;AACA,aAAO,KAAK,6BAA6B;AACzC,cAAQ,KAAK,CAAC;AAAA,IACf;AACA,WAAO,KAAK,uBAAuB;AAEnC,UAAM,iBAAiB,IAAI,eAAe,KAAK,MAAM;AACrD,UAAM,eAAe,IAAI,aAAa;AAAA,MACrC,QAAQ,KAAK;AAAA,MACb;AAAA,MACA;AAAA,IACD,CAAC;AAED,QAAI,eAAe;AAEnB,UAAM,WAAW,OAAO,WAAmB;AAC1C,UAAI,cAAc;AACjB,eAAO,KAAK,EAAE,OAAO,GAAG,iCAAiC;AACzD;AAAA,MACD;AACA,qBAAe;AAEf,aAAO,KAAK,EAAE,OAAO,GAAG,uBAAuB;AAE/C,UAAI;AACH,qBAAa,WAAW;AACxB,cAAM,eAAe,SAAS;AAC9B,cAAM,KAAK,cAAc;AACzB,eAAO,KAAK,EAAE,OAAO,GAAG,0BAA0B;AAAA,MACnD,SAAS,OAAO;AACf,eAAO,MAAM,EAAE,KAAK,OAAO,OAAO,GAAG,uBAAuB;AAAA,MAC7D;AAAA,IACD;AAEA,YAAQ,GAAG,UAAU,MAAM;AAC1B,eAAS,QAAQ,EAAE,MAAM,CAAC,UAAU;AACnC,eAAO,MAAM,EAAE,KAAK,MAAM,GAAG,8BAA8B;AAAA,MAC5D,CAAC;AAAA,IACF,CAAC;AACD,YAAQ,GAAG,WAAW,MAAM;AAC3B,eAAS,SAAS,EAAE,MAAM,CAAC,UAAU;AACpC,eAAO,MAAM,EAAE,KAAK,MAAM,GAAG,+BAA+B;AAAA,MAC7D,CAAC;AAAA,IACF,CAAC;AAED,iBAAa,QAAQ;AAGrB,UAAM,IAAI,QAAQ,MAAM;AAAA,IAAC,CAAC;AAAA,EAC3B;AAAA,EAEA,MAAM,KAAK,SAA+D;AACzE,UAAM,QAAQ,MAAMA,IAAG,QAAQ,KAAK,OAAO,OAAO;AAClD,UAAM,WAAW,MACf,OAAO,CAAC,MAAM,EAAE,SAAS,aAAa,CAAC,EACvC,KAAK,EACL,QAAQ;AAEV,QAAI,SAAS,WAAW,GAAG;AAC1B,aAAO,KAAK,mBAAmB;AAC/B,cAAQ,IAAI,oBAAoB;AAChC;AAAA,IACD;AAEA,UAAM,YAAYC,MAAK,KAAK,KAAK,OAAO,SAAS,SAAS,CAAC,CAAC;AAC5D,WAAO,KAAK,EAAE,SAAS,UAAU,GAAG,oBAAoB;AACxD,YAAQ,IAAI,aAAa,SAAS;AAAA,CAAI;AAEtC,QAAI,SAAS,QAAQ;AAEpB,YAAM,OAAOC,OAAM,QAAQ,CAAC,MAAM,SAAS,GAAG;AAAA,QAC7C,OAAO;AAAA,MACR,CAAC;AACD,YAAM,IAAI,QAAc,CAAC,YAAY;AACpC,aAAK,GAAG,SAAS,MAAM,QAAQ,CAAC;AAAA,MACjC,CAAC;AAAA,IACF,OAAO;AACN,YAAM,UAAU,MAAMF,IAAG,SAAS,WAAW,MAAM;AACnD,YAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,YAAM,QAAQ,SAAS,SAAS;AAChC,cAAQ,IAAI,MAAM,MAAM,CAAC,KAAK,EAAE,KAAK,IAAI,CAAC;AAAA,IAC3C;AAAA,EACD;AACD;;;AN1RA,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACE,KAAK,SAAS,EACd,YAAY,yDAAyD,EACrE,QAAQ,OAAO;AAEjB,QACE,QAAQ,OAAO,EACf,YAAY,0BAA0B,EACtC,OAAO,mBAAmB,eAAe,QAAQ,IAAI,mBAAmB,EACxE,OAAO,gBAAgB,wCAAwC,EAC/D,OAAO,OAAO,YAAY;AAC1B,MAAI,QAAQ,SAAS;AACpB,YAAQ,IAAI,sBAAsB,QAAQ;AAAA,EAC3C;AACA,QAAM,SAAS,MAAM,aAAa;AAClC,QAAM,SAAS,IAAI,cAAc,MAAM;AACvC,QAAM,OAAO,MAAM,EAAE,YAAY,QAAQ,WAAW,CAAC;AACtD,CAAC;AAEF,QACE,QAAQ,MAAM,EACd,YAAY,yBAAyB,EACrC,OAAO,YAAY;AACnB,QAAM,SAAS,MAAM,aAAa;AAClC,QAAM,SAAS,IAAI,cAAc,MAAM;AACvC,QAAM,OAAO,KAAK;AACnB,CAAC;AAEF,QACE,QAAQ,QAAQ,EAChB,YAAY,oBAAoB,EAChC,OAAO,YAAY;AACnB,QAAM,SAAS,MAAM,aAAa;AAClC,QAAM,SAAS,IAAI,cAAc,MAAM;AACvC,QAAM,SAAS,MAAM,OAAO,OAAO;AACnC,MAAI,OAAO,SAAS;AACnB,WAAO,KAAK,EAAE,KAAK,OAAO,IAAI,GAAG,uBAAuB;AACxD,YAAQ,IAAI,0BAA0B,OAAO,GAAG,GAAG;AACnD,QAAI,OAAO,cAAc,QAAW;AACnC,cAAQ,IAAI,yBAAyB,OAAO,YAAY,QAAQ,IAAI,EAAE;AAAA,IACvE;AACA,QAAI,OAAO,iBAAiB,QAAW;AACtC,cAAQ,IAAI,oBAAoB,OAAO,YAAY,EAAE;AAAA,IACtD;AAAA,EACD,OAAO;AACN,WAAO,KAAK,2BAA2B;AACvC,YAAQ,IAAI,uBAAuB;AAAA,EACpC;AACD,CAAC;AAEF,QACE,QAAQ,MAAM,EACd,YAAY,kBAAkB,EAC9B,OAAO,gBAAgB,mBAAmB,EAC1C,OAAO,wBAAwB,2BAA2B,IAAI,EAC9D,OAAO,OAAO,YAAY;AAC1B,QAAM,SAAS,MAAM,aAAa;AAClC,QAAM,SAAS,IAAI,cAAc,MAAM;AACvC,QAAM,OAAO,KAAK;AAAA,IACjB,QAAQ,QAAQ;AAAA,IAChB,OAAO,OAAO,SAAS,QAAQ,OAAO,EAAE;AAAA,EACzC,CAAC;AACF,CAAC;AAEF,QACE,QAAQ,OAAO,EACf,YAAY,6CAA6C,EACzD,OAAO,YAAY;AACnB,QAAM,SAAS,MAAM,MAAM;AAC3B,MAAI,CAAC,OAAO,SAAS;AACpB,WAAO,MAAM,EAAE,KAAK,OAAO,MAAM,GAAG,cAAc;AAClD,YAAQ,MAAM,iBAAiB,OAAO,KAAK,EAAE;AAC7C,YAAQ,KAAK,CAAC;AAAA,EACf;AACD,CAAC;AAEF,QACE,QAAQ,QAAQ,EAChB,YAAY,2BAA2B,EACvC,OAAO,YAAY;AACnB,QAAM,OAAO;AACd,CAAC;AAEF,QACE,QAAQ,aAAa,EACrB,YAAY,4BAA4B,EACxC,OAAO,YAAY;AACnB,QAAM,YAAY;AACnB,CAAC;AAEF,eAAsB,MAAM;AAC3B,QAAM,QAAQ,WAAW,QAAQ,IAAI;AACtC;AAEA,IAAI,EAAE,MAAM,CAAC,UAAU;AACtB,SAAO,MAAM,EAAE,KAAK,MAAM,GAAG,eAAe;AAC5C,UAAQ,MAAM,UAAU,MAAM,OAAO;AACrC,UAAQ,KAAK,CAAC;AACf,CAAC;","names":["os","path","fs","path","os","path","spawn","fs","path","randomUUID","EventEmitter","EventEmitter","randomUUID","EventEmitter","fs","path","path","fs","EventEmitter","preview","fs","path","spawn"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/auth/login.ts","../src/lib/logger.ts","../src/auth/credentials.ts","../src/config.ts","../src/config-loader.ts","../src/daemon/daemon.ts","../src/acp/session-manager.ts","../../../packages/shared/dist/types/errors.js","../src/acp/acp-connection.ts","../src/daemon/socket-client.ts","../src/lib/git-utils.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { login, loginStatus, logout } from \"./auth/login.js\";\nimport { getCliConfig } from \"./config.js\";\nimport { DaemonManager } from \"./daemon/daemon.js\";\nimport { logger } from \"./lib/logger.js\";\n\nconst program = new Command();\n\nprogram\n\t.name(\"mobvibe\")\n\t.description(\"Mobvibe CLI - Connect local ACP backends to the gateway\")\n\t.version(\"0.0.0\");\n\nprogram\n\t.command(\"start\")\n\t.description(\"Start the mobvibe daemon\")\n\t.option(\"--gateway <url>\", \"Gateway URL\", process.env.MOBVIBE_GATEWAY_URL)\n\t.option(\"--foreground\", \"Run in foreground instead of detaching\")\n\t.action(async (options) => {\n\t\tif (options.gateway) {\n\t\t\tprocess.env.MOBVIBE_GATEWAY_URL = options.gateway;\n\t\t}\n\t\tconst config = await getCliConfig();\n\t\tconst daemon = new DaemonManager(config);\n\t\tawait daemon.start({ foreground: options.foreground });\n\t});\n\nprogram\n\t.command(\"stop\")\n\t.description(\"Stop the mobvibe daemon\")\n\t.action(async () => {\n\t\tconst config = await getCliConfig();\n\t\tconst daemon = new DaemonManager(config);\n\t\tawait daemon.stop();\n\t});\n\nprogram\n\t.command(\"status\")\n\t.description(\"Show daemon status\")\n\t.action(async () => {\n\t\tconst config = await getCliConfig();\n\t\tconst daemon = new DaemonManager(config);\n\t\tconst status = await daemon.status();\n\t\tif (status.running) {\n\t\t\tlogger.info({ pid: status.pid }, \"daemon_status_running\");\n\t\t\tconsole.log(`Daemon is running (PID ${status.pid})`);\n\t\t\tif (status.connected !== undefined) {\n\t\t\t\tconsole.log(`Connected to gateway: ${status.connected ? \"yes\" : \"no\"}`);\n\t\t\t}\n\t\t\tif (status.sessionCount !== undefined) {\n\t\t\t\tconsole.log(`Active sessions: ${status.sessionCount}`);\n\t\t\t}\n\t\t} else {\n\t\t\tlogger.info(\"daemon_status_not_running\");\n\t\t\tconsole.log(\"Daemon is not running\");\n\t\t}\n\t});\n\nprogram\n\t.command(\"logs\")\n\t.description(\"Show daemon logs\")\n\t.option(\"-f, --follow\", \"Follow log output\")\n\t.option(\"-n, --lines <number>\", \"Number of lines to show\", \"50\")\n\t.action(async (options) => {\n\t\tconst config = await getCliConfig();\n\t\tconst daemon = new DaemonManager(config);\n\t\tawait daemon.logs({\n\t\t\tfollow: options.follow,\n\t\t\tlines: Number.parseInt(options.lines, 10),\n\t\t});\n\t});\n\nprogram\n\t.command(\"login\")\n\t.description(\"Authenticate with an API key from the WebUI\")\n\t.action(async () => {\n\t\tconst result = await login();\n\t\tif (!result.success) {\n\t\t\tlogger.error({ err: result.error }, \"login_failed\");\n\t\t\tconsole.error(`Login failed: ${result.error}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command(\"logout\")\n\t.description(\"Remove stored credentials\")\n\t.action(async () => {\n\t\tawait logout();\n\t});\n\nprogram\n\t.command(\"auth-status\")\n\t.description(\"Show authentication status\")\n\t.action(async () => {\n\t\tawait loginStatus();\n\t});\n\nexport async function run() {\n\tawait program.parseAsync(process.argv);\n}\n\nrun().catch((error) => {\n\tlogger.error({ err: error }, \"cli_run_error\");\n\tconsole.error(\"Error:\", error.message);\n\tprocess.exit(1);\n});\n","/**\n * Login command for CLI authentication.\n * Prompts user to paste an API key generated from the WebUI.\n */\n\nimport * as readline from \"node:readline/promises\";\nimport { logger } from \"../lib/logger.js\";\nimport {\n\ttype Credentials,\n\tdeleteCredentials,\n\tloadCredentials,\n\tsaveCredentials,\n} from \"./credentials.js\";\n\nexport interface LoginResult {\n\tsuccess: boolean;\n\terror?: string;\n}\n\n/**\n * Start the login flow.\n * Prompts user to paste an API key from the WebUI.\n */\nexport async function login(): Promise<LoginResult> {\n\tlogger.info(\"login_prompt_start\");\n\tconsole.log(\"To get an API key:\");\n\tconsole.log(\" 1. Open the Mobvibe WebUI in your browser\");\n\tconsole.log(\" 2. Go to Settings (gear icon) -> API Keys\");\n\tconsole.log(\" 3. Click 'Create API Key' and copy it\");\n\tconsole.log(\" 4. Paste the API key below\\n\");\n\n\tconst rl = readline.createInterface({\n\t\tinput: process.stdin,\n\t\toutput: process.stdout,\n\t});\n\n\ttry {\n\t\tconst apiKey = await rl.question(\"Paste your API key: \");\n\n\t\tif (!apiKey.trim()) {\n\t\t\tlogger.warn(\"login_missing_api_key\");\n\t\t\treturn { success: false, error: \"No API key provided\" };\n\t\t}\n\n\t\t// Basic format check\n\t\tif (!apiKey.trim().startsWith(\"mbk_\")) {\n\t\t\tlogger.warn(\"login_invalid_api_key_format\");\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: \"Invalid API key format (should start with mbk_)\",\n\t\t\t};\n\t\t}\n\n\t\t// Store credentials - gateway validates on connection\n\t\tconst credentials: Credentials = {\n\t\t\tapiKey: apiKey.trim(),\n\t\t\tcreatedAt: Date.now(),\n\t\t};\n\t\tawait saveCredentials(credentials);\n\t\tlogger.info(\"login_credentials_saved\");\n\n\t\tconsole.log(\"\\nAPI key saved!\");\n\t\tconsole.log(\"Run 'mobvibe start' to connect to the gateway.\");\n\n\t\treturn { success: true };\n\t} finally {\n\t\trl.close();\n\t}\n}\n\n/**\n * Logout - delete stored credentials.\n */\nexport async function logout(): Promise<void> {\n\tawait deleteCredentials();\n\tlogger.info(\"logout_complete\");\n\tconsole.log(\"Logged out successfully. Credentials deleted.\");\n}\n\n/**\n * Show current login status.\n */\nexport async function loginStatus(): Promise<void> {\n\tconst credentials = await loadCredentials();\n\tif (credentials) {\n\t\tlogger.info(\"login_status_logged_in\");\n\t\tconsole.log(\"Status: Logged in\");\n\t\tconsole.log(`API key: ${credentials.apiKey.slice(0, 12)}...`);\n\t\tconsole.log(`Saved: ${new Date(credentials.createdAt).toLocaleString()}`);\n\t} else {\n\t\tlogger.info(\"login_status_logged_out\");\n\t\tconsole.log(\"Status: Not logged in\");\n\t\tconsole.log(\"Run 'mobvibe login' to authenticate.\");\n\t}\n}\n","import pino from \"pino\";\n\nconst LOG_LEVEL = process.env.LOG_LEVEL ?? \"info\";\nconst isPretty = process.env.NODE_ENV !== \"production\";\n\nconst redact = {\n\tpaths: [\n\t\t\"req.headers.authorization\",\n\t\t\"req.headers.cookie\",\n\t\t\"req.headers['x-api-key']\",\n\t\t\"headers.authorization\",\n\t\t\"headers.cookie\",\n\t\t\"headers['x-api-key']\",\n\t\t\"apiKey\",\n\t\t\"token\",\n\t],\n\tcensor: \"[redacted]\",\n};\n\nconst transport = isPretty\n\t? {\n\t\t\ttarget: \"pino-pretty\",\n\t\t\toptions: {\n\t\t\t\tcolorize: true,\n\t\t\t\ttranslateTime: \"SYS:standard\",\n\t\t\t\tignore: \"pid,hostname\",\n\t\t\t},\n\t\t}\n\t: undefined;\n\nexport const logger = pino(\n\t{\n\t\tlevel: LOG_LEVEL,\n\t\tredact,\n\t\tbase: { service: \"mobvibe-cli\" },\n\t\tserializers: {\n\t\t\terr: pino.stdSerializers.err,\n\t\t\terror: pino.stdSerializers.err,\n\t\t},\n\t},\n\ttransport ? pino.transport(transport) : undefined,\n);\n","/**\n * Credentials management for CLI authentication.\n * Stores API key in ~/.mobvibe/credentials.json\n */\n\nimport fs from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nexport interface Credentials {\n\t/** API key for gateway authentication */\n\tapiKey: string;\n\t/** When the credentials were created */\n\tcreatedAt: number;\n\t/** Optional: custom gateway URL (user can manually set this) */\n\tgatewayUrl?: string;\n}\n\nconst MOBVIBE_DIR =\n\tprocess.env.MOBVIBE_HOME ?? path.join(os.homedir(), \".mobvibe\");\nconst CREDENTIALS_FILE = path.join(MOBVIBE_DIR, \"credentials.json\");\n\n/**\n * Ensure the mobvibe directory exists.\n */\nasync function ensureMobvibeDir(): Promise<void> {\n\tawait fs.mkdir(MOBVIBE_DIR, { recursive: true });\n}\n\n/**\n * Load credentials from the credentials file.\n * Returns null if no credentials exist.\n */\nexport async function loadCredentials(): Promise<Credentials | null> {\n\ttry {\n\t\tconst data = await fs.readFile(CREDENTIALS_FILE, \"utf8\");\n\t\tconst credentials = JSON.parse(data) as Credentials;\n\n\t\t// Validate required fields\n\t\tif (!credentials.apiKey) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn credentials;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Save credentials to the credentials file.\n */\nexport async function saveCredentials(credentials: Credentials): Promise<void> {\n\tawait ensureMobvibeDir();\n\tawait fs.writeFile(\n\t\tCREDENTIALS_FILE,\n\t\tJSON.stringify(credentials, null, 2),\n\t\t{ mode: 0o600 }, // Read/write only for owner\n\t);\n}\n\n/**\n * Delete the credentials file.\n */\nexport async function deleteCredentials(): Promise<void> {\n\ttry {\n\t\tawait fs.unlink(CREDENTIALS_FILE);\n\t} catch {\n\t\t// Ignore if file doesn't exist\n\t}\n}\n\n/**\n * Check if credentials exist.\n */\nexport async function hasCredentials(): Promise<boolean> {\n\tconst credentials = await loadCredentials();\n\treturn credentials !== null;\n}\n\n/**\n * Get the API key from credentials.\n * Also checks MOBVIBE_API_KEY env var as override.\n */\nexport async function getApiKey(): Promise<string | undefined> {\n\t// Environment variable takes precedence\n\tif (process.env.MOBVIBE_API_KEY) {\n\t\treturn process.env.MOBVIBE_API_KEY;\n\t}\n\n\tconst credentials = await loadCredentials();\n\treturn credentials?.apiKey;\n}\n\n/** Default production gateway URL */\nconst DEFAULT_GATEWAY_URL = \"https://mobvibe.zeabur.app\";\n\n/**\n * Get the gateway URL with the following priority:\n * 1. MOBVIBE_GATEWAY_URL env var\n * 2. gatewayUrl in credentials file\n * 3. Default production URL\n */\nexport async function getGatewayUrl(): Promise<string> {\n\t// Environment variable takes precedence\n\tif (process.env.MOBVIBE_GATEWAY_URL) {\n\t\treturn process.env.MOBVIBE_GATEWAY_URL;\n\t}\n\n\t// Check credentials file for custom gateway URL\n\tconst credentials = await loadCredentials();\n\tif (credentials?.gatewayUrl) {\n\t\treturn credentials.gatewayUrl;\n\t}\n\n\t// Default to production\n\treturn DEFAULT_GATEWAY_URL;\n}\n","import os from \"node:os\";\nimport path from \"node:path\";\nimport type { AcpBackendId, UserAgentConfig } from \"@mobvibe/shared\";\nimport { getGatewayUrl } from \"./auth/credentials.js\";\nimport { loadUserConfig } from \"./config-loader.js\";\nimport { logger } from \"./lib/logger.js\";\n\nexport type AcpBackendConfig = {\n\tid: AcpBackendId;\n\tlabel: string;\n\tcommand: string;\n\targs: string[];\n\tenvOverrides?: Record<string, string>;\n};\n\nexport type CliConfig = {\n\tgatewayUrl: string;\n\tacpBackends: AcpBackendConfig[];\n\tdefaultAcpBackendId: AcpBackendId;\n\tclientName: string;\n\tclientVersion: string;\n\thomePath: string;\n\tlogPath: string;\n\tpidFile: string;\n\tmachineId: string;\n\thostname: string;\n\tplatform: string;\n\tuserConfigPath?: string;\n\tuserConfigErrors?: string[];\n};\n\n// Default opencode backend\nconst DEFAULT_OPENCODE_BACKEND: AcpBackendConfig = {\n\tid: \"opencode\",\n\tlabel: \"opencode\",\n\tcommand: \"opencode\",\n\targs: [\"acp\"],\n};\n\nconst generateMachineId = (): string => {\n\tconst hostname = os.hostname();\n\tconst platform = os.platform();\n\tconst arch = os.arch();\n\tconst username = os.userInfo().username;\n\treturn `${hostname}-${platform}-${arch}-${username}`;\n};\n\nconst userAgentToBackendConfig = (\n\tagent: UserAgentConfig,\n): AcpBackendConfig => ({\n\tid: agent.id,\n\tlabel: agent.label ?? agent.id,\n\tcommand: agent.command,\n\targs: agent.args ?? [],\n\tenvOverrides: agent.env,\n});\n\nconst mergeBackends = (\n\tdefaultBackend: AcpBackendConfig,\n\tuserAgents: UserAgentConfig[] | undefined,\n): { backends: AcpBackendConfig[]; defaultId: AcpBackendId } => {\n\t// No user agents: use default opencode only\n\tif (!userAgents || userAgents.length === 0) {\n\t\treturn { backends: [defaultBackend], defaultId: defaultBackend.id };\n\t}\n\n\t// Check if user defined opencode (override case)\n\tconst userOpencode = userAgents.find((a) => a.id === \"opencode\");\n\n\tif (userOpencode) {\n\t\t// User overrides opencode - use only user-defined agents\n\t\treturn {\n\t\t\tbackends: userAgents.map(userAgentToBackendConfig),\n\t\t\tdefaultId: userAgents[0].id,\n\t\t};\n\t}\n\n\t// User didn't define opencode - prepend default opencode to user agents\n\treturn {\n\t\tbackends: [defaultBackend, ...userAgents.map(userAgentToBackendConfig)],\n\t\tdefaultId: defaultBackend.id,\n\t};\n};\n\nexport const getCliConfig = async (): Promise<CliConfig> => {\n\tconst env = process.env;\n\tconst homePath = env.MOBVIBE_HOME ?? path.join(os.homedir(), \".mobvibe\");\n\n\t// Load user configuration\n\tconst userConfigResult = await loadUserConfig(homePath);\n\n\t// Log any config errors as warnings\n\tif (userConfigResult.errors.length > 0) {\n\t\tfor (const error of userConfigResult.errors) {\n\t\t\tlogger.warn({ configPath: userConfigResult.path, error }, \"config_error\");\n\t\t}\n\t}\n\n\t// Merge backends\n\tconst { backends, defaultId } = mergeBackends(\n\t\tDEFAULT_OPENCODE_BACKEND,\n\t\tuserConfigResult.config?.agents,\n\t);\n\n\t// Override default if user specified one\n\tconst resolvedDefaultId =\n\t\tuserConfigResult.config?.defaultAgentId &&\n\t\tbackends.some((b) => b.id === userConfigResult.config?.defaultAgentId)\n\t\t\t? userConfigResult.config.defaultAgentId\n\t\t\t: defaultId;\n\n\t// Get gateway URL (env var > credentials file > default production URL)\n\tconst gatewayUrl = await getGatewayUrl();\n\n\treturn {\n\t\tgatewayUrl,\n\t\tacpBackends: backends,\n\t\tdefaultAcpBackendId: resolvedDefaultId,\n\t\tclientName: env.MOBVIBE_ACP_CLIENT_NAME ?? \"mobvibe-cli\",\n\t\tclientVersion: env.MOBVIBE_ACP_CLIENT_VERSION ?? \"0.0.0\",\n\t\thomePath,\n\t\tlogPath: path.join(homePath, \"logs\"),\n\t\tpidFile: path.join(homePath, \"daemon.pid\"),\n\t\tmachineId: env.MOBVIBE_MACHINE_ID ?? generateMachineId(),\n\t\thostname: os.hostname(),\n\t\tplatform: os.platform(),\n\t\tuserConfigPath: userConfigResult.path,\n\t\tuserConfigErrors:\n\t\t\tuserConfigResult.errors.length > 0 ? userConfigResult.errors : undefined,\n\t};\n};\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { MobvibeUserConfig, UserAgentConfig } from \"@mobvibe/shared\";\n\nexport type ConfigLoadResult = {\n\tconfig: MobvibeUserConfig | null;\n\terrors: string[];\n\tpath: string;\n};\n\nconst CONFIG_FILENAME = \".config.json\";\n\nconst validateAgentConfig = (\n\tagent: unknown,\n\tindex: number,\n): { valid: UserAgentConfig | null; errors: string[] } => {\n\tconst errors: string[] = [];\n\tconst prefix = `agents[${index}]`;\n\n\tif (typeof agent !== \"object\" || agent === null) {\n\t\terrors.push(`${prefix}: must be an object`);\n\t\treturn { valid: null, errors };\n\t}\n\n\tconst record = agent as Record<string, unknown>;\n\n\t// Validate id (required)\n\tif (typeof record.id !== \"string\" || record.id.trim().length === 0) {\n\t\terrors.push(`${prefix}.id: must be a non-empty string`);\n\t\treturn { valid: null, errors };\n\t}\n\n\t// Validate command (required)\n\tif (\n\t\ttypeof record.command !== \"string\" ||\n\t\trecord.command.trim().length === 0\n\t) {\n\t\terrors.push(`${prefix}.command: must be a non-empty string`);\n\t\treturn { valid: null, errors };\n\t}\n\n\tconst validated: UserAgentConfig = {\n\t\tid: record.id.trim(),\n\t\tcommand: record.command.trim(),\n\t};\n\n\t// Validate label (optional string)\n\tif (record.label !== undefined) {\n\t\tif (typeof record.label !== \"string\") {\n\t\t\terrors.push(`${prefix}.label: must be a string`);\n\t\t} else if (record.label.trim().length > 0) {\n\t\t\tvalidated.label = record.label.trim();\n\t\t}\n\t}\n\n\t// Validate args (optional string array)\n\tif (record.args !== undefined) {\n\t\tif (!Array.isArray(record.args)) {\n\t\t\terrors.push(`${prefix}.args: must be an array of strings`);\n\t\t} else {\n\t\t\tconst validArgs = record.args.filter((arg): arg is string => {\n\t\t\t\tif (typeof arg !== \"string\") {\n\t\t\t\t\terrors.push(`${prefix}.args: all elements must be strings`);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t});\n\t\t\tif (validArgs.length > 0) {\n\t\t\t\tvalidated.args = validArgs;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Validate env (optional object with string values)\n\tif (record.env !== undefined) {\n\t\tif (typeof record.env !== \"object\" || record.env === null) {\n\t\t\terrors.push(`${prefix}.env: must be an object`);\n\t\t} else {\n\t\t\tconst envRecord = record.env as Record<string, unknown>;\n\t\t\tconst validEnv: Record<string, string> = {};\n\t\t\tlet hasEnv = false;\n\t\t\tfor (const [key, value] of Object.entries(envRecord)) {\n\t\t\t\tif (typeof value !== \"string\") {\n\t\t\t\t\terrors.push(`${prefix}.env.${key}: must be a string`);\n\t\t\t\t} else {\n\t\t\t\t\tvalidEnv[key] = value;\n\t\t\t\t\thasEnv = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (hasEnv) {\n\t\t\t\tvalidated.env = validEnv;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return null if there were any errors after id/command validation\n\tif (errors.length > 0) {\n\t\treturn { valid: null, errors };\n\t}\n\n\treturn { valid: validated, errors: [] };\n};\n\nconst validateUserConfig = (\n\tdata: unknown,\n): { config: MobvibeUserConfig | null; errors: string[] } => {\n\tconst errors: string[] = [];\n\n\tif (typeof data !== \"object\" || data === null) {\n\t\terrors.push(\"config: must be an object\");\n\t\treturn { config: null, errors };\n\t}\n\n\tconst record = data as Record<string, unknown>;\n\tconst config: MobvibeUserConfig = {};\n\n\t// Validate agents array\n\tif (record.agents !== undefined) {\n\t\tif (!Array.isArray(record.agents)) {\n\t\t\terrors.push(\"agents: must be an array\");\n\t\t} else {\n\t\t\tconst validAgents: UserAgentConfig[] = [];\n\t\t\tconst seenIds = new Set<string>();\n\n\t\t\tfor (let i = 0; i < record.agents.length; i++) {\n\t\t\t\tconst result = validateAgentConfig(record.agents[i], i);\n\t\t\t\terrors.push(...result.errors);\n\n\t\t\t\tif (result.valid) {\n\t\t\t\t\tif (seenIds.has(result.valid.id)) {\n\t\t\t\t\t\terrors.push(`agents[${i}].id: duplicate id \"${result.valid.id}\"`);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tseenIds.add(result.valid.id);\n\t\t\t\t\t\tvalidAgents.push(result.valid);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (validAgents.length > 0) {\n\t\t\t\tconfig.agents = validAgents;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Validate defaultAgentId\n\tif (record.defaultAgentId !== undefined) {\n\t\tif (typeof record.defaultAgentId !== \"string\") {\n\t\t\terrors.push(\"defaultAgentId: must be a string\");\n\t\t} else if (record.defaultAgentId.trim().length > 0) {\n\t\t\tconfig.defaultAgentId = record.defaultAgentId.trim();\n\t\t}\n\t}\n\n\tif (errors.length > 0) {\n\t\treturn { config: null, errors };\n\t}\n\n\treturn { config, errors: [] };\n};\n\nexport const loadUserConfig = async (\n\thomePath: string,\n): Promise<ConfigLoadResult> => {\n\tconst configPath = path.join(homePath, CONFIG_FILENAME);\n\tconsole.log(`[config] Loading config from: ${configPath}`);\n\n\ttry {\n\t\tconst content = await fs.readFile(configPath, \"utf-8\");\n\t\tlet parsed: unknown;\n\n\t\ttry {\n\t\t\tparsed = JSON.parse(content);\n\t\t} catch {\n\t\t\tconsole.log(`[config] Invalid JSON in config file: ${configPath}`);\n\t\t\treturn {\n\t\t\t\tconfig: null,\n\t\t\t\terrors: [\"Invalid JSON in config file\"],\n\t\t\t\tpath: configPath,\n\t\t\t};\n\t\t}\n\n\t\tconst { config, errors } = validateUserConfig(parsed);\n\n\t\tif (errors.length > 0) {\n\t\t\tconsole.log(\"[config] Validation errors:\", errors);\n\t\t}\n\n\t\tif (config) {\n\t\t\tconsole.log(\"[config] Loaded config:\", JSON.stringify(config, null, 2));\n\t\t}\n\n\t\treturn { config, errors, path: configPath };\n\t} catch (error) {\n\t\t// File not found is not an error, just return null config\n\t\tif (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") {\n\t\t\tconsole.log(`[config] No config file found at: ${configPath}`);\n\t\t\treturn { config: null, errors: [], path: configPath };\n\t\t}\n\n\t\t// Other errors (permissions, etc.)\n\t\tconst message =\n\t\t\terror instanceof Error ? error.message : \"Unknown error reading config\";\n\t\tconsole.log(`[config] Error reading config: ${message}`);\n\t\treturn { config: null, errors: [message], path: configPath };\n\t}\n};\n","import { spawn } from \"node:child_process\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { SessionManager } from \"../acp/session-manager.js\";\nimport { getApiKey } from \"../auth/credentials.js\";\nimport type { CliConfig } from \"../config.js\";\nimport { logger } from \"../lib/logger.js\";\nimport { SocketClient } from \"./socket-client.js\";\n\ntype DaemonStatus = {\n\trunning: boolean;\n\tpid?: number;\n\tconnected?: boolean;\n\tsessionCount?: number;\n};\n\nexport class DaemonManager {\n\tconstructor(private readonly config: CliConfig) {}\n\n\tasync ensureHomeDirectory(): Promise<void> {\n\t\tawait fs.mkdir(this.config.homePath, { recursive: true });\n\t\tawait fs.mkdir(this.config.logPath, { recursive: true });\n\t}\n\n\tasync getPid(): Promise<number | null> {\n\t\ttry {\n\t\t\tconst content = await fs.readFile(this.config.pidFile, \"utf8\");\n\t\t\tconst pid = Number.parseInt(content.trim(), 10);\n\t\t\tif (Number.isNaN(pid)) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\t// Check if process is running\n\t\t\ttry {\n\t\t\t\tprocess.kill(pid, 0);\n\t\t\t\treturn pid;\n\t\t\t} catch {\n\t\t\t\t// Process not running, clean up stale PID file\n\t\t\t\tawait this.removePidFile();\n\t\t\t\treturn null;\n\t\t\t}\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tasync writePidFile(pid: number): Promise<void> {\n\t\tawait fs.writeFile(this.config.pidFile, String(pid), \"utf8\");\n\t}\n\n\tasync removePidFile(): Promise<void> {\n\t\ttry {\n\t\t\tawait fs.unlink(this.config.pidFile);\n\t\t} catch {\n\t\t\t// Ignore errors\n\t\t}\n\t}\n\n\tasync status(): Promise<DaemonStatus> {\n\t\tconst pid = await this.getPid();\n\t\tif (!pid) {\n\t\t\treturn { running: false };\n\t\t}\n\t\treturn { running: true, pid };\n\t}\n\n\tasync start(options?: { foreground?: boolean }): Promise<void> {\n\t\tconst existingPid = await this.getPid();\n\t\tif (existingPid) {\n\t\t\tlogger.info({ pid: existingPid }, \"daemon_already_running\");\n\t\t\treturn;\n\t\t}\n\n\t\tawait this.ensureHomeDirectory();\n\n\t\tif (options?.foreground) {\n\t\t\tawait this.runForeground();\n\t\t} else {\n\t\t\tawait this.spawnBackground();\n\t\t}\n\t}\n\n\tasync stop(): Promise<void> {\n\t\tconst pid = await this.getPid();\n\t\tif (!pid) {\n\t\t\tlogger.info(\"daemon_not_running\");\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if process actually exists\n\t\ttry {\n\t\t\tprocess.kill(pid, 0);\n\t\t} catch {\n\t\t\tlogger.warn(\"daemon_pid_missing_cleanup\");\n\t\t\tawait this.removePidFile();\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tlogger.info({ pid }, \"daemon_stop_sigterm\");\n\t\t\tprocess.kill(pid, \"SIGTERM\");\n\n\t\t\t// Wait for process to exit (up to 5 seconds)\n\t\t\tconst startTime = Date.now();\n\t\t\tconst timeout = 5000;\n\n\t\t\twhile (Date.now() - startTime < timeout) {\n\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, 100));\n\t\t\t\ttry {\n\t\t\t\t\tprocess.kill(pid, 0);\n\t\t\t\t\t// Process still running\n\t\t\t\t} catch {\n\t\t\t\t\t// Process exited\n\t\t\t\t\tlogger.info({ pid }, \"daemon_stopped_gracefully\");\n\t\t\t\t\tawait this.removePidFile();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Process didn't exit gracefully, force kill\n\t\t\tlogger.warn({ pid }, \"daemon_force_kill_start\");\n\t\t\ttry {\n\t\t\t\tprocess.kill(pid, \"SIGKILL\");\n\t\t\t\t// Wait a bit for SIGKILL to take effect\n\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, 500));\n\t\t\t\tlogger.warn({ pid }, \"daemon_force_kill_complete\");\n\t\t\t} catch {\n\t\t\t\t// Already dead\n\t\t\t\tlogger.info({ pid }, \"daemon_already_stopped\");\n\t\t\t}\n\t\t\tawait this.removePidFile();\n\t\t} catch (error) {\n\t\t\tlogger.error({ err: error }, \"daemon_stop_error\");\n\t\t\tawait this.removePidFile();\n\t\t}\n\t}\n\n\tprivate async spawnBackground(): Promise<void> {\n\t\tconst logFile = path.join(\n\t\t\tthis.config.logPath,\n\t\t\t`${new Date().toISOString().replace(/[:.]/g, \"-\")}-daemon.log`,\n\t\t);\n\n\t\t// Filter out --foreground if already present, then add it\n\t\tconst args = process.argv\n\t\t\t.slice(1)\n\t\t\t.filter((arg) => arg !== \"--foreground\" && arg !== \"-f\");\n\t\targs.push(\"--foreground\");\n\n\t\tconst child = spawn(process.argv[0], args, {\n\t\t\tdetached: true,\n\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t\tenv: {\n\t\t\t\t...process.env,\n\t\t\t\tMOBVIBE_GATEWAY_URL: this.config.gatewayUrl,\n\t\t\t},\n\t\t});\n\n\t\tif (!child.pid) {\n\t\t\tlogger.error(\"daemon_spawn_failed\");\n\t\t\tthrow new Error(\"Failed to spawn daemon process\");\n\t\t}\n\n\t\t// Create log file stream before writing PID\n\t\tconst logStream = await fs.open(logFile, \"a\");\n\t\tconst fileHandle = logStream;\n\n\t\tchild.stdout?.on(\"data\", (data: Buffer) => {\n\t\t\tfileHandle.write(`[stdout] ${data.toString()}`).catch(() => {});\n\t\t});\n\n\t\tchild.stderr?.on(\"data\", (data: Buffer) => {\n\t\t\tfileHandle.write(`[stderr] ${data.toString()}`).catch(() => {});\n\t\t});\n\n\t\t// Handle child exit to clean up\n\t\tchild.on(\"exit\", (code, signal) => {\n\t\t\tfileHandle\n\t\t\t\t.write(`[exit] Process exited with code ${code}, signal ${signal}\\n`)\n\t\t\t\t.catch(() => {});\n\t\t\tfileHandle.close().catch(() => {});\n\t\t});\n\n\t\t// Detach from parent\n\t\t// Note: The child process writes its own PID file in runForeground()\n\t\tchild.unref();\n\n\t\tlogger.info({ pid: child.pid }, \"daemon_started\");\n\t\tconsole.log(`Logs: ${logFile}`);\n\t\tlogger.info({ logFile }, \"daemon_log_path\");\n\t}\n\n\tasync runForeground(): Promise<void> {\n\t\tconst pid = process.pid;\n\t\tawait this.writePidFile(pid);\n\n\t\tlogger.info({ pid }, \"daemon_starting\");\n\t\tlogger.info({ gatewayUrl: this.config.gatewayUrl }, \"daemon_gateway_url\");\n\t\tlogger.info({ machineId: this.config.machineId }, \"daemon_machine_id\");\n\n\t\t// Load API key for authentication\n\t\tconst apiKey = await getApiKey();\n\t\tif (!apiKey) {\n\t\t\tlogger.error(\"daemon_api_key_missing\");\n\t\t\tconsole.error(\n\t\t\t\t`[mobvibe-cli] No API key found. Run 'mobvibe login' to authenticate.`,\n\t\t\t);\n\t\t\tlogger.warn(\"daemon_exit_missing_api_key\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tlogger.info(\"daemon_api_key_loaded\");\n\n\t\tconst sessionManager = new SessionManager(this.config);\n\t\tconst socketClient = new SocketClient({\n\t\t\tconfig: this.config,\n\t\t\tsessionManager,\n\t\t\tapiKey,\n\t\t});\n\n\t\tlet shuttingDown = false;\n\n\t\tconst shutdown = async (signal: string) => {\n\t\t\tif (shuttingDown) {\n\t\t\t\tlogger.warn({ signal }, \"daemon_shutdown_already_running\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tshuttingDown = true;\n\n\t\t\tlogger.info({ signal }, \"daemon_shutdown_start\");\n\n\t\t\ttry {\n\t\t\t\tsocketClient.disconnect();\n\t\t\t\tawait sessionManager.closeAll();\n\t\t\t\tawait this.removePidFile();\n\t\t\t\tlogger.info({ signal }, \"daemon_shutdown_complete\");\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error({ err: error, signal }, \"daemon_shutdown_error\");\n\t\t\t}\n\t\t};\n\n\t\tprocess.on(\"SIGINT\", () => {\n\t\t\tshutdown(\"SIGINT\").catch((error) => {\n\t\t\t\tlogger.error({ err: error }, \"daemon_shutdown_sigint_error\");\n\t\t\t});\n\t\t});\n\t\tprocess.on(\"SIGTERM\", () => {\n\t\t\tshutdown(\"SIGTERM\").catch((error) => {\n\t\t\t\tlogger.error({ err: error }, \"daemon_shutdown_sigterm_error\");\n\t\t\t});\n\t\t});\n\n\t\tsocketClient.connect();\n\n\t\t// Keep process alive\n\t\tawait new Promise(() => {});\n\t}\n\n\tasync logs(options?: { follow?: boolean; lines?: number }): Promise<void> {\n\t\tconst files = await fs.readdir(this.config.logPath);\n\t\tconst logFiles = files\n\t\t\t.filter((f) => f.endsWith(\"-daemon.log\"))\n\t\t\t.sort()\n\t\t\t.reverse();\n\n\t\tif (logFiles.length === 0) {\n\t\t\tlogger.warn(\"daemon_logs_empty\");\n\t\t\tconsole.log(\"No log files found\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst latestLog = path.join(this.config.logPath, logFiles[0]);\n\t\tlogger.info({ logFile: latestLog }, \"daemon_logs_latest\");\n\t\tconsole.log(`Log file: ${latestLog}\\n`);\n\n\t\tif (options?.follow) {\n\t\t\t// Use tail -f\n\t\t\tconst tail = spawn(\"tail\", [\"-f\", latestLog], {\n\t\t\t\tstdio: \"inherit\",\n\t\t\t});\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\ttail.on(\"close\", () => resolve());\n\t\t\t});\n\t\t} else {\n\t\t\tconst content = await fs.readFile(latestLog, \"utf8\");\n\t\t\tconst lines = content.split(\"\\n\");\n\t\t\tconst count = options?.lines ?? 50;\n\t\t\tconsole.log(lines.slice(-count).join(\"\\n\"));\n\t\t}\n\t}\n}\n","import { randomUUID } from \"node:crypto\";\nimport { EventEmitter } from \"node:events\";\nimport fs from \"node:fs/promises\";\nimport type {\n\tAvailableCommand,\n\tRequestPermissionRequest,\n\tRequestPermissionResponse,\n\tSessionModelState,\n\tSessionModeState,\n\tSessionNotification,\n} from \"@agentclientprotocol/sdk\";\nimport {\n\ttype AcpSessionInfo,\n\tAppError,\n\tcreateErrorDetail,\n\ttype DiscoverSessionsRpcResult,\n\ttype ErrorDetail,\n\ttype PermissionDecisionPayload,\n\ttype PermissionRequestPayload,\n\ttype SessionSummary,\n\ttype SessionsChangedPayload,\n\ttype TerminalOutputEvent,\n} from \"@mobvibe/shared\";\nimport type { AcpBackendConfig, CliConfig } from \"../config.js\";\nimport { logger } from \"../lib/logger.js\";\nimport { AcpConnection } from \"./acp-connection.js\";\n\ntype SessionRecord = {\n\tsessionId: string;\n\ttitle: string;\n\tbackendId: string;\n\tbackendLabel: string;\n\tconnection: AcpConnection;\n\tcreatedAt: Date;\n\tupdatedAt: Date;\n\tcwd?: string;\n\tagentName?: string;\n\tmodelId?: string;\n\tmodelName?: string;\n\tmodeId?: string;\n\tmodeName?: string;\n\tavailableModes?: Array<{ id: string; name: string }>;\n\tavailableModels?: Array<{\n\t\tid: string;\n\t\tname: string;\n\t\tdescription?: string | null;\n\t}>;\n\tavailableCommands?: AvailableCommand[];\n\tunsubscribe?: () => void;\n\tunsubscribeTerminal?: () => void;\n\tisAttached?: boolean;\n\tattachedAt?: Date;\n};\n\ntype PermissionRequestRecord = {\n\tsessionId: string;\n\trequestId: string;\n\tparams: RequestPermissionRequest;\n\tpromise: Promise<RequestPermissionResponse>;\n\tresolve: (response: RequestPermissionResponse) => void;\n};\n\nconst buildPermissionKey = (sessionId: string, requestId: string) =>\n\t`${sessionId}:${requestId}`;\n\nconst resolveModelState = (models?: SessionModelState | null) => {\n\tif (!models) {\n\t\treturn {\n\t\t\tmodelId: undefined,\n\t\t\tmodelName: undefined,\n\t\t\tavailableModels: undefined,\n\t\t};\n\t}\n\tconst availableModels = models.availableModels?.map((model) => ({\n\t\tid: model.modelId,\n\t\tname: model.name,\n\t\tdescription: model.description ?? undefined,\n\t}));\n\tconst modelId = models.currentModelId ?? undefined;\n\tconst modelName = availableModels?.find(\n\t\t(model) => model.id === modelId,\n\t)?.name;\n\treturn { modelId, modelName, availableModels };\n};\n\nconst resolveModeState = (modes?: SessionModeState | null) => {\n\tif (!modes) {\n\t\treturn {\n\t\t\tmodeId: undefined,\n\t\t\tmodeName: undefined,\n\t\t\tavailableModes: undefined,\n\t\t};\n\t}\n\tconst modeId = modes.currentModeId ?? undefined;\n\tconst modeName = modes.availableModes?.find(\n\t\t(mode) => mode.id === modeId,\n\t)?.name;\n\treturn {\n\t\tmodeId,\n\t\tmodeName,\n\t\tavailableModes: modes.availableModes?.map((mode) => ({\n\t\t\tid: mode.id,\n\t\t\tname: mode.name,\n\t\t})),\n\t};\n};\n\nconst createCapabilityNotSupportedError = (message: string) =>\n\tnew AppError(\n\t\tcreateErrorDetail({\n\t\t\tcode: \"CAPABILITY_NOT_SUPPORTED\",\n\t\t\tmessage,\n\t\t\tretryable: false,\n\t\t\tscope: \"session\",\n\t\t}),\n\t\t409,\n\t);\n\nconst isValidWorkspacePath = async (cwd: string): Promise<boolean> => {\n\ttry {\n\t\tconst stats = await fs.stat(cwd);\n\t\treturn stats.isDirectory();\n\t} catch {\n\t\treturn false;\n\t}\n};\n\nexport class SessionManager {\n\tprivate sessions = new Map<string, SessionRecord>();\n\tprivate discoveredSessions = new Map<string, AcpSessionInfo>();\n\tprivate backendById: Map<string, AcpBackendConfig>;\n\tprivate defaultBackendId: string;\n\tprivate permissionRequests = new Map<string, PermissionRequestRecord>();\n\tprivate readonly sessionUpdateEmitter = new EventEmitter();\n\tprivate readonly sessionErrorEmitter = new EventEmitter();\n\tprivate readonly permissionRequestEmitter = new EventEmitter();\n\tprivate readonly permissionResultEmitter = new EventEmitter();\n\tprivate readonly terminalOutputEmitter = new EventEmitter();\n\tprivate readonly sessionsChangedEmitter = new EventEmitter();\n\tprivate readonly sessionAttachedEmitter = new EventEmitter();\n\tprivate readonly sessionDetachedEmitter = new EventEmitter();\n\n\tconstructor(private readonly config: CliConfig) {\n\t\tthis.backendById = new Map(\n\t\t\tconfig.acpBackends.map((backend) => [backend.id, backend]),\n\t\t);\n\t\tthis.defaultBackendId = config.defaultAcpBackendId;\n\t}\n\n\tlistSessions(): SessionSummary[] {\n\t\treturn Array.from(this.sessions.values()).map((record) =>\n\t\t\tthis.buildSummary(record),\n\t\t);\n\t}\n\n\tgetSession(sessionId: string): SessionRecord | undefined {\n\t\treturn this.sessions.get(sessionId);\n\t}\n\n\tonSessionUpdate(listener: (notification: SessionNotification) => void) {\n\t\tthis.sessionUpdateEmitter.on(\"update\", listener);\n\t\treturn () => {\n\t\t\tthis.sessionUpdateEmitter.off(\"update\", listener);\n\t\t};\n\t}\n\n\tonSessionError(\n\t\tlistener: (payload: { sessionId: string; error: ErrorDetail }) => void,\n\t) {\n\t\tthis.sessionErrorEmitter.on(\"error\", listener);\n\t\treturn () => {\n\t\t\tthis.sessionErrorEmitter.off(\"error\", listener);\n\t\t};\n\t}\n\n\tonPermissionRequest(listener: (payload: PermissionRequestPayload) => void) {\n\t\tthis.permissionRequestEmitter.on(\"request\", listener);\n\t\treturn () => {\n\t\t\tthis.permissionRequestEmitter.off(\"request\", listener);\n\t\t};\n\t}\n\n\tonPermissionResult(listener: (payload: PermissionDecisionPayload) => void) {\n\t\tthis.permissionResultEmitter.on(\"result\", listener);\n\t\treturn () => {\n\t\t\tthis.permissionResultEmitter.off(\"result\", listener);\n\t\t};\n\t}\n\n\tonTerminalOutput(listener: (event: TerminalOutputEvent) => void) {\n\t\tthis.terminalOutputEmitter.on(\"output\", listener);\n\t\treturn () => {\n\t\t\tthis.terminalOutputEmitter.off(\"output\", listener);\n\t\t};\n\t}\n\n\tonSessionsChanged(listener: (payload: SessionsChangedPayload) => void) {\n\t\tthis.sessionsChangedEmitter.on(\"changed\", listener);\n\t\treturn () => {\n\t\t\tthis.sessionsChangedEmitter.off(\"changed\", listener);\n\t\t};\n\t}\n\n\tonSessionAttached(\n\t\tlistener: (payload: {\n\t\t\tsessionId: string;\n\t\t\tmachineId: string;\n\t\t\tattachedAt: string;\n\t\t}) => void,\n\t) {\n\t\tthis.sessionAttachedEmitter.on(\"attached\", listener);\n\t\treturn () => {\n\t\t\tthis.sessionAttachedEmitter.off(\"attached\", listener);\n\t\t};\n\t}\n\n\tonSessionDetached(\n\t\tlistener: (payload: {\n\t\t\tsessionId: string;\n\t\t\tmachineId: string;\n\t\t\tdetachedAt: string;\n\t\t\treason:\n\t\t\t\t| \"agent_exit\"\n\t\t\t\t| \"cli_disconnect\"\n\t\t\t\t| \"gateway_disconnect\"\n\t\t\t\t| \"unknown\";\n\t\t}) => void,\n\t) {\n\t\tthis.sessionDetachedEmitter.on(\"detached\", listener);\n\t\treturn () => {\n\t\t\tthis.sessionDetachedEmitter.off(\"detached\", listener);\n\t\t};\n\t}\n\n\tprivate emitSessionsChanged(payload: SessionsChangedPayload) {\n\t\tthis.sessionsChangedEmitter.emit(\"changed\", payload);\n\t}\n\n\tprivate emitSessionAttached(sessionId: string, force = false) {\n\t\tconst record = this.sessions.get(sessionId);\n\t\tif (!record) {\n\t\t\treturn;\n\t\t}\n\t\tif (record.isAttached && !force) {\n\t\t\treturn;\n\t\t}\n\t\tconst attachedAt = new Date();\n\t\trecord.isAttached = true;\n\t\trecord.attachedAt = attachedAt;\n\t\tthis.sessionAttachedEmitter.emit(\"attached\", {\n\t\t\tsessionId,\n\t\t\tmachineId: this.config.machineId,\n\t\t\tattachedAt: attachedAt.toISOString(),\n\t\t});\n\t}\n\n\tprivate emitSessionDetached(\n\t\tsessionId: string,\n\t\treason: \"agent_exit\" | \"cli_disconnect\" | \"gateway_disconnect\" | \"unknown\",\n\t) {\n\t\tconst record = this.sessions.get(sessionId);\n\t\tif (!record) {\n\t\t\treturn;\n\t\t}\n\t\tif (!record.isAttached) {\n\t\t\treturn;\n\t\t}\n\t\trecord.isAttached = false;\n\t\tthis.sessionDetachedEmitter.emit(\"detached\", {\n\t\t\tsessionId,\n\t\t\tmachineId: this.config.machineId,\n\t\t\tdetachedAt: new Date().toISOString(),\n\t\t\treason,\n\t\t});\n\t}\n\n\tlistPendingPermissions(sessionId: string): PermissionRequestPayload[] {\n\t\treturn Array.from(this.permissionRequests.values())\n\t\t\t.filter((record) => record.sessionId === sessionId)\n\t\t\t.map((record) => this.buildPermissionRequestPayload(record));\n\t}\n\n\tresolvePermissionRequest(\n\t\tsessionId: string,\n\t\trequestId: string,\n\t\toutcome: RequestPermissionResponse[\"outcome\"],\n\t): PermissionDecisionPayload {\n\t\tconst key = buildPermissionKey(sessionId, requestId);\n\t\tconst record = this.permissionRequests.get(key);\n\t\tif (!record) {\n\t\t\tthrow new AppError(\n\t\t\t\tcreateErrorDetail({\n\t\t\t\t\tcode: \"REQUEST_VALIDATION_FAILED\",\n\t\t\t\t\tmessage: \"Permission request not found\",\n\t\t\t\t\tretryable: false,\n\t\t\t\t\tscope: \"request\",\n\t\t\t\t}),\n\t\t\t\t404,\n\t\t\t);\n\t\t}\n\t\tconst response: RequestPermissionResponse = { outcome };\n\t\trecord.resolve(response);\n\t\tthis.permissionRequests.delete(key);\n\t\tconst payload: PermissionDecisionPayload = {\n\t\t\tsessionId,\n\t\t\trequestId,\n\t\t\toutcome,\n\t\t};\n\t\tthis.permissionResultEmitter.emit(\"result\", payload);\n\t\treturn payload;\n\t}\n\n\tprivate resolveBackend(backendId?: string) {\n\t\tconst normalized = backendId?.trim();\n\t\tconst resolvedId =\n\t\t\tnormalized && normalized.length > 0 ? normalized : this.defaultBackendId;\n\t\tconst backend = this.backendById.get(resolvedId);\n\t\tif (!backend) {\n\t\t\tthrow new AppError(\n\t\t\t\tcreateErrorDetail({\n\t\t\t\t\tcode: \"REQUEST_VALIDATION_FAILED\",\n\t\t\t\t\tmessage: \"Invalid backend ID\",\n\t\t\t\t\tretryable: false,\n\t\t\t\t\tscope: \"request\",\n\t\t\t\t}),\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\t\treturn backend;\n\t}\n\n\tasync createSession(options?: {\n\t\tcwd?: string;\n\t\ttitle?: string;\n\t\tbackendId?: string;\n\t}): Promise<SessionSummary> {\n\t\tconst backend = this.resolveBackend(options?.backendId);\n\t\tconst connection = new AcpConnection({\n\t\t\tbackend,\n\t\t\tclient: {\n\t\t\t\tname: this.config.clientName,\n\t\t\t\tversion: this.config.clientVersion,\n\t\t\t},\n\t\t});\n\t\ttry {\n\t\t\tawait connection.connect();\n\t\t\tconst session = await connection.createSession({ cwd: options?.cwd });\n\t\t\tconnection.setPermissionHandler((params) =>\n\t\t\t\tthis.handlePermissionRequest(session.sessionId, params),\n\t\t\t);\n\t\t\tconst now = new Date();\n\t\t\tconst agentInfo = connection.getAgentInfo();\n\t\t\tconst { modelId, modelName, availableModels } = resolveModelState(\n\t\t\t\tsession.models,\n\t\t\t);\n\t\t\tconst { modeId, modeName, availableModes } = resolveModeState(\n\t\t\t\tsession.modes,\n\t\t\t);\n\t\t\tconst record: SessionRecord = {\n\t\t\t\tsessionId: session.sessionId,\n\t\t\t\ttitle: options?.title ?? `Session ${this.sessions.size + 1}`,\n\t\t\t\tbackendId: backend.id,\n\t\t\t\tbackendLabel: backend.label,\n\t\t\t\tconnection,\n\t\t\t\tcreatedAt: now,\n\t\t\t\tupdatedAt: now,\n\t\t\t\tcwd: options?.cwd,\n\t\t\t\tagentName: agentInfo?.title ?? agentInfo?.name,\n\t\t\t\tmodelId,\n\t\t\t\tmodelName,\n\t\t\t\tmodeId,\n\t\t\t\tmodeName,\n\t\t\t\tavailableModes,\n\t\t\t\tavailableModels,\n\t\t\t\tavailableCommands: undefined,\n\t\t\t};\n\t\t\trecord.unsubscribe = connection.onSessionUpdate(\n\t\t\t\t(notification: SessionNotification) => {\n\t\t\t\t\trecord.updatedAt = new Date();\n\t\t\t\t\tthis.sessionUpdateEmitter.emit(\"update\", notification);\n\t\t\t\t\tthis.applySessionUpdateToRecord(record, notification);\n\t\t\t\t},\n\t\t\t);\n\t\t\trecord.unsubscribeTerminal = connection.onTerminalOutput((event) => {\n\t\t\t\tthis.terminalOutputEmitter.emit(\"output\", event);\n\t\t\t});\n\t\t\tconnection.onStatusChange((status) => {\n\t\t\t\tif (status.error) {\n\t\t\t\t\tthis.sessionErrorEmitter.emit(\"error\", {\n\t\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\t\terror: status.error,\n\t\t\t\t\t});\n\t\t\t\t\tthis.emitSessionDetached(session.sessionId, \"agent_exit\");\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis.sessions.set(session.sessionId, record);\n\t\t\tconst summary = this.buildSummary(record);\n\t\t\tthis.emitSessionsChanged({\n\t\t\t\tadded: [summary],\n\t\t\t\tupdated: [],\n\t\t\t\tremoved: [],\n\t\t\t});\n\t\t\tthis.emitSessionAttached(session.sessionId);\n\t\t\treturn summary;\n\t\t} catch (error) {\n\t\t\tconst status = connection.getStatus();\n\t\t\tawait connection.disconnect();\n\t\t\tif (status.error) {\n\t\t\t\tthrow new AppError(status.error, 500);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate buildPermissionRequestPayload(\n\t\trecord: PermissionRequestRecord,\n\t): PermissionRequestPayload {\n\t\tconst toolCall = record.params.toolCall;\n\t\treturn {\n\t\t\tsessionId: record.sessionId,\n\t\t\trequestId: record.requestId,\n\t\t\toptions: record.params.options.map((option) => ({\n\t\t\t\toptionId: option.optionId,\n\t\t\t\t// SDK uses 'name', our shared type uses 'label'\n\t\t\t\tlabel: option.name,\n\t\t\t\tdescription: (option._meta?.description as string) ?? null,\n\t\t\t})),\n\t\t\ttoolCall: {\n\t\t\t\ttoolCallId: toolCall.toolCallId,\n\t\t\t\tname: (toolCall._meta?.name as string) ?? null,\n\t\t\t\ttitle: toolCall.title,\n\t\t\t\tcommand: (toolCall._meta?.command as string) ?? null,\n\t\t\t\targs: (toolCall._meta?.args as string[]) ?? null,\n\t\t\t},\n\t\t};\n\t}\n\n\tprivate handlePermissionRequest(\n\t\tsessionId: string,\n\t\tparams: RequestPermissionRequest,\n\t): Promise<RequestPermissionResponse> {\n\t\tconst requestId = params.toolCall?.toolCallId ?? randomUUID();\n\t\tconst key = buildPermissionKey(sessionId, requestId);\n\t\tconst existing = this.permissionRequests.get(key);\n\t\tif (existing) {\n\t\t\treturn existing.promise;\n\t\t}\n\t\tlet resolver: (response: RequestPermissionResponse) => void = () => {};\n\t\tconst promise = new Promise<RequestPermissionResponse>((resolve) => {\n\t\t\tresolver = resolve;\n\t\t});\n\t\tconst record: PermissionRequestRecord = {\n\t\t\tsessionId,\n\t\t\trequestId,\n\t\t\tparams,\n\t\t\tpromise,\n\t\t\tresolve: resolver,\n\t\t};\n\t\tthis.permissionRequests.set(key, record);\n\t\tthis.permissionRequestEmitter.emit(\n\t\t\t\"request\",\n\t\t\tthis.buildPermissionRequestPayload(record),\n\t\t);\n\t\treturn promise;\n\t}\n\n\tprivate cancelPermissionRequests(sessionId: string) {\n\t\tconst cancelledOutcome: RequestPermissionResponse[\"outcome\"] = {\n\t\t\toutcome: \"cancelled\",\n\t\t};\n\t\tfor (const [key, record] of this.permissionRequests.entries()) {\n\t\t\tif (record.sessionId !== sessionId) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\trecord.resolve({ outcome: cancelledOutcome });\n\t\t\tthis.permissionRequests.delete(key);\n\t\t\tthis.permissionResultEmitter.emit(\"result\", {\n\t\t\t\tsessionId,\n\t\t\t\trequestId: record.requestId,\n\t\t\t\toutcome: cancelledOutcome,\n\t\t\t});\n\t\t}\n\t}\n\n\tupdateTitle(sessionId: string, title: string): SessionSummary {\n\t\tconst record = this.sessions.get(sessionId);\n\t\tif (!record) {\n\t\t\tthrow new AppError(\n\t\t\t\tcreateErrorDetail({\n\t\t\t\t\tcode: \"SESSION_NOT_FOUND\",\n\t\t\t\t\tmessage: \"Session not found\",\n\t\t\t\t\tretryable: false,\n\t\t\t\t\tscope: \"session\",\n\t\t\t\t}),\n\t\t\t\t404,\n\t\t\t);\n\t\t}\n\t\trecord.title = title;\n\t\trecord.updatedAt = new Date();\n\t\tconst summary = this.buildSummary(record);\n\t\tthis.emitSessionsChanged({\n\t\t\tadded: [],\n\t\t\tupdated: [summary],\n\t\t\tremoved: [],\n\t\t});\n\t\treturn summary;\n\t}\n\n\ttouchSession(sessionId: string) {\n\t\tconst record = this.sessions.get(sessionId);\n\t\tif (!record) {\n\t\t\treturn;\n\t\t}\n\t\trecord.updatedAt = new Date();\n\t}\n\n\tasync setSessionMode(\n\t\tsessionId: string,\n\t\tmodeId: string,\n\t): Promise<SessionSummary> {\n\t\tconst record = this.sessions.get(sessionId);\n\t\tif (!record) {\n\t\t\tthrow new AppError(\n\t\t\t\tcreateErrorDetail({\n\t\t\t\t\tcode: \"SESSION_NOT_FOUND\",\n\t\t\t\t\tmessage: \"Session not found\",\n\t\t\t\t\tretryable: false,\n\t\t\t\t\tscope: \"session\",\n\t\t\t\t}),\n\t\t\t\t404,\n\t\t\t);\n\t\t}\n\t\tif (!record.availableModes || record.availableModes.length === 0) {\n\t\t\tthrow createCapabilityNotSupportedError(\n\t\t\t\t\"Current agent does not support mode switching\",\n\t\t\t);\n\t\t}\n\t\tconst selected = record.availableModes.find((mode) => mode.id === modeId);\n\t\tif (!selected) {\n\t\t\tthrow new AppError(\n\t\t\t\tcreateErrorDetail({\n\t\t\t\t\tcode: \"REQUEST_VALIDATION_FAILED\",\n\t\t\t\t\tmessage: \"Invalid mode ID\",\n\t\t\t\t\tretryable: false,\n\t\t\t\t\tscope: \"request\",\n\t\t\t\t}),\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\t\tawait record.connection.setSessionMode(sessionId, modeId);\n\t\trecord.modeId = selected.id;\n\t\trecord.modeName = selected.name;\n\t\trecord.updatedAt = new Date();\n\t\tconst summary = this.buildSummary(record);\n\t\tthis.emitSessionsChanged({\n\t\t\tadded: [],\n\t\t\tupdated: [summary],\n\t\t\tremoved: [],\n\t\t});\n\t\treturn summary;\n\t}\n\n\tasync setSessionModel(\n\t\tsessionId: string,\n\t\tmodelId: string,\n\t): Promise<SessionSummary> {\n\t\tconst record = this.sessions.get(sessionId);\n\t\tif (!record) {\n\t\t\tthrow new AppError(\n\t\t\t\tcreateErrorDetail({\n\t\t\t\t\tcode: \"SESSION_NOT_FOUND\",\n\t\t\t\t\tmessage: \"Session not found\",\n\t\t\t\t\tretryable: false,\n\t\t\t\t\tscope: \"session\",\n\t\t\t\t}),\n\t\t\t\t404,\n\t\t\t);\n\t\t}\n\t\tif (!record.availableModels || record.availableModels.length === 0) {\n\t\t\tthrow createCapabilityNotSupportedError(\n\t\t\t\t\"Current agent does not support model switching\",\n\t\t\t);\n\t\t}\n\t\tconst selected = record.availableModels.find(\n\t\t\t(model) => model.id === modelId,\n\t\t);\n\t\tif (!selected) {\n\t\t\tthrow new AppError(\n\t\t\t\tcreateErrorDetail({\n\t\t\t\t\tcode: \"REQUEST_VALIDATION_FAILED\",\n\t\t\t\t\tmessage: \"Invalid model ID\",\n\t\t\t\t\tretryable: false,\n\t\t\t\t\tscope: \"request\",\n\t\t\t\t}),\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\t\tawait record.connection.setSessionModel(sessionId, modelId);\n\t\trecord.modelId = selected.id;\n\t\trecord.modelName = selected.name;\n\t\trecord.updatedAt = new Date();\n\t\tconst summary = this.buildSummary(record);\n\t\tthis.emitSessionsChanged({\n\t\t\tadded: [],\n\t\t\tupdated: [summary],\n\t\t\tremoved: [],\n\t\t});\n\t\treturn summary;\n\t}\n\n\tasync cancelSession(sessionId: string): Promise<boolean> {\n\t\tconst record = this.sessions.get(sessionId);\n\t\tif (!record) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.cancelPermissionRequests(sessionId);\n\t\tawait record.connection.cancel(sessionId);\n\t\tthis.touchSession(sessionId);\n\t\treturn true;\n\t}\n\n\tasync closeSession(sessionId: string): Promise<boolean> {\n\t\tconst record = this.sessions.get(sessionId);\n\t\tif (!record) {\n\t\t\treturn false;\n\t\t}\n\t\ttry {\n\t\t\trecord.unsubscribe?.();\n\t\t\trecord.unsubscribeTerminal?.();\n\t\t} catch (error) {\n\t\t\tlogger.error({ err: error, sessionId }, \"session_unsubscribe_failed\");\n\t\t}\n\t\tthis.cancelPermissionRequests(sessionId);\n\t\ttry {\n\t\t\tawait record.connection.disconnect();\n\t\t} catch (error) {\n\t\t\tlogger.error({ err: error, sessionId }, \"session_disconnect_failed\");\n\t\t}\n\t\tthis.emitSessionDetached(sessionId, \"unknown\");\n\t\tthis.sessions.delete(sessionId);\n\t\tthis.emitSessionsChanged({\n\t\t\tadded: [],\n\t\t\tupdated: [],\n\t\t\tremoved: [sessionId],\n\t\t});\n\t\treturn true;\n\t}\n\n\tasync closeAll(): Promise<void> {\n\t\tconst sessionIds = Array.from(this.sessions.keys());\n\t\tawait Promise.all(\n\t\t\tsessionIds.map((sessionId) => this.closeSession(sessionId)),\n\t\t);\n\t}\n\n\t/**\n\t * Discover sessions persisted by the ACP agent.\n\t * Creates a temporary connection to query sessions.\n\t * @param options Optional parameters for discovery\n\t * @returns List of discovered sessions and agent capabilities\n\t */\n\tasync discoverSessions(options?: {\n\t\tcwd?: string;\n\t\tbackendId?: string;\n\t\tcursor?: string;\n\t}): Promise<DiscoverSessionsRpcResult> {\n\t\tconst backend = this.resolveBackend(options?.backendId);\n\t\tconst connection = new AcpConnection({\n\t\t\tbackend,\n\t\t\tclient: {\n\t\t\t\tname: this.config.clientName,\n\t\t\t\tversion: this.config.clientVersion,\n\t\t\t},\n\t\t});\n\n\t\ttry {\n\t\t\tawait connection.connect();\n\t\t\tconst capabilities = connection.getSessionCapabilities();\n\t\t\tconst sessions: AcpSessionInfo[] = [];\n\t\t\tlet nextCursor: string | undefined;\n\n\t\t\tif (capabilities.list) {\n\t\t\t\tconst response = await connection.listSessions({\n\t\t\t\t\tcwd: options?.cwd,\n\t\t\t\t\tcursor: options?.cursor,\n\t\t\t\t});\n\t\t\t\tnextCursor = response.nextCursor;\n\t\t\t\tconst validity = await Promise.all(\n\t\t\t\t\tresponse.sessions.map(async (session) => ({\n\t\t\t\t\t\tsession,\n\t\t\t\t\t\tisValid: session.cwd\n\t\t\t\t\t\t\t? await isValidWorkspacePath(session.cwd)\n\t\t\t\t\t\t\t: false,\n\t\t\t\t\t})),\n\t\t\t\t);\n\t\t\t\tfor (const { session, isValid } of validity) {\n\t\t\t\t\tif (!isValid) {\n\t\t\t\t\t\tthis.discoveredSessions.delete(session.sessionId);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tthis.discoveredSessions.set(session.sessionId, {\n\t\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\t\tcwd: session.cwd,\n\t\t\t\t\t\ttitle: session.title ?? undefined,\n\t\t\t\t\t\tupdatedAt: session.updatedAt ?? undefined,\n\t\t\t\t\t});\n\t\t\t\t\tsessions.push({\n\t\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\t\tcwd: session.cwd,\n\t\t\t\t\t\ttitle: session.title ?? undefined,\n\t\t\t\t\t\tupdatedAt: session.updatedAt ?? undefined,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlogger.info(\n\t\t\t\t{\n\t\t\t\t\tbackendId: backend.id,\n\t\t\t\t\tsessionCount: sessions.length,\n\t\t\t\t\tcapabilities,\n\t\t\t\t},\n\t\t\t\t\"sessions_discovered\",\n\t\t\t);\n\n\t\t\treturn { sessions, capabilities, nextCursor };\n\t\t} finally {\n\t\t\tawait connection.disconnect();\n\t\t}\n\t}\n\n\t/**\n\t * Load a historical session from the ACP agent.\n\t * This will replay the session's message history.\n\t * @param sessionId The session ID to load\n\t * @param cwd The working directory\n\t * @param backendId Optional backend ID\n\t * @returns The loaded session summary\n\t */\n\tasync loadSession(\n\t\tsessionId: string,\n\t\tcwd: string,\n\t\tbackendId?: string,\n\t): Promise<SessionSummary> {\n\t\t// Check if session is already loaded\n\t\tconst existing = this.sessions.get(sessionId);\n\t\tif (existing) {\n\t\t\tthis.emitSessionAttached(sessionId, true);\n\t\t\treturn this.buildSummary(existing);\n\t\t}\n\n\t\tconst backend = this.resolveBackend(backendId);\n\t\tconst connection = new AcpConnection({\n\t\t\tbackend,\n\t\t\tclient: {\n\t\t\t\tname: this.config.clientName,\n\t\t\t\tversion: this.config.clientVersion,\n\t\t\t},\n\t\t});\n\n\t\ttry {\n\t\t\tawait connection.connect();\n\n\t\t\tif (!connection.supportsSessionLoad()) {\n\t\t\t\tthrow createCapabilityNotSupportedError(\n\t\t\t\t\t\"Agent does not support session loading\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst bufferedUpdates: SessionNotification[] = [];\n\t\t\tlet recordRef: SessionRecord | undefined;\n\t\t\tconst unsubscribe = connection.onSessionUpdate(\n\t\t\t\t(notification: SessionNotification) => {\n\t\t\t\t\tthis.sessionUpdateEmitter.emit(\"update\", notification);\n\t\t\t\t\tif (recordRef) {\n\t\t\t\t\t\trecordRef.updatedAt = new Date();\n\t\t\t\t\t\tthis.applySessionUpdateToRecord(recordRef, notification);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbufferedUpdates.push(notification);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tconst response = await connection.loadSession(sessionId, cwd);\n\t\t\tconnection.setPermissionHandler((params) =>\n\t\t\t\tthis.handlePermissionRequest(sessionId, params),\n\t\t\t);\n\n\t\t\tconst now = new Date();\n\t\t\tconst agentInfo = connection.getAgentInfo();\n\t\t\tconst { modelId, modelName, availableModels } = resolveModelState(\n\t\t\t\tresponse.models,\n\t\t\t);\n\t\t\tconst { modeId, modeName, availableModes } = resolveModeState(\n\t\t\t\tresponse.modes,\n\t\t\t);\n\t\t\tconst discovered = this.discoveredSessions.get(sessionId);\n\n\t\t\tconst record: SessionRecord = {\n\t\t\t\tsessionId,\n\t\t\t\ttitle: discovered?.title ?? sessionId,\n\t\t\t\tbackendId: backend.id,\n\t\t\t\tbackendLabel: backend.label,\n\t\t\t\tconnection,\n\t\t\t\tcreatedAt: now,\n\t\t\t\tupdatedAt: now,\n\t\t\t\tcwd,\n\t\t\t\tagentName: agentInfo?.title ?? agentInfo?.name,\n\t\t\t\tmodelId,\n\t\t\t\tmodelName,\n\t\t\t\tmodeId,\n\t\t\t\tmodeName,\n\t\t\t\tavailableModes,\n\t\t\t\tavailableModels,\n\t\t\t\tavailableCommands: undefined,\n\t\t\t};\n\n\t\t\trecordRef = record;\n\t\t\trecord.unsubscribe = unsubscribe;\n\t\t\tfor (const notification of bufferedUpdates) {\n\t\t\t\tthis.applySessionUpdateToRecord(record, notification);\n\t\t\t}\n\n\t\t\tthis.setupSessionSubscriptions(record, { skipSessionUpdates: true });\n\t\t\tthis.sessions.set(sessionId, record);\n\n\t\t\tconst summary = this.buildSummary(record);\n\t\t\tthis.emitSessionsChanged({\n\t\t\t\tadded: [summary],\n\t\t\t\tupdated: [],\n\t\t\t\tremoved: [],\n\t\t\t});\n\t\t\tthis.emitSessionAttached(sessionId);\n\n\t\t\tlogger.info({ sessionId, backendId: backend.id }, \"session_loaded\");\n\n\t\t\treturn summary;\n\t\t} catch (error) {\n\t\t\tawait connection.disconnect();\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Reload a historical session from the ACP agent.\n\t * Replays session history even if the session is already loaded.\n\t */\n\tasync reloadSession(\n\t\tsessionId: string,\n\t\tcwd: string,\n\t\tbackendId?: string,\n\t): Promise<SessionSummary> {\n\t\tconst existing = this.sessions.get(sessionId);\n\t\tif (!existing) {\n\t\t\treturn this.loadSession(sessionId, cwd, backendId);\n\t\t}\n\n\t\tif (!existing.connection.supportsSessionLoad()) {\n\t\t\tthrow createCapabilityNotSupportedError(\n\t\t\t\t\"Agent does not support session loading\",\n\t\t\t);\n\t\t}\n\n\t\tconst response = await existing.connection.loadSession(sessionId, cwd);\n\t\tconst { modelId, modelName, availableModels } = resolveModelState(\n\t\t\tresponse.models,\n\t\t);\n\t\tconst { modeId, modeName, availableModes } = resolveModeState(\n\t\t\tresponse.modes,\n\t\t);\n\t\tconst agentInfo = existing.connection.getAgentInfo();\n\n\t\texisting.cwd = cwd;\n\t\texisting.agentName =\n\t\t\tagentInfo?.title ?? agentInfo?.name ?? existing.agentName;\n\t\texisting.modelId = modelId;\n\t\texisting.modelName = modelName;\n\t\texisting.availableModels = availableModels;\n\t\texisting.modeId = modeId;\n\t\texisting.modeName = modeName;\n\t\texisting.availableModes = availableModes;\n\t\texisting.updatedAt = new Date();\n\n\t\tconst summary = this.buildSummary(existing);\n\t\tthis.emitSessionsChanged({\n\t\t\tadded: [],\n\t\t\tupdated: [summary],\n\t\t\tremoved: [],\n\t\t});\n\t\tthis.emitSessionAttached(sessionId, true);\n\n\t\tlogger.info({ sessionId, backendId }, \"session_reloaded\");\n\n\t\treturn summary;\n\t}\n\n\tprivate applySessionUpdateToRecord(\n\t\trecord: SessionRecord,\n\t\tnotification: SessionNotification,\n\t) {\n\t\tconst update = notification.update;\n\t\tif (update.sessionUpdate === \"current_mode_update\") {\n\t\t\trecord.modeId = update.currentModeId;\n\t\t\trecord.modeName =\n\t\t\t\trecord.availableModes?.find((mode) => mode.id === update.currentModeId)\n\t\t\t\t\t?.name ?? record.modeName;\n\t\t\treturn;\n\t\t}\n\t\tif (update.sessionUpdate === \"session_info_update\") {\n\t\t\tif (typeof update.title === \"string\") {\n\t\t\t\trecord.title = update.title;\n\t\t\t}\n\t\t\tif (typeof update.updatedAt === \"string\") {\n\t\t\t\trecord.updatedAt = new Date(update.updatedAt);\n\t\t\t}\n\t\t}\n\t\tif (update.sessionUpdate === \"available_commands_update\") {\n\t\t\tif (update.availableCommands) {\n\t\t\t\trecord.availableCommands = update.availableCommands;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Set up event subscriptions for a session record.\n\t */\n\tprivate setupSessionSubscriptions(\n\t\trecord: SessionRecord,\n\t\toptions?: { skipSessionUpdates?: boolean },\n\t): void {\n\t\tconst { sessionId, connection } = record;\n\n\t\tif (!options?.skipSessionUpdates) {\n\t\t\trecord.unsubscribe = connection.onSessionUpdate(\n\t\t\t\t(notification: SessionNotification) => {\n\t\t\t\t\trecord.updatedAt = new Date();\n\t\t\t\t\tthis.sessionUpdateEmitter.emit(\"update\", notification);\n\t\t\t\t\tthis.applySessionUpdateToRecord(record, notification);\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\n\t\trecord.unsubscribeTerminal = connection.onTerminalOutput((event) => {\n\t\t\tthis.terminalOutputEmitter.emit(\"output\", event);\n\t\t});\n\n\t\tconnection.onStatusChange((status) => {\n\t\t\tif (status.error) {\n\t\t\t\tthis.sessionErrorEmitter.emit(\"error\", {\n\t\t\t\t\tsessionId,\n\t\t\t\t\terror: status.error,\n\t\t\t\t});\n\t\t\t\tthis.emitSessionDetached(sessionId, \"agent_exit\");\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate buildSummary(record: SessionRecord): SessionSummary {\n\t\tconst status = record.connection.getStatus();\n\t\treturn {\n\t\t\tsessionId: record.sessionId,\n\t\t\ttitle: record.title,\n\t\t\tbackendId: record.backendId,\n\t\t\tbackendLabel: record.backendLabel,\n\t\t\terror: status.error,\n\t\t\tpid: status.pid,\n\t\t\tcreatedAt: record.createdAt.toISOString(),\n\t\t\tupdatedAt: record.updatedAt.toISOString(),\n\t\t\tcwd: record.cwd,\n\t\t\tagentName: record.agentName,\n\t\t\tmodelId: record.modelId,\n\t\t\tmodelName: record.modelName,\n\t\t\tmodeId: record.modeId,\n\t\t\tmodeName: record.modeName,\n\t\t\tavailableModes: record.availableModes,\n\t\t\tavailableModels: record.availableModels,\n\t\t\tavailableCommands: record.availableCommands,\n\t\t};\n\t}\n}\n","export const createErrorDetail = (input) => ({\n ...input,\n});\nexport const withScope = (detail, scope) => createErrorDetail({\n ...detail,\n scope,\n});\nexport const createInternalError = (scope, detail) => createErrorDetail({\n code: \"INTERNAL_ERROR\",\n message: \"Internal server error\",\n retryable: true,\n scope,\n detail,\n});\nexport const isProtocolMismatch = (error) => {\n if (error instanceof Error) {\n return /protocol/i.test(error.message);\n }\n return false;\n};\nexport class AppError extends Error {\n detail;\n status;\n constructor(detail, status = 500) {\n super(detail.message);\n this.detail = detail;\n this.status = status;\n }\n}\nexport const isErrorDetail = (payload) => {\n if (!payload || typeof payload !== \"object\") {\n return false;\n }\n const detail = payload;\n return (typeof detail.code === \"string\" &&\n typeof detail.message === \"string\" &&\n typeof detail.retryable === \"boolean\" &&\n typeof detail.scope === \"string\");\n};\n","import { type ChildProcessWithoutNullStreams, spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { EventEmitter } from \"node:events\";\nimport { Readable, Writable } from \"node:stream\";\nimport {\n\ttype AgentCapabilities,\n\ttype Client,\n\tClientSideConnection,\n\ttype ContentBlock,\n\ttype CreateTerminalRequest,\n\ttype CreateTerminalResponse,\n\ttype Implementation,\n\ttype KillTerminalCommandRequest,\n\ttype KillTerminalCommandResponse,\n\ttype ListSessionsResponse,\n\ttype LoadSessionResponse,\n\ttype NewSessionResponse,\n\tndJsonStream,\n\tPROTOCOL_VERSION,\n\ttype PromptResponse,\n\ttype ReleaseTerminalRequest,\n\ttype ReleaseTerminalResponse,\n\ttype RequestPermissionRequest,\n\ttype RequestPermissionResponse,\n\ttype SessionInfo,\n\ttype SessionNotification,\n\ttype TerminalExitStatus,\n\ttype TerminalOutputRequest,\n\ttype TerminalOutputResponse,\n\ttype WaitForTerminalExitRequest,\n\ttype WaitForTerminalExitResponse,\n} from \"@agentclientprotocol/sdk\";\nimport {\n\ttype AcpConnectionState,\n\ttype AgentSessionCapabilities,\n\tcreateErrorDetail,\n\ttype ErrorDetail,\n\tisProtocolMismatch,\n\ttype TerminalOutputEvent,\n} from \"@mobvibe/shared\";\nimport type { AcpBackendConfig } from \"../config.js\";\n\ntype ClientInfo = {\n\tname: string;\n\tversion: string;\n};\n\nexport type AcpBackendStatus = {\n\tbackendId: string;\n\tbackendLabel: string;\n\tstate: AcpConnectionState;\n\tcommand: string;\n\targs: string[];\n\tconnectedAt?: string;\n\terror?: ErrorDetail;\n\tsessionId?: string;\n\tpid?: number;\n};\n\nconst getErrorMessage = (error: unknown) => {\n\tif (error instanceof Error) {\n\t\treturn error.message;\n\t}\n\treturn String(error);\n};\n\ntype SessionUpdateListener = (notification: SessionNotification) => void;\n\ntype TerminalOutputSnapshot = {\n\toutput: string;\n\ttruncated: boolean;\n\texitStatus?: TerminalExitStatus | null;\n};\n\ntype TerminalRecord = {\n\tsessionId: string;\n\tcommand: string;\n\targs: string[];\n\toutputByteLimit: number;\n\toutput: TerminalOutputSnapshot;\n\tprocess?: ChildProcessWithoutNullStreams;\n\tonExit?: Promise<WaitForTerminalExitResponse>;\n\tresolveExit?: (response: WaitForTerminalExitResponse) => void;\n};\n\ntype ClientHandlers = {\n\tonSessionUpdate: (notification: SessionNotification) => void;\n\tonRequestPermission?: (\n\t\tparams: RequestPermissionRequest,\n\t) => Promise<RequestPermissionResponse>;\n\tonCreateTerminal?: (\n\t\tparams: CreateTerminalRequest,\n\t) => Promise<CreateTerminalResponse>;\n\tonTerminalOutput?: (\n\t\tparams: TerminalOutputRequest,\n\t) => Promise<TerminalOutputResponse>;\n\tonWaitForTerminalExit?: (\n\t\tparams: WaitForTerminalExitRequest,\n\t) => Promise<WaitForTerminalExitResponse>;\n\tonKillTerminal?: (\n\t\tparams: KillTerminalCommandRequest,\n\t) => Promise<KillTerminalCommandResponse>;\n\tonReleaseTerminal?: (\n\t\tparams: ReleaseTerminalRequest,\n\t) => Promise<ReleaseTerminalResponse>;\n};\n\nconst buildClient = (handlers: ClientHandlers): Client => ({\n\tasync requestPermission(params: RequestPermissionRequest) {\n\t\tif (handlers.onRequestPermission) {\n\t\t\treturn handlers.onRequestPermission(params);\n\t\t}\n\t\treturn { outcome: { outcome: \"cancelled\" } };\n\t},\n\tasync sessionUpdate(params: SessionNotification) {\n\t\thandlers.onSessionUpdate(params);\n\t},\n\tasync createTerminal(params: CreateTerminalRequest) {\n\t\tif (!handlers.onCreateTerminal) {\n\t\t\tthrow new Error(\"Terminal create handler not configured\");\n\t\t}\n\t\treturn handlers.onCreateTerminal(params);\n\t},\n\tasync terminalOutput(params: TerminalOutputRequest) {\n\t\tif (!handlers.onTerminalOutput) {\n\t\t\treturn { output: \"\", truncated: false };\n\t\t}\n\t\treturn handlers.onTerminalOutput(params);\n\t},\n\tasync waitForTerminalExit(params: WaitForTerminalExitRequest) {\n\t\tif (!handlers.onWaitForTerminalExit) {\n\t\t\treturn { exitCode: null, signal: null };\n\t\t}\n\t\treturn handlers.onWaitForTerminalExit(params);\n\t},\n\tasync killTerminal(params: KillTerminalCommandRequest) {\n\t\tif (!handlers.onKillTerminal) {\n\t\t\treturn {};\n\t\t}\n\t\treturn handlers.onKillTerminal(params);\n\t},\n\tasync releaseTerminal(params: ReleaseTerminalRequest) {\n\t\tif (!handlers.onReleaseTerminal) {\n\t\t\treturn {};\n\t\t}\n\t\treturn handlers.onReleaseTerminal(params);\n\t},\n});\n\nconst formatExitMessage = (\n\tcode: number | null,\n\tsignal: NodeJS.Signals | null,\n) => {\n\tif (signal) {\n\t\treturn `ACP process received signal ${signal}`;\n\t}\n\tif (code !== null) {\n\t\treturn `ACP process exited with code ${code}`;\n\t}\n\treturn \"ACP process exited\";\n};\n\nconst buildConnectError = (error: unknown): ErrorDetail => {\n\tconst detail = getErrorMessage(error);\n\tif (isProtocolMismatch(error)) {\n\t\treturn createErrorDetail({\n\t\t\tcode: \"ACP_PROTOCOL_MISMATCH\",\n\t\t\tmessage: \"ACP protocol version mismatch\",\n\t\t\tretryable: false,\n\t\t\tscope: \"service\",\n\t\t\tdetail,\n\t\t});\n\t}\n\treturn createErrorDetail({\n\t\tcode: \"ACP_CONNECT_FAILED\",\n\t\tmessage: \"Failed to connect to ACP backend process\",\n\t\tretryable: true,\n\t\tscope: \"service\",\n\t\tdetail,\n\t});\n};\n\nconst buildProcessExitError = (detail: string): ErrorDetail =>\n\tcreateErrorDetail({\n\t\tcode: \"ACP_PROCESS_EXITED\",\n\t\tmessage: \"ACP backend process exited unexpectedly\",\n\t\tretryable: true,\n\t\tscope: \"service\",\n\t\tdetail,\n\t});\n\nconst buildConnectionClosedError = (detail: string): ErrorDetail =>\n\tcreateErrorDetail({\n\t\tcode: \"ACP_CONNECTION_CLOSED\",\n\t\tmessage: \"ACP connection closed\",\n\t\tretryable: true,\n\t\tscope: \"service\",\n\t\tdetail,\n\t});\n\nconst normalizeOutputText = (value: string) => value.normalize(\"NFC\");\n\nconst isOutputOverLimit = (value: string, limit: number) =>\n\tBuffer.byteLength(value, \"utf8\") > limit;\n\nconst sliceOutputToLimit = (value: string, limit: number) => {\n\tconst buffer = Buffer.from(value, \"utf8\");\n\tif (buffer.byteLength <= limit) {\n\t\treturn value;\n\t}\n\tconst sliced = buffer.subarray(buffer.byteLength - limit);\n\tlet start = 0;\n\twhile (start < sliced.length && (sliced[start] & 0b11000000) === 0b10000000) {\n\t\tstart += 1;\n\t}\n\treturn sliced.subarray(start).toString(\"utf8\");\n};\n\nexport class AcpConnection {\n\tprivate connection?: ClientSideConnection;\n\tprivate process?: ChildProcessWithoutNullStreams;\n\tprivate closedPromise?: Promise<void>;\n\tprivate state: AcpConnectionState = \"idle\";\n\tprivate connectedAt?: Date;\n\tprivate error?: ErrorDetail;\n\tprivate sessionId?: string;\n\tprivate agentInfo?: Implementation;\n\tprivate agentCapabilities?: AgentCapabilities;\n\tprivate readonly sessionUpdateEmitter = new EventEmitter();\n\tprivate readonly statusEmitter = new EventEmitter();\n\tprivate readonly terminalOutputEmitter = new EventEmitter();\n\tprivate permissionHandler?: (\n\t\tparams: RequestPermissionRequest,\n\t) => Promise<RequestPermissionResponse>;\n\tprivate terminals = new Map<string, TerminalRecord>();\n\n\tconstructor(\n\t\tprivate readonly options: {\n\t\t\tbackend: AcpBackendConfig;\n\t\t\tclient: ClientInfo;\n\t\t},\n\t) {}\n\n\tgetStatus(): AcpBackendStatus {\n\t\treturn {\n\t\t\tbackendId: this.options.backend.id,\n\t\t\tbackendLabel: this.options.backend.label,\n\t\t\tstate: this.state,\n\t\t\tcommand: this.options.backend.command,\n\t\t\targs: [...this.options.backend.args],\n\t\t\tconnectedAt: this.connectedAt?.toISOString(),\n\t\t\terror: this.error,\n\t\t\tsessionId: this.sessionId,\n\t\t\tpid: this.process?.pid,\n\t\t};\n\t}\n\n\tgetAgentInfo(): Implementation | undefined {\n\t\treturn this.agentInfo;\n\t}\n\n\t/**\n\t * Get the agent's session capabilities.\n\t */\n\tgetSessionCapabilities(): AgentSessionCapabilities {\n\t\treturn {\n\t\t\tlist: this.agentCapabilities?.sessionCapabilities?.list != null,\n\t\t\tload: this.agentCapabilities?.loadSession === true,\n\t\t};\n\t}\n\n\t/**\n\t * Check if the agent supports session/list.\n\t */\n\tsupportsSessionList(): boolean {\n\t\treturn this.agentCapabilities?.sessionCapabilities?.list != null;\n\t}\n\n\t/**\n\t * Check if the agent supports session/load.\n\t */\n\tsupportsSessionLoad(): boolean {\n\t\treturn this.agentCapabilities?.loadSession === true;\n\t}\n\n\t/**\n\t * List sessions from the agent (session/list).\n\t * @param params Optional filter parameters\n\t * @returns List of session info from the agent\n\t */\n\tasync listSessions(params?: {\n\t\tcursor?: string;\n\t\tcwd?: string;\n\t}): Promise<{ sessions: SessionInfo[]; nextCursor?: string }> {\n\t\tif (!this.supportsSessionList()) {\n\t\t\treturn { sessions: [] };\n\t\t}\n\t\tconst connection = await this.ensureReady();\n\t\tconst response: ListSessionsResponse =\n\t\t\tawait connection.unstable_listSessions({\n\t\t\t\tcursor: params?.cursor ?? undefined,\n\t\t\t\tcwd: params?.cwd ?? undefined,\n\t\t\t});\n\t\treturn {\n\t\t\tsessions: response.sessions,\n\t\t\tnextCursor: response.nextCursor ?? undefined,\n\t\t};\n\t}\n\n\t/**\n\t * Load a historical session with message history replay (session/load).\n\t * @param sessionId The session ID to load\n\t * @param cwd The working directory\n\t * @returns Load session response with modes/models state\n\t */\n\tasync loadSession(\n\t\tsessionId: string,\n\t\tcwd: string,\n\t): Promise<LoadSessionResponse> {\n\t\tif (!this.supportsSessionLoad()) {\n\t\t\tthrow new Error(\"Agent does not support session/load capability\");\n\t\t}\n\t\tconst connection = await this.ensureReady();\n\t\tconst response = await connection.loadSession({\n\t\t\tsessionId,\n\t\t\tcwd,\n\t\t\tmcpServers: [],\n\t\t});\n\t\tthis.sessionId = sessionId;\n\t\treturn response;\n\t}\n\n\tsetPermissionHandler(\n\t\thandler?: (\n\t\t\tparams: RequestPermissionRequest,\n\t\t) => Promise<RequestPermissionResponse>,\n\t) {\n\t\tthis.permissionHandler = handler;\n\t}\n\n\tonTerminalOutput(listener: (payload: TerminalOutputEvent) => void) {\n\t\tthis.terminalOutputEmitter.on(\"output\", listener);\n\t\treturn () => {\n\t\t\tthis.terminalOutputEmitter.off(\"output\", listener);\n\t\t};\n\t}\n\n\tonSessionUpdate(listener: SessionUpdateListener) {\n\t\tthis.sessionUpdateEmitter.on(\"update\", listener);\n\t\treturn () => {\n\t\t\tthis.sessionUpdateEmitter.off(\"update\", listener);\n\t\t};\n\t}\n\n\tonStatusChange(listener: (status: AcpBackendStatus) => void) {\n\t\tthis.statusEmitter.on(\"status\", listener);\n\t\treturn () => {\n\t\t\tthis.statusEmitter.off(\"status\", listener);\n\t\t};\n\t}\n\n\tprivate updateStatus(state: AcpConnectionState, error?: ErrorDetail) {\n\t\tthis.state = state;\n\t\tthis.error = error;\n\t\tthis.statusEmitter.emit(\"status\", this.getStatus());\n\t}\n\n\tasync connect(): Promise<void> {\n\t\tif (this.state === \"connecting\" || this.state === \"ready\") {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.updateStatus(\"connecting\");\n\t\tthis.agentInfo = undefined;\n\n\t\ttry {\n\t\t\tconst env = this.options.backend.envOverrides\n\t\t\t\t? { ...process.env, ...this.options.backend.envOverrides }\n\t\t\t\t: process.env;\n\t\t\tconst child = spawn(\n\t\t\t\tthis.options.backend.command,\n\t\t\t\tthis.options.backend.args,\n\t\t\t\t{\n\t\t\t\t\tstdio: [\"pipe\", \"pipe\", \"pipe\"],\n\t\t\t\t\tenv,\n\t\t\t\t},\n\t\t\t);\n\t\t\tthis.process = child;\n\t\t\tthis.sessionId = undefined;\n\t\t\tchild.stderr.pipe(process.stderr);\n\n\t\t\tconst input = Writable.toWeb(child.stdin) as WritableStream<Uint8Array>;\n\t\t\tconst output = Readable.toWeb(child.stdout) as ReadableStream<Uint8Array>;\n\t\t\tconst stream = ndJsonStream(input, output);\n\t\t\tconst connection = new ClientSideConnection(\n\t\t\t\t() =>\n\t\t\t\t\tbuildClient({\n\t\t\t\t\t\tonSessionUpdate: (notification) =>\n\t\t\t\t\t\t\tthis.emitSessionUpdate(notification),\n\t\t\t\t\t\tonRequestPermission: (params) =>\n\t\t\t\t\t\t\tthis.handlePermissionRequest(params),\n\t\t\t\t\t\tonCreateTerminal: (params) => this.createTerminal(params),\n\t\t\t\t\t\tonTerminalOutput: (params) => this.getTerminalOutput(params),\n\t\t\t\t\t\tonWaitForTerminalExit: (params) => this.waitForTerminalExit(params),\n\t\t\t\t\t\tonKillTerminal: (params) => this.killTerminal(params),\n\t\t\t\t\t\tonReleaseTerminal: (params) => this.releaseTerminal(params),\n\t\t\t\t\t}),\n\t\t\t\tstream,\n\t\t\t);\n\t\t\tthis.connection = connection;\n\n\t\t\tchild.once(\"error\", (error) => {\n\t\t\t\tif (this.state === \"stopped\") {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.updateStatus(\"error\", buildConnectError(error));\n\t\t\t});\n\n\t\t\tchild.once(\"exit\", (code, signal) => {\n\t\t\t\tif (this.state === \"stopped\") {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.updateStatus(\n\t\t\t\t\t\"error\",\n\t\t\t\t\tbuildProcessExitError(formatExitMessage(code, signal)),\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tthis.closedPromise = connection.closed.catch((error) => {\n\t\t\t\tthis.updateStatus(\n\t\t\t\t\t\"error\",\n\t\t\t\t\tbuildConnectionClosedError(getErrorMessage(error)),\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tconst initializeResponse = await connection.initialize({\n\t\t\t\tprotocolVersion: PROTOCOL_VERSION,\n\t\t\t\tclientInfo: {\n\t\t\t\t\tname: this.options.client.name,\n\t\t\t\t\tversion: this.options.client.version,\n\t\t\t\t},\n\t\t\t\tclientCapabilities: { terminal: true },\n\t\t\t});\n\n\t\t\tthis.agentInfo = initializeResponse.agentInfo ?? undefined;\n\t\t\tthis.agentCapabilities =\n\t\t\t\tinitializeResponse.agentCapabilities ?? undefined;\n\t\t\tthis.connectedAt = new Date();\n\t\t\tthis.updateStatus(\"ready\");\n\t\t} catch (error) {\n\t\t\tthis.updateStatus(\"error\", buildConnectError(error));\n\t\t\tawait this.stopProcess();\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync createSession(options?: { cwd?: string }): Promise<NewSessionResponse> {\n\t\tconst connection = await this.ensureReady();\n\t\tconst response = await this.createSessionInternal(\n\t\t\tconnection,\n\t\t\toptions?.cwd ?? process.cwd(),\n\t\t);\n\t\tthis.sessionId = response.sessionId;\n\t\treturn response;\n\t}\n\n\tasync prompt(\n\t\tsessionId: string,\n\t\tprompt: ContentBlock[],\n\t): Promise<PromptResponse> {\n\t\tconst connection = await this.ensureReady();\n\t\treturn connection.prompt({ sessionId, prompt });\n\t}\n\n\tasync cancel(sessionId: string): Promise<void> {\n\t\tconst connection = await this.ensureReady();\n\t\tawait connection.cancel({ sessionId });\n\t}\n\n\tasync setSessionMode(sessionId: string, modeId: string): Promise<void> {\n\t\tconst connection = await this.ensureReady();\n\t\tawait connection.setSessionMode({ sessionId, modeId });\n\t}\n\n\tasync setSessionModel(sessionId: string, modelId: string): Promise<void> {\n\t\tconst connection = await this.ensureReady();\n\t\tawait connection.unstable_setSessionModel({ sessionId, modelId });\n\t}\n\n\tasync createTerminal(\n\t\tparams: CreateTerminalRequest,\n\t): Promise<CreateTerminalResponse> {\n\t\tconst outputLimit =\n\t\t\ttypeof params.outputByteLimit === \"number\" && params.outputByteLimit > 0\n\t\t\t\t? Math.floor(params.outputByteLimit)\n\t\t\t\t: 1024 * 1024;\n\t\tconst resolvedEnv = params.env\n\t\t\t? Object.fromEntries(\n\t\t\t\t\tparams.env.map((envVar) => [envVar.name, envVar.value]),\n\t\t\t\t)\n\t\t\t: undefined;\n\t\tconst terminalId = randomUUID();\n\t\tconst record: TerminalRecord = {\n\t\t\tsessionId: params.sessionId,\n\t\t\tcommand: params.command,\n\t\t\targs: params.args ?? [],\n\t\t\toutputByteLimit: outputLimit,\n\t\t\toutput: {\n\t\t\t\toutput: \"\",\n\t\t\t\ttruncated: false,\n\t\t\t\texitStatus: null,\n\t\t\t},\n\t\t};\n\t\tthis.terminals.set(terminalId, record);\n\n\t\tconst child = spawn(params.command, params.args ?? [], {\n\t\t\tcwd: params.cwd ?? undefined,\n\t\t\tenv: resolvedEnv ? { ...process.env, ...resolvedEnv } : process.env,\n\t\t});\n\t\tchild.once(\"error\", (error) => {\n\t\t\trecord.output.exitStatus = {\n\t\t\t\texitCode: null,\n\t\t\t\tsignal: null,\n\t\t\t};\n\t\t\trecord.resolveExit?.({ exitCode: null, signal: null });\n\t\t\tthis.terminalOutputEmitter.emit(\"output\", {\n\t\t\t\tsessionId: record.sessionId,\n\t\t\t\tterminalId,\n\t\t\t\tdelta: `\\n[terminal error] ${String(error)}`,\n\t\t\t\ttruncated: record.output.truncated,\n\t\t\t\toutput: record.output.output,\n\t\t\t\texitStatus: record.output.exitStatus,\n\t\t\t} satisfies TerminalOutputEvent);\n\t\t});\n\t\trecord.process = child;\n\t\tlet resolveExit: (response: WaitForTerminalExitResponse) => void = () => {};\n\t\trecord.onExit = new Promise<WaitForTerminalExitResponse>((resolve) => {\n\t\t\tresolveExit = resolve;\n\t\t});\n\t\trecord.resolveExit = resolveExit;\n\n\t\tconst handleChunk = (chunk: Buffer) => {\n\t\t\tconst delta = normalizeOutputText(chunk.toString(\"utf8\"));\n\t\t\tif (!delta) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst combinedOutput = record.output.output + delta;\n\t\t\trecord.output.truncated = isOutputOverLimit(\n\t\t\t\tcombinedOutput,\n\t\t\t\trecord.outputByteLimit,\n\t\t\t);\n\t\t\trecord.output.output = sliceOutputToLimit(\n\t\t\t\tcombinedOutput,\n\t\t\t\trecord.outputByteLimit,\n\t\t\t);\n\n\t\t\tthis.terminalOutputEmitter.emit(\"output\", {\n\t\t\t\tsessionId: record.sessionId,\n\t\t\t\tterminalId,\n\t\t\t\tdelta,\n\t\t\t\ttruncated: record.output.truncated,\n\t\t\t\toutput: record.output.truncated ? record.output.output : undefined,\n\t\t\t\texitStatus: record.output.exitStatus,\n\t\t\t} satisfies TerminalOutputEvent);\n\t\t};\n\n\t\tchild.stdout?.on(\"data\", handleChunk);\n\t\tchild.stderr?.on(\"data\", handleChunk);\n\t\tchild.on(\"exit\", (code, signal) => {\n\t\t\trecord.output.exitStatus = {\n\t\t\t\texitCode: code ?? null,\n\t\t\t\tsignal: signal ?? null,\n\t\t\t};\n\t\t\trecord.resolveExit?.({\n\t\t\t\texitCode: code ?? null,\n\t\t\t\tsignal: signal ?? null,\n\t\t\t});\n\t\t\tthis.terminalOutputEmitter.emit(\"output\", {\n\t\t\t\tsessionId: record.sessionId,\n\t\t\t\tterminalId,\n\t\t\t\tdelta: \"\",\n\t\t\t\ttruncated: record.output.truncated,\n\t\t\t\toutput: record.output.output,\n\t\t\t\texitStatus: record.output.exitStatus,\n\t\t\t} satisfies TerminalOutputEvent);\n\t\t});\n\n\t\treturn { terminalId };\n\t}\n\n\tasync getTerminalOutput(\n\t\tparams: TerminalOutputRequest,\n\t): Promise<TerminalOutputResponse> {\n\t\tconst record = this.terminals.get(params.terminalId);\n\t\tif (!record || record.sessionId !== params.sessionId) {\n\t\t\treturn { output: \"\", truncated: false };\n\t\t}\n\t\treturn record.output;\n\t}\n\n\tasync waitForTerminalExit(\n\t\tparams: WaitForTerminalExitRequest,\n\t): Promise<WaitForTerminalExitResponse> {\n\t\tconst record = this.terminals.get(params.terminalId);\n\t\tif (!record || record.sessionId !== params.sessionId) {\n\t\t\treturn Promise.resolve({ exitCode: null, signal: null });\n\t\t}\n\t\treturn record.onExit ?? Promise.resolve({ exitCode: null, signal: null });\n\t}\n\n\tasync killTerminal(\n\t\tparams: KillTerminalCommandRequest,\n\t): Promise<KillTerminalCommandResponse> {\n\t\tconst record = this.terminals.get(params.terminalId);\n\t\tif (!record || record.sessionId !== params.sessionId) {\n\t\t\treturn {};\n\t\t}\n\t\trecord.process?.kill(\"SIGTERM\");\n\t\treturn {};\n\t}\n\n\tasync releaseTerminal(\n\t\tparams: ReleaseTerminalRequest,\n\t): Promise<ReleaseTerminalResponse> {\n\t\tconst record = this.terminals.get(params.terminalId);\n\t\tif (record?.process && record.process.exitCode === null) {\n\t\t\trecord.process.kill(\"SIGTERM\");\n\t\t}\n\t\tthis.terminals.delete(params.terminalId);\n\t\treturn {};\n\t}\n\n\tasync disconnect(): Promise<void> {\n\t\tif (this.state === \"stopped\") {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.updateStatus(\"stopped\");\n\t\tthis.sessionId = undefined;\n\t\tthis.agentInfo = undefined;\n\t\tawait this.stopProcess();\n\t\tawait this.closedPromise;\n\t\tthis.connection = undefined;\n\t}\n\n\tprivate async ensureReady(): Promise<ClientSideConnection> {\n\t\tif (this.state !== \"ready\" || !this.connection) {\n\t\t\tawait this.connect();\n\t\t}\n\n\t\tif (!this.connection || this.state !== \"ready\") {\n\t\t\tthrow new Error(\"ACP connection not available\");\n\t\t}\n\n\t\treturn this.connection;\n\t}\n\n\tprivate async createSessionInternal(\n\t\tconnection: ClientSideConnection,\n\t\tcwd: string,\n\t): Promise<NewSessionResponse> {\n\t\tconst session = await connection.newSession({\n\t\t\tcwd,\n\t\t\tmcpServers: [],\n\t\t});\n\t\treturn session;\n\t}\n\n\tprivate emitSessionUpdate(notification: SessionNotification) {\n\t\tthis.sessionUpdateEmitter.emit(\"update\", notification);\n\t}\n\n\tprivate async handlePermissionRequest(\n\t\tparams: RequestPermissionRequest,\n\t): Promise<RequestPermissionResponse> {\n\t\tif (this.permissionHandler) {\n\t\t\treturn this.permissionHandler(params);\n\t\t}\n\t\treturn { outcome: { outcome: \"cancelled\" } };\n\t}\n\n\tprivate async stopProcess(): Promise<void> {\n\t\tconst child = this.process;\n\t\tif (!child) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.process = undefined;\n\t\tif (child.exitCode === null && !child.killed) {\n\t\t\tchild.kill(\"SIGTERM\");\n\t\t}\n\t}\n}\n","import { EventEmitter } from \"node:events\";\nimport fs from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport path from \"node:path\";\nimport type {\n\tCliToGatewayEvents,\n\tFsEntry,\n\tFsRoot,\n\tGatewayToCliEvents,\n\tHostFsRootsResponse,\n\tRpcResponse,\n\tSessionFsFilePreview,\n\tSessionFsResourceEntry,\n\tStopReason,\n} from \"@mobvibe/shared\";\nimport ignore, { type Ignore } from \"ignore\";\nimport { io, type Socket } from \"socket.io-client\";\nimport type { SessionManager } from \"../acp/session-manager.js\";\nimport type { CliConfig } from \"../config.js\";\nimport {\n\taggregateDirStatus,\n\tgetFileDiff,\n\tgetGitBranch,\n\tgetGitStatus,\n\tisGitRepo,\n} from \"../lib/git-utils.js\";\nimport { logger } from \"../lib/logger.js\";\n\ntype SocketClientOptions = {\n\tconfig: CliConfig;\n\tsessionManager: SessionManager;\n\t/** API key for authentication (loaded from credentials) */\n\tapiKey: string;\n};\n\nconst SESSION_ROOT_NAME = \"Working Directory\";\nconst MAX_RESOURCE_FILES = 2000;\nconst DEFAULT_IGNORES = [\n\t\"node_modules\",\n\t\".git\",\n\t\"dist\",\n\t\"build\",\n\t\".next\",\n\t\".nuxt\",\n\t\".output\",\n\t\".cache\",\n\t\"__pycache__\",\n\t\".venv\",\n\t\"venv\",\n\t\"target\",\n];\n\nconst loadGitignore = async (rootPath: string): Promise<Ignore> => {\n\tconst ig = ignore().add(DEFAULT_IGNORES);\n\ttry {\n\t\tconst gitignorePath = path.join(rootPath, \".gitignore\");\n\t\tconst content = await fs.readFile(gitignorePath, \"utf8\");\n\t\tig.add(content);\n\t} catch {\n\t\t// No .gitignore file, use defaults only\n\t}\n\treturn ig;\n};\n\nconst resolveImageMimeType = (filePath: string) => {\n\tconst extension = path.extname(filePath).toLowerCase();\n\tswitch (extension) {\n\t\tcase \".apng\":\n\t\t\treturn \"image/apng\";\n\t\tcase \".avif\":\n\t\t\treturn \"image/avif\";\n\t\tcase \".gif\":\n\t\t\treturn \"image/gif\";\n\t\tcase \".jpeg\":\n\t\t\treturn \"image/jpeg\";\n\t\tcase \".jpg\":\n\t\t\treturn \"image/jpeg\";\n\t\tcase \".png\":\n\t\t\treturn \"image/png\";\n\t\tcase \".svg\":\n\t\t\treturn \"image/svg+xml\";\n\t\tcase \".webp\":\n\t\t\treturn \"image/webp\";\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n};\n\nconst readDirectoryEntries = async (dirPath: string): Promise<FsEntry[]> => {\n\tconst entries = await fs.readdir(dirPath, { withFileTypes: true });\n\tconst resolvedEntries = await Promise.all(\n\t\tentries.map(async (entry) => {\n\t\t\tconst entryPath = path.join(dirPath, entry.name);\n\t\t\tlet isDirectory = entry.isDirectory();\n\t\t\tif (!isDirectory && entry.isSymbolicLink()) {\n\t\t\t\ttry {\n\t\t\t\t\tconst stats = await fs.stat(entryPath);\n\t\t\t\t\tisDirectory = stats.isDirectory();\n\t\t\t\t} catch {\n\t\t\t\t\t// ignore broken symlink\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst entryType: FsEntry[\"type\"] = isDirectory ? \"directory\" : \"file\";\n\t\t\treturn {\n\t\t\t\tname: entry.name,\n\t\t\t\tpath: entryPath,\n\t\t\t\ttype: entryType,\n\t\t\t\thidden: entry.name.startsWith(\".\"),\n\t\t\t};\n\t\t}),\n\t);\n\treturn resolvedEntries.sort((left, right) => {\n\t\tif (left.type !== right.type) {\n\t\t\treturn left.type === \"directory\" ? -1 : 1;\n\t\t}\n\t\treturn left.name.localeCompare(right.name);\n\t});\n};\n\nconst filterVisibleEntries = (entries: FsEntry[]) =>\n\tentries.filter((entry) => !entry.hidden);\n\nconst buildHostFsRoots = async (): Promise<HostFsRootsResponse> => {\n\tconst homePath = homedir();\n\treturn {\n\t\thomePath,\n\t\troots: [{ name: \"Home\", path: homePath }],\n\t};\n};\n\nexport class SocketClient extends EventEmitter {\n\tprivate socket: Socket<GatewayToCliEvents, CliToGatewayEvents>;\n\tprivate connected = false;\n\tprivate reconnectAttempts = 0;\n\tprivate heartbeatInterval?: NodeJS.Timeout;\n\n\tconstructor(private readonly options: SocketClientOptions) {\n\t\tsuper();\n\t\tthis.socket = io(`${options.config.gatewayUrl}/cli`, {\n\t\t\tpath: \"/socket.io\",\n\t\t\treconnection: true,\n\t\t\treconnectionAttempts: Number.POSITIVE_INFINITY,\n\t\t\treconnectionDelay: 1000,\n\t\t\treconnectionDelayMax: 30000,\n\t\t\ttransports: [\"websocket\"],\n\t\t\tautoConnect: false,\n\t\t\textraHeaders: {\n\t\t\t\t\"x-api-key\": options.apiKey,\n\t\t\t},\n\t\t});\n\t\tthis.setupEventHandlers();\n\t\tthis.setupRpcHandlers();\n\t\tthis.setupSessionManagerListeners();\n\t}\n\n\tprivate setupEventHandlers() {\n\t\tthis.socket.on(\"connect\", () => {\n\t\t\tlogger.info(\n\t\t\t\t{ gatewayUrl: this.options.config.gatewayUrl },\n\t\t\t\t\"gateway_connected\",\n\t\t\t);\n\t\t\tthis.connected = true;\n\t\t\tthis.reconnectAttempts = 0;\n\t\t\tlogger.info(\"gateway_register_start\");\n\t\t\tthis.register();\n\t\t\tthis.startHeartbeat();\n\t\t\tthis.emit(\"connected\");\n\t\t});\n\n\t\tthis.socket.on(\"disconnect\", (reason) => {\n\t\t\tlogger.warn({ reason }, \"gateway_disconnected\");\n\t\t\tthis.connected = false;\n\t\t\tthis.stopHeartbeat();\n\t\t\tthis.emit(\"disconnected\", reason);\n\t\t});\n\n\t\tthis.socket.on(\"connect_error\", (error) => {\n\t\t\tthis.reconnectAttempts++;\n\t\t\tif (this.reconnectAttempts <= 3 || this.reconnectAttempts % 10 === 0) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{ attempt: this.reconnectAttempts, err: error },\n\t\t\t\t\t\"gateway_connect_error\",\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\n\t\tthis.socket.on(\"cli:registered\", async (info) => {\n\t\t\tlogger.info({ machineId: info.machineId }, \"gateway_registered\");\n\n\t\t\t// Auto-discover historical sessions from ACP agent\n\t\t\ttry {\n\t\t\t\tlet cursor: string | undefined;\n\t\t\t\tlet page = 0;\n\t\t\t\tdo {\n\t\t\t\t\tconst { sessions, capabilities, nextCursor } =\n\t\t\t\t\t\tawait this.options.sessionManager.discoverSessions({ cursor });\n\t\t\t\t\tcursor = nextCursor;\n\t\t\t\t\tif (sessions.length > 0) {\n\t\t\t\t\t\tthis.socket.emit(\"sessions:discovered\", {\n\t\t\t\t\t\t\tsessions,\n\t\t\t\t\t\t\tcapabilities,\n\t\t\t\t\t\t\tnextCursor,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tlogger.info(\n\t\t\t\t\t\t\t{ count: sessions.length, capabilities, page },\n\t\t\t\t\t\t\t\"historical_sessions_discovered\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tpage += 1;\n\t\t\t\t} while (cursor);\n\t\t\t} catch (error) {\n\t\t\t\tlogger.warn({ err: error }, \"session_discovery_failed\");\n\t\t\t}\n\t\t});\n\n\t\t// Handle authentication errors\n\t\tthis.socket.on(\"cli:error\", (error) => {\n\t\t\tlogger.error({ err: error }, \"gateway_auth_error\");\n\t\t\tthis.emit(\"auth_error\", error);\n\t\t});\n\t}\n\n\tprivate setupRpcHandlers() {\n\t\tconst { sessionManager } = this.options;\n\n\t\t// Session create\n\t\tthis.socket.on(\"rpc:session:create\", async (request) => {\n\t\t\ttry {\n\t\t\t\tlogger.info({ requestId: request.requestId }, \"rpc_session_create\");\n\t\t\t\tconst session = await sessionManager.createSession(request.params);\n\t\t\t\tthis.sendRpcResponse(request.requestId, session);\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{ err: error, requestId: request.requestId },\n\t\t\t\t\t\"rpc_session_create_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\t// Session close\n\t\tthis.socket.on(\"rpc:session:close\", async (request) => {\n\t\t\ttry {\n\t\t\t\tlogger.info(\n\t\t\t\t\t{ requestId: request.requestId, sessionId: request.params.sessionId },\n\t\t\t\t\t\"rpc_session_close\",\n\t\t\t\t);\n\t\t\t\tawait sessionManager.closeSession(request.params.sessionId);\n\t\t\t\tthis.sendRpcResponse(request.requestId, { ok: true });\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_session_close_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\t// Session cancel\n\t\tthis.socket.on(\"rpc:session:cancel\", async (request) => {\n\t\t\ttry {\n\t\t\t\tlogger.info(\n\t\t\t\t\t{ requestId: request.requestId, sessionId: request.params.sessionId },\n\t\t\t\t\t\"rpc_session_cancel\",\n\t\t\t\t);\n\t\t\t\tawait sessionManager.cancelSession(request.params.sessionId);\n\t\t\t\tthis.sendRpcResponse(request.requestId, { ok: true });\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_session_cancel_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\t// Session mode\n\t\tthis.socket.on(\"rpc:session:mode\", async (request) => {\n\t\t\ttry {\n\t\t\t\tlogger.info(\n\t\t\t\t\t{\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t\tmodeId: request.params.modeId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_session_mode\",\n\t\t\t\t);\n\t\t\t\tconst session = await sessionManager.setSessionMode(\n\t\t\t\t\trequest.params.sessionId,\n\t\t\t\t\trequest.params.modeId,\n\t\t\t\t);\n\t\t\t\tthis.sendRpcResponse(request.requestId, session);\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t\tmodeId: request.params.modeId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_session_mode_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\t// Session model\n\t\tthis.socket.on(\"rpc:session:model\", async (request) => {\n\t\t\ttry {\n\t\t\t\tlogger.info(\n\t\t\t\t\t{\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t\tmodelId: request.params.modelId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_session_model\",\n\t\t\t\t);\n\t\t\t\tconst session = await sessionManager.setSessionModel(\n\t\t\t\t\trequest.params.sessionId,\n\t\t\t\t\trequest.params.modelId,\n\t\t\t\t);\n\t\t\t\tthis.sendRpcResponse(request.requestId, session);\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t\tmodelId: request.params.modelId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_session_model_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\t// Send message\n\t\tthis.socket.on(\"rpc:message:send\", async (request) => {\n\t\t\tconst requestStart = process.hrtime.bigint();\n\t\t\ttry {\n\t\t\t\tconst { sessionId, prompt } = request.params;\n\t\t\t\tlogger.info(\n\t\t\t\t\t{\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId,\n\t\t\t\t\t\tpromptBlocks: prompt.length,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_message_send\",\n\t\t\t\t);\n\t\t\t\tlogger.debug(\n\t\t\t\t\t{\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId,\n\t\t\t\t\t\tpromptBlocks: prompt.length,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_message_send_start\",\n\t\t\t\t);\n\t\t\t\tconst record = sessionManager.getSession(sessionId);\n\t\t\t\tif (!record) {\n\t\t\t\t\tthrow new Error(\"Session not found\");\n\t\t\t\t}\n\t\t\t\tsessionManager.touchSession(sessionId);\n\t\t\t\t// Cast through unknown since SDK and shared ContentBlock types are structurally compatible\n\t\t\t\tconst result = await record.connection.prompt(\n\t\t\t\t\tsessionId,\n\t\t\t\t\tprompt as unknown as import(\"@agentclientprotocol/sdk\").ContentBlock[],\n\t\t\t\t);\n\t\t\t\tsessionManager.touchSession(sessionId);\n\t\t\t\tthis.sendRpcResponse<{ stopReason: StopReason }>(request.requestId, {\n\t\t\t\t\tstopReason: result.stopReason as StopReason,\n\t\t\t\t});\n\t\t\t\tconst durationMs =\n\t\t\t\t\tNumber(process.hrtime.bigint() - requestStart) / 1_000_000;\n\t\t\t\tlogger.info(\n\t\t\t\t\t{\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId,\n\t\t\t\t\t\tstopReason: result.stopReason,\n\t\t\t\t\t\tdurationMs,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_message_send_complete\",\n\t\t\t\t);\n\t\t\t\tlogger.debug(\n\t\t\t\t\t{\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId,\n\t\t\t\t\t\tdurationMs,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_message_send_finish\",\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\tconst durationMs =\n\t\t\t\t\tNumber(process.hrtime.bigint() - requestStart) / 1_000_000;\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t\tpromptBlocks: request.params.prompt.length,\n\t\t\t\t\t\tdurationMs,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_message_send_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\t// Permission decision\n\t\tthis.socket.on(\"rpc:permission:decision\", async (request) => {\n\t\t\ttry {\n\t\t\t\tconst { sessionId, requestId, outcome } = request.params;\n\t\t\t\tlogger.info(\n\t\t\t\t\t{ requestId: request.requestId, sessionId, outcome },\n\t\t\t\t\t\"rpc_permission_decision\",\n\t\t\t\t);\n\t\t\t\tsessionManager.resolvePermissionRequest(sessionId, requestId, outcome);\n\t\t\t\tthis.sendRpcResponse(request.requestId, { ok: true });\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t\tpermissionRequestId: request.params.requestId,\n\t\t\t\t\t\toutcome: request.params.outcome,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_permission_decision_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\t// File system handlers\n\t\tthis.socket.on(\"rpc:fs:roots\", async (request) => {\n\t\t\ttry {\n\t\t\t\tlogger.debug(\n\t\t\t\t\t{ requestId: request.requestId, sessionId: request.params.sessionId },\n\t\t\t\t\t\"rpc_fs_roots\",\n\t\t\t\t);\n\t\t\t\tconst record = sessionManager.getSession(request.params.sessionId);\n\t\t\t\tif (!record || !record.cwd) {\n\t\t\t\t\tthrow new Error(\"Session not found or no working directory\");\n\t\t\t\t}\n\t\t\t\tconst root: FsRoot = {\n\t\t\t\t\tname: SESSION_ROOT_NAME,\n\t\t\t\t\tpath: record.cwd,\n\t\t\t\t};\n\t\t\t\tthis.sendRpcResponse(request.requestId, { root });\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_fs_roots_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\tthis.socket.on(\"rpc:hostfs:roots\", async (request) => {\n\t\t\ttry {\n\t\t\t\tlogger.debug(\n\t\t\t\t\t{\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tmachineId: request.params.machineId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_hostfs_roots\",\n\t\t\t\t);\n\t\t\t\tconst result = await buildHostFsRoots();\n\t\t\t\tthis.sendRpcResponse(request.requestId, result);\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tmachineId: request.params.machineId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_hostfs_roots_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\tthis.socket.on(\"rpc:hostfs:entries\", async (request) => {\n\t\t\ttry {\n\t\t\t\tconst { path: requestPath, machineId } = request.params;\n\t\t\t\tlogger.debug(\n\t\t\t\t\t{ requestId: request.requestId, machineId, path: requestPath },\n\t\t\t\t\t\"rpc_hostfs_entries\",\n\t\t\t\t);\n\t\t\t\tconst entries = await readDirectoryEntries(requestPath);\n\t\t\t\tthis.sendRpcResponse(request.requestId, {\n\t\t\t\t\tpath: requestPath,\n\t\t\t\t\tentries: filterVisibleEntries(entries),\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tmachineId: request.params.machineId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_hostfs_entries_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\tthis.socket.on(\"rpc:fs:entries\", async (request) => {\n\t\t\ttry {\n\t\t\t\tconst { sessionId, path: requestPath } = request.params;\n\t\t\t\tlogger.debug(\n\t\t\t\t\t{ requestId: request.requestId, sessionId, path: requestPath },\n\t\t\t\t\t\"rpc_fs_entries\",\n\t\t\t\t);\n\t\t\t\tconst record = sessionManager.getSession(sessionId);\n\t\t\t\tif (!record || !record.cwd) {\n\t\t\t\t\tthrow new Error(\"Session not found or no working directory\");\n\t\t\t\t}\n\t\t\t\tconst resolved = requestPath\n\t\t\t\t\t? path.isAbsolute(requestPath)\n\t\t\t\t\t\t? requestPath\n\t\t\t\t\t\t: path.join(record.cwd, requestPath)\n\t\t\t\t\t: record.cwd;\n\t\t\t\tconst entries = await readDirectoryEntries(resolved);\n\t\t\t\tthis.sendRpcResponse(request.requestId, { path: resolved, entries });\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_fs_entries_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\tthis.socket.on(\"rpc:fs:file\", async (request) => {\n\t\t\ttry {\n\t\t\t\tconst { sessionId, path: requestPath } = request.params;\n\t\t\t\tlogger.debug(\n\t\t\t\t\t{ requestId: request.requestId, sessionId, path: requestPath },\n\t\t\t\t\t\"rpc_fs_file\",\n\t\t\t\t);\n\t\t\t\tconst record = sessionManager.getSession(sessionId);\n\t\t\t\tif (!record || !record.cwd) {\n\t\t\t\t\tthrow new Error(\"Session not found or no working directory\");\n\t\t\t\t}\n\t\t\t\tconst resolved = path.isAbsolute(requestPath)\n\t\t\t\t\t? requestPath\n\t\t\t\t\t: path.join(record.cwd, requestPath);\n\t\t\t\tconst mimeType = resolveImageMimeType(resolved);\n\t\t\t\tif (mimeType) {\n\t\t\t\t\tconst buffer = await fs.readFile(resolved);\n\t\t\t\t\tconst preview: SessionFsFilePreview = {\n\t\t\t\t\t\tpath: resolved,\n\t\t\t\t\t\tpreviewType: \"image\",\n\t\t\t\t\t\tcontent: `data:${mimeType};base64,${buffer.toString(\"base64\")}`,\n\t\t\t\t\t\tmimeType,\n\t\t\t\t\t};\n\t\t\t\t\tthis.sendRpcResponse(request.requestId, preview);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst content = await fs.readFile(resolved, \"utf8\");\n\t\t\t\tconst preview: SessionFsFilePreview = {\n\t\t\t\t\tpath: resolved,\n\t\t\t\t\tpreviewType: \"code\",\n\t\t\t\t\tcontent,\n\t\t\t\t};\n\t\t\t\tthis.sendRpcResponse(request.requestId, preview);\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_fs_file_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\tthis.socket.on(\"rpc:fs:resources\", async (request) => {\n\t\t\ttry {\n\t\t\t\tconst { sessionId } = request.params;\n\t\t\t\tlogger.debug(\n\t\t\t\t\t{ requestId: request.requestId, sessionId },\n\t\t\t\t\t\"rpc_fs_resources\",\n\t\t\t\t);\n\t\t\t\tconst record = sessionManager.getSession(sessionId);\n\t\t\t\tif (!record || !record.cwd) {\n\t\t\t\t\tthrow new Error(\"Session not found or no working directory\");\n\t\t\t\t}\n\t\t\t\tconst entries = await this.listSessionResources(record.cwd);\n\t\t\t\tthis.sendRpcResponse(request.requestId, {\n\t\t\t\t\trootPath: record.cwd,\n\t\t\t\t\tentries,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_fs_resources_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\t// Session discovery - list sessions from ACP agent\n\t\tthis.socket.on(\"rpc:sessions:discover\", async (request) => {\n\t\t\ttry {\n\t\t\t\tconst { cwd, backendId, cursor } = request.params;\n\t\t\t\tlogger.info(\n\t\t\t\t\t{ requestId: request.requestId, cwd, backendId, cursor },\n\t\t\t\t\t\"rpc_sessions_discover\",\n\t\t\t\t);\n\t\t\t\tconst result = await sessionManager.discoverSessions({\n\t\t\t\t\tcwd,\n\t\t\t\t\tbackendId,\n\t\t\t\t\tcursor,\n\t\t\t\t});\n\t\t\t\tthis.sendRpcResponse(request.requestId, result);\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_sessions_discover_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\t// Load historical session from ACP agent\n\t\tthis.socket.on(\"rpc:session:load\", async (request) => {\n\t\t\ttry {\n\t\t\t\tconst { sessionId, cwd } = request.params;\n\t\t\t\tlogger.info(\n\t\t\t\t\t{ requestId: request.requestId, sessionId, cwd },\n\t\t\t\t\t\"rpc_session_load\",\n\t\t\t\t);\n\t\t\t\tconst session = await sessionManager.loadSession(sessionId, cwd);\n\t\t\t\tthis.sendRpcResponse(request.requestId, session);\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_session_load_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\t// Reload historical session from ACP agent\n\t\tthis.socket.on(\"rpc:session:reload\", async (request) => {\n\t\t\ttry {\n\t\t\t\tconst { sessionId, cwd } = request.params;\n\t\t\t\tlogger.info(\n\t\t\t\t\t{ requestId: request.requestId, sessionId, cwd },\n\t\t\t\t\t\"rpc_session_reload\",\n\t\t\t\t);\n\t\t\t\tconst session = await sessionManager.reloadSession(sessionId, cwd);\n\t\t\t\tthis.sendRpcResponse(request.requestId, session);\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_session_reload_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\t// Git status handler\n\t\tthis.socket.on(\"rpc:git:status\", async (request) => {\n\t\t\ttry {\n\t\t\t\tconst { sessionId } = request.params;\n\t\t\t\tlogger.debug(\n\t\t\t\t\t{ requestId: request.requestId, sessionId },\n\t\t\t\t\t\"rpc_git_status\",\n\t\t\t\t);\n\t\t\t\tconst record = sessionManager.getSession(sessionId);\n\t\t\t\tif (!record || !record.cwd) {\n\t\t\t\t\tthrow new Error(\"Session not found or no working directory\");\n\t\t\t\t}\n\n\t\t\t\tconst isRepo = await isGitRepo(record.cwd);\n\t\t\t\tif (!isRepo) {\n\t\t\t\t\tthis.sendRpcResponse(request.requestId, {\n\t\t\t\t\t\tisGitRepo: false,\n\t\t\t\t\t\tfiles: [],\n\t\t\t\t\t\tdirStatus: {},\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst [branch, files] = await Promise.all([\n\t\t\t\t\tgetGitBranch(record.cwd),\n\t\t\t\t\tgetGitStatus(record.cwd),\n\t\t\t\t]);\n\t\t\t\tconst dirStatus = aggregateDirStatus(files);\n\n\t\t\t\tthis.sendRpcResponse(request.requestId, {\n\t\t\t\t\tisGitRepo: true,\n\t\t\t\t\tbranch,\n\t\t\t\t\tfiles,\n\t\t\t\t\tdirStatus,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_git_status_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\n\t\t// Git file diff handler\n\t\tthis.socket.on(\"rpc:git:fileDiff\", async (request) => {\n\t\t\ttry {\n\t\t\t\tconst { sessionId, path: filePath } = request.params;\n\t\t\t\tlogger.debug(\n\t\t\t\t\t{ requestId: request.requestId, sessionId, path: filePath },\n\t\t\t\t\t\"rpc_git_file_diff\",\n\t\t\t\t);\n\t\t\t\tconst record = sessionManager.getSession(sessionId);\n\t\t\t\tif (!record || !record.cwd) {\n\t\t\t\t\tthrow new Error(\"Session not found or no working directory\");\n\t\t\t\t}\n\n\t\t\t\tconst isRepo = await isGitRepo(record.cwd);\n\t\t\t\tif (!isRepo) {\n\t\t\t\t\tthis.sendRpcResponse(request.requestId, {\n\t\t\t\t\t\tisGitRepo: false,\n\t\t\t\t\t\tpath: filePath,\n\t\t\t\t\t\taddedLines: [],\n\t\t\t\t\t\tmodifiedLines: [],\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst { addedLines, modifiedLines } = await getFileDiff(\n\t\t\t\t\trecord.cwd,\n\t\t\t\t\tfilePath,\n\t\t\t\t);\n\n\t\t\t\tthis.sendRpcResponse(request.requestId, {\n\t\t\t\t\tisGitRepo: true,\n\t\t\t\t\tpath: filePath,\n\t\t\t\t\taddedLines,\n\t\t\t\t\tmodifiedLines,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t{\n\t\t\t\t\t\terr: error,\n\t\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\t\tsessionId: request.params.sessionId,\n\t\t\t\t\t},\n\t\t\t\t\t\"rpc_git_file_diff_error\",\n\t\t\t\t);\n\t\t\t\tthis.sendRpcError(request.requestId, error);\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate setupSessionManagerListeners() {\n\t\tconst { sessionManager } = this.options;\n\n\t\tsessionManager.onSessionUpdate((notification) => {\n\t\t\tif (this.connected) {\n\t\t\t\t// Cast through unknown since SDK and shared SessionNotification types are structurally compatible\n\t\t\t\tthis.socket.emit(\n\t\t\t\t\t\"session:update\",\n\t\t\t\t\tnotification as unknown as import(\"@mobvibe/shared\").SessionNotification,\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\n\t\tsessionManager.onSessionError((payload) => {\n\t\t\tif (this.connected) {\n\t\t\t\tthis.socket.emit(\"session:error\", payload);\n\t\t\t}\n\t\t});\n\n\t\tsessionManager.onPermissionRequest((payload) => {\n\t\t\tif (this.connected) {\n\t\t\t\tthis.socket.emit(\"permission:request\", payload);\n\t\t\t}\n\t\t});\n\n\t\tsessionManager.onPermissionResult((payload) => {\n\t\t\tif (this.connected) {\n\t\t\t\tthis.socket.emit(\"permission:result\", payload);\n\t\t\t}\n\t\t});\n\n\t\tsessionManager.onTerminalOutput((event) => {\n\t\t\tif (this.connected) {\n\t\t\t\tthis.socket.emit(\"terminal:output\", event);\n\t\t\t}\n\t\t});\n\n\t\tsessionManager.onSessionsChanged((payload) => {\n\t\t\tif (this.connected) {\n\t\t\t\tlogger.info(\n\t\t\t\t\t{\n\t\t\t\t\t\tadded: payload.added.length,\n\t\t\t\t\t\tupdated: payload.updated.length,\n\t\t\t\t\t\tremoved: payload.removed.length,\n\t\t\t\t\t},\n\t\t\t\t\t\"sessions_changed_emit\",\n\t\t\t\t);\n\t\t\t\tthis.socket.emit(\"sessions:changed\", payload);\n\t\t\t}\n\t\t});\n\n\t\tsessionManager.onSessionAttached((payload) => {\n\t\t\tif (this.connected) {\n\t\t\t\tthis.socket.emit(\"session:attached\", payload);\n\t\t\t}\n\t\t});\n\n\t\tsessionManager.onSessionDetached((payload) => {\n\t\t\tif (this.connected) {\n\t\t\t\tthis.socket.emit(\"session:detached\", payload);\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate async listSessionResources(\n\t\trootPath: string,\n\t): Promise<SessionFsResourceEntry[]> {\n\t\tconst ig = await loadGitignore(rootPath);\n\t\tconst allFiles = await this.listAllFiles(rootPath, ig, rootPath, []);\n\t\treturn allFiles.map((filePath) => ({\n\t\t\tname: path.basename(filePath),\n\t\t\trelativePath: path.relative(rootPath, filePath),\n\t\t\tpath: filePath,\n\t\t}));\n\t}\n\n\tprivate async listAllFiles(\n\t\trootPath: string,\n\t\tig: Ignore,\n\t\tbaseDir: string,\n\t\tcollected: string[] = [],\n\t): Promise<string[]> {\n\t\tif (collected.length >= MAX_RESOURCE_FILES) {\n\t\t\treturn collected;\n\t\t}\n\t\tconst entries = await fs.readdir(rootPath, { withFileTypes: true });\n\t\tfor (const entry of entries) {\n\t\t\tif (collected.length >= MAX_RESOURCE_FILES) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tconst entryPath = path.join(rootPath, entry.name);\n\t\t\tconst relativePath = path.relative(baseDir, entryPath);\n\n\t\t\t// Check gitignore (add trailing slash for directories)\n\t\t\tconst checkPath = entry.isDirectory() ? `${relativePath}/` : relativePath;\n\t\t\tif (ig.ignores(checkPath)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tawait this.listAllFiles(entryPath, ig, baseDir, collected);\n\t\t\t} else if (entry.isFile()) {\n\t\t\t\tcollected.push(entryPath);\n\t\t\t}\n\t\t}\n\t\treturn collected;\n\t}\n\n\tprivate sendRpcResponse<T>(requestId: string, result: T) {\n\t\tconst response: RpcResponse<T> = { requestId, result };\n\t\tthis.socket.emit(\"rpc:response\", response);\n\t\tlogger.debug({ requestId }, \"rpc_response_sent\");\n\t}\n\n\tprivate sendRpcError(requestId: string, error: unknown) {\n\t\tconst message = error instanceof Error ? error.message : \"Unknown error\";\n\t\tconst detail = error instanceof Error ? error.stack : undefined;\n\t\tlogger.error(\n\t\t\t{\n\t\t\t\trequestId,\n\t\t\t\terr: error,\n\t\t\t\tmessage,\n\t\t\t\tdetail,\n\t\t\t},\n\t\t\t\"rpc_response_error_sent\",\n\t\t);\n\t\tconst response: RpcResponse<unknown> = {\n\t\t\trequestId,\n\t\t\terror: {\n\t\t\t\tcode: \"INTERNAL_ERROR\",\n\t\t\t\tmessage,\n\t\t\t\tretryable: true,\n\t\t\t\tscope: \"request\",\n\t\t\t\tdetail,\n\t\t\t},\n\t\t};\n\t\tthis.socket.emit(\"rpc:response\", response);\n\t}\n\n\tprivate register() {\n\t\tconst { config, sessionManager } = this.options;\n\t\tlogger.info({ machineId: config.machineId }, \"cli_register_emit\");\n\t\tthis.socket.emit(\"cli:register\", {\n\t\t\tmachineId: config.machineId,\n\t\t\thostname: config.hostname,\n\t\t\tversion: config.clientVersion,\n\t\t\tbackends: config.acpBackends.map((backend) => ({\n\t\t\t\tbackendId: backend.id,\n\t\t\t\tbackendLabel: backend.label,\n\t\t\t})),\n\t\t\tdefaultBackendId: config.defaultAcpBackendId,\n\t\t});\n\t\tlogger.info({ machineId: config.machineId }, \"cli_register_sessions_list\");\n\t\t// Send current sessions list\n\t\tthis.socket.emit(\"sessions:list\", sessionManager.listSessions());\n\t}\n\n\tprivate startHeartbeat() {\n\t\tthis.stopHeartbeat();\n\t\tthis.heartbeatInterval = setInterval(() => {\n\t\t\tif (this.connected) {\n\t\t\t\tthis.socket.emit(\"cli:heartbeat\");\n\t\t\t\tthis.socket.emit(\n\t\t\t\t\t\"sessions:list\",\n\t\t\t\t\tthis.options.sessionManager.listSessions(),\n\t\t\t\t);\n\t\t\t}\n\t\t}, 30000);\n\t}\n\n\tprivate stopHeartbeat() {\n\t\tif (this.heartbeatInterval) {\n\t\t\tclearInterval(this.heartbeatInterval);\n\t\t\tthis.heartbeatInterval = undefined;\n\t\t}\n\t}\n\n\tconnect() {\n\t\tthis.socket.connect();\n\t}\n\n\tdisconnect() {\n\t\tthis.stopHeartbeat();\n\t\tthis.socket.disconnect();\n\t}\n\n\tisConnected() {\n\t\treturn this.connected;\n\t}\n}\n","import { exec } from \"node:child_process\";\nimport path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport type { GitFileStatus } from \"@mobvibe/shared\";\n\nconst execAsync = promisify(exec);\nconst MAX_BUFFER = 10 * 1024 * 1024; // 10MB buffer for large repos\n\n/**\n * Check if a directory is a git repository.\n */\nexport async function isGitRepo(cwd: string): Promise<boolean> {\n\ttry {\n\t\tawait execAsync(\"git rev-parse --is-inside-work-tree\", {\n\t\t\tcwd,\n\t\t\tmaxBuffer: MAX_BUFFER,\n\t\t});\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Get the current git branch name.\n */\nexport async function getGitBranch(cwd: string): Promise<string | undefined> {\n\ttry {\n\t\tconst { stdout } = await execAsync(\"git branch --show-current\", {\n\t\t\tcwd,\n\t\t\tmaxBuffer: MAX_BUFFER,\n\t\t});\n\t\tconst branch = stdout.trim();\n\t\tif (branch) {\n\t\t\treturn branch;\n\t\t}\n\t\t// Detached HEAD state - try to get the short commit hash\n\t\tconst { stdout: hashOut } = await execAsync(\"git rev-parse --short HEAD\", {\n\t\t\tcwd,\n\t\t\tmaxBuffer: MAX_BUFFER,\n\t\t});\n\t\treturn hashOut.trim() || undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Parse git status --porcelain output to extract file statuses.\n */\nfunction parseGitStatus(\n\toutput: string,\n): Array<{ path: string; status: GitFileStatus }> {\n\tconst files: Array<{ path: string; status: GitFileStatus }> = [];\n\tconst lines = output.split(\"\\n\").filter((line) => line.length > 0);\n\n\tfor (const line of lines) {\n\t\t// Format: XY path or XY original -> renamed\n\t\tconst indexStatus = line[0];\n\t\tconst workTreeStatus = line[1];\n\t\tconst filePath = line.slice(3).split(\" -> \").pop()?.trim();\n\n\t\tif (!filePath) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Determine the most significant status\n\t\tlet status: GitFileStatus;\n\t\tif (indexStatus === \"?\" || workTreeStatus === \"?\") {\n\t\t\tstatus = \"?\";\n\t\t} else if (indexStatus === \"!\" || workTreeStatus === \"!\") {\n\t\t\tstatus = \"!\";\n\t\t} else if (indexStatus === \"A\" || workTreeStatus === \"A\") {\n\t\t\tstatus = \"A\";\n\t\t} else if (indexStatus === \"D\" || workTreeStatus === \"D\") {\n\t\t\tstatus = \"D\";\n\t\t} else if (indexStatus === \"R\" || workTreeStatus === \"R\") {\n\t\t\tstatus = \"R\";\n\t\t} else if (indexStatus === \"C\" || workTreeStatus === \"C\") {\n\t\t\tstatus = \"C\";\n\t\t} else if (indexStatus === \"U\" || workTreeStatus === \"U\") {\n\t\t\tstatus = \"U\";\n\t\t} else if (\n\t\t\tindexStatus === \"M\" ||\n\t\t\tworkTreeStatus === \"M\" ||\n\t\t\tindexStatus !== \" \" ||\n\t\t\tworkTreeStatus !== \" \"\n\t\t) {\n\t\t\tstatus = \"M\";\n\t\t} else {\n\t\t\tcontinue;\n\t\t}\n\n\t\tfiles.push({ path: filePath, status });\n\t}\n\n\treturn files;\n}\n\n/**\n * Get git status for all files in the repository.\n */\nexport async function getGitStatus(\n\tcwd: string,\n): Promise<Array<{ path: string; status: GitFileStatus }>> {\n\ttry {\n\t\tconst { stdout } = await execAsync(\"git status --porcelain=v1\", {\n\t\t\tcwd,\n\t\t\tmaxBuffer: MAX_BUFFER,\n\t\t});\n\t\treturn parseGitStatus(stdout);\n\t} catch {\n\t\treturn [];\n\t}\n}\n\n/**\n * Aggregate file statuses into directory statuses.\n * A directory gets the \"highest priority\" status of its children.\n */\nexport function aggregateDirStatus(\n\tfiles: Array<{ path: string; status: GitFileStatus }>,\n): Record<string, GitFileStatus> {\n\tconst dirStatus: Record<string, GitFileStatus> = {};\n\n\t// Priority order: A > D > M > R > C > U > ? > !\n\tconst statusPriority: Record<GitFileStatus, number> = {\n\t\tA: 7,\n\t\tD: 6,\n\t\tM: 5,\n\t\tR: 4,\n\t\tC: 3,\n\t\tU: 2,\n\t\t\"?\": 1,\n\t\t\"!\": 0,\n\t};\n\n\tfor (const file of files) {\n\t\t// Build all parent directories\n\t\tconst parts = file.path.split(\"/\");\n\t\tlet currentPath = \"\";\n\n\t\tfor (let i = 0; i < parts.length - 1; i++) {\n\t\t\tcurrentPath = currentPath ? `${currentPath}/${parts[i]}` : parts[i];\n\t\t\tconst existing = dirStatus[currentPath];\n\n\t\t\tif (!existing || statusPriority[file.status] > statusPriority[existing]) {\n\t\t\t\tdirStatus[currentPath] = file.status;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn dirStatus;\n}\n\n/**\n * Parse git diff output to extract added, modified, and deleted line numbers.\n * Deleted lines are recorded at the position where the deletion occurred in the new file.\n */\nfunction parseDiffOutput(diffOutput: string): {\n\taddedLines: number[];\n\tmodifiedLines: number[];\n\tdeletedLines: number[];\n} {\n\tconst addedLines: number[] = [];\n\tconst modifiedLines: number[] = [];\n\tconst deletedLines: number[] = [];\n\n\tconst lines = diffOutput.split(\"\\n\");\n\tlet currentLine = 0;\n\tlet inHunk = false;\n\tlet pendingDeletionLine = 0;\n\n\tfor (const line of lines) {\n\t\t// Parse hunk header: @@ -start,count +start,count @@\n\t\tconst hunkMatch = line.match(/^@@\\s+-\\d+(?:,\\d+)?\\s+\\+(\\d+)(?:,\\d+)?\\s+@@/);\n\t\tif (hunkMatch) {\n\t\t\tcurrentLine = Number.parseInt(hunkMatch[1], 10);\n\t\t\tinHunk = true;\n\t\t\tpendingDeletionLine = 0;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!inHunk) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (line.startsWith(\"+\") && !line.startsWith(\"+++\")) {\n\t\t\t// Added line\n\t\t\taddedLines.push(currentLine);\n\t\t\tcurrentLine++;\n\t\t\tpendingDeletionLine = 0;\n\t\t} else if (line.startsWith(\"-\") && !line.startsWith(\"---\")) {\n\t\t\t// Deleted line - record the current new file position\n\t\t\t// If we're at a deletion, mark the position where content was removed\n\t\t\tif (pendingDeletionLine === 0) {\n\t\t\t\tpendingDeletionLine = currentLine;\n\t\t\t}\n\t\t\t// Record deletion at the current line position (or previous line if at start)\n\t\t\tconst deletionPos = Math.max(1, currentLine);\n\t\t\tif (!deletedLines.includes(deletionPos)) {\n\t\t\t\tdeletedLines.push(deletionPos);\n\t\t\t}\n\t\t} else if (!line.startsWith(\"\\\\\")) {\n\t\t\t// Context line or empty line\n\t\t\tcurrentLine++;\n\t\t\tpendingDeletionLine = 0;\n\t\t}\n\t}\n\n\treturn { addedLines, modifiedLines, deletedLines };\n}\n\n/**\n * Get git diff for a specific file.\n */\nexport async function getFileDiff(\n\tcwd: string,\n\tfilePath: string,\n): Promise<{\n\taddedLines: number[];\n\tmodifiedLines: number[];\n\tdeletedLines: number[];\n}> {\n\ttry {\n\t\t// Get diff against HEAD (includes both staged and unstaged changes)\n\t\tconst relativePath = path.isAbsolute(filePath)\n\t\t\t? path.relative(cwd, filePath)\n\t\t\t: filePath;\n\n\t\tconst { stdout } = await execAsync(`git diff HEAD -- \"${relativePath}\"`, {\n\t\t\tcwd,\n\t\t\tmaxBuffer: MAX_BUFFER,\n\t\t});\n\n\t\tif (!stdout.trim()) {\n\t\t\t// No diff - file might be untracked, check status\n\t\t\tconst { stdout: statusOut } = await execAsync(\n\t\t\t\t`git status --porcelain=v1 -- \"${relativePath}\"`,\n\t\t\t\t{ cwd, maxBuffer: MAX_BUFFER },\n\t\t\t);\n\n\t\t\tif (statusOut.startsWith(\"?\") || statusOut.startsWith(\"A\")) {\n\t\t\t\t// Untracked or newly added file - all lines are \"added\"\n\t\t\t\tconst { stdout: wcOut } = await execAsync(`wc -l < \"${relativePath}\"`, {\n\t\t\t\t\tcwd,\n\t\t\t\t\tmaxBuffer: MAX_BUFFER,\n\t\t\t\t});\n\t\t\t\tconst lineCount = Number.parseInt(wcOut.trim(), 10) || 0;\n\t\t\t\treturn {\n\t\t\t\t\taddedLines: Array.from({ length: lineCount }, (_, i) => i + 1),\n\t\t\t\t\tmodifiedLines: [],\n\t\t\t\t\tdeletedLines: [],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn { addedLines: [], modifiedLines: [], deletedLines: [] };\n\t\t}\n\n\t\treturn parseDiffOutput(stdout);\n\t} catch {\n\t\treturn { addedLines: [], modifiedLines: [], deletedLines: [] };\n\t}\n}\n"],"mappings":"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","names":["os","path","fs","path","os","path","spawn","fs","path","randomUUID","EventEmitter","fs","fs","EventEmitter","randomUUID","EventEmitter","fs","path","path","path","fs","EventEmitter","preview","fs","path","spawn"]}