@tencent-ai/cloud-agent-sdk 0.2.15 → 0.3.0
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.cjs +1257 -20082
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +635 -6085
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +635 -6085
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1225 -9368
- package/dist/index.mjs.map +1 -1
- package/dist/tencent-ai-cloud-agent-sdk-0.3.0.tgz +0 -0
- package/package.json +32 -66
- package/dist/e2b-filesystem-4-LU6-jg.cjs +0 -168
- package/dist/e2b-filesystem-4-LU6-jg.cjs.map +0 -1
- package/dist/e2b-filesystem-BNmEfpoW.mjs +0 -162
- package/dist/e2b-filesystem-BNmEfpoW.mjs.map +0 -1
- package/dist/e2b-filesystem-B_WoA22S.cjs +0 -252
- package/dist/e2b-filesystem-B_WoA22S.cjs.map +0 -1
- package/dist/e2b-filesystem-Cac-bpRR.cjs +0 -3
- package/dist/e2b-filesystem-DM_jsT05.mjs +0 -234
- package/dist/e2b-filesystem-DM_jsT05.mjs.map +0 -1
- package/dist/e2b-filesystem-DWj9UkV8.mjs +0 -3
- package/dist/e2b-filesystem-DcVVT_tP.cjs +0 -4
- package/dist/e2b-filesystem-UheQECjB.mjs +0 -3
- package/dist/legacy/index.cjs +0 -24205
- package/dist/legacy/index.cjs.map +0 -1
- package/dist/legacy/index.d.cts +0 -6605
- package/dist/legacy/index.d.cts.map +0 -1
- package/dist/legacy/index.d.mts +0 -6605
- package/dist/legacy/index.d.mts.map +0 -1
- package/dist/legacy/index.mjs +0 -13481
- package/dist/legacy/index.mjs.map +0 -1
- package/dist/tencent-ai-cloud-agent-sdk-0.2.15.tgz +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["z","EventEmitter","this","this","this","EventEmitter","this","ClientSideConnection","PROTOCOL_VERSION","this","AxiosError","utils","prototype","Stream","util","util","Stream","util","http","https","parseUrl","FormData","utils","toFormData","PlatformFormData","AxiosError","encode","toFormData","utils","AxiosURLSearchParams","utils","platform","toFormData","platform","utils","utils","utils","transitionalDefaults","formDataToJSON","toFormData","AxiosError","platform","utils","utils","AxiosHeaders","parseHeaders","defaults","AxiosHeaders","isCancel","CanceledError","AxiosError","utils","AxiosError","tty","util","url","http","https","exports","VERSION","platform","AxiosError","utils","platform","utils","this","readBlob","Readable","utils","speedometer","throttle","utils","utils","followRedirects","platform","callbackify","EventEmitter","CanceledError","AxiosError","AxiosHeaders","VERSION","formDataToStream","readBlob","AxiosTransformStream","ZlibHeaderTransformStream","transitionalDefaults","platform","platform","AxiosHeaders","mergeConfig","utils","mergeConfig","AxiosHeaders","utils","platform","isURLSameOrigin","cookies","resolveConfig","AxiosHeaders","AxiosError","transitionalDefaults","utils","CanceledError","platform","AxiosError","CanceledError","utils","platform","utils","AxiosError","resolveConfig","composeSignals","AxiosHeaders","httpAdapter","xhrAdapter","fetchAdapter","utils","AxiosError","CanceledError","AxiosHeaders","adapters","defaults","isCancel","validators","VERSION","AxiosError","validator","Axios","InterceptorManager","this","mergeConfig","utils","AxiosHeaders","CancelToken","CanceledError","spread","isAxiosError","utils","HttpStatusCode","Axios","mergeConfig","defaults","CanceledError","CancelToken","isCancel","VERSION","toFormData","AxiosError","spread","isAxiosError","AxiosHeaders","formDataToJSON","utils","adapters","HttpStatusCode","axios","axios","this","httpService","httpService","httpService","this","httpService","this","this","this","this","this","httpService","this","httpService","this","httpService","this"],"sources":["../../src/legacy/adapter.ts","../../../agent-provider/src/common/_legacy/tool-schemas.ts","../../../agent-provider/src/common/_legacy/MockAgentProvider.ts","../../../agent-client-protocol/src/common/types.ts","../../../agent-client-protocol/src/common/transport/streamable-http.ts","../../../agent-client-protocol/src/common/client/artifacts.ts","../../../agent-client-protocol/src/common/client/constants.ts","../../../agent-client-protocol/src/common/client/errors.ts","../../../agent-client-protocol/src/common/client/events.ts","../../../agent-client-protocol/src/common/client/extensions.ts","../../../agent-client-protocol/src/common/client/permissions.ts","../../../agent-client-protocol/src/common/client/questions.ts","../../../agent-client-protocol/src/common/client/client.ts","../../../agent-provider/src/common/providers/cloud-agent-provider/cloud-connection.ts","../../../agent-provider/node_modules/axios/lib/helpers/bind.js","../../../agent-provider/node_modules/axios/lib/utils.js","../../../agent-provider/node_modules/axios/lib/core/AxiosError.js","../../../../node_modules/delayed-stream/lib/delayed_stream.js","../../../../node_modules/combined-stream/lib/combined_stream.js","../../../../node_modules/mime-types/node_modules/mime-db/db.json","../../../../node_modules/mime-types/node_modules/mime-db/index.js","../../../../node_modules/mime-types/index.js","../../../../node_modules/asynckit/lib/defer.js","../../../../node_modules/asynckit/lib/async.js","../../../../node_modules/asynckit/lib/abort.js","../../../../node_modules/asynckit/lib/iterate.js","../../../../node_modules/asynckit/lib/state.js","../../../../node_modules/asynckit/lib/terminator.js","../../../../node_modules/asynckit/parallel.js","../../../../node_modules/asynckit/serialOrdered.js","../../../../node_modules/asynckit/serial.js","../../../../node_modules/asynckit/index.js","../../../../node_modules/es-object-atoms/index.js","../../../../node_modules/es-errors/index.js","../../../../node_modules/es-errors/eval.js","../../../../node_modules/es-errors/range.js","../../../../node_modules/es-errors/ref.js","../../../../node_modules/es-errors/syntax.js","../../../../node_modules/es-errors/type.js","../../../../node_modules/es-errors/uri.js","../../../../node_modules/math-intrinsics/abs.js","../../../../node_modules/math-intrinsics/floor.js","../../../../node_modules/math-intrinsics/max.js","../../../../node_modules/math-intrinsics/min.js","../../../../node_modules/math-intrinsics/pow.js","../../../../node_modules/math-intrinsics/round.js","../../../../node_modules/math-intrinsics/isNaN.js","../../../../node_modules/math-intrinsics/sign.js","../../../../node_modules/gopd/gOPD.js","../../../../node_modules/gopd/index.js","../../../../node_modules/es-define-property/index.js","../../../../node_modules/has-symbols/shams.js","../../../../node_modules/has-symbols/index.js","../../../../node_modules/get-proto/Reflect.getPrototypeOf.js","../../../../node_modules/get-proto/Object.getPrototypeOf.js","../../../../node_modules/function-bind/implementation.js","../../../../node_modules/function-bind/index.js","../../../../node_modules/call-bind-apply-helpers/functionCall.js","../../../../node_modules/call-bind-apply-helpers/functionApply.js","../../../../node_modules/call-bind-apply-helpers/reflectApply.js","../../../../node_modules/call-bind-apply-helpers/actualApply.js","../../../../node_modules/call-bind-apply-helpers/index.js","../../../../node_modules/dunder-proto/get.js","../../../../node_modules/get-proto/index.js","../../../../node_modules/hasown/index.js","../../../../node_modules/get-intrinsic/index.js","../../../../node_modules/has-tostringtag/shams.js","../../../../node_modules/es-set-tostringtag/index.js","../../../../node_modules/form-data/lib/populate.js","../../../../node_modules/form-data/lib/form_data.js","../../../agent-provider/node_modules/axios/lib/platform/node/classes/FormData.js","../../../agent-provider/node_modules/axios/lib/helpers/toFormData.js","../../../agent-provider/node_modules/axios/lib/helpers/AxiosURLSearchParams.js","../../../agent-provider/node_modules/axios/lib/helpers/buildURL.js","../../../agent-provider/node_modules/axios/lib/core/InterceptorManager.js","../../../agent-provider/node_modules/axios/lib/defaults/transitional.js","../../../agent-provider/node_modules/axios/lib/platform/node/classes/URLSearchParams.js","../../../agent-provider/node_modules/axios/lib/platform/node/index.js","../../../agent-provider/node_modules/axios/lib/platform/common/utils.js","../../../agent-provider/node_modules/axios/lib/platform/index.js","../../../agent-provider/node_modules/axios/lib/helpers/toURLEncodedForm.js","../../../agent-provider/node_modules/axios/lib/helpers/formDataToJSON.js","../../../agent-provider/node_modules/axios/lib/defaults/index.js","../../../agent-provider/node_modules/axios/lib/helpers/parseHeaders.js","../../../agent-provider/node_modules/axios/lib/core/AxiosHeaders.js","../../../agent-provider/node_modules/axios/lib/core/transformData.js","../../../agent-provider/node_modules/axios/lib/cancel/isCancel.js","../../../agent-provider/node_modules/axios/lib/cancel/CanceledError.js","../../../agent-provider/node_modules/axios/lib/core/settle.js","../../../agent-provider/node_modules/axios/lib/helpers/isAbsoluteURL.js","../../../agent-provider/node_modules/axios/lib/helpers/combineURLs.js","../../../agent-provider/node_modules/axios/lib/core/buildFullPath.js","../../../../node_modules/proxy-from-env/index.js","../../../../node_modules/ms/index.js","../../../../node_modules/debug/src/common.js","../../../../node_modules/debug/src/browser.js","../../../../node_modules/has-flag/index.js","../../../../node_modules/supports-color/index.js","../../../../node_modules/debug/src/node.js","../../../../node_modules/debug/src/index.js","../../../../node_modules/follow-redirects/debug.js","../../../../node_modules/follow-redirects/index.js","../../../agent-provider/node_modules/axios/lib/env/data.js","../../../agent-provider/node_modules/axios/lib/helpers/parseProtocol.js","../../../agent-provider/node_modules/axios/lib/helpers/fromDataURI.js","../../../agent-provider/node_modules/axios/lib/helpers/AxiosTransformStream.js","../../../agent-provider/node_modules/axios/lib/helpers/readBlob.js","../../../agent-provider/node_modules/axios/lib/helpers/formDataToStream.js","../../../agent-provider/node_modules/axios/lib/helpers/ZlibHeaderTransformStream.js","../../../agent-provider/node_modules/axios/lib/helpers/callbackify.js","../../../agent-provider/node_modules/axios/lib/helpers/speedometer.js","../../../agent-provider/node_modules/axios/lib/helpers/throttle.js","../../../agent-provider/node_modules/axios/lib/helpers/progressEventReducer.js","../../../agent-provider/node_modules/axios/lib/adapters/http.js","../../../agent-provider/node_modules/axios/lib/helpers/isURLSameOrigin.js","../../../agent-provider/node_modules/axios/lib/helpers/cookies.js","../../../agent-provider/node_modules/axios/lib/core/mergeConfig.js","../../../agent-provider/node_modules/axios/lib/helpers/resolveConfig.js","../../../agent-provider/node_modules/axios/lib/adapters/xhr.js","../../../agent-provider/node_modules/axios/lib/helpers/composeSignals.js","../../../agent-provider/node_modules/axios/lib/helpers/trackStream.js","../../../agent-provider/node_modules/axios/lib/adapters/fetch.js","../../../agent-provider/node_modules/axios/lib/adapters/adapters.js","../../../agent-provider/node_modules/axios/lib/core/dispatchRequest.js","../../../agent-provider/node_modules/axios/lib/helpers/validator.js","../../../agent-provider/node_modules/axios/lib/core/Axios.js","../../../agent-provider/node_modules/axios/lib/cancel/CancelToken.js","../../../agent-provider/node_modules/axios/lib/helpers/spread.js","../../../agent-provider/node_modules/axios/lib/helpers/isAxiosError.js","../../../agent-provider/node_modules/axios/lib/helpers/HttpStatusCode.js","../../../agent-provider/node_modules/axios/lib/axios.js","../../../agent-provider/node_modules/axios/index.js","../../../agent-provider/src/http/http-service.ts","../../../agent-provider/src/http/index.ts","../../../agent-provider/src/account/account-service.ts","../../../agent-provider/src/common/utils/lru-cache.ts","../../../agent-provider/src/common/utils/concurrency.ts","../../../agent-provider/src/common/providers/cloud-agent-provider/cos-upload-service.ts","../../../agent-provider/src/common/providers/cloud-agent-provider/cloud-provider.ts","../../../agent-provider/src/common/providers/local-agent-provider/local-connection.ts","../../../agent-provider/src/common/types.ts","../../../agent-provider/src/common/client/session.ts","../../../agent-provider/src/common/client/session-manager.ts","../../../agent-provider/src/common/client/client.ts","../../../agent-provider/src/common/client/types.ts","../../../agent-provider/src/backend/types.ts","../../../agent-provider/src/backend/service/oauth-repository-service.ts","../../../agent-provider/src/backend/backend-provider.ts","../../../agent-provider/src/backend/ipc-backend-provider.ts","../../src/legacy/http-service.ts","../../../agent-provider/src/miniprogram/transport.ts","../../../agent-provider/src/miniprogram/e2b-adapter.ts","../../src/legacy/cloud-provider.ts","../../src/legacy/cloud-connection.ts","../../src/legacy/session.ts"],"sourcesContent":["/**\n * Legacy Adapter Layer\n *\n * 提供 polyfill 和适配工具,确保在小程序等低版本 JS 运行时中兼容。\n *\n * 降级处理清单:\n * - Symbol.dispose polyfill → 防止小程序中 Symbol.dispose 未定义导致 crash\n * - Optional chaining 辅助函数 → 替代 ?. 语法\n * - Nullish coalescing 辅助函数 → 替代 ?? 语法\n * - Promise.allSettled polyfill → 部分旧环境不支持\n * - AsyncIterable → 回调式 API 转换工具\n * - Map/Set 安全包装 → 确保基础 API 可用\n */\n\n// ============================================\n// Symbol.dispose Polyfill\n// [降级] Symbol.dispose 在 ES2022+ 引入,小程序环境通常不支持\n// ============================================\n\n/**\n * 确保 Symbol.dispose 可用\n * 如果运行时不支持 Symbol.dispose,创建一个替代 Symbol\n */\nexport function ensureSymbolDispose(): void {\n if (typeof Symbol !== 'undefined' && !Symbol.dispose) {\n // [降级] Symbol.dispose → 使用 Symbol.for 创建全局唯一标识\n (Symbol as any).dispose = Symbol.for('Symbol.dispose');\n }\n}\n\n// 立即执行 polyfill\nensureSymbolDispose();\n\n// ============================================\n// Optional Chaining 辅助函数\n// [降级] ?. → 传统属性访问\n// ============================================\n\n/**\n * 安全属性访问,替代可选链 (?.) 语法\n *\n * @example\n * // 原始: obj?.foo?.bar\n * // 降级: safeGet(obj, 'foo', 'bar')\n *\n * @param obj - 目标对象\n * @param keys - 属性路径\n * @returns 属性值或 undefined\n */\nexport function safeGet(obj: any, ...keys: string[]): any {\n let current = obj;\n for (let i = 0; i < keys.length; i++) {\n if (current == null) {\n return undefined;\n }\n current = current[keys[i]];\n }\n return current;\n}\n\n/**\n * 安全方法调用,替代可选链方法调用 (obj?.method())\n *\n * @example\n * // 原始: obj?.method(arg1, arg2)\n * // 降级: safeCall(obj, 'method', arg1, arg2)\n *\n * @param obj - 目标对象\n * @param method - 方法名\n * @param args - 方法参数\n * @returns 方法返回值或 undefined\n */\nexport function safeCall(obj: any, method: string, ...args: any[]): any {\n if (obj != null && typeof obj[method] === 'function') {\n return obj[method].apply(obj, args);\n }\n return undefined;\n}\n\n// ============================================\n// Nullish Coalescing 辅助函数\n// [降级] ?? → 使用显式 null/undefined 检查\n// ============================================\n\n/**\n * 空值合并,替代 ?? 运算符\n * 注意:与 || 不同,仅在值为 null 或 undefined 时使用默认值\n * 空字符串 ''、数字 0、false 不会触发默认值\n *\n * @example\n * // 原始: value ?? defaultValue\n * // 降级: nullish(value, defaultValue)\n */\nexport function nullish<T>(value: T | null | undefined, defaultValue: T): T {\n if (value === null || value === undefined) {\n return defaultValue;\n }\n return value;\n}\n\n// ============================================\n// Promise.allSettled Polyfill\n// [降级] Promise.allSettled 在部分旧环境中不可用\n// ============================================\n\n/**\n * Promise.allSettled polyfill\n * 等待所有 Promise 完成(无论成功或失败)\n *\n * @param promises - Promise 数组\n * @returns PromiseSettledResult 数组\n */\nexport function allSettled<T>(\n promises: Array<Promise<T>>\n): Promise<Array<PromiseSettledResult<T>>> {\n // [降级] 优先使用原生实现\n if (typeof Promise.allSettled === 'function') {\n return Promise.allSettled(promises);\n }\n\n // [降级] Polyfill 实现\n return Promise.all(\n promises.map(function (promise) {\n return Promise.resolve(promise).then(\n function (value): PromiseSettledResult<T> {\n return { status: 'fulfilled', value: value };\n },\n function (reason): PromiseSettledResult<T> {\n return { status: 'rejected', reason: reason };\n }\n );\n })\n );\n}\n\n// ============================================\n// AsyncIterable → Callback 转换\n// [降级] async generator → 回调模式\n// ============================================\n\n/**\n * 将 AsyncIterable 转换为回调模式\n * 用于不支持 for-await-of 的环境\n *\n * @example\n * // 原始:\n * // for await (const update of session.prompts.stream(params)) {\n * // handleUpdate(update);\n * // }\n *\n * // 降级:\n * // consumeAsyncIterable(session.prompts.stream(params), handleUpdate)\n * // .then(() => console.log('done'))\n * // .catch(err => console.error(err));\n *\n * @param iterable - AsyncIterable 源\n * @param callback - 每次迭代的回调函数\n * @returns Promise,在迭代完成后 resolve\n */\nexport function consumeAsyncIterable<T>(\n iterable: AsyncIterable<T>,\n callback: (value: T) => void | Promise<void>\n): Promise<void> {\n var iterator = iterable[Symbol.asyncIterator]();\n\n function step(): Promise<void> {\n return iterator.next().then(function (result) {\n if (result.done) {\n return;\n }\n var callbackResult = callback(result.value);\n if (callbackResult && typeof (callbackResult as any).then === 'function') {\n return (callbackResult as Promise<void>).then(step);\n }\n return step();\n });\n }\n\n return step();\n}\n\n// ============================================\n// Map/Set 安全性检查\n// [降级] 验证 Map/Set 在当前环境中可用\n// ============================================\n\n/**\n * 检查当前环境是否支持 Map 和 Set\n * 小程序环境通常支持,但某些极老版本可能不完整\n */\nexport function checkMapSetSupport(): {\n hasMap: boolean;\n hasSet: boolean;\n hasWeakMap: boolean;\n hasWeakSet: boolean;\n} {\n return {\n hasMap: typeof Map !== 'undefined' && typeof Map.prototype.entries === 'function',\n hasSet: typeof Set !== 'undefined' && typeof Set.prototype.entries === 'function',\n hasWeakMap: typeof WeakMap !== 'undefined',\n hasWeakSet: typeof WeakSet !== 'undefined',\n };\n}\n\n// ============================================\n// Object.entries / Object.fromEntries Polyfill\n// [降级] 部分旧环境可能不支持\n// ============================================\n\n/**\n * Object.entries polyfill\n */\nexport function objectEntries<T>(obj: Record<string, T>): Array<[string, T]> {\n if (typeof Object.entries === 'function') {\n return Object.entries(obj) as Array<[string, T]>;\n }\n // [降级] 手动实现\n var result: Array<[string, T]> = [];\n for (var key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n result.push([key, obj[key]]);\n }\n }\n return result;\n}\n\n/**\n * Object.fromEntries polyfill\n */\nexport function objectFromEntries<T>(entries: Array<[string, T]>): Record<string, T> {\n if (typeof Object.fromEntries === 'function') {\n return Object.fromEntries(entries) as Record<string, T>;\n }\n // [降级] 手动实现\n var result: Record<string, T> = {};\n for (var i = 0; i < entries.length; i++) {\n result[entries[i][0]] = entries[i][1];\n }\n return result;\n}\n\n// ============================================\n// Array.prototype.flat / flatMap Polyfill\n// [降级] ES2019 方法,部分旧环境不支持\n// ============================================\n\n/**\n * Array.flat polyfill (depth=1)\n */\nexport function arrayFlat<T>(arr: Array<T | T[]>): T[] {\n if (typeof Array.prototype.flat === 'function') {\n return (arr as any).flat();\n }\n // [降级] 手动实现\n var result: T[] = [];\n for (var i = 0; i < arr.length; i++) {\n var item = arr[i];\n if (Array.isArray(item)) {\n for (var j = 0; j < item.length; j++) {\n result.push(item[j]);\n }\n } else {\n result.push(item);\n }\n }\n return result;\n}\n\n// ============================================\n// 环境兼容性检测\n// ============================================\n\n/**\n * 运行环境兼容性检测报告\n * 检查当前运行时是否支持 SDK 需要的所有功能\n */\nexport function checkCompatibility(): {\n compatible: boolean;\n issues: string[];\n} {\n var issues: string[] = [];\n\n // 检查 Promise\n if (typeof Promise === 'undefined') {\n issues.push('Promise 不可用,需要 polyfill');\n }\n\n // 检查 Map/Set\n var mapSet = checkMapSetSupport();\n if (!mapSet.hasMap) {\n issues.push('Map 不可用或不完整');\n }\n if (!mapSet.hasSet) {\n issues.push('Set 不可用或不完整');\n }\n\n // 检查 Symbol\n if (typeof Symbol === 'undefined') {\n issues.push('Symbol 不可用,需要 polyfill');\n }\n\n // 检查 Symbol.asyncIterator\n if (typeof Symbol !== 'undefined' && !Symbol.asyncIterator) {\n issues.push('Symbol.asyncIterator 不可用,async iteration 需要 polyfill');\n }\n\n // 检查 async/await 支持 (通过检查 Promise)\n if (typeof Promise === 'undefined' || typeof Promise.resolve !== 'function') {\n issues.push('Promise.resolve 不可用');\n }\n\n return {\n compatible: issues.length === 0,\n issues: issues,\n };\n}\n","/**\n * ACP Tool Input/Output Schema 定义\n *\n * 用于约束 ACP 协议中 ToolCallUpdate 的 rawInput 和 rawOutput 字段\n * 基于 getCraftToolProvider 使用的工具定义\n */\n\nimport { z } from 'zod';\n\n// ============================================================================\n// 基础类型\n// ============================================================================\n\n/**\n * 工具类型标识\n */\nexport type ToolName =\n | 'list_dir'\n | 'search_file'\n | 'read_file'\n | 'read_lints'\n | 'rag_search'\n | 'mcp_get_tool_description'\n | 'mcp_call_tool'\n | 'fetch_mcp_resource'\n | 'update_memory'\n | 'search_content'\n | 'write_to_file'\n | 'replace_in_file'\n | 'delete_file'\n | 'execute_command'\n | 'preview_url'\n | 'ask_followup_question'\n | 'invoke_integration'\n | 'call_integration'\n | 'search_integration_tool'\n | 'supabase_get_logs'\n | 'supabase_execute_sql'\n | 'supabase_apply_migration'\n | 'supabase_list_migration'\n | 'supabase_list_tables'\n | 'cloud_studio_fetch_log'\n | 'cloud_studio_execute_command'\n | 'cloud_studio_deploy_sandbox'\n | 'web_fetch'\n | 'use_skill'\n | 'web_search'\n | 'task'\n | 'codebase_search'\n | 'lsp'\n | 'spec_create'\n | 'spec_update';\n\n// ============================================================================\n// 工具输入类型定义\n// ============================================================================\n\nexport interface ListDirInput {\n target_directory: string;\n ignore_globs?: string;\n}\n\nexport interface SearchFileInput {\n target_directory: string;\n pattern: string;\n recursive: boolean;\n caseSensitive: boolean;\n}\n\nexport interface ReadFileInput {\n filePath: string;\n offset?: number;\n limit?: number;\n}\n\nexport interface ReadLintsInput {\n paths?: string;\n}\n\nexport interface RagSearchInput {\n queryString: string;\n knowledgeBaseNames: string;\n}\n\nexport interface McpGetToolDescriptionInput {\n toolRequests: string;\n}\n\nexport interface McpCallToolInput {\n serverName: string;\n toolName: string;\n arguments: string;\n maxOutputLength?: number;\n}\n\nexport interface FetchMcpResourceInput {\n server: string;\n uri: string;\n arguments?: Record<string, unknown>;\n downloadPath?: string;\n}\n\nexport interface UpdateMemoryInput {\n action?: 'create' | 'update' | 'delete';\n existing_knowledge_id?: string;\n knowledge_to_store?: string;\n title?: string;\n}\n\nexport interface SearchContentInput {\n pattern: string;\n path: string;\n glob?: string;\n type?: string;\n multiline?: boolean;\n contextBefore?: number;\n contextAfter?: number;\n contextAround?: number;\n outputMode?: string;\n caseSensitive?: boolean;\n headLimit?: number;\n /** @deprecated use path */\n directory?: string;\n /** @deprecated use glob */\n fileTypes?: string;\n}\n\nexport interface WriteToFileInput {\n filePath: string;\n content: string;\n}\n\nexport interface ReplaceInFileInput {\n filePath: string;\n old_str: string;\n new_str: string;\n}\n\nexport interface DeleteFileInput {\n target_file: string;\n explanation?: string;\n}\n\nexport interface ExecuteCommandInput {\n command: string;\n requires_approval: boolean;\n}\n\nexport interface PreviewUrlInput {\n url: string;\n}\n\nexport interface AskFollowupQuestionInput {\n questions: Array<{\n question: string;\n header: string;\n options: Array<{\n label: string;\n description: string;\n }>;\n multiSelect?: boolean;\n }>;\n}\n\nexport interface InvokeIntegrationInput {\n [key: string]: unknown;\n}\n\nexport interface CallIntegrationInput {\n [key: string]: unknown;\n}\n\nexport interface SearchIntegrationToolInput {\n [key: string]: unknown;\n}\n\nexport interface SupabaseGetLogsInput {\n [key: string]: unknown;\n}\n\nexport interface SupabaseExecuteSqlInput {\n [key: string]: unknown;\n}\n\nexport interface SupabaseApplyMigrationInput {\n [key: string]: unknown;\n}\n\nexport interface SupabaseListMigrationInput {\n [key: string]: unknown;\n}\n\nexport interface SupabaseListTablesInput {\n [key: string]: unknown;\n}\n\nexport interface CloudStudioFetchLogInput {\n [key: string]: unknown;\n}\n\nexport interface CloudStudioExecuteCommandInput {\n [key: string]: unknown;\n}\n\nexport interface CloudStudioDeploySandboxInput {\n [key: string]: unknown;\n}\n\nexport interface WebFetchInput {\n url: string;\n fetchInfo: string;\n}\n\nexport interface UseSkillInput {\n command: string;\n}\n\nexport interface WebSearchInput {\n explanation: string;\n query: string;\n max_results?: number;\n language?: string;\n}\n\nexport interface TaskInput {\n subagent_name: string;\n description: string;\n prompt: string;\n subagent_path?: string;\n}\n\nexport interface CodebaseSearchInput {\n query: string;\n path: string;\n limit?: number;\n}\n\nexport interface LspInput {\n [key: string]: unknown;\n}\n\nexport interface SpecCreateInput {\n name: string;\n overview: string;\n relative_history: string;\n}\n\nexport interface SpecUpdateInput {\n status?: 'prepare' | 'ready' | 'building' | 'finished';\n}\n\n/**\n * 工具输入类型映射\n */\nexport interface ToolInputMap {\n list_dir: ListDirInput;\n search_file: SearchFileInput;\n read_file: ReadFileInput;\n read_lints: ReadLintsInput;\n rag_search: RagSearchInput;\n mcp_get_tool_description: McpGetToolDescriptionInput;\n mcp_call_tool: McpCallToolInput;\n fetch_mcp_resource: FetchMcpResourceInput;\n update_memory: UpdateMemoryInput;\n search_content: SearchContentInput;\n write_to_file: WriteToFileInput;\n replace_in_file: ReplaceInFileInput;\n delete_file: DeleteFileInput;\n execute_command: ExecuteCommandInput;\n preview_url: PreviewUrlInput;\n ask_followup_question: AskFollowupQuestionInput;\n invoke_integration: InvokeIntegrationInput;\n call_integration: CallIntegrationInput;\n search_integration_tool: SearchIntegrationToolInput;\n supabase_get_logs: SupabaseGetLogsInput;\n supabase_execute_sql: SupabaseExecuteSqlInput;\n supabase_apply_migration: SupabaseApplyMigrationInput;\n supabase_list_migration: SupabaseListMigrationInput;\n supabase_list_tables: SupabaseListTablesInput;\n cloud_studio_fetch_log: CloudStudioFetchLogInput;\n cloud_studio_execute_command: CloudStudioExecuteCommandInput;\n cloud_studio_deploy_sandbox: CloudStudioDeploySandboxInput;\n web_fetch: WebFetchInput;\n use_skill: UseSkillInput;\n web_search: WebSearchInput;\n task: TaskInput;\n codebase_search: CodebaseSearchInput;\n lsp: LspInput;\n spec_create: SpecCreateInput;\n spec_update: SpecUpdateInput;\n}\n\n// ============================================================================\n// 工具输出类型定义\n// ============================================================================\n\nexport interface ListFilesResult {\n type: 'list_files_result';\n files: Array<{\n filePath: string;\n size: string;\n modifyTime: string;\n }>;\n root: string;\n listing?: string;\n}\n\nexport interface SearchFileResult {\n type: 'search_file_result';\n path: string;\n pattern: string;\n recursive?: boolean;\n caseSensitive?: boolean;\n results: Array<{\n filePath: string;\n size: string;\n modifyTime: string;\n }>;\n}\n\nexport interface ReadFileResult {\n type: 'read_file_result';\n path: string;\n content: string;\n totalLineCount: number;\n hasMore: boolean;\n diagnostic?: string;\n hint?: string;\n image?: {\n data: string;\n mimeType: string;\n };\n}\n\nexport interface ReadLintsResult {\n type: 'read_lints_result';\n diagnostics: string[];\n totalCount?: number;\n hint?: string;\n isTruncated?: boolean;\n}\n\nexport interface KnowledgeSearchResult {\n type: 'knowledge_base_result';\n selectedKnowledgeBases: string;\n queryInput: string;\n}\n\nexport interface McpCallToolResult {\n type: 'mcp_call_tool_result';\n serverName: string;\n toolName: string;\n data: Array<{\n type: 'text' | 'image' | 'resource';\n text?: string;\n data?: string;\n mimeType?: string;\n resource?: {\n uri: string;\n mimeType?: string;\n text?: string;\n blob?: string;\n };\n }>;\n isError?: boolean;\n error?: unknown;\n hint?: string;\n}\n\nexport interface FetchMcpResourceToolResult {\n type: 'fetch_mcp_resource_result';\n server: string;\n uri: string;\n content: string;\n downloadPath?: string;\n}\n\nexport interface UpdateMemoryResult {\n type: 'update_memory_result';\n success: boolean;\n message: string;\n action: 'create' | 'update' | 'delete';\n knowledge_id?: string;\n}\n\nexport interface SearchContentResult {\n type: 'search_content_result';\n path: string;\n pattern: string;\n glob: string;\n matches: Array<{\n filePath: string;\n content: string;\n startLine: number;\n endLine: number;\n size: string;\n modifyTime: string;\n }>;\n totalCount: number;\n hasMore: boolean;\n offset: number;\n headLimit: number;\n contextBefore: number;\n contextAfter: number;\n contextAround?: number;\n outputMode: string;\n caseSensitive: boolean;\n hint?: string;\n}\n\nexport interface WriteToFileResult {\n type: 'write_to_file_result';\n path: string;\n addLineCount: number;\n removedLines: number;\n addedChars?: number;\n removedChars?: number;\n bytesWritten: number;\n isNewFile: boolean;\n oldContent?: string;\n diagnostic?: string;\n}\n\nexport interface ReplaceInFileResult {\n type: 'replace_in_file_result';\n path: string;\n addLineCount?: number;\n removedLines?: number;\n addedChars?: number;\n removedChars?: number;\n matchCount?: number;\n hint?: string;\n diagnosticChange?: {\n added: string;\n removed: string;\n unchanged: string;\n };\n}\n\nexport interface DeleteFilesResult {\n type: 'delete_file_result';\n path: string;\n recursive: boolean;\n hint?: string;\n}\n\nexport interface ExecuteCommandResult {\n type: 'execute_command_result';\n stdout: string;\n stderr: string;\n exitCode: number;\n hint?: string;\n serviceInfo?: {\n isWatchCommand: boolean;\n isServiceOutput: boolean;\n serviceReady: boolean;\n message: string;\n };\n use_standalone_terminal?: boolean;\n}\n\nexport interface PreviewToolResult {\n type: 'preview_tool_result';\n url: string;\n message: string;\n}\n\nexport interface MultiQuestionResult {\n type: 'multi_question_result';\n questions: Array<{\n id: string;\n question: string;\n options: string[];\n multiSelect?: boolean;\n title?: string;\n }>;\n answers: Record<string, string | string[]>;\n message: string;\n}\n\nexport interface InvokeIntegrationToolResult {\n type: 'invoke_integration_tool_result';\n recommend: {\n id: string;\n type: string;\n status: 'connected' | 'disconnected';\n };\n message: string;\n}\n\nexport interface CallIntegrationToolResult {\n type: 'call_integration_tool_result';\n integrationId: string;\n toolName: string;\n data: {\n type: 'text';\n text: string;\n };\n isError?: boolean;\n error?: unknown;\n}\n\nexport interface SearchIntegrationToolResult {\n type: 'search_integration_tool_result';\n data: Array<{\n integrationId: string;\n integrationName: string;\n toolName: string;\n description: string;\n inputSchema: Record<string, unknown>;\n }>;\n hint?: string;\n}\n\nexport interface SupabaseToolsResult {\n type: 'supabase_get_logs_result' | 'supabase_execute_sql_result' | 'supabase_apply_migration_result' | 'supabase_list_migration_result' | 'supabase_list_tables_result';\n message: string;\n}\n\nexport interface CloudStudioFetchLogResult {\n type: 'cloud_studio_fetch_log_result';\n success: boolean;\n logs: Record<string, string>;\n}\n\nexport interface CloudStudioExecuteCommandResult {\n type: 'cloud_studio_execute_command_result';\n success: boolean;\n message: string;\n}\n\nexport interface CloudStudioDeployResult {\n type: 'cloud_studio_integration_result';\n previewUrl?: string;\n steps: Array<{\n status: 'idle' | 'success' | 'running' | 'error';\n name: 'createSandbox' | 'uploadProject' | 'installDependencies' | 'startService' | 'preview';\n error?: {\n code?: number;\n message?: string;\n };\n }>;\n}\n\nexport interface WebFetchToolResult {\n type: 'web_fetch_tool_result';\n message: string;\n data: string;\n loading?: string;\n title?: string;\n favicon?: string;\n}\n\nexport interface UseSkillToolResult {\n type: 'use_skill_tool_result';\n commandMessage: string;\n message: string;\n}\n\nexport interface WebSearchToolResult {\n type: 'web_search_tool_result';\n query?: string;\n searchType?: 'text2text';\n provider?: string;\n results: Array<{\n title: string;\n url: string;\n snippet?: string;\n site?: string;\n highlights?: string[];\n content?: string;\n favicon?: string;\n }>;\n images: Array<{\n url: string;\n description?: string;\n sourceUrl?: string;\n width?: number;\n height?: number;\n title?: string;\n siteName?: string;\n }>;\n totalResults?: number;\n responseTimeMs?: number;\n searchInput?: string;\n}\n\nexport interface TaskToolResult {\n type: 'task_tool_result';\n toolInfo?: Array<{\n name: string;\n info: string;\n needApprove?: boolean;\n toolCallId?: string;\n executeStatus?: 'ing' | 'completed' | 'cancel' | 'fail';\n toolName?: string;\n args?: Record<string, unknown>;\n result?: Record<string, unknown>;\n }>;\n startCallTool?: boolean;\n finalResult?: string;\n toolCallBrief?: string;\n}\n\nexport interface CodebaseSearchResult {\n type: 'codebase_search_result';\n query: string;\n path: string;\n content: string;\n}\n\nexport interface LSPToolResult {\n type: 'lsp_tool_result';\n operation: string;\n result: string;\n resultCount?: number;\n fileCount?: number;\n character?: number;\n}\n\nexport interface PlanCreateToolResult {\n type: 'plan_create_tool_result';\n message: string;\n data: string;\n}\n\nexport interface PlanUpdateToolResult {\n type: 'plan_update_tool_result';\n status: 'prepare' | 'ready' | 'building' | 'finished';\n data: string;\n reminder: string;\n}\n\n/**\n * 工具输出类型映射\n */\nexport interface ToolOutputMap {\n list_dir: ListFilesResult;\n search_file: SearchFileResult;\n read_file: ReadFileResult;\n read_lints: ReadLintsResult;\n rag_search: KnowledgeSearchResult;\n mcp_get_tool_description: Record<string, unknown>;\n mcp_call_tool: McpCallToolResult;\n fetch_mcp_resource: FetchMcpResourceToolResult;\n update_memory: UpdateMemoryResult;\n search_content: SearchContentResult;\n write_to_file: WriteToFileResult;\n replace_in_file: ReplaceInFileResult;\n delete_file: DeleteFilesResult;\n execute_command: ExecuteCommandResult;\n preview_url: PreviewToolResult;\n ask_followup_question: MultiQuestionResult;\n invoke_integration: InvokeIntegrationToolResult;\n call_integration: CallIntegrationToolResult;\n search_integration_tool: SearchIntegrationToolResult;\n supabase_get_logs: SupabaseToolsResult;\n supabase_execute_sql: SupabaseToolsResult;\n supabase_apply_migration: SupabaseToolsResult;\n supabase_list_migration: SupabaseToolsResult;\n supabase_list_tables: SupabaseToolsResult;\n cloud_studio_fetch_log: CloudStudioFetchLogResult;\n cloud_studio_execute_command: CloudStudioExecuteCommandResult;\n cloud_studio_deploy_sandbox: CloudStudioDeployResult;\n web_fetch: WebFetchToolResult;\n use_skill: UseSkillToolResult;\n web_search: WebSearchToolResult;\n task: TaskToolResult;\n codebase_search: CodebaseSearchResult;\n lsp: LSPToolResult;\n spec_create: PlanCreateToolResult;\n spec_update: PlanUpdateToolResult;\n}\n\n// ============================================================================\n// Zod Schema 定义 (用于运行时验证)\n// ============================================================================\n\n/**\n * 工具输入 Schema 定义\n * 用于验证和约束 rawInput\n */\nexport const ToolInputSchemas = {\n list_dir: z.object({\n target_directory: z.string().describe('要列出内容的目录路径'),\n ignore_globs: z.string().optional().describe('可选的 glob 模式数组,用于忽略特定文件'),\n }),\n\n search_file: z.object({\n target_directory: z.string().describe('搜索的目录绝对路径'),\n pattern: z.string().describe('文件模式(如 \"*.js\"),支持通配符'),\n recursive: z.boolean().describe('是否递归搜索子目录'),\n caseSensitive: z.boolean().describe('是否区分大小写'),\n }),\n\n read_file: z.object({\n filePath: z.string().describe('要读取的文件的绝对路径'),\n offset: z.number().optional().describe('开始读取的行号'),\n limit: z.number().optional().describe('要读取的行数'),\n }),\n\n read_lints: z.object({\n paths: z.string().optional().describe('要读取 lint 错误的文件或目录路径'),\n }),\n\n rag_search: z.object({\n queryString: z.string().describe('用户的实际问题或搜索查询'),\n knowledgeBaseNames: z.string().describe('知识库名称,多个用逗号分隔'),\n }),\n\n mcp_get_tool_description: z.object({\n toolRequests: z.string().describe('JSON 字符串,二维数组格式:[[\"server1\", \"tool1\"], [\"server2\", \"tool2\"]]'),\n }),\n\n mcp_call_tool: z.object({\n serverName: z.string().describe('MCP 服务器名称'),\n toolName: z.string().describe('要调用的工具名称'),\n arguments: z.string().describe('目标 MCP 工具的参数,JSON 格式字符串'),\n maxOutputLength: z.number().optional().describe('控制工具输出的最大长度,默认 200000'),\n }),\n\n fetch_mcp_resource: z.object({\n server: z.string().describe('MCP 服务器标识符'),\n uri: z.string().describe('要读取的资源 URI'),\n arguments: z.record(z.unknown()).optional().describe('资源模板的参数'),\n downloadPath: z.string().optional().describe('可选的绝对路径,用于保存资源到磁盘'),\n }),\n\n update_memory: z.object({\n action: z.enum(['create', 'update', 'delete']).optional().describe('执行的操作'),\n existing_knowledge_id: z.string().optional().describe('更新或删除时必需,现有记忆的 ID'),\n knowledge_to_store: z.string().optional().describe('要存储的特定记忆'),\n title: z.string().optional().describe('记忆的标题'),\n }),\n\n search_content: z.object({\n pattern: z.string().describe('要搜索的关键字或正则表达式模式'),\n directory: z.string().describe('要搜索的目录的绝对路径'),\n fileTypes: z.string().optional().describe('可选的逗号分隔文件扩展名'),\n contextBefore: z.number().optional().describe('每个匹配前显示的行数'),\n contextAfter: z.number().optional().describe('每个匹配后显示的行数'),\n contextAround: z.number().optional().describe('每个匹配前后显示的行数'),\n outputMode: z.string().optional().describe('输出模式:content、files_with_matches 或 count'),\n caseSensitive: z.boolean().optional().describe('是否区分大小写'),\n }),\n\n write_to_file: z.object({\n filePath: z.string().describe('目标文件的绝对路径'),\n content: z.string().describe('要写入的内容'),\n }),\n\n replace_in_file: z.object({\n filePath: z.string().describe('要修改的文件的绝对路径'),\n old_str: z.string().describe('要替换的文本'),\n new_str: z.string().describe('替换后的文本'),\n }),\n\n delete_file: z.object({\n target_file: z.string().describe('要删除的文件的绝对路径'),\n explanation: z.string().optional().describe('为什么使用此工具的一句话解释'),\n }),\n\n execute_command: z.object({\n command: z.string().describe('要执行的 CLI 命令'),\n requires_approval: z.boolean().describe('命令是否需要用户批准'),\n }),\n\n preview_url: z.object({\n url: z.string().describe('要打开的完整、有效的 HTTP/HTTPS URL'),\n }),\n\n ask_followup_question: z.object({\n questions: z.array(z.object({\n question: z.string(),\n header: z.string().max(12),\n options: z.array(z.object({\n label: z.string().max(50),\n description: z.string(),\n })).min(2).max(4),\n multiSelect: z.boolean().optional(),\n })).min(1).max(4),\n }),\n\n invoke_integration: z.object({}).passthrough(),\n\n call_integration: z.object({}).passthrough(),\n\n search_integration_tool: z.object({}).passthrough(),\n\n supabase_get_logs: z.object({}).passthrough(),\n\n supabase_execute_sql: z.object({}).passthrough(),\n\n supabase_apply_migration: z.object({}).passthrough(),\n\n supabase_list_migration: z.object({}).passthrough(),\n\n supabase_list_tables: z.object({}).passthrough(),\n\n cloud_studio_fetch_log: z.object({}).passthrough(),\n\n cloud_studio_execute_command: z.object({}).passthrough(),\n\n cloud_studio_deploy_sandbox: z.object({}).passthrough(),\n\n web_fetch: z.object({\n url: z.string().describe('要获取内容的 URL'),\n fetchInfo: z.string().describe('用户想要获取的信息描述'),\n }),\n\n use_skill: z.object({\n command: z.string().describe('技能名称(不含参数),如 \"pdf\" 或 \"xlsx\"'),\n }),\n\n web_search: z.object({\n explanation: z.string().describe('为什么使用此工具的一句话解释'),\n query: z.string().describe('搜索关键词'),\n max_results: z.number().optional().describe('最大返回数量'),\n language: z.string().optional().describe('语言代码,例如 zh-CN'),\n }),\n\n task: z.object({\n subagent_name: z.string().describe('要调用的子代理名称'),\n description: z.string().describe('任务的简短描述(3-5 个词)'),\n prompt: z.string().describe('子代理要执行的任务'),\n subagent_path: z.string().optional().describe('子代理定义文件的路径'),\n }),\n\n codebase_search: z.object({\n query: z.string().describe('关于你想理解的内容的完整问题'),\n path: z.string().describe('限制搜索范围的目录路径前缀'),\n limit: z.number().max(100).optional().describe('返回的最大结果数,默认 10'),\n }),\n\n lsp: z.object({}).passthrough(),\n\n spec_create: z.object({\n name: z.string().describe('Plan 名称,用作稳定标识符/文件名'),\n overview: z.string().describe('用一两句话精确概括本次 plan 的主要内容'),\n relative_history: z.string().describe('准备阶段的上下文,包含用户需求、代码位置、额外上下文等'),\n }),\n\n spec_update: z.object({\n status: z.enum(['prepare', 'ready', 'building', 'finished']).optional().describe('Plan 状态'),\n }),\n} satisfies Record<ToolName, z.ZodTypeAny>;\n\n/**\n * 工具输出 Schema 定义\n * 用于验证和约束 rawOutput\n */\nexport const ToolOutputSchemas = {\n list_dir: z.object({\n type: z.literal('list_files_result'),\n files: z.array(z.object({\n filePath: z.string(),\n size: z.string(),\n modifyTime: z.string(),\n })),\n root: z.string(),\n listing: z.string().optional(),\n }),\n\n search_file: z.object({\n type: z.literal('search_file_result'),\n path: z.string(),\n pattern: z.string(),\n recursive: z.boolean().optional(),\n caseSensitive: z.boolean().optional(),\n results: z.array(z.object({\n filePath: z.string(),\n size: z.string(),\n modifyTime: z.string(),\n })),\n }),\n\n read_file: z.object({\n type: z.literal('read_file_result'),\n path: z.string(),\n content: z.string(),\n totalLineCount: z.number(),\n hasMore: z.boolean(),\n diagnostic: z.string().optional(),\n hint: z.string().optional(),\n image: z.object({\n data: z.string(),\n mimeType: z.string(),\n }).optional(),\n }),\n\n read_lints: z.object({\n type: z.literal('read_lints_result'),\n diagnostics: z.array(z.string()),\n totalCount: z.number().optional(),\n hint: z.string().optional(),\n isTruncated: z.boolean().optional(),\n }),\n\n rag_search: z.object({\n type: z.literal('knowledge_base_result'),\n selectedKnowledgeBases: z.string(),\n queryInput: z.string(),\n }),\n\n mcp_get_tool_description: z.object({}).passthrough(),\n\n mcp_call_tool: z.object({\n type: z.literal('mcp_call_tool_result'),\n serverName: z.string(),\n toolName: z.string(),\n data: z.array(z.union([\n z.object({\n type: z.literal('text'),\n text: z.string(),\n }),\n z.object({\n type: z.literal('image'),\n data: z.string(),\n mimeType: z.string(),\n }),\n z.object({\n type: z.literal('resource'),\n resource: z.object({\n uri: z.string(),\n mimeType: z.string().optional(),\n text: z.string().optional(),\n blob: z.string().optional(),\n }),\n }),\n ])),\n isError: z.boolean().optional(),\n error: z.unknown().optional(),\n hint: z.string().optional(),\n }),\n\n fetch_mcp_resource: z.object({\n type: z.literal('fetch_mcp_resource_result'),\n server: z.string(),\n uri: z.string(),\n content: z.string(),\n downloadPath: z.string().optional(),\n }),\n\n update_memory: z.object({\n type: z.literal('update_memory_result'),\n success: z.boolean(),\n message: z.string(),\n action: z.enum(['create', 'update', 'delete']),\n knowledge_id: z.string().optional(),\n }),\n\n search_content: z.object({\n type: z.literal('search_content_result'),\n path: z.string(),\n pattern: z.string(),\n glob: z.string(),\n matches: z.array(z.object({\n filePath: z.string(),\n content: z.string(),\n startLine: z.number(),\n endLine: z.number(),\n size: z.string(),\n modifyTime: z.string(),\n })),\n totalCount: z.number(),\n hasMore: z.boolean(),\n offset: z.number(),\n headLimit: z.number(),\n contextBefore: z.number(),\n contextAfter: z.number(),\n contextAround: z.number().optional(),\n outputMode: z.string(),\n caseSensitive: z.boolean(),\n hint: z.string().optional(),\n }),\n\n write_to_file: z.object({\n type: z.literal('write_to_file_result'),\n path: z.string(),\n addLineCount: z.number(),\n removedLines: z.number(),\n addedChars: z.number().optional(),\n removedChars: z.number().optional(),\n bytesWritten: z.number(),\n isNewFile: z.boolean(),\n oldContent: z.string().optional(),\n diagnostic: z.string().optional(),\n }),\n\n replace_in_file: z.object({\n type: z.literal('replace_in_file_result'),\n path: z.string(),\n addLineCount: z.number().optional(),\n removedLines: z.number().optional(),\n addedChars: z.number().optional(),\n removedChars: z.number().optional(),\n matchCount: z.number().optional(),\n hint: z.string().optional(),\n diagnosticChange: z.object({\n added: z.string(),\n removed: z.string(),\n unchanged: z.string(),\n }).optional(),\n }),\n\n delete_file: z.object({\n type: z.literal('delete_file_result'),\n path: z.string(),\n recursive: z.boolean(),\n hint: z.string().optional(),\n }),\n\n execute_command: z.object({\n type: z.literal('execute_command_result'),\n stdout: z.string(),\n stderr: z.string(),\n exitCode: z.number(),\n hint: z.string().optional(),\n serviceInfo: z.object({\n isWatchCommand: z.boolean(),\n isServiceOutput: z.boolean(),\n serviceReady: z.boolean(),\n message: z.string(),\n }).optional(),\n use_standalone_terminal: z.boolean().optional(),\n }),\n\n preview_url: z.object({\n type: z.literal('preview_tool_result'),\n url: z.string(),\n message: z.string(),\n }),\n\n ask_followup_question: z.object({\n type: z.literal('multi_question_result'),\n questions: z.array(z.object({\n id: z.string(),\n question: z.string(),\n options: z.array(z.string()),\n multiSelect: z.boolean().optional(),\n title: z.string().optional(),\n })),\n answers: z.record(z.union([z.string(), z.array(z.string())])),\n message: z.string(),\n }),\n\n invoke_integration: z.object({\n type: z.literal('invoke_integration_tool_result'),\n recommend: z.object({\n id: z.string(),\n type: z.string(),\n status: z.enum(['connected', 'disconnected']),\n }),\n message: z.string(),\n }),\n\n call_integration: z.object({\n type: z.literal('call_integration_tool_result'),\n integrationId: z.string(),\n toolName: z.string(),\n data: z.object({\n type: z.literal('text'),\n text: z.string(),\n }),\n isError: z.boolean().optional(),\n error: z.unknown().optional(),\n }),\n\n search_integration_tool: z.object({\n type: z.literal('search_integration_tool_result'),\n data: z.array(z.object({\n integrationId: z.string(),\n integrationName: z.string(),\n toolName: z.string(),\n description: z.string(),\n inputSchema: z.record(z.unknown()),\n })),\n hint: z.string().optional(),\n }),\n\n supabase_get_logs: z.object({\n type: z.enum([\n 'supabase_get_logs_result',\n 'supabase_execute_sql_result',\n 'supabase_apply_migration_result',\n 'supabase_list_migration_result',\n 'supabase_list_tables_result',\n ]),\n message: z.string(),\n }),\n\n supabase_execute_sql: z.object({\n type: z.enum([\n 'supabase_get_logs_result',\n 'supabase_execute_sql_result',\n 'supabase_apply_migration_result',\n 'supabase_list_migration_result',\n 'supabase_list_tables_result',\n ]),\n message: z.string(),\n }),\n\n supabase_apply_migration: z.object({\n type: z.enum([\n 'supabase_get_logs_result',\n 'supabase_execute_sql_result',\n 'supabase_apply_migration_result',\n 'supabase_list_migration_result',\n 'supabase_list_tables_result',\n ]),\n message: z.string(),\n }),\n\n supabase_list_migration: z.object({\n type: z.enum([\n 'supabase_get_logs_result',\n 'supabase_execute_sql_result',\n 'supabase_apply_migration_result',\n 'supabase_list_migration_result',\n 'supabase_list_tables_result',\n ]),\n message: z.string(),\n }),\n\n supabase_list_tables: z.object({\n type: z.enum([\n 'supabase_get_logs_result',\n 'supabase_execute_sql_result',\n 'supabase_apply_migration_result',\n 'supabase_list_migration_result',\n 'supabase_list_tables_result',\n ]),\n message: z.string(),\n }),\n\n cloud_studio_fetch_log: z.object({\n type: z.literal('cloud_studio_fetch_log_result'),\n success: z.boolean(),\n logs: z.record(z.string()),\n }),\n\n cloud_studio_execute_command: z.object({\n type: z.literal('cloud_studio_execute_command_result'),\n success: z.boolean(),\n message: z.string(),\n }),\n\n cloud_studio_deploy_sandbox: z.object({\n type: z.literal('cloud_studio_integration_result'),\n previewUrl: z.string().optional(),\n steps: z.array(z.object({\n status: z.enum(['idle', 'success', 'running', 'error']),\n name: z.enum(['createSandbox', 'uploadProject', 'installDependencies', 'startService', 'preview']),\n error: z.object({\n code: z.number().optional(),\n message: z.string().optional(),\n }).optional(),\n })),\n }),\n\n web_fetch: z.object({\n type: z.literal('web_fetch_tool_result'),\n message: z.string(),\n data: z.string(),\n loading: z.string().optional(),\n title: z.string().optional(),\n favicon: z.string().optional(),\n }),\n\n use_skill: z.object({\n type: z.literal('use_skill_tool_result'),\n commandMessage: z.string(),\n message: z.string(),\n }),\n\n web_search: z.object({\n type: z.literal('web_search_tool_result'),\n query: z.string().optional(),\n searchType: z.literal('text2text').optional(),\n provider: z.string().optional(),\n results: z.array(z.object({\n title: z.string(),\n url: z.string(),\n snippet: z.string().optional(),\n site: z.string().optional(),\n highlights: z.array(z.string()).optional(),\n content: z.string().optional(),\n favicon: z.string().optional(),\n })),\n images: z.array(z.object({\n url: z.string(),\n description: z.string().optional(),\n sourceUrl: z.string().optional(),\n width: z.number().optional(),\n height: z.number().optional(),\n title: z.string().optional(),\n siteName: z.string().optional(),\n })),\n totalResults: z.number().optional(),\n responseTimeMs: z.number().optional(),\n searchInput: z.string().optional(),\n }),\n\n task: z.object({\n type: z.literal('task_tool_result'),\n toolInfo: z.array(z.object({\n name: z.string(),\n info: z.string(),\n needApprove: z.boolean().optional(),\n toolCallId: z.string().optional(),\n executeStatus: z.enum(['ing', 'completed', 'cancel', 'fail']).optional(),\n })).optional(),\n startCallTool: z.boolean().optional(),\n finalResult: z.string().optional(),\n toolCallBrief: z.string().optional(),\n }),\n\n codebase_search: z.object({\n type: z.literal('codebase_search_result'),\n query: z.string(),\n path: z.string(),\n content: z.string(),\n }),\n\n lsp: z.object({\n type: z.literal('lsp_tool_result'),\n operation: z.string(),\n result: z.string(),\n resultCount: z.number().optional(),\n fileCount: z.number().optional(),\n character: z.number().optional(),\n }),\n\n spec_create: z.object({\n type: z.literal('plan_create_tool_result'),\n message: z.string(),\n data: z.string(),\n }),\n\n spec_update: z.object({\n type: z.literal('plan_update_tool_result'),\n status: z.enum(['prepare', 'ready', 'building', 'finished']),\n data: z.string(),\n reminder: z.string(),\n }),\n} satisfies Record<ToolName, z.ZodTypeAny>;\n\n// ============================================================================\n// 工具 Schema 验证工具函数\n// ============================================================================\n\n/**\n * 验证工具输入\n * @param toolName 工具名称\n * @param input 输入数据\n * @returns 验证结果\n */\nexport function validateToolInput<TName extends ToolName>(\n toolName: TName,\n input: unknown\n): { success: true; data: ToolInputMap[TName] } | { success: false; error: z.ZodError } {\n const schema = ToolInputSchemas[toolName];\n const result = schema.safeParse(input);\n if (result.success) {\n return { success: true, data: result.data as ToolInputMap[TName] };\n }\n return { success: false, error: result.error };\n}\n\n/**\n * 验证工具输出\n * @param toolName 工具名称\n * @param output 输出数据\n * @returns 验证结果\n */\nexport function validateToolOutput<TName extends ToolName>(\n toolName: TName,\n output: unknown\n): { success: true; data: ToolOutputMap[TName] } | { success: false; error: z.ZodError } {\n const schema = ToolOutputSchemas[toolName];\n const result = schema.safeParse(output);\n if (result.success) {\n return { success: true, data: result.data as ToolOutputMap[TName] };\n }\n return { success: false, error: result.error };\n}\n","/**\n * Mock Agent Provider\n *\n * 职责:\n * 1. 专门用于 Mock 数据验证链路\n * 2. 返回符合 ACP 协议的模拟数据\n * 3. 用于前端开发和测试阶段\n *\n * Mock 数据包括:\n * - 流式文本消息 (agent_message_chunk)\n * - 嵌入资源内容\n * - 资源链接\n * - 工具调用流程 (tool_call + tool_call_update)\n */\n\nimport type {\n AuthenticateRequest,\n AuthenticateResponse,\n CancelNotification,\n InitializeRequest,\n InitializeResponse,\n LoadSessionRequest,\n LoadSessionResponse,\n NewSessionRequest,\n NewSessionResponse,\n PromptRequest,\n PromptResponse,\n SessionNotification,\n SetSessionModelRequest,\n SetSessionModelResponse,\n SetSessionModeRequest,\n SetSessionModeResponse\n} from '@agentclientprotocol/sdk';\n\nimport type {\n PermissionRequestParams,\n PermissionResponse,\n SessionUpdateParams} from './acp-client-protocol';\nimport {\n DeleteFilesResult,\n ReadFileResult,\n validateToolOutput} from './tool-schemas.js';\nimport type { IAgentProvider } from './types';\n\nexport interface MockAgentProviderConfig {\n useRealProvider?: boolean; // 是否使用真实 Provider(保留向后兼容)\n}\n\n/**\n * ACP 协议 Mock 数据 - 初始化响应\n */\nexport const mockInitializeResponse: InitializeResponse = {\n protocolVersion: 1,\n agentCapabilities: {\n loadSession: true,\n promptCapabilities: {\n image: true,\n audio: false,\n embeddedContext: true\n },\n mcpCapabilities: {\n http: true,\n sse: true\n }\n }\n};\n\n/**\n * ACP 协议 Mock 数据 - 会话创建响应\n */\nexport const mockNewSessionResponse = (sessionId: string): NewSessionResponse => ({\n sessionId\n});\n\n/**\n * Mock 会话数据存储\n * 每个会话都有对应的模拟历史消息\n */\nconst mockSessionHistories = new Map<string, Array<{\n type: 'user' | 'assistant';\n content: string;\n timestamp: number;\n}>>();\n\n// 初始化会话历史数据\nmockSessionHistories.set('1', [\n {\n type: 'user',\n content: '帮我开发一个五子棋游戏,需要包含以下功能:\\n1. 双人对战模式\\n2. 悔棋功能\\n3. 计时器',\n timestamp: Date.now() - 1800000 - 60000,\n },\n {\n type: 'assistant',\n content: '好的,我来帮你开发一个五子棋游戏。我会创建以下文件结构:\\n\\n- `index.html` - 主页面\\n- `game.js` - 游戏逻辑\\n- `style.css` - 样式文件\\n\\n让我开始创建这些文件...',\n timestamp: Date.now() - 1800000 - 50000,\n },\n {\n type: 'assistant',\n content: '我已经完成了所有文件的创建和修改。游戏支持双人对战、悔棋和计时功能。你可以直接在浏览器中打开 index.html 开始游戏。',\n timestamp: Date.now() - 1800000,\n },\n]);\n\nmockSessionHistories.set('2', [\n {\n type: 'user',\n content: '登录页面的样式有问题,按钮颜色不对齐,帮我修复一下',\n timestamp: Date.now() - 7200000 - 120000,\n },\n {\n type: 'assistant',\n content: '我来检查登录页面的样式。让我先看看相关的 CSS 文件...',\n timestamp: Date.now() - 7200000 - 100000,\n },\n {\n type: 'assistant',\n content: '样式问题已修复,请查看效果。主要修改了按钮的 flex 布局和颜色变量。',\n timestamp: Date.now() - 7200000,\n },\n]);\n\nmockSessionHistories.set('3', [\n {\n type: 'user',\n content: 'API 接口响应太慢了,需要添加缓存和错误重试机制',\n timestamp: Date.now() - 14400000 - 180000,\n },\n {\n type: 'assistant',\n content: '好的,我来优化 API 接口。我会实现:\\n1. Redis 缓存层\\n2. 指数退避重试策略\\n3. 请求去重',\n timestamp: Date.now() - 14400000 - 150000,\n },\n {\n type: 'assistant',\n content: '已添加缓存和错误重试机制。性能提升了约 60%。',\n timestamp: Date.now() - 14400000,\n },\n]);\n\nmockSessionHistories.set('4', [\n {\n type: 'user',\n content: '帮我为核心模块添加单元测试,覆盖率要达到 80% 以上',\n timestamp: Date.now() - 86400000 - 300000,\n },\n {\n type: 'assistant',\n content: '好的,我会使用 Jest 来编写单元测试。让我先看看核心模块的代码结构...',\n timestamp: Date.now() - 86400000 - 250000,\n },\n {\n type: 'assistant',\n content: '测试覆盖率已达到 85%,超过了目标。主要测试了:\\n- 用户认证逻辑\\n- 数据验证\\n- 错误处理',\n timestamp: Date.now() - 86400000,\n },\n]);\n\nexport class MockAgentProvider implements IAgentProvider {\n // ========== ACP 原生事件回调集合 ==========\n private sessionUpdateCallbacks: Set<(params: SessionUpdateParams) => void> = new Set();\n private permissionRequestResolvers: Map<string, (params: PermissionRequestParams) => Promise<PermissionResponse>> = new Map();\n private errorCallbacks: Set<(error: Error, sessionId?: string) => void> = new Set();\n\n // Minimal connection tracking to keep API compatibility with previous SSE provider\n private activeConnections: Map<string, unknown> = new Map();\n /**\n * Mock 模式下,等待用户权限决策的解析器集合\n * key: toolCallId -> resolver(outcome)\n */\n private pendingPermissionResolvers: Map<string, (outcome: { outcome: 'selected' | 'cancelled'; optionId?: string; timedOut?: boolean }) => void> = new Map();\n /**\n * Mock 模式下,已初始化的会话集合\n */\n private initializedSessions: Map<string, { cwd: string; mcpServers: any[]; createdAt: number }> = new Map();\n /**\n * 临时缓存当前正在发送的消息的 SessionUpdateParams\n * key: sessionId -> params[]\n * 在 sendMockMessage 开始时初始化,结束时保存到 mockSessionHistories\n */\n private currentSessionUpdates: Map<string, SessionUpdateParams[]> = new Map();\n\n constructor(config: MockAgentProviderConfig = {}) {\n console.log('[MockAgentProvider] Initialized');\n\n // 初始化一些默认的 Mock session 数据\n this.initializeMockSessions();\n }\n\n setSessionMode?(params: SetSessionModeRequest): Promise<SetSessionModeResponse | void> {\n throw new Error('Method not implemented.');\n }\n setSessionModel?(params: SetSessionModelRequest): Promise<SetSessionModelResponse | void> {\n throw new Error('Method not implemented.');\n }\n extMethod?(method: string, params: Record<string, unknown>): Promise<Record<string, unknown>> {\n throw new Error('Method not implemented.');\n }\n extNotification?(method: string, params: Record<string, unknown>): Promise<void> {\n throw new Error('Method not implemented.');\n }\n\n /**\n * 初始化默认的 Mock session 数据\n */\n private initializeMockSessions(): void {\n const mockSessions = [\n {\n sessionId: '1',\n cwd: '/Users/example/Project',\n mcpServers: [],\n createdAt: Date.now() - 3600000, // 1小时前\n },\n {\n sessionId: '2',\n cwd: '/Users/example/Project',\n mcpServers: [],\n createdAt: Date.now() - 7200000, // 2小时前\n },\n {\n sessionId: '3',\n cwd: '/Users/example/Project',\n mcpServers: [],\n createdAt: Date.now() - 86400000, // 1天前\n },\n ];\n\n mockSessions.forEach(session => {\n this.initializedSessions.set(session.sessionId, {\n cwd: session.cwd,\n mcpServers: session.mcpServers,\n createdAt: session.createdAt,\n });\n });\n\n console.log('[MockAgentProvider] Initialized mock sessions:', mockSessions.length);\n }\n\n /**\n * 从 PromptRequest 中提取文本内容\n * Provider 自己决定如何处理 ContentBlock 数组\n */\n private extractTextFromRequest(request: PromptRequest): string {\n if (request.prompt && Array.isArray(request.prompt)) {\n return request.prompt\n .filter(block => block.type === 'text')\n .map(block => ('text' in block ? block.text : ''))\n .join('\\n');\n }\n return '';\n }\n\n /**\n * 发送消息 - 直接使用 Mock 数据\n * 接收 PromptRequest,由 Provider 决定如何处理\n */\n async sendMessage(request: PromptRequest): Promise<void> {\n // 提取文本内容 - 这是 Provider 的职责\n const content = this.extractTextFromRequest(request);\n const sessionId = request.sessionId;\n\n console.log('[MockAgentProvider] Sending mock message:', { sessionId, content });\n\n try {\n // 直接使用 Mock 数据\n await this.sendMockMessage(sessionId, content);\n } catch (error) {\n console.error('[MockAgentProvider] Send message failed:', error);\n\n // 触发错误事件\n this.emitEvent({\n type: 'error',\n sessionId,\n timestamp: Date.now(),\n data: { error: error instanceof Error ? error.message : 'Unknown error' },\n });\n\n throw error;\n }\n }\n\n /**\n * 使用 Mock 数据模拟流式响应\n */\n private async sendMockMessage(sessionId: string, content: string): Promise<void> {\n console.log('[MockAgentProvider] Using mock data for:', content);\n\n // ✅ 初始化临时事件缓存\n this.currentSessionUpdates.set(sessionId, []);\n\n // 发送连接成功事件\n this.emitEvent({\n type: 'connected',\n sessionId,\n timestamp: Date.now(),\n });\n\n // 模拟延迟\n await this.delay(300);\n\n // 1. 发送文本回复消息\n const messageId1 = `m-text-${Date.now()}`;\n const textReply = `我收到了你发送的「${content}」信息,这是符合 ACP 协议的 mock 数据。\\n\\n下面演示不同类型的 ContentBlock:\\n\\n`;\n await this.streamMockTextContent(sessionId, messageId1, textReply);\n\n await this.delay(500);\n\n // 2. 发送包含嵌入资源的回复\n const messageId2 = `m-resource-${Date.now()}`;\n await this.sendMockEmbeddedResource(sessionId, messageId2);\n\n await this.delay(500);\n\n // 3. 发送包含资源链接的回复\n const messageId3 = `m-link-${Date.now()}`;\n await this.sendMockResourceLink(sessionId, messageId3);\n\n await this.delay(500);\n\n // 4. 模拟工具调用流程\n const toolMessageId = `m-tool-${Date.now()}`;\n await this.sendMockEditContentToolCallFlow(sessionId, toolMessageId);\n await this.delay(500);\n\n const diffToolMessageId = `m-tool-d-${Date.now()}`;\n await this.sendMockEditDiffToolCallFlow(sessionId, diffToolMessageId);\n await this.delay(500);\n\n const readToolMessageId = `m-tool-r-${Date.now()}`;\n await this.sendMockReadContentToolCallFlow(sessionId, readToolMessageId);\n await this.delay(300);\n\n // 添加 search_file 和 search_content 的 mock 数据\n const searchContentMessageId = `m-tool-sc-${Date.now()}`;\n await this.sendMockSearchContentToolCallFlow(sessionId, searchContentMessageId);\n\n await this.delay(500);\n\n const searchFileMessageId = `m-tool-sf-${Date.now()}`;\n await this.sendMockSearchFileToolCallFlow(sessionId, searchFileMessageId);\n\n await this.delay(500);\n\n // 6. 发送 list_files 工具调用\n const listFilesMessageId = `m-tool-lf-${Date.now()}`;\n await this.sendMockListFilesToolCallFlow(sessionId, listFilesMessageId);\n\n await this.delay(500);\n\n // 7. 发送 ask_followup_question 工具调用\n const askFollowupMessageId = `m-tool-afq-${Date.now()}`;\n await this.sendMockAskFollowupQuestionToolCallFlow(sessionId, askFollowupMessageId);\n await this.delay(500);\n\n // 添加删除文件工具调用的 mock 数据\n const deleteFileMessageId = `m-tool-df-${Date.now()}`;\n await this.sendMockDeleteFileToolCallFlow(sessionId, deleteFileMessageId);\n\n await this.delay(300);\n\n // 8. 发送 execute_command 工具调用\n const executeCommandMessageId = `m-tool-ec-${Date.now()}`;\n await this.sendMockExecuteCommandToolCallFlow(sessionId, executeCommandMessageId);\n\n await this.delay(300);\n\n // 8.1 发送 execute_command 工具调用(需要权限确认)\n const executeCommandApprovalMessageId = `m-tool-ec-approval-${Date.now()}`;\n await this.sendMockExecuteCommandWithApprovalToolCallFlow(sessionId, executeCommandApprovalMessageId);\n\n await this.delay(300);\n\n // 8.2 发送 write_to_file 工具调用(需要权限确认)\n const writeFileApprovalMessageId = `m-tool-wtf-approval-${Date.now()}`;\n await this.sendMockWriteFileWithApprovalToolCallFlow(sessionId, writeFileApprovalMessageId);\n\n await this.delay(300);\n\n // 9. 发送 preview_url 工具调用 (测试 unknown tool)\n const previewUrlMessageId = `m-tool-pu-${Date.now()}`;\n await this.sendMockPreviewUrlToolCallFlow(sessionId, previewUrlMessageId);\n\n await this.delay(300);\n\n // 10. 发送 list_code_definition_names 工具调用 (测试 unknown tool)\n const listCodeDefMessageId = `m-tool-lcd-${Date.now()}`;\n await this.sendMockListCodeDefinitionNamesToolCallFlow(sessionId, listCodeDefMessageId);\n\n await this.delay(300);\n\n // 添加 web_fetch 工具调用的 mock 数据\n const webFetchMessageId = `m-tool-wf-${Date.now()}`;\n await this.sendMockWebFetchToolCallFlow(sessionId, webFetchMessageId);\n\n await this.delay(300);\n\n // 11. 发送 read_lints 工具调用\n const readLintsMessageId = `m-tool-rl-${Date.now()}`;\n await this.sendMockReadLintsToolCallFlow(sessionId, readLintsMessageId);\n\n await this.delay(300);\n\n // 10. 发送 web_search 工具调用\n const webSearchMessageId = `m-tool-ws-${Date.now()}`;\n await this.sendMockWebSearchToolCallFlow(sessionId, webSearchMessageId);\n\n await this.delay(300);\n\n // 发送完成事件\n this.emitEvent({\n type: 'done',\n sessionId,\n timestamp: Date.now(),\n });\n }\n\n /**\n * 流式发送 Mock 文本消息内容 (符合 ACP 协议的 agent_message_chunk)\n */\n private async streamMockTextContent(sessionId: string, messageId: string, content: string): Promise<void> {\n const chunkSize = 10; // 每次发送 10 个字符\n\n for (let i = 0; i < content.length; i += chunkSize) {\n // 获取当前块的内容\n const chunk = content.substring(i, i + chunkSize);\n\n console.log(`Text Chunk: \"${chunk}\" | messageId: ${messageId} | sessionId: ${sessionId}`);\n\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n update: {\n sessionUpdate: 'agent_message_chunk',\n content: {\n type: 'text',\n text: chunk,\n }\n }\n } as SessionNotification,\n });\n\n // 模拟网络延迟\n await this.delay(50);\n }\n }\n\n /**\n * 延迟函数\n */\n private delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n\n /**\n * 取消消息 (Mock 模式下直接完成)\n * @deprecated 使用 cancel 代替\n */\n async cancelMessage(sessionId: string): Promise<void> {\n console.log('[MockAgentProvider] Message cancelled:', sessionId);\n\n // 发送完成事件\n this.emitEvent({\n type: 'done',\n sessionId,\n timestamp: Date.now(),\n });\n }\n\n /**\n * ACP 协议: prompt - 发送用户消息\n *\n * Mock 实现: 复用 sendMessage\n */\n async prompt(request: PromptRequest): Promise<PromptResponse> {\n console.log('[MockAgentProvider] prompt called:', request);\n await this.sendMessage(request);\n // Mock 模式下,返回 end_turn 响应\n return {\n stopReason: 'end_turn',\n };\n }\n\n /**\n * ACP 协议: cancel - 取消消息\n *\n * Mock 实现: 复用 cancelMessage\n */\n async cancel(params: CancelNotification): Promise<void> {\n console.log('[MockAgentProvider] cancel called:', params);\n return this.cancelMessage(params.sessionId);\n }\n\n // ========== ACP 原生事件监听器 ==========\n\n /**\n * 监听会话更新事件(ACP 协议原生)\n */\n onSessionUpdate(callback: (params: SessionUpdateParams) => void): () => void {\n this.sessionUpdateCallbacks.add(callback);\n return () => {\n this.sessionUpdateCallbacks.delete(callback);\n };\n }\n\n /**\n * 监听权限请求事件(ACP 协议原生)\n */\n onRequestPermission(\n callback: (params: PermissionRequestParams) => Promise<PermissionResponse>\n ): () => void {\n this.permissionRequestResolvers.set('__global__', callback);\n return () => {\n this.permissionRequestResolvers.delete('__global__');\n };\n }\n\n /**\n * 监听错误事件(扩展事件,非 ACP 标准协议)\n */\n onError(callback: (error: Error, sessionId?: string) => void): () => void {\n this.errorCallbacks.add(callback);\n return () => {\n this.errorCallbacks.delete(callback);\n };\n }\n\n /**\n * 触发会话更新事件(内部辅助方法)\n */\n private emitSessionUpdate(params: SessionUpdateParams): void {\n console.log('[MockAgentProvider] Emitting session update:', params, 'to', this.sessionUpdateCallbacks.size, 'callbacks');\n\n this.sessionUpdateCallbacks.forEach(callback => {\n try {\n callback(params);\n } catch (error) {\n console.error('[MockAgentProvider] Session update callback error:', error);\n }\n });\n }\n\n /**\n * 触发错误事件(内部辅助方法)\n */\n private emitError(error: Error, sessionId?: string): void {\n console.log('[MockAgentProvider] Emitting error:', error, 'for session:', sessionId);\n\n this.errorCallbacks.forEach(callback => {\n try {\n callback(error, sessionId);\n } catch (err) {\n console.error('[MockAgentProvider] Error callback error:', err);\n }\n });\n }\n\n /**\n * 向后兼容的 emitEvent 方法\n * 将旧的事件格式桥接到新的 ACP 原生事件\n */\n private emitEvent(event: any): void {\n // 根据 event.type 路由到对应的新方法\n if (event.type === 'error') {\n const error = event.data?.error ? new Error(event.data.error) : new Error('Unknown error');\n this.emitError(error, event.sessionId);\n } else if (event.type === 'session_update' && event.notification) {\n // 转换为 SessionUpdateParams\n const params: SessionUpdateParams = {\n notification: event.notification,\n messageId: event.messageId,\n };\n this.emitSessionUpdate(params);\n } else if (event.type === 'connected' || event.type === 'done') {\n // 这些事件类型不再需要,忽略\n console.log('[MockAgentProvider] Ignoring deprecated event type:', event.type);\n } else {\n console.warn('[MockAgentProvider] Unknown event type:', event.type);\n }\n }\n\n /**\n * ACP 协议: initialize - 初始化连接\n *\n * Mock 实现: 返回预设的初始化响应\n */\n async initialize(request: InitializeRequest): Promise<InitializeResponse> {\n console.log('[MockAgentProvider] initialize', request);\n\n // 模拟网络延迟\n await this.delay(100);\n\n // 返回 Mock 初始化响应\n return mockInitializeResponse;\n }\n\n /**\n * ACP 协议: authenticate - 身份验证\n *\n * Mock 实现: 直接返回成功\n */\n async authenticate(request: AuthenticateRequest): Promise<AuthenticateResponse | void> {\n console.log('[MockAgentProvider] authenticate', request);\n // Mock 模式下不需要身份验证\n return;\n }\n\n /**\n * ACP 协议: newSession - 创建新会话\n *\n * Mock 实现: 生成唯一的 sessionId 并存储会话信息\n */\n async newSession(request: NewSessionRequest): Promise<NewSessionResponse> {\n console.log('[MockAgentProvider] session/new', request);\n\n // 模拟网络延迟\n await this.delay(100);\n\n // 生成唯一的 sessionId (格式: sess_<timestamp>_<random>)\n const sessionId = `sess_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n\n // 存储会话信息\n this.initializedSessions.set(sessionId, {\n cwd: request.cwd,\n mcpServers: request.mcpServers || [],\n createdAt: Date.now()\n });\n\n console.log('[MockAgentProvider] Created session:', sessionId, 'with config:', {\n cwd: request.cwd,\n mcpServers: request.mcpServers\n });\n\n // 返回 sessionId\n return mockNewSessionResponse(sessionId);\n }\n\n /**\n * ACP 协议: session/load - 加载已有会话\n *\n * Mock 实现: 流式回放会话历史(完整的事件回放)\n */\n async loadSession(request: LoadSessionRequest): Promise<LoadSessionResponse> {\n console.log('[MockAgentProvider] session/load', request);\n\n const { sessionId, cwd, mcpServers } = request;\n\n // 更新或添加会话配置\n this.initializedSessions.set(sessionId, {\n cwd,\n mcpServers: mcpServers || [],\n createdAt: Date.now()\n });\n\n // 从 mockSessionHistories 加载历史\n const history = mockSessionHistories.get(sessionId);\n if (history && history.length > 0) {\n console.log('[MockAgentProvider] Loading session from mockSessionHistories:', sessionId, 'with', history.length, 'entries');\n\n // 模拟流式回放会话历史\n for (let i = 0; i < history.length; i++) {\n const message = history[i];\n\n // 检查是否为事件数组格式(JSON 字符串)\n if (message.type === 'assistant' && message.content && message.content.startsWith('[')) {\n try {\n const events: any[] = JSON.parse(message.content);\n console.log('[MockAgentProvider] Replaying events from history:', {\n index: i,\n eventCount: events.length,\n });\n\n // 回放所有事件(通过 emitEvent 桥接)\n for (const event of events) {\n await this.delay(20); // 每个事件间隔 20ms\n this.emitEvent(event);\n }\n } catch (error) {\n console.error('[MockAgentProvider] Failed to parse events from history:', error);\n }\n } else {\n // 旧格式:普通文本消息\n const messageId = `load-${sessionId}-${i}-${Date.now()}`;\n const sessionUpdateType = message.type === 'user'\n ? 'user_message_chunk'\n : 'agent_message_chunk';\n\n await this.delay(50);\n\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: message.timestamp,\n notification: {\n sessionId,\n update: {\n sessionUpdate: sessionUpdateType,\n content: {\n type: 'text',\n text: message.content,\n }\n }\n } as SessionNotification,\n });\n }\n }\n\n console.log('[MockAgentProvider] Session loaded from mockSessionHistories:', sessionId);\n return {};\n }\n\n // 如果没有任何历史数据\n console.log('[MockAgentProvider] No history found for session:', sessionId);\n return {};\n }\n\n /**\n * ACP 协议: session/request_permission - 请求用户权限\n *\n * Agent 调用此方法来请求用户批准工具调用。\n * 此方法会:\n * 1. 发送 request_permission 事件给 UI\n * 2. 阻塞等待用户响应\n * 3. 返回用户的决策结果\n *\n * @param sessionId ACP 会话 ID\n * @param toolCallId 工具调用 ID\n * @param toolCall 工具调用信息\n * @param options 可用的权限选项\n * @returns 用户的决策结果\n */\n async requestPermission(\n sessionId: string,\n toolCallId: string,\n toolCall: any,\n options: any[]\n ): Promise<{ outcome: 'selected' | 'cancelled'; optionId?: string; timedOut?: boolean }> {\n console.log('[MockAgentProvider] requestPermission called:', { sessionId, toolCallId, toolCall, options });\n\n // 发送权限请求事件给 UI\n this.emitEvent({\n type: 'request_permission',\n sessionId,\n messageId: `permission-${toolCallId}`,\n timestamp: Date.now(),\n data: {\n sessionId,\n toolCall,\n options,\n },\n });\n\n // 阻塞等待用户决策(或超时)\n const permissionOutcome = await new Promise<{\n outcome: 'selected' | 'cancelled';\n optionId?: string;\n timedOut?: boolean;\n }>(resolve => {\n // 保存解析器,respondToPermissionRequest 会调用它\n this.pendingPermissionResolvers.set(toolCallId, resolve);\n\n // 超时降级:如果 60s 内没有用户响应,默认拒绝(避免无限挂起)\n setTimeout(() => {\n if (this.pendingPermissionResolvers.has(toolCallId)) {\n this.pendingPermissionResolvers.delete(toolCallId);\n console.log('[MockAgentProvider] Permission request timed out:', toolCallId);\n resolve({ outcome: 'cancelled', optionId: 'reject-once', timedOut: true });\n }\n }, 60000);\n });\n\n console.log('[MockAgentProvider] Permission outcome:', permissionOutcome);\n return permissionOutcome;\n }\n\n /**\n * 直接释放权限请求的 await(更直接的方法)\n *\n * 这个方法直接从 pendingPermissionResolvers 中获取 resolver 并调用,\n * 不需要经过 respondToPermissionRequest 的中转。\n *\n * @param toolCallId 工具调用 ID\n * @param outcome 用户的决策结果\n */\n releasePermissionRequest(toolCallId: string, outcome: { outcome: 'selected' | 'cancelled'; optionId?: string }): void {\n console.log('[MockAgentProvider] releasePermissionRequest called:', { toolCallId, outcome });\n\n const resolver = this.pendingPermissionResolvers.get(toolCallId);\n if (resolver) {\n // 直接调用 resolver 释放 await\n resolver({ ...outcome, timedOut: false });\n this.pendingPermissionResolvers.delete(toolCallId);\n console.log('[MockAgentProvider] Permission request released:', toolCallId);\n } else {\n console.warn('[MockAgentProvider] No pending permission request found for:', toolCallId);\n }\n }\n\n /**\n * 响应用户的权限决策(兼容旧接口)\n *\n * 这个方法内部调用 releasePermissionRequest。\n * 保留这个方法是为了向后兼容和符合 ACP 协议的命名规范。\n *\n * @param sessionId ACP 会话 ID(未使用,保留以符合接口)\n * @param payload 权限响应数据\n */\n async respondToPermissionRequest(sessionId: string, payload: {\n toolCallId: string;\n outcome: { outcome: 'selected' | 'cancelled'; optionId?: string }\n }): Promise<void> {\n console.log('[MockAgentProvider] respondToPermissionRequest called:', payload);\n\n // 直接调用 releasePermissionRequest\n this.releasePermissionRequest(payload.toolCallId, payload.outcome);\n }\n\n /**\n * 销毁 Provider\n */\n destroy(): void {\n // 清空所有回调解集合\n this.activeConnections.clear();\n this.pendingPermissionResolvers.clear();\n this.permissionRequestResolvers.clear();\n this.initializedSessions.clear();\n this.sessionUpdateCallbacks.clear();\n this.errorCallbacks.clear();\n // ✅ 清空临时事件缓存\n this.currentSessionUpdates.clear();\n console.log('[MockAgentProvider] Destroyed');\n }\n\n /**\n * 获取所有已初始化的会话列表(扩展方法,非 ACP 标准协议)\n * 返回 sessionId 及其配置信息和标题\n */\n getAllSessions(): Array<{ sessionId: string; title: string; cwd: string; mcpServers: any[]; createdAt: number }> {\n const mockTitles = {\n '1': '开发五子棋游戏',\n '2': '修复登录页面样式',\n '3': 'API 接口优化',\n };\n\n const sessions = Array.from(this.initializedSessions.entries()).map(([sessionId, config]) => ({\n sessionId,\n title: mockTitles[sessionId as keyof typeof mockTitles] || `Session ${sessionId}`,\n ...config,\n }));\n console.log('[MockAgentProvider] Getting all sessions:', sessions.length);\n return sessions;\n }\n\n /**\n * 发送嵌入资源消息 (符合 ACP 协议)\n */\n private async sendMockEmbeddedResource(sessionId: string, messageId: string): Promise<void> {\n console.log(`📎 Sending embedded resource: ${messageId}`);\n\n // 发送文本介绍部分\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId: `${messageId}-intro`,\n timestamp: Date.now(),\n notification: {\n sessionId,\n update: {\n sessionUpdate: 'agent_message_chunk',\n content: {\n type: 'text',\n text: '这是一个嵌入的 Python 文件示例:\\n\\n',\n }\n }\n } as SessionNotification,\n });\n\n await this.delay(200);\n\n // 发送嵌入资源内容块\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId: `${messageId}-resource`,\n timestamp: Date.now(),\n notification: {\n sessionId,\n update: {\n sessionUpdate: 'agent_message_chunk',\n content: {\n type: 'resource',\n resource: {\n uri: 'file:///mock/example.py',\n mimeType: 'text/x-python',\n text: 'def hello_world():\\n print(\"Hello, World!\")\\n return \"success\"\\n\\nif __name__ == \"__main__\":\\n hello_world()'\n }\n }\n }\n } as SessionNotification,\n });\n\n await this.delay(200);\n\n // 发送结尾文本\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId: `${messageId}-conclusion`,\n timestamp: Date.now(),\n notification: {\n sessionId,\n update: {\n sessionUpdate: 'agent_message_chunk',\n content: {\n type: 'text',\n text: '\\n\\n以上是直接嵌入的文件内容,无需额外请求即可显示。',\n }\n }\n } as SessionNotification,\n });\n\n await this.delay(100);\n }\n\n /**\n * 发送资源链接消息 (符合 ACP 协议)\n */\n private async sendMockResourceLink(sessionId: string, messageId: string): Promise<void> {\n console.log(`🔗 Sending resource link: ${messageId}`);\n\n // 发送文本介绍部分\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId: `${messageId}-intro`,\n timestamp: Date.now(),\n notification: {\n sessionId,\n update: {\n sessionUpdate: 'agent_message_chunk',\n content: {\n type: 'text',\n text: '这是一个指向外部文档的资源链接:\\n\\n',\n }\n }\n } as SessionNotification,\n });\n\n await this.delay(200);\n\n // 发送资源链接内容块\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId: `${messageId}-link`,\n timestamp: Date.now(),\n notification: {\n sessionId,\n update: {\n sessionUpdate: 'agent_message_chunk',\n content: {\n type: 'resource_link',\n uri: 'https://agentclientprotocol.com/protocol/content',\n name: 'ACP Content Protocol',\n mimeType: 'text/html',\n description: 'Agent Client Protocol - Content specification',\n size: 256000\n }\n }\n } as SessionNotification,\n });\n\n await this.delay(200);\n\n // 发送结尾文本\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId: `${messageId}-conclusion`,\n timestamp: Date.now(),\n notification: {\n sessionId,\n update: {\n sessionUpdate: 'agent_message_chunk',\n content: {\n type: 'text',\n text: '\\n\\n点击上面的链接可以访问完整的协议文档。',\n }\n }\n } as SessionNotification,\n });\n\n await this.delay(100);\n }\n\n /**\n * 发送完整的工具调用流程 (符合 ACP 协议)\n */\n private async sendMockEditDiffToolCallFlow(sessionId: string, messageId: string): Promise<void> {\n console.log(`🔧 Starting tool call flow: ${messageId}`);\n\n // 2. 发送工具调用事件 - 使用 ACP 协议的 tool_call session/update\n const toolCallId = `tool-${Date.now()}`;\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n update: {\n sessionUpdate: 'tool_call',\n toolCallId,\n title: 'Write File',\n kind: 'edit',\n status: 'pending',\n locations: [{ path: 'example.py', line: 0 }]\n }\n } as SessionNotification,\n });\n\n await this.delay(100);\n\n // 调用 requestPermission 接口请求用户权限\n // 这个方法会:\n // 1. 发送 request_permission 事件给 UI\n // 2. 阻塞等待用户响应\n // 3. 返回用户的决策结果\n // const permissionOutcome = await this.requestPermission(\n // sessionId,\n // toolCallId,\n // {\n // toolCallId,\n // kind: 'edit',\n // arguments: {\n // file_path: 'example.py',\n // content: 'def hello_world():\\n print(\"Hello from ACP tool call!\")...'\n // }\n // },\n // [\n // { optionId: 'allow-once', name: 'Allow once', kind: 'allow_once' },\n // { optionId: 'reject-once', name: 'Reject', kind: 'reject_once' }\n // ]\n // );\n\n // 根据用户决策推进后续 Mock 行为,区分同意与拒绝,发送不同的 tool_call_update 与消息\n // if (permissionOutcome.outcome === 'selected') {\n const content = 'def hello_world():\\n print(\"Hello from ACP tool call!\")\\n return \"success\"\\n\\nif __name__ == \"__main__\":\\n hello_world()';\n const chunkSize = 10; // 每次发送 10 个字符\n\n for (let i = 0; i < content.length; i += chunkSize) {\n // 获取当前块的内容\n const chunk = content.substring(i, i + chunkSize);\n\n console.log(`🐸 tool call Chunk: \"${chunk}\" | messageId: ${messageId} | sessionId: ${sessionId}`);\n\n // ✅ 5.1 开始执行 (in_progress)\n\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'in_progress', // ✅ 最终完成状态\n content: [\n {\n type: 'diff', // ✅ 使用 diff 类型显示文件修改\n path: 'example.py',\n oldText: '', // 新文件\n newText: chunk\n }\n ],\n locations: [{ path: 'example.py', line: 0 }]\n }\n } as SessionNotification,\n });\n // 模拟网络延迟\n await this.delay(50);\n }\n\n // 模拟工具执行时间\n await this.delay(1200);\n\n // ✅ 5.2 执行完成 (completed)\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'completed', // ✅ 最终完成状态\n content: [\n {\n type: 'diff', // ✅ 使用 diff 类型显示文件修改\n path: 'example.py',\n oldText: 'def 213', // 新文件\n newText: 'def hello_world():\\n print(\"Hello from ACP tool call!\")\\n return \"success\"\\n\\nif __name__ == \"__main__\":\\n hello_world()'\n }\n ],\n locations: [{ path: 'example.py', line: 0 }]\n }\n } as SessionNotification,\n });\n\n // 发送总结消息\n await this.delay(300);\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId: `${messageId}-summary`,\n timestamp: Date.now(),\n notification: {\n sessionId,\n update: {\n sessionUpdate: 'agent_message_chunk',\n content: {\n type: 'text',\n text: '✅ 工具调用完成!我成功创建了一个名为 `example.py` 的文件。\\n\\nACP 协议工具调用流程:\\n1. `tool_call` (pending) - 创建工具调用\\n2. `tool_call_update` (in_progress) - 开始执行\\n3. `tool_call_update` (completed) - 执行完成\\n\\n这就是完整的工具调用生命周期!',\n }\n }\n } as SessionNotification,\n });\n // } else {\n // // ✅ 5.3 权限拒绝 (failed)\n // await this.delay(300);\n // this.emitEvent({\n // type: 'session_update',\n // sessionId,\n // messageId,\n // timestamp: Date.now(),\n // notification: {\n // sessionId,\n // update: {\n // sessionUpdate: 'tool_call_update',\n // toolCallId,\n // status: 'failed', // ✅ 失败状态\n // content: [\n // {\n // type: 'content',\n // content: {\n // type: 'text',\n // text: permissionOutcome.timedOut\n // ? 'Permission request timed out; tool execution cancelled (mock)'\n // : 'User rejected permission; tool execution cancelled (mock)'\n // }\n // }\n // ]\n // }\n // } as SessionNotification,\n // });\n\n // // 发送总结消息\n // await this.delay(300);\n // this.emitEvent({\n // type: 'session_update',\n // sessionId,\n // messageId: `${messageId}-summary`,\n // timestamp: Date.now(),\n // notification: {\n // sessionId,\n // update: {\n // sessionUpdate: 'agent_message_chunk',\n // content: {\n // type: 'text',\n // text: permissionOutcome.timedOut\n // ? '⏰ 权限请求超时,工具调用已取消(mock)。'\n // : '❌ 已拒绝执行写文件操作,工具调用已取消(mock)。',\n // }\n // }\n // } as SessionNotification,\n // });\n // }\n\n await this.delay(100);\n\n // 5. 发送工具调用完成后的总结消息\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId: `${messageId}-summary`,\n timestamp: Date.now(),\n notification: {\n sessionId,\n update: {\n sessionUpdate: 'agent_message_chunk',\n content: {\n type: 'text',\n text: '✅ 工具调用完成!我成功创建了一个名为 `example.py` 的文件。\\n\\n工具调用流程包括:\\n1. 发送工具调用请求 (tool_call)\\n2. 返回执行结果 (tool_call_update)\\n\\n这就是 ACP 协议中完整的工具调用生命周期。',\n }\n }\n } as SessionNotification,\n });\n\n await this.delay(100);\n }\n\n private async sendMockEditContentToolCallFlow(sessionId: string, messageId: string): Promise<void> {\n console.log(`🔧 Starting tool call flow: ${messageId}`);\n\n // 2. 发送工具调用事件 - 使用 ACP 协议的 tool_call session/update\n const toolCallId = `tool-${Date.now()}`;\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'write_to_file',\n },\n },\n update: {\n sessionUpdate: 'tool_call',\n toolCallId,\n title: 'Write File',\n kind: 'edit',\n status: 'pending',\n locations: [{ path: 'example-edit-content.py', line: 0 }]\n }\n } as SessionNotification,\n });\n\n await this.delay(100);\n\n const content = 'def hello_world():\\n print(\"Hello from ACP tool call!\")\\n return \"success\"\\n\\nif __name__ == \"__main__\":\\n hello_world()';\n const chunkSize = 10; // 每次发送 10 个字符\n\n let accumulatedInput = '';\n for (let i = 0; i < content.length; i += chunkSize) {\n // 获取当前块的内容\n const chunk = content.substring(i, i + chunkSize);\n accumulatedInput += chunk;\n\n console.log(`🐸 tool call Chunk: \"${chunk}\" | messageId: ${messageId} | sessionId: ${sessionId}`);\n\n // ✅ 5.1 开始执行 (in_progress)\n\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'write_to_file',\n },\n },\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'in_progress', // ✅ 最终完成状态\n content: [\n {\n type: 'content',\n content: {\n type: 'text',\n text: accumulatedInput,\n\n }\n }\n ],\n rawInput: {\n 'filePath': 'example-edit-content.py',\n 'content': accumulatedInput,\n },\n locations: [{ path: 'example-edit-content.py', line: 0 }]\n }\n } as SessionNotification,\n });\n // 模拟网络延迟\n await this.delay(50);\n }\n\n // 模拟工具执行时间\n await this.delay(1200);\n\n // ✅ 5.2 执行完成 (completed)\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'write_to_file',\n },\n },\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'completed', // ✅ 最终完成状态\n content: [\n {\n type: 'content',\n content: {\n type: 'text',\n text: content\n }\n }\n ],\n rawOutput: {\n 'type': 'write_to_file_result',\n 'path': 'example-edit-content.py',\n 'addLineCount': 10,\n 'removedLines': 20,\n },\n locations: [{ path: 'example-edit-content.py', line: 0 }]\n }\n } as SessionNotification,\n });\n\n // 发送总结消息\n await this.delay(300);\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId: `${messageId}-summary`,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'write_to_file',\n },\n },\n update: {\n sessionUpdate: 'agent_message_chunk',\n content: {\n type: 'text',\n text: '✅ 工具调用完成!我成功创建了一个名为 `example.py` 的文件。\\n\\nACP 协议工具调用流程:\\n1. `tool_call` (pending) - 创建工具调用\\n2. `tool_call_update` (in_progress) - 开始执行\\n3. `tool_call_update` (completed) - 执行完成\\n\\n这就是完整的工具调用生命周期!',\n }\n },\n rawInput: {\n 'filePath': 'example-edit-content.py',\n 'content': accumulatedInput,\n }\n } as SessionNotification,\n });\n\n await this.delay(100);\n\n // 5. 发送工具调用完成后的总结消息\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId: `${messageId}-summary`,\n timestamp: Date.now(),\n notification: {\n sessionId,\n update: {\n sessionUpdate: 'agent_message_chunk',\n content: {\n type: 'text',\n text: '✅ 工具调用完成!我成功创建了一个名为 `example.py` 的文件。\\n\\n工具调用流程包括:\\n1. 发送工具调用请求 (tool_call)\\n2. 返回执行结果 (tool_call_update)\\n\\n这就是 ACP 协议中完整的工具调用生命周期。',\n }\n }\n } as SessionNotification,\n });\n\n await this.delay(100);\n }\n\n /**\n * 发送完整的工具调用流程 - kind 为 read (符合 ACP 协议)\n *\n * 模拟 read_file 工具调用流程,流式发送 rawInput 和 rawOutput\n */\n private async sendMockReadContentToolCallFlow(sessionId: string, messageId: string): Promise<void> {\n console.log(`📖 Starting read tool call flow: ${messageId}`);\n\n // 配置:模拟读取文件\n const filePath = '/Users/liumingyuan/Project/caseTest/subagent/test.js';\n const toolCallId = `tool-${Date.now()}`;\n\n // 1. 发送 tool_call (pending) - 不带 rawInput\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'read_file'\n }\n },\n update: {\n sessionUpdate: 'tool_call',\n toolCallId,\n title: 'Read File',\n status: 'pending',\n locations: [{ path: filePath, line: 0 }]\n }\n } as SessionNotification\n });\n\n console.log('[MockAgentProvider] tool_call (pending) sent');\n await this.delay(100);\n\n // 2. 流式发送 rawInput (模拟参数逐个到达)\n // 将 filePath 分块流式发送\n const filePathChunks = [\n '/Users/liumingyuan/',\n 'Project/caseTest',\n '/subagent/',\n 'test.js'\n ];\n\n let accumulatedInput = '';\n for (const chunk of filePathChunks) {\n accumulatedInput += chunk;\n\n // 尝试解析累积的 input\n try {\n // const parsed = JSON.parse(accumulatedInput);\n // const rawInput: ReadFileInput = {\n // filePath: parsed.filePath\n // };\n\n // 验证 rawInput\n // const inputValidation = validateToolInput('read_file', rawInput);\n // if (inputValidation.success) {\n // 发送 tool_call_update with rawInput\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'read_file'\n }\n },\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'in_progress',\n rawInput: {\n filePath: accumulatedInput\n }\n }\n } as SessionNotification\n });\n await this.delay(100);\n console.log('[MockAgentProvider] tool_call_update with rawInput:', chunk);\n // }\n } catch {\n // JSON 还未完整,继续累积\n }\n\n }\n\n // Mock file content\n const fileContent = `/**\n * Test file for subagent functionality\n */\n\nfunction helloWorld() {\n console.log('Hello from test.js!');\n return 'success';\n}\n\nclass TestClass {\n constructor(name) {\n this.name = name;\n }\n\n greet() {\n return \\`Hello, \\${this.name}!\\`;\n }\n}\n\n// Export functions\nmodule.exports = {\n helloWorld,\n TestClass\n};\n`;\n\n const totalLineCount = 26;\n const chunkSize = 20;\n let accumulatedContent = '';\n\n // 3. 流式返回结果 with in_progress\n for (let i = 0; i < fileContent.length; i += chunkSize) {\n const chunk = fileContent.substring(i, i + chunkSize);\n accumulatedContent += chunk;\n const progress = Math.round(((i + chunkSize) / fileContent.length) * 100);\n const isLastChunk = (i + chunkSize) >= fileContent.length;\n\n const rawOutput: ReadFileResult = {\n type: 'read_file_result',\n path: filePath,\n content: accumulatedContent,\n totalLineCount,\n hasMore: !isLastChunk,\n hint: `Reading file... ${Math.min(progress, 100)}% complete`\n };\n\n // 验证 rawOutput\n const outputValidation = validateToolOutput('read_file', rawOutput);\n\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'read_file'\n }\n },\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'in_progress',\n content: [\n {\n type: 'content',\n content: {\n type: 'text',\n text: accumulatedContent\n }\n }\n ],\n locations: [{ path: filePath, line: 0 }],\n rawOutput: (outputValidation.success ? outputValidation.data : rawOutput) as unknown as Record<string, unknown>\n }\n } as SessionNotification\n });\n\n console.log(`📖 Read chunk ${i / chunkSize + 1}: progress ${progress}%`);\n await this.delay(30);\n }\n\n // 4. 发送 completed 事件\n const finalRawOutput: ReadFileResult = {\n type: 'read_file_result',\n path: filePath,\n content: fileContent,\n totalLineCount,\n hasMore: false\n };\n\n const finalOutputValidation = validateToolOutput('read_file', finalRawOutput);\n if (!finalOutputValidation.success) {\n throw new Error(`Invalid rawOutput: ${JSON.stringify(finalOutputValidation.error.errors)}`);\n }\n\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'completed',\n content: [\n {\n type: 'content',\n content: {\n type: 'text',\n text: fileContent\n }\n }\n ],\n locations: [{ path: filePath, line: 0 }],\n rawOutput: finalOutputValidation.data as unknown as Record<string, unknown>\n }\n } as SessionNotification\n });\n\n console.log('[MockAgentProvider] tool_call_update (completed) sent');\n }\n\n /**\n * 发送 search_content 工具调用流程 (符合 ACP 协议)\n *\n * 用于模拟在文件内容中搜索特定文本的工具调用\n * 支持显示匹配的文件路径、行号和上下文内容\n */\n private async sendMockSearchContentToolCallFlow(sessionId: string, messageId: string): Promise<void> {\n console.log(`🔍 Starting search_content tool call flow: ${messageId}`);\n\n const pattern = '一行工具';\n const directory = '/Users/liumingyuan/Project/caseTest/subagent';\n\n // 1. 发送工具调用事件\n const toolCallId = `tool-sc-${Date.now()}`;\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'search_content',\n },\n },\n update: {\n sessionUpdate: 'tool_call',\n toolCallId,\n title: 'Search Content',\n kind: 'search', // ✅ kind 为 search\n status: 'pending',\n locations: [{ path: directory, line: 0 }],\n rawInput: {\n pattern,\n path: directory,\n }\n }\n } as SessionNotification,\n });\n\n await this.delay(100);\n\n // 2. 发送 in_progress 状态和搜索结果\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'in_progress',\n content: [\n {\n type: 'content',\n content: {\n type: 'text',\n text: `Searching for \"${pattern}\" in ${directory}...`,\n }\n }\n ],\n locations: [{ path: directory, line: 0 }]\n }\n } as SessionNotification,\n });\n\n await this.delay(500);\n\n // 3. 发送完成状态和匹配结果\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'completed',\n content: [\n {\n type: 'content',\n content: {\n type: 'text',\n text: 'Found 1 matching result\\n\\nconvert_to_oneline.py\\n 56| print(\"文件内容转一行工具\")\\n',\n }\n }\n ],\n locations: [{ path: directory, line: 0 }],\n rawOutput: {\n pattern,\n path: directory,\n matches: [\n {\n filePath: 'convert_to_oneline.py',\n fileName: 'convert_to_oneline.py',\n content: ' print(\"文件内容转一行工具\")',\n startLine: 56,\n endLine: 56,\n }\n ],\n totalCount: 1,\n hasMore: false,\n }\n }\n } as SessionNotification,\n });\n\n // 4. 发送总结消息\n await this.delay(300);\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId: `${messageId}-summary`,\n timestamp: Date.now(),\n notification: {\n sessionId,\n update: {\n sessionUpdate: 'agent_message_chunk',\n content: {\n type: 'text',\n text: `✅ 内容搜索完成!在 \\`${directory}\\` 目录中找到 1 个匹配结果。\\n\\n**搜索结果:**\\n- \\`convert_to_oneline.py\\` 第 56 行: \\`print(\"文件内容转一行工具\")\\`\\n\\n**工具调用流程:**\\n1. \\`tool_call\\` (pending) - 创建搜索工具调用\\n2. \\`tool_call_update\\` (in_progress) - 执行搜索\\n3. \\`tool_call_update\\` (completed) - 返回匹配结果`,\n }\n }\n } as SessionNotification,\n });\n\n await this.delay(100);\n }\n\n /**\n * 发送 search_file 工具调用流程 (符合 ACP 协议)\n *\n * 用于模拟按文件名模式搜索文件的工具调用\n * 支持递归搜索和文件大小显示\n */\n private async sendMockSearchFileToolCallFlow(sessionId: string, messageId: string): Promise<void> {\n console.log(`🔍 Starting search_file tool call flow: ${messageId}`);\n\n const pattern = '*.py';\n const directory = '/Users/liumingyuan/Project/caseTest/subagent';\n\n // 1. 发送工具调用事件\n const toolCallId = `tool-sf-${Date.now()}`;\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'search_file',\n },\n },\n update: {\n sessionUpdate: 'tool_call',\n toolCallId,\n title: 'Search File',\n kind: 'search', // ✅ kind 为 search\n status: 'pending',\n locations: [{ path: directory, line: 0 }],\n rawInput: {\n target_directory: directory,\n pattern,\n recursive: true,\n caseSensitive: false,\n }\n }\n } as SessionNotification,\n });\n\n await this.delay(100);\n\n // 2. 发送 in_progress 状态\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'in_progress',\n content: [\n {\n type: 'content',\n content: {\n type: 'text',\n text: `Searching for files matching \"${pattern}\" in ${directory}...`,\n }\n }\n ],\n locations: [{ path: directory, line: 0 }]\n }\n } as SessionNotification,\n });\n\n await this.delay(500);\n\n // 3. 发送完成状态和搜索结果\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'completed',\n content: [\n {\n type: 'content',\n content: {\n type: 'text',\n text: 'Found 5 files\\n\\nbubble_sort.py (10.38 KB)\\nconvert_to_oneline.py (2.2 KB)\\ntls12_examples.py (4.58 KB)\\n.codebuddy/skills/analyzing-financial-statements/calculate_ratios.py (12.22 KB)\\n.codebuddy/skills/analyzing-financial-statements/interpret_ratios.py (15.83 KB)\\n',\n }\n }\n ],\n locations: [{ path: directory, line: 0 }],\n rawOutput: {\n path: directory,\n pattern,\n recursive: true,\n caseSensitive: false,\n results: [\n { filePath: 'bubble_sort.py', size: '10.38 KB' },\n { filePath: 'convert_to_oneline.py', size: '2.2 KB' },\n { filePath: 'tls12_examples.py', size: '4.58 KB' },\n { filePath: '.codebuddy/skills/analyzing-financial-statements/calculate_ratios.py', size: '12.22 KB' },\n { filePath: '.codebuddy/skills/analyzing-financial-statements/interpret_ratios.py', size: '15.83 KB' },\n ],\n }\n }\n } as SessionNotification,\n });\n\n // 4. 发送总结消息\n await this.delay(300);\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId: `${messageId}-summary`,\n timestamp: Date.now(),\n notification: {\n sessionId,\n update: {\n sessionUpdate: 'agent_message_chunk',\n content: {\n type: 'text',\n text: `✅ 文件搜索完成!在 \\`${directory}\\` 目录中找到 5 个匹配的 Python 文件。\\n\\n**搜索结果:**\\n- \\`bubble_sort.py\\` (10.38 KB)\\n- \\`convert_to_oneline.py\\` (2.2 KB)\\n- \\`tls12_examples.py\\` (4.58 KB)\\n- \\`.codebuddy/skills/analyzing-financial-statements/calculate_ratios.py\\` (12.22 KB)\\n- \\`.codebuddy/skills/analyzing-financial-statements/interpret_ratios.py\\` (15.83 KB)\\n\\n**工具调用流程:**\\n1. \\`tool_call\\` (pending) - 创建搜索工具调用\\n2. \\`tool_call_update\\` (in_progress) - 执行搜索\\n3. \\`tool_call_update\\` (completed) - 返回搜索结果`,\n }\n }\n } as SessionNotification,\n });\n\n await this.delay(100);\n }\n\n /**\n * 发送删除文件工具调用流程 (符合 ACP 协议)\n *\n * 用于模拟删除文件的工具调用\n * 支持显示删除操作的进度和结果\n */\n private async sendMockDeleteFileToolCallFlow(sessionId: string, messageId: string): Promise<void> {\n console.log(`🗑️ Starting delete_file tool call flow: ${messageId}`);\n\n // 配置:模拟删除文件\n const targetFile = '/Users/liumingyuan/Project/caseTest/subagent/temp_file.txt';\n const toolCallId = `tool-df-${Date.now()}`;\n\n // 1. 发送 tool_call (pending) - 不带 rawInput\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'delete_file'\n }\n },\n update: {\n sessionUpdate: 'tool_call',\n toolCallId,\n title: 'Delete File',\n status: 'pending',\n locations: [{ path: targetFile, line: 0 }]\n }\n } as SessionNotification\n });\n\n console.log('[MockAgentProvider] delete_file tool_call (pending) sent');\n await this.delay(200);\n\n // 2. 流式发送 rawInput (模拟参数逐个到达)\n // 将 target_file 分块流式发送\n const filePathChunks = [\n '/Users/liumingyuan/',\n 'Project/caseTest',\n '/subagent/',\n 'temp_file.txt'\n ];\n\n let accumulatedInput = '';\n for (const chunk of filePathChunks) {\n accumulatedInput += chunk;\n\n // 发送 tool_call_update with rawInput\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'delete_file'\n }\n },\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'in_progress',\n rawInput: {\n target_file: accumulatedInput,\n explanation: 'Deleting temporary test file'\n }\n }\n } as SessionNotification\n });\n await this.delay(100);\n console.log('[MockAgentProvider] delete_file tool_call_update with rawInput:', chunk);\n }\n\n await this.delay(300);\n\n // 3. 模拟删除操作进度\n const progressSteps = [\n { progress: 25, message: 'Checking file permissions...' },\n { progress: 50, message: 'Validating file path...' },\n { progress: 75, message: 'Removing file...' },\n { progress: 100, message: 'File deleted successfully' }\n ];\n\n for (const step of progressSteps) {\n const rawOutput: DeleteFilesResult = {\n type: 'delete_file_result',\n path: targetFile,\n recursive: false,\n hint: step.message\n };\n\n // 验证 rawOutput\n const outputValidation = validateToolOutput('delete_file', rawOutput);\n\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'delete_file'\n }\n },\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: step.progress === 100 ? 'deleted' : 'in_progress',\n content: [\n {\n type: 'content',\n content: {\n type: 'text',\n text: `🗑️ ${step.message} (${step.progress}%)`\n }\n }\n ],\n locations: [{ path: targetFile, line: 0 }],\n rawOutput: (outputValidation.success ? outputValidation.data : rawOutput) as unknown as Record<string, unknown>\n }\n } as SessionNotification\n });\n\n console.log(`🗑️ Delete progress: ${step.progress}% - ${step.message}`);\n await this.delay(200);\n }\n\n // 4. 发送最终完成事件\n const finalRawOutput: DeleteFilesResult = {\n type: 'delete_file_result',\n path: targetFile,\n recursive: false,\n hint: 'File successfully deleted from filesystem'\n };\n\n const finalOutputValidation = validateToolOutput('delete_file', finalRawOutput);\n if (!finalOutputValidation.success) {\n throw new Error(`Invalid delete_file rawOutput: ${JSON.stringify(finalOutputValidation.error.errors)}`);\n }\n\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'completed',\n content: [\n {\n type: 'content',\n content: {\n type: 'text',\n text: `✅ 文件删除完成!\\n\\n**删除的文件:** \\`${targetFile}\\`\\n\\n**操作详情:**\\n- 文件路径验证 ✓\\n- 权限检查 ✓\\n- 文件删除 ✓\\n\\n文件已从文件系统中成功移除。`\n }\n }\n ],\n locations: [{ path: targetFile, line: 0 }],\n rawOutput: finalOutputValidation.data as unknown as Record<string, unknown>\n }\n } as SessionNotification\n });\n\n console.log('[MockAgentProvider] delete_file tool_call_update (completed) sent');\n\n // 5. 发送总结消息\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId: `${messageId}-summary`,\n timestamp: Date.now(),\n notification: {\n sessionId,\n update: {\n sessionUpdate: 'agent_message_chunk',\n content: {\n type: 'text',\n text: '🗑️ **删除文件工具调用演示完成**\\n\\n**工具调用流程:**\\n1. `tool_call` (pending) - 创建删除文件工具调用\\n2. `tool_call_update` (in_progress) - 流式发送参数和执行删除操作\\n3. `tool_call_update` (completed) - 返回删除结果\\n\\n**rawInput 包含:**\\n- `target_file`: 要删除的文件路径\\n- `explanation`: 删除原因说明\\n\\n**rawOutput 包含:**\\n- `type`: \\'delete_file_result\\'\\n- `path`: 被删除的文件路径\\n- `recursive`: 是否递归删除\\n- `hint`: 操作提示信息',\n }\n }\n } as SessionNotification,\n });\n\n await this.delay(100);\n }\n\n /**\n * 发送 ask_followup_question 工具调用流程 (符合 ACP 协议)\n *\n * 用于模拟向用户提问并获取回答的工具调用\n * 数据结构与 genie-ide 保持一致:question (单个问题字符串) + options (选项数组)\n */\n private async sendMockAskFollowupQuestionToolCallFlow(sessionId: string, messageId: string): Promise<void> {\n console.log(`❓ Starting ask_followup_question tool call flow: ${messageId}`);\n\n const toolCallId = `tool-afq-${Date.now()}`;\n\n // 问题数据 - 与 genie-ide 保持一致的数据结构\n const question = '你希望创建什么类型的项目?';\n const options = [\n 'Web 应用(前端 + 后端)',\n '命令行工具(CLI)',\n '移动应用(React Native / Flutter)',\n '桌面应用(Electron)',\n '后端服务(API / 微服务)',\n ];\n\n // 1. 发送 tool_call (pending)\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'ask_followup_question',\n },\n },\n update: {\n sessionUpdate: 'tool_call',\n toolCallId,\n title: 'Ask Followup Question',\n kind: 'other',\n status: 'pending',\n rawInput: {\n question,\n options: JSON.stringify(options),\n },\n },\n } as SessionNotification,\n });\n\n await this.delay(100);\n\n // 2. 发送 tool_call_update (in_progress) - 显示问题\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'ask_followup_question',\n },\n },\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'in_progress',\n rawInput: {\n question,\n options: JSON.stringify(options),\n },\n },\n } as SessionNotification,\n });\n\n console.log('[MockAgentProvider] ask_followup_question tool displayed, waiting for user interaction...');\n // 工具显示完成,等待用户交互(暂未实现交互逻辑)\n }\n\n /**\n * 发送 list_dir 工具调用流程 (符合 ACP 协议)\n *\n * 用于模拟列出目录中的文件\n * 数据结构符合 tool-schemas.ts 中的 ListDirInput 和 ListFilesResult\n */\n private async sendMockListFilesToolCallFlow(sessionId: string, messageId: string): Promise<void> {\n console.log(`📁 Starting list_dir tool call flow: ${messageId}`);\n\n const target_directory = '/Users/test/project/src';\n const toolCallId = `tool-ld-${Date.now()}`;\n\n // Mock 文件列表数据 - 符合 ListFilesResult.files 格式\n const mockFiles = [\n { filePath: `${target_directory}/index.ts`, size: '2.5 KB', modifyTime: '2024-01-15 10:30:00' },\n { filePath: `${target_directory}/App.tsx`, size: '8.2 KB', modifyTime: '2024-01-15 09:45:00' },\n { filePath: `${target_directory}/utils.ts`, size: '1.8 KB', modifyTime: '2024-01-14 16:20:00' },\n { filePath: `${target_directory}/components/`, size: '-', modifyTime: '2024-01-15 11:00:00' },\n { filePath: `${target_directory}/hooks/`, size: '-', modifyTime: '2024-01-14 14:30:00' },\n { filePath: `${target_directory}/styles/`, size: '-', modifyTime: '2024-01-13 09:00:00' },\n { filePath: `${target_directory}/types.d.ts`, size: '3.1 KB', modifyTime: '2024-01-12 18:45:00' },\n { filePath: `${target_directory}/constants.ts`, size: '0.9 KB', modifyTime: '2024-01-10 12:00:00' },\n ];\n\n // 生成 listing 格式的文本输出\n const listing = mockFiles\n .map(f => {\n const name = f.filePath.split('/').pop() || '';\n const isDir = f.filePath.endsWith('/');\n return isDir ? `📁 ${name}` : `📄 ${name} (${f.size})`;\n })\n .join('\\n');\n\n // 1. 发送 tool_call (pending)\n // rawInput 符合 ListDirInput: { target_directory, ignore_globs? }\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'list_dir',\n },\n },\n update: {\n sessionUpdate: 'tool_call',\n toolCallId,\n title: 'List Directory',\n kind: 'search',\n status: 'pending',\n locations: [{ path: target_directory, line: 0 }],\n rawInput: {\n target_directory,\n // ignore_globs 是可选的,这里不传\n },\n },\n } as SessionNotification,\n });\n\n await this.delay(100);\n\n // 2. 发送 tool_call_update (in_progress)\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'list_dir',\n },\n },\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'in_progress',\n content: [\n {\n type: 'content',\n content: {\n type: 'text',\n text: `Listing directory ${target_directory}...`,\n },\n },\n ],\n locations: [{ path: target_directory, line: 0 }],\n },\n } as SessionNotification,\n });\n\n await this.delay(300);\n\n // 3. 发送 tool_call_update (completed) 包含文件列表\n // rawOutput 符合 ListFilesResult: { type, files, root, listing? }\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'list_dir',\n },\n },\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'completed',\n content: [\n {\n type: 'content',\n content: {\n type: 'text',\n text: `Listed ${mockFiles.length} items in ${target_directory}`,\n },\n },\n ],\n locations: [{ path: target_directory, line: 0 }],\n rawOutput: {\n type: 'list_files_result',\n files: mockFiles,\n root: target_directory,\n listing: listing,\n },\n },\n } as SessionNotification,\n });\n\n console.log('[MockAgentProvider] list_dir tool call completed');\n }\n\n /**\n * 发送 preview_url 工具调用流程 (符合 ACP 协议)\n *\n * 用于测试 unknown-tool-renderer 的显示效果\n * preview_url 是一个未知工具,会使用 UnknownToolRenderer 渲染\n */\n private async sendMockPreviewUrlToolCallFlow(sessionId: string, messageId: string): Promise<void> {\n console.log(`🌐 Starting preview_url tool call flow: ${messageId}`);\n\n const toolCallId = `tool-pu-${Date.now()}`;\n const url = 'https://example.com/preview';\n\n // 1. 发送 tool_call (pending)\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'preview_url',\n },\n },\n update: {\n sessionUpdate: 'tool_call',\n toolCallId,\n title: 'Preview URL',\n kind: 'other',\n status: 'pending',\n rawInput: {\n url,\n },\n },\n } as SessionNotification,\n });\n\n await this.delay(200);\n\n // 2. 发送 tool_call_update (in_progress)\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'preview_url',\n },\n },\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'in_progress',\n content: [\n {\n type: 'content',\n content: {\n type: 'text',\n text: `Loading preview for ${url}...`,\n },\n },\n ],\n },\n } as SessionNotification,\n });\n\n await this.delay(800);\n\n // 3. 发送 tool_call_update (completed)\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'preview_url',\n },\n },\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'completed',\n content: [\n {\n type: 'content',\n content: {\n type: 'text',\n text: `Preview loaded successfully for ${url}`,\n },\n },\n ],\n rawOutput: {\n url,\n title: 'Example Domain',\n screenshot: 'base64-encoded-screenshot-data...',\n status: 200,\n },\n },\n } as SessionNotification,\n });\n\n console.log('[MockAgentProvider] preview_url tool call completed');\n }\n\n /**\n * 发送 list_code_definition_names 工具调用流程 (符合 ACP 协议)\n *\n * 用于测试 unknown-tool-renderer 的显示效果\n * list_code_definition_names 是一个未知工具,会使用 UnknownToolRenderer 渲染\n */\n private async sendMockListCodeDefinitionNamesToolCallFlow(sessionId: string, messageId: string): Promise<void> {\n console.log(`📝 Starting list_code_definition_names tool call flow: ${messageId}`);\n\n const toolCallId = `tool-lcd-${Date.now()}`;\n const filePath = '/Users/test/project/src/utils.ts';\n\n // 1. 发送 tool_call (pending)\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'list_code_definition_names',\n },\n },\n update: {\n sessionUpdate: 'tool_call',\n toolCallId,\n title: 'List Code Definitions',\n kind: 'other',\n status: 'pending',\n rawInput: {\n filePath,\n },\n },\n } as SessionNotification,\n });\n\n await this.delay(200);\n\n // 2. 发送 tool_call_update (in_progress)\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'list_code_definition_names',\n },\n },\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'in_progress',\n content: [\n {\n type: 'content',\n content: {\n type: 'text',\n text: `Analyzing code definitions in ${filePath}...`,\n },\n },\n ],\n },\n } as SessionNotification,\n });\n\n await this.delay(600);\n\n // 3. 发送 tool_call_update (completed)\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'list_code_definition_names',\n },\n },\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'completed',\n content: [\n {\n type: 'content',\n content: {\n type: 'text',\n text: `Found 5 code definitions in ${filePath}`,\n },\n },\n ],\n rawOutput: {\n filePath,\n definitions: [\n { name: 'formatDate', type: 'function', line: 5 },\n { name: 'parseJSON', type: 'function', line: 15 },\n { name: 'debounce', type: 'function', line: 28 },\n { name: 'Config', type: 'interface', line: 42 },\n { name: 'DEFAULT_OPTIONS', type: 'const', line: 55 },\n ],\n },\n },\n } as SessionNotification,\n });\n\n console.log('[MockAgentProvider] list_code_definition_names tool call completed');\n }\n\n /**\n * 发送 web_fetch 工具调用流程 (符合 ACP 协议)\n *\n * 用于模拟从 URL 获取网页内容的工具调用\n */\n private async sendMockWebFetchToolCallFlow(sessionId: string, messageId: string): Promise<void> {\n console.log(`🌐 Starting web_fetch tool call flow: ${messageId}`);\n\n const toolCallId = `tool-wf-${Date.now()}`;\n const targetUrl = 'https://github.com/anthropics/claude-code';\n\n // 1. 发送 tool_call (pending)\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'web_fetch',\n },\n },\n update: {\n sessionUpdate: 'tool_call',\n toolCallId,\n title: 'Web Fetch',\n kind: 'other',\n status: 'pending',\n rawInput: {\n url: targetUrl,\n fetchInfo: 'Fetching page content...',\n },\n },\n } as SessionNotification,\n });\n\n await this.delay(200);\n\n // 2. 流式发送 rawInput(模拟 URL 逐步到达)\n const urlChunks = [\n 'https://github.com/',\n 'anthropics/',\n 'claude-code',\n ];\n\n let accumulatedUrl = '';\n for (const chunk of urlChunks) {\n accumulatedUrl += chunk;\n\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'web_fetch',\n },\n },\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'in_progress',\n rawInput: {\n url: accumulatedUrl,\n fetchInfo: 'Fetching page content...',\n },\n },\n } as SessionNotification,\n });\n await this.delay(100);\n console.log('[MockAgentProvider] web_fetch tool_call_update with rawInput:', chunk);\n }\n\n await this.delay(500);\n\n // 3. 模拟获取进度\n const progressSteps = [\n { loading: 'Connecting to server...' },\n { loading: 'Downloading content...' },\n { loading: 'Parsing HTML...' },\n ];\n\n for (const step of progressSteps) {\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'web_fetch',\n },\n },\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'in_progress',\n rawInput: {\n url: targetUrl,\n fetchInfo: step.loading,\n },\n rawOutput: {\n loading: step.loading,\n },\n },\n } as SessionNotification,\n });\n console.log(`🌐 Fetch progress: ${step.loading}`);\n await this.delay(300);\n }\n\n // 4. 发送完成事件,包含模拟的网页内容\n const mockWebContent = `# Claude Code\n\nClaude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster through natural conversation.\n\n## Features\n\n- **Agentic coding**: Claude Code can read, write, and edit files, run commands, and more.\n- **Context-aware**: Claude Code understands your entire codebase and can answer questions about it.\n- **Natural conversation**: Just describe what you want to do in plain English.\n\n## Installation\n\n\\`\\`\\`bash\nnpm install -g @anthropic-ai/claude-code\n\\`\\`\\`\n\n## Usage\n\n\\`\\`\\`bash\nclaude-code\n\\`\\`\\`\n\nStart a conversation with Claude Code and let it help you with your coding tasks!`;\n\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'web_fetch',\n },\n },\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'completed',\n rawInput: {\n url: targetUrl,\n fetchInfo: 'Fetch web page content',\n },\n rawOutput: {\n title: 'Claude Code - GitHub',\n favicon: 'https://github.githubassets.com/favicons/favicon.svg',\n data: mockWebContent,\n },\n },\n } as SessionNotification,\n });\n\n console.log('[MockAgentProvider] web_fetch tool_call_update (completed) sent');\n\n // 5. 发送总结消息\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId: `${messageId}-summary`,\n timestamp: Date.now(),\n notification: {\n sessionId,\n update: {\n sessionUpdate: 'agent_message_chunk',\n content: {\n type: 'text',\n text: '🌐 **Web Fetch 工具调用演示完成**\\n\\n**工具调用流程:**\\n1. `tool_call` (pending) - 创建 web_fetch 工具调用\\n2. `tool_call_update` (in_progress) - 流式发送 URL 和获取进度\\n3. `tool_call_update` (completed) - 返回网页内容\\n\\n**rawInput 包含:**\\n- `url`: 目标 URL\\n- `fetchInfo`: 获取说明\\n\\n**rawOutput 包含:**\\n- `title`: 网页标题\\n- `favicon`: 网站图标\\n- `data`: 网页内容(Markdown 格式)',\n },\n },\n } as SessionNotification,\n });\n\n await this.delay(100);\n }\n\n /**\n * 发送 web_search 工具调用流程 (符合 ACP 协议)\n *\n * 用于模拟网络搜索的工具调用\n * 数据结构符合 tool-schemas.ts 中的 web_search 定义\n */\n private async sendMockWebSearchToolCallFlow(sessionId: string, messageId: string): Promise<void> {\n console.log(`🔍 Starting web_search tool call flow: ${messageId}`);\n\n const toolCallId = `tool-ws-${Date.now()}`;\n const searchTerm = 'TypeScript 5.0 new features';\n const explanation = 'Searching for the latest TypeScript 5.0 features to provide accurate and up-to-date information.';\n\n // 1. 发送 tool_call (pending)\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'web_search',\n },\n },\n update: {\n sessionUpdate: 'tool_call',\n toolCallId,\n title: 'Web Search',\n kind: 'search',\n status: 'pending',\n rawInput: {\n searchTerm,\n explanation,\n },\n },\n } as SessionNotification,\n });\n\n await this.delay(200);\n\n // 2. 发送 tool_call_update (in_progress) - 流式显示搜索中\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'web_search',\n },\n },\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'in_progress',\n content: [\n {\n type: 'content',\n content: {\n type: 'text',\n text: `🔍 Searching the web for \"${searchTerm}\"...`,\n },\n },\n ],\n rawInput: {\n searchTerm,\n explanation,\n },\n },\n } as SessionNotification,\n });\n\n await this.delay(800);\n\n // 3. 发送 tool_call_update (completed) - 包含搜索结果\n const searchResults = [\n {\n title: 'Announcing TypeScript 5.0 - TypeScript Blog',\n url: 'https://devblogs.microsoft.com/typescript/announcing-typescript-5-0/',\n snippet: 'TypeScript 5.0 brings many new features, including decorators, const type parameters, and improvements to enums. This release also includes significant performance improvements...',\n publishedDate: '2023-03-16',\n },\n {\n title: 'TypeScript 5.0: What\\'s New - LogRocket Blog',\n url: 'https://blog.logrocket.com/whats-new-typescript-5-0/',\n snippet: 'TypeScript 5.0 introduces several exciting features: ECMAScript decorators, const type parameters, multiple config extends, all enums are union enums, and more...',\n publishedDate: '2023-04-10',\n },\n {\n title: 'TypeScript 5.0 Release Notes - GitHub',\n url: 'https://github.com/microsoft/TypeScript/releases/tag/v5.0.0',\n snippet: 'Official release notes for TypeScript 5.0. Key highlights include: Decorators, const Type Parameters, Supporting Multiple Configuration Files in extends...',\n publishedDate: '2023-03-16',\n },\n {\n title: 'A Complete Guide to TypeScript 5.0 Features - Medium',\n url: 'https://medium.com/typescript-5-features-guide',\n snippet: 'Explore all the new features in TypeScript 5.0: decorators with metadata, const type parameters for better type inference, improved module resolution...',\n publishedDate: '2023-05-22',\n },\n {\n title: 'TypeScript 5.0 Performance Improvements',\n url: 'https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-0.html',\n snippet: 'TypeScript 5.0 includes significant performance improvements: faster type checking, reduced memory usage, and improved build times. Package size reduced by 50%...',\n publishedDate: '2023-03-16',\n },\n ];\n\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'web_search',\n },\n },\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'completed',\n content: [\n {\n type: 'content',\n content: {\n type: 'text',\n text: `Found ${searchResults.length} results for \"${searchTerm}\"`,\n },\n },\n ],\n rawInput: {\n searchTerm,\n explanation,\n },\n rawOutput: {\n query: searchTerm,\n totalResults: searchResults.length,\n results: searchResults,\n searchEngine: 'web',\n timestamp: new Date().toISOString(),\n },\n },\n } as SessionNotification,\n });\n\n // 4. 发送总结消息\n await this.delay(300);\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId: `${messageId}-summary`,\n timestamp: Date.now(),\n notification: {\n sessionId,\n update: {\n sessionUpdate: 'agent_message_chunk',\n content: {\n type: 'text',\n text: `🔍 **Web 搜索完成**\\n\\n**搜索词:** \\`${searchTerm}\\`\\n\\n**搜索结果:** 找到 ${searchResults.length} 个相关结果\\n\\n**主要发现:**\\n1. **TypeScript 5.0 新特性** - 包括装饰器、const 类型参数、枚举改进等\\n2. **性能提升** - 类型检查更快,内存使用减少,包大小减少 50%\\n3. **配置增强** - 支持多配置文件继承\\n\\n**工具调用流程:**\\n1. \\`tool_call\\` (pending) - 创建搜索工具调用\\n2. \\`tool_call_update\\` (in_progress) - 执行网络搜索\\n3. \\`tool_call_update\\` (completed) - 返回搜索结果\\n\\n**rawInput 包含:**\\n- \\`searchTerm\\`: 搜索关键词\\n- \\`explanation\\`: 搜索原因说明\\n\\n**rawOutput 包含:**\\n- \\`query\\`: 搜索查询\\n- \\`totalResults\\`: 结果总数\\n- \\`results\\`: 搜索结果数组(包含 title、url、snippet、publishedDate)`,\n },\n },\n } as SessionNotification,\n });\n\n console.log('[MockAgentProvider] web_search tool call completed');\n }\n\n /**\n * 发送 read_lints 工具调用流程 (符合 ACP 协议)\n *\n * 数据结构 (来自 tool-schemas.ts):\n * - Input: ReadLintsInput = { paths?: string }\n * - Output: ReadLintsResult = {\n * type: 'read_lints_result';\n * diagnostics: string[];\n * totalCount?: number;\n * hint?: string;\n * isTruncated?: boolean;\n * }\n */\n private async sendMockReadLintsToolCallFlow(sessionId: string, messageId: string): Promise<void> {\n console.log(`🔍 Starting read_lints tool call flow: ${messageId}`);\n\n const toolCallId = `tool-rl-${Date.now()}`;\n const targetPath = '/Users/test/project/src/components/Button.tsx';\n\n // 1. 发送 tool_call (pending)\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'read_lints',\n },\n },\n update: {\n sessionUpdate: 'tool_call',\n toolCallId,\n title: 'Read Lints',\n kind: 'read',\n status: 'pending',\n rawInput: {\n paths: targetPath,\n },\n },\n } as SessionNotification,\n });\n\n await this.delay(200);\n\n // 2. 发送 tool_call_update (in_progress)\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'read_lints',\n },\n },\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'in_progress',\n rawInput: {\n paths: targetPath,\n },\n },\n } as SessionNotification,\n });\n\n await this.delay(300);\n\n // 3. 发送 tool_call_update (completed) - 包含 lint 错误\n const diagnosticsText = `Button.tsx - ERROR (3 issues)\n[ERROR] Line 15, Column 8: 'useState' is defined but never used. Consider removing this import.\n[ERROR] Line 23, Column 12: Type 'string' is not assignable to type 'number'. Expected a numeric value.\n[ERROR] Line 45, Column 4: Missing return statement in function that is expected to return 'ReactNode'.`;\n\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'read_lints',\n },\n },\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'completed',\n rawInput: {\n paths: targetPath,\n },\n rawOutput: {\n type: 'read_lints_result',\n diagnostics: [diagnosticsText],\n totalCount: 3,\n hint: 'Found 3 lint errors in Button.tsx',\n isTruncated: false,\n },\n },\n } as SessionNotification,\n });\n\n console.log('[MockAgentProvider] read_lints tool call completed');\n }\n\n /**\n * 发送 execute_command 工具调用流程 (符合 ACP 协议)\n *\n * 数据结构 (来自 tool-schemas.ts):\n * - Input: ExecuteCommandInput = { command: string; requires_approval: boolean; }\n * - Output: ExecuteCommandResult = {\n * type: 'execute_command_result';\n * stdout: string;\n * stderr: string;\n * exitCode: number;\n * hint?: string;\n * serviceInfo?: { isWatchCommand, isServiceOutput, serviceReady, message };\n * use_standalone_terminal?: boolean;\n * }\n */\n private async sendMockExecuteCommandToolCallFlow(sessionId: string, messageId: string): Promise<void> {\n console.log(`💻 Starting execute_command tool call flow: ${messageId}`);\n const toolCallId = `tool-ec-${Date.now()}`;\n const command = 'npm run build';\n // 1. 发送 tool_call (pending)\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'execute_command',\n },\n },\n update: {\n sessionUpdate: 'tool_call',\n toolCallId,\n title: 'Execute Command',\n kind: 'execute',\n status: 'pending',\n rawInput: {\n command,\n requires_approval: false,\n },\n },\n } as SessionNotification,\n });\n await this.delay(200);\n // 2. 发送 tool_call_update (in_progress) - 模拟命令执行中\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'execute_command',\n },\n },\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'in_progress',\n content: [\n {\n type: 'content',\n content: {\n type: 'text',\n text: '> npm run build\\n\\nRunning build script...',\n },\n },\n ],\n },\n } as SessionNotification,\n });\n await this.delay(1000);\n // 3. 发送 tool_call_update (completed) - 命令执行完成\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'execute_command',\n },\n },\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'completed',\n content: [\n {\n type: 'content',\n content: {\n type: 'text',\n text: '> npm run build\\n\\n> genie@1.0.0 build\\n> tsc -b\\n\\nBuild completed successfully.',\n },\n },\n ],\n rawOutput: {\n type: 'execute_command_result',\n stdout: '> genie@1.0.0 build\\n> tsc -b\\n\\nBuild completed successfully.',\n stderr: '',\n exitCode: 0,\n hint: 'Build completed in 2.5s',\n },\n },\n } as SessionNotification,\n });\n console.log('[MockAgentProvider] execute_command tool call completed');\n }\n /**\n * 发送 execute_command 工具调用流程(需要权限确认)(符合 ACP 协议)\n *\n * 这个方法模拟需要用户确认才能执行的命令\n * 用于测试权限确认菜单 (Run/Skip/Reject)\n *\n * 数据结构 (来自 tool-schemas.ts):\n * - Input: ExecuteCommandInput = { command: string; requires_approval: boolean; }\n *\n * 权限请求通过 rawInput.permissionRequest 字段传递:\n * - permissionRequest.options: 可选的权限选项数组\n */\n private async sendMockExecuteCommandWithApprovalToolCallFlow(sessionId: string, messageId: string): Promise<void> {\n console.log(`💻 Starting execute_command (with approval) tool call flow: ${messageId}`);\n const toolCallId = `tool-ec-approval-${Date.now()}`;\n const command = 'rm -rf node_modules && npm install';\n // 权限请求选项 - 与 ACP 协议的 PermissionOption 结构一致\n const permissionRequest = {\n options: [\n { optionId: 'allow-once', name: '运行', kind: 'allow_once' },\n { optionId: 'skip-once', name: '跳过', kind: 'skip_once' },\n { optionId: 'reject-once', name: '拒绝', kind: 'reject_once' },\n ],\n };\n // 1. 发送 tool_call (pending) - 需要权限确认\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'execute_command',\n },\n },\n update: {\n sessionUpdate: 'tool_call',\n toolCallId,\n title: 'Execute Command',\n kind: 'execute',\n status: 'pending',\n rawInput: {\n command,\n requires_approval: true, // 保留向后兼容\n permissionRequest, // 新增:权限请求信息\n },\n },\n } as SessionNotification,\n });\n await this.delay(200);\n // 2. 发送 tool_call_update (in_progress) - 等待用户确认\n // 这时 UI 应该显示权限确认菜单 (Run/Skip/Reject)\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'execute_command',\n },\n },\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'pending', // 保持 pending 状态等待用户审批\n content: [\n {\n type: 'content',\n content: {\n type: 'text',\n text: `$ ${command}\\n\\nWaiting for approval...`,\n },\n },\n ],\n rawInput: {\n command,\n requires_approval: true,\n permissionRequest, // 确保 rawInput 中也包含权限请求\n },\n },\n } as SessionNotification,\n });\n console.log('[MockAgentProvider] execute_command (with approval) tool call waiting for user approval');\n // 注意:这里不发送 completed,等待用户在 UI 上点击 Run/Skip/Reject\n }\n /**\n * 发送 write_to_file 工具调用流程(需要权限确认)(符合 ACP 协议)\n *\n * 这个方法模拟需要用户确认才能执行的文件写入\n * 用于测试权限确认菜单 (允许/跳过/拒绝)\n *\n * 权限请求通过 rawInput.permissionRequest 字段传递:\n * - permissionRequest.options: 可选的权限选项数组\n */\n private async sendMockWriteFileWithApprovalToolCallFlow(sessionId: string, messageId: string): Promise<void> {\n console.log(`📝 Starting write_to_file (with approval) tool call flow: ${messageId}`);\n const toolCallId = `tool-wtf-approval-${Date.now()}`;\n const filePath = '/Users/test/project/src/config.ts';\n const content = `export const config = {\n apiUrl: 'https://api.example.com',\n debug: true,\n timeout: 5000,\n};`;\n // 权限请求选项 - 与 ACP 协议的 PermissionOption 结构一致\n const permissionRequest = {\n options: [\n { optionId: 'allow-once', name: '允许', kind: 'allow_once' },\n { optionId: 'skip-once', name: '跳过', kind: 'skip_once' },\n { optionId: 'reject-once', name: '拒绝', kind: 'reject_once' },\n ],\n };\n // 1. 发送 tool_call (pending) - 需要权限确认\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'write_to_file',\n },\n },\n update: {\n sessionUpdate: 'tool_call',\n toolCallId,\n title: 'Write File',\n kind: 'edit',\n status: 'pending',\n locations: [{ path: filePath, line: 0 }],\n rawInput: {\n filePath,\n content,\n permissionRequest, // 权限请求信息\n },\n },\n } as SessionNotification,\n });\n await this.delay(200);\n // 2. 发送 tool_call_update (pending) - 等待用户确认\n // 这时 UI 应该显示权限确认菜单\n this.emitEvent({\n type: 'session_update',\n sessionId,\n messageId,\n timestamp: Date.now(),\n notification: {\n sessionId,\n _meta: {\n 'codebuddy.ai': {\n toolName: 'write_to_file',\n },\n },\n update: {\n sessionUpdate: 'tool_call_update',\n toolCallId,\n status: 'pending', // 保持 pending 状态等待用户审批\n content: [\n {\n type: 'content',\n content: {\n type: 'text',\n text: content,\n },\n },\n ],\n locations: [{ path: filePath, line: 0 }],\n rawInput: {\n filePath,\n content,\n permissionRequest, // 确保 rawInput 中也包含权限请求\n },\n },\n } as SessionNotification,\n });\n console.log('[MockAgentProvider] write_to_file (with approval) tool call waiting for user approval');\n // 注意:这里不发送 completed,等待用户在 UI 上点击 允许/跳过/拒绝\n }\n}\n","/**\n * Protocol Extension Types for Agent Client Protocol\n *\n * This file contains codebuddy.ai extension types that extend the base ACP protocol.\n * For SDK type re-exports and capability extensions, see ./sdk.ts\n */\n\n// ============================================\n// Extension Method Constants\n// ============================================\n\n/**\n * Extension method names as const for type safety\n */\nexport const ExtensionMethod = {\n ARTIFACT: '_codebuddy.ai/artifact',\n /**\n * Question/ToolInput extension method.\n * Used for tools that require user input (e.g., AskUserQuestion).\n * Request: ToolInputRequest, Response: ToolInputResponse\n */\n QUESTION: '_codebuddy.ai/question',\n CHECKPOINT: '_codebuddy.ai/checkpoint',\n /** Usage notification for token/cost tracking */\n USAGE: '_codebuddy.ai/usage',\n /** Command extension method for executing custom commands */\n COMMAND: '_codebuddy.ai/command',\n /** Auth URL notification for external authentication */\n AUTH_URL: '_codebuddy.ai/authUrl',\n /** File history snapshot for checkpoint processing */\n FILE_HISTORY_SNAPSHOT: '_codebuddy.ai/file_history_snapshot',\n /** Delegate tool execution from external client-side tool provider */\n DELEGATE_TOOL: '_codebuddy.ai/delegateTool',\n /** Notification when available delegate tools change */\n DELEGATE_TOOLS_CHANGED: '_codebuddy.ai/delegateToolsChanged',\n /** UI control for operating Web UI elements */\n UI_CONTROL: '_codebuddy.ai/uiControl',\n} as const;\n\nexport type ExtensionMethodName = (typeof ExtensionMethod)[keyof typeof ExtensionMethod];\n\n/**\n * All known extension methods\n */\nexport const KNOWN_EXTENSIONS = [\n ExtensionMethod.ARTIFACT,\n ExtensionMethod.QUESTION,\n ExtensionMethod.CHECKPOINT,\n ExtensionMethod.USAGE,\n ExtensionMethod.COMMAND,\n ExtensionMethod.AUTH_URL,\n ExtensionMethod.FILE_HISTORY_SNAPSHOT,\n ExtensionMethod.DELEGATE_TOOL,\n ExtensionMethod.DELEGATE_TOOLS_CHANGED,\n] as const;\n\n// ============================================\n// Extension Notification Types (Discriminated Union)\n// ============================================\n\n/**\n * Discriminated union for extension notifications\n * Use `method` field as discriminant for type narrowing\n */\nexport type ExtensionNotification = ArtifactExtNotification;\n\nexport interface ArtifactExtNotification {\n method: typeof ExtensionMethod.ARTIFACT;\n params: ArtifactNotificationParams;\n}\n\n// ============================================\n// Artifact Types\n// ============================================\n\n/**\n * Types of artifacts that can be created by the agent\n * Uses discriminant for TypeScript type narrowing\n */\nexport type ArtifactType = 'plan' | 'tasks' | 'media' | 'overview';\n\n/**\n * Artifact lifecycle events\n */\nexport type ArtifactEvent = 'created' | 'updated' | 'deleted';\n\n/**\n * Base Artifact interface\n * Inspired by MCP Resource: https://modelcontextprotocol.io/specification/2025-11-25/server/resources\n */\nexport interface BaseArtifact<T extends ArtifactType = ArtifactType> {\n /** Artifact type (discriminant for type narrowing) */\n type: T;\n /**\n * Unique identifier URI\n * - Cloud Agent: agent:///{path} e.g. agent:///artifacts/plan.md\n * - Local Agent: file:///{path} e.g. file:///Users/xxx/project/plan.md\n */\n uri: string;\n /** Resource name */\n name: string;\n /** Display title */\n title?: string;\n /** Description */\n description?: string;\n}\n\n// ============================================\n// Plan Artifact\n// ============================================\n\n/**\n * Plan Artifact - Markdown document\n * mimeType: text/markdown\n */\nexport interface PlanArtifact extends BaseArtifact<'plan'> {\n /** MIME type fixed as text/markdown */\n mimeType: 'text/markdown';\n /** Markdown text content */\n text: string;\n /** Version number (for diff) */\n version?: number;\n /** Previous version content (for diff display) */\n previousText?: string;\n /** Whether editing is enabled */\n enableEdit?: boolean;\n}\n\n// ============================================\n// Tasks Artifact\n// ============================================\n\n/**\n * Task item status\n */\nexport type TaskItemStatus = 'pending' | 'in_progress' | 'completed' | 'cancelled';\n\n/**\n * Single task item\n */\nexport interface TaskItem {\n id: string;\n content: string;\n status: TaskItemStatus;\n order?: number;\n}\n\n/**\n * Tasks Artifact - Task list\n * mimeType: application/json\n */\nexport interface TasksArtifact extends BaseArtifact<'tasks'> {\n /** MIME type fixed as application/json */\n mimeType: 'application/json';\n /** Task list */\n tasks: TaskItem[];\n /** Whether editing is enabled */\n enableEdit?: boolean;\n}\n\n// ============================================\n// Media Artifact\n// ============================================\n\n/**\n * Media content type (auxiliary classification)\n */\nexport type MediaContentType = 'image' | 'video' | 'audio' | 'document' | 'spreadsheet' | 'presentation' | 'diagram' | 'code';\n\n/**\n * Media Artifact - Media files\n * Supports images, videos, documents and other browser-renderable files\n *\n * URI schemes:\n * - data:image/png;base64,... (inline small files)\n * - agent:///artifacts/... (cloud agent resources)\n * - file:///path/to/file (local agent files)\n */\nexport interface MediaArtifact extends BaseArtifact<'media'> {\n /** MIME type, e.g. image/png, video/mp4, application/pdf */\n mimeType: string;\n /** File size in bytes */\n size?: number;\n /** Media content classification (auxiliary for frontend rendering) */\n contentType?: MediaContentType;\n /** Width (for images/videos) */\n width?: number;\n /** Height (for images/videos) */\n height?: number;\n}\n\n// ============================================\n// Overview Artifact\n// ============================================\n\n/**\n * Overview Artifact - 任务完成后的总结文档\n * mimeType: text/markdown\n */\nexport interface OverviewArtifact extends BaseArtifact<'overview'> {\n /** MIME type fixed as text/markdown */\n mimeType: 'text/markdown';\n /** Markdown text content */\n text?: string;\n}\n\n// ============================================\n// Artifact Union Type\n// ============================================\n\n/**\n * Artifact union type\n * Uses type field for discriminated union\n */\nexport type Artifact = PlanArtifact | TasksArtifact | MediaArtifact | OverviewArtifact;\n\n// ============================================\n// Artifact Notification Types (Discriminated Union by event)\n// ============================================\n\nexport interface ArtifactCreatedParams {\n sessionId: string;\n event: 'created';\n artifact: Artifact;\n}\n\nexport interface ArtifactUpdatedParams {\n sessionId: string;\n event: 'updated';\n artifact: Artifact;\n}\n\nexport interface ArtifactDeletedParams {\n sessionId: string;\n event: 'deleted';\n artifact: Pick<Artifact, 'type' | 'uri'>; // Only type and uri needed for deletion\n}\n\n/**\n * Artifact notification discriminated by event\n */\nexport type ArtifactNotificationParams =\n | ArtifactCreatedParams\n | ArtifactUpdatedParams\n | ArtifactDeletedParams;\n\n// ============================================\n// Question Types\n// ============================================\n\n/**\n * Question option structure\n */\nexport interface QuestionOption {\n /** Display text (1-5 words) */\n label: string;\n /** Option description */\n description: string;\n}\n\n/**\n * Single question structure\n */\nexport interface UserQuestion {\n /** Question ID */\n id: string;\n /** Question text */\n question: string;\n /** Short label (max 12 chars) */\n header?: string;\n /** Available options (2-4) */\n options: QuestionOption[];\n /** Allow multiple selections */\n multiSelect?: boolean;\n}\n\n/**\n * Question request (Server -> Client)\n * Sent via extMethod: _codebuddy.ai/question\n */\nexport interface QuestionRequest {\n /** Session ID */\n sessionId: string;\n /** Associated tool call ID (links extMethod to tool_call for UI) */\n toolCallId: string;\n /** Input type */\n inputType?: string;\n /** Schema containing questions */\n schema?: {\n /** Questions to ask (1-4) */\n questions: UserQuestion[];\n };\n /** Questions to ask (1-4) - legacy format */\n questions?: UserQuestion[];\n /** Request timeout in ms */\n timeout?: number;\n}\n\n/**\n * Question response (Client -> Server)\n */\nexport interface QuestionResponse {\n /** Response outcome */\n outcome: 'submitted' | 'cancelled';\n /** User's answers keyed by question ID (when submitted) */\n answers?: Record<string, string | string[]>;\n /** Cancellation reason (when cancelled) */\n reason?: string;\n}\n\n// ============================================\n// Usage Update Types\n// ============================================\n\n/**\n * Token usage information\n * Sent via extNotification: _codebuddy.ai/usage\n */\nexport interface UsageUpdate {\n sessionId: string;\n inputTokens?: number;\n outputTokens?: number;\n totalTokens?: number;\n cost?: number;\n model?: string;\n _meta?: Record<string, unknown>;\n}\n\n// ============================================\n// Command Types\n// ============================================\n\n/**\n * Command notification parameters\n * Sent via extNotification: _codebuddy.ai/command\n */\nexport interface CommandNotificationParams {\n /** Session ID */\n sessionId: string;\n /** Command action to execute */\n action: string;\n /** Command parameters */\n params?: Record<string, unknown>;\n}\n\n// ============================================\n// Checkpoint Types\n// ============================================\n\n/**\n * Checkpoint event types\n */\nexport type CheckpointEvent = 'created' | 'updated';\n\n/**\n * Checkpoint notification parameters\n * Sent via extNotification: _codebuddy.ai/checkpoint\n */\nexport interface CheckpointNotificationParams {\n /** Session ID */\n sessionId: string;\n /** Event type */\n event: CheckpointEvent;\n /** Checkpoint information */\n checkpoint: CheckpointInfo;\n}\n\n/**\n * Checkpoint information visible to clients\n */\nexport interface CheckpointInfo {\n /** Checkpoint ID */\n id: string;\n /** Label/description */\n label?: string;\n /** Creation timestamp */\n createdAt: number;\n /** File change summary */\n fileChanges: FileChangeSummary;\n}\n\n/**\n * File change summary for a checkpoint\n */\nexport interface FileChangeSummary {\n /** List of changed files */\n files: FileChangeInfo[];\n /** Total lines added */\n totalAdditions: number;\n /** Total lines deleted */\n totalDeletions: number;\n}\n\n/**\n * Change type for a file\n */\nexport type FileChangeType = 'created' | 'modified' | 'deleted';\n\n/**\n * Information about a single file change\n */\nexport interface FileChangeInfo {\n /** File URI (agent://files/{path}) */\n uri: string;\n /** Type of change */\n changeType: FileChangeType;\n /** Lines added */\n additions: number;\n /** Lines deleted */\n deletions: number;\n /** Unified diff format content\n * https://unifiedjs.com/explore/package/unified-diff/\n */\n diff?: string;\n /** File language */\n language?: string;\n}\n\n// ============================================\n// Auth URL Types\n// ============================================\n\n/**\n * Auth URL notification parameters\n * Sent via extNotification: _codebuddy.ai/authUrl\n *\n * Used when the Agent CLI attempts to open an external browser for OAuth authentication.\n * The client displays this URL so users can manually copy and open it if the browser\n * doesn't open automatically.\n */\nexport interface AuthUrlNotificationParams {\n /** The authentication URL to display */\n authUrl: string;\n /** Optional authentication provider identifier (e.g., 'oauth', 'external') */\n provider?: string;\n}\n\n// ============================================\n// Session Update Meta Types\n// ============================================\n\n/**\n * Mode for session update messages\n * - 'stream': Real-time updates during prompt execution (should be broadcast)\n * - 'history': Historical messages during session/load (should NOT be broadcast)\n */\nexport type SessionUpdateMode = 'stream' | 'history';\n\n/**\n * codebuddy.ai extension metadata for session updates\n */\nexport interface SessionUpdateCodebuddyMeta {\n /** Mode indicating the source of this update */\n mode?: SessionUpdateMode;\n}\n\n/**\n * _meta structure for session update notifications\n */\nexport interface SessionUpdateMeta {\n 'codebuddy.ai'?: SessionUpdateCodebuddyMeta;\n [key: string]: unknown;\n}\n\n// ============================================\n// Delegate Tool Types\n// ============================================\n\n/**\n * Parameter schema for delegate tools using JSON Schema\n * Supports standard JSON Schema draft 2020-12 with validation keywords\n *\n * Example:\n * ```json\n * {\n * \"type\": \"object\",\n * \"properties\": {\n * \"path\": { \"type\": \"string\", \"description\": \"File path\" },\n * \"force\": { \"type\": \"boolean\", \"description\": \"Force operation\" }\n * },\n * \"required\": [\"path\"]\n * }\n * ```\n */\nexport type ParameterSchema = Record<string, unknown>;\n\n/**\n * Delegate tool definition provided by client-side tool providers\n * Represents a tool that can be invoked by the agent\n */\nexport interface DelegateToolDefinition {\n /** Unique tool identifier (e.g., \"github-api\", \"custom-validator\") */\n id: string;\n /** Human-readable tool name */\n name: string;\n /** Tool description for agent understanding */\n description: string;\n /** Parameter schema (JSON Schema) */\n inputSchema: ParameterSchema;\n /** Tool category/group for organization (e.g., \"vcs\", \"validation\", \"custom\") */\n category?: string;\n /** Tool provider identifier (e.g., extension name, plugin id) */\n provider?: string;\n /** Whether this tool requires user approval before execution */\n requiresApproval?: boolean;\n /** Tool availability (e.g., \"enabled\", \"disabled\", \"beta\") */\n availability?: 'enabled' | 'disabled' | 'beta';\n /** Additional metadata */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Delegate tool execution request (Agent -> Client)\n * Sent via extMethod: _codebuddy.ai/delegateTool\n */\nexport interface DelegateToolRequest {\n /** Session ID */\n sessionId: string;\n /** Tool call ID for tracing */\n toolCallId: string;\n /** Tool ID from the definition */\n toolId: string;\n /** Tool input parameters */\n input: Record<string, unknown>;\n /** Request timeout in milliseconds */\n timeout?: number;\n /** Abort signal URI for cancellation support */\n abortSignal?: string;\n}\n\n/**\n * Delegate tool execution result (Client -> Agent)\n */\nexport interface DelegateToolResult {\n /** Execution outcome */\n status: 'success' | 'error' | 'timeout' | 'cancelled';\n /** Output data (when status is 'success') */\n output?: unknown;\n /** Error message and details (when status is 'error' or other failure) */\n error?: {\n message: string;\n code?: string;\n details?: Record<string, unknown>;\n };\n /** Execution duration in milliseconds */\n duration?: number;\n /** Additional metadata */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Delegate tools changed notification (Client -> Agent)\n * Sent via extNotification: _codebuddy.ai/delegateToolsChanged\n * Notifies agent when available delegate tools are added, removed, or updated\n */\nexport interface DelegateToolsChangedParams {\n /** Session ID */\n sessionId: string;\n /** Type of change */\n changeType: 'added' | 'removed' | 'updated';\n /** Tool definitions added/removed/updated */\n tools: DelegateToolDefinition[];\n /** Timestamp of the change */\n timestamp: number;\n}\n\n// ============================================\n// UI Control Types\n// ============================================\n\n/**\n * UI Control action types\n */\nexport type UIControlAction = 'click' | 'fill' | 'scroll' | 'focus' | 'select';\n\n/**\n * UI Control target specification\n */\nexport interface UIControlTarget {\n /** CSS selector */\n selector?: string;\n /** Match element by text content */\n text?: string;\n /** Match element by aria-label or label text */\n label?: string;\n /** Match element by ARIA role (button, textbox, etc.) */\n role?: string;\n /** Index of matching element (0-based) */\n index?: number;\n}\n\n/**\n * UI Control request (Agent -> Client)\n * Sent via extMethod: _codebuddy.ai/uiControl\n */\nexport interface UIControlRequest {\n /** Session ID */\n sessionId: string;\n /** Action to perform */\n action: UIControlAction;\n /** Target element specification */\n target: UIControlTarget;\n /** Value for fill action */\n value?: string;\n /** Request timeout in milliseconds */\n timeout?: number;\n}\n\n/**\n * UI Control result (Client -> Agent)\n */\nexport interface UIControlResult {\n /** Whether the action was successful */\n success: boolean;\n /** Error message if failed */\n error?: string;\n /** Whether the target element was found */\n elementFound?: boolean;\n /** Action that was performed */\n action?: UIControlAction;\n /** Timestamp of execution */\n timestamp: number;\n}\n","// Streamable HTTP Transport for ACP\n// Enables browser-based clients to connect to cloud-hosted ACP agents.\n//\n// Protocol flow:\n// 1. Client establishes GET SSE connection, receives Acp-Connection-Id\n// 2. Client sends POST requests with Acp-Connection-Id header\n// 3. Notifications arrive via GET SSE, responses via POST SSE\n\nimport type { Stream } from '@agentclientprotocol/sdk';\n\ntype StreamMessage = Stream extends { readable: ReadableStream<infer T> } ? T : never;\n\nexport interface StreamableHttpOptions {\n // ACP endpoint URL, e.g. 'https://cloud-agent.example.com/acp'\n endpoint: string;\n // Authorization token (sent as Bearer token)\n authToken?: string;\n // Custom headers to include in all requests\n headers?: Record<string, string>;\n // Reconnect options for SSE connections\n reconnect?: {\n enabled?: boolean; // default: true\n initialDelay?: number; // ms, default: 1000\n maxDelay?: number; // ms, default: 30000\n maxRetries?: number; // default: Infinity\n jitter?: boolean; // default: true, adds ±25% jitter to prevent thundering herd\n };\n // AbortSignal to cancel the connection\n signal?: AbortSignal;\n // Custom fetch implementation (for testing or non-browser environments)\n fetch?: typeof fetch;\n // Callback when connection is established\n onConnect?: (connectionId: string) => void;\n // Callback when connection is closed\n onDisconnect?: (connectionId: string) => void;\n // Callback when an error occurs\n onError?: (error: Error) => void;\n // Heartbeat timeout in ms (default: 60000). If no heartbeat received within this time, reconnect.\n // Set to 0 to disable heartbeat detection.\n heartbeatTimeout?: number;\n // Connection establishment timeout in ms (default: 30000).\n // If GET SSE connection is not established within this time, retry.\n connectionTimeout?: number;\n // POST request timeout in ms (default: 30000)\n postTimeout?: number;\n // Backpressure options for message queue\n backpressure?: {\n highWaterMark?: number; // default: 100, pause reading SSE when queue reaches this\n lowWaterMark?: number; // default: 50, resume reading SSE when queue drops to this\n pauseTimeout?: number; // default: 5000ms, timeout for backpressure pause to prevent deadlock\n };\n}\n\n/**\n * Extended Stream interface with connection management\n */\nexport interface StreamableHttpTransport extends Stream {\n /**\n * Current connection ID, undefined if not connected\n */\n readonly connectionId: string | undefined;\n /**\n * Promise that resolves when the SSE connection is established\n * and the connectionId is available. Callers should await this\n * before sending messages to ensure the transport is ready.\n */\n readonly ready: Promise<void>;\n /**\n * Close the connection gracefully (sends DELETE request)\n */\n close(): Promise<void>;\n}\n\ninterface SSEEvent {\n type: string;\n data: string;\n id?: string;\n}\n\nfunction parseSSELine(\n line: string,\n currentEvent: Partial<SSEEvent>\n): { event?: SSEEvent; reset: boolean; isComment: boolean } {\n if (line === '') {\n if (currentEvent.data) {\n return {\n event: {\n type: currentEvent.type || 'message',\n data: currentEvent.data,\n id: currentEvent.id,\n },\n reset: true,\n isComment: false,\n };\n }\n return { reset: true, isComment: false };\n }\n\n // SSE comments (including heartbeats) start with ':'\n if (line.startsWith(':')) {\n return { reset: false, isComment: true };\n }\n\n const colonIndex = line.indexOf(':');\n if (colonIndex === -1) {\n return { reset: false, isComment: false };\n }\n\n const field = line.slice(0, colonIndex);\n let value = line.slice(colonIndex + 1);\n if (value.startsWith(' ')) {\n value = value.slice(1);\n }\n\n switch (field) {\n case 'event':\n // Reset data when starting a new event type\n // This prevents data from previous events being concatenated\n if (currentEvent.type && currentEvent.type !== value) {\n currentEvent.data = undefined;\n }\n currentEvent.type = value;\n break;\n case 'data':\n currentEvent.data = (currentEvent.data || '') + value;\n break;\n case 'id':\n currentEvent.id = value;\n break;\n }\n\n return { reset: false, isComment: false };\n}\n\n// Create a Streamable HTTP transport.\n//\n// Example:\n// const transport = streamableHttp({\n// endpoint: 'https://agent.example.com/acp',\n// authToken: 'token123',\n// onConnect: (id) => console.log('Connected:', id),\n// onDisconnect: (id) => console.log('Disconnected:', id),\n// });\n//\n// // Later, close gracefully\n// await transport.close();\nexport function streamableHttp(options: StreamableHttpOptions): StreamableHttpTransport {\n const {\n endpoint,\n authToken,\n headers: customHeaders = {},\n reconnect = {},\n signal: externalSignal,\n fetch: customFetch = globalThis.fetch,\n onConnect,\n onDisconnect,\n onError,\n heartbeatTimeout = 60000,\n connectionTimeout = 30000,\n postTimeout = 30000,\n backpressure = {},\n } = options;\n\n const {\n enabled: reconnectEnabled = true,\n initialDelay = 1000,\n maxDelay = 30000,\n maxRetries = Infinity,\n jitter: jitterEnabled = true,\n } = reconnect;\n\n const {\n highWaterMark = 100,\n lowWaterMark = 50,\n pauseTimeout = 5000,\n } = backpressure;\n\n // Connection state\n let connectionId: string | undefined;\n let lastEventId: string | undefined;\n let reconnectAttempts = 0;\n let closed = false;\n let isClosing = false;\n\n // Promise that resolves when GET SSE is connected and we have connectionId\n let connectionReady: Promise<void>;\n let resolveConnection: () => void;\n let rejectConnection: (error: Error) => void;\n\n // Connection version to track reconnections\n let connectionVersion = 0;\n\n connectionReady = new Promise((resolve, reject) => {\n resolveConnection = resolve;\n rejectConnection = reject;\n });\n\n const abortController = new AbortController();\n\n // Combine signals - use manual approach for broader compatibility\n function isAborted(): boolean {\n return abortController.signal.aborted || (externalSignal?.aborted ?? false);\n }\n\n function getSignal(): AbortSignal {\n // AbortSignal.any is available in newer Node.js versions\n const anyFn = (AbortSignal as unknown as { any?: (signals: AbortSignal[]) => AbortSignal }).any;\n if (externalSignal && typeof anyFn === 'function') {\n return anyFn([externalSignal, abortController.signal]);\n }\n return abortController.signal;\n }\n\n const combinedSignal = getSignal();\n\n // Message queue for incoming messages with backpressure\n const messageQueue: StreamMessage[] = [];\n const messageResolvers: Array<(value: StreamMessage | null) => void> = [];\n let streamError: Error | null = null;\n let isPaused = false;\n let resumeReading: (() => void) | null = null;\n\n // Track background SSE processors to handle POST responses asynchronously\n const backgroundSSEProcessors: Set<Promise<void>> = new Set();\n\n // Heartbeat tracking\n let lastActivity = Date.now();\n let heartbeatCheckTimer: ReturnType<typeof setInterval> | undefined;\n\n function enqueueMessage(message: StreamMessage): boolean {\n if (messageResolvers.length > 0) {\n const resolver = messageResolvers.shift()!;\n resolver(message);\n return true;\n } else {\n messageQueue.push(message);\n // Check if we should pause reading due to backpressure\n if (messageQueue.length >= highWaterMark) {\n isPaused = true;\n return false;\n }\n return true;\n }\n }\n\n function dequeueMessage(): Promise<StreamMessage | null> {\n if (closed) {\n return Promise.resolve(null);\n }\n if (streamError) {\n return Promise.reject(streamError);\n }\n if (messageQueue.length > 0) {\n const message = messageQueue.shift()!;\n // Check if we should resume reading\n if (isPaused && messageQueue.length <= lowWaterMark) {\n isPaused = false;\n const resume = resumeReading;\n if (resume) {\n // Use queueMicrotask to avoid potential stack issues\n queueMicrotask(() => resume());\n }\n }\n return Promise.resolve(message);\n }\n return new Promise(resolve => {\n messageResolvers.push(resolve);\n });\n }\n\n function updateLastActivity(): void {\n lastActivity = Date.now();\n }\n\n function startHeartbeatCheck(triggerReconnect: () => void): void {\n if (heartbeatTimeout <= 0) {\n return;\n }\n // Check heartbeat every 10 seconds\n heartbeatCheckTimer = setInterval(() => {\n if (Date.now() - lastActivity > heartbeatTimeout) {\n console.warn('[StreamableHTTP] Heartbeat timeout, triggering reconnect');\n triggerReconnect();\n }\n }, 10000);\n }\n\n function stopHeartbeatCheck(): void {\n if (heartbeatCheckTimer) {\n clearInterval(heartbeatCheckTimer);\n heartbeatCheckTimer = undefined;\n }\n }\n\n /**\n * Calculate reconnect delay with optional jitter\n */\n function calculateDelay(attempt: number): number {\n const baseDelay = Math.min(initialDelay * Math.pow(2, attempt - 1), maxDelay);\n if (!jitterEnabled) {\n return baseDelay;\n }\n // Add ±25% jitter to prevent thundering herd\n const jitterFactor = 0.25 * (Math.random() * 2 - 1);\n return Math.round(baseDelay * (1 + jitterFactor));\n }\n\n function closeWithError(error: Error): void {\n streamError = error;\n closed = true;\n stopHeartbeatCheck();\n // Resume any paused reading\n if (resumeReading) {\n resumeReading();\n resumeReading = null;\n }\n rejectConnection(error);\n onError?.(error);\n while (messageResolvers.length > 0) {\n const resolver = messageResolvers.shift()!;\n resolver(null);\n }\n }\n\n function closeNormally(): void {\n closed = true;\n stopHeartbeatCheck();\n // Resume any paused reading\n if (resumeReading) {\n resumeReading();\n resumeReading = null;\n }\n // Clear background SSE processors (they will exit due to closed=true)\n backgroundSSEProcessors.clear();\n while (messageResolvers.length > 0) {\n const resolver = messageResolvers.shift()!;\n resolver(null);\n }\n }\n\n // Send DELETE request to close connection gracefully\n async function sendDelete(): Promise<void> {\n if (!connectionId || isClosing) {\n return;\n }\n\n isClosing = true;\n const currentConnectionId = connectionId;\n\n try {\n const headers = buildHeaders();\n headers['Acp-Connection-Id'] = currentConnectionId;\n\n await customFetch(endpoint, {\n method: 'DELETE',\n headers,\n signal: AbortSignal.timeout(5000), // 5s timeout for DELETE\n });\n } catch {\n // Ignore DELETE errors - connection may already be closed\n } finally {\n if (currentConnectionId) {\n onDisconnect?.(currentConnectionId);\n }\n isClosing = false;\n }\n }\n\n function buildHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n ...customHeaders,\n };\n\n if (authToken) {\n headers['Authorization'] = `Bearer ${authToken}`;\n }\n\n return headers;\n }\n\n async function processSSEStream(\n reader: ReadableStreamDefaultReader<Uint8Array>\n ): Promise<void> {\n const decoder = new TextDecoder();\n let buffer = '';\n let currentEvent: Partial<SSEEvent> = {};\n\n try {\n while (true) {\n // Check for backpressure - wait if paused with timeout protection\n if (isPaused) {\n await new Promise<void>(resolve => {\n let resolved = false;\n\n // Timeout protection to prevent permanent deadlock\n const timeoutId = setTimeout(() => {\n if (!resolved) {\n resolved = true;\n console.warn('[StreamableHTTP] Backpressure pause timeout, forcing resume');\n resolve();\n }\n }, pauseTimeout);\n\n resumeReading = () => {\n if (!resolved) {\n resolved = true;\n clearTimeout(timeoutId);\n resolve();\n }\n };\n });\n resumeReading = null;\n }\n\n const { value, done } = await reader.read();\n if (done) { break; }\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n const { event, reset, isComment } = parseSSELine(line, currentEvent);\n\n // SSE comments (including heartbeats) update last activity\n if (isComment) {\n updateLastActivity();\n continue;\n }\n\n if (event) {\n // Any event means we're receiving data - update activity\n updateLastActivity();\n\n if (event.id) {\n lastEventId = event.id;\n }\n\n // Skip non-message events (like \"connected\")\n if (event.type !== 'message') {\n continue;\n }\n\n try {\n const message = JSON.parse(event.data) as StreamMessage;\n // Only enqueue valid JSON-RPC messages\n if (message && typeof message === 'object' && 'jsonrpc' in message) {\n enqueueMessage(message);\n }\n } catch {\n console.error('[StreamableHTTP] Failed to parse SSE data:', event.data);\n }\n }\n\n if (reset) {\n currentEvent = {};\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n /**\n * Process SSE stream in background without blocking the caller.\n * This prevents deadlock when POST responses return SSE streams.\n */\n function processSSEStreamBackground(\n reader: ReadableStreamDefaultReader<Uint8Array>\n ): void {\n const promise = processSSEStream(reader)\n .catch(error => {\n console.error('[StreamableHTTP] Background SSE processing error:', error);\n onError?.(error instanceof Error ? error : new Error(String(error)));\n })\n .finally(() => {\n backgroundSSEProcessors.delete(promise);\n });\n backgroundSSEProcessors.add(promise);\n }\n\n // Establish GET SSE connection and get connectionId\n async function startSSEConnection(): Promise<void> {\n // Track current reader for heartbeat-triggered reconnect\n let currentReader: ReadableStreamDefaultReader<Uint8Array> | null = null;\n\n // Function to trigger reconnect (called from heartbeat timeout)\n const triggerReconnect = (): void => {\n if (currentReader) {\n currentReader.cancel().catch(() => {/* ignore */ });\n }\n };\n\n while (!closed && !isAborted()) {\n try {\n const headers = buildHeaders();\n headers['Accept'] = 'text/event-stream';\n\n if (lastEventId) {\n headers['Last-Event-ID'] = lastEventId;\n }\n\n // When reconnecting, send the existing connectionId so the server\n // can reuse the same connection state (initialized flag, session, etc.)\n // instead of creating a brand-new connection. This is critical for\n // environments like WeChat Mini Programs where wx.request has a hard\n // 60-second timeout that forces periodic GET SSE reconnections.\n if (connectionId) {\n headers['Acp-Connection-Id'] = connectionId;\n }\n\n // Create connection timeout signal\n // If we can't establish SSE within connectionTimeout, retry\n const connectTimeoutMs = connectionTimeout > 0 ? connectionTimeout : 30000;\n const connectController = new AbortController();\n const connectTimer = setTimeout(() => connectController.abort(), connectTimeoutMs);\n\n // Propagate external abort signals to the connect controller\n // (same pattern as postTimeout — works without AbortSignal.any)\n if (externalSignal) {\n externalSignal.addEventListener('abort', () => connectController.abort(), { once: true });\n }\n abortController.signal.addEventListener('abort', () => connectController.abort(), { once: true });\n\n let response: Response;\n try {\n response = await customFetch(endpoint, {\n method: 'GET',\n headers,\n signal: connectController.signal,\n });\n } finally {\n clearTimeout(connectTimer);\n }\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}`);\n }\n\n // Get connection ID from response - MUST have it\n const newConnectionId = response.headers.get('Acp-Connection-Id');\n if (!newConnectionId) {\n throw new Error('Server did not return Acp-Connection-Id header');\n }\n\n // Track previous connection for disconnect callback\n const previousConnectionId = connectionId;\n\n // Update connection state atomically\n connectionVersion++;\n connectionId = newConnectionId;\n resolveConnection();\n\n // Notify callbacks\n if (previousConnectionId && previousConnectionId !== newConnectionId) {\n onDisconnect?.(previousConnectionId);\n }\n onConnect?.(newConnectionId);\n\n reconnectAttempts = 0;\n\n // Reset heartbeat tracking and start heartbeat check\n updateLastActivity();\n startHeartbeatCheck(triggerReconnect);\n\n const reader = response.body?.getReader();\n if (reader) {\n currentReader = reader;\n await processSSEStream(reader);\n currentReader = null;\n }\n\n // Stop heartbeat check when connection ends\n stopHeartbeatCheck();\n\n // Connection ended\n const endedConnectionId = connectionId;\n connectionId = undefined;\n\n // Notify disconnect\n if (endedConnectionId) {\n onDisconnect?.(endedConnectionId);\n }\n\n if (!reconnectEnabled || closed) {\n break;\n }\n\n // Reconnect - create new connectionReady promise BEFORE clearing connectionId\n // so that sendMessage waits for new connection\n connectionReady = new Promise((resolve, reject) => {\n resolveConnection = resolve;\n rejectConnection = reject;\n });\n\n // Add delay before reconnecting to prevent tight loop\n // This gives sendMessage a chance to use the connection before it's replaced\n const reconnectDelay = calculateDelay(1); // Use minimal delay with jitter\n await new Promise(resolve => setTimeout(resolve, reconnectDelay));\n } catch (error) {\n // Stop heartbeat check on error\n stopHeartbeatCheck();\n currentReader = null;\n\n if (isAborted() || closed) {\n break;\n }\n\n reconnectAttempts++;\n\n if (reconnectAttempts > maxRetries) {\n closeWithError(new Error(`SSE reconnect failed after ${maxRetries} attempts`));\n break;\n }\n\n // Use calculateDelay with jitter\n const delay = calculateDelay(reconnectAttempts);\n\n console.warn(\n `[StreamableHTTP] SSE error, retrying in ${delay}ms (attempt ${reconnectAttempts}):`,\n error\n );\n\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n }\n }\n\n // Send message via POST\n async function sendMessage(message: StreamMessage): Promise<void> {\n if (closed) {\n throw new Error('Connection is closed');\n }\n\n // Wait for stable connection with retry logic\n // This handles rapid reconnection scenarios\n const maxWaitAttempts = 5;\n let currentConnectionId: string | undefined;\n\n for (let attempt = 0; attempt < maxWaitAttempts; attempt++) {\n // Wait for GET SSE to establish and get connectionId\n const versionBeforeWait = connectionVersion;\n await connectionReady;\n\n // Check if reconnection happened while we were waiting\n if (versionBeforeWait !== connectionVersion && versionBeforeWait > 0) {\n // A reconnection happened - wait for new connection\n await connectionReady;\n }\n\n // Capture connectionId after waiting\n currentConnectionId = connectionId;\n\n if (currentConnectionId) {\n break; // Got a valid connection\n }\n\n // Connection became undefined (reconnecting), wait a bit and retry\n if (attempt < maxWaitAttempts - 1) {\n await new Promise(resolve => setTimeout(resolve, 100));\n }\n }\n\n if (!currentConnectionId) {\n throw new Error('No connection ID available after multiple attempts');\n }\n\n const headers = buildHeaders();\n headers['Content-Type'] = 'application/json';\n headers['Accept'] = 'application/json, text/event-stream';\n headers['Acp-Connection-Id'] = currentConnectionId;\n\n // Create timeout controller for POST request\n const postController = new AbortController();\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n // Combine with external signal if present\n const postSignal = postTimeout > 0\n ? postController.signal\n : combinedSignal;\n\n if (postTimeout > 0) {\n timeoutId = setTimeout(() => postController.abort(), postTimeout);\n // Also abort if external signal is aborted\n if (externalSignal) {\n externalSignal.addEventListener('abort', () => postController.abort(), { once: true });\n }\n abortController.signal.addEventListener('abort', () => postController.abort(), { once: true });\n }\n\n try {\n const response = await customFetch(endpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify(message),\n signal: postSignal,\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'Unknown error');\n throw new Error(`HTTP ${response.status}: ${errorText}`);\n }\n\n // Handle response based on content type\n const contentType = response.headers.get('Content-Type') || '';\n\n if (contentType.includes('text/event-stream')) {\n const reader = response.body?.getReader();\n if (reader) {\n // Process SSE in background to avoid blocking sendMessage\n // This prevents deadlock when backpressure causes processSSEStream to pause\n processSSEStreamBackground(reader);\n }\n } else if (contentType.includes('application/json')) {\n const data = await response.json();\n if (data && typeof data === 'object' && 'jsonrpc' in data) {\n enqueueMessage(data as StreamMessage);\n }\n }\n // 202 responses have no body\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n }\n\n // Start SSE connection immediately\n startSSEConnection().catch(error => {\n console.error('[StreamableHTTP] SSE connection error:', error);\n });\n\n const readable = new ReadableStream<StreamMessage>({\n async pull(controller) {\n const message = await dequeueMessage();\n if (message === null) {\n controller.close();\n } else {\n controller.enqueue(message);\n }\n },\n cancel() {\n closeNormally();\n abortController.abort();\n },\n });\n\n const writable = new WritableStream<StreamMessage>({\n async write(message) {\n await sendMessage(message);\n },\n close() {\n closeNormally();\n abortController.abort();\n },\n abort(reason) {\n closeWithError(reason instanceof Error ? reason : new Error(String(reason)));\n abortController.abort();\n },\n });\n\n // Close the connection gracefully\n async function close(): Promise<void> {\n if (closed) {\n return;\n }\n\n // Send DELETE to server first\n await sendDelete();\n\n // Then close locally\n closeNormally();\n abortController.abort();\n }\n\n return {\n readable,\n writable,\n get connectionId() {\n return connectionId;\n },\n get ready() {\n return connectionReady;\n },\n close,\n };\n}\n\nexport default streamableHttp;\n","/**\n * Artifact Manager for Streamable HTTP ACP Client\n * Handles artifact notification processing\n */\n\nimport type {\n Artifact,\n ArtifactEvent,\n ArtifactNotificationParams,\n} from '../types.js';\nimport type { Logger } from './types.js';\n\n/**\n * Configuration for ArtifactManager\n */\nexport interface ArtifactManagerConfig {\n /** Logger instance */\n logger?: Logger;\n}\n\n/**\n * Callback for artifact events\n */\nexport type ArtifactEventCallback = (artifact: Artifact, event: ArtifactEvent) => void;\n\n/**\n * Manages artifact notifications from the agent\n */\nexport class ArtifactManager {\n private artifacts = new Map<string, Artifact>();\n private logger?: Logger;\n private eventCallbacks: Set<ArtifactEventCallback> = new Set();\n\n constructor(config: ArtifactManagerConfig) {\n this.logger = config.logger;\n }\n\n /**\n * Register a callback for artifact events\n */\n onArtifactEvent(callback: ArtifactEventCallback): () => void {\n this.eventCallbacks.add(callback);\n return () => {\n this.eventCallbacks.delete(callback);\n };\n }\n\n /**\n * Handle an artifact notification from the agent\n */\n handleNotification(notification: ArtifactNotificationParams): void {\n const { event } = notification;\n\n if (event === 'deleted') {\n const { artifact } = notification;\n const existing = this.artifacts.get(artifact.uri);\n this.logger?.debug(`Artifact deleted: ${artifact.uri}`);\n this.artifacts.delete(artifact.uri);\n\n // Notify callbacks with existing artifact if available\n if (existing) {\n this.notifyCallbacks(existing, event);\n }\n } else {\n const { artifact } = notification;\n this.logger?.debug(`Artifact ${event}: ${artifact.uri} (${artifact.type})`);\n this.artifacts.set(artifact.uri, artifact);\n this.notifyCallbacks(artifact, event);\n }\n }\n\n private notifyCallbacks(artifact: Artifact, event: ArtifactEvent): void {\n for (const callback of this.eventCallbacks) {\n try {\n callback(artifact, event);\n } catch (err) {\n this.logger?.error('Error in artifact event callback:', err);\n }\n }\n }\n\n /**\n * Get an artifact by URI (used internally for deleted event handling)\n */\n get(uri: string): Artifact | undefined {\n return this.artifacts.get(uri);\n }\n\n /**\n * Clear all artifacts\n */\n clear(): void {\n this.artifacts.clear();\n this.logger?.debug('Cleared all artifacts');\n }\n}\n","/**\n * Protocol constants for Streamable HTTP ACP Client\n */\n\nimport type { ClientCapabilities } from '../sdk.js';\nimport { ExtensionMethod, KNOWN_EXTENSIONS } from '../types.js';\n\n// Re-export extension constants\nexport { ExtensionMethod, KNOWN_EXTENSIONS };\n\n// ============================================\n// Default Timeouts (in milliseconds)\n// ============================================\n\n/**\n * Default timeout for initialize operation\n */\nexport const DEFAULT_INITIALIZE_TIMEOUT = 30_000; // 30 seconds\n\n/**\n * Default timeout for session/new operation (waiting for sessionId via SSE)\n */\nexport const DEFAULT_SESSION_TIMEOUT = 30_000; // 30 seconds\n\n/**\n * Default timeout for prompt operation\n */\nexport const DEFAULT_PROMPT_TIMEOUT = 300_000; // 5 minutes\n\n/**\n * Default timeout for permission requests\n */\nexport const DEFAULT_PERMISSION_TIMEOUT = 300_000; // 5 minutes\n\n/**\n * Default timeout for question requests (ask_followup_question)\n */\nexport const DEFAULT_QUESTION_TIMEOUT = 300_000; // 5 minutes\n\n/**\n * Default timeout for tool input requests\n * @deprecated Use DEFAULT_QUESTION_TIMEOUT instead\n */\nexport const DEFAULT_TOOL_INPUT_TIMEOUT = DEFAULT_QUESTION_TIMEOUT;\n\n// ============================================\n// Default Reconnect Configuration\n// ============================================\n\n/**\n * Default reconnect options\n */\nexport const DEFAULT_RECONNECT_OPTIONS = {\n enabled: true,\n initialDelay: 1000, // 1 second\n maxDelay: 30_000, // 30 seconds\n maxRetries: Infinity\n} as const;\n\n// ============================================\n// Client Capabilities\n// ============================================\n\n/**\n * Default client capabilities for cloud-based clients\n * Cloud clients typically have no direct file system access\n */\nexport const CLOUD_CLIENT_CAPABILITIES: ClientCapabilities = {\n fs: {\n readTextFile: false,\n writeTextFile: false\n }\n} as const;\n\n/**\n * Default client capabilities for local (Node.js) clients\n * Local clients have file system access\n */\nexport const LOCAL_CLIENT_CAPABILITIES: ClientCapabilities = {\n fs: {\n readTextFile: true,\n writeTextFile: true\n }\n} as const;\n","/**\n * Custom error classes for Streamable HTTP ACP Client\n */\n\n/**\n * Base error class for all ACP client errors\n */\nexport class ACPClientError extends Error {\n public readonly code: string;\n public readonly cause?: Error;\n\n constructor(message: string, code: string, cause?: Error) {\n super(message);\n this.name = 'ACPClientError';\n this.code = code;\n this.cause = cause;\n\n // Maintain proper stack trace in V8 environments\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n}\n\n/**\n * Error thrown when connection fails\n */\nexport class ConnectionError extends ACPClientError {\n constructor(message: string, cause?: Error) {\n super(message, 'CONNECTION_ERROR', cause);\n this.name = 'ConnectionError';\n }\n}\n\n/**\n * Error thrown when initialization fails\n */\nexport class InitializationError extends ACPClientError {\n constructor(message: string, cause?: Error) {\n super(message, 'INITIALIZATION_ERROR', cause);\n this.name = 'InitializationError';\n }\n}\n\n/**\n * Error thrown for session-related failures\n */\nexport class SessionError extends ACPClientError {\n public readonly sessionId?: string;\n\n /**\n * Agent ID associated with the failed session operation.\n * Available when session/new fails after agent creation + connection established.\n * Can be used with `retryNewSession()` to recover from transient failures.\n *\n * @experimental This field is subject to change\n */\n public readonly agentId?: string;\n\n constructor(message: string, sessionId?: string, cause?: Error);\n constructor(message: string, sessionId?: string, agentId?: string, cause?: Error);\n constructor(message: string, sessionId?: string, agentIdOrCause?: string | Error, cause?: Error) {\n // Overload resolution: distinguish (msg, sid, cause) from (msg, sid, agentId, cause)\n if (agentIdOrCause instanceof Error) {\n super(message, 'SESSION_ERROR', agentIdOrCause);\n this.agentId = undefined;\n } else {\n super(message, 'SESSION_ERROR', cause);\n this.agentId = agentIdOrCause;\n }\n this.name = 'SessionError';\n this.sessionId = sessionId;\n }\n}\n\n/**\n * Error thrown when prompt operation fails\n */\nexport class PromptError extends ACPClientError {\n public readonly sessionId?: string;\n\n constructor(message: string, sessionId?: string, cause?: Error) {\n super(message, 'PROMPT_ERROR', cause);\n this.name = 'PromptError';\n this.sessionId = sessionId;\n }\n}\n\n/**\n * Error thrown for permission-related failures\n */\nexport class PermissionError extends ACPClientError {\n public readonly requestId?: string;\n\n constructor(message: string, requestId?: string, cause?: Error) {\n super(message, 'PERMISSION_ERROR', cause);\n this.name = 'PermissionError';\n this.requestId = requestId;\n }\n}\n\n/**\n * Error thrown when an operation times out\n */\nexport class TimeoutError extends ACPClientError {\n public readonly operation: string;\n public readonly timeoutMs: number;\n\n constructor(operation: string, timeoutMs: number) {\n super(`Operation '${operation}' timed out after ${timeoutMs}ms`, 'TIMEOUT_ERROR');\n this.name = 'TimeoutError';\n this.operation = operation;\n this.timeoutMs = timeoutMs;\n }\n}\n\n/**\n * Error thrown when client is in invalid state for an operation\n */\nexport class InvalidStateError extends ACPClientError {\n public readonly currentState: string;\n public readonly expectedStates: string[];\n\n constructor(operation: string, currentState: string, expectedStates: string[]) {\n super(\n `Cannot perform '${operation}' in state '${currentState}'. Expected: ${expectedStates.join(' or ')}`,\n 'INVALID_STATE_ERROR'\n );\n this.name = 'InvalidStateError';\n this.currentState = currentState;\n this.expectedStates = expectedStates;\n }\n}\n\n","/**\n * Type-safe event emitter for Streamable HTTP ACP Client\n * Platform-agnostic implementation (no browser dependencies)\n */\n\n/**\n * Event listener function type\n */\nexport type EventListener<T> = (data: T) => void | Promise<void>;\n\n/**\n * Type-safe event emitter implementation\n */\nexport class EventEmitter<TEvents extends Record<string, unknown>> {\n private listeners: Map<keyof TEvents, Set<EventListener<unknown>>> = new Map();\n private onceListeners: Map<keyof TEvents, Set<EventListener<unknown>>> = new Map();\n\n /**\n * Add an event listener\n */\n on<K extends keyof TEvents>(event: K, listener: EventListener<TEvents[K]>): this {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(listener as EventListener<unknown>);\n return this;\n }\n\n /**\n * Remove an event listener\n */\n off<K extends keyof TEvents>(event: K, listener: EventListener<TEvents[K]>): this {\n const eventListeners = this.listeners.get(event);\n if (eventListeners) {\n eventListeners.delete(listener as EventListener<unknown>);\n }\n\n const onceEventListeners = this.onceListeners.get(event);\n if (onceEventListeners) {\n onceEventListeners.delete(listener as EventListener<unknown>);\n }\n\n return this;\n }\n\n /**\n * Add a one-time event listener\n */\n once<K extends keyof TEvents>(event: K, listener: EventListener<TEvents[K]>): this {\n if (!this.onceListeners.has(event)) {\n this.onceListeners.set(event, new Set());\n }\n this.onceListeners.get(event)!.add(listener as EventListener<unknown>);\n return this;\n }\n\n /**\n * Emit an event to all registered listeners\n * Returns true if any listeners were invoked\n */\n emit<K extends keyof TEvents>(event: K, data: TEvents[K]): boolean {\n const regularListeners = this.listeners.get(event);\n const onceEventListeners = this.onceListeners.get(event);\n\n let hasListeners = false;\n\n // Call regular listeners\n if (regularListeners && regularListeners.size > 0) {\n hasListeners = true;\n for (const listener of regularListeners) {\n try {\n const result = listener(data);\n // Handle async listeners\n if (result instanceof Promise) {\n result.catch(err => {\n console.error(`Error in async event listener for '${String(event)}':`, err);\n });\n }\n } catch (err) {\n console.error(`Error in event listener for '${String(event)}':`, err);\n }\n }\n }\n\n // Call once listeners and remove them\n if (onceEventListeners && onceEventListeners.size > 0) {\n hasListeners = true;\n const listenersToCall = Array.from(onceEventListeners);\n this.onceListeners.delete(event);\n\n for (const listener of listenersToCall) {\n try {\n const result = listener(data);\n if (result instanceof Promise) {\n result.catch(err => {\n console.error(\n `Error in async once event listener for '${String(event)}':`,\n err\n );\n });\n }\n } catch (err) {\n console.error(`Error in once event listener for '${String(event)}':`, err);\n }\n }\n }\n\n return hasListeners;\n }\n\n /**\n * Remove all listeners for an event, or all listeners if no event specified\n */\n removeAllListeners<K extends keyof TEvents>(event?: K): this {\n if (event !== undefined) {\n this.listeners.delete(event);\n this.onceListeners.delete(event);\n } else {\n this.listeners.clear();\n this.onceListeners.clear();\n }\n return this;\n }\n\n /**\n * Get the number of listeners for an event\n */\n listenerCount<K extends keyof TEvents>(event: K): number {\n const regular = this.listeners.get(event)?.size ?? 0;\n const once = this.onceListeners.get(event)?.size ?? 0;\n return regular + once;\n }\n\n /**\n * Get all event names that have listeners\n */\n eventNames(): Array<keyof TEvents> {\n const names = new Set<keyof TEvents>();\n for (const event of this.listeners.keys()) {\n names.add(event);\n }\n for (const event of this.onceListeners.keys()) {\n names.add(event);\n }\n return Array.from(names);\n }\n}\n","/**\n * Extension Method Handler for Streamable HTTP ACP Client\n * Routes and handles custom extension notifications\n */\n\nimport type { UsageUpdate } from '../types.js';\nimport { ExtensionMethod, KNOWN_EXTENSIONS } from './constants.js';\nimport type { Logger } from './types.js';\n\n/**\n * Configuration for ExtensionManager\n */\nexport interface ExtensionManagerConfig {\n /** Logger instance */\n logger?: Logger;\n}\n\n/**\n * Handler for extension notifications\n */\nexport type ExtensionNotificationHandler = (\n method: string,\n params: Record<string, unknown>\n) => void | Promise<void>;\n\n/**\n * Manages extension methods and notifications\n */\nexport class ExtensionManager {\n private config: ExtensionManagerConfig;\n private handlers = new Map<string, ExtensionNotificationHandler>();\n private fallbackHandler?: ExtensionNotificationHandler;\n\n constructor(config: ExtensionManagerConfig = {}) {\n this.config = config;\n }\n\n /**\n * Register a handler for a specific extension method\n */\n registerHandler(method: string, handler: ExtensionNotificationHandler): () => void {\n this.handlers.set(method, handler);\n return () => {\n this.handlers.delete(method);\n };\n }\n\n /**\n * Set a fallback handler for unknown extensions\n */\n setFallbackHandler(handler: ExtensionNotificationHandler): void {\n this.fallbackHandler = handler;\n }\n\n /**\n * Handle an extension notification\n */\n async handleNotification(method: string, params: Record<string, unknown>): Promise<void> {\n this.config.logger?.debug(`Extension notification: ${method}`);\n\n // Try specific handler first\n const handler = this.handlers.get(method);\n if (handler) {\n await handler(method, params);\n return;\n }\n\n // Try fallback handler\n if (this.fallbackHandler) {\n await this.fallbackHandler(method, params);\n return;\n }\n\n // Log unknown extension\n if (!this.isKnownExtension(method)) {\n this.config.logger?.warn(`Unknown extension notification: ${method}`);\n }\n }\n\n /**\n * Check if a method is a known extension\n */\n isKnownExtension(method: string): boolean {\n return KNOWN_EXTENSIONS.includes(method as typeof KNOWN_EXTENSIONS[number]);\n }\n\n /**\n * Check if method is the artifact extension\n */\n isArtifactExtension(method: string): boolean {\n return method === ExtensionMethod.ARTIFACT;\n }\n\n /**\n * Clear all handlers\n */\n clear(): void {\n this.handlers.clear();\n this.fallbackHandler = undefined;\n }\n}\n\n/**\n * Parse usage update from extension params\n */\nexport function parseUsageUpdate(params: Record<string, unknown>): UsageUpdate {\n return {\n sessionId: params.sessionId as string,\n inputTokens: params.inputTokens as number | undefined,\n outputTokens: params.outputTokens as number | undefined,\n totalTokens: params.totalTokens as number | undefined,\n cost: params.cost as number | undefined,\n model: params.model as string | undefined,\n _meta: params._meta as Record<string, unknown> | undefined\n };\n}\n","/**\n * Permission Manager for Streamable HTTP ACP Client\n * Handles permission requests with timeout support\n */\n\nimport type { RequestPermissionRequest, RequestPermissionResponse } from '@agentclientprotocol/sdk';\n\nimport { DEFAULT_PERMISSION_TIMEOUT } from './constants.js';\nimport { TimeoutError } from './errors.js';\nimport type { Logger, PermissionHandler } from './types.js';\n\n/**\n * Pending permission request state\n */\ninterface PendingPermission {\n params: RequestPermissionRequest;\n resolve: (response: RequestPermissionResponse) => void;\n reject: (error: Error) => void;\n timeoutId?: ReturnType<typeof setTimeout>;\n createdAt: number;\n}\n\n/**\n * Configuration for PermissionManager\n */\nexport interface PermissionManagerConfig {\n /** Default timeout for permission requests (ms) */\n timeout?: number;\n /** Auto-reject permissions on timeout */\n autoRejectOnTimeout?: boolean;\n /** Auto-approve all permissions (for testing) */\n autoApprove?: boolean;\n /** Custom permission handler */\n handler?: PermissionHandler;\n /** Logger instance */\n logger?: Logger;\n}\n\n/**\n * Event callbacks for permission events\n */\nexport interface PermissionEventCallbacks {\n onRequest?: (requestId: string, params: RequestPermissionRequest) => void;\n onResolved?: (requestId: string, optionId: string) => void;\n onRejected?: (requestId: string, reason?: string) => void;\n onTimeout?: (requestId: string) => void;\n}\n\n/**\n * Manages permission requests from the agent\n */\nexport class PermissionManager {\n private pending = new Map<string, PendingPermission>();\n private config: PermissionManagerConfig;\n private callbacks: PermissionEventCallbacks = {};\n\n constructor(config: PermissionManagerConfig = {}) {\n this.config = {\n timeout: DEFAULT_PERMISSION_TIMEOUT,\n autoRejectOnTimeout: true,\n autoApprove: false,\n ...config\n };\n }\n\n /**\n * Set event callbacks\n */\n setCallbacks(callbacks: PermissionEventCallbacks): void {\n this.callbacks = callbacks;\n }\n\n /**\n * Handle a permission request from the agent\n */\n async handleRequest(params: RequestPermissionRequest): Promise<RequestPermissionResponse> {\n const requestId = params.toolCall.toolCallId;\n\n this.config.logger?.debug(`Permission request received: ${requestId}`);\n\n // Auto-approve mode\n if (this.config.autoApprove) {\n const firstOption = params.options[0];\n this.config.logger?.debug(`Auto-approving permission: ${requestId}`);\n return {\n outcome: {\n outcome: 'selected',\n optionId: firstOption?.optionId ?? 'approve'\n }\n };\n }\n\n // Custom handler\n if (this.config.handler) {\n return this.config.handler(params);\n }\n\n // Create pending permission\n return new Promise<RequestPermissionResponse>((resolve, reject) => {\n const pending: PendingPermission = {\n params,\n resolve,\n reject,\n createdAt: Date.now()\n };\n\n // Set up timeout\n if (this.config.timeout && this.config.timeout > 0) {\n pending.timeoutId = setTimeout(() => {\n this.handleTimeout(requestId);\n }, this.config.timeout);\n }\n\n this.pending.set(requestId, pending);\n\n // Notify callback\n this.callbacks.onRequest?.(requestId, params);\n });\n }\n\n /**\n * Handle timeout for a permission request\n */\n private handleTimeout(requestId: string): void {\n const pending = this.pending.get(requestId);\n if (!pending) {return;}\n\n this.config.logger?.warn(`Permission request timed out: ${requestId}`);\n this.callbacks.onTimeout?.(requestId);\n\n if (this.config.autoRejectOnTimeout) {\n pending.resolve({\n outcome: { outcome: 'cancelled' }\n });\n } else {\n pending.reject(new TimeoutError('permission', this.config.timeout ?? DEFAULT_PERMISSION_TIMEOUT));\n }\n\n this.pending.delete(requestId);\n }\n\n /**\n * Resolve a permission request with a selected option\n * Returns true if the permission was found and resolved\n */\n resolve(requestId: string, optionId: string): boolean {\n const pending = this.pending.get(requestId);\n if (!pending) {\n this.config.logger?.warn(`Permission request not found: ${requestId}`);\n return false;\n }\n\n // Clear timeout\n if (pending.timeoutId) {\n clearTimeout(pending.timeoutId);\n }\n\n this.config.logger?.debug(`Permission resolved: ${requestId} -> ${optionId}`);\n\n pending.resolve({\n outcome: { outcome: 'selected', optionId }\n });\n\n this.pending.delete(requestId);\n this.callbacks.onResolved?.(requestId, optionId);\n\n return true;\n }\n\n /**\n * Reject (cancel) a permission request\n * Returns true if the permission was found and rejected\n */\n reject(requestId: string, reason?: string): boolean {\n const pending = this.pending.get(requestId);\n if (!pending) {\n this.config.logger?.warn(`Permission request not found: ${requestId}`);\n return false;\n }\n\n // Clear timeout\n if (pending.timeoutId) {\n clearTimeout(pending.timeoutId);\n }\n\n this.config.logger?.debug(`Permission rejected: ${requestId}${reason ? ` - ${reason}` : ''}`);\n\n pending.resolve({\n outcome: { outcome: 'cancelled' }\n });\n\n this.pending.delete(requestId);\n this.callbacks.onRejected?.(requestId, reason);\n\n return true;\n }\n\n /**\n * Get all pending permissions\n */\n getPending(): Map<string, { params: RequestPermissionRequest; createdAt: number }> {\n const result = new Map<string, { params: RequestPermissionRequest; createdAt: number }>();\n for (const [id, pending] of this.pending) {\n result.set(id, {\n params: pending.params,\n createdAt: pending.createdAt\n });\n }\n return result;\n }\n\n /**\n * Get a specific pending permission\n */\n getPendingById(requestId: string): { params: RequestPermissionRequest; createdAt: number } | undefined {\n const pending = this.pending.get(requestId);\n if (!pending) {return undefined;}\n return {\n params: pending.params,\n createdAt: pending.createdAt\n };\n }\n\n /**\n * Check if there are any pending permissions\n */\n hasPending(): boolean {\n return this.pending.size > 0;\n }\n\n /**\n * Get the count of pending permissions\n */\n get pendingCount(): number {\n return this.pending.size;\n }\n\n /**\n * Clear all pending permissions (reject all)\n */\n clear(): void {\n for (const [requestId, pending] of this.pending) {\n if (pending.timeoutId) {\n clearTimeout(pending.timeoutId);\n }\n pending.resolve({\n outcome: { outcome: 'cancelled' }\n });\n this.callbacks.onRejected?.(requestId, 'cleared');\n }\n this.pending.clear();\n this.config.logger?.debug('Cleared all pending permissions');\n }\n\n /**\n * Update configuration\n */\n updateConfig(config: Partial<PermissionManagerConfig>): void {\n this.config = { ...this.config, ...config };\n }\n}\n","/**\n * Question Manager for Streamable HTTP ACP Client\n * Handles ask_followup_question requests with timeout support\n */\n\nimport type {\n QuestionRequest,\n QuestionResponse,\n} from '../types.js';\nimport { DEFAULT_QUESTION_TIMEOUT } from './constants.js';\nimport { TimeoutError } from './errors.js';\nimport type { Logger } from './types.js';\n\n// Re-export for convenience\nexport type { QuestionRequest, QuestionResponse };\n\n/**\n * Pending question state\n */\ninterface PendingQuestion {\n request: QuestionRequest;\n resolve: (response: QuestionResponse) => void;\n reject: (error: Error) => void;\n timeoutId?: ReturnType<typeof setTimeout>;\n createdAt: number;\n}\n\n/**\n * Configuration for QuestionManager\n */\nexport interface QuestionManagerConfig {\n /** Default timeout for question requests (ms) */\n timeout?: number;\n /** Auto-cancel requests on timeout */\n autoCancelOnTimeout?: boolean;\n /** Logger instance */\n logger?: Logger;\n}\n\n/**\n * User's answers to questions\n */\nexport type QuestionAnswers = Record<string, string | string[]>;\n\n/**\n * Event callbacks for question events\n */\nexport interface QuestionEventCallbacks {\n onRequest?: (toolCallId: string, request: QuestionRequest) => void;\n onAnswered?: (toolCallId: string, answers: QuestionAnswers) => void;\n onCancelled?: (toolCallId: string, reason?: string) => void;\n onTimeout?: (toolCallId: string) => void;\n}\n\n/**\n * Manages question requests from the agent (ask_followup_question tool)\n */\nexport class QuestionManager {\n private pending = new Map<string, PendingQuestion>();\n private config: QuestionManagerConfig;\n private callbacks: QuestionEventCallbacks = {};\n\n constructor(config: QuestionManagerConfig = {}) {\n this.config = {\n timeout: DEFAULT_QUESTION_TIMEOUT,\n autoCancelOnTimeout: true,\n ...config\n };\n }\n\n /**\n * Set event callbacks\n */\n setCallbacks(callbacks: QuestionEventCallbacks): void {\n this.callbacks = callbacks;\n }\n\n /**\n * Handle a question request from the agent\n * Called when receiving _codebuddy.ai/question extMethod\n */\n async handleRequest(request: QuestionRequest): Promise<QuestionResponse> {\n const toolCallId = request.toolCallId;\n\n this.config.logger?.debug(`Question request received: ${toolCallId}`);\n\n return new Promise<QuestionResponse>((resolve, reject) => {\n const pending: PendingQuestion = {\n request,\n resolve,\n reject,\n createdAt: Date.now()\n };\n\n // Set up timeout\n const timeout = request.timeout ?? this.config.timeout;\n if (timeout && timeout > 0) {\n pending.timeoutId = setTimeout(() => {\n this.handleTimeout(toolCallId);\n }, timeout);\n }\n\n this.pending.set(toolCallId, pending);\n\n // Notify callback\n this.callbacks.onRequest?.(toolCallId, request);\n });\n }\n\n /**\n * Handle timeout for a question request\n */\n private handleTimeout(toolCallId: string): void {\n const pending = this.pending.get(toolCallId);\n if (!pending) {return;}\n\n this.config.logger?.warn(`Question request timed out: ${toolCallId}`);\n this.callbacks.onTimeout?.(toolCallId);\n\n if (this.config.autoCancelOnTimeout) {\n pending.resolve({\n outcome: 'cancelled',\n reason: 'timeout'\n });\n } else {\n pending.reject(new TimeoutError('question', this.config.timeout ?? DEFAULT_QUESTION_TIMEOUT));\n }\n\n this.pending.delete(toolCallId);\n }\n\n /**\n * Answer a question request with user's selections\n * Returns true if the request was found and answered\n */\n answer(toolCallId: string, answers: QuestionAnswers): boolean {\n const pending = this.pending.get(toolCallId);\n if (!pending) {\n this.config.logger?.warn(`Question request not found: ${toolCallId}`);\n return false;\n }\n\n // Clear timeout\n if (pending.timeoutId) {\n clearTimeout(pending.timeoutId);\n }\n\n this.config.logger?.debug(`Question answered: ${toolCallId}`);\n\n pending.resolve({\n outcome: 'submitted',\n answers\n });\n\n this.pending.delete(toolCallId);\n this.callbacks.onAnswered?.(toolCallId, answers);\n\n return true;\n }\n\n /**\n * Cancel a question request\n * Returns true if the request was found and cancelled\n */\n cancel(toolCallId: string, reason?: string): boolean {\n const pending = this.pending.get(toolCallId);\n if (!pending) {\n this.config.logger?.warn(`Question request not found: ${toolCallId}`);\n return false;\n }\n\n // Clear timeout\n if (pending.timeoutId) {\n clearTimeout(pending.timeoutId);\n }\n\n this.config.logger?.debug(`Question cancelled: ${toolCallId}${reason ? ` - ${reason}` : ''}`);\n\n pending.resolve({\n outcome: 'cancelled',\n reason\n });\n\n this.pending.delete(toolCallId);\n this.callbacks.onCancelled?.(toolCallId, reason);\n\n return true;\n }\n\n /**\n * Get all pending question requests\n */\n getPending(): Map<string, { request: QuestionRequest; createdAt: number }> {\n const result = new Map<string, { request: QuestionRequest; createdAt: number }>();\n for (const [id, pending] of this.pending) {\n result.set(id, {\n request: pending.request,\n createdAt: pending.createdAt\n });\n }\n return result;\n }\n\n /**\n * Get a specific pending question request\n */\n getPendingById(toolCallId: string): { request: QuestionRequest; createdAt: number } | undefined {\n const pending = this.pending.get(toolCallId);\n if (!pending) {return undefined;}\n return {\n request: pending.request,\n createdAt: pending.createdAt\n };\n }\n\n /**\n * Check if there are any pending question requests\n */\n hasPending(): boolean {\n return this.pending.size > 0;\n }\n\n /**\n * Get the count of pending question requests\n */\n get pendingCount(): number {\n return this.pending.size;\n }\n\n /**\n * Clear all pending question requests (cancel all)\n */\n clear(): void {\n for (const [toolCallId, pending] of this.pending) {\n if (pending.timeoutId) {\n clearTimeout(pending.timeoutId);\n }\n pending.resolve({\n outcome: 'cancelled',\n reason: 'cleared'\n });\n this.callbacks.onCancelled?.(toolCallId, 'cleared');\n }\n this.pending.clear();\n this.config.logger?.debug('Cleared all pending question requests');\n }\n\n /**\n * Update configuration\n */\n updateConfig(config: Partial<QuestionManagerConfig>): void {\n this.config = { ...this.config, ...config };\n }\n}\n","/**\n * Streamable HTTP ACP Client\n * Production-grade client for connecting to cloud-hosted ACP agents\n */\n\nimport {\n type Client,\n ClientSideConnection,\n ContentBlock,\n type InitializeResponse,\n type LoadSessionResponse,\n type NewSessionResponse,\n type PromptResponse,\n PROTOCOL_VERSION,\n type RequestPermissionRequest,\n type RequestPermissionResponse,\n type SessionNotification,\n type SetSessionModelRequest,\n type SetSessionModelResponse,\n type SetSessionModeRequest,\n type SetSessionModeResponse\n} from '@agentclientprotocol/sdk';\n\nimport { streamableHttp, type StreamableHttpTransport } from '../transport/streamable-http.js';\nimport type {\n ArtifactNotificationParams,\n CheckpointNotificationParams\n} from '../types.js';\nimport { ArtifactManager } from './artifacts.js';\nimport {\n CLOUD_CLIENT_CAPABILITIES,\n DEFAULT_INITIALIZE_TIMEOUT,\n DEFAULT_SESSION_TIMEOUT,\n ExtensionMethod\n} from './constants.js';\nimport {\n ConnectionError,\n InitializationError,\n InvalidStateError,\n SessionError\n} from './errors.js';\nimport { EventEmitter } from './events.js';\nimport { ExtensionManager, parseUsageUpdate } from './extensions.js';\nimport { PermissionManager } from './permissions.js';\nimport { type QuestionAnswers, QuestionManager, type QuestionRequest } from './questions.js';\nimport type {\n ClientEvents,\n ClientState,\n PromptOptions,\n StreamableHttpClientOptions,\n} from './types.js';\n\n/**\n * Production-grade Streamable HTTP ACP Client\n *\n * Features:\n * - Full ACP protocol support (initialize, session, prompt, cancel)\n * - Artifact notification handling\n * - Permission handling with timeout support\n * - Extension method support\n * - Type-safe event system\n * - Configurable logging\n */\nexport class StreamableHttpClient {\n private connection!: ClientSideConnection;\n private transport?: StreamableHttpTransport;\n private options: StreamableHttpClientOptions;\n private state: ClientState = 'disconnected';\n private initializeResponse?: InitializeResponse;\n\n // Managers\n private artifactManager: ArtifactManager;\n private permissionManager: PermissionManager;\n private questionManager: QuestionManager;\n private extensionManager: ExtensionManager;\n\n // Event emitter\n private emitter = new EventEmitter<ClientEvents>();\n\n constructor(options: StreamableHttpClientOptions) {\n this.options = options;\n\n // Initialize artifact manager\n this.artifactManager = new ArtifactManager({\n logger: options.logger\n });\n\n // Initialize permission manager\n this.permissionManager = new PermissionManager({\n timeout: options.permissionTimeout,\n autoRejectOnTimeout: options.permissionAutoRejectOnTimeout ?? true,\n autoApprove: options.autoApprove,\n handler: options.requestPermissionHandler,\n logger: options.logger\n });\n\n // Set up permission event callbacks\n this.permissionManager.setCallbacks({\n onRequest: (requestId, params) => {\n this.emitter.emit('permissionRequest', { requestId, params });\n },\n onResolved: (requestId, optionId) => {\n this.emitter.emit('permissionResolved', { requestId, optionId });\n },\n onRejected: (requestId, reason) => {\n this.emitter.emit('permissionRejected', { requestId, reason });\n },\n onTimeout: requestId => {\n this.emitter.emit('permissionTimeout', { requestId });\n }\n });\n\n // Initialize question manager\n this.questionManager = new QuestionManager({\n timeout: options.questionTimeout,\n autoCancelOnTimeout: options.questionAutoCancelOnTimeout ?? true,\n logger: options.logger\n });\n\n // Set up question event callbacks\n this.questionManager.setCallbacks({\n onRequest: (toolCallId: string, request: QuestionRequest) => {\n this.emitter.emit('questionRequest', { toolCallId, request });\n options.onQuestionRequest?.(toolCallId, request);\n },\n onAnswered: (toolCallId: string, answers: QuestionAnswers) => {\n this.emitter.emit('questionAnswered', { toolCallId, answers });\n },\n onCancelled: (toolCallId: string, reason?: string) => {\n this.emitter.emit('questionCancelled', { toolCallId, reason });\n },\n onTimeout: (toolCallId: string) => {\n this.emitter.emit('questionTimeout', { toolCallId });\n }\n });\n\n // Initialize extension manager\n this.extensionManager = new ExtensionManager({\n logger: options.logger\n });\n }\n\n // ============================================\n // State Management\n // ============================================\n\n /**\n * Get current client state\n */\n get currentState(): ClientState {\n return this.state;\n }\n\n /**\n * Check if client is initialized\n */\n get isInitialized(): boolean {\n return this.state === 'initialized';\n }\n\n /**\n * Check if client is connected (but maybe not initialized)\n */\n get isConnected(): boolean {\n return this.state === 'connected' || this.state === 'initialized';\n }\n\n /**\n * Get agent capabilities from initialization response\n */\n get agentCapabilities() {\n return this.initializeResponse?.agentCapabilities;\n }\n\n /**\n * Get full initialization response\n */\n get initializeResult() {\n return this.initializeResponse;\n }\n\n /**\n * Get current transport connection ID\n */\n get connectionId(): string | undefined {\n return this.transport?.connectionId;\n }\n\n private setState(newState: ClientState): void {\n const previous = this.state;\n this.state = newState;\n\n this.options.logger?.debug(`State change: ${previous} -> ${newState}`);\n this.emitter.emit('stateChange', { previous, current: newState });\n\n // Emit specific state events\n switch (newState) {\n case 'connecting':\n this.emitter.emit('connecting', undefined);\n break;\n case 'connected':\n this.emitter.emit('connected', undefined);\n break;\n case 'disconnected':\n this.emitter.emit('disconnected', undefined);\n break;\n case 'error':\n // Error event is emitted separately with the actual error\n break;\n }\n }\n\n // ============================================\n // Connection Management\n // ============================================\n\n /**\n * Connect and initialize the client\n */\n async connect(): Promise<InitializeResponse> {\n if (this.state !== 'disconnected') {\n await this.disconnect();\n }\n if (this.state === 'initialized') {\n return this.initializeResponse!;\n }\n\n if (this.state === 'connecting') {\n throw new ConnectionError('Connection already in progress');\n }\n\n this.setState('connecting');\n\n try {\n // Create transport\n this.transport = streamableHttp({\n endpoint: this.options.endpoint,\n authToken: this.options.authToken,\n headers: this.options.headers,\n reconnect: this.options.reconnect,\n fetch: this.options.fetch,\n heartbeatTimeout: this.options.heartbeatTimeout,\n postTimeout: this.options.postTimeout,\n connectionTimeout: this.options.connectionTimeout,\n onConnect: connectionId => {\n this.options.logger?.debug(`Transport connected: ${connectionId}`);\n },\n onDisconnect: connectionId => {\n this.options.logger?.debug(`Transport disconnected: ${connectionId}`);\n },\n onError: error => {\n this.options.logger?.error('Transport error:', error);\n this.emitter.emit('error', error);\n },\n });\n\n // Create connection\n this.connection = new ClientSideConnection(\n () => this.createClientHandler(),\n this.transport\n );\n\n this.setState('connected');\n\n // Initialize protocol\n // Merge client capabilities with provider defaults (provider takes priority)\n const timeout = this.options.initializeTimeout ?? DEFAULT_INITIALIZE_TIMEOUT;\n const mergedCapabilities = {\n ...this.options.clientCapabilities,\n ...CLOUD_CLIENT_CAPABILITIES,\n _meta: {\n ...this.options.clientCapabilities?._meta,\n ...CLOUD_CLIENT_CAPABILITIES._meta\n }\n };\n const initPromise = this.connection.initialize({\n protocolVersion: PROTOCOL_VERSION,\n clientCapabilities: mergedCapabilities\n });\n\n // Apply timeout\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => {\n reject(new InitializationError(`Initialize timed out after ${timeout}ms`));\n }, timeout);\n });\n\n this.initializeResponse = await Promise.race([initPromise, timeoutPromise]);\n this.setState('initialized');\n\n this.options.logger?.info('Client initialized successfully');\n\n return this.initializeResponse;\n } catch (err) {\n this.setState('error');\n const error = err instanceof Error ? err : new Error(String(err));\n this.emitter.emit('error', error);\n\n if (err instanceof InitializationError || err instanceof ConnectionError) {\n throw err;\n }\n throw new ConnectionError('Failed to connect', error);\n }\n }\n\n /**\n * Disconnect the client gracefully\n * Sends DELETE request to server before closing local resources\n */\n async disconnect(): Promise<void> {\n if (this.state === 'disconnected') {\n return;\n }\n\n this.options.logger?.info('Disconnecting client');\n\n // Close transport gracefully (sends DELETE to server)\n if (this.transport) {\n try {\n await this.transport.close();\n } catch (err) {\n this.options.logger?.warn('Error closing transport:', err);\n }\n this.transport = undefined;\n }\n\n // Clear pending permissions\n this.permissionManager.clear();\n\n // Clear pending question requests\n this.questionManager.clear();\n\n // Clear artifacts\n this.artifactManager.clear();\n\n // Reset state\n this.initializeResponse = undefined;\n this.setState('disconnected');\n }\n\n /**\n * Create the client handler for the connection\n */\n private createClientHandler(): Client {\n return {\n sessionUpdate: async (params: SessionNotification) => {\n await this.handleSessionUpdate(params);\n },\n requestPermission: async (params: RequestPermissionRequest) => this.handleRequestPermission(params),\n extNotification: async (method: string, params: Record<string, unknown>) => {\n await this.handleExtNotification(method, params);\n },\n extMethod: async (method: string, params: Record<string, unknown>): Promise<Record<string, unknown>> =>\n this.handleExtMethod(method, params as unknown as QuestionRequest)\n };\n }\n\n // ============================================\n // Session Management\n // ============================================\n\n /**\n * Create a new session\n *\n * Retries on transient network errors (e.g., proxy connection reset)\n * since session/new is idempotent and safe to retry.\n *\n * A timeout (`options.sessionTimeout`, default 30 s) guards against the\n * SSE response never arriving — the POST returns 202 immediately and the\n * sessionId comes back via GET SSE, which can hang indefinitely.\n * On timeout a `SessionError` is thrown.\n */\n async createSession(cwd: string): Promise<NewSessionResponse> {\n this.ensureInitialized('createSession');\n\n const maxRetries = 2;\n const timeout = this.options.sessionTimeout ?? DEFAULT_SESSION_TIMEOUT;\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const sessionPromise = this.connection.newSession({\n cwd,\n mcpServers: []\n });\n\n // Apply timeout - session/new response comes via GET SSE,\n // which can hang indefinitely if the server never responds\n let response: NewSessionResponse;\n if (timeout > 0) {\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => {\n reject(new SessionError(`session/new timed out after ${timeout}ms`));\n }, timeout);\n });\n response = await Promise.race([sessionPromise, timeoutPromise]);\n } else {\n response = await sessionPromise;\n }\n\n this.options.logger?.info(`Session created: ${response.sessionId}`);\n return response;\n } catch (err) {\n lastError = err instanceof Error ? err : new Error(String(err));\n\n if (attempt < maxRetries && isRetryableNetworkError(err)) {\n const delay = 500 * Math.pow(2, attempt); // 500ms, 1000ms\n this.options.logger?.warn(\n `session/new network error, retrying in ${delay}ms ` +\n `(attempt ${attempt + 1}/${maxRetries}): ${lastError.message}`\n );\n await new Promise(resolve => setTimeout(resolve, delay));\n continue;\n }\n\n throw new SessionError(\n `Failed to create session: ${lastError.message}`,\n undefined,\n lastError\n );\n }\n }\n\n // Safety net\n throw new SessionError(\n `Failed to create session: ${lastError?.message}`,\n undefined,\n lastError\n );\n }\n\n /**\n * Load an existing session\n * Requires agent to support loadSession capability\n */\n async loadSession(sessionId: string, cwd: string): Promise<LoadSessionResponse> {\n this.ensureInitialized('loadSession');\n\n if (!this.agentCapabilities?.loadSession) {\n throw new SessionError('Agent does not support session loading', sessionId);\n }\n\n try {\n const response = await this.connection.loadSession({\n sessionId,\n cwd,\n mcpServers: []\n });\n\n this.options.logger?.info(`Session loaded: ${sessionId}`);\n return response;\n } catch (err) {\n throw new SessionError(\n `Failed to load session: ${err instanceof Error ? err.message : String(err)}`,\n sessionId,\n err instanceof Error ? err : undefined\n );\n }\n }\n\n /**\n * Set the session mode\n */\n async setSessionMode(params: SetSessionModeRequest): Promise<SetSessionModeResponse> {\n this.ensureInitialized('setSessionMode');\n\n this.options.logger?.debug(`Setting session mode: ${params.sessionId} -> ${params.modeId}`);\n\n return this.connection.setSessionMode(params);\n }\n\n /**\n * Set the session model\n * @experimental This API is unstable and may change\n */\n async setSessionModel(params: SetSessionModelRequest): Promise<SetSessionModelResponse> {\n this.ensureInitialized('setSessionModel');\n\n this.options.logger?.debug(`Setting session model: ${params.sessionId} -> ${params.modelId}`);\n\n return this.connection.unstable_setSessionModel(params);\n }\n\n // ============================================\n // Prompt\n // ============================================\n\n /**\n * Send a prompt to the agent\n */\n async prompt(\n sessionId: string,\n prompt: ContentBlock[],\n options?: PromptOptions\n ): Promise<PromptResponse> {\n this.ensureInitialized('prompt');\n\n this.options.logger?.debug(`Sending prompt to session: ${sessionId}`);\n\n return this.connection.prompt({\n sessionId,\n prompt,\n _meta: options?.planMode ? { planMode: true, ...options._meta } : options?._meta\n });\n }\n\n /**\n * Cancel ongoing operations for a session\n */\n async cancel(sessionId: string): Promise<void> {\n this.ensureInitialized('cancel');\n\n this.options.logger?.debug(`Cancelling session: ${sessionId}`);\n\n await this.connection.cancel({ sessionId });\n }\n\n // ============================================\n // Permission Management\n // ============================================\n\n /**\n * Resolve a pending permission request\n */\n resolvePermission(requestId: string, optionId: string): boolean {\n return this.permissionManager.resolve(requestId, optionId);\n }\n\n /**\n * Reject a pending permission request\n */\n rejectPermission(requestId: string, reason?: string): boolean {\n return this.permissionManager.reject(requestId, reason);\n }\n\n /**\n * Get all pending permissions\n */\n getPendingPermissions() {\n return this.permissionManager.getPending();\n }\n\n /**\n * Check if there are pending permissions\n */\n hasPendingPermissions(): boolean {\n return this.permissionManager.hasPending();\n }\n\n // ============================================\n // Question Management (ask_followup_question)\n // ============================================\n\n /**\n * Answer a pending question request with user's selections\n */\n answerQuestion(toolCallId: string, answers: QuestionAnswers): boolean {\n return this.questionManager.answer(toolCallId, answers);\n }\n\n /**\n * Cancel a pending question request\n */\n cancelQuestion(toolCallId: string, reason?: string): boolean {\n return this.questionManager.cancel(toolCallId, reason);\n }\n\n /**\n * Get all pending question requests\n */\n getPendingQuestions() {\n return this.questionManager.getPending();\n }\n\n /**\n * Check if there are pending question requests\n */\n hasPendingQuestions(): boolean {\n return this.questionManager.hasPending();\n }\n\n // ============================================\n // Extension Methods\n // ============================================\n\n /**\n * Send an extension method request\n */\n async extMethod(method: string, params: Record<string, unknown>): Promise<Record<string, unknown>> {\n this.ensureInitialized('extMethod');\n return this.connection.extMethod(method, params);\n }\n\n /**\n * Send an extension notification\n */\n async extNotification(method: string, params: Record<string, unknown>): Promise<void> {\n this.ensureInitialized('extNotification');\n return this.connection.extNotification(method, params);\n }\n\n // ============================================\n // Event Emitter Implementation\n // ============================================\n\n on<K extends keyof ClientEvents>(\n event: K,\n listener: (data: ClientEvents[K]) => void | Promise<void>\n ): this {\n this.emitter.on(event, listener);\n return this;\n }\n\n off<K extends keyof ClientEvents>(\n event: K,\n listener: (data: ClientEvents[K]) => void | Promise<void>\n ): this {\n this.emitter.off(event, listener);\n return this;\n }\n\n once<K extends keyof ClientEvents>(\n event: K,\n listener: (data: ClientEvents[K]) => void | Promise<void>\n ): this {\n this.emitter.once(event, listener);\n return this;\n }\n\n emit<K extends keyof ClientEvents>(event: K, data: ClientEvents[K]): boolean {\n return this.emitter.emit(event, data);\n }\n\n removeAllListeners<K extends keyof ClientEvents>(event?: K): this {\n this.emitter.removeAllListeners(event);\n return this;\n }\n\n // ============================================\n // Internal Handlers\n // ============================================\n\n private async handleSessionUpdate(params: SessionNotification): Promise<void> {\n // Forward to callback\n await this.options.onSessionUpdate?.(params);\n\n // Emit event\n this.emitter.emit('sessionUpdate', params);\n }\n\n private async handleRequestPermission(\n params: RequestPermissionRequest\n ): Promise<RequestPermissionResponse> {\n return this.permissionManager.handleRequest(params);\n }\n\n private async handleExtNotification(\n method: string,\n params: Record<string, unknown>\n ): Promise<void> {\n // Handle artifact notifications\n if (method === ExtensionMethod.ARTIFACT) {\n const notification = params as unknown as ArtifactNotificationParams;\n const artifactData = notification.artifact as any;\n console.log('[ACP-Client] Received artifact notification:', {\n event: notification.event,\n artifactUri: artifactData?.uri,\n artifactType: artifactData?.type,\n });\n\n // For deleted events, get full artifact before deletion for callbacks\n if (notification.event === 'deleted') {\n const existing = this.artifactManager.get(notification.artifact.uri);\n this.artifactManager.handleNotification(notification);\n if (existing) {\n await this.options.onArtifact?.(existing, 'deleted');\n this.emitter.emit('artifactDeleted', existing);\n }\n } else {\n const { artifact, event } = notification;\n // Let artifactManager handle the notification\n this.artifactManager.handleNotification(notification);\n // Get the artifact from manager or use the original\n const storedArtifact = this.artifactManager.get(artifact.uri) || artifact;\n\n console.log('[ACP-Client] Stored artifact:', {\n event,\n artifactUri: storedArtifact.uri,\n artifactType: storedArtifact.type,\n hasText: storedArtifact.type === 'plan' ? !!(storedArtifact as any).text : undefined,\n });\n\n await this.options.onArtifact?.(storedArtifact, event);\n\n if (event === 'created') {\n console.log('[ACP-Client] Emitting artifactCreated event');\n this.emitter.emit('artifactCreated', storedArtifact);\n if (storedArtifact.type === 'plan') {\n await this.options.onPlanReady?.(storedArtifact);\n }\n } else {\n console.log('[ACP-Client] Emitting artifactUpdated event');\n this.emitter.emit('artifactUpdated', storedArtifact);\n }\n }\n return;\n }\n\n // Handle usage update notifications\n if (method === ExtensionMethod.USAGE) {\n const usage = parseUsageUpdate(params);\n await this.options.onUsageUpdate?.(usage);\n this.emitter.emit('usageUpdate', usage);\n return;\n }\n\n // Handle checkpoint notifications\n if (method === ExtensionMethod.CHECKPOINT) {\n const notification = params as unknown as CheckpointNotificationParams;\n if (notification.event === 'created') {\n this.emitter.emit('checkpointCreated', notification.checkpoint);\n } else if (notification.event === 'updated') {\n this.emitter.emit('checkpointUpdated', notification.checkpoint);\n }\n return;\n }\n\n // Forward other extensions to callback and manager\n await this.options.onExtNotification?.(method, params);\n await this.extensionManager.handleNotification(method, params);\n }\n\n private async handleExtMethod(\n method: string,\n params: QuestionRequest\n ): Promise<Record<string, unknown>> {\n // Handle question requests (ask_followup_question via question extMethod)\n if (method === ExtensionMethod.QUESTION) {\n const response = await this.questionManager.handleRequest(params);\n\n // Convert QuestionResponse to ToolInputResponse format expected by SDK\n if (response.outcome === 'submitted' && response.answers) {\n return {\n outcome: {\n outcome: 'submitted',\n data: {\n answers: response.answers\n }\n }\n };\n } else {\n return {\n outcome: {\n outcome: 'cancelled',\n reason: response.reason\n }\n };\n }\n }\n\n // Unknown extension method\n this.options.logger?.warn(`Unknown extension method: ${method}`);\n return {\n outcome: {\n outcome: 'cancelled',\n reason: 'unknown method'\n }\n };\n }\n\n // ============================================\n // Helpers\n // ============================================\n\n private ensureInitialized(operation: string): void {\n if (this.state !== 'initialized') {\n throw new InvalidStateError(operation, this.state, ['initialized']);\n }\n }\n}\n\nexport default StreamableHttpClient;\n\n/**\n * Check if an error is a retryable network-level error.\n * Only network failures (TypeError from fetch) are retried, NOT HTTP errors (4xx/5xx).\n */\nfunction isRetryableNetworkError(error: unknown): boolean {\n if (error instanceof TypeError) {return true;}\n if (error instanceof Error) {\n const msg = error.message.toLowerCase();\n return msg.includes('failed to fetch') ||\n msg.includes('fetch failed') ||\n msg.includes('network request failed') ||\n msg.includes('econnreset') ||\n msg.includes('econnrefused') ||\n msg.includes('socket hang up');\n }\n return false;\n}\n","/**\n * Cloud Agent Connection\n * Wraps StreamableHttpClient to implement AgentConnection interface\n */\n\nimport type {\n ContentBlock,\n InitializeResponse,\n LoadSessionResponse,\n NewSessionResponse,\n PromptResponse,\n RequestPermissionRequest,\n SessionNotification,\n SetSessionModelResponse,\n SetSessionModeResponse\n} from '@agentclientprotocol/sdk';\nimport {\n ExtensionMethod,\n StreamableHttpClient\n} from '@genie/agent-client-protocol';\n\nimport type { SessionConnectionInfo } from '../../client/types.js';\nimport type {\n AgentCapabilities,\n AgentConnection,\n AgentStatus,\n CloudConnectionConfig,\n ConnectionEventListener,\n ConnectionEvents,\n CreateSessionParams,\n LoadSessionParams,\n PromptParams\n} from '../../types.js';\n\n/**\n * Cloud Agent Connection implementation\n * Uses Streamable HTTP transport to connect to cloud-hosted ACP agents\n * Uses composition pattern - implements event emitter methods internally\n *\n * TODO: Connection Lifecycle Responsibilities\n * CloudAgentProvider caches connections by endpoint link. This class needs to:\n * - Implement connection health checks (detect and handle connection failures/reconnection)\n * - Handle token expiration (refresh or re-authentication when tokens expire)\n * - Emit 'disconnected' event when connection becomes unhealthy so provider can clean up cache\n */\nexport class CloudAgentConnection implements AgentConnection {\n private client: StreamableHttpClient;\n private listeners: Map<keyof ConnectionEvents, Set<ConnectionEventListener<unknown>>> = new Map();\n private onceListeners: Map<keyof ConnectionEvents, Set<ConnectionEventListener<unknown>>> = new Map();\n\n /**\n * Flag to suppress sessionUpdate event emission during streaming.\n * When true, onSessionUpdate callback won't emit to avoid duplicate messages with promptStream.\n */\n private _isStreaming = false;\n\n /**\n * Session connection information (sandboxId, link, token, etc.)\n * Set by CloudAgentProvider.connect() after fetching session data from backend.\n */\n private _sessionConnectionInfo?: SessionConnectionInfo;\n\n readonly agentId: string;\n readonly transport = 'cloud' as const;\n readonly cwd: string;\n\n constructor(agentId: string, config: CloudConnectionConfig, cwd: string = '/workspace') {\n this.agentId = agentId;\n this.cwd = cwd;\n\n // Create the underlying StreamableHttpClient\n this.client = new StreamableHttpClient({\n endpoint: config.endpoint,\n authToken: config.authToken,\n headers: config.headers,\n reconnect: config.reconnect,\n initializeTimeout: config.initializeTimeout,\n permissionTimeout: config.permissionTimeout,\n permissionAutoRejectOnTimeout: config.permissionAutoRejectOnTimeout,\n autoApprove: config.autoApprove,\n logger: config.logger,\n fetch: config.fetch,\n clientCapabilities: config.clientCapabilities,\n // Forward events to our emitter (suppressed during streaming to avoid duplicates)\n onSessionUpdate: update => {\n if (!this._isStreaming && this.isOwnSessionNotification(update)) {\n this.emit('sessionUpdate', update);\n }\n },\n onArtifact: (artifact, event) => {\n console.log('[CloudConnection] onArtifact callback:', {\n event,\n artifactUri: artifact.uri,\n artifactType: artifact.type,\n });\n if (event === 'created') {\n this.emit('artifactCreated', artifact);\n } else if (event === 'updated') {\n this.emit('artifactUpdated', artifact);\n } else if (event === 'deleted') {\n this.emit('artifactDeleted', artifact);\n }\n },\n onUsageUpdate: usage => {\n this.emit('usageUpdate', usage);\n },\n onExtNotification: (method: string, params: Record<string, unknown>) => {\n console.log('[CloudConnection] Received extNotification:', { method, paramsKeys: Object.keys(params) });\n\n // Handle command notifications (e.g., openBrowser)\n // Note: Cloud mode does NOT set __sessionId on command data.\n // In cloud mode, each connection is per-agent, so per-session filtering is unnecessary.\n // (Unlike Local mode, there is no need for per-session routing on the same connection.)\n if (method === ExtensionMethod.COMMAND) {\n const action = params.action as string;\n const commandParams = params.params as Record<string, unknown> | undefined;\n\n console.log('[CloudConnection] Emitting command event:', {\n action,\n paramsKeys: commandParams ? Object.keys(commandParams) : []\n });\n\n this.emit('command', { action, params: commandParams });\n }\n }\n });\n\n // Forward client events\n this.setupEventForwarding();\n }\n\n /**\n * Check whether a notification belongs to this connection's own session.\n *\n * CloudConnection.createSession() overrides sessionId to agentId, so the\n * rest of the client stack uses agentId as the canonical session\n * identifier. Notifications whose sessionId differs from agentId\n * originate from sub-agent sessions running inside the same sandbox and\n * should be silently ignored at this layer — the adapter layer handles\n * sub-agent messages independently via parentToolUseId in _meta.\n */\n private isOwnSessionNotification(notification: SessionNotification): boolean {\n return notification.sessionId === this.agentId;\n }\n\n private setupEventForwarding(): void {\n // Forward connection state events\n this.client.on('connecting', () => { this.emit('connecting', undefined); });\n this.client.on('connected', () => { this.emit('connected', undefined); });\n this.client.on('disconnected', () => { this.emit('disconnected', undefined); });\n this.client.on('error', error => { this.emit('error', error); });\n this.client.on('stateChange', change => { this.emit('stateChange', change); });\n\n // Forward permission events\n this.client.on('permissionRequest', data => { this.emit('permissionRequest', data); });\n this.client.on('permissionResolved', data => { this.emit('permissionResolved', data); });\n this.client.on('permissionRejected', data => { this.emit('permissionRejected', data); });\n this.client.on('permissionTimeout', data => { this.emit('permissionTimeout', data); });\n\n // Forward question events\n this.client.on('questionRequest', data => { this.emit('questionRequest', data); });\n this.client.on('questionAnswered', data => { this.emit('questionAnswered', data); });\n this.client.on('questionCancelled', data => { this.emit('questionCancelled', data); });\n this.client.on('questionTimeout', data => { this.emit('questionTimeout', data); });\n\n // Forward checkpoint events\n this.client.on('checkpointCreated', checkpoint => { this.emit('checkpointCreated', checkpoint); });\n this.client.on('checkpointUpdated', checkpoint => { this.emit('checkpointUpdated', checkpoint); });\n }\n\n // ============================================\n // Event Emitter Implementation\n // ============================================\n\n on<K extends keyof ConnectionEvents>(event: K, listener: ConnectionEventListener<ConnectionEvents[K]>): this {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(listener as ConnectionEventListener<unknown>);\n return this;\n }\n\n off<K extends keyof ConnectionEvents>(event: K, listener: ConnectionEventListener<ConnectionEvents[K]>): this {\n const eventListeners = this.listeners.get(event);\n if (eventListeners) {\n eventListeners.delete(listener as ConnectionEventListener<unknown>);\n }\n const onceEventListeners = this.onceListeners.get(event);\n if (onceEventListeners) {\n onceEventListeners.delete(listener as ConnectionEventListener<unknown>);\n }\n return this;\n }\n\n once<K extends keyof ConnectionEvents>(event: K, listener: ConnectionEventListener<ConnectionEvents[K]>): this {\n if (!this.onceListeners.has(event)) {\n this.onceListeners.set(event, new Set());\n }\n this.onceListeners.get(event)!.add(listener as ConnectionEventListener<unknown>);\n return this;\n }\n\n emit<K extends keyof ConnectionEvents>(event: K, data: ConnectionEvents[K]): boolean {\n const regularListeners = this.listeners.get(event);\n const onceEventListeners = this.onceListeners.get(event);\n\n let hasListeners = false;\n\n // Call regular listeners\n if (regularListeners && regularListeners.size > 0) {\n hasListeners = true;\n for (const listener of regularListeners) {\n try {\n const result = listener(data);\n if (result instanceof Promise) {\n result.catch(err => {\n console.error(`Error in async event listener for '${String(event)}':`, err);\n });\n }\n } catch (err) {\n console.error(`Error in event listener for '${String(event)}':`, err);\n }\n }\n }\n\n // Call once listeners and remove them\n if (onceEventListeners && onceEventListeners.size > 0) {\n hasListeners = true;\n const listenersToCall = Array.from(onceEventListeners);\n this.onceListeners.delete(event);\n\n for (const listener of listenersToCall) {\n try {\n const result = listener(data);\n if (result instanceof Promise) {\n result.catch(err => {\n console.error(`Error in async once event listener for '${String(event)}':`, err);\n });\n }\n } catch (err) {\n console.error(`Error in once event listener for '${String(event)}':`, err);\n }\n }\n }\n\n return hasListeners;\n }\n\n removeAllListeners<K extends keyof ConnectionEvents>(event?: K): this {\n if (event !== undefined) {\n this.listeners.delete(event);\n this.onceListeners.delete(event);\n } else {\n this.listeners.clear();\n this.onceListeners.clear();\n }\n return this;\n }\n\n // ============================================\n // State Properties\n // ============================================\n\n get state(): AgentStatus {\n return this.client.currentState as AgentStatus;\n }\n\n get isInitialized(): boolean {\n return this.client.isInitialized;\n }\n\n get capabilities(): AgentCapabilities | undefined {\n return this.client.agentCapabilities as AgentCapabilities | undefined;\n }\n\n get initializeResult(): InitializeResponse | undefined {\n return this.client.initializeResult;\n }\n\n // ============================================\n // Connection Lifecycle\n // ============================================\n\n async connect(): Promise<InitializeResponse> {\n return this.client.connect();\n }\n\n async disconnect(): Promise<void> {\n await this.client.disconnect();\n }\n\n // ============================================\n // Session Management\n // ============================================\n\n async createSession(params: CreateSessionParams): Promise<NewSessionResponse> {\n // Cloud Side does not support creating new sessions directly\n // Use this.cwd (provided by CloudAgentProvider) as the working directory\n // params.cwd is ignored because cloud agents already have a fixed cwd from backend\n const loadedSession = await this.client.createSession(this.cwd);\n return { ...loadedSession, sessionId: this.agentId };\n }\n\n async loadSession(params: LoadSessionParams): Promise<LoadSessionResponse> {\n if (!params.sessionId) {\n throw new Error('sessionId is required for loadSession');\n }\n return this.client.loadSession(params.sessionId, this.cwd);\n }\n\n async setSessionMode(sessionId: string, modeId: string): Promise<SetSessionModeResponse> {\n return this.client.setSessionMode({ sessionId, modeId });\n }\n\n async setSessionModel(sessionId: string, modelId: string): Promise<SetSessionModelResponse> {\n return this.client.setSessionModel({ sessionId, modelId });\n }\n\n // ============================================\n // Prompt Operations\n // ============================================\n\n async prompt(sessionId: string, params: PromptParams): Promise<PromptResponse> {\n const blocks =\n typeof params.content === 'string'\n ? [{ type: 'text', text: params.content }] as ContentBlock[]\n : params.content as ContentBlock[];\n\n return this.client.prompt(sessionId, blocks, {\n planMode: params.planMode,\n _meta: params._meta\n });\n }\n\n async *promptStream(sessionId: string, params: PromptParams): AsyncIterable<SessionNotification> {\n // Suppress sessionUpdate event emission during streaming to avoid duplicates\n this._isStreaming = true;\n\n // For streaming, we need to collect updates via the event system\n const updates: SessionNotification[] = [];\n let resolveUpdate: ((value: SessionNotification | null) => void) | null = null;\n let done = false;\n\n const listener = (update: SessionNotification) => {\n if (!this.isOwnSessionNotification(update)) {\n return; // Drop notifications from sub-agent sessions\n }\n if (resolveUpdate) {\n resolveUpdate(update);\n resolveUpdate = null;\n } else {\n updates.push(update);\n }\n };\n\n this.client.on('sessionUpdate', listener);\n\n try {\n // Start the prompt (non-blocking)\n const promptPromise = this.prompt(sessionId, params);\n\n // Yield updates as they come in\n while (!done) {\n const update = updates.shift();\n if (update) {\n yield update;\n } else {\n // Wait for next update or prompt completion\n const nextUpdate = await new Promise<SessionNotification | null>(resolve => {\n resolveUpdate = resolve;\n // Check if prompt completed while we were setting up\n promptPromise.then(() => {\n if (resolveUpdate === resolve) {\n resolveUpdate = null;\n resolve(null);\n }\n }).catch(() => {\n if (resolveUpdate === resolve) {\n resolveUpdate = null;\n resolve(null);\n }\n });\n });\n\n if (nextUpdate === null) {\n done = true;\n } else {\n yield nextUpdate;\n }\n }\n }\n } finally {\n this._isStreaming = false;\n this.client.off('sessionUpdate', listener);\n }\n }\n\n async cancel(sessionId: string): Promise<void> {\n return this.client.cancel(sessionId);\n }\n\n // ============================================\n // Permission Management\n // ============================================\n\n resolvePermission(requestId: string, optionId: string): boolean {\n return this.client.resolvePermission(requestId, optionId);\n }\n\n rejectPermission(requestId: string, reason?: string): boolean {\n return this.client.rejectPermission(requestId, reason);\n }\n\n getPendingPermissions(): Map<string, { params: RequestPermissionRequest; createdAt: number }> {\n return this.client.getPendingPermissions();\n }\n\n hasPendingPermissions(): boolean {\n return this.client.hasPendingPermissions();\n }\n\n // ============================================\n // Question Management (ask_followup_question)\n // ============================================\n\n answerQuestion(toolCallId: string, answers: import('@genie/agent-client-protocol').QuestionAnswers): boolean {\n return this.client.answerQuestion(toolCallId, answers);\n }\n\n cancelQuestion(toolCallId: string, reason?: string): boolean {\n return this.client.cancelQuestion(toolCallId, reason);\n }\n\n getPendingQuestions() {\n return this.client.getPendingQuestions();\n }\n\n hasPendingQuestions(): boolean {\n return this.client.hasPendingQuestions();\n }\n\n // ============================================\n // Tool Callback Management\n // ============================================\n\n async toolCallback(sessionId: string, toolCallId: string, toolName: string, action: 'approve' | 'skip' | 'cancel'): Promise<{ success: boolean; error?: string }> {\n // Cloud connection does not support toolCallback yet\n return { success: false, error: 'toolCallback not supported for cloud connections' };\n }\n\n // ============================================\n // Session Connection Info\n // ============================================\n\n /**\n * Set session connection information\n * Called by CloudAgentProvider.connect() after fetching session data from backend.\n */\n setSessionConnectionInfo(info: SessionConnectionInfo): void {\n this._sessionConnectionInfo = info;\n }\n\n /**\n * Get session connection information\n * Contains sandboxId, link, token, etc.\n */\n get sessionConnectionInfo(): SessionConnectionInfo | undefined {\n return this._sessionConnectionInfo;\n }\n\n // ============================================\n // Telemetry\n // ============================================\n\n async reportTelemetry(eventName: string, payload: Record<string, unknown>): Promise<void> {\n try {\n await this.client.extMethod('reportTelemetry', { eventName, payload });\n } catch (error) {\n console.warn('[CloudAgentConnection] reportTelemetry failed:', error);\n }\n }\n\n // ============================================\n // Extension Methods\n // ============================================\n\n async extMethod(method: string, params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.client.extMethod(method, params);\n }\n}\n\nexport default CloudAgentConnection;\n","'use strict';\n\nexport default function bind(fn, thisArg) {\n return function wrap() {\n return fn.apply(thisArg, arguments);\n };\n}\n","'use strict';\n\nimport bind from './helpers/bind.js';\n\n// utils is a library of generic helper functions non-specific to axios\n\nconst {toString} = Object.prototype;\nconst {getPrototypeOf} = Object;\nconst {iterator, toStringTag} = Symbol;\n\nconst kindOf = (cache => thing => {\n const str = toString.call(thing);\n return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase());\n})(Object.create(null));\n\nconst kindOfTest = (type) => {\n type = type.toLowerCase();\n return (thing) => kindOf(thing) === type\n}\n\nconst typeOfTest = type => thing => typeof thing === type;\n\n/**\n * Determine if a value is an Array\n *\n * @param {Object} val The value to test\n *\n * @returns {boolean} True if value is an Array, otherwise false\n */\nconst {isArray} = Array;\n\n/**\n * Determine if a value is undefined\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if the value is undefined, otherwise false\n */\nconst isUndefined = typeOfTest('undefined');\n\n/**\n * Determine if a value is a Buffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Buffer, otherwise false\n */\nfunction isBuffer(val) {\n return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor)\n && isFunction(val.constructor.isBuffer) && val.constructor.isBuffer(val);\n}\n\n/**\n * Determine if a value is an ArrayBuffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is an ArrayBuffer, otherwise false\n */\nconst isArrayBuffer = kindOfTest('ArrayBuffer');\n\n\n/**\n * Determine if a value is a view on an ArrayBuffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false\n */\nfunction isArrayBufferView(val) {\n let result;\n if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {\n result = ArrayBuffer.isView(val);\n } else {\n result = (val) && (val.buffer) && (isArrayBuffer(val.buffer));\n }\n return result;\n}\n\n/**\n * Determine if a value is a String\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a String, otherwise false\n */\nconst isString = typeOfTest('string');\n\n/**\n * Determine if a value is a Function\n *\n * @param {*} val The value to test\n * @returns {boolean} True if value is a Function, otherwise false\n */\nconst isFunction = typeOfTest('function');\n\n/**\n * Determine if a value is a Number\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Number, otherwise false\n */\nconst isNumber = typeOfTest('number');\n\n/**\n * Determine if a value is an Object\n *\n * @param {*} thing The value to test\n *\n * @returns {boolean} True if value is an Object, otherwise false\n */\nconst isObject = (thing) => thing !== null && typeof thing === 'object';\n\n/**\n * Determine if a value is a Boolean\n *\n * @param {*} thing The value to test\n * @returns {boolean} True if value is a Boolean, otherwise false\n */\nconst isBoolean = thing => thing === true || thing === false;\n\n/**\n * Determine if a value is a plain Object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a plain Object, otherwise false\n */\nconst isPlainObject = (val) => {\n if (kindOf(val) !== 'object') {\n return false;\n }\n\n const prototype = getPrototypeOf(val);\n return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(toStringTag in val) && !(iterator in val);\n}\n\n/**\n * Determine if a value is a Date\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Date, otherwise false\n */\nconst isDate = kindOfTest('Date');\n\n/**\n * Determine if a value is a File\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a File, otherwise false\n */\nconst isFile = kindOfTest('File');\n\n/**\n * Determine if a value is a Blob\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Blob, otherwise false\n */\nconst isBlob = kindOfTest('Blob');\n\n/**\n * Determine if a value is a FileList\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a File, otherwise false\n */\nconst isFileList = kindOfTest('FileList');\n\n/**\n * Determine if a value is a Stream\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Stream, otherwise false\n */\nconst isStream = (val) => isObject(val) && isFunction(val.pipe);\n\n/**\n * Determine if a value is a FormData\n *\n * @param {*} thing The value to test\n *\n * @returns {boolean} True if value is an FormData, otherwise false\n */\nconst isFormData = (thing) => {\n let kind;\n return thing && (\n (typeof FormData === 'function' && thing instanceof FormData) || (\n isFunction(thing.append) && (\n (kind = kindOf(thing)) === 'formdata' ||\n // detect form-data instance\n (kind === 'object' && isFunction(thing.toString) && thing.toString() === '[object FormData]')\n )\n )\n )\n}\n\n/**\n * Determine if a value is a URLSearchParams object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a URLSearchParams object, otherwise false\n */\nconst isURLSearchParams = kindOfTest('URLSearchParams');\n\nconst [isReadableStream, isRequest, isResponse, isHeaders] = ['ReadableStream', 'Request', 'Response', 'Headers'].map(kindOfTest);\n\n/**\n * Trim excess whitespace off the beginning and end of a string\n *\n * @param {String} str The String to trim\n *\n * @returns {String} The String freed of excess whitespace\n */\nconst trim = (str) => str.trim ?\n str.trim() : str.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, '');\n\n/**\n * Iterate over an Array or an Object invoking a function for each item.\n *\n * If `obj` is an Array callback will be called passing\n * the value, index, and complete array for each item.\n *\n * If 'obj' is an Object callback will be called passing\n * the value, key, and complete object for each property.\n *\n * @param {Object|Array} obj The object to iterate\n * @param {Function} fn The callback to invoke for each item\n *\n * @param {Boolean} [allOwnKeys = false]\n * @returns {any}\n */\nfunction forEach(obj, fn, {allOwnKeys = false} = {}) {\n // Don't bother if no value provided\n if (obj === null || typeof obj === 'undefined') {\n return;\n }\n\n let i;\n let l;\n\n // Force an array if not already something iterable\n if (typeof obj !== 'object') {\n /*eslint no-param-reassign:0*/\n obj = [obj];\n }\n\n if (isArray(obj)) {\n // Iterate over array values\n for (i = 0, l = obj.length; i < l; i++) {\n fn.call(null, obj[i], i, obj);\n }\n } else {\n // Iterate over object keys\n const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj);\n const len = keys.length;\n let key;\n\n for (i = 0; i < len; i++) {\n key = keys[i];\n fn.call(null, obj[key], key, obj);\n }\n }\n}\n\nfunction findKey(obj, key) {\n key = key.toLowerCase();\n const keys = Object.keys(obj);\n let i = keys.length;\n let _key;\n while (i-- > 0) {\n _key = keys[i];\n if (key === _key.toLowerCase()) {\n return _key;\n }\n }\n return null;\n}\n\nconst _global = (() => {\n /*eslint no-undef:0*/\n if (typeof globalThis !== \"undefined\") return globalThis;\n return typeof self !== \"undefined\" ? self : (typeof window !== 'undefined' ? window : global)\n})();\n\nconst isContextDefined = (context) => !isUndefined(context) && context !== _global;\n\n/**\n * Accepts varargs expecting each argument to be an object, then\n * immutably merges the properties of each object and returns result.\n *\n * When multiple objects contain the same key the later object in\n * the arguments list will take precedence.\n *\n * Example:\n *\n * ```js\n * var result = merge({foo: 123}, {foo: 456});\n * console.log(result.foo); // outputs 456\n * ```\n *\n * @param {Object} obj1 Object to merge\n *\n * @returns {Object} Result of all merge properties\n */\nfunction merge(/* obj1, obj2, obj3, ... */) {\n const {caseless} = isContextDefined(this) && this || {};\n const result = {};\n const assignValue = (val, key) => {\n const targetKey = caseless && findKey(result, key) || key;\n if (isPlainObject(result[targetKey]) && isPlainObject(val)) {\n result[targetKey] = merge(result[targetKey], val);\n } else if (isPlainObject(val)) {\n result[targetKey] = merge({}, val);\n } else if (isArray(val)) {\n result[targetKey] = val.slice();\n } else {\n result[targetKey] = val;\n }\n }\n\n for (let i = 0, l = arguments.length; i < l; i++) {\n arguments[i] && forEach(arguments[i], assignValue);\n }\n return result;\n}\n\n/**\n * Extends object a by mutably adding to it the properties of object b.\n *\n * @param {Object} a The object to be extended\n * @param {Object} b The object to copy properties from\n * @param {Object} thisArg The object to bind function to\n *\n * @param {Boolean} [allOwnKeys]\n * @returns {Object} The resulting value of object a\n */\nconst extend = (a, b, thisArg, {allOwnKeys}= {}) => {\n forEach(b, (val, key) => {\n if (thisArg && isFunction(val)) {\n a[key] = bind(val, thisArg);\n } else {\n a[key] = val;\n }\n }, {allOwnKeys});\n return a;\n}\n\n/**\n * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)\n *\n * @param {string} content with BOM\n *\n * @returns {string} content value without BOM\n */\nconst stripBOM = (content) => {\n if (content.charCodeAt(0) === 0xFEFF) {\n content = content.slice(1);\n }\n return content;\n}\n\n/**\n * Inherit the prototype methods from one constructor into another\n * @param {function} constructor\n * @param {function} superConstructor\n * @param {object} [props]\n * @param {object} [descriptors]\n *\n * @returns {void}\n */\nconst inherits = (constructor, superConstructor, props, descriptors) => {\n constructor.prototype = Object.create(superConstructor.prototype, descriptors);\n constructor.prototype.constructor = constructor;\n Object.defineProperty(constructor, 'super', {\n value: superConstructor.prototype\n });\n props && Object.assign(constructor.prototype, props);\n}\n\n/**\n * Resolve object with deep prototype chain to a flat object\n * @param {Object} sourceObj source object\n * @param {Object} [destObj]\n * @param {Function|Boolean} [filter]\n * @param {Function} [propFilter]\n *\n * @returns {Object}\n */\nconst toFlatObject = (sourceObj, destObj, filter, propFilter) => {\n let props;\n let i;\n let prop;\n const merged = {};\n\n destObj = destObj || {};\n // eslint-disable-next-line no-eq-null,eqeqeq\n if (sourceObj == null) return destObj;\n\n do {\n props = Object.getOwnPropertyNames(sourceObj);\n i = props.length;\n while (i-- > 0) {\n prop = props[i];\n if ((!propFilter || propFilter(prop, sourceObj, destObj)) && !merged[prop]) {\n destObj[prop] = sourceObj[prop];\n merged[prop] = true;\n }\n }\n sourceObj = filter !== false && getPrototypeOf(sourceObj);\n } while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype);\n\n return destObj;\n}\n\n/**\n * Determines whether a string ends with the characters of a specified string\n *\n * @param {String} str\n * @param {String} searchString\n * @param {Number} [position= 0]\n *\n * @returns {boolean}\n */\nconst endsWith = (str, searchString, position) => {\n str = String(str);\n if (position === undefined || position > str.length) {\n position = str.length;\n }\n position -= searchString.length;\n const lastIndex = str.indexOf(searchString, position);\n return lastIndex !== -1 && lastIndex === position;\n}\n\n\n/**\n * Returns new array from array like object or null if failed\n *\n * @param {*} [thing]\n *\n * @returns {?Array}\n */\nconst toArray = (thing) => {\n if (!thing) return null;\n if (isArray(thing)) return thing;\n let i = thing.length;\n if (!isNumber(i)) return null;\n const arr = new Array(i);\n while (i-- > 0) {\n arr[i] = thing[i];\n }\n return arr;\n}\n\n/**\n * Checking if the Uint8Array exists and if it does, it returns a function that checks if the\n * thing passed in is an instance of Uint8Array\n *\n * @param {TypedArray}\n *\n * @returns {Array}\n */\n// eslint-disable-next-line func-names\nconst isTypedArray = (TypedArray => {\n // eslint-disable-next-line func-names\n return thing => {\n return TypedArray && thing instanceof TypedArray;\n };\n})(typeof Uint8Array !== 'undefined' && getPrototypeOf(Uint8Array));\n\n/**\n * For each entry in the object, call the function with the key and value.\n *\n * @param {Object<any, any>} obj - The object to iterate over.\n * @param {Function} fn - The function to call for each entry.\n *\n * @returns {void}\n */\nconst forEachEntry = (obj, fn) => {\n const generator = obj && obj[iterator];\n\n const _iterator = generator.call(obj);\n\n let result;\n\n while ((result = _iterator.next()) && !result.done) {\n const pair = result.value;\n fn.call(obj, pair[0], pair[1]);\n }\n}\n\n/**\n * It takes a regular expression and a string, and returns an array of all the matches\n *\n * @param {string} regExp - The regular expression to match against.\n * @param {string} str - The string to search.\n *\n * @returns {Array<boolean>}\n */\nconst matchAll = (regExp, str) => {\n let matches;\n const arr = [];\n\n while ((matches = regExp.exec(str)) !== null) {\n arr.push(matches);\n }\n\n return arr;\n}\n\n/* Checking if the kindOfTest function returns true when passed an HTMLFormElement. */\nconst isHTMLForm = kindOfTest('HTMLFormElement');\n\nconst toCamelCase = str => {\n return str.toLowerCase().replace(/[-_\\s]([a-z\\d])(\\w*)/g,\n function replacer(m, p1, p2) {\n return p1.toUpperCase() + p2;\n }\n );\n};\n\n/* Creating a function that will check if an object has a property. */\nconst hasOwnProperty = (({hasOwnProperty}) => (obj, prop) => hasOwnProperty.call(obj, prop))(Object.prototype);\n\n/**\n * Determine if a value is a RegExp object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a RegExp object, otherwise false\n */\nconst isRegExp = kindOfTest('RegExp');\n\nconst reduceDescriptors = (obj, reducer) => {\n const descriptors = Object.getOwnPropertyDescriptors(obj);\n const reducedDescriptors = {};\n\n forEach(descriptors, (descriptor, name) => {\n let ret;\n if ((ret = reducer(descriptor, name, obj)) !== false) {\n reducedDescriptors[name] = ret || descriptor;\n }\n });\n\n Object.defineProperties(obj, reducedDescriptors);\n}\n\n/**\n * Makes all methods read-only\n * @param {Object} obj\n */\n\nconst freezeMethods = (obj) => {\n reduceDescriptors(obj, (descriptor, name) => {\n // skip restricted props in strict mode\n if (isFunction(obj) && ['arguments', 'caller', 'callee'].indexOf(name) !== -1) {\n return false;\n }\n\n const value = obj[name];\n\n if (!isFunction(value)) return;\n\n descriptor.enumerable = false;\n\n if ('writable' in descriptor) {\n descriptor.writable = false;\n return;\n }\n\n if (!descriptor.set) {\n descriptor.set = () => {\n throw Error('Can not rewrite read-only method \\'' + name + '\\'');\n };\n }\n });\n}\n\nconst toObjectSet = (arrayOrString, delimiter) => {\n const obj = {};\n\n const define = (arr) => {\n arr.forEach(value => {\n obj[value] = true;\n });\n }\n\n isArray(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(delimiter));\n\n return obj;\n}\n\nconst noop = () => {}\n\nconst toFiniteNumber = (value, defaultValue) => {\n return value != null && Number.isFinite(value = +value) ? value : defaultValue;\n}\n\n/**\n * If the thing is a FormData object, return true, otherwise return false.\n *\n * @param {unknown} thing - The thing to check.\n *\n * @returns {boolean}\n */\nfunction isSpecCompliantForm(thing) {\n return !!(thing && isFunction(thing.append) && thing[toStringTag] === 'FormData' && thing[iterator]);\n}\n\nconst toJSONObject = (obj) => {\n const stack = new Array(10);\n\n const visit = (source, i) => {\n\n if (isObject(source)) {\n if (stack.indexOf(source) >= 0) {\n return;\n }\n\n if(!('toJSON' in source)) {\n stack[i] = source;\n const target = isArray(source) ? [] : {};\n\n forEach(source, (value, key) => {\n const reducedValue = visit(value, i + 1);\n !isUndefined(reducedValue) && (target[key] = reducedValue);\n });\n\n stack[i] = undefined;\n\n return target;\n }\n }\n\n return source;\n }\n\n return visit(obj, 0);\n}\n\nconst isAsyncFn = kindOfTest('AsyncFunction');\n\nconst isThenable = (thing) =>\n thing && (isObject(thing) || isFunction(thing)) && isFunction(thing.then) && isFunction(thing.catch);\n\n// original code\n// https://github.com/DigitalBrainJS/AxiosPromise/blob/16deab13710ec09779922131f3fa5954320f83ab/lib/utils.js#L11-L34\n\nconst _setImmediate = ((setImmediateSupported, postMessageSupported) => {\n if (setImmediateSupported) {\n return setImmediate;\n }\n\n return postMessageSupported ? ((token, callbacks) => {\n _global.addEventListener(\"message\", ({source, data}) => {\n if (source === _global && data === token) {\n callbacks.length && callbacks.shift()();\n }\n }, false);\n\n return (cb) => {\n callbacks.push(cb);\n _global.postMessage(token, \"*\");\n }\n })(`axios@${Math.random()}`, []) : (cb) => setTimeout(cb);\n})(\n typeof setImmediate === 'function',\n isFunction(_global.postMessage)\n);\n\nconst asap = typeof queueMicrotask !== 'undefined' ?\n queueMicrotask.bind(_global) : ( typeof process !== 'undefined' && process.nextTick || _setImmediate);\n\n// *********************\n\n\nconst isIterable = (thing) => thing != null && isFunction(thing[iterator]);\n\n\nexport default {\n isArray,\n isArrayBuffer,\n isBuffer,\n isFormData,\n isArrayBufferView,\n isString,\n isNumber,\n isBoolean,\n isObject,\n isPlainObject,\n isReadableStream,\n isRequest,\n isResponse,\n isHeaders,\n isUndefined,\n isDate,\n isFile,\n isBlob,\n isRegExp,\n isFunction,\n isStream,\n isURLSearchParams,\n isTypedArray,\n isFileList,\n forEach,\n merge,\n extend,\n trim,\n stripBOM,\n inherits,\n toFlatObject,\n kindOf,\n kindOfTest,\n endsWith,\n toArray,\n forEachEntry,\n matchAll,\n isHTMLForm,\n hasOwnProperty,\n hasOwnProp: hasOwnProperty, // an alias to avoid ESLint no-prototype-builtins detection\n reduceDescriptors,\n freezeMethods,\n toObjectSet,\n toCamelCase,\n noop,\n toFiniteNumber,\n findKey,\n global: _global,\n isContextDefined,\n isSpecCompliantForm,\n toJSONObject,\n isAsyncFn,\n isThenable,\n setImmediate: _setImmediate,\n asap,\n isIterable\n};\n","'use strict';\n\nimport utils from '../utils.js';\n\n/**\n * Create an Error with the specified message, config, error code, request and response.\n *\n * @param {string} message The error message.\n * @param {string} [code] The error code (for example, 'ECONNABORTED').\n * @param {Object} [config] The config.\n * @param {Object} [request] The request.\n * @param {Object} [response] The response.\n *\n * @returns {Error} The created error.\n */\nfunction AxiosError(message, code, config, request, response) {\n Error.call(this);\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n } else {\n this.stack = (new Error()).stack;\n }\n\n this.message = message;\n this.name = 'AxiosError';\n code && (this.code = code);\n config && (this.config = config);\n request && (this.request = request);\n if (response) {\n this.response = response;\n this.status = response.status ? response.status : null;\n }\n}\n\nutils.inherits(AxiosError, Error, {\n toJSON: function toJSON() {\n return {\n // Standard\n message: this.message,\n name: this.name,\n // Microsoft\n description: this.description,\n number: this.number,\n // Mozilla\n fileName: this.fileName,\n lineNumber: this.lineNumber,\n columnNumber: this.columnNumber,\n stack: this.stack,\n // Axios\n config: utils.toJSONObject(this.config),\n code: this.code,\n status: this.status\n };\n }\n});\n\nconst prototype = AxiosError.prototype;\nconst descriptors = {};\n\n[\n 'ERR_BAD_OPTION_VALUE',\n 'ERR_BAD_OPTION',\n 'ECONNABORTED',\n 'ETIMEDOUT',\n 'ERR_NETWORK',\n 'ERR_FR_TOO_MANY_REDIRECTS',\n 'ERR_DEPRECATED',\n 'ERR_BAD_RESPONSE',\n 'ERR_BAD_REQUEST',\n 'ERR_CANCELED',\n 'ERR_NOT_SUPPORT',\n 'ERR_INVALID_URL'\n// eslint-disable-next-line func-names\n].forEach(code => {\n descriptors[code] = {value: code};\n});\n\nObject.defineProperties(AxiosError, descriptors);\nObject.defineProperty(prototype, 'isAxiosError', {value: true});\n\n// eslint-disable-next-line func-names\nAxiosError.from = (error, code, config, request, response, customProps) => {\n const axiosError = Object.create(prototype);\n\n utils.toFlatObject(error, axiosError, function filter(obj) {\n return obj !== Error.prototype;\n }, prop => {\n return prop !== 'isAxiosError';\n });\n\n AxiosError.call(axiosError, error.message, code, config, request, response);\n\n axiosError.cause = error;\n\n axiosError.name = error.name;\n\n customProps && Object.assign(axiosError, customProps);\n\n return axiosError;\n};\n\nexport default AxiosError;\n","var Stream = require('stream').Stream;\nvar util = require('util');\n\nmodule.exports = DelayedStream;\nfunction DelayedStream() {\n this.source = null;\n this.dataSize = 0;\n this.maxDataSize = 1024 * 1024;\n this.pauseStream = true;\n\n this._maxDataSizeExceeded = false;\n this._released = false;\n this._bufferedEvents = [];\n}\nutil.inherits(DelayedStream, Stream);\n\nDelayedStream.create = function(source, options) {\n var delayedStream = new this();\n\n options = options || {};\n for (var option in options) {\n delayedStream[option] = options[option];\n }\n\n delayedStream.source = source;\n\n var realEmit = source.emit;\n source.emit = function() {\n delayedStream._handleEmit(arguments);\n return realEmit.apply(source, arguments);\n };\n\n source.on('error', function() {});\n if (delayedStream.pauseStream) {\n source.pause();\n }\n\n return delayedStream;\n};\n\nObject.defineProperty(DelayedStream.prototype, 'readable', {\n configurable: true,\n enumerable: true,\n get: function() {\n return this.source.readable;\n }\n});\n\nDelayedStream.prototype.setEncoding = function() {\n return this.source.setEncoding.apply(this.source, arguments);\n};\n\nDelayedStream.prototype.resume = function() {\n if (!this._released) {\n this.release();\n }\n\n this.source.resume();\n};\n\nDelayedStream.prototype.pause = function() {\n this.source.pause();\n};\n\nDelayedStream.prototype.release = function() {\n this._released = true;\n\n this._bufferedEvents.forEach(function(args) {\n this.emit.apply(this, args);\n }.bind(this));\n this._bufferedEvents = [];\n};\n\nDelayedStream.prototype.pipe = function() {\n var r = Stream.prototype.pipe.apply(this, arguments);\n this.resume();\n return r;\n};\n\nDelayedStream.prototype._handleEmit = function(args) {\n if (this._released) {\n this.emit.apply(this, args);\n return;\n }\n\n if (args[0] === 'data') {\n this.dataSize += args[1].length;\n this._checkIfMaxDataSizeExceeded();\n }\n\n this._bufferedEvents.push(args);\n};\n\nDelayedStream.prototype._checkIfMaxDataSizeExceeded = function() {\n if (this._maxDataSizeExceeded) {\n return;\n }\n\n if (this.dataSize <= this.maxDataSize) {\n return;\n }\n\n this._maxDataSizeExceeded = true;\n var message =\n 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.'\n this.emit('error', new Error(message));\n};\n","var util = require('util');\nvar Stream = require('stream').Stream;\nvar DelayedStream = require('delayed-stream');\n\nmodule.exports = CombinedStream;\nfunction CombinedStream() {\n this.writable = false;\n this.readable = true;\n this.dataSize = 0;\n this.maxDataSize = 2 * 1024 * 1024;\n this.pauseStreams = true;\n\n this._released = false;\n this._streams = [];\n this._currentStream = null;\n this._insideLoop = false;\n this._pendingNext = false;\n}\nutil.inherits(CombinedStream, Stream);\n\nCombinedStream.create = function(options) {\n var combinedStream = new this();\n\n options = options || {};\n for (var option in options) {\n combinedStream[option] = options[option];\n }\n\n return combinedStream;\n};\n\nCombinedStream.isStreamLike = function(stream) {\n return (typeof stream !== 'function')\n && (typeof stream !== 'string')\n && (typeof stream !== 'boolean')\n && (typeof stream !== 'number')\n && (!Buffer.isBuffer(stream));\n};\n\nCombinedStream.prototype.append = function(stream) {\n var isStreamLike = CombinedStream.isStreamLike(stream);\n\n if (isStreamLike) {\n if (!(stream instanceof DelayedStream)) {\n var newStream = DelayedStream.create(stream, {\n maxDataSize: Infinity,\n pauseStream: this.pauseStreams,\n });\n stream.on('data', this._checkDataSize.bind(this));\n stream = newStream;\n }\n\n this._handleErrors(stream);\n\n if (this.pauseStreams) {\n stream.pause();\n }\n }\n\n this._streams.push(stream);\n return this;\n};\n\nCombinedStream.prototype.pipe = function(dest, options) {\n Stream.prototype.pipe.call(this, dest, options);\n this.resume();\n return dest;\n};\n\nCombinedStream.prototype._getNext = function() {\n this._currentStream = null;\n\n if (this._insideLoop) {\n this._pendingNext = true;\n return; // defer call\n }\n\n this._insideLoop = true;\n try {\n do {\n this._pendingNext = false;\n this._realGetNext();\n } while (this._pendingNext);\n } finally {\n this._insideLoop = false;\n }\n};\n\nCombinedStream.prototype._realGetNext = function() {\n var stream = this._streams.shift();\n\n\n if (typeof stream == 'undefined') {\n this.end();\n return;\n }\n\n if (typeof stream !== 'function') {\n this._pipeNext(stream);\n return;\n }\n\n var getStream = stream;\n getStream(function(stream) {\n var isStreamLike = CombinedStream.isStreamLike(stream);\n if (isStreamLike) {\n stream.on('data', this._checkDataSize.bind(this));\n this._handleErrors(stream);\n }\n\n this._pipeNext(stream);\n }.bind(this));\n};\n\nCombinedStream.prototype._pipeNext = function(stream) {\n this._currentStream = stream;\n\n var isStreamLike = CombinedStream.isStreamLike(stream);\n if (isStreamLike) {\n stream.on('end', this._getNext.bind(this));\n stream.pipe(this, {end: false});\n return;\n }\n\n var value = stream;\n this.write(value);\n this._getNext();\n};\n\nCombinedStream.prototype._handleErrors = function(stream) {\n var self = this;\n stream.on('error', function(err) {\n self._emitError(err);\n });\n};\n\nCombinedStream.prototype.write = function(data) {\n this.emit('data', data);\n};\n\nCombinedStream.prototype.pause = function() {\n if (!this.pauseStreams) {\n return;\n }\n\n if(this.pauseStreams && this._currentStream && typeof(this._currentStream.pause) == 'function') this._currentStream.pause();\n this.emit('pause');\n};\n\nCombinedStream.prototype.resume = function() {\n if (!this._released) {\n this._released = true;\n this.writable = true;\n this._getNext();\n }\n\n if(this.pauseStreams && this._currentStream && typeof(this._currentStream.resume) == 'function') this._currentStream.resume();\n this.emit('resume');\n};\n\nCombinedStream.prototype.end = function() {\n this._reset();\n this.emit('end');\n};\n\nCombinedStream.prototype.destroy = function() {\n this._reset();\n this.emit('close');\n};\n\nCombinedStream.prototype._reset = function() {\n this.writable = false;\n this._streams = [];\n this._currentStream = null;\n};\n\nCombinedStream.prototype._checkDataSize = function() {\n this._updateDataSize();\n if (this.dataSize <= this.maxDataSize) {\n return;\n }\n\n var message =\n 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.';\n this._emitError(new Error(message));\n};\n\nCombinedStream.prototype._updateDataSize = function() {\n this.dataSize = 0;\n\n var self = this;\n this._streams.forEach(function(stream) {\n if (!stream.dataSize) {\n return;\n }\n\n self.dataSize += stream.dataSize;\n });\n\n if (this._currentStream && this._currentStream.dataSize) {\n this.dataSize += this._currentStream.dataSize;\n }\n};\n\nCombinedStream.prototype._emitError = function(err) {\n this._reset();\n this.emit('error', err);\n};\n","","/*!\n * mime-db\n * Copyright(c) 2014 Jonathan Ong\n * Copyright(c) 2015-2022 Douglas Christopher Wilson\n * MIT Licensed\n */\n\n/**\n * Module exports.\n */\n\nmodule.exports = require('./db.json')\n","/*!\n * mime-types\n * Copyright(c) 2014 Jonathan Ong\n * Copyright(c) 2015 Douglas Christopher Wilson\n * MIT Licensed\n */\n\n'use strict'\n\n/**\n * Module dependencies.\n * @private\n */\n\nvar db = require('mime-db')\nvar extname = require('path').extname\n\n/**\n * Module variables.\n * @private\n */\n\nvar EXTRACT_TYPE_REGEXP = /^\\s*([^;\\s]*)(?:;|\\s|$)/\nvar TEXT_TYPE_REGEXP = /^text\\//i\n\n/**\n * Module exports.\n * @public\n */\n\nexports.charset = charset\nexports.charsets = { lookup: charset }\nexports.contentType = contentType\nexports.extension = extension\nexports.extensions = Object.create(null)\nexports.lookup = lookup\nexports.types = Object.create(null)\n\n// Populate the extensions/types maps\npopulateMaps(exports.extensions, exports.types)\n\n/**\n * Get the default charset for a MIME type.\n *\n * @param {string} type\n * @return {boolean|string}\n */\n\nfunction charset (type) {\n if (!type || typeof type !== 'string') {\n return false\n }\n\n // TODO: use media-typer\n var match = EXTRACT_TYPE_REGEXP.exec(type)\n var mime = match && db[match[1].toLowerCase()]\n\n if (mime && mime.charset) {\n return mime.charset\n }\n\n // default text/* to utf-8\n if (match && TEXT_TYPE_REGEXP.test(match[1])) {\n return 'UTF-8'\n }\n\n return false\n}\n\n/**\n * Create a full Content-Type header given a MIME type or extension.\n *\n * @param {string} str\n * @return {boolean|string}\n */\n\nfunction contentType (str) {\n // TODO: should this even be in this module?\n if (!str || typeof str !== 'string') {\n return false\n }\n\n var mime = str.indexOf('/') === -1\n ? exports.lookup(str)\n : str\n\n if (!mime) {\n return false\n }\n\n // TODO: use content-type or other module\n if (mime.indexOf('charset') === -1) {\n var charset = exports.charset(mime)\n if (charset) mime += '; charset=' + charset.toLowerCase()\n }\n\n return mime\n}\n\n/**\n * Get the default extension for a MIME type.\n *\n * @param {string} type\n * @return {boolean|string}\n */\n\nfunction extension (type) {\n if (!type || typeof type !== 'string') {\n return false\n }\n\n // TODO: use media-typer\n var match = EXTRACT_TYPE_REGEXP.exec(type)\n\n // get extensions\n var exts = match && exports.extensions[match[1].toLowerCase()]\n\n if (!exts || !exts.length) {\n return false\n }\n\n return exts[0]\n}\n\n/**\n * Lookup the MIME type for a file path/extension.\n *\n * @param {string} path\n * @return {boolean|string}\n */\n\nfunction lookup (path) {\n if (!path || typeof path !== 'string') {\n return false\n }\n\n // get the extension (\"ext\" or \".ext\" or full path)\n var extension = extname('x.' + path)\n .toLowerCase()\n .substr(1)\n\n if (!extension) {\n return false\n }\n\n return exports.types[extension] || false\n}\n\n/**\n * Populate the extensions and types maps.\n * @private\n */\n\nfunction populateMaps (extensions, types) {\n // source preference (least -> most)\n var preference = ['nginx', 'apache', undefined, 'iana']\n\n Object.keys(db).forEach(function forEachMimeType (type) {\n var mime = db[type]\n var exts = mime.extensions\n\n if (!exts || !exts.length) {\n return\n }\n\n // mime -> extensions\n extensions[type] = exts\n\n // extension -> mime\n for (var i = 0; i < exts.length; i++) {\n var extension = exts[i]\n\n if (types[extension]) {\n var from = preference.indexOf(db[types[extension]].source)\n var to = preference.indexOf(mime.source)\n\n if (types[extension] !== 'application/octet-stream' &&\n (from > to || (from === to && types[extension].substr(0, 12) === 'application/'))) {\n // skip the remapping\n continue\n }\n }\n\n // set the extension -> mime\n types[extension] = type\n }\n })\n}\n","module.exports = defer;\n\n/**\n * Runs provided function on next iteration of the event loop\n *\n * @param {function} fn - function to run\n */\nfunction defer(fn)\n{\n var nextTick = typeof setImmediate == 'function'\n ? setImmediate\n : (\n typeof process == 'object' && typeof process.nextTick == 'function'\n ? process.nextTick\n : null\n );\n\n if (nextTick)\n {\n nextTick(fn);\n }\n else\n {\n setTimeout(fn, 0);\n }\n}\n","var defer = require('./defer.js');\n\n// API\nmodule.exports = async;\n\n/**\n * Runs provided callback asynchronously\n * even if callback itself is not\n *\n * @param {function} callback - callback to invoke\n * @returns {function} - augmented callback\n */\nfunction async(callback)\n{\n var isAsync = false;\n\n // check if async happened\n defer(function() { isAsync = true; });\n\n return function async_callback(err, result)\n {\n if (isAsync)\n {\n callback(err, result);\n }\n else\n {\n defer(function nextTick_callback()\n {\n callback(err, result);\n });\n }\n };\n}\n","// API\nmodule.exports = abort;\n\n/**\n * Aborts leftover active jobs\n *\n * @param {object} state - current state object\n */\nfunction abort(state)\n{\n Object.keys(state.jobs).forEach(clean.bind(state));\n\n // reset leftover jobs\n state.jobs = {};\n}\n\n/**\n * Cleans up leftover job by invoking abort function for the provided job id\n *\n * @this state\n * @param {string|number} key - job id to abort\n */\nfunction clean(key)\n{\n if (typeof this.jobs[key] == 'function')\n {\n this.jobs[key]();\n }\n}\n","var async = require('./async.js')\n , abort = require('./abort.js')\n ;\n\n// API\nmodule.exports = iterate;\n\n/**\n * Iterates over each job object\n *\n * @param {array|object} list - array or object (named list) to iterate over\n * @param {function} iterator - iterator to run\n * @param {object} state - current job status\n * @param {function} callback - invoked when all elements processed\n */\nfunction iterate(list, iterator, state, callback)\n{\n // store current index\n var key = state['keyedList'] ? state['keyedList'][state.index] : state.index;\n\n state.jobs[key] = runJob(iterator, key, list[key], function(error, output)\n {\n // don't repeat yourself\n // skip secondary callbacks\n if (!(key in state.jobs))\n {\n return;\n }\n\n // clean up jobs\n delete state.jobs[key];\n\n if (error)\n {\n // don't process rest of the results\n // stop still active jobs\n // and reset the list\n abort(state);\n }\n else\n {\n state.results[key] = output;\n }\n\n // return salvaged results\n callback(error, state.results);\n });\n}\n\n/**\n * Runs iterator over provided job element\n *\n * @param {function} iterator - iterator to invoke\n * @param {string|number} key - key/index of the element in the list of jobs\n * @param {mixed} item - job description\n * @param {function} callback - invoked after iterator is done with the job\n * @returns {function|mixed} - job abort function or something else\n */\nfunction runJob(iterator, key, item, callback)\n{\n var aborter;\n\n // allow shortcut if iterator expects only two arguments\n if (iterator.length == 2)\n {\n aborter = iterator(item, async(callback));\n }\n // otherwise go with full three arguments\n else\n {\n aborter = iterator(item, key, async(callback));\n }\n\n return aborter;\n}\n","// API\nmodule.exports = state;\n\n/**\n * Creates initial state object\n * for iteration over list\n *\n * @param {array|object} list - list to iterate over\n * @param {function|null} sortMethod - function to use for keys sort,\n * or `null` to keep them as is\n * @returns {object} - initial state object\n */\nfunction state(list, sortMethod)\n{\n var isNamedList = !Array.isArray(list)\n , initState =\n {\n index : 0,\n keyedList: isNamedList || sortMethod ? Object.keys(list) : null,\n jobs : {},\n results : isNamedList ? {} : [],\n size : isNamedList ? Object.keys(list).length : list.length\n }\n ;\n\n if (sortMethod)\n {\n // sort array keys based on it's values\n // sort object's keys just on own merit\n initState.keyedList.sort(isNamedList ? sortMethod : function(a, b)\n {\n return sortMethod(list[a], list[b]);\n });\n }\n\n return initState;\n}\n","var abort = require('./abort.js')\n , async = require('./async.js')\n ;\n\n// API\nmodule.exports = terminator;\n\n/**\n * Terminates jobs in the attached state context\n *\n * @this AsyncKitState#\n * @param {function} callback - final callback to invoke after termination\n */\nfunction terminator(callback)\n{\n if (!Object.keys(this.jobs).length)\n {\n return;\n }\n\n // fast forward iteration index\n this.index = this.size;\n\n // abort jobs\n abort(this);\n\n // send back results we have so far\n async(callback)(null, this.results);\n}\n","var iterate = require('./lib/iterate.js')\n , initState = require('./lib/state.js')\n , terminator = require('./lib/terminator.js')\n ;\n\n// Public API\nmodule.exports = parallel;\n\n/**\n * Runs iterator over provided array elements in parallel\n *\n * @param {array|object} list - array or object (named list) to iterate over\n * @param {function} iterator - iterator to run\n * @param {function} callback - invoked when all elements processed\n * @returns {function} - jobs terminator\n */\nfunction parallel(list, iterator, callback)\n{\n var state = initState(list);\n\n while (state.index < (state['keyedList'] || list).length)\n {\n iterate(list, iterator, state, function(error, result)\n {\n if (error)\n {\n callback(error, result);\n return;\n }\n\n // looks like it's the last one\n if (Object.keys(state.jobs).length === 0)\n {\n callback(null, state.results);\n return;\n }\n });\n\n state.index++;\n }\n\n return terminator.bind(state, callback);\n}\n","var iterate = require('./lib/iterate.js')\n , initState = require('./lib/state.js')\n , terminator = require('./lib/terminator.js')\n ;\n\n// Public API\nmodule.exports = serialOrdered;\n// sorting helpers\nmodule.exports.ascending = ascending;\nmodule.exports.descending = descending;\n\n/**\n * Runs iterator over provided sorted array elements in series\n *\n * @param {array|object} list - array or object (named list) to iterate over\n * @param {function} iterator - iterator to run\n * @param {function} sortMethod - custom sort function\n * @param {function} callback - invoked when all elements processed\n * @returns {function} - jobs terminator\n */\nfunction serialOrdered(list, iterator, sortMethod, callback)\n{\n var state = initState(list, sortMethod);\n\n iterate(list, iterator, state, function iteratorHandler(error, result)\n {\n if (error)\n {\n callback(error, result);\n return;\n }\n\n state.index++;\n\n // are we there yet?\n if (state.index < (state['keyedList'] || list).length)\n {\n iterate(list, iterator, state, iteratorHandler);\n return;\n }\n\n // done here\n callback(null, state.results);\n });\n\n return terminator.bind(state, callback);\n}\n\n/*\n * -- Sort methods\n */\n\n/**\n * sort helper to sort array elements in ascending order\n *\n * @param {mixed} a - an item to compare\n * @param {mixed} b - an item to compare\n * @returns {number} - comparison result\n */\nfunction ascending(a, b)\n{\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\n/**\n * sort helper to sort array elements in descending order\n *\n * @param {mixed} a - an item to compare\n * @param {mixed} b - an item to compare\n * @returns {number} - comparison result\n */\nfunction descending(a, b)\n{\n return -1 * ascending(a, b);\n}\n","var serialOrdered = require('./serialOrdered.js');\n\n// Public API\nmodule.exports = serial;\n\n/**\n * Runs iterator over provided array elements in series\n *\n * @param {array|object} list - array or object (named list) to iterate over\n * @param {function} iterator - iterator to run\n * @param {function} callback - invoked when all elements processed\n * @returns {function} - jobs terminator\n */\nfunction serial(list, iterator, callback)\n{\n return serialOrdered(list, iterator, null, callback);\n}\n","module.exports =\n{\n parallel : require('./parallel.js'),\n serial : require('./serial.js'),\n serialOrdered : require('./serialOrdered.js')\n};\n","'use strict';\n\n/** @type {import('.')} */\nmodule.exports = Object;\n","'use strict';\n\n/** @type {import('.')} */\nmodule.exports = Error;\n","'use strict';\n\n/** @type {import('./eval')} */\nmodule.exports = EvalError;\n","'use strict';\n\n/** @type {import('./range')} */\nmodule.exports = RangeError;\n","'use strict';\n\n/** @type {import('./ref')} */\nmodule.exports = ReferenceError;\n","'use strict';\n\n/** @type {import('./syntax')} */\nmodule.exports = SyntaxError;\n","'use strict';\n\n/** @type {import('./type')} */\nmodule.exports = TypeError;\n","'use strict';\n\n/** @type {import('./uri')} */\nmodule.exports = URIError;\n","'use strict';\n\n/** @type {import('./abs')} */\nmodule.exports = Math.abs;\n","'use strict';\n\n/** @type {import('./floor')} */\nmodule.exports = Math.floor;\n","'use strict';\n\n/** @type {import('./max')} */\nmodule.exports = Math.max;\n","'use strict';\n\n/** @type {import('./min')} */\nmodule.exports = Math.min;\n","'use strict';\n\n/** @type {import('./pow')} */\nmodule.exports = Math.pow;\n","'use strict';\n\n/** @type {import('./round')} */\nmodule.exports = Math.round;\n","'use strict';\n\n/** @type {import('./isNaN')} */\nmodule.exports = Number.isNaN || function isNaN(a) {\n\treturn a !== a;\n};\n","'use strict';\n\nvar $isNaN = require('./isNaN');\n\n/** @type {import('./sign')} */\nmodule.exports = function sign(number) {\n\tif ($isNaN(number) || number === 0) {\n\t\treturn number;\n\t}\n\treturn number < 0 ? -1 : +1;\n};\n","'use strict';\n\n/** @type {import('./gOPD')} */\nmodule.exports = Object.getOwnPropertyDescriptor;\n","'use strict';\n\n/** @type {import('.')} */\nvar $gOPD = require('./gOPD');\n\nif ($gOPD) {\n\ttry {\n\t\t$gOPD([], 'length');\n\t} catch (e) {\n\t\t// IE 8 has a broken gOPD\n\t\t$gOPD = null;\n\t}\n}\n\nmodule.exports = $gOPD;\n","'use strict';\n\n/** @type {import('.')} */\nvar $defineProperty = Object.defineProperty || false;\nif ($defineProperty) {\n\ttry {\n\t\t$defineProperty({}, 'a', { value: 1 });\n\t} catch (e) {\n\t\t// IE 8 has a broken defineProperty\n\t\t$defineProperty = false;\n\t}\n}\n\nmodule.exports = $defineProperty;\n","'use strict';\n\n/** @type {import('./shams')} */\n/* eslint complexity: [2, 18], max-statements: [2, 33] */\nmodule.exports = function hasSymbols() {\n\tif (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; }\n\tif (typeof Symbol.iterator === 'symbol') { return true; }\n\n\t/** @type {{ [k in symbol]?: unknown }} */\n\tvar obj = {};\n\tvar sym = Symbol('test');\n\tvar symObj = Object(sym);\n\tif (typeof sym === 'string') { return false; }\n\n\tif (Object.prototype.toString.call(sym) !== '[object Symbol]') { return false; }\n\tif (Object.prototype.toString.call(symObj) !== '[object Symbol]') { return false; }\n\n\t// temp disabled per https://github.com/ljharb/object.assign/issues/17\n\t// if (sym instanceof Symbol) { return false; }\n\t// temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4\n\t// if (!(symObj instanceof Symbol)) { return false; }\n\n\t// if (typeof Symbol.prototype.toString !== 'function') { return false; }\n\t// if (String(sym) !== Symbol.prototype.toString.call(sym)) { return false; }\n\n\tvar symVal = 42;\n\tobj[sym] = symVal;\n\tfor (var _ in obj) { return false; } // eslint-disable-line no-restricted-syntax, no-unreachable-loop\n\tif (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; }\n\n\tif (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; }\n\n\tvar syms = Object.getOwnPropertySymbols(obj);\n\tif (syms.length !== 1 || syms[0] !== sym) { return false; }\n\n\tif (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; }\n\n\tif (typeof Object.getOwnPropertyDescriptor === 'function') {\n\t\t// eslint-disable-next-line no-extra-parens\n\t\tvar descriptor = /** @type {PropertyDescriptor} */ (Object.getOwnPropertyDescriptor(obj, sym));\n\t\tif (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; }\n\t}\n\n\treturn true;\n};\n","'use strict';\n\nvar origSymbol = typeof Symbol !== 'undefined' && Symbol;\nvar hasSymbolSham = require('./shams');\n\n/** @type {import('.')} */\nmodule.exports = function hasNativeSymbols() {\n\tif (typeof origSymbol !== 'function') { return false; }\n\tif (typeof Symbol !== 'function') { return false; }\n\tif (typeof origSymbol('foo') !== 'symbol') { return false; }\n\tif (typeof Symbol('bar') !== 'symbol') { return false; }\n\n\treturn hasSymbolSham();\n};\n","'use strict';\n\n/** @type {import('./Reflect.getPrototypeOf')} */\nmodule.exports = (typeof Reflect !== 'undefined' && Reflect.getPrototypeOf) || null;\n","'use strict';\n\nvar $Object = require('es-object-atoms');\n\n/** @type {import('./Object.getPrototypeOf')} */\nmodule.exports = $Object.getPrototypeOf || null;\n","'use strict';\n\n/* eslint no-invalid-this: 1 */\n\nvar ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';\nvar toStr = Object.prototype.toString;\nvar max = Math.max;\nvar funcType = '[object Function]';\n\nvar concatty = function concatty(a, b) {\n var arr = [];\n\n for (var i = 0; i < a.length; i += 1) {\n arr[i] = a[i];\n }\n for (var j = 0; j < b.length; j += 1) {\n arr[j + a.length] = b[j];\n }\n\n return arr;\n};\n\nvar slicy = function slicy(arrLike, offset) {\n var arr = [];\n for (var i = offset || 0, j = 0; i < arrLike.length; i += 1, j += 1) {\n arr[j] = arrLike[i];\n }\n return arr;\n};\n\nvar joiny = function (arr, joiner) {\n var str = '';\n for (var i = 0; i < arr.length; i += 1) {\n str += arr[i];\n if (i + 1 < arr.length) {\n str += joiner;\n }\n }\n return str;\n};\n\nmodule.exports = function bind(that) {\n var target = this;\n if (typeof target !== 'function' || toStr.apply(target) !== funcType) {\n throw new TypeError(ERROR_MESSAGE + target);\n }\n var args = slicy(arguments, 1);\n\n var bound;\n var binder = function () {\n if (this instanceof bound) {\n var result = target.apply(\n this,\n concatty(args, arguments)\n );\n if (Object(result) === result) {\n return result;\n }\n return this;\n }\n return target.apply(\n that,\n concatty(args, arguments)\n );\n\n };\n\n var boundLength = max(0, target.length - args.length);\n var boundArgs = [];\n for (var i = 0; i < boundLength; i++) {\n boundArgs[i] = '$' + i;\n }\n\n bound = Function('binder', 'return function (' + joiny(boundArgs, ',') + '){ return binder.apply(this,arguments); }')(binder);\n\n if (target.prototype) {\n var Empty = function Empty() {};\n Empty.prototype = target.prototype;\n bound.prototype = new Empty();\n Empty.prototype = null;\n }\n\n return bound;\n};\n","'use strict';\n\nvar implementation = require('./implementation');\n\nmodule.exports = Function.prototype.bind || implementation;\n","'use strict';\n\n/** @type {import('./functionCall')} */\nmodule.exports = Function.prototype.call;\n","'use strict';\n\n/** @type {import('./functionApply')} */\nmodule.exports = Function.prototype.apply;\n","'use strict';\n\n/** @type {import('./reflectApply')} */\nmodule.exports = typeof Reflect !== 'undefined' && Reflect && Reflect.apply;\n","'use strict';\n\nvar bind = require('function-bind');\n\nvar $apply = require('./functionApply');\nvar $call = require('./functionCall');\nvar $reflectApply = require('./reflectApply');\n\n/** @type {import('./actualApply')} */\nmodule.exports = $reflectApply || bind.call($call, $apply);\n","'use strict';\n\nvar bind = require('function-bind');\nvar $TypeError = require('es-errors/type');\n\nvar $call = require('./functionCall');\nvar $actualApply = require('./actualApply');\n\n/** @type {(args: [Function, thisArg?: unknown, ...args: unknown[]]) => Function} TODO FIXME, find a way to use import('.') */\nmodule.exports = function callBindBasic(args) {\n\tif (args.length < 1 || typeof args[0] !== 'function') {\n\t\tthrow new $TypeError('a function is required');\n\t}\n\treturn $actualApply(bind, $call, args);\n};\n","'use strict';\n\nvar callBind = require('call-bind-apply-helpers');\nvar gOPD = require('gopd');\n\nvar hasProtoAccessor;\ntry {\n\t// eslint-disable-next-line no-extra-parens, no-proto\n\thasProtoAccessor = /** @type {{ __proto__?: typeof Array.prototype }} */ ([]).__proto__ === Array.prototype;\n} catch (e) {\n\tif (!e || typeof e !== 'object' || !('code' in e) || e.code !== 'ERR_PROTO_ACCESS') {\n\t\tthrow e;\n\t}\n}\n\n// eslint-disable-next-line no-extra-parens\nvar desc = !!hasProtoAccessor && gOPD && gOPD(Object.prototype, /** @type {keyof typeof Object.prototype} */ ('__proto__'));\n\nvar $Object = Object;\nvar $getPrototypeOf = $Object.getPrototypeOf;\n\n/** @type {import('./get')} */\nmodule.exports = desc && typeof desc.get === 'function'\n\t? callBind([desc.get])\n\t: typeof $getPrototypeOf === 'function'\n\t\t? /** @type {import('./get')} */ function getDunder(value) {\n\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\treturn $getPrototypeOf(value == null ? value : $Object(value));\n\t\t}\n\t\t: false;\n","'use strict';\n\nvar reflectGetProto = require('./Reflect.getPrototypeOf');\nvar originalGetProto = require('./Object.getPrototypeOf');\n\nvar getDunderProto = require('dunder-proto/get');\n\n/** @type {import('.')} */\nmodule.exports = reflectGetProto\n\t? function getProto(O) {\n\t\t// @ts-expect-error TS can't narrow inside a closure, for some reason\n\t\treturn reflectGetProto(O);\n\t}\n\t: originalGetProto\n\t\t? function getProto(O) {\n\t\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\t\tthrow new TypeError('getProto: not an object');\n\t\t\t}\n\t\t\t// @ts-expect-error TS can't narrow inside a closure, for some reason\n\t\t\treturn originalGetProto(O);\n\t\t}\n\t\t: getDunderProto\n\t\t\t? function getProto(O) {\n\t\t\t\t// @ts-expect-error TS can't narrow inside a closure, for some reason\n\t\t\t\treturn getDunderProto(O);\n\t\t\t}\n\t\t\t: null;\n","'use strict';\n\nvar call = Function.prototype.call;\nvar $hasOwn = Object.prototype.hasOwnProperty;\nvar bind = require('function-bind');\n\n/** @type {import('.')} */\nmodule.exports = bind.call(call, $hasOwn);\n","'use strict';\n\nvar undefined;\n\nvar $Object = require('es-object-atoms');\n\nvar $Error = require('es-errors');\nvar $EvalError = require('es-errors/eval');\nvar $RangeError = require('es-errors/range');\nvar $ReferenceError = require('es-errors/ref');\nvar $SyntaxError = require('es-errors/syntax');\nvar $TypeError = require('es-errors/type');\nvar $URIError = require('es-errors/uri');\n\nvar abs = require('math-intrinsics/abs');\nvar floor = require('math-intrinsics/floor');\nvar max = require('math-intrinsics/max');\nvar min = require('math-intrinsics/min');\nvar pow = require('math-intrinsics/pow');\nvar round = require('math-intrinsics/round');\nvar sign = require('math-intrinsics/sign');\n\nvar $Function = Function;\n\n// eslint-disable-next-line consistent-return\nvar getEvalledConstructor = function (expressionSyntax) {\n\ttry {\n\t\treturn $Function('\"use strict\"; return (' + expressionSyntax + ').constructor;')();\n\t} catch (e) {}\n};\n\nvar $gOPD = require('gopd');\nvar $defineProperty = require('es-define-property');\n\nvar throwTypeError = function () {\n\tthrow new $TypeError();\n};\nvar ThrowTypeError = $gOPD\n\t? (function () {\n\t\ttry {\n\t\t\t// eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties\n\t\t\targuments.callee; // IE 8 does not throw here\n\t\t\treturn throwTypeError;\n\t\t} catch (calleeThrows) {\n\t\t\ttry {\n\t\t\t\t// IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '')\n\t\t\t\treturn $gOPD(arguments, 'callee').get;\n\t\t\t} catch (gOPDthrows) {\n\t\t\t\treturn throwTypeError;\n\t\t\t}\n\t\t}\n\t}())\n\t: throwTypeError;\n\nvar hasSymbols = require('has-symbols')();\n\nvar getProto = require('get-proto');\nvar $ObjectGPO = require('get-proto/Object.getPrototypeOf');\nvar $ReflectGPO = require('get-proto/Reflect.getPrototypeOf');\n\nvar $apply = require('call-bind-apply-helpers/functionApply');\nvar $call = require('call-bind-apply-helpers/functionCall');\n\nvar needsEval = {};\n\nvar TypedArray = typeof Uint8Array === 'undefined' || !getProto ? undefined : getProto(Uint8Array);\n\nvar INTRINSICS = {\n\t__proto__: null,\n\t'%AggregateError%': typeof AggregateError === 'undefined' ? undefined : AggregateError,\n\t'%Array%': Array,\n\t'%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer,\n\t'%ArrayIteratorPrototype%': hasSymbols && getProto ? getProto([][Symbol.iterator]()) : undefined,\n\t'%AsyncFromSyncIteratorPrototype%': undefined,\n\t'%AsyncFunction%': needsEval,\n\t'%AsyncGenerator%': needsEval,\n\t'%AsyncGeneratorFunction%': needsEval,\n\t'%AsyncIteratorPrototype%': needsEval,\n\t'%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics,\n\t'%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt,\n\t'%BigInt64Array%': typeof BigInt64Array === 'undefined' ? undefined : BigInt64Array,\n\t'%BigUint64Array%': typeof BigUint64Array === 'undefined' ? undefined : BigUint64Array,\n\t'%Boolean%': Boolean,\n\t'%DataView%': typeof DataView === 'undefined' ? undefined : DataView,\n\t'%Date%': Date,\n\t'%decodeURI%': decodeURI,\n\t'%decodeURIComponent%': decodeURIComponent,\n\t'%encodeURI%': encodeURI,\n\t'%encodeURIComponent%': encodeURIComponent,\n\t'%Error%': $Error,\n\t'%eval%': eval, // eslint-disable-line no-eval\n\t'%EvalError%': $EvalError,\n\t'%Float16Array%': typeof Float16Array === 'undefined' ? undefined : Float16Array,\n\t'%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array,\n\t'%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array,\n\t'%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry,\n\t'%Function%': $Function,\n\t'%GeneratorFunction%': needsEval,\n\t'%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array,\n\t'%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array,\n\t'%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array,\n\t'%isFinite%': isFinite,\n\t'%isNaN%': isNaN,\n\t'%IteratorPrototype%': hasSymbols && getProto ? getProto(getProto([][Symbol.iterator]())) : undefined,\n\t'%JSON%': typeof JSON === 'object' ? JSON : undefined,\n\t'%Map%': typeof Map === 'undefined' ? undefined : Map,\n\t'%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols || !getProto ? undefined : getProto(new Map()[Symbol.iterator]()),\n\t'%Math%': Math,\n\t'%Number%': Number,\n\t'%Object%': $Object,\n\t'%Object.getOwnPropertyDescriptor%': $gOPD,\n\t'%parseFloat%': parseFloat,\n\t'%parseInt%': parseInt,\n\t'%Promise%': typeof Promise === 'undefined' ? undefined : Promise,\n\t'%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy,\n\t'%RangeError%': $RangeError,\n\t'%ReferenceError%': $ReferenceError,\n\t'%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect,\n\t'%RegExp%': RegExp,\n\t'%Set%': typeof Set === 'undefined' ? undefined : Set,\n\t'%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols || !getProto ? undefined : getProto(new Set()[Symbol.iterator]()),\n\t'%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer,\n\t'%String%': String,\n\t'%StringIteratorPrototype%': hasSymbols && getProto ? getProto(''[Symbol.iterator]()) : undefined,\n\t'%Symbol%': hasSymbols ? Symbol : undefined,\n\t'%SyntaxError%': $SyntaxError,\n\t'%ThrowTypeError%': ThrowTypeError,\n\t'%TypedArray%': TypedArray,\n\t'%TypeError%': $TypeError,\n\t'%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array,\n\t'%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray,\n\t'%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array,\n\t'%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array,\n\t'%URIError%': $URIError,\n\t'%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap,\n\t'%WeakRef%': typeof WeakRef === 'undefined' ? undefined : WeakRef,\n\t'%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet,\n\n\t'%Function.prototype.call%': $call,\n\t'%Function.prototype.apply%': $apply,\n\t'%Object.defineProperty%': $defineProperty,\n\t'%Object.getPrototypeOf%': $ObjectGPO,\n\t'%Math.abs%': abs,\n\t'%Math.floor%': floor,\n\t'%Math.max%': max,\n\t'%Math.min%': min,\n\t'%Math.pow%': pow,\n\t'%Math.round%': round,\n\t'%Math.sign%': sign,\n\t'%Reflect.getPrototypeOf%': $ReflectGPO\n};\n\nif (getProto) {\n\ttry {\n\t\tnull.error; // eslint-disable-line no-unused-expressions\n\t} catch (e) {\n\t\t// https://github.com/tc39/proposal-shadowrealm/pull/384#issuecomment-1364264229\n\t\tvar errorProto = getProto(getProto(e));\n\t\tINTRINSICS['%Error.prototype%'] = errorProto;\n\t}\n}\n\nvar doEval = function doEval(name) {\n\tvar value;\n\tif (name === '%AsyncFunction%') {\n\t\tvalue = getEvalledConstructor('async function () {}');\n\t} else if (name === '%GeneratorFunction%') {\n\t\tvalue = getEvalledConstructor('function* () {}');\n\t} else if (name === '%AsyncGeneratorFunction%') {\n\t\tvalue = getEvalledConstructor('async function* () {}');\n\t} else if (name === '%AsyncGenerator%') {\n\t\tvar fn = doEval('%AsyncGeneratorFunction%');\n\t\tif (fn) {\n\t\t\tvalue = fn.prototype;\n\t\t}\n\t} else if (name === '%AsyncIteratorPrototype%') {\n\t\tvar gen = doEval('%AsyncGenerator%');\n\t\tif (gen && getProto) {\n\t\t\tvalue = getProto(gen.prototype);\n\t\t}\n\t}\n\n\tINTRINSICS[name] = value;\n\n\treturn value;\n};\n\nvar LEGACY_ALIASES = {\n\t__proto__: null,\n\t'%ArrayBufferPrototype%': ['ArrayBuffer', 'prototype'],\n\t'%ArrayPrototype%': ['Array', 'prototype'],\n\t'%ArrayProto_entries%': ['Array', 'prototype', 'entries'],\n\t'%ArrayProto_forEach%': ['Array', 'prototype', 'forEach'],\n\t'%ArrayProto_keys%': ['Array', 'prototype', 'keys'],\n\t'%ArrayProto_values%': ['Array', 'prototype', 'values'],\n\t'%AsyncFunctionPrototype%': ['AsyncFunction', 'prototype'],\n\t'%AsyncGenerator%': ['AsyncGeneratorFunction', 'prototype'],\n\t'%AsyncGeneratorPrototype%': ['AsyncGeneratorFunction', 'prototype', 'prototype'],\n\t'%BooleanPrototype%': ['Boolean', 'prototype'],\n\t'%DataViewPrototype%': ['DataView', 'prototype'],\n\t'%DatePrototype%': ['Date', 'prototype'],\n\t'%ErrorPrototype%': ['Error', 'prototype'],\n\t'%EvalErrorPrototype%': ['EvalError', 'prototype'],\n\t'%Float32ArrayPrototype%': ['Float32Array', 'prototype'],\n\t'%Float64ArrayPrototype%': ['Float64Array', 'prototype'],\n\t'%FunctionPrototype%': ['Function', 'prototype'],\n\t'%Generator%': ['GeneratorFunction', 'prototype'],\n\t'%GeneratorPrototype%': ['GeneratorFunction', 'prototype', 'prototype'],\n\t'%Int8ArrayPrototype%': ['Int8Array', 'prototype'],\n\t'%Int16ArrayPrototype%': ['Int16Array', 'prototype'],\n\t'%Int32ArrayPrototype%': ['Int32Array', 'prototype'],\n\t'%JSONParse%': ['JSON', 'parse'],\n\t'%JSONStringify%': ['JSON', 'stringify'],\n\t'%MapPrototype%': ['Map', 'prototype'],\n\t'%NumberPrototype%': ['Number', 'prototype'],\n\t'%ObjectPrototype%': ['Object', 'prototype'],\n\t'%ObjProto_toString%': ['Object', 'prototype', 'toString'],\n\t'%ObjProto_valueOf%': ['Object', 'prototype', 'valueOf'],\n\t'%PromisePrototype%': ['Promise', 'prototype'],\n\t'%PromiseProto_then%': ['Promise', 'prototype', 'then'],\n\t'%Promise_all%': ['Promise', 'all'],\n\t'%Promise_reject%': ['Promise', 'reject'],\n\t'%Promise_resolve%': ['Promise', 'resolve'],\n\t'%RangeErrorPrototype%': ['RangeError', 'prototype'],\n\t'%ReferenceErrorPrototype%': ['ReferenceError', 'prototype'],\n\t'%RegExpPrototype%': ['RegExp', 'prototype'],\n\t'%SetPrototype%': ['Set', 'prototype'],\n\t'%SharedArrayBufferPrototype%': ['SharedArrayBuffer', 'prototype'],\n\t'%StringPrototype%': ['String', 'prototype'],\n\t'%SymbolPrototype%': ['Symbol', 'prototype'],\n\t'%SyntaxErrorPrototype%': ['SyntaxError', 'prototype'],\n\t'%TypedArrayPrototype%': ['TypedArray', 'prototype'],\n\t'%TypeErrorPrototype%': ['TypeError', 'prototype'],\n\t'%Uint8ArrayPrototype%': ['Uint8Array', 'prototype'],\n\t'%Uint8ClampedArrayPrototype%': ['Uint8ClampedArray', 'prototype'],\n\t'%Uint16ArrayPrototype%': ['Uint16Array', 'prototype'],\n\t'%Uint32ArrayPrototype%': ['Uint32Array', 'prototype'],\n\t'%URIErrorPrototype%': ['URIError', 'prototype'],\n\t'%WeakMapPrototype%': ['WeakMap', 'prototype'],\n\t'%WeakSetPrototype%': ['WeakSet', 'prototype']\n};\n\nvar bind = require('function-bind');\nvar hasOwn = require('hasown');\nvar $concat = bind.call($call, Array.prototype.concat);\nvar $spliceApply = bind.call($apply, Array.prototype.splice);\nvar $replace = bind.call($call, String.prototype.replace);\nvar $strSlice = bind.call($call, String.prototype.slice);\nvar $exec = bind.call($call, RegExp.prototype.exec);\n\n/* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */\nvar rePropName = /[^%.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|%$))/g;\nvar reEscapeChar = /\\\\(\\\\)?/g; /** Used to match backslashes in property paths. */\nvar stringToPath = function stringToPath(string) {\n\tvar first = $strSlice(string, 0, 1);\n\tvar last = $strSlice(string, -1);\n\tif (first === '%' && last !== '%') {\n\t\tthrow new $SyntaxError('invalid intrinsic syntax, expected closing `%`');\n\t} else if (last === '%' && first !== '%') {\n\t\tthrow new $SyntaxError('invalid intrinsic syntax, expected opening `%`');\n\t}\n\tvar result = [];\n\t$replace(string, rePropName, function (match, number, quote, subString) {\n\t\tresult[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : number || match;\n\t});\n\treturn result;\n};\n/* end adaptation */\n\nvar getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) {\n\tvar intrinsicName = name;\n\tvar alias;\n\tif (hasOwn(LEGACY_ALIASES, intrinsicName)) {\n\t\talias = LEGACY_ALIASES[intrinsicName];\n\t\tintrinsicName = '%' + alias[0] + '%';\n\t}\n\n\tif (hasOwn(INTRINSICS, intrinsicName)) {\n\t\tvar value = INTRINSICS[intrinsicName];\n\t\tif (value === needsEval) {\n\t\t\tvalue = doEval(intrinsicName);\n\t\t}\n\t\tif (typeof value === 'undefined' && !allowMissing) {\n\t\t\tthrow new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!');\n\t\t}\n\n\t\treturn {\n\t\t\talias: alias,\n\t\t\tname: intrinsicName,\n\t\t\tvalue: value\n\t\t};\n\t}\n\n\tthrow new $SyntaxError('intrinsic ' + name + ' does not exist!');\n};\n\nmodule.exports = function GetIntrinsic(name, allowMissing) {\n\tif (typeof name !== 'string' || name.length === 0) {\n\t\tthrow new $TypeError('intrinsic name must be a non-empty string');\n\t}\n\tif (arguments.length > 1 && typeof allowMissing !== 'boolean') {\n\t\tthrow new $TypeError('\"allowMissing\" argument must be a boolean');\n\t}\n\n\tif ($exec(/^%?[^%]*%?$/, name) === null) {\n\t\tthrow new $SyntaxError('`%` may not be present anywhere but at the beginning and end of the intrinsic name');\n\t}\n\tvar parts = stringToPath(name);\n\tvar intrinsicBaseName = parts.length > 0 ? parts[0] : '';\n\n\tvar intrinsic = getBaseIntrinsic('%' + intrinsicBaseName + '%', allowMissing);\n\tvar intrinsicRealName = intrinsic.name;\n\tvar value = intrinsic.value;\n\tvar skipFurtherCaching = false;\n\n\tvar alias = intrinsic.alias;\n\tif (alias) {\n\t\tintrinsicBaseName = alias[0];\n\t\t$spliceApply(parts, $concat([0, 1], alias));\n\t}\n\n\tfor (var i = 1, isOwn = true; i < parts.length; i += 1) {\n\t\tvar part = parts[i];\n\t\tvar first = $strSlice(part, 0, 1);\n\t\tvar last = $strSlice(part, -1);\n\t\tif (\n\t\t\t(\n\t\t\t\t(first === '\"' || first === \"'\" || first === '`')\n\t\t\t\t|| (last === '\"' || last === \"'\" || last === '`')\n\t\t\t)\n\t\t\t&& first !== last\n\t\t) {\n\t\t\tthrow new $SyntaxError('property names with quotes must have matching quotes');\n\t\t}\n\t\tif (part === 'constructor' || !isOwn) {\n\t\t\tskipFurtherCaching = true;\n\t\t}\n\n\t\tintrinsicBaseName += '.' + part;\n\t\tintrinsicRealName = '%' + intrinsicBaseName + '%';\n\n\t\tif (hasOwn(INTRINSICS, intrinsicRealName)) {\n\t\t\tvalue = INTRINSICS[intrinsicRealName];\n\t\t} else if (value != null) {\n\t\t\tif (!(part in value)) {\n\t\t\t\tif (!allowMissing) {\n\t\t\t\t\tthrow new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.');\n\t\t\t\t}\n\t\t\t\treturn void undefined;\n\t\t\t}\n\t\t\tif ($gOPD && (i + 1) >= parts.length) {\n\t\t\t\tvar desc = $gOPD(value, part);\n\t\t\t\tisOwn = !!desc;\n\n\t\t\t\t// By convention, when a data property is converted to an accessor\n\t\t\t\t// property to emulate a data property that does not suffer from\n\t\t\t\t// the override mistake, that accessor's getter is marked with\n\t\t\t\t// an `originalValue` property. Here, when we detect this, we\n\t\t\t\t// uphold the illusion by pretending to see that original data\n\t\t\t\t// property, i.e., returning the value rather than the getter\n\t\t\t\t// itself.\n\t\t\t\tif (isOwn && 'get' in desc && !('originalValue' in desc.get)) {\n\t\t\t\t\tvalue = desc.get;\n\t\t\t\t} else {\n\t\t\t\t\tvalue = value[part];\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tisOwn = hasOwn(value, part);\n\t\t\t\tvalue = value[part];\n\t\t\t}\n\n\t\t\tif (isOwn && !skipFurtherCaching) {\n\t\t\t\tINTRINSICS[intrinsicRealName] = value;\n\t\t\t}\n\t\t}\n\t}\n\treturn value;\n};\n","'use strict';\n\nvar hasSymbols = require('has-symbols/shams');\n\n/** @type {import('.')} */\nmodule.exports = function hasToStringTagShams() {\n\treturn hasSymbols() && !!Symbol.toStringTag;\n};\n","'use strict';\n\nvar GetIntrinsic = require('get-intrinsic');\n\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\n\nvar hasToStringTag = require('has-tostringtag/shams')();\nvar hasOwn = require('hasown');\nvar $TypeError = require('es-errors/type');\n\nvar toStringTag = hasToStringTag ? Symbol.toStringTag : null;\n\n/** @type {import('.')} */\nmodule.exports = function setToStringTag(object, value) {\n\tvar overrideIfSet = arguments.length > 2 && !!arguments[2] && arguments[2].force;\n\tvar nonConfigurable = arguments.length > 2 && !!arguments[2] && arguments[2].nonConfigurable;\n\tif (\n\t\t(typeof overrideIfSet !== 'undefined' && typeof overrideIfSet !== 'boolean')\n\t\t|| (typeof nonConfigurable !== 'undefined' && typeof nonConfigurable !== 'boolean')\n\t) {\n\t\tthrow new $TypeError('if provided, the `overrideIfSet` and `nonConfigurable` options must be booleans');\n\t}\n\tif (toStringTag && (overrideIfSet || !hasOwn(object, toStringTag))) {\n\t\tif ($defineProperty) {\n\t\t\t$defineProperty(object, toStringTag, {\n\t\t\t\tconfigurable: !nonConfigurable,\n\t\t\t\tenumerable: false,\n\t\t\t\tvalue: value,\n\t\t\t\twritable: false\n\t\t\t});\n\t\t} else {\n\t\t\tobject[toStringTag] = value; // eslint-disable-line no-param-reassign\n\t\t}\n\t}\n};\n","// populates missing values\nmodule.exports = function(dst, src) {\n\n Object.keys(src).forEach(function(prop)\n {\n dst[prop] = dst[prop] || src[prop];\n });\n\n return dst;\n};\n","var CombinedStream = require('combined-stream');\nvar util = require('util');\nvar path = require('path');\nvar http = require('http');\nvar https = require('https');\nvar parseUrl = require('url').parse;\nvar fs = require('fs');\nvar Stream = require('stream').Stream;\nvar mime = require('mime-types');\nvar asynckit = require('asynckit');\nvar setToStringTag = require('es-set-tostringtag');\nvar populate = require('./populate.js');\n\n// Public API\nmodule.exports = FormData;\n\n// make it a Stream\nutil.inherits(FormData, CombinedStream);\n\n/**\n * Create readable \"multipart/form-data\" streams.\n * Can be used to submit forms\n * and file uploads to other web applications.\n *\n * @constructor\n * @param {Object} options - Properties to be added/overriden for FormData and CombinedStream\n */\nfunction FormData(options) {\n if (!(this instanceof FormData)) {\n return new FormData(options);\n }\n\n this._overheadLength = 0;\n this._valueLength = 0;\n this._valuesToMeasure = [];\n\n CombinedStream.call(this);\n\n options = options || {};\n for (var option in options) {\n this[option] = options[option];\n }\n}\n\nFormData.LINE_BREAK = '\\r\\n';\nFormData.DEFAULT_CONTENT_TYPE = 'application/octet-stream';\n\nFormData.prototype.append = function(field, value, options) {\n\n options = options || {};\n\n // allow filename as single option\n if (typeof options == 'string') {\n options = {filename: options};\n }\n\n var append = CombinedStream.prototype.append.bind(this);\n\n // all that streamy business can't handle numbers\n if (typeof value == 'number') {\n value = '' + value;\n }\n\n // https://github.com/felixge/node-form-data/issues/38\n if (Array.isArray(value)) {\n // Please convert your array into string\n // the way web server expects it\n this._error(new Error('Arrays are not supported.'));\n return;\n }\n\n var header = this._multiPartHeader(field, value, options);\n var footer = this._multiPartFooter();\n\n append(header);\n append(value);\n append(footer);\n\n // pass along options.knownLength\n this._trackLength(header, value, options);\n};\n\nFormData.prototype._trackLength = function(header, value, options) {\n var valueLength = 0;\n\n // used w/ getLengthSync(), when length is known.\n // e.g. for streaming directly from a remote server,\n // w/ a known file a size, and not wanting to wait for\n // incoming file to finish to get its size.\n if (options.knownLength != null) {\n valueLength += +options.knownLength;\n } else if (Buffer.isBuffer(value)) {\n valueLength = value.length;\n } else if (typeof value === 'string') {\n valueLength = Buffer.byteLength(value);\n }\n\n this._valueLength += valueLength;\n\n // @check why add CRLF? does this account for custom/multiple CRLFs?\n this._overheadLength +=\n Buffer.byteLength(header) +\n FormData.LINE_BREAK.length;\n\n // empty or either doesn't have path or not an http response or not a stream\n if (!value || ( !value.path && !(value.readable && Object.prototype.hasOwnProperty.call(value, 'httpVersion')) && !(value instanceof Stream))) {\n return;\n }\n\n // no need to bother with the length\n if (!options.knownLength) {\n this._valuesToMeasure.push(value);\n }\n};\n\nFormData.prototype._lengthRetriever = function(value, callback) {\n if (Object.prototype.hasOwnProperty.call(value, 'fd')) {\n\n // take read range into a account\n // `end` = Infinity –> read file till the end\n //\n // TODO: Looks like there is bug in Node fs.createReadStream\n // it doesn't respect `end` options without `start` options\n // Fix it when node fixes it.\n // https://github.com/joyent/node/issues/7819\n if (value.end != undefined && value.end != Infinity && value.start != undefined) {\n\n // when end specified\n // no need to calculate range\n // inclusive, starts with 0\n callback(null, value.end + 1 - (value.start ? value.start : 0));\n\n // not that fast snoopy\n } else {\n // still need to fetch file size from fs\n fs.stat(value.path, function(err, stat) {\n\n var fileSize;\n\n if (err) {\n callback(err);\n return;\n }\n\n // update final size based on the range options\n fileSize = stat.size - (value.start ? value.start : 0);\n callback(null, fileSize);\n });\n }\n\n // or http response\n } else if (Object.prototype.hasOwnProperty.call(value, 'httpVersion')) {\n callback(null, +value.headers['content-length']);\n\n // or request stream http://github.com/mikeal/request\n } else if (Object.prototype.hasOwnProperty.call(value, 'httpModule')) {\n // wait till response come back\n value.on('response', function(response) {\n value.pause();\n callback(null, +response.headers['content-length']);\n });\n value.resume();\n\n // something else\n } else {\n callback('Unknown stream');\n }\n};\n\nFormData.prototype._multiPartHeader = function(field, value, options) {\n // custom header specified (as string)?\n // it becomes responsible for boundary\n // (e.g. to handle extra CRLFs on .NET servers)\n if (typeof options.header == 'string') {\n return options.header;\n }\n\n var contentDisposition = this._getContentDisposition(value, options);\n var contentType = this._getContentType(value, options);\n\n var contents = '';\n var headers = {\n // add custom disposition as third element or keep it two elements if not\n 'Content-Disposition': ['form-data', 'name=\"' + field + '\"'].concat(contentDisposition || []),\n // if no content type. allow it to be empty array\n 'Content-Type': [].concat(contentType || [])\n };\n\n // allow custom headers.\n if (typeof options.header == 'object') {\n populate(headers, options.header);\n }\n\n var header;\n for (var prop in headers) {\n if (Object.prototype.hasOwnProperty.call(headers, prop)) {\n header = headers[prop];\n\n // skip nullish headers.\n if (header == null) {\n continue;\n }\n\n // convert all headers to arrays.\n if (!Array.isArray(header)) {\n header = [header];\n }\n\n // add non-empty headers.\n if (header.length) {\n contents += prop + ': ' + header.join('; ') + FormData.LINE_BREAK;\n }\n }\n }\n\n return '--' + this.getBoundary() + FormData.LINE_BREAK + contents + FormData.LINE_BREAK;\n};\n\nFormData.prototype._getContentDisposition = function(value, options) {\n\n var filename\n , contentDisposition\n ;\n\n if (typeof options.filepath === 'string') {\n // custom filepath for relative paths\n filename = path.normalize(options.filepath).replace(/\\\\/g, '/');\n } else if (options.filename || value.name || value.path) {\n // custom filename take precedence\n // formidable and the browser add a name property\n // fs- and request- streams have path property\n filename = path.basename(options.filename || value.name || value.path);\n } else if (value.readable && Object.prototype.hasOwnProperty.call(value, 'httpVersion')) {\n // or try http response\n filename = path.basename(value.client._httpMessage.path || '');\n }\n\n if (filename) {\n contentDisposition = 'filename=\"' + filename + '\"';\n }\n\n return contentDisposition;\n};\n\nFormData.prototype._getContentType = function(value, options) {\n\n // use custom content-type above all\n var contentType = options.contentType;\n\n // or try `name` from formidable, browser\n if (!contentType && value.name) {\n contentType = mime.lookup(value.name);\n }\n\n // or try `path` from fs-, request- streams\n if (!contentType && value.path) {\n contentType = mime.lookup(value.path);\n }\n\n // or if it's http-reponse\n if (!contentType && value.readable && Object.prototype.hasOwnProperty.call(value, 'httpVersion')) {\n contentType = value.headers['content-type'];\n }\n\n // or guess it from the filepath or filename\n if (!contentType && (options.filepath || options.filename)) {\n contentType = mime.lookup(options.filepath || options.filename);\n }\n\n // fallback to the default content type if `value` is not simple value\n if (!contentType && typeof value == 'object') {\n contentType = FormData.DEFAULT_CONTENT_TYPE;\n }\n\n return contentType;\n};\n\nFormData.prototype._multiPartFooter = function() {\n return function(next) {\n var footer = FormData.LINE_BREAK;\n\n var lastPart = (this._streams.length === 0);\n if (lastPart) {\n footer += this._lastBoundary();\n }\n\n next(footer);\n }.bind(this);\n};\n\nFormData.prototype._lastBoundary = function() {\n return '--' + this.getBoundary() + '--' + FormData.LINE_BREAK;\n};\n\nFormData.prototype.getHeaders = function(userHeaders) {\n var header;\n var formHeaders = {\n 'content-type': 'multipart/form-data; boundary=' + this.getBoundary()\n };\n\n for (header in userHeaders) {\n if (Object.prototype.hasOwnProperty.call(userHeaders, header)) {\n formHeaders[header.toLowerCase()] = userHeaders[header];\n }\n }\n\n return formHeaders;\n};\n\nFormData.prototype.setBoundary = function(boundary) {\n this._boundary = boundary;\n};\n\nFormData.prototype.getBoundary = function() {\n if (!this._boundary) {\n this._generateBoundary();\n }\n\n return this._boundary;\n};\n\nFormData.prototype.getBuffer = function() {\n var dataBuffer = new Buffer.alloc(0);\n var boundary = this.getBoundary();\n\n // Create the form content. Add Line breaks to the end of data.\n for (var i = 0, len = this._streams.length; i < len; i++) {\n if (typeof this._streams[i] !== 'function') {\n\n // Add content to the buffer.\n if(Buffer.isBuffer(this._streams[i])) {\n dataBuffer = Buffer.concat( [dataBuffer, this._streams[i]]);\n }else {\n dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(this._streams[i])]);\n }\n\n // Add break after content.\n if (typeof this._streams[i] !== 'string' || this._streams[i].substring( 2, boundary.length + 2 ) !== boundary) {\n dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(FormData.LINE_BREAK)] );\n }\n }\n }\n\n // Add the footer and return the Buffer object.\n return Buffer.concat( [dataBuffer, Buffer.from(this._lastBoundary())] );\n};\n\nFormData.prototype._generateBoundary = function() {\n // This generates a 50 character boundary similar to those used by Firefox.\n // They are optimized for boyer-moore parsing.\n var boundary = '--------------------------';\n for (var i = 0; i < 24; i++) {\n boundary += Math.floor(Math.random() * 10).toString(16);\n }\n\n this._boundary = boundary;\n};\n\n// Note: getLengthSync DOESN'T calculate streams length\n// As workaround one can calculate file size manually\n// and add it as knownLength option\nFormData.prototype.getLengthSync = function() {\n var knownLength = this._overheadLength + this._valueLength;\n\n // Don't get confused, there are 3 \"internal\" streams for each keyval pair\n // so it basically checks if there is any value added to the form\n if (this._streams.length) {\n knownLength += this._lastBoundary().length;\n }\n\n // https://github.com/form-data/form-data/issues/40\n if (!this.hasKnownLength()) {\n // Some async length retrievers are present\n // therefore synchronous length calculation is false.\n // Please use getLength(callback) to get proper length\n this._error(new Error('Cannot calculate proper length in synchronous way.'));\n }\n\n return knownLength;\n};\n\n// Public API to check if length of added values is known\n// https://github.com/form-data/form-data/issues/196\n// https://github.com/form-data/form-data/issues/262\nFormData.prototype.hasKnownLength = function() {\n var hasKnownLength = true;\n\n if (this._valuesToMeasure.length) {\n hasKnownLength = false;\n }\n\n return hasKnownLength;\n};\n\nFormData.prototype.getLength = function(cb) {\n var knownLength = this._overheadLength + this._valueLength;\n\n if (this._streams.length) {\n knownLength += this._lastBoundary().length;\n }\n\n if (!this._valuesToMeasure.length) {\n process.nextTick(cb.bind(this, null, knownLength));\n return;\n }\n\n asynckit.parallel(this._valuesToMeasure, this._lengthRetriever, function(err, values) {\n if (err) {\n cb(err);\n return;\n }\n\n values.forEach(function(length) {\n knownLength += length;\n });\n\n cb(null, knownLength);\n });\n};\n\nFormData.prototype.submit = function(params, cb) {\n var request\n , options\n , defaults = {method: 'post'}\n ;\n\n // parse provided url if it's string\n // or treat it as options object\n if (typeof params == 'string') {\n\n params = parseUrl(params);\n options = populate({\n port: params.port,\n path: params.pathname,\n host: params.hostname,\n protocol: params.protocol\n }, defaults);\n\n // use custom params\n } else {\n\n options = populate(params, defaults);\n // if no port provided use default one\n if (!options.port) {\n options.port = options.protocol == 'https:' ? 443 : 80;\n }\n }\n\n // put that good code in getHeaders to some use\n options.headers = this.getHeaders(params.headers);\n\n // https if specified, fallback to http in any other case\n if (options.protocol == 'https:') {\n request = https.request(options);\n } else {\n request = http.request(options);\n }\n\n // get content length and fire away\n this.getLength(function(err, length) {\n if (err && err !== 'Unknown stream') {\n this._error(err);\n return;\n }\n\n // add content length\n if (length) {\n request.setHeader('Content-Length', length);\n }\n\n this.pipe(request);\n if (cb) {\n var onResponse;\n\n var callback = function (error, responce) {\n request.removeListener('error', callback);\n request.removeListener('response', onResponse);\n\n return cb.call(this, error, responce);\n };\n\n onResponse = callback.bind(this, null);\n\n request.on('error', callback);\n request.on('response', onResponse);\n }\n }.bind(this));\n\n return request;\n};\n\nFormData.prototype._error = function(err) {\n if (!this.error) {\n this.error = err;\n this.pause();\n this.emit('error', err);\n }\n};\n\nFormData.prototype.toString = function () {\n return '[object FormData]';\n};\nsetToStringTag(FormData, 'FormData');\n","import FormData from 'form-data';\n\nexport default FormData;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosError from '../core/AxiosError.js';\n// temporary hotfix to avoid circular references until AxiosURLSearchParams is refactored\nimport PlatformFormData from '../platform/node/classes/FormData.js';\n\n/**\n * Determines if the given thing is a array or js object.\n *\n * @param {string} thing - The object or array to be visited.\n *\n * @returns {boolean}\n */\nfunction isVisitable(thing) {\n return utils.isPlainObject(thing) || utils.isArray(thing);\n}\n\n/**\n * It removes the brackets from the end of a string\n *\n * @param {string} key - The key of the parameter.\n *\n * @returns {string} the key without the brackets.\n */\nfunction removeBrackets(key) {\n return utils.endsWith(key, '[]') ? key.slice(0, -2) : key;\n}\n\n/**\n * It takes a path, a key, and a boolean, and returns a string\n *\n * @param {string} path - The path to the current key.\n * @param {string} key - The key of the current object being iterated over.\n * @param {string} dots - If true, the key will be rendered with dots instead of brackets.\n *\n * @returns {string} The path to the current key.\n */\nfunction renderKey(path, key, dots) {\n if (!path) return key;\n return path.concat(key).map(function each(token, i) {\n // eslint-disable-next-line no-param-reassign\n token = removeBrackets(token);\n return !dots && i ? '[' + token + ']' : token;\n }).join(dots ? '.' : '');\n}\n\n/**\n * If the array is an array and none of its elements are visitable, then it's a flat array.\n *\n * @param {Array<any>} arr - The array to check\n *\n * @returns {boolean}\n */\nfunction isFlatArray(arr) {\n return utils.isArray(arr) && !arr.some(isVisitable);\n}\n\nconst predicates = utils.toFlatObject(utils, {}, null, function filter(prop) {\n return /^is[A-Z]/.test(prop);\n});\n\n/**\n * Convert a data object to FormData\n *\n * @param {Object} obj\n * @param {?Object} [formData]\n * @param {?Object} [options]\n * @param {Function} [options.visitor]\n * @param {Boolean} [options.metaTokens = true]\n * @param {Boolean} [options.dots = false]\n * @param {?Boolean} [options.indexes = false]\n *\n * @returns {Object}\n **/\n\n/**\n * It converts an object into a FormData object\n *\n * @param {Object<any, any>} obj - The object to convert to form data.\n * @param {string} formData - The FormData object to append to.\n * @param {Object<string, any>} options\n *\n * @returns\n */\nfunction toFormData(obj, formData, options) {\n if (!utils.isObject(obj)) {\n throw new TypeError('target must be an object');\n }\n\n // eslint-disable-next-line no-param-reassign\n formData = formData || new (PlatformFormData || FormData)();\n\n // eslint-disable-next-line no-param-reassign\n options = utils.toFlatObject(options, {\n metaTokens: true,\n dots: false,\n indexes: false\n }, false, function defined(option, source) {\n // eslint-disable-next-line no-eq-null,eqeqeq\n return !utils.isUndefined(source[option]);\n });\n\n const metaTokens = options.metaTokens;\n // eslint-disable-next-line no-use-before-define\n const visitor = options.visitor || defaultVisitor;\n const dots = options.dots;\n const indexes = options.indexes;\n const _Blob = options.Blob || typeof Blob !== 'undefined' && Blob;\n const useBlob = _Blob && utils.isSpecCompliantForm(formData);\n\n if (!utils.isFunction(visitor)) {\n throw new TypeError('visitor must be a function');\n }\n\n function convertValue(value) {\n if (value === null) return '';\n\n if (utils.isDate(value)) {\n return value.toISOString();\n }\n\n if (utils.isBoolean(value)) {\n return value.toString();\n }\n\n if (!useBlob && utils.isBlob(value)) {\n throw new AxiosError('Blob is not supported. Use a Buffer instead.');\n }\n\n if (utils.isArrayBuffer(value) || utils.isTypedArray(value)) {\n return useBlob && typeof Blob === 'function' ? new Blob([value]) : Buffer.from(value);\n }\n\n return value;\n }\n\n /**\n * Default visitor.\n *\n * @param {*} value\n * @param {String|Number} key\n * @param {Array<String|Number>} path\n * @this {FormData}\n *\n * @returns {boolean} return true to visit the each prop of the value recursively\n */\n function defaultVisitor(value, key, path) {\n let arr = value;\n\n if (value && !path && typeof value === 'object') {\n if (utils.endsWith(key, '{}')) {\n // eslint-disable-next-line no-param-reassign\n key = metaTokens ? key : key.slice(0, -2);\n // eslint-disable-next-line no-param-reassign\n value = JSON.stringify(value);\n } else if (\n (utils.isArray(value) && isFlatArray(value)) ||\n ((utils.isFileList(value) || utils.endsWith(key, '[]')) && (arr = utils.toArray(value))\n )) {\n // eslint-disable-next-line no-param-reassign\n key = removeBrackets(key);\n\n arr.forEach(function each(el, index) {\n !(utils.isUndefined(el) || el === null) && formData.append(\n // eslint-disable-next-line no-nested-ternary\n indexes === true ? renderKey([key], index, dots) : (indexes === null ? key : key + '[]'),\n convertValue(el)\n );\n });\n return false;\n }\n }\n\n if (isVisitable(value)) {\n return true;\n }\n\n formData.append(renderKey(path, key, dots), convertValue(value));\n\n return false;\n }\n\n const stack = [];\n\n const exposedHelpers = Object.assign(predicates, {\n defaultVisitor,\n convertValue,\n isVisitable\n });\n\n function build(value, path) {\n if (utils.isUndefined(value)) return;\n\n if (stack.indexOf(value) !== -1) {\n throw Error('Circular reference detected in ' + path.join('.'));\n }\n\n stack.push(value);\n\n utils.forEach(value, function each(el, key) {\n const result = !(utils.isUndefined(el) || el === null) && visitor.call(\n formData, el, utils.isString(key) ? key.trim() : key, path, exposedHelpers\n );\n\n if (result === true) {\n build(el, path ? path.concat(key) : [key]);\n }\n });\n\n stack.pop();\n }\n\n if (!utils.isObject(obj)) {\n throw new TypeError('data must be an object');\n }\n\n build(obj);\n\n return formData;\n}\n\nexport default toFormData;\n","'use strict';\n\nimport toFormData from './toFormData.js';\n\n/**\n * It encodes a string by replacing all characters that are not in the unreserved set with\n * their percent-encoded equivalents\n *\n * @param {string} str - The string to encode.\n *\n * @returns {string} The encoded string.\n */\nfunction encode(str) {\n const charMap = {\n '!': '%21',\n \"'\": '%27',\n '(': '%28',\n ')': '%29',\n '~': '%7E',\n '%20': '+',\n '%00': '\\x00'\n };\n return encodeURIComponent(str).replace(/[!'()~]|%20|%00/g, function replacer(match) {\n return charMap[match];\n });\n}\n\n/**\n * It takes a params object and converts it to a FormData object\n *\n * @param {Object<string, any>} params - The parameters to be converted to a FormData object.\n * @param {Object<string, any>} options - The options object passed to the Axios constructor.\n *\n * @returns {void}\n */\nfunction AxiosURLSearchParams(params, options) {\n this._pairs = [];\n\n params && toFormData(params, this, options);\n}\n\nconst prototype = AxiosURLSearchParams.prototype;\n\nprototype.append = function append(name, value) {\n this._pairs.push([name, value]);\n};\n\nprototype.toString = function toString(encoder) {\n const _encode = encoder ? function(value) {\n return encoder.call(this, value, encode);\n } : encode;\n\n return this._pairs.map(function each(pair) {\n return _encode(pair[0]) + '=' + _encode(pair[1]);\n }, '').join('&');\n};\n\nexport default AxiosURLSearchParams;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosURLSearchParams from '../helpers/AxiosURLSearchParams.js';\n\n/**\n * It replaces all instances of the characters `:`, `$`, `,`, `+`, `[`, and `]` with their\n * URI encoded counterparts\n *\n * @param {string} val The value to be encoded.\n *\n * @returns {string} The encoded value.\n */\nfunction encode(val) {\n return encodeURIComponent(val).\n replace(/%3A/gi, ':').\n replace(/%24/g, '$').\n replace(/%2C/gi, ',').\n replace(/%20/g, '+').\n replace(/%5B/gi, '[').\n replace(/%5D/gi, ']');\n}\n\n/**\n * Build a URL by appending params to the end\n *\n * @param {string} url The base of the url (e.g., http://www.google.com)\n * @param {object} [params] The params to be appended\n * @param {?(object|Function)} options\n *\n * @returns {string} The formatted url\n */\nexport default function buildURL(url, params, options) {\n /*eslint no-param-reassign:0*/\n if (!params) {\n return url;\n }\n \n const _encode = options && options.encode || encode;\n\n if (utils.isFunction(options)) {\n options = {\n serialize: options\n };\n } \n\n const serializeFn = options && options.serialize;\n\n let serializedParams;\n\n if (serializeFn) {\n serializedParams = serializeFn(params, options);\n } else {\n serializedParams = utils.isURLSearchParams(params) ?\n params.toString() :\n new AxiosURLSearchParams(params, options).toString(_encode);\n }\n\n if (serializedParams) {\n const hashmarkIndex = url.indexOf(\"#\");\n\n if (hashmarkIndex !== -1) {\n url = url.slice(0, hashmarkIndex);\n }\n url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;\n }\n\n return url;\n}\n","'use strict';\n\nimport utils from './../utils.js';\n\nclass InterceptorManager {\n constructor() {\n this.handlers = [];\n }\n\n /**\n * Add a new interceptor to the stack\n *\n * @param {Function} fulfilled The function to handle `then` for a `Promise`\n * @param {Function} rejected The function to handle `reject` for a `Promise`\n *\n * @return {Number} An ID used to remove interceptor later\n */\n use(fulfilled, rejected, options) {\n this.handlers.push({\n fulfilled,\n rejected,\n synchronous: options ? options.synchronous : false,\n runWhen: options ? options.runWhen : null\n });\n return this.handlers.length - 1;\n }\n\n /**\n * Remove an interceptor from the stack\n *\n * @param {Number} id The ID that was returned by `use`\n *\n * @returns {Boolean} `true` if the interceptor was removed, `false` otherwise\n */\n eject(id) {\n if (this.handlers[id]) {\n this.handlers[id] = null;\n }\n }\n\n /**\n * Clear all interceptors from the stack\n *\n * @returns {void}\n */\n clear() {\n if (this.handlers) {\n this.handlers = [];\n }\n }\n\n /**\n * Iterate over all the registered interceptors\n *\n * This method is particularly useful for skipping over any\n * interceptors that may have become `null` calling `eject`.\n *\n * @param {Function} fn The function to call for each interceptor\n *\n * @returns {void}\n */\n forEach(fn) {\n utils.forEach(this.handlers, function forEachHandler(h) {\n if (h !== null) {\n fn(h);\n }\n });\n }\n}\n\nexport default InterceptorManager;\n","'use strict';\n\nexport default {\n silentJSONParsing: true,\n forcedJSONParsing: true,\n clarifyTimeoutError: false\n};\n","'use strict';\n\nimport url from 'url';\nexport default url.URLSearchParams;\n","import crypto from 'crypto';\nimport URLSearchParams from './classes/URLSearchParams.js'\nimport FormData from './classes/FormData.js'\n\nconst ALPHA = 'abcdefghijklmnopqrstuvwxyz'\n\nconst DIGIT = '0123456789';\n\nconst ALPHABET = {\n DIGIT,\n ALPHA,\n ALPHA_DIGIT: ALPHA + ALPHA.toUpperCase() + DIGIT\n}\n\nconst generateString = (size = 16, alphabet = ALPHABET.ALPHA_DIGIT) => {\n let str = '';\n const {length} = alphabet;\n const randomValues = new Uint32Array(size);\n crypto.randomFillSync(randomValues);\n for (let i = 0; i < size; i++) {\n str += alphabet[randomValues[i] % length];\n }\n\n return str;\n}\n\n\nexport default {\n isNode: true,\n classes: {\n URLSearchParams,\n FormData,\n Blob: typeof Blob !== 'undefined' && Blob || null\n },\n ALPHABET,\n generateString,\n protocols: [ 'http', 'https', 'file', 'data' ]\n};\n","const hasBrowserEnv = typeof window !== 'undefined' && typeof document !== 'undefined';\n\nconst _navigator = typeof navigator === 'object' && navigator || undefined;\n\n/**\n * Determine if we're running in a standard browser environment\n *\n * This allows axios to run in a web worker, and react-native.\n * Both environments support XMLHttpRequest, but not fully standard globals.\n *\n * web workers:\n * typeof window -> undefined\n * typeof document -> undefined\n *\n * react-native:\n * navigator.product -> 'ReactNative'\n * nativescript\n * navigator.product -> 'NativeScript' or 'NS'\n *\n * @returns {boolean}\n */\nconst hasStandardBrowserEnv = hasBrowserEnv &&\n (!_navigator || ['ReactNative', 'NativeScript', 'NS'].indexOf(_navigator.product) < 0);\n\n/**\n * Determine if we're running in a standard browser webWorker environment\n *\n * Although the `isStandardBrowserEnv` method indicates that\n * `allows axios to run in a web worker`, the WebWorker will still be\n * filtered out due to its judgment standard\n * `typeof window !== 'undefined' && typeof document !== 'undefined'`.\n * This leads to a problem when axios post `FormData` in webWorker\n */\nconst hasStandardBrowserWebWorkerEnv = (() => {\n return (\n typeof WorkerGlobalScope !== 'undefined' &&\n // eslint-disable-next-line no-undef\n self instanceof WorkerGlobalScope &&\n typeof self.importScripts === 'function'\n );\n})();\n\nconst origin = hasBrowserEnv && window.location.href || 'http://localhost';\n\nexport {\n hasBrowserEnv,\n hasStandardBrowserWebWorkerEnv,\n hasStandardBrowserEnv,\n _navigator as navigator,\n origin\n}\n","import platform from './node/index.js';\nimport * as utils from './common/utils.js';\n\nexport default {\n ...utils,\n ...platform\n}\n","'use strict';\n\nimport utils from '../utils.js';\nimport toFormData from './toFormData.js';\nimport platform from '../platform/index.js';\n\nexport default function toURLEncodedForm(data, options) {\n return toFormData(data, new platform.classes.URLSearchParams(), Object.assign({\n visitor: function(value, key, path, helpers) {\n if (platform.isNode && utils.isBuffer(value)) {\n this.append(key, value.toString('base64'));\n return false;\n }\n\n return helpers.defaultVisitor.apply(this, arguments);\n }\n }, options));\n}\n","'use strict';\n\nimport utils from '../utils.js';\n\n/**\n * It takes a string like `foo[x][y][z]` and returns an array like `['foo', 'x', 'y', 'z']\n *\n * @param {string} name - The name of the property to get.\n *\n * @returns An array of strings.\n */\nfunction parsePropPath(name) {\n // foo[x][y][z]\n // foo.x.y.z\n // foo-x-y-z\n // foo x y z\n return utils.matchAll(/\\w+|\\[(\\w*)]/g, name).map(match => {\n return match[0] === '[]' ? '' : match[1] || match[0];\n });\n}\n\n/**\n * Convert an array to an object.\n *\n * @param {Array<any>} arr - The array to convert to an object.\n *\n * @returns An object with the same keys and values as the array.\n */\nfunction arrayToObject(arr) {\n const obj = {};\n const keys = Object.keys(arr);\n let i;\n const len = keys.length;\n let key;\n for (i = 0; i < len; i++) {\n key = keys[i];\n obj[key] = arr[key];\n }\n return obj;\n}\n\n/**\n * It takes a FormData object and returns a JavaScript object\n *\n * @param {string} formData The FormData object to convert to JSON.\n *\n * @returns {Object<string, any> | null} The converted object.\n */\nfunction formDataToJSON(formData) {\n function buildPath(path, value, target, index) {\n let name = path[index++];\n\n if (name === '__proto__') return true;\n\n const isNumericKey = Number.isFinite(+name);\n const isLast = index >= path.length;\n name = !name && utils.isArray(target) ? target.length : name;\n\n if (isLast) {\n if (utils.hasOwnProp(target, name)) {\n target[name] = [target[name], value];\n } else {\n target[name] = value;\n }\n\n return !isNumericKey;\n }\n\n if (!target[name] || !utils.isObject(target[name])) {\n target[name] = [];\n }\n\n const result = buildPath(path, value, target[name], index);\n\n if (result && utils.isArray(target[name])) {\n target[name] = arrayToObject(target[name]);\n }\n\n return !isNumericKey;\n }\n\n if (utils.isFormData(formData) && utils.isFunction(formData.entries)) {\n const obj = {};\n\n utils.forEachEntry(formData, (name, value) => {\n buildPath(parsePropPath(name), value, obj, 0);\n });\n\n return obj;\n }\n\n return null;\n}\n\nexport default formDataToJSON;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosError from '../core/AxiosError.js';\nimport transitionalDefaults from './transitional.js';\nimport toFormData from '../helpers/toFormData.js';\nimport toURLEncodedForm from '../helpers/toURLEncodedForm.js';\nimport platform from '../platform/index.js';\nimport formDataToJSON from '../helpers/formDataToJSON.js';\n\n/**\n * It takes a string, tries to parse it, and if it fails, it returns the stringified version\n * of the input\n *\n * @param {any} rawValue - The value to be stringified.\n * @param {Function} parser - A function that parses a string into a JavaScript object.\n * @param {Function} encoder - A function that takes a value and returns a string.\n *\n * @returns {string} A stringified version of the rawValue.\n */\nfunction stringifySafely(rawValue, parser, encoder) {\n if (utils.isString(rawValue)) {\n try {\n (parser || JSON.parse)(rawValue);\n return utils.trim(rawValue);\n } catch (e) {\n if (e.name !== 'SyntaxError') {\n throw e;\n }\n }\n }\n\n return (encoder || JSON.stringify)(rawValue);\n}\n\nconst defaults = {\n\n transitional: transitionalDefaults,\n\n adapter: ['xhr', 'http', 'fetch'],\n\n transformRequest: [function transformRequest(data, headers) {\n const contentType = headers.getContentType() || '';\n const hasJSONContentType = contentType.indexOf('application/json') > -1;\n const isObjectPayload = utils.isObject(data);\n\n if (isObjectPayload && utils.isHTMLForm(data)) {\n data = new FormData(data);\n }\n\n const isFormData = utils.isFormData(data);\n\n if (isFormData) {\n return hasJSONContentType ? JSON.stringify(formDataToJSON(data)) : data;\n }\n\n if (utils.isArrayBuffer(data) ||\n utils.isBuffer(data) ||\n utils.isStream(data) ||\n utils.isFile(data) ||\n utils.isBlob(data) ||\n utils.isReadableStream(data)\n ) {\n return data;\n }\n if (utils.isArrayBufferView(data)) {\n return data.buffer;\n }\n if (utils.isURLSearchParams(data)) {\n headers.setContentType('application/x-www-form-urlencoded;charset=utf-8', false);\n return data.toString();\n }\n\n let isFileList;\n\n if (isObjectPayload) {\n if (contentType.indexOf('application/x-www-form-urlencoded') > -1) {\n return toURLEncodedForm(data, this.formSerializer).toString();\n }\n\n if ((isFileList = utils.isFileList(data)) || contentType.indexOf('multipart/form-data') > -1) {\n const _FormData = this.env && this.env.FormData;\n\n return toFormData(\n isFileList ? {'files[]': data} : data,\n _FormData && new _FormData(),\n this.formSerializer\n );\n }\n }\n\n if (isObjectPayload || hasJSONContentType ) {\n headers.setContentType('application/json', false);\n return stringifySafely(data);\n }\n\n return data;\n }],\n\n transformResponse: [function transformResponse(data) {\n const transitional = this.transitional || defaults.transitional;\n const forcedJSONParsing = transitional && transitional.forcedJSONParsing;\n const JSONRequested = this.responseType === 'json';\n\n if (utils.isResponse(data) || utils.isReadableStream(data)) {\n return data;\n }\n\n if (data && utils.isString(data) && ((forcedJSONParsing && !this.responseType) || JSONRequested)) {\n const silentJSONParsing = transitional && transitional.silentJSONParsing;\n const strictJSONParsing = !silentJSONParsing && JSONRequested;\n\n try {\n return JSON.parse(data);\n } catch (e) {\n if (strictJSONParsing) {\n if (e.name === 'SyntaxError') {\n throw AxiosError.from(e, AxiosError.ERR_BAD_RESPONSE, this, null, this.response);\n }\n throw e;\n }\n }\n }\n\n return data;\n }],\n\n /**\n * A timeout in milliseconds to abort a request. If set to 0 (default) a\n * timeout is not created.\n */\n timeout: 0,\n\n xsrfCookieName: 'XSRF-TOKEN',\n xsrfHeaderName: 'X-XSRF-TOKEN',\n\n maxContentLength: -1,\n maxBodyLength: -1,\n\n env: {\n FormData: platform.classes.FormData,\n Blob: platform.classes.Blob\n },\n\n validateStatus: function validateStatus(status) {\n return status >= 200 && status < 300;\n },\n\n headers: {\n common: {\n 'Accept': 'application/json, text/plain, */*',\n 'Content-Type': undefined\n }\n }\n};\n\nutils.forEach(['delete', 'get', 'head', 'post', 'put', 'patch'], (method) => {\n defaults.headers[method] = {};\n});\n\nexport default defaults;\n","'use strict';\n\nimport utils from './../utils.js';\n\n// RawAxiosHeaders whose duplicates are ignored by node\n// c.f. https://nodejs.org/api/http.html#http_message_headers\nconst ignoreDuplicateOf = utils.toObjectSet([\n 'age', 'authorization', 'content-length', 'content-type', 'etag',\n 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',\n 'last-modified', 'location', 'max-forwards', 'proxy-authorization',\n 'referer', 'retry-after', 'user-agent'\n]);\n\n/**\n * Parse headers into an object\n *\n * ```\n * Date: Wed, 27 Aug 2014 08:58:49 GMT\n * Content-Type: application/json\n * Connection: keep-alive\n * Transfer-Encoding: chunked\n * ```\n *\n * @param {String} rawHeaders Headers needing to be parsed\n *\n * @returns {Object} Headers parsed into an object\n */\nexport default rawHeaders => {\n const parsed = {};\n let key;\n let val;\n let i;\n\n rawHeaders && rawHeaders.split('\\n').forEach(function parser(line) {\n i = line.indexOf(':');\n key = line.substring(0, i).trim().toLowerCase();\n val = line.substring(i + 1).trim();\n\n if (!key || (parsed[key] && ignoreDuplicateOf[key])) {\n return;\n }\n\n if (key === 'set-cookie') {\n if (parsed[key]) {\n parsed[key].push(val);\n } else {\n parsed[key] = [val];\n }\n } else {\n parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;\n }\n });\n\n return parsed;\n};\n","'use strict';\n\nimport utils from '../utils.js';\nimport parseHeaders from '../helpers/parseHeaders.js';\n\nconst $internals = Symbol('internals');\n\nfunction normalizeHeader(header) {\n return header && String(header).trim().toLowerCase();\n}\n\nfunction normalizeValue(value) {\n if (value === false || value == null) {\n return value;\n }\n\n return utils.isArray(value) ? value.map(normalizeValue) : String(value);\n}\n\nfunction parseTokens(str) {\n const tokens = Object.create(null);\n const tokensRE = /([^\\s,;=]+)\\s*(?:=\\s*([^,;]+))?/g;\n let match;\n\n while ((match = tokensRE.exec(str))) {\n tokens[match[1]] = match[2];\n }\n\n return tokens;\n}\n\nconst isValidHeaderName = (str) => /^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(str.trim());\n\nfunction matchHeaderValue(context, value, header, filter, isHeaderNameFilter) {\n if (utils.isFunction(filter)) {\n return filter.call(this, value, header);\n }\n\n if (isHeaderNameFilter) {\n value = header;\n }\n\n if (!utils.isString(value)) return;\n\n if (utils.isString(filter)) {\n return value.indexOf(filter) !== -1;\n }\n\n if (utils.isRegExp(filter)) {\n return filter.test(value);\n }\n}\n\nfunction formatHeader(header) {\n return header.trim()\n .toLowerCase().replace(/([a-z\\d])(\\w*)/g, (w, char, str) => {\n return char.toUpperCase() + str;\n });\n}\n\nfunction buildAccessors(obj, header) {\n const accessorName = utils.toCamelCase(' ' + header);\n\n ['get', 'set', 'has'].forEach(methodName => {\n Object.defineProperty(obj, methodName + accessorName, {\n value: function(arg1, arg2, arg3) {\n return this[methodName].call(this, header, arg1, arg2, arg3);\n },\n configurable: true\n });\n });\n}\n\nclass AxiosHeaders {\n constructor(headers) {\n headers && this.set(headers);\n }\n\n set(header, valueOrRewrite, rewrite) {\n const self = this;\n\n function setHeader(_value, _header, _rewrite) {\n const lHeader = normalizeHeader(_header);\n\n if (!lHeader) {\n throw new Error('header name must be a non-empty string');\n }\n\n const key = utils.findKey(self, lHeader);\n\n if(!key || self[key] === undefined || _rewrite === true || (_rewrite === undefined && self[key] !== false)) {\n self[key || _header] = normalizeValue(_value);\n }\n }\n\n const setHeaders = (headers, _rewrite) =>\n utils.forEach(headers, (_value, _header) => setHeader(_value, _header, _rewrite));\n\n if (utils.isPlainObject(header) || header instanceof this.constructor) {\n setHeaders(header, valueOrRewrite)\n } else if(utils.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {\n setHeaders(parseHeaders(header), valueOrRewrite);\n } else if (utils.isObject(header) && utils.isIterable(header)) {\n let obj = {}, dest, key;\n for (const entry of header) {\n if (!utils.isArray(entry)) {\n throw TypeError('Object iterator must return a key-value pair');\n }\n\n obj[key = entry[0]] = (dest = obj[key]) ?\n (utils.isArray(dest) ? [...dest, entry[1]] : [dest, entry[1]]) : entry[1];\n }\n\n setHeaders(obj, valueOrRewrite)\n } else {\n header != null && setHeader(valueOrRewrite, header, rewrite);\n }\n\n return this;\n }\n\n get(header, parser) {\n header = normalizeHeader(header);\n\n if (header) {\n const key = utils.findKey(this, header);\n\n if (key) {\n const value = this[key];\n\n if (!parser) {\n return value;\n }\n\n if (parser === true) {\n return parseTokens(value);\n }\n\n if (utils.isFunction(parser)) {\n return parser.call(this, value, key);\n }\n\n if (utils.isRegExp(parser)) {\n return parser.exec(value);\n }\n\n throw new TypeError('parser must be boolean|regexp|function');\n }\n }\n }\n\n has(header, matcher) {\n header = normalizeHeader(header);\n\n if (header) {\n const key = utils.findKey(this, header);\n\n return !!(key && this[key] !== undefined && (!matcher || matchHeaderValue(this, this[key], key, matcher)));\n }\n\n return false;\n }\n\n delete(header, matcher) {\n const self = this;\n let deleted = false;\n\n function deleteHeader(_header) {\n _header = normalizeHeader(_header);\n\n if (_header) {\n const key = utils.findKey(self, _header);\n\n if (key && (!matcher || matchHeaderValue(self, self[key], key, matcher))) {\n delete self[key];\n\n deleted = true;\n }\n }\n }\n\n if (utils.isArray(header)) {\n header.forEach(deleteHeader);\n } else {\n deleteHeader(header);\n }\n\n return deleted;\n }\n\n clear(matcher) {\n const keys = Object.keys(this);\n let i = keys.length;\n let deleted = false;\n\n while (i--) {\n const key = keys[i];\n if(!matcher || matchHeaderValue(this, this[key], key, matcher, true)) {\n delete this[key];\n deleted = true;\n }\n }\n\n return deleted;\n }\n\n normalize(format) {\n const self = this;\n const headers = {};\n\n utils.forEach(this, (value, header) => {\n const key = utils.findKey(headers, header);\n\n if (key) {\n self[key] = normalizeValue(value);\n delete self[header];\n return;\n }\n\n const normalized = format ? formatHeader(header) : String(header).trim();\n\n if (normalized !== header) {\n delete self[header];\n }\n\n self[normalized] = normalizeValue(value);\n\n headers[normalized] = true;\n });\n\n return this;\n }\n\n concat(...targets) {\n return this.constructor.concat(this, ...targets);\n }\n\n toJSON(asStrings) {\n const obj = Object.create(null);\n\n utils.forEach(this, (value, header) => {\n value != null && value !== false && (obj[header] = asStrings && utils.isArray(value) ? value.join(', ') : value);\n });\n\n return obj;\n }\n\n [Symbol.iterator]() {\n return Object.entries(this.toJSON())[Symbol.iterator]();\n }\n\n toString() {\n return Object.entries(this.toJSON()).map(([header, value]) => header + ': ' + value).join('\\n');\n }\n\n getSetCookie() {\n return this.get(\"set-cookie\") || [];\n }\n\n get [Symbol.toStringTag]() {\n return 'AxiosHeaders';\n }\n\n static from(thing) {\n return thing instanceof this ? thing : new this(thing);\n }\n\n static concat(first, ...targets) {\n const computed = new this(first);\n\n targets.forEach((target) => computed.set(target));\n\n return computed;\n }\n\n static accessor(header) {\n const internals = this[$internals] = (this[$internals] = {\n accessors: {}\n });\n\n const accessors = internals.accessors;\n const prototype = this.prototype;\n\n function defineAccessor(_header) {\n const lHeader = normalizeHeader(_header);\n\n if (!accessors[lHeader]) {\n buildAccessors(prototype, _header);\n accessors[lHeader] = true;\n }\n }\n\n utils.isArray(header) ? header.forEach(defineAccessor) : defineAccessor(header);\n\n return this;\n }\n}\n\nAxiosHeaders.accessor(['Content-Type', 'Content-Length', 'Accept', 'Accept-Encoding', 'User-Agent', 'Authorization']);\n\n// reserved names hotfix\nutils.reduceDescriptors(AxiosHeaders.prototype, ({value}, key) => {\n let mapped = key[0].toUpperCase() + key.slice(1); // map `set` => `Set`\n return {\n get: () => value,\n set(headerValue) {\n this[mapped] = headerValue;\n }\n }\n});\n\nutils.freezeMethods(AxiosHeaders);\n\nexport default AxiosHeaders;\n","'use strict';\n\nimport utils from './../utils.js';\nimport defaults from '../defaults/index.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\n\n/**\n * Transform the data for a request or a response\n *\n * @param {Array|Function} fns A single function or Array of functions\n * @param {?Object} response The response object\n *\n * @returns {*} The resulting transformed data\n */\nexport default function transformData(fns, response) {\n const config = this || defaults;\n const context = response || config;\n const headers = AxiosHeaders.from(context.headers);\n let data = context.data;\n\n utils.forEach(fns, function transform(fn) {\n data = fn.call(config, data, headers.normalize(), response ? response.status : undefined);\n });\n\n headers.normalize();\n\n return data;\n}\n","'use strict';\n\nexport default function isCancel(value) {\n return !!(value && value.__CANCEL__);\n}\n","'use strict';\n\nimport AxiosError from '../core/AxiosError.js';\nimport utils from '../utils.js';\n\n/**\n * A `CanceledError` is an object that is thrown when an operation is canceled.\n *\n * @param {string=} message The message.\n * @param {Object=} config The config.\n * @param {Object=} request The request.\n *\n * @returns {CanceledError} The created error.\n */\nfunction CanceledError(message, config, request) {\n // eslint-disable-next-line no-eq-null,eqeqeq\n AxiosError.call(this, message == null ? 'canceled' : message, AxiosError.ERR_CANCELED, config, request);\n this.name = 'CanceledError';\n}\n\nutils.inherits(CanceledError, AxiosError, {\n __CANCEL__: true\n});\n\nexport default CanceledError;\n","'use strict';\n\nimport AxiosError from './AxiosError.js';\n\n/**\n * Resolve or reject a Promise based on response status.\n *\n * @param {Function} resolve A function that resolves the promise.\n * @param {Function} reject A function that rejects the promise.\n * @param {object} response The response.\n *\n * @returns {object} The response.\n */\nexport default function settle(resolve, reject, response) {\n const validateStatus = response.config.validateStatus;\n if (!response.status || !validateStatus || validateStatus(response.status)) {\n resolve(response);\n } else {\n reject(new AxiosError(\n 'Request failed with status code ' + response.status,\n [AxiosError.ERR_BAD_REQUEST, AxiosError.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4],\n response.config,\n response.request,\n response\n ));\n }\n}\n","'use strict';\n\n/**\n * Determines whether the specified URL is absolute\n *\n * @param {string} url The URL to test\n *\n * @returns {boolean} True if the specified URL is absolute, otherwise false\n */\nexport default function isAbsoluteURL(url) {\n // A URL is considered absolute if it begins with \"<scheme>://\" or \"//\" (protocol-relative URL).\n // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed\n // by any combination of letters, digits, plus, period, or hyphen.\n return /^([a-z][a-z\\d+\\-.]*:)?\\/\\//i.test(url);\n}\n","'use strict';\n\n/**\n * Creates a new URL by combining the specified URLs\n *\n * @param {string} baseURL The base URL\n * @param {string} relativeURL The relative URL\n *\n * @returns {string} The combined URL\n */\nexport default function combineURLs(baseURL, relativeURL) {\n return relativeURL\n ? baseURL.replace(/\\/?\\/$/, '') + '/' + relativeURL.replace(/^\\/+/, '')\n : baseURL;\n}\n","'use strict';\n\nimport isAbsoluteURL from '../helpers/isAbsoluteURL.js';\nimport combineURLs from '../helpers/combineURLs.js';\n\n/**\n * Creates a new URL by combining the baseURL with the requestedURL,\n * only when the requestedURL is not already an absolute URL.\n * If the requestURL is absolute, this function returns the requestedURL untouched.\n *\n * @param {string} baseURL The base URL\n * @param {string} requestedURL Absolute or relative URL to combine\n *\n * @returns {string} The combined full path\n */\nexport default function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) {\n let isRelativeUrl = !isAbsoluteURL(requestedURL);\n if (baseURL && (isRelativeUrl || allowAbsoluteUrls == false)) {\n return combineURLs(baseURL, requestedURL);\n }\n return requestedURL;\n}\n","'use strict';\n\nvar parseUrl = require('url').parse;\n\nvar DEFAULT_PORTS = {\n ftp: 21,\n gopher: 70,\n http: 80,\n https: 443,\n ws: 80,\n wss: 443,\n};\n\nvar stringEndsWith = String.prototype.endsWith || function(s) {\n return s.length <= this.length &&\n this.indexOf(s, this.length - s.length) !== -1;\n};\n\n/**\n * @param {string|object} url - The URL, or the result from url.parse.\n * @return {string} The URL of the proxy that should handle the request to the\n * given URL. If no proxy is set, this will be an empty string.\n */\nfunction getProxyForUrl(url) {\n var parsedUrl = typeof url === 'string' ? parseUrl(url) : url || {};\n var proto = parsedUrl.protocol;\n var hostname = parsedUrl.host;\n var port = parsedUrl.port;\n if (typeof hostname !== 'string' || !hostname || typeof proto !== 'string') {\n return ''; // Don't proxy URLs without a valid scheme or host.\n }\n\n proto = proto.split(':', 1)[0];\n // Stripping ports in this way instead of using parsedUrl.hostname to make\n // sure that the brackets around IPv6 addresses are kept.\n hostname = hostname.replace(/:\\d*$/, '');\n port = parseInt(port) || DEFAULT_PORTS[proto] || 0;\n if (!shouldProxy(hostname, port)) {\n return ''; // Don't proxy URLs that match NO_PROXY.\n }\n\n var proxy =\n getEnv('npm_config_' + proto + '_proxy') ||\n getEnv(proto + '_proxy') ||\n getEnv('npm_config_proxy') ||\n getEnv('all_proxy');\n if (proxy && proxy.indexOf('://') === -1) {\n // Missing scheme in proxy, default to the requested URL's scheme.\n proxy = proto + '://' + proxy;\n }\n return proxy;\n}\n\n/**\n * Determines whether a given URL should be proxied.\n *\n * @param {string} hostname - The host name of the URL.\n * @param {number} port - The effective port of the URL.\n * @returns {boolean} Whether the given URL should be proxied.\n * @private\n */\nfunction shouldProxy(hostname, port) {\n var NO_PROXY =\n (getEnv('npm_config_no_proxy') || getEnv('no_proxy')).toLowerCase();\n if (!NO_PROXY) {\n return true; // Always proxy if NO_PROXY is not set.\n }\n if (NO_PROXY === '*') {\n return false; // Never proxy if wildcard is set.\n }\n\n return NO_PROXY.split(/[,\\s]/).every(function(proxy) {\n if (!proxy) {\n return true; // Skip zero-length hosts.\n }\n var parsedProxy = proxy.match(/^(.+):(\\d+)$/);\n var parsedProxyHostname = parsedProxy ? parsedProxy[1] : proxy;\n var parsedProxyPort = parsedProxy ? parseInt(parsedProxy[2]) : 0;\n if (parsedProxyPort && parsedProxyPort !== port) {\n return true; // Skip if ports don't match.\n }\n\n if (!/^[.*]/.test(parsedProxyHostname)) {\n // No wildcards, so stop proxying if there is an exact match.\n return hostname !== parsedProxyHostname;\n }\n\n if (parsedProxyHostname.charAt(0) === '*') {\n // Remove leading wildcard.\n parsedProxyHostname = parsedProxyHostname.slice(1);\n }\n // Stop proxying if the hostname ends with the no_proxy host.\n return !stringEndsWith.call(hostname, parsedProxyHostname);\n });\n}\n\n/**\n * Get the value for an environment variable.\n *\n * @param {string} key - The name of the environment variable.\n * @return {string} The value of the environment variable.\n * @private\n */\nfunction getEnv(key) {\n return process.env[key.toLowerCase()] || process.env[key.toUpperCase()] || '';\n}\n\nexports.getProxyForUrl = getProxyForUrl;\n","/**\n * Helpers.\n */\n\nvar s = 1000;\nvar m = s * 60;\nvar h = m * 60;\nvar d = h * 24;\nvar w = d * 7;\nvar y = d * 365.25;\n\n/**\n * Parse or format the given `val`.\n *\n * Options:\n *\n * - `long` verbose formatting [false]\n *\n * @param {String|Number} val\n * @param {Object} [options]\n * @throws {Error} throw an error if val is not a non-empty string or a number\n * @return {String|Number}\n * @api public\n */\n\nmodule.exports = function (val, options) {\n options = options || {};\n var type = typeof val;\n if (type === 'string' && val.length > 0) {\n return parse(val);\n } else if (type === 'number' && isFinite(val)) {\n return options.long ? fmtLong(val) : fmtShort(val);\n }\n throw new Error(\n 'val is not a non-empty string or a valid number. val=' +\n JSON.stringify(val)\n );\n};\n\n/**\n * Parse the given `str` and return milliseconds.\n *\n * @param {String} str\n * @return {Number}\n * @api private\n */\n\nfunction parse(str) {\n str = String(str);\n if (str.length > 100) {\n return;\n }\n var match = /^(-?(?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(\n str\n );\n if (!match) {\n return;\n }\n var n = parseFloat(match[1]);\n var type = (match[2] || 'ms').toLowerCase();\n switch (type) {\n case 'years':\n case 'year':\n case 'yrs':\n case 'yr':\n case 'y':\n return n * y;\n case 'weeks':\n case 'week':\n case 'w':\n return n * w;\n case 'days':\n case 'day':\n case 'd':\n return n * d;\n case 'hours':\n case 'hour':\n case 'hrs':\n case 'hr':\n case 'h':\n return n * h;\n case 'minutes':\n case 'minute':\n case 'mins':\n case 'min':\n case 'm':\n return n * m;\n case 'seconds':\n case 'second':\n case 'secs':\n case 'sec':\n case 's':\n return n * s;\n case 'milliseconds':\n case 'millisecond':\n case 'msecs':\n case 'msec':\n case 'ms':\n return n;\n default:\n return undefined;\n }\n}\n\n/**\n * Short format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction fmtShort(ms) {\n var msAbs = Math.abs(ms);\n if (msAbs >= d) {\n return Math.round(ms / d) + 'd';\n }\n if (msAbs >= h) {\n return Math.round(ms / h) + 'h';\n }\n if (msAbs >= m) {\n return Math.round(ms / m) + 'm';\n }\n if (msAbs >= s) {\n return Math.round(ms / s) + 's';\n }\n return ms + 'ms';\n}\n\n/**\n * Long format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction fmtLong(ms) {\n var msAbs = Math.abs(ms);\n if (msAbs >= d) {\n return plural(ms, msAbs, d, 'day');\n }\n if (msAbs >= h) {\n return plural(ms, msAbs, h, 'hour');\n }\n if (msAbs >= m) {\n return plural(ms, msAbs, m, 'minute');\n }\n if (msAbs >= s) {\n return plural(ms, msAbs, s, 'second');\n }\n return ms + ' ms';\n}\n\n/**\n * Pluralization helper.\n */\n\nfunction plural(ms, msAbs, n, name) {\n var isPlural = msAbs >= n * 1.5;\n return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');\n}\n","\n/**\n * This is the common logic for both the Node.js and web browser\n * implementations of `debug()`.\n */\n\nfunction setup(env) {\n\tcreateDebug.debug = createDebug;\n\tcreateDebug.default = createDebug;\n\tcreateDebug.coerce = coerce;\n\tcreateDebug.disable = disable;\n\tcreateDebug.enable = enable;\n\tcreateDebug.enabled = enabled;\n\tcreateDebug.humanize = require('ms');\n\tcreateDebug.destroy = destroy;\n\n\tObject.keys(env).forEach(key => {\n\t\tcreateDebug[key] = env[key];\n\t});\n\n\t/**\n\t* The currently active debug mode names, and names to skip.\n\t*/\n\n\tcreateDebug.names = [];\n\tcreateDebug.skips = [];\n\n\t/**\n\t* Map of special \"%n\" handling functions, for the debug \"format\" argument.\n\t*\n\t* Valid key names are a single, lower or upper-case letter, i.e. \"n\" and \"N\".\n\t*/\n\tcreateDebug.formatters = {};\n\n\t/**\n\t* Selects a color for a debug namespace\n\t* @param {String} namespace The namespace string for the debug instance to be colored\n\t* @return {Number|String} An ANSI color code for the given namespace\n\t* @api private\n\t*/\n\tfunction selectColor(namespace) {\n\t\tlet hash = 0;\n\n\t\tfor (let i = 0; i < namespace.length; i++) {\n\t\t\thash = ((hash << 5) - hash) + namespace.charCodeAt(i);\n\t\t\thash |= 0; // Convert to 32bit integer\n\t\t}\n\n\t\treturn createDebug.colors[Math.abs(hash) % createDebug.colors.length];\n\t}\n\tcreateDebug.selectColor = selectColor;\n\n\t/**\n\t* Create a debugger with the given `namespace`.\n\t*\n\t* @param {String} namespace\n\t* @return {Function}\n\t* @api public\n\t*/\n\tfunction createDebug(namespace) {\n\t\tlet prevTime;\n\t\tlet enableOverride = null;\n\t\tlet namespacesCache;\n\t\tlet enabledCache;\n\n\t\tfunction debug(...args) {\n\t\t\t// Disabled?\n\t\t\tif (!debug.enabled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst self = debug;\n\n\t\t\t// Set `diff` timestamp\n\t\t\tconst curr = Number(new Date());\n\t\t\tconst ms = curr - (prevTime || curr);\n\t\t\tself.diff = ms;\n\t\t\tself.prev = prevTime;\n\t\t\tself.curr = curr;\n\t\t\tprevTime = curr;\n\n\t\t\targs[0] = createDebug.coerce(args[0]);\n\n\t\t\tif (typeof args[0] !== 'string') {\n\t\t\t\t// Anything else let's inspect with %O\n\t\t\t\targs.unshift('%O');\n\t\t\t}\n\n\t\t\t// Apply any `formatters` transformations\n\t\t\tlet index = 0;\n\t\t\targs[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {\n\t\t\t\t// If we encounter an escaped % then don't increase the array index\n\t\t\t\tif (match === '%%') {\n\t\t\t\t\treturn '%';\n\t\t\t\t}\n\t\t\t\tindex++;\n\t\t\t\tconst formatter = createDebug.formatters[format];\n\t\t\t\tif (typeof formatter === 'function') {\n\t\t\t\t\tconst val = args[index];\n\t\t\t\t\tmatch = formatter.call(self, val);\n\n\t\t\t\t\t// Now we need to remove `args[index]` since it's inlined in the `format`\n\t\t\t\t\targs.splice(index, 1);\n\t\t\t\t\tindex--;\n\t\t\t\t}\n\t\t\t\treturn match;\n\t\t\t});\n\n\t\t\t// Apply env-specific formatting (colors, etc.)\n\t\t\tcreateDebug.formatArgs.call(self, args);\n\n\t\t\tconst logFn = self.log || createDebug.log;\n\t\t\tlogFn.apply(self, args);\n\t\t}\n\n\t\tdebug.namespace = namespace;\n\t\tdebug.useColors = createDebug.useColors();\n\t\tdebug.color = createDebug.selectColor(namespace);\n\t\tdebug.extend = extend;\n\t\tdebug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release.\n\n\t\tObject.defineProperty(debug, 'enabled', {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: false,\n\t\t\tget: () => {\n\t\t\t\tif (enableOverride !== null) {\n\t\t\t\t\treturn enableOverride;\n\t\t\t\t}\n\t\t\t\tif (namespacesCache !== createDebug.namespaces) {\n\t\t\t\t\tnamespacesCache = createDebug.namespaces;\n\t\t\t\t\tenabledCache = createDebug.enabled(namespace);\n\t\t\t\t}\n\n\t\t\t\treturn enabledCache;\n\t\t\t},\n\t\t\tset: v => {\n\t\t\t\tenableOverride = v;\n\t\t\t}\n\t\t});\n\n\t\t// Env-specific initialization logic for debug instances\n\t\tif (typeof createDebug.init === 'function') {\n\t\t\tcreateDebug.init(debug);\n\t\t}\n\n\t\treturn debug;\n\t}\n\n\tfunction extend(namespace, delimiter) {\n\t\tconst newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);\n\t\tnewDebug.log = this.log;\n\t\treturn newDebug;\n\t}\n\n\t/**\n\t* Enables a debug mode by namespaces. This can include modes\n\t* separated by a colon and wildcards.\n\t*\n\t* @param {String} namespaces\n\t* @api public\n\t*/\n\tfunction enable(namespaces) {\n\t\tcreateDebug.save(namespaces);\n\t\tcreateDebug.namespaces = namespaces;\n\n\t\tcreateDebug.names = [];\n\t\tcreateDebug.skips = [];\n\n\t\tconst split = (typeof namespaces === 'string' ? namespaces : '')\n\t\t\t.trim()\n\t\t\t.replace(' ', ',')\n\t\t\t.split(',')\n\t\t\t.filter(Boolean);\n\n\t\tfor (const ns of split) {\n\t\t\tif (ns[0] === '-') {\n\t\t\t\tcreateDebug.skips.push(ns.slice(1));\n\t\t\t} else {\n\t\t\t\tcreateDebug.names.push(ns);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Checks if the given string matches a namespace template, honoring\n\t * asterisks as wildcards.\n\t *\n\t * @param {String} search\n\t * @param {String} template\n\t * @return {Boolean}\n\t */\n\tfunction matchesTemplate(search, template) {\n\t\tlet searchIndex = 0;\n\t\tlet templateIndex = 0;\n\t\tlet starIndex = -1;\n\t\tlet matchIndex = 0;\n\n\t\twhile (searchIndex < search.length) {\n\t\t\tif (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === '*')) {\n\t\t\t\t// Match character or proceed with wildcard\n\t\t\t\tif (template[templateIndex] === '*') {\n\t\t\t\t\tstarIndex = templateIndex;\n\t\t\t\t\tmatchIndex = searchIndex;\n\t\t\t\t\ttemplateIndex++; // Skip the '*'\n\t\t\t\t} else {\n\t\t\t\t\tsearchIndex++;\n\t\t\t\t\ttemplateIndex++;\n\t\t\t\t}\n\t\t\t} else if (starIndex !== -1) { // eslint-disable-line no-negated-condition\n\t\t\t\t// Backtrack to the last '*' and try to match more characters\n\t\t\t\ttemplateIndex = starIndex + 1;\n\t\t\t\tmatchIndex++;\n\t\t\t\tsearchIndex = matchIndex;\n\t\t\t} else {\n\t\t\t\treturn false; // No match\n\t\t\t}\n\t\t}\n\n\t\t// Handle trailing '*' in template\n\t\twhile (templateIndex < template.length && template[templateIndex] === '*') {\n\t\t\ttemplateIndex++;\n\t\t}\n\n\t\treturn templateIndex === template.length;\n\t}\n\n\t/**\n\t* Disable debug output.\n\t*\n\t* @return {String} namespaces\n\t* @api public\n\t*/\n\tfunction disable() {\n\t\tconst namespaces = [\n\t\t\t...createDebug.names,\n\t\t\t...createDebug.skips.map(namespace => '-' + namespace)\n\t\t].join(',');\n\t\tcreateDebug.enable('');\n\t\treturn namespaces;\n\t}\n\n\t/**\n\t* Returns true if the given mode name is enabled, false otherwise.\n\t*\n\t* @param {String} name\n\t* @return {Boolean}\n\t* @api public\n\t*/\n\tfunction enabled(name) {\n\t\tfor (const skip of createDebug.skips) {\n\t\t\tif (matchesTemplate(name, skip)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tfor (const ns of createDebug.names) {\n\t\t\tif (matchesTemplate(name, ns)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t* Coerce `val`.\n\t*\n\t* @param {Mixed} val\n\t* @return {Mixed}\n\t* @api private\n\t*/\n\tfunction coerce(val) {\n\t\tif (val instanceof Error) {\n\t\t\treturn val.stack || val.message;\n\t\t}\n\t\treturn val;\n\t}\n\n\t/**\n\t* XXX DO NOT USE. This is a temporary stub function.\n\t* XXX It WILL be removed in the next major release.\n\t*/\n\tfunction destroy() {\n\t\tconsole.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');\n\t}\n\n\tcreateDebug.enable(createDebug.load());\n\n\treturn createDebug;\n}\n\nmodule.exports = setup;\n","/* eslint-env browser */\n\n/**\n * This is the web browser implementation of `debug()`.\n */\n\nexports.formatArgs = formatArgs;\nexports.save = save;\nexports.load = load;\nexports.useColors = useColors;\nexports.storage = localstorage();\nexports.destroy = (() => {\n\tlet warned = false;\n\n\treturn () => {\n\t\tif (!warned) {\n\t\t\twarned = true;\n\t\t\tconsole.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');\n\t\t}\n\t};\n})();\n\n/**\n * Colors.\n */\n\nexports.colors = [\n\t'#0000CC',\n\t'#0000FF',\n\t'#0033CC',\n\t'#0033FF',\n\t'#0066CC',\n\t'#0066FF',\n\t'#0099CC',\n\t'#0099FF',\n\t'#00CC00',\n\t'#00CC33',\n\t'#00CC66',\n\t'#00CC99',\n\t'#00CCCC',\n\t'#00CCFF',\n\t'#3300CC',\n\t'#3300FF',\n\t'#3333CC',\n\t'#3333FF',\n\t'#3366CC',\n\t'#3366FF',\n\t'#3399CC',\n\t'#3399FF',\n\t'#33CC00',\n\t'#33CC33',\n\t'#33CC66',\n\t'#33CC99',\n\t'#33CCCC',\n\t'#33CCFF',\n\t'#6600CC',\n\t'#6600FF',\n\t'#6633CC',\n\t'#6633FF',\n\t'#66CC00',\n\t'#66CC33',\n\t'#9900CC',\n\t'#9900FF',\n\t'#9933CC',\n\t'#9933FF',\n\t'#99CC00',\n\t'#99CC33',\n\t'#CC0000',\n\t'#CC0033',\n\t'#CC0066',\n\t'#CC0099',\n\t'#CC00CC',\n\t'#CC00FF',\n\t'#CC3300',\n\t'#CC3333',\n\t'#CC3366',\n\t'#CC3399',\n\t'#CC33CC',\n\t'#CC33FF',\n\t'#CC6600',\n\t'#CC6633',\n\t'#CC9900',\n\t'#CC9933',\n\t'#CCCC00',\n\t'#CCCC33',\n\t'#FF0000',\n\t'#FF0033',\n\t'#FF0066',\n\t'#FF0099',\n\t'#FF00CC',\n\t'#FF00FF',\n\t'#FF3300',\n\t'#FF3333',\n\t'#FF3366',\n\t'#FF3399',\n\t'#FF33CC',\n\t'#FF33FF',\n\t'#FF6600',\n\t'#FF6633',\n\t'#FF9900',\n\t'#FF9933',\n\t'#FFCC00',\n\t'#FFCC33'\n];\n\n/**\n * Currently only WebKit-based Web Inspectors, Firefox >= v31,\n * and the Firebug extension (any Firefox version) are known\n * to support \"%c\" CSS customizations.\n *\n * TODO: add a `localStorage` variable to explicitly enable/disable colors\n */\n\n// eslint-disable-next-line complexity\nfunction useColors() {\n\t// NB: In an Electron preload script, document will be defined but not fully\n\t// initialized. Since we know we're in Chrome, we'll just detect this case\n\t// explicitly\n\tif (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {\n\t\treturn true;\n\t}\n\n\t// Internet Explorer and Edge do not support colors.\n\tif (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\\/(\\d+)/)) {\n\t\treturn false;\n\t}\n\n\tlet m;\n\n\t// Is webkit? http://stackoverflow.com/a/16459606/376773\n\t// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632\n\t// eslint-disable-next-line no-return-assign\n\treturn (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||\n\t\t// Is firebug? http://stackoverflow.com/a/398120/376773\n\t\t(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||\n\t\t// Is firefox >= v31?\n\t\t// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages\n\t\t(typeof navigator !== 'undefined' && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\\/(\\d+)/)) && parseInt(m[1], 10) >= 31) ||\n\t\t// Double check webkit in userAgent just in case we are in a worker\n\t\t(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\\/(\\d+)/));\n}\n\n/**\n * Colorize log arguments if enabled.\n *\n * @api public\n */\n\nfunction formatArgs(args) {\n\targs[0] = (this.useColors ? '%c' : '') +\n\t\tthis.namespace +\n\t\t(this.useColors ? ' %c' : ' ') +\n\t\targs[0] +\n\t\t(this.useColors ? '%c ' : ' ') +\n\t\t'+' + module.exports.humanize(this.diff);\n\n\tif (!this.useColors) {\n\t\treturn;\n\t}\n\n\tconst c = 'color: ' + this.color;\n\targs.splice(1, 0, c, 'color: inherit');\n\n\t// The final \"%c\" is somewhat tricky, because there could be other\n\t// arguments passed either before or after the %c, so we need to\n\t// figure out the correct index to insert the CSS into\n\tlet index = 0;\n\tlet lastC = 0;\n\targs[0].replace(/%[a-zA-Z%]/g, match => {\n\t\tif (match === '%%') {\n\t\t\treturn;\n\t\t}\n\t\tindex++;\n\t\tif (match === '%c') {\n\t\t\t// We only are interested in the *last* %c\n\t\t\t// (the user may have provided their own)\n\t\t\tlastC = index;\n\t\t}\n\t});\n\n\targs.splice(lastC, 0, c);\n}\n\n/**\n * Invokes `console.debug()` when available.\n * No-op when `console.debug` is not a \"function\".\n * If `console.debug` is not available, falls back\n * to `console.log`.\n *\n * @api public\n */\nexports.log = console.debug || console.log || (() => {});\n\n/**\n * Save `namespaces`.\n *\n * @param {String} namespaces\n * @api private\n */\nfunction save(namespaces) {\n\ttry {\n\t\tif (namespaces) {\n\t\t\texports.storage.setItem('debug', namespaces);\n\t\t} else {\n\t\t\texports.storage.removeItem('debug');\n\t\t}\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n}\n\n/**\n * Load `namespaces`.\n *\n * @return {String} returns the previously persisted debug modes\n * @api private\n */\nfunction load() {\n\tlet r;\n\ttry {\n\t\tr = exports.storage.getItem('debug');\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n\n\t// If debug isn't set in LS, and we're in Electron, try to load $DEBUG\n\tif (!r && typeof process !== 'undefined' && 'env' in process) {\n\t\tr = process.env.DEBUG;\n\t}\n\n\treturn r;\n}\n\n/**\n * Localstorage attempts to return the localstorage.\n *\n * This is necessary because safari throws\n * when a user disables cookies/localstorage\n * and you attempt to access it.\n *\n * @return {LocalStorage}\n * @api private\n */\n\nfunction localstorage() {\n\ttry {\n\t\t// TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context\n\t\t// The Browser also has localStorage in the global context.\n\t\treturn localStorage;\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n}\n\nmodule.exports = require('./common')(exports);\n\nconst {formatters} = module.exports;\n\n/**\n * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.\n */\n\nformatters.j = function (v) {\n\ttry {\n\t\treturn JSON.stringify(v);\n\t} catch (error) {\n\t\treturn '[UnexpectedJSONParseError]: ' + error.message;\n\t}\n};\n","'use strict';\n\nmodule.exports = (flag, argv = process.argv) => {\n\tconst prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');\n\tconst position = argv.indexOf(prefix + flag);\n\tconst terminatorPosition = argv.indexOf('--');\n\treturn position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);\n};\n","'use strict';\nconst os = require('os');\nconst tty = require('tty');\nconst hasFlag = require('has-flag');\n\nconst {env} = process;\n\nlet forceColor;\nif (hasFlag('no-color') ||\n\thasFlag('no-colors') ||\n\thasFlag('color=false') ||\n\thasFlag('color=never')) {\n\tforceColor = 0;\n} else if (hasFlag('color') ||\n\thasFlag('colors') ||\n\thasFlag('color=true') ||\n\thasFlag('color=always')) {\n\tforceColor = 1;\n}\n\nif ('FORCE_COLOR' in env) {\n\tif (env.FORCE_COLOR === 'true') {\n\t\tforceColor = 1;\n\t} else if (env.FORCE_COLOR === 'false') {\n\t\tforceColor = 0;\n\t} else {\n\t\tforceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3);\n\t}\n}\n\nfunction translateLevel(level) {\n\tif (level === 0) {\n\t\treturn false;\n\t}\n\n\treturn {\n\t\tlevel,\n\t\thasBasic: true,\n\t\thas256: level >= 2,\n\t\thas16m: level >= 3\n\t};\n}\n\nfunction supportsColor(haveStream, streamIsTTY) {\n\tif (forceColor === 0) {\n\t\treturn 0;\n\t}\n\n\tif (hasFlag('color=16m') ||\n\t\thasFlag('color=full') ||\n\t\thasFlag('color=truecolor')) {\n\t\treturn 3;\n\t}\n\n\tif (hasFlag('color=256')) {\n\t\treturn 2;\n\t}\n\n\tif (haveStream && !streamIsTTY && forceColor === undefined) {\n\t\treturn 0;\n\t}\n\n\tconst min = forceColor || 0;\n\n\tif (env.TERM === 'dumb') {\n\t\treturn min;\n\t}\n\n\tif (process.platform === 'win32') {\n\t\t// Windows 10 build 10586 is the first Windows release that supports 256 colors.\n\t\t// Windows 10 build 14931 is the first release that supports 16m/TrueColor.\n\t\tconst osRelease = os.release().split('.');\n\t\tif (\n\t\t\tNumber(osRelease[0]) >= 10 &&\n\t\t\tNumber(osRelease[2]) >= 10586\n\t\t) {\n\t\t\treturn Number(osRelease[2]) >= 14931 ? 3 : 2;\n\t\t}\n\n\t\treturn 1;\n\t}\n\n\tif ('CI' in env) {\n\t\tif (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'GITHUB_ACTIONS', 'BUILDKITE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {\n\t\t\treturn 1;\n\t\t}\n\n\t\treturn min;\n\t}\n\n\tif ('TEAMCITY_VERSION' in env) {\n\t\treturn /^(9\\.(0*[1-9]\\d*)\\.|\\d{2,}\\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;\n\t}\n\n\tif (env.COLORTERM === 'truecolor') {\n\t\treturn 3;\n\t}\n\n\tif ('TERM_PROGRAM' in env) {\n\t\tconst version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);\n\n\t\tswitch (env.TERM_PROGRAM) {\n\t\t\tcase 'iTerm.app':\n\t\t\t\treturn version >= 3 ? 3 : 2;\n\t\t\tcase 'Apple_Terminal':\n\t\t\t\treturn 2;\n\t\t\t// No default\n\t\t}\n\t}\n\n\tif (/-256(color)?$/i.test(env.TERM)) {\n\t\treturn 2;\n\t}\n\n\tif (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {\n\t\treturn 1;\n\t}\n\n\tif ('COLORTERM' in env) {\n\t\treturn 1;\n\t}\n\n\treturn min;\n}\n\nfunction getSupportLevel(stream) {\n\tconst level = supportsColor(stream, stream && stream.isTTY);\n\treturn translateLevel(level);\n}\n\nmodule.exports = {\n\tsupportsColor: getSupportLevel,\n\tstdout: translateLevel(supportsColor(true, tty.isatty(1))),\n\tstderr: translateLevel(supportsColor(true, tty.isatty(2)))\n};\n","/**\n * Module dependencies.\n */\n\nconst tty = require('tty');\nconst util = require('util');\n\n/**\n * This is the Node.js implementation of `debug()`.\n */\n\nexports.init = init;\nexports.log = log;\nexports.formatArgs = formatArgs;\nexports.save = save;\nexports.load = load;\nexports.useColors = useColors;\nexports.destroy = util.deprecate(\n\t() => {},\n\t'Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'\n);\n\n/**\n * Colors.\n */\n\nexports.colors = [6, 2, 3, 4, 5, 1];\n\ntry {\n\t// Optional dependency (as in, doesn't need to be installed, NOT like optionalDependencies in package.json)\n\t// eslint-disable-next-line import/no-extraneous-dependencies\n\tconst supportsColor = require('supports-color');\n\n\tif (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) {\n\t\texports.colors = [\n\t\t\t20,\n\t\t\t21,\n\t\t\t26,\n\t\t\t27,\n\t\t\t32,\n\t\t\t33,\n\t\t\t38,\n\t\t\t39,\n\t\t\t40,\n\t\t\t41,\n\t\t\t42,\n\t\t\t43,\n\t\t\t44,\n\t\t\t45,\n\t\t\t56,\n\t\t\t57,\n\t\t\t62,\n\t\t\t63,\n\t\t\t68,\n\t\t\t69,\n\t\t\t74,\n\t\t\t75,\n\t\t\t76,\n\t\t\t77,\n\t\t\t78,\n\t\t\t79,\n\t\t\t80,\n\t\t\t81,\n\t\t\t92,\n\t\t\t93,\n\t\t\t98,\n\t\t\t99,\n\t\t\t112,\n\t\t\t113,\n\t\t\t128,\n\t\t\t129,\n\t\t\t134,\n\t\t\t135,\n\t\t\t148,\n\t\t\t149,\n\t\t\t160,\n\t\t\t161,\n\t\t\t162,\n\t\t\t163,\n\t\t\t164,\n\t\t\t165,\n\t\t\t166,\n\t\t\t167,\n\t\t\t168,\n\t\t\t169,\n\t\t\t170,\n\t\t\t171,\n\t\t\t172,\n\t\t\t173,\n\t\t\t178,\n\t\t\t179,\n\t\t\t184,\n\t\t\t185,\n\t\t\t196,\n\t\t\t197,\n\t\t\t198,\n\t\t\t199,\n\t\t\t200,\n\t\t\t201,\n\t\t\t202,\n\t\t\t203,\n\t\t\t204,\n\t\t\t205,\n\t\t\t206,\n\t\t\t207,\n\t\t\t208,\n\t\t\t209,\n\t\t\t214,\n\t\t\t215,\n\t\t\t220,\n\t\t\t221\n\t\t];\n\t}\n} catch (error) {\n\t// Swallow - we only care if `supports-color` is available; it doesn't have to be.\n}\n\n/**\n * Build up the default `inspectOpts` object from the environment variables.\n *\n * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js\n */\n\nexports.inspectOpts = Object.keys(process.env).filter(key => {\n\treturn /^debug_/i.test(key);\n}).reduce((obj, key) => {\n\t// Camel-case\n\tconst prop = key\n\t\t.substring(6)\n\t\t.toLowerCase()\n\t\t.replace(/_([a-z])/g, (_, k) => {\n\t\t\treturn k.toUpperCase();\n\t\t});\n\n\t// Coerce string value into JS value\n\tlet val = process.env[key];\n\tif (/^(yes|on|true|enabled)$/i.test(val)) {\n\t\tval = true;\n\t} else if (/^(no|off|false|disabled)$/i.test(val)) {\n\t\tval = false;\n\t} else if (val === 'null') {\n\t\tval = null;\n\t} else {\n\t\tval = Number(val);\n\t}\n\n\tobj[prop] = val;\n\treturn obj;\n}, {});\n\n/**\n * Is stdout a TTY? Colored output is enabled when `true`.\n */\n\nfunction useColors() {\n\treturn 'colors' in exports.inspectOpts ?\n\t\tBoolean(exports.inspectOpts.colors) :\n\t\ttty.isatty(process.stderr.fd);\n}\n\n/**\n * Adds ANSI color escape codes if enabled.\n *\n * @api public\n */\n\nfunction formatArgs(args) {\n\tconst {namespace: name, useColors} = this;\n\n\tif (useColors) {\n\t\tconst c = this.color;\n\t\tconst colorCode = '\\u001B[3' + (c < 8 ? c : '8;5;' + c);\n\t\tconst prefix = ` ${colorCode};1m${name} \\u001B[0m`;\n\n\t\targs[0] = prefix + args[0].split('\\n').join('\\n' + prefix);\n\t\targs.push(colorCode + 'm+' + module.exports.humanize(this.diff) + '\\u001B[0m');\n\t} else {\n\t\targs[0] = getDate() + name + ' ' + args[0];\n\t}\n}\n\nfunction getDate() {\n\tif (exports.inspectOpts.hideDate) {\n\t\treturn '';\n\t}\n\treturn new Date().toISOString() + ' ';\n}\n\n/**\n * Invokes `util.formatWithOptions()` with the specified arguments and writes to stderr.\n */\n\nfunction log(...args) {\n\treturn process.stderr.write(util.formatWithOptions(exports.inspectOpts, ...args) + '\\n');\n}\n\n/**\n * Save `namespaces`.\n *\n * @param {String} namespaces\n * @api private\n */\nfunction save(namespaces) {\n\tif (namespaces) {\n\t\tprocess.env.DEBUG = namespaces;\n\t} else {\n\t\t// If you set a process.env field to null or undefined, it gets cast to the\n\t\t// string 'null' or 'undefined'. Just delete instead.\n\t\tdelete process.env.DEBUG;\n\t}\n}\n\n/**\n * Load `namespaces`.\n *\n * @return {String} returns the previously persisted debug modes\n * @api private\n */\n\nfunction load() {\n\treturn process.env.DEBUG;\n}\n\n/**\n * Init logic for `debug` instances.\n *\n * Create a new `inspectOpts` object in case `useColors` is set\n * differently for a particular `debug` instance.\n */\n\nfunction init(debug) {\n\tdebug.inspectOpts = {};\n\n\tconst keys = Object.keys(exports.inspectOpts);\n\tfor (let i = 0; i < keys.length; i++) {\n\t\tdebug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]];\n\t}\n}\n\nmodule.exports = require('./common')(exports);\n\nconst {formatters} = module.exports;\n\n/**\n * Map %o to `util.inspect()`, all on a single line.\n */\n\nformatters.o = function (v) {\n\tthis.inspectOpts.colors = this.useColors;\n\treturn util.inspect(v, this.inspectOpts)\n\t\t.split('\\n')\n\t\t.map(str => str.trim())\n\t\t.join(' ');\n};\n\n/**\n * Map %O to `util.inspect()`, allowing multiple lines if needed.\n */\n\nformatters.O = function (v) {\n\tthis.inspectOpts.colors = this.useColors;\n\treturn util.inspect(v, this.inspectOpts);\n};\n","/**\n * Detect Electron renderer / nwjs process, which is node, but we should\n * treat as a browser.\n */\n\nif (typeof process === 'undefined' || process.type === 'renderer' || process.browser === true || process.__nwjs) {\n\tmodule.exports = require('./browser.js');\n} else {\n\tmodule.exports = require('./node.js');\n}\n","var debug;\n\nmodule.exports = function () {\n if (!debug) {\n try {\n /* eslint global-require: off */\n debug = require(\"debug\")(\"follow-redirects\");\n }\n catch (error) { /* */ }\n if (typeof debug !== \"function\") {\n debug = function () { /* */ };\n }\n }\n debug.apply(null, arguments);\n};\n","var url = require(\"url\");\nvar URL = url.URL;\nvar http = require(\"http\");\nvar https = require(\"https\");\nvar Writable = require(\"stream\").Writable;\nvar assert = require(\"assert\");\nvar debug = require(\"./debug\");\n\n// Preventive platform detection\n// istanbul ignore next\n(function detectUnsupportedEnvironment() {\n var looksLikeNode = typeof process !== \"undefined\";\n var looksLikeBrowser = typeof window !== \"undefined\" && typeof document !== \"undefined\";\n var looksLikeV8 = isFunction(Error.captureStackTrace);\n if (!looksLikeNode && (looksLikeBrowser || !looksLikeV8)) {\n console.warn(\"The follow-redirects package should be excluded from browser builds.\");\n }\n}());\n\n// Whether to use the native URL object or the legacy url module\nvar useNativeURL = false;\ntry {\n assert(new URL(\"\"));\n}\ncatch (error) {\n useNativeURL = error.code === \"ERR_INVALID_URL\";\n}\n\n// URL fields to preserve in copy operations\nvar preservedUrlFields = [\n \"auth\",\n \"host\",\n \"hostname\",\n \"href\",\n \"path\",\n \"pathname\",\n \"port\",\n \"protocol\",\n \"query\",\n \"search\",\n \"hash\",\n];\n\n// Create handlers that pass events from native requests\nvar events = [\"abort\", \"aborted\", \"connect\", \"error\", \"socket\", \"timeout\"];\nvar eventHandlers = Object.create(null);\nevents.forEach(function (event) {\n eventHandlers[event] = function (arg1, arg2, arg3) {\n this._redirectable.emit(event, arg1, arg2, arg3);\n };\n});\n\n// Error types with codes\nvar InvalidUrlError = createErrorType(\n \"ERR_INVALID_URL\",\n \"Invalid URL\",\n TypeError\n);\nvar RedirectionError = createErrorType(\n \"ERR_FR_REDIRECTION_FAILURE\",\n \"Redirected request failed\"\n);\nvar TooManyRedirectsError = createErrorType(\n \"ERR_FR_TOO_MANY_REDIRECTS\",\n \"Maximum number of redirects exceeded\",\n RedirectionError\n);\nvar MaxBodyLengthExceededError = createErrorType(\n \"ERR_FR_MAX_BODY_LENGTH_EXCEEDED\",\n \"Request body larger than maxBodyLength limit\"\n);\nvar WriteAfterEndError = createErrorType(\n \"ERR_STREAM_WRITE_AFTER_END\",\n \"write after end\"\n);\n\n// istanbul ignore next\nvar destroy = Writable.prototype.destroy || noop;\n\n// An HTTP(S) request that can be redirected\nfunction RedirectableRequest(options, responseCallback) {\n // Initialize the request\n Writable.call(this);\n this._sanitizeOptions(options);\n this._options = options;\n this._ended = false;\n this._ending = false;\n this._redirectCount = 0;\n this._redirects = [];\n this._requestBodyLength = 0;\n this._requestBodyBuffers = [];\n\n // Attach a callback if passed\n if (responseCallback) {\n this.on(\"response\", responseCallback);\n }\n\n // React to responses of native requests\n var self = this;\n this._onNativeResponse = function (response) {\n try {\n self._processResponse(response);\n }\n catch (cause) {\n self.emit(\"error\", cause instanceof RedirectionError ?\n cause : new RedirectionError({ cause: cause }));\n }\n };\n\n // Perform the first request\n this._performRequest();\n}\nRedirectableRequest.prototype = Object.create(Writable.prototype);\n\nRedirectableRequest.prototype.abort = function () {\n destroyRequest(this._currentRequest);\n this._currentRequest.abort();\n this.emit(\"abort\");\n};\n\nRedirectableRequest.prototype.destroy = function (error) {\n destroyRequest(this._currentRequest, error);\n destroy.call(this, error);\n return this;\n};\n\n// Writes buffered data to the current native request\nRedirectableRequest.prototype.write = function (data, encoding, callback) {\n // Writing is not allowed if end has been called\n if (this._ending) {\n throw new WriteAfterEndError();\n }\n\n // Validate input and shift parameters if necessary\n if (!isString(data) && !isBuffer(data)) {\n throw new TypeError(\"data should be a string, Buffer or Uint8Array\");\n }\n if (isFunction(encoding)) {\n callback = encoding;\n encoding = null;\n }\n\n // Ignore empty buffers, since writing them doesn't invoke the callback\n // https://github.com/nodejs/node/issues/22066\n if (data.length === 0) {\n if (callback) {\n callback();\n }\n return;\n }\n // Only write when we don't exceed the maximum body length\n if (this._requestBodyLength + data.length <= this._options.maxBodyLength) {\n this._requestBodyLength += data.length;\n this._requestBodyBuffers.push({ data: data, encoding: encoding });\n this._currentRequest.write(data, encoding, callback);\n }\n // Error when we exceed the maximum body length\n else {\n this.emit(\"error\", new MaxBodyLengthExceededError());\n this.abort();\n }\n};\n\n// Ends the current native request\nRedirectableRequest.prototype.end = function (data, encoding, callback) {\n // Shift parameters if necessary\n if (isFunction(data)) {\n callback = data;\n data = encoding = null;\n }\n else if (isFunction(encoding)) {\n callback = encoding;\n encoding = null;\n }\n\n // Write data if needed and end\n if (!data) {\n this._ended = this._ending = true;\n this._currentRequest.end(null, null, callback);\n }\n else {\n var self = this;\n var currentRequest = this._currentRequest;\n this.write(data, encoding, function () {\n self._ended = true;\n currentRequest.end(null, null, callback);\n });\n this._ending = true;\n }\n};\n\n// Sets a header value on the current native request\nRedirectableRequest.prototype.setHeader = function (name, value) {\n this._options.headers[name] = value;\n this._currentRequest.setHeader(name, value);\n};\n\n// Clears a header value on the current native request\nRedirectableRequest.prototype.removeHeader = function (name) {\n delete this._options.headers[name];\n this._currentRequest.removeHeader(name);\n};\n\n// Global timeout for all underlying requests\nRedirectableRequest.prototype.setTimeout = function (msecs, callback) {\n var self = this;\n\n // Destroys the socket on timeout\n function destroyOnTimeout(socket) {\n socket.setTimeout(msecs);\n socket.removeListener(\"timeout\", socket.destroy);\n socket.addListener(\"timeout\", socket.destroy);\n }\n\n // Sets up a timer to trigger a timeout event\n function startTimer(socket) {\n if (self._timeout) {\n clearTimeout(self._timeout);\n }\n self._timeout = setTimeout(function () {\n self.emit(\"timeout\");\n clearTimer();\n }, msecs);\n destroyOnTimeout(socket);\n }\n\n // Stops a timeout from triggering\n function clearTimer() {\n // Clear the timeout\n if (self._timeout) {\n clearTimeout(self._timeout);\n self._timeout = null;\n }\n\n // Clean up all attached listeners\n self.removeListener(\"abort\", clearTimer);\n self.removeListener(\"error\", clearTimer);\n self.removeListener(\"response\", clearTimer);\n self.removeListener(\"close\", clearTimer);\n if (callback) {\n self.removeListener(\"timeout\", callback);\n }\n if (!self.socket) {\n self._currentRequest.removeListener(\"socket\", startTimer);\n }\n }\n\n // Attach callback if passed\n if (callback) {\n this.on(\"timeout\", callback);\n }\n\n // Start the timer if or when the socket is opened\n if (this.socket) {\n startTimer(this.socket);\n }\n else {\n this._currentRequest.once(\"socket\", startTimer);\n }\n\n // Clean up on events\n this.on(\"socket\", destroyOnTimeout);\n this.on(\"abort\", clearTimer);\n this.on(\"error\", clearTimer);\n this.on(\"response\", clearTimer);\n this.on(\"close\", clearTimer);\n\n return this;\n};\n\n// Proxy all other public ClientRequest methods\n[\n \"flushHeaders\", \"getHeader\",\n \"setNoDelay\", \"setSocketKeepAlive\",\n].forEach(function (method) {\n RedirectableRequest.prototype[method] = function (a, b) {\n return this._currentRequest[method](a, b);\n };\n});\n\n// Proxy all public ClientRequest properties\n[\"aborted\", \"connection\", \"socket\"].forEach(function (property) {\n Object.defineProperty(RedirectableRequest.prototype, property, {\n get: function () { return this._currentRequest[property]; },\n });\n});\n\nRedirectableRequest.prototype._sanitizeOptions = function (options) {\n // Ensure headers are always present\n if (!options.headers) {\n options.headers = {};\n }\n\n // Since http.request treats host as an alias of hostname,\n // but the url module interprets host as hostname plus port,\n // eliminate the host property to avoid confusion.\n if (options.host) {\n // Use hostname if set, because it has precedence\n if (!options.hostname) {\n options.hostname = options.host;\n }\n delete options.host;\n }\n\n // Complete the URL object when necessary\n if (!options.pathname && options.path) {\n var searchPos = options.path.indexOf(\"?\");\n if (searchPos < 0) {\n options.pathname = options.path;\n }\n else {\n options.pathname = options.path.substring(0, searchPos);\n options.search = options.path.substring(searchPos);\n }\n }\n};\n\n\n// Executes the next native request (initial or redirect)\nRedirectableRequest.prototype._performRequest = function () {\n // Load the native protocol\n var protocol = this._options.protocol;\n var nativeProtocol = this._options.nativeProtocols[protocol];\n if (!nativeProtocol) {\n throw new TypeError(\"Unsupported protocol \" + protocol);\n }\n\n // If specified, use the agent corresponding to the protocol\n // (HTTP and HTTPS use different types of agents)\n if (this._options.agents) {\n var scheme = protocol.slice(0, -1);\n this._options.agent = this._options.agents[scheme];\n }\n\n // Create the native request and set up its event handlers\n var request = this._currentRequest =\n nativeProtocol.request(this._options, this._onNativeResponse);\n request._redirectable = this;\n for (var event of events) {\n request.on(event, eventHandlers[event]);\n }\n\n // RFC7230§5.3.1: When making a request directly to an origin server, […]\n // a client MUST send only the absolute path […] as the request-target.\n this._currentUrl = /^\\//.test(this._options.path) ?\n url.format(this._options) :\n // When making a request to a proxy, […]\n // a client MUST send the target URI in absolute-form […].\n this._options.path;\n\n // End a redirected request\n // (The first request must be ended explicitly with RedirectableRequest#end)\n if (this._isRedirect) {\n // Write the request entity and end\n var i = 0;\n var self = this;\n var buffers = this._requestBodyBuffers;\n (function writeNext(error) {\n // Only write if this request has not been redirected yet\n // istanbul ignore else\n if (request === self._currentRequest) {\n // Report any write errors\n // istanbul ignore if\n if (error) {\n self.emit(\"error\", error);\n }\n // Write the next buffer if there are still left\n else if (i < buffers.length) {\n var buffer = buffers[i++];\n // istanbul ignore else\n if (!request.finished) {\n request.write(buffer.data, buffer.encoding, writeNext);\n }\n }\n // End the request if `end` has been called on us\n else if (self._ended) {\n request.end();\n }\n }\n }());\n }\n};\n\n// Processes a response from the current native request\nRedirectableRequest.prototype._processResponse = function (response) {\n // Store the redirected response\n var statusCode = response.statusCode;\n if (this._options.trackRedirects) {\n this._redirects.push({\n url: this._currentUrl,\n headers: response.headers,\n statusCode: statusCode,\n });\n }\n\n // RFC7231§6.4: The 3xx (Redirection) class of status code indicates\n // that further action needs to be taken by the user agent in order to\n // fulfill the request. If a Location header field is provided,\n // the user agent MAY automatically redirect its request to the URI\n // referenced by the Location field value,\n // even if the specific status code is not understood.\n\n // If the response is not a redirect; return it as-is\n var location = response.headers.location;\n if (!location || this._options.followRedirects === false ||\n statusCode < 300 || statusCode >= 400) {\n response.responseUrl = this._currentUrl;\n response.redirects = this._redirects;\n this.emit(\"response\", response);\n\n // Clean up\n this._requestBodyBuffers = [];\n return;\n }\n\n // The response is a redirect, so abort the current request\n destroyRequest(this._currentRequest);\n // Discard the remainder of the response to avoid waiting for data\n response.destroy();\n\n // RFC7231§6.4: A client SHOULD detect and intervene\n // in cyclical redirections (i.e., \"infinite\" redirection loops).\n if (++this._redirectCount > this._options.maxRedirects) {\n throw new TooManyRedirectsError();\n }\n\n // Store the request headers if applicable\n var requestHeaders;\n var beforeRedirect = this._options.beforeRedirect;\n if (beforeRedirect) {\n requestHeaders = Object.assign({\n // The Host header was set by nativeProtocol.request\n Host: response.req.getHeader(\"host\"),\n }, this._options.headers);\n }\n\n // RFC7231§6.4: Automatic redirection needs to done with\n // care for methods not known to be safe, […]\n // RFC7231§6.4.2–3: For historical reasons, a user agent MAY change\n // the request method from POST to GET for the subsequent request.\n var method = this._options.method;\n if ((statusCode === 301 || statusCode === 302) && this._options.method === \"POST\" ||\n // RFC7231§6.4.4: The 303 (See Other) status code indicates that\n // the server is redirecting the user agent to a different resource […]\n // A user agent can perform a retrieval request targeting that URI\n // (a GET or HEAD request if using HTTP) […]\n (statusCode === 303) && !/^(?:GET|HEAD)$/.test(this._options.method)) {\n this._options.method = \"GET\";\n // Drop a possible entity and headers related to it\n this._requestBodyBuffers = [];\n removeMatchingHeaders(/^content-/i, this._options.headers);\n }\n\n // Drop the Host header, as the redirect might lead to a different host\n var currentHostHeader = removeMatchingHeaders(/^host$/i, this._options.headers);\n\n // If the redirect is relative, carry over the host of the last request\n var currentUrlParts = parseUrl(this._currentUrl);\n var currentHost = currentHostHeader || currentUrlParts.host;\n var currentUrl = /^\\w+:/.test(location) ? this._currentUrl :\n url.format(Object.assign(currentUrlParts, { host: currentHost }));\n\n // Create the redirected request\n var redirectUrl = resolveUrl(location, currentUrl);\n debug(\"redirecting to\", redirectUrl.href);\n this._isRedirect = true;\n spreadUrlObject(redirectUrl, this._options);\n\n // Drop confidential headers when redirecting to a less secure protocol\n // or to a different domain that is not a superdomain\n if (redirectUrl.protocol !== currentUrlParts.protocol &&\n redirectUrl.protocol !== \"https:\" ||\n redirectUrl.host !== currentHost &&\n !isSubdomain(redirectUrl.host, currentHost)) {\n removeMatchingHeaders(/^(?:(?:proxy-)?authorization|cookie)$/i, this._options.headers);\n }\n\n // Evaluate the beforeRedirect callback\n if (isFunction(beforeRedirect)) {\n var responseDetails = {\n headers: response.headers,\n statusCode: statusCode,\n };\n var requestDetails = {\n url: currentUrl,\n method: method,\n headers: requestHeaders,\n };\n beforeRedirect(this._options, responseDetails, requestDetails);\n this._sanitizeOptions(this._options);\n }\n\n // Perform the redirected request\n this._performRequest();\n};\n\n// Wraps the key/value object of protocols with redirect functionality\nfunction wrap(protocols) {\n // Default settings\n var exports = {\n maxRedirects: 21,\n maxBodyLength: 10 * 1024 * 1024,\n };\n\n // Wrap each protocol\n var nativeProtocols = {};\n Object.keys(protocols).forEach(function (scheme) {\n var protocol = scheme + \":\";\n var nativeProtocol = nativeProtocols[protocol] = protocols[scheme];\n var wrappedProtocol = exports[scheme] = Object.create(nativeProtocol);\n\n // Executes a request, following redirects\n function request(input, options, callback) {\n // Parse parameters, ensuring that input is an object\n if (isURL(input)) {\n input = spreadUrlObject(input);\n }\n else if (isString(input)) {\n input = spreadUrlObject(parseUrl(input));\n }\n else {\n callback = options;\n options = validateUrl(input);\n input = { protocol: protocol };\n }\n if (isFunction(options)) {\n callback = options;\n options = null;\n }\n\n // Set defaults\n options = Object.assign({\n maxRedirects: exports.maxRedirects,\n maxBodyLength: exports.maxBodyLength,\n }, input, options);\n options.nativeProtocols = nativeProtocols;\n if (!isString(options.host) && !isString(options.hostname)) {\n options.hostname = \"::1\";\n }\n\n assert.equal(options.protocol, protocol, \"protocol mismatch\");\n debug(\"options\", options);\n return new RedirectableRequest(options, callback);\n }\n\n // Executes a GET request, following redirects\n function get(input, options, callback) {\n var wrappedRequest = wrappedProtocol.request(input, options, callback);\n wrappedRequest.end();\n return wrappedRequest;\n }\n\n // Expose the properties on the wrapped protocol\n Object.defineProperties(wrappedProtocol, {\n request: { value: request, configurable: true, enumerable: true, writable: true },\n get: { value: get, configurable: true, enumerable: true, writable: true },\n });\n });\n return exports;\n}\n\nfunction noop() { /* empty */ }\n\nfunction parseUrl(input) {\n var parsed;\n // istanbul ignore else\n if (useNativeURL) {\n parsed = new URL(input);\n }\n else {\n // Ensure the URL is valid and absolute\n parsed = validateUrl(url.parse(input));\n if (!isString(parsed.protocol)) {\n throw new InvalidUrlError({ input });\n }\n }\n return parsed;\n}\n\nfunction resolveUrl(relative, base) {\n // istanbul ignore next\n return useNativeURL ? new URL(relative, base) : parseUrl(url.resolve(base, relative));\n}\n\nfunction validateUrl(input) {\n if (/^\\[/.test(input.hostname) && !/^\\[[:0-9a-f]+\\]$/i.test(input.hostname)) {\n throw new InvalidUrlError({ input: input.href || input });\n }\n if (/^\\[/.test(input.host) && !/^\\[[:0-9a-f]+\\](:\\d+)?$/i.test(input.host)) {\n throw new InvalidUrlError({ input: input.href || input });\n }\n return input;\n}\n\nfunction spreadUrlObject(urlObject, target) {\n var spread = target || {};\n for (var key of preservedUrlFields) {\n spread[key] = urlObject[key];\n }\n\n // Fix IPv6 hostname\n if (spread.hostname.startsWith(\"[\")) {\n spread.hostname = spread.hostname.slice(1, -1);\n }\n // Ensure port is a number\n if (spread.port !== \"\") {\n spread.port = Number(spread.port);\n }\n // Concatenate path\n spread.path = spread.search ? spread.pathname + spread.search : spread.pathname;\n\n return spread;\n}\n\nfunction removeMatchingHeaders(regex, headers) {\n var lastValue;\n for (var header in headers) {\n if (regex.test(header)) {\n lastValue = headers[header];\n delete headers[header];\n }\n }\n return (lastValue === null || typeof lastValue === \"undefined\") ?\n undefined : String(lastValue).trim();\n}\n\nfunction createErrorType(code, message, baseClass) {\n // Create constructor\n function CustomError(properties) {\n // istanbul ignore else\n if (isFunction(Error.captureStackTrace)) {\n Error.captureStackTrace(this, this.constructor);\n }\n Object.assign(this, properties || {});\n this.code = code;\n this.message = this.cause ? message + \": \" + this.cause.message : message;\n }\n\n // Attach constructor and set default properties\n CustomError.prototype = new (baseClass || Error)();\n Object.defineProperties(CustomError.prototype, {\n constructor: {\n value: CustomError,\n enumerable: false,\n },\n name: {\n value: \"Error [\" + code + \"]\",\n enumerable: false,\n },\n });\n return CustomError;\n}\n\nfunction destroyRequest(request, error) {\n for (var event of events) {\n request.removeListener(event, eventHandlers[event]);\n }\n request.on(\"error\", noop);\n request.destroy(error);\n}\n\nfunction isSubdomain(subdomain, domain) {\n assert(isString(subdomain) && isString(domain));\n var dot = subdomain.length - domain.length - 1;\n return dot > 0 && subdomain[dot] === \".\" && subdomain.endsWith(domain);\n}\n\nfunction isString(value) {\n return typeof value === \"string\" || value instanceof String;\n}\n\nfunction isFunction(value) {\n return typeof value === \"function\";\n}\n\nfunction isBuffer(value) {\n return typeof value === \"object\" && (\"length\" in value);\n}\n\nfunction isURL(value) {\n return URL && value instanceof URL;\n}\n\n// Exports\nmodule.exports = wrap({ http: http, https: https });\nmodule.exports.wrap = wrap;\n","export const VERSION = \"1.10.0\";","'use strict';\n\nexport default function parseProtocol(url) {\n const match = /^([-+\\w]{1,25})(:?\\/\\/|:)/.exec(url);\n return match && match[1] || '';\n}\n","'use strict';\n\nimport AxiosError from '../core/AxiosError.js';\nimport parseProtocol from './parseProtocol.js';\nimport platform from '../platform/index.js';\n\nconst DATA_URL_PATTERN = /^(?:([^;]+);)?(?:[^;]+;)?(base64|),([\\s\\S]*)$/;\n\n/**\n * Parse data uri to a Buffer or Blob\n *\n * @param {String} uri\n * @param {?Boolean} asBlob\n * @param {?Object} options\n * @param {?Function} options.Blob\n *\n * @returns {Buffer|Blob}\n */\nexport default function fromDataURI(uri, asBlob, options) {\n const _Blob = options && options.Blob || platform.classes.Blob;\n const protocol = parseProtocol(uri);\n\n if (asBlob === undefined && _Blob) {\n asBlob = true;\n }\n\n if (protocol === 'data') {\n uri = protocol.length ? uri.slice(protocol.length + 1) : uri;\n\n const match = DATA_URL_PATTERN.exec(uri);\n\n if (!match) {\n throw new AxiosError('Invalid URL', AxiosError.ERR_INVALID_URL);\n }\n\n const mime = match[1];\n const isBase64 = match[2];\n const body = match[3];\n const buffer = Buffer.from(decodeURIComponent(body), isBase64 ? 'base64' : 'utf8');\n\n if (asBlob) {\n if (!_Blob) {\n throw new AxiosError('Blob is not supported', AxiosError.ERR_NOT_SUPPORT);\n }\n\n return new _Blob([buffer], {type: mime});\n }\n\n return buffer;\n }\n\n throw new AxiosError('Unsupported protocol ' + protocol, AxiosError.ERR_NOT_SUPPORT);\n}\n","'use strict';\n\nimport stream from 'stream';\nimport utils from '../utils.js';\n\nconst kInternals = Symbol('internals');\n\nclass AxiosTransformStream extends stream.Transform{\n constructor(options) {\n options = utils.toFlatObject(options, {\n maxRate: 0,\n chunkSize: 64 * 1024,\n minChunkSize: 100,\n timeWindow: 500,\n ticksRate: 2,\n samplesCount: 15\n }, null, (prop, source) => {\n return !utils.isUndefined(source[prop]);\n });\n\n super({\n readableHighWaterMark: options.chunkSize\n });\n\n const internals = this[kInternals] = {\n timeWindow: options.timeWindow,\n chunkSize: options.chunkSize,\n maxRate: options.maxRate,\n minChunkSize: options.minChunkSize,\n bytesSeen: 0,\n isCaptured: false,\n notifiedBytesLoaded: 0,\n ts: Date.now(),\n bytes: 0,\n onReadCallback: null\n };\n\n this.on('newListener', event => {\n if (event === 'progress') {\n if (!internals.isCaptured) {\n internals.isCaptured = true;\n }\n }\n });\n }\n\n _read(size) {\n const internals = this[kInternals];\n\n if (internals.onReadCallback) {\n internals.onReadCallback();\n }\n\n return super._read(size);\n }\n\n _transform(chunk, encoding, callback) {\n const internals = this[kInternals];\n const maxRate = internals.maxRate;\n\n const readableHighWaterMark = this.readableHighWaterMark;\n\n const timeWindow = internals.timeWindow;\n\n const divider = 1000 / timeWindow;\n const bytesThreshold = (maxRate / divider);\n const minChunkSize = internals.minChunkSize !== false ? Math.max(internals.minChunkSize, bytesThreshold * 0.01) : 0;\n\n const pushChunk = (_chunk, _callback) => {\n const bytes = Buffer.byteLength(_chunk);\n internals.bytesSeen += bytes;\n internals.bytes += bytes;\n\n internals.isCaptured && this.emit('progress', internals.bytesSeen);\n\n if (this.push(_chunk)) {\n process.nextTick(_callback);\n } else {\n internals.onReadCallback = () => {\n internals.onReadCallback = null;\n process.nextTick(_callback);\n };\n }\n }\n\n const transformChunk = (_chunk, _callback) => {\n const chunkSize = Buffer.byteLength(_chunk);\n let chunkRemainder = null;\n let maxChunkSize = readableHighWaterMark;\n let bytesLeft;\n let passed = 0;\n\n if (maxRate) {\n const now = Date.now();\n\n if (!internals.ts || (passed = (now - internals.ts)) >= timeWindow) {\n internals.ts = now;\n bytesLeft = bytesThreshold - internals.bytes;\n internals.bytes = bytesLeft < 0 ? -bytesLeft : 0;\n passed = 0;\n }\n\n bytesLeft = bytesThreshold - internals.bytes;\n }\n\n if (maxRate) {\n if (bytesLeft <= 0) {\n // next time window\n return setTimeout(() => {\n _callback(null, _chunk);\n }, timeWindow - passed);\n }\n\n if (bytesLeft < maxChunkSize) {\n maxChunkSize = bytesLeft;\n }\n }\n\n if (maxChunkSize && chunkSize > maxChunkSize && (chunkSize - maxChunkSize) > minChunkSize) {\n chunkRemainder = _chunk.subarray(maxChunkSize);\n _chunk = _chunk.subarray(0, maxChunkSize);\n }\n\n pushChunk(_chunk, chunkRemainder ? () => {\n process.nextTick(_callback, null, chunkRemainder);\n } : _callback);\n };\n\n transformChunk(chunk, function transformNextChunk(err, _chunk) {\n if (err) {\n return callback(err);\n }\n\n if (_chunk) {\n transformChunk(_chunk, transformNextChunk);\n } else {\n callback(null);\n }\n });\n }\n}\n\nexport default AxiosTransformStream;\n","const {asyncIterator} = Symbol;\n\nconst readBlob = async function* (blob) {\n if (blob.stream) {\n yield* blob.stream()\n } else if (blob.arrayBuffer) {\n yield await blob.arrayBuffer()\n } else if (blob[asyncIterator]) {\n yield* blob[asyncIterator]();\n } else {\n yield blob;\n }\n}\n\nexport default readBlob;\n","import util from 'util';\nimport {Readable} from 'stream';\nimport utils from \"../utils.js\";\nimport readBlob from \"./readBlob.js\";\nimport platform from \"../platform/index.js\";\n\nconst BOUNDARY_ALPHABET = platform.ALPHABET.ALPHA_DIGIT + '-_';\n\nconst textEncoder = typeof TextEncoder === 'function' ? new TextEncoder() : new util.TextEncoder();\n\nconst CRLF = '\\r\\n';\nconst CRLF_BYTES = textEncoder.encode(CRLF);\nconst CRLF_BYTES_COUNT = 2;\n\nclass FormDataPart {\n constructor(name, value) {\n const {escapeName} = this.constructor;\n const isStringValue = utils.isString(value);\n\n let headers = `Content-Disposition: form-data; name=\"${escapeName(name)}\"${\n !isStringValue && value.name ? `; filename=\"${escapeName(value.name)}\"` : ''\n }${CRLF}`;\n\n if (isStringValue) {\n value = textEncoder.encode(String(value).replace(/\\r?\\n|\\r\\n?/g, CRLF));\n } else {\n headers += `Content-Type: ${value.type || \"application/octet-stream\"}${CRLF}`\n }\n\n this.headers = textEncoder.encode(headers + CRLF);\n\n this.contentLength = isStringValue ? value.byteLength : value.size;\n\n this.size = this.headers.byteLength + this.contentLength + CRLF_BYTES_COUNT;\n\n this.name = name;\n this.value = value;\n }\n\n async *encode(){\n yield this.headers;\n\n const {value} = this;\n\n if(utils.isTypedArray(value)) {\n yield value;\n } else {\n yield* readBlob(value);\n }\n\n yield CRLF_BYTES;\n }\n\n static escapeName(name) {\n return String(name).replace(/[\\r\\n\"]/g, (match) => ({\n '\\r' : '%0D',\n '\\n' : '%0A',\n '\"' : '%22',\n }[match]));\n }\n}\n\nconst formDataToStream = (form, headersHandler, options) => {\n const {\n tag = 'form-data-boundary',\n size = 25,\n boundary = tag + '-' + platform.generateString(size, BOUNDARY_ALPHABET)\n } = options || {};\n\n if(!utils.isFormData(form)) {\n throw TypeError('FormData instance required');\n }\n\n if (boundary.length < 1 || boundary.length > 70) {\n throw Error('boundary must be 10-70 characters long')\n }\n\n const boundaryBytes = textEncoder.encode('--' + boundary + CRLF);\n const footerBytes = textEncoder.encode('--' + boundary + '--' + CRLF);\n let contentLength = footerBytes.byteLength;\n\n const parts = Array.from(form.entries()).map(([name, value]) => {\n const part = new FormDataPart(name, value);\n contentLength += part.size;\n return part;\n });\n\n contentLength += boundaryBytes.byteLength * parts.length;\n\n contentLength = utils.toFiniteNumber(contentLength);\n\n const computedHeaders = {\n 'Content-Type': `multipart/form-data; boundary=${boundary}`\n }\n\n if (Number.isFinite(contentLength)) {\n computedHeaders['Content-Length'] = contentLength;\n }\n\n headersHandler && headersHandler(computedHeaders);\n\n return Readable.from((async function *() {\n for(const part of parts) {\n yield boundaryBytes;\n yield* part.encode();\n }\n\n yield footerBytes;\n })());\n};\n\nexport default formDataToStream;\n","\"use strict\";\n\nimport stream from \"stream\";\n\nclass ZlibHeaderTransformStream extends stream.Transform {\n __transform(chunk, encoding, callback) {\n this.push(chunk);\n callback();\n }\n\n _transform(chunk, encoding, callback) {\n if (chunk.length !== 0) {\n this._transform = this.__transform;\n\n // Add Default Compression headers if no zlib headers are present\n if (chunk[0] !== 120) { // Hex: 78\n const header = Buffer.alloc(2);\n header[0] = 120; // Hex: 78\n header[1] = 156; // Hex: 9C \n this.push(header, encoding);\n }\n }\n\n this.__transform(chunk, encoding, callback);\n }\n}\n\nexport default ZlibHeaderTransformStream;\n","import utils from \"../utils.js\";\n\nconst callbackify = (fn, reducer) => {\n return utils.isAsyncFn(fn) ? function (...args) {\n const cb = args.pop();\n fn.apply(this, args).then((value) => {\n try {\n reducer ? cb(null, ...reducer(value)) : cb(null, value);\n } catch (err) {\n cb(err);\n }\n }, cb);\n } : fn;\n}\n\nexport default callbackify;\n","'use strict';\n\n/**\n * Calculate data maxRate\n * @param {Number} [samplesCount= 10]\n * @param {Number} [min= 1000]\n * @returns {Function}\n */\nfunction speedometer(samplesCount, min) {\n samplesCount = samplesCount || 10;\n const bytes = new Array(samplesCount);\n const timestamps = new Array(samplesCount);\n let head = 0;\n let tail = 0;\n let firstSampleTS;\n\n min = min !== undefined ? min : 1000;\n\n return function push(chunkLength) {\n const now = Date.now();\n\n const startedAt = timestamps[tail];\n\n if (!firstSampleTS) {\n firstSampleTS = now;\n }\n\n bytes[head] = chunkLength;\n timestamps[head] = now;\n\n let i = tail;\n let bytesCount = 0;\n\n while (i !== head) {\n bytesCount += bytes[i++];\n i = i % samplesCount;\n }\n\n head = (head + 1) % samplesCount;\n\n if (head === tail) {\n tail = (tail + 1) % samplesCount;\n }\n\n if (now - firstSampleTS < min) {\n return;\n }\n\n const passed = startedAt && now - startedAt;\n\n return passed ? Math.round(bytesCount * 1000 / passed) : undefined;\n };\n}\n\nexport default speedometer;\n","/**\n * Throttle decorator\n * @param {Function} fn\n * @param {Number} freq\n * @return {Function}\n */\nfunction throttle(fn, freq) {\n let timestamp = 0;\n let threshold = 1000 / freq;\n let lastArgs;\n let timer;\n\n const invoke = (args, now = Date.now()) => {\n timestamp = now;\n lastArgs = null;\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n fn.apply(null, args);\n }\n\n const throttled = (...args) => {\n const now = Date.now();\n const passed = now - timestamp;\n if ( passed >= threshold) {\n invoke(args, now);\n } else {\n lastArgs = args;\n if (!timer) {\n timer = setTimeout(() => {\n timer = null;\n invoke(lastArgs)\n }, threshold - passed);\n }\n }\n }\n\n const flush = () => lastArgs && invoke(lastArgs);\n\n return [throttled, flush];\n}\n\nexport default throttle;\n","import speedometer from \"./speedometer.js\";\nimport throttle from \"./throttle.js\";\nimport utils from \"../utils.js\";\n\nexport const progressEventReducer = (listener, isDownloadStream, freq = 3) => {\n let bytesNotified = 0;\n const _speedometer = speedometer(50, 250);\n\n return throttle(e => {\n const loaded = e.loaded;\n const total = e.lengthComputable ? e.total : undefined;\n const progressBytes = loaded - bytesNotified;\n const rate = _speedometer(progressBytes);\n const inRange = loaded <= total;\n\n bytesNotified = loaded;\n\n const data = {\n loaded,\n total,\n progress: total ? (loaded / total) : undefined,\n bytes: progressBytes,\n rate: rate ? rate : undefined,\n estimated: rate && total && inRange ? (total - loaded) / rate : undefined,\n event: e,\n lengthComputable: total != null,\n [isDownloadStream ? 'download' : 'upload']: true\n };\n\n listener(data);\n }, freq);\n}\n\nexport const progressEventDecorator = (total, throttled) => {\n const lengthComputable = total != null;\n\n return [(loaded) => throttled[0]({\n lengthComputable,\n total,\n loaded\n }), throttled[1]];\n}\n\nexport const asyncDecorator = (fn) => (...args) => utils.asap(() => fn(...args));\n","'use strict';\n\nimport utils from './../utils.js';\nimport settle from './../core/settle.js';\nimport buildFullPath from '../core/buildFullPath.js';\nimport buildURL from './../helpers/buildURL.js';\nimport proxyFromEnv from 'proxy-from-env';\nimport http from 'http';\nimport https from 'https';\nimport util from 'util';\nimport followRedirects from 'follow-redirects';\nimport zlib from 'zlib';\nimport {VERSION} from '../env/data.js';\nimport transitionalDefaults from '../defaults/transitional.js';\nimport AxiosError from '../core/AxiosError.js';\nimport CanceledError from '../cancel/CanceledError.js';\nimport platform from '../platform/index.js';\nimport fromDataURI from '../helpers/fromDataURI.js';\nimport stream from 'stream';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\nimport AxiosTransformStream from '../helpers/AxiosTransformStream.js';\nimport {EventEmitter} from 'events';\nimport formDataToStream from \"../helpers/formDataToStream.js\";\nimport readBlob from \"../helpers/readBlob.js\";\nimport ZlibHeaderTransformStream from '../helpers/ZlibHeaderTransformStream.js';\nimport callbackify from \"../helpers/callbackify.js\";\nimport {progressEventReducer, progressEventDecorator, asyncDecorator} from \"../helpers/progressEventReducer.js\";\n\nconst zlibOptions = {\n flush: zlib.constants.Z_SYNC_FLUSH,\n finishFlush: zlib.constants.Z_SYNC_FLUSH\n};\n\nconst brotliOptions = {\n flush: zlib.constants.BROTLI_OPERATION_FLUSH,\n finishFlush: zlib.constants.BROTLI_OPERATION_FLUSH\n}\n\nconst isBrotliSupported = utils.isFunction(zlib.createBrotliDecompress);\n\nconst {http: httpFollow, https: httpsFollow} = followRedirects;\n\nconst isHttps = /https:?/;\n\nconst supportedProtocols = platform.protocols.map(protocol => {\n return protocol + ':';\n});\n\nconst flushOnFinish = (stream, [throttled, flush]) => {\n stream\n .on('end', flush)\n .on('error', flush);\n\n return throttled;\n}\n\n/**\n * If the proxy or config beforeRedirects functions are defined, call them with the options\n * object.\n *\n * @param {Object<string, any>} options - The options object that was passed to the request.\n *\n * @returns {Object<string, any>}\n */\nfunction dispatchBeforeRedirect(options, responseDetails) {\n if (options.beforeRedirects.proxy) {\n options.beforeRedirects.proxy(options);\n }\n if (options.beforeRedirects.config) {\n options.beforeRedirects.config(options, responseDetails);\n }\n}\n\n/**\n * If the proxy or config afterRedirects functions are defined, call them with the options\n *\n * @param {http.ClientRequestArgs} options\n * @param {AxiosProxyConfig} configProxy configuration from Axios options object\n * @param {string} location\n *\n * @returns {http.ClientRequestArgs}\n */\nfunction setProxy(options, configProxy, location) {\n let proxy = configProxy;\n if (!proxy && proxy !== false) {\n const proxyUrl = proxyFromEnv.getProxyForUrl(location);\n if (proxyUrl) {\n proxy = new URL(proxyUrl);\n }\n }\n if (proxy) {\n // Basic proxy authorization\n if (proxy.username) {\n proxy.auth = (proxy.username || '') + ':' + (proxy.password || '');\n }\n\n if (proxy.auth) {\n // Support proxy auth object form\n if (proxy.auth.username || proxy.auth.password) {\n proxy.auth = (proxy.auth.username || '') + ':' + (proxy.auth.password || '');\n }\n const base64 = Buffer\n .from(proxy.auth, 'utf8')\n .toString('base64');\n options.headers['Proxy-Authorization'] = 'Basic ' + base64;\n }\n\n options.headers.host = options.hostname + (options.port ? ':' + options.port : '');\n const proxyHost = proxy.hostname || proxy.host;\n options.hostname = proxyHost;\n // Replace 'host' since options is not a URL object\n options.host = proxyHost;\n options.port = proxy.port;\n options.path = location;\n if (proxy.protocol) {\n options.protocol = proxy.protocol.includes(':') ? proxy.protocol : `${proxy.protocol}:`;\n }\n }\n\n options.beforeRedirects.proxy = function beforeRedirect(redirectOptions) {\n // Configure proxy for redirected request, passing the original config proxy to apply\n // the exact same logic as if the redirected request was performed by axios directly.\n setProxy(redirectOptions, configProxy, redirectOptions.href);\n };\n}\n\nconst isHttpAdapterSupported = typeof process !== 'undefined' && utils.kindOf(process) === 'process';\n\n// temporary hotfix\n\nconst wrapAsync = (asyncExecutor) => {\n return new Promise((resolve, reject) => {\n let onDone;\n let isDone;\n\n const done = (value, isRejected) => {\n if (isDone) return;\n isDone = true;\n onDone && onDone(value, isRejected);\n }\n\n const _resolve = (value) => {\n done(value);\n resolve(value);\n };\n\n const _reject = (reason) => {\n done(reason, true);\n reject(reason);\n }\n\n asyncExecutor(_resolve, _reject, (onDoneHandler) => (onDone = onDoneHandler)).catch(_reject);\n })\n};\n\nconst resolveFamily = ({address, family}) => {\n if (!utils.isString(address)) {\n throw TypeError('address must be a string');\n }\n return ({\n address,\n family: family || (address.indexOf('.') < 0 ? 6 : 4)\n });\n}\n\nconst buildAddressEntry = (address, family) => resolveFamily(utils.isObject(address) ? address : {address, family});\n\n/*eslint consistent-return:0*/\nexport default isHttpAdapterSupported && function httpAdapter(config) {\n return wrapAsync(async function dispatchHttpRequest(resolve, reject, onDone) {\n let {data, lookup, family} = config;\n const {responseType, responseEncoding} = config;\n const method = config.method.toUpperCase();\n let isDone;\n let rejected = false;\n let req;\n\n if (lookup) {\n const _lookup = callbackify(lookup, (value) => utils.isArray(value) ? value : [value]);\n // hotfix to support opt.all option which is required for node 20.x\n lookup = (hostname, opt, cb) => {\n _lookup(hostname, opt, (err, arg0, arg1) => {\n if (err) {\n return cb(err);\n }\n\n const addresses = utils.isArray(arg0) ? arg0.map(addr => buildAddressEntry(addr)) : [buildAddressEntry(arg0, arg1)];\n\n opt.all ? cb(err, addresses) : cb(err, addresses[0].address, addresses[0].family);\n });\n }\n }\n\n // temporary internal emitter until the AxiosRequest class will be implemented\n const emitter = new EventEmitter();\n\n const onFinished = () => {\n if (config.cancelToken) {\n config.cancelToken.unsubscribe(abort);\n }\n\n if (config.signal) {\n config.signal.removeEventListener('abort', abort);\n }\n\n emitter.removeAllListeners();\n }\n\n onDone((value, isRejected) => {\n isDone = true;\n if (isRejected) {\n rejected = true;\n onFinished();\n }\n });\n\n function abort(reason) {\n emitter.emit('abort', !reason || reason.type ? new CanceledError(null, config, req) : reason);\n }\n\n emitter.once('abort', reject);\n\n if (config.cancelToken || config.signal) {\n config.cancelToken && config.cancelToken.subscribe(abort);\n if (config.signal) {\n config.signal.aborted ? abort() : config.signal.addEventListener('abort', abort);\n }\n }\n\n // Parse url\n const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);\n const parsed = new URL(fullPath, platform.hasBrowserEnv ? platform.origin : undefined);\n const protocol = parsed.protocol || supportedProtocols[0];\n\n if (protocol === 'data:') {\n let convertedData;\n\n if (method !== 'GET') {\n return settle(resolve, reject, {\n status: 405,\n statusText: 'method not allowed',\n headers: {},\n config\n });\n }\n\n try {\n convertedData = fromDataURI(config.url, responseType === 'blob', {\n Blob: config.env && config.env.Blob\n });\n } catch (err) {\n throw AxiosError.from(err, AxiosError.ERR_BAD_REQUEST, config);\n }\n\n if (responseType === 'text') {\n convertedData = convertedData.toString(responseEncoding);\n\n if (!responseEncoding || responseEncoding === 'utf8') {\n convertedData = utils.stripBOM(convertedData);\n }\n } else if (responseType === 'stream') {\n convertedData = stream.Readable.from(convertedData);\n }\n\n return settle(resolve, reject, {\n data: convertedData,\n status: 200,\n statusText: 'OK',\n headers: new AxiosHeaders(),\n config\n });\n }\n\n if (supportedProtocols.indexOf(protocol) === -1) {\n return reject(new AxiosError(\n 'Unsupported protocol ' + protocol,\n AxiosError.ERR_BAD_REQUEST,\n config\n ));\n }\n\n const headers = AxiosHeaders.from(config.headers).normalize();\n\n // Set User-Agent (required by some servers)\n // See https://github.com/axios/axios/issues/69\n // User-Agent is specified; handle case where no UA header is desired\n // Only set header if it hasn't been set in config\n headers.set('User-Agent', 'axios/' + VERSION, false);\n\n const {onUploadProgress, onDownloadProgress} = config;\n const maxRate = config.maxRate;\n let maxUploadRate = undefined;\n let maxDownloadRate = undefined;\n\n // support for spec compliant FormData objects\n if (utils.isSpecCompliantForm(data)) {\n const userBoundary = headers.getContentType(/boundary=([-_\\w\\d]{10,70})/i);\n\n data = formDataToStream(data, (formHeaders) => {\n headers.set(formHeaders);\n }, {\n tag: `axios-${VERSION}-boundary`,\n boundary: userBoundary && userBoundary[1] || undefined\n });\n // support for https://www.npmjs.com/package/form-data api\n } else if (utils.isFormData(data) && utils.isFunction(data.getHeaders)) {\n headers.set(data.getHeaders());\n\n if (!headers.hasContentLength()) {\n try {\n const knownLength = await util.promisify(data.getLength).call(data);\n Number.isFinite(knownLength) && knownLength >= 0 && headers.setContentLength(knownLength);\n /*eslint no-empty:0*/\n } catch (e) {\n }\n }\n } else if (utils.isBlob(data) || utils.isFile(data)) {\n data.size && headers.setContentType(data.type || 'application/octet-stream');\n headers.setContentLength(data.size || 0);\n data = stream.Readable.from(readBlob(data));\n } else if (data && !utils.isStream(data)) {\n if (Buffer.isBuffer(data)) {\n // Nothing to do...\n } else if (utils.isArrayBuffer(data)) {\n data = Buffer.from(new Uint8Array(data));\n } else if (utils.isString(data)) {\n data = Buffer.from(data, 'utf-8');\n } else {\n return reject(new AxiosError(\n 'Data after transformation must be a string, an ArrayBuffer, a Buffer, or a Stream',\n AxiosError.ERR_BAD_REQUEST,\n config\n ));\n }\n\n // Add Content-Length header if data exists\n headers.setContentLength(data.length, false);\n\n if (config.maxBodyLength > -1 && data.length > config.maxBodyLength) {\n return reject(new AxiosError(\n 'Request body larger than maxBodyLength limit',\n AxiosError.ERR_BAD_REQUEST,\n config\n ));\n }\n }\n\n const contentLength = utils.toFiniteNumber(headers.getContentLength());\n\n if (utils.isArray(maxRate)) {\n maxUploadRate = maxRate[0];\n maxDownloadRate = maxRate[1];\n } else {\n maxUploadRate = maxDownloadRate = maxRate;\n }\n\n if (data && (onUploadProgress || maxUploadRate)) {\n if (!utils.isStream(data)) {\n data = stream.Readable.from(data, {objectMode: false});\n }\n\n data = stream.pipeline([data, new AxiosTransformStream({\n maxRate: utils.toFiniteNumber(maxUploadRate)\n })], utils.noop);\n\n onUploadProgress && data.on('progress', flushOnFinish(\n data,\n progressEventDecorator(\n contentLength,\n progressEventReducer(asyncDecorator(onUploadProgress), false, 3)\n )\n ));\n }\n\n // HTTP basic authentication\n let auth = undefined;\n if (config.auth) {\n const username = config.auth.username || '';\n const password = config.auth.password || '';\n auth = username + ':' + password;\n }\n\n if (!auth && parsed.username) {\n const urlUsername = parsed.username;\n const urlPassword = parsed.password;\n auth = urlUsername + ':' + urlPassword;\n }\n\n auth && headers.delete('authorization');\n\n let path;\n\n try {\n path = buildURL(\n parsed.pathname + parsed.search,\n config.params,\n config.paramsSerializer\n ).replace(/^\\?/, '');\n } catch (err) {\n const customErr = new Error(err.message);\n customErr.config = config;\n customErr.url = config.url;\n customErr.exists = true;\n return reject(customErr);\n }\n\n headers.set(\n 'Accept-Encoding',\n 'gzip, compress, deflate' + (isBrotliSupported ? ', br' : ''), false\n );\n\n const options = {\n path,\n method: method,\n headers: headers.toJSON(),\n agents: { http: config.httpAgent, https: config.httpsAgent },\n auth,\n protocol,\n family,\n beforeRedirect: dispatchBeforeRedirect,\n beforeRedirects: {}\n };\n\n // cacheable-lookup integration hotfix\n !utils.isUndefined(lookup) && (options.lookup = lookup);\n\n if (config.socketPath) {\n options.socketPath = config.socketPath;\n } else {\n options.hostname = parsed.hostname.startsWith(\"[\") ? parsed.hostname.slice(1, -1) : parsed.hostname;\n options.port = parsed.port;\n setProxy(options, config.proxy, protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path);\n }\n\n let transport;\n const isHttpsRequest = isHttps.test(options.protocol);\n options.agent = isHttpsRequest ? config.httpsAgent : config.httpAgent;\n if (config.transport) {\n transport = config.transport;\n } else if (config.maxRedirects === 0) {\n transport = isHttpsRequest ? https : http;\n } else {\n if (config.maxRedirects) {\n options.maxRedirects = config.maxRedirects;\n }\n if (config.beforeRedirect) {\n options.beforeRedirects.config = config.beforeRedirect;\n }\n transport = isHttpsRequest ? httpsFollow : httpFollow;\n }\n\n if (config.maxBodyLength > -1) {\n options.maxBodyLength = config.maxBodyLength;\n } else {\n // follow-redirects does not skip comparison, so it should always succeed for axios -1 unlimited\n options.maxBodyLength = Infinity;\n }\n\n if (config.insecureHTTPParser) {\n options.insecureHTTPParser = config.insecureHTTPParser;\n }\n\n // Create the request\n req = transport.request(options, function handleResponse(res) {\n if (req.destroyed) return;\n\n const streams = [res];\n\n const responseLength = +res.headers['content-length'];\n\n if (onDownloadProgress || maxDownloadRate) {\n const transformStream = new AxiosTransformStream({\n maxRate: utils.toFiniteNumber(maxDownloadRate)\n });\n\n onDownloadProgress && transformStream.on('progress', flushOnFinish(\n transformStream,\n progressEventDecorator(\n responseLength,\n progressEventReducer(asyncDecorator(onDownloadProgress), true, 3)\n )\n ));\n\n streams.push(transformStream);\n }\n\n // decompress the response body transparently if required\n let responseStream = res;\n\n // return the last request in case of redirects\n const lastRequest = res.req || req;\n\n // if decompress disabled we should not decompress\n if (config.decompress !== false && res.headers['content-encoding']) {\n // if no content, but headers still say that it is encoded,\n // remove the header not confuse downstream operations\n if (method === 'HEAD' || res.statusCode === 204) {\n delete res.headers['content-encoding'];\n }\n\n switch ((res.headers['content-encoding'] || '').toLowerCase()) {\n /*eslint default-case:0*/\n case 'gzip':\n case 'x-gzip':\n case 'compress':\n case 'x-compress':\n // add the unzipper to the body stream processing pipeline\n streams.push(zlib.createUnzip(zlibOptions));\n\n // remove the content-encoding in order to not confuse downstream operations\n delete res.headers['content-encoding'];\n break;\n case 'deflate':\n streams.push(new ZlibHeaderTransformStream());\n\n // add the unzipper to the body stream processing pipeline\n streams.push(zlib.createUnzip(zlibOptions));\n\n // remove the content-encoding in order to not confuse downstream operations\n delete res.headers['content-encoding'];\n break;\n case 'br':\n if (isBrotliSupported) {\n streams.push(zlib.createBrotliDecompress(brotliOptions));\n delete res.headers['content-encoding'];\n }\n }\n }\n\n responseStream = streams.length > 1 ? stream.pipeline(streams, utils.noop) : streams[0];\n\n const offListeners = stream.finished(responseStream, () => {\n offListeners();\n onFinished();\n });\n\n const response = {\n status: res.statusCode,\n statusText: res.statusMessage,\n headers: new AxiosHeaders(res.headers),\n config,\n request: lastRequest\n };\n\n if (responseType === 'stream') {\n response.data = responseStream;\n settle(resolve, reject, response);\n } else {\n const responseBuffer = [];\n let totalResponseBytes = 0;\n\n responseStream.on('data', function handleStreamData(chunk) {\n responseBuffer.push(chunk);\n totalResponseBytes += chunk.length;\n\n // make sure the content length is not over the maxContentLength if specified\n if (config.maxContentLength > -1 && totalResponseBytes > config.maxContentLength) {\n // stream.destroy() emit aborted event before calling reject() on Node.js v16\n rejected = true;\n responseStream.destroy();\n reject(new AxiosError('maxContentLength size of ' + config.maxContentLength + ' exceeded',\n AxiosError.ERR_BAD_RESPONSE, config, lastRequest));\n }\n });\n\n responseStream.on('aborted', function handlerStreamAborted() {\n if (rejected) {\n return;\n }\n\n const err = new AxiosError(\n 'stream has been aborted',\n AxiosError.ERR_BAD_RESPONSE,\n config,\n lastRequest\n );\n responseStream.destroy(err);\n reject(err);\n });\n\n responseStream.on('error', function handleStreamError(err) {\n if (req.destroyed) return;\n reject(AxiosError.from(err, null, config, lastRequest));\n });\n\n responseStream.on('end', function handleStreamEnd() {\n try {\n let responseData = responseBuffer.length === 1 ? responseBuffer[0] : Buffer.concat(responseBuffer);\n if (responseType !== 'arraybuffer') {\n responseData = responseData.toString(responseEncoding);\n if (!responseEncoding || responseEncoding === 'utf8') {\n responseData = utils.stripBOM(responseData);\n }\n }\n response.data = responseData;\n } catch (err) {\n return reject(AxiosError.from(err, null, config, response.request, response));\n }\n settle(resolve, reject, response);\n });\n }\n\n emitter.once('abort', err => {\n if (!responseStream.destroyed) {\n responseStream.emit('error', err);\n responseStream.destroy();\n }\n });\n });\n\n emitter.once('abort', err => {\n reject(err);\n req.destroy(err);\n });\n\n // Handle errors\n req.on('error', function handleRequestError(err) {\n // @todo remove\n // if (req.aborted && err.code !== AxiosError.ERR_FR_TOO_MANY_REDIRECTS) return;\n reject(AxiosError.from(err, null, config, req));\n });\n\n // set tcp keep alive to prevent drop connection by peer\n req.on('socket', function handleRequestSocket(socket) {\n // default interval of sending ack packet is 1 minute\n socket.setKeepAlive(true, 1000 * 60);\n });\n\n // Handle request timeout\n if (config.timeout) {\n // This is forcing a int timeout to avoid problems if the `req` interface doesn't handle other types.\n const timeout = parseInt(config.timeout, 10);\n\n if (Number.isNaN(timeout)) {\n reject(new AxiosError(\n 'error trying to parse `config.timeout` to int',\n AxiosError.ERR_BAD_OPTION_VALUE,\n config,\n req\n ));\n\n return;\n }\n\n // Sometime, the response will be very slow, and does not respond, the connect event will be block by event loop system.\n // And timer callback will be fired, and abort() will be invoked before connection, then get \"socket hang up\" and code ECONNRESET.\n // At this time, if we have a large number of request, nodejs will hang up some socket on background. and the number will up and up.\n // And then these socket which be hang up will devouring CPU little by little.\n // ClientRequest.setTimeout will be fired on the specify milliseconds, and can make sure that abort() will be fired after connect.\n req.setTimeout(timeout, function handleRequestTimeout() {\n if (isDone) return;\n let timeoutErrorMessage = config.timeout ? 'timeout of ' + config.timeout + 'ms exceeded' : 'timeout exceeded';\n const transitional = config.transitional || transitionalDefaults;\n if (config.timeoutErrorMessage) {\n timeoutErrorMessage = config.timeoutErrorMessage;\n }\n reject(new AxiosError(\n timeoutErrorMessage,\n transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,\n config,\n req\n ));\n abort();\n });\n }\n\n\n // Send the request\n if (utils.isStream(data)) {\n let ended = false;\n let errored = false;\n\n data.on('end', () => {\n ended = true;\n });\n\n data.once('error', err => {\n errored = true;\n req.destroy(err);\n });\n\n data.on('close', () => {\n if (!ended && !errored) {\n abort(new CanceledError('Request stream has been aborted', config, req));\n }\n });\n\n data.pipe(req);\n } else {\n req.end(data);\n }\n });\n}\n\nexport const __setProxy = setProxy;\n","import platform from '../platform/index.js';\n\nexport default platform.hasStandardBrowserEnv ? ((origin, isMSIE) => (url) => {\n url = new URL(url, platform.origin);\n\n return (\n origin.protocol === url.protocol &&\n origin.host === url.host &&\n (isMSIE || origin.port === url.port)\n );\n})(\n new URL(platform.origin),\n platform.navigator && /(msie|trident)/i.test(platform.navigator.userAgent)\n) : () => true;\n","import utils from './../utils.js';\nimport platform from '../platform/index.js';\n\nexport default platform.hasStandardBrowserEnv ?\n\n // Standard browser envs support document.cookie\n {\n write(name, value, expires, path, domain, secure) {\n const cookie = [name + '=' + encodeURIComponent(value)];\n\n utils.isNumber(expires) && cookie.push('expires=' + new Date(expires).toGMTString());\n\n utils.isString(path) && cookie.push('path=' + path);\n\n utils.isString(domain) && cookie.push('domain=' + domain);\n\n secure === true && cookie.push('secure');\n\n document.cookie = cookie.join('; ');\n },\n\n read(name) {\n const match = document.cookie.match(new RegExp('(^|;\\\\s*)(' + name + ')=([^;]*)'));\n return (match ? decodeURIComponent(match[3]) : null);\n },\n\n remove(name) {\n this.write(name, '', Date.now() - 86400000);\n }\n }\n\n :\n\n // Non-standard browser env (web workers, react-native) lack needed support.\n {\n write() {},\n read() {\n return null;\n },\n remove() {}\n };\n\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosHeaders from \"./AxiosHeaders.js\";\n\nconst headersToObject = (thing) => thing instanceof AxiosHeaders ? { ...thing } : thing;\n\n/**\n * Config-specific merge-function which creates a new config-object\n * by merging two configuration objects together.\n *\n * @param {Object} config1\n * @param {Object} config2\n *\n * @returns {Object} New object resulting from merging config2 to config1\n */\nexport default function mergeConfig(config1, config2) {\n // eslint-disable-next-line no-param-reassign\n config2 = config2 || {};\n const config = {};\n\n function getMergedValue(target, source, prop, caseless) {\n if (utils.isPlainObject(target) && utils.isPlainObject(source)) {\n return utils.merge.call({caseless}, target, source);\n } else if (utils.isPlainObject(source)) {\n return utils.merge({}, source);\n } else if (utils.isArray(source)) {\n return source.slice();\n }\n return source;\n }\n\n // eslint-disable-next-line consistent-return\n function mergeDeepProperties(a, b, prop , caseless) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(a, b, prop , caseless);\n } else if (!utils.isUndefined(a)) {\n return getMergedValue(undefined, a, prop , caseless);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function valueFromConfig2(a, b) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(undefined, b);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function defaultToConfig2(a, b) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(undefined, b);\n } else if (!utils.isUndefined(a)) {\n return getMergedValue(undefined, a);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function mergeDirectKeys(a, b, prop) {\n if (prop in config2) {\n return getMergedValue(a, b);\n } else if (prop in config1) {\n return getMergedValue(undefined, a);\n }\n }\n\n const mergeMap = {\n url: valueFromConfig2,\n method: valueFromConfig2,\n data: valueFromConfig2,\n baseURL: defaultToConfig2,\n transformRequest: defaultToConfig2,\n transformResponse: defaultToConfig2,\n paramsSerializer: defaultToConfig2,\n timeout: defaultToConfig2,\n timeoutMessage: defaultToConfig2,\n withCredentials: defaultToConfig2,\n withXSRFToken: defaultToConfig2,\n adapter: defaultToConfig2,\n responseType: defaultToConfig2,\n xsrfCookieName: defaultToConfig2,\n xsrfHeaderName: defaultToConfig2,\n onUploadProgress: defaultToConfig2,\n onDownloadProgress: defaultToConfig2,\n decompress: defaultToConfig2,\n maxContentLength: defaultToConfig2,\n maxBodyLength: defaultToConfig2,\n beforeRedirect: defaultToConfig2,\n transport: defaultToConfig2,\n httpAgent: defaultToConfig2,\n httpsAgent: defaultToConfig2,\n cancelToken: defaultToConfig2,\n socketPath: defaultToConfig2,\n responseEncoding: defaultToConfig2,\n validateStatus: mergeDirectKeys,\n headers: (a, b , prop) => mergeDeepProperties(headersToObject(a), headersToObject(b),prop, true)\n };\n\n utils.forEach(Object.keys(Object.assign({}, config1, config2)), function computeConfigValue(prop) {\n const merge = mergeMap[prop] || mergeDeepProperties;\n const configValue = merge(config1[prop], config2[prop], prop);\n (utils.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue);\n });\n\n return config;\n}\n","import platform from \"../platform/index.js\";\nimport utils from \"../utils.js\";\nimport isURLSameOrigin from \"./isURLSameOrigin.js\";\nimport cookies from \"./cookies.js\";\nimport buildFullPath from \"../core/buildFullPath.js\";\nimport mergeConfig from \"../core/mergeConfig.js\";\nimport AxiosHeaders from \"../core/AxiosHeaders.js\";\nimport buildURL from \"./buildURL.js\";\n\nexport default (config) => {\n const newConfig = mergeConfig({}, config);\n\n let {data, withXSRFToken, xsrfHeaderName, xsrfCookieName, headers, auth} = newConfig;\n\n newConfig.headers = headers = AxiosHeaders.from(headers);\n\n newConfig.url = buildURL(buildFullPath(newConfig.baseURL, newConfig.url, newConfig.allowAbsoluteUrls), config.params, config.paramsSerializer);\n\n // HTTP basic authentication\n if (auth) {\n headers.set('Authorization', 'Basic ' +\n btoa((auth.username || '') + ':' + (auth.password ? unescape(encodeURIComponent(auth.password)) : ''))\n );\n }\n\n let contentType;\n\n if (utils.isFormData(data)) {\n if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv) {\n headers.setContentType(undefined); // Let the browser set it\n } else if ((contentType = headers.getContentType()) !== false) {\n // fix semicolon duplication issue for ReactNative FormData implementation\n const [type, ...tokens] = contentType ? contentType.split(';').map(token => token.trim()).filter(Boolean) : [];\n headers.setContentType([type || 'multipart/form-data', ...tokens].join('; '));\n }\n }\n\n // Add xsrf header\n // This is only done if running in a standard browser environment.\n // Specifically not if we're in a web worker, or react-native.\n\n if (platform.hasStandardBrowserEnv) {\n withXSRFToken && utils.isFunction(withXSRFToken) && (withXSRFToken = withXSRFToken(newConfig));\n\n if (withXSRFToken || (withXSRFToken !== false && isURLSameOrigin(newConfig.url))) {\n // Add xsrf header\n const xsrfValue = xsrfHeaderName && xsrfCookieName && cookies.read(xsrfCookieName);\n\n if (xsrfValue) {\n headers.set(xsrfHeaderName, xsrfValue);\n }\n }\n }\n\n return newConfig;\n}\n\n","import utils from './../utils.js';\nimport settle from './../core/settle.js';\nimport transitionalDefaults from '../defaults/transitional.js';\nimport AxiosError from '../core/AxiosError.js';\nimport CanceledError from '../cancel/CanceledError.js';\nimport parseProtocol from '../helpers/parseProtocol.js';\nimport platform from '../platform/index.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\nimport {progressEventReducer} from '../helpers/progressEventReducer.js';\nimport resolveConfig from \"../helpers/resolveConfig.js\";\n\nconst isXHRAdapterSupported = typeof XMLHttpRequest !== 'undefined';\n\nexport default isXHRAdapterSupported && function (config) {\n return new Promise(function dispatchXhrRequest(resolve, reject) {\n const _config = resolveConfig(config);\n let requestData = _config.data;\n const requestHeaders = AxiosHeaders.from(_config.headers).normalize();\n let {responseType, onUploadProgress, onDownloadProgress} = _config;\n let onCanceled;\n let uploadThrottled, downloadThrottled;\n let flushUpload, flushDownload;\n\n function done() {\n flushUpload && flushUpload(); // flush events\n flushDownload && flushDownload(); // flush events\n\n _config.cancelToken && _config.cancelToken.unsubscribe(onCanceled);\n\n _config.signal && _config.signal.removeEventListener('abort', onCanceled);\n }\n\n let request = new XMLHttpRequest();\n\n request.open(_config.method.toUpperCase(), _config.url, true);\n\n // Set the request timeout in MS\n request.timeout = _config.timeout;\n\n function onloadend() {\n if (!request) {\n return;\n }\n // Prepare the response\n const responseHeaders = AxiosHeaders.from(\n 'getAllResponseHeaders' in request && request.getAllResponseHeaders()\n );\n const responseData = !responseType || responseType === 'text' || responseType === 'json' ?\n request.responseText : request.response;\n const response = {\n data: responseData,\n status: request.status,\n statusText: request.statusText,\n headers: responseHeaders,\n config,\n request\n };\n\n settle(function _resolve(value) {\n resolve(value);\n done();\n }, function _reject(err) {\n reject(err);\n done();\n }, response);\n\n // Clean up request\n request = null;\n }\n\n if ('onloadend' in request) {\n // Use onloadend if available\n request.onloadend = onloadend;\n } else {\n // Listen for ready state to emulate onloadend\n request.onreadystatechange = function handleLoad() {\n if (!request || request.readyState !== 4) {\n return;\n }\n\n // The request errored out and we didn't get a response, this will be\n // handled by onerror instead\n // With one exception: request that using file: protocol, most browsers\n // will return status as 0 even though it's a successful request\n if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {\n return;\n }\n // readystate handler is calling before onerror or ontimeout handlers,\n // so we should call onloadend on the next 'tick'\n setTimeout(onloadend);\n };\n }\n\n // Handle browser request cancellation (as opposed to a manual cancellation)\n request.onabort = function handleAbort() {\n if (!request) {\n return;\n }\n\n reject(new AxiosError('Request aborted', AxiosError.ECONNABORTED, config, request));\n\n // Clean up request\n request = null;\n };\n\n // Handle low level network errors\n request.onerror = function handleError() {\n // Real errors are hidden from us by the browser\n // onerror should only fire if it's a network error\n reject(new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request));\n\n // Clean up request\n request = null;\n };\n\n // Handle timeout\n request.ontimeout = function handleTimeout() {\n let timeoutErrorMessage = _config.timeout ? 'timeout of ' + _config.timeout + 'ms exceeded' : 'timeout exceeded';\n const transitional = _config.transitional || transitionalDefaults;\n if (_config.timeoutErrorMessage) {\n timeoutErrorMessage = _config.timeoutErrorMessage;\n }\n reject(new AxiosError(\n timeoutErrorMessage,\n transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,\n config,\n request));\n\n // Clean up request\n request = null;\n };\n\n // Remove Content-Type if data is undefined\n requestData === undefined && requestHeaders.setContentType(null);\n\n // Add headers to the request\n if ('setRequestHeader' in request) {\n utils.forEach(requestHeaders.toJSON(), function setRequestHeader(val, key) {\n request.setRequestHeader(key, val);\n });\n }\n\n // Add withCredentials to request if needed\n if (!utils.isUndefined(_config.withCredentials)) {\n request.withCredentials = !!_config.withCredentials;\n }\n\n // Add responseType to request if needed\n if (responseType && responseType !== 'json') {\n request.responseType = _config.responseType;\n }\n\n // Handle progress if needed\n if (onDownloadProgress) {\n ([downloadThrottled, flushDownload] = progressEventReducer(onDownloadProgress, true));\n request.addEventListener('progress', downloadThrottled);\n }\n\n // Not all browsers support upload events\n if (onUploadProgress && request.upload) {\n ([uploadThrottled, flushUpload] = progressEventReducer(onUploadProgress));\n\n request.upload.addEventListener('progress', uploadThrottled);\n\n request.upload.addEventListener('loadend', flushUpload);\n }\n\n if (_config.cancelToken || _config.signal) {\n // Handle cancellation\n // eslint-disable-next-line func-names\n onCanceled = cancel => {\n if (!request) {\n return;\n }\n reject(!cancel || cancel.type ? new CanceledError(null, config, request) : cancel);\n request.abort();\n request = null;\n };\n\n _config.cancelToken && _config.cancelToken.subscribe(onCanceled);\n if (_config.signal) {\n _config.signal.aborted ? onCanceled() : _config.signal.addEventListener('abort', onCanceled);\n }\n }\n\n const protocol = parseProtocol(_config.url);\n\n if (protocol && platform.protocols.indexOf(protocol) === -1) {\n reject(new AxiosError('Unsupported protocol ' + protocol + ':', AxiosError.ERR_BAD_REQUEST, config));\n return;\n }\n\n\n // Send the request\n request.send(requestData || null);\n });\n}\n","import CanceledError from \"../cancel/CanceledError.js\";\nimport AxiosError from \"../core/AxiosError.js\";\nimport utils from '../utils.js';\n\nconst composeSignals = (signals, timeout) => {\n const {length} = (signals = signals ? signals.filter(Boolean) : []);\n\n if (timeout || length) {\n let controller = new AbortController();\n\n let aborted;\n\n const onabort = function (reason) {\n if (!aborted) {\n aborted = true;\n unsubscribe();\n const err = reason instanceof Error ? reason : this.reason;\n controller.abort(err instanceof AxiosError ? err : new CanceledError(err instanceof Error ? err.message : err));\n }\n }\n\n let timer = timeout && setTimeout(() => {\n timer = null;\n onabort(new AxiosError(`timeout ${timeout} of ms exceeded`, AxiosError.ETIMEDOUT))\n }, timeout)\n\n const unsubscribe = () => {\n if (signals) {\n timer && clearTimeout(timer);\n timer = null;\n signals.forEach(signal => {\n signal.unsubscribe ? signal.unsubscribe(onabort) : signal.removeEventListener('abort', onabort);\n });\n signals = null;\n }\n }\n\n signals.forEach((signal) => signal.addEventListener('abort', onabort));\n\n const {signal} = controller;\n\n signal.unsubscribe = () => utils.asap(unsubscribe);\n\n return signal;\n }\n}\n\nexport default composeSignals;\n","\nexport const streamChunk = function* (chunk, chunkSize) {\n let len = chunk.byteLength;\n\n if (!chunkSize || len < chunkSize) {\n yield chunk;\n return;\n }\n\n let pos = 0;\n let end;\n\n while (pos < len) {\n end = pos + chunkSize;\n yield chunk.slice(pos, end);\n pos = end;\n }\n}\n\nexport const readBytes = async function* (iterable, chunkSize) {\n for await (const chunk of readStream(iterable)) {\n yield* streamChunk(chunk, chunkSize);\n }\n}\n\nconst readStream = async function* (stream) {\n if (stream[Symbol.asyncIterator]) {\n yield* stream;\n return;\n }\n\n const reader = stream.getReader();\n try {\n for (;;) {\n const {done, value} = await reader.read();\n if (done) {\n break;\n }\n yield value;\n }\n } finally {\n await reader.cancel();\n }\n}\n\nexport const trackStream = (stream, chunkSize, onProgress, onFinish) => {\n const iterator = readBytes(stream, chunkSize);\n\n let bytes = 0;\n let done;\n let _onFinish = (e) => {\n if (!done) {\n done = true;\n onFinish && onFinish(e);\n }\n }\n\n return new ReadableStream({\n async pull(controller) {\n try {\n const {done, value} = await iterator.next();\n\n if (done) {\n _onFinish();\n controller.close();\n return;\n }\n\n let len = value.byteLength;\n if (onProgress) {\n let loadedBytes = bytes += len;\n onProgress(loadedBytes);\n }\n controller.enqueue(new Uint8Array(value));\n } catch (err) {\n _onFinish(err);\n throw err;\n }\n },\n cancel(reason) {\n _onFinish(reason);\n return iterator.return();\n }\n }, {\n highWaterMark: 2\n })\n}\n","import platform from \"../platform/index.js\";\nimport utils from \"../utils.js\";\nimport AxiosError from \"../core/AxiosError.js\";\nimport composeSignals from \"../helpers/composeSignals.js\";\nimport {trackStream} from \"../helpers/trackStream.js\";\nimport AxiosHeaders from \"../core/AxiosHeaders.js\";\nimport {progressEventReducer, progressEventDecorator, asyncDecorator} from \"../helpers/progressEventReducer.js\";\nimport resolveConfig from \"../helpers/resolveConfig.js\";\nimport settle from \"../core/settle.js\";\n\nconst isFetchSupported = typeof fetch === 'function' && typeof Request === 'function' && typeof Response === 'function';\nconst isReadableStreamSupported = isFetchSupported && typeof ReadableStream === 'function';\n\n// used only inside the fetch adapter\nconst encodeText = isFetchSupported && (typeof TextEncoder === 'function' ?\n ((encoder) => (str) => encoder.encode(str))(new TextEncoder()) :\n async (str) => new Uint8Array(await new Response(str).arrayBuffer())\n);\n\nconst test = (fn, ...args) => {\n try {\n return !!fn(...args);\n } catch (e) {\n return false\n }\n}\n\nconst supportsRequestStream = isReadableStreamSupported && test(() => {\n let duplexAccessed = false;\n\n const hasContentType = new Request(platform.origin, {\n body: new ReadableStream(),\n method: 'POST',\n get duplex() {\n duplexAccessed = true;\n return 'half';\n },\n }).headers.has('Content-Type');\n\n return duplexAccessed && !hasContentType;\n});\n\nconst DEFAULT_CHUNK_SIZE = 64 * 1024;\n\nconst supportsResponseStream = isReadableStreamSupported &&\n test(() => utils.isReadableStream(new Response('').body));\n\n\nconst resolvers = {\n stream: supportsResponseStream && ((res) => res.body)\n};\n\nisFetchSupported && (((res) => {\n ['text', 'arrayBuffer', 'blob', 'formData', 'stream'].forEach(type => {\n !resolvers[type] && (resolvers[type] = utils.isFunction(res[type]) ? (res) => res[type]() :\n (_, config) => {\n throw new AxiosError(`Response type '${type}' is not supported`, AxiosError.ERR_NOT_SUPPORT, config);\n })\n });\n})(new Response));\n\nconst getBodyLength = async (body) => {\n if (body == null) {\n return 0;\n }\n\n if(utils.isBlob(body)) {\n return body.size;\n }\n\n if(utils.isSpecCompliantForm(body)) {\n const _request = new Request(platform.origin, {\n method: 'POST',\n body,\n });\n return (await _request.arrayBuffer()).byteLength;\n }\n\n if(utils.isArrayBufferView(body) || utils.isArrayBuffer(body)) {\n return body.byteLength;\n }\n\n if(utils.isURLSearchParams(body)) {\n body = body + '';\n }\n\n if(utils.isString(body)) {\n return (await encodeText(body)).byteLength;\n }\n}\n\nconst resolveBodyLength = async (headers, body) => {\n const length = utils.toFiniteNumber(headers.getContentLength());\n\n return length == null ? getBodyLength(body) : length;\n}\n\nexport default isFetchSupported && (async (config) => {\n let {\n url,\n method,\n data,\n signal,\n cancelToken,\n timeout,\n onDownloadProgress,\n onUploadProgress,\n responseType,\n headers,\n withCredentials = 'same-origin',\n fetchOptions\n } = resolveConfig(config);\n\n responseType = responseType ? (responseType + '').toLowerCase() : 'text';\n\n let composedSignal = composeSignals([signal, cancelToken && cancelToken.toAbortSignal()], timeout);\n\n let request;\n\n const unsubscribe = composedSignal && composedSignal.unsubscribe && (() => {\n composedSignal.unsubscribe();\n });\n\n let requestContentLength;\n\n try {\n if (\n onUploadProgress && supportsRequestStream && method !== 'get' && method !== 'head' &&\n (requestContentLength = await resolveBodyLength(headers, data)) !== 0\n ) {\n let _request = new Request(url, {\n method: 'POST',\n body: data,\n duplex: \"half\"\n });\n\n let contentTypeHeader;\n\n if (utils.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) {\n headers.setContentType(contentTypeHeader)\n }\n\n if (_request.body) {\n const [onProgress, flush] = progressEventDecorator(\n requestContentLength,\n progressEventReducer(asyncDecorator(onUploadProgress))\n );\n\n data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush);\n }\n }\n\n if (!utils.isString(withCredentials)) {\n withCredentials = withCredentials ? 'include' : 'omit';\n }\n\n // Cloudflare Workers throws when credentials are defined\n // see https://github.com/cloudflare/workerd/issues/902\n const isCredentialsSupported = \"credentials\" in Request.prototype;\n request = new Request(url, {\n ...fetchOptions,\n signal: composedSignal,\n method: method.toUpperCase(),\n headers: headers.normalize().toJSON(),\n body: data,\n duplex: \"half\",\n credentials: isCredentialsSupported ? withCredentials : undefined\n });\n\n let response = await fetch(request, fetchOptions);\n\n const isStreamResponse = supportsResponseStream && (responseType === 'stream' || responseType === 'response');\n\n if (supportsResponseStream && (onDownloadProgress || (isStreamResponse && unsubscribe))) {\n const options = {};\n\n ['status', 'statusText', 'headers'].forEach(prop => {\n options[prop] = response[prop];\n });\n\n const responseContentLength = utils.toFiniteNumber(response.headers.get('content-length'));\n\n const [onProgress, flush] = onDownloadProgress && progressEventDecorator(\n responseContentLength,\n progressEventReducer(asyncDecorator(onDownloadProgress), true)\n ) || [];\n\n response = new Response(\n trackStream(response.body, DEFAULT_CHUNK_SIZE, onProgress, () => {\n flush && flush();\n unsubscribe && unsubscribe();\n }),\n options\n );\n }\n\n responseType = responseType || 'text';\n\n let responseData = await resolvers[utils.findKey(resolvers, responseType) || 'text'](response, config);\n\n !isStreamResponse && unsubscribe && unsubscribe();\n\n return await new Promise((resolve, reject) => {\n settle(resolve, reject, {\n data: responseData,\n headers: AxiosHeaders.from(response.headers),\n status: response.status,\n statusText: response.statusText,\n config,\n request\n })\n })\n } catch (err) {\n unsubscribe && unsubscribe();\n\n if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) {\n throw Object.assign(\n new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request),\n {\n cause: err.cause || err\n }\n )\n }\n\n throw AxiosError.from(err, err && err.code, config, request);\n }\n});\n\n\n","import utils from '../utils.js';\nimport httpAdapter from './http.js';\nimport xhrAdapter from './xhr.js';\nimport fetchAdapter from './fetch.js';\nimport AxiosError from \"../core/AxiosError.js\";\n\nconst knownAdapters = {\n http: httpAdapter,\n xhr: xhrAdapter,\n fetch: fetchAdapter\n}\n\nutils.forEach(knownAdapters, (fn, value) => {\n if (fn) {\n try {\n Object.defineProperty(fn, 'name', {value});\n } catch (e) {\n // eslint-disable-next-line no-empty\n }\n Object.defineProperty(fn, 'adapterName', {value});\n }\n});\n\nconst renderReason = (reason) => `- ${reason}`;\n\nconst isResolvedHandle = (adapter) => utils.isFunction(adapter) || adapter === null || adapter === false;\n\nexport default {\n getAdapter: (adapters) => {\n adapters = utils.isArray(adapters) ? adapters : [adapters];\n\n const {length} = adapters;\n let nameOrAdapter;\n let adapter;\n\n const rejectedReasons = {};\n\n for (let i = 0; i < length; i++) {\n nameOrAdapter = adapters[i];\n let id;\n\n adapter = nameOrAdapter;\n\n if (!isResolvedHandle(nameOrAdapter)) {\n adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];\n\n if (adapter === undefined) {\n throw new AxiosError(`Unknown adapter '${id}'`);\n }\n }\n\n if (adapter) {\n break;\n }\n\n rejectedReasons[id || '#' + i] = adapter;\n }\n\n if (!adapter) {\n\n const reasons = Object.entries(rejectedReasons)\n .map(([id, state]) => `adapter ${id} ` +\n (state === false ? 'is not supported by the environment' : 'is not available in the build')\n );\n\n let s = length ?\n (reasons.length > 1 ? 'since :\\n' + reasons.map(renderReason).join('\\n') : ' ' + renderReason(reasons[0])) :\n 'as no adapter specified';\n\n throw new AxiosError(\n `There is no suitable adapter to dispatch the request ` + s,\n 'ERR_NOT_SUPPORT'\n );\n }\n\n return adapter;\n },\n adapters: knownAdapters\n}\n","'use strict';\n\nimport transformData from './transformData.js';\nimport isCancel from '../cancel/isCancel.js';\nimport defaults from '../defaults/index.js';\nimport CanceledError from '../cancel/CanceledError.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\nimport adapters from \"../adapters/adapters.js\";\n\n/**\n * Throws a `CanceledError` if cancellation has been requested.\n *\n * @param {Object} config The config that is to be used for the request\n *\n * @returns {void}\n */\nfunction throwIfCancellationRequested(config) {\n if (config.cancelToken) {\n config.cancelToken.throwIfRequested();\n }\n\n if (config.signal && config.signal.aborted) {\n throw new CanceledError(null, config);\n }\n}\n\n/**\n * Dispatch a request to the server using the configured adapter.\n *\n * @param {object} config The config that is to be used for the request\n *\n * @returns {Promise} The Promise to be fulfilled\n */\nexport default function dispatchRequest(config) {\n throwIfCancellationRequested(config);\n\n config.headers = AxiosHeaders.from(config.headers);\n\n // Transform request data\n config.data = transformData.call(\n config,\n config.transformRequest\n );\n\n if (['post', 'put', 'patch'].indexOf(config.method) !== -1) {\n config.headers.setContentType('application/x-www-form-urlencoded', false);\n }\n\n const adapter = adapters.getAdapter(config.adapter || defaults.adapter);\n\n return adapter(config).then(function onAdapterResolution(response) {\n throwIfCancellationRequested(config);\n\n // Transform response data\n response.data = transformData.call(\n config,\n config.transformResponse,\n response\n );\n\n response.headers = AxiosHeaders.from(response.headers);\n\n return response;\n }, function onAdapterRejection(reason) {\n if (!isCancel(reason)) {\n throwIfCancellationRequested(config);\n\n // Transform response data\n if (reason && reason.response) {\n reason.response.data = transformData.call(\n config,\n config.transformResponse,\n reason.response\n );\n reason.response.headers = AxiosHeaders.from(reason.response.headers);\n }\n }\n\n return Promise.reject(reason);\n });\n}\n","'use strict';\n\nimport {VERSION} from '../env/data.js';\nimport AxiosError from '../core/AxiosError.js';\n\nconst validators = {};\n\n// eslint-disable-next-line func-names\n['object', 'boolean', 'number', 'function', 'string', 'symbol'].forEach((type, i) => {\n validators[type] = function validator(thing) {\n return typeof thing === type || 'a' + (i < 1 ? 'n ' : ' ') + type;\n };\n});\n\nconst deprecatedWarnings = {};\n\n/**\n * Transitional option validator\n *\n * @param {function|boolean?} validator - set to false if the transitional option has been removed\n * @param {string?} version - deprecated version / removed since version\n * @param {string?} message - some message with additional info\n *\n * @returns {function}\n */\nvalidators.transitional = function transitional(validator, version, message) {\n function formatMessage(opt, desc) {\n return '[Axios v' + VERSION + '] Transitional option \\'' + opt + '\\'' + desc + (message ? '. ' + message : '');\n }\n\n // eslint-disable-next-line func-names\n return (value, opt, opts) => {\n if (validator === false) {\n throw new AxiosError(\n formatMessage(opt, ' has been removed' + (version ? ' in ' + version : '')),\n AxiosError.ERR_DEPRECATED\n );\n }\n\n if (version && !deprecatedWarnings[opt]) {\n deprecatedWarnings[opt] = true;\n // eslint-disable-next-line no-console\n console.warn(\n formatMessage(\n opt,\n ' has been deprecated since v' + version + ' and will be removed in the near future'\n )\n );\n }\n\n return validator ? validator(value, opt, opts) : true;\n };\n};\n\nvalidators.spelling = function spelling(correctSpelling) {\n return (value, opt) => {\n // eslint-disable-next-line no-console\n console.warn(`${opt} is likely a misspelling of ${correctSpelling}`);\n return true;\n }\n};\n\n/**\n * Assert object's properties type\n *\n * @param {object} options\n * @param {object} schema\n * @param {boolean?} allowUnknown\n *\n * @returns {object}\n */\n\nfunction assertOptions(options, schema, allowUnknown) {\n if (typeof options !== 'object') {\n throw new AxiosError('options must be an object', AxiosError.ERR_BAD_OPTION_VALUE);\n }\n const keys = Object.keys(options);\n let i = keys.length;\n while (i-- > 0) {\n const opt = keys[i];\n const validator = schema[opt];\n if (validator) {\n const value = options[opt];\n const result = value === undefined || validator(value, opt, options);\n if (result !== true) {\n throw new AxiosError('option ' + opt + ' must be ' + result, AxiosError.ERR_BAD_OPTION_VALUE);\n }\n continue;\n }\n if (allowUnknown !== true) {\n throw new AxiosError('Unknown option ' + opt, AxiosError.ERR_BAD_OPTION);\n }\n }\n}\n\nexport default {\n assertOptions,\n validators\n};\n","'use strict';\n\nimport utils from './../utils.js';\nimport buildURL from '../helpers/buildURL.js';\nimport InterceptorManager from './InterceptorManager.js';\nimport dispatchRequest from './dispatchRequest.js';\nimport mergeConfig from './mergeConfig.js';\nimport buildFullPath from './buildFullPath.js';\nimport validator from '../helpers/validator.js';\nimport AxiosHeaders from './AxiosHeaders.js';\n\nconst validators = validator.validators;\n\n/**\n * Create a new instance of Axios\n *\n * @param {Object} instanceConfig The default config for the instance\n *\n * @return {Axios} A new instance of Axios\n */\nclass Axios {\n constructor(instanceConfig) {\n this.defaults = instanceConfig || {};\n this.interceptors = {\n request: new InterceptorManager(),\n response: new InterceptorManager()\n };\n }\n\n /**\n * Dispatch a request\n *\n * @param {String|Object} configOrUrl The config specific for this request (merged with this.defaults)\n * @param {?Object} config\n *\n * @returns {Promise} The Promise to be fulfilled\n */\n async request(configOrUrl, config) {\n try {\n return await this._request(configOrUrl, config);\n } catch (err) {\n if (err instanceof Error) {\n let dummy = {};\n\n Error.captureStackTrace ? Error.captureStackTrace(dummy) : (dummy = new Error());\n\n // slice off the Error: ... line\n const stack = dummy.stack ? dummy.stack.replace(/^.+\\n/, '') : '';\n try {\n if (!err.stack) {\n err.stack = stack;\n // match without the 2 top stack lines\n } else if (stack && !String(err.stack).endsWith(stack.replace(/^.+\\n.+\\n/, ''))) {\n err.stack += '\\n' + stack\n }\n } catch (e) {\n // ignore the case where \"stack\" is an un-writable property\n }\n }\n\n throw err;\n }\n }\n\n _request(configOrUrl, config) {\n /*eslint no-param-reassign:0*/\n // Allow for axios('example/url'[, config]) a la fetch API\n if (typeof configOrUrl === 'string') {\n config = config || {};\n config.url = configOrUrl;\n } else {\n config = configOrUrl || {};\n }\n\n config = mergeConfig(this.defaults, config);\n\n const {transitional, paramsSerializer, headers} = config;\n\n if (transitional !== undefined) {\n validator.assertOptions(transitional, {\n silentJSONParsing: validators.transitional(validators.boolean),\n forcedJSONParsing: validators.transitional(validators.boolean),\n clarifyTimeoutError: validators.transitional(validators.boolean)\n }, false);\n }\n\n if (paramsSerializer != null) {\n if (utils.isFunction(paramsSerializer)) {\n config.paramsSerializer = {\n serialize: paramsSerializer\n }\n } else {\n validator.assertOptions(paramsSerializer, {\n encode: validators.function,\n serialize: validators.function\n }, true);\n }\n }\n\n // Set config.allowAbsoluteUrls\n if (config.allowAbsoluteUrls !== undefined) {\n // do nothing\n } else if (this.defaults.allowAbsoluteUrls !== undefined) {\n config.allowAbsoluteUrls = this.defaults.allowAbsoluteUrls;\n } else {\n config.allowAbsoluteUrls = true;\n }\n\n validator.assertOptions(config, {\n baseUrl: validators.spelling('baseURL'),\n withXsrfToken: validators.spelling('withXSRFToken')\n }, true);\n\n // Set config.method\n config.method = (config.method || this.defaults.method || 'get').toLowerCase();\n\n // Flatten headers\n let contextHeaders = headers && utils.merge(\n headers.common,\n headers[config.method]\n );\n\n headers && utils.forEach(\n ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],\n (method) => {\n delete headers[method];\n }\n );\n\n config.headers = AxiosHeaders.concat(contextHeaders, headers);\n\n // filter out skipped interceptors\n const requestInterceptorChain = [];\n let synchronousRequestInterceptors = true;\n this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {\n if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) {\n return;\n }\n\n synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous;\n\n requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected);\n });\n\n const responseInterceptorChain = [];\n this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {\n responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected);\n });\n\n let promise;\n let i = 0;\n let len;\n\n if (!synchronousRequestInterceptors) {\n const chain = [dispatchRequest.bind(this), undefined];\n chain.unshift.apply(chain, requestInterceptorChain);\n chain.push.apply(chain, responseInterceptorChain);\n len = chain.length;\n\n promise = Promise.resolve(config);\n\n while (i < len) {\n promise = promise.then(chain[i++], chain[i++]);\n }\n\n return promise;\n }\n\n len = requestInterceptorChain.length;\n\n let newConfig = config;\n\n i = 0;\n\n while (i < len) {\n const onFulfilled = requestInterceptorChain[i++];\n const onRejected = requestInterceptorChain[i++];\n try {\n newConfig = onFulfilled(newConfig);\n } catch (error) {\n onRejected.call(this, error);\n break;\n }\n }\n\n try {\n promise = dispatchRequest.call(this, newConfig);\n } catch (error) {\n return Promise.reject(error);\n }\n\n i = 0;\n len = responseInterceptorChain.length;\n\n while (i < len) {\n promise = promise.then(responseInterceptorChain[i++], responseInterceptorChain[i++]);\n }\n\n return promise;\n }\n\n getUri(config) {\n config = mergeConfig(this.defaults, config);\n const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);\n return buildURL(fullPath, config.params, config.paramsSerializer);\n }\n}\n\n// Provide aliases for supported request methods\nutils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {\n /*eslint func-names:0*/\n Axios.prototype[method] = function(url, config) {\n return this.request(mergeConfig(config || {}, {\n method,\n url,\n data: (config || {}).data\n }));\n };\n});\n\nutils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {\n /*eslint func-names:0*/\n\n function generateHTTPMethod(isForm) {\n return function httpMethod(url, data, config) {\n return this.request(mergeConfig(config || {}, {\n method,\n headers: isForm ? {\n 'Content-Type': 'multipart/form-data'\n } : {},\n url,\n data\n }));\n };\n }\n\n Axios.prototype[method] = generateHTTPMethod();\n\n Axios.prototype[method + 'Form'] = generateHTTPMethod(true);\n});\n\nexport default Axios;\n","'use strict';\n\nimport CanceledError from './CanceledError.js';\n\n/**\n * A `CancelToken` is an object that can be used to request cancellation of an operation.\n *\n * @param {Function} executor The executor function.\n *\n * @returns {CancelToken}\n */\nclass CancelToken {\n constructor(executor) {\n if (typeof executor !== 'function') {\n throw new TypeError('executor must be a function.');\n }\n\n let resolvePromise;\n\n this.promise = new Promise(function promiseExecutor(resolve) {\n resolvePromise = resolve;\n });\n\n const token = this;\n\n // eslint-disable-next-line func-names\n this.promise.then(cancel => {\n if (!token._listeners) return;\n\n let i = token._listeners.length;\n\n while (i-- > 0) {\n token._listeners[i](cancel);\n }\n token._listeners = null;\n });\n\n // eslint-disable-next-line func-names\n this.promise.then = onfulfilled => {\n let _resolve;\n // eslint-disable-next-line func-names\n const promise = new Promise(resolve => {\n token.subscribe(resolve);\n _resolve = resolve;\n }).then(onfulfilled);\n\n promise.cancel = function reject() {\n token.unsubscribe(_resolve);\n };\n\n return promise;\n };\n\n executor(function cancel(message, config, request) {\n if (token.reason) {\n // Cancellation has already been requested\n return;\n }\n\n token.reason = new CanceledError(message, config, request);\n resolvePromise(token.reason);\n });\n }\n\n /**\n * Throws a `CanceledError` if cancellation has been requested.\n */\n throwIfRequested() {\n if (this.reason) {\n throw this.reason;\n }\n }\n\n /**\n * Subscribe to the cancel signal\n */\n\n subscribe(listener) {\n if (this.reason) {\n listener(this.reason);\n return;\n }\n\n if (this._listeners) {\n this._listeners.push(listener);\n } else {\n this._listeners = [listener];\n }\n }\n\n /**\n * Unsubscribe from the cancel signal\n */\n\n unsubscribe(listener) {\n if (!this._listeners) {\n return;\n }\n const index = this._listeners.indexOf(listener);\n if (index !== -1) {\n this._listeners.splice(index, 1);\n }\n }\n\n toAbortSignal() {\n const controller = new AbortController();\n\n const abort = (err) => {\n controller.abort(err);\n };\n\n this.subscribe(abort);\n\n controller.signal.unsubscribe = () => this.unsubscribe(abort);\n\n return controller.signal;\n }\n\n /**\n * Returns an object that contains a new `CancelToken` and a function that, when called,\n * cancels the `CancelToken`.\n */\n static source() {\n let cancel;\n const token = new CancelToken(function executor(c) {\n cancel = c;\n });\n return {\n token,\n cancel\n };\n }\n}\n\nexport default CancelToken;\n","'use strict';\n\n/**\n * Syntactic sugar for invoking a function and expanding an array for arguments.\n *\n * Common use case would be to use `Function.prototype.apply`.\n *\n * ```js\n * function f(x, y, z) {}\n * var args = [1, 2, 3];\n * f.apply(null, args);\n * ```\n *\n * With `spread` this example can be re-written.\n *\n * ```js\n * spread(function(x, y, z) {})([1, 2, 3]);\n * ```\n *\n * @param {Function} callback\n *\n * @returns {Function}\n */\nexport default function spread(callback) {\n return function wrap(arr) {\n return callback.apply(null, arr);\n };\n}\n","'use strict';\n\nimport utils from './../utils.js';\n\n/**\n * Determines whether the payload is an error thrown by Axios\n *\n * @param {*} payload The value to test\n *\n * @returns {boolean} True if the payload is an error thrown by Axios, otherwise false\n */\nexport default function isAxiosError(payload) {\n return utils.isObject(payload) && (payload.isAxiosError === true);\n}\n","const HttpStatusCode = {\n Continue: 100,\n SwitchingProtocols: 101,\n Processing: 102,\n EarlyHints: 103,\n Ok: 200,\n Created: 201,\n Accepted: 202,\n NonAuthoritativeInformation: 203,\n NoContent: 204,\n ResetContent: 205,\n PartialContent: 206,\n MultiStatus: 207,\n AlreadyReported: 208,\n ImUsed: 226,\n MultipleChoices: 300,\n MovedPermanently: 301,\n Found: 302,\n SeeOther: 303,\n NotModified: 304,\n UseProxy: 305,\n Unused: 306,\n TemporaryRedirect: 307,\n PermanentRedirect: 308,\n BadRequest: 400,\n Unauthorized: 401,\n PaymentRequired: 402,\n Forbidden: 403,\n NotFound: 404,\n MethodNotAllowed: 405,\n NotAcceptable: 406,\n ProxyAuthenticationRequired: 407,\n RequestTimeout: 408,\n Conflict: 409,\n Gone: 410,\n LengthRequired: 411,\n PreconditionFailed: 412,\n PayloadTooLarge: 413,\n UriTooLong: 414,\n UnsupportedMediaType: 415,\n RangeNotSatisfiable: 416,\n ExpectationFailed: 417,\n ImATeapot: 418,\n MisdirectedRequest: 421,\n UnprocessableEntity: 422,\n Locked: 423,\n FailedDependency: 424,\n TooEarly: 425,\n UpgradeRequired: 426,\n PreconditionRequired: 428,\n TooManyRequests: 429,\n RequestHeaderFieldsTooLarge: 431,\n UnavailableForLegalReasons: 451,\n InternalServerError: 500,\n NotImplemented: 501,\n BadGateway: 502,\n ServiceUnavailable: 503,\n GatewayTimeout: 504,\n HttpVersionNotSupported: 505,\n VariantAlsoNegotiates: 506,\n InsufficientStorage: 507,\n LoopDetected: 508,\n NotExtended: 510,\n NetworkAuthenticationRequired: 511,\n};\n\nObject.entries(HttpStatusCode).forEach(([key, value]) => {\n HttpStatusCode[value] = key;\n});\n\nexport default HttpStatusCode;\n","'use strict';\n\nimport utils from './utils.js';\nimport bind from './helpers/bind.js';\nimport Axios from './core/Axios.js';\nimport mergeConfig from './core/mergeConfig.js';\nimport defaults from './defaults/index.js';\nimport formDataToJSON from './helpers/formDataToJSON.js';\nimport CanceledError from './cancel/CanceledError.js';\nimport CancelToken from './cancel/CancelToken.js';\nimport isCancel from './cancel/isCancel.js';\nimport {VERSION} from './env/data.js';\nimport toFormData from './helpers/toFormData.js';\nimport AxiosError from './core/AxiosError.js';\nimport spread from './helpers/spread.js';\nimport isAxiosError from './helpers/isAxiosError.js';\nimport AxiosHeaders from \"./core/AxiosHeaders.js\";\nimport adapters from './adapters/adapters.js';\nimport HttpStatusCode from './helpers/HttpStatusCode.js';\n\n/**\n * Create an instance of Axios\n *\n * @param {Object} defaultConfig The default config for the instance\n *\n * @returns {Axios} A new instance of Axios\n */\nfunction createInstance(defaultConfig) {\n const context = new Axios(defaultConfig);\n const instance = bind(Axios.prototype.request, context);\n\n // Copy axios.prototype to instance\n utils.extend(instance, Axios.prototype, context, {allOwnKeys: true});\n\n // Copy context to instance\n utils.extend(instance, context, null, {allOwnKeys: true});\n\n // Factory for creating new instances\n instance.create = function create(instanceConfig) {\n return createInstance(mergeConfig(defaultConfig, instanceConfig));\n };\n\n return instance;\n}\n\n// Create the default instance to be exported\nconst axios = createInstance(defaults);\n\n// Expose Axios class to allow class inheritance\naxios.Axios = Axios;\n\n// Expose Cancel & CancelToken\naxios.CanceledError = CanceledError;\naxios.CancelToken = CancelToken;\naxios.isCancel = isCancel;\naxios.VERSION = VERSION;\naxios.toFormData = toFormData;\n\n// Expose AxiosError class\naxios.AxiosError = AxiosError;\n\n// alias for CanceledError for backward compatibility\naxios.Cancel = axios.CanceledError;\n\n// Expose all/spread\naxios.all = function all(promises) {\n return Promise.all(promises);\n};\n\naxios.spread = spread;\n\n// Expose isAxiosError\naxios.isAxiosError = isAxiosError;\n\n// Expose mergeConfig\naxios.mergeConfig = mergeConfig;\n\naxios.AxiosHeaders = AxiosHeaders;\n\naxios.formToJSON = thing => formDataToJSON(utils.isHTMLForm(thing) ? new FormData(thing) : thing);\n\naxios.getAdapter = adapters.getAdapter;\n\naxios.HttpStatusCode = HttpStatusCode;\n\naxios.default = axios;\n\n// this module should only have a default export\nexport default axios\n","import axios from './lib/axios.js';\n\n// This module is intended to unwrap Axios default export as named.\n// Keep top-level export same with static properties\n// so that it can keep same with es module or cjs\nconst {\n Axios,\n AxiosError,\n CanceledError,\n isCancel,\n CancelToken,\n VERSION,\n all,\n Cancel,\n isAxiosError,\n spread,\n toFormData,\n AxiosHeaders,\n HttpStatusCode,\n formToJSON,\n getAdapter,\n mergeConfig\n} = axios;\n\nexport {\n axios as default,\n Axios,\n AxiosError,\n CanceledError,\n isCancel,\n CancelToken,\n VERSION,\n all,\n Cancel,\n isAxiosError,\n spread,\n toFormData,\n AxiosHeaders,\n HttpStatusCode,\n formToJSON,\n getAdapter,\n mergeConfig\n}\n","import axios, { AxiosError, type AxiosInstance, type AxiosRequestConfig, type AxiosResponse, type InternalAxiosRequestConfig } from 'axios';\n\nimport {\n HttpServiceConfig,\n RequestErrorInterceptor,\n RequestInterceptor,\n ResponseErrorInterceptor,\n ResponseInterceptor,\n UnauthorizedCallback,\n} from './types';\n\n/** 扩展 AxiosRequestConfig,添加重试标记 */\ninterface ExtendedAxiosRequestConfig extends InternalAxiosRequestConfig {\n _retry?: boolean;\n}\n\n/**\n * HttpService - 单例 HTTP 客户端\n *\n * 特性:\n * - 单例模式,全局唯一实例,延迟初始化(首次使用时自动创建)\n * - 支持拦截器注册(其他模块可注入 header)\n * - 统一 401 处理(支持自动刷新 token 并重试)\n * - 自动携带凭证(withCredentials)\n * - 类型安全\n *\n * @example\n * ```typescript\n * // 直接使用导出的 httpService(首次使用时自动初始化)\n * import { httpService } from '@genie/agent-provider';\n *\n * // 按需设置 baseURL\n * httpService.setBaseURL('https://api.example.com');\n *\n * // 按需设置 authToken\n * httpService.setAuthToken('your-token');\n *\n * // 注册请求拦截器(注入 header)\n * httpService.registerRequestInterceptor((config) => {\n * config.headers['X-Enterprise-Id'] = 'enterprise-123';\n * return config;\n * });\n *\n * // 注册 401 回调\n * httpService.onUnauthorized(() => {\n * console.log('User unauthorized');\n * window.location.href = '/login';\n * });\n *\n * // 发起请求\n * const data = await httpService.get<Account>('/console/accounts');\n * ```\n */\nexport class HttpService {\n private static instance: HttpService | null = null;\n private axiosInstance: AxiosInstance;\n private unauthorizedCallbacks: Set<UnauthorizedCallback> = new Set();\n private config: HttpServiceConfig;\n\n /** 是否正在刷新 token */\n private isRefreshing = false;\n /** 等待 token 刷新完成的请求队列 */\n private refreshSubscribers: Array<(success: boolean) => void> = [];\n\n /**\n * 私有构造函数(单例模式)\n */\n private constructor(config: HttpServiceConfig = {}) {\n this.config = config;\n\n // 创建 axios 实例\n this.axiosInstance = axios.create({\n baseURL: config.baseURL?.replace(/\\/$/, '') || '',\n timeout: config.timeout || 60000,\n withCredentials: config.withCredentials !== false, // 默认 true\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n ...config.headers,\n },\n });\n\n // 注册默认请求拦截器(添加 Authorization)\n this.registerDefaultRequestInterceptor();\n\n // 注册默认响应拦截器(处理 401)\n this.registerDefaultResponseInterceptor();\n }\n\n /**\n * 获取单例实例(延迟初始化)\n */\n public static getInstance(): HttpService {\n if (!HttpService.instance) {\n HttpService.instance = new HttpService();\n }\n return HttpService.instance;\n }\n\n /**\n * 重置单例实例(主要用于测试)\n */\n public static resetInstance(): void {\n HttpService.instance = null;\n }\n\n /**\n * 注册默认请求拦截器(添加 Authorization header)\n */\n private registerDefaultRequestInterceptor(): void {\n this.axiosInstance.interceptors.request.use(\n requestConfig => {\n // 添加 Authorization header\n if (this.config.authToken) {\n requestConfig.headers = requestConfig.headers || {};\n requestConfig.headers['Authorization'] = `Bearer ${this.config.authToken}`;\n }\n return requestConfig;\n },\n error => Promise.reject(error)\n );\n }\n\n /**\n * 注册默认响应拦截器(处理 401,支持自动重试)\n */\n private registerDefaultResponseInterceptor(): void {\n this.axiosInstance.interceptors.response.use(\n response => response,\n async (error: AxiosError) => {\n const originalRequest = error.config as ExtendedAxiosRequestConfig;\n\n // 统一处理 401\n if (error.response?.status === 401 && originalRequest && !originalRequest._retry) {\n // 排除 token 刷新接口本身,避免死循环\n // getAccount (/console/accounts) 是用来刷新 token 的,不应该重试\n const isRefreshRequest = originalRequest.url?.includes('/console/accounts');\n if (isRefreshRequest) {\n console.warn('[HttpService] Unauthorized 401 on refresh endpoint, not retrying');\n return Promise.reject(error);\n }\n\n console.warn('[HttpService] Unauthorized 401, attempting token refresh and retry');\n\n // 标记已重试,避免死循环\n originalRequest._retry = true;\n\n // 如果正在刷新 token,等待刷新完成后重试\n if (this.isRefreshing) {\n return new Promise((resolve, reject) => {\n this.refreshSubscribers.push((success: boolean) => {\n if (success) {\n // token 刷新成功,重试原请求\n this.axiosInstance.request(originalRequest)\n .then(resolve)\n .catch(reject);\n } else {\n // token 刷新失败,拒绝请求\n reject(error);\n }\n });\n });\n }\n\n // 设置刷新标记\n this.isRefreshing = true;\n\n try {\n // 触发 401 回调(BackendProvider 会进行 token 刷新)\n // 等待所有回调完成\n await this.triggerUnauthorizedCallbacks();\n\n // 刷新成功,通知所有等待的请求\n this.onRefreshSuccess();\n\n // 重试原请求\n return this.axiosInstance.request(originalRequest);\n } catch (refreshError) {\n // 刷新失败,通知所有等待的请求\n this.onRefreshFailure();\n return Promise.reject(error);\n } finally {\n this.isRefreshing = false;\n }\n }\n\n return Promise.reject(error);\n }\n );\n }\n\n /**\n * token 刷新成功,通知所有等待的请求\n */\n private onRefreshSuccess(): void {\n this.refreshSubscribers.forEach(callback => callback(true));\n this.refreshSubscribers = [];\n }\n\n /**\n * token 刷新失败,通知所有等待的请求\n */\n private onRefreshFailure(): void {\n this.refreshSubscribers.forEach(callback => callback(false));\n this.refreshSubscribers = [];\n }\n\n /**\n * 注册请求拦截器\n * @param onFulfilled 请求成功拦截器\n * @param onRejected 请求失败拦截器\n * @returns 拦截器 ID(用于移除)\n *\n * @example\n * ```typescript\n * const id = httpService.registerRequestInterceptor((config) => {\n * config.headers['X-Custom-Header'] = 'value';\n * return config;\n * });\n *\n * // 移除拦截器\n * httpService.ejectRequestInterceptor(id);\n * ```\n */\n public registerRequestInterceptor(\n onFulfilled: RequestInterceptor,\n onRejected?: RequestErrorInterceptor\n ): number {\n return this.axiosInstance.interceptors.request.use(onFulfilled, onRejected);\n }\n\n /**\n * 注册响应拦截器\n * @param onFulfilled 响应成功拦截器\n * @param onRejected 响应失败拦截器\n * @returns 拦截器 ID(用于移除)\n *\n * @example\n * ```typescript\n * const id = httpService.registerResponseInterceptor((response) => {\n * console.log('Response:', response.data);\n * return response;\n * });\n *\n * // 移除拦截器\n * httpService.ejectResponseInterceptor(id);\n * ```\n */\n public registerResponseInterceptor(\n onFulfilled: ResponseInterceptor,\n onRejected?: ResponseErrorInterceptor\n ): number {\n return this.axiosInstance.interceptors.response.use(onFulfilled, onRejected);\n }\n\n /**\n * 移除请求拦截器\n * @param id 拦截器 ID\n */\n public ejectRequestInterceptor(id: number): void {\n this.axiosInstance.interceptors.request.eject(id);\n }\n\n /**\n * 移除响应拦截器\n * @param id 拦截器 ID\n */\n public ejectResponseInterceptor(id: number): void {\n this.axiosInstance.interceptors.response.eject(id);\n }\n\n /**\n * 注册 401 未授权回调\n * @param callback 回调函数\n *\n * @example\n * ```typescript\n * httpService.onUnauthorized(() => {\n * console.log('User logged out');\n * window.location.href = '/login';\n * });\n * ```\n */\n public onUnauthorized(callback: UnauthorizedCallback): void {\n this.unauthorizedCallbacks.add(callback);\n }\n\n /**\n * 移除 401 未授权回调\n * @param callback 回调函数\n */\n public offUnauthorized(callback: UnauthorizedCallback): void {\n this.unauthorizedCallbacks.delete(callback);\n }\n\n /**\n * 触发所有 401 回调并等待完成\n * @returns Promise,等待所有回调完成\n * @throws 如果任何回调失败,则抛出错误\n */\n private async triggerUnauthorizedCallbacks(): Promise<void> {\n const callbacks = Array.from(this.unauthorizedCallbacks);\n const results = await Promise.allSettled(callbacks.map(callback => callback()));\n\n // 检查是否有失败的回调\n const failedResults = results.filter(r => r.status === 'rejected');\n if (failedResults.length > 0) {\n const errors = failedResults.map(r => (r as PromiseRejectedResult).reason);\n console.error('[HttpService] Some unauthorized callbacks failed:', errors);\n throw errors[0]; // 抛出第一个错误\n }\n }\n\n /**\n * 更新 authToken\n * @param token 新的 token\n */\n public setAuthToken(token: string | undefined): void {\n this.config.authToken = token;\n }\n\n /**\n * 更新 baseURL\n * @param baseURL 新的 baseURL\n */\n public setBaseURL(baseURL: string): void {\n this.config.baseURL = baseURL;\n this.axiosInstance.defaults.baseURL = baseURL.replace(/\\/$/, '');\n }\n\n /**\n * GET 请求\n * @param url 请求路径\n * @param config axios 配置\n * @returns 响应数据\n */\n public async get<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {\n const response = await this.axiosInstance.get<T>(url, config);\n return response.data;\n }\n\n /**\n * POST 请求\n * @param url 请求路径\n * @param data 请求体\n * @param config axios 配置\n * @returns 响应数据\n */\n public async post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {\n const response = await this.axiosInstance.post<T>(url, data, config);\n return response.data;\n }\n\n /**\n * PATCH 请求\n * @param url 请求路径\n * @param data 请求体\n * @param config axios 配置\n * @returns 响应数据\n */\n public async patch<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {\n const response = await this.axiosInstance.patch<T>(url, data, config);\n return response.data;\n }\n\n /**\n * DELETE 请求\n * @param url 请求路径\n * @param config axios 配置\n * @returns 响应数据\n */\n public async delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {\n const response = await this.axiosInstance.delete<T>(url, config);\n return response.data;\n }\n\n /**\n * PUT 请求\n * @param url 请求路径\n * @param data 请求体\n * @param config axios 配置\n * @returns 响应数据\n */\n public async put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {\n const response = await this.axiosInstance.put<T>(url, data, config);\n return response.data;\n }\n\n /**\n * 通用请求方法\n * @param config axios 请求配置\n * @returns 原始 AxiosResponse\n */\n public async request<T = any>(config: AxiosRequestConfig): Promise<AxiosResponse<T>> {\n return this.axiosInstance.request<T>(config);\n }\n\n /**\n * 获取原始 axios 实例(用于高级场景)\n */\n public getAxiosInstance(): AxiosInstance {\n return this.axiosInstance;\n }\n}\n","import { HttpService } from './http-service';\n\nexport * from './http-service';\nexport * from './types';\n\n/**\n * 导出 httpService 单例实例\n * 首次访问时自动初始化,无需手动调用初始化方法\n *\n * @example\n * ```typescript\n * import { httpService } from '@genie/agent-provider';\n *\n * // 按需设置 baseURL\n * httpService.setBaseURL('https://api.example.com');\n *\n * // 按需设置 authToken\n * httpService.setAuthToken('your-token');\n *\n * // 直接使用\n * const data = await httpService.get('/api/endpoint');\n * ```\n */\nexport const httpService = new Proxy({} as HttpService, {\n get(target, prop) {\n const instance = HttpService.getInstance();\n return (instance as any)[prop];\n },\n});\n\n","/**\n * AccountService - 账号状态管理单例\n *\n * 提供全局的账号状态管理,任何模块都可以:\n * - 获取当前账号: accountService.getAccount()\n * - 设置账号: accountService.setAccount(account)\n * - 订阅变化: accountService.subscribe(callback)\n * - 初始化时自动注册 HTTP 拦截器,注入账号相关 headers\n */\n\nimport type { Account } from '../backend/types';\nimport { httpService } from '../http';\n\n/**\n * 账号变化回调函数类型\n */\nexport type AccountChangeCallback = (account: Account | null) => void;\n\n/**\n * 跨标签页认证同步的广播函数类型\n */\nexport interface CrossTabAuthBroadcaster {\n broadcastLogin: () => void;\n broadcastLogout: () => void;\n}\n\n/**\n * AccountService 类\n *\n * 单例模式,管理全局账号状态\n */\nclass AccountService {\n /** 当前账号 */\n private account: Account | null = null;\n\n /** 订阅者列表 */\n private listeners = new Set<AccountChangeCallback>();\n\n /** 是否已初始化(首次加载完成) */\n private initialized = false;\n\n /** 初始化等待队列 */\n private initPromise: Promise<Account | null> | null = null;\n private initResolve: ((account: Account | null) => void) | null = null;\n\n /** HTTP 请求拦截器 ID(未来可用于清理拦截器) */\n private requestInterceptorId: number | null = null;\n\n /** 跨标签页认证同步广播器(由上层注入) */\n private crossTabBroadcaster: CrossTabAuthBroadcaster | null = null;\n\n constructor() {\n // 创建初始化 Promise,允许其他模块等待首次加载完成\n this.initPromise = new Promise(resolve => {\n this.initResolve = resolve;\n });\n\n // 注册 HTTP 拦截器,注入账号相关 headers\n this.registerHttpInterceptor();\n }\n\n /**\n * 注册 HTTP 请求拦截器\n * 自动注入账号相关的 headers (X-User-Id, X-Enterprise-Id, X-Tenant-Id)\n */\n private registerHttpInterceptor(): void {\n try {\n this.requestInterceptorId = httpService.registerRequestInterceptor(config => {\n const account = this.getAccount();\n\n if (account?.uid) {\n config.headers = config.headers || {};\n config.headers['X-User-Id'] = account.uid;\n }\n\n if (account?.enterpriseId) {\n config.headers = config.headers || {};\n config.headers['X-Enterprise-Id'] = account.enterpriseId;\n config.headers['X-Tenant-Id'] = account.enterpriseId;\n }\n\n return config;\n });\n\n console.log('[AccountService] HTTP interceptor registered');\n } catch (error) {\n // HttpService 可能还未初始化,延迟注册\n console.warn('[AccountService] Failed to register HTTP interceptor, will retry on first request:', error);\n }\n }\n\n /**\n * 获取当前账号\n * @returns 当前账号,未登录或未加载时返回 null\n */\n getAccount(): Account | null {\n return this.account;\n }\n\n /**\n * 设置账号\n * @param account 账号信息,登出时传 null\n */\n setAccount(account: Account | null): void {\n const prev = this.account;\n const wasInitialized = this.initialized;\n this.account = account;\n\n // 首次设置时,标记为已初始化并 resolve 等待的 Promise\n if (!this.initialized) {\n this.initialized = true;\n this.initResolve?.(account);\n }\n\n // 首次初始化时总是通知订阅者,之后只有账号真正变化时才通知\n if (!wasInitialized || prev?.uid !== account?.uid) {\n this.notifyListeners();\n\n // 跨标签页广播:拿到新账号时广播 login\n if (account && this.crossTabBroadcaster) {\n this.crossTabBroadcaster.broadcastLogin();\n }\n }\n }\n\n /**\n * 清除账号(登出)\n * 先广播登出消息,再清除本地账号\n */\n clearAccount(): void {\n // 跨标签页广播:登出前先广播 logout\n if (this.crossTabBroadcaster) {\n this.crossTabBroadcaster.broadcastLogout();\n }\n this.setAccount(null);\n }\n\n /**\n * 静默清除账号(不广播)\n * 用于收到其他标签页 logout 消息时,避免循环广播\n */\n clearAccountSilently(): void {\n this.setAccount(null);\n }\n\n /**\n * 设置跨标签页认证同步广播器\n * 应在应用初始化时由上层(如 agent-ui)调用\n */\n setCrossTabBroadcaster(broadcaster: CrossTabAuthBroadcaster | null): void {\n this.crossTabBroadcaster = broadcaster;\n }\n\n /**\n * 订阅账号变化\n * @param callback 变化时的回调函数\n * @returns 取消订阅函数\n */\n subscribe(callback: AccountChangeCallback): () => void {\n this.listeners.add(callback);\n return () => {\n this.listeners.delete(callback);\n };\n }\n\n /**\n * 等待首次账号加载完成\n * @returns Promise<Account | null>\n */\n waitForInit(): Promise<Account | null> {\n if (this.initialized) {\n return Promise.resolve(this.account);\n }\n return this.initPromise!;\n }\n\n /**\n * 是否已初始化\n */\n isInitialized(): boolean {\n return this.initialized;\n }\n\n /**\n * 是否已登录\n */\n isLoggedIn(): boolean {\n return this.account !== null;\n }\n\n /**\n * 通知所有订阅者\n */\n private notifyListeners(): void {\n this.listeners.forEach(callback => {\n try {\n callback(this.account);\n } catch (error) {\n console.error('[AccountService] Listener error:', error);\n }\n });\n }\n\n /**\n * 重置服务状态(仅用于测试)\n */\n _reset(): void {\n this.account = null;\n this.listeners.clear();\n this.initialized = false;\n this.initPromise = new Promise(resolve => {\n this.initResolve = resolve;\n });\n\n // 清理拦截器\n if (this.requestInterceptorId !== null) {\n try {\n httpService.ejectRequestInterceptor(this.requestInterceptorId);\n this.requestInterceptorId = null;\n } catch (error) {\n console.warn('[AccountService] Failed to eject interceptor during reset:', error);\n }\n }\n }\n}\n\n/**\n * 导出单例实例\n */\nexport const accountService = new AccountService();\n\n/**\n * 暴露给全局,供 Agent Manager 直接调用 setAccount 刷新 Widget 状态\n * 这是为了解决 IDE 环境中 IPC 事件无法直接触发 Widget 账号刷新的问题\n */\nif (typeof window !== 'undefined') {\n (window as any).__genieAccountService = accountService;\n}\n","/**\n * LRU (Least Recently Used) Cache\n * 当缓存达到容量上限时,自动淘汰最久未使用的数据\n *\n * @template K - Key 类型\n * @template V - Value 类型\n */\nexport class LRUCache<K, V> {\n private capacity: number;\n private cache: Map<K, V>;\n\n /**\n * 创建 LRU 缓存实例\n * @param capacity - 缓存容量上限\n */\n constructor(capacity: number) {\n if (capacity <= 0) {\n throw new Error('Cache capacity must be greater than 0');\n }\n this.capacity = capacity;\n this.cache = new Map();\n }\n\n /**\n * 获取缓存值\n * @param key - 键\n * @returns 值,如果不存在返回 undefined\n */\n get(key: K): V | undefined {\n if (!this.cache.has(key)) {\n return undefined;\n }\n\n // 将访问的元素移到最后(最近使用)\n const value = this.cache.get(key)!;\n this.cache.delete(key);\n this.cache.set(key, value);\n return value;\n }\n\n /**\n * 设置缓存值\n * @param key - 键\n * @param value - 值\n */\n set(key: K, value: V): void {\n // 如果 key 已存在,先删除(为了更新位置)\n if (this.cache.has(key)) {\n this.cache.delete(key);\n } else if (this.cache.size >= this.capacity) {\n // 缓存已满,删除最久未使用的(Map 的第一个元素)\n const firstKey = this.cache.keys().next().value;\n this.cache.delete(firstKey);\n }\n\n // 添加到最后(最近使用)\n this.cache.set(key, value);\n }\n\n /**\n * 检查 key 是否存在\n * @param key - 键\n * @returns 是否存在\n */\n has(key: K): boolean {\n return this.cache.has(key);\n }\n\n /**\n * 删除指定 key\n * @param key - 键\n * @returns 是否删除成功\n */\n delete(key: K): boolean {\n return this.cache.delete(key);\n }\n\n /**\n * 清空缓存\n */\n clear(): void {\n this.cache.clear();\n }\n\n /**\n * 获取当前缓存大小\n * @returns 当前缓存的元素数量\n */\n get size(): number {\n return this.cache.size;\n }\n\n /**\n * 获取缓存容量\n * @returns 缓存容量上限\n */\n get maxSize(): number {\n return this.capacity;\n }\n\n /**\n * 获取所有 key\n * @returns key 数组\n */\n keys(): K[] {\n return Array.from(this.cache.keys());\n }\n\n /**\n * 获取所有 value\n * @returns value 数组\n */\n values(): V[] {\n return Array.from(this.cache.values());\n }\n\n /**\n * 遍历缓存\n * @param callback - 回调函数\n */\n forEach(callback: (value: V, key: K) => void): void {\n this.cache.forEach((value, key) => callback(value, key));\n }\n}\n","/**\n * 并发控制工具\n *\n * 提供限制并发数量的工具函数,用于控制并行请求数量\n */\n\n/**\n * 并发执行任务,限制同时运行的任务数量\n *\n * @param tasks - 任务函数数组,每个函数返回 Promise\n * @param concurrency - 最大并发数,默认 5\n * @returns 所有任务的结果数组,顺序与输入一致\n *\n * @example\n * ```typescript\n * const urls = ['url1', 'url2', 'url3', 'url4', 'url5'];\n * const tasks = urls.map(url => () => fetch(url));\n * const results = await runWithConcurrency(tasks, 2); // 最多同时 2 个请求\n * ```\n */\nexport async function runWithConcurrency<T>(\n tasks: Array<() => Promise<T>>,\n concurrency: number = 5\n): Promise<T[]> {\n if (tasks.length === 0) {\n return [];\n }\n\n // 确保并发数至少为 1\n const limit = Math.max(1, concurrency);\n\n const results: T[] = new Array(tasks.length);\n let currentIndex = 0;\n\n async function runNext(): Promise<void> {\n while (currentIndex < tasks.length) {\n const index = currentIndex++;\n const task = tasks[index];\n results[index] = await task();\n }\n }\n\n // 启动 limit 个 worker\n const workers = Array(Math.min(limit, tasks.length))\n .fill(null)\n .map(() => runNext());\n\n await Promise.all(workers);\n\n return results;\n}\n\n/**\n * 并发执行任务,返回包含成功/失败状态的结果\n *\n * @param tasks - 任务函数数组\n * @param concurrency - 最大并发数,默认 5\n * @returns 所有任务的结果数组,包含状态信息\n *\n * @example\n * ```typescript\n * const results = await runWithConcurrencySettled(tasks, 3);\n * const successes = results.filter(r => r.status === 'fulfilled');\n * const failures = results.filter(r => r.status === 'rejected');\n * ```\n */\nexport async function runWithConcurrencySettled<T>(\n tasks: Array<() => Promise<T>>,\n concurrency: number = 5\n): Promise<PromiseSettledResult<T>[]> {\n if (tasks.length === 0) {\n return [];\n }\n\n const limit = Math.max(1, concurrency);\n const results: PromiseSettledResult<T>[] = new Array(tasks.length);\n let currentIndex = 0;\n\n async function runNext(): Promise<void> {\n while (currentIndex < tasks.length) {\n const index = currentIndex++;\n const task = tasks[index];\n try {\n const value = await task();\n results[index] = { status: 'fulfilled', value };\n } catch (reason) {\n results[index] = { status: 'rejected', reason };\n }\n }\n }\n\n const workers = Array(Math.min(limit, tasks.length))\n .fill(null)\n .map(() => runNext());\n\n await Promise.all(workers);\n\n return results;\n}\n\n/**\n * 创建一个并发限制器,可复用于多次调用\n *\n * @param concurrency - 最大并发数\n * @returns 并发限制器实例\n *\n * @example\n * ```typescript\n * const limiter = createConcurrencyLimiter(3);\n *\n * // 多个地方可以共用同一个限制器\n * const result1 = await limiter.run(() => fetch(url1));\n * const result2 = await limiter.run(() => fetch(url2));\n *\n * // 或者批量执行\n * const results = await limiter.runAll([\n * () => fetch(url1),\n * () => fetch(url2),\n * ]);\n * ```\n */\nexport function createConcurrencyLimiter(concurrency: number = 5) {\n const limit = Math.max(1, concurrency);\n let running = 0;\n const queue: Array<{\n task: () => Promise<unknown>;\n resolve: (value: unknown) => void;\n reject: (reason: unknown) => void;\n }> = [];\n\n async function processQueue(): Promise<void> {\n if (running >= limit || queue.length === 0) {\n return;\n }\n\n running++;\n const item = queue.shift()!;\n\n try {\n const result = await item.task();\n item.resolve(result);\n } catch (error) {\n item.reject(error);\n } finally {\n running--;\n processQueue();\n }\n }\n\n return {\n /**\n * 执行单个任务,受并发限制\n */\n run<T>(task: () => Promise<T>): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n queue.push({\n task: task as () => Promise<unknown>,\n resolve: resolve as (value: unknown) => void,\n reject,\n });\n processQueue();\n });\n },\n\n /**\n * 批量执行任务,受并发限制\n */\n async runAll<T>(tasks: Array<() => Promise<T>>): Promise<T[]> {\n return Promise.all(tasks.map(task => this.run(task)));\n },\n\n /**\n * 获取当前正在运行的任务数\n */\n get runningCount(): number {\n return running;\n },\n\n /**\n * 获取队列中等待的任务数\n */\n get pendingCount(): number {\n return queue.length;\n },\n };\n}\n","/**\n * COS Upload Service\n *\n * 负责通过预签名 URL 上传文件到腾讯云 COS\n *\n * 上传流程:\n * 1. 生成 objectKey (uploads/{timestamp}-{random}-{filename})\n * 2. 批量请求后端获取预签名 URL (同时包含 upload_url 和 download_url)\n * 3. 使用 upload_url 并发上传文件到 COS\n * 4. 返回 download_url 作为访问地址\n *\n * 注意:文件级缓存(避免重复上传相同文件)由上层 agent-ui 的 upload-cache 处理\n */\n\nimport { httpService } from '../../../http/index.js';\nimport type { Logger } from '../../client/types.js';\nimport { runWithConcurrencySettled } from '../../utils/index.js';\n\n/**\n * 预签名 URL 请求参数\n */\nexport interface PresignedURLRequest {\n /** 对象路径数组 */\n object_keys: string[];\n}\n\n/**\n * 预签名 URL 响应项\n */\nexport interface PresignedURLItem {\n /** 对象路径 */\n object_key: string;\n /** 上传 URL (PUT) */\n upload_url: string;\n /** 下载 URL (GET) */\n download_url: string;\n}\n\n/**\n * 预签名 URL 响应\n */\nexport interface PresignedURLResponse {\n /** 过期时间 (秒) */\n expire: number;\n /** 预签名 URL 列表 */\n items: PresignedURLItem[];\n}\n\n/**\n * API 响应包装类型\n */\ninterface ApiResponse<T> {\n code: number;\n message: string;\n data?: T;\n}\n\n/**\n * 上传结果\n */\nexport interface UploadResult {\n /** 是否成功 */\n success: boolean;\n /** 访问 URL (成功时返回) */\n url?: string;\n /** 对象路径 */\n objectKey?: string;\n /** 错误信息 (失败时返回) */\n error?: string;\n /** 是否被用户取消 */\n aborted?: boolean;\n}\n\n/**\n * COS Upload Service 配置\n */\nexport interface CosUploadServiceOptions {\n /** Logger 实例 */\n logger?: Logger;\n /** 上传并发数,默认 3 */\n uploadConcurrency?: number;\n}\n\n/**\n * COS 上传服务\n *\n * @example\n * ```typescript\n * const service = new CosUploadService({\n * logger: console,\n * uploadConcurrency: 3,\n * });\n *\n * const result = await service.uploadFile(file);\n * if (result.success) {\n * console.log('File URL:', result.url);\n * }\n * ```\n */\nexport class CosUploadService {\n private logger?: Logger;\n private uploadConcurrency: number;\n\n constructor(options: CosUploadServiceOptions = {}) {\n this.logger = options.logger;\n this.uploadConcurrency = options.uploadConcurrency ?? 3;\n }\n\n /**\n * 生成唯一的 objectKey\n *\n * 格式: uploads/{timestamp}-{randomId}-{encodedFilename}\n */\n private generateObjectKey(filename: string): string {\n const timestamp = Date.now();\n const randomId = Math.random().toString(36).substring(2, 10);\n const encodedFilename = encodeURIComponent(filename);\n return `uploads/${timestamp}-${randomId}-${encodedFilename}`;\n }\n\n /**\n * 批量获取预签名 URL\n *\n * POST /console/as/support/presigned_url\n */\n private async getPresignedUrls(objectKeys: string[]): Promise<PresignedURLResponse> {\n const apiResponse = await httpService.post<ApiResponse<PresignedURLResponse>>(\n '/console/as/support/presigned_url',\n { object_keys: objectKeys }\n );\n\n if (!apiResponse.data) {\n throw new Error('No data in presigned URL response');\n }\n\n return apiResponse.data;\n }\n\n /**\n * 上传单个文件到 COS\n *\n * @param file - 要上传的文件\n * @param abortSignal - 可选的 AbortSignal,用于取消上传\n * @returns 上传结果,包含访问 URL 或错误信息\n */\n async uploadFile(file: File, abortSignal?: AbortSignal): Promise<UploadResult> {\n const filename = file.name;\n this.logger?.info(`[CosUploadService] Uploading file: ${filename}`);\n\n try {\n // 检查是否已经被取消\n if (abortSignal?.aborted) {\n return {\n success: false,\n error: 'Upload cancelled',\n aborted: true,\n };\n }\n\n // 1. 生成 objectKey\n const objectKey = this.generateObjectKey(filename);\n this.logger?.debug(`[CosUploadService] Generated objectKey: ${objectKey}`);\n\n // 2. 获取预签名 URL\n const presignedResponse = await this.getPresignedUrls([objectKey]);\n const presignedItem = presignedResponse.items[0];\n if (!presignedItem) {\n throw new Error('No presigned URL item returned');\n }\n\n // 再次检查是否在获取预签名 URL 期间被取消\n if (abortSignal?.aborted) {\n return {\n success: false,\n error: 'Upload cancelled',\n aborted: true,\n };\n }\n\n // 3. 上传文件到 COS(使用原生 fetch,因为这是上传到外部 COS)\n const uploadResponse = await fetch(presignedItem.upload_url, {\n method: 'PUT',\n body: file,\n headers: {\n 'Content-Type': file.type || 'application/octet-stream',\n },\n signal: abortSignal, // 传入 AbortSignal 以支持取消\n });\n\n if (!uploadResponse.ok) {\n const errorText = await uploadResponse.text().catch(() => uploadResponse.statusText);\n throw new Error(`COS upload failed: ${uploadResponse.status} ${errorText}`);\n }\n this.logger?.debug('[CosUploadService] File uploaded to COS');\n\n this.logger?.info(`[CosUploadService] Upload success: ${filename}`);\n return {\n success: true,\n url: presignedItem.download_url,\n objectKey,\n };\n } catch (error) {\n // 检查是否是取消导致的错误\n if (error instanceof Error && error.name === 'AbortError') {\n return {\n success: false,\n error: 'Upload cancelled',\n aborted: true,\n };\n }\n\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n this.logger?.error(`[CosUploadService] Upload failed: ${filename}`, error);\n return {\n success: false,\n error: errorMessage,\n };\n }\n }\n\n /**\n * 批量上传文件到 COS\n *\n * 使用并发控制,限制同时上传的文件数量\n *\n * @param files - 要上传的文件数组\n * @param abortSignal - 可选的 AbortSignal,用于取消上传\n * @returns 所有文件的上传结果\n */\n async uploadFiles(files: File[], abortSignal?: AbortSignal): Promise<{\n success: boolean;\n urls?: string[];\n expireSeconds?: number;\n error?: string;\n results: UploadResult[];\n aborted?: boolean;\n }> {\n if (files.length === 0) {\n return { success: true, urls: [], results: [] };\n }\n\n // 检查是否已经被取消\n if (abortSignal?.aborted) {\n return {\n success: false,\n error: 'Upload cancelled',\n aborted: true,\n results: files.map(() => ({ success: false, error: 'Upload cancelled', aborted: true })),\n };\n }\n\n this.logger?.info(`[CosUploadService] Uploading ${files.length} file(s) with concurrency ${this.uploadConcurrency}`);\n\n try {\n // 1. 为所有文件生成 objectKey\n const fileInfos = files.map(file => ({\n file,\n objectKey: this.generateObjectKey(file.name),\n }));\n\n // 2. 批量获取预签名 URL\n const objectKeys = fileInfos.map(info => info.objectKey);\n const presignedResponse = await this.getPresignedUrls(objectKeys);\n this.logger?.debug(`[CosUploadService] Got ${presignedResponse.items.length} presigned URLs`);\n\n // 3. 验证返回的数量\n if (presignedResponse.items.length !== fileInfos.length) {\n throw new Error(`Expected ${fileInfos.length} presigned URLs, got ${presignedResponse.items.length}`);\n }\n\n // 4. 创建上传任务(使用后端返回的顺序来匹配)\n // 后端会在 objectKey 前加上 userID,所以我们使用数组索引来匹配\n const uploadTasks = fileInfos.map(({ file }, index) => async (): Promise<UploadResult> => {\n // 检查是否在任务开始前被取消\n if (abortSignal?.aborted) {\n return {\n success: false,\n error: 'Upload cancelled',\n aborted: true,\n objectKey: fileInfos[index].objectKey,\n };\n }\n\n const presignedItem = presignedResponse.items[index];\n if (!presignedItem) {\n return {\n success: false,\n error: `No presigned URL for ${file.name}`,\n objectKey: fileInfos[index].objectKey,\n };\n }\n\n try {\n // 使用原生 fetch 上传到 COS\n const uploadResponse = await fetch(presignedItem.upload_url, {\n method: 'PUT',\n body: file,\n headers: {\n 'Content-Type': file.type || 'application/octet-stream',\n },\n signal: abortSignal, // 传入 AbortSignal 以支持取消\n });\n\n if (!uploadResponse.ok) {\n const errorText = await uploadResponse.text().catch(() => uploadResponse.statusText);\n return {\n success: false,\n error: `COS upload failed: ${uploadResponse.status} ${errorText}`,\n objectKey: presignedItem.object_key,\n };\n }\n\n this.logger?.debug(`[CosUploadService] Uploaded: ${file.name}`);\n return {\n success: true,\n url: presignedItem.download_url,\n objectKey: presignedItem.object_key,\n };\n } catch (error) {\n // 检查是否是取消导致的错误\n if (error instanceof Error && error.name === 'AbortError') {\n return {\n success: false,\n error: 'Upload cancelled',\n aborted: true,\n objectKey: presignedItem.object_key,\n };\n }\n\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n return {\n success: false,\n error: errorMessage,\n objectKey: presignedItem.object_key,\n };\n }\n });\n\n // 5. 并发执行上传任务\n const settledResults = await runWithConcurrencySettled(uploadTasks, this.uploadConcurrency);\n\n // 6. 处理结果\n const results: UploadResult[] = settledResults.map((result, index) => {\n if (result.status === 'fulfilled') {\n return result.value;\n }\n // rejected 的情况\n return {\n success: false,\n error: result.reason instanceof Error ? result.reason.message : 'Unknown error',\n objectKey: fileInfos[index].objectKey,\n };\n });\n\n const urls = results.filter(r => r.success && r.url).map(r => r.url!);\n const failedResults = results.filter(r => !r.success);\n\n if (failedResults.length > 0) {\n const failedErrors = failedResults.map(r => r.error).join('; ');\n return {\n success: false,\n error: `${failedResults.length} file(s) failed: ${failedErrors}`,\n expireSeconds: presignedResponse.expire,\n results,\n };\n }\n\n this.logger?.info(`[CosUploadService] All ${files.length} file(s) uploaded successfully`);\n return {\n success: true,\n urls,\n expireSeconds: presignedResponse.expire,\n results,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n this.logger?.error('[CosUploadService] Batch upload failed', error);\n return {\n success: false,\n error: errorMessage,\n results: files.map(() => ({ success: false, error: errorMessage })),\n };\n }\n }\n}\n\nexport default CosUploadService;\n","/**\n * Cloud Agent Provider\n *\n * REST API based agent provider that manages cloud-hosted agents.\n * Implements the AgentProvider interface for the unified agent API.\n */\n\nimport { AxiosError } from 'axios';\n\nimport { accountService } from '../../../account/index.js';\nimport type { BatchPluginOperationFailedItem, BatchPluginOperationItem, BatchPluginOperationRequest, BatchPluginOperationResult, SupportScene } from '../../../backend/types.js';\nimport { httpService } from '../../../http/index.js';\nimport type {\n AgentProvider,\n CloudAgentState,\n CreateSessionParams,\n FilesResource,\n FilesystemProvider,\n ListAgentOptions,\n ListAgentResult,\n Logger,\n PaginationInfo,\n PickFileParams,\n PickFileResponse,\n UploadFileParams,\n UploadFileResponse,\n} from '../../client/types.js';\nimport type {\n AgentStatus,\n ClientCapabilities,\n E2BSandboxConnectionInfo,\n ModelInfo\n} from '../../types.js';\nimport { LRUCache } from '../../utils/lru-cache.js';\nimport {\n ApiResponse,\n ArchiveConversationResponse,\n Conversation as ConversationDto,\n CreateConversationRequest,\n CreateConversationResponse,\n DeleteConversationRequest,\n GetConversationResponse,\n GetConversationSessionResponse,\n ListConversationRequest,\n ListConversationResponse,\n PatchConversationRequest,\n PatchConversationResponse,\n ProductConfigResponse,\n} from './api-types.js';\nimport { CloudAgentConnection } from './cloud-connection.js';\nimport { CosUploadService } from './cos-upload-service.js';\n\n/**\n * Configuration for CloudAgentProvider\n */\n/**\n * Factory function to create a FilesResource from sandbox connection info.\n * Used to inject different filesystem implementations (e.g., MiniProgramE2BFilesystem for miniprogram).\n */\nexport type FilesystemFactory = (info: E2BSandboxConnectionInfo) => Promise<FilesResource & { setReconnectFn?: (fn: () => Promise<E2BSandboxConnectionInfo>) => void }>;\n\nexport interface CloudAgentProviderOptions {\n /** Base endpoint URL for agent management API (e.g., 'https://api.example.com') */\n endpoint: string;\n /** Authorization token */\n authToken?: string;\n /** Custom headers */\n headers?: Record<string, string>;\n /** Logger instance */\n logger?: Logger;\n /** Client capabilities (sent during agent initialization) */\n clientCapabilities?: ClientCapabilities;\n /**\n * Optional filesystem factory for creating FilesResource instances.\n * If not provided, defaults to E2BFilesystem (requires e2b package).\n * Set this to MiniProgramE2BFilesystem.connect for miniprogram environments.\n */\n filesystemFactory?: FilesystemFactory;\n}\n\n/**\n * Normalize a path by resolving `.` and `..` segments\n * This is a simplified version that works in browser environment\n */\nfunction normalizePath(path: string): string {\n const segments = path.split('/');\n const result: string[] = [];\n\n for (const segment of segments) {\n if (segment === '..') {\n // Don't pop if we're at root level\n if (result.length > 0 && result[result.length - 1] !== '') {\n result.pop();\n }\n } else if (segment !== '.' && segment !== '') {\n result.push(segment);\n }\n }\n\n // Preserve leading slash for absolute paths\n return (path.startsWith('/') ? '/' : '') + result.join('/');\n}\n\n/**\n * Resolve agent:/// URI to filesystem path\n *\n * 只处理 agent:// 协议的 URI,raw path 直接透传不做任何处理\n *\n * Supported formats:\n * - `agent:///workspace/{path}` → `/workspace/{path}`\n * - `agent:///plans/{path}` → `/root/.codebuddy/plans/{path}`\n * - `agent:///{path}` → `/{path}`\n * - Raw paths (e.g. `/foo/bar`) → 直接透传,不处理\n *\n * Security: Path traversal attacks are prevented by normalizing paths\n * and verifying they stay within expected boundaries.\n */\nfunction resolveAgentUri(input: string): string {\n // 只处理 agent:// 协议,raw path 直接返回\n if (!input.startsWith('agent://')) {\n return input;\n }\n\n const path = input.slice('agent://'.length);\n if (!path.startsWith('/')) {\n return input;\n }\n\n // Normalize path to prevent traversal attacks\n const normalizedPath = normalizePath(path);\n\n // 路径映射: /plans/{path} → /root/.codebuddy/plans/{path}\n if (normalizedPath.startsWith('/plans/') || normalizedPath === '/plans') {\n const mappedPath = '/root/.codebuddy' + normalizedPath;\n // Verify the mapped path stays within /root/.codebuddy/plans\n const finalPath = normalizePath(mappedPath);\n if (!finalPath.startsWith('/root/.codebuddy/plans')) {\n throw new Error(`Invalid path: path traversal detected in ${input}`);\n }\n return finalPath;\n }\n\n return normalizedPath;\n}\n\n/**\n * Create a FilesResource wrapper that resolves agent:/// URIs\n */\nfunction createAgentFilesystem(fs: FilesResource): FilesResource {\n return {\n read: (path: string, opts?: any) => fs.read(resolveAgentUri(path), opts),\n write: (pathOrFiles: any, dataOrOpts?: any, opts?: any) => {\n if (Array.isArray(pathOrFiles)) {\n const resolved = pathOrFiles.map(f => ({ ...f, path: resolveAgentUri(f.path) }));\n return fs.write(resolved, dataOrOpts);\n }\n return fs.write(resolveAgentUri(pathOrFiles), dataOrOpts, opts);\n },\n list: (path: string, opts?: any) => fs.list(resolveAgentUri(path), opts),\n exists: (path: string, opts?: any) => fs.exists(resolveAgentUri(path), opts),\n makeDir: (path: string, opts?: any) => fs.makeDir(resolveAgentUri(path), opts),\n remove: (path: string, opts?: any) => fs.remove(resolveAgentUri(path), opts),\n rename: (oldPath: string, newPath: string, opts?: any) =>\n fs.rename(resolveAgentUri(oldPath), resolveAgentUri(newPath), opts),\n getInfo: (path: string, opts?: any) => fs.getInfo(resolveAgentUri(path), opts),\n watchDir: (path: string, onEvent: any, opts?: any) =>\n fs.watchDir(resolveAgentUri(path), onEvent, opts),\n } as FilesResource;\n}\n\n/**\n * CloudAgentProvider - Manages cloud-hosted agents via REST API\n *\n * API Endpoints (base path: /console/as):\n * - POST {endpoint}/console/as/conversations - Create new conversation\n * - GET {endpoint}/console/as/conversations/{id} - Get conversation details\n * - GET {endpoint}/console/as/conversations - List all conversations\n * - POST {endpoint}/console/as/conversations/{id}/delete - Delete conversation\n * - POST {endpoint}/console/as/conversations/{id}/archive - Archive conversation\n * - POST {endpoint}/console/as/conversations/{id} - Update conversation (rename)\n * - GET {endpoint}/console/as/conversations/{id}/session - Get conversation session (includes sandboxId)\n * - GET {endpoint}/console/enterprises/{id}/models - Get available models\n *\n * The provider stores agent endpoint configurations in the cloud backend.\n * When connect() is called, it creates a CloudAgentConnection to the agent's\n * endpoint and returns an Agent instance.\n *\n * @example\n * ```typescript\n * const provider = new CloudAgentProvider({\n * endpoint: 'https://staging-copilot.tencent.com',\n * authToken: 'token'\n * });\n *\n * // List all agents (uses default pagination and sorting)\n * const allAgents = await provider.list();\n *\n * // List agents with custom pagination\n * const page2 = await provider.list({\n * page: 2,\n * size: 50\n * });\n *\n * // List agents with filtering\n * const runningAgents = await provider.list({\n * filters: [\n * { field: 'status', value: 'running' }\n * ]\n * });\n *\n * // List agents with custom sorting\n * const sortedAgents = await provider.list({\n * sort: {\n * orderBy: 'createdAt',\n * order: 'desc'\n * }\n * });\n *\n * // List agents created in last 14 days with multiple filters\n * const recentAgents = await provider.list({\n * dayRange: 14,\n * filters: [\n * { field: 'status', value: 'running,stopped' }\n * ],\n * page: 1,\n * size: 20\n * });\n *\n * // Get agent state\n * const state = await provider.get('agent-id');\n *\n * // Connect to agent\n * const agent = await provider.connect('agent-id');\n *\n * // Use agent\n * const session = await agent.sessions.create({ cwd: '/workspace' });\n *\n * // Get available models\n * const models = await provider.getModels('my-repo');\n * ```\n */\nexport class CloudAgentProvider implements AgentProvider<CloudAgentConnection>, FilesystemProvider {\n private options: CloudAgentProviderOptions;\n private logger?: Logger;\n private requestInterceptorId: number | null = null;\n\n /** Cache for filesystem instances (keyed by agentId) */\n private filesystemCache: Map<string, FilesResource> = new Map();\n\n /** Cache for agent connections (keyed by endpoint link) */\n private connectionCache: Map<string, CloudAgentConnection> = new Map();\n\n /** COS upload service instance */\n private cosUploadService: CosUploadService;\n\n /** Event listeners for provider-level events */\n private eventListeners: Map<string, Set<(...args: any[]) => void>> = new Map();\n\n /** 产品配置缓存(内存),用于存储 deploymentType 和 creditPurchaseActions */\n private productConfigCache: ProductConfigResponse | null = null;\n\n /**\n * Plugin marketplace cache (name/id -> marketplace info)\n * LRU 缓存,容量上限 200\n * Key: marketplace name 或 id\n * Value: marketplace 完整信息\n */\n private marketplaceCache: LRUCache<string, { id: string; name: string }>;\n\n /**\n * Installed plugin cache (plugin name -> plugin info with install_id)\n * LRU 缓存,容量上限 2000\n * Key: plugin name\n * Value: plugin 完整信息(包含 installId)\n */\n private pluginCache: LRUCache<string, {\n name: string;\n marketplaceName: string;\n installId: string;\n status: string;\n description?: string;\n version?: string;\n installScope?: 'user' | 'project';\n installedScopes?: Array<'user' | 'project' | 'local' | 'project-local'>;\n }>;\n\n constructor(options: CloudAgentProviderOptions) {\n this.options = options;\n this.logger = options.logger;\n\n // 初始化 LRU 缓存\n this.marketplaceCache = new LRUCache(200); // Marketplace 上限 200\n this.pluginCache = new LRUCache(2000); // Plugin 上限 2000\n\n // 设置 baseURL(如果提供)\n if (options.endpoint) {\n httpService.setBaseURL(options.endpoint);\n }\n\n // 设置 authToken(如果提供)\n if (options.authToken) {\n httpService.setAuthToken(options.authToken);\n }\n\n // 注册请求拦截器,只注入 options 中的 headers\n if (options.headers && Object.keys(options.headers).length > 0) {\n this.requestInterceptorId = httpService.registerRequestInterceptor(config => {\n config.headers = config.headers || {};\n // 注入 options 中的自定义 headers\n Object.entries(options.headers!).forEach(([key, value]) => {\n config.headers[key] = value;\n });\n return config;\n });\n }\n\n // Initialize COS upload service\n this.cosUploadService = new CosUploadService({\n logger: this.logger,\n });\n }\n\n /**\n * Dispose the provider and clean up resources\n */\n dispose(): void {\n this.filesystemCache.clear();\n this.connectionCache.clear();\n\n // 移除注册的拦截器\n if (this.requestInterceptorId !== null) {\n httpService.ejectRequestInterceptor(this.requestInterceptorId);\n }\n }\n\n // ============================================\n // FilesystemProvider Implementation\n // ============================================\n\n /**\n * Get the filesystem provider (returns self)\n */\n get filesystem(): FilesystemProvider {\n return this;\n }\n\n /**\n * Get filesystem resource for an agent\n *\n * Creates or returns cached filesystem instance for the agent's sandbox.\n * The filesystem supports both `agent:///` URIs and raw paths.\n *\n * @param agentId - Agent ID to get filesystem for\n * @returns FilesResource instance for the agent's sandbox (with URI support)\n *\n * @example\n * ```typescript\n * const fs = await provider.getFilesystem(agentId);\n *\n * // Use agent:/// URIs\n * const content = await fs.read('agent:///files/src/app.ts');\n * await fs.write('agent:///artifacts/output.txt', 'Hello');\n *\n * // Raw paths still work (backward compatible)\n * const content2 = await fs.read('/src/app.ts');\n * ```\n */\n async getFilesystem(agentId: string): Promise<FilesResource> {\n // Check cache first\n const cached = this.filesystemCache.get(agentId);\n if (cached) {\n return cached;\n }\n\n // Get sandbox info from backend\n const info = await this.getSandboxInfo(agentId);\n\n // Create filesystem with auto-reconnect on auth failure\n let e2bFilesystem: FilesResource & { setReconnectFn?: (fn: () => Promise<E2BSandboxConnectionInfo>) => void };\n if (this.options.filesystemFactory) {\n e2bFilesystem = await this.options.filesystemFactory(info);\n } else {\n // Dynamic import to avoid pulling e2b at module load time\n const { E2BFilesystem } = await import('./e2b-filesystem.js');\n e2bFilesystem = await E2BFilesystem.connect(info);\n }\n if (e2bFilesystem.setReconnectFn) {\n e2bFilesystem.setReconnectFn(async () => {\n this.logger?.debug(`Reconnecting E2B sandbox for agent: ${agentId}`);\n const newInfo = await this.getSandboxInfo(agentId);\n this.logger?.debug(`E2B sandbox reconnected for agent: ${agentId}`);\n return newInfo;\n });\n }\n\n // Wrap with URI resolution support\n const filesystem = createAgentFilesystem(e2bFilesystem);\n\n this.filesystemCache.set(agentId, filesystem);\n\n this.logger?.debug(`Created filesystem for agent: ${agentId}`);\n return filesystem;\n }\n\n /**\n * Get sandbox information from backend\n *\n * Uses GET {endpoint}/console/as/conversations/{agentId}/session\n * to retrieve sandbox information. Extracts sandboxId from the session response\n * and constructs the apiUrl for E2B proxy.\n *\n * @param agentId - Agent ID\n * @returns E2B Sandbox connection information with sandboxId and apiUrl\n */\n private async getSandboxInfo(agentId: string): Promise<E2BSandboxConnectionInfo> {\n const apiResponse = await httpService.get<ApiResponse<GetConversationSessionResponse>>(\n `/console/as/conversations/${agentId}/session`\n );\n\n if (!apiResponse.data) {\n throw new Error('No data in API response');\n }\n\n // Build E2BSandboxConnectionInfo from session response\n // apiUrl is from response endpoint with /v2 replaced by /console\n const apiUrl = apiResponse.data.e2bEndpoint.replace(/^http:\\/\\//, 'https://').replace('/v2', '/console');\n const currentEnterpriseId = localStorage.getItem('currentEnterpriseId');\n\n return {\n sandboxId: apiResponse.data.sandboxId,\n apiUrl,\n accessToken: apiResponse.data.token,\n headers: {\n // 只有当 enterpriseId 存在时才添加该 header\n ...(currentEnterpriseId && { 'X-Enterprise-Id': currentEnterpriseId }),\n },\n };\n }\n\n /**\n * Get agent state by ID\n */\n async get(agentId: string): Promise<CloudAgentState | undefined> {\n try {\n const apiResponse = await httpService.get<ApiResponse<GetConversationResponse>>(\n `/console/as/conversations/${agentId}`\n );\n\n if (!apiResponse.data) {\n throw new Error('No data in API response');\n }\n return this.toAgentState(apiResponse.data);\n } catch (error: any) {\n // axios will throw error on 404\n if (error.response?.status === 404) {\n return undefined;\n }\n this.logger?.error(`Failed to get agent ${agentId}:`, error);\n throw error;\n }\n }\n\n /**\n * List all agent states with pagination information\n *\n * @param options - Optional query parameters for filtering, sorting, and pagination\n * @returns Object containing agents array and pagination info\n */\n async list(options?: ListAgentOptions): Promise<ListAgentResult<CloudAgentState>> {\n try {\n // Build request parameters with defaults and user overrides\n const params: ListConversationRequest = {\n // Default values\n page: 1,\n size: 30,\n sort: {\n order: 'desc',\n orderBy: 'status'\n },\n // User overrides\n ...options && {\n ...(options.dayRange !== undefined && { dayRange: options.dayRange }),\n ...(options.page !== undefined && { page: options.page }),\n ...(options.size !== undefined && { size: options.size }),\n ...(options.sort !== undefined && { sort: options.sort }),\n ...(options.filters !== undefined && { filters: options.filters }),\n ...(options.title !== undefined && { title: options.title }),\n }\n };\n\n const url = this.buildGetUrl('/console/as/conversations/', params);\n const apiResponse = await httpService.get<ApiResponse<ListConversationResponse>>(url);\n\n if (!apiResponse.data) {\n throw new Error('No data in API response');\n }\n\n const agents = apiResponse.data.conversations.map(a => this.toAgentState(a));\n const pagination: PaginationInfo = apiResponse.data.pagination;\n\n return { agents, pagination };\n } catch (error) {\n this.logger?.error('Failed to list agents:', error);\n throw error;\n }\n }\n\n /**\n * Create a new conversation\n * POST {endpoint}/console/as/conversations\n * @param params - Session params containing cwd and optional configuration\n */\n async create(params: CreateSessionParams): Promise<string> {\n try {\n const { options = {} } = params;\n\n // Extract tags from options.tags or _meta['codebuddy.ai'].tags\n // Priority: options.tags > _meta['codebuddy.ai'].tags\n const codebuddyMeta = options._meta?.['codebuddy.ai'] as { tags?: Record<string, string> } | undefined;\n const tagsObj = options.tags || codebuddyMeta?.tags;\n const tagsArray = tagsObj\n ? Object.entries(tagsObj).map(([key, value]) => `${key}:${value}`)\n : undefined;\n\n // All fields are optional in CreateConversationRequest\n const createPayload: CreateConversationRequest = {\n prompt: (options.prompt || '').slice(0, 100),\n model: options.model || 'deepseek-r1',\n ...(tagsArray && tagsArray.length > 0 ? { tags: tagsArray } : {}),\n };\n\n console.log('[CloudAgentProvider] Creating conversation with payload:', createPayload);\n\n const apiResponse = await httpService.post<ApiResponse<CreateConversationResponse>>(\n '/console/as/conversations/',\n createPayload\n );\n\n if (!apiResponse.data) {\n throw new Error('No data in API response');\n }\n\n this.logger?.info(`Created conversation: ${apiResponse.data.id}`);\n return apiResponse.data.id;\n } catch (error) {\n this.logger?.error('Failed to create conversation:', error);\n throw error;\n }\n }\n\n /**\n * Connect to an agent and return the connection\n *\n * This method:\n * 1. Fetches the agent configuration from the backend\n * 2. Checks if an existing connection can be reused (based on endpoint link)\n * 3. Creates a CloudAgentConnection to the agent's endpoint if not cached\n * 4. Saves session connection info to the connection\n * 5. Connects and initializes the connection\n * 6. Returns the connected CloudAgentConnection\n *\n * Connection caching:\n * - Connections are cached by endpoint link to enable reuse\n * - CloudAgentConnection is responsible for handling connection health checks\n * and token expiration internally\n */\n async connect(agentId: string): Promise<CloudAgentConnection> {\n // Fetch conversation session data from backend\n let sessionApiResponse: ApiResponse<GetConversationSessionResponse>;\n try {\n sessionApiResponse = await httpService.get<ApiResponse<GetConversationSessionResponse>>(\n `/console/as/conversations/${agentId}/session`\n );\n\n if (!sessionApiResponse.data) {\n throw new Error('No data in API response');\n }\n } catch (error: any) {\n // axios will throw error on 404\n if (error.response?.status === 404) {\n throw new Error(`Agent not found: ${agentId}`);\n }\n throw new Error(`Failed to get agent for connection: ${error.message}`);\n }\n\n const sessionData = sessionApiResponse.data;\n const endpoint = sessionData.link.replace(/^http:\\/\\//, 'https://');\n const cwd = sessionApiResponse.data.cwd || '/workspace';\n\n // Fetch conversation details to get name, createdAt and status\n let agentName: string | undefined;\n let agentCreatedAt: Date | undefined;\n let agentStatus: string | undefined;\n\n try {\n const agentApiResponse = await httpService.get<ApiResponse<GetConversationResponse>>(\n `/console/as/conversations/${agentId}`\n );\n if (agentApiResponse.data) {\n agentName = agentApiResponse.data.name;\n agentCreatedAt = agentApiResponse.data.createdAt ? new Date(agentApiResponse.data.createdAt) : undefined;\n // 优先使用 sessionStatus(会话状态),fallback 到 status(Agent 状态)\n agentStatus = agentApiResponse.data.sessionStatus || agentApiResponse.data.status;\n }\n } catch (error) {\n // Ignore errors when fetching conversation details (non-critical)\n this.logger?.debug(`Failed to fetch conversation details for ${agentId}:`, error);\n }\n\n // TEMP FIX: Disable connection cache to ensure GET long-polling reconnects\n // TODO: Remove this after backend implements history message push on every session/load\n const existingConnection = this.connectionCache.get(endpoint);\n if (existingConnection) {\n this.connectionCache.delete(endpoint);\n // Clean up old connection to prevent ghost SSE connections on the server\n existingConnection.removeAllListeners();\n existingConnection.disconnect().catch(err => {\n this.logger?.debug('Failed to disconnect old connection:', err);\n });\n }\n\n // Prepare client capabilities with cwd in _meta (consistent with LocalAgentProvider)\n const clientCapabilities = {\n ...this.options.clientCapabilities,\n _meta: {\n ...this.options.clientCapabilities?._meta,\n 'codebuddy.ai': {\n ...this.options.clientCapabilities?._meta?.['codebuddy.ai'],\n cwd,\n }\n }\n };\n\n // Create connection to agent's endpoint\n // Note: CloudAgentConnection is responsible for:\n // - Connection health checks (reconnection on disconnect)\n // - Token expiration handling (refresh or re-authentication)\n const connection = new CloudAgentConnection(sessionData.sessionId || agentId, {\n endpoint,\n authToken: sessionData.token,\n // Backend does not provide custom headers currently\n // headers: data.headers,\n logger: this.logger,\n clientCapabilities\n }, cwd);\n\n // Save session connection info to the connection\n connection.setSessionConnectionInfo({\n sessionId: sessionData.sessionId,\n agentId: sessionData.id,\n link: sessionData.link,\n token: sessionData.token,\n sandboxId: sessionData.sandboxId,\n expireAt: sessionData.expireAt,\n cwd\n });\n\n // Connect and initialize\n try {\n await connection.connect();\n } catch (error) {\n this.logger?.error(`Failed to connect to agent ${agentId}:`, error);\n throw error;\n }\n\n // Cache the connection\n this.connectionCache.set(endpoint, connection);\n\n // Clean up cache when connection is disconnected\n connection.once('disconnected', () => {\n this.connectionCache.delete(endpoint);\n this.logger?.debug(`Connection removed from cache: ${endpoint}`);\n });\n\n this.logger?.info(`Connected to agent: ${agentId}`);\n\n // Emit sessionCreated event for agent-new-adapter to create conversation\n // SessionInfo format: Use agentId as both id and agentId (1:1 mapping per SessionManager)\n this.emitEvent('sessionCreated', {\n id: agentId, // Use agentId as sessionId (1:1 mapping in current design)\n agentId: agentId,\n name: agentName,\n status: agentStatus as AgentStatus,\n cwd: cwd,\n createdAt: agentCreatedAt\n });\n\n return connection;\n }\n\n /**\n * Delete a conversation by ID\n * POST {endpoint}/console/as/conversations/{agentId}/delete\n */\n async delete(agentId: string): Promise<boolean> {\n try {\n const requestBody: DeleteConversationRequest = { id: agentId };\n await httpService.post(\n `/console/as/conversations/${agentId}/delete`,\n requestBody\n );\n\n return true;\n } catch (error: any) {\n // axios will throw error on 404\n if (error.response?.status === 404) {\n return false;\n }\n this.logger?.error(`Failed to delete conversation ${agentId}:`, error);\n throw error;\n }\n }\n\n /**\n * Archive a conversation by ID\n * POST {endpoint}/console/as/conversations/{agentId}/archive\n *\n * @param agentId - Conversation ID to archive\n * @returns ArchiveConversationResponse containing the archived conversation ID\n *\n * @example\n * ```typescript\n * const result = await provider.archive('agent-123');\n * console.log('Archived conversation:', result.id);\n * ```\n */\n async archive(agentId: string): Promise<ArchiveConversationResponse> {\n try {\n const apiResponse = await httpService.post<ApiResponse<ArchiveConversationResponse>>(\n `/console/as/conversations/${agentId}/archive`\n );\n\n if (!apiResponse.data) {\n // 如果后端没有返回 data,使用传入的 agentId\n this.logger?.info(`Archived conversation: ${agentId}`);\n return { id: agentId };\n }\n\n this.logger?.info(`Archived conversation: ${apiResponse.data.id}`);\n return apiResponse.data;\n } catch (error) {\n this.logger?.error(`Failed to archive conversation ${agentId}:`, error);\n throw error;\n }\n }\n\n /**\n * Rename a conversation by ID\n * POST {endpoint}/console/as/conversations/{agentId}\n *\n * @param agentId - Conversation ID to rename\n * @param title - New title for the conversation\n * @returns PatchConversationResponse containing the renamed conversation ID\n *\n * @example\n * ```typescript\n * const result = await provider.rename('agent-123', 'New Title');\n * console.log('Renamed conversation:', result.id);\n * ```\n */\n async rename(agentId: string, title: string): Promise<PatchConversationResponse> {\n try {\n const body: PatchConversationRequest = { title };\n const apiResponse = await httpService.post<ApiResponse<PatchConversationResponse>>(\n `/console/as/conversations/${agentId}`,\n body\n );\n\n if (!apiResponse.data) {\n // 如果后端没有返回 data,使用传入的 agentId\n this.logger?.info(`Renamed conversation: ${agentId} to \"${title}\"`);\n return { id: agentId };\n }\n\n this.logger?.info(`Renamed conversation: ${apiResponse.data.id} to \"${title}\"`);\n return apiResponse.data;\n } catch (error) {\n this.logger?.error(`Failed to rename conversation ${agentId}:`, error);\n throw error;\n }\n }\n\n /**\n * Update conversation status by ID\n * POST {endpoint}/console/as/conversations/{agentId}\n *\n * @param agentId - Conversation ID to update\n * @param status - New status for the conversation\n * @returns PatchConversationResponse containing the updated conversation ID\n *\n * @example\n * ```typescript\n * const result = await provider.updateStatus('agent-123', 'completed');\n * console.log('Updated conversation status:', result.id);\n * ```\n */\n async updateStatus(agentId: string, status: string): Promise<PatchConversationResponse> {\n try {\n const body: PatchConversationRequest = { status: status as any };\n const apiResponse = await httpService.post<ApiResponse<PatchConversationResponse>>(\n `/console/as/conversations/${agentId}`,\n body\n );\n\n if (!apiResponse.data) {\n this.logger?.info(`Updated conversation status: ${agentId} to \"${status}\"`);\n return { id: agentId };\n }\n\n this.logger?.info(`Updated conversation status: ${apiResponse.data.id} to \"${status}\"`);\n return apiResponse.data;\n } catch (error) {\n this.logger?.error(`Failed to update conversation status ${agentId}:`, error);\n throw error;\n }\n }\n\n /**\n * Get available models from product configuration\n *\n * GET {endpoint}/console/enterprises/{personal|enterpriseId}/models?repos[]={repo}\n *\n * This method fetches the models from /console/enterprises API\n * and extracts the models array from the response.\n *\n * @param repo - Optional repository URL for context-specific config\n * @returns Array of ModelInfo with full model details\n */\n async getModels(repo?: string): Promise<ModelInfo[]> {\n try {\n // Get user info from accountService to determine personal vs enterprise account\n const account = accountService.getAccount();\n\n // Check if user is logged in\n if (!account) {\n this.logger?.warn('[CloudAgentProvider] No account info available, cannot get models');\n return [];\n }\n\n // Determine account type: personal or enterprise\n const accountIdentifier = account.enterpriseId || 'personal';\n\n // Build URL with new console API format\n let url = `/console/enterprises/${accountIdentifier}/models`;\n if (repo) {\n // Keep same parameter format: ?repos[]=encoded_repo_url\n url += `?repos[]=${encodeURIComponent(repo)}`;\n }\n\n // Build custom headers specific to this request\n // Note: Authorization, X-User-Id, X-Enterprise-Id, X-Tenant-Id, X-Product, X-User-Agent\n // are already added by the request interceptor\n const headers: Record<string, string> = {\n 'Accept': 'application/json, text/plain, */*',\n 'X-Requested-With': 'XMLHttpRequest',\n 'X-Request-ID': this.generateRequestId(),\n };\n\n this.logger?.debug(`[CloudAgentProvider] GET ${url}`);\n\n // Parse response - expecting { data: ProductConfiguration }\n const apiResponse = await httpService.get<ApiResponse<ProductConfigResponse>>(url, {\n headers\n });\n if (!apiResponse.data) {\n this.logger?.warn('[CloudAgentProvider] No data in config response, returning empty models');\n return [];\n }\n\n // 🆕 缓存完整的产品配置数据到内存\n this.productConfigCache = apiResponse.data;\n\n // Extract models and agents from product configuration\n const productConfig = apiResponse.data;\n const allModels = productConfig.models ?? [];\n const agents = productConfig.agents ?? [];\n\n // Find the 'cli' agent and get its model IDs\n const cliAgent = agents.find(agent => agent.name === 'cli');\n const cliModelIds = cliAgent?.models ?? [];\n\n // Filter models to only include those available for the 'cli' agent\n // If no cli agent found or cli agent has no models, fall back to all models\n const filteredModels = cliModelIds.length > 0\n ? allModels.filter(model => cliModelIds.includes(model.id))\n : allModels;\n\n this.logger?.info(`[CloudAgentProvider] Retrieved ${filteredModels.length} models for cli agent (total: ${allModels.length})`);\n\n // Convert LanguageModel to ModelInfo\n return filteredModels.map((model): ModelInfo => ({\n id: model.id,\n name: model.name ?? model.id,\n description: model.description,\n credits: model.credits,\n configurable: model.configurable,\n configured: model.configured,\n isDefault: model.isDefault,\n supportsImages: model.supportsImages,\n supportsReasoning: model.supportsReasoning,\n onlyReasoning: model.onlyReasoning,\n disabledMultimodal: model.disabledMultimodal,\n disabled: model.disabled,\n disabledReason: model.disabledReason,\n disabledAction: model.disabledAction,\n }));\n } catch (error) {\n this.logger?.error('[CloudAgentProvider] Failed to get models:', error);\n throw error;\n }\n }\n\n /**\n * 获取产品部署类型(从缓存)\n * 需要先调用 getModels() 初始化缓存\n *\n * @returns 部署类型:'SaaS' | 'Cloud-Hosted' | 'Self-Hosted',默认为 'SaaS'\n */\n getDeploymentType(): string {\n return this.productConfigCache?.deploymentType ?? 'SaaS';\n }\n\n /**\n * 获取 Credit 购买引导配置(从缓存)\n * 需要先调用 getModels() 初始化缓存\n *\n * @returns Credit 购买引导配置,key 为错误码。如果后端未返回,则使用默认配置\n */\n getCreditPurchaseActions(): Record<string, {\n labelZh: string;\n labelEn: string;\n url: string;\n showButton?: boolean;\n }> {\n // 默认配置\n const defaultActions = {\n '14018': {\n labelZh: '获取 Credits',\n labelEn: 'Get credits',\n url: 'https://www.codebuddy.cn/profile/plan',\n showButton: true,\n },\n '6004': {\n labelZh: '升级专业版',\n labelEn: 'Upgrade to Pro',\n url: 'https://www.codebuddy.cn/profile/plan',\n showButton: true,\n },\n '6005': {\n labelZh: '升级专业版',\n labelEn: 'Upgrade to Pro',\n url: 'https://www.codebuddy.cn/profile/plan',\n showButton: true,\n },\n };\n\n // 返回后端配置,如果没有则返回默认配置\n return this.productConfigCache?.config?.creditPurchaseActions ?? defaultActions;\n }\n\n /**\n * Generate a unique request ID\n */\n private generateRequestId(): string {\n // Generate UUID without dashes\n return 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'.replace(/x/g, () =>\n Math.floor(Math.random() * 16).toString(16)\n );\n }\n\n // ============================================\n // File Picker (Browser Environment)\n // ============================================\n\n /**\n * Common image MIME types for filtering\n */\n private static readonly IMAGE_MIME_TYPES = [\n 'image/png',\n 'image/jpeg',\n 'image/jpg',\n 'image/gif',\n 'image/webp',\n 'image/svg+xml',\n 'image/bmp',\n ];\n\n /**\n * Pick files using browser's native file input\n *\n * @param params - File picker parameters\n * @returns Response with selected file paths (filenames in browser)\n */\n async pickFile(params?: PickFileParams): Promise<PickFileResponse> {\n return new Promise(resolve => {\n const input = document.createElement('input');\n input.type = 'file';\n input.style.display = 'none';\n\n // Set accept attribute\n if (params?.filters && params.filters.length > 0) {\n const acceptTypes: string[] = [];\n for (const filter of params.filters) {\n for (const ext of filter.extensions) {\n const mimeType = this.extensionToMimeType(ext);\n acceptTypes.push(mimeType || `.${ext}`);\n }\n }\n input.accept = acceptTypes.join(',');\n } else {\n input.accept = CloudAgentProvider.IMAGE_MIME_TYPES.join(',');\n }\n\n input.multiple = params?.canSelectMany ?? false;\n\n input.onchange = () => {\n const files = input.files;\n if (!files || files.length === 0) {\n resolve({ files: [], canceled: true });\n } else {\n const fileArray = Array.from(files);\n this.logger?.info(`Picked ${fileArray.length} file(s)`);\n resolve({ files: fileArray, canceled: false });\n }\n document.body.removeChild(input);\n };\n\n input.oncancel = () => {\n resolve({ files: [], canceled: true });\n document.body.removeChild(input);\n };\n\n document.body.appendChild(input);\n input.click();\n });\n }\n\n /**\n * Convert file extension to MIME type\n */\n private extensionToMimeType(ext: string): string | null {\n const extLower = ext.toLowerCase().replace(/^\\./, '');\n const mimeMap: Record<string, string> = {\n 'png': 'image/png',\n 'jpg': 'image/jpeg',\n 'jpeg': 'image/jpeg',\n 'gif': 'image/gif',\n 'webp': 'image/webp',\n 'svg': 'image/svg+xml',\n 'bmp': 'image/bmp',\n 'ico': 'image/x-icon',\n };\n return mimeMap[extLower] || null;\n }\n\n // ============================================\n // File Upload (Browser Environment)\n // ============================================\n\n /**\n * Upload files to cloud storage via COS presigned URL\n *\n * @param params - files array (File objects in browser), optional abortSignal\n * @returns Response with corresponding cloud URLs\n */\n async uploadFile(params: UploadFileParams): Promise<UploadFileResponse> {\n this.logger?.info(`[CloudAgentProvider] uploadFile called for ${params.files.length} file(s)`);\n\n // Filter out string paths (only File objects are supported in browser)\n const files = params.files.filter((f): f is File => typeof f !== 'string');\n if (files.length === 0) {\n return {\n success: false,\n error: 'No valid File objects provided',\n };\n }\n\n // Use CosUploadService for actual upload, passing abortSignal\n const result = await this.cosUploadService.uploadFiles(files, params.abortSignal);\n\n return {\n success: result.success,\n urls: result.urls,\n expireSeconds: result.expireSeconds,\n error: result.error,\n aborted: result.aborted,\n };\n }\n\n // ============================================\n // Event Emitter Implementation\n // ============================================\n\n /**\n * Register event listener\n * @param event - Event name\n * @param handler - Event handler function\n */\n on(event: string, handler: (...args: any[]) => void): () => void {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, new Set());\n }\n this.eventListeners.get(event)!.add(handler);\n\n // Return unsubscribe function\n return () => {\n this.off(event, handler);\n };\n }\n\n /**\n * Unregister event listener\n * @param event - Event name\n * @param handler - Event handler function\n */\n off(event: string, handler: (...args: any[]) => void): void {\n const listeners = this.eventListeners.get(event);\n if (listeners) {\n listeners.delete(handler);\n }\n }\n\n /**\n * Emit event to all registered listeners\n * @param event - Event name\n * @param args - Event arguments\n */\n private emitEvent(event: string, ...args: any[]): void {\n const listeners = this.eventListeners.get(event);\n if (listeners && listeners.size > 0) {\n this.logger?.debug(`Emitting event: ${event}`, args);\n for (const handler of listeners) {\n try {\n handler(...args);\n } catch (error) {\n this.logger?.error(`Error in event handler for ${event}:`, error);\n }\n }\n }\n }\n\n // ============================================\n // Support Scenes\n // ============================================\n\n /**\n * 获取支持的场景列表\n * API 端点: GET /v2/as/support/scenes (不鉴权)\n * 用于 Welcome 页面的 QuickActions 快捷操作\n *\n * @param locale - 可选,语言环境(如 'zh-CN', 'en-US'),用于获取对应语言的场景数据\n * @returns Promise<SupportScene[]> 支持的场景列表\n */\n async getSupportScenes(locale?: string): Promise<SupportScene[]> {\n try {\n const url = this.buildGetUrl('/v2/as/support/scenes', locale ? { locale } : undefined);\n\n const apiResponse = await httpService.get<ApiResponse<{ scenes: SupportScene[] }>>(\n url\n );\n\n if (!apiResponse.data) {\n this.logger?.warn('[CloudAgentProvider] No data in support scenes response');\n return [];\n }\n\n const scenes = apiResponse.data.scenes || [];\n this.logger?.info(`[CloudAgentProvider] Retrieved ${scenes.length} support scenes${locale ? ` for locale: ${locale}` : ''}`);\n return scenes;\n } catch (error) {\n this.logger?.error('[CloudAgentProvider] Failed to get support scenes:', error);\n return [];\n }\n }\n\n // ============================================\n // Helpers\n // ============================================\n\n private toAgentState(data: ConversationDto): CloudAgentState {\n // 优先使用 sessionStatus(会话状态),fallback 到 status(Agent 状态)\n const status = data.sessionStatus || data.status;\n return {\n id: data.id,\n name: data.name,\n description: data.summary,\n type: 'cloud',\n status: status as AgentStatus,\n createdAt: data.createdAt ? new Date(data.createdAt) : undefined,\n updatedAt: data.updatedAt ? new Date(data.updatedAt) : undefined,\n capabilities: this.options.clientCapabilities,\n isUserDefinedTitle: data.isUserDefinedTitle,\n };\n }\n\n /**\n * Helper: 将 GET 请求的 body 转换为 URL 查询参数\n */\n private buildGetUrl(path: string, params?: unknown): string {\n if (!params) {\n return path;\n }\n\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(params as Record<string, unknown>)) {\n if (value !== undefined && value !== null) {\n const stringValue = typeof value === 'object'\n ? JSON.stringify(value)\n : String(value);\n searchParams.append(key, stringValue);\n }\n }\n\n const queryString = searchParams.toString();\n return queryString ? `${path}?${queryString}` : path;\n }\n\n // ========================================================================\n // Plugin Management\n // ========================================================================\n\n /**\n * 获取已安装插件列表\n * GET /console/as/user/plugins/installed\n */\n async getInstalledPlugins(forceRefresh?: boolean): Promise<Array<{\n name: string;\n marketplaceName: string;\n status: string;\n description?: string;\n version?: string;\n installScope?: 'user' | 'project';\n installedScopes?: Array<'user' | 'project' | 'local' | 'project-local'>;\n installId?: string;\n }>> {\n try {\n const response = await httpService.get<ApiResponse<{\n plugins: Array<{\n id: string; // 后端返回的是 id,不是 install_id\n plugin_name: string;\n marketplace_name: string;\n enabled: boolean;\n description?: string;\n version?: string;\n scope: string;\n status: string;\n }>;\n }>>('/console/as/user/plugins/installed');\n\n const plugins = response.data?.plugins || [];\n const result = plugins.map(p => ({\n name: p.plugin_name,\n marketplaceName: p.marketplace_name,\n status: p.enabled ? 'enabled' : 'disabled',\n description: p.description,\n version: p.version,\n installScope: (p.scope === 'local' ? 'project' : p.scope) as 'user' | 'project',\n installedScopes: [p.scope as 'user' | 'project' | 'local'],\n installId: p.id\n }));\n\n // 缓存插件列表(key = plugin name)\n result.forEach(plugin => {\n this.pluginCache.set(plugin.name, plugin);\n });\n\n return result;\n } catch (error) {\n this.logger?.error('[CloudAgentProvider] getInstalledPlugins failed:', error);\n throw error;\n }\n }\n\n /**\n * 安装插件\n * POST /console/as/user/plugins/install\n *\n * @param pluginNames - 插件名称数组\n * @param marketplaceNameOrId - 市场名称或 ID\n */\n async installPlugins(\n pluginNames: string[],\n marketplaceNameOrId: string,\n installScope?: 'user' | 'project' | 'project-local',\n marketplaceSource?: string,\n workspacePath?: string\n ): Promise<{ success: boolean; error?: string }> {\n try {\n // 从缓存获取 marketplace ID\n const marketplaceId = await this.findMarketplaceId(marketplaceNameOrId);\n if (!marketplaceId) {\n return {\n success: false,\n error: `Marketplace not found: ${marketplaceNameOrId}`\n };\n }\n\n // 并发安装多个插件\n const results = await Promise.allSettled(\n pluginNames.map(pluginName =>\n httpService.post('/console/as/user/plugins/install', {\n plugin_name: pluginName,\n marketplace_id: marketplaceId,\n version: 'latest'\n })\n )\n );\n\n const failed = results.filter(r => r.status === 'rejected');\n if (failed.length > 0) {\n const errors = failed.map((r: any) => r.reason?.message || 'Unknown error');\n return {\n success: false,\n error: `安装失败 ${failed.length} 个插件: ${errors.join(', ')}`\n };\n }\n\n return { success: true };\n } catch (error) {\n return {\n success: false,\n error: this.extractErrorMessage(error)\n };\n }\n }\n\n /**\n * 卸载插件\n * POST /console/as/user/plugins/installed/:id/uninstall\n *\n * 完整链路:\n * CloudAgentProvider.uninstallPlugin()\n * -> HTTP POST /console/as/user/plugins/installed/:id/uninstall\n * -> agentserver: PluginInstallService.Uninstall()\n * -> 软删除 DB + 异步同步到活跃沙箱\n *\n * @param pluginName - 插件名称\n * @param marketplaceName - 市场名称(用于标识唯一插件)\n * @param scope - 卸载范围 ('user' | 'project' | 'project-local')\n */\n async uninstallPlugin(\n pluginName: string,\n marketplaceName: string,\n scope: 'user' | 'project' | 'project-local'\n ): Promise<{ success: boolean; error?: string }> {\n try {\n // 从缓存获取 installId\n const installId = await this.findPluginInstallId(pluginName);\n if (!installId) {\n return {\n success: false,\n error: `Plugin not found or not installed: ${pluginName}`\n };\n }\n\n // 调用后端 API 卸载插件\n // 注意:根据文档,卸载 API 可能不需要 body 参数,:id 已经唯一标识了安装记录\n await httpService.post(`/console/as/user/plugins/installed/${installId}/uninstall`);\n\n return { success: true };\n } catch (error) {\n return {\n success: false,\n error: this.extractErrorMessage(error)\n };\n }\n }\n\n /**\n * 获取插件市场列表\n * GET /console/as/marketplace/sources\n */\n async getPluginMarketplaces(forceRefresh?: boolean): Promise<Array<{\n id: string;\n name: string;\n type: 'github' | 'local' | 'custom';\n source: { repo?: string; ref?: string; url?: string };\n description?: string;\n isBuiltin?: boolean;\n }>> {\n try {\n const response = await httpService.get<ApiResponse<{\n sources: Array<{\n id: string;\n name: string;\n url: string;\n source_type: string;\n status: string;\n is_default: boolean;\n created_at: string;\n }>;\n }>>('/console/as/marketplace/sources');\n\n const sources = response.data?.sources || [];\n const result = sources.map(src => ({\n id: src.id,\n name: src.name,\n type: this.mapSourceType(src.source_type),\n source: { url: src.url },\n description: src.name,\n isBuiltin: src.is_default\n }));\n\n // 缓存市场列表(同时用 name 和 id 作为 key)\n result.forEach(m => {\n const marketplaceInfo = { id: m.id, name: m.name };\n this.marketplaceCache.set(m.name, marketplaceInfo);\n this.marketplaceCache.set(m.id, marketplaceInfo);\n });\n\n return result;\n } catch (error) {\n this.logger?.error('[CloudAgentProvider] getPluginMarketplaces failed:', error);\n throw error;\n }\n }\n\n /**\n * 获取市场下的插件列表\n * - 有 searchText: GET /console/as/marketplace/plugins/search (跨所有市场搜索)\n * - 无 searchText: GET /console/as/marketplace/plugins (指定市场)\n *\n * @param marketplaceNameOrId - 市场名称或 ID(优先使用 ID,如果是名称则从缓存查询 ID)\n * @param forceRefresh - 是否强制刷新\n * @param searchText - 搜索关键字(如果提供,则跨所有市场搜索)\n */\n async getMarketplacePlugins(\n marketplaceNameOrId: string,\n forceRefresh?: boolean,\n searchText?: string\n ): Promise<Array<{\n name: string;\n marketplaceName: string;\n description?: string;\n version?: string;\n author?: string;\n homepage?: string;\n iconUrl?: string;\n tags?: string[];\n installed?: boolean;\n status?: 'enabled' | 'disabled' | 'not-installed';\n installedScopes?: Array<'user' | 'project'>;\n hasUpdate?: boolean;\n latestVersion?: string;\n agents?: any;\n commands?: any;\n skills?: any;\n mcpServers?: any;\n hooks?: any;\n rules?: any;\n }>> {\n try {\n // 如果有搜索关键字,使用跨市场搜索接口\n if (searchText) {\n const response = await httpService.get<ApiResponse<{\n plugins: Array<{\n name: string;\n display_name: string;\n description?: string;\n version?: string;\n icon_url?: string;\n marketplace_name: string;\n tags?: string | string[];\n capabilities?: string;\n installed?: boolean;\n enabled?: boolean;\n installed_scope?: string;\n }>;\n }>>('/console/as/marketplace/plugins/search', {\n params: {\n q: searchText,\n page: 1,\n page_size: 100\n }\n });\n\n const plugins = response.data?.plugins || [];\n return plugins.map(p => this.mapPluginData(p));\n }\n\n // 无搜索关键字,获取指定市场的插件列表\n const sourceId = await this.findMarketplaceId(marketplaceNameOrId);\n if (!sourceId) {\n this.logger?.warn(`[CloudAgentProvider] Marketplace not found: ${marketplaceNameOrId}`);\n return [];\n }\n\n const params: any = {\n source_id: sourceId,\n page: 1,\n page_size: 100\n };\n\n const response = await httpService.get<ApiResponse<{\n plugins: Array<{\n name: string;\n display_name: string;\n description?: string;\n version?: string;\n icon_url?: string;\n marketplace_name: string;\n tags?: string | string[];\n capabilities?: string;\n installed?: boolean;\n enabled?: boolean;\n installed_scope?: string;\n }>;\n }>>('/console/as/marketplace/plugins', { params });\n\n const plugins = response.data?.plugins || [];\n return plugins.map(p => this.mapPluginData(p));\n } catch (error) {\n this.logger?.error('[CloudAgentProvider] getMarketplacePlugins failed:', error);\n throw error;\n }\n }\n\n /**\n * 获取插件详情\n * GET /console/as/marketplace/plugins/:name/detail\n *\n * @param pluginName - 插件名称\n * @param marketplaceNameOrId - 市场名称或 ID(优先使用 ID,如果是名称则从缓存查询 ID)\n */\n async getPluginDetail(\n pluginName: string,\n marketplaceNameOrId: string\n ): Promise<{\n name: string;\n marketplaceName: string;\n description?: string;\n version?: string;\n author?: string;\n homepage?: string;\n iconUrl?: string;\n tags?: string[];\n installed?: boolean;\n status?: 'enabled' | 'disabled' | 'not-installed';\n installedScopes?: Array<'user' | 'project'>;\n readme?: string;\n configSchema?: Record<string, unknown>;\n tools?: Array<{ name: string; description?: string }>;\n resources?: Array<{ name: string; description?: string }>;\n prompts?: Array<{ name: string; description?: string }>;\n downloadCount?: number;\n lastUpdated?: string;\n license?: string;\n repositoryUrl?: string;\n } | null> {\n try {\n // 从缓存获取 marketplace ID\n const sourceId = await this.findMarketplaceId(marketplaceNameOrId);\n if (!sourceId) {\n this.logger?.warn(`[CloudAgentProvider] Marketplace not found: ${marketplaceNameOrId}`);\n return null;\n }\n\n const response = await httpService.get<ApiResponse<{\n plugin: {\n name: string;\n display_name: string;\n description?: string;\n version?: string;\n icon_url?: string;\n marketplace_name: string;\n tags?: string;\n capabilities?: string;\n installed?: boolean;\n enabled?: boolean;\n readme?: string;\n author?: string;\n homepage?: string;\n repository_url?: string;\n license?: string;\n };\n }>>(`/console/as/marketplace/plugins/${pluginName}/detail`, {\n params: { source_id: sourceId }\n });\n\n const p = response.data?.plugin;\n if (!p) {return null;}\n\n const capabilities = p.capabilities ? this.parseCapabilities(p.capabilities) : {};\n const tags = p.tags ? JSON.parse(p.tags) : [];\n\n return {\n name: p.name,\n marketplaceName: p.marketplace_name,\n description: p.description,\n version: p.version,\n iconUrl: p.icon_url,\n tags,\n installed: p.installed,\n status: p.enabled ? 'enabled' : (p.installed ? 'disabled' : 'not-installed'),\n readme: p.readme,\n author: p.author,\n homepage: p.homepage,\n repositoryUrl: p.repository_url,\n license: p.license,\n ...capabilities\n };\n } catch (error) {\n this.logger?.error('[CloudAgentProvider] getPluginDetail failed:', error);\n throw error;\n }\n }\n\n /**\n * 添加插件市场\n * POST /console/as/marketplace/sources\n */\n async addPluginMarketplace(\n sourceUrl: string,\n name?: string\n ): Promise<{\n success: boolean;\n error?: string;\n marketplace?: {\n id: string;\n name: string;\n type: 'github' | 'local' | 'custom';\n source: { repo?: string; ref?: string; url?: string };\n description?: string;\n isBuiltin?: boolean;\n };\n }> {\n try {\n const body = {\n source_type: sourceUrl.startsWith('http') ? 'url' : 'github',\n url: sourceUrl,\n name: name || sourceUrl\n };\n\n const response = await httpService.post<ApiResponse<{\n source: {\n id: string;\n name: string;\n url: string;\n source_type: string;\n status: string;\n is_default: boolean;\n created_at: string;\n };\n }>>('/console/as/marketplace/sources', body);\n\n const sourceData = response.data?.source;\n if (!sourceData) {\n throw new Error('Invalid response from server');\n }\n\n // 缓存新添加的 marketplace(同时用 name 和 id 作为 key)\n const marketplaceInfo = { id: sourceData.id, name: sourceData.name };\n this.marketplaceCache.set(sourceData.name, marketplaceInfo);\n this.marketplaceCache.set(sourceData.id, marketplaceInfo);\n\n return {\n success: true,\n marketplace: {\n id: sourceData.id,\n name: sourceData.name,\n type: this.mapSourceType(sourceData.source_type),\n source: { url: sourceData.url },\n isBuiltin: sourceData.is_default\n }\n };\n } catch (error) {\n return {\n success: false,\n error: this.extractErrorMessage(error)\n };\n }\n }\n\n /**\n * 删除插件市场\n * POST /console/as/marketplace/sources/:id/delete\n */\n async removePluginMarketplace(marketplaceNameOrId: string): Promise<{ success: boolean; error?: string }> {\n try {\n // 从缓存获取 marketplace ID\n const marketplaceId = await this.findMarketplaceId(marketplaceNameOrId);\n if (!marketplaceId) {\n return {\n success: false,\n error: `Marketplace not found: ${marketplaceNameOrId}`\n };\n }\n\n await httpService.post(`/console/as/marketplace/sources/${marketplaceId}/delete`, {});\n\n return { success: true };\n } catch (error) {\n return {\n success: false,\n error: this.extractErrorMessage(error)\n };\n }\n }\n\n /**\n * 刷新插件市场\n * POST /console/as/marketplace/sources/:id/check-updates\n */\n async refreshPluginMarketplace(marketplaceNameOrId: string): Promise<{\n success: boolean;\n error?: string;\n plugins?: Array<any>;\n }> {\n try {\n // 从缓存获取 marketplace ID\n const marketplaceId = await this.findMarketplaceId(marketplaceNameOrId);\n if (!marketplaceId) {\n return {\n success: false,\n error: `Marketplace not found: ${marketplaceNameOrId}`\n };\n }\n\n const response = await httpService.post<ApiResponse<{\n has_updates: boolean;\n updated_plugins?: Array<any>;\n }>>(`/console/as/marketplace/sources/${marketplaceId}/check-updates`, {});\n\n return {\n success: true,\n plugins: response.data?.updated_plugins || []\n };\n } catch (error) {\n return {\n success: false,\n error: this.extractErrorMessage(error)\n };\n }\n }\n\n /**\n * 批量切换插件启用/禁用状态\n * POST /console/as/user/plugins/installed/:id/toggle\n */\n async batchTogglePlugins(request: BatchPluginOperationRequest): Promise<BatchPluginOperationResult> {\n try {\n const results = await Promise.allSettled(\n request.items.map(async item => {\n // 从缓存获取 install_id\n const installId = await this.findPluginInstallId(item.pluginName);\n if (!installId) {\n throw new Error(`Plugin not found or not installed: ${item.pluginName}`);\n }\n\n const enabled = item.operation === 'enable';\n await httpService.post(\n `/console/as/user/plugins/installed/${installId}/toggle`,\n { enabled }\n );\n\n return item;\n })\n );\n\n const succeededPlugins: BatchPluginOperationItem[] = [];\n const failedPlugins: BatchPluginOperationFailedItem[] = [];\n\n results.forEach((r, i) => {\n const item = request.items[i];\n if (r.status === 'fulfilled') {\n succeededPlugins.push(item);\n } else {\n failedPlugins.push({\n ...item,\n error: (r as any).reason?.message || 'Unknown error'\n });\n }\n });\n\n return {\n success: failedPlugins.length === 0,\n succeededPlugins,\n failedPlugins\n };\n } catch (error) {\n return {\n success: false,\n succeededPlugins: [],\n failedPlugins: request.items.map(item => ({\n ...item,\n error: this.extractErrorMessage(error)\n }))\n };\n }\n }\n\n // ========================================================================\n // Plugin Helper Methods\n // ========================================================================\n\n /**\n * 将后端插件数据映射为前端格式\n */\n private mapPluginData(p: {\n name: string;\n display_name: string;\n description?: string;\n version?: string;\n icon_url?: string;\n marketplace_name: string;\n tags?: string | string[]; // 可能是字符串、JSON字符串或数组\n capabilities?: string;\n installed?: boolean;\n enabled?: boolean;\n installed_scope?: string;\n }): any {\n const capabilities = p.capabilities ? this.parseCapabilities(p.capabilities) : {};\n\n // 处理 tags:可能是数组、JSON 字符串数组,或逗号分隔的字符串\n let tags: string[] = [];\n if (p.tags) {\n if (Array.isArray(p.tags)) {\n // 已经是数组\n tags = p.tags;\n } else if (typeof p.tags === 'string') {\n try {\n // 尝试作为 JSON 解析\n const parsed = JSON.parse(p.tags);\n tags = Array.isArray(parsed) ? parsed : [parsed];\n } catch {\n // 如果不是 JSON,作为逗号分隔的字符串处理\n tags = p.tags.split(',').map(t => t.trim()).filter(t => t);\n }\n }\n }\n\n return {\n name: p.name,\n marketplaceName: p.marketplace_name,\n description: p.description,\n version: p.version,\n iconUrl: p.icon_url,\n tags,\n installed: p.installed,\n status: p.enabled ? 'enabled' : (p.installed ? 'disabled' : 'not-installed'),\n installedScopes: p.installed ? [p.installed_scope as 'user' | 'project'] : [],\n ...capabilities\n };\n }\n\n /**\n * 从缓存中查找插件的 install_id\n * 如果缓存未命中,则调用 API 获取并缓存\n *\n * @param pluginName - 插件名称\n * @returns install_id 或 null\n */\n private async findPluginInstallId(pluginName: string): Promise<string | null> {\n // 先从缓存找\n const cached = this.pluginCache.get(pluginName);\n if (cached) {\n return cached.installId;\n }\n\n // 缓存未命中,调用 API 获取(会自动填充缓存)\n await this.getInstalledPlugins();\n\n const cachedAfterRefresh = this.pluginCache.get(pluginName);\n return cachedAfterRefresh?.installId || null;\n }\n\n /**\n * 从缓存中查找 marketplace ID\n * 如果缓存未命中,则调用 API 获取并缓存\n */\n private async findMarketplaceId(nameOrId: string): Promise<string | null> {\n // 先从缓存找\n const cached = this.marketplaceCache.get(nameOrId);\n if (cached) {\n return cached.id;\n }\n\n // 缓存未命中,调用 API 获取(会自动填充缓存)\n await this.getPluginMarketplaces();\n const cachedAfterRefresh = this.marketplaceCache.get(nameOrId);\n return cachedAfterRefresh?.id || null;\n }\n\n /**\n * 提取 API 错误信息\n * 从 AxiosError 中提取详细的错误信息,包括 HTTP 状态码、错误码和错误消息\n */\n private extractErrorMessage(error: unknown): string {\n if (error instanceof AxiosError) {\n const status = error.response?.status;\n const apiResponse = error.response?.data as ApiResponse<unknown> | undefined;\n\n // 构建详细的错误信息\n const parts: string[] = [];\n\n if (status) {\n parts.push(`HTTP ${status}`);\n }\n\n if (apiResponse?.code) {\n parts.push(`Code ${apiResponse.code}`);\n }\n\n if (apiResponse?.msg) {\n parts.push(apiResponse.msg);\n } else if (error.message) {\n parts.push(error.message);\n }\n\n const errorMessage = parts.join(' - ');\n\n // 打印详细日志\n this.logger?.error('[CloudAgentProvider] API Error:', {\n status,\n code: apiResponse?.code,\n msg: apiResponse?.msg,\n requestId: apiResponse?.requestId,\n url: error.config?.url,\n method: error.config?.method,\n });\n\n return errorMessage;\n }\n\n if (error instanceof Error) {\n return error.message;\n }\n\n return 'Unknown error';\n }\n\n /**\n * 映射后端 source_type 到前端类型\n */\n private mapSourceType(sourceType: string): 'github' | 'local' | 'custom' {\n switch (sourceType) {\n case 'github': return 'github';\n case 'official': return 'custom';\n default: return 'custom';\n }\n }\n\n /**\n * 解析 capabilities JSON 字符串\n */\n private parseCapabilities(capabilitiesStr: string): {\n commands?: any;\n skills?: any;\n mcpServers?: any;\n agents?: any;\n hooks?: any;\n rules?: any;\n } {\n try {\n const cap = JSON.parse(capabilitiesStr);\n return {\n commands: cap.commands,\n skills: cap.skills,\n mcpServers: cap.mcp,\n agents: cap.agents,\n hooks: cap.hooks,\n rules: cap.rules\n };\n } catch {\n return {};\n }\n }\n\n // ========================================================================\n // Telemetry\n // ========================================================================\n\n /**\n * 上报 telemetry 事件(Cloud 模式)\n * 通过 HTTP POST 发送到 /v2/report\n * 注入用户信息和浏览器环境等公共字段\n */\n async reportTelemetry(eventName: string, payload: Record<string, unknown>): Promise<void> {\n try {\n // 从 accountService 获取用户信息\n const account = accountService.getAccount();\n const commonFields: Record<string, unknown> = {};\n\n if (account) {\n commonFields.userId = account.uid;\n commonFields.userNickname = account.nickname;\n if (account.enterpriseId) {\n commonFields.enterpriseId = account.enterpriseId;\n }\n if (account.enterpriseUserName) {\n commonFields.username = account.enterpriseUserName;\n }\n }\n\n // 浏览器环境信息\n if (typeof navigator !== 'undefined') {\n commonFields.userAgent = navigator.userAgent;\n commonFields.os = navigator.platform;\n }\n\n const events = [{\n eventCode: eventName,\n timestamp: Date.now(),\n reportDelay: 0,\n ...commonFields,\n ...payload,\n }];\n\n await httpService.post('/v2/report', events);\n } catch (error) {\n this.logger?.warn('reportTelemetry() failed:', error);\n }\n }\n}\n\nexport default CloudAgentProvider;\n","/**\n * Local Agent Connection\n * Wraps AcpJsonRpcClient to implement AgentConnection interface\n *\n * Uses IWidgetChannel for IPC communication with ExtensionHost\n * Migrated from ipc-agent-provider for unified local agent access\n */\n\nimport {\n type ContentBlock,\n type InitializeResponse,\n type LoadSessionResponse,\n type NewSessionResponse,\n type PromptResponse,\n PROTOCOL_VERSION,\n type RequestPermissionRequest,\n type SessionNotification,\n type SetSessionModelResponse,\n type SetSessionModeResponse} from '@agentclientprotocol/sdk';\nimport type {\n Artifact,\n ArtifactType,\n CheckpointInfo,\n ClientCapabilities,\n QuestionAnswers,\n QuestionRequest} from '@genie/agent-client-protocol';\nimport { ExtensionMethod } from '@genie/agent-client-protocol';\n\nimport type {\n AgentCapabilities,\n AgentConnection,\n AgentStatus,\n ConnectionEventListener,\n ConnectionEvents,\n CreateSessionParams,\n LoadSessionParams,\n LocalConnectionConfig,\n PromptParams,\n} from '../../types.js';\nimport {\n AcpJsonRpcClient,\n type OpenWorkspaceRequest,\n type OpenWorkspaceResponse,\n type PermissionRequestParams,\n type PermissionResponse,\n type SessionUpdateParams,\n type ToolCallbackRequest\n} from './acp/index.js';\n\n// Re-export IWidgetChannel for convenience\nexport type { IWidgetChannel } from './acp/index.js';\n\n// ============================================================================\n// Local Agent Connection Implementation\n// ============================================================================\n\n/**\n * Local Agent Connection implementation\n * Uses AcpJsonRpcClient to communicate with ExtensionHost via IWidgetChannel\n *\n * Phase 1 Implementation:\n * - connect/disconnect: ✅ via initialize\n * - createSession/loadSession: ✅ via AcpJsonRpcClient\n * - prompt/cancel: ✅ via AcpJsonRpcClient\n * - Event forwarding: ✅ sessionUpdate, permissionRequest\n * - resolvePermission/rejectPermission: ✅ via callback\n *\n * Phase 2 (Not Implemented):\n * - promptStream: throws 'Not implemented'\n * - Artifact methods: return empty\n * - Question methods: return empty\n * - Extension methods: throw 'Not implemented'\n * - Filesystem methods: throw 'Not implemented'\n */\nexport class LocalAgentConnection implements AgentConnection {\n // ========================================================================\n // Private Fields\n // ========================================================================\n\n /** ACP JSON-RPC Client */\n private readonly acpClient: AcpJsonRpcClient;\n\n /** Debug mode */\n private readonly debug: boolean;\n\n /** Event listeners */\n private listeners: Map<keyof ConnectionEvents, Set<ConnectionEventListener<unknown>>> = new Map();\n private onceListeners: Map<keyof ConnectionEvents, Set<ConnectionEventListener<unknown>>> = new Map();\n\n /** Connection state */\n private _state: AgentStatus = 'disconnected';\n private _isInitialized = false;\n private _capabilities?: AgentCapabilities;\n private _initializeResult?: InitializeResponse;\n\n /** Pending permission requests: requestId → { params, createdAt } */\n private pendingPermissions: Map<string, { params: PermissionRequestParams; createdAt: number }> = new Map();\n\n /** Permission timeout config */\n private readonly permissionTimeout: number;\n private readonly permissionAutoRejectOnTimeout: boolean;\n\n /** Local artifact cache: id → Artifact */\n private artifactCache: Map<string, Artifact> = new Map();\n\n // ========================================================================\n // Public Properties\n // ========================================================================\n\n /** agentId = cwd (工作区路径) */\n readonly agentId: string;\n\n /** 工作区路径 (与 agentId 相同,语义更清晰) */\n readonly cwd: string;\n\n readonly transport = 'local' as const;\n\n private onRequest?: () => void = undefined;\n\n // ========================================================================\n // Constructor\n // ========================================================================\n\n constructor(agentId: string, config: LocalConnectionConfig) {\n this.agentId = agentId;\n this.cwd = agentId; // agentId 就是 cwd\n this.debug = config.debug ?? false;\n this.permissionTimeout = config.permissionTimeout ?? 30000;\n this.permissionAutoRejectOnTimeout = config.permissionAutoRejectOnTimeout ?? false;\n\n // Initialize ACP JSON-RPC Client\n this.acpClient = new AcpJsonRpcClient(config.channel, {\n timeoutMs: config.acpConfig?.timeoutMs ?? 30000,\n debug: this.debug\n });\n\n // Setup event forwarding\n this.setupEventForwarding();\n\n this.log('LocalAgentConnection initialized');\n }\n\n // ========================================================================\n // Event Forwarding Setup\n // ========================================================================\n\n private setupEventForwarding(): void {\n // Forward session updates from AcpJsonRpcClient\n this.acpClient.onSessionUpdate((params: SessionUpdateParams) => {\n this.emit('sessionUpdate', params.notification);\n });\n\n // Forward extNotification from AcpJsonRpcClient (for artifacts, checkpoints, etc.)\n this.acpClient.onExtNotification((method: string, params: Record<string, unknown>) => {\n console.log('[LocalConnection] Received extNotification:', { method, paramsKeys: Object.keys(params) });\n\n // Handle artifact notifications\n if (method === '_codebuddy.ai/artifact') {\n const event = params.event as 'created' | 'updated' | 'deleted';\n const artifact = params.artifact as Artifact;\n const notificationSessionId = params.sessionId as string | undefined;\n\n // Update local artifact cache\n if (artifact?.uri) {\n if (event === 'created' || event === 'updated') {\n this.artifactCache.set(artifact.uri, artifact);\n } else if (event === 'deleted') {\n this.artifactCache.delete(artifact.uri);\n }\n }\n\n // 将 notificationSessionId 挂到 artifact 上,供 ActiveSessionImpl 过滤\n // 使用 __sessionId 作为内部标记,不修改 Artifact 类型定义\n if (artifact && notificationSessionId) {\n (artifact as any).__sessionId = notificationSessionId;\n }\n\n if (event === 'created') {\n this.emit('artifactCreated', artifact);\n } else if (event === 'updated') {\n this.emit('artifactUpdated', artifact);\n } else if (event === 'deleted') {\n this.emit('artifactDeleted', artifact);\n }\n }\n\n // Handle checkpoint notifications\n if (method === '_codebuddy.ai/checkpoint') {\n const event = params.event as 'created' | 'updated';\n const checkpoint = params.checkpoint as CheckpointInfo;\n const checkpointSessionId = params.sessionId as string | undefined;\n\n console.log('[LocalConnection] Emitting checkpoint event:', {\n event,\n checkpointId: checkpoint?.id,\n checkpointSessionId,\n filesCount: checkpoint?.fileChanges?.files?.length ?? 0\n });\n\n // 将 sessionId 挂到 checkpoint 上,供 ActiveSessionImpl 过滤\n if (checkpoint && checkpointSessionId) {\n (checkpoint as any).__sessionId = checkpointSessionId;\n }\n\n if (event === 'created') {\n this.emit('checkpointCreated', checkpoint);\n } else if (event === 'updated') {\n this.emit('checkpointUpdated', checkpoint);\n }\n }\n\n // Handle command notifications\n if (method === ExtensionMethod.COMMAND) {\n const action = params.action as string;\n const commandParams = params.params as Record<string, unknown> | undefined;\n const commandSessionId = params.sessionId as string | undefined;\n\n console.log('[LocalConnection] Emitting command event:', {\n action,\n commandSessionId,\n paramsKeys: commandParams ? Object.keys(commandParams) : []\n });\n\n // Emit command event with action, params and __sessionId\n const commandData: { action: string; params?: Record<string, unknown>; } = { action, params: commandParams };\n if (commandSessionId) {\n (commandData as any).__sessionId = commandSessionId;\n }\n this.emit('command', commandData);\n }\n });\n\n this.log('Event forwarding setup complete');\n }\n\n // ========================================================================\n // Event Emitter Implementation\n // ========================================================================\n\n on<K extends keyof ConnectionEvents>(event: K, listener: ConnectionEventListener<ConnectionEvents[K]>): this {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(listener as ConnectionEventListener<unknown>);\n return this;\n }\n\n off<K extends keyof ConnectionEvents>(event: K, listener: ConnectionEventListener<ConnectionEvents[K]>): this {\n const eventListeners = this.listeners.get(event);\n if (eventListeners) {\n eventListeners.delete(listener as ConnectionEventListener<unknown>);\n }\n const onceEventListeners = this.onceListeners.get(event);\n if (onceEventListeners) {\n onceEventListeners.delete(listener as ConnectionEventListener<unknown>);\n }\n return this;\n }\n\n once<K extends keyof ConnectionEvents>(event: K, listener: ConnectionEventListener<ConnectionEvents[K]>): this {\n if (!this.onceListeners.has(event)) {\n this.onceListeners.set(event, new Set());\n }\n this.onceListeners.get(event)!.add(listener as ConnectionEventListener<unknown>);\n return this;\n }\n\n emit<K extends keyof ConnectionEvents>(event: K, data: ConnectionEvents[K]): boolean {\n const regularListeners = this.listeners.get(event);\n const onceEventListeners = this.onceListeners.get(event);\n\n // 诊断日志:检查 sessionUpdate 事件是否有 listener 接收\n if (event === 'sessionUpdate') {\n const updateType = (data as any)?.update?.sessionUpdate;\n const notifSessionId = (data as any)?.sessionId;\n const listenerCount = (regularListeners?.size ?? 0) + (onceEventListeners?.size ?? 0);\n if (listenerCount === 0) {\n console.warn(`[RT-DEBUG][LocalConn] emit sessionUpdate NO LISTENERS: type=${updateType}, sessionId=${notifSessionId?.substring(0, 8)}, cwd=${this.cwd?.substring(this.cwd.length - 20)}`);\n }\n }\n\n let hasListeners = false;\n\n // Call regular listeners\n if (regularListeners && regularListeners.size > 0) {\n hasListeners = true;\n for (const listener of regularListeners) {\n try {\n const result = listener(data);\n if (result instanceof Promise) {\n result.catch(err => {\n console.error(`Error in async event listener for '${String(event)}':`, err);\n });\n }\n } catch (err) {\n console.error(`Error in event listener for '${String(event)}':`, err);\n }\n }\n }\n\n // Call once listeners and remove them\n if (onceEventListeners && onceEventListeners.size > 0) {\n hasListeners = true;\n const listenersToCall = Array.from(onceEventListeners);\n this.onceListeners.delete(event);\n\n for (const listener of listenersToCall) {\n try {\n const result = listener(data);\n if (result instanceof Promise) {\n result.catch(err => {\n console.error(`Error in async once event listener for '${String(event)}':`, err);\n });\n }\n } catch (err) {\n console.error(`Error in once event listener for '${String(event)}':`, err);\n }\n }\n }\n\n return hasListeners;\n }\n\n removeAllListeners<K extends keyof ConnectionEvents>(event?: K): this {\n if (event !== undefined) {\n this.listeners.delete(event);\n this.onceListeners.delete(event);\n } else {\n this.listeners.clear();\n this.onceListeners.clear();\n }\n return this;\n }\n\n // ========================================================================\n // State Properties\n // ========================================================================\n\n get state(): AgentStatus {\n return this._state;\n }\n\n get isInitialized(): boolean {\n return this._isInitialized;\n }\n\n get capabilities(): AgentCapabilities | undefined {\n return this._capabilities;\n }\n\n get initializeResult(): InitializeResponse | undefined {\n return this._initializeResult;\n }\n\n // ========================================================================\n // Connection Lifecycle (Phase 1: Implemented)\n // ========================================================================\n\n async connect(_clientCapabilities?: ClientCapabilities): Promise<InitializeResponse> {\n this.log('Connecting...');\n this._state = 'connecting';\n this.emit('connecting', undefined);\n this._isInitialized = true;\n this._initializeResult = { protocolVersion: PROTOCOL_VERSION };\n this.emit('connected', undefined);\n this._state = 'initialized';\n return this._initializeResult;\n }\n\n disconnect(): void {\n this.log('Disconnecting...');\n\n // 清理所有待处理的权限请求\n this.cleanupPendingPermissionsOnDisconnect();\n\n this._state = 'disconnected';\n this._isInitialized = false;\n this.acpClient.destroy();\n this.emit('disconnected', undefined);\n this.log('Disconnected');\n }\n\n /**\n * 清理断开连接时所有待处理的权限请求\n * 在连接断开时主动清理所有 pending 权限请求并返回 cancelled\n */\n private cleanupPendingPermissionsOnDisconnect(): void {\n const count = this.pendingPermissions.size;\n if (count === 0) {\n return;\n }\n\n for (const [requestId] of this.pendingPermissions) {\n const resolver = (this as any)[`_permissionResolver_${requestId}`];\n if (resolver) {\n resolver({ outcome: 'cancelled' });\n delete (this as any)[`_permissionResolver_${requestId}`];\n }\n }\n this.pendingPermissions.clear();\n this.log(`Cleaned up ${count} pending permission request(s) on disconnect`);\n }\n\n // ========================================================================\n // Session Management (Phase 1: Implemented)\n // ========================================================================\n\n async createSession(params: CreateSessionParams): Promise<NewSessionResponse> {\n this.log('Creating session with cwd:', params.cwd, params._meta);\n const response = await this.acpClient.newSession({\n _meta: params._meta,\n cwd: params.cwd,\n mcpServers: (params.mcpServers ?? []) as any // Type cast needed for McpServerConfig → McpServer\n });\n\n this.bindPermissionRequest(response.sessionId);\n return response;\n }\n\n async loadSession(params: LoadSessionParams): Promise<LoadSessionResponse> {\n if (!params.sessionId) {\n throw new Error('sessionId is required for loadSession');\n }\n this.log(`[LocalAgentConnection] loadSession: ${params.sessionId}`);\n const response = await this.acpClient.loadSession({\n sessionId: params.sessionId,\n cwd: params.cwd,\n mcpServers: (params.mcpServers ?? []) as any // Type cast needed for McpServerConfig → McpServer\n });\n this.log(`[LocalAgentConnection] loadSession response:${response}`);\n\n this.bindPermissionRequest(params.sessionId);\n return response;\n }\n\n async bindPermissionRequest(sessionId: string) {\n if (this.onRequest) {\n this.onRequest();\n }\n // Forward permission requests from AcpJsonRpcClient\n this.onRequest = this.acpClient.onRequestPermission(sessionId, async (params: PermissionRequestParams): Promise<PermissionResponse> => {\n // Store pending permission (using PermissionRequestParams format)\n this.pendingPermissions.set(params.requestId, {\n params: params,\n createdAt: Date.now()\n });\n\n // Emit event (convert to RequestPermissionRequest format expected by ConnectionEvents)\n const permissionRequest: RequestPermissionRequest = {\n sessionId: params.sessionId,\n toolCall: params.toolCall, // Type mismatch between legacy and SDK\n options: params.options\n };\n this.emit('permissionRequest', { requestId: params.requestId, params: permissionRequest });\n\n // Wait for resolution\n return new Promise<PermissionResponse>(resolve => {\n const checkResolution = () => {\n // Check if resolved/rejected\n if (!this.pendingPermissions.has(params.requestId)) {\n // Already resolved by resolvePermission/rejectPermission\n return;\n }\n\n // Check timeout\n const pending = this.pendingPermissions.get(params.requestId);\n if (pending && Date.now() - pending.createdAt > this.permissionTimeout) {\n this.pendingPermissions.delete(params.requestId);\n this.emit('permissionTimeout', { requestId: params.requestId });\n if (this.permissionAutoRejectOnTimeout) {\n resolve({ outcome: 'cancelled' });\n }\n }\n };\n\n // Store resolver for external resolution\n (this as any)[`_permissionResolver_${params.requestId}`] = resolve;\n\n // Setup timeout check\n setTimeout(checkResolution, this.permissionTimeout);\n });\n });\n }\n\n // ========================================================================\n // Session Mode Management\n // ========================================================================\n\n async setSessionMode(sessionId: string, modeId: string): Promise<SetSessionModeResponse> {\n this.log('Setting session mode:', sessionId, 'to', modeId);\n return await this.acpClient.setSessionMode({ sessionId, modeId });\n }\n\n async setSessionModel(sessionId: string, modelId: string): Promise<SetSessionModelResponse> {\n this.log('Setting session model:', sessionId, 'to', modelId);\n return await this.acpClient.setSessionModel({ sessionId, modelId });\n }\n\n // ========================================================================\n // Workspace Operations\n // ========================================================================\n\n /**\n * 打开工作区窗口\n * 使用 __workspace__ session ID,由 Main Process 直接处理,不转发到 ExtensionHost\n * @param params 打开工作区请求参数\n * @returns 打开工作区响应\n */\n async openWorkspace(params: OpenWorkspaceRequest): Promise<OpenWorkspaceResponse> {\n this.log('Opening workspace:', params.cwd);\n return await this.acpClient.openWorkspace(params);\n }\n\n // ========================================================================\n // Prompt Operations (Phase 1: Implemented, except promptStream)\n // ========================================================================\n\n async prompt(sessionId: string, params: PromptParams): Promise<PromptResponse> {\n // 如果 content 是字符串,包装成 ContentBlock;否则直接使用\n const prompt = typeof params.content === 'string'\n ? [{ type: 'text' as const, text: params.content }]\n : params.content as ContentBlock[];\n\n this.log('Sending prompt to session:', sessionId);\n return await this.acpClient.prompt({\n sessionId,\n prompt,\n ...{ _meta: { ...params._meta, planMode: params.planMode } }\n }); // Cast needed due to legacy type mismatch\n }\n\n // eslint-disable-next-line require-yield\n async *promptStream(_sessionId: string, _params: PromptParams): AsyncIterable<SessionNotification> {\n // Phase 2: Not implemented yet\n throw new Error('promptStream not implemented for Local connection');\n }\n\n async cancel(sessionId: string): Promise<void> {\n this.log('Cancelling session:', sessionId);\n await this.acpClient.cancel({ sessionId });\n }\n\n // ========================================================================\n // Artifact Management (Implemented via local cache)\n // ========================================================================\n\n getArtifacts(): Map<string, Artifact> {\n return new Map(this.artifactCache);\n }\n\n getArtifact(uri: string): Artifact | undefined {\n return this.artifactCache.get(uri);\n }\n\n getArtifactsByType(type: ArtifactType): Artifact[] {\n return Array.from(this.artifactCache.values()).filter(artifact => artifact.type === type);\n }\n\n async fetchArtifactContent(_artifact: Artifact): Promise<string> {\n // Phase 2: Not implemented\n throw new Error('fetchArtifactContent not implemented for Local connection');\n }\n\n async fetchArtifactContentById(_id: string): Promise<string> {\n // Phase 2: Not implemented\n throw new Error('fetchArtifactContentById not implemented for Local connection');\n }\n\n // ========================================================================\n // Permission Management (Phase 1: Implemented)\n // ========================================================================\n\n resolvePermission(requestId: string, optionId: string): boolean {\n const resolver = (this as any)[`_permissionResolver_${requestId}`];\n if (resolver) {\n this.pendingPermissions.delete(requestId);\n delete (this as any)[`_permissionResolver_${requestId}`];\n resolver({ outcome: 'selected', optionId });\n this.emit('permissionResolved', { requestId, optionId });\n return true;\n }\n return false;\n }\n\n rejectPermission(requestId: string, reason?: string): boolean {\n const resolver = (this as any)[`_permissionResolver_${requestId}`];\n if (resolver) {\n this.pendingPermissions.delete(requestId);\n delete (this as any)[`_permissionResolver_${requestId}`];\n resolver({ outcome: 'cancelled' });\n this.emit('permissionRejected', { requestId, reason });\n return true;\n }\n return false;\n }\n\n getPendingPermissions(): Map<string, { params: RequestPermissionRequest; createdAt: number }> {\n // Convert PermissionRequestParams to RequestPermissionRequest format\n const result = new Map<string, { params: RequestPermissionRequest; createdAt: number }>();\n for (const [requestId, pending] of this.pendingPermissions) {\n result.set(requestId, {\n params: {\n sessionId: pending.params.sessionId,\n toolCall: pending.params.toolCall as any,\n options: pending.params.options\n },\n createdAt: pending.createdAt\n });\n }\n return result;\n }\n\n hasPendingPermissions(): boolean {\n return this.pendingPermissions.size > 0;\n }\n\n // ========================================================================\n // Question Management (Phase 2: Not Implemented)\n // ========================================================================\n\n answerQuestion(_toolCallId: string, _answers: QuestionAnswers): boolean {\n // Phase 2: Not implemented\n return false;\n }\n\n // ========================================================================\n // Tool Callback Management\n // ========================================================================\n\n /**\n * 工具回调操作\n * 用于对正在执行的工具进行 approve / skip / cancel 操作\n * @param sessionId 会话 ID\n * @param toolCallId 工具调用 ID\n * @param toolName 工具名称\n * @param action 操作类型 ('approve' | 'skip' | 'cancel')\n * @returns 工具回调响应\n */\n async toolCallback(sessionId: string, toolCallId: string, toolName: string, action: 'approve' | 'skip' | 'cancel'): Promise<{ success: boolean; error?: string }> {\n this.log('toolCallback called for session:', sessionId, 'action:', action);\n const request: ToolCallbackRequest = { sessionId, toolCallId, toolName, action };\n return await this.acpClient.toolCallback(request);\n }\n\n cancelQuestion(_toolCallId: string, _reason?: string): boolean {\n // Phase 2: Not implemented\n return false;\n }\n\n getPendingQuestions(): Map<string, { request: QuestionRequest; createdAt: number }> {\n // Phase 2: Not implemented\n return new Map();\n }\n\n hasPendingQuestions(): boolean {\n // Phase 2: Not implemented\n return false;\n }\n\n // ========================================================================\n // Telemetry\n // ========================================================================\n\n async reportTelemetry(eventName: string, payload: Record<string, unknown>): Promise<void> {\n try {\n await this.acpClient.sendRequest(\n this.agentId,\n 'reportTelemetry',\n { eventName, payload }\n );\n } catch (error) {\n console.warn('[LocalAgentConnection] reportTelemetry failed:', error);\n }\n }\n\n // ========================================================================\n // Extension Methods (Phase 2: Not Implemented)\n // ========================================================================\n\n async extMethod(_method: string, _params: Record<string, unknown>): Promise<Record<string, unknown>> {\n // Phase 2: Not implemented\n throw new Error('extMethod not implemented for Local connection');\n }\n\n async extNotification(_method: string, _params: Record<string, unknown>): Promise<void> {\n // Phase 2: Not implemented\n throw new Error('extNotification not implemented for Local connection');\n }\n\n // ========================================================================\n // Filesystem Operations (Phase 2: Not Implemented)\n // ========================================================================\n\n async readFile(_path: string): Promise<string> {\n // Phase 2: Not implemented\n throw new Error('readFile not implemented for Local connection');\n }\n\n async listDir(_path: string): Promise<any[]> {\n // Phase 2: Not implemented\n throw new Error('listDir not implemented for Local connection');\n }\n\n async fileExists(_path: string): Promise<boolean> {\n // Phase 2: Not implemented\n throw new Error('fileExists not implemented for Local connection');\n }\n\n async fileStat(_path: string): Promise<any> {\n // Phase 2: Not implemented\n throw new Error('fileStat not implemented for Local connection');\n }\n\n // ========================================================================\n // Utility Methods\n // ========================================================================\n\n private log(...args: unknown[]): void {\n // if (this.debug) {\n console.log('[LocalAgentConnection]', ...args);\n // }\n }\n}\n\nexport default LocalAgentConnection;\n","/**\n * Provider and Connection type definitions\n * Enables unified access to Cloud and Local agents\n */\n\nimport type {\n InitializeResponse,\n LoadSessionResponse,\n NewSessionResponse,\n PromptResponse,\n RequestPermissionRequest,\n SessionNotification,\n SetSessionModelResponse,\n SetSessionModeResponse\n} from '@agentclientprotocol/sdk';\nimport type {\n AgentCapabilities,\n Artifact,\n ArtifactEvent,\n ClientCapabilities,\n ClientEvents,\n Logger,\n QuestionAnswers,\n QuestionRequest,\n UsageUpdate\n} from '@genie/agent-client-protocol';\n\nimport type { IWidgetChannel } from './providers/local-agent-provider/acp/types.js';\n\n// Re-export capability types from agent-client-protocol\nexport type {\n ClientCapabilities,\n AgentCapabilities,\n ArtifactTypeConfig,\n ArtifactsConfig,\n CodebuddyClientMeta,\n CodebuddyAgentMeta\n} from '@genie/agent-client-protocol';\n\n// ============================================\n// Filesystem Types - Standalone definitions (no e2b dependency)\n// ============================================\n\n/**\n * File type enumeration\n * Compatible with e2b SDK FileType\n */\nexport enum FileType {\n FILE = 'file',\n DIR = 'dir',\n}\n\n/**\n * Filesystem event type enumeration\n * Compatible with e2b SDK FilesystemEventType\n */\nexport enum FilesystemEventType {\n CHMOD = 'chmod',\n CREATE = 'create',\n REMOVE = 'remove',\n RENAME = 'rename',\n WRITE = 'write',\n}\n\n/**\n * File or directory entry information\n * Compatible with e2b SDK EntryInfo\n */\nexport interface EntryInfo {\n name: string;\n type: FileType;\n path: string;\n size: number;\n mode: number;\n permissions: string;\n owner: string;\n group: string;\n modifiedTime?: Date;\n symlinkTarget?: string;\n}\n\n/**\n * Write operation result\n * Compatible with e2b SDK WriteInfo\n */\nexport interface WriteInfo {\n path: string;\n type: FileType;\n name: string;\n}\n\n/**\n * Filesystem watch event\n * Compatible with e2b SDK FilesystemEvent\n */\nexport interface FilesystemEvent {\n name: string;\n type: FilesystemEventType;\n}\n\n/**\n * Handle for stopping a directory watch\n * Compatible with e2b SDK WatchHandle\n */\nexport interface WatchHandle {\n stop(): Promise<void>;\n}\n\n/**\n * @deprecated Use the standalone type definitions above instead.\n * This type alias is kept for backward compatibility with code that\n * imported `Filesystem` type from this module.\n */\nexport type Filesystem = FilesResource;\n\n// ============================================\n// Filesystem Options Types - 对齐 e2b SDK\n// ============================================\n\n/**\n * Base options for filesystem operations\n * 对齐 e2b SDK FilesystemRequestOpts\n */\nexport interface FilesystemRequestOpts {\n user?: string;\n requestTimeoutMs?: number;\n}\n\n/**\n * Options for list operation\n * 对齐 e2b SDK FilesystemListOpts\n */\nexport interface FilesystemListOpts extends FilesystemRequestOpts {\n depth?: number;\n}\n\n/**\n * Options for watchDir operation\n * 对齐 e2b SDK WatchOpts\n */\nexport interface WatchOpts extends FilesystemRequestOpts {\n timeoutMs?: number;\n onExit?: (err?: Error) => void | Promise<void>;\n recursive?: boolean;\n}\n\n/**\n * Entry for batch write operation\n * 对齐 e2b SDK WriteEntry\n */\nexport interface WriteEntry {\n path: string;\n data: string | ArrayBuffer | Blob | ReadableStream;\n}\n\n/**\n * E2B Sandbox connection information\n * 与 e2b SDK 的 ConnectionOpts 对齐\n */\nexport interface E2BSandboxConnectionInfo {\n /** Sandbox ID */\n sandboxId: string;\n /** API key for authentication (e2b_ 开头的 key) */\n apiKey?: string;\n /** Access token for authentication (JWT 格式的 token) */\n accessToken?: string;\n /** Domain for the API (不带 https://) */\n domain?: string;\n /** API URL override (internal) */\n apiUrl?: string;\n /** Request timeout in milliseconds */\n requestTimeoutMs?: number;\n /** Debug mode */\n debug?: boolean;\n /**\n * Additional headers to send with the request.\n */\n headers?: Record<string, string>;\n}\n\n/**\n * Filesystem resource interface\n * Mirrors e2b SDK Filesystem API\n * 完全对齐 e2b SDK 的 Filesystem 类\n */\nexport interface FilesResource {\n // ============================================\n // Read 方法重载 - 支持多种格式\n // ============================================\n\n /** Read file content as text (default) */\n read(path: string, opts?: FilesystemRequestOpts & { format?: 'text' }): Promise<string>;\n /** Read file content as bytes */\n read(path: string, opts: FilesystemRequestOpts & { format: 'bytes' }): Promise<Uint8Array>;\n /** Read file content as blob */\n read(path: string, opts: FilesystemRequestOpts & { format: 'blob' }): Promise<Blob>;\n /** Read file content as stream */\n read(path: string, opts: FilesystemRequestOpts & { format: 'stream' }): Promise<ReadableStream<Uint8Array>>;\n\n // ============================================\n // Write 方法重载 - 支持单文件和批量写入\n // ============================================\n\n /** Write content to a single file */\n write(path: string, data: string | ArrayBuffer | Blob | ReadableStream, opts?: FilesystemRequestOpts): Promise<WriteInfo>;\n /** Write multiple files in batch */\n write(files: WriteEntry[], opts?: FilesystemRequestOpts): Promise<WriteInfo[]>;\n\n // ============================================\n // 其他文件操作方法\n // ============================================\n\n /** List directory contents with optional depth */\n list(path: string, opts?: FilesystemListOpts): Promise<EntryInfo[]>;\n\n /** Check if path exists */\n exists(path: string, opts?: FilesystemRequestOpts): Promise<boolean>;\n\n /** Create directory */\n makeDir(path: string, opts?: FilesystemRequestOpts): Promise<boolean>;\n\n /** Remove file or directory */\n remove(path: string, opts?: FilesystemRequestOpts): Promise<void>;\n\n /** Rename/move file or directory */\n rename(oldPath: string, newPath: string, opts?: FilesystemRequestOpts): Promise<EntryInfo>;\n\n /** Get file or directory information */\n getInfo(path: string, opts?: FilesystemRequestOpts): Promise<EntryInfo>;\n\n /** Watch directory for changes */\n watchDir(\n path: string,\n onEvent: (event: FilesystemEvent) => void | Promise<void>,\n opts?: WatchOpts & { onExit?: (err?: Error) => void | Promise<void> }\n ): Promise<WatchHandle>;\n}\n\n/**\n * Filesystem provider interface - implemented by Provider\n */\nexport interface FilesystemProvider {\n /**\n * Get filesystem resource for an agent\n * @param agentId - Agent ID (used to get the corresponding sandbox connection)\n */\n getFilesystem(agentId: string): Promise<FilesResource>;\n}\n\n// ============================================\n// Agent Types\n// ============================================\n\n/**\n * Transport type for agents\n */\nexport type AgentTransport = 'cloud' | 'local';\n\n/**\n * Agent connection status\n */\nexport type AgentStatus = 'disconnected' | 'connecting' | 'connected' | 'initialized' | 'error';\n\n/**\n * Agent information\n */\nexport interface Agent {\n id: string;\n name: string;\n description?: string;\n version?: string;\n transport: AgentTransport;\n status: AgentStatus;\n capabilities?: AgentCapabilities;\n metadata?: Record<string, unknown>;\n}\n\n// ============================================\n// Session Types\n// ============================================\n\n/**\n * Session mode configuration\n */\nexport interface SessionMode {\n id: string;\n name: string;\n description?: string | null;\n}\n\n/**\n * Session information\n */\nexport interface Session {\n id: string;\n agentId: string;\n availableModes?: SessionMode[];\n currentMode?: string;\n}\n\n/**\n * Parameters for creating a new session\n */\nexport interface CreateSessionParams {\n cwd: string;\n mcpServers?: McpServerConfig[];\n _meta?: Record<string, unknown>;\n}\n\n/**\n * Parameters for loading an existing session\n * If sessionId is not provided, reloads the current session\n */\nexport interface LoadSessionParams {\n /** Session ID to load (optional - uses current session if not provided) */\n sessionId?: string;\n cwd: string;\n mcpServers?: McpServerConfig[];\n}\n\n/**\n * MCP server configuration\n */\nexport interface McpServerConfig {\n name: string;\n command: string;\n args?: string[];\n env?: Record<string, string>;\n}\n\n// ============================================\n// Prompt Types\n// ============================================\n\n/**\n * Prompt content block types\n */\nexport type PromptContentBlock =\n | {\n type: 'text'; text: string; _meta?: {\n [key: string]: unknown;\n } | null | undefined;\n }\n | {\n type: 'image';\n data: string;\n mimeType: string;\n uri?: string | null;\n _meta?: { [key: string]: unknown } | null | undefined;\n }\n | {\n type: 'resource';\n uri: string;\n mimeType?: string | null;\n name: string;\n size?: number | null;\n title?: string | null;\n _meta?: { [key: string]: unknown } | null | undefined;\n };\n\n/**\n * Parameters for sending a prompt\n */\nexport interface PromptParams {\n content: string | PromptContentBlock[];\n planMode?: boolean;\n _meta?: Record<string, unknown>;\n}\n\n/**\n * Events emitted by agent connections\n */\nexport interface ConnectionEvents extends ClientEvents {\n // Local agent specific events\n spawn: { pid: number };\n exit: { code: number | null; signal: string | null };\n\n // Question events (from ClientEvents but explicitly listed for clarity)\n questionRequest: { toolCallId: string; request: QuestionRequest };\n questionAnswered: { toolCallId: string; answers: QuestionAnswers };\n questionCancelled: { toolCallId: string; reason?: string };\n questionTimeout: { toolCallId: string };\n\n // Command events\n command: { action: string; params?: Record<string, unknown> };\n}\n\n// ============================================\n// Agent Connection Interface\n// ============================================\n\n/**\n * Event listener type\n */\nexport type ConnectionEventListener<T> = (data: T) => void | Promise<void>;\n\n/**\n * Abstract interface for agent connections\n * Implemented by CloudAgentConnection and LocalAgentConnection\n */\nexport interface AgentConnection {\n /** Agent ID */\n readonly agentId: string;\n\n /** Current working directory */\n readonly cwd?: string;\n\n // Event emitter methods\n on<K extends keyof ConnectionEvents>(event: K, listener: ConnectionEventListener<ConnectionEvents[K]>): this;\n off<K extends keyof ConnectionEvents>(event: K, listener: ConnectionEventListener<ConnectionEvents[K]>): this;\n once<K extends keyof ConnectionEvents>(event: K, listener: ConnectionEventListener<ConnectionEvents[K]>): this;\n emit<K extends keyof ConnectionEvents>(event: K, data: ConnectionEvents[K]): boolean;\n removeAllListeners<K extends keyof ConnectionEvents>(event?: K): this;\n\n /** Transport type */\n readonly transport: AgentTransport;\n\n /** Current connection state */\n readonly state: AgentStatus;\n\n /** Whether the connection is initialized */\n readonly isInitialized: boolean;\n\n /** Agent capabilities (available after initialization) */\n readonly capabilities?: AgentCapabilities;\n\n /** Initialize response (available after initialization) */\n readonly initializeResult?: InitializeResponse;\n\n // Connection lifecycle\n connect(): Promise<InitializeResponse>;\n disconnect(): void | Promise<void>;\n\n // Session management\n createSession(params: CreateSessionParams): Promise<NewSessionResponse>;\n loadSession(params: LoadSessionParams): Promise<LoadSessionResponse>;\n setSessionMode(sessionId: string, modeId: string): Promise<SetSessionModeResponse>;\n /**\n * Set the session model\n * @experimental This API is unstable and may change\n */\n setSessionModel(sessionId: string, modelId: string): Promise<SetSessionModelResponse>;\n\n // Prompt operations\n prompt(sessionId: string, params: PromptParams): Promise<PromptResponse>;\n promptStream(sessionId: string, params: PromptParams): AsyncIterable<SessionNotification>;\n cancel(sessionId: string): Promise<void>;\n\n // Permission management\n resolvePermission(requestId: string, optionId: string): boolean;\n rejectPermission(requestId: string, reason?: string): boolean;\n getPendingPermissions(): Map<string, { params: RequestPermissionRequest; createdAt: number }>;\n hasPendingPermissions(): boolean;\n\n // Question management (ask_followup_question)\n answerQuestion(toolCallId: string, answers: QuestionAnswers): boolean;\n cancelQuestion(toolCallId: string, reason?: string): boolean;\n getPendingQuestions(): Map<string, { request: QuestionRequest; createdAt: number }>;\n hasPendingQuestions(): boolean;\n\n // Tool callback management\n /**\n * 工具回调操作\n * 用于对正在执行的工具进行 skip 或 cancel 操作\n * @param sessionId 会话 ID\n * @param toolCallId 工具调用 ID\n * @param toolName 工具名称\n * @param action 操作类型 ('approve' | 'skip' | 'cancel')\n */\n toolCallback(sessionId: string, toolCallId: string, toolName: string, action: 'approve' | 'skip' | 'cancel'): Promise<{ success: boolean; error?: string }>;\n\n // Extension methods\n extMethod(method: string, params: Record<string, unknown>): Promise<Record<string, unknown>>;\n\n // Telemetry\n /**\n * Report telemetry event through the standard provider chain\n * - Local: via ACP JSON-RPC → IDE EventService\n * - Cloud: via StreamableHTTP → cloud telemetry endpoint\n *\n * @param eventName - Event name / code\n * @param payload - Event data (already includes mode)\n */\n reportTelemetry?(eventName: string, payload: Record<string, unknown>): Promise<void>;\n}\n\n// ============================================\n// Configuration Types\n// ============================================\n\n/**\n * Base configuration for connections\n */\nexport interface BaseConnectionConfig {\n /** Logger instance */\n logger?: Logger;\n /** Permission timeout (ms) */\n permissionTimeout?: number;\n /** Auto-reject permissions on timeout */\n permissionAutoRejectOnTimeout?: boolean;\n /** Auto-approve all permissions */\n autoApprove?: boolean;\n /** Client capabilities (sent during initialization) */\n clientCapabilities?: ClientCapabilities;\n}\n\n/**\n * Configuration for cloud agent connections\n */\nexport interface CloudConnectionConfig extends BaseConnectionConfig {\n /** Agent endpoint URL */\n endpoint: string;\n /** Authorization token */\n authToken?: string;\n /** Custom headers */\n headers?: Record<string, string>;\n /** Reconnect options */\n reconnect?: {\n enabled?: boolean;\n initialDelay?: number;\n maxDelay?: number;\n maxRetries?: number;\n };\n /** Initialize timeout (ms) */\n initializeTimeout?: number;\n /** Custom fetch implementation */\n fetch?: typeof fetch;\n}\n\n/**\n * Configuration for local process agent connections (spawns child process)\n */\nexport interface LocalProcessConnectionConfig extends BaseConnectionConfig {\n /** Command to execute */\n command: string;\n /** Command arguments */\n args?: string[];\n /** Working directory */\n cwd?: string;\n /** Environment variables */\n env?: Record<string, string>;\n /** Initialize timeout (ms) */\n initializeTimeout?: number;\n}\n\n/**\n * Configuration for local IPC agent connections (via IWidgetChannel)\n */\nexport interface LocalConnectionConfig extends BaseConnectionConfig {\n /** Widget Channel for IPC communication (required) */\n channel: IWidgetChannel;\n /** Enable debug logging */\n debug?: boolean;\n /** ACP Client configuration */\n acpConfig?: {\n /** Request timeout in milliseconds */\n timeoutMs?: number;\n };\n}\n\n// ============================================\n// Event Callbacks\n// ============================================\n\n/**\n * Callback for session updates\n */\nexport type SessionUpdateCallback = (agentId: string, update: SessionNotification) => void | Promise<void>;\n\n/**\n * Callback for artifact events\n */\nexport type ArtifactCallback = (agentId: string, artifact: Artifact, event: ArtifactEvent) => void | Promise<void>;\n\n/**\n * Callback for permission requests\n */\nexport type PermissionCallback = (agentId: string, request: RequestPermissionRequest) => void | Promise<void>;\n\n/**\n * Callback for usage updates\n */\nexport type UsageCallback = (agentId: string, usage: UsageUpdate) => void | Promise<void>;\n\n// ============================================\n// Model Types\n// ============================================\n\n/**\n * Model reasoning configuration\n */\nexport interface ModelReasoning {\n /** Reasoning effort level */\n effort: 'low' | 'medium' | 'high';\n /** When to show summary */\n summary: 'never' | 'always' | 'auto';\n}\n\n/**\n * Model information\n */\nexport interface ModelInfo {\n /** 模型唯一标识符,例如\"gpt-3.5-turbo\" */\n readonly id: string;\n /** 可选,模型名称,例如\"GPT-3.5 Turbo\" */\n readonly name?: string;\n /** 可选,模型供应商,例如\"OpenAI\" */\n readonly vendor?: string;\n /** 可选,模型版本,例如\"2024-06-01\" */\n readonly version?: string;\n /** 可选,模型家族,例如\"gpt\" */\n readonly family?: string;\n /** 可选,最大输入 token 数,例如 4096 */\n readonly maxInputTokens?: number;\n /** 可选,最大输出 token 数,例如 1024 */\n readonly maxOutputTokens?: number;\n /** 描述 */\n readonly description?: string;\n /** 英文描述 */\n readonly descriptionEn?: string;\n /** 中文描述 */\n readonly descriptionZh?: string;\n /** 是否可配置 */\n readonly configurable?: boolean;\n /** 已经配置 */\n readonly configured?: boolean;\n /** 接口地址(全路径) */\n readonly url?: string;\n /** 模型 apiKey,自定义模型需要 */\n readonly apiKey?: string;\n /** 是否支持 extra 上下文 */\n readonly supportsExtra?: boolean;\n /** 是否支持工具调用 */\n readonly supportsToolCall?: boolean;\n /** 是否支持图片 */\n readonly supportsImages?: boolean;\n /** 是否支持推理 */\n readonly supportsReasoning?: boolean;\n /** 是否只支持推理模型 */\n readonly onlyReasoning?: boolean;\n /** 开始上下文处理的 token 阈值 */\n readonly maxAllowedSize?: number;\n /** tags */\n readonly tags?: string[];\n /** 是否关闭多模态能力 */\n readonly disabledMultimodal?: boolean;\n /** 模型消耗的积分信息 */\n readonly credits?: string;\n /** 推理配置 */\n readonly reasoning?: ModelReasoning;\n /** 最多支持的图片数量 */\n readonly maxImageCount?: number;\n /** 是否是默认模型 */\n readonly isDefault?: boolean;\n /** 温度 */\n readonly temperature?: number;\n /** icon */\n readonly iconUrl?: string;\n /** 模型类型:enterprise 表示企业版模型,built-in 表示内置模型 */\n readonly modelType?: 'enterprise' | 'built-in';\n /** 模型可信安全级别 */\n readonly trustLevel?: ModelTrustLevel;\n /** 是否禁用该模型(用于安全限制等场景) */\n readonly disabled?: boolean;\n /** 禁用原因说明(例如:\"当前项目为敏感项目,建议使用内部模型\") */\n readonly disabledReason?: string;\n /** 禁用模型交互 */\n readonly disabledAction?: {\n type: 'link' | 'applyGroup'; // 交互类型,applyGroup 当前需要端侧动态生成链接\n text?: string; // 交互文本\n link?: string; // 链接\n };\n}\n\nexport enum ModelTrustLevel {\n /** 未经验证,存在潜在风险 */\n UNVERIFIED = 'unverified',\n /** 用户配置 */\n CUSTOM = 'custom',\n /** 认证安全 */\n CERTIFIED = 'certified',\n}\n","/**\n * ActiveSessionImpl - Implements the ActiveSession interface\n *\n * Represents an active session with its resources and operations.\n * Session is the primary API surface for client interactions.\n */\n\nimport type { PromptResponse as SdkPromptResponse,SessionNotification } from '@agentclientprotocol/sdk';\n\nimport type { AgentStatus, ConnectionEvents, FilesResource, PromptParams } from '../types.js';\nimport type {\n ActiveSession,\n AgentCapabilities,\n AgentConnection,\n AgentState,\n Artifact,\n ArtifactsResource,\n ArtifactType,\n AvailableCommand,\n Logger,\n ModelInfo,\n PromptResponse,\n PromptsResource,\n QuestionAnswers,\n SessionAgentOperations,\n SessionConnectionInfo,\n SessionEventHandler,\n SessionEvents,\n SessionMode} from './types.js';\n\n/**\n * Event listener type\n */\ntype EventListener<T> = (data: T) => void | Promise<void>;\n\n/**\n * Filesystem getter function type\n * Returns a FilesResource instance for file operations\n */\nexport type FilesystemGetter = () => Promise<FilesResource>;\n\n/**\n * Options for creating an ActiveSessionImpl instance\n */\nexport interface ActiveSessionImplOptions {\n /** Logger instance */\n logger?: Logger;\n /** Getter function for filesystem resource (provided by SessionManager) */\n getFilesystem?: FilesystemGetter;\n /** Session connection information (for cloud sessions) */\n connectionInfo?: SessionConnectionInfo;\n}\n\n/**\n * ActiveSessionImpl - Implements the ActiveSession interface\n *\n * This class wraps an AgentConnection and provides the session-centric API.\n * It is created by SessionManager when creating or loading sessions.\n *\n * @example\n * ```typescript\n * // Created by client.sessions.new() or client.sessions.load()\n * const session = await client.sessions.new({ cwd: '/workspace' });\n *\n * // Access agent state\n * console.log(session.agentState.status);\n *\n * // Send prompt\n * const response = await session.prompts.send({ content: 'Hello!' });\n *\n * // Cleanup\n * session.disconnect();\n * ```\n */\nexport class ActiveSessionImpl implements ActiveSession {\n private _id: string;\n private _agentId: string;\n private _cwd?: string;\n private _availableModes?: SessionMode[];\n private _currentMode?: string;\n private _availableModels?: ModelInfo[];\n private _currentModelId?: string;\n private _availableCommands: AvailableCommand[] = [];\n private logger?: Logger;\n private connection: AgentConnection;\n private _getFilesystem?: FilesystemGetter;\n private _connectionInfo?: SessionConnectionInfo;\n\n // Event emitter storage\n private listeners: Map<keyof SessionEvents, Set<EventListener<unknown>>> = new Map();\n private onceListeners: Map<keyof SessionEvents, Set<EventListener<unknown>>> = new Map();\n\n // 保存注册在 connection 上的 listener 引用,disconnect 时从 connection 上移除\n private connectionListeners: Array<{ event: string; listener: (...args: any[]) => void }> = [];\n\n /**\n * Agent operations namespace\n */\n readonly agent: SessionAgentOperations;\n\n /**\n * Prompts resource namespace\n */\n readonly prompts: PromptsResource;\n\n /**\n * Artifacts resource namespace\n */\n readonly artifacts: ArtifactsResource;\n\n /**\n * Files resource namespace (lazily loaded via getter)\n */\n readonly files: FilesResource;\n\n /**\n * Create an ActiveSessionImpl instance\n *\n * @param sessionId - Session ID\n * @param agentId - Agent ID\n * @param connection - Already connected AgentConnection\n * @param options - Additional options\n */\n constructor(\n sessionId: string,\n agentId: string,\n connection: AgentConnection,\n options: ActiveSessionImplOptions = {}\n ) {\n this._id = sessionId;\n this._agentId = agentId;\n this.connection = connection;\n this.logger = options.logger;\n this._getFilesystem = options.getFilesystem;\n this._connectionInfo = options.connectionInfo;\n\n // Set up event forwarding from connection\n this.setupConnectionEvents(connection);\n\n // Initialize agent operations namespace\n this.agent = this.createAgentOperations();\n\n // Initialize resource namespaces\n this.prompts = this.createPromptsResource();\n this.artifacts = this.createArtifactsResource();\n this.files = this.createFilesResource();\n }\n\n // ============================================\n // Properties\n // ============================================\n\n /**\n * Session ID\n */\n get id(): string {\n return this._id;\n }\n\n /**\n * Agent ID\n */\n get agentId(): string {\n return this._agentId;\n }\n\n /**\n * Actual workspace path (set from newSession response _meta)\n */\n get cwd(): string | undefined {\n return this._cwd;\n }\n\n /**\n * Set actual workspace path (called by SessionManager after createSession)\n */\n setCwd(cwd: string): void {\n this._cwd = cwd;\n }\n\n /**\n * Agent state (live connection state)\n * Returns LocalAgentState or CloudAgentState based on transport type\n */\n get agentState(): AgentState {\n return {\n id: this._agentId,\n status: this.connection.state as AgentStatus,\n capabilities: this.connection.capabilities,\n type: this.connection.transport,\n cwd: this.connection.cwd || ''\n };\n }\n\n /**\n * Get agent capabilities (available after connection)\n */\n get capabilities(): AgentCapabilities | undefined {\n return this.connection.capabilities;\n }\n\n /**\n * Available session modes\n */\n get availableModes(): SessionMode[] | undefined {\n return this._availableModes;\n }\n\n /**\n * Current session mode\n */\n get currentMode(): string | undefined {\n return this._currentMode;\n }\n\n /**\n * Available models for this session\n */\n get availableModels(): ModelInfo[] | undefined {\n return this._availableModels;\n }\n\n /**\n * Current model ID\n */\n get currentModelId(): string | undefined {\n return this._currentModelId;\n }\n\n /**\n * Available slash commands\n *\n * When Agent sends available_commands_update, this list is automatically updated.\n * Commands can be accessed directly without waiting for events.\n */\n get availableCommands(): AvailableCommand[] {\n return this._availableCommands;\n }\n\n /**\n * Set available commands (called when available_commands_update is received)\n */\n setAvailableCommands(commands: AvailableCommand[]): void {\n this._availableCommands = commands;\n this.logger?.info(`Session ${this._id}: Available commands updated, count: ${commands.length}`);\n }\n\n /**\n * Check if the session is active\n */\n get isActive(): boolean {\n return this.connection.isInitialized;\n }\n\n /**\n * Session connection information (only available for cloud sessions)\n * 会话连接信息,包括sandboxId、link、token等\n */\n get connectionInfo(): SessionConnectionInfo | undefined {\n return this._connectionInfo;\n }\n\n /**\n * Set session modes (called after create/load)\n */\n setModes(availableModes?: SessionMode[], currentMode?: string): void {\n this._availableModes = availableModes;\n this._currentMode = currentMode;\n }\n\n /**\n * Set available models (called after create/load)\n */\n setModels(availableModels?: ModelInfo[], currentModelId?: string): void {\n this._availableModels = availableModels;\n this._currentModelId = currentModelId;\n }\n\n // ============================================\n // Agent Operations Namespace\n // ============================================\n\n private createAgentOperations(): SessionAgentOperations {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n return {\n get id(): string {\n return self._agentId;\n },\n get state(): AgentState {\n return self.agentState;\n },\n get isConnected(): boolean {\n return self.connection.isInitialized;\n },\n get capabilities(): AgentCapabilities | undefined {\n return self.connection.capabilities;\n }\n };\n }\n\n // ============================================\n // Prompts Resource\n // ============================================\n\n private createPromptsResource(): PromptsResource {\n return {\n send: async (params: PromptParams): Promise<PromptResponse> => {\n const connection = this.getConnectionOrThrow();\n const response = await connection.prompt(this._id, params);\n return this.mapPromptResponse(response);\n },\n\n stream: (params: PromptParams): AsyncIterable<SessionNotification> => {\n const connection = this.getConnectionOrThrow();\n return connection.promptStream(this._id, params);\n },\n\n cancel: async (): Promise<void> => {\n const connection = this.getConnectionOrThrow();\n await connection.cancel(this._id);\n }\n };\n }\n\n // ============================================\n // Artifacts Resource\n // ============================================\n\n private createArtifactsResource(): ArtifactsResource {\n // Artifact management has been simplified - these methods are no longer supported\n const notSupported = () => {\n throw new Error('Artifact management is no longer supported through this API');\n };\n\n return {\n list: async (_params?: { type?: ArtifactType }): Promise<Artifact[]> => {\n notSupported();\n return [];\n },\n\n retrieve: async (_artifactId: string): Promise<Artifact> => {\n notSupported();\n return undefined as unknown as Artifact;\n },\n\n content: async (_artifactId: string): Promise<string> => {\n notSupported();\n return '';\n }\n };\n }\n\n // ============================================\n // Files Resource\n // ============================================\n\n /**\n * Create files resource with lazy-loaded filesystem\n *\n * The filesystem is lazily loaded on first use to avoid unnecessary\n * connections to the sandbox. The actual filesystem instance is obtained\n * via the getter function provided by SessionManager.\n */\n private createFilesResource(): FilesResource {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n let filesPromise: Promise<FilesResource> | null = null;\n\n /**\n * Get or create the filesystem instance\n */\n const getFs = async (): Promise<FilesResource> => {\n if (!self._getFilesystem) {\n throw new Error('Filesystem not available: provider does not support filesystem operations');\n }\n if (!filesPromise) {\n filesPromise = self._getFilesystem();\n }\n return filesPromise;\n };\n\n return {\n // Read operations - 支持多种格式重载\n read: (async (path: string, opts?: any) => (await getFs()).read(path, opts)) as FilesResource['read'],\n\n // Write operations - 支持单文件和批量写入重载\n write: (async (pathOrFiles: any, dataOrOpts?: any, opts?: any) => {\n const fs = await getFs();\n if (Array.isArray(pathOrFiles)) {\n // Batch write\n return fs.write(pathOrFiles, dataOrOpts);\n }\n // Single file write\n return fs.write(pathOrFiles, dataOrOpts, opts);\n }) as FilesResource['write'],\n\n // List with depth support\n list: async (path, opts) => (await getFs()).list(path, opts),\n exists: async (path, opts) => (await getFs()).exists(path, opts),\n makeDir: async (path, opts) => (await getFs()).makeDir(path, opts),\n remove: async (path, opts) => (await getFs()).remove(path, opts),\n rename: async (oldPath, newPath, opts) => (await getFs()).rename(oldPath, newPath, opts),\n\n // 新增 getInfo 方法\n getInfo: async (path, opts) => (await getFs()).getInfo(path, opts),\n\n // Watch operations - 支持扩展的 opts\n watchDir: async (path, onEvent, opts) => (await getFs()).watchDir(path, onEvent, opts)\n };\n }\n\n // ============================================\n // Permission Management\n // ============================================\n\n /**\n * Resolve a permission request\n */\n resolvePermission(requestId: string, optionId: string): boolean {\n return this.connection.resolvePermission(requestId, optionId);\n }\n\n /**\n * Reject a permission request\n */\n rejectPermission(requestId: string, reason?: string): boolean {\n return this.connection.rejectPermission(requestId, reason);\n }\n\n // ============================================\n // Question Management (ask_followup_question)\n // ============================================\n\n /**\n * Answer a question request with user's selections\n */\n answerQuestion(toolCallId: string, answers: QuestionAnswers): boolean {\n return this.connection.answerQuestion(toolCallId, answers);\n }\n\n /**\n * Cancel a question request\n */\n cancelQuestion(toolCallId: string, reason?: string): boolean {\n return this.connection.cancelQuestion(toolCallId, reason);\n }\n\n // ============================================\n // Tool Callback Management\n // ============================================\n\n /**\n * Callback for tool operations (approve / skip / cancel)\n * @param toolCallId Tool call ID\n * @param toolName Tool name\n * @param action Action to perform ('approve' / 'skip' / 'cancel')\n */\n async toolCallback(toolCallId: string, toolName: string, action: 'approve' | 'skip' | 'cancel'): Promise<{ success: boolean; error?: string }> {\n const connection = this.getConnectionOrThrow();\n return await connection.toolCallback(this._id, toolCallId, toolName, action);\n }\n\n // ============================================\n // Session Mode Management\n // ============================================\n\n /**\n * Set the current session mode\n *\n * @param modeId - The mode ID to switch to (must be in availableModes)\n * @throws Error if modeId is not in availableModes or connection fails\n *\n * @example\n * ```typescript\n * // Switch to 'code' mode\n * await session.setMode('code');\n *\n * // Switch to 'architect' mode\n * await session.setMode('architect');\n * ```\n */\n async setMode(modeId: string, skipAvailableChecker?: boolean): Promise<void> {\n // Validate modeId if availableModes is set\n if (this._availableModes && !skipAvailableChecker) {\n const modeExists = this._availableModes.some(m => m.id === modeId);\n if (!modeExists) {\n const availableIds = this._availableModes.map(m => m.id).join(', ');\n throw new Error(`Invalid modeId: \"${modeId}\". Available modes: ${availableIds}`);\n }\n }\n\n const connection = this.getConnectionOrThrow();\n await connection.setSessionMode(this._id, modeId);\n\n // Update internal state\n this._currentMode = modeId;\n }\n\n /**\n * Set the current session model\n *\n * @param modelId - The model ID to switch to\n * @example\n * ```typescript\n * // Switch to Claude Sonnet 4\n * await session.setSessionModel('claude-sonnet-4-20250514');\n *\n * // Switch to GPT-4o\n * await session.setSessionModel('gpt-4o');\n * ```\n */\n async setSessionModel(modelId: string): Promise<void> {\n this._currentModelId = modelId;\n const connection = this.getConnectionOrThrow();\n await connection.setSessionModel(this._id, modelId);\n }\n\n // ============================================\n // Event Subscription\n // ============================================\n\n /**\n * Subscribe to session events\n */\n on<K extends keyof SessionEvents>(event: K, handler: SessionEventHandler<K>): this {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(handler as EventListener<unknown>);\n return this;\n }\n\n /**\n * Unsubscribe from session events\n */\n off<K extends keyof SessionEvents>(event: K, handler: SessionEventHandler<K>): this {\n const eventListeners = this.listeners.get(event);\n if (eventListeners) {\n eventListeners.delete(handler as EventListener<unknown>);\n }\n const onceEventListeners = this.onceListeners.get(event);\n if (onceEventListeners) {\n onceEventListeners.delete(handler as EventListener<unknown>);\n }\n return this;\n }\n\n /**\n * Subscribe to a session event once\n */\n once<K extends keyof SessionEvents>(event: K, handler: SessionEventHandler<K>): this {\n if (!this.onceListeners.has(event)) {\n this.onceListeners.set(event, new Set());\n }\n this.onceListeners.get(event)!.add(handler as EventListener<unknown>);\n return this;\n }\n\n /**\n * Emit an event to all registered listeners\n */\n private emit<K extends keyof SessionEvents>(event: K, data: SessionEvents[K]): boolean {\n const regularListeners = this.listeners.get(event);\n const onceEventListeners = this.onceListeners.get(event);\n\n let hasListeners = false;\n\n // Call regular listeners\n if (regularListeners && regularListeners.size > 0) {\n hasListeners = true;\n for (const listener of regularListeners) {\n try {\n const result = listener(data);\n if (result instanceof Promise) {\n result.catch(err => {\n console.error(`Error in async event listener for '${String(event)}':`, err);\n });\n }\n } catch (err) {\n console.error(`Error in event listener for '${String(event)}':`, err);\n }\n }\n }\n\n // Call once listeners and remove them\n if (onceEventListeners && onceEventListeners.size > 0) {\n hasListeners = true;\n const listenersToCall = Array.from(onceEventListeners);\n this.onceListeners.delete(event);\n\n for (const listener of listenersToCall) {\n try {\n const result = listener(data);\n if (result instanceof Promise) {\n result.catch(err => {\n console.error(`Error in async once event listener for '${String(event)}':`, err);\n });\n }\n } catch (err) {\n console.error(`Error in once event listener for '${String(event)}':`, err);\n }\n }\n }\n\n return hasListeners;\n }\n\n /**\n * Remove all listeners for an event\n */\n private removeAllListeners<K extends keyof SessionEvents>(event?: K): void {\n if (event !== undefined) {\n this.listeners.delete(event);\n this.onceListeners.delete(event);\n } else {\n this.listeners.clear();\n this.onceListeners.clear();\n }\n }\n\n // ============================================\n // Lifecycle\n // ============================================\n\n /**\n * Disconnect from the session/agent\n */\n disconnect(): void {\n this.removeConnectionListeners();\n this.connection.disconnect();\n this.removeAllListeners();\n this.logger?.info(`Session ${this._id}: Disconnected`);\n }\n\n /**\n * Detach the session from connection events without disconnecting the connection.\n * This should be called when the session is being replaced but the connection is shared.\n * Unlike disconnect(), this only removes event listeners without closing the connection.\n */\n detach(): void {\n this.logger?.info(`Session ${this._id}: Detaching from connection events`);\n this.removeConnectionListeners();\n this.removeAllListeners();\n this.logger?.info(`Session ${this._id}: Detached successfully`);\n }\n\n /**\n * Symbol.dispose for 'using' keyword support\n * Automatically disconnects and cleans up when session goes out of scope\n *\n * @example\n * ```typescript\n * {\n * using session = await client.sessions.new({ cwd: '/workspace' });\n * // ... use session\n * } // session automatically disposed\n * ```\n */\n [Symbol.dispose](): void {\n this.disconnect();\n }\n\n // ============================================\n // Helpers\n // ============================================\n\n private getConnectionOrThrow(): AgentConnection {\n if (!this.connection.isInitialized) {\n throw new Error(`Session ${this._id}: Connection not initialized.`);\n }\n return this.connection;\n }\n\n /**\n * 在 connection 上注册 listener 并保存引用,便于 disconnect 时移除\n */\n private addConnectionListener<K extends keyof ConnectionEvents>(\n connection: AgentConnection,\n event: K,\n listener: (data: ConnectionEvents[K]) => void\n ): void {\n connection.on(event, listener);\n this.connectionListeners.push({ event: event as string, listener: listener as (...args: any[]) => void });\n }\n\n /**\n * 从 connection 上移除所有本 session 注册的 listener\n */\n private removeConnectionListeners(): void {\n for (const { event, listener } of this.connectionListeners) {\n this.connection.off(event as keyof ConnectionEvents, listener as any);\n }\n this.connectionListeners = [];\n }\n\n private setupConnectionEvents(connection: AgentConnection): void {\n // Connection lifecycle events\n this.addConnectionListener(connection, 'connected', () => {\n this.emit('connected', undefined as never);\n });\n\n this.addConnectionListener(connection, 'disconnected', () => {\n this.emit('disconnected', undefined as never);\n });\n\n this.addConnectionListener(connection, 'error', error => {\n this.emit('error', error);\n });\n\n // Session updates — 添加 sessionId 过滤,只转发属于当前 session 的更新\n // connection 可能被多个 session 共享(同 cwd),不过滤会导致消息串扰\n this.addConnectionListener(connection, 'sessionUpdate', update => {\n const notificationSessionId = (update as any)?.sessionId;\n // 过滤:只转发属于当前 session 的消息,或者 sessionId 缺失时放行(兼容旧协议)\n if (notificationSessionId && notificationSessionId !== this._id) {\n console.log(`[RT-DEBUG][AgentMgr:Session] sessionUpdate SKIPPED: notifSessionId mismatch, notif=${notificationSessionId?.substring(0, 8)}, my=${this._id?.substring(0, 8)}`);\n return;\n }\n this.emit('sessionUpdate', update);\n });\n\n // Artifact events — 使用 __sessionId 过滤,只转发属于当前 session 的 artifact\n // media 类型特殊处理:按 cwd 路径隔离(同 cwd 下不同 session 共享 media)\n this.addConnectionListener(connection, 'artifactCreated', artifact => {\n if (!this.shouldForwardArtifact(artifact)) {\n return;\n }\n this.emit('artifactCreated', artifact);\n });\n\n this.addConnectionListener(connection, 'artifactUpdated', artifact => {\n if (!this.shouldForwardArtifact(artifact)) {\n return;\n }\n this.emit('artifactUpdated', artifact);\n });\n\n this.addConnectionListener(connection, 'artifactDeleted', artifact => {\n if (!this.shouldForwardArtifact(artifact)) {\n return;\n }\n this.emit('artifactDeleted', artifact);\n });\n\n // Permission requests\n this.addConnectionListener(connection, 'permissionRequest', request => {\n this.emit('permissionRequest', request);\n });\n\n // Question requests\n this.addConnectionListener(connection, 'questionRequest', request => {\n this.emit('questionRequest', request);\n });\n\n this.addConnectionListener(connection, 'questionCancelled', () => {\n this.prompts.cancel();\n });\n\n // Usage updates\n this.addConnectionListener(connection, 'usageUpdate', usage => {\n this.emit('usageUpdate', usage);\n });\n\n // Checkpoint events — 使用 __sessionId 过滤\n this.addConnectionListener(connection, 'checkpointCreated', checkpoint => {\n const originSessionId = (checkpoint as any).__sessionId as string | undefined;\n if (originSessionId && originSessionId !== this._id) {\n return;\n }\n this.emit('checkpointCreated', checkpoint);\n });\n\n this.addConnectionListener(connection, 'checkpointUpdated', checkpoint => {\n const originSessionId = (checkpoint as any).__sessionId as string | undefined;\n if (originSessionId && originSessionId !== this._id) {\n return;\n }\n this.emit('checkpointUpdated', checkpoint);\n });\n\n // Command events — 使用 __sessionId 过滤\n this.addConnectionListener(connection, 'command', command => {\n const originSessionId = (command as any).__sessionId as string | undefined;\n if (originSessionId && originSessionId !== this._id) {\n console.log('[Session] Command not forwarded:', {\n command,\n originSessionId,\n sessionId: this._id,\n });\n return;\n }\n this.emit('command', command);\n });\n }\n\n private mapPromptResponse(response: SdkPromptResponse): PromptResponse {\n return {\n stopReason: response.stopReason as PromptResponse['stopReason'],\n _meta: response._meta ?? undefined\n };\n }\n\n /**\n * 判断 artifact 是否应该转发给当前 session\n * 所有类型的 artifact 都按 __sessionId 严格隔离\n */\n private shouldForwardArtifact(artifact: Artifact): boolean {\n const originSessionId = (artifact as any).__sessionId as string | undefined;\n\n // 按 sessionId 过滤:只转发属于当前 session 的 artifact\n // 如果没有 __sessionId,也拒绝(避免跨 session 污染)\n if (!originSessionId || originSessionId !== this._id) {\n return false;\n }\n return true;\n }\n}\n","/**\n * SessionManager - Manages session lifecycle and connections\n *\n * Provides the core implementation for session-centric API operations:\n * - list() - Lists sessions (mapped from agents)\n * - createSession() - Creates new session (auto-creates agent)\n * - loadSession() - Loads existing session (finds agent by sessionId)\n */\n\nimport { LoadSessionResponse, type NewSessionResponse } from '@agentclientprotocol/sdk';\nimport { SessionError } from '@genie/agent-client-protocol';\n\nimport { ActiveSessionImpl } from './session.js';\nimport type {\n ActiveSession,\n AgentConnection,\n AgentProvider,\n CreateSessionParams,\n ListAgentOptions,\n ListAgentResult,\n LoadSessionParams,\n Logger,\n ModelInfo,\n SessionInfo\n} from './types.js';\n\n/**\n * Options for creating a SessionManager instance\n */\nexport interface SessionManagerOptions {\n /** Agent provider (required) */\n provider: AgentProvider;\n /** Logger instance */\n logger?: Logger;\n}\n\n/**\n * SessionManager - Session lifecycle management\n *\n * This class manages the relationship between sessions and agents.\n * Since the backend is agent-centric, SessionManager handles the mapping:\n * - Sessions are views over agents\n * - sessionId may equal agentId in simple cases\n *\n * Features:\n * - Session caching: reuses existing ActiveSession instances\n * - Automatic cleanup on session disconnect\n *\n * @example\n * ```typescript\n * const manager = new SessionManager({ provider, logger });\n *\n * // List sessions\n * const sessions = await manager.listSessions();\n *\n * // Create new session\n * const session = await manager.createSession({ cwd: '/workspace' });\n *\n * // Load existing session (returns cached instance if available)\n * const loaded = await manager.loadSession({ sessionId: 'xxx', cwd: '/workspace' });\n * ```\n */\nexport class SessionManager {\n private provider: AgentProvider;\n private logger?: Logger;\n\n /**\n * Cache of connections from failed createSession() attempts.\n * Keyed by agentId, used by retryNewSession() to reuse the\n * existing initialized connection instead of re-connecting.\n *\n * @experimental Internal cache for retryNewSession support\n */\n private pendingConnections: Map<string, AgentConnection> = new Map();\n\n constructor(options: SessionManagerOptions) {\n this.provider = options.provider;\n this.logger = options.logger;\n }\n\n /**\n * List all sessions with pagination info (mapped from agents)\n *\n * Each agent maps to a session. The sessionId is derived from the agent.\n * Cloud: Returns server-side filtered/sorted/paginated results\n * Local: Returns client-side filtered/sorted results (synthetic pagination)\n *\n * @param options - Optional query parameters for filtering, sorting, and pagination\n */\n async listSessions(options?: ListAgentOptions): Promise<ListAgentResult<SessionInfo>> {\n const result = await this.provider.list(options);\n const sessions = result.agents.map(agent => ({\n // Use agentId as sessionId (since sessions are 1:1 with agents in current design)\n id: agent.id,\n agentId: agent.id,\n name: agent.name,\n status: agent.status,\n createdAt: agent.createdAt,\n updatedAt: agent.updatedAt,\n lastActivityAt: agent.updatedAt,\n // cwd is only available for local agents\n cwd: agent.type === 'local' ? agent.cwd : undefined,\n isPlayground: agent.isPlayground,\n isUserDefinedTitle: agent.isUserDefinedTitle,\n }));\n\n console.log('[SessionManager] Returning sessions:', { count: sessions.length, pagination: result.pagination });\n return {\n agents: sessions,\n pagination: result.pagination\n };\n }\n\n /**\n * Create a new session\n *\n * Steps:\n * 1. Create new agent (if provider supports it) or use existing\n * 2. Connect to agent\n * 3. Call ACP newSession\n * 4. Register session mapping (for LocalAgentProvider)\n * 5. Return ActiveSession instance\n */\n async createSession(params: CreateSessionParams): Promise<ActiveSession> {\n this.logger?.info('Creating new session');\n\n // Step 1: Create new agent if provider supports it\n let agentId: string;\n\n if (this.provider.create) {\n // Pass params to create() - LocalAgentProvider uses cwd as agentId\n agentId = await this.provider.create(params);\n this.logger?.debug(`Created new agent: ${agentId}`);\n\n // Step 1.5: Call onSessionPrepared callback immediately after POST succeeds\n // This allows UI to show the conversation before connect() completes\n if (params.options?.onSessionPrepared) {\n const initialPrompt = params.options?.prompt;\n const initialTitle = initialPrompt?.slice(0, 50) || '';\n params.options.onSessionPrepared({\n id: agentId,\n agentId: agentId,\n name: initialTitle + (initialPrompt && initialPrompt.length > 50 ? '...' : ''),\n status: 'connecting' as any,\n cwd: params.cwd || '',\n createdAt: new Date(),\n });\n this.logger?.debug(`Called onSessionPrepared for: ${agentId}`);\n }\n } else {\n // If provider doesn't support create, we need to throw\n // The provider must support creating agents for sessions.new()\n throw new Error('Provider does not support creating agents. Use sessions.load() with an existing sessionId.');\n }\n\n // Step 2: Connect to agent\n const connection = await this.provider.connect(agentId);\n this.logger?.debug(`Connected to agent: ${agentId}`);\n\n // Step 3: Create session via ACP\n // If session/new fails, attach agentId and connection to the error\n // so callers can use retryNewSession() to recover\n let response;\n try {\n response = await connection.createSession({\n _meta: params.options?._meta,\n cwd: params.cwd,\n mcpServers: params.options?.mcpServers\n });\n } catch (err) {\n // Cache the initialized connection so retryNewSession() can reuse it\n this.pendingConnections.set(agentId, connection);\n this.logger?.debug(`Cached pending connection for agent: ${agentId}`);\n\n // Wrap or augment the error with agentId for retry support\n if (err instanceof SessionError) {\n throw new SessionError(\n err.message,\n err.sessionId,\n agentId,\n err.cause instanceof Error ? err.cause : undefined\n );\n }\n // For non-SessionError, wrap with agentId\n const cause = err instanceof Error ? err : new Error(String(err));\n throw new SessionError(\n `Failed to create session: ${cause.message}`,\n undefined,\n agentId,\n cause\n );\n }\n\n return this.buildActiveSession(response, agentId, connection, params);\n }\n\n /**\n * Retry creating a session after initial session/new request failed.\n *\n * Use this when `sessions.create()` fails at the `session/new` step\n * (after agent creation and connection establishment succeeded).\n * The caller retrieves `agentId` from the thrown `SessionError.agentId`,\n * then calls this method to re-attempt only the `session/new` request\n * while reusing the already-initialized connection (no re-connect).\n *\n * @experimental This API is subject to change\n *\n * @param agentId - Agent ID from the failed SessionError\n * @param params - Original create session params (cwd, mcpServers, etc.)\n * @returns ActiveSession on success\n * @throws SessionError if session/new fails again\n *\n * @example\n * ```typescript\n * try {\n * const session = await client.sessions.create({ cwd: '/workspace' });\n * } catch (err) {\n * if (err instanceof SessionError && err.agentId) {\n * // Retry with custom logic\n * for (let i = 0; i < 3; i++) {\n * try {\n * const session = await client.sessions.retryNewSession(err.agentId, { cwd: '/workspace' });\n * break; // success\n * } catch (retryErr) {\n * await new Promise(r => setTimeout(r, 1000 * (i + 1)));\n * }\n * }\n * }\n * }\n * ```\n */\n async retryNewSession(agentId: string, params: CreateSessionParams): Promise<ActiveSession> {\n this.logger?.info(`Retrying session/new for agent: ${agentId}`);\n\n // Reuse the cached connection from the failed createSession() attempt\n // This avoids re-running the initialize handshake\n const connection = this.pendingConnections.get(agentId);\n if (!connection) {\n throw new SessionError(\n `No pending connection found for agent: ${agentId}. ` +\n 'retryNewSession() can only be called after a failed sessions.create().',\n undefined,\n agentId\n );\n }\n this.logger?.debug(`Reusing cached connection for agent: ${agentId}`);\n\n // Retry session/new\n const response = await connection.createSession({\n _meta: params.options?._meta,\n cwd: params.cwd,\n mcpServers: params.options?.mcpServers\n });\n\n // Success - remove from pending cache\n this.pendingConnections.delete(agentId);\n this.logger?.debug(`Cleared pending connection for agent: ${agentId}`);\n\n return this.buildActiveSession(response, agentId, connection, params);\n }\n\n /**\n * Build an ActiveSession from a NewSessionResponse.\n * Shared by createSession() and retryNewSession().\n */\n private buildActiveSession(\n response: NewSessionResponse,\n agentId: string,\n connection: AgentConnection,\n params: CreateSessionParams\n ): ActiveSession {\n // Register session mapping (for LocalAgentProvider to support loadSession)\n if (this.provider.registerSession) {\n this.provider.registerSession(response.sessionId, agentId);\n this.logger?.debug(`Registered session mapping: ${response.sessionId} → ${agentId}`);\n }\n\n // Get connectionInfo from CloudAgentConnection if available\n const connectionInfo = (connection as any).sessionConnectionInfo;\n\n const session = new ActiveSessionImpl(\n response.sessionId,\n agentId,\n connection,\n {\n logger: this.logger,\n // Bind sessionId (not agentId) to create a getter function for filesystem\n // Note: conversation-channel-router binds sessionId to windowId,\n // so we must use sessionId for filesystem routing\n getFilesystem: this.provider.filesystem\n ? () => this.provider.filesystem!.getFilesystem(response.sessionId)\n : undefined,\n // Pass connectionInfo from CloudAgentConnection (if available)\n connectionInfo\n }\n );\n\n // Set modes from response\n session.setModes(\n response.modes?.availableModes,\n response.modes?.currentModeId\n );\n\n // Set models from response\n const availableModels = this.extractAvailableModels(response);\n if (availableModels) {\n session.setModels(availableModels, response.models?.currentModelId);\n }\n\n // Set actual cwd from response _meta (important for Playground where cwd is generated server-side)\n const responseCwd = (response._meta as any)?.['codebuddy.ai']?.cwd;\n if (responseCwd) {\n session.setCwd(responseCwd);\n }\n\n this.logger?.info(`Session created: ${response.sessionId}`);\n return session;\n }\n\n /**\n * Load an existing session\n *\n * Steps:\n * 1. Check cache for existing session\n * 2. Find agent by sessionId (sessionId === agentId in current design)\n * 3. Connect to agent\n * 4. Create ActiveSession instance\n * 5. Execute onSessionCreated callback (if provided) to allow early setup (e.g., event listeners)\n * 6. Call ACP loadSession\n * 7. Return ActiveSession instance (cached)\n */\n async loadSession(params: LoadSessionParams): Promise<ActiveSession> {\n this.logger?.info(`Loading session: ${params.sessionId}`);\n\n // Step 2: Find agent by sessionId\n // In current design, sessionId === agentId\n const agentId = params.sessionId;\n\n // Verify agent exists\n const agentState = await this.provider.get(agentId);\n if (!agentState) {\n throw new Error(`Session not found: ${params.sessionId}`);\n }\n\n // Step 3: Connect to agent\n const connection = await this.provider.connect(agentId);\n this.logger?.debug(`Connected to agent: ${agentId}`);\n\n // Step 4: Create ActiveSession instance (BEFORE loadSession call)\n // Get connectionInfo from CloudAgentConnection if available\n const connectionInfo = (connection as any).sessionConnectionInfo;\n\n const session = new ActiveSessionImpl(\n params.sessionId,\n agentId,\n connection,\n {\n logger: this.logger,\n // Bind sessionId (not agentId) to create a getter function for filesystem\n // Note: conversation-channel-router binds sessionId to windowId,\n // so we must use sessionId for filesystem routing\n getFilesystem: this.provider.filesystem\n ? () => this.provider.filesystem!.getFilesystem(params.sessionId)\n : undefined,\n // Pass connectionInfo from CloudAgentConnection (if available)\n connectionInfo\n }\n );\n\n // Step 5: Execute onSessionCreated callback (BEFORE loadSession)\n // This allows callers to set up event listeners before historical messages arrive\n if (params.onSessionCreated) {\n await params.onSessionCreated(session);\n }\n\n // Step 6: Load session via ACP (may trigger historical message push)\n const response = await connection.loadSession({\n sessionId: params.sessionId,\n cwd: agentState.type === 'local' ? agentState.cwd : params.cwd,\n mcpServers: params.mcpServers\n });\n\n // Step 7: Set modes and models from response\n session.setModes(\n response.modes?.availableModes,\n response.modes?.currentModeId\n );\n\n // Set models from response\n const availableModels = this.extractAvailableModels(response);\n if (availableModels) {\n session.setModels(availableModels, response.models?.currentModelId);\n }\n\n this.logger?.info(`Session loaded: ${params.sessionId}`);\n return session;\n }\n\n /**\n * 从 ACP response 中提取可用模型列表\n *\n * 优先级:\n * 1. response.models._meta?.['codebuddy.ai']?.availableModels - 包含完整的模型信息(字段名为 'id')\n * 2. response.models?.availableModels - 只包含基本信息(字段名为 'modelId')\n * 3. undefined - 都没有时返回 undefined\n *\n * @param response - ACP 响应对象\n * @returns ModelInfo[] | undefined\n */\n protected extractAvailableModels(response: LoadSessionResponse): ModelInfo[] | undefined {\n // Priority 1: 检查 _meta['codebuddy.ai'].availableModels (完整信息,字段名为 'id')\n const metaModels = (response.models?._meta?.['codebuddy.ai'] as { availableModels: ModelInfo[] })?.availableModels;\n if (metaModels && Array.isArray(metaModels) && metaModels.length > 0) {\n return metaModels;\n }\n\n // Priority 2: 检查 models.availableModels (基本信息,字段名为 'modelId')\n const availableModels = response.models?.availableModels;\n if (availableModels && Array.isArray(availableModels) && availableModels.length > 0) {\n return availableModels.map(model => ({\n ...model,\n ...(model._meta?.['codebuddy.ai'] || {}),\n } as unknown as ModelInfo));\n }\n\n // Priority 3: 没有可用模型\n return undefined;\n }\n}\n","/**\n * AgentClient - Session-centric API\n *\n * Provides a unified entry point for managing sessions.\n * Sessions are the primary API surface; agents are internal implementation.\n */\n\nimport type { ModelInfo } from '../types.js';\nimport { SessionManager } from './session-manager.js';\nimport type {\n AgentClientOptions,\n AgentProvider,\n AutomationSnapshot,\n AutomationUpdatePayload,\n AutomationUpdateResult,\n BatchPluginOperationRequest,\n BatchPluginOperationResult,\n ClientSessionsResource,\n DeleteSkillParams,\n DeleteSkillResponse,\n GetAvailableCommandsParams,\n GetMarketplaceSkillContentParams,\n GetMarketplaceSkillContentResponse,\n GetMarketplaceSkillsResponse,\n GetSkillContentParams,\n GetSkillContentResponse,\n GetSkillListParams,\n GetSkillListResponse,\n GetSubagentListParams,\n GetSubagentListResponse,\n ImportSkillParams,\n ImportSkillResponse,\n InitializeWorkspaceParams,\n InitializeWorkspaceResponse,\n InstallMarketplaceSkillParams,\n InstallMarketplaceSkillResponse,\n ListAgentOptions,\n Logger,\n ModelsResource,\n PickFileParams,\n PickFileResponse,\n PickFolderParams,\n PickFolderResponse,\n SearchFileParams,\n SearchFileResponse,\n SessionsResourceEventHandler,\n SessionsResourceEvents,\n ToggleSkillParams,\n ToggleSkillResponse,\n UploadFileParams,\n UploadFileResponse,\n WorkspaceInfo} from './types.js';\n\n// ============================================\n// AgentClient - Session-Centric API\n// ============================================\n\n/**\n * AgentClient - Session-centric client\n *\n * Provides a session-centric API that internally manages agents.\n * Users interact with sessions; the agent lifecycle is handled internally.\n *\n * @example\n * ```typescript\n * // Create client with a provider\n * const provider = new CloudAgentProvider({\n * endpoint: 'https://api.example.com',\n * authToken: 'token'\n * });\n *\n * const client = new AgentClient({\n * provider,\n * logger: console\n * });\n *\n * // List all sessions\n * const sessions = await client.sessions.list();\n *\n * // Create new session (auto-creates agent and connects)\n * const session = await client.sessions.create({ cwd: '/workspace' });\n * console.log(session.agentState.status); // agent status\n * console.log(session.agentState.id); // agent ID\n *\n * // Send prompt\n * await session.prompts.send({ content: 'Hello' });\n *\n * // Get available models\n * const models = await client.sessions.models.list('my-repo');\n *\n * // Use 'using' keyword for automatic cleanup\n * {\n * using session = await client.sessions.create({ cwd: '/workspace' });\n * // ... use session\n * } // session automatically disposed\n *\n * // Or manually disconnect\n * session.disconnect();\n *\n * // Load existing session\n * const loadedSession = await client.sessions.load({\n * sessionId: 'xxx',\n * cwd: '/workspace'\n * });\n * ```\n */\nexport class AgentClient {\n private logger?: Logger;\n private provider: AgentProvider;\n private sessionManager: SessionManager;\n\n /**\n * Sessions resource namespace (primary API entry point)\n */\n readonly sessions: ClientSessionsResource;\n\n /**\n * 运行环境类型\n * - 'local': IDE 本地环境\n * - 'cloud': 云端环境\n */\n readonly environmentType: 'local' | 'cloud';\n\n constructor(options: AgentClientOptions) {\n this.logger = options.logger;\n this.provider = options.provider;\n this.environmentType = options.environmentType ?? 'cloud';\n\n // Initialize session manager\n this.sessionManager = new SessionManager({\n provider: this.provider,\n logger: this.logger\n });\n\n // Initialize sessions resource\n this.sessions = this.createSessionsResource();\n }\n\n // ============================================\n // Sessions Resource\n // ============================================\n\n private createSessionsResource(): ClientSessionsResource {\n return {\n list: async (options?: ListAgentOptions) => this.sessionManager.listSessions(options),\n\n create: async params => this.sessionManager.createSession(params),\n\n retryNewSession: async (agentId, params) => this.sessionManager.retryNewSession(agentId, params),\n\n load: async params => {\n console.log('[AgentClient] sessions.load called:', params.sessionId);\n return this.sessionManager.loadSession(params);\n },\n\n archive: async (sessionId: string): Promise<{ id: string }> => {\n this.logger?.debug('AgentClient.sessions.archive called', { sessionId });\n\n try {\n // Check if provider supports archive\n if (this.provider.archive) {\n const result = await this.provider.archive(sessionId);\n this.logger?.info('Session archived successfully', { sessionId });\n return result;\n }\n\n // If provider does not support archive, throw error\n throw new Error('Provider does not support archive method');\n } catch (error) {\n this.logger?.error('Failed to archive session', error);\n throw error;\n }\n },\n\n rename: async (sessionId: string, title: string): Promise<{ id: string }> => {\n this.logger?.debug('AgentClient.sessions.rename called', { sessionId, title });\n\n try {\n // Check if provider supports rename\n if (this.provider.rename) {\n const result = await this.provider.rename(sessionId, title);\n this.logger?.info('Session renamed successfully', { sessionId, title });\n return result;\n }\n\n // If provider does not support rename, throw error\n throw new Error('Provider does not support rename method');\n } catch (error) {\n this.logger?.error('Failed to rename session', error);\n throw error;\n }\n },\n\n updateStatus: async (sessionId: string, status: string): Promise<{ id: string }> => {\n this.logger?.debug('AgentClient.sessions.updateStatus called', { sessionId, status });\n\n try {\n // Check if provider supports updateStatus\n if (this.provider.updateStatus) {\n const result = await this.provider.updateStatus(sessionId, status);\n this.logger?.info('Session status updated successfully', { sessionId, status });\n return result;\n }\n\n // If provider does not support updateStatus, throw error\n throw new Error('Provider does not support updateStatus method');\n } catch (error) {\n this.logger?.error('Failed to update session status', error);\n throw error;\n }\n },\n\n move: async (sessionId: string): Promise<{ id: string }> => {\n this.logger?.debug('AgentClient.sessions.move called', { sessionId });\n\n try {\n // Check if provider supports move\n if (this.provider.move) {\n const result = await this.provider.move(sessionId);\n this.logger?.info('Session moved successfully', { sessionId });\n return result;\n }\n\n // If provider does not support move, throw error\n throw new Error('Provider does not support move method');\n } catch (error) {\n this.logger?.error('Failed to move session', error);\n throw error;\n }\n },\n\n // Initialize workspace for future sessions\n initializeWorkspace: async (params: InitializeWorkspaceParams): Promise<InitializeWorkspaceResponse> => {\n this.logger?.debug('AgentClient.sessions.initializeWorkspace called', params);\n\n try {\n // openWorkspace 是 LocalAgentProvider 特有的能力\n if (this.provider.openWorkspace) {\n const result = await this.provider.openWorkspace(params);\n this.logger?.info('Workspace opened successfully', { cwd: params.cwd });\n return result;\n }\n\n // 如果 provider 不支持 openWorkspace,返回成功(向后兼容)\n this.logger?.warn('Provider does not support openWorkspace');\n return { success: true };\n\n } catch (error) {\n this.logger?.error('Failed to initialize workspace', error);\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error'\n };\n }\n },\n\n requestYieldAfterCurrentStep: async (sessionId: string): Promise<boolean> => {\n try {\n if (this.provider?.requestYieldAfterCurrentStep) {\n return await this.provider.requestYieldAfterCurrentStep(sessionId);\n }\n this.logger?.warn('Provider does not support requestYieldAfterCurrentStep');\n return false;\n } catch (error) {\n this.logger?.error('Failed to request yield after current step', error);\n return false;\n }\n },\n\n // Get current workspaces list\n getCurrentWorkspaces: async (filter?: { activeOnly?: boolean }): Promise<WorkspaceInfo[]> => {\n this.logger?.debug('AgentClient.sessions.getCurrentWorkspaces called', filter);\n\n try {\n // getCurrentWorkspaces 是 LocalAgentProvider 特有的能力\n if ('getCurrentWorkspaces' in this.provider && typeof this.provider.getCurrentWorkspaces === 'function') {\n const result = await this.provider.getCurrentWorkspaces(filter);\n this.logger?.info('Current workspaces retrieved', { count: result.length });\n return result;\n }\n\n // 如果 provider 不支持 getCurrentWorkspaces,返回空数组(向后兼容)\n this.logger?.warn('Provider does not support getCurrentWorkspaces');\n return [];\n\n } catch (error) {\n this.logger?.error('Failed to get current workspaces', error);\n return [];\n }\n },\n\n // ==================== Automation ====================\n getAutomationSnapshot: async (): Promise<AutomationSnapshot> => {\n try {\n if (this.provider?.getAutomationSnapshot) {\n return await this.provider.getAutomationSnapshot();\n }\n this.logger?.warn('Provider does not support getAutomationSnapshot');\n } catch (error) {\n this.logger?.error('Failed to get automation snapshot', error);\n }\n\n return {\n automations: [],\n inbox: [],\n runtimeState: {},\n updatedAt: Date.now(),\n };\n },\n\n updateAutomation: async (payload: AutomationUpdatePayload): Promise<AutomationUpdateResult> => {\n try {\n if (this.provider?.updateAutomation) {\n return await this.provider.updateAutomation(payload);\n }\n this.logger?.warn('Provider does not support updateAutomation');\n } catch (error) {\n this.logger?.error('Failed to update automation', error);\n return {\n success: false,\n message: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n\n return {\n success: false,\n message: 'Provider does not support updateAutomation',\n };\n },\n\n deleteAutomation: async (id: string): Promise<AutomationUpdateResult> => {\n try {\n if (this.provider?.deleteAutomation) {\n return await this.provider.deleteAutomation(id);\n }\n this.logger?.warn('Provider does not support deleteAutomation');\n } catch (error) {\n this.logger?.error('Failed to delete automation', error);\n return {\n success: false,\n message: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n\n return {\n success: false,\n message: 'Provider does not support deleteAutomation',\n };\n },\n\n archiveAutomationInboxItem: async (itemId: string): Promise<AutomationUpdateResult> => {\n try {\n if (this.provider?.archiveAutomationInboxItem) {\n return await this.provider.archiveAutomationInboxItem(itemId);\n }\n this.logger?.warn('Provider does not support archiveAutomationInboxItem');\n } catch (error) {\n this.logger?.error('Failed to archive automation inbox item', error);\n return {\n success: false,\n message: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n\n return {\n success: false,\n message: 'Provider does not support archiveAutomationInboxItem',\n };\n },\n\n deleteAutomationInboxItem: async (itemId: string): Promise<AutomationUpdateResult> => {\n try {\n if (this.provider?.deleteAutomationInboxItem) {\n return await this.provider.deleteAutomationInboxItem(itemId);\n }\n this.logger?.warn('Provider does not support deleteAutomationInboxItem');\n } catch (error) {\n this.logger?.error('Failed to delete automation inbox item', error);\n return {\n success: false,\n message: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n\n return {\n success: false,\n message: 'Provider does not support deleteAutomationInboxItem',\n };\n },\n\n testAutomation: async (id: string): Promise<AutomationUpdateResult> => {\n try {\n if (this.provider?.testAutomation) {\n return await this.provider.testAutomation(id);\n }\n this.logger?.warn('Provider does not support testAutomation');\n } catch (error) {\n this.logger?.error('Failed to test automation', error);\n return {\n success: false,\n message: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n\n return {\n success: false,\n message: 'Provider does not support testAutomation',\n };\n },\n\n // Event methods - forward to provider if supported\n on: <K extends keyof SessionsResourceEvents>(\n event: K,\n handler: SessionsResourceEventHandler<K>\n ): void => {\n if (this.provider.on) {\n this.provider.on(event as string, handler as (...args: any[]) => void);\n } else {\n this.logger?.warn(`Provider does not support event registration: ${String(event)}`);\n }\n },\n\n off: <K extends keyof SessionsResourceEvents>(\n event: K,\n handler: SessionsResourceEventHandler<K>\n ): void => {\n if (this.provider.off) {\n this.provider.off(event as string, handler as (...args: any[]) => void);\n } else {\n this.logger?.warn(`Provider does not support event unregistration: ${String(event)}`);\n }\n },\n\n openWorkspace: async (params: InitializeWorkspaceParams): Promise<InitializeWorkspaceResponse> => {\n try {\n if (this.provider && this.provider.openWorkspace) {\n const result = await this.provider.openWorkspace(params);\n this.logger?.info('Workspace opened successfully', { cwd: params.cwd });\n return result;\n }\n return { success: false, error: 'Provider does not support openWorkspace' };\n } catch (error) {\n this.logger?.error('Failed to open workspace', error);\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error'\n };\n }\n },\n\n pickFile: async (params?: PickFileParams): Promise<PickFileResponse> => {\n try {\n if (this.provider && this.provider.pickFile) {\n const result = await this.provider.pickFile(params);\n this.logger?.info('File picker completed', { fileCount: result.files.length, canceled: result.canceled });\n return result;\n }\n return { files: [], canceled: true, error: 'Provider does not support pickFile' };\n } catch (error) {\n this.logger?.error('Failed to pick file', error);\n return {\n files: [],\n canceled: true,\n error: error instanceof Error ? error.message : 'Unknown error'\n };\n }\n },\n\n pickFolder: async (params?: PickFolderParams): Promise<PickFolderResponse> => {\n try {\n if (this.provider && this.provider.pickFolder) {\n const result = await this.provider.pickFolder(params);\n this.logger?.info('Folder picker completed', { folderPaths: result.folderPaths, canceled: result.canceled });\n return result;\n }\n return { folderPaths: [], canceled: true, error: 'Provider does not support pickFolder' };\n } catch (error) {\n this.logger?.error('Failed to pick folder', error);\n return {\n folderPaths: [],\n canceled: true,\n error: error instanceof Error ? error.message : 'Unknown error'\n };\n }\n },\n\n uploadFile: async (params: UploadFileParams): Promise<UploadFileResponse> => {\n try {\n if (this.provider && this.provider.uploadFile) {\n const result = await this.provider.uploadFile(params);\n this.logger?.info('File upload completed', { count: params.files.length, success: result.success });\n return result;\n }\n return { success: false, error: 'Provider does not support uploadFile' };\n } catch (error) {\n this.logger?.error('Failed to upload file', error);\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error'\n };\n }\n },\n\n searchFile: async (params: SearchFileParams): Promise<SearchFileResponse> => {\n try {\n if (this.provider && this.provider.searchFile) {\n const result = await this.provider.searchFile(params);\n this.logger?.info('File search completed', { resultCount: result.results.length, hasError: !!result.error });\n return result;\n }\n return { results: [], error: 'Provider does not support searchFile' };\n } catch (error) {\n this.logger?.error('Failed to search file', error);\n return {\n results: [],\n error: error instanceof Error ? error.message : 'Unknown error'\n };\n }\n },\n\n getSubagentList: async (params: GetSubagentListParams): Promise<GetSubagentListResponse> => {\n try {\n if (this.provider && this.provider.getSubagentList) {\n const result = await this.provider.getSubagentList(params);\n this.logger?.info('Subagent list retrieved', { resultCount: result.results.length, hasError: !!result.error });\n return result;\n }\n return { results: [], error: 'Provider does not support getSubagentList' };\n } catch (error) {\n this.logger?.error('Failed to get subagent list', error);\n return {\n results: [],\n error: error instanceof Error ? error.message : 'Unknown error'\n };\n }\n },\n\n getSkillList: async (params?: GetSkillListParams): Promise<GetSkillListResponse> => {\n try {\n if (this.provider && this.provider.getSkillList) {\n const result = await this.provider.getSkillList(params);\n this.logger?.info('Skill list retrieved', { resultCount: result.results.length, hasError: !!result.error });\n return result;\n }\n return { results: [], error: 'Provider does not support getSkillList' };\n } catch (error) {\n this.logger?.error('Failed to get skill list', error);\n return {\n results: [],\n error: error instanceof Error ? error.message : 'Unknown error'\n };\n }\n },\n\n importSkill: async (params: ImportSkillParams): Promise<ImportSkillResponse> => {\n try {\n if (this.provider && this.provider.importSkill) {\n const result = await this.provider.importSkill(params);\n this.logger?.info('Import skill completed', { success: result.success, hasError: !!result.error });\n return result;\n }\n return { success: false, error: 'Provider does not support importSkill' };\n } catch (error) {\n this.logger?.error('Failed to import skill', error);\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error'\n };\n }\n },\n\n toggleSkill: async (params: ToggleSkillParams): Promise<ToggleSkillResponse> => {\n try {\n if (this.provider && this.provider.toggleSkill) {\n const result = await this.provider.toggleSkill(params);\n this.logger?.info('Toggle skill completed', { success: result.success, hasError: !!result.error });\n return result;\n }\n return { success: false, error: 'Provider does not support toggleSkill' };\n } catch (error) {\n this.logger?.error('Failed to toggle skill', error);\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error'\n };\n }\n },\n\n deleteSkill: async (params: DeleteSkillParams): Promise<DeleteSkillResponse> => {\n try {\n if (this.provider && this.provider.deleteSkill) {\n const result = await this.provider.deleteSkill(params);\n this.logger?.info('Delete skill completed', { success: result.success, hasError: !!result.error });\n return result;\n }\n return { success: false, error: 'Provider does not support deleteSkill' };\n } catch (error) {\n this.logger?.error('Failed to delete skill', error);\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error'\n };\n }\n },\n\n getSkillContent: async (params: GetSkillContentParams): Promise<GetSkillContentResponse> => {\n try {\n if (this.provider && this.provider.getSkillContent) {\n const result = await this.provider.getSkillContent(params);\n this.logger?.info('Get skill content completed', { hasError: !!result.error });\n return result;\n }\n return { content: '', error: 'Provider does not support getSkillContent' };\n } catch (error) {\n this.logger?.error('Failed to get skill content', error);\n return {\n content: '',\n error: error instanceof Error ? error.message : 'Unknown error'\n };\n }\n },\n\n getMarketplaceSkills: async (): Promise<GetMarketplaceSkillsResponse> => {\n try {\n if (this.provider && this.provider.getMarketplaceSkills) {\n const result = await this.provider.getMarketplaceSkills();\n this.logger?.info('Marketplace skills retrieved', { resultCount: result.results.length, hasError: !!result.error });\n return result;\n }\n return { results: [], error: 'Provider does not support getMarketplaceSkills' };\n } catch (error) {\n this.logger?.error('Failed to get marketplace skills', error);\n return {\n results: [],\n error: error instanceof Error ? error.message : 'Unknown error'\n };\n }\n },\n\n getMarketplaceSkillContent: async (params: GetMarketplaceSkillContentParams): Promise<GetMarketplaceSkillContentResponse> => {\n try {\n if (this.provider && this.provider.getMarketplaceSkillContent) {\n return await this.provider.getMarketplaceSkillContent(params);\n }\n return { content: '', error: 'Provider does not support getMarketplaceSkillContent' };\n } catch (error) {\n this.logger?.error('Failed to get marketplace skill content', error);\n return {\n content: '',\n error: error instanceof Error ? error.message : 'Unknown error'\n };\n }\n },\n\n installMarketplaceSkill: async (params: InstallMarketplaceSkillParams): Promise<InstallMarketplaceSkillResponse> => {\n try {\n if (this.provider && this.provider.installMarketplaceSkill) {\n return await this.provider.installMarketplaceSkill(params);\n }\n return { success: false, skillName: params.skillName, errorMessage: 'Provider does not support installMarketplaceSkill' };\n } catch (error) {\n this.logger?.error('Failed to install marketplace skill', error);\n return {\n success: false,\n skillName: params.skillName,\n errorMessage: error instanceof Error ? error.message : 'Unknown error'\n };\n }\n },\n\n batchTogglePlugins: async (request: BatchPluginOperationRequest): Promise<BatchPluginOperationResult> => {\n try {\n if (this.provider && this.provider.batchTogglePlugins) {\n const result = await this.provider.batchTogglePlugins(request);\n this.logger?.info('Batch toggle plugins completed', {\n succeededCount: result.succeededPlugins.length,\n failedCount: result.failedPlugins.length\n });\n return result;\n }\n return {\n success: false,\n succeededPlugins: [],\n failedPlugins: request.items.map(item => ({\n ...item,\n error: 'Provider does not support batchTogglePlugins'\n }))\n };\n } catch (error) {\n this.logger?.error('Failed to batch toggle plugins', error);\n return {\n success: false,\n succeededPlugins: [],\n failedPlugins: request.items.map(item => ({\n ...item,\n error: error instanceof Error ? error.message : 'Unknown error'\n }))\n };\n }\n },\n\n getInstalledPlugins: async (forceRefresh?: boolean) => {\n try {\n if (this.provider && 'getInstalledPlugins' in this.provider && typeof this.provider.getInstalledPlugins === 'function') {\n const result = await this.provider.getInstalledPlugins(forceRefresh);\n this.logger?.info('Got installed plugins', { count: result?.length ?? 0 });\n return result;\n }\n this.logger?.warn('Provider does not support getInstalledPlugins');\n return [];\n } catch (error) {\n this.logger?.error('Failed to get installed plugins', error);\n return [];\n }\n },\n\n installPlugins: async (pluginNames, marketplaceName, installScope, marketplaceSource, workspacePath) => {\n try {\n if (this.provider && 'installPlugins' in this.provider && typeof this.provider.installPlugins === 'function') {\n const result = await this.provider.installPlugins(pluginNames, marketplaceName, installScope, marketplaceSource, workspacePath);\n this.logger?.info('Install plugins', { pluginNames, marketplaceName, success: result.success });\n return result;\n }\n this.logger?.warn('Provider does not support installPlugins');\n return { success: false, error: 'Provider does not support installPlugins' };\n } catch (error) {\n this.logger?.error('Failed to install plugins', error);\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error'\n };\n }\n },\n\n uninstallPlugin: async (pluginName: string, marketplaceName: string, scope: 'user' | 'project' | 'project-local') => {\n try {\n if (this.provider && 'uninstallPlugin' in this.provider && typeof this.provider.uninstallPlugin === 'function') {\n const result = await this.provider.uninstallPlugin(pluginName, marketplaceName, scope);\n this.logger?.info('Uninstall plugin', { pluginName, marketplaceName, scope, success: result.success });\n return result;\n }\n this.logger?.warn('Provider does not support uninstallPlugin');\n return { success: false, error: 'Provider does not support uninstallPlugin' };\n } catch (error) {\n this.logger?.error('Failed to uninstall plugin', error);\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error'\n };\n }\n },\n\n updatePlugin: async (pluginName: string, marketplaceName: string) => {\n try {\n if (this.provider && 'updatePlugin' in this.provider && typeof this.provider.updatePlugin === 'function') {\n const result = await this.provider.updatePlugin(pluginName, marketplaceName);\n this.logger?.info('Update plugin', { pluginName, marketplaceName, success: result.success });\n return result;\n }\n this.logger?.warn('Provider does not support updatePlugin');\n return { success: false, error: 'Provider does not support updatePlugin' };\n } catch (error) {\n this.logger?.error('Failed to update plugin', error);\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error'\n };\n }\n },\n\n getPluginMarketplaces: async (forceRefresh?: boolean) => {\n try {\n if (this.provider && 'getPluginMarketplaces' in this.provider && typeof this.provider.getPluginMarketplaces === 'function') {\n const result = await this.provider.getPluginMarketplaces(forceRefresh);\n this.logger?.info('Got plugin marketplaces', { count: result?.length ?? 0 });\n return result;\n }\n this.logger?.warn('Provider does not support getPluginMarketplaces');\n return [];\n } catch (error) {\n this.logger?.error('Failed to get plugin marketplaces', error);\n return [];\n }\n },\n\n getMarketplacePlugins: async (marketplaceName: string, forceRefresh?: boolean, searchText?: string) => {\n try {\n if (this.provider && 'getMarketplacePlugins' in this.provider && typeof this.provider.getMarketplacePlugins === 'function') {\n const result = await this.provider.getMarketplacePlugins(marketplaceName, forceRefresh, searchText);\n this.logger?.info('Got marketplace plugins', { marketplaceName, count: result?.length ?? 0 });\n return result;\n }\n this.logger?.warn('Provider does not support getMarketplacePlugins');\n return [];\n } catch (error) {\n this.logger?.error('Failed to get marketplace plugins', error);\n return [];\n }\n },\n\n getPluginDetail: async (pluginName: string, marketplaceName: string) => {\n try {\n if (this.provider && 'getPluginDetail' in this.provider && typeof this.provider.getPluginDetail === 'function') {\n const result = await this.provider.getPluginDetail(pluginName, marketplaceName);\n this.logger?.info('Got plugin detail', { pluginName, marketplaceName });\n return result;\n }\n this.logger?.warn('Provider does not support getPluginDetail');\n return null;\n } catch (error) {\n this.logger?.error('Failed to get plugin detail', error);\n return null;\n }\n },\n\n addPluginMarketplace: async (source: string, name?: string) => {\n try {\n if (this.provider && 'addPluginMarketplace' in this.provider && typeof this.provider.addPluginMarketplace === 'function') {\n const result = await this.provider.addPluginMarketplace(source, name);\n this.logger?.info('Add plugin marketplace', { source, name, success: result.success });\n return result;\n }\n this.logger?.warn('Provider does not support addPluginMarketplace');\n return { success: false, error: 'Provider does not support addPluginMarketplace' };\n } catch (error) {\n this.logger?.error('Failed to add plugin marketplace', error);\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error'\n };\n }\n },\n\n removePluginMarketplace: async (marketplaceName: string) => {\n try {\n if (this.provider && 'removePluginMarketplace' in this.provider && typeof this.provider.removePluginMarketplace === 'function') {\n const result = await this.provider.removePluginMarketplace(marketplaceName);\n this.logger?.info('Remove plugin marketplace', { marketplaceName, success: result.success });\n return result;\n }\n this.logger?.warn('Provider does not support removePluginMarketplace');\n return { success: false, error: 'Provider does not support removePluginMarketplace' };\n } catch (error) {\n this.logger?.error('Failed to remove plugin marketplace', error);\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error'\n };\n }\n },\n\n refreshPluginMarketplace: async (marketplaceName: string) => {\n try {\n if (this.provider && 'refreshPluginMarketplace' in this.provider && typeof this.provider.refreshPluginMarketplace === 'function') {\n const result = await this.provider.refreshPluginMarketplace(marketplaceName);\n this.logger?.info('Refresh plugin marketplace', { marketplaceName, success: result.success });\n return result;\n }\n this.logger?.warn('Provider does not support refreshPluginMarketplace');\n return { success: false, error: 'Provider does not support refreshPluginMarketplace' };\n } catch (error) {\n this.logger?.error('Failed to refresh plugin marketplace', error);\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error'\n };\n }\n },\n\n openFolderInNewWindow: async (folderPath: string) => {\n try {\n if (this.provider && 'openFolderInNewWindow' in this.provider && typeof this.provider.openFolderInNewWindow === 'function') {\n await this.provider.openFolderInNewWindow(folderPath);\n this.logger?.info('Opened folder in new window', { folderPath });\n } else {\n this.logger?.warn('Provider does not support openFolderInNewWindow');\n throw new Error('Provider does not support openFolderInNewWindow');\n }\n } catch (error) {\n this.logger?.error('Failed to open folder in new window', error);\n throw error;\n }\n },\n\n openFolder: async (folderPath: string) => {\n try {\n if (this.provider && 'openFolder' in this.provider && typeof this.provider.openFolder === 'function') {\n const result = await this.provider.openFolder(folderPath);\n this.logger?.info('Opened folder in system file manager', { folderPath });\n return result;\n } else {\n this.logger?.warn('Provider does not support openFolder');\n throw new Error('Provider does not support openFolder');\n }\n } catch (error) {\n this.logger?.error('Failed to open folder', error);\n throw error;\n }\n },\n\n getSupportScenes: async (locale?: string) => {\n try {\n if (this.provider && 'getSupportScenes' in this.provider && typeof this.provider.getSupportScenes === 'function') {\n const result = await this.provider.getSupportScenes(locale);\n return result;\n }\n this.logger?.warn('Provider does not support getSupportScenes');\n return [];\n } catch (error) {\n this.logger?.error('Failed to get support scenes', error);\n return [];\n }\n },\n\n getProductScenes: async (locale?: string) => {\n try {\n if (this.provider?.getProductScenes) {\n const result = await this.provider.getProductScenes(locale);\n this.logger?.info('Got product scenes', { count: result?.length ?? 0 });\n return result;\n }\n this.logger?.warn('Provider does not support getProductScenes');\n return [];\n } catch (error) {\n this.logger?.error('Failed to get product scenes', error);\n return [];\n }\n },\n\n /**\n * Get available commands for a session\n * If session.availableCommands has cached values, return them\n * Otherwise, fetch from provider (for LocalAgentProvider)\n */\n getAvailableCommands: async (params?: GetAvailableCommandsParams) => {\n try {\n // Get from provider's getAvailableCommands method\n if (this.provider && 'getAvailableCommands' in this.provider && typeof this.provider.getAvailableCommands === 'function') {\n const result = await this.provider.getAvailableCommands(params);\n this.logger?.info('Got available commands from provider', { sessionId: params?.sessionId ?? '(default)', count: result?.length ?? 0 });\n return result;\n }\n\n this.logger?.warn('Provider does not support getAvailableCommands', { params });\n return [];\n } catch (error) {\n this.logger?.error('Failed to get available commands', error);\n return [];\n }\n },\n\n // ==================== Telemetry ====================\n\n reportTelemetry: async (eventName: string, payload: Record<string, unknown>) => {\n try {\n if (this.provider?.reportTelemetry) {\n await this.provider.reportTelemetry(eventName, payload);\n } else {\n this.logger?.warn('Provider does not support reportTelemetry');\n }\n } catch (error) {\n this.logger?.error('Failed to report telemetry', error);\n }\n },\n\n // ==================== Product Configuration ====================\n\n getProductConfiguration: async () => {\n try {\n if (this.provider?.getProductConfiguration) {\n return await this.provider.getProductConfiguration();\n }\n this.logger?.warn('Provider does not support getProductConfiguration');\n return {};\n } catch (error) {\n this.logger?.error('Failed to get product configuration', error);\n return {};\n }\n },\n\n getUserInfo: async () => {\n this.logger?.info('[AgentClient.sessions] getUserInfo() called');\n try {\n if (this.provider?.getUserInfo) {\n const result = await this.provider.getUserInfo();\n this.logger?.info('[AgentClient.sessions] getUserInfo() result:', JSON.stringify(result));\n return result;\n }\n this.logger?.warn('Provider does not support getUserInfo');\n return {};\n } catch (error) {\n this.logger?.error('Failed to get user info', error);\n return {};\n }\n },\n\n // ==================== MCP Sampling/Roots 确认相关 ====================\n\n /**\n * Respond to MCP Sampling confirmation request\n */\n respondToSampling: async (sessionId, response) => {\n try {\n if (this.provider?.respondToSampling) {\n await this.provider.respondToSampling(sessionId, response);\n this.logger?.info('Responded to sampling request', { sessionId, requestId: response.id, approved: response.approved });\n } else {\n this.logger?.warn('Provider does not support respondToSampling');\n }\n } catch (error) {\n this.logger?.error('Failed to respond to sampling request', error);\n throw error;\n }\n },\n\n /**\n * Respond to MCP Roots confirmation request\n */\n respondToRoots: async (sessionId, response) => {\n try {\n if (this.provider?.respondToRoots) {\n await this.provider.respondToRoots(sessionId, response);\n this.logger?.info('Responded to roots request', { sessionId, requestId: response.id, approved: response.approved });\n } else {\n this.logger?.warn('Provider does not support respondToRoots');\n }\n } catch (error) {\n this.logger?.error('Failed to respond to roots request', error);\n throw error;\n }\n },\n\n /**\n * Subscribe to MCP Sampling confirmation requests\n */\n subscribeSamplingRequests: (serverName, callback) => {\n if (this.provider?.subscribeSamplingRequests) {\n this.logger?.info('Subscribing to sampling requests', { serverName });\n return this.provider.subscribeSamplingRequests(serverName, callback);\n }\n this.logger?.warn('Provider does not support subscribeSamplingRequests');\n return () => {};\n },\n\n /**\n * Subscribe to MCP Roots confirmation requests\n */\n subscribeRootsRequests: (serverName, callback) => {\n if (this.provider?.subscribeRootsRequests) {\n this.logger?.info('Subscribing to roots requests', { serverName });\n return this.provider.subscribeRootsRequests(serverName, callback);\n }\n this.logger?.warn('Provider does not support subscribeRootsRequests');\n return () => {};\n },\n\n // ==================== MCP Server Management ====================\n\n /**\n * Get MCP servers list\n */\n getMcpServers: async () => {\n if (this.provider?.getMcpServers) {\n this.logger?.info('Getting MCP servers list');\n return this.provider.getMcpServers();\n }\n this.logger?.warn('Provider does not support getMcpServers');\n return [];\n },\n\n /**\n * Toggle MCP server enabled/disabled state\n */\n toggleMcpServer: async (serverName, enabled) => {\n if (this.provider?.toggleMcpServer) {\n this.logger?.info('Toggling MCP server', { serverName, enabled });\n await this.provider.toggleMcpServer(serverName, enabled);\n } else {\n this.logger?.warn('Provider does not support toggleMcpServer');\n throw new Error('toggleMcpServer not supported by provider');\n }\n },\n\n /**\n * Reconnect to an MCP server\n */\n reconnectMcpServer: async (serverName, forceHttpCallback) => {\n if (this.provider?.reconnectMcpServer) {\n this.logger?.info('Reconnecting MCP server', { serverName, forceHttpCallback });\n await this.provider.reconnectMcpServer(serverName, forceHttpCallback);\n } else {\n this.logger?.warn('Provider does not support reconnectMcpServer');\n throw new Error('reconnectMcpServer not supported by provider');\n }\n },\n\n /**\n * Delete an MCP server configuration\n */\n deleteMcpServer: async serverName => {\n if (this.provider?.deleteMcpServer) {\n this.logger?.info('Deleting MCP server', { serverName });\n await this.provider.deleteMcpServer(serverName);\n } else {\n this.logger?.warn('Provider does not support deleteMcpServer');\n throw new Error('deleteMcpServer not supported by provider');\n }\n },\n\n /**\n * Open MCP configuration file in editor\n */\n openMcpConfig: async () => {\n if (this.provider?.openMcpConfig) {\n this.logger?.info('Opening MCP config');\n await this.provider.openMcpConfig();\n } else {\n this.logger?.warn('Provider does not support openMcpConfig');\n throw new Error('openMcpConfig not supported by provider');\n }\n },\n\n /**\n * Get MCP configuration file content\n */\n getMcpConfigContent: async () => {\n if (this.provider?.getMcpConfigContent) {\n this.logger?.info('Getting MCP config content');\n return await this.provider.getMcpConfigContent();\n } else {\n this.logger?.warn('Provider does not support getMcpConfigContent');\n throw new Error('getMcpConfigContent not supported by provider');\n }\n },\n\n /**\n * Save MCP configuration file content\n */\n saveMcpConfigContent: async (content: string) => {\n if (this.provider?.saveMcpConfigContent) {\n this.logger?.info('Saving MCP config content');\n await this.provider.saveMcpConfigContent(content);\n } else {\n this.logger?.warn('Provider does not support saveMcpConfigContent');\n throw new Error('saveMcpConfigContent not supported by provider');\n }\n },\n\n /**\n * Read text from clipboard\n */\n clipboardReadText: async () => {\n if (this.provider?.clipboardReadText) {\n this.logger?.info('Reading clipboard text');\n return await this.provider.clipboardReadText();\n } else {\n this.logger?.warn('Provider does not support clipboardReadText');\n throw new Error('clipboardReadText not supported by provider');\n }\n },\n\n // Models resource - delegates to provider's getModels method\n models: this.createModelsResource(),\n };\n }\n\n private createModelsResource(): ModelsResource {\n return {\n list: async (repo: string): Promise<ModelInfo[]> => {\n // Check if provider supports getModels\n if (this.provider.getModels) {\n return this.provider.getModels(repo);\n }\n throw new Error('Provider does not support getModels method');\n }\n };\n }\n\n // ============================================\n // Lifecycle\n // ============================================\n\n /**\n * Dispose the client\n *\n * Note: Active sessions are not automatically disposed.\n * The caller is responsible for disconnecting sessions they created.\n */\n dispose(): void {\n this.logger?.info('AgentClient disposed');\n }\n}\n\nexport default AgentClient;\n","/**\n * API type definitions for AgentClient\n * Session-centric API design\n */\n\nimport type { RequestPermissionRequest,SessionNotification } from '@agentclientprotocol/sdk';\nimport type {\n Artifact,\n ArtifactEvent,\n ArtifactType,\n CheckpointInfo,\n ClientEvents,\n EventListener,\n QuestionAnswers,\n QuestionRequest,\n StopReason,\n UsageUpdate,\n} from '@genie/agent-client-protocol';\n\nimport type { BatchPluginOperationRequest, BatchPluginOperationResult } from '../../backend/types.js';\nimport type { AvailableCommand } from '../providers/local-agent-provider/acp/types.js';\nimport type {\n Agent as AgentInfo,\n AgentCapabilities,\n AgentConnection,\n AgentStatus,\n ArtifactsConfig,\n ArtifactTypeConfig,\n ClientCapabilities,\n CodebuddyAgentMeta,\n CodebuddyClientMeta,\n E2BSandboxConnectionInfo,\n // e2b SDK types (re-exported from types.js)\n EntryInfo,\n FilesResource,\n Filesystem,\n FilesystemProvider,\n McpServerConfig,\n // Model types\n ModelInfo,\n PromptContentBlock,\n PromptParams,\n Session,\n SessionMode} from '../types.js';\n\n// Re-export commonly used types\nexport type {\n AgentInfo,\n AgentConnection,\n AgentStatus,\n Session,\n SessionMode,\n PromptParams,\n PromptContentBlock,\n AgentCapabilities,\n ClientCapabilities,\n // codebuddy.ai extension types\n ArtifactTypeConfig,\n ArtifactsConfig,\n CodebuddyClientMeta,\n CodebuddyAgentMeta,\n // Other types\n Artifact,\n ArtifactType,\n ArtifactEvent,\n UsageUpdate,\n ClientEvents,\n EventListener,\n SessionNotification,\n RequestPermissionRequest,\n QuestionRequest,\n QuestionAnswers,\n // Filesystem types\n FilesResource,\n FilesystemProvider,\n McpServerConfig,\n E2BSandboxConnectionInfo,\n // e2b SDK types (re-exported from types.js)\n EntryInfo,\n Filesystem,\n // Model types\n ModelInfo,\n // ACP types\n AvailableCommand,\n // Plugin types\n BatchPluginOperationRequest,\n BatchPluginOperationResult\n};\n\n// ============================================\n// Session Connection Info (for cloud sessions)\n// ============================================\n\n/**\n * Session connection information\n * 包含连接到Agent会话所需的所有信息,包括sandbox连接凭证\n */\nexport interface SessionConnectionInfo {\n /** Session ID */\n sessionId: string;\n /** Agent ID */\n agentId: string;\n /** Session endpoint URL (Agent的WebSocket/HTTP端点) */\n link: string;\n /** Session token (JWT格式的认证令牌) */\n token: string;\n /** Sandbox ID (E2B沙箱的唯一标识) */\n sandboxId: string;\n /** Session expiration timestamp (unix timestamp) */\n expireAt: number;\n /** Current working directory (optional) */\n cwd?: string;\n}\n\n// ============================================\n// Agent State (Unified agent state object)\n// ============================================\n\n/**\n * Agent 来源类型\n */\nexport type AgentStateType = 'local' | 'cloud';\n\n/**\n * 云端 Agent 可见性\n */\nexport type CloudAgentVisibility = 'PRIVATE' | 'PUBLIC' | 'TEAM';\n\n/**\n * 云端 Agent 来源信息\n */\nexport interface CloudAgentSourceInfo {\n /** 提供商: github, gitlab 等 */\n provider: string;\n /** 分支/引用 */\n ref: string;\n /** 仓库路径 */\n repository: string;\n}\n\n/**\n * 云端 Agent 目标信息\n */\nexport interface CloudAgentTarget {\n /** 是否自动创建 PR */\n autoCreatePr: boolean;\n /** 分支名称 */\n branchName?: string;\n /** PR URL */\n prUrl?: string;\n /** Agent URL */\n url?: string;\n}\n\n/**\n * AgentState 基础接口\n * 所有类型的 AgentState 都必须实现此接口\n */\nexport interface BaseAgentState {\n /** Unique agent ID */\n id: string;\n /** Display name */\n name?: string;\n /** Description */\n description?: string;\n /** Agent type */\n type: AgentStateType;\n /** Current connection status */\n status: AgentStatus;\n /** Agent capabilities (available after connection) */\n capabilities?: AgentCapabilities;\n /** When the agent was created */\n createdAt?: Date;\n /** When the agent was last updated */\n updatedAt?: Date;\n /** 是否为 playground */\n isPlayground?: boolean;\n /** Whether the title is user defined (1 = user defined) */\n isUserDefinedTitle?: number;\n}\n\n/**\n * LocalAgentState - 本地 Agent 状态\n * 来自本地 IPC 通信的 Agent\n */\nexport interface LocalAgentState extends BaseAgentState {\n type: 'local';\n /** 工作目录 */\n cwd: string;\n}\n\n/**\n * CloudAgentState - 云端 Agent 状态\n * 来自远程 API 的云端实例\n */\nexport interface CloudAgentState extends BaseAgentState {\n type: 'cloud';\n}\n\n/**\n * AgentState - Unified agent state object exposed to client users\n *\n * This is the primary way clients access agent information.\n * Uses discriminated union pattern to distinguish between local and cloud agents.\n */\nexport type AgentState = LocalAgentState | CloudAgentState;\n\n/**\n * 类型守卫:判断是否为 LocalAgentState\n */\nexport function isLocalAgentState(state: AgentState): state is LocalAgentState {\n return state.type === 'local';\n}\n\n/**\n * 类型守卫:判断是否为 CloudAgentState\n */\nexport function isCloudAgentState(state: AgentState): state is CloudAgentState {\n return state.type === 'cloud';\n}\n\n/**\n * Logger interface\n */\nexport interface Logger {\n debug(message: string, ...args: unknown[]): void;\n info(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n}\n\n// ============================================\n// Agent List Query Options\n// ============================================\n\n/**\n * Filter condition for listing agents\n */\nexport interface ListAgentFilter {\n /** Filter field name (e.g., 'status', 'name') */\n field: string;\n /** Filter value (comma-separated for multiple values) */\n value: string;\n}\n\n/**\n * Sort options for listing agents\n */\nexport interface ListAgentSort {\n /** Sort field (e.g., 'createdAt', 'status') */\n orderBy: string;\n /** Sort direction */\n order?: 'asc' | 'desc';\n}\n\n/**\n * Query options for listing agents\n *\n * These options are supported by both CloudAgentProvider and LocalAgentProvider.\n * Cloud: Server-side filtering, sorting, and pagination\n * Local: Client-side filtering and sorting, no pagination (returns all)\n */\nexport interface ListAgentOptions {\n /**\n * User ID for filtering sessions (required for multi-user isolation)\n * If not provided, returns empty list for Local provider\n */\n userId?: string;\n\n /**\n * Page number (starts from 1)\n * Cloud: Used for API pagination\n * Local: Ignored (returns all sessions)\n */\n page?: number;\n\n /**\n * Page size\n * Cloud: Number of items per page (default 20, max 100)\n * Local: Ignored (returns all sessions)\n */\n size?: number;\n\n /**\n * Sort options\n * Cloud: Sorts results by specified field and order\n * Local: Sorts results by specified field and order\n */\n sort?: ListAgentSort;\n\n /**\n * Filter conditions\n * Cloud: Filters results by specified field values\n * Local: Filters results by specified field values\n */\n filters?: ListAgentFilter[];\n\n /**\n * Day range filter (e.g., agents created in last N days)\n * Cloud: Filters by creation date\n * Local: Filters by creation date\n */\n dayRange?: number;\n\n /**\n * Title search keyword (matches agent title)\n * Cloud: Server-side search\n * Local: Client-side search\n */\n title?: string;\n}\n\n/**\n * Pagination metadata returned from list operations\n */\nexport interface PaginationInfo {\n /** Current page number (starts from 1) */\n page: number;\n /** Page size */\n size: number;\n /** Total number of items */\n total: number;\n /** Total number of pages */\n totalPages: number;\n /** Whether there is a next page */\n hasNext: boolean;\n /** Whether there is a previous page */\n hasPrev: boolean;\n}\n\n/**\n * Response from list operations that includes pagination\n */\nexport interface ListAgentResult<T = AgentState> {\n /** List of agent states or session info */\n agents: T[];\n /** Pagination information */\n pagination: PaginationInfo;\n}\n\n// ============================================\n// Session-Centric Types\n// ============================================\n\n/**\n * Session information (returned by list, mapped from Agent)\n */\nexport interface SessionInfo {\n /** Session ID (from agent.session) */\n id: string;\n /** Associated agent ID */\n agentId: string;\n /** Agent name */\n name?: string;\n /** Agent status */\n status: AgentStatus;\n /** When the session/agent was created */\n createdAt?: Date;\n /** When the session/agent was last updated */\n updatedAt?: Date;\n /** Last activity timestamp */\n lastActivityAt?: Date;\n /** Working directory (for local agents) */\n cwd?: string;\n /** Whether the session is a playground */\n isPlayground?: boolean;\n /** Whether the title is user defined (1 = user defined) */\n isUserDefinedTitle?: number;\n}\n\n/**\n * Parameters for creating a new session\n */\nexport interface CreateSessionParams {\n /** Working directory (required) */\n cwd: string;\n /** Optional configuration */\n options?: CreateSessionOptions;\n}\n\n/**\n * Optional configuration for creating a session\n */\nexport interface CreateSessionOptions {\n /** MCP server configurations */\n mcpServers?: McpServerConfig[];\n /** Initial prompt for the session (Cloud only) */\n prompt?: string;\n /** Initial model for the session (Cloud only) */\n model?: string;\n /** Mode ID (e.g., 'craft', 'architect') */\n mode?: string;\n /** Whether this is a playground session (no cwd) */\n isPlayground?: boolean;\n /** Tags for template scenes (Cloud only, format: { scene: 'xxx' }) */\n tags?: Record<string, string>;\n /** Additional metadata */\n _meta?: Record<string, unknown>;\n /** Callback when session is prepared (POST succeeded, before WebSocket connect) */\n onSessionPrepared?: (sessionInfo: SessionInfo) => void;\n}\n\n/**\n * Parameters for loading an existing session\n */\nexport interface LoadSessionParams {\n /** Session ID to load (required) */\n sessionId: string;\n /** Working directory */\n cwd: string;\n /** MCP server configurations */\n mcpServers?: McpServerConfig[];\n /** Callback executed right after session instance is created, before connection.loadSession() is called */\n onSessionCreated?: (session: ActiveSession) => Promise<void> | void;\n}\n\n/**\n * Parameters for initializing a workspace\n */\nexport interface InitializeWorkspaceParams {\n /** Working directory */\n cwd: string;\n /** MCP server configurations */\n mcpServers?: McpServerConfig[];\n /** Whether to activate the workspace window to foreground (default true) */\n needActivated?: boolean;\n}\n\n/**\n * Response for workspace initialization\n */\nexport interface InitializeWorkspaceResponse {\n /** Whether initialization was successful */\n success: boolean;\n /** Error message (if failed) */\n error?: string;\n}\n\n// ============================================\n// Automation Types\n// ============================================\n\nexport type AutomationStatus = 'ACTIVE' | 'PAUSED';\nexport type AutomationScheduleType = 'recurring' | 'once';\nexport type AutomationUpdateMode = 'view' | 'suggested create' | 'suggested update';\nexport type AutomationRunStatus = 'ACCEPTED' | 'ARCHIVED' | 'PENDING_REVIEW' | 'IN_PROGRESS';\n\nexport interface AutomationDefinition {\n version: number;\n id: string;\n name: string;\n prompt: string;\n status: AutomationStatus;\n scheduleType: AutomationScheduleType;\n rrule: string;\n scheduledAt?: string;\n validFrom?: string;\n validUntil?: string;\n nextRunAt?: number;\n cwds: string[];\n modelId?: string;\n modelIsThinking?: boolean;\n created_at: number;\n updated_at: number;\n}\n\nexport interface AutomationCwdRunResult {\n cwd: string;\n success: boolean;\n startedAt: number;\n finishedAt: number;\n conversationId?: string;\n output?: string;\n error?: string;\n}\n\nexport interface AutomationInboxItem {\n id: string;\n automationId: string;\n automationName: string;\n status?: AutomationRunStatus;\n readAt?: number;\n startedAt: number;\n finishedAt: number;\n success: boolean;\n summary: string;\n runs: AutomationCwdRunResult[];\n archived?: boolean;\n archivedAt?: number;\n}\n\nexport interface AutomationRuntimeState {\n lastRunAt?: number;\n lastError?: string;\n running?: boolean;\n runningStartedAt?: number;\n runningConversationId?: string;\n}\n\nexport interface AutomationSnapshot {\n automations: AutomationDefinition[];\n inbox: AutomationInboxItem[];\n runtimeState: Record<string, AutomationRuntimeState>;\n updatedAt: number;\n}\n\nexport interface AutomationUpdatePayload {\n mode: AutomationUpdateMode;\n id?: string;\n name?: string;\n prompt?: string;\n scheduleType?: AutomationScheduleType;\n rrule?: string;\n scheduledAt?: string;\n validFrom?: string;\n validUntil?: string;\n cwds?: string[] | string;\n status?: AutomationStatus;\n modelId?: string;\n modelIsThinking?: boolean;\n}\n\nexport interface AutomationUpdateResult {\n success: boolean;\n message: string;\n automation?: AutomationDefinition;\n snapshot?: AutomationSnapshot;\n}\n\nexport interface AutomationWorkspaceFolderInfo {\n name: string;\n uri: string;\n}\n\n/**\n * Parameters for getting available commands\n */\nexport interface GetAvailableCommandsParams {\n /** Session ID to get commands for (optional, for global commands) */\n sessionId?: string;\n /** Workspace path for getting custom commands (optional) */\n workspacePath?: string;\n}\n\n// ============================================\n// Resource Interfaces\n// ============================================\n\n/**\n * Prompts resource interface (ACP verbs)\n * Operations use the current session automatically\n */\nexport interface PromptsResource {\n /** Send a prompt and wait for completion */\n send(params: PromptParams): Promise<PromptResponse>;\n\n /** Stream a prompt (yields session updates) */\n stream(params: PromptParams): AsyncIterable<SessionNotification>;\n\n /** Cancel an ongoing prompt */\n cancel(): Promise<void>;\n}\n\n/**\n * Artifacts resource interface\n */\nexport interface ArtifactsResource {\n /** List all artifacts */\n list(params?: { type?: ArtifactType }): Promise<Artifact[]>;\n\n /** Get a single artifact */\n retrieve(artifactId: string): Promise<Artifact>;\n\n /** Get artifact content */\n content(artifactId: string): Promise<string>;\n}\n\n/**\n * Models resource interface\n */\nexport interface ModelsResource {\n /** Get available models for a repository */\n list(repo?: string): Promise<ModelInfo[]>;\n}\n\n// ============================================\n// Response Types\n// ============================================\n\n/**\n * ACP 官方 StopReason 类型\n *\n * 从 @genie/agent-client-protocol 重新导出,确保类型一致性\n * 如需扩展,请在 agent-client-protocol 包中修改\n * @see https://agentclientprotocol.com/protocol/prompt-turn#stop-reasons\n */\nexport type { StopReason as ACPStopReason } from '@genie/agent-client-protocol';\n\n/**\n * Prompt response\n */\nexport interface PromptResponse {\n /** Stop reason */\n stopReason: StopReason;\n /** Response metadata */\n _meta?: Record<string, unknown>;\n}\n\n// ============================================\n// Sessions Resource Events (for ClientSessionsResource)\n// ============================================\n\n/**\n * Sessions resource events for monitoring session list changes\n */\nexport interface SessionsResourceEvents {\n\t/** Emitted when the sessions list changes (create, delete, update) */\n\tsessionsChanged: SessionInfo[];\n\t/** Emitted when a new session is fully connected and ready */\n\tsessionCreated: SessionInfo;\n\t/** Emitted when a session is deleted */\n\tsessionDeleted: { sessionId: string };\n\t/** Emitted when a session is updated (status change, etc.) */\n\tsessionUpdated: SessionInfo;\n\t/** Emitted when automation snapshot is updated (pushed from server) */\n\tautomationSnapshotUpdate: AutomationSnapshot;\n\t/** Emitted when plugins or marketplaces change (install/uninstall/add/remove/update) */\n\tpluginsChanged: { newMarketplaceName?: string } | undefined;\n\t/** Emitted when ProductConfiguration changes (account switch, config sync, etc.) */\n\tproductConfigChanged: { timestamp: number; productFeatures: Record<string, boolean> };\n\t/** Emitted when identity changes (IDENTITY.md file modified) */\n\tidentityChanged: { name: string; timestamp: number };\n}\n\n/**\n * Event handler type for sessions resource events\n */\nexport type SessionsResourceEventHandler<K extends keyof SessionsResourceEvents> = (\n data: SessionsResourceEvents[K]\n) => void | Promise<void>;\n\n// ============================================\n// Session Events (for ActiveSession)\n// ============================================\n\n/**\n * Session events for event subscription\n */\nexport interface SessionEvents {\n /** Emitted when session updates occur */\n sessionUpdate: SessionNotification;\n /** Emitted when an artifact is created */\n artifactCreated: Artifact;\n /** Emitted when an artifact is updated */\n artifactUpdated: Artifact;\n /** Emitted when an artifact is deleted */\n artifactDeleted: Artifact;\n /** Emitted when a permission request is received */\n permissionRequest: { requestId: string; params: RequestPermissionRequest };\n /** Emitted when a question request is received (ask_followup_question) */\n questionRequest: { toolCallId: string; request: QuestionRequest };\n /** Emitted when usage data is updated */\n usageUpdate: UsageUpdate;\n /** Emitted when a checkpoint is created */\n checkpointCreated: CheckpointInfo;\n /** Emitted when a checkpoint is updated */\n checkpointUpdated: CheckpointInfo;\n /** Emitted when a command is received */\n command: { action: string; params?: Record<string, unknown> };\n /** Emitted when connected to agent */\n connected: void;\n /** Emitted when disconnected from agent */\n disconnected: void;\n /** Emitted when an error occurs */\n error: Error;\n}\n\n/**\n * Event handler type for session events\n */\nexport type SessionEventHandler<K extends keyof SessionEvents> = (data: SessionEvents[K]) => void | Promise<void>;\n\n// ============================================\n// Active Session Interface\n// ============================================\n\n/**\n * Agent operations (accessed via session.agent)\n */\nexport interface SessionAgentOperations {\n /** Agent ID */\n readonly id: string;\n /** Agent state */\n readonly state: AgentState;\n /** Whether the agent is connected */\n readonly isConnected: boolean;\n /** Agent capabilities */\n readonly capabilities?: AgentCapabilities;\n}\n\n/**\n * Active Session interface\n * Represents an active session with its resources and operations\n *\n * Key design:\n * - Session is the primary API surface\n * - agentState provides direct access to underlying agent state\n * - disconnect() is called directly on session (not session.agent)\n */\nexport interface ActiveSession {\n /** Session ID */\n readonly id: string;\n /** Agent ID */\n readonly agentId: string;\n /** Actual workspace path (set after newSession, useful for Playground scenario) */\n readonly cwd?: string;\n /** Agent state (direct access to underlying agent state) */\n readonly agentState: AgentState;\n /** Agent capabilities (available after connection) */\n readonly capabilities?: AgentCapabilities;\n /** Available session modes */\n readonly availableModes?: SessionMode[];\n /** Current session mode */\n readonly currentMode?: string;\n /** Available models for this session */\n readonly availableModels?: ModelInfo[];\n /** Current model ID */\n readonly currentModelId?: string;\n /** Available slash commands (updated via available_commands_update) */\n readonly availableCommands: AvailableCommand[];\n /** Whether the session is active */\n readonly isActive: boolean;\n /**\n * Session connection information (only available for cloud sessions)\n * 会话连接信息,包括sandboxId、link、token等\n */\n readonly connectionInfo?: SessionConnectionInfo;\n\n // Agent operations namespace (optional agent-level access)\n /** Agent operations */\n readonly agent: SessionAgentOperations;\n\n // ACP Resources\n /** Prompts resource */\n readonly prompts: PromptsResource;\n /** Artifacts resource */\n readonly artifacts: ArtifactsResource;\n /** Files resource */\n readonly files: FilesResource;\n\n // Permission management\n /** Resolve a permission request */\n resolvePermission(requestId: string, optionId: string): boolean;\n /** Reject a permission request */\n rejectPermission(requestId: string, reason?: string): boolean;\n\n // Question management (ask_followup_question)\n /** Answer a question request with user's selections */\n answerQuestion(toolCallId: string, answers: QuestionAnswers): boolean;\n /** Cancel a question request */\n cancelQuestion(toolCallId: string, reason?: string): boolean;\n\n // Tool callback management\n /** Callback for tool operations (approve / skip / cancel) */\n toolCallback(toolCallId: string, toolName: string, action: 'approve' | 'skip' | 'cancel'): Promise<{ success: boolean; error?: string }>;\n\n // Session mode management\n /** Set the current session mode */\n setMode(modeId: string, skipChecker?: boolean): Promise<void>;\n /** Set the current session model */\n setSessionModel(modelId: string): Promise<void>;\n /** Set available commands (called when available_commands_update is received) */\n setAvailableCommands(commands: AvailableCommand[]): void;\n /** Set available modes (called after create/load) */\n setModes(availableModes?: SessionMode[], currentMode?: string): void;\n /** Set available models (called after create/load) */\n setModels(availableModels?: ModelInfo[], currentModelId?: string): void;\n\n // Event subscription\n /** Subscribe to an event */\n on<K extends keyof SessionEvents>(event: K, handler: SessionEventHandler<K>): this;\n /** Unsubscribe from an event */\n off<K extends keyof SessionEvents>(event: K, handler: SessionEventHandler<K>): this;\n /** Subscribe to an event once */\n once<K extends keyof SessionEvents>(event: K, handler: SessionEventHandler<K>): this;\n\n // Lifecycle - disconnect directly on session\n /** Disconnect from the session/agent */\n disconnect(): void;\n\n /**\n * Detach the session from connection events without disconnecting the connection.\n * This should be called when the session is being replaced but the connection is shared.\n * Unlike disconnect(), this only removes event listeners without closing the connection.\n */\n detach(): void;\n\n /** Symbol.dispose for 'using' keyword support */\n [Symbol.dispose](): void;\n}\n\n// ============================================\n// Provider & Client Types\n// ============================================\n\n/**\n * 环境类型\n */\nexport type EnvironmentType = 'local' | 'cloud';\n\n/**\n * Agent provider interface\n *\n * Responsible for:\n * - Managing agent state/configuration storage\n * - Creating connections to agents\n * - Abstracting away transport details (cloud/local)\n *\n * The provider.connect() method returns an AgentConnection.\n * The client wraps the connection in an ActiveSession instance.\n *\n * @typeParam C - Connection type used by this provider (e.g., CloudAgentConnection, LocalAgentConnection)\n */\nexport interface AgentProvider<C extends AgentConnection = AgentConnection> {\n /**\n * Create a new agent and return its ID\n *\n * @param params - Optional session params (used by LocalAgentProvider to get cwd)\n * @returns Agent ID (Cloud: UUID, Local: cwd)\n */\n create?(params?: CreateSessionParams): Promise<string>;\n /** Get agent state by ID */\n get(agentId: string): Promise<AgentState | undefined>;\n\n /**\n * List all agent states with pagination information\n *\n * @param options - Optional query parameters for filtering, sorting, and pagination\n * Cloud providers use these for API queries and return server pagination\n * Local providers apply client-side filtering and return synthetic pagination\n * @returns Object containing agents array and pagination info\n */\n list(options?: ListAgentOptions): Promise<ListAgentResult<AgentState>>;\n\n /** Connect to an agent and return the connection */\n connect(agentId: string): Promise<C>;\n /** Delete an agent by ID */\n delete(agentId: string): Promise<boolean>;\n\n /**\n * Archive an agent by ID (optional)\n * Used by CloudAgentProvider for archiving agents\n *\n * @param agentId - Agent ID to archive\n * @returns Object containing the archived agent ID\n */\n archive?(agentId: string): Promise<{ id: string }>;\n\n /**\n * Rename an agent by ID (optional)\n * Used by CloudAgentProvider and LocalAgentProvider for renaming agents\n *\n * @param agentId - Agent ID to rename\n * @param title - New title for the agent\n * @returns Object containing the renamed agent ID\n */\n rename?(agentId: string, title: string): Promise<{ id: string }>;\n\n /**\n * Update agent status by ID (optional)\n * Used by CloudAgentProvider for updating session status\n *\n * @param agentId - Agent ID to update\n * @param status - New status for the agent\n * @returns Object containing the updated agent ID\n */\n updateStatus?(agentId: string, status: string): Promise<{ id: string }>;\n\n /**\n * Move an agent by ID (optional)\n * Used by LocalAgentProvider for moving Playground sessions to Workspace\n *\n * @param agentId - Agent ID to move\n * @returns Object containing the moved agent ID\n */\n move?(agentId: string): Promise<{ id: string }>;\n\n /** Filesystem provider (optional - some providers may not support filesystem operations) */\n readonly filesystem?: FilesystemProvider;\n\n /**\n * Get available models for a repository (optional)\n * Implementation varies by provider type\n * @param repo - Repository identifier\n * @returns Array of model information\n */\n getModels?(repo?: string): Promise<ModelInfo[]>;\n\n /**\n * Get product configuration subset (optional)\n * Returns deploymentType, creditPurchaseActions, links, networkEnvironment, productFeatures\n */\n getProductConfiguration?(): Promise<{\n deploymentType?: string;\n creditPurchaseActions?: Record<string, {\n labelZh: string;\n labelEn: string;\n url: string;\n showButton?: boolean;\n }>;\n links?: {\n craftFeedback?: string;\n mcpMarketUrl?: string;\n mcpDocumentUrl?: string;\n helpDocument?: string;\n };\n networkEnvironment?: string;\n productFeatures?: Record<string, boolean>;\n customModelSettings?: unknown;\n skillScanDirs?: string[];\n }>;\n\n /**\n * Get user info (optional)\n * Returns enterpriseId from authentication session\n */\n getUserInfo?(): Promise<{\n enterpriseId?: string;\n }>;\n\n /**\n * Register sessionId → agentId mapping (optional, used by LocalAgentProvider)\n * Called after session creation to maintain the mapping for loadSession\n *\n * @param sessionId - Session ID returned by connection.createSession()\n * @param agentId - Agent ID (cwd for Local)\n */\n registerSession?(sessionId: string, agentId: string): void;\n\n /**\n * Open a workspace window (optional, used by LocalAgentProvider)\n *\n * @param params - Workspace params including cwd\n * @returns Response with success status\n */\n openWorkspace?(params: InitializeWorkspaceParams): Promise<InitializeWorkspaceResponse>;\n\n /** Request yielding after current step for a running session (optional, used by LocalAgentProvider) */\n requestYieldAfterCurrentStep?(sessionId: string): Promise<boolean>;\n\n /**\n * Pick files from file dialog (optional, used by LocalAgentProvider)\n *\n * @param params - File picker params including filters\n * @returns Response with file paths and cancel status\n */\n pickFile?(params?: PickFileParams): Promise<PickFileResponse>;\n\n /**\n * Pick folders from folder dialog (optional, used by LocalAgentProvider)\n *\n * @param params - Folder picker params\n * @returns Response with folder paths and cancel status\n */\n pickFolder?(params?: PickFolderParams): Promise<PickFolderResponse>;\n\n /**\n * Upload a file to cloud storage (optional)\n *\n * @param params - Upload parameters including file content\n * @returns Response with cloud URL after successful upload\n */\n uploadFile?(params: UploadFileParams): Promise<UploadFileResponse>;\n\n /**\n * Search for files in the workspace (optional, used by LocalAgentProvider)\n *\n * @param params - Search parameters including options\n * @returns Response with search results\n */\n searchFile?(params: SearchFileParams): Promise<SearchFileResponse>;\n\n /**\n * Get subagent list (optional, used by LocalAgentProvider)\n *\n * @param params - Query parameters including options\n * @returns Response with subagent list\n */\n getSubagentList?(params: GetSubagentListParams): Promise<GetSubagentListResponse>;\n\n /**\n * Get skill list (optional, used by LocalAgentProvider)\n *\n * @param params - Query parameters\n * @returns Response with skill list\n */\n getSkillList?(params?: GetSkillListParams): Promise<GetSkillListResponse>;\n\n /**\n * Import a skill folder (optional, used by LocalAgentProvider)\n *\n * @param params - Import parameters including source location\n * @returns Response with import result\n */\n importSkill?(params: ImportSkillParams): Promise<ImportSkillResponse>;\n\n /**\n * Get skill content by file path (optional, used by LocalAgentProvider)\n *\n * @param params - Parameters including skill file path\n * @returns Response with skill content\n */\n getSkillContent?(params: GetSkillContentParams): Promise<GetSkillContentResponse>;\n\n /**\n * Get marketplace skills list (optional, used by LocalAgentProvider)\n *\n * @returns Response with marketplace skill list\n */\n getMarketplaceSkills?(): Promise<GetMarketplaceSkillsResponse>;\n\n /**\n * Get marketplace skill content (optional, used by LocalAgentProvider)\n *\n * @param params - Parameters including skill name\n * @returns Response with skill content\n */\n getMarketplaceSkillContent?(params: GetMarketplaceSkillContentParams): Promise<GetMarketplaceSkillContentResponse>;\n\n /**\n * Install marketplace skill to user directory (optional, used by LocalAgentProvider)\n *\n * @param params - Parameters including skill name\n * @returns Response with install result\n */\n installMarketplaceSkill?(params: InstallMarketplaceSkillParams): Promise<InstallMarketplaceSkillResponse>;\n\n /**\n * Toggle skill enable/disable state (optional, used by LocalAgentProvider)\n *\n * @param params - Toggle parameters including filePath and disable state\n * @returns Response with toggle result\n */\n toggleSkill?(params: ToggleSkillParams): Promise<ToggleSkillResponse>;\n\n /**\n * Delete a skill (optional, used by LocalAgentProvider)\n *\n * @param params - Delete parameters including filePath and name\n * @returns Response with delete result\n */\n deleteSkill?(params: DeleteSkillParams): Promise<DeleteSkillResponse>;\n\n /**\n * Batch toggle plugins (optional, used by LocalAgentProvider)\n *\n * @param request - Batch plugin operation request\n * @returns Batch operation result\n */\n batchTogglePlugins?(request: BatchPluginOperationRequest): Promise<BatchPluginOperationResult>;\n\n /**\n * Get installed plugins (optional, used by LocalAgentProvider)\n *\n * @param forceRefresh - Whether to force refresh the cache\n * @returns Array of installed plugins\n */\n getInstalledPlugins?(forceRefresh?: boolean): Promise<Array<{\n name: string;\n marketplaceName: string;\n status: string;\n description?: string;\n version?: string;\n installScope?: 'user' | 'project';\n installedScopes?: Array<'user' | 'project' | 'local' | 'project-local'>;\n installedScopesStatus?: Record<string, boolean>;\n installId?: string;\n }>>;\n\n /**\n * Install plugins (optional, used by LocalAgentProvider)\n *\n * @param pluginNames - Array of plugin names to install\n * @param marketplaceName - Marketplace name\n * @param installScope - Install scope ('user' | 'project')\n * @param marketplaceSource - Marketplace source URL (for auto-adding marketplace when not exists)\n * @returns Result of the operation\n */\n installPlugins?(\n pluginNames: string[],\n marketplaceName: string,\n installScope?: 'user' | 'project',\n marketplaceSource?: string,\n workspacePath?: string\n ): Promise<{ success: boolean; error?: string }>;\n\n /**\n * Get available commands for a session (optional, used by LocalAgentProvider)\n * If session.availableCommands has cached values, return them\n * Otherwise, fetch from product configuration\n *\n * @param params - Parameters for getting commands\n * @returns Array of available commands\n */\n getAvailableCommands?(params?: GetAvailableCommandsParams): Promise<AvailableCommand[]>;\n\n /**\n * Get automation snapshot (optional, used by LocalAgentProvider)\n */\n getAutomationSnapshot?(): Promise<AutomationSnapshot>;\n\n /**\n * Create/update automation definition (optional, used by LocalAgentProvider)\n */\n updateAutomation?(payload: AutomationUpdatePayload): Promise<AutomationUpdateResult>;\n\n /**\n * Delete automation definition (optional, used by LocalAgentProvider)\n */\n deleteAutomation?(id: string): Promise<AutomationUpdateResult>;\n\n /**\n * Archive an automation inbox item (optional, used by LocalAgentProvider)\n */\n archiveAutomationInboxItem?(itemId: string): Promise<AutomationUpdateResult>;\n\n /**\n * Delete an automation inbox item (optional, used by LocalAgentProvider)\n */\n deleteAutomationInboxItem?(itemId: string): Promise<AutomationUpdateResult>;\n\n /**\n * Trigger test run for automation (optional, used by LocalAgentProvider)\n */\n testAutomation?(id: string): Promise<AutomationUpdateResult>;\n\n /**\n * Register an event listener\n * Provider implementations should forward events to the underlying transport\n *\n * @param event - Event name\n * @param handler - Event handler function\n */\n on?(event: string, handler: (...args: any[]) => void): void;\n\n /**\n * Unregister an event listener\n *\n * @param event - Event name\n * @param handler - Event handler function to remove\n */\n off?(event: string, handler: (...args: any[]) => void): void;\n\n // ==================== Telemetry ====================\n\n /**\n * Report telemetry event through the provider chain\n * - Local: via ACP JSON-RPC → AcpAgent → IDE EventService\n * - Cloud: via connection → cloud endpoint\n *\n * @param eventName - Event name / code\n * @param payload - Event data\n */\n reportTelemetry?(eventName: string, payload: Record<string, unknown>): Promise<void>;\n\n // ==================== MCP Sampling/Roots 确认相关 ====================\n\n /**\n * Respond to MCP Sampling confirmation request (optional, used by LocalAgentProvider)\n * Called when user confirms/rejects a sampling request\n *\n * @param sessionId - Session ID\n * @param response - Sampling confirmation response\n */\n respondToSampling?(sessionId: string, response: McpSamplingConfirmResponse): Promise<void>;\n\n /**\n * Respond to MCP Roots confirmation request (optional, used by LocalAgentProvider)\n * Called when user confirms/rejects a roots request\n *\n * @param sessionId - Session ID\n * @param response - Roots confirmation response\n */\n respondToRoots?(sessionId: string, response: McpRootsConfirmResponse): Promise<void>;\n\n /**\n * Subscribe to MCP Sampling confirmation requests (optional, used by LocalAgentProvider)\n * Called when MCP server initiates a sampling request\n *\n * @param serverName - MCP server name\n * @param callback - Request callback\n * @returns Unsubscribe function\n */\n subscribeSamplingRequests?(serverName: string, callback: (request: McpSamplingConfirmRequest) => void): () => void;\n\n /**\n * Subscribe to MCP Roots confirmation requests (optional, used by LocalAgentProvider)\n * Called when MCP server initiates a roots request\n *\n * @param serverName - MCP server name\n * @param callback - Request callback\n * @returns Unsubscribe function\n */\n subscribeRootsRequests?(serverName: string, callback: (request: McpRootsConfirmRequest) => void): () => void;\n\n /**\n * Get product scenes from ProductManager configuration (optional, for LocalAgentProvider)\n * 从 ProductManager.waitConfiguration().scenes 获取本地配置的场景数据\n * @param locale - 可选,语言环境\n */\n getProductScenes?(locale?: string): Promise<Array<{\n id: number;\n name: string;\n plugins: Array<{\n id: number;\n name: string;\n marketplaceName: string;\n }>;\n prompts: string[];\n mode?: 'coding' | 'working';\n target?: 'local' | 'cloud' | 'all';\n }>>;\n\n // ==================== MCP Server Management ====================\n\n /**\n * Get all MCP servers with their status and tools (optional, used by LocalAgentProvider)\n * Returns the list of configured MCP servers from McpServerManager\n *\n * @returns Array of MCP server information\n */\n getMcpServers?(): Promise<Array<{\n id: string;\n name: string;\n status: 'connecting' | 'connected' | 'disconnected' | 'disabled';\n description?: string;\n tools?: Array<{ name: string; description?: string; enabled?: boolean }>;\n disabled?: boolean;\n error?: string;\n logoUrl?: string;\n officialUrl?: string;\n configSource?: 'user' | 'project' | 'plugin';\n }>>;\n\n /**\n * Toggle MCP server enabled/disabled state (optional, used by LocalAgentProvider)\n *\n * @param serverName - Name of the MCP server to toggle\n * @param enabled - Whether to enable (true) or disable (false) the server\n */\n toggleMcpServer?(serverName: string, enabled: boolean): Promise<void>;\n\n /**\n * Reconnect to an MCP server (optional, used by LocalAgentProvider)\n *\n * @param serverName - Name of the MCP server to reconnect\n * @param forceHttpCallback - Force using HTTP callback instead of URL scheme\n */\n reconnectMcpServer?(serverName: string, forceHttpCallback?: boolean): Promise<void>;\n\n /**\n * Delete an MCP server configuration (optional, used by LocalAgentProvider)\n *\n * @param serverName - Name of the MCP server to delete\n */\n deleteMcpServer?(serverName: string): Promise<void>;\n\n /**\n * Open the MCP configuration file in editor (optional, used by LocalAgentProvider)\n * Executes 'codebuddy.openMcpConfig' command\n */\n openMcpConfig?(): Promise<void>;\n\n /**\n * Get MCP configuration file content\n * @returns File path and content\n */\n getMcpConfigContent?(): Promise<{ filePath: string; content: string }>;\n\n /**\n * Save MCP configuration file content\n * @param content New configuration content\n */\n saveMcpConfigContent?(content: string): Promise<void>;\n\n /**\n * Read text from clipboard (optional, used by LocalAgentProvider for webview clipboard access)\n * @returns Clipboard text content\n */\n clipboardReadText?(): Promise<string>;\n}\n\n/**\n * AgentClient initialization options\n */\nexport interface AgentClientOptions {\n /** Agent provider (required) */\n provider: AgentProvider;\n /** Logger instance */\n logger?: Logger;\n /** Client capabilities (sent during initialization) */\n clientCapabilities?: ClientCapabilities;\n /**\n * 运行环境类型\n * - 'local': IDE 本地环境\n * - 'cloud': 云端环境\n */\n environmentType?: EnvironmentType;\n}\n\n/**\n * Client sessions resource interface\n * Top-level API for session management\n *\n * Key design:\n * - list() returns sessions with pagination info (mapped from agents)\n * - create() creates a new session (auto-creates agent and connects)\n * - load() loads an existing session (finds agent by sessionId and connects)\n * - archive() archives a session/agent\n * - initializeWorkspace() initializes a workspace for future sessions\n */\nexport interface ClientSessionsResource {\n /**\n * List all sessions with pagination info\n * Cloud: Returns server-side filtered/sorted/paginated results\n * Local: Returns client-side filtered/sorted results (synthetic pagination)\n */\n list(options?: ListAgentOptions): Promise<ListAgentResult<SessionInfo>>;\n\n /** Create a new session (auto-creates agent and connects) */\n create(params: CreateSessionParams): Promise<ActiveSession>;\n\n /**\n * Retry creating a session after initial session/new request failed.\n *\n * Use this when `sessions.create()` fails at the `session/new` step\n * (after agent creation and connection establishment succeeded).\n * The caller retrieves `agentId` from the thrown `SessionError.agentId`,\n * then calls this method to re-attempt only the `session/new` request.\n *\n * @experimental This API is subject to change\n *\n * @param agentId - Agent ID from the failed SessionError.agentId\n * @param params - Original create session params (cwd, etc.)\n * @returns ActiveSession on success\n * @throws SessionError if session/new fails again\n */\n retryNewSession(agentId: string, params: CreateSessionParams): Promise<ActiveSession>;\n\n /** Load an existing session (finds agent by sessionId and connects) */\n load(params: LoadSessionParams): Promise<ActiveSession>;\n\n /**\n * Archive a session/agent\n * @param sessionId - Session ID to archive\n * @returns Object containing the archived session ID\n */\n archive(sessionId: string): Promise<{ id: string }>;\n\n /**\n * Rename a session/agent\n * @param sessionId - Session ID to rename\n * @param title - New title for the session\n * @returns Object containing the renamed session ID\n */\n rename(sessionId: string, title: string): Promise<{ id: string }>;\n\n /**\n * Update session status\n * @param sessionId - Session ID to update\n * @param status - New status for the session\n * @returns Object containing the updated session ID\n */\n updateStatus(sessionId: string, status: string): Promise<{ id: string }>;\n\n /**\n * Move a session (Playground → Workspace)\n * @param sessionId - Session ID to move\n * @returns Object containing the moved session ID\n */\n move(sessionId: string): Promise<{ id: string }>;\n\n /** Initialize a workspace for future sessions */\n initializeWorkspace(params: InitializeWorkspaceParams): Promise<InitializeWorkspaceResponse>;\n\n /** Request yielding after current step for a running session */\n requestYieldAfterCurrentStep(sessionId: string): Promise<boolean>;\n\n /** Models resource for getting available models */\n readonly models: ModelsResource;\n\n /** Get current workspaces list */\n getCurrentWorkspaces(filter?: { activeOnly?: boolean }): Promise<WorkspaceInfo[]>;\n\n // Event subscription for sessions list changes\n /** Subscribe to sessions resource events */\n on<K extends keyof SessionsResourceEvents>(\n event: K,\n handler: SessionsResourceEventHandler<K>\n ): void;\n\n /** Unsubscribe from sessions resource events */\n off<K extends keyof SessionsResourceEvents>(\n event: K,\n handler: SessionsResourceEventHandler<K>\n ): void;\n\n /** Open a workspace (for LocalAgentProvider) */\n openWorkspace(params: InitializeWorkspaceParams): Promise<InitializeWorkspaceResponse>;\n\n /** Pick files from file dialog (for LocalAgentProvider) */\n pickFile(params?: PickFileParams): Promise<PickFileResponse>;\n\n /** Pick folders from folder dialog (for LocalAgentProvider) */\n pickFolder(params?: PickFolderParams): Promise<PickFolderResponse>;\n\n /** Upload a file to cloud storage */\n uploadFile(params: UploadFileParams): Promise<UploadFileResponse>;\n\n /** Search for files in the workspace (for LocalAgentProvider) */\n searchFile(params: SearchFileParams): Promise<SearchFileResponse>;\n\n /** Get subagent list (for LocalAgentProvider) */\n getSubagentList(params: GetSubagentListParams): Promise<GetSubagentListResponse>;\n\n /** Get skill list (for LocalAgentProvider) */\n getSkillList(params?: GetSkillListParams): Promise<GetSkillListResponse>;\n\n /** Import a skill folder (for LocalAgentProvider) */\n importSkill(params: ImportSkillParams): Promise<ImportSkillResponse>;\n\n /** Toggle skill enable/disable state (for LocalAgentProvider) */\n toggleSkill(params: ToggleSkillParams): Promise<ToggleSkillResponse>;\n\n /** Delete a skill (for LocalAgentProvider) */\n deleteSkill(params: DeleteSkillParams): Promise<DeleteSkillResponse>;\n\n /** Get skill content by file path (for LocalAgentProvider) */\n getSkillContent(params: GetSkillContentParams): Promise<GetSkillContentResponse>;\n\n /** Get marketplace skills list (for LocalAgentProvider) */\n getMarketplaceSkills(): Promise<GetMarketplaceSkillsResponse>;\n\n /** Get marketplace skill content (for LocalAgentProvider) */\n getMarketplaceSkillContent(params: GetMarketplaceSkillContentParams): Promise<GetMarketplaceSkillContentResponse>;\n\n /** Install marketplace skill to user directory (for LocalAgentProvider) */\n installMarketplaceSkill(params: InstallMarketplaceSkillParams): Promise<InstallMarketplaceSkillResponse>;\n\n /** Batch toggle plugins (for LocalAgentProvider) */\n batchTogglePlugins(request: BatchPluginOperationRequest): Promise<BatchPluginOperationResult>;\n\n /** Get installed plugins (for LocalAgentProvider) */\n getInstalledPlugins?(forceRefresh?: boolean): Promise<Array<{\n name: string;\n marketplaceName: string;\n status: string;\n description?: string;\n version?: string;\n installScope?: 'user' | 'project';\n installedScopes?: Array<'user' | 'project' | 'local' | 'project-local'>;\n installedScopesStatus?: Record<string, boolean>;\n installId?: string;\n }>>;\n\n /** Install plugins (for LocalAgentProvider) */\n installPlugins(\n pluginNames: string[],\n marketplaceName: string,\n installScope?: 'user' | 'project',\n marketplaceSource?: string,\n workspacePath?: string\n ): Promise<{ success: boolean; error?: string }>;\n\n /** Uninstall a plugin (for LocalAgentProvider) */\n uninstallPlugin?(\n pluginName: string,\n marketplaceName: string,\n scope: 'user' | 'project' | 'project-local'\n ): Promise<{ success: boolean; error?: string }>;\n\n /** Update a plugin to the latest version (for LocalAgentProvider) */\n updatePlugin?(\n pluginName: string,\n marketplaceName: string\n ): Promise<{ success: boolean; error?: string }>;\n\n /** Get plugin marketplaces list (for LocalAgentProvider) */\n getPluginMarketplaces?(forceRefresh?: boolean): Promise<Array<{\n id: string;\n name: string;\n type: 'github' | 'local' | 'custom';\n source: { repo?: string; ref?: string; url?: string };\n description?: string;\n isBuiltin?: boolean;\n }>>;\n\n /** Get plugins from a marketplace (for LocalAgentProvider) */\n getMarketplacePlugins?(\n marketplaceName: string,\n forceRefresh?: boolean,\n searchText?: string\n ): Promise<Array<{\n name: string;\n marketplaceName: string;\n description?: string;\n version?: string;\n author?: string;\n homepage?: string;\n iconUrl?: string;\n tags?: string[];\n installed?: boolean;\n status?: 'enabled' | 'disabled' | 'not-installed';\n installedScopes?: Array<'user' | 'project'>;\n hasUpdate?: boolean;\n }>>;\n\n /** Get plugin detail (for LocalAgentProvider) */\n getPluginDetail?(\n pluginName: string,\n marketplaceName: string\n ): Promise<{\n name: string;\n marketplaceName: string;\n description?: string;\n version?: string;\n author?: string;\n homepage?: string;\n readme?: string;\n tools?: Array<{ name: string; description?: string }>;\n resources?: Array<{ name: string; description?: string }>;\n prompts?: Array<{ name: string; description?: string }>;\n installed?: boolean;\n status?: 'enabled' | 'disabled' | 'not-installed';\n } | null>;\n\n /** Add a plugin marketplace (for LocalAgentProvider) */\n addPluginMarketplace?(\n source: string,\n name?: string\n ): Promise<{\n success: boolean;\n error?: string;\n marketplace?: {\n id: string;\n name: string;\n type: 'github' | 'local' | 'custom';\n source: { repo?: string; ref?: string; url?: string };\n description?: string;\n isBuiltin?: boolean;\n };\n }>;\n\n /** Remove a plugin marketplace (for LocalAgentProvider) */\n removePluginMarketplace?(marketplaceName: string): Promise<{\n success: boolean;\n error?: string;\n }>;\n\n /** Refresh a plugin marketplace (for LocalAgentProvider) */\n refreshPluginMarketplace?(marketplaceName: string): Promise<{\n success: boolean;\n error?: string;\n plugins?: Array<{\n name: string;\n marketplaceName: string;\n description?: string;\n version?: string;\n installed?: boolean;\n status?: 'enabled' | 'disabled' | 'not-installed';\n }>;\n }>;\n\n /** Open folder in new window (for LocalAgentProvider) */\n openFolderInNewWindow?(folderPath: string): Promise<void>;\n\n /** Open folder in system file manager (for LocalAgentProvider) */\n openFolder?(folderPath: string): Promise<boolean>;\n\n /**\n * Get support scenes from backend API (for LocalAgentProvider)\n * API 端点: GET /v2/as/support/scenes (Local) 或 GET /console/as/support/scenes (Web)\n * @param locale - 可选,语言环境(如 'zh-CN', 'en-US'),用于获取对应语言的场景数据\n */\n getSupportScenes(locale?: string): Promise<Array<{\n id: number;\n name: string;\n plugins: Array<{\n id: number;\n name: string;\n marketplaceName: string;\n }>;\n prompts: string[];\n mode?: 'coding' | 'working';\n }>>;\n\n /**\n * Get product scenes from ProductManager configuration (for LocalAgentProvider)\n * 从 ProductManager.waitConfiguration().scenes 获取本地配置的场景数据\n * @param locale - 可选,语言环境\n */\n getProductScenes?(locale?: string): Promise<Array<{\n id: number;\n name: string;\n plugins: Array<{\n id: number;\n name: string;\n marketplaceName: string;\n }>;\n prompts: string[];\n mode?: 'coding' | 'working';\n target?: 'local' | 'cloud' | 'all';\n }>>;\n\n /**\n * Get available commands for a session\n * If session.availableCommands has cached values, return them\n * Otherwise, fetch from provider (for LocalAgentProvider)\n * @param params - Parameters for getting commands\n * @returns Promise<AvailableCommand[]> - Array of available commands\n */\n getAvailableCommands(params?: GetAvailableCommandsParams): Promise<AvailableCommand[]>;\n\n /**\n * Get automation snapshot\n */\n getAutomationSnapshot(): Promise<AutomationSnapshot>;\n\n /**\n * Create/update automation definition\n */\n updateAutomation(payload: AutomationUpdatePayload): Promise<AutomationUpdateResult>;\n\n /**\n * Delete automation definition\n */\n deleteAutomation(id: string): Promise<AutomationUpdateResult>;\n\n /**\n * Archive automation inbox item\n */\n archiveAutomationInboxItem(itemId: string): Promise<AutomationUpdateResult>;\n\n /**\n * Delete automation inbox item\n */\n deleteAutomationInboxItem(itemId: string): Promise<AutomationUpdateResult>;\n\n /**\n * Trigger automation test run\n */\n testAutomation(id: string): Promise<AutomationUpdateResult>;\n\n // ==================== Telemetry ====================\n\n /**\n * Report telemetry event through the provider chain\n * Delegates to AgentProvider.reportTelemetry()\n *\n * @param eventName - Event name / code\n * @param payload - Event data\n */\n reportTelemetry?(eventName: string, payload: Record<string, unknown>): Promise<void>;\n\n // ==================== Product Configuration ====================\n\n /**\n * Get product configuration subset\n * Returns deploymentType, creditPurchaseActions, links, productFeatures\n * Used by agent-ui for error banner credit purchase guidance\n */\n getProductConfiguration?(): Promise<{\n deploymentType?: string;\n creditPurchaseActions?: Record<string, {\n labelZh: string;\n labelEn: string;\n url: string;\n showButton?: boolean;\n }>;\n links?: {\n craftFeedback?: string;\n mcpMarketUrl?: string;\n mcpDocumentUrl?: string;\n helpDocument?: string;\n };\n networkEnvironment?: string;\n productFeatures?: Record<string, boolean>;\n customModelSettings?: unknown;\n skillScanDirs?: string[];\n }>;\n\n /**\n * Get user info\n * Returns enterpriseId from authentication session\n * Used by agent-ui for determining personal/enterprise user\n */\n getUserInfo?(): Promise<{\n enterpriseId?: string;\n }>;\n\n // ==================== MCP Sampling/Roots 确认相关 ====================\n\n /**\n * Respond to MCP Sampling confirmation request\n * Called when user confirms/rejects a sampling request in MCP tool renderer\n *\n * @param sessionId - Session ID\n * @param response - Sampling confirmation response\n */\n respondToSampling?(sessionId: string, response: McpSamplingConfirmResponse): Promise<void>;\n\n /**\n * Respond to MCP Roots confirmation request\n * Called when user confirms/rejects a roots request in MCP tool renderer\n *\n * @param sessionId - Session ID\n * @param response - Roots confirmation response\n */\n respondToRoots?(sessionId: string, response: McpRootsConfirmResponse): Promise<void>;\n\n /**\n * Subscribe to MCP Sampling confirmation requests\n * Called when MCP server initiates a sampling request\n *\n * @param serverName - MCP server name\n * @param callback - Request callback\n * @returns Unsubscribe function\n */\n subscribeSamplingRequests?(serverName: string, callback: (request: McpSamplingConfirmRequest) => void): () => void;\n\n /**\n * Subscribe to MCP Roots confirmation requests\n * Called when MCP server initiates a roots request\n *\n * @param serverName - MCP server name\n * @param callback - Request callback\n * @returns Unsubscribe function\n */\n subscribeRootsRequests?(serverName: string, callback: (request: McpRootsConfirmRequest) => void): () => void;\n\n // ==================== MCP Server Management ====================\n\n /**\n * Get MCP servers list\n * Returns the list of configured MCP servers with their status\n *\n * @returns Promise<McpServerInfo[]> - Array of MCP server info\n */\n getMcpServers?(): Promise<McpServerInfo[]>;\n\n /**\n * Toggle MCP server enabled/disabled state\n *\n * @param serverName - Server name\n * @param enabled - Whether to enable the server\n */\n toggleMcpServer?(serverName: string, enabled: boolean): Promise<void>;\n\n /**\n * Reconnect to an MCP server\n *\n * @param serverName - Server name\n * @param forceHttpCallback - Force using HTTP callback instead of URL scheme\n */\n reconnectMcpServer?(serverName: string, forceHttpCallback?: boolean): Promise<void>;\n\n /**\n * Delete an MCP server configuration\n *\n * @param serverName - Server name\n */\n deleteMcpServer?(serverName: string): Promise<void>;\n\n /**\n * Open MCP configuration file in editor\n */\n openMcpConfig?(): Promise<void>;\n\n /**\n * Get MCP configuration file content\n * @returns File path and content\n */\n getMcpConfigContent?(): Promise<{ filePath: string; content: string }>;\n\n /**\n * Save MCP configuration file content\n * @param content New configuration content\n */\n saveMcpConfigContent?(content: string): Promise<void>;\n\n /**\n * Read text from clipboard (optional, used by LocalAgentProvider for webview clipboard access)\n * @returns Clipboard text content\n */\n clipboardReadText?(): Promise<string>;\n\n}\n\n// ============================================\n// MCP Sampling/Roots Confirmation Types\n// ============================================\n\n/**\n * MCP Sampling message role\n */\nexport type McpSamplingRole = 'user' | 'assistant';\n\n/**\n * MCP Sampling message content - text\n */\nexport interface McpSamplingTextContent {\n type: 'text';\n text: string;\n}\n\n/**\n * MCP Sampling message content - image\n */\nexport interface McpSamplingImageContent {\n type: 'image';\n data: string;\n mimeType: string;\n}\n\n/**\n * MCP Sampling message content - audio\n */\nexport interface McpSamplingAudioContent {\n type: 'audio';\n data: string;\n mimeType: string;\n}\n\n/**\n * MCP Sampling message content union type\n */\nexport type McpSamplingContent = McpSamplingTextContent | McpSamplingImageContent | McpSamplingAudioContent;\n\n/**\n * MCP Sampling message\n */\nexport interface McpSamplingMessage {\n role: McpSamplingRole;\n content: McpSamplingContent;\n}\n\n/**\n * MCP Sampling confirmation request\n * Sent from backend when MCP server requests sampling\n */\nexport interface McpSamplingConfirmRequest {\n id: string;\n serverName: string;\n model?: string;\n messages: McpSamplingMessage[];\n systemPrompt?: string;\n maxTokens: number;\n timestamp: number;\n}\n\n/**\n * MCP Sampling confirmation response\n * Sent from frontend when user confirms/rejects\n */\nexport interface McpSamplingConfirmResponse {\n id: string;\n approved: boolean;\n rememberChoice?: boolean;\n}\n\n/**\n * MCP Root definition\n */\nexport interface McpRoot {\n uri: string;\n name?: string;\n}\n\n/**\n * MCP Roots confirmation request\n * Sent from backend when MCP server requests roots access\n */\nexport interface McpRootsConfirmRequest {\n id: string;\n serverName: string;\n roots: McpRoot[];\n timestamp: number;\n}\n\n/**\n * MCP Roots confirmation response\n * Sent from frontend when user confirms/rejects\n */\nexport interface McpRootsConfirmResponse {\n id: string;\n approved: boolean;\n rememberChoice?: boolean;\n}\n\n// ============================================\n// Workspace Types\n// ============================================\n\n/**\n * Workspace information (aligned with FolderSelectResult)\n */\nexport interface WorkspaceInfo {\n /** Folder path */\n path: string;\n /** Folder display name */\n label: string;\n}\n\n// ============================================\n// File Picker Types\n// ============================================\n\n/**\n * File filter for pickFile dialog\n */\nexport interface FileFilter {\n /** Display name for the filter */\n readonly name: string;\n /** File extensions (without dot) */\n readonly extensions: string[];\n}\n\n/**\n * Parameters for picking files\n */\nexport interface PickFileParams {\n /** Default path for the dialog */\n readonly defaultPath?: string;\n /** File type filters */\n readonly filters?: FileFilter[];\n /** Whether to allow multiple selection (default false) */\n readonly canSelectMany?: boolean;\n}\n\n/**\n * Response from picking files\n */\nexport interface PickFileResponse {\n /** Selected files - File objects in browser, absolute path strings in IDE */\n readonly files: Array<File | string>;\n /** Whether user cancelled the dialog */\n readonly canceled: boolean;\n /** Error message (if failed) */\n readonly error?: string;\n}\n\n// ============================================\n// Folder Picker Types\n// ============================================\n\n/**\n * Parameters for picking folders\n */\nexport interface PickFolderParams {\n /** Default path for the dialog */\n readonly defaultPath?: string;\n}\n\n/**\n * Response from picking folders\n */\nexport interface PickFolderResponse {\n /** Selected folder paths */\n readonly folderPaths: string[];\n /** Whether user cancelled the dialog */\n readonly canceled: boolean;\n /** Error message (if failed) */\n readonly error?: string;\n}\n\n// ============================================\n// File Upload Types\n// ============================================\n\n/**\n * Parameters for uploading files\n */\nexport interface UploadFileParams {\n /** Files to upload - File objects in browser, absolute path strings in IDE */\n readonly files: Array<File | string>;\n /** Optional AbortSignal to cancel the upload */\n readonly abortSignal?: AbortSignal;\n}\n\n/**\n * Response from uploading files\n */\nexport interface UploadFileResponse {\n /** Whether upload was successful */\n readonly success: boolean;\n /** Cloud URLs corresponding to each uploaded file (same order as input files) */\n readonly urls?: string[];\n /** URL expiration time in seconds (from backend) */\n readonly expireSeconds?: number;\n /** Error message (if upload failed) */\n readonly error?: string;\n /** Whether the upload was cancelled by user */\n readonly aborted?: boolean;\n}\n\n// ============================================\n// File Search Types\n// ============================================\n\n/**\n * Mention type for file/folder\n */\nexport enum MentionType {\n file = 'file',\n folder = 'folder'\n}\n\n/**\n * Search options for file search\n */\nexport interface SearchOptions {\n /** Search keyword */\n readonly search?: string;\n /** Number of results to return */\n readonly resultNum: number;\n}\n\n/**\n * File search result\n */\nexport interface SearchFileResult {\n /** Full path */\n path: string;\n /** Relative path */\n relativePath: string;\n /** File name */\n fileName?: string;\n /** Folder name */\n folderName?: string;\n /** Type (file or folder) */\n type: MentionType.file | MentionType.folder;\n}\n\n/**\n * Parameters for searching files\n */\nexport interface SearchFileParams {\n /** Search options */\n readonly options: SearchOptions;\n /** Search path*/\n readonly cwd?: string;\n}\n\n/**\n * Response from searching files\n */\nexport interface SearchFileResponse {\n /** Search results */\n readonly results: SearchFileResult[];\n /** Error message (if failed) */\n readonly error?: string;\n}\n\n/**\n * Subagent information\n */\nexport interface SubagentInfo {\n /** Subagent name */\n name: string;\n /** Subagent description */\n description: string;\n /** System prompt */\n systemPrompt: string;\n /** File path */\n filePath?: string;\n /** Model type */\n model?: string;\n /** Agent mode */\n agentMode?: 'agentic' | 'manual';\n /** Whether enabled */\n enabled?: boolean;\n /** Model ID */\n modelID?: string;\n /** Subagent level */\n level?: 'project' | 'user';\n}\n\n/**\n * Parameters for getting subagent list\n */\nexport interface GetSubagentListParams {\n /** Search options */\n readonly options: {\n /** Search keyword (filter by name or description) */\n readonly search?: string;\n /** Limit number of results */\n readonly resultNum?: number;\n /** Agent mode filter */\n readonly agentMode?: 'agentic' | 'manual' | 'all';\n /** Whether to return only enabled subagents */\n readonly onlyEnabled?: boolean;\n };\n /** Working directory (optional, for filtering project-level subagents) */\n readonly cwd?: string;\n}\n\n/**\n * Response from getting subagent list\n */\nexport interface GetSubagentListResponse {\n /** Subagent list */\n readonly results: SubagentInfo[];\n /** Error message (if failed) */\n readonly error?: string;\n}\n\n/**\n * Skill info returned from getSkillList\n */\nexport interface SkillInfo {\n /** Skill name */\n name: string;\n /** File path of the skill */\n filePath: string;\n /** Description of the skill */\n description: string;\n /** Chinese description of the skill */\n description_zh?: string;\n /** English description of the skill */\n description_en?: string;\n /** When to use the skill */\n whenToUse?: string;\n /** Source of the skill */\n source: 'localSettings' | 'userSettings' | 'plugin' | 'builtin';\n /** Skill type */\n type: 'prompt';\n /** License information */\n license?: string;\n /** Allowed tools */\n allowedTools?: string[];\n /** Whether the skill is disabled */\n disable?: boolean;\n}\n\n/**\n * Parameters for getting skill list\n */\nexport interface GetSkillListParams {\n /** Working directory (optional, for filtering project-level skills) */\n readonly cwd?: string;\n /** Whether to use global (backend) channel, defaults to true. When false, uses sendBroadcastRequest. */\n readonly global?: boolean;\n /** Whether to exclude plugin skills from the result, defaults to false. */\n readonly excludePluginSkills?: boolean;\n /**\n * 用户级 skill 扫描目录名称列表(相对于 home 目录),按优先级从高到低排列。\n * 同名 skill 以高优先级目录为准。\n * 未传入或为空时使用产品默认目录。\n */\n readonly skillScanDirs?: string[];\n}\n\n/**\n * Response from getting skill list\n */\nexport interface GetSkillListResponse {\n /** Skill list */\n readonly results: SkillInfo[];\n /** Error message (if failed) */\n readonly error?: string;\n}\n\n/**\n * Parameters for importing a skill folder\n */\nexport interface ImportSkillParams {\n /** Source location: project-level or user-level */\n readonly source: 'localSettings' | 'userSettings';\n /** Working directory (required when source is localSettings). */\n readonly cwd?: string;\n /** 直接传入文件夹路径(拖拽导入时使用),有此字段时跳过系统文件选择器 */\n readonly folderPath?: string;\n}\n\n/**\n * Response from importing a skill folder\n */\nexport interface ImportSkillResponse {\n /** Whether the import was successful */\n readonly success: boolean;\n /** Error message (if failed) */\n readonly error?: string;\n /** Imported skill name */\n readonly skillName?: string;\n}\n\n/**\n * Parameters for toggling skill enable/disable state\n */\nexport interface ToggleSkillParams {\n /** File path of the skill to toggle */\n readonly filePath: string;\n /** Whether to disable the skill */\n readonly disable: boolean;\n}\n\n/**\n * Response from toggling skill state\n */\nexport interface ToggleSkillResponse {\n /** Whether the toggle was successful */\n readonly success: boolean;\n /** Error message (if failed) */\n readonly error?: string;\n}\n\n/**\n * Parameters for deleting a skill\n */\nexport interface DeleteSkillParams {\n /** File path of the skill to delete */\n readonly filePath: string;\n /** Name of the skill */\n readonly name: string;\n}\n\n/**\n * Response from deleting a skill\n */\nexport interface DeleteSkillResponse {\n /** Whether the deletion was successful */\n readonly success: boolean;\n /** Error message (if failed) */\n readonly error?: string;\n}\n\n/**\n * Parameters for getting skill content\n */\nexport interface GetSkillContentParams {\n /** File path of the skill */\n readonly filePath: string;\n}\n\n/**\n * Response from getting skill content\n */\nexport interface GetSkillContentResponse {\n /** Skill file content */\n readonly content: string;\n /** Error message (if failed) */\n readonly error?: string;\n}\n\n/**\n * Marketplace skill info (simplified structure for UI layer)\n */\nexport interface MarketplaceSkillInfo {\n /** Skill name */\n name: string;\n /** Skill description */\n description: string;\n /** Skill description in Chinese */\n description_zh?: string;\n /** Skill description in English */\n description_en?: string;\n /** Skill version */\n version?: string;\n /** Skill author */\n author?: string;\n /** Skill icon URL */\n iconUrl?: string;\n /** Skill tags */\n tags?: string[];\n}\n\n/**\n * Response from getting marketplace skills\n */\nexport interface GetMarketplaceSkillsResponse {\n /** Marketplace skill list */\n readonly results: MarketplaceSkillInfo[];\n /** Error message (if failed) */\n readonly error?: string;\n}\n\n/**\n * Parameters for getting marketplace skill content\n */\nexport interface GetMarketplaceSkillContentParams {\n /** Skill name */\n readonly skillName: string;\n}\n\n/**\n * Response from getting marketplace skill content\n */\nexport interface GetMarketplaceSkillContentResponse {\n /** Skill file content */\n readonly content: string;\n /** Error message (if failed) */\n readonly error?: string;\n}\n\n/**\n * Parameters for installing marketplace skill\n */\nexport interface InstallMarketplaceSkillParams {\n /** Skill name to install */\n readonly skillName: string;\n}\n\n/**\n * Response from installing marketplace skill\n */\nexport interface InstallMarketplaceSkillResponse {\n /** Whether the install was successful */\n readonly success: boolean;\n /** Skill name */\n readonly skillName: string;\n /** Error message (if failed) */\n readonly errorMessage?: string;\n}\n\n// ============================================\n// MCP Server Management Types\n// ============================================\n\n/**\n * MCP Tool information\n */\nexport interface McpToolInfo {\n /** Tool name */\n name: string;\n /** Tool description */\n description?: string;\n /** Whether the tool is enabled */\n enabled?: boolean;\n}\n\n/**\n * MCP Server information\n */\nexport interface McpServerInfo {\n /** Server ID */\n id: string;\n /** Server name */\n name: string;\n /** Connection status */\n status: 'connecting' | 'connected' | 'disconnected' | 'disabled';\n /** Server description */\n description?: string;\n /** Available tools */\n tools?: McpToolInfo[];\n /** Whether the server is disabled */\n disabled?: boolean;\n /** Error message (if connection failed) */\n error?: string;\n /** Logo URL */\n logoUrl?: string;\n /** Official website URL */\n officialUrl?: string;\n /** Configuration source */\n configSource?: 'user' | 'project' | 'plugin';\n}\n","/**\n * Backend Provider 类型定义\n *\n * 定义 IBackendProvider 接口和配置\n */\n\n// ============================================================================\n// OAuth Repository Types (re-exported from service module)\n// ============================================================================\n\nimport type {\n CNBBranchParams as _CNBBranchParams,\n GitHubBranchParams as _GitHubBranchParams,\n GongfengBranchParams as _GongfengBranchParams,\n ListBranchesRequest as _ListBranchesRequest,\n ListBranchesResponse as _ListBranchesResponse,\n ListReposRequest as _ListReposRequest,\n ListReposResponse as _ListReposResponse,\n OauthBranch as _OauthBranch,\n OauthCNBRepo as _OauthCNBRepo,\n OauthConnectorName as _OauthConnectorName,\n OauthGitHubRepo as _OauthGitHubRepo,\n OauthGitHubRepoOwner as _OauthGitHubRepoOwner,\n OauthGongFengRepo as _OauthGongFengRepo,\n OauthGongFengRepoNamespace as _OauthGongFengRepoNamespace,\n OauthGongFengRepoOwner as _OauthGongFengRepoOwner,\n} from './service/oauth-repository-types';\n\n// Re-export with original names\nexport type OauthConnectorName = _OauthConnectorName;\nexport type OauthBranch = _OauthBranch;\nexport type GitHubBranchParams = _GitHubBranchParams;\nexport type GongfengBranchParams = _GongfengBranchParams;\nexport type CNBBranchParams = _CNBBranchParams;\nexport type ListBranchesRequest = _ListBranchesRequest;\nexport type ListBranchesResponse = _ListBranchesResponse;\nexport type OauthGitHubRepoOwner = _OauthGitHubRepoOwner;\nexport type OauthGitHubRepo = _OauthGitHubRepo;\nexport type OauthGongFengRepoNamespace = _OauthGongFengRepoNamespace;\nexport type OauthGongFengRepoOwner = _OauthGongFengRepoOwner;\nexport type OauthGongFengRepo = _OauthGongFengRepo;\nexport type OauthCNBRepo = _OauthCNBRepo;\nexport type ListReposRequest = _ListReposRequest;\nexport type ListReposResponse = _ListReposResponse;\n\n// ============================================================================\n// Account 相关类型\n// ============================================================================\n\n/**\n * 账号版本类型\n */\nexport type Edition = 'pro' | 'personal' | 'ultimate' | 'exclusive';\n\n/**\n * 版本展示类型(用于 UI 展示)\n * - free: 免费版(个人版未订阅 Pro)\n * - pro: Pro 版(个人版已订阅 Pro)\n * - ultimate: 旗舰版(团队版)\n * - exclusive: 专享版(企业版)\n */\nexport type EditionDisplayType = 'free' | 'pro' | 'ultimate' | 'exclusive';\n\n/**\n * 部署状态\n */\nexport interface DeployStatus {\n statusCode: number;\n statusMsg: string;\n detailMsg: string;\n}\n\n/**\n * 套餐代码\n */\n\n/**\n * TCACA_code_001_PqouKr6QWV CodeBuddy海外版免费包\n * TCACA_code_002_AkiJS3ZHF5 CodeBuddy海外版Pro版本包-包月/CodeBuddy Pro Plan - Monthly:\n * TCACA_code_006_DbXS0lrypC CodeBuddy海外版一次性免费赠送2周的Pro版本包/CodeBuddy One-time Free 2-Week Pro Plan Trial\n * TCACA_code_007_nzdH5h4Nl0 CodeBuddy海外版运营裂变包/CodeBuddy Growth Plan\n * TCACA_code_003_FAnt7lcmRT CodeBuddy海外版Pro版本包-包年/CodeBuddy Pro Plan - Yearly\n * TCACA_code_008_cfWoLwvjU4 赠送月包\n */\nexport enum CommodityCode {\n free = 'TCACA_code_001_PqouKr6QWV', // free\n proMon = 'TCACA_code_002_AkiJS3ZHF5',\n // 国内月包(国际pro+)\n proMonPlus = 'TCACA_code_005_maRGyrHhw1',\n // 免费赠送2周\n gift = 'TCACA_code_006_DbXS0lrypC',\n activity = 'TCACA_code_007_nzdH5h4Nl0',\n proYear = 'TCACA_code_003_FAnt7lcmRT',\n // 国际(free 月包、国内试用包)\n freeMon = 'TCACA_code_008_cfWoLwvjU4', // free\n // 加量包\n extra = 'TCACA_code_009_0XmEQc2xOf',\n}\n\n/**\n * 套餐资源项(用于展示列表)\n */\nexport interface PlanResource {\n /** 资源 ID */\n id: string;\n /** 套餐名称(i18n key) */\n name: string;\n /** 套餐代码 */\n packageCode: CommodityCode;\n /** 是否是每日刷新的套餐 */\n isDaily: boolean;\n /** 总量 */\n total: number;\n /** 已用 */\n used: number;\n /** 剩余 */\n left: number;\n /** 到期时间戳 */\n expireAt?: number;\n /** 刷新时间戳 */\n refreshAt?: number;\n}\n\n/**\n * 账号套餐信息\n */\nexport interface AccountPlan {\n /** 是否是 Pro 版本 */\n isPro: boolean;\n // 是否是试用版本\n isTria?: boolean;\n /** 到期时间戳 */\n expireAt?: number;\n // 刷新时间(年套餐下、本周期结束日期)\n refreshAt?: number;\n /** 自动续费标志 0-关闭 1-开启 */\n renewFlag: 0 | 1;\n /** 套餐代码 */\n PackageCode?: CommodityCode;\n /** 套餐名称 */\n name: string;\n usageTotal?: string;\n usageUsed?: string;\n usageLeft?: string;\n /** 所有套餐资源列表 */\n resources?: PlanResource[];\n}\n\n/**\n * 账号类型\n * - sso: SSO 登录账号\n * - unified: 统一登录账号\n * - 空字符串: 普通账号\n */\nexport type AccountType = 'sso' | 'unified' | '';\n\n/**\n * 账号信息\n */\nexport interface Account {\n /** 用户ID(唯一标识) */\n uid: string;\n /** 用户昵称 */\n nickname: string;\n /** 版本类型 */\n type: Edition;\n /** 版本展示类型(用于 UI 展示) */\n editionType: EditionDisplayType;\n /** 是否最后一次登录 */\n lastLogin: boolean;\n /** 企业ID */\n enterpriseId?: string;\n /** 企业名称 */\n enterpriseName?: string;\n /** 企业LOGO */\n enterpriseLogo?: string;\n /** 企业内用户名 */\n enterpriseUserName?: string;\n /** 插件是否启用 */\n pluginEnabled?: boolean;\n /** 部署状态 */\n deployStatus?: DeployStatus;\n /** 账号类型 */\n accountType?: AccountType;\n /** 是否是 Pro 版本 */\n isPro?: boolean;\n /** 到期时间戳 */\n expireAt?: string | number;\n /** 刷新时间(年套餐下、本周期结束日期) */\n refreshAt?: number;\n /** 自动续费标志 0-关闭 1-开启 */\n renewFlag?: 0 | 1;\n /** 套餐代码 */\n PackageCode?: CommodityCode;\n /** 套餐名称 */\n name?: string;\n email?: string;\n /** 套餐总用量 */\n usageTotal?: string;\n /** 套餐已用量 */\n usageUsed?: string;\n /** 套餐剩余用量 */\n usageLeft?: string;\n /** 所有套餐资源列表(个人用户) */\n resources?: PlanResource[];\n}\n\n/** 账户状态 */\nexport enum AccountStatus {\n /** 有效 */\n valid = 0,\n /** 已退款 */\n refund = 1,\n /** 已过期 */\n expired = 2,\n /** 已用完 */\n usedUp = 3,\n}\n\n// https://iwiki.woa.com/p/1151041572#7%E3%80%81%E8%B4%B9%E7%94%A8%E4%B8%AD%E5%BF%83%E6%8E%A7%E5%88%B6%E5%8F%B0-%E8%B5%84%E6%BA%90%E5%8C%85%E7%AE%A1%E7%90%86%E6%9F%A5%E8%AF%A2%E6%8E%A5%E5%8F%A3\nexport interface UserResource {\n AccountId: number;\n ResourceId: string;\n // 账户类型: 1-RI 2-资源包 9 - 组合包\n // ResourceType: 1 | 2 | 9;\n // 总周期数量\n TotalCycles: 1 | 12;\n // 剩余周期数量\n RemainCycles: number;\n Status: AccountStatus;\n // 费用类型:免费1/付费2\n FeeType: 1 | 2;\n PackageCode: CommodityCode;\n PackageName: string;\n // // 周期容量(使用下方精确值)\n // CycleCapacitySize: number;\n // // 剩余周期数量\n // CycleCapacityRemain: number;\n SupportAutoRenew: 0 | 1;\n SupportManualRenew: 0 | 1;\n AutoRenewFlag: 0 | 1;\n // AutoRenewTimeUnit: string;\n // AutoRenewTimeSpan: 1;\n // ProductCode: string;\n // SubProductCode: string;\n // 单周期开始时间\n CycleStartTime: number; // 时间戳 单位为毫秒\n // 单周期结束时间\n CycleEndTime: string; // 2025-11-27 14:36:00\n // CapacityType: string;\n CreateTime: string;\n ExpiredTime: string; // 2025-11-27 14:36:00\n DeductionStartTime: number; // 时间戳 单位为毫秒\n // 抵扣结束时间戳 单位为毫秒\n DeductionEndTime: number; // 时间戳 单位为毫秒\n CapacityUsedPrecise: string;\n // 当前周期余量精确值\n CycleCapacityRemainPrecise: string;\n // 当前周期总量精确值\n CycleCapacitySizePrecise: string;\n // 剩余容量精确值\n CapacityRemainPrecise: string;\n // 用量精确值\n CapacitySizePrecise: string;\n}\n\n// ============================================================================\n// Model 相关类型\n// ============================================================================\n\n/**\n * 推理配置\n */\nexport interface ReasoningConfig {\n /** 推理努力程度 */\n effort: 'low' | 'medium' | 'high';\n /** 摘要模式 */\n summary: 'auto' | 'always' | 'never';\n}\n\n/**\n * 模型信息\n */\nexport interface ModelInfo {\n /** 模型ID */\n id: string;\n /** 模型名称 */\n name: string;\n /** 供应商 */\n vendor: string;\n /** 最大输出 token 数 */\n maxOutputTokens: number;\n /** 最大输入 token 数 */\n maxInputTokens: number;\n /** 是否支持工具调用 */\n supportsToolCall: boolean;\n /** 是否支持图像 */\n supportsImages: boolean;\n /** 是否禁用多模态 */\n disabledMultimodal: boolean;\n /** 最大允许大小 */\n maxAllowedSize: number;\n /** 是否支持推理 */\n supportsReasoning: boolean;\n /** 是否仅推理模式 */\n onlyReasoning: boolean;\n /** 温度参数 */\n temperature: number;\n /** 推理配置 */\n reasoning: ReasoningConfig;\n /** 英文描述 */\n descriptionEn: string;\n /** 中文描述 */\n descriptionZh: string;\n}\n\n/**\n * 本地自定义模型配置\n * 对应 ~/.codebuddy/models.json 中的单个模型定义\n */\nexport interface LocalCustomModelConfig {\n /** 模型唯一标识(同时作为请求时使用的 model 参数) */\n id: string;\n /** 模型展示名 */\n name?: string;\n /** 提供商名称 */\n vendor?: string;\n /** OpenAI 兼容接口地址(完整路径) */\n url?: string;\n /** API Key */\n apiKey?: string;\n /** 最大输入 token 数 */\n maxInputTokens?: number;\n /** 最大输出 token 数 */\n maxOutputTokens?: number;\n /** 温度 */\n temperature?: number;\n /** 是否支持工具调用 */\n supportsToolCall?: boolean;\n /** 是否支持图片输入 */\n supportsImages?: boolean;\n /** 是否支持推理 */\n supportsReasoning?: boolean;\n}\n\n/**\n * 获取本地自定义模型响应\n */\nexport interface GetLocalCustomModelsResponse {\n /** 用户级 models.json 中配置的模型列表 */\n models: LocalCustomModelConfig[];\n /** 原始 availableModels 配置 */\n availableModels?: string[];\n /** 配置文件路径 */\n path: string;\n}\n\n/**\n * 保存本地自定义模型请求\n */\nexport interface SaveLocalCustomModelRequest {\n /** 新模型配置 */\n model: LocalCustomModelConfig;\n /** 编辑时旧的模型 ID(用于重命名) */\n previousId?: string;\n /** 是否加入可见模型列表,默认 true */\n visible?: boolean;\n}\n\n// ============================================================================\n// UserConnector 相关类型\n// ============================================================================\n\n/**\n * 用户连接器信息\n */\nexport interface UserConnector {\n /** 用户ID */\n user_id: string;\n /** 连接器名称 */\n name: ConnectorType;\n displayName: string;\n /** 连接时间 */\n connect_at: string;\n /** 连接状态,0未连接,1已连接 */\n connectStatus: 0 | 1;\n /** 勾选仓库列表,逗号分隔 */\n repos: string;\n /** 激活状态,0未激活,1已激活 */\n activeStatus: 0 | 1;\n /** 提示词 */\n prompt: string;\n /** 跳转URL */\n url: string;\n /** 描述 */\n description: string;\n /** OAuth Client ID */\n oauthClientId: string;\n /** OAuth 重定向 URL */\n oauthRedirectUrl: string;\n oauthAppName: string;\n}\n\n/**\n * 获取用户连接器列表响应\n */\nexport interface ListUserConnectorResponse {\n /** 连接器列表 */\n connectors: UserConnector[];\n}\n\n/**\n * 修改用户连接器连接状态请求\n */\nexport interface ModifyUserConnectorConnectStatusRequest {\n /** 连接器名称 */\n name: ConnectorType;\n /** 连接状态,0未连接,1已连接 */\n connectStatus: 0 | 1;\n /** 激活状态,0未激活,1已激活 */\n activeStatus?: 0 | 1;\n /** 勾选仓库列表 */\n repos?: string[];\n}\n\n/**\n * 修改用户连接器仓库请求\n */\nexport interface ModifyUserConnectorRepoRequest {\n /** 连接器名称 */\n name: ConnectorType;\n /** 仓库列表 */\n repo?: string[];\n}\n\n/**\n * 修改用户连接器激活状态请求\n */\nexport interface ModifyUserConnectorActiveStatusRequest {\n /** 连接器名称 */\n name: ConnectorType;\n /** 激活状态,0未激活,1已激活 */\n activeStatus: 0 | 1;\n}\n\n// 连接器类型\nexport type ConnectorType = 'github' | 'gongfeng' | 'cnb' | 'figma';\n\n// ============================================================================\n// TaskConnector 相关类型\n// ============================================================================\n\n/**\n * 任务连接器信息\n */\nexport interface TaskConnector {\n /** 用户ID */\n user_id: string;\n /** 任务ID */\n task_id: string;\n /** 连接器名称(唯一标识,如github/gongfeng/figma/cnb) */\n name: string;\n displayName: string;\n /** 勾选仓库列表,逗号分隔 */\n repos: string;\n /** 激活状态:0未激活 / 1已激活 */\n activeStatus: 0 | 1;\n /** 创建时间 */\n created_at: string;\n /** 更新时间 */\n updated_at: string;\n /** 提示词 */\n prompt: string;\n /** 跳转URL */\n url: string;\n /** 描述 */\n description: string;\n /** OAuth Client ID */\n oauthClientId?: string;\n /** OAuth 重定向 URL */\n oauthRedirectUrl?: string;\n /** 连接时间 */\n connect_at: string;\n /** 连接状态,0未连接,1已连接 */\n connectStatus: 0 | 1;\n oauthAppName: string;\n}\n\n/**\n * 添加任务请求\n */\nexport interface AddTaskRequest {\n /** 任务ID */\n taskId: string;\n /** 连接器列表 */\n connectors?: Array<{\n name: string;\n repos: string;\n activeStatus?: 0 | 1;\n }>;\n}\n\n/**\n * 添加任务响应\n */\nexport interface AddTaskResponse {\n /** 任务ID */\n taskId: string;\n}\n\n/**\n * 获取任务连接器列表响应\n */\nexport interface ListTaskConnectorResponse {\n /** 连接器列表 */\n connectors: TaskConnector[];\n}\n\n/**\n * 修改任务连接器激活状态请求\n */\nexport interface ModifyTaskConnectorActiveStatusRequest {\n /** 任务ID */\n taskId: string;\n /** 连接器名称 */\n name: string;\n /** 激活状态,0未激活,1已激活 */\n activeStatus: 0 | 1;\n}\n\n/**\n * 修改任务连接器激活状态响应\n */\nexport interface ModifyTaskConnectorActiveStatusResponse {\n /** 任务ID */\n taskId: string;\n}\n\n/**\n * 修改任务连接器仓库请求\n */\nexport interface ModifyTaskConnectorRepoRequest {\n /** 任务ID */\n taskId: string;\n /** 连接器名称 */\n name: string;\n /** 仓库列表 */\n repo: string[];\n}\n\n/**\n * 修改任务连接器仓库响应\n */\nexport interface ModifyTaskConnectorRepoResponse {\n /** 任务ID */\n taskId: string;\n}\n\n/**\n * oauth回调请求参数\n */\nexport interface SaveOauthTokenRequest {\n /** 连接器名称 */\n name: ConnectorType;\n /** 第三方回调code */\n authorizationCode: string;\n}\n\n/**\n * 获取仓库列表请求参数\n */\nexport interface GetRepoListRequest {\n /** 连接器名称 */\n name: ConnectorType;\n}\n\n/**\n * 撤销所有OAuth连接请求参数\n */\nexport interface RevokeAllRequest {\n /** 连接器名称 */\n name: ConnectorType;\n /** 安装ID列表(可选,如果不传则撤销所有) */\n installationIds?: string[];\n}\n\n/**\n * 获取仓库列表响应\n */\nexport interface GetRepoListResponse {\n github_repos?: {\n [key: string | number]: OauthGitHubRepo[]\n }\n gongfeng_repos?: OauthGongFengRepo[]\n cnb_repos?: OauthCNBRepo[]\n}\n\n/**\n * OAuth 用户信息\n */\nexport interface OauthUserInfo {\n /** 头像 URL */\n avatarUrl: string;\n /** 用户名 */\n name: string;\n}\n\n/**\n * 获取 OAuth 用户信息请求参数\n */\nexport interface GetOauthUserRequest {\n /** 连接器名称 */\n name: ConnectorType;\n}\n\n/**\n * 获取 OAuth 用户信息响应\n */\nexport interface GetOauthUserResponse {\n /** 用户信息 */\n user: OauthUserInfo;\n}\n\n/**\n * Figma 文件信息\n */\nexport interface FigmaFileInfo {\n /** 文件名 */\n name: string;\n /** 角色 */\n role: string;\n /** 最后修改时间 */\n lastModified: string;\n /** 编辑器类型 */\n editorType: string;\n /** 缩略图 URL */\n thumbnailUrl: string;\n /** 版本 */\n version: string;\n /** 主文件 Key */\n mainFileKey: string;\n}\n\n/**\n * 获取文件信息请求参数\n */\nexport interface GetFileRequest {\n /** 连接器名称 */\n name: ConnectorType;\n /** 文件 URL */\n url: string;\n}\n\n/**\n * 获取文件信息响应\n */\nexport interface GetFileResponse {\n /** Figma 文件信息 */\n figmaFileInfo: FigmaFileInfo | null;\n}\n\n// ============================================================================\n// Backend Provider 配置\n// ============================================================================\n\n/**\n * Backend Provider 配置选项\n */\nexport interface BackendProviderConfig {\n /** API 基础 URL (例如: https://api.example.com) */\n baseUrl: string;\n /** 认证 Token */\n authToken?: string;\n}\n\n// ============================================================================\n// Checkin 相关类型\n// ============================================================================\n\n/**\n * 签到状态响应\n */\nexport interface CheckinStatusResponse {\n /** 活动是否开启 */\n active: boolean;\n /** 今天是否已签到 */\n today_checked_in: boolean;\n /** 当前连续签到天数 */\n streak_days: number;\n /** 普通日签 credit 数量 */\n daily_credit: number;\n /** 今天签到可获得的 credit 数量 */\n today_credit: number;\n /** 今天是否是连续签到奖励日 */\n is_streak_day: boolean;\n /** 距离下一个连续签到奖励日还需签到天数(0 表示今天就是) */\n next_streak_day: number;\n /** 签到日期列表(yyyy-MM-dd 格式) */\n checkin_dates: string[];\n}\n\n/**\n * 签到结果响应\n */\nexport interface CheckinResultResponse {\n /** 本次签到实际获得的 credit */\n credit: number;\n /** 签到后的连续签到天数 */\n streak_days: number;\n /** 本次签到是否为连续签到奖励日 */\n is_streak_day: boolean;\n}\n\n/**\n * 活动 Banner 响应\n */\nexport interface ActivityBannerResponse {\n /** 活动 ID */\n id: string;\n /** 活动是否开启 */\n active: boolean;\n /** Banner 文案内容 */\n bannerContent: string;\n /** 详情链接 */\n link: string;\n /** 活动优先级 */\n level: number;\n /** 活动开始时间(格式:\"2026-03-20 00:00:00\",不存在则视为已开始) */\n startTime?: string;\n /** 活动结束时间(格式:\"2026-04-20 23:59:59\",不存在则视为永不过期) */\n endTime?: string;\n}\n\n// ============================================================================\n// Backend Provider 接口\n// ============================================================================\n\n/**\n * 企业用户用量信息\n */\nexport interface EnterpriseUsage {\n /** 已使用 credit */\n credit: number;\n /** 周期开始时间 */\n cycleStartTime: string;\n /** 周期结束时间 */\n cycleEndTime: string;\n /** 周期重置时间 */\n cycleResetTime: string;\n /** 限额数量 */\n limitNum: number;\n}\n\n/**\n * IBackendProvider 接口\n *\n * 定义与后端 API 交互的抽象接口\n *\n * 注意:getAgents 和 getModels 方法已废弃并移除,\n * 请使用 IAgentAdapter 中的对应方法\n */\nexport interface IBackendProvider {\n /**\n * 获取当前账号信息\n * @returns Promise<Account | null> 账号信息,未登录时返回 null\n */\n getAccount(): Promise<Account | null>;\n\n /**\n * 获取用户连接器列表\n * @returns Promise<ListUserConnectorResponse | null> 用户连接器列表,失败时返回 null\n */\n getUserConnector(): Promise<ListUserConnectorResponse>;\n\n /**\n * 修改用户连接器连接状态\n * @param request 请求参数\n * @returns Promise<void>\n */\n modifyUserConnectorConnectStatus(request: ModifyUserConnectorConnectStatusRequest): Promise<void>;\n\n /**\n * 修改用户连接器仓库\n * @param request 请求参数\n * @returns Promise<void>\n */\n modifyUserConnectorRepo(request: ModifyUserConnectorRepoRequest): Promise<void>;\n\n /**\n * 修改用户连接器激活状态\n * @param request 请求参数\n * @returns Promise<void>\n */\n modifyUserConnectorActiveStatus(request: ModifyUserConnectorActiveStatusRequest): Promise<void>;\n\n /**\n * 删除用户连接器\n * @param name 连接器名称\n * @returns Promise<void>\n */\n deleteUserConnector(name: ConnectorType): Promise<void>;\n\n /**\n * 添加任务\n * @param request 请求参数\n * @returns Promise<AddTaskResponse>\n */\n addConnectorTask(request: AddTaskRequest): Promise<AddTaskResponse>;\n\n /**\n * 获取任务连接器列表\n * @param taskId 任务ID\n * @returns Promise<ListTaskConnectorResponse>\n */\n getTaskConnector(taskId: string): Promise<ListTaskConnectorResponse>;\n\n /**\n * 修改任务连接器激活状态\n * @param request 请求参数\n * @returns Promise<ModifyTaskConnectorActiveStatusResponse>\n */\n modifyTaskConnectorActiveStatus(request: ModifyTaskConnectorActiveStatusRequest): Promise<ModifyTaskConnectorActiveStatusResponse>;\n\n /**\n * 修改任务连接器仓库\n * @param request 请求参数\n * @returns Promise<ModifyTaskConnectorRepoResponse>\n */\n modifyTaskConnectorRepo(request: ModifyTaskConnectorRepoRequest): Promise<ModifyTaskConnectorRepoResponse>;\n\n /**\n * oauth回调,后端用第三方的code换token的\n */\n saveOauthToken(request: SaveOauthTokenRequest): Promise<void>;\n\n /**\n * 获取OAuth连接器的仓库列表\n * @param request 请求参数\n * @returns Promise<GetRepoListResponse> 仓库列表响应\n */\n getRepoList(request: GetRepoListRequest): Promise<GetRepoListResponse>;\n\n /**\n * 撤销OAuth连接器的所有连接\n * @param request 请求参数\n * @returns Promise<void>\n */\n revokeAll(request: RevokeAllRequest): Promise<void>;\n\n /**\n * 获取 OAuth 用户信息\n * @param request 请求参数\n * @returns Promise<GetOauthUserResponse> 用户信息响应\n */\n getOauthUser(request: GetOauthUserRequest): Promise<GetOauthUserResponse>;\n\n /**\n * 获取文件信息\n * @param request 请求参数\n * @returns Promise<GetFileResponse> 文件信息响应\n */\n getFile(request: GetFileRequest): Promise<GetFileResponse>;\n\n /**\n * 触发登录流程\n * - Web 环境: 跳转到登录页面\n * - IDE 环境: 通过 IPC 通知 IDE 打开登录流程\n */\n login(): Promise<void>;\n\n /**\n * 登出账号\n */\n logout(): Promise<void>;\n\n /**\n * 重新加载窗口(可选,仅 IPC 环境支持)\n * @param params 可选参数,如 locale\n */\n reloadWindow?(params?: { locale?: string }): Promise<void>;\n\n /**\n * Save locale to argv.json without restarting the app (optional, IPC only).\n * The change takes effect on next manual restart.\n * @param params locale to save\n */\n saveLocale?(params: { locale: string }): Promise<void>;\n\n /**\n * 关闭 Agent Manager 面板(可选,仅 IPC 环境支持)\n * 用于 Local 模式下点击 Logo 返回 IDE\n */\n closeAgentManager?(): Promise<void>;\n\n /**\n * 在外部浏览器中打开链接(可选,仅 IPC 环境支持)\n * 用于 Local 模式下打开外部 URL\n * @param url 要打开的 URL\n */\n openExternal?(url: string): Promise<void>;\n\n /**\n * 打开本地文件(可选,仅 IPC 环境支持)\n * 用于 Local 模式下打开本地配置文件\n * @param filePath 要打开的文件路径\n */\n openLocalFile?(filePath: string): Promise<void>;\n\n /**\n * 获取用户级本地自定义模型列表(可选,仅 IPC 环境支持)\n */\n getLocalCustomModels?(): Promise<GetLocalCustomModelsResponse>;\n\n /**\n * 保存用户级本地自定义模型(可选,仅 IPC 环境支持)\n */\n saveLocalCustomModel?(request: SaveLocalCustomModelRequest): Promise<GetLocalCustomModelsResponse>;\n\n /**\n * 删除用户级本地自定义模型(可选,仅 IPC 环境支持)\n */\n deleteLocalCustomModel?(id: string): Promise<GetLocalCustomModelsResponse>;\n\n /**\n * 监听事件(可选,用于 IPC 环境)\n * @param event 事件名称\n * @param callback 回调函数\n * @returns 取消订阅函数\n */\n on?(event: string, callback: (data?: unknown) => void): () => void;\n\n /** 获取企业用户用量信息\n * @param enterpriseId 企业 ID\n * @returns Promise<EnterpriseUsage | null> 企业用户用量信息\n */\n getEnterpriseUsage?(enterpriseId: string): Promise<EnterpriseUsage | null>;\n\n /**\n * 获取账号用量信息(积分/Credits)\n * 实时获取,每次打开菜单时调用,不依赖 getAccount 缓存\n * @returns Promise<Partial<Account> | null> 包含 usageLeft, usageTotal, refreshAt 等字段\n */\n getAccountUsage?(): Promise<Partial<Account> | null>;\n\n /**\n * 获取每日签到状态\n * @returns Promise<CheckinStatusResponse | null> 签到状态,失败时返回 null\n */\n getCheckinStatus?(): Promise<CheckinStatusResponse | null>;\n\n /**\n * 执行每日签到\n * @returns Promise<CheckinResultResponse> 签到结果\n */\n claimDailyCheckin?(): Promise<CheckinResultResponse>;\n\n /**\n * 获取活动 Banner\n * @returns Promise<ActivityBannerResponse | null> 活动 Banner 信息,失败时返回 null\n */\n getActivityBanner?(): Promise<ActivityBannerResponse | null>;\n\n /**\n * 刷新 Token(可选)\n * 通过调用 getAccount 刷新 cookie\n * 适用于 Cloud 场景下页面切换回来时刷新登录态\n * @returns Promise<Account | null> 刷新后的账号信息\n */\n refreshToken?(): Promise<Account | null>;\n\n /**\n * 获取仓库分支列表\n * API 端点: GET /console/as/connector/oauth/{name}/branches\n *\n * @param connector 连接器名称 ('github' | 'gongfeng' | 'cnb')\n * @param params 平台特定的查询参数\n * @param page 页码,从1开始,0表示不分页获取全部\n * @param perPage 每页数量,最大100\n * @returns Promise<OauthBranch[]> 分支列表\n */\n getBranches?(\n connector: OauthConnectorName,\n params: GitHubBranchParams | GongfengBranchParams | CNBBranchParams,\n page?: number,\n perPage?: number\n ): Promise<OauthBranch[]>;\n\n /**\n * 获取仓库列表\n * API 端点: GET /console/as/connector/oauth/{name}/repos\n *\n * @param connector 连接器名称 ('github' | 'gongfeng' | 'cnb')\n * @param page 页码,从1开始,0表示不分页获取全部\n * @param perPage 每页数量,最大100\n * @returns Promise<ListReposResponse> 仓库列表响应\n */\n getRepositories?(\n connector: OauthConnectorName,\n page?: number,\n perPage?: number\n ): Promise<ListReposResponse>;\n\n /**\n * 保存待发送的输入内容到后端(用于跨域登录场景)\n * API 端点: POST /api/v1/code-id\n *\n * @param code 要保存的文本内容\n * @returns Promise<string | null> 返回 codeId,失败返回 null\n */\n savePendingInput?(code: string): Promise<string | null>;\n\n /**\n * 从后端加载待发送的输入内容(用于跨域登录场景)\n * API 端点: GET /api/v1/code?id=xxx\n *\n * @param codeId 内容 ID\n * @returns Promise<string | null> 返回保存的文本内容,失败返回 null\n */\n loadPendingInput?(codeId: string): Promise<string | null>;\n\n // ==================== SkillHub 相关方法 ====================\n\n /**\n * 获取 SkillHub 技能列表(分页)\n * @param params 分页/过滤参数\n * @returns Promise<SkillHubListResponse>\n */\n getSkillHubList?(params?: SkillHubListParams): Promise<SkillHubListResponse>;\n\n /**\n * 获取 SkillHub 分类列表\n * @returns Promise<SkillHubCategoriesResponse>\n */\n getSkillHubCategories?(): Promise<SkillHubCategoriesResponse>;\n\n /**\n * 搜索 SkillHub 技能\n * @param q 搜索关键词\n * @param limit 结果数量限制\n * @returns Promise<SkillHubSearchResponse>\n */\n getSkillHubSearch?(q: string, limit?: number): Promise<SkillHubSearchResponse>;\n\n /**\n * 获取 SkillHub 技能详情\n * @param slug 技能唯一标识\n * @returns Promise<SkillHubDetailResponse>\n */\n getSkillHubDetail?(slug: string): Promise<SkillHubDetailResponse>;\n\n /**\n * 批量检查 SkillHub 技能是否存在\n * @param slugs 技能标识列表\n * @returns Promise<SkillHubExistsResponse>\n */\n getSkillHubExists?(slugs: string[]): Promise<SkillHubExistsResponse>;\n\n /**\n * 上报 SkillHub 技能统计\n * @param slug 技能标识\n * @param inc 增量统计\n */\n reportSkillHubStats?(slug: string, inc: { downloads?: number; installs?: number; stars?: number }): Promise<void>;\n\n /**\n * 安装 SkillHub 技能(下载 zip → 解压到本地)\n * @param slug 技能标识\n * @param version 版本号\n * @param name 原始显示名称(保留大小写)\n * @returns Promise<SkillHubInstallResponse>\n */\n installSkillHubSkill?(slug: string, version?: string, name?: string): Promise<SkillHubInstallResponse>;\n\n /**\n * 获取本地已安装的 SkillHub 技能元信息\n * @returns Promise<SkillHubInstalledMeta[]>\n */\n getSkillHubInstalledMetas?(): Promise<SkillHubInstalledMeta[]>;\n}\n\n// ============================================================================\n// SkillHub 相关类型\n// ============================================================================\n\nexport interface SkillHubSkill {\n slug: string;\n ownerName: string;\n category: string;\n name: string;\n description: string;\n description_zh: string;\n version: string;\n homepage: string;\n tags: string[];\n downloads: number;\n stars: number;\n installs: number;\n updated_at: number;\n score: number;\n /** Optional source marker used in merged search results */\n _source?: 'recommend' | 'skillhub';\n}\n\nexport interface SkillHubListResponse {\n code: number;\n message: string;\n data: {\n total: number;\n skills: SkillHubSkill[];\n };\n}\n\nexport interface SkillHubCategory {\n key: string;\n name: string;\n nameEn: string;\n sortOrder: number;\n active: boolean;\n}\n\nexport interface SkillHubCategoriesResponse {\n items: SkillHubCategory[];\n count: number;\n}\n\nexport interface SkillHubSearchResult {\n score: number;\n slug: string;\n displayName: string;\n summary: string;\n version: string;\n updatedAt: number;\n}\n\nexport interface SkillHubSearchResponse {\n results: SkillHubSearchResult[];\n}\n\nexport interface SkillHubDetailResponse {\n skill: {\n slug: string;\n category: string;\n displayName: string;\n summary: string;\n summary_zh: string;\n tags: Record<string, string>;\n stats: {\n downloads: number;\n stars: number;\n installs: number;\n versions: number;\n comments: number;\n };\n createdAt: number;\n updatedAt: number;\n };\n latestVersion: {\n version: string;\n createdAt: number;\n changelog: string;\n };\n owner: {\n handle: string;\n displayName: string;\n image: string | null;\n };\n}\n\nexport interface SkillHubExistsResponse {\n exists: Record<string, boolean>;\n count: number;\n}\n\nexport interface SkillHubInstallResponse {\n success: boolean;\n skillName: string;\n errorMessage?: string;\n}\n\nexport interface SkillHubInstalledMeta {\n slug: string;\n version: string | null;\n installedAt?: number;\n}\n\nexport type SkillHubSortBy = 'score' | 'downloads' | 'updated_at' | 'installs';\n\nexport interface SkillHubListParams {\n page?: number;\n pageSize?: number;\n sortBy?: SkillHubSortBy;\n order?: 'asc' | 'desc';\n keyword?: string;\n category?: string;\n}\n\n// ============================================================================\n// Support Scenes 相关类型\n// ============================================================================\n\n/**\n * 场景中的插件信息\n * 用于描述场景关联的插件\n */\nexport interface ScenePlugin {\n /** 插件唯一标识 */\n id: number;\n /** 插件名称 */\n name: string;\n /** 插件市场名称 */\n marketplaceName: string;\n}\n\n/**\n * 场景模式类型\n * - coding: 编程相关场景\n * - working: 工作/通用场景\n */\nexport type SupportSceneMode = 'coding' | 'working';\n\n/**\n * 支持的场景信息\n * 用于 Welcome 页面的 QuickActions 快捷操作\n * API 端点: GET /console/as/support/scenes (Web) 或 GET /v2/as/support/scenes (Local)\n */\nexport interface SupportScene {\n /** 场景唯一标识 */\n id: number;\n /** 场景显示名称 */\n name: string;\n /** 场景关联的插件列表 */\n plugins: ScenePlugin[];\n /** 场景对应的 prompt 列表 */\n prompts: string[];\n /** 场景模式类型 */\n mode?: SupportSceneMode;\n}\n\n/**\n * 获取支持场景列表响应\n */\nexport interface GetSupportScenesResponse {\n /** 场景列表 */\n scenes: SupportScene[];\n}\n\n// ============================================================================\n// Plugin Management 相关类型\n// ============================================================================\n\n/**\n * 插件作用域\n * 使用 agent-craft 的 PluginInstallScope 类型\n * 注意: 当前后端 API 只支持 user 和 project,暂不支持 project-local\n */\nexport type PluginScope = 'user' | 'project' | 'project-local' | 'local';\n\n/**\n * 插件操作类型\n */\nexport type PluginOperation = 'enable' | 'disable';\n\n/**\n * 批量插件操作项\n */\nexport interface BatchPluginOperationItem {\n /** 插件名称 */\n readonly pluginName: string;\n /** 市场名称 */\n readonly marketplaceName: string;\n /** 作用域 */\n readonly scope: PluginScope;\n /** 操作类型 */\n readonly operation: PluginOperation;\n}\n\n/**\n * 批量插件操作请求\n */\nexport interface BatchPluginOperationRequest {\n /** 操作项列表 */\n readonly items: BatchPluginOperationItem[];\n}\n\n/**\n * 批量插件操作失败项\n */\nexport interface BatchPluginOperationFailedItem extends BatchPluginOperationItem {\n /** 错误信息 */\n readonly error: string;\n}\n\n/**\n * 批量插件操作结果\n */\nexport interface BatchPluginOperationResult {\n /** 是否全部成功 */\n readonly success: boolean;\n /** 成功的插件列表 */\n readonly succeededPlugins: BatchPluginOperationItem[];\n /** 失败的插件列表 */\n readonly failedPlugins: BatchPluginOperationFailedItem[];\n}\n","/**\n * OAuth Repository Service\n *\n * 封装 OAuth 连接器相关的仓库和分支操作\n */\nimport { httpService } from '../../http';\nimport {\n CNBBranchParams,\n GitHubBranchParams,\n GongfengBranchParams,\n ListBranchesResponse,\n ListReposResponse,\n OauthBranch,\n OauthConnectorName,\n} from './oauth-repository-types';\n\n/**\n * OAuth Repository Service\n *\n * 提供仓库和分支的查询操作\n */\nexport class OAuthRepositoryService {\n /**\n * 获取仓库分支列表\n * API 端点: GET /console/as/connector/oauth/{name}/branches\n *\n * @param connector 连接器名称 ('github' | 'gongfeng' | 'cnb')\n * @param params 平台特定的查询参数\n * @param page 页码,从1开始,0表示不分页获取全部\n * @param perPage 每页数量,最大100\n * @returns Promise<OauthBranch[]> 分支列表\n *\n * @example\n * ```typescript\n * // GitHub\n * const branches = await service.getBranches('github', {\n * owner: 'CodeBuddy-Official-Account',\n * repo: 'CodeBuddyIDE'\n * });\n *\n * // Gongfeng\n * const branches = await service.getBranches('gongfeng', {\n * project_id: '1611499'\n * });\n *\n * // CNB\n * const branches = await service.getBranches('cnb', {\n * repo: 'genie/genie-ide'\n * });\n * ```\n */\n async getBranches(\n connector: OauthConnectorName,\n params: GitHubBranchParams | GongfengBranchParams | CNBBranchParams,\n page: number = 0,\n perPage: number = 100\n ): Promise<OauthBranch[]> {\n try {\n const queryParams = this.buildBranchQueryParams(connector, params, page, perPage);\n const url = `/console/as/connector/oauth/${connector}/branches?${queryParams.toString()}`;\n console.log(`[OAuthRepositoryService] GET ${url}`);\n\n const apiResponse = await httpService.get<{ code: number; data?: ListBranchesResponse }>(url);\n\n if (!apiResponse.data) {\n console.warn(`[OAuthRepositoryService] No data in branches response for ${connector}`);\n return [];\n }\n\n const branches = apiResponse.data.branches || [];\n console.log(`[OAuthRepositoryService] Retrieved ${branches.length} branches from ${connector}`);\n return branches;\n } catch (error) {\n console.error(`[OAuthRepositoryService] Failed to get branches from ${connector}:`, error);\n throw error;\n }\n }\n\n /**\n * 获取仓库列表\n * API 端点: GET /console/as/connector/oauth/{name}/repos\n *\n * Note: 由于工蜂原生支持的 Search 能力会匹配 path/name/description 部分,\n * 且不支持定制,不满足产品要求(只按 name 匹配),因此前端拉取全量数据后做筛选。\n *\n * @param connector 连接器名称 ('github' | 'gongfeng' | 'cnb')\n * @param page 页码,从1开始,0表示不分页获取全部\n * - GitHub 只支持全量数据,必须传 0\n * - 工蜂和 CNB 依据前端逻辑而定\n * @param perPage 每页数量,最大100\n * @returns Promise<ListReposResponse> 仓库列表响应\n *\n * @example\n * ```typescript\n * // GitHub - 必须传 page=0 获取全量数据\n * const response = await service.getRepositories('github', 0, 100);\n * // response.github_repos 是 map: installation_id => repo[]\n *\n * // Gongfeng\n * const response = await service.getRepositories('gongfeng', 0, 100);\n * // response.gongfeng_repos 是数组\n *\n * // CNB\n * const response = await service.getRepositories('cnb', 0, 100);\n * // response.cnb_repos 是数组\n * ```\n */\n async getRepositories(\n connector: OauthConnectorName,\n page: number = 0,\n perPage: number = 100\n ): Promise<ListReposResponse> {\n try {\n const queryParams = new URLSearchParams();\n queryParams.append('page', String(page));\n queryParams.append('per_page', String(Math.min(perPage, 100)));\n\n const url = `/console/as/connector/oauth/${connector}/repos?${queryParams.toString()}`;\n console.log(`[OAuthRepositoryService] GET ${url}`);\n\n const apiResponse = await httpService.get<{ code: number; data?: ListReposResponse }>(url);\n\n if (!apiResponse.data) {\n console.warn(`[OAuthRepositoryService] No data in repos response for ${connector}`);\n return {};\n }\n\n const response = apiResponse.data;\n this.logRepositoryCounts(response);\n\n return response;\n } catch (error) {\n console.error(`[OAuthRepositoryService] Failed to get repos from ${connector}:`, error);\n throw error;\n }\n }\n\n /**\n * 构建分支查询参数\n */\n private buildBranchQueryParams(\n connector: OauthConnectorName,\n params: GitHubBranchParams | GongfengBranchParams | CNBBranchParams,\n page: number,\n perPage: number\n ): URLSearchParams {\n const queryParams = new URLSearchParams();\n\n queryParams.append('page', String(page));\n queryParams.append('per_page', String(Math.min(perPage, 100)));\n\n if (connector === 'github') {\n const githubParams = params as GitHubBranchParams;\n if (!githubParams.owner || !githubParams.repo) {\n throw new Error('GitHub requires owner and repo parameters');\n }\n queryParams.append('owner', githubParams.owner);\n queryParams.append('repo', githubParams.repo);\n } else if (connector === 'gongfeng') {\n const gongfengParams = params as GongfengBranchParams;\n if (!gongfengParams.project_id) {\n throw new Error('Gongfeng requires project_id parameter');\n }\n queryParams.append('project_id', gongfengParams.project_id);\n } else if (connector === 'cnb') {\n const cnbParams = params as CNBBranchParams;\n if (!cnbParams.repo) {\n throw new Error('CNB requires repo parameter');\n }\n queryParams.append('repo', cnbParams.repo);\n } else {\n throw new Error(`Unknown connector: ${connector}`);\n }\n\n return queryParams;\n }\n\n /**\n * 记录仓库数量日志\n */\n private logRepositoryCounts(response: ListReposResponse): void {\n if (response.github_repos) {\n const totalCount = Object.values(response.github_repos).reduce(\n (sum, repos) => sum + repos.length,\n 0\n );\n console.log(`[OAuthRepositoryService] Retrieved ${totalCount} GitHub repos across ${Object.keys(response.github_repos).length} installations`);\n }\n if (response.gongfeng_repos) {\n console.log(`[OAuthRepositoryService] Retrieved ${response.gongfeng_repos.length} Gongfeng repos`);\n }\n if (response.cnb_repos) {\n console.log(`[OAuthRepositoryService] Retrieved ${response.cnb_repos.length} CNB repos`);\n }\n }\n}\n\n/**\n * OAuth Repository Service 单例实例\n */\nexport const oauthRepositoryService = new OAuthRepositoryService();\n","/**\n * Backend Provider 实现\n *\n * 封装与后端 API 的 HTTP 通信\n */\n\nimport { accountService } from '../account';\nimport { httpService } from '../http';\nimport { oauthRepositoryService } from './service';\nimport {\n Account,\n AccountPlan,\n AccountStatus,\n AddTaskRequest,\n AddTaskResponse,\n BackendProviderConfig,\n BatchPluginOperationRequest,\n BatchPluginOperationResult,\n CheckinResultResponse,\n CheckinStatusResponse,\n CNBBranchParams,\n CommodityCode,\n EditionDisplayType,\n EnterpriseUsage,\n GetFileRequest,\n GetFileResponse,\n GetOauthUserRequest,\n GetOauthUserResponse,\n GetRepoListRequest,\n GetRepoListResponse,\n GitHubBranchParams,\n GongfengBranchParams,\n IBackendProvider,\n ListReposResponse,\n ListTaskConnectorResponse,\n ListUserConnectorResponse,\n ModifyTaskConnectorActiveStatusRequest,\n ModifyTaskConnectorActiveStatusResponse,\n ModifyTaskConnectorRepoRequest,\n ModifyTaskConnectorRepoResponse,\n ModifyUserConnectorActiveStatusRequest,\n ModifyUserConnectorConnectStatusRequest,\n ModifyUserConnectorRepoRequest,\n OauthBranch,\n OauthConnectorName,\n RevokeAllRequest,\n SaveOauthTokenRequest,\n SkillHubCategoriesResponse,\n SkillHubDetailResponse,\n SkillHubExistsResponse,\n SkillHubInstalledMeta,\n SkillHubInstallResponse,\n SkillHubListParams,\n SkillHubListResponse,\n SkillHubSearchResponse,\n UserResource,\n} from './types';\n\n/**\n * 判断当前账号是否是 SSO 账号\n * 通过 account.accountType === 'sso' 来判断,这种不行,因为未登录之前account 为空\n */\n// const isSSODomain = () => {\n// const { hostname } = window.location;\n// return hostname.includes('.sso.copilot') ||\n// hostname.includes('sso.codebuddy.cn') ||\n// hostname.includes('.sso.copilot-staging') ||\n// hostname.includes('.staging-sso.codebuddy.cn');\n// };\n\n/**\n * 根据路径获取完整 URL\n * - SSO 账号需要跳转到对应的预发/生产域名\n * - 非 SSO 账号直接使用当前域名\n * @param path 路径,如 '/login'、'/logout'、'/home' 等\n * @returns 完整的 URL 地址\n */\nexport const getFullUrl = (path: string): string => `${window.location.origin}${path}`;\n\n/** 获取当前域名的账号选择页面 URL */\nconst getSelectAccountUrl = () => `${window.location.origin}/login/select`;\n\n/** localStorage 中存储选中账号 ID 的 key */\nexport const SELECTED_ACCOUNT_KEY = 'CODEBUDDY_IDE_SELECTED_ACCOUNT_ID';\n\n/**\n * 套餐代码对应的 i18n key 映射\n */\nconst CommodityCodeText: Record<CommodityCode, string> = {\n [CommodityCode.free]: 'plan.codebuddyFreePlan',\n [CommodityCode.proMon]: 'plan.codebuddyProPlanMonthly',\n [CommodityCode.proMonPlus]: 'plan.codebuddyProPlanMonthly',\n [CommodityCode.gift]: 'plan.codebuddyProPlanTrial',\n [CommodityCode.activity]: 'plan.codebuddyGrowthPlan',\n [CommodityCode.proYear]: 'plan.codebuddyProPlanYearly',\n [CommodityCode.freeMon]: 'plan.codebuddyProPlanDaily',\n [CommodityCode.extra]: 'plan.codebuddyCreditPackage',\n};\n\n/**\n * 获取套餐名称的 i18n key\n */\nconst getPackageName = (packageCode: CommodityCode): string => CommodityCodeText[packageCode] || '';\n\n/**\n * Backend Provider 实现类\n *\n * 职责:\n * - 触发登录/登出流程\n * - 获取 account 后自动同步到 accountService\n * - 使用单例 httpService 进行所有 HTTP 请求\n *\n * 注意:getAgents 和 getModels 方法已废弃并移除,\n * 请使用 IAgentAdapter 中的对应方法\n */\nexport class BackendProvider implements IBackendProvider {\n constructor(config: BackendProviderConfig) {\n // 设置 httpService 配置\n httpService.setBaseURL(config.baseUrl);\n\n if (config.authToken) {\n httpService.setAuthToken(config.authToken);\n }\n\n // 注册 401 回调,先尝试刷新 token,失败后再执行登出流程\n // 注意:此回调返回 Promise,HttpService 会等待它完成后再重试请求\n httpService.onUnauthorized(() => this.handleUnauthorized());\n }\n\n /**\n * 处理 401 未授权错误\n * 先尝试刷新 token,失败后再执行登出流程\n *\n * @throws 如果 token 刷新失败,抛出错误通知 HttpService 不要重试\n */\n protected async handleUnauthorized(): Promise<void> {\n console.log('[BackendProvider] User unauthorized (401), attempting token refresh first');\n\n try {\n // 先尝试刷新 token\n const refreshedAccount = await this.refreshToken();\n if (refreshedAccount) {\n console.log('[BackendProvider] Token refresh successful after 401, user still logged in');\n return; // 刷新成功,HttpService 会自动重试原请求\n }\n // 刷新返回 null,视为失败\n throw new Error('Token refresh returned null');\n } catch (error) {\n console.error('[BackendProvider] Token refresh failed after 401:', error);\n\n // 刷新失败,执行完整的登出流程\n console.log('[BackendProvider] Token refresh failed, triggering logout');\n this.logout().catch(logoutError => {\n console.error('[BackendProvider] Logout failed in 401 handler:', logoutError);\n });\n\n // 抛出错误,通知 HttpService 刷新失败,不要重试\n throw error;\n }\n }\n\n /**\n * 获取当前账号信息\n * API 端点: GET /console/accounts (返回账号列表)\n *\n * 逻辑:\n * 1. 从 localStorage 读取 CODEBUDDY_IDE_SELECTED_ACCOUNT_ID\n * 2. 根据 CODEBUDDY_IDE_SELECTED_ACCOUNT_ID 找到对应账号\n * - personal 类型: 用 uid 匹配\n * - 其他类型: 用 enterpriseId 匹配\n * 3. 如果没有选中的账号,跳转到账号选择页面\n * 4. 获取套餐信息并合并到账号中\n * 5. 同步到 accountService\n */\n async getAccount(): Promise<Account | null> {\n try {\n const result = await httpService.get<{ data: { accounts: Account[] } }>(\n '/console/accounts'\n );\n\n const accounts: Account[] = result.data?.accounts || [];\n if (!accounts || accounts.length === 0) {\n accountService.setAccount(null);\n return null;\n }\n\n // 从 localStorage 读取选中的账号 ID\n const selectedAccountId = localStorage.getItem(SELECTED_ACCOUNT_KEY);\n let selectedAccount: Account | undefined;\n\n if (selectedAccountId) {\n // 查找选中的账号\n selectedAccount = accounts.find(account => {\n // personal 类型用 uid 匹配,其他类型用 enterpriseId 匹配\n if (account.type === 'personal') {\n return account.uid === selectedAccountId;\n }\n return account.enterpriseId === selectedAccountId;\n });\n\n if (selectedAccount) {\n const account = await this.enrichAccountWithUsage(selectedAccount);\n accountService.setAccount(account);\n return account;\n }\n }\n\n // 如果只有一个账号,自动选中它\n if (accounts.length === 1) {\n selectedAccount = accounts[0];\n // 保存选中的账号 ID 到 localStorage\n const accountId = selectedAccount.type === 'personal'\n ? selectedAccount.uid\n : selectedAccount.enterpriseId;\n if (accountId) {\n localStorage.setItem(SELECTED_ACCOUNT_KEY, accountId);\n }\n const account = await this.enrichAccountWithUsage(selectedAccount);\n console.log('account (auto-selected)', account);\n accountService.setAccount(account);\n return account;\n }\n\n // 多个账号但没有选中的,跳转到账号选择页面\n const redirectUrl = encodeURIComponent(window.location.href);\n window.location.href = `${getSelectAccountUrl()}?platform=agents&state=0&redirect_uri=${redirectUrl}`;\n accountService.setAccount(null);\n return null;\n } catch (error) {\n console.error('[BackendProvider] getAccount failed:', error);\n accountService.setAccount(null);\n return null;\n }\n }\n\n /**\n * 获取用户连接器列表\n * API 端点: GET /console/as/connector/user/\n */\n async getUserConnector(): Promise<ListUserConnectorResponse> {\n const result = await httpService.get<any>('/console/as/connector/user/');\n\n if (result.code === 0) {\n const { connectors } = result.data;\n return {\n connectors: connectors.map((connector: any) => ({\n ...connector,\n connectStatus: connector.connect_status,\n activeStatus: connector.active_status,\n displayName: connector.display_name,\n oauthClientId: connector.oauth_client_id,\n oauthRedirectUrl: connector.oauth_redirect_url,\n oauthAppName: connector.oauth_app_name\n }))\n };\n }\n\n throw result;\n }\n\n /**\n * 修改用户连接器连接状态\n * API 端点: PATCH /console/as/connector/user/:name/connect_status\n */\n async modifyUserConnectorConnectStatus(request: ModifyUserConnectorConnectStatusRequest): Promise<void> {\n // 构造请求体,将驼峰命名转换为下划线命名\n const body: Record<string, any> = {\n name: request.name,\n connect_status: request.connectStatus,\n };\n\n if (request.activeStatus !== undefined) {\n body.active_status = request.activeStatus;\n }\n\n if (request.repos !== undefined) {\n body.repos = request.repos;\n }\n\n const result = await httpService.patch<any>(\n `/console/as/connector/user/${request.name}/connect_status`,\n body\n );\n\n if (result.code === 0) {\n return;\n }\n\n throw result;\n }\n\n /**\n * 修改用户连接器仓库\n * API 端点: PATCH /console/as/connector/user/:name/repo/\n */\n async modifyUserConnectorRepo(request: ModifyUserConnectorRepoRequest): Promise<void> {\n const body: Record<string, any> = {\n name: request.name,\n };\n\n if (request.repo !== undefined) {\n body.repo = request.repo;\n }\n\n const result = await httpService.patch<any>(\n `/console/as/connector/user/${request.name}/repo`,\n body\n );\n\n if (result.code === 0) {\n return;\n }\n\n throw result;\n }\n\n /**\n * 修改用户连接器激活状态\n * API 端点: PATCH /console/as/connector/user/:name/active_status\n */\n async modifyUserConnectorActiveStatus(request: ModifyUserConnectorActiveStatusRequest): Promise<void> {\n const body = {\n name: request.name,\n active_status: request.activeStatus,\n };\n\n const result = await httpService.patch<any>(\n `/console/as/connector/user/${request.name}/active_status`,\n body\n );\n\n if (result.code === 0) {\n return;\n }\n\n throw result;\n }\n\n /**\n * 删除用户连接器\n * API 端点: DELETE /console/as/connector/user/:name/\n */\n async deleteUserConnector(name: 'github' | 'gongfeng'): Promise<void> {\n const result = await httpService.delete<any>(\n `/console/as/connector/user/${name}/`\n );\n\n if (result.code === 0) {\n return;\n }\n\n throw result;\n }\n\n /**\n * 添加任务\n * API 端点: POST /console/as/connector/task/\n */\n async addConnectorTask(request: AddTaskRequest): Promise<AddTaskResponse> {\n // 构造请求体,将驼峰命名转换为下划线命名\n const body: Record<string, any> = {\n task_id: request.taskId,\n };\n\n if (request.connectors !== undefined) {\n body.connectors = request.connectors.map(c => ({\n name: c.name,\n repos: c.repos,\n active_status: c.activeStatus,\n }));\n }\n\n const result = await httpService.post<any>(\n '/console/as/connector/task/',\n body\n );\n\n if (result.code === 0) {\n return {\n taskId: result.data?.task_id || request.taskId,\n };\n }\n\n throw result;\n }\n\n /**\n * 获取任务连接器列表\n * API 端点: GET /console/as/connector/task/:taskid\n */\n async getTaskConnector(taskId: string): Promise<ListTaskConnectorResponse> {\n const result = await httpService.get<any>(\n `/console/as/connector/task/${taskId}`\n );\n\n if (result.code === 0) {\n const { connectors } = result.data;\n return {\n connectors: (connectors || []).map((connector: any) => ({\n ...connector,\n activeStatus: connector.active_status,\n connectStatus: connector.connect_status,\n displayName: connector.display_name,\n oauthClientId: connector.oauth_client_id,\n oauthRedirectUrl: connector.oauth_redirect_url,\n oauthAppName: connector.oauth_app_name\n }))\n };\n }\n\n throw result;\n }\n\n /**\n * 修改任务连接器激活状态\n * API 端点: PATCH /console/as/connector/task/:taskid/active_status\n */\n async modifyTaskConnectorActiveStatus(request: ModifyTaskConnectorActiveStatusRequest): Promise<ModifyTaskConnectorActiveStatusResponse> {\n const body = {\n task_id: request.taskId,\n name: request.name,\n active_status: request.activeStatus,\n };\n\n const result = await httpService.patch<any>(\n `/console/as/connector/task/${request.taskId}/active_status`,\n body\n );\n\n if (result.code === 0) {\n return {\n taskId: result.data?.task_id || request.taskId,\n };\n }\n\n throw result;\n }\n\n /**\n * 修改任务连接器仓库\n * API 端点: PATCH /console/as/connector/task/:taskid/repo\n */\n async modifyTaskConnectorRepo(request: ModifyTaskConnectorRepoRequest): Promise<ModifyTaskConnectorRepoResponse> {\n const body = {\n task_id: request.taskId,\n name: request.name,\n repo: request.repo,\n };\n\n const result = await httpService.patch<any>(\n `/console/as/connector/task/${request.taskId}/repo`,\n body\n );\n\n if (result.code === 0) {\n return {\n taskId: result.data?.task_id || request.taskId,\n };\n }\n\n throw result;\n }\n\n /**\n * 根据账号类型获取用量信息并合并到账号中\n * - 企业用户:调用 getEnterpriseUsage 获取月度限额\n * - 个人用户:调用 getCurrentPlan 获取套餐信息\n */\n private async enrichAccountWithUsage(selectedAccount: Account): Promise<Account> {\n const isEnterpriseUser = !!(selectedAccount.enterpriseId && selectedAccount.enterpriseId !== '');\n\n try {\n if (isEnterpriseUser) {\n // 企业用户:获取企业用量\n const enterpriseUsage = await this.getEnterpriseUsage(selectedAccount.enterpriseId!);\n const editionType = this.getEditionDisplayType(selectedAccount.type, false);\n\n if (enterpriseUsage) {\n const usageLeft = (enterpriseUsage.limitNum - enterpriseUsage.credit).toString();\n const usageTotal = enterpriseUsage.limitNum.toString();\n return {\n ...selectedAccount,\n editionType,\n usageLeft,\n usageTotal,\n refreshAt: enterpriseUsage.cycleResetTime ? new Date(enterpriseUsage.cycleResetTime).getTime() : undefined,\n };\n }\n return { ...selectedAccount, editionType };\n } else {\n // 个人用户:获取套餐信息\n const plan = await this.getCurrentPlan();\n const editionType = this.getEditionDisplayType(selectedAccount.type, plan.isPro);\n console.log('account', { ...selectedAccount, ...plan, editionType });\n return { ...selectedAccount, ...plan, editionType };\n }\n } catch (error) {\n console.error('[BackendProvider] enrichAccountWithUsage failed:', error);\n return { ...selectedAccount };\n }\n }\n\n /**\n * 获取当前套餐信息\n * 从计量计费接口获取用户的套餐信息\n * API: POST /billing/meter/get-user-resource\n */\n private async getCurrentPlan(): Promise<AccountPlan> {\n // 默认套餐信息\n const defaultPlan: AccountPlan = {\n isPro: false,\n expireAt: 0,\n renewFlag: 0,\n PackageCode: undefined,\n name: '',\n };\n\n try {\n // 构造请求参数\n const now = new Date();\n const futureDate = new Date(now.getTime() + 101 * 365 * 24 * 60 * 60 * 1000);\n const formatDate = (d: Date) => {\n const pad = (n: number) => n.toString().padStart(2, '0');\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;\n };\n\n const body = {\n PageNumber: 1,\n // PageSize、用户购买包的数量、暂定 100 上限。\n PageSize: 100,\n ProductCode: 'p_tcaca',\n Status: [AccountStatus.valid, AccountStatus.usedUp], // 0-有效, 3-已用完\n PackageEndTimeRangeBegin: formatDate(now),\n PackageEndTimeRangeEnd: formatDate(futureDate),\n };\n\n const result = await httpService.post<any>(\n '/billing/meter/get-user-resource',\n body\n );\n\n // 响应格式: { Response: { Data: { Accounts: [...] } } }\n const resources = (result?.data?.Response?.Data?.Accounts || []) as UserResource[];\n\n if (!resources || resources.length === 0) {\n return defaultPlan;\n }\n\n // 解析时间字符串或时间戳为毫秒时间戳\n const parseTime = (time: string | number | undefined): number => {\n if (!time) { return 0; }\n return new Date(time).getTime();\n };\n\n // 每日刷新的套餐类型\n const dailyCredits = [CommodityCode.free];\n\n // 转换所有套餐为 PlanResource 列表\n const planResources = resources.map(r => {\n const isDaily = dailyCredits.includes(r.PackageCode);\n const endTime = isDaily ? r.CycleEndTime : r.DeductionEndTime;\n\n // 刷新时间是截止时间 + 1s\n const refreshAt = parseTime(r.CycleEndTime) + 1000;\n\n return {\n id: r.ResourceId,\n name: isDaily ? 'plan.addonCredits' : getPackageName(r.PackageCode),\n packageCode: r.PackageCode,\n isDaily,\n total: Number(r.CycleCapacitySizePrecise) || 0,\n used: Math.max(0, Number(r.CycleCapacitySizePrecise) - Number(r.CycleCapacityRemainPrecise)) || 0,\n left: Number(r.CycleCapacityRemainPrecise) || 0,\n expireAt: parseTime(endTime),\n refreshAt: isDaily ? undefined : refreshAt,\n };\n }).sort((a, b) => {\n const getPriority = (code: CommodityCode) => {\n // 付费套餐优先\n if ([CommodityCode.proMon, CommodityCode.proMonPlus, CommodityCode.proYear, CommodityCode.freeMon, CommodityCode.extra].includes(code)) {\n return 1;\n }\n // 赠送/试用套餐次之\n if ([CommodityCode.gift, CommodityCode.activity].includes(code)) {\n return 2;\n }\n // 免费版最后\n if ([CommodityCode.free].includes(code)) {\n return 3;\n }\n return 4;\n };\n return getPriority(a.packageCode) - getPriority(b.packageCode);\n });\n\n // 查找 Pro 套餐(proYear 或 proMon)\n const proPlan = resources.find((r: any) =>\n r.PackageCode === CommodityCode.proYear || r.PackageCode === CommodityCode.proMon || r.PackageCode === CommodityCode.proMonPlus\n );\n\n // 查找试用套餐\n const trialPlan = resources.find((r: any) => r.PackageCode === CommodityCode.gift || r.PackageCode === CommodityCode.freeMon);\n\n const activePlan = proPlan || trialPlan;\n\n // 计算所有套餐的总量、已用和剩余\n const totalUsageLeft = planResources.reduce((sum, r) => sum + r.left, 0);\n const totalUsageTotal = planResources.reduce((sum, r) => sum + r.total, 0);\n const totalUsageUsed = planResources.reduce((sum, r) => sum + r.used, 0);\n\n if (activePlan) {\n return {\n isPro: !!proPlan,\n // 试用套餐\n isTria: trialPlan ? [AccountStatus.valid, AccountStatus.usedUp].includes(trialPlan.Status) : false,\n expireAt: parseTime(activePlan.DeductionEndTime || activePlan.ExpiredTime || activePlan.CycleEndTime),\n refreshAt: parseTime(activePlan.CycleEndTime),\n renewFlag: Number(activePlan.AutoRenewFlag) === 1 ? 1 : 0,\n PackageCode: activePlan.PackageCode,\n name: getPackageName(activePlan.PackageCode),\n usageTotal: String(totalUsageTotal),\n usageUsed: String(totalUsageUsed),\n usageLeft: String(totalUsageLeft),\n resources: planResources,\n };\n }\n\n return {\n ...defaultPlan,\n usageTotal: String(totalUsageTotal),\n usageUsed: String(totalUsageUsed),\n usageLeft: String(totalUsageLeft),\n resources: planResources\n };\n } catch (error) {\n console.error('[BackendProvider] getCurrentPlan error:', error);\n return defaultPlan;\n }\n }\n\n /**\n * 通过回调code,换token\n * @param request\n * @returns\n */\n async saveOauthToken(request: SaveOauthTokenRequest) {\n const body = {\n authorization_code: request.authorizationCode,\n };\n\n const result = await httpService.post<any>(\n `/console/as/connector/oauth/${request.name}/connect`,\n body\n );\n\n if (result.code === 0) {\n return;\n }\n\n throw result;\n }\n\n /**\n * 获取OAuth连接器的仓库列表\n */\n async getRepoList(request: GetRepoListRequest): Promise<GetRepoListResponse> {\n const result = await httpService.get<any>(\n `/console/as/connector/oauth/${request.name}/repos`\n );\n\n if (result.code === 0) {\n return result.data;\n }\n\n throw result;\n }\n\n /**\n * 撤销OAuth连接器的所有连接\n */\n async revokeAll(request: RevokeAllRequest): Promise<void> {\n const installationIds = request?.installationIds ?? [];\n\n const body: { name: string; installation_ids?: string[] } = {\n name: request.name,\n };\n\n if (installationIds) {\n body.installation_ids = installationIds;\n }\n\n const result = await httpService.post<any>(\n `/console/as/connector/oauth/${request.name}/revokeall`,\n body\n );\n\n if (result.code === 0) {\n return;\n }\n\n throw result;\n }\n\n /**\n * 获取 OAuth 用户信息\n * API 端点: GET /console/as/connector/oauth/:name/oauthuser\n */\n async getOauthUser(request: GetOauthUserRequest): Promise<GetOauthUserResponse> {\n const result = await httpService.get<any>(\n `/console/as/connector/oauth/${request.name}/oauthuser`\n );\n\n if (result.code === 0) {\n const data = result.data || {};\n return {\n user: {\n avatarUrl: data.user?.avatar_url || '',\n name: data.user?.name || '',\n }\n };\n }\n\n throw result;\n }\n\n /**\n * 获取文件信息\n * API 端点: GET /console/as/connector/oauth/:name/file\n */\n async getFile(request: GetFileRequest): Promise<GetFileResponse> {\n const body: { url: string; } = {\n url: request.url,\n };\n\n const result = await httpService.post<any>(\n `/console/as/connector/oauth/${request.name}/file`,\n body\n );\n\n if (result.code === 0) {\n const data = result.data || {};\n const figmaFileInfo = data.figma_file_info;\n return {\n figmaFileInfo: figmaFileInfo ? {\n name: figmaFileInfo.name || '',\n role: figmaFileInfo.role || '',\n lastModified: figmaFileInfo.last_modified || '',\n editorType: figmaFileInfo.editor_type || '',\n thumbnailUrl: figmaFileInfo.thumbnail_url || '',\n version: figmaFileInfo.version || '',\n mainFileKey: figmaFileInfo.main_file_key || '',\n } : null\n };\n }\n\n throw result;\n }\n\n /**\n * 根据账号类型和 Pro 状态计算版本展示类型\n * - personal + isPro = 'pro'\n * - personal + !isPro = 'free'\n * - ultimate = 'ultimate' (旗舰版/团队版)\n * - exclusive = 'exclusive' (专享版/企业版)\n */\n private getEditionDisplayType(type: string, isPro: boolean): EditionDisplayType {\n if (type === 'personal') {\n return isPro ? 'pro' : 'free';\n }\n if (type === 'ultimate') {\n return 'ultimate';\n }\n if (type === 'exclusive') {\n return 'exclusive';\n }\n // 默认返回 free\n return 'free';\n }\n\n /**\n * 触发登录流程\n * Web 环境: 跳转到登录页面\n */\n async login(): Promise<void> {\n // 获取当前页面 URL 作为回调地址\n // todo 支持弹窗和跳转、弹窗优化点 别让主页面 reload\n const redirectUrl = encodeURIComponent(window.location.href);\n window.location.href = `${getFullUrl('/login')}?platform=agents&state=0&redirect_uri=${redirectUrl}`;\n }\n\n /**\n * 登出账号\n *\n * 策略:\n * - IOA 企业:用 iframe 走 SSO/SAML SLO 登出链路(涉及跨域重定向),通过轮询 iframe URL 变化检测完成\n * - 非 IOA 企业:直接用 httpService 请求 /console/logout,速度快\n */\n async logout(): Promise<void> {\n const account = accountService.getAccount();\n const isIOA = account?.enterpriseId\n && ['esoikz80kd8g', 'etahzsqej0n4'].includes(account.enterpriseId);\n\n if (isIOA) {\n await this.logoutViaIframe();\n } else {\n await this.logoutViaHttp();\n }\n\n // 清理本地状态\n localStorage.removeItem(SELECTED_ACCOUNT_KEY);\n accountService.clearAccount();\n }\n\n /**\n * IOA 企业登出:通过 iframe 走 SSO/SAML SLO 登出链路\n * 轮询 iframe URL 变化检测完成,兜底超时 5 秒\n */\n private async logoutViaIframe(): Promise<void> {\n const baseURL = httpService.getAxiosInstance().defaults.baseURL;\n const logoutUrl = `${baseURL}/console/logout`;\n\n try {\n await new Promise<void>(resolve => {\n const iframe = document.createElement('iframe');\n iframe.style.cssText = 'position:fixed;top:-9999px;left:-9999px;width:1px;height:1px;border:none;';\n iframe.src = logoutUrl;\n\n // eslint-disable-next-line prefer-const\n let pollTimer: ReturnType<typeof setInterval>;\n let settled = false;\n\n const done = () => {\n if (settled) { return; }\n settled = true;\n clearInterval(pollTimer);\n clearTimeout(timeout);\n if (iframe.parentNode) {\n iframe.parentNode.removeChild(iframe);\n }\n resolve();\n };\n\n // 轮询检测 iframe URL 变化:\n // 初始同域 → 跨域(抛异常,说明重定向进行中)→ 回到同域(链路完成)\n let wasRedirecting = false;\n pollTimer = setInterval(() => {\n try {\n const href = iframe.contentWindow?.location?.href;\n if (wasRedirecting && href) {\n // 从跨域回到同域,登出链路已完成\n done();\n }\n } catch {\n // 跨域阶段,读取 location 会抛 SecurityError\n wasRedirecting = true;\n }\n }, 100);\n\n // 兜底超时 5 秒\n const timeout = setTimeout(done, 5000);\n iframe.onerror = done;\n\n document.body.appendChild(iframe);\n });\n } catch (error) {\n console.error('[BackendProvider] logout via iframe failed:', error);\n }\n }\n\n /**\n * 非 IOA 企业登出:直接 HTTP 请求 /console/logout\n */\n private async logoutViaHttp(): Promise<void> {\n try {\n await httpService.get('/console/logout');\n } catch (error) {\n console.error('[BackendProvider] logout via http failed:', error);\n }\n }\n\n /**\n * 批量切换插件状态\n * Web 环境不支持此功能\n */\n async batchTogglePlugins(request: BatchPluginOperationRequest): Promise<BatchPluginOperationResult> {\n console.warn('[BackendProvider] batchTogglePlugins is not supported in web environment');\n return {\n success: false,\n succeededPlugins: [],\n failedPlugins: request.items.map(item => ({\n ...item,\n error: 'Plugin batch toggle is not supported in web environment'\n }))\n };\n }\n\n /**\n * 获取企业用户用量信息\n * API: POST /billing/meter/get-enterprise-user-usage\n */\n async getEnterpriseUsage(enterpriseId: string): Promise<EnterpriseUsage | null> {\n try {\n const result = await httpService.post<any>(\n '/billing/meter/get-enterprise-user-usage',\n {},\n {\n headers: {\n 'X-Enterprise-Id': enterpriseId,\n },\n }\n );\n\n // 响应格式: { code, data, msg } 或直接是 EnterpriseUsage\n const usageData = result?.data?.data || result?.data || result;\n\n if (usageData && typeof usageData.limitNum === 'number') {\n return usageData as EnterpriseUsage;\n }\n\n return null;\n } catch (error) {\n console.error('[BackendProvider] getEnterpriseUsage error:', error);\n return null;\n }\n }\n\n /**\n * 刷新 Token\n * 通过调用 getAccount 刷新 cookie,适用于 Cloud 场景下页面切换回来时刷新登录态\n * @returns Promise<Account | null> 刷新后的账号信息\n */\n async refreshToken(): Promise<Account | null> {\n console.log('[BackendProvider] Refreshing token...');\n try {\n const account = await this.getAccount();\n console.log('[BackendProvider] Token refreshed, account:', account?.uid);\n return account;\n } catch (error) {\n console.error('[BackendProvider] refreshToken failed:', error);\n return null;\n }\n }\n\n /**\n * 获取仓库分支列表\n * API 端点: GET /console/as/connector/oauth/{name}/branches\n *\n * @param connector 连接器名称 ('github' | 'gongfeng' | 'cnb')\n * @param params 平台特定的查询参数\n * @param page 页码,从1开始,0表示不分页获取全部\n * @param perPage 每页数量,最大100\n * @returns Promise<OauthBranch[]> 分支列表\n */\n async getBranches(\n connector: OauthConnectorName,\n params: GitHubBranchParams | GongfengBranchParams | CNBBranchParams,\n page: number = 0,\n perPage: number = 100\n ): Promise<OauthBranch[]> {\n return oauthRepositoryService.getBranches(connector, params, page, perPage);\n }\n\n /**\n * 获取仓库列表\n * API 端点: GET /console/as/connector/oauth/{name}/repos\n *\n * Note: 由于工蜂原生支持的 Search 能力会匹配 path/name/description 部分,\n * 且不支持定制,不满足产品要求(只按 name 匹配),因此前端拉取全量数据后做筛选。\n *\n * @param connector 连接器名称 ('github' | 'gongfeng' | 'cnb')\n * @param page 页码,从1开始,0表示不分页获取全部\n * - GitHub 只支持全量数据,必须传 0\n * - 工蜂和 CNB 依据前端逻辑而定\n * @param perPage 每页数量,最大100\n * @returns Promise<ListReposResponse> 仓库列表响应\n */\n async getRepositories(\n connector: OauthConnectorName,\n page: number = 0,\n perPage: number = 100\n ): Promise<ListReposResponse> {\n return oauthRepositoryService.getRepositories(connector, page, perPage);\n }\n\n /**\n * 保存待发送的输入内容到后端\n * API 端点: POST /api/v1/code-id\n */\n async savePendingInput(code: string): Promise<string | null> {\n try {\n const result = await httpService.post<any>('/api/v1/code-id', { code });\n return result?.codeId || result?.data?.codeId || null;\n } catch (e) {\n console.warn('[BackendProvider] savePendingInput failed:', e);\n return null;\n }\n }\n\n /**\n * 从后端加载待发送的输入内容\n * API 端点: GET /api/v1/code?id=xxx\n */\n async loadPendingInput(codeId: string): Promise<string | null> {\n try {\n const result = await httpService.get<any>(`/api/v1/code?id=${encodeURIComponent(codeId)}`);\n return result?.code || result?.data?.code || null;\n } catch (e) {\n console.warn('[BackendProvider] loadPendingInput failed:', e);\n return null;\n }\n }\n\n /**\n * 获取每日签到状态\n * API 端点: POST /billing/meter/checkin-status\n */\n async getCheckinStatus(): Promise<CheckinStatusResponse | null> {\n try {\n const result = await httpService.post<any>('/billing/meter/checkin-status', {});\n if (result?.code === 0 && result?.data) {\n return result.data as CheckinStatusResponse;\n }\n return null;\n } catch (error) {\n console.error('[BackendProvider] getCheckinStatus failed:', error);\n return null;\n }\n }\n\n /**\n * 执行每日签到\n * API 端点: POST /billing/meter/daily-checkin\n */\n async claimDailyCheckin(): Promise<CheckinResultResponse> {\n const result = await httpService.post<any>('/billing/meter/daily-checkin', {});\n if (result?.code === 0 && result?.data) {\n return result.data as CheckinResultResponse;\n }\n throw new Error(result?.msg || 'Checkin failed');\n }\n\n // ==================== SkillHub 方法 (Cloud 模式: 直接 fetch) ====================\n\n private static readonly SKILLHUB_BASE_URL = 'https://lightmake.site';\n private static readonly SKILLHUB_FETCH_TIMEOUT = 10_000;\n\n private async skillHubFetch(url: string, init?: RequestInit): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), BackendProvider.SKILLHUB_FETCH_TIMEOUT);\n try {\n return await fetch(url, { ...init, signal: controller.signal });\n } finally {\n clearTimeout(timer);\n }\n }\n\n async getSkillHubList(params: SkillHubListParams = {}): Promise<SkillHubListResponse> {\n const qs = new URLSearchParams();\n if (params.page) { qs.set('page', String(params.page)); }\n if (params.pageSize) { qs.set('pageSize', String(params.pageSize)); }\n if (params.sortBy) { qs.set('sortBy', params.sortBy); }\n if (params.order) { qs.set('order', params.order); }\n if (params.keyword) { qs.set('keyword', params.keyword); }\n if (params.category) { qs.set('category', params.category); }\n const res = await this.skillHubFetch(`${BackendProvider.SKILLHUB_BASE_URL}/api/skills?${qs.toString()}`);\n if (!res.ok) { throw new Error(`SkillHub list: ${res.status}`); }\n return res.json();\n }\n\n async getSkillHubCategories(): Promise<SkillHubCategoriesResponse> {\n const res = await this.skillHubFetch(`${BackendProvider.SKILLHUB_BASE_URL}/api/v1/categories`);\n if (!res.ok) { throw new Error(`SkillHub categories: ${res.status}`); }\n return res.json();\n }\n\n async getSkillHubSearch(q: string, limit = 20): Promise<SkillHubSearchResponse> {\n const qs = new URLSearchParams({ q, limit: String(limit) });\n const res = await this.skillHubFetch(`${BackendProvider.SKILLHUB_BASE_URL}/api/v1/search?${qs.toString()}`);\n if (!res.ok) { throw new Error(`SkillHub search: ${res.status}`); }\n return res.json();\n }\n\n async getSkillHubDetail(slug: string): Promise<SkillHubDetailResponse> {\n const res = await this.skillHubFetch(`${BackendProvider.SKILLHUB_BASE_URL}/api/v1/skills/${encodeURIComponent(slug)}`);\n if (!res.ok) { throw new Error(`SkillHub detail: ${res.status}`); }\n return res.json();\n }\n\n async getSkillHubExists(slugs: string[]): Promise<SkillHubExistsResponse> {\n const res = await this.skillHubFetch(`${BackendProvider.SKILLHUB_BASE_URL}/api/v1/skills/exists`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ slugs }),\n });\n if (!res.ok) { throw new Error(`SkillHub exists: ${res.status}`); }\n return res.json();\n }\n\n async reportSkillHubStats(slug: string, inc: { downloads?: number; installs?: number; stars?: number }): Promise<void> {\n try {\n await this.skillHubFetch(`${BackendProvider.SKILLHUB_BASE_URL}/api/v1/skills/${encodeURIComponent(slug)}/stats/inc`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(inc),\n });\n } catch {\n // fire-and-forget: stats reporting failure is non-critical\n }\n }\n\n async installSkillHubSkill(_slug: string, _version?: string, _name?: string): Promise<SkillHubInstallResponse> {\n // Web/cloud fallback: cannot install via main process\n return { success: false, skillName: _slug, errorMessage: 'SkillHub install requires IDE mode (no IPC channel available)' };\n }\n\n async getSkillHubInstalledMetas(): Promise<SkillHubInstalledMeta[]> {\n // Web/cloud fallback: no local file system access\n return [];\n }\n}\n\n/**\n * 创建 BackendProvider 实例\n */\nexport function createBackendProvider(config: BackendProviderConfig): BackendProvider {\n return new BackendProvider(config);\n}\n","/**\n * IPC Backend Provider 实现\n *\n * 通过 IWidgetChannel 与后端通信\n * 使用统一的消息格式: { type: 'backend', requestId, params: { type, params } }\n */\n\nimport { accountService } from '../account';\nimport { IWidgetChannel } from '../common';\nimport type { Account, ActivityBannerResponse, AddTaskRequest, AddTaskResponse, BatchPluginOperationRequest, BatchPluginOperationResult, CheckinResultResponse, CheckinStatusResponse, GetFileRequest, GetFileResponse, GetLocalCustomModelsResponse, GetOauthUserRequest, GetOauthUserResponse, GetRepoListRequest, GetRepoListResponse, IBackendProvider, ListTaskConnectorResponse, ListUserConnectorResponse, ModifyTaskConnectorActiveStatusRequest, ModifyTaskConnectorActiveStatusResponse, ModifyTaskConnectorRepoRequest, ModifyTaskConnectorRepoResponse, ModifyUserConnectorActiveStatusRequest, ModifyUserConnectorConnectStatusRequest, ModifyUserConnectorRepoRequest, RevokeAllRequest, SaveLocalCustomModelRequest, SaveOauthTokenRequest, SkillHubCategoriesResponse, SkillHubDetailResponse, SkillHubExistsResponse, SkillHubInstalledMeta, SkillHubInstallResponse, SkillHubListParams, SkillHubListResponse, SkillHubSearchResponse, SupportScene } from './types';\n\n/**\n * IPC Backend Provider 配置\n */\nexport interface IPCBackendProviderConfig {\n /** Widget Channel 接口 */\n channel: IWidgetChannel;\n /** 是否启用调试日志 */\n debug?: boolean;\n /** 请求超时时间(毫秒,默认 30000) */\n timeoutMs?: number;\n}\n\n/**\n * Backend 请求类型常量\n */\nconst BACKEND_REQUEST_TYPES = {\n LOGIN: 'backend:login',\n LOGOUT: 'backend:logout',\n GET_ACCOUNT: 'backend:get-account',\n GET_USER_CONNECTOR: 'backend:get-user-connector',\n MODIFY_USER_CONNECTOR_CONNECT_STATUS: 'backend:modify-user-connector-connect-status',\n MODIFY_USER_CONNECTOR_REPO: 'backend:modify-user-connector-repo',\n MODIFY_USER_CONNECTOR_ACTIVE_STATUS: 'backend:modify-user-connector-active-status',\n DELETE_USER_CONNECTOR: 'backend:delete-user-connector',\n ADD_CONNECTOR_TASK: 'backend:add-connector-task',\n GET_TASK_CONNECTOR: 'backend:get-task-connector',\n MODIFY_TASK_CONNECTOR_ACTIVE_STATUS: 'backend:modify-task-connector-active-status',\n MODIFY_TASK_CONNECTOR_REPO: 'backend:modify-task-connector-repo',\n GET_OAUTH_USER: 'backend:get-oauth-user',\n SAVE_OAUTH_TOKEN: 'backend:save-oauth-token',\n GET_REPO_LIST: 'backend:get-repo-list',\n REVOKE_ALL: 'backend:revoke-all',\n GET_FILE: 'backend:get-file',\n RELOAD_WINDOW: 'backend:reload-window',\n SAVE_LOCALE: 'backend:save-locale',\n CLOSE_AGENT_MANAGER: 'backend:close-agent-manager',\n OPEN_EXTERNAL: 'backend:open-external',\n OPEN_LOCAL_FILE: 'backend:open-local-file',\n GET_LOCAL_CUSTOM_MODELS: 'backend:get-local-custom-models',\n SAVE_LOCAL_CUSTOM_MODEL: 'backend:save-local-custom-model',\n DELETE_LOCAL_CUSTOM_MODEL: 'backend:delete-local-custom-model',\n BATCH_TOGGLE_PLUGINS: 'backend:batch-toggle-plugins',\n GET_SUPPORT_SCENES: 'backend:get-support-scenes',\n GET_ACCOUNT_USAGE: 'backend:get-account-usage',\n GET_CHECKIN_STATUS: 'backend:get-checkin-status',\n CLAIM_DAILY_CHECKIN: 'backend:claim-daily-checkin',\n GET_ACTIVITY_BANNER: 'backend:get-activity-banner',\n // SkillHub\n SKILLHUB_LIST: 'backend:skillhub-list',\n SKILLHUB_CATEGORIES: 'backend:skillhub-categories',\n SKILLHUB_SEARCH: 'backend:skillhub-search',\n SKILLHUB_DETAIL: 'backend:skillhub-detail',\n SKILLHUB_DOWNLOAD_URL: 'backend:skillhub-download-url',\n SKILLHUB_EXISTS: 'backend:skillhub-exists',\n SKILLHUB_REPORT_STATS: 'backend:skillhub-report-stats',\n} as const;\n\n/**\n * 生成唯一请求 ID\n */\nfunction generateRequestId(): string {\n return `req-${Date.now()}-${Math.random().toString(36).slice(2)}`;\n}\n\n/**\n * IPC Backend Provider 实现类\n *\n * 通过 IWidgetChannel 与后端通信\n */\nexport class IPCBackendProvider implements IBackendProvider {\n private readonly channel: IWidgetChannel;\n private readonly debug: boolean;\n private readonly timeoutMs: number;\n\n constructor(config: IPCBackendProviderConfig) {\n this.channel = config.channel;\n this.debug = config.debug ?? false;\n this.timeoutMs = config.timeoutMs ?? 30000;\n\n this.log('Initialized with IWidgetChannel');\n // 设置会话变化监听(IDE 环境下 Extension Host 推送的认证状态变化)\n this.setupSessionChangeListener();\n }\n\n /**\n * 设置会话变化监听器\n * 监听来自 Extension Host (BackendBridgeService) 推送的 auth:session-changed 事件\n * 并更新本地 accountService\n */\n private setupSessionChangeListener(): void {\n this.log('Setting up session change listener');\n\n this.channel.on('auth:session-changed', (data: any) => {\n this.log('Received auth:session-changed event from Extension Host:', data);\n\n const account = data?.account || null;\n\n // 更新本地 accountService\n accountService.setAccount(account);\n\n this.log('Updated accountService with new session', {\n hasAccount: !!account,\n accountNickname: account?.nickname,\n });\n });\n\n this.log('Session change listener setup complete');\n }\n\n /**\n * 发送统一格式的后端请求\n * @param requestType 请求类型\n * @param params 请求参数\n * @returns 响应数据\n */\n private async sendBackendRequest<T>(requestType: string, params?: unknown): Promise<T> {\n const message = {\n type: 'backend',\n requestId: generateRequestId(),\n params: {\n type: requestType,\n params: params,\n },\n };\n\n this.log('Sending backend request:', message);\n\n const response = await this.channel.callMethod('__backend__', message, this.timeoutMs);\n\n this.log('Received response:', response);\n\n // 检查响应中是否有错误\n if (response?.error) {\n throw new Error(response.error);\n }\n\n // 从响应的 data 字段中提取实际数据\n return (response?.data !== undefined ? response.data : response) as T;\n }\n\n /**\n * 获取当前账号信息\n * IDE 环境: 通过 IPC 获取账号信息,并同步到 accountService\n */\n async getAccount(): Promise<Account | null> {\n this.log('Getting account via IPC');\n const startTime = performance.now();\n\n try {\n const account = await this.sendBackendRequest<Account | null>(\n BACKEND_REQUEST_TYPES.GET_ACCOUNT\n );\n this.log(`getAccount IPC completed in ${(performance.now() - startTime).toFixed(0)}ms`);\n // 同步到 accountService\n accountService.setAccount(account);\n return account;\n } catch (error) {\n this.log(`getAccount IPC failed after ${(performance.now() - startTime).toFixed(0)}ms:`, error);\n accountService.setAccount(null);\n return null;\n }\n }\n\n /**\n * 获取用户连接器列表\n * IDE 环境: 通过 IPC 获取用户连接器列表\n */\n async getUserConnector(): Promise<ListUserConnectorResponse> {\n this.log('Getting user connector via IPC');\n\n try {\n return await this.sendBackendRequest<ListUserConnectorResponse>(\n BACKEND_REQUEST_TYPES.GET_USER_CONNECTOR\n );\n } catch (error) {\n this.log('Get user connector failed:', error);\n throw error;\n }\n }\n\n /**\n * 修改用户连接器连接状态\n * IDE 环境: 通过 IPC 修改用户连接器连接状态\n */\n async modifyUserConnectorConnectStatus(request: ModifyUserConnectorConnectStatusRequest): Promise<void> {\n this.log('Modifying user connector connect status via IPC:', request);\n\n try {\n await this.sendBackendRequest<void>(\n BACKEND_REQUEST_TYPES.MODIFY_USER_CONNECTOR_CONNECT_STATUS,\n request\n );\n } catch (error) {\n this.log('Modify user connector connect status failed:', error);\n throw error;\n }\n }\n\n /**\n * 修改用户连接器仓库\n * IDE 环境: 通过 IPC 修改用户连接器仓库\n */\n async modifyUserConnectorRepo(request: ModifyUserConnectorRepoRequest): Promise<void> {\n this.log('Modifying user connector repo via IPC:', request);\n\n try {\n await this.sendBackendRequest<void>(\n BACKEND_REQUEST_TYPES.MODIFY_USER_CONNECTOR_REPO,\n request\n );\n } catch (error) {\n this.log('Modify user connector repo failed:', error);\n throw error;\n }\n }\n\n /**\n * 修改用户连接器激活状态\n * IDE 环境: 通过 IPC 修改用户连接器激活状态\n */\n async modifyUserConnectorActiveStatus(request: ModifyUserConnectorActiveStatusRequest): Promise<void> {\n this.log('Modifying user connector active status via IPC:', request);\n\n try {\n await this.sendBackendRequest<void>(\n BACKEND_REQUEST_TYPES.MODIFY_USER_CONNECTOR_ACTIVE_STATUS,\n request\n );\n } catch (error) {\n this.log('Modify user connector active status failed:', error);\n throw error;\n }\n }\n\n /**\n * 删除用户连接器\n * IDE 环境: 通过 IPC 删除用户连接器\n */\n async deleteUserConnector(name: 'github' | 'gongfeng'): Promise<void> {\n this.log('Deleting user connector via IPC:', name);\n\n try {\n await this.sendBackendRequest<void>(\n BACKEND_REQUEST_TYPES.DELETE_USER_CONNECTOR,\n { name }\n );\n } catch (error) {\n this.log('Delete user connector failed:', error);\n throw error;\n }\n }\n\n /**\n * 添加任务\n * IDE 环境: 通过 IPC 添加任务\n */\n async addConnectorTask(request: AddTaskRequest): Promise<AddTaskResponse> {\n this.log('Adding connector task via IPC:', request);\n\n try {\n return await this.sendBackendRequest<AddTaskResponse>(\n BACKEND_REQUEST_TYPES.ADD_CONNECTOR_TASK,\n request\n );\n } catch (error) {\n this.log('Add task failed:', error);\n throw error;\n }\n }\n\n /**\n * 获取任务连接器列表\n * IDE 环境: 通过 IPC 获取任务连接器列表\n */\n async getTaskConnector(taskId: string): Promise<ListTaskConnectorResponse> {\n this.log('Getting task connector via IPC:', taskId);\n\n try {\n return await this.sendBackendRequest<ListTaskConnectorResponse>(\n BACKEND_REQUEST_TYPES.GET_TASK_CONNECTOR,\n { taskId }\n );\n } catch (error) {\n this.log('Get task connector failed:', error);\n throw error;\n }\n }\n\n /**\n * 修改任务连接器激活状态\n * IDE 环境: 通过 IPC 修改任务连接器激活状态\n */\n async modifyTaskConnectorActiveStatus(request: ModifyTaskConnectorActiveStatusRequest): Promise<ModifyTaskConnectorActiveStatusResponse> {\n this.log('Modifying task connector active status via IPC:', request);\n\n try {\n return await this.sendBackendRequest<ModifyTaskConnectorActiveStatusResponse>(\n BACKEND_REQUEST_TYPES.MODIFY_TASK_CONNECTOR_ACTIVE_STATUS,\n request\n );\n } catch (error) {\n this.log('Modify task connector active status failed:', error);\n throw error;\n }\n }\n\n /**\n * 修改任务连接器仓库\n * IDE 环境: 通过 IPC 修改任务连接器仓库\n */\n async modifyTaskConnectorRepo(request: ModifyTaskConnectorRepoRequest): Promise<ModifyTaskConnectorRepoResponse> {\n this.log('Modifying task connector repo via IPC:', request);\n\n try {\n return await this.sendBackendRequest<ModifyTaskConnectorRepoResponse>(\n BACKEND_REQUEST_TYPES.MODIFY_TASK_CONNECTOR_REPO,\n request\n );\n } catch (error) {\n this.log('Modify task connector repo failed:', error);\n throw error;\n }\n }\n\n /**\n * 获取 OAuth 用户信息\n * IDE 环境: 通过 IPC 获取 OAuth 用户信息\n */\n async getOauthUser(request: GetOauthUserRequest): Promise<GetOauthUserResponse> {\n this.log('Getting OAuth user via IPC:', request);\n\n try {\n return await this.sendBackendRequest<GetOauthUserResponse>(\n BACKEND_REQUEST_TYPES.GET_OAUTH_USER,\n request\n );\n } catch (error) {\n this.log('Get OAuth user failed:', error);\n throw error;\n }\n }\n\n /**\n * 通过回调code,换token\n * IDE 环境: 通过 IPC 保存 OAuth Token\n */\n async saveOauthToken(request: SaveOauthTokenRequest): Promise<void> {\n this.log('Saving OAuth token via IPC:', request);\n\n try {\n await this.sendBackendRequest<void>(\n BACKEND_REQUEST_TYPES.SAVE_OAUTH_TOKEN,\n request\n );\n } catch (error) {\n this.log('Save OAuth token failed:', error);\n throw error;\n }\n }\n\n /**\n * 获取OAuth连接器的仓库列表\n * IDE 环境: 通过 IPC 获取仓库列表\n */\n async getRepoList(request: GetRepoListRequest): Promise<GetRepoListResponse> {\n this.log('Getting repo list via IPC:', request);\n\n try {\n return await this.sendBackendRequest<GetRepoListResponse>(\n BACKEND_REQUEST_TYPES.GET_REPO_LIST,\n request\n );\n } catch (error) {\n this.log('Get repo list failed:', error);\n throw error;\n }\n }\n\n /**\n * 撤销OAuth连接器的所有连接\n * IDE 环境: 通过 IPC 撤销所有连接\n */\n async revokeAll(request: RevokeAllRequest): Promise<void> {\n this.log('Revoking all connections via IPC:', request);\n\n try {\n await this.sendBackendRequest<void>(\n BACKEND_REQUEST_TYPES.REVOKE_ALL,\n request\n );\n } catch (error) {\n this.log('Revoke all connections failed:', error);\n throw error;\n }\n }\n\n /**\n * 获取文件信息\n * IDE 环境: 通过 IPC 获取文件信息\n */\n async getFile(request: GetFileRequest): Promise<GetFileResponse> {\n this.log('Getting file via IPC:', request);\n\n try {\n return await this.sendBackendRequest<GetFileResponse>(\n BACKEND_REQUEST_TYPES.GET_FILE,\n request\n );\n } catch (error) {\n this.log('Get file failed:', error);\n throw error;\n }\n }\n\n /**\n * 触发登录流程\n * IDE 环境: 通过 IPC 通知 IDE 打开登录流程\n */\n async login(): Promise<void> {\n this.log('Triggering login via IPC');\n\n try {\n await this.sendBackendRequest<void>(BACKEND_REQUEST_TYPES.LOGIN);\n } catch (error) {\n this.log('Login request failed:', error);\n throw error;\n }\n }\n\n /**\n * 登出账号\n * IDE 环境: 通过 IPC 通知 IDE 登出\n */\n async logout(): Promise<void> {\n this.log('Triggering logout via IPC');\n\n try {\n await this.sendBackendRequest<void>(BACKEND_REQUEST_TYPES.LOGOUT);\n // 清空 accountService\n accountService.clearAccount();\n } catch (error) {\n this.log('Logout request failed:', error);\n throw error;\n }\n }\n\n /**\n * 重新加载窗口\n * IDE 环境: 通过 IPC 通知 IDE 重新加载窗口(用于应用语言设置等)\n * @param params 可选参数,如 locale\n */\n async reloadWindow(params?: { locale?: string }): Promise<void> {\n this.log('Triggering reload window via IPC', params);\n\n try {\n await this.sendBackendRequest<void>(BACKEND_REQUEST_TYPES.RELOAD_WINDOW, params);\n } catch (error) {\n this.log('Reload window request failed:', error);\n throw error;\n }\n }\n\n /**\n * Save locale to argv.json without restarting the app.\n * The change takes effect on next manual restart.\n * @param params locale to save\n */\n async saveLocale(params: { locale: string }): Promise<void> {\n this.log('Saving locale to argv.json via IPC', params);\n\n try {\n await this.sendBackendRequest<void>(BACKEND_REQUEST_TYPES.SAVE_LOCALE, params);\n } catch (error) {\n this.log('Save locale request failed:', error);\n throw error;\n }\n }\n\n /**\n * 关闭 Agent Manager 面板\n * IDE 环境: 通过 IPC 通知 IDE 关闭 Agent Manager(用于返回 IDE)\n */\n async closeAgentManager(): Promise<void> {\n this.log('Triggering close agent manager via IPC');\n\n try {\n await this.sendBackendRequest<void>(BACKEND_REQUEST_TYPES.CLOSE_AGENT_MANAGER);\n } catch (error) {\n this.log('Close agent manager request failed:', error);\n throw error;\n }\n }\n\n /**\n * 在外部浏览器中打开链接\n * IDE 环境: 通过 IPC 通知 IDE 使用 vscode.env.openExternal 打开 URL\n * @param url 要打开的 URL\n */\n async openExternal(url: string): Promise<void> {\n this.log('Opening external URL via IPC:', url);\n\n try {\n await this.sendBackendRequest<void>(BACKEND_REQUEST_TYPES.OPEN_EXTERNAL, { url });\n } catch (error) {\n this.log('Open external request failed:', error);\n throw error;\n }\n }\n\n /**\n * 打开本地文件\n * IDE 环境: 通过 IPC 通知 IDE 打开本地配置文件\n * @param filePath 要打开的文件路径\n */\n async openLocalFile(filePath: string): Promise<void> {\n this.log('Opening local file via IPC:', filePath);\n\n try {\n const opened = await this.sendBackendRequest<boolean>(BACKEND_REQUEST_TYPES.OPEN_LOCAL_FILE, { filePath });\n if (!opened) {\n throw new Error(`Failed to open local file: ${filePath}`);\n }\n } catch (error) {\n this.log('Open local file request failed:', error);\n throw error;\n }\n }\n\n /**\n * 获取用户级本地自定义模型\n */\n async getLocalCustomModels(): Promise<GetLocalCustomModelsResponse> {\n this.log('Getting local custom models via IPC');\n\n return await this.sendBackendRequest<GetLocalCustomModelsResponse>(\n BACKEND_REQUEST_TYPES.GET_LOCAL_CUSTOM_MODELS\n );\n }\n\n /**\n * 保存用户级本地自定义模型\n */\n async saveLocalCustomModel(request: SaveLocalCustomModelRequest): Promise<GetLocalCustomModelsResponse> {\n this.log('Saving local custom model via IPC:', request);\n\n return await this.sendBackendRequest<GetLocalCustomModelsResponse>(\n BACKEND_REQUEST_TYPES.SAVE_LOCAL_CUSTOM_MODEL,\n request\n );\n }\n\n /**\n * 删除用户级本地自定义模型\n */\n async deleteLocalCustomModel(id: string): Promise<GetLocalCustomModelsResponse> {\n this.log('Deleting local custom model via IPC:', id);\n\n return await this.sendBackendRequest<GetLocalCustomModelsResponse>(\n BACKEND_REQUEST_TYPES.DELETE_LOCAL_CUSTOM_MODEL,\n { id }\n );\n }\n\n /**\n * 批量切换插件状态\n * IDE 环境: 通过 IPC 调用 Extension Host 的 PluginService\n */\n async batchTogglePlugins(request: BatchPluginOperationRequest): Promise<BatchPluginOperationResult> {\n this.log('Batch toggling plugins via IPC:', request);\n\n try {\n return await this.sendBackendRequest<BatchPluginOperationResult>(\n BACKEND_REQUEST_TYPES.BATCH_TOGGLE_PLUGINS,\n request\n );\n } catch (error) {\n this.log('Batch toggle plugins failed:', error);\n throw error;\n }\n }\n\n /**\n * 获取支持的场景列表\n * IDE 环境: 通过 IPC 调用后端 API\n * 用于 Welcome 页面的 QuickActions 快捷操作\n *\n * 调用链:\n * 1. agent-ui: IPCBackendProvider.getSupportScenes()\n * 2. Extension Host: BackendBridgeService.handleGetSupportScenes()\n * 3. Backend API: GET /v2/as/support/scenes\n * 4. 返回 SupportScene[] 数据给 agent-ui\n */\n async getSupportScenes(): Promise<SupportScene[]> {\n this.log('Getting support scenes via IPC');\n\n try {\n const result = await this.sendBackendRequest<{ scenes: SupportScene[] }>(\n BACKEND_REQUEST_TYPES.GET_SUPPORT_SCENES,\n {}\n );\n return result?.scenes || [];\n } catch (error) {\n this.log('Get support scenes failed:', error);\n return [];\n }\n }\n\n /**\n * 获取账号用量信息(积分/Credits)\n * IDE 环境: 通过 IPC 实时获取用量信息,每次打开菜单时调用\n *\n * 调用链:\n * 1. agent-ui: IPCBackendProvider.getAccountUsage()\n * 2. Agent Manager renderer: BackendService.getAccountUsage()\n * 3. Main Process: codebuddy:getAccountUsage IPC handler\n * 4. 返回 { usageLeft, usageTotal, editionType, refreshAt } 等字段\n */\n async getAccountUsage(): Promise<Partial<Account> | null> {\n this.log('Getting account usage via IPC');\n\n try {\n const usage = await this.sendBackendRequest<Partial<Account> | null>(\n BACKEND_REQUEST_TYPES.GET_ACCOUNT_USAGE\n );\n return usage;\n } catch (error) {\n this.log('Get account usage failed:', error);\n return null;\n }\n }\n\n /**\n * 获取每日签到状态\n * IDE 环境: 通过 IPC 获取签到状态\n */\n async getCheckinStatus(): Promise<CheckinStatusResponse | null> {\n this.log('Getting checkin status via IPC');\n\n try {\n return await this.sendBackendRequest<CheckinStatusResponse | null>(\n BACKEND_REQUEST_TYPES.GET_CHECKIN_STATUS\n );\n } catch (error) {\n this.log('Get checkin status failed:', error);\n return null;\n }\n }\n\n /**\n * 执行每日签到\n * IDE 环境: 通过 IPC 执行签到\n */\n async claimDailyCheckin(): Promise<CheckinResultResponse> {\n this.log('Claiming daily checkin via IPC');\n\n try {\n return await this.sendBackendRequest<CheckinResultResponse>(\n BACKEND_REQUEST_TYPES.CLAIM_DAILY_CHECKIN\n );\n } catch (error) {\n this.log('Claim daily checkin failed:', error);\n throw error;\n }\n }\n\n /**\n * 获取活动 Banner\n * IDE 环境: 通过 IPC 获取活动 Banner\n */\n async getActivityBanner(): Promise<ActivityBannerResponse | null> {\n this.log('Getting activity banner via IPC');\n\n try {\n return await this.sendBackendRequest<ActivityBannerResponse | null>(\n BACKEND_REQUEST_TYPES.GET_ACTIVITY_BANNER\n );\n } catch (error) {\n this.log('Get activity banner failed:', error);\n return null;\n }\n }\n\n // ==================== SkillHub 方法 ====================\n\n /**\n * 获取 SkillHub 技能列表\n * IDE 环境: 通过 IPC 获取技能列表\n */\n async getSkillHubList(params?: SkillHubListParams): Promise<SkillHubListResponse> {\n this.log('Getting SkillHub list via IPC', params);\n\n try {\n return await this.sendBackendRequest<SkillHubListResponse>(\n BACKEND_REQUEST_TYPES.SKILLHUB_LIST,\n params\n );\n } catch (error) {\n this.log('Get SkillHub list failed:', error);\n throw error;\n }\n }\n\n /**\n * 获取 SkillHub 分类列表\n * IDE 环境: 通过 IPC 获取分类列表\n */\n async getSkillHubCategories(): Promise<SkillHubCategoriesResponse> {\n this.log('Getting SkillHub categories via IPC');\n\n try {\n return await this.sendBackendRequest<SkillHubCategoriesResponse>(\n BACKEND_REQUEST_TYPES.SKILLHUB_CATEGORIES\n );\n } catch (error) {\n this.log('Get SkillHub categories failed:', error);\n throw error;\n }\n }\n\n /**\n * 搜索 SkillHub 技能\n * IDE 环境: 通过 IPC 搜索技能\n */\n async getSkillHubSearch(q: string, limit = 20): Promise<SkillHubSearchResponse> {\n this.log('Searching SkillHub via IPC', { q, limit });\n\n try {\n return await this.sendBackendRequest<SkillHubSearchResponse>(\n BACKEND_REQUEST_TYPES.SKILLHUB_SEARCH,\n { q, limit }\n );\n } catch (error) {\n this.log('SkillHub search failed:', error);\n throw error;\n }\n }\n\n /**\n * 获取 SkillHub 技能详情\n * IDE 环境: 通过 IPC 获取技能详情\n */\n async getSkillHubDetail(slug: string): Promise<SkillHubDetailResponse> {\n this.log('Getting SkillHub detail via IPC', { slug });\n\n try {\n return await this.sendBackendRequest<SkillHubDetailResponse>(\n BACKEND_REQUEST_TYPES.SKILLHUB_DETAIL,\n { slug }\n );\n } catch (error) {\n this.log('Get SkillHub detail failed:', error);\n throw error;\n }\n }\n\n /**\n * 批量检查 SkillHub 技能是否存在\n * IDE 环境: 通过 IPC 检查技能是否存在\n */\n async getSkillHubExists(slugs: string[]): Promise<SkillHubExistsResponse> {\n this.log('Checking SkillHub exists via IPC', { slugs });\n\n try {\n return await this.sendBackendRequest<SkillHubExistsResponse>(\n BACKEND_REQUEST_TYPES.SKILLHUB_EXISTS,\n { slugs }\n );\n } catch (error) {\n this.log('SkillHub exists check failed:', error);\n throw error;\n }\n }\n\n /**\n * 上报 SkillHub 技能统计\n * IDE 环境: 通过 IPC 上报统计\n */\n async reportSkillHubStats(slug: string, inc: { downloads?: number; installs?: number; stars?: number }): Promise<void> {\n this.log('Reporting SkillHub stats via IPC', { slug, inc });\n\n try {\n await this.sendBackendRequest<void>(\n BACKEND_REQUEST_TYPES.SKILLHUB_REPORT_STATS,\n { slug, inc }\n );\n } catch (error) {\n this.log('Report SkillHub stats failed:', error);\n // fire-and-forget: stats reporting failure is non-critical\n }\n }\n\n /**\n * 安装 SkillHub 技能\n * IDE 环境: 通过 IPC 安装技能(下载 zip → 解压到本地)\n */\n async installSkillHubSkill(slug: string, version?: string, name?: string): Promise<SkillHubInstallResponse> {\n this.log('Installing SkillHub skill via IPC', { slug, version, name });\n\n try {\n return await this.sendBackendRequest<SkillHubInstallResponse>(\n 'backend:skillhub-install',\n { slug, version, name }\n );\n } catch (error) {\n this.log('Install SkillHub skill failed:', error);\n throw error;\n }\n }\n\n /**\n * 获取本地已安装的 SkillHub 技能元信息\n * IDE 环境: 通过 IPC 获取元信息\n */\n async getSkillHubInstalledMetas(): Promise<SkillHubInstalledMeta[]> {\n this.log('Getting SkillHub installed metas via IPC');\n\n try {\n return await this.sendBackendRequest<SkillHubInstalledMeta[]>(\n 'backend:skillhub-installed-metas'\n );\n } catch (error) {\n this.log('Get SkillHub installed metas failed:', error);\n return [];\n }\n }\n\n /**\n * 调试日志\n */\n private log(...args: unknown[]): void {\n if (this.debug) {\n console.log('[IPCBackendProvider]', ...args);\n }\n }\n}\n\n/**\n * 创建 IPCBackendProvider 实例\n */\nexport function createIPCBackendProvider(config: IPCBackendProviderConfig): IPCBackendProvider {\n return new IPCBackendProvider(config);\n}\n","/**\n * Legacy HTTP Service - Proxy-free httpService singleton\n *\n * 降级处理清单:\n * - Proxy → 直接使用 HttpService.getInstance() 获取单例\n * 原始代码使用 `new Proxy({} as HttpService, { get(target, prop) { ... } })`\n * 实现懒加载单例。小程序不支持 Proxy,改用直接获取单例的方式。\n *\n * 注意:此降级会失去 Proxy 的惰性初始化特性,httpService 在首次导入时即初始化。\n * 在实践中这不是问题,因为 httpService 总是在应用启动时就被使用。\n */\n\nimport { HttpService } from '@genie/agent-provider';\n\n// ============================================\n// [降级] Proxy → 直接单例\n// ============================================\n\n/**\n * 降级版 httpService 单例\n *\n * 原始版本使用 Proxy 实现懒加载:\n * ```typescript\n * // 原始 (使用 Proxy):\n * export const httpService = new Proxy({} as HttpService, {\n * get(target, prop) {\n * const instance = HttpService.getInstance();\n * return (instance as any)[prop];\n * },\n * });\n * ```\n *\n * 降级版本直接获取单例:\n * ```typescript\n * // 降级 (无 Proxy):\n * export const httpService = HttpService.getInstance();\n * ```\n *\n * 差异:\n * - 原始版本在首次访问任意属性时才调用 getInstance()\n * - 降级版本在模块加载时立即调用 getInstance()\n * - 功能上等价,因为 HttpService 使用延迟初始化的单例模式\n */\nexport const httpService: HttpService = HttpService.getInstance();\n\n// Re-export HttpService class for consumers that need it\nexport { HttpService } from '@genie/agent-provider';\n","/**\n * Miniprogram Transport Layer\n *\n * 抽象网络请求层,支持小程序 wx.request 和浏览器 fetch 两种实现。\n * 通过 RequestAdapter 接口解耦具体网络 API,方便扩展到不同小程序平台。\n *\n * 支持的平台:\n * - 微信小程序 (wx.request)\n * - 支付宝小程序 (my.request)\n * - httpService (走 axios 拦截器)\n * - 其他小程序平台(实现 RequestAdapter 接口即可)\n */\n\nimport { httpService } from '../http/index.js';\n\n// ============================================\n// Request Adapter Interface\n// ============================================\n\n/**\n * HTTP request configuration\n */\nexport interface RequestConfig {\n /** Full URL */\n url: string;\n /** HTTP method */\n method: 'GET' | 'POST' | 'PUT' | 'DELETE';\n /** Request headers */\n headers?: Record<string, string>;\n /** Request body (will be serialized according to content-type) */\n data?: unknown;\n /** Response type */\n responseType?: 'text' | 'arraybuffer';\n /** Request timeout in milliseconds */\n timeout?: number;\n}\n\n/**\n * HTTP response\n */\nexport interface RequestResponse<T = unknown> {\n /** HTTP status code */\n statusCode: number;\n /** Response data */\n data: T;\n /** Response headers */\n headers: Record<string, string>;\n}\n\n/**\n * Abstract request adapter interface.\n * Implement this to support different miniprogram platforms.\n *\n * @example\n * ```typescript\n * // 微信小程序\n * const adapter = new WxRequestAdapter();\n *\n * // 自定义适配器\n * class MyRequestAdapter implements RequestAdapter {\n * request<T>(config: RequestConfig): Promise<RequestResponse<T>> {\n * return my.request({ ... }); // 支付宝小程序\n * }\n * }\n * ```\n */\nexport interface RequestAdapter {\n request<T = unknown>(config: RequestConfig): Promise<RequestResponse<T>>;\n}\n\n// ============================================\n// WeChat Miniprogram Request Adapter\n// ============================================\n\n/**\n * wx.request type declarations (minimal subset)\n */\ndeclare const wx: {\n request(options: {\n url: string;\n method?: string;\n header?: Record<string, string>;\n data?: unknown;\n responseType?: string;\n timeout?: number;\n success: (res: { statusCode: number; data: unknown; header: Record<string, string> }) => void;\n fail: (err: { errMsg: string }) => void;\n }): void;\n};\n\n/**\n * WeChat Miniprogram request adapter using wx.request\n *\n * @example\n * ```typescript\n * const adapter = new WxRequestAdapter();\n * const response = await adapter.request({\n * url: 'https://example.com/api',\n * method: 'GET',\n * headers: { 'Authorization': 'Bearer xxx' }\n * });\n * ```\n */\nexport class WxRequestAdapter implements RequestAdapter {\n async request<T = unknown>(config: RequestConfig): Promise<RequestResponse<T>> {\n return new Promise((resolve, reject) => {\n wx.request({\n url: config.url,\n method: config.method,\n header: config.headers,\n data: config.data,\n responseType: config.responseType === 'arraybuffer' ? 'arraybuffer' : 'text',\n timeout: config.timeout,\n success: res => {\n resolve({\n statusCode: res.statusCode,\n data: res.data as T,\n headers: res.header,\n });\n },\n fail: err => {\n reject(new Error(`wx.request failed: ${err.errMsg}`));\n },\n });\n });\n }\n}\n\n// ============================================\n// Fetch Request Adapter (for testing / browser fallback)\n// ============================================\n\n/**\n * Fetch-based request adapter.\n * Can be used in browser or Node.js environments for testing.\n */\nexport class HttpServiceRequestAdapter implements RequestAdapter {\n /**\n * 通过 httpService (axios) 发送请求。\n *\n * 所有请求都会经过 httpService 注册的拦截器(如 URL 替换、header 注入等)。\n *\n * - `validateStatus: () => true`:让 axios 不因 4xx/5xx 抛错,\n * 保持与 WxRequestAdapter 行为一致,由 e2b-adapter 自行处理错误状态码。\n * - httpService 的默认 401 响应拦截器不会触发(因为 validateStatus 跳过了 reject 路径),\n * 但 MiniProgramE2BFilesystem 自带独立的 401/403 重连机制,无影响。\n */\n async request<T = unknown>(config: RequestConfig): Promise<RequestResponse<T>> {\n const response = await httpService.request<T>({\n url: config.url,\n method: config.method,\n headers: config.headers,\n data: config.data,\n responseType: config.responseType,\n timeout: config.timeout,\n validateStatus: () => true,\n });\n return {\n statusCode: response.status,\n data: response.data,\n headers: response.headers as Record<string, string>,\n };\n }\n}\n\n// ============================================\n// Fetch Request Adapter (for testing / browser fallback)\n// ============================================\n\n/**\n * Fetch-based request adapter.\n * Can be used in browser or Node.js environments for testing.\n */\nexport class FetchRequestAdapter implements RequestAdapter {\n async request<T = unknown>(config: RequestConfig): Promise<RequestResponse<T>> {\n const init: RequestInit = {\n method: config.method,\n headers: config.headers,\n };\n\n if (config.data !== undefined && config.method !== 'GET') {\n if (typeof config.data === 'string') {\n init.body = config.data;\n } else if (config.data instanceof ArrayBuffer) {\n // ArrayBuffer 直接作为 fetch body(二进制数据零损耗)\n init.body = config.data;\n } else {\n init.body = JSON.stringify(config.data);\n }\n }\n\n if (config.timeout) {\n const controller = new AbortController();\n init.signal = controller.signal;\n setTimeout(() => controller.abort(), config.timeout);\n }\n\n const response = await fetch(config.url, init);\n\n let data: T;\n if (config.responseType === 'arraybuffer') {\n data = (await response.arrayBuffer()) as unknown as T;\n } else {\n const text = await response.text();\n try {\n data = JSON.parse(text) as T;\n } catch {\n data = text as unknown as T;\n }\n }\n\n const headers: Record<string, string> = {};\n response.headers.forEach((value, key) => {\n headers[key] = value;\n });\n\n return {\n statusCode: response.status,\n data,\n headers,\n };\n }\n}\n","/**\n * Miniprogram E2B Filesystem Adapter\n *\n * 不依赖 e2b npm 包,直接调用 E2B envd 的 REST API 和 Connect-RPC JSON 协议。\n * 实现 FilesResource 接口,与 E2BFilesystem 完全兼容。\n *\n * ## 协议说明\n *\n * E2B envd 暴露两种协议:\n *\n * ### 1. REST API (openapi-fetch 风格)\n * - `GET /files?path=xxx` → 读取文件\n * - `POST /files?path=xxx` → 写入文件 (multipart/form-data)\n *\n * ### 2. Connect-RPC JSON 协议 (gRPC-Web JSON 模式)\n * - `POST /filesystem.Filesystem/Stat` → 文件信息 / 存在检测\n * - `POST /filesystem.Filesystem/ListDir` → 列目录\n * - `POST /filesystem.Filesystem/MakeDir` → 创建目录\n * - `POST /filesystem.Filesystem/Move` → 重命名 / 移动\n * - `POST /filesystem.Filesystem/Remove` → 删除\n * - `POST /filesystem.Filesystem/WatchDir` → 监听目录变化 (server-stream)\n *\n * Connect-RPC JSON 模式请求格式:\n * - Content-Type: application/json\n * - Body: JSON serialized protobuf message\n * - 不需要 protobuf 编解码,直接 JSON 即可\n *\n * @see https://e2b.dev/docs/filesystem/read-write\n * @see https://connectrpc.com/docs/protocol\n */\n\nimport type {\n E2BSandboxConnectionInfo,\n FilesResource,\n FilesystemListOpts,\n FilesystemRequestOpts,\n WatchOpts,\n WriteEntry,\n} from '../common/types.js';\nimport { HttpServiceRequestAdapter, type RequestAdapter, type RequestResponse } from './transport.js';\nimport {\n type EntryInfo,\n type FilesystemEvent,\n FilesystemEventType,\n FileType,\n type ListDirResponse,\n type MakeDirResponse,\n type MoveResponse,\n type ProtoEntryInfo,\n type ProtoEventType,\n type ProtoTimestamp,\n type WatchHandle,\n type WriteInfo,\n} from './types.js';\n\n// ============================================\n// Constants\n// ============================================\n\n/** Default request timeout (30s) */\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\n/** Connect-RPC JSON content type */\nconst CONNECT_CONTENT_TYPE = 'application/json';\n\n/** Connect-RPC gRPC service base path */\nconst RPC_BASE = '/filesystem.Filesystem';\n\n// ============================================\n// Reconnect Function Type\n// ============================================\n\n/**\n * Callback to fetch fresh sandbox connection info from backend.\n * Called when an operation fails with 401/403.\n */\nexport type ReconnectFn = () => Promise<E2BSandboxConnectionInfo>;\n\n// ============================================\n// Error Classes\n// ============================================\n\n/**\n * E2B API error\n */\nexport class E2BApiError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number,\n public readonly code?: string,\n ) {\n super(message);\n this.name = 'E2BApiError';\n }\n}\n\n/**\n * E2B Not Found error\n */\nexport class E2BNotFoundError extends E2BApiError {\n constructor(message: string) {\n super(message, 404, 'NOT_FOUND');\n this.name = 'E2BNotFoundError';\n }\n}\n\n/**\n * E2B Authentication error\n */\nexport class E2BAuthError extends E2BApiError {\n constructor(message: string) {\n super(message, 401, 'UNAUTHENTICATED');\n this.name = 'E2BAuthError';\n }\n}\n\n// ============================================\n// Helper Functions\n// ============================================\n\n/**\n * Map protobuf FileType enum to FileType string\n */\nfunction mapProtoFileType(type: number): FileType | undefined {\n switch (type) {\n case 1: return FileType.FILE;\n case 2: return FileType.DIR;\n default: return undefined;\n }\n}\n\n/**\n * Map protobuf EventType enum to FilesystemEventType string\n */\nfunction mapProtoEventType(type: ProtoEventType): FilesystemEventType | undefined {\n switch (type) {\n case 1: return FilesystemEventType.CREATE;\n case 2: return FilesystemEventType.WRITE;\n case 3: return FilesystemEventType.REMOVE;\n case 4: return FilesystemEventType.RENAME;\n case 5: return FilesystemEventType.CHMOD;\n default: return undefined;\n }\n}\n\n/**\n * Map protobuf Timestamp to Date\n */\nfunction mapProtoTimestamp(ts?: ProtoTimestamp): Date | undefined {\n if (!ts) {return undefined;}\n return new Date(Number(ts.seconds) * 1000 + Math.floor(ts.nanos / 1_000_000));\n}\n\n/**\n * Map protobuf EntryInfo to SDK EntryInfo\n */\nfunction mapProtoEntry(e: ProtoEntryInfo): EntryInfo | undefined {\n const type = mapProtoFileType(e.type);\n if (!type) {return undefined;}\n return {\n name: e.name,\n type,\n path: e.path,\n size: Number(e.size),\n mode: e.mode,\n permissions: e.permissions,\n owner: e.owner,\n group: e.group,\n modifiedTime: mapProtoTimestamp(e.modifiedTime),\n symlinkTarget: e.symlinkTarget,\n };\n}\n\n/**\n * Encode string to base64 (miniprogram compatible)\n */\nfunction base64Encode(str: string): string {\n // 小程序环境中 btoa 不一定可用,使用 ArrayBuffer 编码\n if (typeof btoa === 'function') {\n return btoa(str);\n }\n // Fallback for miniprogram: manual base64\n const bytes = new TextEncoder().encode(str);\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n let result = '';\n for (let i = 0; i < bytes.length; i += 3) {\n const a = bytes[i];\n const b = bytes[i + 1] ?? 0;\n const c = bytes[i + 2] ?? 0;\n result += chars[a >> 2];\n result += chars[((a & 3) << 4) | (b >> 4)];\n result += i + 1 < bytes.length ? chars[((b & 15) << 2) | (c >> 6)] : '=';\n result += i + 2 < bytes.length ? chars[c & 63] : '=';\n }\n return result;\n}\n\n/**\n * Convert an ASCII string to Uint8Array (each char → one byte via charCodeAt).\n * Used to build multipart boundary headers/footers as raw bytes.\n */\nfunction stringToUint8Array(str: string): Uint8Array {\n const arr = new Uint8Array(str.length);\n for (let i = 0; i < str.length; i++) {\n arr[i] = str.charCodeAt(i);\n }\n return arr;\n}\n\n/**\n * Escape filename for Content-Disposition header.\n * Escapes `\"` and `\\` to avoid multipart parsing errors.\n */\nfunction escapeFilename(name: string): string {\n return name.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n}\n\n/**\n * Concatenate multiple Uint8Array segments into one.\n */\nfunction concatUint8Arrays(segments: Uint8Array[]): Uint8Array {\n let totalLength = 0;\n for (const seg of segments) {\n totalLength += seg.byteLength;\n }\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const seg of segments) {\n result.set(seg, offset);\n offset += seg.byteLength;\n }\n return result;\n}\n\n// ============================================\n// MiniProgramE2BFilesystem\n// ============================================\n\n/**\n * E2B Filesystem adapter for Miniprogram\n *\n * 替代 e2b npm 包的 Sandbox + Filesystem,直接通过 HTTP 调用 E2B envd API。\n * 不依赖 fetch / ReadableStream / FormData / Blob 等浏览器 API。\n *\n * ## 两种协议\n *\n * 1. **REST (envd HTTP API)**:\n * - 读文件: `GET {envdApiUrl}/files?path=xxx`\n * - 写文件: `POST {envdApiUrl}/files?path=xxx` (使用 boundary 手动构造 multipart)\n *\n * 2. **Connect-RPC JSON**:\n * - 其他操作: `POST {envdApiUrl}/filesystem.Filesystem/{Method}` (JSON body)\n *\n * ## 自动重连\n *\n * 与 E2BFilesystem 相同的重连机制:\n * - 检测 401/403 错误\n * - 10s 冷却\n * - 单例重连 + subscriber 模式\n *\n * @example\n * ```typescript\n * const fs = await MiniProgramE2BFilesystem.connect({\n * sandboxId: 'xxx',\n * apiUrl: 'https://...',\n * headers: { 'X-Enterprise-Id': '...' }\n * });\n *\n * fs.setReconnectFn(async () => fetchFreshConnectionInfo());\n *\n * // 使用方式与 E2BFilesystem 完全一致\n * const content = await fs.read('/workspace/src/app.ts');\n * await fs.write('/workspace/src/app.ts', 'console.log(\"hello\")');\n * const entries = await fs.list('/workspace/src');\n * ```\n */\nexport class MiniProgramE2BFilesystem implements FilesResource {\n private envdApiUrl: string;\n private accessToken: string;\n private customHeaders: Record<string, string>;\n private requestTimeoutMs: number;\n private adapter: RequestAdapter;\n private reconnectFn?: ReconnectFn;\n\n /** Whether a reconnect is currently in-flight */\n private isReconnecting = false;\n /** Callers waiting for the in-flight reconnect to complete */\n private reconnectSubscribers: Array<(success: boolean) => void> = [];\n /** Timestamp of last reconnect attempt (anti-loop: min 10s between attempts) */\n private lastReconnectAt = 0;\n\n private static readonly MIN_RECONNECT_INTERVAL_MS = 10_000;\n\n constructor(\n envdApiUrl: string,\n accessToken: string,\n customHeaders: Record<string, string>,\n requestTimeoutMs: number,\n adapter?: RequestAdapter,\n ) {\n this.envdApiUrl = envdApiUrl;\n this.accessToken = accessToken;\n this.customHeaders = customHeaders;\n this.requestTimeoutMs = requestTimeoutMs;\n this.adapter = adapter ?? new HttpServiceRequestAdapter();\n }\n\n /**\n * Connect to an E2B Sandbox (miniprogram version).\n *\n * 与 E2BFilesystem.connect 接口兼容:接受相同的 E2BSandboxConnectionInfo。\n *\n * ## 鉴权说明\n *\n * e2b SDK 内部的 Sandbox.connect() 做了两步:\n * 1. 调用管理 API(用 apiKey/accessToken 认证)→ 获取 envdAccessToken\n * 2. 用 envdAccessToken 作为 X-Access-Token 访问 envd 文件系统 API\n *\n * 但在本项目中,CloudAgentProvider.getSandboxInfo() 已经从后端获取了:\n * - sandboxId\n * - apiUrl(已是 envd proxy URL)\n * - accessToken(已是 envdAccessToken)\n * - headers(包含 X-Enterprise-Id 等)\n *\n * 因此小程序适配器**跳过了管理 API 调用**,直接使用后端提供的信息连接 envd。\n * 这与 E2BFilesystem 的最终行为一致——都是用 X-Access-Token 访问 envd API。\n *\n * ## URL 格式\n * - 如果有 apiUrl: 直接使用(项目中后端已经提供了完整的 proxy URL)\n * - 否则: `https://49983-{sandboxId}.{domain}` (标准 e2b envd URL)\n *\n * @param info - Sandbox connection info (from backend API / CloudAgentProvider.getSandboxInfo())\n * @param adapter - Optional custom request adapter (default: WxRequestAdapter)\n */\n static async connect(\n info: E2BSandboxConnectionInfo,\n adapter?: RequestAdapter,\n ): Promise<MiniProgramE2BFilesystem> {\n const domain = info.domain || 'e2b.dev';\n const envdApiUrl = info.apiUrl || `https://49983-${info.sandboxId}.${domain}`;\n const accessToken = info.accessToken || info.apiKey || '';\n const customHeaders = info.headers || {};\n const timeoutMs = info.requestTimeoutMs || DEFAULT_TIMEOUT_MS;\n\n return new MiniProgramE2BFilesystem(\n envdApiUrl,\n accessToken,\n customHeaders,\n timeoutMs,\n adapter,\n );\n }\n\n /**\n * Set reconnect callback. When set, auth errors trigger automatic reconnect + retry.\n */\n setReconnectFn(fn: ReconnectFn): void {\n this.reconnectFn = fn;\n }\n\n /**\n * Update connection info (used during reconnect)\n */\n private updateConnection(info: E2BSandboxConnectionInfo): void {\n const domain = info.domain || 'e2b.dev';\n this.envdApiUrl = info.apiUrl || `https://49983-${info.sandboxId}.${domain}`;\n this.accessToken = info.accessToken || info.apiKey || '';\n this.customHeaders = info.headers || {};\n if (info.requestTimeoutMs) {\n this.requestTimeoutMs = info.requestTimeoutMs;\n }\n }\n\n // ============================================\n // Auto-Reconnect (与 E2BFilesystem 相同逻辑)\n // ============================================\n\n private isAuthError(error: unknown): boolean {\n if (!error || typeof error !== 'object') {return false;}\n const err = error as Record<string, unknown>;\n\n // Check status codes\n if (err.statusCode === 401 || err.statusCode === 403) {return true;}\n\n // Check E2BApiError\n if (err instanceof E2BApiError) {\n return err.statusCode === 401 || err.statusCode === 403;\n }\n\n // Check error message\n if (typeof err.message === 'string') {\n const msg = err.message.toLowerCase();\n if (msg.includes('unauthorized') || msg.includes('token expired') || msg.includes('authentication')) {\n return true;\n }\n }\n\n return false;\n }\n\n private canAttemptReconnect(): boolean {\n return (Date.now() - this.lastReconnectAt) >= MiniProgramE2BFilesystem.MIN_RECONNECT_INTERVAL_MS;\n }\n\n private async reconnect(): Promise<void> {\n if (this.isReconnecting) {\n return new Promise<void>((resolve, reject) => {\n this.reconnectSubscribers.push((success: boolean) => {\n if (success) {resolve();}\n else {reject(new Error('E2B sandbox reconnect failed'));}\n });\n });\n }\n\n this.isReconnecting = true;\n this.lastReconnectAt = Date.now();\n\n try {\n const info = await this.reconnectFn!();\n this.updateConnection(info);\n this.reconnectSubscribers.forEach(cb => cb(true));\n this.reconnectSubscribers = [];\n } catch (error) {\n this.reconnectSubscribers.forEach(cb => cb(false));\n this.reconnectSubscribers = [];\n throw error;\n } finally {\n this.isReconnecting = false;\n }\n }\n\n /**\n * Execute an operation with auto-reconnect on auth error\n */\n private async exec<T>(operation: () => Promise<T>): Promise<T> {\n try {\n return await operation();\n } catch (error) {\n if (this.reconnectFn && this.isAuthError(error) && this.canAttemptReconnect()) {\n await this.reconnect();\n return operation();\n }\n throw error;\n }\n }\n\n // ============================================\n // HTTP Helpers\n // ============================================\n\n /**\n * Build common headers for envd REST API\n */\n private getRestHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n ...this.customHeaders,\n };\n if (this.accessToken) {\n headers['X-Access-Token'] = this.accessToken;\n }\n return headers;\n }\n\n /**\n * Build common headers for Connect-RPC JSON calls\n */\n private getRpcHeaders(user?: string): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': CONNECT_CONTENT_TYPE,\n ...this.customHeaders,\n };\n if (this.accessToken) {\n headers['X-Access-Token'] = this.accessToken;\n }\n // Connect-RPC uses Basic auth for filesystem operations\n // Username is the user parameter, password is empty\n if (user) {\n headers['Authorization'] = `Basic ${base64Encode(`${user}:`)}`;\n }\n return headers;\n }\n\n /**\n * Make a REST API call\n */\n private async restRequest<T>(\n method: 'GET' | 'POST',\n path: string,\n query?: Record<string, string | undefined>,\n data?: unknown,\n headers?: Record<string, string>,\n responseType?: 'text' | 'arraybuffer',\n timeoutMs?: number,\n ): Promise<RequestResponse<T>> {\n // Build URL with query parameters\n let url = `${this.envdApiUrl}${path}`;\n if (query) {\n const params = Object.entries(query)\n .filter(([, v]) => v !== undefined)\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v!)}`)\n .join('&');\n if (params) {\n url += `?${params}`;\n }\n }\n\n const response = await this.adapter.request<T>({\n url,\n method,\n headers: { ...this.getRestHeaders(), ...headers },\n data,\n responseType,\n timeout: timeoutMs ?? this.requestTimeoutMs,\n });\n\n // Handle error status codes\n if (response.statusCode >= 400) {\n const message = typeof response.data === 'string'\n ? response.data\n : JSON.stringify(response.data);\n\n switch (response.statusCode) {\n case 401:\n case 403:\n throw new E2BAuthError(message);\n case 404:\n throw new E2BNotFoundError(message);\n default:\n throw new E2BApiError(message, response.statusCode);\n }\n }\n\n return response;\n }\n\n /**\n * Make a Connect-RPC JSON call\n *\n * Connect protocol (JSON mode):\n * - POST to /{service}/{method}\n * - Content-Type: application/json\n * - Body: JSON-serialized protobuf message\n * - Response: JSON-serialized protobuf message\n */\n private async rpcCall<TReq, TRes>(\n method: string,\n request: TReq,\n opts?: { user?: string; requestTimeoutMs?: number },\n ): Promise<TRes> {\n const url = `${this.envdApiUrl}${RPC_BASE}/${method}`;\n\n const response = await this.adapter.request<TRes>({\n url,\n method: 'POST',\n headers: this.getRpcHeaders(opts?.user),\n data: request,\n timeout: opts?.requestTimeoutMs ?? this.requestTimeoutMs,\n });\n\n // Handle Connect-RPC error responses\n if (response.statusCode >= 400) {\n const errorBody = response.data as unknown as { code?: string; message?: string };\n const message = errorBody?.message || JSON.stringify(response.data);\n\n switch (response.statusCode) {\n case 401:\n case 403:\n throw new E2BAuthError(message);\n case 404:\n // Connect-RPC returns 404 for NOT_FOUND code\n throw new E2BNotFoundError(message);\n default:\n throw new E2BApiError(message, response.statusCode, errorBody?.code);\n }\n }\n\n return response.data;\n }\n\n // ============================================\n // FilesResource Implementation\n // ============================================\n\n // --- read ---\n\n read(path: string, opts?: FilesystemRequestOpts & { format?: 'text' }): Promise<string>;\n read(path: string, opts: FilesystemRequestOpts & { format: 'bytes' }): Promise<Uint8Array>;\n read(path: string, opts: FilesystemRequestOpts & { format: 'blob' }): Promise<Blob>;\n read(path: string, opts: FilesystemRequestOpts & { format: 'stream' }): Promise<ReadableStream<Uint8Array>>;\n read(path: string, opts?: FilesystemRequestOpts & { format?: string }): Promise<string | Uint8Array | Blob | ReadableStream<Uint8Array>> {\n return this.exec(async () => {\n const format = (opts as any)?.format ?? 'text';\n const user = opts?.user;\n\n // stream 格式:小程序没有 ReadableStream,直接抛出\n if (format === 'stream') {\n throw new Error(\n \"read format 'stream' is not supported in miniprogram, use 'text' or 'bytes' instead\"\n );\n }\n\n // blob 格式:小程序没有 Blob,降级为 ArrayBuffer 读取\n // 上层 UI 需要适配:用 ArrayBuffer → base64 等方式替代 Blob URL 预览\n if (format === 'blob') {\n const response = await this.restRequest<ArrayBuffer>(\n 'GET',\n '/files',\n { path, username: user },\n undefined,\n undefined,\n 'arraybuffer',\n opts?.requestTimeoutMs,\n );\n // 返回 ArrayBuffer,调用方需要自行处理(而非 Blob)\n // 注意:类型签名声明返回 Blob,但小程序环境实际返回 ArrayBuffer\n // 这是已知的平台限制,上层代码需做环境判断\n return response.data as unknown as Blob;\n }\n\n const responseType = format === 'bytes' ? 'arraybuffer' : 'text';\n const response = await this.restRequest<string | ArrayBuffer>(\n 'GET',\n '/files',\n { path, username: user },\n undefined,\n undefined,\n responseType as 'text' | 'arraybuffer',\n opts?.requestTimeoutMs,\n );\n\n if (format === 'bytes') {\n return new Uint8Array(response.data as ArrayBuffer);\n }\n\n return response.data as string;\n });\n }\n\n // --- write ---\n\n write(path: string, data: string | ArrayBuffer | Blob | ReadableStream, opts?: FilesystemRequestOpts): Promise<WriteInfo>;\n write(files: WriteEntry[], opts?: FilesystemRequestOpts): Promise<WriteInfo[]>;\n write(\n pathOrFiles: string | WriteEntry[],\n dataOrOpts?: string | ArrayBuffer | Blob | ReadableStream | FilesystemRequestOpts,\n opts?: FilesystemRequestOpts,\n ): Promise<WriteInfo | WriteInfo[]> {\n return this.exec(async () => {\n let writePath: string | undefined;\n let writeFiles: Array<{ path?: string; data: unknown }>;\n let writeOpts: FilesystemRequestOpts | undefined;\n\n if (typeof pathOrFiles === 'string') {\n writePath = pathOrFiles;\n writeFiles = [{ data: dataOrOpts }];\n writeOpts = opts;\n } else {\n writeFiles = pathOrFiles;\n writeOpts = dataOrOpts as FilesystemRequestOpts | undefined;\n }\n\n if (writeFiles.length === 0) {return [];}\n\n const user = writeOpts?.user;\n\n // 构造 multipart/form-data body 为 ArrayBuffer\n // 避免 string body 被 wx.request 以 UTF-8 编码发送导致二进制数据损坏\n const boundary = `----MiniProgramBoundary${Date.now()}${Math.random().toString(36).slice(2)}`;\n const segments: Uint8Array[] = [];\n\n for (const file of writeFiles) {\n const fileName = file.path || writePath || 'file';\n\n // 将文件数据转为 Uint8Array\n let fileBytes: Uint8Array;\n if (typeof file.data === 'string') {\n fileBytes = new TextEncoder().encode(file.data);\n } else if (file.data instanceof ArrayBuffer) {\n fileBytes = new Uint8Array(file.data);\n } else {\n // Blob / ReadableStream 小程序不支持,直接抛出\n throw new Error(\n 'write with Blob/ReadableStream is not supported in miniprogram, use string or ArrayBuffer instead'\n );\n }\n\n // multipart 各段都构造为 Uint8Array\n const header = `--${boundary}\\r\\n`\n + `Content-Disposition: form-data; name=\"file\"; filename=\"${escapeFilename(fileName)}\"\\r\\n`\n + 'Content-Type: application/octet-stream\\r\\n'\n + '\\r\\n';\n segments.push(stringToUint8Array(header));\n segments.push(fileBytes);\n segments.push(stringToUint8Array('\\r\\n'));\n }\n segments.push(stringToUint8Array(`--${boundary}--\\r\\n`));\n\n // 拼接所有段为一个 ArrayBuffer\n const body = concatUint8Arrays(segments);\n\n const response = await this.restRequest<WriteInfo[]>(\n 'POST',\n '/files',\n { path: writePath, username: user },\n body.buffer,\n {\n 'Content-Type': `multipart/form-data; boundary=${boundary}`,\n },\n 'text',\n writeOpts?.requestTimeoutMs,\n );\n\n const files = response.data;\n if (!files) {\n throw new Error('Expected to receive information about written file');\n }\n\n return files.length === 1 && writePath ? files[0] : files;\n });\n }\n\n // --- list ---\n\n async list(path: string, opts?: FilesystemListOpts): Promise<EntryInfo[]> {\n return this.exec(async () => {\n if (typeof opts?.depth === 'number' && opts.depth < 1) {\n throw new Error('depth should be at least one');\n }\n\n const response = await this.rpcCall<{ path: string; depth: number }, ListDirResponse>(\n 'ListDir',\n { path, depth: opts?.depth ?? 1 },\n { user: opts?.user, requestTimeoutMs: opts?.requestTimeoutMs },\n );\n\n const entries: EntryInfo[] = [];\n for (const e of response.entries || []) {\n const entry = mapProtoEntry(e);\n if (entry) {entries.push(entry);}\n }\n return entries;\n });\n }\n\n // --- exists ---\n\n async exists(path: string, opts?: FilesystemRequestOpts): Promise<boolean> {\n return this.exec(async () => {\n try {\n await this.rpcCall(\n 'Stat',\n { path },\n { user: opts?.user, requestTimeoutMs: opts?.requestTimeoutMs },\n );\n return true;\n } catch (err) {\n if (err instanceof E2BNotFoundError) {\n return false;\n }\n // Connect-RPC 可能返回 JSON error with code \"not_found\"\n if (err instanceof E2BApiError && (err.code === 'NOT_FOUND' || err.code === 'not_found')) {\n return false;\n }\n throw err;\n }\n });\n }\n\n // --- makeDir ---\n\n async makeDir(path: string, opts?: FilesystemRequestOpts): Promise<boolean> {\n return this.exec(async () => {\n try {\n await this.rpcCall<{ path: string }, MakeDirResponse>(\n 'MakeDir',\n { path },\n { user: opts?.user, requestTimeoutMs: opts?.requestTimeoutMs },\n );\n return true;\n } catch (err) {\n // AlreadyExists → return false\n if (err instanceof E2BApiError && (err.code === 'ALREADY_EXISTS' || err.code === 'already_exists')) {\n return false;\n }\n throw err;\n }\n });\n }\n\n // --- remove ---\n\n async remove(path: string, opts?: FilesystemRequestOpts): Promise<void> {\n return this.exec(async () => {\n await this.rpcCall(\n 'Remove',\n { path },\n { user: opts?.user, requestTimeoutMs: opts?.requestTimeoutMs },\n );\n });\n }\n\n // --- rename ---\n\n async rename(oldPath: string, newPath: string, opts?: FilesystemRequestOpts): Promise<EntryInfo> {\n return this.exec(async () => {\n const response = await this.rpcCall<\n { source: string; destination: string },\n MoveResponse\n >(\n 'Move',\n { source: oldPath, destination: newPath },\n { user: opts?.user, requestTimeoutMs: opts?.requestTimeoutMs },\n );\n\n const entry = response.entry ? mapProtoEntry(response.entry) : undefined;\n if (!entry) {\n throw new Error('Expected to receive information about moved object');\n }\n return entry;\n });\n }\n\n // --- getInfo ---\n\n async getInfo(path: string, opts?: FilesystemRequestOpts): Promise<EntryInfo> {\n return this.exec(async () => {\n const response = await this.rpcCall<{ path: string }, { entry: ProtoEntryInfo }>(\n 'Stat',\n { path },\n { user: opts?.user, requestTimeoutMs: opts?.requestTimeoutMs },\n );\n\n const entry = response.entry ? mapProtoEntry(response.entry) : undefined;\n if (!entry) {\n throw new Error('Expected to receive information about the file or directory');\n }\n return entry;\n });\n }\n\n // --- watchDir ---\n\n /**\n * Watch directory for changes.\n *\n * 小程序环境限制:\n * - 不支持 gRPC server-streaming (需要 ReadableStream)\n * - 降级为轮询方案:使用 CreateWatcher + GetWatcherEvents + RemoveWatcher API\n *\n * E2B envd 提供了基于轮询的 Watcher API:\n * 1. POST /filesystem.Filesystem/CreateWatcher → { watcherId }\n * 2. POST /filesystem.Filesystem/GetWatcherEvents → { events[] } (轮询)\n * 3. POST /filesystem.Filesystem/RemoveWatcher → {} (停止)\n */\n async watchDir(\n path: string,\n onEvent: (event: FilesystemEvent) => void | Promise<void>,\n opts?: WatchOpts & { onExit?: (err?: Error) => void | Promise<void> },\n ): Promise<WatchHandle> {\n return this.exec(async () => {\n // 1. Create watcher\n const createRes = await this.rpcCall<\n { path: string; recursive: boolean },\n { watcherId: string }\n >(\n 'CreateWatcher',\n { path, recursive: opts?.recursive ?? false },\n { user: opts?.user, requestTimeoutMs: opts?.requestTimeoutMs },\n );\n\n const watcherId = createRes.watcherId;\n if (!watcherId) {\n throw new Error('Failed to create watcher: no watcherId returned');\n }\n\n // 2. Start polling loop\n let stopped = false;\n const pollIntervalMs = 1000; // 1s polling interval\n const timeoutMs = opts?.timeoutMs ?? 60_000;\n const startTime = Date.now();\n\n const poll = async () => {\n while (!stopped) {\n // Check timeout\n if (Date.now() - startTime > timeoutMs) {\n stopped = true;\n opts?.onExit?.();\n break;\n }\n\n try {\n const eventsRes = await this.rpcCall<\n { watcherId: string },\n { events: Array<{ name: string; type: ProtoEventType }> }\n >(\n 'GetWatcherEvents',\n\n { watcherId: watcherId },\n { user: opts?.user },\n );\n\n for (const evt of eventsRes.events || []) {\n const eventType = mapProtoEventType(evt.type);\n if (eventType) {\n await onEvent({ name: evt.name, type: eventType });\n }\n }\n } catch (err) {\n if (!stopped) {\n stopped = true;\n opts?.onExit?.(err instanceof Error ? err : new Error(String(err)));\n }\n break;\n }\n\n // Wait before next poll\n if (!stopped) {\n await new Promise(resolve => setTimeout(resolve, pollIntervalMs));\n }\n }\n };\n\n // Start polling in background\n poll().catch(err => {\n opts?.onExit?.(err instanceof Error ? err : new Error(String(err)));\n });\n\n // 3. Return WatchHandle\n return {\n stop: async () => {\n stopped = true;\n try {\n await this.rpcCall(\n 'RemoveWatcher',\n\n { watcherId: watcherId },\n { user: opts?.user },\n );\n } catch {\n // Ignore errors during cleanup\n }\n },\n };\n });\n }\n}\n\nexport default MiniProgramE2BFilesystem;\n","/**\n * Legacy Cloud Agent Provider Wrapper\n *\n * CloudAgentProvider 本身不直接使用 Proxy/Symbol 等不兼容语法,\n * 但其内部依赖 httpService(通过 Proxy 实现)和可选链语法。\n *\n * 此文件的作用:\n * 1. 重新导出 CloudAgentProvider(本身不需要修改)\n * 2. 提供 createLegacyCloudAgentProvider 工厂函数,确保\n * 使用降级版 httpService 而非 Proxy 版本\n * 3. 注入 MiniProgramE2BFilesystem 作为默认 filesystemFactory,\n * 避免运行时依赖 e2b npm 包\n *\n * 降级处理清单:\n * - 确保 httpService 通过非 Proxy 方式初始化\n * - 注入 MiniProgramE2BFilesystem 替代 E2BFilesystem (无 e2b 依赖)\n * - Optional chaining (?.) → 由构建工具(tsdown/esbuild)处理降级\n * - Nullish coalescing (??) → 由构建工具处理降级\n *\n * 注意:CloudAgentProvider 源码中使用的 ?. 和 ?? 语法会在\n * tsdown 构建时通过 esbuild 自动降级到目标 ES 版本。\n * 这里不需要手动转换这些语法。\n */\n\nimport type { CloudAgentProviderOptions } from '@genie/agent-provider';\nimport { CloudAgentProvider } from '@genie/agent-provider';\nimport { MiniProgramE2BFilesystem } from '@genie/agent-provider/miniprogram';\n\n// [降级] 导入非 Proxy 版 httpService,确保在 Proxy 不可用环境也能工作\nimport { httpService } from './http-service';\n\n// ============================================\n// Legacy Factory Function\n// ============================================\n\n/**\n * 创建兼容小程序的 CloudAgentProvider\n *\n * 与直接 `new CloudAgentProvider(options)` 的区别:\n * - 确保 httpService 已通过非 Proxy 方式初始化\n * - 默认注入 MiniProgramE2BFilesystem 作为 filesystemFactory,\n * 避免拉入 e2b npm 包\n * - 在创建 provider 之前验证环境兼容性\n *\n * @param options - CloudAgentProvider 配置\n * @returns CloudAgentProvider 实例\n *\n * @example\n * ```typescript\n * import { createLegacyCloudAgentProvider } from '@genie/cloud-agent-sdk/legacy';\n *\n * const provider = createLegacyCloudAgentProvider({\n * endpoint: 'https://api.example.com',\n * authToken: 'token',\n * });\n * ```\n */\nexport function createLegacyCloudAgentProvider(\n options: CloudAgentProviderOptions\n): CloudAgentProvider {\n // [降级] 确保 httpService 单例已初始化(非 Proxy 版本)\n // CloudAgentProvider 构造函数内部会调用 httpService.setBaseURL()\n // 这里提前触发初始化,避免 Proxy 依赖\n if (options.endpoint) {\n httpService.setBaseURL(options.endpoint);\n }\n if (options.authToken) {\n httpService.setAuthToken(options.authToken);\n }\n\n // [降级] 默认注入 MiniProgramE2BFilesystem 替代 E2BFilesystem\n // 避免运行时依赖 e2b npm 包\n if (!options.filesystemFactory) {\n options.filesystemFactory = info => MiniProgramE2BFilesystem.connect(info);\n }\n\n return new CloudAgentProvider(options);\n}\n\n// ============================================\n// Re-exports\n// ============================================\n\n// [保持兼容] 原始类和类型仍然可用\nexport { CloudAgentProvider } from '@genie/agent-provider';\nexport type { CloudAgentProviderOptions } from '@genie/agent-provider';\n","/**\n * Legacy Cloud Agent Connection Wrapper\n *\n * 对 CloudAgentConnection 进行降级包装,提供小程序兼容的 API。\n *\n * 降级处理清单:\n * - promptStream (async generator) → 提供 streamPromptWithCallback 回调模式替代\n * - AsyncIterable 返回类型 → 转换为 Promise + callback\n * - Optional chaining → 传统属性访问\n * - Map 使用 → 保留(小程序普遍支持 Map)\n */\n\nimport type { SessionNotification } from '@agentclientprotocol/sdk';\n\nimport { CloudAgentConnection } from '@genie/agent-provider';\n\nimport type { PromptParams } from './types';\n\n// ============================================\n// Legacy Prompt Stream API\n// [降级] async generator → callback 模式\n// ============================================\n\n/**\n * 回调式流式 prompt 方法\n *\n * 替代 CloudAgentConnection.promptStream 的 async generator API,\n * 提供基于回调的流式接口,兼容不支持 for-await-of 的环境。\n *\n * @example\n * ```typescript\n * // 原始 (ES2018+ async generator):\n * // for await (const update of connection.promptStream(sessionId, params)) {\n * // handleUpdate(update);\n * // }\n *\n * // 降级 (回调模式):\n * streamPromptWithCallback(\n * connection,\n * sessionId,\n * params,\n * function(update) { handleUpdate(update); }\n * ).then(function() {\n * console.log('Stream completed');\n * }).catch(function(err) {\n * console.error('Stream error:', err);\n * });\n * ```\n *\n * @param connection - CloudAgentConnection 实例\n * @param sessionId - 会话 ID\n * @param params - Prompt 参数\n * @param onUpdate - 每次收到 SessionNotification 时的回调\n * @param onError - 错误回调(可选)\n * @returns Promise,在流完成时 resolve\n */\nexport function streamPromptWithCallback(\n connection: CloudAgentConnection,\n sessionId: string,\n params: PromptParams,\n onUpdate: (update: SessionNotification) => void,\n onError?: (error: Error) => void\n): Promise<void> {\n // [降级] 使用 async generator 的内部迭代器协议,但通过 Promise 链消费\n var iterable = connection.promptStream(sessionId, params);\n\n // 获取异步迭代器\n var iterator: AsyncIterator<SessionNotification>;\n if (typeof Symbol !== 'undefined' && Symbol.asyncIterator) {\n iterator = (iterable as any)[Symbol.asyncIterator]();\n } else {\n // [降级] 如果 Symbol.asyncIterator 不可用,尝试直接使用迭代器协议\n iterator = (iterable as any)[Symbol.asyncIterator || '@@asyncIterator']();\n }\n\n // [降级] 递归 Promise 链替代 for-await-of\n function step(): Promise<void> {\n return iterator.next().then(function (result) {\n if (result.done) {\n return;\n }\n try {\n onUpdate(result.value);\n } catch (callbackError) {\n if (onError) {\n onError(callbackError instanceof Error ? callbackError : new Error(String(callbackError)));\n }\n }\n return step();\n }).catch(function (err) {\n if (onError) {\n onError(err instanceof Error ? err : new Error(String(err)));\n }\n throw err;\n });\n }\n\n return step();\n}\n\n/**\n * 事件驱动式流式 prompt 方法\n *\n * 使用事件监听器模式消费 prompt 流,适合框架集成场景。\n *\n * @example\n * ```typescript\n * const controller = createPromptStreamController(connection, sessionId, params);\n *\n * controller.onUpdate(function(update) {\n * renderUpdate(update);\n * });\n *\n * controller.onComplete(function() {\n * console.log('Done');\n * });\n *\n * controller.onError(function(err) {\n * console.error(err);\n * });\n *\n * // 开始流\n * controller.start();\n * ```\n */\nexport interface PromptStreamController {\n /** 注册更新回调 */\n onUpdate(callback: (update: SessionNotification) => void): void;\n /** 注册完成回调 */\n onComplete(callback: () => void): void;\n /** 注册错误回调 */\n onError(callback: (error: Error) => void): void;\n /** 开始流式传输 */\n start(): void;\n}\n\n/**\n * 创建 Prompt 流控制器\n *\n * [降级] async generator → 事件驱动控制器模式\n */\nexport function createPromptStreamController(\n connection: CloudAgentConnection,\n sessionId: string,\n params: PromptParams\n): PromptStreamController {\n var updateCallbacks: Array<(update: SessionNotification) => void> = [];\n var completeCallbacks: Array<() => void> = [];\n var errorCallbacks: Array<(error: Error) => void> = [];\n\n return {\n onUpdate: function (callback) {\n updateCallbacks.push(callback);\n },\n onComplete: function (callback) {\n completeCallbacks.push(callback);\n },\n onError: function (callback) {\n errorCallbacks.push(callback);\n },\n start: function () {\n streamPromptWithCallback(\n connection,\n sessionId,\n params,\n function (update) {\n for (var i = 0; i < updateCallbacks.length; i++) {\n try {\n updateCallbacks[i](update);\n } catch (e) {\n console.error('[LegacyStream] Update callback error:', e);\n }\n }\n },\n function (error) {\n for (var i = 0; i < errorCallbacks.length; i++) {\n try {\n errorCallbacks[i](error);\n } catch (e) {\n console.error('[LegacyStream] Error callback error:', e);\n }\n }\n }\n ).then(function () {\n for (var i = 0; i < completeCallbacks.length; i++) {\n try {\n completeCallbacks[i]();\n } catch (e) {\n console.error('[LegacyStream] Complete callback error:', e);\n }\n }\n }).catch(function (err) {\n // Error already handled by onError callback\n console.error('[LegacyStream] Unhandled stream error:', err);\n });\n }\n };\n}\n\n// ============================================\n// Re-export\n// ============================================\n\n// [保持兼容] 原始 CloudAgentConnection 仍然可用\nexport { CloudAgentConnection } from '@genie/agent-provider';\n","/**\n * Legacy Session Wrapper\n *\n * 对 ActiveSessionImpl 进行降级包装,处理 Symbol.dispose 不兼容问题,\n * 并提供回调式 promptStream 替代方案。\n *\n * 降级处理清单:\n * - [Symbol.dispose]() → 添加普通 dispose() 方法作为替代\n * - promptStream (AsyncIterable) → 提供 streamWithCallback 方法\n * - Symbol.dispose polyfill → 通过 adapter.ts 自动注入\n */\n\n// [降级] 导入 Symbol.dispose polyfill,确保在使用前已注入\nimport './adapter';\n\nimport type { SessionNotification } from '@agentclientprotocol/sdk';\n\nimport { ActiveSessionImpl } from '@genie/agent-provider';\n\nimport type { PromptParams } from './types';\n\n// ============================================\n// Legacy Session Wrapper\n// [降级] Symbol.dispose → 普通方法\n// ============================================\n\n/**\n * LegacyActiveSession - 降级版 ActiveSession 包装器\n *\n * 原始 ActiveSessionImpl 中的不兼容语法:\n *\n * 1. Symbol.dispose (ES2024):\n * ```typescript\n * // 原始:\n * [Symbol.dispose](): void {\n * this.disconnect();\n * }\n * ```\n * 降级:添加普通 dispose() 方法\n *\n * 2. promptStream 返回 AsyncIterable:\n * ```typescript\n * // 原始:\n * for await (const update of session.prompts.stream(params)) {\n * handleUpdate(update);\n * }\n * ```\n * 降级:提供 streamWithCallback 方法\n *\n * @example\n * ```typescript\n * import { createLegacySession } from '@genie/cloud-agent-sdk/legacy';\n *\n * // 包装现有 session\n * const session = await client.sessions.create({ cwd: '/workspace' });\n * const legacySession = createLegacySession(session);\n *\n * // 使用 dispose() 替代 Symbol.dispose\n * legacySession.dispose();\n *\n * // 使用回调替代 for-await-of\n * legacySession.streamWithCallback(\n * { content: 'Hello' },\n * function(update) { console.log(update); },\n * function() { console.log('done'); },\n * function(err) { console.error(err); }\n * );\n * ```\n */\nexport interface LegacyActiveSession {\n /** 原始 session 实例(所有原始属性和方法均可访问) */\n readonly session: ActiveSessionImpl;\n\n /**\n * 显式资源清理方法\n * [降级] 替代 [Symbol.dispose]()\n *\n * 原始 (ES2024):\n * ```typescript\n * { using session = await client.sessions.create(...); }\n * // session 自动清理\n * ```\n *\n * 降级:\n * ```typescript\n * const session = createLegacySession(await client.sessions.create(...));\n * try { ... } finally { session.dispose(); }\n * ```\n */\n dispose(): void;\n\n /**\n * 回调式流式 prompt\n * [降级] 替代 for-await-of 消费 AsyncIterable\n *\n * @param params - Prompt 参数\n * @param onUpdate - 每次收到更新时的回调\n * @param onComplete - 流完成时的回调\n * @param onError - 错误时的回调(可选)\n * @returns Promise,在流完成时 resolve\n */\n streamWithCallback(\n params: PromptParams,\n onUpdate: (update: SessionNotification) => void,\n onComplete?: () => void,\n onError?: (error: Error) => void\n ): Promise<void>;\n}\n\n/**\n * 创建降级版 ActiveSession 包装器\n *\n * @param session - 原始 ActiveSessionImpl 实例\n * @returns LegacyActiveSession 包装器\n */\nexport function createLegacySession(\n session: ActiveSessionImpl\n): LegacyActiveSession & ActiveSessionImpl {\n // [降级] 创建包装对象,添加 dispose 和 streamWithCallback 方法\n\n var wrapper = {\n session: session,\n\n // [降级] Symbol.dispose → dispose()\n dispose: function () {\n session.disconnect();\n },\n\n // [降级] AsyncIterable → callback\n streamWithCallback: function (\n params: PromptParams,\n onUpdate: (update: SessionNotification) => void,\n onComplete?: () => void,\n onError?: (error: Error) => void\n ): Promise<void> {\n var iterable = session.prompts.stream(params);\n var iterator: AsyncIterator<SessionNotification>;\n\n // [降级] 获取异步迭代器\n if (typeof Symbol !== 'undefined' && Symbol.asyncIterator) {\n iterator = (iterable as any)[Symbol.asyncIterator]();\n } else {\n iterator = (iterable as any)['@@asyncIterator']();\n }\n\n function step(): Promise<void> {\n return iterator.next().then(function (result) {\n if (result.done) {\n if (onComplete) {\n try {\n onComplete();\n } catch (e) {\n console.error('[LegacySession] Complete callback error:', e);\n }\n }\n return;\n }\n try {\n onUpdate(result.value);\n } catch (callbackError) {\n if (onError) {\n onError(\n callbackError instanceof Error\n ? callbackError\n : new Error(String(callbackError))\n );\n }\n }\n return step();\n }).catch(function (err) {\n var error = err instanceof Error ? err : new Error(String(err));\n if (onError) {\n try {\n onError(error);\n } catch (e) {\n console.error('[LegacySession] Error callback error:', e);\n }\n }\n throw err;\n });\n }\n\n return step();\n }\n };\n\n // 使用 Object.assign 将原始 session 的方法合并到 wrapper\n // 这样 wrapper 既有降级方法,也保留原始 session 的所有功能\n // 注意:不使用 Object.create (Proxy-like) 而是简单合并\n var combined = Object.assign(\n Object.create(Object.getPrototypeOf(session)),\n session,\n wrapper\n );\n\n return combined;\n}\n\n// ============================================\n// Re-exports\n// ============================================\n\nexport { ActiveSessionImpl } from '@genie/agent-provider';\n"],"x_google_ignoreList":[14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131],"mappings":"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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"}
|