{"version":3,"file":"index.cjs","names":["TimeoutError","TimeoutError","TimeoutError","streamableHttp"],"sources":["../src/v1/agent.ts","../src/v1/internal/log.ts","../src/v1/errors.ts","../src/v1/internal/redact.ts","../src/v1/rest/client.ts","../src/v1/acp/transport.ts","../src/v1/acp/vendor/artifacts.ts","../src/v1/acp/vendor/acp-types.ts","../src/v1/acp/vendor/constants.ts","../src/v1/acp/vendor/errors.ts","../src/v1/acp/vendor/events.ts","../src/v1/acp/vendor/extensions.ts","../src/v1/acp/vendor/permissions.ts","../src/v1/acp/vendor/questions.ts","../src/v1/acp/vendor/sdk.ts","../src/v1/acp/vendor/client.ts","../src/v1/acp/client.ts","../src/v1/session.ts","../src/v1/runtime.ts","../src/v1/client.ts","../src/v1/manifest.ts"],"sourcesContent":["/**\n * Agent — 云端 Agent 实例 + 类型定义\n *\n * 由 CloudAgentClient.agents.create() 或 .get() 返回。\n * 持有 Agent 基本信息，通过 versions / draft 子命名空间管理版本。\n *\n * 对应后端 services/cmd/console/app/path/api/agentapi 的请求/响应模型。\n * 外部路径：/v2/agentos/agents/...\n */\n\nimport type { RequestOpts } from './opts';\nimport type { RestClient } from './rest/client';\nimport type { AgentManifest, PageResult } from './types';\n\n// ============================================================\n// Agent 响应模型\n// ============================================================\n\n/** Agent 详情（create/get 返回） */\nexport interface AgentInfo {\n    id: string;\n    agentId: string;\n    agentName: string;\n    description: string;\n    avatar: string;\n    model: string;\n    manifest: Record<string, unknown> | null;\n    enabled: boolean;\n    createdAt: string;\n    updatedAt: string;\n}\n\n/** Agent 列表项（不含 manifest，减少传输） */\nexport interface AgentListItem {\n    id: string;\n    agentId: string;\n    agentName: string;\n    description: string;\n    avatar: string;\n    model: string;\n    enabled: boolean;\n    createdAt: string;\n    updatedAt: string;\n}\n\n// ============================================================\n// Version 响应模型\n// ============================================================\n\n/** 版本详情 */\nexport interface AgentVersionInfo {\n    id: string;\n    agentId: string;\n    versionNumber: string;\n    description: string;\n    isCurrent: boolean;\n    status: number;\n    model: string;\n    manifest: Record<string, unknown> | null;\n    creatorId: string;\n    creatorName: string;\n    createdAt: string;\n    updatedAt: string;\n}\n\n/** 版本列表项 */\nexport interface AgentVersionListItem {\n    id: string;\n    versionNumber: string;\n    description: string;\n    isCurrent: boolean;\n    status: number;\n    instanceCount: number;\n    creatorName: string;\n    createdAt: string;\n}\n\n// ============================================================\n// Session 响应模型\n// ============================================================\n\n/** ACP 连接信息 */\nexport interface AgentACPLink {\n    url: string;\n    token: string;\n    tokenExpiresAt: number;\n}\n\n/** 创建 Session 响应 */\nexport interface AgentSessionResponse {\n    sessionId: string;\n    runtimeId: string;\n    acp?: AgentACPLink;\n    createdAt: string;\n}\n\n// ============================================================\n// 请求体\n// ============================================================\n\n/** 创建 Agent */\nexport interface CreateAgentRequest {\n    agentName: string;\n    model: string;\n    manifest: Record<string, unknown> | AgentManifest;\n    description?: string;\n    avatar?: string;\n}\n\n/** 创建 Agent Session */\nexport interface CreateAgentSessionRequest {\n    agentId: string;\n    runtimeId: string;\n    sessionName?: string;\n}\n\n/** 发布版本 */\nexport interface PublishVersionRequest {\n    model: string;\n    manifest: Record<string, unknown> | AgentManifest;\n    description?: string;\n    agentName?: string;\n}\n\n/** 保存草稿 */\nexport interface SaveDraftRequest {\n    model: string;\n    manifest: Record<string, unknown> | AgentManifest;\n    description?: string;\n    agentName?: string;\n}\n\n// ============================================================\n// 列表响应\n// ============================================================\n\n/** 分页结果（Agent 列表专用，对齐后端） */\nexport interface AgentListResponse {\n    total: number;\n    page: number;\n    pageSize: number;\n    items: AgentListItem[];\n}\n\n/** 分页结果（Version 列表专用） */\nexport interface VersionListResponse {\n    total: number;\n    page: number;\n    pageSize: number;\n    items: AgentVersionListItem[];\n}\n\n// ============================================================\n// Agent 类\n// ============================================================\n\nexport class Agent {\n    readonly id: string;\n\n    /** Agent 详情快照 */\n    private _info: AgentInfo;\n\n    /** @internal */\n    private readonly _restClient: RestClient;\n\n    /** @internal */\n    constructor(restClient: RestClient, info: AgentInfo) {\n        this.id = info.id;\n        this._info = info;\n        this._restClient = restClient;\n    }\n\n    // ─── 公共属性 ────────────────────────────────\n\n    get agentInfo(): AgentInfo { return this._info; }\n    get agentName(): string { return this._info.agentName; }\n    get description(): string { return this._info.description; }\n    get model(): string { return this._info.model; }\n    get enabled(): boolean { return this._info.enabled; }\n\n    // ============================================================\n    // versions — 版本管理\n    // ============================================================\n\n    readonly versions = {\n        /** 版本列表 */\n        list: async (opts?: RequestOpts & { page?: number; pageSize?: number }): Promise<PageResult<AgentVersionListItem>> => {\n            const params: Record<string, string> = {};\n            if (opts?.page !== undefined) {params.page = String(opts.page);}\n            if (opts?.pageSize !== undefined) {params.pageSize = String(opts.pageSize);}\n            return this._restClient.get<PageResult<AgentVersionListItem>>(\n                `/agents/${this.id}/versions`,\n                params,\n                opts,\n            );\n        },\n\n        /** 获取版本详情 */\n        get: async (versionId: string, opts?: RequestOpts): Promise<AgentVersionInfo> => this._restClient.get<AgentVersionInfo>(\n            `/agents/${this.id}/versions/${versionId}`,\n            undefined,\n            opts,\n        ),\n\n        /** 发布新版本 */\n        publish: async (req: PublishVersionRequest, opts?: RequestOpts): Promise<AgentVersionInfo> => this._restClient.post<AgentVersionInfo>(\n            `/agents/${this.id}/versions`,\n            req,\n            opts,\n        ),\n\n        /** 删除版本 */\n        delete: async (versionId: string, opts?: RequestOpts): Promise<void> => {\n            await this._restClient.delete<void>(\n                `/agents/${this.id}/versions/${versionId}`,\n                opts,\n            );\n        },\n\n        /** 切换当前版本 */\n        setCurrent: async (versionId: string, opts?: RequestOpts): Promise<void> => {\n            await this._restClient.put<void>(\n                `/agents/${this.id}/versions/current`,\n                { versionId },\n                opts,\n            );\n        },\n    };\n\n    // ============================================================\n    // draft — 草稿管理\n    // ============================================================\n\n    readonly draft = {\n        /** 保存草稿 */\n        save: async (req: SaveDraftRequest, opts?: RequestOpts): Promise<AgentVersionInfo> => this._restClient.put<AgentVersionInfo>(\n            `/agents/${this.id}/draft`,\n            req,\n            opts,\n        ),\n\n        /** 获取草稿 */\n        get: async (opts?: RequestOpts): Promise<AgentVersionInfo | null> => this._restClient.get<AgentVersionInfo | null>(\n            `/agents/${this.id}/draft`,\n            undefined,\n            opts,\n        ),\n\n        /** 发布草稿 */\n        publish: async (description?: string, opts?: RequestOpts): Promise<AgentVersionInfo> => this._restClient.post<AgentVersionInfo>(\n            `/agents/${this.id}/draft/publish`,\n            { description },\n            opts,\n        ),\n    };\n}\n","/**\n * 日志基础设施 — 对齐 OpenAI / Anthropic 官方 SDK 的做法\n *\n * - `LogLevel`: 5 级（`'off' | 'error' | 'warn' | 'info' | 'debug'`），默认 `'warn'`\n * - `loggerFor(opts)`: 返回一个按级别过滤后的 Logger\n *   - 关闭的级别是**真正的空函数**（零字符串拼接开销）\n *   - 开放的级别**直接 `bind` 原 logger**（保留调用点栈信息）\n *   - 结果用 WeakMap 缓存，相同 `[logger, level]` 组合复用\n *\n * **日志 ID 策略**（对齐 Anthropic SDK）：\n * SDK 日志**不自造本地 ID**。唯一的定位 ID 是服务端返回的 `requestId`\n * （`x-request-id` 响应头 / 业务 `body.requestId`），会以独立 debug 行\n * `\"request_id: <id>\"` 打出，也会挂在 `CloudAgentError.requestId` 上。\n * 重试链路可读性：通过 `\"Retrying request to ... in Nms (attempt 2/3): ...\"`\n * 这种独立告警行表达\"第几次重试\"，无需额外 ID。\n * 业务维度定位（session / runtime / connection）：通过日志前缀带上业务上下文\n * （如 `[acp conn=xxx]` / `[session sess_yyy] ...`）。\n */\n\nimport type { ConnectionOpts, Logger, LogLevel } from '../opts';\n\n/** 级别数值：越大越详细；方法级别 > 当前级别时，该方法变成 noop。 */\nconst LEVEL_NUMBER: Record<LogLevel, number> = {\n    off: 0,\n    error: 200,\n    warn: 300,\n    info: 400,\n    debug: 500,\n};\n\n/** 默认级别（不配置时）。 */\nconst DEFAULT_LEVEL: LogLevel = 'warn';\n\n/** 真正的空函数。替换被关闭的级别，避免字符串拼接开销。 */\nconst noop = (): void => { /* intentionally empty */ };\n\n/** 全 noop 的 logger（内部单例）。 */\nconst noopLogger: Logger = {\n    error: noop,\n    warn: noop,\n    info: noop,\n    debug: noop,\n};\n\n/**\n * 缓存 `[baseLogger, logLevel] -> wrappedLogger`。\n *\n * 用 WeakMap<Logger, ...>：只要 user 传的 logger 引用不变、level 不变，就复用。\n */\nconst cache: WeakMap<Logger, Map<LogLevel, Logger>> = new WeakMap();\n\n/**\n * 解析级别字符串；非法值返回 undefined（调用方自行回退）。\n */\nexport function parseLogLevel(value: unknown): LogLevel | undefined {\n    if (typeof value !== 'string') return undefined;\n    const lower = value.toLowerCase();\n    if (lower in LEVEL_NUMBER) return lower as LogLevel;\n    return undefined;\n}\n\n/**\n * 读取环境变量 `CLOUD_AGENT_SDK_LOG`（仅 Node.js 环境，浏览器返回 undefined）。\n *\n * 用 `globalThis` 方式访问避免对 `@types/node` 的强依赖。\n */\nfunction readEnvLogLevel(): LogLevel | undefined {\n    const g = globalThis as { process?: { env?: Record<string, string | undefined> } };\n    const env = g.process?.env;\n    if (!env) return undefined;\n    return parseLogLevel(env.CLOUD_AGENT_SDK_LOG);\n}\n\n/**\n * 按 ConnectionOpts 决定最终的 LogLevel。\n *\n * 优先级：`opts.logLevel` > env `CLOUD_AGENT_SDK_LOG` > `'warn'`。\n */\nexport function resolveLogLevel(opts: ConnectionOpts): LogLevel {\n    return parseLogLevel(opts.logLevel)\n        ?? readEnvLogLevel()\n        ?? DEFAULT_LEVEL;\n}\n\n/**\n * 返回按 `opts` 过滤后的 Logger。\n *\n * - `opts.logger` 为空时使用 `globalThis.console`\n * - 级别关闭时返回 noop，开启时返回 `baseLogger[fn].bind(baseLogger)`\n * - 相同入参多次调用复用同一对象（WeakMap 缓存）\n */\nexport function loggerFor(opts: ConnectionOpts): Logger {\n    const base: Logger = opts.logger ?? console;\n    const level = resolveLogLevel(opts);\n\n    if (level === 'off') return noopLogger;\n\n    let byLevel = cache.get(base);\n    if (!byLevel) {\n        byLevel = new Map();\n        cache.set(base, byLevel);\n    }\n    const cached = byLevel.get(level);\n    if (cached) return cached;\n\n    const wrapped = makeLeveledLogger(base, level);\n    byLevel.set(level, wrapped);\n    return wrapped;\n}\n\n/** Logger 上真正存在的方法级别（排除 'off'）。 */\ntype LoggerMethod = Exclude<LogLevel, 'off'>;\n\n/**\n * 按级别构造 Logger：开放的级别直接 bind，关闭的级别替换为 noop。\n *\n * bind 而非 wrap 是为了保留调用点的 stack trace（开发者看日志能点回 SDK 行号）。\n */\nfunction makeLeveledLogger(base: Logger, level: LogLevel): Logger {\n    const threshold = LEVEL_NUMBER[level];\n    const enable = (fn: LoggerMethod): Logger[LoggerMethod] =>\n        LEVEL_NUMBER[fn] <= threshold && typeof base[fn] === 'function'\n            ? base[fn].bind(base)\n            : noop;\n    return {\n        error: enable('error'),\n        warn: enable('warn'),\n        info: enable('info'),\n        debug: enable('debug'),\n    };\n}\n","/**\n * 错误类型体系\n *\n * 对齐 Anthropic / OpenAI SDK 的做法 —— 只暴露**服务端 requestId**\n * 这一个定位 ID。SDK 内部日志通过 logger name (`cloud-agent-sdk`) 和\n * 业务上下文（sessionId / connectionId / runtimeId）做定位，用户侧想把\n * SDK 日志和业务日志串起来的标准姿势是 `AsyncLocalStorage` 注入业务 id\n * （见 docs 里的指南）。\n *\n * 重试决策**不**挂在错误类上。是否重试由 `RetryOpts.retryOn(err, ctx)` 统一决定\n * （见 `rest/client.ts` 里的 `DEFAULT_RETRY_ON`）。这样决策只有一个入口，\n * 用户可以通过 `retry: { retryOn: ... }` 完全覆盖。\n */\n\nexport interface CloudAgentErrorOpts {\n    code?: number;\n    httpStatus?: number;\n    /**\n     * 服务端返回的 `x-request-id` 或 body.requestId。\n     * 贴给服务端团队排障用。网络错 / 超时时可能为 `undefined`\n     * （请求还没到服务端），此时排查靠客户端日志（logger `cloud-agent-sdk`）。\n     */\n    requestId?: string;\n    cause?: Error;\n}\n\nexport class CloudAgentError extends Error {\n    readonly code: number;\n    readonly httpStatus?: number;\n    readonly requestId?: string;\n    readonly originalCause?: Error;\n\n    constructor(message: string, opts: CloudAgentErrorOpts = {}) {\n        super(message);\n        this.name = 'CloudAgentError';\n        this.code = opts.code ?? -1;\n        this.httpStatus = opts.httpStatus;\n        this.requestId = opts.requestId;\n        this.originalCause = opts.cause;\n        // ES2022 cause polyfill\n        if (opts.cause && !('cause' in this)) {\n            Object.defineProperty(this, 'cause', { value: opts.cause, writable: false });\n        }\n    }\n}\n\nexport class NetworkError extends CloudAgentError {\n    constructor(message: string, opts?: CloudAgentErrorOpts) {\n        super(message, opts);\n        this.name = 'NetworkError';\n    }\n}\n\nexport class TimeoutError extends CloudAgentError {\n    constructor(message: string, opts?: CloudAgentErrorOpts) {\n        super(message, opts);\n        this.name = 'TimeoutError';\n    }\n}\n\nexport class AuthError extends CloudAgentError {\n    constructor(message: string, opts?: CloudAgentErrorOpts) {\n        super(message, opts);\n        this.name = 'AuthError';\n    }\n}\n\nexport class NotFoundError extends CloudAgentError {\n    constructor(message: string, opts?: CloudAgentErrorOpts) {\n        super(message, opts);\n        this.name = 'NotFoundError';\n    }\n}\n\nexport class ValidationError extends CloudAgentError {\n    constructor(message: string, opts?: CloudAgentErrorOpts) {\n        super(message, opts);\n        this.name = 'ValidationError';\n    }\n}\n\nexport class AcpProtocolError extends CloudAgentError {\n    constructor(message: string, opts?: CloudAgentErrorOpts) {\n        super(message, opts);\n        this.name = 'AcpProtocolError';\n    }\n}\n","/**\n * 敏感信息脱敏\n *\n * 范围：headers + 特定已知的 body 字段（白名单 path，非启发式猜测）。\n * 脱敏仅作用于日志打印和钩子回调，不影响实际发送的请求。\n *\n * 详见 docs/agentos/sdk/07-error-retry.md § 4.5。\n */\n\n/** 需要脱敏的 header 名（小写）。 */\nconst SENSITIVE_HEADER_NAMES: ReadonlySet<string> = new Set([\n    'authorization',\n    'cookie',\n    'set-cookie',\n    'x-api-key',\n]);\n\n/** 脱敏替换值。 */\nconst REDACTED = '***';\n\n/**\n * 返回脱敏后的 headers 副本。\n *\n * - 键按原样保留（大小写不变）\n * - 值按键名（小写后）匹配敏感列表时替换为 `'***'`\n * - **纯函数**，不修改入参\n */\nexport function redactHeaders(\n    headers: Record<string, string> | undefined,\n): Record<string, string> {\n    if (!headers) return {};\n    const out: Record<string, string> = {};\n    for (const [name, value] of Object.entries(headers)) {\n        out[name] = SENSITIVE_HEADER_NAMES.has(name.toLowerCase()) ? REDACTED : value;\n    }\n    return out;\n}\n\n/**\n * 给定一个 header 名是否属于敏感名（小写比较）。\n *\n * 供扩展处使用（如需要自定义 Headers/Map 迭代的场景）。\n */\nexport function isSensitiveHeader(name: string): boolean {\n    return SENSITIVE_HEADER_NAMES.has(name.toLowerCase());\n}\n\n// ─── Body 脱敏 ────────────────────────────────\n//\n// 与 OpenAI / Anthropic 官方 SDK 不同：它们的 body 只含 prompt / messages / tools\n// 等业务内容，没有高敏感字段，所以不脱敏。\n//\n// 我们的 `runtimes.create` / `sessions.create` body 里会携带 `agentManifest.secrets[].value`\n// —— 用户业务下发到 sandbox 的真实密钥（数据库密码、第三方 API Key 等），\n// 泄露后果远超 apiKey（apiKey 泄露只影响当前调用方，secret 泄露影响用户业务的下游）。\n//\n// 策略：\n// - **白名单**：只处理已知的、明确含密钥的字段（而非启发式猜测字段名）\n// - **深克隆**：不修改原始 body，只在日志/钩子里使用脱敏副本\n// - **未来扩展**：新增敏感字段时显式加到下面的 REDACTOR 表\n\n/** 判断 value 是否是对象数组（`Array<Record<string, unknown>>`）。 */\nfunction isObjectArray(v: unknown): v is Array<Record<string, unknown>> {\n    return Array.isArray(v) && v.every(x => x !== null && typeof x === 'object' && !Array.isArray(x));\n}\n\n/**\n * Body 脱敏器：对给定对象做**浅复制 + 定向脱敏**，返回安全的日志副本。\n *\n * 不修改入参。若入参不是对象（string / number / ...），原样返回。\n *\n * 已处理字段：\n * - `agentManifest.secrets[].value` → `'***'`（保留 name，只脱 value）\n */\nexport function redactBody(body: unknown): unknown {\n    if (body === null || body === undefined) return body;\n    if (typeof body !== 'object' || Array.isArray(body)) return body;\n\n    const input = body as Record<string, unknown>;\n    // 浅复制 + 按 path 定向深复制\n    const out: Record<string, unknown> = { ...input };\n\n    // agentManifest.secrets[].value\n    const manifest = input.agentManifest as Record<string, unknown> | undefined;\n    if (manifest && typeof manifest === 'object' && !Array.isArray(manifest)) {\n        const secrets = manifest.secrets;\n        if (isObjectArray(secrets)) {\n            out.agentManifest = {\n                ...manifest,\n                secrets: secrets.map(s => (\n                    'value' in s ? { ...s, value: REDACTED } : s\n                )),\n            };\n        }\n    }\n\n    return out;\n}\n","/**\n * REST 客户端 — 基于原生 fetch\n *\n * 职责：\n * - 注入认证 / 身份 / 自定义 header（apiKey / source* / user 定制）\n * - 统一解包 `{ code, msg, data, requestId }`，非 0 抛 `CloudAgentError`\n * - 超时控制（AbortController + AbortSignal 合并）\n * - 重试（指数退避 + 抖动；默认仅 GET 重试，非 GET 需显式 `retry`）\n * - 日志：对齐 Anthropic SDK —— 日志行不带自造 ID，只带**服务端 requestId**\n *   作为定位 ID；\"是否在重试 / 第几次重试\" 通过独立的告警行 + `attempt=N/M`\n *   字段表达，而非自造 logId/retryOf 链\n * - 脱敏：onRequest / onResponse 钩子 + debug 日志里的 headers 自动脱敏\n */\n\nimport {\n    AcpProtocolError,\n    AuthError,\n    CloudAgentError,\n    NetworkError,\n    NotFoundError,\n    TimeoutError,\n    ValidationError,\n} from '../errors';\nimport { loggerFor } from '../internal/log';\nimport { redactBody, redactHeaders } from '../internal/redact';\nimport type { ConnectionOpts, Logger, RequestOpts, RetryContext, RetryOn,RetryOpts } from '../opts';\n\ninterface ApiResponse<T = unknown> {\n    code: number;\n    msg: string;\n    requestId: string;\n    data?: T;\n}\n\n/** 默认 baseUrl */\nconst DEFAULT_BASE_URL = 'https://www.codebuddy.cn/v2/agentos';\n\n/**\n * SDK 内置的默认重试判定。\n *\n * 传 `retry: { retryOn: ... }` 会**完全替换**这里的规则（不叠加）。\n * 公开这个函数是为了让用户在自定义 `retryOn` 里可以手动调用回落到默认：\n *\n * ```ts\n * retry: {\n *     retryOn: (err, ctx) => {\n *         if (err instanceof TimeoutError && ctx.url.includes('/upload')) return false;\n *         return DEFAULT_RETRY_ON(err, ctx);\n *     },\n * }\n * ```\n */\nexport const DEFAULT_RETRY_ON: RetryOn = (err: Error, ctx: RetryContext): boolean => {\n    // 用户主动取消\n    if (err.name === 'AbortError') {return false;}\n\n    // SDK 业务错误：按类型决定\n    if (err instanceof AuthError) {return false;}\n    if (err instanceof NotFoundError) {return false;}\n    if (err instanceof ValidationError) {return false;}\n    if (err instanceof AcpProtocolError) {return false;}\n\n    // 超时：仅幂等方法（GET）重试。POST / PATCH / DELETE 超时可能已成功执行，\n    // 重试会造成重复副作用（如重复创建 Runtime）。\n    if (err instanceof TimeoutError) {return ctx.method === 'GET';}\n\n    // 网络错误：所有方法都可重试（连接根本没成功，不会有副作用）\n    if (err instanceof NetworkError) {return true;}\n\n    // 其他未知错误（例如 fetch 抛的原生 TypeError）：保守重试\n    return true;\n};\n\n/** 默认重试配置。 */\nconst DEFAULT_RETRY: Required<RetryOpts> = {\n    maxAttempts: 3,\n    backoffMs: 300,\n    backoffFactor: 2,\n    jitter: true,\n    retryOn: DEFAULT_RETRY_ON,\n};\n\n/** 单次请求的内部上下文（跨 doRequest 复用）。 */\ninterface RequestContext {\n    /** 尝试编号：首次=1，每次重试 +1。 */\n    attempt: number;\n    startTimeMs: number;\n}\n\nexport class RestClient {\n    private readonly opts: ConnectionOpts;\n    private readonly logger: Logger;\n    private readonly fetchImpl: typeof fetch;\n\n    constructor(opts: ConnectionOpts) {\n        this.opts = opts;\n        this.logger = loggerFor(opts);\n        // 逃生舱：允许业务替换 fetch（如 OTel instrumented fetch）；\n        // 保留 bind(globalThis) 避免某些 runtime 上 this 绑定问题。\n        const userFetch = opts.fetch;\n        this.fetchImpl = userFetch ?? fetch.bind(globalThis);\n    }\n\n    /** GET 请求。 */\n    async get<T>(path: string, query?: Record<string, string>, opts?: RequestOpts): Promise<T> {\n        const url = this.buildUrl(path, query);\n        return this.request<T>('GET', url, undefined, opts);\n    }\n\n    /** POST 请求。 */\n    async post<T>(path: string, body?: unknown, opts?: RequestOpts): Promise<T> {\n        const url = this.buildUrl(path);\n        return this.request<T>('POST', url, body, opts);\n    }\n\n    /** PUT 请求。 */\n    async put<T>(path: string, body?: unknown, opts?: RequestOpts): Promise<T> {\n        const url = this.buildUrl(path);\n        return this.request<T>('PUT', url, body, opts);\n    }\n\n    /** PATCH 请求。 */\n    async patch<T>(path: string, body?: unknown, opts?: RequestOpts): Promise<T> {\n        const url = this.buildUrl(path);\n        return this.request<T>('PATCH', url, body, opts);\n    }\n\n    /** DELETE 请求。 */\n    async delete<T>(path: string, opts?: RequestOpts): Promise<T> {\n        const url = this.buildUrl(path);\n        return this.request<T>('DELETE', url, undefined, opts);\n    }\n\n    //\n    // 是否重试由 `RetryOpts.retryOn(err, ctx)` 统一决定（见 DEFAULT_RETRY_ON）：\n    // GET/POST/PATCH/DELETE 全部进入 retry 链路，retryOn 按错误类型 + method\n    // 精确决策（非幂等方法超时默认不重试，避免副作用）。\n\n    // ─── 内部方法 ────────────────────────────────\n\n    /** 构建完整 URL。 */\n    private buildUrl(path: string, query?: Record<string, string>): string {\n        const base = (this.opts.baseUrl || DEFAULT_BASE_URL).replace(/\\/+$/, '');\n        const fullPath = path.startsWith('/') ? path : `/${path}`;\n        const url = new URL(`${base}${fullPath}`);\n\n        if (query) {\n            for (const [k, v] of Object.entries(query)) {\n                if (v !== undefined && v !== '') {\n                    url.searchParams.set(k, v);\n                }\n            }\n        }\n\n        return url.toString();\n    }\n\n    /** 构建请求 headers（含认证、身份、trace、自定义）。 */\n    private buildHeaders(opts?: RequestOpts): Record<string, string> {\n        const headers: Record<string, string> = {\n            'Content-Type': 'application/json',\n            'Accept': 'application/json',\n        };\n\n        // 认证：仅支持 apiKey（后端场景）；浏览器场景通过 baseUrl 代理或自定义 headers 注入鉴权\n        // pt_ 前缀的幻影令牌必须通过 Authorization: Bearer 传递（网关 phantom-token 插件仅从该 header 提取）\n        // ck_ 等其他前缀继续使用 x-api-key header\n        if (this.opts.apiKey) {\n            if (this.opts.apiKey.startsWith('pt_')) {\n                headers['Authorization'] = `Bearer ${this.opts.apiKey}`;\n            } else {\n                headers['X-Api-Key'] = this.opts.apiKey;\n            }\n        }\n\n        // 身份 headers\n        // sourceApp 默认 'cloud-agent'：避免服务端 fallback 到 'default-app'\n        // 后者会被 ListRuntimes SQL 的硬编码条件 `source_app != 'default-app'` 过滤掉\n        headers['X-Source-App'] = this.opts.sourceApp || 'cloud-agent';\n        if (this.opts.sourceTenantId) {headers['X-Source-Tenant-Id'] = this.opts.sourceTenantId;}\n        if (this.opts.userId) {headers['X-User-Id'] = this.opts.userId;}\n\n        // 全局自定义 headers\n        if (this.opts.headers) {Object.assign(headers, this.opts.headers);}\n\n        // 逐请求覆盖 headers（用户可塞 traceparent 等，SDK 原样透传）\n        if (opts?.headers) {Object.assign(headers, opts.headers);}\n\n        // Request ID（不传则生成 UUID，用于服务端请求识别）\n        headers['X-Request-Id'] = opts?.requestId ?? generateRequestId();\n\n        return headers;\n    }\n\n    /** 发起请求（含超时 + 重试 + 日志 + 脱敏 + hooks）。 */\n    private async request<T>(method: string, url: string, body?: unknown, opts?: RequestOpts): Promise<T> {\n        // 确定重试策略。优先级：per-request `opts.retry` > 全局 `this.opts.retry` > DEFAULT_RETRY。\n        // 传 `false` 关闭重试；method 相关的精细决策交给 `retryOn(err, ctx)`。\n        const shouldRetry: RetryOpts | false = opts?.retry !== undefined\n            ? opts.retry\n            : this.opts.retry ?? DEFAULT_RETRY;\n\n        const ctx: RequestContext = {\n            attempt: 1,\n            startTimeMs: 0,\n        };\n\n        const doRequest = async (): Promise<T> => {\n            ctx.startTimeMs = Date.now();\n            const timeoutMs = opts?.timeoutMs ?? this.opts.timeoutMs ?? 30_000;\n            const headers = this.buildHeaders(opts);\n            const requestId = headers['X-Request-Id'];\n\n            // 构建 abort 信号\n            const controller = new AbortController();\n            let timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n            if (timeoutMs > 0) {\n                timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n            }\n\n            // 外部 signal 合并\n            if (opts?.signal) {\n                if (opts.signal.aborted) {\n                    controller.abort();\n                } else {\n                    opts.signal.addEventListener('abort', () => controller.abort(), { once: true });\n                }\n            }\n\n            const redactedReqHeaders = redactHeaders(headers);\n\n            // 触发 onRequest hook（传脱敏后的 headers 副本）\n            this.opts.onRequest?.({ method, url, headers: { ...redactedReqHeaders } });\n\n            // 对齐 Anthropic SDK：debug 两段（发出 + 响应）+ 独立 request_id 行。\n            // 首次请求不带 attempt 前缀（减噪音），重试由 withRetry 的独立告警行承担。\n            this.logger.debug(\n                `Sending HTTP Request: ${method} ${url}`,\n                {\n                    headers: redactedReqHeaders,\n                    body: body !== undefined ? truncate(redactBody(body)) : undefined,\n                },\n            );\n\n            try {\n                const response = await this.fetchImpl(url, {\n                    method,\n                    headers,\n                    body: body !== undefined ? JSON.stringify(body) : undefined,\n                    signal: controller.signal,\n                });\n\n                const durationMs = Date.now() - ctx.startTimeMs;\n\n                // 收集响应 headers（脱敏后用于 hook/日志）\n                const responseHeaders: Record<string, string> = {};\n                response.headers.forEach((v, k) => { responseHeaders[k] = v; });\n                const redactedResHeaders = redactHeaders(responseHeaders);\n\n                this.opts.onResponse?.({\n                    status: response.status,\n                    headers: { ...redactedResHeaders },\n                    url,\n                });\n\n                // 服务端 request-id 响应头（不同于客户端传的 X-Request-Id，部分网关会回填）\n                const serverReqId = response.headers.get('x-request-id') ?? requestId;\n                // 对齐 Anthropic：\n                //   HTTP Response: POST <url> \"201 Created\" durationMs=...\n                //   request_id: <serverReqId>\n                this.logger.debug(\n                    `HTTP Response: ${method} ${url} \"${response.status} ${response.statusText}\" durationMs=${durationMs}`,\n                    { headers: redactedResHeaders },\n                );\n                if (serverReqId) {\n                    this.logger.debug(`request_id: ${serverReqId}`);\n                }\n\n                // 解包\n                return await this.unwrap<T>(response, serverReqId);\n            } catch (err) {\n                if (timeoutId) {clearTimeout(timeoutId);}\n\n                const durationMs = Date.now() - ctx.startTimeMs;\n\n                // AbortError → 判断是超时还是用户取消\n                if (err instanceof Error && err.name === 'AbortError') {\n                    if (opts?.signal?.aborted) {\n                        this.logger.debug(\n                            `Request cancelled by caller after ${durationMs}ms: ${method} ${url}`,\n                        );\n                        throw err; // 用户主动取消，不包装\n                    }\n                    // 超时：仅 GET 默认重试（见 DEFAULT_RETRY_ON），非 GET 超时\n                    // 立即抛出避免重复副作用。这里只打 debug，避免重试循环里\n                    // \"Request timed out\" warn + withRetry 的 \"retrying\" warn 双倍刷屏。\n                    // 最终失败（重试耗尽）由调用方 catch 决定是否上报。\n                    const msg = `Request timed out after ${timeoutMs}ms: ${method} ${url}`;\n                    this.logger.debug(msg);\n                    throw new TimeoutError(msg, { cause: err });\n                }\n\n                // fetch 网络错误\n                // 注意：这里只打 debug，真正可见的重试告警由 withRetry 的 \"retrying...\" warn 承担，\n                // 避免重试循环中 \"NetworkError\" warn + \"retrying\" warn 双倍刷屏。\n                // 最终失败（重试耗尽）时由调用方的 catch 决定是否上报。\n                if (err instanceof TypeError || (err instanceof Error && isNetworkError(err))) {\n                    const msg = `Network error: ${method} ${url} - ${(err as Error).message}`;\n                    this.logger.debug(msg);\n                    throw new NetworkError(msg, {\n                        cause: err as Error,\n                    });\n                }\n\n                // 已是 CloudAgentError 则直接抛（它本身已带 requestId）\n                if (err instanceof CloudAgentError) {\n                    throw err;\n                }\n\n                // 意外异常（非网络、非超时、非业务错）：值得 error 级别\n                const msg = `Unexpected error: ${method} ${url} - ${(err as Error).message}`;\n                this.logger.error(msg);\n                throw new NetworkError(msg, { cause: err as Error });\n            } finally {\n                if (timeoutId) {clearTimeout(timeoutId);}\n            }\n        };\n\n        // 包装重试\n        if (shouldRetry === false) {\n            return doRequest();\n        }\n\n        return this.withRetry(doRequest, shouldRetry, ctx, method, url);\n    }\n\n    /** 解包响应 `{ code, msg, data }` → `data` 或抛错。 */\n    private async unwrap<T>(response: Response, serverReqId?: string): Promise<T> {\n        // 对于 204 No Content\n        if (response.status === 204) {\n            return undefined as unknown as T;\n        }\n\n        let body: ApiResponse<T> | undefined;\n        let rawText: string;\n        try {\n            // 用 text + 正则处理 int64 大数精度丢失\n            // 将 17 位及以上的纯数字值转为字符串（MAX_SAFE_INTEGER = 9007199254740991，16 位）\n            rawText = await response.text();\n            const safeText = rawText.replace(\n                /:\\s*(\\d{17,})/g,\n                (match, num) => match.replace(num, `\"${num}\"`),\n            );\n            body = JSON.parse(safeText) as ApiResponse<T>;\n        } catch {\n            // 非 JSON 响应\n            if (!response.ok) {\n                throw this.httpStatusToError(response.status, `HTTP ${response.status}`, {\n                    requestId: serverReqId,\n                });\n            }\n            return (rawText! as unknown) as T;\n        }\n\n        // 服务端返回的 requestId 两个来源：\n        // - body.requestId：由 middleware 写入 gin ctx 后由错误/成功响应包装器读出（业务层值）\n        // - response header X-Request-Id：由 RequestIDMiddleware 直接回显\n        // 两者在正常路径上是同一个值（都来自 middleware），优先 body 是因为：\n        //   1) 4xx/5xx 非 JSON 时 body 可能解析不到，header 是最后兜底\n        //   2) body 是服务端\"明确意图\"返回的字段，header 可能被反代重写\n        // 服务端源码: services/pkg/middleware/request_id.go\n        const effectiveRequestId = body.requestId || serverReqId;\n\n        // HTTP 层错误\n        if (!response.ok) {\n            throw this.httpStatusToError(\n                response.status,\n                body.msg || `HTTP ${response.status}`,\n                { requestId: effectiveRequestId, code: body.code },\n            );\n        }\n\n        // 业务层错误 (code !== 0)\n        if (body.code !== 0) {\n            throw this.codeToError(body.code, body.msg, {\n                requestId: effectiveRequestId,\n                httpStatus: response.status,\n            });\n        }\n\n        return body.data as T;\n    }\n\n    /** HTTP 状态码映射为错误。 */\n    private httpStatusToError(\n        status: number,\n        message: string,\n        ctx: { requestId?: string; code?: number },\n    ): CloudAgentError {\n        const opts = { httpStatus: status, requestId: ctx.requestId, code: ctx.code };\n\n        switch (status) {\n            case 400:\n                return new ValidationError(message, opts);\n            case 401:\n            case 403:\n                return new AuthError(message, opts);\n            case 404:\n                return new NotFoundError(message, opts);\n            case 408:\n            case 504:\n                return new TimeoutError(message, opts);\n            case 429:\n                return new NetworkError(message, opts);\n            default:\n                if (status >= 500) {\n                    return new NetworkError(message, opts);\n                }\n                return new CloudAgentError(message, opts);\n        }\n    }\n\n    /** 业务 code 映射为错误。 */\n    private codeToError(\n        code: number,\n        message: string,\n        ctx: { requestId?: string; httpStatus?: number },\n    ): CloudAgentError {\n        const opts = { code, httpStatus: ctx.httpStatus, requestId: ctx.requestId };\n\n        // 按照 code 映射到具体子类\n        switch (code) {\n            case 10001:\n                return new ValidationError(message, opts);\n            case 10034:\n            case 10085:\n                return new AuthError(message, opts);\n            case 10064:\n            case 10065:\n            case 10067:\n                return new NetworkError(message, opts);\n            case 10084:\n                return new NotFoundError(message, opts);\n            case 10094:\n                return new TimeoutError(message, opts);\n            case 10000:\n                return new NetworkError(message, opts);\n            default:\n                return new CloudAgentError(message, opts);\n        }\n    }\n\n    /**\n     * 重试逻辑。\n     *\n     * 是否重试只看 `opts.retryOn(err, ctx)`。用户传的 retryOn **完全替换** SDK\n     * 默认判定（不叠加、不 fallback 到 error 类上的任何字段）。\n     */\n    private async withRetry<T>(\n        fn: () => Promise<T>,\n        retryOpts: RetryOpts,\n        reqCtx: RequestContext,\n        method: string,\n        url: string,\n    ): Promise<T> {\n        const opts = { ...DEFAULT_RETRY, ...retryOpts };\n        let lastError: Error | undefined;\n\n        for (let attempt = 1; attempt <= opts.maxAttempts; attempt++) {\n            reqCtx.attempt = attempt;\n            try {\n                return await fn();\n            } catch (err) {\n                lastError = err as Error;\n\n                const retryCtx: RetryContext = { attempt, method, url };\n                if (!opts.retryOn(err as Error, retryCtx)) {\n                    throw err;\n                }\n\n                // 最后一次尝试不再退避\n                if (attempt >= opts.maxAttempts) {\n                    break;\n                }\n\n                const delayMs = this.getBackoffMs(attempt, opts);\n                // 对齐 Anthropic：\"Retrying request to ... in N seconds\"\n                this.logger.warn(\n                    `Retrying request to ${method} ${url} in ${delayMs}ms (attempt ${attempt}/${opts.maxAttempts}): ${(err as Error).name}: ${(err as Error).message}`,\n                );\n\n                await sleep(delayMs);\n            }\n        }\n\n        throw lastError ?? new Error('Retry exhausted with no captured error');\n    }\n\n    /** 计算退避时间。 */\n    private getBackoffMs(attempt: number, opts: Required<RetryOpts>): number {\n        const baseDelay = Math.min(\n            opts.backoffMs * Math.pow(opts.backoffFactor, attempt - 1),\n            30_000, // 最大退避 30s\n        );\n\n        if (!opts.jitter) {\n            return Math.round(baseDelay);\n        }\n\n        // ±20% 随机抖动\n        const jitterFactor = 0.2 * (Math.random() * 2 - 1);\n        return Math.round(baseDelay * (1 + jitterFactor));\n    }\n}\n\n// ─── 工具函数 ────────────────────────────────\n\nfunction sleep(ms: number): Promise<void> {\n    return new Promise(resolve => setTimeout(resolve, ms));\n}\n\nfunction isNetworkError(err: Error): boolean {\n    const msg = err.message.toLowerCase();\n    return msg.includes('failed to fetch')\n        || msg.includes('fetch failed')\n        || msg.includes('network')\n        || msg.includes('econnrefused')\n        || msg.includes('econnreset')\n        || msg.includes('enotfound')\n        || msg.includes('socket hang up');\n}\n\nfunction generateRequestId(): string {\n    // 简单的随机 ID 生成，兼容浏览器和 Node.js\n    if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n        return crypto.randomUUID();\n    }\n    // Fallback: 简易实现\n    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {\n        const r = Math.random() * 16 | 0;\n        const v = c === 'x' ? r : (r & 0x3 | 0x8);\n        return v.toString(16);\n    });\n}\n\n/**\n * 截断超长 body 用于 debug 日志，避免刷屏。\n *\n * 调用方应先通过 `redactBody()` 做敏感字段脱敏，此函数只负责序列化 + 截断。\n */\nfunction truncate(body: unknown, maxChars = 500): string {\n    try {\n        const str = typeof body === 'string' ? body : JSON.stringify(body);\n        if (str.length <= maxChars) {return str;}\n        return str.slice(0, maxChars) + `…(truncated, total ${str.length} chars)`;\n    } catch {\n        return '[unserializable]';\n    }\n}\n","/**\n * Streamable HTTP Transport for ACP\n *\n * 从 @genie/agent-client-protocol/src/common/transport/streamable-http.ts 迁移。\n * 实现官方 @agentclientprotocol/sdk 的 Stream 接口。\n *\n * 协议流程:\n *   1. Client 建立 GET SSE 连接，获取 Acp-Connection-Id\n *   2. Client 通过 POST 发送 JSON-RPC 请求（携带 Acp-Connection-Id header）\n *   3. 通知通过 GET SSE 推送，响应通过 POST SSE 返回\n *\n * 稳定性保证:\n *   - 指数退避自动重连 + ±25% jitter\n *   - Last-Event-ID 断点续传\n *   - Acp-Connection-Id 复用\n *   - 心跳超时检测（默认 60s）\n *   - connectionVersion 防竞态\n *   - backpressure 保护（highWaterMark/lowWaterMark）\n *   - POST SSE 后台处理（防死锁）\n */\n\nexport interface StreamableHttpTransportOptions {\n    /** ACP endpoint URL */\n    endpoint: string;\n    /** Authorization token (Bearer) */\n    authToken?: string;\n    /** Custom headers */\n    headers?: Record<string, string>;\n    /** Initial Last-Event-ID for replay/resume on a fresh connection. */\n    lastEventId?: string;\n    /** Reconnect options */\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 (±25%)\n    };\n    /** AbortSignal to cancel */\n    signal?: AbortSignal;\n    /** Custom fetch */\n    fetch?: typeof fetch;\n    /** Callbacks */\n    onConnect?: (connectionId: string) => void;\n    onDisconnect?: (connectionId: string) => void;\n    onError?: (error: Error) => void;\n    /** Heartbeat timeout ms (default: 60000). 0 to disable. */\n    heartbeatTimeout?: number;\n    /** Connection establishment timeout ms (default: 30000) */\n    connectionTimeout?: number;\n    /** POST request timeout ms (default: 30000) */\n    postTimeout?: number;\n    /** Backpressure options */\n    backpressure?: {\n        highWaterMark?: number;  // default: 100\n        lowWaterMark?: number;   // default: 50\n        pauseTimeout?: number;   // default: 5000ms\n    };\n}\n\n/** Transport 接口（兼容 @agentclientprotocol/sdk 的 Stream） */\nexport interface StreamableHttpTransport {\n    readonly readable: ReadableStream<unknown>;\n    readonly writable: WritableStream<unknown>;\n    readonly connectionId: string | undefined;\n    readonly ready: Promise<void>;\n    close(): Promise<void>;\n}\n\ninterface SSEEvent {\n    type: string;\n    data: string;\n    id?: string;\n}\n\n/**\n * 创建 Streamable HTTP transport。\n * 返回的对象实现 Stream 接口（readable + writable），可直接传给 ClientSideConnection。\n */\nexport function createStreamableHttpTransport(options: StreamableHttpTransportOptions): StreamableHttpTransport {\n    const {\n        endpoint,\n        authToken,\n        headers: customHeaders = {},\n        lastEventId: initialLastEventId,\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    // 连接状态\n    let connectionId: string | undefined;\n    let lastEventId: string | undefined = initialLastEventId;\n    let reconnectAttempts = 0;\n    let closed = false;\n    let isClosing = false;\n    let connectionVersion = 0;\n\n    // 连接就绪 promise\n    let connectionReady: Promise<void>;\n    let resolveConnection: () => void;\n    let rejectConnection: (error: Error) => void;\n\n    connectionReady = new Promise((resolve, reject) => {\n        resolveConnection = resolve;\n        rejectConnection = reject;\n    });\n\n    const abortController = new AbortController();\n\n    function isAborted(): boolean {\n        return abortController.signal.aborted || (externalSignal?.aborted ?? false);\n    }\n\n    // 消息队列 + backpressure\n    const messageQueue: unknown[] = [];\n    const messageResolvers: Array<(value: unknown | null) => void> = [];\n    let streamError: Error | null = null;\n    let isPaused = false;\n    let resumeReading: (() => void) | null = null;\n\n    // 心跳\n    let lastActivity = Date.now();\n    let heartbeatCheckTimer: ReturnType<typeof setInterval> | undefined;\n\n    function enqueueMessage(message: unknown): void {\n        if (messageResolvers.length > 0) {\n            messageResolvers.shift()!(message);\n        } else {\n            messageQueue.push(message);\n            if (messageQueue.length >= highWaterMark) {\n                isPaused = true;\n            }\n        }\n    }\n\n    function dequeueMessage(): Promise<unknown | null> {\n        if (closed) {return Promise.resolve(null);}\n        if (streamError) {return Promise.reject(streamError);}\n        if (messageQueue.length > 0) {\n            const message = messageQueue.shift()!;\n            if (isPaused && messageQueue.length <= lowWaterMark) {\n                isPaused = false;\n                if (resumeReading) { queueMicrotask(() => resumeReading!()); }\n            }\n            return Promise.resolve(message);\n        }\n        return new Promise(resolve => { messageResolvers.push(resolve); });\n    }\n\n    function updateLastActivity(): void { lastActivity = Date.now(); }\n\n    function startHeartbeatCheck(triggerReconnect: () => void): void {\n        if (heartbeatTimeout <= 0) {return;}\n        heartbeatCheckTimer = setInterval(() => {\n            if (Date.now() - lastActivity > heartbeatTimeout) {\n                triggerReconnect();\n            }\n        }, 10000);\n    }\n\n    function stopHeartbeatCheck(): void {\n        if (heartbeatCheckTimer) { clearInterval(heartbeatCheckTimer); heartbeatCheckTimer = undefined; }\n    }\n\n    function calculateDelay(attempt: number): number {\n        const baseDelay = Math.min(initialDelay * Math.pow(2, attempt - 1), maxDelay);\n        if (!jitterEnabled) {return baseDelay;}\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        if (resumeReading) { resumeReading(); resumeReading = null; }\n        rejectConnection(error);\n        onError?.(error);\n        while (messageResolvers.length > 0) { messageResolvers.shift()!(null); }\n    }\n\n    function closeNormally(): void {\n        closed = true;\n        stopHeartbeatCheck();\n        if (resumeReading) { resumeReading(); resumeReading = null; }\n        while (messageResolvers.length > 0) { messageResolvers.shift()!(null); }\n    }\n\n    function buildHeaders(): Record<string, string> {\n        const headers: Record<string, string> = { ...customHeaders };\n        if (authToken) {headers['Authorization'] = `Bearer ${authToken}`;}\n        return headers;\n    }\n\n    // SSE 流处理\n    async function processSSEStream(reader: ReadableStreamDefaultReader<Uint8Array>): Promise<void> {\n        const decoder = new TextDecoder();\n        let buffer = '';\n        let currentEvent: Partial<SSEEvent> = {};\n\n        try {\n            while (true) {\n                if (isPaused) {\n                    await new Promise<void>(resolve => {\n                        let resolved = false;\n                        const timeoutId = setTimeout(() => {\n                            if (!resolved) { resolved = true; resolve(); }\n                        }, pauseTimeout);\n                        resumeReading = () => {\n                            if (!resolved) { resolved = true; clearTimeout(timeoutId); resolve(); }\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                    if (line === '') {\n                        if (currentEvent.data) {\n                            updateLastActivity();\n                            if (currentEvent.id) {lastEventId = currentEvent.id;}\n                            if (currentEvent.type === 'message' || !currentEvent.type) {\n                                try {\n                                    const message = JSON.parse(currentEvent.data);\n                                    if (message && typeof message === 'object' && 'jsonrpc' in message) {\n                                        enqueueMessage(message);\n                                    }\n                                } catch { /* ignore */ }\n                            }\n                        }\n                        currentEvent = {};\n                    } else if (line.startsWith(':')) {\n                        updateLastActivity(); // 心跳\n                    } else {\n                        const colonIdx = line.indexOf(':');\n                        if (colonIdx === -1) {continue;}\n                        const field = line.slice(0, colonIdx);\n                        let val = line.slice(colonIdx + 1);\n                        if (val.startsWith(' ')) {val = val.slice(1);}\n                        switch (field) {\n                            case 'event':\n                                if (currentEvent.type && currentEvent.type !== val) {currentEvent.data = undefined;}\n                                currentEvent.type = val; break;\n                            case 'data':\n                                currentEvent.data = (currentEvent.data || '') + val; break;\n                            case 'id':\n                                currentEvent.id = val; break;\n                        }\n                    }\n                }\n            }\n        } finally {\n            reader.releaseLock();\n        }\n    }\n\n    function processSSEStreamBackground(reader: ReadableStreamDefaultReader<Uint8Array>): void {\n        processSSEStream(reader).catch(error => {\n            onError?.(error instanceof Error ? error : new Error(String(error)));\n        });\n    }\n\n    // GET SSE 连接循环\n    async function startSSEConnection(): Promise<void> {\n        let currentReader: ReadableStreamDefaultReader<Uint8Array> | null = null;\n\n        const triggerReconnect = (): void => {\n            currentReader?.cancel().catch(() => {});\n        };\n\n        while (!closed && !isAborted()) {\n            try {\n                const headers = buildHeaders();\n                headers['Accept'] = 'text/event-stream';\n                if (lastEventId) {headers['Last-Event-ID'] = lastEventId;}\n                if (connectionId) {headers['Acp-Connection-Id'] = connectionId;}\n\n                const connectController = new AbortController();\n                const connectTimer = setTimeout(() => connectController.abort(), connectionTimeout > 0 ? connectionTimeout : 30000);\n                if (externalSignal) {externalSignal.addEventListener('abort', () => connectController.abort(), { once: true });}\n                abortController.signal.addEventListener('abort', () => connectController.abort(), { once: true });\n\n                let response: Response;\n                try {\n                    response = await customFetch(endpoint, { method: 'GET', headers, signal: connectController.signal });\n                } finally {\n                    clearTimeout(connectTimer);\n                }\n\n                if (!response.ok) {throw new Error(`HTTP ${response.status}`);}\n\n                const newConnectionId = response.headers.get('Acp-Connection-Id');\n                if (!newConnectionId) {throw new Error('Server did not return Acp-Connection-Id');}\n\n                const previousConnectionId = connectionId;\n                connectionVersion++;\n                connectionId = newConnectionId;\n                resolveConnection();\n\n                if (previousConnectionId && previousConnectionId !== newConnectionId) {\n                    onDisconnect?.(previousConnectionId);\n                }\n                onConnect?.(newConnectionId);\n                reconnectAttempts = 0;\n\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                stopHeartbeatCheck();\n                const endedConnectionId = connectionId;\n                connectionId = undefined;\n                if (endedConnectionId) {onDisconnect?.(endedConnectionId);}\n\n                if (!reconnectEnabled || closed) {break;}\n\n                connectionReady = new Promise((resolve, reject) => {\n                    resolveConnection = resolve;\n                    rejectConnection = reject;\n                });\n\n                const reconnectDelay = calculateDelay(1);\n                await new Promise(resolve => setTimeout(resolve, reconnectDelay));\n\n            } catch (error) {\n                stopHeartbeatCheck();\n                currentReader = null;\n                if (isAborted() || closed) {break;}\n\n                reconnectAttempts++;\n                if (reconnectAttempts > maxRetries) {\n                    closeWithError(new Error(`SSE reconnect failed after ${maxRetries} attempts`));\n                    break;\n                }\n\n                const delay = calculateDelay(reconnectAttempts);\n                await new Promise(resolve => setTimeout(resolve, delay));\n            }\n        }\n    }\n\n    // POST 发送消息\n    async function sendMessage(message: unknown): Promise<void> {\n        if (closed) {throw new Error('Connection is closed');}\n\n        // 等待连接稳定（防竞态）\n        const maxWaitAttempts = 5;\n        let currentConnectionId: string | undefined;\n\n        for (let attempt = 0; attempt < maxWaitAttempts; attempt++) {\n            const versionBeforeWait = connectionVersion;\n            await connectionReady;\n            if (versionBeforeWait !== connectionVersion && versionBeforeWait > 0) {\n                await connectionReady;\n            }\n            currentConnectionId = connectionId;\n            if (currentConnectionId) {break;}\n            if (attempt < maxWaitAttempts - 1) {\n                await new Promise(resolve => setTimeout(resolve, 100));\n            }\n        }\n\n        if (!currentConnectionId) {throw new Error('No connection ID available');}\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        const postController = new AbortController();\n        let timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n        if (postTimeout > 0) {\n            timeoutId = setTimeout(() => postController.abort(), postTimeout);\n            if (externalSignal) {externalSignal.addEventListener('abort', () => postController.abort(), { once: true });}\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: postTimeout > 0 ? postController.signal : abortController.signal,\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            const contentType = response.headers.get('Content-Type') || '';\n            if (contentType.includes('text/event-stream')) {\n                const reader = response.body?.getReader();\n                if (reader) {processSSEStreamBackground(reader);}\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);\n                }\n            }\n        } finally {\n            if (timeoutId) {clearTimeout(timeoutId);}\n        }\n    }\n\n    // 启动 SSE\n    startSSEConnection().catch(() => {});\n\n    // 构造 ReadableStream / WritableStream（实现 Stream 接口）\n    const readable = new ReadableStream<unknown>({\n        async pull(controller) {\n            const message = await dequeueMessage();\n            if (message === null) { controller.close(); }\n            else { controller.enqueue(message); }\n        },\n        cancel() { closeNormally(); abortController.abort(); },\n    });\n\n    const writable = new WritableStream<unknown>({\n        async write(message) { await sendMessage(message); },\n        close() { closeNormally(); abortController.abort(); },\n        abort(reason) {\n            closeWithError(reason instanceof Error ? reason : new Error(String(reason)));\n            abortController.abort();\n        },\n    });\n\n    async function close(): Promise<void> {\n        if (closed) {return;}\n        if (!connectionId || isClosing) { closeNormally(); abortController.abort(); return; }\n        isClosing = true;\n        try {\n            const headers = buildHeaders();\n            headers['Acp-Connection-Id'] = connectionId;\n            await customFetch(endpoint, { method: 'DELETE', headers, signal: AbortSignal.timeout(5000) });\n        } catch { /* ignore */ }\n        finally {\n            if (connectionId) {onDisconnect?.(connectionId);}\n            isClosing = false;\n        }\n        closeNormally();\n        abortController.abort();\n    }\n\n    return {\n        readable,\n        writable,\n        get connectionId() { return connectionId; },\n        get ready() { return connectionReady; },\n        close,\n    };\n}\n\n// 别名 - 与老 SDK @genie/agent-client-protocol 保持一致\nexport { createStreamableHttpTransport as streamableHttp };\nexport type { StreamableHttpTransportOptions as StreamableHttpOptions };\n\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 './acp-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 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    /** 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.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    /** Artifact creation timestamp (epoch milliseconds) */\n    createdAt?: number;\n    /** Artifact last update timestamp (epoch milliseconds) */\n    updatedAt?: number;\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// 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    /** Creation timestamp */\n    createdAt?: number;\n    /** Latest update timestamp */\n    updatedAt?: number;\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","/**\n * Protocol constants for Streamable HTTP ACP Client\n */\n\nimport { ExtensionMethod, KNOWN_EXTENSIONS } from './acp-types.js';\nimport type { ClientCapabilities } from './sdk.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\n    constructor(message: string, code: string, cause?: Error) {\n        super(message);\n        this.name = 'ACPClientError';\n        this.code = code;\n        (this as Error & { cause?: Error }).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 * 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 { 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 * Permission Manager for Streamable HTTP ACP Client\n * Handles permission requests with timeout support\n */\n\nimport type { RequestPermissionRequest, RequestPermissionResponse } from '@agentclientprotocol/sdk' with { 'resolution-mode': 'import' };\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 './acp-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 * SDK Type Re-exports and Capability Extensions\n *\n * This file provides:\n * 1. Re-exports of commonly used types from @agentclientprotocol/sdk\n * 2. Extended capability types with codebuddy.ai metadata\n */\n\n// ============================================\n// SDK Type Re-exports\n// ============================================\n\n// ============================================\n// codebuddy.ai Capability Extensions\n// ============================================\n\nimport type { ArtifactType } from './acp-types.js';\n\ntype SdkClientCapabilities = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).ClientCapabilities;\ntype SdkAgentCapabilities = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).AgentCapabilities;\n\nexport type InitializeRequest = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).InitializeRequest;\nexport type InitializeResponse = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).InitializeResponse;\nexport type NewSessionRequest = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).NewSessionRequest;\nexport type NewSessionResponse = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).NewSessionResponse;\nexport type LoadSessionRequest = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).LoadSessionRequest;\nexport type LoadSessionResponse = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).LoadSessionResponse;\nexport type PromptRequest = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).PromptRequest;\nexport type PromptResponse = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).PromptResponse;\nexport type CancelNotification = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).CancelNotification;\nexport type RequestPermissionRequest = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).RequestPermissionRequest;\nexport type RequestPermissionResponse = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).RequestPermissionResponse;\nexport type SessionNotification = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).SessionNotification;\nexport type ContentBlock = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).ContentBlock;\nexport type TextContent = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).TextContent;\nexport type ImageContent = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).ImageContent;\nexport type AudioContent = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).AudioContent;\nexport type ResourceLink = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).ResourceLink;\nexport type EmbeddedResource = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).EmbeddedResource;\nexport type ToolCallContent = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).ToolCallContent;\nexport type ToolCallStatus = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).ToolCallStatus;\nexport type ToolKind = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).ToolKind;\nexport type Client = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).Client;\n// session/set_model 是本仓库保留的扩展方言（SDK 0.25 起协议面移除）。vendored\n// 副本保持自包含，这里本地定义（wire 形状与 0.18.2 一致，与\n// @genie/agent-client-protocol 的本地方言定义对齐）。\nexport interface SetSessionModelRequest {\n    _meta?: { [key: string]: unknown } | null;\n    /** The ID of the model to set. */\n    modelId: string;\n    /** The ID of the session to set the model for. */\n    sessionId: string;\n}\nexport interface SetSessionModelResponse {\n    _meta?: { [key: string]: unknown } | null;\n}\nexport type SetSessionModeRequest = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).SetSessionModeRequest;\nexport type SetSessionModeResponse = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).SetSessionModeResponse;\nexport type Stream = import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } }).Stream;\nexport type { SdkClientCapabilities, SdkAgentCapabilities };\n\n// ACP TS SDK v0.18.2 exports this from schema/index.js as a simple numeric constant.\n// Re-declare it locally so CommonJS consumers don't need to statically import an ESM package.\nexport const PROTOCOL_VERSION = 1 as const;\n\nexport async function loadAcpSdk(): Promise<typeof import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } })> {\n    return import('@agentclientprotocol/sdk') as Promise<typeof import('@agentclientprotocol/sdk', { with: { 'resolution-mode': 'import' } })>;\n}\n\n/**\n * Configuration for a specific artifact type\n */\nexport interface ArtifactTypeConfig {\n    /** Whether this artifact type is enabled */\n    enabled?: boolean;\n}\n\n/**\n * Artifacts configuration in codebuddy.ai extension\n */\nexport type ArtifactsConfig = {\n    [K in ArtifactType]?: ArtifactTypeConfig;\n};\n\n/**\n * codebuddy.ai extension capabilities for Client\n * Symmetric with CodebuddyAgentMeta for capability negotiation\n */\nexport interface CodebuddyClientMeta {\n    /** Artifact types the client supports receiving */\n    artifacts?: ArtifactsConfig;\n    /** Whether the client supports checkpoint notifications */\n    checkpoint?: boolean;\n    /**\n     * Whether the client supports handling AskUserQuestion tool via extMethod.\n     * When true, AskUserQuestion requests will be sent to the client via\n     * the '_codebuddy.ai/question' extMethod instead of being handled locally.\n     */\n    question?: boolean;\n}\n\n/**\n * codebuddy.ai extension capabilities for Agent\n */\nexport interface CodebuddyAgentMeta {\n    /** Artifact types the agent can produce */\n    artifacts?: ArtifactsConfig;\n    /** Whether the agent supports checkpoint notifications */\n    checkpoint?: boolean;\n}\n\n/**\n * Client capabilities with codebuddy.ai extensions\n */\nexport type ClientCapabilities = Omit<SdkClientCapabilities, '_meta'> & {\n    /** Extension methods the client can handle (e.g., '_codebuddy.ai/*') */\n    extensions?: string[];\n    _meta?: {\n        'codebuddy.ai'?: CodebuddyClientMeta;\n        [key: string]: unknown;\n    } | null;\n};\n\n/**\n * Agent capabilities with codebuddy.ai extensions\n */\nexport type AgentCapabilities = Omit<SdkAgentCapabilities, '_meta'> & {\n    /** Extension methods supported by this agent (e.g., '_codebuddy.ai/*') */\n    extensions?: string[];\n    _meta?: {\n        'codebuddy.ai'?: CodebuddyAgentMeta;\n        [key: string]: unknown;\n    } | null;\n};\n","/**\n * Streamable HTTP ACP Client\n * Production-grade client for connecting to cloud-hosted ACP agents\n */\n\nimport { streamableHttp, type StreamableHttpTransport } from '../transport.js';\nimport type {\n    ArtifactNotificationParams,\n    CheckpointNotificationParams\n} from './acp-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 } from './extensions.js';\nimport { PermissionManager } from './permissions.js';\nimport { type QuestionAnswers, QuestionManager, type QuestionRequest } from './questions.js';\nimport {\n    type CancelNotification,\n    type Client,\n    type ContentBlock,\n    type InitializeRequest,\n    type InitializeResponse,\n    loadAcpSdk,\n    type LoadSessionRequest,\n    type LoadSessionResponse,\n    type NewSessionRequest,\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 './sdk.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!: {\n        initialize(params: InitializeRequest): Promise<InitializeResponse>;\n        newSession(params: NewSessionRequest): Promise<NewSessionResponse>;\n        loadSession(params: LoadSessionRequest): Promise<LoadSessionResponse>;\n        setSessionMode?(params: SetSessionModeRequest): Promise<SetSessionModeResponse>;\n        prompt(params: {\n            sessionId: string;\n            prompt: ContentBlock[];\n            _meta?: Record<string, unknown>;\n        }): Promise<PromptResponse>;\n        cancel(params: CancelNotification): Promise<void>;\n        extMethod?(method: string, params: Record<string, unknown>): Promise<Record<string, unknown>>;\n        extNotification?(method: string, params: Record<string, unknown>): Promise<void>;\n    };\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                lastEventId: this.options.lastEventId,\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            const { ClientSideConnection } = await loadAcpSdk();\n            this.connection = new ClientSideConnection(\n                () => this.createClientHandler(),\n                this.transport as unknown as ConstructorParameters<typeof ClientSideConnection>[1]\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            const initializeResponse = await Promise.race([initPromise, timeoutPromise]) as InitializeResponse;\n            this.initializeResponse = initializeResponse;\n            this.setState('initialized');\n\n            this.options.logger?.info('Client initialized successfully');\n\n            return 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        // SDK 0.25 移除了 typed 的 unstable_setSessionModel；session/set_model 是\n        // 本仓库保留的扩展方言，经 extMethod 原样发送（agent 端 extMethod 回退处理）。\n        return await this.connection.extMethod!(\n            'session/set_model',\n            params as unknown as Record<string, unknown>,\n        ) as SetSessionModelResponse;\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            this.options.logger?.debug('[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                this.options.logger?.debug('[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                    this.options.logger?.debug('[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                    this.options.logger?.debug('[ACP-Client] Emitting artifactUpdated event');\n                    this.emitter.emit('artifactUpdated', storedArtifact);\n                }\n            }\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 * ACP 客户端 — 订阅模型\n *\n * 设计：直接映射到 ACP 协议的两条独立通道：\n *\n * - **RPC 通道（POST）**：`prompt` / `sessionCancel` 等是纯 `Promise`，转发上游。\n * - **Notification 通道（SSE）**：`subscribe(sessionId, listener)` 给用户注册\n *   监听器，每条上游 `SessionNotification` 多路分发给所有订阅者。\n *\n * 不做聚合、不建队列。上游 `SessionNotification` / `PromptResponse` 等类型原封\n * 不动透给上层（`Session` 类）。\n *\n * 具体实现基于 vendor 的 `StreamableHttpClient`，它内部管理一条 SSE + POST 复合\n * 通道。用户侧看到的只是\"一个 session 对应一个 AcpClient\"。\n */\n\nimport { AcpProtocolError, NetworkError } from '../errors';\nimport type { Logger, LogLevel, RuntimeConnectOpts } from '../opts';\nimport type { PromptResponse } from '../types';\nimport { StreamableHttpClient } from './vendor/client';\nimport type {\n    ContentBlock,\n    SessionNotification,\n    SetSessionModelResponse,\n} from './vendor/sdk';\n\n// ─── 过滤官方 ACP SDK 噪音日志 ────────────────\n//\n// @agentclientprotocol/sdk v0.4.8 内部对 session/update 做 zod schema 校验，\n// CodeBuddy 扩展的 session_info_update / usage_update / available_commands_update\n// 等扩展消息不符合官方 schema，会触发硬编码的\n// `console.error(\"Error handling notification\", message, error)`。\n// 这些日志纯粹是噪音，不影响功能（标准 agent_message_chunk 仍能通过校验）。\n//\n// 策略：只过滤 JSON-RPC \"Invalid params\"（code -32602）错误。\n// 其他错误类型（method not found / internal error / 用户代码异常等）全部保留。\nlet _consolePatched = false;\nfunction patchAcpSdkNoiseLogsOnce(): void {\n    if (_consolePatched) {\n        return;\n    }\n    _consolePatched = true;\n    const origError = console.error.bind(console);\n    console.error = (...args: unknown[]): void => {\n        // 匹配签名：console.error(\"Error handling notification\", message, error)\n        if (args.length >= 3 && args[0] === 'Error handling notification') {\n            const err = args[2] as { code?: number } | null | undefined;\n            // JSON-RPC Invalid params (schema 校验失败) → 过滤\n            if (err && typeof err === 'object' && err.code === -32602) {\n                return;\n            }\n        }\n        origError(...args);\n    };\n}\n\n// ─── 类型 ────────────────────────────────\n\nexport type AcpConnectionState =\n    | 'INITIAL'\n    | 'CONNECTING'\n    | 'OPEN'\n    | 'CLOSING'\n    | 'CLOSED';\n\n/** 连接级事件（用于高级用户诊断，如 UI 显示\"重连中\"）。 */\nexport interface AcpConnectionEvents {\n    open: () => void;\n    error: (err: Error) => void;\n    close: () => void;\n}\n\n/** Notification 订阅器签名 —— 收到的是上游 `SessionNotification` 原样。 */\nexport type NotificationListener = (notification: SessionNotification) => void;\n\n/** AcpClient 构造选项。 */\nexport interface AcpClientOpts {\n    /** 日志器（已按级别过滤；通常由上层 `loggerFor(connectionOpts)` 传入）。 */\n    logger?: Logger;\n    /**\n     * 已解析的日志级别（`resolveLogLevel(connectionOpts)` 的结果）。\n     *\n     * 唯一用途：决定是否把 logger **透传给底层 vendor**（ACP StreamableHttpClient）。\n     * 规则：只有 `'debug'` 级别才透传，其他级别下 vendor 内部日志全部 noop。\n     */\n    logLevel?: LogLevel;\n    /** 替换底层 fetch（接 OpenTelemetry / 代理 / mock）。 */\n    fetch?: typeof fetch;\n}\n\n// ─── AcpClient ────────────────────────────────\n\nexport class AcpClient {\n    private _state: AcpConnectionState = 'INITIAL';\n    private _client: StreamableHttpClient | undefined;\n    private _initialized = false;\n    private _sessionIds: Set<string> = new Set();\n\n    private readonly _logger: Logger | undefined;\n    private readonly _fetch: typeof fetch | undefined;\n    private readonly _exposeVendorLogs: boolean;\n\n    tokenRefresher?: () => Promise<string>;\n\n    /** 按 sessionId 分组的 notification 订阅器。 */\n    private readonly _subscribers: Map<string, Set<NotificationListener>> =\n        new Map();\n\n    /** 连接级事件监听器（open / error / close）。 */\n    private readonly _connListeners: {\n        [K in keyof AcpConnectionEvents]: Set<AcpConnectionEvents[K]>;\n    } = {\n            open: new Set(),\n            error: new Set(),\n            close: new Set(),\n        };\n\n    /** per-session prompt 串行队列（ACP 协议要求：同 session 不能并发 prompt）。 */\n    private readonly _activePrompts: Set<string> = new Set();\n    private readonly _promptQueues: Map<string, Array<() => void>> = new Map();\n\n    constructor(opts?: AcpClientOpts) {\n        this._logger = opts?.logger;\n        this._fetch = opts?.fetch;\n        this._exposeVendorLogs = opts?.logLevel === 'debug';\n    }\n\n    // ─── 属性 ────────────────────────────────\n\n    get state(): AcpConnectionState {\n        return this._state;\n    }\n    get connectionId(): string | undefined {\n        return this._client?.connectionId;\n    }\n    get sessionIds(): string[] {\n        return Array.from(this._sessionIds);\n    }\n    get initialized(): boolean {\n        return this._initialized;\n    }\n\n    setTokenRefresher(fn: () => Promise<string>): void {\n        this.tokenRefresher = fn;\n    }\n\n    // ─── 连接管理 ────────────────────────────────\n\n    async connect(\n        acpUrl: string,\n        token: string,\n        opts?: RuntimeConnectOpts,\n    ): Promise<void> {\n        if (this._state === 'OPEN' || this._state === 'CONNECTING') {\n            return;\n        }\n        this._state = 'CONNECTING';\n\n        // 首次连接时惰性过滤官方 SDK 的噪音日志\n        patchAcpSdkNoiseLogsOnce();\n\n        this._logger?.debug(`[acp conn=-] connecting to ${acpUrl}`);\n\n        try {\n            this._client = new StreamableHttpClient({\n                endpoint: acpUrl,\n                authToken: token,\n                headers: opts?.headers,\n                lastEventId: opts?.lastEventId,\n                reconnect: {\n                    enabled: true,\n                    initialDelay: opts?.reconnectBackoffMs ?? 1000,\n                    maxDelay: opts?.reconnectMaxBackoffMs ?? 30_000,\n                    maxRetries: opts?.reconnectMaxAttempts ?? Infinity,\n                },\n                heartbeatTimeout: opts?.heartbeatTimeoutMs ?? 60_000,\n                initializeTimeout: 30_000,\n                postTimeout: 30_000,\n                logger: this._exposeVendorLogs ? this._logger : undefined,\n                fetch: this._fetch,\n                // 上游每来一条 session/update notification 就回调这里。\n                // vendor 的 `SessionUpdateCallback` 签名就是 `(n: SessionNotification) => void`，\n                // 所以这里直接用强类型，不需要 `params: unknown` + 类型守卫。\n                onSessionUpdate: (notification: SessionNotification) =>\n                    this.dispatchNotification(notification),\n            });\n\n            this._client.on('connected', () => {\n                this._logger?.debug(\n                    `[acp conn=${this._client?.connectionId ?? '-'}] connected`,\n                );\n                this.emitConnEvent('open');\n            });\n            this._client.on('error', (err: Error) => {\n                // 运行期 transport 抖动：SDK 会自动重连，错误不会抛给调用方。\n                // 默认级别下仍可见（warn），对齐 Python 的 exhausted 类 warning 策略。\n                this._logger?.warn(\n                    `[acp conn=${this._client?.connectionId ?? '-'}] error: ${err.message}`,\n                );\n                this.emitConnEvent('error', err);\n            });\n\n            await this._client.connect();\n\n            this._state = 'OPEN';\n            this._initialized = true;\n        } catch (err) {\n            this._state = 'CLOSED';\n            this._logger?.debug(\n                `[acp conn=-] connect failed: ${(err as Error).message}`,\n            );\n            throw new NetworkError(\n                `ACP connect failed: ${(err as Error).message}`,\n                { cause: err as Error },\n            );\n        }\n    }\n\n    async disconnect(): Promise<void> {\n        if (this._state === 'CLOSED' || this._state === 'CLOSING') {\n            return;\n        }\n        this._state = 'CLOSING';\n        // 先记住 id —— client 清空后就拿不到了，但日志希望带断开前的 id\n        const lastConnId = this._client?.connectionId ?? '-';\n        if (this._client) {\n            try {\n                await this._client.disconnect();\n            } catch {\n                /* ignore */\n            }\n            this._client = undefined;\n        }\n        this._initialized = false;\n        this._state = 'CLOSED';\n        this._subscribers.clear();\n        this._activePrompts.clear();\n        this._promptQueues.clear();\n        this._logger?.debug(`[acp conn=${lastConnId}] disconnected`);\n        this.emitConnEvent('close');\n    }\n\n    // ─── 协议方法（转发上游）────────────────────────────────\n\n    /** initialize 由 connect() 内部完成，这里只取缓存结果。 */\n    async initialize(): Promise<unknown> {\n        if (!this._client) {\n            throw new AcpProtocolError('Not connected');\n        }\n        return this._client.initializeResult;\n    }\n\n    async sessionNew(sessionId?: string): Promise<string> {\n        if (!this._client) {\n            throw new AcpProtocolError('Not connected');\n        }\n        const result = await this._client.createSession('/workspace');\n        const newId = result.sessionId || sessionId || '';\n        this._sessionIds.add(newId);\n        return newId;\n    }\n\n    async sessionLoad(sessionId: string): Promise<void> {\n        if (!this._client) {\n            throw new AcpProtocolError('Not connected');\n        }\n        await this._client.loadSession(sessionId, '/workspace');\n        this._sessionIds.add(sessionId);\n    }\n\n    /**\n     * 发 prompt。纯 Promise，直接转发上游 `session/prompt` RPC。\n     *\n     * - **不聚合 notification**：本次 prompt 期间的 notifications 由\n     *   `subscribe()` 订阅器独立接收，与此 Promise 并行。\n     * - **串行化**：同 sessionId 的多次 `prompt()` 会**排队**等前一个完成再发出\n     *   （ACP 协议要求），保证顺序一致。\n     * - **signal 支持**：`opts.signal` abort 时向服务端发 `session/cancel`。\n     *   本 Promise 会以 `AbortError` reject。\n     */\n    async prompt(\n        sessionId: string,\n        input: ContentBlock[],\n        opts?: { signal?: AbortSignal },\n    ): Promise<PromptResponse> {\n        if (!this._client) {\n            throw new AcpProtocolError('Not connected');\n        }\n\n        return new Promise<PromptResponse>((resolve, reject) => {\n            this.enqueuePrompt(sessionId, async () => {\n                // abort 时立即向服务端发 cancel 通知，并 reject 调用方 Promise\n                let aborted = false;\n                const onAbort = (): void => {\n                    aborted = true;\n                    // 尽力而为：cancel RPC 失败也无所谓，调用方已经知道要放弃\n                    this._client?.cancel(sessionId).catch(() => {\n                        /* warn 在 Session.cancel 做 */\n                    });\n                    const err = new Error('Prompt aborted');\n                    err.name = 'AbortError';\n                    reject(err);\n                };\n                if (opts?.signal) {\n                    if (opts.signal.aborted) {\n                        onAbort();\n                        return;\n                    }\n                    opts.signal.addEventListener('abort', onAbort, {\n                        once: true,\n                    });\n                }\n\n                try {\n                    const response = (await this._client!.prompt(\n                        sessionId,\n                        input as never[],\n                    )) as PromptResponse;\n                    if (!aborted) {\n                        resolve(response);\n                    }\n                } catch (err) {\n                    if (!aborted) {\n                        reject(err);\n                    }\n                } finally {\n                    opts?.signal?.removeEventListener('abort', onAbort);\n                }\n            });\n        });\n    }\n\n    /** 发 session/cancel 通知（幂等，尽力而为）。 */\n    async sessionCancel(sessionId: string): Promise<void> {\n        if (!this._client) {\n            throw new AcpProtocolError('Not connected');\n        }\n        await this._client.cancel(sessionId);\n    }\n\n    /**\n     * 设置 session 使用的模型。\n     *\n     * @experimental 对应 ACP 协议的 `unstable_setSessionModel`，API 尚未稳定。\n     */\n    async setSessionModel(\n        sessionId: string,\n        modelId: string,\n    ): Promise<SetSessionModelResponse> {\n        if (!this._client) {\n            throw new AcpProtocolError('Not connected');\n        }\n        return this._client.setSessionModel({ sessionId, modelId });\n    }\n\n    // ─── Notification 订阅 ────────────────────────────────\n\n    /**\n     * 订阅指定 sessionId 的上游 notifications。\n     *\n     * Listener 收到的是上游 `SessionNotification` 原样（`{ sessionId, update, _meta? }`）。\n     * 同一 session 可以有任意多个 listener，彼此独立；每条 notification 都会\n     * 按注册顺序调用所有 listener（同步调用，异常被吞）。\n     *\n     * @returns unsubscribe 函数，调用即退订。\n     */\n    subscribe(sessionId: string, listener: NotificationListener): () => void {\n        if (!this._subscribers.has(sessionId)) {\n            this._subscribers.set(sessionId, new Set());\n        }\n        this._subscribers.get(sessionId)!.add(listener);\n        return () => {\n            this._subscribers.get(sessionId)?.delete(listener);\n        };\n    }\n\n    // ─── 连接级事件订阅（高级用户诊断用）────────────────────────────────\n\n    on<K extends keyof AcpConnectionEvents>(\n        event: K,\n        handler: AcpConnectionEvents[K],\n    ): void {\n        this._connListeners[event].add(handler as AcpConnectionEvents[K]);\n    }\n    off<K extends keyof AcpConnectionEvents>(\n        event: K,\n        handler: AcpConnectionEvents[K],\n    ): void {\n        this._connListeners[event].delete(handler as AcpConnectionEvents[K]);\n    }\n\n    // ─── 内部 ────────────────────────────────\n\n    /**\n     * 把上游 notification 按 sessionId 分发给订阅者。不做任何转换。\n     *\n     * 上游保证 `SessionNotification` 的 `sessionId` / `update` 字段都有值\n     * （vendor 的 `SessionUpdateCallback` 签名即如此），无需再做类型守卫。\n     */\n    private dispatchNotification(notification: SessionNotification): void {\n        const subs = this._subscribers.get(notification.sessionId);\n        if (!subs || subs.size === 0) {\n            return;\n        }\n\n        for (const listener of subs) {\n            try {\n                listener(notification);\n            } catch {\n                // 订阅者抛错不影响其他订阅者；不记日志（SDK 不能替用户处理业务异常）\n            }\n        }\n    }\n\n    private emitConnEvent<K extends keyof AcpConnectionEvents>(\n        event: K,\n        ...args: Parameters<AcpConnectionEvents[K]>\n    ): void {\n        for (const handler of this._connListeners[event]) {\n            try {\n                (handler as (...a: unknown[]) => void)(...args);\n            } catch {\n                /* ignore */\n            }\n        }\n    }\n\n    private enqueuePrompt(sid: string, exec: () => Promise<void>): void {\n        if (!this._promptQueues.has(sid)) {\n            this._promptQueues.set(sid, []);\n        }\n        const runThenDequeue = (): void => {\n            this._activePrompts.add(sid);\n            exec().finally(() => this.dequeuePrompt(sid));\n        };\n        if (this._activePrompts.has(sid)) {\n            this._promptQueues.get(sid)!.push(runThenDequeue);\n        } else {\n            runThenDequeue();\n        }\n    }\n\n    private dequeuePrompt(sid: string): void {\n        this._activePrompts.delete(sid);\n        const q = this._promptQueues.get(sid);\n        if (q && q.length > 0) {\n            q.shift()!();\n        }\n    }\n}\n","/**\n * Session — 对话上下文\n *\n * 控制面（REST）：`info` / `update` / `delete`\n * 数据面（ACP）：`connect` / `prompt` / `subscribe` / `disconnect`\n *\n * **订阅模型**（对齐 ACP 协议原生形态）：\n * - `prompt(input)` 返回 `Promise<PromptResponse>` —— 一轮的终局\n * - `subscribe(listener)` —— 流式 notifications 由 listener 异步接收\n * - 两条通道独立、不聚合、无队列\n *\n * 典型用法：\n * ```ts\n * await session.connect();\n *\n * // 场景 A：只要最终结果\n * const response = await session.prompt('hello');\n * console.log(response.stopReason);\n *\n * // 场景 B：流式打印 + 最终结果\n * const unsub = session.subscribe((n) => {\n *   if (n.update.sessionUpdate === 'agent_message_chunk' &&\n *       n.update.content.type === 'text') {\n *     process.stdout.write(n.update.content.text);\n *   }\n * });\n * const response = await session.prompt('hello');\n * unsub();\n *\n * // 场景 C：便利钩子（等价于 B 但不需手动 unsub）\n * const response = await session.prompt('hello', {\n *   onChunk: (n) => { ... },\n * });\n * ```\n */\n\nimport { AcpClient } from './acp/client';\nimport { ValidationError } from './errors';\nimport { loggerFor, resolveLogLevel } from './internal/log';\nimport type { PromptOpts, RequestOpts, RuntimeConnectOpts } from './opts';\nimport { RestClient } from './rest/client';\nimport type { Runtime } from './runtime';\nimport type {\n    ContentBlock,\n    DeleteResult,\n    PromptResponse,\n    SessionInfo,\n    SessionNotification,\n    SessionStatus,\n    UpdateSessionRequest,\n} from './types';\n\nexport class Session {\n    readonly id: string;\n    readonly runtimeId: string;\n\n    private readonly _runtime: Runtime;\n    private readonly _restClient: RestClient;\n\n    /** 数据面 ACP 客户端（connect() 后可用） */\n    private _acpClient: AcpClient | undefined;\n\n    /** connect 前预注册的订阅器；连接建立后会灌入当前 acp client。 */\n    private readonly _pendingSubscribers: Set<\n        (notification: SessionNotification) => void\n    > = new Set();\n\n    /** 控制面状态（来自最近一次 info() / update()）。 */\n    private _status: SessionStatus | undefined;\n\n    /** @internal */\n    constructor(id: string, runtime: Runtime, restClient: RestClient) {\n        this.id = id;\n        this.runtimeId = runtime.id;\n        this._runtime = runtime;\n        this._restClient = restClient;\n    }\n\n    // ============================================================\n    // 状态\n    // ============================================================\n\n    get status(): SessionStatus | undefined {\n        return this._status;\n    }\n\n    /** ACP 连接是否已建立 */\n    get connected(): boolean {\n        return this._acpClient?.state === 'OPEN';\n    }\n\n    // ============================================================\n    // 控制面（REST）\n    // ============================================================\n\n    /** 拉最新元数据 */\n    async info(opts?: RequestOpts): Promise<SessionInfo> {\n        const info = await this._restClient.get<SessionInfo>(\n            `/runtimes/${this.runtimeId}/sessions/${this.id}`,\n            undefined,\n            opts,\n        );\n        this._status = info.sessionStatus;\n        return info;\n    }\n\n    /** 更新 name / manifest */\n    async update(\n        req: UpdateSessionRequest,\n        opts?: RequestOpts,\n    ): Promise<SessionInfo> {\n        const info = await this._restClient.post<SessionInfo>(\n            `/runtimes/${this.runtimeId}/sessions/${this.id}/update`,\n            req,\n            opts,\n        );\n        this._status = info.sessionStatus;\n        return info;\n    }\n\n    /** 软删除 */\n    async delete(opts?: RequestOpts): Promise<DeleteResult> {\n        // 断开 ACP\n        if (this._acpClient) {\n            await this._acpClient.disconnect();\n            this._acpClient = undefined;\n        }\n        return this._restClient.post<DeleteResult>(\n            `/runtimes/${this.runtimeId}/sessions/${this.id}/delete`,\n            undefined,\n            opts,\n        );\n    }\n\n    // ============================================================\n    // 数据面 — 连接管理（ACP）\n    // ============================================================\n\n    /**\n     * 建立到沙箱的 ACP 连接。\n     *\n     * 内部流程：GET SSE → 获取 connectionId → initialize → session/load。\n     * 调用后 `prompt` / `subscribe` / `cancel` 才可用。\n     *\n     * 幂等：已连接时直接返回；并发调用时后来的等前者完成。\n     */\n    async connect(opts?: RuntimeConnectOpts): Promise<void> {\n        if (this._acpClient && this._acpClient.state === 'OPEN') {\n            return; // 已连接\n        }\n\n        const acpUrl = this._runtime.acpUrl;\n        let acpToken = this._runtime.acpToken;\n\n        if (!acpUrl || !acpToken) {\n            // 尝试刷新\n            acpToken = await this._runtime.refreshToken();\n            if (!this._runtime.acpUrl || !acpToken) {\n                throw new ValidationError(\n                    'Runtime does not have ACP link. Is it in RUNNING state?',\n                );\n            }\n        }\n\n        const connOpts = this._runtime._connectionOpts;\n        const client = new AcpClient({\n            logger: loggerFor(connOpts),\n            logLevel: resolveLogLevel(connOpts),\n            fetch: connOpts.fetch,\n        });\n\n        // 注入 token 刷新\n        client.setTokenRefresher(async () => this._runtime.refreshToken());\n\n        // 建立 SSE 连接。`...opts` 必须放前面，让后面显式字段兜底 undefined。\n        await client.connect(this._runtime.acpUrl!, acpToken!, {\n            ...opts,\n            heartbeatTimeoutMs: opts?.heartbeatTimeoutMs ?? 45_000,\n            reconnectMaxAttempts: opts?.reconnectMaxAttempts ?? Infinity,\n            reconnectBackoffMs: opts?.reconnectBackoffMs ?? 300,\n            reconnectMaxBackoffMs: opts?.reconnectMaxBackoffMs ?? 30_000,\n            lastEventId: opts?.lastEventId,\n        });\n\n        // ACP initialize\n        if (opts?.initialize !== false) {\n            await client.initialize();\n        }\n\n        // 数据面只做 session/load（session 创建是控制面的事，通过 REST 完成）\n        await client.sessionLoad(this.id);\n\n        for (const listener of this._pendingSubscribers) {\n            client.subscribe(this.id, listener);\n        }\n\n        this._acpClient = client;\n    }\n\n    /** 断开 ACP 连接。所有订阅器被自动清除。 */\n    async disconnect(): Promise<void> {\n        if (this._acpClient) {\n            await this._acpClient.disconnect();\n            this._acpClient = undefined;\n        }\n    }\n\n    // ============================================================\n    // 数据面 — Prompt & Notification 订阅（ACP）\n    // ============================================================\n\n    /**\n     * 发送 prompt 并等待 `PromptResponse`。\n     *\n     * @param input 纯文本字符串（自动包装成 text block）或 `ContentBlock[]`（多模态）\n     * @param opts 见 `PromptOpts`，支持 `signal` 取消、`onChunk` 便利钩子等\n     *\n     * @returns `PromptResponse`（当前只含 `stopReason`）\n     *\n     * **时序**：\n     * - 如果未 connect，会自动 connect\n     * - RPC 发出期间，上游会通过 **SSE notification 通道**推送 `session/update`，\n     *   这些消息**不会进 Promise 的结果**，需要通过 `subscribe()` 或 `onChunk`\n     *   回调接收\n     * - 同 session 并发 prompt 会被内部**串行化**（ACP 协议要求）\n     *\n     * @example\n     * ```ts\n     * // 最简：只要结果\n     * const r = await session.prompt('2+2?');\n     *\n     * // 流式打印 + 结果\n     * const r = await session.prompt('write a poem', {\n     *   onChunk: (n) => {\n     *     if (n.update.sessionUpdate === 'agent_message_chunk' &&\n     *         n.update.content.type === 'text') {\n     *       process.stdout.write(n.update.content.text);\n     *     }\n     *   },\n     * });\n     *\n     * // 取消\n     * const ctrl = new AbortController();\n     * setTimeout(() => ctrl.abort(), 5000);\n     * const r = await session.prompt('long task', { signal: ctrl.signal });\n     * ```\n     */\n    async prompt(\n        input: string | ContentBlock[],\n        opts?: PromptOpts,\n    ): Promise<PromptResponse> {\n        // 自动 connect\n        if (!this._acpClient || this._acpClient.state !== 'OPEN') {\n            await this.connect();\n        }\n\n        const content: ContentBlock[] =\n            typeof input === 'string' ? [{ type: 'text', text: input }] : input;\n\n        // 便利钩子：临时订阅，prompt 结束自动 unsub\n        const unsubChunk = opts?.onChunk\n            ? this._acpClient!.subscribe(this.id, opts.onChunk)\n            : undefined;\n\n        // 合并用户 signal 与超时\n        let timeoutCtrl: AbortController | undefined;\n        let signal = opts?.signal;\n        if (opts?.timeoutMs !== undefined && opts.timeoutMs > 0) {\n            timeoutCtrl = new AbortController();\n            const timer = setTimeout(\n                () => timeoutCtrl!.abort(),\n                opts.timeoutMs,\n            );\n            // 用户 signal 触发时也要清 timer 避免 leak\n            signal?.addEventListener(\n                'abort',\n                () => {\n                    clearTimeout(timer);\n                    timeoutCtrl!.abort();\n                },\n                { once: true },\n            );\n            // 把 timeoutCtrl.signal 作为最终 signal 传下去（abort 会传染）\n            if (!signal) {\n                signal = timeoutCtrl.signal;\n            } else {\n                // 两个 signal 合并：任一 abort 就 abort\n                signal = mergeAbortSignals(signal, timeoutCtrl.signal);\n            }\n        }\n\n        opts?.onTurnStart?.();\n\n        try {\n            const response = await this._acpClient!.prompt(this.id, content, {\n                signal,\n            });\n            opts?.onTurnEnd?.(response);\n            return response;\n        } finally {\n            unsubChunk?.();\n        }\n    }\n\n    /**\n     * 订阅该 session 所有上游 notifications。\n     *\n     * Listener 收到的是上游 `SessionNotification` 原样（`{ sessionId, update, _meta? }`）。\n     * `update` 是上游 11-tag 判别联合，在 switch 分支里类型自动收窄。\n     *\n     * 订阅独立于 prompt 生命周期——connect 之后注册，直到 unsubscribe 或\n     * disconnect 为止。未 connect 时也可以先注册，后续 connect / reconnect 到\n     * 该 session 后会自动生效。一个 session 支持任意多个订阅者。\n     *\n     * @returns unsubscribe 函数，调用即退订。\n     *\n     * @example\n     * ```ts\n     * const unsub = session.subscribe((n) => {\n     *   switch (n.update.sessionUpdate) {\n     *     case 'agent_message_chunk':\n     *       if (n.update.content.type === 'text') print(n.update.content.text);\n     *       break;\n     *     case 'tool_call':\n     *       console.log('tool:', n.update.title);\n     *       break;\n     *   }\n     * });\n     * // ...\n     * unsub();\n     * ```\n     */\n    subscribe(\n        listener: (notification: SessionNotification) => void,\n    ): () => void {\n        this._pendingSubscribers.add(listener);\n\n        if (this._acpClient && this._acpClient.state === 'OPEN') {\n            const unsub = this._acpClient.subscribe(this.id, listener);\n            return () => {\n                unsub();\n                this._pendingSubscribers.delete(listener);\n            };\n        }\n\n        return () => {\n            this._pendingSubscribers.delete(listener);\n        };\n    }\n\n    /**\n     * 取消当前运行的 prompt（如果有）。\n     *\n     * 向服务端发 `session/cancel` notification，服务端会以 `stopReason: 'cancelled'`\n     * 结束当前 prompt，对应的 `prompt()` Promise 正常 resolve（不 reject）。\n     *\n     * **尽力而为**：服务端 RPC 失败时打 warn 日志吞掉，不抛给调用方——\n     * 因为\"用户点了取消按钮\"的 UX 契约就是\"本地能返回\"。\n     */\n    async cancel(): Promise<void> {\n        if (!this._acpClient) {\n            return;\n        }\n        try {\n            await this._acpClient.sessionCancel(this.id);\n        } catch (err) {\n            const logger = loggerFor(this._runtime._connectionOpts);\n            logger.warn(\n                `[session ${this.id}] cancel failed: ${(err as Error).message}`,\n            );\n        }\n    }\n\n    /**\n     * 设置 session 使用的模型。\n     *\n     * 必须在 `connect()` 之后调用。\n     *\n     * @param modelId 目标模型 ID，例如 `\"gpt-4o\"` / `\"claude-3-7-sonnet\"`\n     *\n     * @experimental 对应 ACP 协议的 `unstable_setSessionModel`，API 尚未稳定。\n     *\n     * @example\n     * ```ts\n     * await session.connect();\n     * await session.setModel('claude-3-7-sonnet');\n     * const r = await session.prompt('hello');\n     * ```\n     */\n    async setModel(modelId: string): Promise<void> {\n        if (!this._acpClient || this._acpClient.state !== 'OPEN') {\n            throw new ValidationError(\n                'Session not connected. Call connect() first.',\n            );\n        }\n        await this._acpClient.setSessionModel(this.id, modelId);\n    }\n}\n\n// ─── 工具 ────────────────────────────────\n\n/**\n * 合并两个 AbortSignal：任一 abort 时返回的 signal 也 abort。\n *\n * 用原生 `AbortSignal.any()` 不行——Node 18 没有。这里用最小 polyfill。\n */\nfunction mergeAbortSignals(a: AbortSignal, b: AbortSignal): AbortSignal {\n    if (\n        typeof (\n            AbortSignal as unknown as {\n                any?: (s: AbortSignal[]) => AbortSignal;\n            }\n        ).any === 'function'\n    ) {\n        return (\n            AbortSignal as unknown as { any: (s: AbortSignal[]) => AbortSignal }\n        ).any([a, b]);\n    }\n    const ctrl = new AbortController();\n    const onAbort = (): void => ctrl.abort();\n    if (a.aborted || b.aborted) {\n        ctrl.abort();\n    } else {\n        a.addEventListener('abort', onAbort, { once: true });\n        b.addEventListener('abort', onAbort, { once: true });\n    }\n    return ctrl.signal;\n}\n","/**\n * Runtime — 一个云端沙箱实例\n *\n * 由 CloudAgentClient.runtimes.create() 或 .from() 返回。\n * 返回时已持有控制面 info（status、metadata）和数据面连接信息（acpLink、sandboxId）。\n *\n * Runtime 实例方法覆盖自身的控制面操作（update/delete/refreshToken）。\n * 通过 sessions 子命名空间管理 Session 的控制面 CRUD。\n */\n\nimport type { ConnectionOpts, RequestOpts, SessionCreateOpts, SessionListOpts } from './opts';\nimport { RestClient } from './rest/client';\nimport { Session } from './session';\nimport type {\n    CreateSessionRequest,\n    DeleteResult,\n    PageResult,     RuntimeInfo, SessionInfo,     UpdateRuntimeRequest, } from './types';\n\nexport class Runtime {\n    readonly id: string;\n\n    /** 控制面信息快照（创建/刷新时更新） */\n    private _info: RuntimeInfo;\n\n    /** 数据面连接信息 */\n    readonly sandboxId?: string;\n    readonly sandboxDomain?: string;\n    private _acpUrl?: string;\n    private _acpToken?: string;\n\n    /** 内部依赖 */\n    private readonly _restClient: RestClient;\n    /** @internal 供 Session 构造 AcpClient 时读取（logger / fetch）。 */\n    readonly _connectionOpts: ConnectionOpts;\n\n    /** 默认 session ID */\n    private _defaultSessionId: string | undefined;\n\n    /** @internal */\n    constructor(\n        restClient: RestClient,\n        connectionOpts: ConnectionOpts,\n        info: RuntimeInfo,\n    ) {\n        this.id = info.id;\n        this._info = info;\n        this._restClient = restClient;\n        this._connectionOpts = connectionOpts;\n\n        this.sandboxId = info.links?.sandboxLink?.sandboxId;\n        this.sandboxDomain = info.links?.sandboxLink?.endpoint;\n        this._acpUrl = info.links?.acpLink?.url;\n        this._acpToken = info.links?.acpLink?.token;\n\n        if (info.sessions && info.sessions.length > 0) {\n            this._defaultSessionId = info.sessions[0].sessionId;\n        }\n    }\n\n    // ─── 公共属性 ────────────────────────────────\n\n    get runtimeInfo(): RuntimeInfo { return this._info; }\n    get acpUrl(): string | undefined { return this._acpUrl; }\n    get acpToken(): string | undefined { return this._acpToken; }\n\n    // ============================================================\n    // Runtime 自身操作（控制面）\n    // ============================================================\n\n    /** 更新 Runtime 元数据 */\n    async update(req: UpdateRuntimeRequest, opts?: RequestOpts): Promise<RuntimeInfo> {\n        const info = await this._restClient.post<RuntimeInfo>(`/runtimes/${this.id}/update`, req, opts);\n        this._info = info;\n        return info;\n    }\n\n    /** 软删除 */\n    async delete(opts?: RequestOpts): Promise<DeleteResult> {\n        return this._restClient.post<DeleteResult>(`/runtimes/${this.id}/delete`, undefined, opts);\n    }\n\n    /** 刷新 token（拉最新 RuntimeInfo，更新 acpLink） */\n    async refreshToken(opts?: RequestOpts): Promise<string> {\n        const info = await this._restClient.get<RuntimeInfo>(`/runtimes/${this.id}`, undefined, opts);\n        this._info = info;\n        if (info.links?.acpLink) {\n            this._acpUrl = info.links.acpLink.url;\n            this._acpToken = info.links.acpLink.token;\n        }\n        return this._acpToken || '';\n    }\n\n    // ============================================================\n    // sessions — 控制面 CRUD\n    // ============================================================\n\n    readonly sessions = {\n        /**\n         * 创建新 Session（控制面），返回 Session 实例。\n         *\n         * - 不传 `agentId`：走 `/runtimes/{id}/sessions`，使用入参 manifest\n         * - 传 `agentId`：走 `/agents/sessions`，使用 Agent 已发布版本的 manifest\n         */\n        create: async (opts: SessionCreateOpts): Promise<Session> => {\n            const reqOpts = {\n                timeoutMs: opts.timeoutMs,\n                headers: opts.headers,\n                signal: opts.signal,\n                requestId: opts.requestId,\n            };\n\n            let info: SessionInfo;\n\n            if (opts.agentId) {\n                // 走 Agent Session 接口\n                info = await this._restClient.post<SessionInfo>(\n                    '/agents/sessions',\n                    {\n                        agentId: opts.agentId,\n                        runtimeId: this.id,\n                        sessionName: opts.sessionName,\n                    },\n                    reqOpts,\n                );\n            } else {\n                // 走标准 Runtime Session 接口\n                const body: CreateSessionRequest = {\n                    sessionId: opts.sessionId,\n                    sessionName: opts.sessionName,\n                    agentManifest: opts.agentManifest,\n                };\n                info = await this._restClient.post<SessionInfo>(\n                    `/runtimes/${this.id}/sessions`,\n                    body,\n                    reqOpts,\n                );\n            }\n\n            return new Session(info.sessionId, this, this._restClient);\n        },\n\n        /** 获取 Session（返回实例） */\n        get: async (sessionId: string, opts?: RequestOpts): Promise<Session> => {\n            // 验证 session 存在（发请求），然后返回实例\n            await this._restClient.get<SessionInfo>(\n                `/runtimes/${this.id}/sessions/${sessionId}`,\n                undefined,\n                opts\n            );\n            return new Session(sessionId, this, this._restClient);\n        },\n\n        /** 分页列表（返回纯数据） */\n        list: async (opts?: SessionListOpts): Promise<PageResult<SessionInfo>> => {\n            const params: Record<string, string> = {};\n            if (opts?.page !== undefined) {params.page = String(opts.page);}\n            if (opts?.pageSize !== undefined) {params.pageSize = String(opts.pageSize);}\n            if (opts?.sessionStatus) {params.sessionStatus = opts.sessionStatus;}\n            return this._restClient.get<PageResult<SessionInfo>>(\n                `/runtimes/${this.id}/sessions`,\n                params,\n                opts\n            );\n        },\n\n        /** 默认 session（Runtime 创建时自动生成的） */\n        default: (): Session => {\n            const sessionId = this._defaultSessionId || this.id;\n            return new Session(sessionId, this, this._restClient);\n        },\n    };\n}\n","/**\n * CloudAgentClient — SDK 顶层入口\n *\n * 持有 ConnectionOpts，提供 runtimes 子命名空间（仅控制面集合操作）。\n * 本身不发起网络请求、不持有连接。\n */\n\nimport {\n    Agent,\n    type AgentInfo,\n    type AgentListResponse,\n    type CreateAgentRequest,\n} from './agent';\nimport { loggerFor } from './internal/log';\nimport type { ConnectionOpts, RequestOpts, RuntimeCreateOpts, RuntimeListOpts } from './opts';\nimport { RestClient } from './rest/client';\nimport { Runtime } from './runtime';\nimport type { AgentManifest, CreateRuntimeRequest, PageResult, RuntimeBrief, RuntimeInfo } from './types';\n\n/** Secret key 名（服务端 `constants.CodebuddyAPIKey`）。 */\nconst CODEBUDDY_API_KEY = 'CODEBUDDY_API_KEY';\n\nexport class CloudAgentClient {\n    private readonly opts: ConnectionOpts;\n    /** @internal */\n    readonly _restClient: RestClient;\n\n    /** 构造（同步，不发网络请求） */\n    constructor(opts: ConnectionOpts = {}) {\n        // 认证策略由调用方决定：\n        // - 后端：提供 apiKey\n        // - 浏览器：通过 baseUrl 指向业务后端代理（由代理注入鉴权），或通过 headers 携带业务登录态\n        // 这里不做强校验，请求失败时服务端会返回 401/403。\n        this.opts = opts;\n        this._restClient = new RestClient(opts);\n    }\n\n    /** 派生新实例（覆盖部分配置，如切换 sourceApp） */\n    with(overrides: Partial<ConnectionOpts>): CloudAgentClient {\n        return new CloudAgentClient({ ...this.opts, ...overrides });\n    }\n\n    // ============================================================\n    // agents — Agent 管理（CRUD + Version + Session）\n    // ============================================================\n\n    readonly agents = {\n        /**\n         * 创建 Agent\n         *\n         * 创建后自动生成一个 v1 版本。\n         */\n        create: async (req: CreateAgentRequest, opts?: RequestOpts): Promise<Agent> => {\n            const info = await this._restClient.post<AgentInfo>(\n                '/agents',\n                req,\n                opts,\n            );\n            return new Agent(this._restClient, info);\n        },\n\n        /** 获取 Agent 详情（返回 Agent 实例） */\n        get: async (agentId: string, opts?: RequestOpts): Promise<Agent> => {\n            const info = await this._restClient.get<AgentInfo>(\n                `/agents/${agentId}`,\n                undefined,\n                opts,\n            );\n            return new Agent(this._restClient, info);\n        },\n\n        /** Agent 分页列表 */\n        list: async (opts?: RequestOpts & { page?: number; pageSize?: number; keyword?: string }): Promise<AgentListResponse> => {\n            const params: Record<string, string> = {};\n            if (opts?.page !== undefined) {params.page = String(opts.page);}\n            if (opts?.pageSize !== undefined) {params.pageSize = String(opts.pageSize);}\n            if (opts?.keyword) {params.keyword = opts.keyword;}\n            return this._restClient.get<AgentListResponse>('/agents', params, opts);\n        },\n\n        /** 删除 Agent */\n        delete: async (agentId: string, opts?: RequestOpts): Promise<void> => {\n            await this._restClient.delete<void>(`/agents/${agentId}`, opts);\n        },\n    };\n\n    // ============================================================\n    // runtimes — 控制面集合操作\n    // ============================================================\n\n    readonly runtimes = {\n        /**\n         * 创建 Runtime（同步接口，返回时沙箱已 RUNNING）\n         * 返回 Runtime 实例，可直接操作 sessions。\n         *\n         * **自动注入 `CODEBUDDY_API_KEY`**：沙箱内 agent 调大模型网关需要这个 secret\n         * （见服务端 `sandbox_builder.go`）。SDK 兜底逻辑：\n         *\n         * - 如果 `opts.agentManifest.secrets` 已显式声明 `CODEBUDDY_API_KEY` → 保留用户值\n         * - 否则若 `opts.agentManifest` 已传 **且** `ConnectionOpts.apiKey` 存在\n         *   → 追加一条 `CODEBUDDY_API_KEY` secret（不 mutate 入参）\n         *\n         * 这样用户只需在 `new CloudAgentClient({ apiKey })` 里提供一次，不必在每次\n         * `runtimes.create` 里重复声明同一个 key。\n         *\n         * 注意：SDK 不会在用户完全没传 `agentManifest` 时帮他编造 `id/name/manifestVersion`\n         * 等业务字段——那些是用户自己的 agent 身份标识，必须显式指定。\n         */\n        create: async (opts: RuntimeCreateOpts): Promise<Runtime> => {\n            const agentManifest = withInjectedApiKeySecret(\n                opts.agentManifest,\n                this.opts.apiKey,\n                this.opts,\n            );\n\n            // 组装 REST body —— CreateRuntimeRequest 是后端 API 的权威镜像\n            // （JSON.stringify 自动跳过 undefined 字段，不用手动 if-push）\n            const body: CreateRuntimeRequest = {\n                runtimeName: opts.runtimeName,\n                agentManifest,\n                sandboxTemplateId: opts.sandboxTemplateId,\n                sandboxSpec: opts.sandboxSpec,\n                sandboxType: opts.sandboxType,\n                visibility: opts.visibility,\n                metadata: opts.metadata,\n            };\n\n            const info = await this._restClient.post<RuntimeInfo>(\n                '/runtimes',\n                body,\n                {\n                    timeoutMs: opts.timeoutMs ?? 120_000,\n                    headers: opts.headers,\n                    signal: opts.signal,\n                    requestId: opts.requestId,\n                }\n            );\n\n            return new Runtime(this._restClient, this.opts, info);\n        },\n\n        /** 获取 Runtime（返回实例） */\n        get: async (runtimeId: string, opts?: RequestOpts): Promise<Runtime> => {\n            const info = await this._restClient.get<RuntimeInfo>(`/runtimes/${runtimeId}`, undefined, opts);\n            return new Runtime(this._restClient, this.opts, info);\n        },\n\n        /** 分页列表（轻量返回 RuntimeBrief，仅含 id/runtimeName/createdAt） */\n        list: async (opts?: RuntimeListOpts): Promise<PageResult<RuntimeBrief>> => {\n            const params: Record<string, string> = {};\n            if (opts?.page !== undefined) {params.page = String(opts.page);}\n            if (opts?.pageSize !== undefined) {params.pageSize = String(opts.pageSize);}\n            if (opts?.metadata) {params.metadata = JSON.stringify(opts.metadata);}\n            return this._restClient.get<PageResult<RuntimeBrief>>('/runtimes', params, opts);\n        },\n    };\n}\n\n// ============================================================\n// 内部辅助\n// ============================================================\n\n/**\n * 按需注入 `CODEBUDDY_API_KEY` secret 的兜底逻辑。\n *\n * SDK 只负责一件事：**把 `ConnectionOpts.apiKey` 透传到沙箱 agent** —— 这个\n * credential 本来就是调用方已经提供过的，用户不应该被迫在 manifest 里再写一遍。\n *\n * 规则（按优先级）：\n * 1. `userManifest.secrets[CODEBUDDY_API_KEY]` 已显式声明 → 保留用户值，不覆盖\n * 2. `userManifest` 根本没传 → 原样返回 `undefined`，让服务端按\"manifest 必填字段缺失\"\n *    报明确错误（SDK 不编造 `id/name/manifestVersion` 等用户的业务语义）\n * 3. `ConnectionOpts.apiKey` 为空 → 无从兜底，原样返回\n * 4. 其他情况（用户传了 manifest 但没 `CODEBUDDY_API_KEY`，且 Client 有 apiKey）\n *    → 追加 secrets，不 mutate 入参\n *\n * 设计取舍：SDK 不探查 `opts.metadata.CODEBUDDY_API_KEY` —— metadata 是\n * AgentOS 与上游网关之间的内部协议（见服务端 `sandbox_builder.go` 的优先级逻辑），\n * 不是 SDK 用户的常规使用通道。即便用户显式在 metadata 里塞了一个 key，服务端\n * 自身的优先级会用 metadata 值覆盖 manifest 里注入的那条，行为正确。\n */\nfunction withInjectedApiKeySecret(\n    userManifest: AgentManifest | undefined,\n    apiKey: string | undefined,\n    connectionOpts: ConnectionOpts,\n): AgentManifest | undefined {\n    // Case 1: 用户已显式声明\n    if (userManifest?.secrets?.some(s => s.key === CODEBUDDY_API_KEY)) {\n        return userManifest;\n    }\n\n    // Case 2: 用户根本没传 manifest —— SDK 不越界编造业务字段\n    // 服务端会按\"manifest 缺 id/name/manifestVersion\"报错，这是用户该看到的真实错误\n    if (!userManifest) {\n        return undefined;\n    }\n\n    // Case 3: 无 apiKey 可兜底\n    if (!apiKey) {\n        return userManifest;\n    }\n\n    // Case 4: 兜底注入（纯函数，不 mutate 入参）\n    const logger = loggerFor(connectionOpts);\n    logger.debug(\n        `[runtimes.create] auto-injected ${CODEBUDDY_API_KEY} secret from ConnectionOpts.apiKey `\n        + '(no explicit value in agentManifest.secrets)',\n    );\n\n    return {\n        ...userManifest,\n        secrets: [\n            ...(userManifest.secrets ?? []),\n            { key: CODEBUDDY_API_KEY, value: apiKey },\n        ],\n    };\n}\n","/**\n * ManifestBuilder — Agent Manifest 构造器\n *\n * 按 manifest-spec.md v1.0 的 4 大类提供 fluent API。\n * 纯本地，不发网络请求。\n */\n\nimport type {\n    AgentManifest,\n    ManifestRule,\n    ManifestSkill,\n    ManifestSubagent,\n    ManifestSlashCommand,\n    ManifestPlugin,\n    ManifestMcp,\n    ManifestWorkspace,\n    ManifestEnv,\n    ManifestSecret,\n} from './types';\nimport { ValidationError } from './errors';\n\nexport class ManifestBuilder {\n    // ─── 基础配置 ────────────────────────────────\n    private _id?: string;\n    private _name?: string;\n    private _version?: string;\n    private _systemPrompt?: string;\n    private _systemPromptFile?: string;\n    private _useWorkspaceRoot?: boolean;\n    private _isolateConfigDir?: boolean;\n    private _settings?: string;\n\n    // ─── 能力与规范 ──────────────────────────────\n    private _rules: ManifestRule[] = [];\n    private _skills: ManifestSkill[] = [];\n    private _subagents: ManifestSubagent[] = [];\n    private _slashCommands: ManifestSlashCommand[] = [];\n    private _plugins: ManifestPlugin[] = [];\n    private _mcp: ManifestMcp[] = [];\n\n    // ─── 工作空间 ────────────────────────────────\n    private _workspaces: ManifestWorkspace[] = [];\n\n    // ─── 环境配置 ────────────────────────────────\n    private _secrets: ManifestSecret[] = [];\n    private _envs: ManifestEnv[] = [];\n\n    // ─── 扩展字段 ────────────────────────────────\n    private _extra: Record<string, unknown> = {};\n\n    // ============================================================\n    // 基础配置\n    // ============================================================\n\n    id(id: string): this {\n        this._id = id;\n        return this;\n    }\n\n    name(name: string): this {\n        this._name = name;\n        return this;\n    }\n\n    version(version: string): this {\n        this._version = version;\n        return this;\n    }\n\n    systemPrompt(prompt: string): this {\n        this._systemPrompt = prompt;\n        this._systemPromptFile = undefined;\n        return this;\n    }\n\n    systemPromptFile(url: string): this {\n        this._systemPromptFile = url;\n        this._systemPrompt = undefined;\n        return this;\n    }\n\n    useWorkspaceRoot(value = true): this {\n        this._useWorkspaceRoot = value;\n        return this;\n    }\n\n    isolateConfigDir(value = true): this {\n        this._isolateConfigDir = value;\n        return this;\n    }\n\n    settings(url: string): this {\n        this._settings = url;\n        return this;\n    }\n\n    // ============================================================\n    // 能力与规范（统一复数，接受单个或数组）\n    // ============================================================\n\n    rules(...rules: ManifestRule[]): this {\n        this._rules.push(...rules);\n        return this;\n    }\n\n    skills(...skills: Array<ManifestSkill | string>): this {\n        for (const s of skills) {\n            this._skills.push(typeof s === 'string' ? { name: s } : s);\n        }\n        return this;\n    }\n\n    subagents(...subagents: Array<ManifestSubagent | string>): this {\n        for (const s of subagents) {\n            this._subagents.push(typeof s === 'string' ? { name: s } : s);\n        }\n        return this;\n    }\n\n    slashCommands(...cmds: Array<ManifestSlashCommand | string>): this {\n        for (const c of cmds) {\n            this._slashCommands.push(typeof c === 'string' ? { name: c } : c);\n        }\n        return this;\n    }\n\n    plugins(...plugins: ManifestPlugin[]): this {\n        this._plugins.push(...plugins);\n        return this;\n    }\n\n    mcp(...mcps: ManifestMcp[]): this {\n        this._mcp.push(...mcps);\n        return this;\n    }\n\n    // ============================================================\n    // 工作空间（统一复数）\n    // ============================================================\n\n    workspaces(...wss: ManifestWorkspace[]): this {\n        this._workspaces.push(...wss);\n        return this;\n    }\n\n    // ============================================================\n    // 环境配置（统一复数）\n    // ============================================================\n\n    secrets(...secrets: ManifestSecret[]): this {\n        this._secrets.push(...secrets);\n        return this;\n    }\n\n    envs(...envs: ManifestEnv[]): this {\n        this._envs.push(...envs);\n        return this;\n    }\n\n    // ============================================================\n    // 扩展\n    // ============================================================\n\n    /** 设置任意扩展字段 */\n    raw(key: string, value: unknown): this {\n        this._extra[key] = value;\n        return this;\n    }\n\n    // ============================================================\n    // 构建\n    // ============================================================\n\n    /** 校验必填字段并构建 */\n    build(): AgentManifest {\n        if (!this._id) throw new ValidationError('manifest.id is required');\n        if (!this._name) throw new ValidationError('manifest.name is required');\n        if (!this._version) throw new ValidationError('manifest.manifestVersion is required');\n        if (this._systemPrompt && this._systemPromptFile) {\n            throw new ValidationError('system_prompt and system_prompt_file are mutually exclusive');\n        }\n\n        const manifest: AgentManifest = {\n            id: this._id,\n            name: this._name,\n            manifestVersion: this._version,\n        };\n\n        // 基础配置\n        if (this._systemPrompt) manifest.system_prompt = this._systemPrompt;\n        if (this._systemPromptFile) manifest.system_prompt_file = this._systemPromptFile;\n        if (this._useWorkspaceRoot !== undefined) manifest.useWorkspaceRoot = this._useWorkspaceRoot;\n        if (this._isolateConfigDir !== undefined) manifest.isolateConfigDir = this._isolateConfigDir;\n        if (this._settings) manifest.settings = this._settings;\n\n        // 能力与规范\n        if (this._rules.length > 0) manifest.rules = this._rules;\n        if (this._skills.length > 0) manifest.skills = this._skills;\n        if (this._subagents.length > 0) manifest.subagents = this._subagents;\n        if (this._slashCommands.length > 0) manifest.slashCommands = this._slashCommands;\n        if (this._plugins.length > 0) manifest.plugins = this._plugins;\n        if (this._mcp.length > 0) manifest.mcp = this._mcp;\n\n        // 工作空间\n        if (this._workspaces.length > 0) manifest.workspaces = this._workspaces;\n\n        // 环境配置\n        if (this._secrets.length > 0) manifest.secrets = this._secrets;\n        if (this._envs.length > 0) manifest.envs = this._envs;\n\n        // 扩展字段\n        Object.assign(manifest, this._extra);\n\n        return manifest;\n    }\n}\n"],"mappings":"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"}