agent-phonon 0.2.8 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +43 -21
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +43 -21
- package/dist/daemon.js.map +1 -1
- package/package.json +2 -2
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../protocol/src/schemas/common.ts","../../protocol/src/schemas/capabilities.ts","../../protocol/src/schemas/discovery.ts","../../protocol/src/schemas/session.ts","../../protocol/src/schemas/stream.ts","../../protocol/src/schemas/hook.ts","../../protocol/src/schemas/document.ts","../../protocol/src/schemas/interaction.ts","../../protocol/src/schemas/project.ts","../../protocol/src/schemas/skill.ts","../../protocol/src/schemas/policy.ts","../../protocol/src/schemas/connect.ts","../../protocol/src/schemas/device.ts","../../protocol/src/schemas/file.ts","../../protocol/src/schemas/env.ts","../../protocol/src/schemas/jsonrpc.ts","../../protocol/src/schemas/methods.ts","../../protocol/src/index.ts","../../core/src/rpc.ts","../../core/src/session-engine.ts","../../core/src/index.ts","../../core/src/project-manager.ts","../../core/src/skill-manager.ts","../../core/src/policy.ts","../../core/src/idempotency.ts","../../core/src/outbox.ts","../../core/src/store.ts","../../core/src/secret-box.ts","../../core/src/file-manager.ts","../../core/src/resources.ts","../../core/src/device-info.ts","../../core/src/env-manager.ts","../../core/src/adapters/openclaw.ts","../../core/src/custom-compress.ts","../../core/src/gateway-client.ts","../../core/src/adapters/openclaw-gateway.ts","../../core/src/client.ts","../../core/src/hook-bridge.ts","../../core/src/sqlite-compress.ts","../../core/src/adapters/codex.ts","../../core/src/adapters/opencode.ts","../../core/src/adapters/hermes.ts","../../core/src/observability.ts","../../core/src/adapters/claude-code.ts","../src/config.ts","../src/commands.ts","../src/obs-server.ts","../src/daemon.ts","../src/cli.ts"],"sourcesContent":["import { z } from \"zod\";\n\n/**\n * agent-phonon wire protocol — shared primitives.\n *\n * 设计参考 docs/design.md。本文件定义全协议复用的基础类型:\n * 协议版本、各类 ID、verbosity、错误码。\n */\n\n/** 协议语义版本。device 与 server 握手时比对(见 connect.hello)。 */\nexport const PROTOCOL_VERSION = \"0.1.0\" as const;\n\n// ---------------------------------------------------------------------------\n// ID 原语(全部是不透明字符串,调用方不应解析其结构)\n// ---------------------------------------------------------------------------\n\n/** phonon 侧全局唯一的 session id(归属某一 tenant)。 */\nexport const SessionId = z.string().min(1).brand<\"SessionId\">();\nexport type SessionId = z.infer<typeof SessionId>;\n\n/** discovery 返回的 agent 标识,也是 session.create 的 `agent` 入参。 */\nexport const AgentId = z.string().min(1).brand<\"AgentId\">();\nexport type AgentId = z.infer<typeof AgentId>;\n\n/** 项目标识(项目 = 目录 + Git)。所有 session 必须绑定一个项目。 */\nexport const ProjectId = z.string().min(1).brand<\"ProjectId\">();\nexport type ProjectId = z.infer<typeof ProjectId>;\n\n/** 本地配置赋予的稳定租户 id(= 一条服务端连接,见 design D13)。 */\nexport const TenantId = z.string().min(1).brand<\"TenantId\">();\nexport type TenantId = z.infer<typeof TenantId>;\n\n/** 设备自身标识(一台设备一个,用于服务端区分多设备,但 phonon 不感知其他设备)。 */\nexport const DeviceId = z.string().min(1).brand<\"DeviceId\">();\nexport type DeviceId = z.infer<typeof DeviceId>;\n\n// ---------------------------------------------------------------------------\n// Verbosity — 控制 session 返回内容的多少(design §4)\n// ---------------------------------------------------------------------------\n\n/**\n * 4 档详细度,create 时设定、send 可覆盖:\n * - final : 仅最终结果\n * - messages : 每轮消息\n * - tools : 含工具调用\n * - trace : 全量(含思考)\n */\nexport const Verbosity = z.enum([\"final\", \"messages\", \"tools\", \"trace\"]);\nexport type Verbosity = z.infer<typeof Verbosity>;\n\n// ---------------------------------------------------------------------------\n// 错误码 — JSON-RPC error.data.code 用(design 中提到的归一化错误)\n// ---------------------------------------------------------------------------\n\n/**\n * 应用级错误码(区别于 JSON-RPC 传输级 code)。\n * 放在 JSON-RPC error 对象的 `data.appCode` 字段,便于调用方稳定判别。\n */\nexport const PhononErrorCode = z.enum([\n // 协议/握手\n \"errProtocolMismatch\", // device 与 server 协议版本不兼容\n \"errUnauthorized\", // device key 无效(注:终端用户鉴权在 server,不在此)\n // 租户隔离(design §6 / D13)\n \"errSessionNotInTenant\", // 跨租户访问 session\n \"errTenantQuotaExceeded\", // 触达 per-tenant 配额\n \"errDeviceQuotaExceeded\", // 触达全局配额\n // 发现 / agent 绑定(design §5 / D14 / D15)\n \"errAgentUnavailable\", // 目标 agent 不存在或不可用\n \"errModelUnavailable\", // 模型不在该 agent 的可用列表内\n // session 生命周期\n \"errSessionNotFound\",\n \"errSessionTerminated\", // 操作了已结束的 session\n \"errSessionBusy\", // session 正忙(如上一轮未结束)\n // 能力\n \"errCapabilityUnsupported\", // adapter 不支持该操作(如 native 压缩缺失)\n // hook / HITL\n \"errHookResolveInvalid\", // hook.resolve 的裁决非法\n \"errHookTimeout\", // 等待服务端裁决超时\n // 项目 / skill(D23-D26)\n \"errProjectNotFound\",\n \"errProjectExists\", // 同名/同路径项目已存在\n \"errProjectHasActiveSessions\", // 项目下还有 active session(remove 拦)\n \"errSkillNotFound\",\n \"errSkillScopeInvalid\", // scope=project 但缺 projectId 等\n \"errSkillInstallFailed\",\n // git / worktree(D25)\n \"errWorktreeNotFound\",\n \"errWorktreeHasChanges\", // 未提交变更,非 force 不清\n \"errWorktreeInUse\", // worktree 还有 active session\n \"errBranchNotMerged\", // 分支未合并,非 force 不删\n \"errBranchInUse\", // 分支仍被某 worktree 检出\n // 文档 / 上传(D20)\n \"errDocumentTooLarge\", // 超 maxUploadBytes\n \"errDocumentPathDenied\", // 路径不在项目范围 / 命中 deny\n // 本地 policy(D27)\n \"errPolicyDenied\", // 被设备本地安全策略拦截\n // 幂等\n \"errDuplicateRequest\", // clientRequestId 重复(已处理过)\n // 通用\n \"errInvalidParams\",\n \"errInternal\",\n]);\nexport type PhononErrorCode = z.infer<typeof PhononErrorCode>;\n\n/** 统一附在 JSON-RPC error.data 上的结构。 */\nexport const PhononErrorData = z.object({\n appCode: PhononErrorCode,\n /** 可选的人类可读补充(不用于程序判别)。 */\n detail: z.string().optional(),\n /** 可选:相关 session/agent/tenant,便于服务端定位。 */\n sessionId: SessionId.optional(),\n agentId: AgentId.optional(),\n tenantId: TenantId.optional(),\n});\nexport type PhononErrorData = z.infer<typeof PhononErrorData>;\n\n/** ISO-8601 时间戳字符串(统一用字符串,避免时区/精度歧义)。 */\nexport const Timestamp = z.string().datetime({ offset: true });\nexport type Timestamp = z.infer<typeof Timestamp>;\n","import { z } from \"zod\";\n\n/**\n * Hook 类型 — 归一化的拦截点(design §8)。\n * adapter 负责把各家原生 hook 点(Codex hooks / Claude Code PreToolUse /\n * OpenClaw 审批…)映射成这些归一化类型。\n */\nexport const HookType = z.enum([\n \"pre_tool\", // 工具调用前\n \"post_tool\", // 工具调用后\n \"pre_command\", // 执行 shell/命令前(rm/git push 等危险操作)\n \"pre_file_write\", // 写文件前\n \"pre_network\", // 发起网络/外部请求前\n \"session_start\", // 会话开始\n \"session_end\", // 会话结束\n \"notification\", // agent 主动通知(无需裁决,纯告知)\n]);\nexport type HookType = z.infer<typeof HookType>;\n\n/**\n * Adapter 能力声明(design §7)。\n * adapter 不假装统一,而是声明自己原生支持什么,phonon core 据此补齐缺口。\n * 这份能力随 discovery 一起暴露给服务端,服务端先知能力再决定怎么用。\n */\nexport const AgentCapabilities = z.object({\n /** 原生 session / resume(无则由 core 用注册表模拟)。 */\n nativeSession: z.boolean(),\n /** 原生上下文压缩(决定 session.compress mode=native 是否可用)。 */\n nativeCompression: z.boolean(),\n /** 原生上下文注入。 */\n contextInjection: z.boolean(),\n /**\n * 是否会**主动/非请求触发地输出**(design 订阅模型)。\n * OpenClaw 这类有 cron/心跳/定时任务,同一 session 内会不定期自发冲泡 → true;\n * Codex 这类一次性,流到结果就结束 → false。\n * server 据此判断哪些 session 需要长期保持监听。\n */\n proactiveOutput: z.boolean(),\n /** 是否支持同会话中途切换模型(design D16)。 */\n modelSwitch: z.boolean(),\n /** 是否支持打断正在进行的 turn(session.interrupt / whenBusy=interrupt,D18)。 */\n interrupt: z.boolean(),\n /** 是否支持中途插入输入(下一次 tool call 边界,whenBusy=inject,D18)。 */\n injectMidTurn: z.boolean(),\n /** 是否支持给该 agent 安装/卸载 skill(skill.* 接口,D24)。 */\n skillManagement: z.boolean(),\n /** 原生支持的 hook 点(其余由 core 尽力补齐或不支持)。 */\n hooks: z.array(HookType),\n /** 是否支持流式输出。 */\n streaming: z.boolean(),\n /**\n * 可选调度限制(P2-13):server 据此做调度/背压。\n */\n limits: z\n .object({\n maxConcurrentSessions: z.number().int().positive().optional(),\n maxContextTokens: z.number().int().positive().optional(),\n maxMessageBytes: z.number().int().positive().optional(),\n })\n .optional(),\n});\nexport type AgentCapabilities = z.infer<typeof AgentCapabilities>;\n","import { z } from \"zod\";\nimport { AgentId, Timestamp } from \"./common.js\";\nimport { AgentCapabilities } from \"./capabilities.js\";\n\n/**\n * Agent / 模型发现(design §5 / D14)。\n *\n * 发现 = 内部扫描机制(非协议)+ 对外暴露接口(属协议)。本文件只定义\n * **对外接口**的数据形状:服务端借此感知「这台设备上哪些 agent 可用、\n * 各自哪些模型可用」。\n */\n\n/** 单个模型的可用性描述。 */\nexport const ModelInfo = z.object({\n /** 模型 id,session.create 的 `model` 入参取自这里。 */\n id: z.string().min(1),\n /** 展示名(可选)。 */\n displayName: z.string().optional(),\n /** 上下文窗口(token,若已知)。注意:以 phonon 实测/配置为准,不盲信后端返回。 */\n contextWindow: z.number().int().positive().optional(),\n /** 该模型当前是否可用(如鉴权过期会变 false)。 */\n available: z.boolean().default(true),\n});\nexport type ModelInfo = z.infer<typeof ModelInfo>;\n\n/** 单个 agent 的发现条目。 */\nexport const AgentDescriptor = z.object({\n agentId: AgentId,\n /** 展示名,如 \"Claude Code\" / \"OpenClaw\"。 */\n displayName: z.string().min(1),\n /** 适配器内部名,如 \"openclaw\" / \"claude-code\"。 */\n adapter: z.string().min(1),\n /** 整体是否可用(已安装 + 可执行 + 凭证就绪)。 */\n available: z.boolean(),\n /** 不可用时的原因(如 \"not_installed\" / \"not_logged_in\" / \"no_credentials\")。 */\n unavailableReason: z.string().optional(),\n /** agent 自身版本(若可探测)。 */\n version: z.string().optional(),\n /** 可用模型列表。 */\n models: z.array(ModelInfo),\n /** 能力声明(随 discovery 暴露,见 §7)。 */\n capabilities: AgentCapabilities,\n /** 最近一次扫描时间。 */\n scannedAt: Timestamp.optional(),\n});\nexport type AgentDescriptor = z.infer<typeof AgentDescriptor>;\n\n// --- discovery.list ---\nexport const DiscoveryListParams = z.object({\n /** 可选:只看可用的。 */\n availableOnly: z.boolean().optional(),\n});\nexport type DiscoveryListParams = z.infer<typeof DiscoveryListParams>;\n\nexport const DiscoveryListResult = z.object({\n agents: z.array(AgentDescriptor),\n});\nexport type DiscoveryListResult = z.infer<typeof DiscoveryListResult>;\n\n// --- discovery.get ---\nexport const DiscoveryGetParams = z.object({\n agentId: AgentId,\n});\nexport type DiscoveryGetParams = z.infer<typeof DiscoveryGetParams>;\n\nexport const DiscoveryGetResult = z.object({\n agent: AgentDescriptor,\n});\nexport type DiscoveryGetResult = z.infer<typeof DiscoveryGetResult>;\n\n// --- discovery.changed (phonon -> server 主动推送,notification) ---\nexport const DiscoveryChangedParams = z.object({\n /** 变更类型:agent 上/下线、模型增减、能力变化。 */\n kind: z.enum([\"agent_added\", \"agent_removed\", \"agent_updated\", \"models_changed\"]),\n agentId: AgentId,\n /** 变更后的完整快照(可选,便于服务端直接更新缓存)。 */\n snapshot: AgentDescriptor.optional(),\n at: Timestamp,\n});\nexport type DiscoveryChangedParams = z.infer<typeof DiscoveryChangedParams>;\n","import { z } from \"zod\";\nimport { AgentId, ProjectId, SessionId, Timestamp, Verbosity } from \"./common.js\";\n\n/**\n * L1 Session 协议原语(design §4)。\n *\n * 铁律:session 必须绑定 agent(D15)。每条 session 天生属于某个 agent + model,\n * 这是 session 的一等身份,不是可选配置。发任务 = 在 session 里对话。\n */\n\n/** session 状态。 */\n/**\n * session 状态(design D19)。\n * - idle : 活着、空闲、就绪可接 send(create 后初始态;turn 结束/interrupt 后回到这)\n * - running : agent 正在执行一个 turn\n * - paused : 挂起(重启后从 DB 恢复、原生 ref 尚未 re-attach;或被显式暂停),需恢复才能用\n * - terminated : 已结束销毁\n */\nexport const SessionStatus = z.enum([\"idle\", \"running\", \"paused\", \"terminated\"]);\nexport type SessionStatus = z.infer<typeof SessionStatus>;\n\n/**\n * 上下文条目 —— 用于 initialContext / inject。\n * 设计成「角色 + 文本」的最小通用形态,具体 adapter 自行翻译成原生格式。\n */\nexport const ContextItem = z.object({\n role: z.enum([\"system\", \"user\", \"assistant\"]),\n content: z.string(),\n});\nexport type ContextItem = z.infer<typeof ContextItem>;\n\n// ---------------------------------------------------------------------------\n// session.create\n// ---------------------------------------------------------------------------\nexport const SessionCreateParams = z.object({\n /** 可选:幂等键(P0-3,断线重发去重)。 */\n clientRequestId: z.string().optional(),\n /** 必填:绑定的项目(所有 session 必须有项目目录,D23)。 */\n project: ProjectId,\n /** 可选:跑在哪个 worktree(缺省用项目主工作区,D25)。 */\n worktreeId: z.string().optional(),\n /** 必填:绑定的 agent(来自 discovery 的 agentId)。 */\n agent: AgentId,\n /** 必填:绑定的模型(必须在该 agent 的可用模型列表内)。 */\n model: z.string().min(1),\n /** 透传给 adapter 的 agent 私有配置(cwd、工具白名单、thinking 等)。 */\n agentConfig: z.record(z.unknown()).optional(),\n /** 初始上下文设置(system prompt / 预置对话)。 */\n initialContext: z.array(ContextItem).optional(),\n /** 默认返回详细度,send 可覆盖。默认 messages。 */\n verbosity: Verbosity.default(\"messages\"),\n /** 可选:调用方自带的标签,便于服务端侧对账(phonon 原样回显)。 */\n clientTag: z.string().optional(),\n});\nexport type SessionCreateParams = z.infer<typeof SessionCreateParams>;\n\nexport const SessionCreateResult = z.object({\n sessionId: SessionId,\n /** 回显绑定身份,方便调用方确认。 */\n project: ProjectId,\n agent: AgentId,\n model: z.string(),\n status: SessionStatus,\n createdAt: Timestamp,\n});\nexport type SessionCreateResult = z.infer<typeof SessionCreateResult>;\n\n// ---------------------------------------------------------------------------\n// session.send —— 发任务 = 对话;结果以流式 events 异步返回(见 stream.ts)\n// ---------------------------------------------------------------------------\n\n/**\n * 忙碌处理模式(D18)—— 新消息进来时上一轮还没结束怎么办:\n * - queue :等待,上一轮结束后自动发送积压消息(默认,最安全)。\n * - interrupt:中断当前 turn(session 存活),再发新消息;需 capability.interrupt。\n * - inject :不中断,在下一次 tool call 边界插入输入让 agent 接着处理;\n * 需 capability.injectMidTurn(agent 原生接口或通过 hook 实现)。\n * 不论哪种模式,**消息不丢**:要么按序送达、要么明确拒绝并告知原因。\n */\nexport const WhenBusy = z.enum([\"queue\", \"interrupt\", \"inject\"]);\nexport type WhenBusy = z.infer<typeof WhenBusy>;\n\nexport const SessionSendParams = z.object({\n sessionId: SessionId,\n /** 用户输入 / 任务内容。 */\n input: z.string(),\n /**\n * 可选:幂等键(P0-3)。服务端断线重发同一 send 时带相同值,\n * phonon 去重,避免 agent 收两遍同样消息;重复回 `errDuplicateRequest` 或原 turnId。\n */\n clientRequestId: z.string().optional(),\n /**\n * 可选:本轮指定要用的 skill(D26)。每项可是简单名字(string),\n * 或结构体 {name,version?,scope?,force?}(P2-12,消除同名 global/project 歧义)。\n * phonon 保证:(1) skill 在 agent 能访问到的位置;(2) 上下文注入强制加载指令。\n * 优先级:send 指定 > project skill > global skill。\n */\n skills: z\n .array(\n z.union([\n z.string(),\n z.object({\n name: z.string().min(1),\n version: z.string().optional(),\n scope: z.enum([\"global\", \"project\"]).optional(),\n force: z.boolean().optional(),\n }),\n ]),\n )\n .optional(),\n /** 可选:覆盖本轮详细度。 */\n verbosity: Verbosity.optional(),\n /**\n * 忙碌时的处理模式(D18)。缺省 queue。\n * 若选的模式该 agent 不支持(看 capability)且未设 fallback → errCapabilityUnsupported。\n */\n whenBusy: WhenBusy.default(\"queue\"),\n /**\n * 可选:降级模式(P1-11)。当 whenBusy 该 agent 不支持时,不报错而自动降级为它,\n * 保证自动化编排连贯。如 whenBusy=\"inject\", fallback=\"queue\"。\n */\n fallback: WhenBusy.optional(),\n /**\n * 可选:本轮关联 id。phonon 会把该轮所有 stream.event 标上同一 turnId,\n * 调用方据此聚合流式输出。缺省由 phonon 生成并在 ack 中返回。\n */\n turnId: z.string().optional(),\n});\nexport type SessionSendParams = z.infer<typeof SessionSendParams>;\n\n/** send 的同步 ack(真正的内容走 stream.event 异步推)。 */\nexport const SessionSendAck = z.object({\n sessionId: SessionId,\n turnId: z.string(),\n accepted: z.literal(true),\n /**\n * 本次 send 的实际处由:\n * - started :立即开始执行(session 空闲)\n * - queued :已排队(whenBusy=queue 且正忙)\n * - interrupted:已中断上一轮并开始本轮(whenBusy=interrupt)\n * - injected :将在下一 tool call 边界插入(whenBusy=inject)\n */\n disposition: z.enum([\"started\", \"queued\", \"interrupted\", \"injected\"]),\n /** queued 时的队列位置(从 1 起)。 */\n queuePosition: z.number().int().positive().optional(),\n});\nexport type SessionSendAck = z.infer<typeof SessionSendAck>;\n\n// ---------------------------------------------------------------------------\n// session.interrupt —— 打断当前正在进行的 turn(session 存活,D18)\n// 区别于 session.terminate(销毁整个 session)。\n// P0-2:interrupt 后 phonon 必须为被打断的 turn 发一条终态 stream.event\n// { type:\"result\", final:true, status:\"interrupted\" },服务端状态机才不悬空。\n// ---------------------------------------------------------------------------\nexport const SessionInterruptParams = z.object({\n sessionId: SessionId,\n /** 可选:中断原因(传给 agent / 记录)。 */\n reason: z.string().optional(),\n});\nexport type SessionInterruptParams = z.infer<typeof SessionInterruptParams>;\n\nexport const SessionInterruptResult = z.object({\n sessionId: SessionId,\n /** 被中断的 turn(若当时有在跑的)。 */\n interruptedTurnId: z.string().optional(),\n /** 中断后 session 状态(通常回到 active 空闲)。 */\n status: SessionStatus,\n});\nexport type SessionInterruptResult = z.infer<typeof SessionInterruptResult>;\n\n// ---------------------------------------------------------------------------\n// session.inject —— 上下文注入\n// ---------------------------------------------------------------------------\nexport const SessionInjectParams = z.object({\n sessionId: SessionId,\n context: z.array(ContextItem),\n});\nexport type SessionInjectParams = z.infer<typeof SessionInjectParams>;\n\nexport const SessionInjectResult = z.object({\n sessionId: SessionId,\n injected: z.number().int().nonnegative(),\n});\nexport type SessionInjectResult = z.infer<typeof SessionInjectResult>;\n\n// ---------------------------------------------------------------------------\n// session.compress —— 压缩双模(design §4 / D7)\n// ---------------------------------------------------------------------------\nexport const CompressMode = z.enum([\"native\", \"custom\"]);\nexport type CompressMode = z.infer<typeof CompressMode>;\n\nexport const SessionCompressParams = z.object({\n sessionId: SessionId,\n /** native = 透传 agent 原生压缩;custom = phonon 自有压缩引擎。 */\n mode: CompressMode,\n /**\n * custom 模式下的策略名(P2-15)。**server-private:phonon 不做协议层枚举校验**,\n * 透传给 adapter/压缩引擎自行解释(如 summary / truncate_keep_recent)。\n */\n strategy: z.string().optional(),\n /** dropToolIO 策略:保留最近 N 个 tool call 及其 result,默认 3。 */\n keepRecentToolCalls: z.number().int().nonnegative().optional(),\n});\nexport type SessionCompressParams = z.infer<typeof SessionCompressParams>;\n\nexport const SessionCompressResult = z.object({\n sessionId: SessionId,\n mode: CompressMode,\n /** 压缩前后的 token 估算(若可得)。 */\n tokensBefore: z.number().int().nonnegative().optional(),\n tokensAfter: z.number().int().nonnegative().optional(),\n /** 简短摘要/说明。 */\n summary: z.string().optional(),\n});\nexport type SessionCompressResult = z.infer<typeof SessionCompressResult>;\n\n// ---------------------------------------------------------------------------\n// session.terminate\n// ---------------------------------------------------------------------------\nexport const SessionTerminateParams = z.object({\n sessionId: SessionId,\n /**\n * 可选:销毁会话时顺手清理其专用 worktree(P1-10)。\n * 仅当该 session 跑在一个专为它建的 worktree 上才生效;主工作区不清。\n */\n cleanWorktree: z.boolean().default(false),\n});\nexport type SessionTerminateParams = z.infer<typeof SessionTerminateParams>;\n\nexport const SessionTerminateResult = z.object({\n sessionId: SessionId,\n status: z.literal(\"terminated\"),\n /** 若 cleanWorktree 且确实清了,返回被清理的 worktreeId。 */\n cleanedWorktreeId: z.string().optional(),\n});\nexport type SessionTerminateResult = z.infer<typeof SessionTerminateResult>;\n\n// ---------------------------------------------------------------------------\n// session.switchModel —— 同会话中途切换模型(design D16)\n// agent 绑定不可变,但 model 可换:某模型不行了就换另一个。\n// ---------------------------------------------------------------------------\nexport const SessionSwitchModelParams = z.object({\n sessionId: SessionId,\n /** 新模型,必须在该 session 绑定 agent 的可用模型列表内。 */\n model: z.string().min(1),\n /**\n * running 时的策略(P1-8):\n * - reject(默认) :running 时拒绝切换,避免 adapter 状态不一致\n * - afterCurrentTurn:等当前 turn 结束后再切\n * - interrupt :打断当前 turn 立即切\n * idle 时忽略此参数,直接切。\n */\n whenRunning: z.enum([\"reject\", \"afterCurrentTurn\", \"interrupt\"]).default(\"reject\"),\n});\nexport type SessionSwitchModelParams = z.infer<typeof SessionSwitchModelParams>;\n\nexport const SessionSwitchModelResult = z.object({\n sessionId: SessionId,\n /** 切换前的模型(便于调用方记录/回滚)。 */\n previousModel: z.string(),\n model: z.string(),\n /**\n * 可选警告(P1-8 / Minimax):adapter 发现潜在不兼容(系统提示格式/tool schema 变化)\n * 时填入,server 据此决定是否继续。\n */\n warnings: z.array(z.string()).optional(),\n /** 若 whenRunning=afterCurrentTurn 且当时 running,表示已排期未立即生效。 */\n deferred: z.boolean().optional(),\n});\nexport type SessionSwitchModelResult = z.infer<typeof SessionSwitchModelResult>;\n\n// ---------------------------------------------------------------------------\n// session.status / session.list —— 始终携带 agent 身份\n// ---------------------------------------------------------------------------\nexport const SessionMeta = z.object({\n sessionId: SessionId,\n /** 绑定的项目(一等身份,D23)。 */\n project: ProjectId,\n /** 绑定的 agent 身份,全程携带。 */\n agent: AgentId,\n model: z.string(),\n status: SessionStatus,\n /** 当 status=running 时,正在执行的 turnId(服务端据此知道「在跑哪一轮」)。 */\n currentTurnId: z.string().optional(),\n /** 队列中等待的 send 数(whenBusy=queue 积压,D18)。 */\n queuedCount: z.number().int().nonnegative().optional(),\n /**\n * 上下文信息(D33)——adapter 能提供时填,便于 server 监控上下文压力。\n */\n context: z\n .object({\n /** 上下文窗口总容量(token)。 */\n contextWindow: z.number().int().nonnegative().optional(),\n /** 已用上下文(token,若可估)。 */\n usedTokens: z.number().int().nonnegative().optional(),\n /** 已用上下文占比 0-100。 */\n usagePercent: z.number().min(0).max(100).optional(),\n /** 已发生的压缩次数。 */\n compactions: z.number().int().nonnegative().optional(),\n })\n .optional(),\n verbosity: Verbosity,\n clientTag: z.string().optional(),\n createdAt: Timestamp,\n lastActiveAt: Timestamp.optional(),\n});\nexport type SessionMeta = z.infer<typeof SessionMeta>;\n\nexport const SessionStatusParams = z.object({\n sessionId: SessionId,\n});\nexport type SessionStatusParams = z.infer<typeof SessionStatusParams>;\n\nexport const SessionStatusResult = SessionMeta;\nexport type SessionStatusResult = z.infer<typeof SessionStatusResult>;\n\nexport const SessionListParams = z.object({\n /** 可选:按项目过滤。 */\n project: ProjectId.optional(),\n /** 可选:按 agent 过滤。 */\n agent: AgentId.optional(),\n /** 可选:按状态过滤。 */\n status: SessionStatus.optional(),\n /** 可选:分页上限(P2-14)。 */\n limit: z.number().int().positive().max(500).optional(),\n /** 可选:分页游标(上一页返回的 nextCursor)。 */\n cursor: z.string().optional(),\n});\nexport type SessionListParams = z.infer<typeof SessionListParams>;\n\nexport const SessionListResult = z.object({\n sessions: z.array(SessionMeta),\n /** 下一页游标;缺省/null 表示已到末尾。 */\n nextCursor: z.string().optional(),\n});\nexport type SessionListResult = z.infer<typeof SessionListResult>;\n","import { z } from \"zod\";\nimport { SessionId, Timestamp } from \"./common.js\";\n\n/**\n * 流式事件(design §4 / §6 / 订阅模型)——phonon → server 异步推送。\n *\n * 关键:session 不只是「请求-响应」,还是一条**可订阅的持续输出流**。\n * 输出分两种来源(origin):\n * - solicited :某次 session.send 触发的响应(用 send 返回的 turnId)。\n * - unsolicited:agent 自发输出(OpenClaw 的 cron/定时/心跳),无 send 触发;\n * turnId 由 phonon 生成,source 标明冲泡来源。\n *\n * “create 即订阅”:server 拥有的 session 的**所有** stream.event(含自发)都自动\n * 推给该 tenant 连接,无需显式 subscribe。Codex 一次性 session 流到 result final 就停;\n * OpenClaw 持久 session 即使不 send 也会持续往上冒。\n *\n * 不同事件对应不同 verbosity 档位:\n * final → 只会收到 result\n * messages → message + result\n * tools → message + tool_call + tool_result + result\n * trace → 以上 + thinking + token delta\n */\n\n/** 输出来源:请求触发 vs agent 自发。 */\nexport const StreamOrigin = z.enum([\"solicited\", \"unsolicited\"]);\nexport type StreamOrigin = z.infer<typeof StreamOrigin>;\n\n/** 事件种类。 */\nexport const StreamEventType = z.enum([\n \"message\", // 一条完整/增量消息文本\n \"thinking\", // 思考过程(trace 档)\n \"tool_call\", // agent 发起工具调用\n \"tool_result\", // 工具返回\n \"token\", // 增量 token(流式打字机,trace/可选)\n \"result\", // 本轮最终结果(终止事件)\n \"error\", // 本轮出错(终止事件)\n]);\nexport type StreamEventType = z.infer<typeof StreamEventType>;\n\nconst StreamEventBase = z.object({\n sessionId: SessionId,\n /**\n * 本轮关联 id。solicited 事件用 send 返回的 turnId;\n * unsolicited(自发)事件由 phonon 生成,server 从事件中首次见到。\n */\n turnId: z.string(),\n /** 输出来源:默认 solicited;agent 自发为 unsolicited。 */\n origin: StreamOrigin.default(\"solicited\"),\n /** unsolicited 时的冲泡来源标签,如 \"cron\" / \"scheduled\" / \"heartbeat\"。 */\n source: z.string().optional(),\n /** 单调递增序号(按 session),保证调用方可排序/去重。 */\n seq: z.number().int().nonnegative(),\n at: Timestamp,\n});\n\nexport const StreamMessageEvent = StreamEventBase.extend({\n type: z.literal(\"message\"),\n role: z.enum([\"assistant\", \"user\", \"system\"]).default(\"assistant\"),\n text: z.string(),\n /** 是否为增量分片(true 表示需要与同 turn 的后续 message 拼接)。 */\n delta: z.boolean().default(false),\n});\n\nexport const StreamThinkingEvent = StreamEventBase.extend({\n type: z.literal(\"thinking\"),\n text: z.string(),\n delta: z.boolean().default(false),\n});\n\nexport const StreamToolCallEvent = StreamEventBase.extend({\n type: z.literal(\"tool_call\"),\n toolName: z.string(),\n /** 工具入参(原样透传,结构由 agent/工具决定)。 */\n args: z.unknown().optional(),\n /** 工具调用 id,用于和 tool_result 配对。 */\n toolCallId: z.string().optional(),\n});\n\nexport const StreamToolResultEvent = StreamEventBase.extend({\n type: z.literal(\"tool_result\"),\n toolName: z.string(),\n toolCallId: z.string().optional(),\n ok: z.boolean(),\n /** 工具输出(可能被截断,取决于 verbosity/大小限制)。 */\n output: z.unknown().optional(),\n});\n\nexport const StreamTokenEvent = StreamEventBase.extend({\n type: z.literal(\"token\"),\n text: z.string(),\n});\n\nexport const StreamResultEvent = StreamEventBase.extend({\n type: z.literal(\"result\"),\n /** 本轮最终文本结果。 */\n text: z.string(),\n /** 可选 usage 统计。 */\n usage: z\n .object({\n inputTokens: z.number().int().nonnegative().optional(),\n outputTokens: z.number().int().nonnegative().optional(),\n })\n .optional(),\n /**\n * 本轮终态(P0-2)——每个 turn 必须有明确终态,服务端状态机才不会悬空:\n * completed 正常完成\n * interrupted 被 session.interrupt 打断\n * aborted 被 hook abort / 主动中止\n * failed 出错终止(详情另见 error 事件)\n * timeout 超时\n */\n status: z.enum([\"completed\", \"interrupted\", \"aborted\", \"failed\", \"timeout\"]).default(\"completed\"),\n /** 标记本轮结束。 */\n final: z.literal(true),\n});\n\nexport const StreamErrorEvent = StreamEventBase.extend({\n type: z.literal(\"error\"),\n message: z.string(),\n /** 可选应用错误码(与 common.PhononErrorCode 对齐)。 */\n appCode: z.string().optional(),\n /** 终态(与 result.status 对齐,错误场景通常 failed/aborted/timeout)。 */\n status: z.enum([\"failed\", \"aborted\", \"timeout\", \"interrupted\"]).default(\"failed\"),\n final: z.literal(true),\n});\n\n// ---------------------------------------------------------------------------\n// stream.ack —— server → phonon,确认已收到 seq <= lastSeq(P0-4)\n// 让 phonon 能清理 outbox / 控制背压;可按 session 粒度或全局。\n// ---------------------------------------------------------------------------\nexport const StreamAckParams = z.object({\n /** 按 session 确认;缺省表示该连接全局。 */\n sessionId: SessionId.optional(),\n /** 已收到的最大连续 seq(含);phonon 可清理 <= 此值的 outbox。 */\n lastSeq: z.number().int().nonnegative(),\n});\nexport type StreamAckParams = z.infer<typeof StreamAckParams>;\n\n/** 流式事件联合体(phonon → server,方法名 stream.event)。 */\nexport const StreamEvent = z.discriminatedUnion(\"type\", [\n StreamMessageEvent,\n StreamThinkingEvent,\n StreamToolCallEvent,\n StreamToolResultEvent,\n StreamTokenEvent,\n StreamResultEvent,\n StreamErrorEvent,\n]);\nexport type StreamEvent = z.infer<typeof StreamEvent>;\n","import { z } from \"zod\";\nimport { SessionId, Timestamp } from \"./common.js\";\nimport { HookType } from \"./capabilities.js\";\nimport { ContextItem } from \"./session.js\";\n\n/**\n * Hook / 人在回路 HITL(design §8)。\n *\n * 核心:phonon 自己不实现人在回路,只做事件中转 + 阻塞等裁决。\n * phonon → server : hook.fired (到 hook 点抛事件)\n * server → phonon : hook.resolve (裁决;服务端决定是否问真人、怎么问、等多久)\n */\n\n/** hook 触发载荷(phonon → server)。 */\nexport const HookFiredParams = z.object({\n sessionId: SessionId,\n /** 本次 hook 的唯一 id,hook.resolve 用它配对。 */\n hookId: z.string().min(1),\n hookType: HookType,\n /** 触发上下文:被拦截的操作详情(命令、工具名、参数、文件路径等)。 */\n payload: z\n .object({\n toolName: z.string().optional(),\n command: z.string().optional(),\n filePath: z.string().optional(),\n url: z.string().optional(),\n /** 其余 adapter 特定字段。 */\n extra: z.record(z.unknown()).optional(),\n })\n .default({}),\n /** 该 turn 的关联 id(若在某轮对话内触发)。 */\n turnId: z.string().optional(),\n at: Timestamp,\n});\nexport type HookFiredParams = z.infer<typeof HookFiredParams>;\n\n/**\n * 裁决动作(server → phonon)。\n * - continue : 放行,照常执行\n * - inject : 先注入上下文再继续(用 context 字段)\n * - modify : 用修改后的参数继续(用 patch 字段,如改写命令)\n * - abort : 中止该操作(可带原因)\n */\nexport const HookAction = z.enum([\"continue\", \"inject\", \"modify\", \"abort\"]);\nexport type HookAction = z.infer<typeof HookAction>;\n\nexport const HookResolveParams = z.object({\n sessionId: SessionId,\n /** 必须与对应 hook.fired 的 hookId 一致。 */\n hookId: z.string().min(1),\n action: HookAction,\n /** action=inject 时:要注入的上下文。 */\n context: z.array(ContextItem).optional(),\n /** action=modify 时:对被拦截操作的修改(结构与该 hook 的 payload 对应)。 */\n patch: z.record(z.unknown()).optional(),\n /** action=abort 时:可选原因,会回传给 agent / 记录。 */\n reason: z.string().optional(),\n});\nexport type HookResolveParams = z.infer<typeof HookResolveParams>;\n\nexport const HookResolveResult = z.object({\n sessionId: SessionId,\n hookId: z.string(),\n applied: z.boolean(),\n});\nexport type HookResolveResult = z.infer<typeof HookResolveResult>;\n","import { z } from \"zod\";\nimport { SessionId, Timestamp } from \"./common.js\";\n\n/**\n * 文档交换协议(design 平面③ / D20)。\n *\n * 场景:agent 需要/被要求发送本地文档时,在输出里 emit 一个**指令**(skill 教的格式,\n * 见 DocumentDirective),phonon 解析后**负责读取本地文件**,打包成附件/其他形式发到服务端。\n * 也就是说:agent 只说「路径」,读盘 + 传输由 phonon 这一层兜。\n *\n * 两个层次要分清:\n * - DocumentDirective :agent ↔ phonon 的指令(含本地 path,skill 教)\n * - document.send :phonon ↔ server 的线协议(含真实内容/附件)\n */\n\n/** 文档用途/形式。 */\nexport const DocumentKind = z.enum([\n \"attachment\", // 通用附件\n \"document\", // 富文本文档(如 .md → 服务端可转云文档)\n \"image\", // 图片\n \"file\", // 其他普通文件\n]);\nexport type DocumentKind = z.infer<typeof DocumentKind>;\n\n/** 内容承载方式:小文件内联,大文件用 ref 走分块传输(具体待定)。 */\nexport const DocumentContent = z.union([\n z.object({ encoding: z.literal(\"base64\"), data: z.string() }),\n z.object({ encoding: z.literal(\"utf8\"), data: z.string() }),\n z.object({ ref: z.string() }), // 分块传输句柄(大文件,开放问题)\n]);\nexport type DocumentContent = z.infer<typeof DocumentContent>;\n\n/**\n * agent 在输出里 emit 的指令格式(skill 教)——只含本地路径与元信息,\n * phonon 据此读本地文件。**不直接进线协议。**\n *\n * 安全(D27 policy):默认 **project-scoped**——路径必须在绑定项目/worktree 目录内,\n * 越界需 tenant policy 显式 `allowExternalDocuments`;命中 denyPathPatterns 一律拒。\n */\nexport const DocumentDirective = z.object({\n /** 文件路径(默认相对于项目/worktree 根;绝对路径需 policy 允许且在范围内)。 */\n path: z.string().min(1),\n /** 可选:覆盖文件名(默认取 path 的 basename)。 */\n name: z.string().optional(),\n kind: DocumentKind.optional(),\n caption: z.string().optional(),\n});\nexport type DocumentDirective = z.infer<typeof DocumentDirective>;\n\n/** 单个文档的线上描述(phonon 读完本地文件后封装)。 */\nexport const DocumentDescriptor = z.object({\n name: z.string().min(1),\n /** 相对项目根的路径(审计/去重用;不暴露设备绝对路径)。 */\n relativePath: z.string().optional(),\n mimeType: z.string().optional(),\n kind: DocumentKind.default(\"file\"),\n caption: z.string().optional(),\n sizeBytes: z.number().int().nonnegative().optional(),\n /** 内容 sha256(完整性校验 / 去重)。 */\n sha256: z.string().optional(),\n content: DocumentContent,\n});\nexport type DocumentDescriptor = z.infer<typeof DocumentDescriptor>;\n\n// --- document.send(phonon → server)---\nexport const DocumentSendParams = z.object({\n /** 关联会话(通常有;纯设备级发送可省)。 */\n sessionId: SessionId.optional(),\n /** 关联轮次(若在某轮对话内触发)。 */\n turnId: z.string().optional(),\n documents: z.array(DocumentDescriptor).min(1),\n at: Timestamp,\n});\nexport type DocumentSendParams = z.infer<typeof DocumentSendParams>;\n\nexport const DocumentSendResult = z.object({\n delivered: z.array(\n z.object({\n name: z.string(),\n ok: z.boolean(),\n /** 服务端落地引用(如云文档 token / 附件 id)。 */\n serverRef: z.string().optional(),\n error: z.string().optional(),\n }),\n ),\n});\nexport type DocumentSendResult = z.infer<typeof DocumentSendResult>;\n\n// ===========================================================================\n// 大文件:凭证上传(P1-6 / Gemini#2)\n// 不走 WS 发文件主体(避免内存暴涨/断线重传痛),而是:\n// phonon → document.prepare_upload {filename,size,mime,sha256}\n// server → 返回一个 HTTP 上传地址(预签名 URL / 一次性 token)\n// phonon 本地跑标准 HTTP POST(multipart/流式/断点续传)\n// 上传成功后用 document.send 用 ref 关联回 session\n// ===========================================================================\nexport const DocumentPrepareUploadParams = z.object({\n sessionId: SessionId.optional(),\n turnId: z.string().optional(),\n filename: z.string().min(1),\n sizeBytes: z.number().int().nonnegative(),\n mimeType: z.string().optional(),\n sha256: z.string().optional(),\n kind: DocumentKind.default(\"file\"),\n at: Timestamp,\n});\nexport type DocumentPrepareUploadParams = z.infer<typeof DocumentPrepareUploadParams>;\n\nexport const DocumentPrepareUploadResult = z.object({\n /** 上传句柄,上传成功后回填到 DocumentContent.ref。 */\n uploadRef: z.string(),\n /** server 给的 HTTP 上传地址(预签名 URL 等)。 */\n uploadUrl: z.string(),\n /** HTTP 方法(默认 PUT)。 */\n method: z.enum([\"PUT\", \"POST\"]).default(\"PUT\"),\n /** 需携带的额外请求头。 */\n headers: z.record(z.string()).optional(),\n /** 上传地址过期时间。 */\n expiresAt: Timestamp.optional(),\n});\nexport type DocumentPrepareUploadResult = z.infer<typeof DocumentPrepareUploadResult>;\n","import { z } from \"zod\";\nimport { SessionId, Timestamp } from \"./common.js\";\n\n/**\n * 人机交互协议(design 平面③ / D21)。\n *\n * 场景:HITL 时、或 agent 主动想问人,发一个**可交互卡片/表单**(抽象结构),\n * phonon → server 渲染给人(飞书卡片/网页/TG 按钮…由服务端决定,复用「甩锅服务端」原则),\n * 人填完 → 原路返回 → 注入回 agent。\n *\n * 两个层次:\n * - InteractionDirective :agent emit 的表单定义(skill 教,让任何模型都能发)\n * - interaction.request :phonon → server 线协议(带 requestId,阻塞等回填)\n * - interaction.response :server → phonon 线协议(人填完的值)\n *\n * 表单只定义**抽象字段结构**,不绑定任何渲染方式——服务端自由渲染。\n */\n\n/** 字段类型(抽象,渲染由服务端决定)。 */\nexport const FieldType = z.enum([\n \"text\", // 单行文本\n \"textarea\", // 多行文本\n \"number\",\n \"boolean\", // 开关/勾选\n \"select\", // 单选\n \"multiselect\", // 多选\n \"date\",\n]);\nexport type FieldType = z.infer<typeof FieldType>;\n\nexport const FormFieldOption = z.object({\n label: z.string(),\n value: z.string(),\n});\nexport type FormFieldOption = z.infer<typeof FormFieldOption>;\n\n/**\n * 表单字段——按 type 的 discriminated union(P2-16)。\n * 每种类型携自己的 defaultValue 类型与专属字段,避免「select 该传 string 还是 string[]」的歧义。\n */\nconst FieldBase = { key: z.string().min(1), label: z.string().min(1), required: z.boolean().default(false), help: z.string().optional() };\n\nexport const FormField = z.discriminatedUnion(\"type\", [\n z.object({ ...FieldBase, type: z.literal(\"text\"), placeholder: z.string().optional(), defaultValue: z.string().optional() }),\n z.object({ ...FieldBase, type: z.literal(\"textarea\"), placeholder: z.string().optional(), defaultValue: z.string().optional() }),\n z.object({ ...FieldBase, type: z.literal(\"number\"), defaultValue: z.number().optional() }),\n z.object({ ...FieldBase, type: z.literal(\"boolean\"), defaultValue: z.boolean().optional() }),\n z.object({ ...FieldBase, type: z.literal(\"select\"), options: z.array(FormFieldOption), defaultValue: z.string().optional() }),\n z.object({ ...FieldBase, type: z.literal(\"multiselect\"), options: z.array(FormFieldOption), defaultValue: z.array(z.string()).optional() }),\n z.object({ ...FieldBase, type: z.literal(\"date\"), defaultValue: z.string().optional() }),\n]);\nexport type FormField = z.infer<typeof FormField>;\n\n/** 表单/卡片定义(抽象)。 */\nexport const InteractionForm = z.object({\n title: z.string().min(1),\n /** 卡片正文/说明(可选)。 */\n description: z.string().optional(),\n fields: z.array(FormField).default([]),\n /** 提交/操作按钮;纯通知类可只放一个「知道了」。 */\n submitLabel: z.string().default(\"提交\"),\n cancelLabel: z.string().optional(),\n});\nexport type InteractionForm = z.infer<typeof InteractionForm>;\n\n/**\n * agent emit 的指令(skill 教)——和 interaction.request 结构基本一致,\n * 但不带 requestId(由 phonon 生成)。\n */\nexport const InteractionDirective = z.object({\n form: InteractionForm,\n /** 是否阻塞等待人回填(true=问答;false=纯通知不等)。 */\n blocking: z.boolean().default(true),\n /** 关联 hookId(若由 HITL hook 触发,便于和 hook.resolve 合流)。 */\n hookId: z.string().optional(),\n});\nexport type InteractionDirective = z.infer<typeof InteractionDirective>;\n\n// --- interaction.request(phonon → server)---\nexport const InteractionRequestParams = z.object({\n /** 本次交互唯一 id,response 用它配对。 */\n requestId: z.string().min(1),\n sessionId: SessionId.optional(),\n turnId: z.string().optional(),\n form: InteractionForm,\n blocking: z.boolean().default(true),\n /** 关联 hookId(HITL 场景)。 */\n hookId: z.string().optional(),\n /**\n * 可选超时(秒,P1-5)。超时后 phonon 以 timeout 收尾本次交互,agent 按预设继续。\n * 0 或缺省 = 不超时(人可能去开会/带娃,长期挂起)。\n */\n timeoutSeconds: z.number().int().nonnegative().optional(),\n at: Timestamp,\n});\nexport type InteractionRequestParams = z.infer<typeof InteractionRequestParams>;\n\n/** 人机交互的生命周期状态(P1-5):pending → submitted | cancelled | timeout。 */\nexport const InteractionStatus = z.enum([\"pending\", \"submitted\", \"cancelled\", \"timeout\"]);\nexport type InteractionStatus = z.infer<typeof InteractionStatus>;\n\n/** 阻塞模式下,request 的最终结果(人填完后服务端回的)。 */\nexport const InteractionRequestResult = z.object({\n requestId: z.string(),\n /** 结果状态:submit | cancel | timeout。 */\n action: z.enum([\"submit\", \"cancel\", \"timeout\"]),\n /** 提交时各字段值(key → 值)。 */\n values: z.record(z.union([z.string(), z.array(z.string()), z.boolean(), z.number()])).optional(),\n});\nexport type InteractionRequestResult = z.infer<typeof InteractionRequestResult>;\n\n// --- interaction.cancel(server → phonon 或 phonon 内部):主动取消一个 pending 交互 ---\nexport const InteractionCancelParams = z.object({\n requestId: z.string().min(1),\n reason: z.string().optional(),\n});\nexport type InteractionCancelParams = z.infer<typeof InteractionCancelParams>;\n\nexport const InteractionCancelResult = z.object({\n requestId: z.string(),\n cancelled: z.boolean(),\n});\nexport type InteractionCancelResult = z.infer<typeof InteractionCancelResult>;\n\n/**\n * server → phonon 的回填(非阻塞模式或异步回填走这个 notification;\n * 阻塞模式可直接用 interaction.request 的 result 返回,二选一,实现可都支持)。\n */\nexport const InteractionResponseParams = z.object({\n requestId: z.string().min(1),\n action: z.enum([\"submit\", \"cancel\", \"timeout\"]),\n values: z.record(z.union([z.string(), z.array(z.string()), z.boolean(), z.number()])).optional(),\n at: Timestamp,\n});\nexport type InteractionResponseParams = z.infer<typeof InteractionResponseParams>;\n","import { z } from \"zod\";\nimport { ProjectId, Timestamp } from \"./common.js\";\n\n/**\n * 项目管理协议(design D23)。\n *\n * 一个项目 = 一个目录 + Git。所有 session 必须绑定一个项目(projectId)。\n * 项目是磁盘上的客观目录,**设备级共享、不受 tenant 隔离**——不同 tenant 都能看到/用\n * 同一项目,在其下各干各的;冲突风险用户自担。(隔离发生在会话/任务层,不在文件层。)\n */\n\n/** 项目描述。 */\nexport const ProjectDescriptor = z.object({\n projectId: ProjectId,\n /** 展示名。 */\n name: z.string().min(1),\n /** 项目目录的绝对路径(设备本地)。 */\n path: z.string().min(1),\n /** 是否已 git init。 */\n git: z.boolean().default(true),\n /** 当前分支(若有)。 */\n branch: z.string().optional(),\n /** 可选:远端 URL。 */\n remote: z.string().optional(),\n createdAt: Timestamp,\n});\nexport type ProjectDescriptor = z.infer<typeof ProjectDescriptor>;\n\n// --- project.create ---\nexport const ProjectCreateParams = z.object({\n /** 可选:幂等键(P0-3)。 */\n clientRequestId: z.string().optional(),\n name: z.string().min(1),\n /**\n * 可选:指定目录路径。缺省由 phonon 在受控工作区下按 name 生成\n * (避免服务端越权指定任意本地路径)。\n */\n path: z.string().optional(),\n /** 是否 git init(默认 true,项目 = 目录 + Git)。 */\n git: z.boolean().default(true),\n /** 可选:初始化时设置的远端。 */\n remote: z.string().optional(),\n});\nexport type ProjectCreateParams = z.infer<typeof ProjectCreateParams>;\n\nexport const ProjectCreateResult = z.object({\n project: ProjectDescriptor,\n});\nexport type ProjectCreateResult = z.infer<typeof ProjectCreateResult>;\n\n// --- project.list ---\nexport const ProjectListParams = z.object({}).default({});\nexport type ProjectListParams = z.infer<typeof ProjectListParams>;\n\nexport const ProjectListResult = z.object({\n projects: z.array(ProjectDescriptor),\n});\nexport type ProjectListResult = z.infer<typeof ProjectListResult>;\n\n// --- project.get ---\nexport const ProjectGetParams = z.object({ projectId: ProjectId });\nexport type ProjectGetParams = z.infer<typeof ProjectGetParams>;\n\nexport const ProjectGetResult = z.object({ project: ProjectDescriptor });\nexport type ProjectGetResult = z.infer<typeof ProjectGetResult>;\n\n// --- project.remove ---\nexport const ProjectRemoveParams = z.object({\n projectId: ProjectId,\n /**\n * 是否删除物理目录。默认 false(仅从 phonon 解绑/注销,保留磁盘文件,防误删)。\n * true 才真正删目录——危险操作,需 policy allowDeleteFiles。\n */\n deleteFiles: z.boolean().default(false),\n /**\n * 有 active session 绑定本项目时的处理(P1-7 / Minimax#5):\n * - reject(默认):还有 active session → errProjectHasActiveSessions\n * - cascade :级联 terminate 所有 active session 再移除\n */\n whenActiveSessions: z.enum([\"reject\", \"cascade\"]).default(\"reject\"),\n});\nexport type ProjectRemoveParams = z.infer<typeof ProjectRemoveParams>;\n\nexport const ProjectRemoveResult = z.object({\n projectId: ProjectId,\n removed: z.literal(true),\n filesDeleted: z.boolean(),\n /** cascade 时被级联 terminate 的 session。 */\n terminatedSessions: z.array(z.string()).optional(),\n});\nexport type ProjectRemoveResult = z.infer<typeof ProjectRemoveResult>;\n\n// ===========================================================================\n// Git / worktree 子能力(D25)\n// worktree = 同一仓库的多个工作目录,天然适配「多 tenant/session 在同一项目各干各的」。\n// ===========================================================================\n\n/** worktree 描述。 */\nexport const WorktreeDescriptor = z.object({\n /** worktree 标识(phonon 生成)。 */\n worktreeId: z.string().min(1),\n projectId: ProjectId,\n /** worktree 的工作目录路径。 */\n path: z.string().min(1),\n /** 该 worktree 检出的分支。 */\n branch: z.string().min(1),\n /** 是否是主工作区(项目本体目录)。 */\n isPrimary: z.boolean().default(false),\n createdAt: Timestamp.optional(),\n});\nexport type WorktreeDescriptor = z.infer<typeof WorktreeDescriptor>;\n\n// --- project.worktree.create:基于某 branch 创建 worktree ---\nexport const WorktreeCreateParams = z.object({\n /** 可选:幂等键(P0-3)。 */\n clientRequestId: z.string().optional(),\n projectId: ProjectId,\n /** 基于哪个已有 branch 创建(检出点)。 */\n baseBranch: z.string().min(1),\n /**\n * 可选:新建并检出的分支名。缺省则直接检出 baseBranch\n * (注:同一 branch 不能被两个 worktree 同时检出,所以多开并发时通常传 newBranch)。\n */\n newBranch: z.string().optional(),\n /** 可选:指定 worktree 路径;缺省由 phonon 在受控区生成。 */\n path: z.string().optional(),\n});\nexport type WorktreeCreateParams = z.infer<typeof WorktreeCreateParams>;\n\nexport const WorktreeCreateResult = z.object({\n worktree: WorktreeDescriptor,\n});\nexport type WorktreeCreateResult = z.infer<typeof WorktreeCreateResult>;\n\n// --- project.worktree.list ---\nexport const WorktreeListParams = z.object({ projectId: ProjectId });\nexport type WorktreeListParams = z.infer<typeof WorktreeListParams>;\n\nexport const WorktreeListResult = z.object({\n worktrees: z.array(WorktreeDescriptor),\n});\nexport type WorktreeListResult = z.infer<typeof WorktreeListResult>;\n\n// --- project.worktree.remove:清理 worktree ---\nexport const WorktreeRemoveParams = z.object({\n projectId: ProjectId,\n worktreeId: z.string().min(1),\n /**\n * 是否强制清理(P1-7)。默认 false:\n * 有未提交变更 → errWorktreeHasChanges;还有 active/running session 绑定 → errWorktreeInUse。\n * force=true 才允许硬删,但会连带影响返回 affectedSessions。\n */\n force: z.boolean().default(false),\n});\nexport type WorktreeRemoveParams = z.infer<typeof WorktreeRemoveParams>;\n\nexport const WorktreeRemoveResult = z.object({\n worktreeId: z.string(),\n removed: z.literal(true),\n /** 被连带影响(被迫 terminate)的 session(force 硬删时)。 */\n affectedSessions: z.array(z.string()).optional(),\n});\nexport type WorktreeRemoveResult = z.infer<typeof WorktreeRemoveResult>;\n\n// --- project.git.deleteBranch:删除(已合并的)branch ---\nexport const GitDeleteBranchParams = z.object({\n projectId: ProjectId,\n branch: z.string().min(1),\n /**\n * 是否强制删除(P1-7)。默认 false:\n * 未合并 → errBranchNotMerged;仍被某 worktree 检出 → errBranchInUse。\n * force=true 强删未合并(git branch -D),返回 affectedWorktrees。\n */\n force: z.boolean().default(false),\n});\nexport type GitDeleteBranchParams = z.infer<typeof GitDeleteBranchParams>;\n\nexport const GitDeleteBranchResult = z.object({\n branch: z.string(),\n deleted: z.literal(true),\n wasMerged: z.boolean().optional(),\n /** 被连带影响的 worktree(force 硬删时)。 */\n affectedWorktrees: z.array(z.string()).optional(),\n});\nexport type GitDeleteBranchResult = z.infer<typeof GitDeleteBranchResult>;\n","import { z } from \"zod\";\nimport { AgentId, ProjectId, Timestamp } from \"./common.js\";\n\n/**\n * Skill 管理协议(design D24)。\n *\n * 给指定 agent 安装/卸载 skill,支持两级 scope:\n * - global : agent 全局,对该 agent 所有项目可见\n * - project : 项目级,仅对某 projectId 可见(需 projectId)\n *\n * 每个 agent 靠 capability `skillManagement` 声明是否支持;不支持 → errCapabilityUnsupported。\n */\n\nexport const SkillScope = z.enum([\"global\", \"project\"]);\nexport type SkillScope = z.infer<typeof SkillScope>;\n\n/** skill 来源:内联内容、本地路径、或远端引用。 */\nexport const SkillSource = z.union([\n z.object({ kind: z.literal(\"inline\"), files: z.record(z.string()) }), // path → content\n z.object({\n kind: z.literal(\"archive\"),\n /** v0 先支持 tar.gz;zip/archiveUrl 后续再加,避免安全边界没收稳。 */\n format: z.literal(\"tar.gz\"),\n contentBase64: z.string().min(1),\n /** 强烈建议传;phonon 会校验内容 hash,防传输/供应链篡改。 */\n sha256: z.string().optional(),\n /** 可选大小提示,便于 policy/日志;实际大小以 decode 后为准。 */\n sizeBytes: z.number().int().positive().optional(),\n }),\n z.object({ kind: z.literal(\"localPath\"), path: z.string().min(1) }),\n z.object({\n kind: z.literal(\"url\"),\n url: z.string().min(1),\n /** 可选:内容校验和(P2-12 / 供应链可信度)。url 装需 policy allowUrlSkillInstall。 */\n sha256: z.string().optional(),\n }),\n]);\nexport type SkillSource = z.infer<typeof SkillSource>;\n\n/** 已安装 skill 的描述。 */\nexport const SkillDescriptor = z.object({\n /** skill 名/key。 */\n name: z.string().min(1),\n /** 归属哪个 agent。 */\n agent: AgentId,\n scope: SkillScope,\n /** scope=project 时所属项目。 */\n projectId: ProjectId.optional(),\n /** 版本(P2-12,同名冲突可辨)。 */\n version: z.string().optional(),\n /** 内容 hash(P2-12,可复现/防篡改)。 */\n hash: z.string().optional(),\n /** 适配的 agent(某些 skill 只适 OpenClaw 不适 Codex)。 */\n compatibleAgents: z.array(AgentId).optional(),\n /** 来源是否可信(本地/内联=可信,url=需校验)。 */\n sourceTrusted: z.boolean().optional(),\n /** 安装落地路径(设备本地)。 */\n installedPath: z.string().optional(),\n installedAt: Timestamp.optional(),\n});\nexport type SkillDescriptor = z.infer<typeof SkillDescriptor>;\n\n// --- skill.install ---\nexport const SkillInstallParams = z\n .object({\n /** 目标 agent。 */\n agent: AgentId,\n name: z.string().min(1),\n scope: SkillScope,\n /** scope=project 时必填。 */\n projectId: ProjectId.optional(),\n source: SkillSource,\n })\n .refine((v) => v.scope !== \"project\" || !!v.projectId, {\n message: \"scope=project requires projectId\",\n path: [\"projectId\"],\n });\nexport type SkillInstallParams = z.infer<typeof SkillInstallParams>;\n\nexport const SkillInstallResult = z.object({\n skill: SkillDescriptor,\n});\nexport type SkillInstallResult = z.infer<typeof SkillInstallResult>;\n\n// --- skill.uninstall ---\nexport const SkillUninstallParams = z\n .object({\n agent: AgentId,\n name: z.string().min(1),\n scope: SkillScope,\n projectId: ProjectId.optional(),\n })\n .refine((v) => v.scope !== \"project\" || !!v.projectId, {\n message: \"scope=project requires projectId\",\n path: [\"projectId\"],\n });\nexport type SkillUninstallParams = z.infer<typeof SkillUninstallParams>;\n\nexport const SkillUninstallResult = z.object({\n agent: AgentId,\n name: z.string(),\n scope: SkillScope,\n uninstalled: z.literal(true),\n});\nexport type SkillUninstallResult = z.infer<typeof SkillUninstallResult>;\n\n// --- skill.list ---\nexport const SkillListParams = z.object({\n /** 可选:按 agent 过滤。 */\n agent: AgentId.optional(),\n /** 可选:按 scope 过滤。 */\n scope: SkillScope.optional(),\n /** 可选:按项目过滤(看某项目可见的 skill)。 */\n projectId: ProjectId.optional(),\n});\nexport type SkillListParams = z.infer<typeof SkillListParams>;\n\nexport const SkillListResult = z.object({\n skills: z.array(SkillDescriptor),\n});\nexport type SkillListResult = z.infer<typeof SkillListResult>;\n","import { z } from \"zod\";\nimport { AgentId, ProjectId } from \"./common.js\";\n\n/**\n * 本地安全策略(design D27 / review P0-1)。\n *\n * phonon 不做终端用户鉴权(那是服务端的事),但**必须有设备主人配置的本地授权边界**——\n * 否则任意接入的 server 都能让本地 agent 读任意文件、装任意 skill、删 worktree。\n *\n * 这是「设备 policy」,不是「用户鉴权」。每个 tenant 一份,phonon 在执行前据此拦截。\n * 这些是本地配置,不进 device→server 的线协议;放协议包是为了类型共享与校验。\n */\n\n/** 单个 tenant 的本地授权边界。 */\nexport const TenantPolicy = z.object({\n /** 允许操作的项目根目录白名单(绝对路径)。document/project 路径必须落在其下。 */\n allowedProjectRoots: z.array(z.string()).default([]),\n /** 允许使用的 agent 白名单;空 = 不限制。 */\n allowedAgents: z.array(AgentId).default([]),\n /** 允许的方法白名单;空 = 全允许。用它可表达「只读租户」(只放查询类方法)。 */\n allowedMethods: z.array(z.string()).default([]),\n /** 是否允许全局 skill 安装(影响该 agent 所有项目,危险)。默认 false。 */\n allowGlobalSkillInstall: z.boolean().default(false),\n /** 是否允许从 url 安装 skill(供应链入口,危险)。默认 false。 */\n allowUrlSkillInstall: z.boolean().default(false),\n /** 是否允许物理删盘(project.remove deleteFiles / worktree force 等)。默认 false。 */\n allowDeleteFiles: z.boolean().default(false),\n /** document.send 是否允许发送项目/worktree 目录之外的文件。默认 false(project-scoped)。 */\n allowExternalDocuments: z.boolean().default(false),\n /** env.list reveal=true 是否允许返回环境变量明文。默认 false(只能脱敏查看)。 */\n allowEnvReveal: z.boolean().default(false),\n /** 单文件上传上限(字节);超出走 prepare_upload 或拒绝。 */\n maxUploadBytes: z.number().int().positive().optional(),\n /** 敏感路径黑名单(即使在 allowedProjectRoots 内也拒绝,如 .ssh/.aws/.env)。 */\n denyPathPatterns: z.array(z.string()).default([\n \"**/.ssh/**\",\n \"**/.aws/**\",\n \"**/.env\",\n \"**/.git/config\",\n \"**/id_rsa*\",\n \"**/*.pem\",\n \"**/openclaw.json\",\n ]),\n});\nexport type TenantPolicy = z.infer<typeof TenantPolicy>;\n\n/** policy 默认值(最严格:白名单空、写操作全关)。 */\nexport const DEFAULT_TENANT_POLICY: TenantPolicy = TenantPolicy.parse({});\n\n/**\n * 校验一个绝对路径是否落在某项目根白名单内(不含 deny 匹配)。\n * 真实 glob/deny 匹配由 core 实现;这里给协议层一个轻量前缀检查骨架。\n */\nexport function isPathUnderRoots(absPath: string, roots: readonly string[]): boolean {\n if (roots.length === 0) return false;\n const norm = absPath.replace(/\\\\/g, \"/\");\n return roots.some((r) => {\n const root = r.replace(/\\\\/g, \"/\").replace(/\\/+$/, \"\");\n return norm === root || norm.startsWith(root + \"/\");\n });\n}\n\n/** policy 拒绝时的归一化结果(core 用,便于回 errPolicyDenied)。 */\nexport const PolicyDecision = z.object({\n allowed: z.boolean(),\n /** 拒绝原因(如 \"path_outside_project\" / \"url_skill_disabled\" / \"delete_not_allowed\")。 */\n reason: z.string().optional(),\n /** 关联 projectId(若适用)。 */\n projectId: ProjectId.optional(),\n});\nexport type PolicyDecision = z.infer<typeof PolicyDecision>;\n","import { z } from \"zod\";\nimport { DeviceId, TenantId, Timestamp } from \"./common.js\";\n\n/**\n * 连接握手(design §6)。\n *\n * phonon 拨出连接后,首先发 connect.hello 表明:协议版本、设备身份。\n * device key 的鉴权由传输层/服务端处理(如 WS header / 首帧),不在业务 params 里明文带。\n * server 回 connect.welcome 确认,并可下发 tenant 绑定与服务端能力。\n */\n\nexport const ConnectHelloParams = z.object({\n /** 本端协议版本(= PROTOCOL_VERSION)。 */\n protocolVersion: z.string(),\n /** 设备标识(服务端用于区分多设备)。 */\n deviceId: DeviceId,\n /** phonon 实现版本(软件版本,便于服务端兼容处理)。 */\n phononVersion: z.string().optional(),\n /** 本端声明支持的可选特性开关,便于前向兼容。 */\n features: z.array(z.string()).default([]),\n /** 设备鉴权(可选):server 据此验证设备身份。也可走传输层 header。 */\n auth: z.object({ deviceKey: z.string() }).optional(),\n /**\n * 重连时携带(P0-4):phonon 本地 outbox 中每个 session 尚未被 ack 的起始 seq,\n * 让 server 知道哪些要补发 / 从哪重放。首次连接可省略。\n */\n resumeFrom: z\n .array(z.object({ sessionId: z.string(), fromSeq: z.number().int().nonnegative() }))\n .optional(),\n at: Timestamp,\n});\nexport type ConnectHelloParams = z.infer<typeof ConnectHelloParams>;\n\nexport const ConnectWelcomeResult = z.object({\n /** 服务端协议版本。 */\n protocolVersion: z.string(),\n /** 服务端为本连接分配/确认的租户身份(= 一条服务端连接,design D13)。 */\n tenantId: TenantId,\n /** 服务端声明支持的可选特性。 */\n features: z.array(z.string()).default([]),\n /**\n * 重连时服务端告知「我各 session 最后收到的 seq」(P0-4),\n * phonon 据此从 outbox 精确补发(> lastSeq 的),避免重复/遗漏。\n */\n ackedSeqs: z\n .array(z.object({ sessionId: z.string(), lastSeq: z.number().int().nonnegative() }))\n .optional(),\n at: Timestamp,\n});\nexport type ConnectWelcomeResult = z.infer<typeof ConnectWelcomeResult>;\n","import { z } from \"zod\";\n\n/**\n * 设备级信息与可观测协议。\n *\n * device.info:相对静态的 OS/机器信息,用于服务端按需调度。\n * device.resources:运行时资源快照,用于 debug,不做资源调度或限制。\n */\n\nexport const DeviceInfoParams = z.object({}).default({});\nexport type DeviceInfoParams = z.infer<typeof DeviceInfoParams>;\n\nexport const DeviceInfoResult = z.object({\n at: z.string().datetime({ offset: true }),\n hostname: z.string(),\n os: z.object({\n platform: z.enum([\"aix\", \"darwin\", \"freebsd\", \"linux\", \"openbsd\", \"sunos\", \"win32\", \"cygwin\", \"netbsd\"]).or(z.string()),\n type: z.string(),\n release: z.string(),\n arch: z.string(),\n }),\n runtime: z.object({\n node: z.string().optional(),\n }).optional(),\n /** 便于 server 做粗粒度任务路由:ios-development/windows-desktop-development/nvidia-gpu 等。 */\n capabilities: z.array(z.string()).default([]),\n});\nexport type DeviceInfoResult = z.infer<typeof DeviceInfoResult>;\n\nexport const DeviceResourcesParams = z.object({}).default({});\nexport type DeviceResourcesParams = z.infer<typeof DeviceResourcesParams>;\n\nexport const DeviceResourcesResult = z.object({\n at: z.string().datetime({ offset: true }),\n cpu: z.object({\n loadavg: z.array(z.number()).length(3).optional(),\n cores: z.number().int().positive().optional(),\n usagePercent: z.number().min(0).max(100).optional(),\n }).optional(),\n memory: z.object({\n totalBytes: z.number().nonnegative(),\n freeBytes: z.number().nonnegative(),\n usedBytes: z.number().nonnegative(),\n usagePercent: z.number().min(0).max(100).optional(),\n }),\n disk: z.object({\n path: z.string(),\n totalBytes: z.number().nonnegative().optional(),\n freeBytes: z.number().nonnegative().optional(),\n usedBytes: z.number().nonnegative().optional(),\n usagePercent: z.number().min(0).max(100).optional(),\n }).optional(),\n gpu: z.array(z.object({\n name: z.string().optional(),\n memoryTotalBytes: z.number().nonnegative().optional(),\n memoryUsedBytes: z.number().nonnegative().optional(),\n utilizationPercent: z.number().min(0).max(100).optional(),\n })).optional(),\n process: z.object({\n pid: z.number().int().positive(),\n uptimeSeconds: z.number().nonnegative(),\n rssBytes: z.number().nonnegative().optional(),\n heapUsedBytes: z.number().nonnegative().optional(),\n heapTotalBytes: z.number().nonnegative().optional(),\n }).optional(),\n});\nexport type DeviceResourcesResult = z.infer<typeof DeviceResourcesResult>;\n","import { z } from \"zod\";\nimport { ProjectId } from \"./common.js\";\n\n/**\n * 受控工作区文件读写协议。\n *\n * 与 document.send 不同:document.send 是 agent 主动把产物发给 server;\n * file.* 是 server 主动读写本地 project/worktree 内文件。\n */\n\nexport const FileEncoding = z.enum([\"utf8\", \"base64\"]);\nexport type FileEncoding = z.infer<typeof FileEncoding>;\n\nexport const FileScope = z.object({\n projectId: ProjectId,\n /** 可选:指定 worktree;缺省为项目主目录。 */\n worktreeId: z.string().min(1).optional(),\n});\nexport type FileScope = z.infer<typeof FileScope>;\n\nconst RelativePath = z.string().min(1).refine((p) => !p.startsWith(\"/\") && !p.includes(\"\\0\"), {\n message: \"path must be a relative path\",\n});\n\nexport const FileStat = z.object({\n path: z.string(),\n type: z.enum([\"file\", \"directory\", \"symlink\", \"other\"]),\n sizeBytes: z.number().nonnegative(),\n modifiedAt: z.string().datetime({ offset: true }).optional(),\n});\nexport type FileStat = z.infer<typeof FileStat>;\n\nexport const FileReadParams = FileScope.extend({\n path: RelativePath,\n encoding: FileEncoding.default(\"utf8\"),\n /** 可选:最大读取字节数,避免误读超大文件。 */\n maxBytes: z.number().int().positive().optional(),\n});\nexport type FileReadParams = z.infer<typeof FileReadParams>;\n\nexport const FileReadResult = z.object({\n path: z.string(),\n encoding: FileEncoding,\n data: z.string(),\n sizeBytes: z.number().nonnegative(),\n truncated: z.boolean().default(false),\n});\nexport type FileReadResult = z.infer<typeof FileReadResult>;\n\nexport const FileWriteParams = FileScope.extend({\n /** 可选:幂等键。 */\n clientRequestId: z.string().optional(),\n path: RelativePath,\n encoding: FileEncoding.default(\"utf8\"),\n data: z.string(),\n /** 缺省 true;false 时若文件已存在则报错。 */\n overwrite: z.boolean().default(true),\n /** 是否自动创建父目录。 */\n createDirs: z.boolean().default(true),\n});\nexport type FileWriteParams = z.infer<typeof FileWriteParams>;\n\nexport const FileWriteResult = z.object({\n path: z.string(),\n sizeBytes: z.number().nonnegative(),\n written: z.literal(true),\n});\nexport type FileWriteResult = z.infer<typeof FileWriteResult>;\n\nexport const FileListParams = FileScope.extend({\n path: RelativePath.default(\".\"),\n recursive: z.boolean().default(false),\n limit: z.number().int().positive().max(10000).default(500),\n});\nexport type FileListParams = z.infer<typeof FileListParams>;\n\nexport const FileListResult = z.object({\n path: z.string(),\n entries: z.array(FileStat),\n truncated: z.boolean().default(false),\n});\nexport type FileListResult = z.infer<typeof FileListResult>;\n\nexport const FileStatParams = FileScope.extend({ path: RelativePath });\nexport type FileStatParams = z.infer<typeof FileStatParams>;\nexport const FileStatResult = z.object({ stat: FileStat });\nexport type FileStatResult = z.infer<typeof FileStatResult>;\n\nexport const FileMkdirParams = FileScope.extend({\n /** 可选:幂等键。 */\n clientRequestId: z.string().optional(),\n path: RelativePath,\n recursive: z.boolean().default(true),\n});\nexport type FileMkdirParams = z.infer<typeof FileMkdirParams>;\nexport const FileMkdirResult = z.object({ path: z.string(), created: z.literal(true) });\nexport type FileMkdirResult = z.infer<typeof FileMkdirResult>;\n","import { z } from \"zod\";\nimport { ProjectId, AgentId } from \"./common.js\";\n\n/** Skill / agent 执行环境变量配置。明文存储在设备本地,list 默认脱敏。 */\nexport const EnvScope = z.enum([\"global\", \"project\", \"skill\"]);\nexport type EnvScope = z.infer<typeof EnvScope>;\n\nconst EnvTargetBase = z.object({\n scope: EnvScope,\n projectId: ProjectId.optional(),\n agent: AgentId.optional(),\n skillName: z.string().min(1).optional(),\n});\n\nfunction withEnvTargetRefine<T extends z.ZodTypeAny>(schema: T): T {\n return schema\n .refine((v: unknown) => (v as { scope?: string; projectId?: string }).scope !== \"project\" || !!(v as { projectId?: string }).projectId, { message: \"project scope requires projectId\", path: [\"projectId\"] })\n .refine((v: unknown) => {\n const x = v as { scope?: string; projectId?: string; agent?: string; skillName?: string };\n return x.scope !== \"skill\" || (!!x.projectId && !!x.agent && !!x.skillName);\n }, { message: \"skill scope requires projectId+agent+skillName\", path: [\"skillName\"] }) as unknown as T;\n}\n\nexport const EnvTarget = withEnvTargetRefine(EnvTargetBase);\nexport type EnvTarget = z.infer<typeof EnvTargetBase>;\n\nexport const EnvVarDescriptor = withEnvTargetRefine(EnvTargetBase.extend({\n name: z.string().min(1),\n value: z.string().optional(),\n redacted: z.boolean().default(true),\n updatedAt: z.string().datetime({ offset: true }).optional(),\n}));\nexport type EnvVarDescriptor = z.infer<typeof EnvVarDescriptor>;\n\nexport const EnvSetParams = withEnvTargetRefine(EnvTargetBase.extend({\n clientRequestId: z.string().optional(),\n name: z.string().min(1),\n value: z.string(),\n /** 可选:如果是 secret,list 默认永远脱敏。默认 true。 */\n secret: z.boolean().default(true),\n}));\nexport type EnvSetParams = z.infer<typeof EnvSetParams>;\nexport const EnvSetResult = z.object({ variable: EnvVarDescriptor });\nexport type EnvSetResult = z.infer<typeof EnvSetResult>;\n\nexport const EnvListParams = EnvTargetBase.partial().extend({\n /** 默认 false;true 需要本地 policy allowEnvReveal。 */\n reveal: z.boolean().default(false),\n});\nexport type EnvListParams = z.infer<typeof EnvListParams>;\nexport const EnvListResult = z.object({ variables: z.array(EnvVarDescriptor) });\nexport type EnvListResult = z.infer<typeof EnvListResult>;\n\nexport const EnvDeleteParams = withEnvTargetRefine(EnvTargetBase.extend({\n clientRequestId: z.string().optional(),\n name: z.string().min(1),\n}));\nexport type EnvDeleteParams = z.infer<typeof EnvDeleteParams>;\nexport const EnvDeleteResult = z.object({ deleted: z.literal(true), name: z.string() });\nexport type EnvDeleteResult = z.infer<typeof EnvDeleteResult>;\n","import { z } from \"zod\";\nimport { PhononErrorData } from \"./common.js\";\n\n/**\n * JSON-RPC 2.0 信封(design D2)。\n *\n * 单条 WebSocket 上双向跑 JSON-RPC 2.0:两端皆可作 requester。\n * - server → phonon:session.* / discovery.* / hook.resolve\n * - phonon → server:stream.event / hook.fired / discovery.changed / connect.hello\n *\n * 这里只定义「信封」的通用形状;具体方法的 params/result 由 methods.ts 绑定。\n */\n\nexport const JsonRpcVersion = z.literal(\"2.0\");\n\n/** 请求 id:字符串或数字(JSON-RPC 允许两者;notification 无 id)。 */\nexport const JsonRpcId = z.union([z.string(), z.number()]);\nexport type JsonRpcId = z.infer<typeof JsonRpcId>;\n\n/** 请求(需要响应)。 */\nexport const JsonRpcRequest = z.object({\n jsonrpc: JsonRpcVersion,\n id: JsonRpcId,\n method: z.string(),\n params: z.unknown().optional(),\n});\nexport type JsonRpcRequest = z.infer<typeof JsonRpcRequest>;\n\n/** 通知(不需要响应,无 id)——用于 stream.event / hook.fired / discovery.changed。 */\nexport const JsonRpcNotification = z.object({\n jsonrpc: JsonRpcVersion,\n method: z.string(),\n params: z.unknown().optional(),\n});\nexport type JsonRpcNotification = z.infer<typeof JsonRpcNotification>;\n\n/** 成功响应。 */\nexport const JsonRpcSuccess = z.object({\n jsonrpc: JsonRpcVersion,\n id: JsonRpcId,\n result: z.unknown(),\n});\nexport type JsonRpcSuccess = z.infer<typeof JsonRpcSuccess>;\n\n/** JSON-RPC error 对象;data 携带 phonon 应用级错误结构。 */\nexport const JsonRpcErrorObject = z.object({\n /** JSON-RPC 传输级 code(-32700..-32600 保留;应用错误用 data.appCode 判别)。 */\n code: z.number().int(),\n message: z.string(),\n data: PhononErrorData.optional(),\n});\nexport type JsonRpcErrorObject = z.infer<typeof JsonRpcErrorObject>;\n\n/** 失败响应。 */\nexport const JsonRpcError = z.object({\n jsonrpc: JsonRpcVersion,\n id: JsonRpcId.nullable(),\n error: JsonRpcErrorObject,\n});\nexport type JsonRpcError = z.infer<typeof JsonRpcError>;\n\n/** 任意一条 JSON-RPC 报文。 */\nexport const JsonRpcMessage = z.union([\n JsonRpcRequest,\n JsonRpcNotification,\n JsonRpcSuccess,\n JsonRpcError,\n]);\nexport type JsonRpcMessage = z.infer<typeof JsonRpcMessage>;\n\n/** 标准 JSON-RPC 传输级错误码。 */\nexport const JSON_RPC_CODES = {\n parseError: -32700,\n invalidRequest: -32600,\n methodNotFound: -32601,\n invalidParams: -32602,\n internalError: -32603,\n /** 应用级错误统一用这个 code,细分看 data.appCode。 */\n applicationError: -32000,\n} as const;\n","import { z } from \"zod\";\nimport {\n ConnectHelloParams,\n ConnectWelcomeResult,\n} from \"./connect.js\";\nimport {\n DiscoveryListParams,\n DiscoveryListResult,\n DiscoveryGetParams,\n DiscoveryGetResult,\n DiscoveryChangedParams,\n} from \"./discovery.js\";\nimport {\n SessionCreateParams,\n SessionCreateResult,\n SessionSendParams,\n SessionSendAck,\n SessionInjectParams,\n SessionInjectResult,\n SessionCompressParams,\n SessionCompressResult,\n SessionSwitchModelParams,\n SessionSwitchModelResult,\n SessionInterruptParams,\n SessionInterruptResult,\n SessionTerminateParams,\n SessionTerminateResult,\n SessionStatusParams,\n SessionStatusResult,\n SessionListParams,\n SessionListResult,\n} from \"./session.js\";\nimport { StreamEvent, StreamAckParams } from \"./stream.js\";import {\n HookFiredParams,\n HookResolveParams,\n HookResolveResult,\n} from \"./hook.js\";\nimport { DocumentSendParams, DocumentSendResult, DocumentPrepareUploadParams, DocumentPrepareUploadResult } from \"./document.js\";\nimport {\n InteractionRequestParams,\n InteractionRequestResult,\n InteractionResponseParams,\n InteractionCancelParams,\n InteractionCancelResult,\n} from \"./interaction.js\";\nimport {\n ProjectCreateParams,\n ProjectCreateResult,\n ProjectListParams,\n ProjectListResult,\n ProjectGetParams,\n ProjectGetResult,\n ProjectRemoveParams,\n ProjectRemoveResult,\n WorktreeCreateParams,\n WorktreeCreateResult,\n WorktreeListParams,\n WorktreeListResult,\n WorktreeRemoveParams,\n WorktreeRemoveResult,\n GitDeleteBranchParams,\n GitDeleteBranchResult,\n} from \"./project.js\";\nimport {\n SkillInstallParams,\n SkillInstallResult,\n SkillUninstallParams,\n SkillUninstallResult,\n SkillListParams,\n SkillListResult,\n} from \"./skill.js\";\nimport { DeviceInfoParams, DeviceInfoResult, DeviceResourcesParams, DeviceResourcesResult } from \"./device.js\";\nimport {\n FileReadParams,\n FileReadResult,\n FileWriteParams,\n FileWriteResult,\n FileListParams,\n FileListResult,\n FileStatParams,\n FileStatResult,\n FileMkdirParams,\n FileMkdirResult,\n} from \"./file.js\";\nimport { EnvSetParams, EnvSetResult, EnvListParams, EnvListResult, EnvDeleteParams, EnvDeleteResult } from \"./env.js\";\n\n/**\n * 方法注册表(design 全协议的单一事实来源)。\n *\n * 每个方法声明:\n * - direction: 谁是 requester\n * s2p = server → phonon (服务端下发操作)\n * p2s = phonon → server (设备上报结果/事件/发现)\n * - kind: \"request\"(需响应)| \"notification\"(无响应)\n * - params / result 的 zod schema\n *\n * core 与 client-sdk 都 import 本表,确保两端对齐、可机器校验。\n */\n\nconst z_void = z.undefined();\n\nexport const METHODS = {\n // --- 握手(phonon 拨出后先发)---\n \"connect.hello\": {\n direction: \"p2s\",\n kind: \"request\",\n params: ConnectHelloParams,\n result: ConnectWelcomeResult,\n },\n\n // --- 设备级信息与可观测(server 查询)---\n \"device.info\": {\n direction: \"s2p\",\n kind: \"request\",\n params: DeviceInfoParams,\n result: DeviceInfoResult,\n },\n \"device.resources\": {\n direction: \"s2p\",\n kind: \"request\",\n params: DeviceResourcesParams,\n result: DeviceResourcesResult,\n },\n\n // --- 发现(server 查询;phonon 主动推变更)---\n \"discovery.list\": {\n direction: \"s2p\",\n kind: \"request\",\n params: DiscoveryListParams,\n result: DiscoveryListResult,\n },\n \"discovery.get\": {\n direction: \"s2p\",\n kind: \"request\",\n params: DiscoveryGetParams,\n result: DiscoveryGetResult,\n },\n \"discovery.changed\": {\n direction: \"p2s\",\n kind: \"notification\",\n params: DiscoveryChangedParams,\n result: z_void,\n },\n\n // --- session 原语(server 下发)---\n \"session.create\": {\n direction: \"s2p\",\n kind: \"request\",\n params: SessionCreateParams,\n result: SessionCreateResult,\n },\n \"session.send\": {\n direction: \"s2p\",\n kind: \"request\",\n params: SessionSendParams,\n result: SessionSendAck,\n },\n \"session.inject\": {\n direction: \"s2p\",\n kind: \"request\",\n params: SessionInjectParams,\n result: SessionInjectResult,\n },\n \"session.compress\": {\n direction: \"s2p\",\n kind: \"request\",\n params: SessionCompressParams,\n result: SessionCompressResult,\n },\n \"session.switchModel\": {\n direction: \"s2p\",\n kind: \"request\",\n params: SessionSwitchModelParams,\n result: SessionSwitchModelResult,\n },\n \"session.interrupt\": {\n direction: \"s2p\",\n kind: \"request\",\n params: SessionInterruptParams,\n result: SessionInterruptResult,\n },\n \"session.terminate\": {\n direction: \"s2p\",\n kind: \"request\",\n params: SessionTerminateParams,\n result: SessionTerminateResult,\n },\n \"session.status\": {\n direction: \"s2p\",\n kind: \"request\",\n params: SessionStatusParams,\n result: SessionStatusResult,\n },\n \"session.list\": {\n direction: \"s2p\",\n kind: \"request\",\n params: SessionListParams,\n result: SessionListResult,\n },\n\n // --- 流式结果(phonon 上推;无响应)---\n \"stream.event\": {\n direction: \"p2s\",\n kind: \"notification\",\n params: StreamEvent,\n result: z_void,\n },\n // --- 流式 ack(server 确认 seq,phonon 据此清 outbox,P0-4)---\n \"stream.ack\": {\n direction: \"s2p\",\n kind: \"notification\",\n params: StreamAckParams,\n result: z_void,\n },\n\n // --- hook / HITL ---\n \"hook.fired\": {\n direction: \"p2s\",\n kind: \"request\", // phonon 发起、阻塞等 server 裁决\n params: HookFiredParams,\n result: HookResolveResult,\n },\n \"hook.resolve\": {\n direction: \"s2p\",\n kind: \"request\",\n params: HookResolveParams,\n result: HookResolveResult,\n },\n\n // --- 文档交换(agent emit 指令 → phonon 读本地文件 → 上传,平面③ / D20)---\n \"document.send\": {\n direction: \"p2s\",\n kind: \"request\",\n params: DocumentSendParams,\n result: DocumentSendResult,\n },\n \"document.prepare_upload\": {\n direction: \"p2s\",\n kind: \"request\", // 大文件凭证上传(P1-6)\n params: DocumentPrepareUploadParams,\n result: DocumentPrepareUploadResult,\n },\n\n // --- 人机交互(表单/卡片,agent主动或HITL发起,平面③ / D21)---\n \"interaction.request\": {\n direction: \"p2s\",\n kind: \"request\", // blocking 时阻塞等人回填\n params: InteractionRequestParams,\n result: InteractionRequestResult,\n },\n \"interaction.response\": {\n direction: \"s2p\",\n kind: \"notification\", // 异步/非阻塞回填走这条\n params: InteractionResponseParams,\n result: z_void,\n },\n \"interaction.cancel\": {\n direction: \"s2p\",\n kind: \"request\", // 主动取消一个 pending 交互(P1-5)\n params: InteractionCancelParams,\n result: InteractionCancelResult,\n },\n\n // --- 项目管理(目录 + Git;server 下发,D23)---\n \"project.create\": {\n direction: \"s2p\",\n kind: \"request\",\n params: ProjectCreateParams,\n result: ProjectCreateResult,\n },\n \"project.list\": {\n direction: \"s2p\",\n kind: \"request\",\n params: ProjectListParams,\n result: ProjectListResult,\n },\n \"project.get\": {\n direction: \"s2p\",\n kind: \"request\",\n params: ProjectGetParams,\n result: ProjectGetResult,\n },\n \"project.remove\": {\n direction: \"s2p\",\n kind: \"request\",\n params: ProjectRemoveParams,\n result: ProjectRemoveResult,\n },\n\n // --- worktree / git 子能力(D25)---\n \"project.worktree.create\": {\n direction: \"s2p\",\n kind: \"request\",\n params: WorktreeCreateParams,\n result: WorktreeCreateResult,\n },\n \"project.worktree.list\": {\n direction: \"s2p\",\n kind: \"request\",\n params: WorktreeListParams,\n result: WorktreeListResult,\n },\n \"project.worktree.remove\": {\n direction: \"s2p\",\n kind: \"request\",\n params: WorktreeRemoveParams,\n result: WorktreeRemoveResult,\n },\n \"project.git.deleteBranch\": {\n direction: \"s2p\",\n kind: \"request\",\n params: GitDeleteBranchParams,\n result: GitDeleteBranchResult,\n },\n\n // --- 受控工作区文件读写(server 下发,project/worktree scoped)---\n \"file.read\": {\n direction: \"s2p\",\n kind: \"request\",\n params: FileReadParams,\n result: FileReadResult,\n },\n \"file.write\": {\n direction: \"s2p\",\n kind: \"request\",\n params: FileWriteParams,\n result: FileWriteResult,\n },\n \"file.list\": {\n direction: \"s2p\",\n kind: \"request\",\n params: FileListParams,\n result: FileListResult,\n },\n \"file.stat\": {\n direction: \"s2p\",\n kind: \"request\",\n params: FileStatParams,\n result: FileStatResult,\n },\n \"file.mkdir\": {\n direction: \"s2p\",\n kind: \"request\",\n params: FileMkdirParams,\n result: FileMkdirResult,\n },\n\n // --- 环境变量配置(skill/agent 运行环境,默认脱敏)---\n \"env.set\": {\n direction: \"s2p\",\n kind: \"request\",\n params: EnvSetParams,\n result: EnvSetResult,\n },\n \"env.list\": {\n direction: \"s2p\",\n kind: \"request\",\n params: EnvListParams,\n result: EnvListResult,\n },\n \"env.delete\": {\n direction: \"s2p\",\n kind: \"request\",\n params: EnvDeleteParams,\n result: EnvDeleteResult,\n },\n\n // --- skill 管理(给 agent 装/卸 skill,global|project 两级,D24)---\n \"skill.install\": {\n direction: \"s2p\",\n kind: \"request\",\n params: SkillInstallParams,\n result: SkillInstallResult,\n },\n \"skill.uninstall\": {\n direction: \"s2p\",\n kind: \"request\",\n params: SkillUninstallParams,\n result: SkillUninstallResult,\n },\n \"skill.list\": {\n direction: \"s2p\",\n kind: \"request\",\n params: SkillListParams,\n result: SkillListResult,\n },\n} as const;\n\nexport type MethodName = keyof typeof METHODS;\nexport type MethodSpec = (typeof METHODS)[MethodName];\n\n/** 取某方法的 params 类型。 */\nexport type ParamsOf<M extends MethodName> = z.infer<(typeof METHODS)[M][\"params\"]>;\n/** 取某方法的 result 类型。 */\nexport type ResultOf<M extends MethodName> = z.infer<(typeof METHODS)[M][\"result\"]>;\n\n/** 运行时校验某方法的 params。 */\nexport function parseParams<M extends MethodName>(\n method: M,\n data: unknown,\n): ParamsOf<M> {\n return METHODS[method].params.parse(data) as ParamsOf<M>;\n}\n\n/** 运行时校验某方法的 result。 */\nexport function parseResult<M extends MethodName>(\n method: M,\n data: unknown,\n): ResultOf<M> {\n return METHODS[method].result.parse(data) as ResultOf<M>;\n}\n\n/** 全部方法名(运行时数组)。 */\nexport const METHOD_NAMES = Object.keys(METHODS) as MethodName[];\n","/**\n * @agent-phonon/protocol\n *\n * agent-phonon 的线协议——phonon 设备与服务端之间的唯一契约。\n * zod schema + 类型 + 方法注册表的单一事实来源(design docs/design.md)。\n */\n\nexport * from \"./schemas/common.js\";\nexport * from \"./schemas/capabilities.js\";\nexport * from \"./schemas/discovery.js\";\nexport * from \"./schemas/session.js\";\nexport * from \"./schemas/stream.js\";\nexport * from \"./schemas/hook.js\";\nexport * from \"./schemas/document.js\";\nexport * from \"./schemas/interaction.js\";\nexport * from \"./schemas/project.js\";\nexport * from \"./schemas/skill.js\";\nexport * from \"./schemas/policy.js\";\nexport * from \"./schemas/connect.js\";\nexport * from \"./schemas/device.js\";\nexport * from \"./schemas/file.js\";\nexport * from \"./schemas/env.js\";\nexport * from \"./schemas/jsonrpc.js\";\nexport * from \"./schemas/methods.js\";\n","import { EventEmitter } from \"node:events\";\nimport {\n JSON_RPC_CODES,\n type JsonRpcId,\n type MethodName,\n type ParamsOf,\n type ResultOf,\n} from \"@agent-phonon/protocol\";\n\n/**\n * 双向 JSON-RPC 2.0 peer(design D2)。\n *\n * 抽象掉传输:构造时传入一个 send 函数(把字符串发出去)和把收到的字符串喂给 handle()。\n * 两端皆可作 requester。core 与 test-server 都用它。\n */\n\nexport interface RpcTransport {\n /** 把一条 JSON 文本发出去。 */\n send(data: string): void;\n /** 关闭传输。 */\n close(): void;\n}\n\n/** 方法处理器:收到对端请求时调用,返回 result(或抛错)。 */\nexport type RpcHandler = (method: string, params: unknown) => Promise<unknown> | unknown;\n\ninterface Pending {\n resolve: (v: unknown) => void;\n reject: (e: unknown) => void;\n timer?: ReturnType<typeof setTimeout>;\n}\n\nexport class RpcPeer extends EventEmitter {\n private transport: RpcTransport;\n private handler: RpcHandler;\n private pending = new Map<string | number, Pending>();\n private nextId = 1;\n\n constructor(transport: RpcTransport, handler: RpcHandler) {\n super();\n this.transport = transport;\n this.handler = handler;\n }\n\n /** 发一个请求(需要响应),强类型版本。 */\n async request<M extends MethodName>(method: M, params: ParamsOf<M>): Promise<ResultOf<M>> {\n return this.requestRaw(method, params) as Promise<ResultOf<M>>;\n }\n\n /** 发一个请求(弱类型,内部用)。 */\n /** 发一个请求(弱类型,内部用)。timeoutMs 缺省 120s,0=不超时。 */\n requestRaw(method: string, params: unknown, timeoutMs = 120000): Promise<unknown> {\n const id = this.nextId++;\n const msg = { jsonrpc: \"2.0\", id, method, params };\n return new Promise((resolve, reject) => {\n const timer =\n timeoutMs > 0\n ? setTimeout(() => {\n this.pending.delete(id);\n reject(new PhononError(\"errInternal\", `RPC timeout: ${method}`));\n }, timeoutMs)\n : undefined;\n this.pending.set(id, { resolve, reject, timer });\n this.transport.send(JSON.stringify(msg));\n });\n }\n\n /** 发一个通知(不需要响应)。 */\n notify<M extends MethodName>(method: M, params: ParamsOf<M>): void {\n this.notifyRaw(method, params);\n }\n\n notifyRaw(method: string, params: unknown): void {\n this.transport.send(JSON.stringify({ jsonrpc: \"2.0\", method, params }));\n }\n\n /** 喂入一条收到的文本。 */\n async handle(data: string): Promise<void> {\n let msg: Record<string, unknown>;\n try {\n msg = JSON.parse(data);\n } catch {\n this.sendError(null, JSON_RPC_CODES.parseError, \"parse error\");\n return;\n }\n\n // 响应(成功/失败)\n if ((\"result\" in msg || \"error\" in msg) && \"id\" in msg) {\n const p = this.pending.get(msg.id as string | number);\n if (!p) return;\n this.pending.delete(msg.id as string | number);\n if (p.timer) clearTimeout(p.timer);\n if (\"error\" in msg && msg.error) {\n p.reject(msg.error);\n } else {\n p.resolve((msg as { result: unknown }).result);\n }\n return;\n }\n\n // 请求 / 通知\n if (typeof msg.method === \"string\") {\n const isNotification = !(\"id\" in msg) || msg.id === undefined || msg.id === null;\n try {\n const result = await this.handler(msg.method, msg.params);\n if (!isNotification) {\n this.transport.send(\n JSON.stringify({ jsonrpc: \"2.0\", id: msg.id as JsonRpcId, result: result ?? null }),\n );\n }\n } catch (err) {\n if (!isNotification) {\n const appCode = (err as { appCode?: string })?.appCode;\n const message = (err as Error)?.message ?? \"internal error\";\n this.transport.send(\n JSON.stringify({\n jsonrpc: \"2.0\",\n id: msg.id as JsonRpcId,\n error: {\n code: JSON_RPC_CODES.applicationError,\n message,\n ...(appCode ? { data: { appCode } } : {}),\n },\n }),\n );\n }\n }\n return;\n }\n }\n\n private sendError(id: JsonRpcId | null, code: number, message: string): void {\n this.transport.send(JSON.stringify({ jsonrpc: \"2.0\", id, error: { code, message } }));\n }\n\n /** 连接断开时:拒绝所有 pending,避免悬挂。 */\n rejectAllPending(reason: string): void {\n for (const [, p] of this.pending) {\n if (p.timer) clearTimeout(p.timer);\n p.reject(new Error(reason));\n }\n this.pending.clear();\n }\n}\n\n/** 带 appCode 的应用错误,handler 抛它,peer 会编码进 JSON-RPC error.data。 */\nexport class PhononError extends Error {\n appCode: string;\n constructor(appCode: string, message?: string) {\n super(message ?? appCode);\n this.appCode = appCode;\n }\n}\n","import type {\n AgentAdapter,\n AdapterSession,\n} from \"./adapter.js\";\nimport type { ContextItem, StreamEvent } from \"@agent-phonon/protocol\";\nimport { PhononError } from \"./rpc.js\";\n\n/** adapter 注册表:runtime name → adapter 实例。复合 agentId 按 runtime 前缀路由。 */\nexport class AdapterRegistry {\n private adapters = new Map<string, AgentAdapter>();\n\n register(adapter: AgentAdapter): void {\n this.adapters.set(adapter.name, adapter);\n }\n\n /** 按 runtime name 取。 */\n get(name: string): AgentAdapter | undefined {\n return this.adapters.get(name);\n }\n\n /**\n * 按完整 agentId 路由到 runtime adapter。\n * agentId 形如 \"openclaw:phonon\" → runtime \"openclaw\";单 agent runtime \"codex\" → \"codex\"。\n */\n resolve(agentId: string): AgentAdapter | undefined {\n const runtime = agentId.includes(\":\") ? agentId.split(\":\")[0]! : agentId;\n return this.adapters.get(runtime);\n }\n\n all(): AgentAdapter[] {\n return [...this.adapters.values()];\n }\n}\n\n/** 引擎内 session 记录。 */\ninterface SessionRecord {\n sessionId: string;\n tenantId: string;\n project: string;\n worktreeId?: string;\n agent: string;\n model: string;\n adapterName: string;\n adapterSession: AdapterSession;\n status: \"idle\" | \"running\" | \"paused\" | \"terminated\";\n /** 重启恢复后的游离态:无 live adapterSession,需 reattach 或 recreate。 */\n detached?: boolean;\n verbosity: \"final\" | \"messages\" | \"tools\" | \"trace\";\n currentTurnId?: string;\n /** 当前 turn 的 AbortController(interrupt 用,传给 adapter)。 */\n abort?: AbortController;\n /** 已发终态事件的 turnId(去重,避免双终态)。 */\n terminalTurns: Set<string>;\n queue: string[];\n seq: number;\n createdAt: string;\n lastActiveAt?: string;\n}\n\n/** 流式事件订阅回调(core 用它转发给对应 tenant 连接)。 */\nexport type StreamSink = (event: StreamEvent) => void;\n\n/**\n * Session 引擎(L1,design §4)。\n * 只认 sessionId,不感知 tenant 隔离(隔离在 L2 dispatch);但记录 tenantId 便于 L2 校验。\n */\nexport class SessionEngine {\n private sessions = new Map<string, SessionRecord>();\n private registry: AdapterRegistry;\n private sink: StreamSink;\n private idSeq = 1;\n /** 可观测事件总线(可选)。 */\n private obs?: import(\"./observability.js\").ObsBus;\n\n constructor(registry: AdapterRegistry, sink: StreamSink, obs?: import(\"./observability.js\").ObsBus, store?: import(\"./store.js\").PhononStore) {\n this.registry = registry;\n this.sink = sink;\n this.obs = obs;\n this.store = store;\n if (store) this.restoreSessions(store);\n }\n\n /** 重启恢复(功能缺口):从 sqlite 加载未 terminated 的 session,恢复为 paused(游离态)。\n * native-session adapter 可在下次 send 时 reattach;否则标记 needsRecreate。 */\n private restoreSessions(store: import(\"./store.js\").PhononStore): void {\n for (const row of store.loadSessions()) {\n const sessionId = row.session_id as string;\n if (this.sessions.has(sessionId)) continue;\n this.sessions.set(sessionId, {\n sessionId,\n tenantId: row.tenant_id as string,\n project: (row.project_id as string) ?? \"\",\n worktreeId: (row.worktree_id as string) ?? undefined,\n agent: row.agent_id as string,\n model: row.model as string,\n adapterName: (row.agent_id as string).split(\":\")[0] ?? (row.agent_id as string),\n adapterSession: undefined as never, // 游离:无 live session\n status: \"paused\",\n detached: true,\n verbosity: (row.verbosity as \"messages\") ?? \"messages\",\n terminalTurns: new Set(),\n queue: [],\n seq: 0,\n createdAt: row.created_at as string,\n lastActiveAt: (row.last_active as string) ?? undefined,\n });\n }\n }\n\n private store?: import(\"./store.js\").PhononStore;\n\n /** 持久化 session 元数据(bug-bash#2 B6)。 */\n private persist(rec: SessionRecord): void {\n this.store?.upsertSession({\n sessionId: rec.sessionId, tenantId: rec.tenantId, projectId: rec.project,\n worktreeId: rec.worktreeId, agent: rec.agent, model: rec.model,\n status: rec.status, verbosity: rec.verbosity, createdAt: rec.createdAt, lastActive: rec.lastActiveAt,\n });\n }\n\n private emit2(category: \"session\" | \"turn\" | \"tool\" | \"stream\" | \"error\", level: \"debug\" | \"info\" | \"warn\" | \"error\", event: string, rec: { sessionId: string; tenantId: string; agent: string; project: string } | undefined, extra?: { turnId?: string; msg?: string; data?: Record<string, unknown> }): void {\n this.obs?.emitEvent({\n category, level, event,\n tenantId: rec?.tenantId, sessionId: rec?.sessionId, agentId: rec?.agent, projectId: rec?.project,\n turnId: extra?.turnId, msg: extra?.msg, data: extra?.data,\n });\n }\n\n /** 校验 sessionId 是否属于某 tenant(L2 dispatch 用,D13)。 */\n assertTenant(sessionId: string, tenantId: string): SessionRecord {\n const rec = this.sessions.get(sessionId);\n if (!rec) throw new PhononError(\"errSessionNotFound\", `session ${sessionId} not found`);\n if (rec.tenantId !== tenantId)\n throw new PhononError(\"errSessionNotInTenant\", `session ${sessionId} not in tenant`);\n return rec;\n }\n\n async create(params: {\n tenantId: string;\n project: string;\n worktreeId?: string;\n cwd: string;\n agent: string;\n model: string;\n verbosity: \"final\" | \"messages\" | \"tools\" | \"trace\";\n agentConfig?: Record<string, unknown>;\n initialContext?: ContextItem[];\n }): Promise<{ sessionId: string; status: string; createdAt: string }> {\n const adapter = this.registry.resolve(params.agent);\n if (!adapter) throw new PhononError(\"errAgentUnavailable\", `agent ${params.agent} not found`);\n\n const sessionId = `s-${Date.now()}-${this.idSeq++}`;\n const adapterSession = await adapter.createSession({\n sessionId,\n agentId: params.agent,\n model: params.model,\n cwd: params.cwd,\n agentConfig: params.agentConfig,\n initialContext: params.initialContext,\n });\n\n // 自发输出水槽(D16):adapter 在无 active turn 时的输出走这里,core 统一打 seq 后转发\n adapterSession.setUnsolicitedSink?.((event) => {\n const rec = this.sessions.get(sessionId);\n if (rec) this.sink({ ...event, seq: rec.seq++ } as StreamEvent);\n });\n\n const createdAt = new Date().toISOString();\n this.sessions.set(sessionId, {\n sessionId,\n tenantId: params.tenantId,\n project: params.project,\n worktreeId: params.worktreeId,\n agent: params.agent,\n model: params.model,\n adapterName: params.agent,\n adapterSession,\n status: \"idle\",\n verbosity: params.verbosity,\n terminalTurns: new Set(),\n queue: [],\n seq: 0,\n createdAt,\n });\n const rec0 = this.sessions.get(sessionId)!;\n this.persist(rec0);\n this.emit2(\"session\", \"info\", \"session.create\", rec0, { msg: `session ${sessionId} on ${params.agent} (${params.model})`, data: { model: params.model } });\n return { sessionId, status: \"idle\", createdAt };\n }\n\n /** 可选:reattach 时解析 project cwd(由 connection 注入)。 */\n resolveCwdForReattach?: (projectId: string) => string;\n\n /** 重新附着游离 session(重启恢复后首次使用)。\n * native-session adapter 重建会复用原生会话(如 OpenClaw sessionKey / Claude --resume)。 */\n private async reattach(rec: SessionRecord): Promise<void> {\n const adapter = this.registry.resolve(rec.agent);\n if (!adapter) throw new PhononError(\"errAgentUnavailable\", `agent ${rec.agent} unavailable for reattach`);\n const cwd = this.resolveCwdForReattach?.(rec.project) ?? rec.project;\n rec.adapterSession = await adapter.createSession({\n sessionId: rec.sessionId, agentId: rec.agent, model: rec.model, cwd,\n });\n rec.adapterSession.setUnsolicitedSink?.((event) => {\n const r = this.sessions.get(rec.sessionId);\n if (r) this.sink({ ...event, seq: r.seq++ } as StreamEvent);\n });\n rec.detached = false;\n rec.status = \"idle\";\n this.emit2(\"session\", \"info\", \"session.reattach\", rec, { msg: `reattached ${rec.sessionId}` });\n }\n\n async send(\n tenantId: string,\n sessionId: string,\n input: string,\n opts: {\n verbosity?: \"final\" | \"messages\" | \"tools\" | \"trace\";\n turnId?: string;\n skills?: string[];\n whenBusy?: \"queue\" | \"interrupt\" | \"inject\";\n fallback?: \"queue\" | \"interrupt\" | \"inject\";\n environment?: Record<string, string>;\n },\n ): Promise<{ turnId: string; disposition: string; queuePosition?: number }> {\n const rec = this.assertTenant(sessionId, tenantId);\n if (rec.status === \"terminated\")\n throw new PhononError(\"errSessionTerminated\", \"session terminated\");\n // 重启恢复:游离 session 首次 send 时 reattach(重建 adapterSession)\n if (rec.detached) await this.reattach(rec);\n\n const turnId = opts.turnId ?? `t-${Date.now()}-${this.idSeq++}`;\n const verbosity = opts.verbosity ?? rec.verbosity;\n const payload = JSON.stringify({ turnId, input, verbosity, skills: opts.skills, environment: opts.environment });\n\n if (rec.status === \"running\") {\n // 忙碌处理(D18)。whenBusy 不支持时走 fallback。\n let mode = opts.whenBusy ?? \"queue\";\n const adapter = this.registry.resolve(rec.agent);\n if (mode === \"interrupt\" && !adapter?.capabilities.interrupt) mode = opts.fallback ?? \"queue\";\n if (mode === \"inject\" && !adapter?.capabilities.injectMidTurn) mode = opts.fallback ?? \"queue\";\n\n if (mode === \"interrupt\") {\n await this.interrupt(tenantId, sessionId);\n // 中断后立即跑本轮\n } else {\n // queue(默认):FIFO 排队,上轮结束自动出队\n rec.queue.push(payload);\n return { turnId, disposition: \"queued\", queuePosition: rec.queue.length };\n }\n }\n\n rec.status = \"running\";\n rec.currentTurnId = turnId;\n rec.lastActiveAt = new Date().toISOString();\n this.emit2(\"turn\", \"info\", \"turn.start\", rec, { turnId, msg: `turn ${turnId} started`, data: { input: input.slice(0, 200) } });\n this.persist(rec);\n void this.runTurn(rec, input, turnId, verbosity, opts.skills, opts.environment);\n return { turnId, disposition: \"started\" };\n }\n\n private async runTurn(\n rec: SessionRecord,\n input: string,\n turnId: string,\n verbosity: \"final\" | \"messages\" | \"tools\" | \"trace\",\n skills?: string[],\n environment?: Record<string, string>,\n ): Promise<void> {\n const abort = new AbortController();\n rec.abort = abort;\n const emit = (event: StreamEvent) => {\n const t = (event as { type?: string }).type;\n // 终态事件去重(避免双终态):engine 统一发,adapter 重复发的丢弃\n const isFinal = (event as { final?: boolean }).final === true;\n if (isFinal) {\n if (rec.terminalTurns.has(turnId)) return; // 已有终态,丢\n rec.terminalTurns.add(turnId);\n // 限制集合大小(避免无限增长)\n if (rec.terminalTurns.size > 200) {\n const first = rec.terminalTurns.values().next().value;\n if (first !== undefined) rec.terminalTurns.delete(first);\n }\n }\n // 可观测:工具调用事件\n if (t === \"tool_call\") {\n this.emit2(\"tool\", \"info\", \"tool.call\", rec, { turnId, msg: `tool ${(event as { toolName?: string }).toolName}`, data: { toolName: (event as { toolName?: string }).toolName } });\n } else if (t === \"tool_result\") {\n this.emit2(\"tool\", \"debug\", \"tool.result\", rec, { turnId, data: { toolName: (event as { toolName?: string }).toolName } });\n }\n this.sink({ ...event, seq: rec.seq++ } as StreamEvent);\n };\n try {\n await rec.adapterSession.send(input, { turnId, verbosity, skills, environment, emit, signal: abort.signal });\n } catch (err) {\n emit({\n type: \"error\",\n sessionId: rec.sessionId,\n turnId,\n seq: 0,\n at: new Date().toISOString(),\n message: (err as Error)?.message ?? \"turn failed\",\n status: \"failed\",\n final: true,\n } as StreamEvent);\n } finally {\n // 竞态守卫:只有本 turn 仍是当前 turn 才能收尾(避免旧 turn 覆盖新 turn 状态)\n if (rec.currentTurnId === turnId && rec.status !== \"terminated\") {\n rec.abort = undefined;\n rec.status = \"idle\";\n rec.currentTurnId = undefined;\n this.persist(rec);\n this.emit2(\"turn\", \"info\", \"turn.end\", rec, { turnId, msg: `turn ${turnId} ended` });\n const next = rec.queue.shift();\n if (next) {\n const n = JSON.parse(next) as { turnId: string; input: string; verbosity: typeof verbosity; skills?: string[]; environment?: Record<string, string> };\n rec.status = \"running\";\n rec.currentTurnId = n.turnId;\n rec.lastActiveAt = new Date().toISOString();\n void this.runTurn(rec, n.input, n.turnId, n.verbosity, n.skills, n.environment);\n }\n }\n }\n }\n\n async interrupt(tenantId: string, sessionId: string, reason?: string): Promise<{ interruptedTurnId?: string; status: string }> {\n const rec = this.assertTenant(sessionId, tenantId);\n const turnId = rec.currentTurnId;\n // 先发 engine 统一终态(标记 terminalTurns),确保 interrupted 是唯一终态;\n // 后续 adapter 被 kill 重发的 failed/close 会被 runTurn.emit 去重。\n if (turnId && !rec.terminalTurns.has(turnId)) {\n rec.terminalTurns.add(turnId);\n this.sink({\n type: \"result\",\n sessionId,\n turnId,\n seq: rec.seq++,\n at: new Date().toISOString(),\n text: \"\",\n status: \"interrupted\",\n final: true,\n } as StreamEvent);\n }\n // 再触发 abort + 停底层执行\n rec.abort?.abort();\n if (!rec.detached && rec.adapterSession?.interrupt) await rec.adapterSession.interrupt(reason);\n if (!turnId && rec.status !== \"terminated\") rec.status = \"idle\";\n return { interruptedTurnId: turnId, status: rec.status === \"running\" ? \"idle\" : rec.status };\n }\n\n async switchModel(tenantId: string, sessionId: string, model: string): Promise<{ previousModel: string; model: string; warnings?: string[] }> {\n const rec = this.assertTenant(sessionId, tenantId);\n if (rec.status === \"running\")\n throw new PhononError(\"errSessionBusy\", \"cannot switch model while running (whenRunning=reject)\");\n const previousModel = rec.model;\n let warnings: string[] | undefined;\n if (!rec.detached && rec.adapterSession?.switchModel) {\n const r = await rec.adapterSession.switchModel(model);\n warnings = r.warnings;\n }\n rec.model = model;\n rec.adapterSession.model = model;\n return { previousModel, model, warnings };\n }\n\n async inject(tenantId: string, sessionId: string, context: ContextItem[]): Promise<{ injected: number }> {\n const rec = this.assertTenant(sessionId, tenantId);\n if (!rec.detached && rec.adapterSession?.inject) await rec.adapterSession.inject(context);\n return { injected: context.length };\n }\n\n async compress(\n tenantId: string,\n sessionId: string,\n mode: \"native\" | \"custom\",\n strategy?: string,\n options?: { keepRecentToolCalls?: number },\n ): Promise<{ mode: string; summary?: string; filesChanged?: number; recordsChanged?: number; blocksRemoved?: number; bytesBefore?: number; bytesAfter?: number; backups?: string[] }> {\n const rec = this.assertTenant(sessionId, tenantId);\n if (mode === \"native\") {\n const adapter = this.registry.resolve(rec.agent);\n if (!adapter?.capabilities.nativeCompression)\n throw new PhononError(\"errCapabilityUnsupported\", \"native compression not supported by this agent\");\n if (!rec.detached && rec.adapterSession?.compressNative) {\n const r = await rec.adapterSession.compressNative();\n return { mode, summary: r.summary };\n }\n return { mode, summary: \"native compress requested\" };\n }\n if (!rec.detached && rec.adapterSession?.compressCustom) {\n const r = await rec.adapterSession.compressCustom(strategy ?? \"dropToolIO\", options);\n return { mode, ...r };\n }\n throw new PhononError(\"errCapabilityUnsupported\", `custom compression not supported by adapter ${rec.agent}`);\n }\n\n /** 实时快照:当前所有 session 在干什么(可观测 /sessions 用)。 */\n snapshot(tenantId?: string): Array<Record<string, unknown>> {\n const out: Array<Record<string, unknown>> = [];\n for (const rec of this.sessions.values()) {\n if (tenantId && rec.tenantId !== tenantId) continue;\n out.push({\n sessionId: rec.sessionId,\n tenantId: rec.tenantId,\n agent: rec.agent,\n model: rec.model,\n project: rec.project,\n status: rec.status, // idle/running/paused/terminated\n currentTurnId: rec.currentTurnId,\n queued: rec.queue.length,\n lastActiveAt: rec.lastActiveAt,\n });\n }\n return out;\n }\n\n async terminate(tenantId: string, sessionId: string): Promise<{ status: \"terminated\" }> {\n const rec = this.assertTenant(sessionId, tenantId);\n if (!rec.detached) await rec.adapterSession?.terminate();\n rec.status = \"terminated\";\n this.persist(rec);\n this.emit2(\"session\", \"info\", \"session.terminate\", rec, { msg: `session ${sessionId} terminated` });\n return { status: \"terminated\" };\n }\n\n async status(tenantId: string, sessionId: string) {\n const rec = this.assertTenant(sessionId, tenantId);\n const meta = this.toMeta(rec);\n // 补充上下文信息(adapter 能提供时,D33);detached/游离 session 无 live adapterSession,跳过\n if (!rec.detached && rec.adapterSession?.describe) {\n try {\n const ctx = await rec.adapterSession.describe();\n if (ctx.contextWindow !== undefined && ctx.usedTokens !== undefined && ctx.usagePercent === undefined && ctx.contextWindow > 0) {\n ctx.usagePercent = Math.min(100, Math.max(0, (ctx.usedTokens / ctx.contextWindow) * 100));\n }\n if (ctx.contextWindow !== undefined || ctx.usedTokens !== undefined || ctx.usagePercent !== undefined || ctx.compactions !== undefined) {\n return { ...meta, context: ctx };\n }\n } catch {\n /* ignore */\n }\n }\n return meta;\n }\n\n /** server ack 了 seq≤lastSeq(P0-4)。v0 内存模型 no-op;接 sqlite outbox 后在此清理。 */\n ackStream(_sessionId: string | undefined, _lastSeq: number): void {\n // TODO: 接 outbox 持久化后清理 <= lastSeq\n }\n\n /** server 回填 interaction(P1-5)。v0:如果有等待者则 resolve。 */\n private interactionWaiters = new Map<string, (v: unknown) => void>();\n resolveInteraction(requestId: string, payload: unknown): void {\n const w = this.interactionWaiters.get(requestId);\n if (w) {\n w(payload);\n this.interactionWaiters.delete(requestId);\n }\n }\n registerInteractionWaiter(requestId: string, resolve: (v: unknown) => void): void {\n this.interactionWaiters.set(requestId, resolve);\n }\n\n list(\n tenantId: string,\n filter?: { project?: string; agent?: string; status?: string; limit?: number; cursor?: string },\n ): { sessions: ReturnType<SessionEngine[\"toMeta\"]>[]; nextCursor?: string } {\n const all = [];\n for (const rec of this.sessions.values()) {\n if (rec.tenantId !== tenantId) continue; // tenant 隔离\n if (filter?.project && rec.project !== filter.project) continue;\n if (filter?.agent && rec.agent !== filter.agent) continue;\n if (filter?.status && rec.status !== filter.status) continue;\n all.push(rec);\n }\n // 稳定排序(按 createdAt),游标分页(P2#14)\n all.sort((a, b) => a.createdAt.localeCompare(b.createdAt) || a.sessionId.localeCompare(b.sessionId));\n const start = filter?.cursor ? Math.max(0, all.findIndex((r) => r.sessionId === filter.cursor) + 1) : 0;\n const limit = filter?.limit;\n const page = limit ? all.slice(start, start + limit) : all.slice(start);\n const last = page[page.length - 1];\n const hasMore = limit !== undefined && start + page.length < all.length;\n return {\n sessions: page.map((rec) => this.toMeta(rec)),\n ...(hasMore && last ? { nextCursor: last.sessionId } : {}),\n };\n }\n\n /** 某 project 下的 active(idle/running/paused) session ids(bug-bash P0#8)。 */\n activeSessionsForProject(projectId: string): string[] {\n const out: string[] = [];\n for (const rec of this.sessions.values()) {\n if (rec.project === projectId && rec.status !== \"terminated\") out.push(rec.sessionId);\n }\n return out;\n }\n\n /** 某 worktree 上的 active session ids。 */\n activeSessionsForWorktree(worktreeId: string): string[] {\n const out: string[] = [];\n for (const rec of this.sessions.values()) {\n if (rec.worktreeId === worktreeId && rec.status !== \"terminated\") out.push(rec.sessionId);\n }\n return out;\n }\n\n private toMeta(rec: SessionRecord) {\n return {\n sessionId: rec.sessionId,\n project: rec.project,\n ...(rec.worktreeId ? { worktreeId: rec.worktreeId } : {}),\n agent: rec.agent,\n model: rec.model,\n status: rec.status,\n currentTurnId: rec.currentTurnId,\n queuedCount: rec.queue.length,\n verbosity: rec.verbosity,\n createdAt: rec.createdAt,\n lastActiveAt: rec.lastActiveAt,\n };\n }\n}\n","import { SessionEngine, AdapterRegistry } from \"./session-engine.js\";\nimport { RpcPeer, PhononError, type RpcTransport } from \"./rpc.js\";\nimport { ProjectManager } from \"./project-manager.js\";\nimport { SkillManager } from \"./skill-manager.js\";\nimport { PolicyEnforcer } from \"./policy.js\";\nimport { IdempotencyStore } from \"./idempotency.js\";\nimport { Outbox } from \"./outbox.js\";\nimport { PhononStore } from \"./store.js\";\nimport { FileManager } from \"./file-manager.js\";\nimport { collectDeviceResources } from \"./resources.js\";\nimport { collectDeviceInfo } from \"./device-info.js\";\nimport { EnvManager } from \"./env-manager.js\";\nimport type { AgentAdapter } from \"./adapter.js\";\nimport { PROTOCOL_VERSION, parseParams, METHODS, type StreamEvent, type TenantPolicy, type MethodName } from \"@agent-phonon/protocol\";\n\n/** 改状态的方法(幂等适用)。 */\nconst MUTATING_METHODS = new Set<string>([\n \"session.create\",\n \"session.send\",\n \"project.create\",\n \"project.remove\",\n \"project.worktree.create\",\n \"project.worktree.remove\",\n \"project.git.deleteBranch\",\n \"skill.install\",\n \"skill.uninstall\",\n \"file.write\",\n \"file.mkdir\",\n \"env.set\",\n \"env.delete\",\n]);\n\n/**\n * 设备侧 daemon 的「一条连接处理器」(L2 dispatch,design §6)。\n *\n * 一个 PhononConnection = 一条到某 server 的连接 = 一个 tenant。\n * 它把 server 下发的 session.* 路由到 SessionEngine,并在交给 L1 前做 tenant 校验;\n * 同时把 engine 产出的 stream.event 推回 server。\n *\n * 真实场景:phonon 主动拨出连真 server。\n * 测试场景:test-server 主动连进来,或 phonon 连 test-server——传输无关,靠 RpcTransport 抽象。\n */\nexport class PhononConnection {\n readonly tenantId: string;\n private engine: SessionEngine;\n private peer: RpcPeer;\n private registry: AdapterRegistry;\n private projects: ProjectManager;\n private skills: SkillManager;\n private policy: PolicyEnforcer;\n private idempotency: IdempotencyStore;\n private outbox: Outbox;\n private store: PhononStore;\n private files: FileManager;\n private env: EnvManager;\n private obs?: import(\"./observability.js\").ObsBus;\n /** 该 tenant 绑定的默认项目工作目录解析器(v0 简化:projectId 即绝对路径或映射)。 */\n private resolveProjectCwd: (project: string) => string;\n\n constructor(opts: {\n tenantId: string;\n transport: RpcTransport;\n registry: AdapterRegistry;\n resolveProjectCwd?: (project: string) => string;\n policy?: Partial<TenantPolicy>;\n trustLocal?: boolean;\n workspaceRoot?: string;\n /** sqlite 文件路径(缺省内存库)。 */\n dbPath?: string;\n /** 或直接注入已有 store(多连接共享)。 */\n store?: PhononStore;\n /** 可观测事件总线(可选)。 */\n obs?: import(\"./observability.js\").ObsBus;\n }) {\n this.tenantId = opts.tenantId;\n this.registry = opts.registry;\n this.policy = new PolicyEnforcer({ policy: opts.policy, trustLocal: opts.trustLocal, workspaceRoot: opts.workspaceRoot });\n // 持久化(D6):projects/skills/worktrees/outbox 落 sqlite;dbPath 缺省内存库\n this.store = opts.store ?? new PhononStore(opts.dbPath ?? \":memory:\");\n this.idempotency = new IdempotencyStore({ store: this.store });\n\n // 先建 engine(ProjectManager 要用它查 active session)\n this.outbox = new Outbox({ store: this.store, tenantId: opts.tenantId });\n this.engine = new SessionEngine(opts.registry, (event: StreamEvent) => {\n // 下行可靠投递(D29):先入 outbox(含 sqlite)再发;server ack 后清理\n this.outbox.enqueue(event);\n this.peer.notifyRaw(\"stream.event\", event);\n }, opts.obs, this.store);\n this.engine.resolveCwdForReattach = (projectId) => this.resolveProjectCwd(projectId);\n this.obs = opts.obs;\n\n this.projects = new ProjectManager(\n (projectId) => this.engine.activeSessionsForProject(projectId), // 真实 active 查询(修 P0#8)\n {\n assertProjectPath: (p) => this.policy.assertProjectPath(p),\n assertDeleteFiles: () => this.policy.assertDeleteFiles(),\n store: this.store,\n workspaceRoot: this.policy.workspaceRoot, // 与 policy 一致,避免路径校验冲突\n hasActiveSessionsForWorktree: (wtId) => this.engine.activeSessionsForWorktree(wtId), // 精确查询(B8)\n },\n );\n this.skills = new SkillManager(\n opts.registry,\n (projectId) => {\n try {\n return this.projects.get(projectId).path;\n } catch {\n return undefined;\n }\n },\n this.store,\n );\n this.files = new FileManager({ resolveCwd: (projectId, worktreeId) => this.projects.resolveCwd(projectId, worktreeId) });\n this.env = new EnvManager(this.store, { allowReveal: () => this.policy.allowEnvReveal() });\n this.resolveProjectCwd = opts.resolveProjectCwd ?? ((p) => this.projects.resolveCwd(p));\n\n this.peer = new RpcPeer(opts.transport, (method, params) => this.dispatch(method, params));\n }\n\n /** 喂入收到的文本。 */\n handle(data: string): Promise<void> {\n return this.peer.handle(data);\n }\n\n /** 连接断开:拒绝 pending RPC;outbox 保留供重连补发。 */\n onClose(reason = \"connection closed\"): void {\n this.peer.rejectAllPending(reason);\n }\n\n /** 重连后补发未 ack 的 stream.event(D29)。resumeFrom = server welcome.ackedSeqs 转换。 */\n replayPending(resumeFrom?: Array<{ sessionId: string; fromSeq: number }>): number {\n const events = this.outbox.pending(resumeFrom);\n for (const e of events) this.peer.notifyRaw(\"stream.event\", e);\n return events.length;\n }\n\n /** outbox 待投递事件数(监控用)。 */\n get outboxSize(): number {\n return this.outbox.size;\n }\n\n /** 当前 session 实时快照(可观测 /sessions)。 */\n sessionsSnapshot(): Array<Record<string, unknown>> {\n return this.engine.snapshot(this.tenantId);\n }\n\n // ---- p2s 主动发起(phonon → server,平面③ + HITL)----\n\n /** 发本地文档给 server(document.send,D20)。adapter 解析 directive 后调用。 */\n async sendDocument(params: unknown): Promise<unknown> {\n return this.peer.requestRaw(\"document.send\", params);\n }\n\n /** 请求大文件上传凭证(document.prepare_upload,P1-6)。 */\n async prepareUpload(params: unknown): Promise<unknown> {\n return this.peer.requestRaw(\"document.prepare_upload\", params);\n }\n\n /** 主动通知 server:agent 可用性变化(discovery.changed,D14)。 */\n notifyDiscoveryChanged(params: unknown): void {\n this.peer.notifyRaw(\"discovery.changed\", params);\n }\n\n /** 发可交互表单给 server,阻塞等人填(interaction.request,D21/P1-5)。 */\n async requestInteraction(params: unknown): Promise<unknown> {\n return this.peer.requestRaw(\"interaction.request\", params);\n }\n\n /** 报 hook 事件并阻塞等 server 裁决(hook.fired,design §8,HITL)。 */\n async fireHook(params: unknown): Promise<unknown> {\n const p = (params ?? {}) as { sessionId?: string; hookType?: string; payload?: { toolName?: string } };\n this.obs?.emitEvent({\n category: \"hitl\", level: \"info\", event: \"hitl.fired\",\n tenantId: this.tenantId, sessionId: p.sessionId,\n msg: `HITL ${p.hookType} for tool ${p.payload?.toolName ?? \"?\"}`,\n data: { hookType: p.hookType, toolName: p.payload?.toolName },\n });\n const res = (await this.peer.requestRaw(\"hook.fired\", params)) as { action?: string };\n this.obs?.emitEvent({\n category: \"hitl\", level: res?.action === \"abort\" ? \"warn\" : \"info\", event: \"hitl.resolved\",\n tenantId: this.tenantId, sessionId: p.sessionId,\n msg: `HITL decision: ${res?.action ?? \"continue\"}`, data: { action: res?.action },\n });\n return res;\n }\n\n /** 某 phonon sessionId 是否属于本连接(tenant)——HookBridge 路由用。 */\n ownsSession(sessionId: string): boolean {\n try {\n this.engine.assertTenant(sessionId, this.tenantId);\n return true;\n } catch {\n return false;\n }\n }\n\n /** server → phonon 方法分发(L2 dispatch)。 */\n private async dispatch(method: string, params: unknown): Promise<unknown> {\n let p = (params ?? {}) as Record<string, unknown>;\n // 协议级参数校验(bug-bash#2 B6):s2p 方法过 zod,非法参数 → errInvalidParams\n if (method in METHODS && (METHODS as Record<string, { direction: string }>)[method]?.direction === \"s2p\") {\n try {\n p = parseParams(method as MethodName, params) as Record<string, unknown>;\n } catch (err) {\n throw new PhononError(\"errInvalidParams\", `invalid params for ${method}: ${(err as Error)?.message?.slice(0, 200)}`);\n }\n }\n // 只读租户 / 方法白名单(policy)\n this.policy.assertMethodAllowed(method);\n // 幂等:改状态请求带 clientRequestId 则去重(D28 / P0#2)\n const crid = p.clientRequestId as string | undefined;\n if (crid && MUTATING_METHODS.has(method)) {\n return this.idempotency.run(this.tenantId, method, crid, () => this.dispatchInner(method, p));\n }\n return this.dispatchInner(method, p);\n }\n\n private async dispatchInner(method: string, p: Record<string, unknown>): Promise<unknown> {\n switch (method) {\n case \"device.info\":\n return collectDeviceInfo();\n case \"device.resources\":\n return collectDeviceResources(this.policy.workspaceRoot);\n case \"discovery.list\": {\n // 聚合所有 runtime 的 sub-agents(OpenClaw 多 agent / Codex 单 agent)\n const nested = await Promise.all(this.registry.all().map((a) => a.discoverAgents()));\n return { agents: nested.flat() };\n }\n case \"discovery.get\": {\n const adapter = this.registry.resolve(p.agentId as string);\n if (!adapter) throw new PhononError(\"errAgentUnavailable\", `agent ${p.agentId} not found`);\n const agents = await adapter.discoverAgents();\n const found = agents.find((a) => a.agentId === p.agentId) ?? agents[0];\n return { agent: found };\n }\n case \"session.create\": {\n // worktreeId 指定时,cwd = 该 worktree 路径(修 P0#12)\n let cwd = this.resolveProjectCwd(p.project as string);\n if (p.worktreeId) {\n const wt = this.projects.worktreeList(p.project as string).find((w) => w.worktreeId === p.worktreeId);\n if (wt) cwd = wt.path;\n }\n const r = await this.engine.create({\n tenantId: this.tenantId,\n project: p.project as string,\n worktreeId: p.worktreeId as string | undefined,\n cwd,\n agent: p.agent as string,\n model: p.model as string,\n verbosity: (p.verbosity as \"messages\") ?? \"messages\",\n agentConfig: p.agentConfig as Record<string, unknown> | undefined,\n initialContext: p.initialContext as never,\n });\n return { sessionId: r.sessionId, project: p.project, agent: p.agent, model: p.model, status: r.status, createdAt: r.createdAt };\n }\n case \"session.send\": {\n const meta = await this.engine.status(this.tenantId, p.sessionId as string);\n const r = await this.engine.send(this.tenantId, p.sessionId as string, p.input as string, {\n verbosity: p.verbosity as never,\n turnId: p.turnId as string | undefined,\n skills: (p.skills as string[]) ?? undefined,\n environment: this.env.resolveForExecution({ projectId: meta.project, agent: meta.agent, skills: (p.skills as string[]) ?? undefined }),\n whenBusy: p.whenBusy as never,\n fallback: p.fallback as never,\n });\n return { sessionId: p.sessionId, turnId: r.turnId, accepted: true, disposition: r.disposition, queuePosition: r.queuePosition };\n }\n case \"session.interrupt\": {\n const r = await this.engine.interrupt(this.tenantId, p.sessionId as string, p.reason as string | undefined);\n return { sessionId: p.sessionId, interruptedTurnId: r.interruptedTurnId, status: r.status };\n }\n case \"session.switchModel\": {\n const r = await this.engine.switchModel(this.tenantId, p.sessionId as string, p.model as string);\n return { sessionId: p.sessionId, previousModel: r.previousModel, model: r.model, warnings: r.warnings };\n }\n case \"session.inject\": {\n const r = await this.engine.inject(this.tenantId, p.sessionId as string, p.context as never);\n return { sessionId: p.sessionId, injected: r.injected };\n }\n case \"session.compress\": {\n const r = await this.engine.compress(this.tenantId, p.sessionId as string, (p.mode as \"native\" | \"custom\") ?? \"native\", p.strategy as string | undefined, { keepRecentToolCalls: p.keepRecentToolCalls as number | undefined });\n return { sessionId: p.sessionId, mode: r.mode, summary: r.summary };\n }\n case \"session.terminate\": {\n const r = await this.engine.terminate(this.tenantId, p.sessionId as string);\n return { sessionId: p.sessionId, status: r.status };\n }\n case \"session.status\":\n return this.engine.status(this.tenantId, p.sessionId as string);\n case \"session.list\":\n return this.engine.list(this.tenantId, p as never);\n\n // ---- project (D23/D25) ----\n case \"project.create\": {\n const r = await this.projects.create({ name: p.name as string, path: p.path as string | undefined, git: p.git as boolean | undefined, remote: p.remote as string | undefined });\n return { project: { projectId: r.projectId, name: r.name, path: r.path, git: r.git, createdAt: r.createdAt } };\n }\n case \"project.list\":\n return { projects: this.projects.list().map((r) => ({ projectId: r.projectId, name: r.name, path: r.path, git: r.git, createdAt: r.createdAt })) };\n case \"project.get\": {\n const r = this.projects.get(p.projectId as string);\n return { project: { projectId: r.projectId, name: r.name, path: r.path, git: r.git, createdAt: r.createdAt } };\n }\n case \"project.remove\": {\n const r = await this.projects.remove(p.projectId as string, { deleteFiles: p.deleteFiles as boolean, whenActiveSessions: p.whenActiveSessions as \"reject\" | \"cascade\" });\n // cascade:真正 terminate 被级联的 session(修 B8:之前只返回列表不 terminate)\n if (r.terminatedSessions) {\n for (const sid of r.terminatedSessions) {\n await this.engine.terminate(this.tenantId, sid).catch(() => {});\n }\n }\n return { projectId: p.projectId, removed: true, filesDeleted: r.filesDeleted, terminatedSessions: r.terminatedSessions };\n }\n case \"project.worktree.create\": {\n const r = await this.projects.worktreeCreate({ projectId: p.projectId as string, baseBranch: p.baseBranch as string, newBranch: p.newBranch as string | undefined, path: p.path as string | undefined });\n return { worktree: r };\n }\n case \"project.worktree.list\":\n return { worktrees: this.projects.worktreeList(p.projectId as string) };\n case \"project.worktree.remove\": {\n const r = await this.projects.worktreeRemove({ projectId: p.projectId as string, worktreeId: p.worktreeId as string, force: p.force as boolean });\n return { worktreeId: p.worktreeId, removed: true, affectedSessions: r.affectedSessions };\n }\n case \"project.git.deleteBranch\": {\n const r = await this.projects.deleteBranch({ projectId: p.projectId as string, branch: p.branch as string, force: p.force as boolean });\n return { branch: p.branch, deleted: true, wasMerged: r.wasMerged, affectedWorktrees: r.affectedWorktrees };\n }\n\n // ---- file workspace IO (project/worktree scoped) ----\n case \"file.read\":\n return this.files.read(p as { projectId: string; worktreeId?: string; path: string; encoding?: \"utf8\" | \"base64\"; maxBytes?: number });\n case \"file.write\":\n return this.files.write(p as { projectId: string; worktreeId?: string; path: string; encoding?: \"utf8\" | \"base64\"; data: string; overwrite?: boolean; createDirs?: boolean });\n case \"file.list\":\n return this.files.list(p as { projectId: string; worktreeId?: string; path?: string; recursive?: boolean; limit?: number });\n case \"file.stat\":\n return this.files.stat(p as { projectId: string; worktreeId?: string; path: string });\n case \"file.mkdir\":\n return this.files.mkdir(p as { projectId: string; worktreeId?: string; path: string; recursive?: boolean });\n\n case \"env.set\":\n return this.env.set(p as { scope: \"global\" | \"project\" | \"skill\"; projectId?: string; agent?: string; skillName?: string; name: string; value: string; secret?: boolean });\n case \"env.list\":\n return this.env.list(p as { scope?: \"global\" | \"project\" | \"skill\"; projectId?: string; agent?: string; skillName?: string; reveal?: boolean });\n case \"env.delete\":\n return this.env.delete(p as { scope: \"global\" | \"project\" | \"skill\"; projectId?: string; agent?: string; skillName?: string; name: string });\n\n // ---- skill (D24 + 边界规则) ----\n case \"skill.install\": {\n // policy:global 装 / url 源 检查(P0-1)\n if ((p.scope as string) === \"global\") this.policy.assertGlobalSkillInstall();\n const src = p.source as { kind?: string } | undefined;\n if (src?.kind === \"url\") this.policy.assertUrlSkillInstall();\n const r = await this.skills.install({\n agent: p.agent as string, name: p.name as string,\n scope: p.scope as \"global\" | \"project\", projectId: p.projectId as string | undefined,\n source: p.source as never,\n allowUrl: true, // policy 已在上面把关\n });\n return { skill: r };\n }\n case \"skill.uninstall\": {\n await this.skills.uninstall({ agent: p.agent as string, name: p.name as string, scope: p.scope as \"global\" | \"project\", projectId: p.projectId as string | undefined });\n return { agent: p.agent, name: p.name, scope: p.scope, uninstalled: true };\n }\n case \"skill.list\":\n return { skills: this.skills.list({ agent: p.agent as string | undefined, scope: p.scope as \"global\" | \"project\" | undefined, projectId: p.projectId as string | undefined }) };\n\n // ---- 连接/可靠性(s2p) ----\n case \"stream.ack\": {\n // server 确认已收 seq≤lastSeq → phonon 清 outbox(D29 / P0-4)。\n this.outbox.ack(p.sessionId as string | undefined, p.lastSeq as number);\n return null;\n }\n case \"interaction.response\": {\n // server 回填人机交互结果(P1-5)→ 路由回对应 session/turn。v0 记录即可。\n this.engine.resolveInteraction?.(p.requestId as string, p as never);\n return null;\n }\n case \"interaction.cancel\": {\n // server 主动取消一个 pending 交互(P1-5)。\n this.engine.resolveInteraction?.(p.requestId as string, { action: \"cancel\", requestId: p.requestId });\n return { requestId: p.requestId, cancelled: true };\n }\n case \"hook.resolve\": {\n // server 主动下发裁决(异步路径;同步路径是 hook.fired 的 RPC 响应)。\n return { sessionId: p.sessionId, hookId: p.hookId, applied: true };\n }\n default:\n throw new PhononError(\"errInvalidParams\", `method not implemented in v0 core: ${method}`);\n }\n }\n}\n\nexport { SessionEngine, AdapterRegistry, RpcPeer, PhononError, PROTOCOL_VERSION };\nexport type { AgentAdapter, RpcTransport };\nexport * from \"./adapter.js\";\nexport { OpenClawAdapter } from \"./adapters/openclaw.js\";\nexport { OpenClawGatewayAdapter } from \"./adapters/openclaw-gateway.js\";\nexport { GatewayClient } from \"./gateway-client.js\";\nexport type { GatewayConfig } from \"./gateway-client.js\";\nexport { PhononClient } from \"./client.js\";\nexport { HookBridge } from \"./hook-bridge.js\";\nexport type { HookRouteResolver } from \"./hook-bridge.js\";\nexport { ProjectManager } from \"./project-manager.js\";\nexport { SkillManager } from \"./skill-manager.js\";\nexport { PolicyEnforcer } from \"./policy.js\";\nexport { IdempotencyStore } from \"./idempotency.js\";\nexport { Outbox } from \"./outbox.js\";\nexport { PhononStore } from \"./store.js\";\nexport { SecretBox } from \"./secret-box.js\";\nexport { FileManager } from \"./file-manager.js\";\nexport { EnvManager } from \"./env-manager.js\";\nexport { dropToolIOFromJsonlFiles, dropToolIOFromValue, computeKeepToolBlocks } from \"./custom-compress.js\";\nexport { dropToolIORowsSqlite } from \"./sqlite-compress.js\";\nexport { resolveCodexSessionFile } from \"./adapters/codex.js\";\nexport { resolveOpenCodeDbPath } from \"./adapters/opencode.js\";\nexport { resolveHermesDbPath, resolveHermesSessionByTitle } from \"./adapters/hermes.js\";\nexport { collectDeviceResources } from \"./resources.js\";\nexport { collectDeviceInfo } from \"./device-info.js\";\nexport { ObsBus, StructuredLogger, Metrics, AuditSink } from \"./observability.js\";\nexport type { ObsEvent, ObsCategory, ObsLevel } from \"./observability.js\";\nexport { ClaudeCodeAdapter } from \"./adapters/claude-code.js\";\nexport type { ClaudeCodeEnv } from \"./adapters/claude-code.js\";\nexport { CodexAdapter } from \"./adapters/codex.js\";\nexport type { CodexEnv } from \"./adapters/codex.js\";\nexport { HermesAdapter } from \"./adapters/hermes.js\";\nexport type { HermesEnv } from \"./adapters/hermes.js\";\nexport { OpenCodeAdapter } from \"./adapters/opencode.js\";\nexport type { OpenCodeEnv } from \"./adapters/opencode.js\";\n","import { spawn } from \"node:child_process\";\nimport { mkdir, rm, readdir, stat } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join, resolve, basename } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { PhononError } from \"./rpc.js\";\n\n/**\n * 项目管理(design §8c / D23 + D25)。\n *\n * 一个项目 = 一个目录 + Git。core 直接跑 git 命令实现 worktree/分支操作。\n * 项目设备级共享、不受 tenant 隔离(D23 修正)。\n * 持久化 v0 用内存表 + 磁盘探测;后续接 sqlite。\n */\n\nexport interface ProjectRecord {\n projectId: string;\n name: string;\n path: string;\n git: boolean;\n createdAt: string;\n}\n\nexport interface WorktreeRecord {\n worktreeId: string;\n projectId: string;\n path: string;\n branch: string;\n isPrimary: boolean;\n createdAt: string;\n}\n\n/** 受控工作区根:项目缺省建在这里下面(避免 server 越权指定任意路径,P0-1)。 */\nfunction defaultWorkspaceRoot(): string {\n return process.env.PHONON_PROJECTS_ROOT ?? join(homedir(), \"phonon-projects\");\n}\n\nfunction runGit(cwd: string, args: string[], timeoutMs = 30000): Promise<string> {\n return new Promise((resolveP, reject) => {\n const child = spawn(\"git\", args, { cwd });\n let out = \"\";\n let err = \"\";\n const timer = setTimeout(() => {\n child.kill(\"SIGTERM\");\n reject(new PhononError(\"errInternal\", `git ${args[0]} timeout`));\n }, timeoutMs);\n child.stdout.on(\"data\", (d) => (out += d.toString()));\n child.stderr.on(\"data\", (d) => (err += d.toString()));\n child.on(\"error\", (e) => {\n clearTimeout(timer);\n reject(new PhononError(\"errInternal\", `git spawn failed: ${e.message}`));\n });\n child.on(\"close\", (code) => {\n clearTimeout(timer);\n if (code === 0) resolveP(out.trim());\n else reject(new PhononError(\"errInternal\", `git ${args.join(\" \")} exited ${code}: ${err.slice(0, 300)}`));\n });\n });\n}\n\nexport class ProjectManager {\n private projects = new Map<string, ProjectRecord>();\n private worktrees = new Map<string, WorktreeRecord>();\n private idSeq = 1;\n /** 查询某 project 是否有 active session(由 engine 注入)。 */\n private hasActiveSessions: (projectId: string) => string[];\n /** 查询某 worktree 是否有 active session(bug-bash#2 B8)。 */\n private hasActiveSessionsForWorktree: (worktreeId: string) => string[];\n /** 可选 policy 校验回调(bug-bash P0-1)。 */\n private assertProjectPath?: (path: string) => void;\n private assertDeleteFiles?: () => void;\n\n constructor(\n hasActiveSessions: (projectId: string) => string[] = () => [],\n hooks?: { assertProjectPath?: (path: string) => void; assertDeleteFiles?: () => void; store?: import(\"./store.js\").PhononStore; workspaceRoot?: string; hasActiveSessionsForWorktree?: (worktreeId: string) => string[] },\n ) {\n this.hasActiveSessions = hasActiveSessions;\n this.hasActiveSessionsForWorktree = hooks?.hasActiveSessionsForWorktree ?? (() => []);\n this.assertProjectPath = hooks?.assertProjectPath;\n this.assertDeleteFiles = hooks?.assertDeleteFiles;\n this.store = hooks?.store;\n this.workspaceRoot = hooks?.workspaceRoot;\n // 重启恢复:从 sqlite 加载已有 project/worktree\n if (this.store) {\n for (const p of this.store.loadProjects()) this.projects.set(p.projectId, p);\n for (const w of this.store.loadWorktrees()) this.worktrees.set(w.worktreeId, w);\n }\n }\n\n private store?: import(\"./store.js\").PhononStore;\n /** 受控项目根(与 PolicyEnforcer.workspaceRoot 一致,避免路径校验不一致)。 */\n private workspaceRoot?: string;\n\n /** 解析 projectId → 工作目录(session.create / file.* 用)。 */\n resolveCwd(projectId: string, worktreeId?: string): string {\n if (worktreeId) {\n const wt = this.worktrees.get(worktreeId);\n if (!wt || wt.projectId !== projectId) throw new PhononError(\"errWorktreeNotFound\", `worktree ${worktreeId} not found`);\n return wt.path;\n }\n const rec = this.projects.get(projectId);\n return rec?.path ?? projectId; // 兼容:未注册时把 projectId 当路径\n }\n\n async create(params: { name: string; path?: string; git?: boolean; remote?: string }): Promise<ProjectRecord> {\n const projectId = `proj-${Date.now()}-${this.idSeq++}`;\n const root = this.workspaceRoot ?? defaultWorkspaceRoot();\n const path = params.path ? resolve(params.path) : join(root, params.name);\n // 路径校验(P0-1):policy 执行越界拒绝(不再「记风险但放行」)\n if (this.assertProjectPath) this.assertProjectPath(path);\n if (existsSync(path) && (await readdir(path)).length > 0) {\n // 目录已存在且非空:当作既有项目接管,不报错\n } else {\n await mkdir(path, { recursive: true });\n }\n const git = params.git !== false;\n if (git && !existsSync(join(path, \".git\"))) {\n await runGit(path, [\"init\"]);\n if (params.remote) await runGit(path, [\"remote\", \"add\", \"origin\", params.remote]).catch(() => {});\n }\n const rec: ProjectRecord = { projectId, name: params.name, path, git, createdAt: new Date().toISOString() };\n this.projects.set(projectId, rec);\n this.store?.upsertProject(rec);\n return rec;\n }\n\n list(): ProjectRecord[] {\n return [...this.projects.values()];\n }\n\n get(projectId: string): ProjectRecord {\n const rec = this.projects.get(projectId);\n if (!rec) throw new PhononError(\"errProjectNotFound\", `project ${projectId} not found`);\n return rec;\n }\n\n async remove(projectId: string, opts: { deleteFiles?: boolean; whenActiveSessions?: \"reject\" | \"cascade\" }): Promise<{ filesDeleted: boolean; terminatedSessions?: string[] }> {\n const rec = this.get(projectId);\n const active = this.hasActiveSessions(projectId);\n let terminatedSessions: string[] | undefined;\n if (active.length > 0) {\n if ((opts.whenActiveSessions ?? \"reject\") === \"reject\")\n throw new PhononError(\"errProjectHasActiveSessions\", `project has ${active.length} active sessions`);\n terminatedSessions = active; // cascade:调用方负责 terminate(engine 注入回调)\n }\n let filesDeleted = false;\n if (opts.deleteFiles) {\n if (this.assertDeleteFiles) this.assertDeleteFiles(); // policy:allowDeleteFiles\n await rm(rec.path, { recursive: true, force: true });\n filesDeleted = true;\n }\n this.projects.delete(projectId);\n this.store?.deleteProject(projectId);\n // 清理该 project 的 worktree 记录\n for (const [id, wt] of this.worktrees) if (wt.projectId === projectId) this.worktrees.delete(id);\n return { filesDeleted, terminatedSessions };\n }\n\n // ---- worktree (D25) ----\n async worktreeCreate(params: { projectId: string; baseBranch: string; newBranch?: string; path?: string }): Promise<WorktreeRecord> {\n const proj = this.get(params.projectId);\n const worktreeId = `wt-${Date.now()}-${this.idSeq++}`;\n const wtPath = params.path ? resolve(params.path) : join(proj.path, \"..\", `${proj.name}-${params.newBranch ?? params.baseBranch}`.replace(/\\//g, \"-\"));\n // 自定义 worktree path 同样走 policy 路径校验(bug-bash#2 B8)\n if (params.path && this.assertProjectPath) this.assertProjectPath(wtPath);\n const branch = params.newBranch ?? params.baseBranch;\n const args = [\"worktree\", \"add\"];\n if (params.newBranch) args.push(\"-b\", params.newBranch);\n args.push(wtPath, params.baseBranch);\n await runGit(proj.path, args);\n const rec: WorktreeRecord = { worktreeId, projectId: params.projectId, path: wtPath, branch, isPrimary: false, createdAt: new Date().toISOString() };\n this.worktrees.set(worktreeId, rec);\n this.store?.upsertWorktree(rec);\n return rec;\n }\n\n worktreeList(projectId: string): WorktreeRecord[] {\n return [...this.worktrees.values()].filter((w) => w.projectId === projectId);\n }\n\n async worktreeRemove(params: { projectId: string; worktreeId: string; force?: boolean }): Promise<{ affectedSessions?: string[] }> {\n const proj = this.get(params.projectId);\n const wt = this.worktrees.get(params.worktreeId);\n if (!wt) throw new PhononError(\"errWorktreeNotFound\", `worktree ${params.worktreeId} not found`);\n // 精确到该 worktree 的 active session(不是整个 project,bug-bash#2 B8)\n const active = this.hasActiveSessionsForWorktree(params.worktreeId).filter(Boolean);\n if (active.length > 0 && !params.force)\n throw new PhononError(\"errWorktreeInUse\", \"worktree has active sessions\");\n const args = [\"worktree\", \"remove\", wt.path];\n if (params.force) args.push(\"--force\");\n await runGit(proj.path, args).catch((e) => {\n if (String(e?.message).includes(\"contains modified\") || String(e?.message).includes(\"not empty\"))\n throw new PhononError(\"errWorktreeHasChanges\", \"worktree has uncommitted changes (use force)\");\n throw e;\n });\n this.worktrees.delete(params.worktreeId);\n this.store?.deleteWorktree(params.worktreeId);\n return { affectedSessions: params.force ? active : undefined };\n }\n\n async deleteBranch(params: { projectId: string; branch: string; force?: boolean }): Promise<{ wasMerged: boolean; affectedWorktrees?: string[] }> {\n const proj = this.get(params.projectId);\n const inUse = this.worktreeList(params.projectId).filter((w) => w.branch === params.branch);\n if (inUse.length > 0 && !params.force)\n throw new PhononError(\"errBranchInUse\", \"branch is checked out by a worktree\");\n const flag = params.force ? \"-D\" : \"-d\";\n try {\n await runGit(proj.path, [\"branch\", flag, params.branch]);\n } catch (e) {\n if (String((e as Error)?.message).includes(\"not fully merged\"))\n throw new PhononError(\"errBranchNotMerged\", \"branch not merged (use force)\");\n throw e;\n }\n return { wasMerged: !params.force, affectedWorktrees: inUse.length ? inUse.map((w) => w.worktreeId) : undefined };\n }\n}\n\nexport { runGit };\n","import { mkdir, rm, writeFile, readdir, stat, mkdtemp, lstat } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join, resolve, sep } from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { createHash } from \"node:crypto\";\nimport { PhononError } from \"./rpc.js\";\nimport type { AdapterRegistry } from \"./session-engine.js\";\n\n/**\n * Skill 管理(design D24 + 安全边界规则)。\n *\n * 安装位置规则:\n * - project scope → 装到 <project>/.agent/skills/<name>/ —— **runtime 无关**,谁用这个 project 都看得到\n * - global scope → **依赖 runtime**,装到对应 runtime 的全局 skill 目录\n * (adapter.globalSkillDir(agentId) 提供;OpenClaw = 该 sub-agent workspace/skills)\n *\n * phonon 自己管一套安装逻辑;global 位置交给各 adapter(只有它知道自己 runtime skill 目录)。\n */\n\nexport interface SkillRecord {\n name: string;\n agent: string;\n scope: \"global\" | \"project\";\n projectId?: string;\n version?: string;\n hash?: string;\n installedPath: string;\n installedAt: string;\n}\n\ntype SkillSource =\n | { kind: \"inline\"; files: Record<string, string> }\n | { kind: \"archive\"; format: \"tar.gz\"; contentBase64: string; sha256?: string; sizeBytes?: number }\n | { kind: \"localPath\"; path: string }\n | { kind: \"url\"; url: string; sha256?: string };\n\nconst execFileAsync = promisify(execFile);\n\nexport class SkillManager {\n private skills: SkillRecord[] = [];\n private registry: AdapterRegistry;\n /** projectId → 项目目录解析(core 注入)。 */\n private resolveProjectPath: (projectId: string) => string | undefined;\n private store?: import(\"./store.js\").PhononStore;\n\n constructor(\n registry: AdapterRegistry,\n resolveProjectPath: (projectId: string) => string | undefined,\n store?: import(\"./store.js\").PhononStore,\n ) {\n this.registry = registry;\n this.resolveProjectPath = resolveProjectPath;\n this.store = store;\n if (this.store) for (const s of this.store.loadSkills()) this.skills.push(s);\n }\n\n /** 计算安装目标目录(核心边界规则)。 */\n private targetDir(params: { agent: string; name: string; scope: \"global\" | \"project\"; projectId?: string }): string {\n // 防路径穿越(bug-bash#2 B8):skill name 限定安全字符\n if (!/^[a-zA-Z0-9._-]+$/.test(params.name) || params.name === \".\" || params.name === \"..\") {\n throw new PhononError(\"errSkillScopeInvalid\", `invalid skill name: ${params.name}`);\n }\n if (params.scope === \"project\") {\n if (!params.projectId) throw new PhononError(\"errSkillScopeInvalid\", \"project scope requires projectId\");\n const projPath = this.resolveProjectPath(params.projectId);\n if (!projPath) throw new PhononError(\"errProjectNotFound\", `project ${params.projectId} not found`);\n // project scope → <project>/.agent/skills/<name>,runtime 无关\n return join(projPath, \".agent\", \"skills\", params.name);\n }\n // global scope → adapter 提供的 runtime skill 目录\n const adapter = this.registry.resolve(params.agent);\n if (!adapter) throw new PhononError(\"errAgentUnavailable\", `agent ${params.agent} not found`);\n if (!adapter.globalSkillDir) throw new PhononError(\"errCapabilityUnsupported\", `runtime does not support global skills`);\n const dir = adapter.globalSkillDir(params.agent);\n if (!dir) throw new PhononError(\"errCapabilityUnsupported\", `no global skill dir for ${params.agent}`);\n return join(dir, params.name);\n }\n\n async install(params: {\n agent: string;\n name: string;\n scope: \"global\" | \"project\";\n projectId?: string;\n source: SkillSource;\n allowUrl?: boolean;\n }): Promise<SkillRecord> {\n const dest = this.targetDir(params);\n await mkdir(dest, { recursive: true });\n\n let hash: string | undefined;\n const hasher = createHash(\"sha256\");\n\n if (params.source.kind === \"inline\") {\n for (const [rel, content] of Object.entries(params.source.files)) {\n const full = resolve(dest, rel);\n // 防路径穿越:写入目标必须在 dest 内(bug-bash#2 B8)\n if (full !== dest && !full.startsWith(dest + sep)) {\n throw new PhononError(\"errSkillInstallFailed\", `inline file path escapes skill dir: ${rel}`);\n }\n await mkdir(join(full, \"..\"), { recursive: true });\n await writeFile(full, content);\n hasher.update(rel).update(content);\n }\n hash = hasher.digest(\"hex\");\n } else if (params.source.kind === \"archive\") {\n hash = await this.installArchive(params.source, dest);\n } else if (params.source.kind === \"localPath\") {\n // 复制本地目录(用 cp -r 的等价:递归读写)\n await this.copyDir(params.source.path, dest, hasher);\n hash = hasher.digest(\"hex\");\n } else {\n // url:受 policy 控制(P0-1 allowUrlSkillInstall),v0 默认拒\n if (!params.allowUrl)\n throw new PhononError(\"errPolicyDenied\", \"url skill install disabled by policy (allowUrlSkillInstall)\");\n throw new PhononError(\"errSkillInstallFailed\", \"url install not implemented in v0\");\n }\n\n const rec: SkillRecord = {\n name: params.name,\n agent: params.agent,\n scope: params.scope,\n projectId: params.projectId,\n hash,\n installedPath: dest,\n installedAt: new Date().toISOString(),\n };\n // 去重:同 agent+scope+name(+project) 覆盖\n this.skills = this.skills.filter(\n (s) => !(s.agent === rec.agent && s.scope === rec.scope && s.name === rec.name && s.projectId === rec.projectId),\n );\n this.skills.push(rec);\n this.store?.upsertSkill(rec);\n return rec;\n }\n\n async uninstall(params: { agent: string; name: string; scope: \"global\" | \"project\"; projectId?: string }): Promise<void> {\n const dest = this.targetDir(params);\n if (existsSync(dest)) await rm(dest, { recursive: true, force: true });\n this.skills = this.skills.filter(\n (s) => !(s.agent === params.agent && s.scope === params.scope && s.name === params.name && s.projectId === params.projectId),\n );\n this.store?.deleteSkill(params);\n }\n\n list(filter?: { agent?: string; scope?: \"global\" | \"project\"; projectId?: string }): SkillRecord[] {\n return this.skills.filter((s) => {\n if (filter?.agent && s.agent !== filter.agent) return false;\n if (filter?.scope && s.scope !== filter.scope) return false;\n if (filter?.projectId && s.projectId !== filter.projectId) return false;\n return true;\n });\n }\n\n private async installArchive(source: Extract<SkillSource, { kind: \"archive\" }>, dest: string): Promise<string> {\n if (source.format !== \"tar.gz\") throw new PhononError(\"errSkillInstallFailed\", `unsupported archive format: ${source.format}`);\n const buf = Buffer.from(source.contentBase64, \"base64\");\n const hash = createHash(\"sha256\").update(buf).digest(\"hex\");\n if (source.sha256 && source.sha256 !== hash) throw new PhononError(\"errSkillInstallFailed\", \"archive sha256 mismatch\");\n\n const tmp = await mkdtemp(join(tmpdir(), \"phonon-skill-\"));\n const archive = join(tmp, \"skill.tar.gz\");\n const staging = join(tmp, \"staging\");\n await mkdir(staging, { recursive: true });\n try {\n await writeFile(archive, buf, { mode: 0o600 });\n const { stdout } = await execFileAsync(\"tar\", [\"-tzf\", archive], { timeout: 10000, maxBuffer: 10 * 1024 * 1024 });\n for (const entry of stdout.split(/\\n/).filter(Boolean)) this.assertArchiveEntrySafe(entry);\n await execFileAsync(\"tar\", [\"-xzf\", archive, \"-C\", staging], { timeout: 30000, maxBuffer: 10 * 1024 * 1024 });\n await this.assertNoSymlinks(staging);\n await this.copyDir(staging, dest, createHash(\"sha256\"));\n return hash;\n } finally {\n await rm(tmp, { recursive: true, force: true });\n }\n }\n\n private assertArchiveEntrySafe(entry: string): void {\n const normalized = entry.replace(/\\\\/g, \"/\");\n if (normalized.startsWith(\"/\") || normalized === \"..\" || normalized.startsWith(\"../\") || normalized.includes(\"/../\") || normalized.includes(\"\\0\")) {\n throw new PhononError(\"errSkillInstallFailed\", `unsafe archive entry: ${entry}`);\n }\n }\n\n private async assertNoSymlinks(root: string): Promise<void> {\n const entries = await readdir(root, { withFileTypes: true });\n for (const e of entries) {\n const p = join(root, e.name);\n const s = await lstat(p);\n if (s.isSymbolicLink()) throw new PhononError(\"errSkillInstallFailed\", `archive contains symlink: ${e.name}`);\n if (s.isDirectory()) await this.assertNoSymlinks(p);\n }\n }\n\n private async copyDir(src: string, dest: string, hasher: ReturnType<typeof createHash>): Promise<void> {\n if (!existsSync(src)) throw new PhononError(\"errSkillNotFound\", `source ${src} not found`);\n const entries = await readdir(src, { withFileTypes: true });\n for (const e of entries) {\n const s = join(src, e.name);\n const d = join(dest, e.name);\n if (e.isDirectory()) {\n await mkdir(d, { recursive: true });\n await this.copyDir(s, d, hasher);\n } else {\n const { readFile } = await import(\"node:fs/promises\");\n const content = await readFile(s);\n await writeFile(d, content);\n hasher.update(e.name).update(content);\n }\n }\n }\n}\n","import { resolve } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { TenantPolicy, DEFAULT_TENANT_POLICY, isPathUnderRoots, type TenantPolicy as TenantPolicyT } from \"@agent-phonon/protocol\";\nimport { PhononError } from \"./rpc.js\";\n\n/**\n * 本地安全策略执行器(design D27 / bug-bash P0-1)。\n *\n * 协议定义了 TenantPolicy,但 v0 dispatch 没真执行。这里把它落地:\n * 每个 PhononConnection 持一个 PolicyEnforcer,在 project/skill/document/destructive\n * 操作入口强制检查,违反抛 errPolicyDenied / errDocumentPathDenied。\n *\n * 默认最严格(DEFAULT_TENANT_POLICY):白名单空、写操作全关、敏感路径黑名单。\n * 但为了不破坏「单设备本地自用」的开箱体验,构造时可传宽松默认(trustLocal)。\n */\nexport class PolicyEnforcer {\n readonly policy: TenantPolicyT;\n /** 受控工作区根(项目缺省建在这下面)。 */\n readonly workspaceRoot: string;\n\n constructor(opts?: { policy?: Partial<TenantPolicyT>; workspaceRoot?: string; trustLocal?: boolean }) {\n this.workspaceRoot = opts?.workspaceRoot ?? process.env.PHONON_PROJECTS_ROOT ?? `${homedir()}/phonon-projects`;\n if (opts?.policy) {\n this.policy = TenantPolicy.parse(opts.policy);\n } else if (opts?.trustLocal) {\n // 本地自用:允许写操作 + 受控根作为默认 allowedProjectRoots\n this.policy = TenantPolicy.parse({\n allowedProjectRoots: [this.workspaceRoot],\n allowDeleteFiles: true,\n allowGlobalSkillInstall: true,\n allowUrlSkillInstall: false, // url 装仍默认禁(供应链风险)\n allowExternalDocuments: false,\n });\n } else {\n this.policy = DEFAULT_TENANT_POLICY;\n }\n }\n\n /** 项目路径是否允许(落在 allowedProjectRoots 或受控根下)。 */\n assertProjectPath(path: string): void {\n const abs = resolve(path);\n const roots = [this.workspaceRoot, ...this.policy.allowedProjectRoots];\n if (!isPathUnderRoots(abs, roots)) {\n throw new PhononError(\"errPolicyDenied\", `project path outside allowed roots: ${abs}`);\n }\n }\n\n /** 文档路径是否允许(默认 project-scoped;外部需 allowExternalDocuments)。 */\n assertDocumentPath(absPath: string, projectRoot: string | undefined): void {\n const abs = resolve(absPath);\n // deny 黑名单优先(即使在项目内也拒)\n for (const pat of this.policy.denyPathPatterns) {\n if (matchGlob(abs, pat)) throw new PhononError(\"errDocumentPathDenied\", `denied by pattern ${pat}`);\n }\n if (projectRoot && isPathUnderRoots(abs, [projectRoot])) return; // 项目内放行\n if (this.policy.allowExternalDocuments) return;\n throw new PhononError(\"errDocumentPathDenied\", `document path outside project: ${abs}`);\n }\n\n assertDeleteFiles(): void {\n if (!this.policy.allowDeleteFiles) throw new PhononError(\"errPolicyDenied\", \"deleteFiles disabled by policy\");\n }\n\n assertGlobalSkillInstall(): void {\n if (!this.policy.allowGlobalSkillInstall) throw new PhononError(\"errPolicyDenied\", \"global skill install disabled by policy\");\n }\n\n assertUrlSkillInstall(): void {\n if (!this.policy.allowUrlSkillInstall) throw new PhononError(\"errPolicyDenied\", \"url skill install disabled by policy\");\n }\n\n assertMethodAllowed(method: string): void {\n if (this.policy.allowedMethods.length > 0 && !this.policy.allowedMethods.includes(method)) {\n throw new PhononError(\"errPolicyDenied\", `method ${method} not in allowedMethods (read-only tenant)`);\n }\n }\n\n allowEnvReveal(): boolean {\n return !!this.policy.allowEnvReveal;\n }\n\n assertUploadSize(bytes: number): void {\n if (this.policy.maxUploadBytes !== undefined && bytes > this.policy.maxUploadBytes) {\n throw new PhononError(\"errDocumentTooLarge\", `${bytes} bytes exceeds maxUploadBytes ${this.policy.maxUploadBytes}`);\n }\n }\n}\n\n/** 极简 glob 匹配(仅支持 ** 和 *),用于 denyPathPatterns。 */\nfunction matchGlob(path: string, pattern: string): boolean {\n const norm = path.replace(/\\\\/g, \"/\");\n const re = new RegExp(\n \"^\" +\n pattern\n .replace(/\\\\/g, \"/\")\n .replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\")\n .replace(/\\*\\*/g, \"\\u0000\") // 占位\n .replace(/\\*/g, \"[^/]*\")\n .replace(/\\u0000/g, \".*\") +\n \"$\",\n );\n return re.test(norm);\n}\n\nexport { matchGlob };\n","/**\n * 幂等存储(design D28 / bug-bash P0#2)。\n *\n * 协议定义了 clientRequestId,但 v0 dispatch 没去重。这里实现:\n * tenantId + method + clientRequestId → 缓存的 result(或 in-flight promise)\n * 断线重发同一请求时返回缓存结果,不重复执行(不丢 + 不重)。\n *\n * v0 内存版,带 TTL + 上限;后续可接 sqlite。\n */\ninterface Entry {\n promise: Promise<unknown>;\n at: number;\n}\n\nexport class IdempotencyStore {\n private map = new Map<string, Entry>();\n private ttlMs: number;\n private max: number;\n private store?: { idempotencyGet: (k: string) => string | undefined; idempotencyPut: (k: string, r: string) => void };\n\n constructor(opts?: { ttlMs?: number; max?: number; store?: { idempotencyGet: (k: string) => string | undefined; idempotencyPut: (k: string, r: string) => void } }) {\n this.ttlMs = opts?.ttlMs ?? 10 * 60 * 1000; // 10 分钟\n this.max = opts?.max ?? 5000;\n this.store = opts?.store;\n }\n\n private key(tenantId: string, method: string, clientRequestId: string): string {\n return `${tenantId}\\u0000${method}\\u0000${clientRequestId}`;\n }\n\n /**\n * 若该 (tenant,method,clientRequestId) 已见过,返回其结果;否则执行 fn 并缓存。\n * 内存 + sqlite 两级:跨重启也去重(功能缺口)。clientRequestId 为空不去重。\n */\n async run<T>(\n tenantId: string,\n method: string,\n clientRequestId: string | undefined,\n fn: () => Promise<T>,\n ): Promise<T> {\n if (!clientRequestId) return fn();\n this.gc();\n const k = this.key(tenantId, method, clientRequestId);\n const existing = this.map.get(k);\n if (existing) return existing.promise as Promise<T>;\n // sqlite 二级:跨重启命中则直接返回缓存结果\n const persisted = this.store?.idempotencyGet(k);\n if (persisted !== undefined) return JSON.parse(persisted) as T;\n const promise = fn();\n this.map.set(k, { promise, at: Date.now() });\n // 成功落 sqlite(跨重启);失败不缓存(允许重试)\n promise.then(\n (r) => { try { this.store?.idempotencyPut(k, JSON.stringify(r)); } catch { /* ignore */ } },\n () => this.map.delete(k),\n );\n return promise;\n }\n\n private gc(): void {\n const now = Date.now();\n if (this.map.size < this.max && now % 16 !== 0) return; // 抽样 GC\n for (const [k, v] of this.map) {\n if (now - v.at > this.ttlMs) this.map.delete(k);\n }\n // 仍超限:删最旧\n if (this.map.size >= this.max) {\n const sorted = [...this.map.entries()].sort((a, b) => a[1].at - b[1].at);\n for (let i = 0; i < sorted.length - this.max + 1; i++) this.map.delete(sorted[i]![0]);\n }\n }\n}\n","import type { StreamEvent } from \"@agent-phonon/protocol\";\n\n/**\n * 下行 outbox(design D29 / bug-bash P1)。\n *\n * stream.event 先入 outbox 再发;server 用 stream.ack{lastSeq} 确认后清理 <= lastSeq。\n * 连接断开期间事件继续缓存;重连后按 seq 补发未 ack 的。\n *\n * v0 内存版,带上限(超限丢最旧 + 计数告警)。后续可接 sqlite outbox_events 表。\n *\n * 注意:seq 是 per-session 单调递增(engine 打的),outbox 按 (sessionId, seq) 索引。\n */\ninterface Buffered {\n sessionId: string;\n seq: number;\n event: StreamEvent;\n}\n\nexport class Outbox {\n private buffer: Buffered[] = [];\n private maxEvents: number;\n private droppedCount = 0;\n /** per-session 已 ack 的最大 seq。 */\n private acked = new Map<string, number>();\n private store?: import(\"./store.js\").PhononStore;\n private tenantId?: string;\n\n constructor(opts?: { maxEvents?: number; store?: import(\"./store.js\").PhononStore; tenantId?: string }) {\n this.maxEvents = opts?.maxEvents ?? 10000;\n this.store = opts?.store;\n this.tenantId = opts?.tenantId;\n if (this.store && this.tenantId) {\n for (const r of this.store.outboxLoad(this.tenantId)) {\n this.buffer.push({ sessionId: r.sessionId, seq: r.seq, event: JSON.parse(r.payload) as StreamEvent });\n }\n }\n }\n\n /** 记录一个待投递事件(已带 seq)。返回是否触发超限丢弃。 */\n enqueue(event: StreamEvent): void {\n const sessionId = (event as { sessionId: string }).sessionId;\n const seq = (event as { seq: number }).seq;\n this.buffer.push({ sessionId, seq, event });\n this.store?.outboxAdd(this.tenantId ?? \"\", sessionId, seq, JSON.stringify(event), new Date().toISOString());\n if (this.buffer.length > this.maxEvents) {\n this.buffer.shift(); // 丢最旧\n this.droppedCount++;\n }\n }\n\n /** server ack 了某 session 的 seq <= lastSeq → 清理。 */\n ack(sessionId: string | undefined, lastSeq: number): void {\n if (sessionId) {\n const prev = this.acked.get(sessionId) ?? -1;\n if (lastSeq > prev) this.acked.set(sessionId, lastSeq);\n this.buffer = this.buffer.filter((b) => !(b.sessionId === sessionId && b.seq <= lastSeq));\n } else {\n // 全局 ack(无 sessionId):按 seq 清所有 session 中 <= lastSeq 的(少用)\n this.buffer = this.buffer.filter((b) => b.seq > lastSeq);\n }\n this.store?.outboxAck(this.tenantId ?? \"\", sessionId, lastSeq);\n }\n\n /**\n * 重连补发:返回所有未 ack 的事件(按 seq 排序),由调用方重新 send。\n * resumeFrom 可指定每个 session 从哪个 seq 开始(server 告知 ackedSeqs)。\n */\n pending(resumeFrom?: Array<{ sessionId: string; fromSeq: number }>): StreamEvent[] {\n let items = [...this.buffer];\n if (resumeFrom && resumeFrom.length > 0) {\n const map = new Map(resumeFrom.map((r) => [r.sessionId, r.fromSeq]));\n items = items.filter((b) => {\n const from = map.get(b.sessionId);\n return from === undefined || b.seq > from;\n });\n }\n items.sort((a, b) => a.seq - b.seq);\n return items.map((b) => b.event);\n }\n\n get size(): number {\n return this.buffer.length;\n }\n\n get dropped(): number {\n return this.droppedCount;\n }\n}\n","import { DatabaseSync } from \"node:sqlite\";\nimport { mkdirSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { SecretBox } from \"./secret-box.js\";\n\n/**\n * 本地持久化(design D6 / bug-bash B3)。\n *\n * 用 Node 原生 `node:sqlite`(Node 22.5+,零第三方依赖、免编译)。\n * daemon 重启后 projects/skills/worktrees/sessions 元数据/outbox/幂等不丢。\n *\n * v0 落这些表:projects, worktrees, skills, sessions, outbox_events,\n * idempotency, pending_interactions。tenant/inbox_queue 后续按需。\n */\nexport class PhononStore {\n private db: DatabaseSync;\n /** env 变量值 at-rest 加密(AES-256-GCM)。密钥文件与库同目录、0600。 */\n private secrets: SecretBox;\n\n constructor(dbPath: string) {\n if (dbPath !== \":memory:\") mkdirSync(dirname(dbPath), { recursive: true });\n this.db = new DatabaseSync(dbPath);\n this.db.exec(\"PRAGMA journal_mode = WAL;\");\n this.db.exec(\"PRAGMA foreign_keys = ON;\");\n // 设备密钥:内存库用进程内随机密钥;落盘库用同目录 device.key(0600)。\n this.secrets = SecretBox.fromKeyFile(dbPath === \":memory:\" ? undefined : join(dirname(dbPath), \"device.key\"));\n this.migrate();\n }\n\n private migrate(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS projects (\n project_id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n path TEXT NOT NULL,\n git INTEGER NOT NULL DEFAULT 1,\n remote TEXT,\n created_at TEXT NOT NULL\n );\n CREATE TABLE IF NOT EXISTS worktrees (\n worktree_id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL,\n path TEXT NOT NULL,\n branch TEXT NOT NULL,\n is_primary INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL\n );\n CREATE TABLE IF NOT EXISTS skills (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n agent_id TEXT NOT NULL,\n name TEXT NOT NULL,\n scope TEXT NOT NULL,\n project_id TEXT,\n version TEXT,\n hash TEXT,\n installed_path TEXT NOT NULL,\n installed_at TEXT NOT NULL,\n UNIQUE(agent_id, scope, name, project_id)\n );\n CREATE TABLE IF NOT EXISTS sessions (\n session_id TEXT PRIMARY KEY,\n tenant_id TEXT NOT NULL,\n project_id TEXT,\n worktree_id TEXT,\n agent_id TEXT NOT NULL,\n model TEXT NOT NULL,\n status TEXT NOT NULL,\n verbosity TEXT NOT NULL,\n created_at TEXT NOT NULL,\n last_active TEXT\n );\n CREATE TABLE IF NOT EXISTS outbox_events (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n tenant_id TEXT NOT NULL,\n session_id TEXT NOT NULL,\n seq INTEGER NOT NULL,\n payload TEXT NOT NULL,\n created_at TEXT NOT NULL\n );\n CREATE INDEX IF NOT EXISTS idx_outbox_tenant ON outbox_events(tenant_id, session_id, seq);\n CREATE TABLE IF NOT EXISTS idempotency (\n k TEXT PRIMARY KEY,\n result TEXT NOT NULL,\n created_at INTEGER NOT NULL\n );\n CREATE TABLE IF NOT EXISTS pending_interactions (\n request_id TEXT PRIMARY KEY,\n session_id TEXT,\n turn_id TEXT,\n form TEXT NOT NULL,\n status TEXT NOT NULL,\n timeout_seconds INTEGER,\n created_at TEXT NOT NULL\n );\n CREATE TABLE IF NOT EXISTS audit_events (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n ts TEXT NOT NULL,\n category TEXT NOT NULL,\n level TEXT NOT NULL,\n event TEXT NOT NULL,\n tenant_id TEXT,\n session_id TEXT,\n agent_id TEXT,\n project_id TEXT,\n turn_id TEXT,\n msg TEXT,\n data TEXT\n );\n CREATE INDEX IF NOT EXISTS idx_audit_ts ON audit_events(ts);\n CREATE INDEX IF NOT EXISTS idx_audit_session ON audit_events(session_id, ts);\n CREATE TABLE IF NOT EXISTS env_vars (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n scope TEXT NOT NULL,\n project_id TEXT,\n agent_id TEXT,\n skill_name TEXT,\n name TEXT NOT NULL,\n value TEXT NOT NULL,\n secret INTEGER NOT NULL DEFAULT 1,\n updated_at TEXT NOT NULL\n );\n CREATE INDEX IF NOT EXISTS idx_env_scope ON env_vars(scope, project_id, agent_id, skill_name);\n CREATE UNIQUE INDEX IF NOT EXISTS idx_env_unique ON env_vars(scope, IFNULL(project_id,''), IFNULL(agent_id,''), IFNULL(skill_name,''), name);\n `);\n }\n\n // ---- projects ----\n upsertProject(r: { projectId: string; name: string; path: string; git: boolean; remote?: string; createdAt: string }): void {\n this.db\n .prepare(\n `INSERT INTO projects(project_id,name,path,git,remote,created_at)\n VALUES(?,?,?,?,?,?)\n ON CONFLICT(project_id) DO UPDATE SET name=excluded.name, path=excluded.path, git=excluded.git, remote=excluded.remote`,\n )\n .run(r.projectId, r.name, r.path, r.git ? 1 : 0, r.remote ?? null, r.createdAt);\n }\n deleteProject(projectId: string): void {\n this.db.prepare(\"DELETE FROM projects WHERE project_id=?\").run(projectId);\n this.db.prepare(\"DELETE FROM worktrees WHERE project_id=?\").run(projectId);\n }\n loadProjects(): Array<{ projectId: string; name: string; path: string; git: boolean; remote?: string; createdAt: string }> {\n return (this.db.prepare(\"SELECT * FROM projects\").all() as Record<string, unknown>[]).map((row) => ({\n projectId: row.project_id as string,\n name: row.name as string,\n path: row.path as string,\n git: (row.git as number) === 1,\n remote: (row.remote as string) ?? undefined,\n createdAt: row.created_at as string,\n }));\n }\n\n // ---- worktrees ----\n upsertWorktree(r: { worktreeId: string; projectId: string; path: string; branch: string; isPrimary: boolean; createdAt: string }): void {\n this.db\n .prepare(\n `INSERT INTO worktrees(worktree_id,project_id,path,branch,is_primary,created_at)\n VALUES(?,?,?,?,?,?) ON CONFLICT(worktree_id) DO NOTHING`,\n )\n .run(r.worktreeId, r.projectId, r.path, r.branch, r.isPrimary ? 1 : 0, r.createdAt);\n }\n deleteWorktree(worktreeId: string): void {\n this.db.prepare(\"DELETE FROM worktrees WHERE worktree_id=?\").run(worktreeId);\n }\n loadWorktrees(): Array<{ worktreeId: string; projectId: string; path: string; branch: string; isPrimary: boolean; createdAt: string }> {\n return (this.db.prepare(\"SELECT * FROM worktrees\").all() as Record<string, unknown>[]).map((row) => ({\n worktreeId: row.worktree_id as string,\n projectId: row.project_id as string,\n path: row.path as string,\n branch: row.branch as string,\n isPrimary: (row.is_primary as number) === 1,\n createdAt: row.created_at as string,\n }));\n }\n\n // ---- skills ----\n upsertSkill(r: { agent: string; name: string; scope: string; projectId?: string; version?: string; hash?: string; installedPath: string; installedAt: string }): void {\n this.db\n .prepare(\n `INSERT INTO skills(agent_id,name,scope,project_id,version,hash,installed_path,installed_at)\n VALUES(?,?,?,?,?,?,?,?)\n ON CONFLICT(agent_id,scope,name,project_id) DO UPDATE SET version=excluded.version, hash=excluded.hash, installed_path=excluded.installed_path, installed_at=excluded.installed_at`,\n )\n .run(r.agent, r.name, r.scope, r.projectId ?? null, r.version ?? null, r.hash ?? null, r.installedPath, r.installedAt);\n }\n deleteSkill(r: { agent: string; name: string; scope: string; projectId?: string }): void {\n this.db\n .prepare(\"DELETE FROM skills WHERE agent_id=? AND name=? AND scope=? AND IFNULL(project_id,'')=IFNULL(?,'')\")\n .run(r.agent, r.name, r.scope, r.projectId ?? null);\n }\n loadSkills(): Array<{ agent: string; name: string; scope: \"global\" | \"project\"; projectId?: string; version?: string; hash?: string; installedPath: string; installedAt: string }> {\n return (this.db.prepare(\"SELECT * FROM skills\").all() as Record<string, unknown>[]).map((row) => ({\n agent: row.agent_id as string,\n name: row.name as string,\n scope: row.scope as \"global\" | \"project\",\n projectId: (row.project_id as string) ?? undefined,\n version: (row.version as string) ?? undefined,\n hash: (row.hash as string) ?? undefined,\n installedPath: row.installed_path as string,\n installedAt: row.installed_at as string,\n }));\n }\n\n // ---- sessions(元数据,OpenClaw 原生可 resume)----\n upsertSession(r: { sessionId: string; tenantId: string; projectId?: string; worktreeId?: string; agent: string; model: string; status: string; verbosity: string; createdAt: string; lastActive?: string }): void {\n this.db\n .prepare(\n `INSERT INTO sessions(session_id,tenant_id,project_id,worktree_id,agent_id,model,status,verbosity,created_at,last_active)\n VALUES(?,?,?,?,?,?,?,?,?,?)\n ON CONFLICT(session_id) DO UPDATE SET model=excluded.model, status=excluded.status, last_active=excluded.last_active`,\n )\n .run(r.sessionId, r.tenantId, r.projectId ?? null, r.worktreeId ?? null, r.agent, r.model, r.status, r.verbosity, r.createdAt, r.lastActive ?? null);\n }\n loadSessions(): Array<Record<string, unknown>> {\n return this.db.prepare(\"SELECT * FROM sessions WHERE status != 'terminated'\").all() as Record<string, unknown>[];\n }\n\n // ---- outbox ----\n outboxAdd(tenantId: string, sessionId: string, seq: number, payload: string, createdAt: string): void {\n this.db.prepare(\"INSERT INTO outbox_events(tenant_id,session_id,seq,payload,created_at) VALUES(?,?,?,?,?)\").run(tenantId, sessionId, seq, payload, createdAt);\n }\n outboxAck(tenantId: string, sessionId: string | undefined, lastSeq: number): void {\n if (sessionId) this.db.prepare(\"DELETE FROM outbox_events WHERE tenant_id=? AND session_id=? AND seq<=?\").run(tenantId, sessionId, lastSeq);\n else this.db.prepare(\"DELETE FROM outbox_events WHERE tenant_id=? AND seq<=?\").run(tenantId, lastSeq);\n }\n outboxLoad(tenantId: string): Array<{ sessionId: string; seq: number; payload: string }> {\n return (this.db.prepare(\"SELECT session_id,seq,payload FROM outbox_events WHERE tenant_id=? ORDER BY seq\").all(tenantId) as Record<string, unknown>[]).map((r) => ({\n sessionId: r.session_id as string,\n seq: r.seq as number,\n payload: r.payload as string,\n }));\n }\n\n // ---- env vars(设备本地环境变量配置,默认脱敏返回)----\n envSet(r: { scope: string; projectId?: string; agent?: string; skillName?: string; name: string; value: string; secret?: boolean; updatedAt: string }): void {\n this.envDelete(r);\n // 落库前加密 value(at-rest)。\n const stored = this.secrets.encrypt(r.value);\n this.db.prepare(\n `INSERT INTO env_vars(scope,project_id,agent_id,skill_name,name,value,secret,updated_at)\n VALUES(?,?,?,?,?,?,?,?)`,\n ).run(r.scope, r.projectId ?? null, r.agent ?? null, r.skillName ?? null, r.name, stored, r.secret === false ? 0 : 1, r.updatedAt);\n }\n envDelete(r: { scope: string; projectId?: string; agent?: string; skillName?: string; name: string }): void {\n this.db.prepare(\"DELETE FROM env_vars WHERE scope=? AND IFNULL(project_id,'')=IFNULL(?,'') AND IFNULL(agent_id,'')=IFNULL(?,'') AND IFNULL(skill_name,'')=IFNULL(?,'') AND name=?\")\n .run(r.scope, r.projectId ?? null, r.agent ?? null, r.skillName ?? null, r.name);\n }\n envList(filter?: { scope?: string; projectId?: string; agent?: string; skillName?: string }): Array<{ scope: string; projectId?: string; agent?: string; skillName?: string; name: string; value: string; secret: boolean; updatedAt: string }> {\n const where: string[] = [];\n const params: unknown[] = [];\n if (filter?.scope) { where.push(\"scope=?\"); params.push(filter.scope); }\n if (filter?.projectId) { where.push(\"project_id=?\"); params.push(filter.projectId); }\n if (filter?.agent) { where.push(\"agent_id=?\"); params.push(filter.agent); }\n if (filter?.skillName) { where.push(\"skill_name=?\"); params.push(filter.skillName); }\n const sql = `SELECT * FROM env_vars ${where.length ? \"WHERE \" + where.join(\" AND \") : \"\"} ORDER BY scope, project_id, agent_id, skill_name, name`;\n return (this.db.prepare(sql).all(...(params as never[])) as Record<string, unknown>[]).map((row) => ({\n scope: row.scope as string,\n projectId: (row.project_id as string) ?? undefined,\n agent: (row.agent_id as string) ?? undefined,\n skillName: (row.skill_name as string) ?? undefined,\n name: row.name as string,\n value: this.secrets.decrypt(row.value as string),\n secret: (row.secret as number) === 1,\n updatedAt: row.updated_at as string,\n }));\n }\n\n close(): void {\n this.db.close();\n }\n\n // ---- audit 事件时间线(可观测回溯)----\n auditAdd(e: {\n ts: string; category: string; level: string; event: string;\n tenantId?: string; sessionId?: string; agentId?: string; projectId?: string; turnId?: string;\n msg?: string; data?: string;\n }): void {\n this.db\n .prepare(\n `INSERT INTO audit_events(ts,category,level,event,tenant_id,session_id,agent_id,project_id,turn_id,msg,data)\n VALUES(?,?,?,?,?,?,?,?,?,?,?)`,\n )\n .run(e.ts, e.category, e.level, e.event, e.tenantId ?? null, e.sessionId ?? null, e.agentId ?? null, e.projectId ?? null, e.turnId ?? null, e.msg ?? null, e.data ?? null);\n }\n\n /** 查 audit 时间线(最近 N 条,可按 session/category 过滤)。 */\n auditQuery(opts?: { sessionId?: string; category?: string; limit?: number }): Array<Record<string, unknown>> {\n const where: string[] = [];\n const params: unknown[] = [];\n if (opts?.sessionId) { where.push(\"session_id=?\"); params.push(opts.sessionId); }\n if (opts?.category) { where.push(\"category=?\"); params.push(opts.category); }\n const sql = `SELECT * FROM audit_events ${where.length ? \"WHERE \" + where.join(\" AND \") : \"\"} ORDER BY id DESC LIMIT ?`;\n params.push(opts?.limit ?? 200);\n return this.db.prepare(sql).all(...(params as never[])) as Record<string, unknown>[];\n }\n\n // ---- idempotency(跨重启去重)----\n idempotencyGet(key: string): string | undefined {\n const row = this.db.prepare(\"SELECT result FROM idempotency WHERE k=?\").get(key) as { result?: string } | undefined;\n return row?.result;\n }\n idempotencyPut(key: string, result: string): void {\n this.db.prepare(\"INSERT INTO idempotency(k,result,created_at) VALUES(?,?,?) ON CONFLICT(k) DO NOTHING\").run(key, result, Date.now());\n }\n}\n","import { createCipheriv, createDecipheriv, randomBytes } from \"node:crypto\";\nimport { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\n\n/**\n * 设备本地 secret 加密(env 变量 at-rest 加密)。\n *\n * - AES-256-GCM,每条 value 独立随机 IV。\n * - 设备密钥存独立文件(0600),与 sqlite 库分离,方便单独保护/轮换。\n * - 落库格式:`enc:v1:<base64(iv|tag|ciphertext)>`,带前缀便于识别与平滑迁移\n * (老的明文值没有前缀 → 读时原样返回,写时才升级为密文)。\n */\n\nconst PREFIX = \"enc:v1:\";\nconst IV_LEN = 12;\nconst TAG_LEN = 16;\nconst KEY_LEN = 32;\n\nexport class SecretBox {\n private key: Buffer;\n\n constructor(key: Buffer) {\n if (key.length !== KEY_LEN) throw new Error(`SecretBox key must be ${KEY_LEN} bytes`);\n this.key = key;\n }\n\n /**\n * 从密钥文件加载,缺失则生成(0600)。`:memory:`/缺省路径用进程内随机密钥\n * (测试/纯内存场景,不落盘也就不需要持久密钥)。\n */\n static fromKeyFile(keyPath: string | undefined): SecretBox {\n if (!keyPath || keyPath === \":memory:\") return new SecretBox(randomBytes(KEY_LEN));\n if (existsSync(keyPath)) {\n const raw = readFileSync(keyPath, \"utf8\").trim();\n const key = Buffer.from(raw, \"base64\");\n if (key.length === KEY_LEN) return new SecretBox(key);\n // 文件存在但内容异常:不静默覆盖(可能是误配),直接报错让人介入。\n throw new Error(`invalid device key at ${keyPath} (expected ${KEY_LEN}-byte base64)`);\n }\n const key = randomBytes(KEY_LEN);\n mkdirSync(dirname(keyPath), { recursive: true });\n writeFileSync(keyPath, key.toString(\"base64\"), { mode: 0o600 });\n try { chmodSync(keyPath, 0o600); } catch { /* best-effort on platforms without chmod */ }\n return new SecretBox(key);\n }\n\n /** 是否已是本方案的密文。 */\n static isEncrypted(value: string): boolean {\n return value.startsWith(PREFIX);\n }\n\n encrypt(plain: string): string {\n const iv = randomBytes(IV_LEN);\n const cipher = createCipheriv(\"aes-256-gcm\", this.key, iv);\n const ct = Buffer.concat([cipher.update(plain, \"utf8\"), cipher.final()]);\n const tag = cipher.getAuthTag();\n return PREFIX + Buffer.concat([iv, tag, ct]).toString(\"base64\");\n }\n\n /** 解密;非本方案前缀的值视为历史明文,原样返回(平滑迁移)。 */\n decrypt(value: string): string {\n if (!SecretBox.isEncrypted(value)) return value;\n const raw = Buffer.from(value.slice(PREFIX.length), \"base64\");\n const iv = raw.subarray(0, IV_LEN);\n const tag = raw.subarray(IV_LEN, IV_LEN + TAG_LEN);\n const ct = raw.subarray(IV_LEN + TAG_LEN);\n const decipher = createDecipheriv(\"aes-256-gcm\", this.key, iv);\n decipher.setAuthTag(tag);\n return Buffer.concat([decipher.update(ct), decipher.final()]).toString(\"utf8\");\n }\n}\n","import { mkdir, readFile, readdir, lstat, realpath, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, join, resolve, sep } from \"node:path\";\nimport { PhononError } from \"./rpc.js\";\n\nexport interface FileScopeResolver {\n resolveCwd(projectId: string, worktreeId?: string): string;\n}\n\ntype StatEntry = { path: string; type: \"file\" | \"directory\" | \"symlink\" | \"other\"; sizeBytes: number; modifiedAt: string };\n\nexport class FileManager {\n constructor(private resolver: FileScopeResolver) {}\n\n /**\n * Realpath of the deepest existing ancestor, with any non-existent suffix re-appended.\n * Lets us containment-check write/mkdir targets that don't exist yet, while still\n * resolving symlinks in the existing portion of the path.\n */\n private async realpathBoundary(abs: string): Promise<string> {\n const suffix: string[] = [];\n let cur = abs;\n for (;;) {\n try {\n const real = await realpath(cur);\n return suffix.length ? resolve(real, ...suffix) : real;\n } catch (e) {\n if ((e as NodeJS.ErrnoException)?.code !== \"ENOENT\") throw e;\n const parent = dirname(cur);\n if (parent === cur) return abs; // hit fs root, nothing left to resolve\n suffix.unshift(basename(cur));\n cur = parent;\n }\n }\n }\n\n /**\n * Resolve a project-relative path to an absolute path, enforcing that it stays\n * inside the project/worktree root — including via symlinks (defeats `evil -> /etc`).\n *\n * followFinal=true (read/write/mkdir/list-base): the final component is resolved too,\n * so a final symlink pointing outside is rejected (readFile/writeFile would follow it).\n * followFinal=false (stat): the final component is NOT resolved, so an in-project symlink\n * can be lstat'd and reported as \"symlink\" without being followed. Middle-of-path\n * symlinks are still resolved and rejected.\n */\n private async resolvePath(projectId: string, worktreeId: string | undefined, rel: string, followFinal = true): Promise<string> {\n if (rel.includes(\"\\0\") || rel.startsWith(\"/\") || rel === \"\") {\n throw new PhononError(\"errInvalidParams\", \"file path must be a non-empty relative path\");\n }\n // Normalize the root through realpath too, so both sides are comparable on\n // platforms where the workspace itself sits under a symlink (e.g. macOS /tmp).\n const root = await this.realpathBoundary(resolve(this.resolver.resolveCwd(projectId, worktreeId)));\n const abs = resolve(root, rel);\n // 1) lexical containment — fast reject of ../ escapes.\n if (abs !== root && !abs.startsWith(root + sep)) {\n throw new PhononError(\"errPolicyDenied\", `file path escapes project/worktree: ${rel}`);\n }\n // 2) realpath containment — defeats symlink escape (string prefix check alone is insufficient).\n // For stat we probe the parent dir so an in-project symlink entry can still be reported.\n const probe = !followFinal && abs !== root ? dirname(abs) : abs;\n const real = await this.realpathBoundary(probe);\n if (real !== root && !real.startsWith(root + sep)) {\n throw new PhononError(\"errPolicyDenied\", `file path escapes project/worktree via symlink: ${rel}`);\n }\n return abs;\n }\n\n async read(params: { projectId: string; worktreeId?: string; path: string; encoding?: \"utf8\" | \"base64\"; maxBytes?: number }) {\n const abs = await this.resolvePath(params.projectId, params.worktreeId, params.path);\n const buf = await readFile(abs);\n const max = params.maxBytes;\n const out = max && buf.length > max ? buf.subarray(0, max) : buf;\n const encoding = params.encoding ?? \"utf8\";\n return {\n path: params.path,\n encoding,\n data: encoding === \"base64\" ? out.toString(\"base64\") : out.toString(\"utf8\"),\n sizeBytes: buf.length,\n truncated: !!max && buf.length > max,\n };\n }\n\n async write(params: { projectId: string; worktreeId?: string; path: string; encoding?: \"utf8\" | \"base64\"; data: string; overwrite?: boolean; createDirs?: boolean }) {\n const abs = await this.resolvePath(params.projectId, params.worktreeId, params.path);\n if (params.createDirs ?? true) await mkdir(dirname(abs), { recursive: true });\n const content = params.encoding === \"base64\" ? Buffer.from(params.data, \"base64\") : Buffer.from(params.data, \"utf8\");\n await writeFile(abs, content, { flag: params.overwrite === false ? \"wx\" : \"w\" });\n return { path: params.path, sizeBytes: content.length, written: true as const };\n }\n\n async mkdir(params: { projectId: string; worktreeId?: string; path: string; recursive?: boolean }) {\n const abs = await this.resolvePath(params.projectId, params.worktreeId, params.path);\n await mkdir(abs, { recursive: params.recursive ?? true });\n return { path: params.path, created: true as const };\n }\n\n async stat(params: { projectId: string; worktreeId?: string; path: string }) {\n const abs = await this.resolvePath(params.projectId, params.worktreeId, params.path, false);\n return { stat: await this.lstatOne(abs, params.path) };\n }\n\n async list(params: { projectId: string; worktreeId?: string; path?: string; recursive?: boolean; limit?: number }) {\n const baseRel = params.path ?? \".\";\n const limit = params.limit ?? 500;\n const baseAbs = await this.resolvePath(params.projectId, params.worktreeId, baseRel);\n const entries: StatEntry[] = [];\n const walk = async (absDir: string, relDir: string): Promise<void> => {\n if (entries.length >= limit) return;\n const names = await readdir(absDir);\n for (const name of names) {\n if (entries.length >= limit) return;\n const childRel = relDir === \".\" ? name : `${relDir}/${name}`;\n const childAbs = join(absDir, name);\n const s = await this.lstatOne(childAbs, childRel);\n entries.push(s);\n // Only descend into REAL directories. lstat reports symlinks as \"symlink\",\n // so symlinked dirs are never followed (also avoids symlink-cycle loops).\n if (params.recursive && s.type === \"directory\") await walk(childAbs, childRel);\n }\n };\n await walk(baseAbs, baseRel);\n return { path: baseRel, entries, truncated: entries.length >= limit };\n }\n\n private async lstatOne(abs: string, rel: string): Promise<StatEntry> {\n const s = await lstat(abs);\n const type = s.isSymbolicLink() ? \"symlink\" : s.isFile() ? \"file\" : s.isDirectory() ? \"directory\" : \"other\";\n return { path: rel, type, sizeBytes: s.size, modifiedAt: s.mtime.toISOString() };\n }\n}\n","import { cpus, freemem, loadavg, totalmem } from \"node:os\";\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst execFileAsync = promisify(execFile);\n\n/** 设备资源监控:debug 用,不做资源调度。 */\nexport async function collectDeviceResources(path = process.cwd()) {\n const total = totalmem();\n const free = freemem();\n const used = Math.max(0, total - free);\n const mem = process.memoryUsage();\n const disk = await diskUsage(path).catch(() => undefined);\n const gpu = await gpuInfo().catch(() => undefined);\n return {\n at: new Date().toISOString(),\n cpu: { loadavg: loadavg(), cores: cpus().length },\n memory: { totalBytes: total, freeBytes: free, usedBytes: used, usagePercent: total ? (used / total) * 100 : undefined },\n disk,\n gpu,\n process: { pid: process.pid, uptimeSeconds: process.uptime(), rssBytes: mem.rss, heapUsedBytes: mem.heapUsed, heapTotalBytes: mem.heapTotal },\n };\n}\n\nasync function diskUsage(path: string) {\n const { stdout } = await execFileAsync(\"df\", [\"-Pk\", path], { timeout: 3000 });\n const lines = stdout.trim().split(/\\n/);\n const row = lines[lines.length - 1]?.trim().split(/\\s+/);\n if (!row || row.length < 6) return { path };\n const totalBytes = Number(row[1]) * 1024;\n const usedBytes = Number(row[2]) * 1024;\n const freeBytes = Number(row[3]) * 1024;\n return { path, totalBytes, freeBytes, usedBytes, usagePercent: totalBytes ? (usedBytes / totalBytes) * 100 : undefined };\n}\n\nasync function gpuInfo() {\n const { stdout } = await execFileAsync(\"nvidia-smi\", [\"--query-gpu=name,memory.total,memory.used,utilization.gpu\", \"--format=csv,noheader,nounits\"], { timeout: 3000 });\n return stdout.trim().split(/\\n/).filter(Boolean).map((line) => {\n const [name, totalMb, usedMb, util] = line.split(\",\").map((s) => s.trim());\n return {\n name,\n memoryTotalBytes: Number(totalMb) * 1024 * 1024,\n memoryUsedBytes: Number(usedMb) * 1024 * 1024,\n utilizationPercent: Number(util),\n };\n });\n}\n","import { arch, hostname, platform, release, type } from \"node:os\";\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst execFileAsync = promisify(execFile);\n\n/**\n * 相对静态的设备信息,用于服务端做调度决策。\n * 例如:iOS/macOS 开发任务优先派给 darwin 设备,Windows 桌面开发派给 win32 设备。\n */\nexport async function collectDeviceInfo() {\n const base = {\n at: new Date().toISOString(),\n hostname: hostname(),\n os: {\n platform: platform(),\n type: type(),\n release: release(),\n arch: arch(),\n },\n runtime: {\n node: process.version,\n },\n capabilities: await inferCapabilities(),\n };\n return base;\n}\n\nasync function inferCapabilities(): Promise<string[]> {\n const caps = new Set<string>();\n const p = platform();\n if (p === \"darwin\") {\n caps.add(\"macos\");\n caps.add(\"ios-development\");\n }\n if (p === \"win32\") {\n caps.add(\"windows\");\n caps.add(\"windows-desktop-development\");\n }\n if (p === \"linux\") caps.add(\"linux\");\n if (await commandExists(\"git\")) caps.add(\"git\");\n if (await commandExists(\"node\")) caps.add(\"node\");\n if (await commandExists(\"python3\")) caps.add(\"python\");\n if (await commandExists(\"xcodebuild\")) caps.add(\"xcode\");\n if (await commandExists(\"swift\")) caps.add(\"swift\");\n if (await commandExists(\"powershell\") || await commandExists(\"pwsh\")) caps.add(\"powershell\");\n if (await commandExists(\"nvidia-smi\")) caps.add(\"nvidia-gpu\");\n return [...caps].sort();\n}\n\nasync function commandExists(cmd: string): Promise<boolean> {\n try {\n const which = platform() === \"win32\" ? \"where\" : \"which\";\n await execFileAsync(which, [cmd], { timeout: 1500 });\n return true;\n } catch {\n return false;\n }\n}\n","import { PhononError } from \"./rpc.js\";\nimport type { PhononStore } from \"./store.js\";\n\ntype Scope = \"global\" | \"project\" | \"skill\";\n\nexport interface EnvTarget {\n scope: Scope;\n projectId?: string;\n agent?: string;\n skillName?: string;\n}\n\nfunction redact(value: string): string {\n if (value.length <= 4) return \"****\";\n return `****${value.slice(-4)}`;\n}\n\nfunction validateName(name: string): void {\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)) throw new PhononError(\"errInvalidParams\", `invalid env var name: ${name}`);\n}\n\nexport class EnvManager {\n constructor(private store: PhononStore, private opts: { allowReveal: () => boolean }) {}\n\n set(params: EnvTarget & { name: string; value: string; secret?: boolean }) {\n validateName(params.name);\n const updatedAt = new Date().toISOString();\n this.store.envSet({ ...params, updatedAt });\n return { variable: this.describe({ ...params, updatedAt, secret: params.secret !== false }, false) };\n }\n\n delete(params: EnvTarget & { name: string }) {\n validateName(params.name);\n this.store.envDelete(params);\n return { deleted: true as const, name: params.name };\n }\n\n list(filter: Partial<EnvTarget> & { reveal?: boolean }) {\n const reveal = !!filter.reveal;\n if (reveal && !this.opts.allowReveal()) throw new PhononError(\"errPolicyDenied\", \"env reveal disabled by policy\");\n const rows = this.store.envList(filter);\n return { variables: rows.map((r) => this.describe(r, reveal)) };\n }\n\n /** 返回本次执行应该注入的环境变量:global < project < skill。 */\n resolveForExecution(params: { projectId?: string; agent?: string; skills?: string[] }): Record<string, string> {\n const env: Record<string, string> = {};\n for (const r of this.store.envList({ scope: \"global\" })) env[r.name] = r.value;\n if (params.projectId) for (const r of this.store.envList({ scope: \"project\", projectId: params.projectId })) env[r.name] = r.value;\n if (params.projectId && params.agent && params.skills) {\n for (const skillName of params.skills) {\n for (const r of this.store.envList({ scope: \"skill\", projectId: params.projectId, agent: params.agent, skillName })) env[r.name] = r.value;\n }\n }\n return env;\n }\n\n private describe(r: { scope: string; projectId?: string; agent?: string; skillName?: string; name: string; value: string; secret?: boolean; updatedAt?: string }, reveal: boolean) {\n return {\n scope: r.scope,\n projectId: r.projectId,\n agent: r.agent,\n skillName: r.skillName,\n name: r.name,\n value: reveal ? r.value : redact(r.value),\n redacted: !reveal,\n updatedAt: r.updatedAt,\n };\n }\n}\n","import { spawn } from \"node:child_process\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { dropToolIOFromJsonlFiles } from \"../custom-compress.js\";\nimport type {\n AgentAdapter,\n AdapterSession,\n CreateSessionParams,\n SendOptions,\n} from \"../adapter.js\";\nimport type { AgentCapabilities, AgentDescriptor, StreamEvent, ContextItem } from \"@agent-phonon/protocol\";\n\n/**\n * OpenClaw adapter(design D10,第一个 adapter)。\n *\n * 驱动 `openclaw agent --local --json --session-key <key> --message <text> [--model <id>]`。\n * 实测(2026-06-20):\n * - --session-key 给持续会话,同 key 跨调用记忆上下文 → nativeSession=true\n * - --json 输出 { payloads:[{text}], meta:{ finalAssistantVisibleText, ... } }\n * - --model 覆盖模型 → modelSwitch=true(下一轮生效)\n * OpenClaw adapter 极薄(design D8):直接调 CLI,把最终文本封成 result 事件。\n */\n\nconst OPENCLAW_CAPABILITIES: AgentCapabilities = {\n nativeSession: true, // --session-key resume\n nativeCompression: true, // OpenClaw 有 /compact\n contextInjection: true, // 可在 message 前注入\n proactiveOutput: true, // OpenClaw 有 cron/心跳,会自发输出\n modelSwitch: true, // --model 覆盖\n interrupt: false, // CLI 一次性调用,靠 core 兜底 kill 子进程\n injectMidTurn: false,\n skillManagement: true, // OpenClaw 有 skills 目录\n hooks: [\"pre_tool\", \"pre_command\"],\n streaming: false, // --json 是一次性返回,非增量流(v0 用 final 事件)\n limits: { maxConcurrentSessions: 4, maxContextTokens: 1048576 },\n};\n\ninterface OpenClawJson {\n payloads?: Array<{ text?: string }>;\n meta?: {\n finalAssistantVisibleText?: string;\n aborted?: boolean;\n stopReason?: string;\n };\n}\n\nclass OpenClawSession implements AdapterSession {\n readonly sessionId: string;\n model: string;\n private sessionKey: string;\n private cwd: string;\n private openclawAgent: string;\n private current?: ReturnType<typeof spawn>;\n /** 暂存的注入上下文(下次 send 拼进 input,不单独跑一轮,修 P0#13)。 */\n private pendingInject: string[] = [];\n\n constructor(sessionId: string, model: string, cwd: string, openclawAgent = \"main\") {\n this.sessionId = sessionId;\n this.model = model;\n this.cwd = cwd;\n this.openclawAgent = openclawAgent;\n // 用 phonon sessionId 派生稳定的 OpenClaw session-key\n this.sessionKey = `agent:${openclawAgent}:phonon-${sessionId}`;\n }\n\n async send(input: string, opts: SendOptions): Promise<void> {\n const { turnId, emit } = opts;\n\n let message = input;\n // 暂存的注入先拼进本轮(避免单独 turn,P0#13)\n if (this.pendingInject.length > 0) {\n message = this.pendingInject.join(\"\\n\") + \"\\n\\n\" + message;\n this.pendingInject = [];\n }\n // 若指定了 skill,在 message 前注入强制加载指令(D26 方式2)\n if (opts.skills && opts.skills.length > 0) {\n message = `[必须本轮加载并使用这些 skill: ${opts.skills.join(\", \")}]\\n\\n${message}`;\n }\n\n const args = [\n \"agent\",\n \"--local\",\n \"--agent\",\n this.openclawAgent,\n \"--json\",\n \"--session-key\",\n this.sessionKey,\n \"--message\",\n message,\n \"--model\",\n this.model,\n ];\n\n const stdout = await this.run(args, opts.signal, opts.environment);\n if (stdout === null) {\n // 被 interrupt\n emit({\n type: \"result\",\n sessionId: this.sessionId,\n turnId,\n seq: 0,\n at: new Date().toISOString(),\n text: \"\",\n status: \"interrupted\",\n final: true,\n } as StreamEvent);\n return;\n }\n\n let parsed: OpenClawJson | undefined;\n try {\n parsed = JSON.parse(stdout) as OpenClawJson;\n } catch {\n // 解析失败也要给终态\n }\n const text =\n parsed?.meta?.finalAssistantVisibleText ?? parsed?.payloads?.[0]?.text ?? stdout.slice(0, 2000);\n\n emit({\n type: \"result\",\n sessionId: this.sessionId,\n turnId,\n seq: 0,\n at: new Date().toISOString(),\n text,\n status: parsed?.meta?.aborted ? \"aborted\" : \"completed\",\n final: true,\n } as StreamEvent);\n }\n\n async interrupt(): Promise<void> {\n if (this.current) {\n this.current.kill(\"SIGTERM\");\n this.current = undefined;\n }\n }\n\n async switchModel(model: string): Promise<{ warnings?: string[] }> {\n this.model = model;\n return {};\n }\n\n async inject(context: ContextItem[]): Promise<void> {\n // OpenClaw spawn 版没有 transcript append API:暂存到下次 send 拼进 input,\n // 不单独跑一轮(修 P0#13:之前会产生额外 turn)。\n if (context.length === 0) return;\n for (const c of context) this.pendingInject.push(`[${c.role}] ${c.content}`);\n }\n\n async compressCustom(strategy = \"dropToolIO\", options?: { keepRecentToolCalls?: number }): Promise<{ summary?: string; filesChanged?: number; recordsChanged?: number; blocksRemoved?: number; bytesBefore?: number; bytesAfter?: number; backups?: string[] }> {\n if (strategy !== \"dropToolIO\") throw new Error(`unsupported custom compression strategy: ${strategy}`);\n const file = this.resolveSessionFile();\n if (!file) throw new Error(`OpenClaw session file not found for ${this.sessionKey}`);\n const r = await dropToolIOFromJsonlFiles([file], options);\n return { summary: `dropToolIO removed ${r.blocksRemoved} tool blocks from ${r.filesChanged} files`, ...r };\n }\n\n async compressNative(): Promise<{ summary?: string }> {\n await this.run([\n \"agent\", \"--local\", \"--agent\", this.openclawAgent, \"--json\",\n \"--session-key\", this.sessionKey,\n \"--message\", \"/compact\",\n \"--model\", this.model,\n ]);\n return { summary: \"compacted via OpenClaw /compact\" };\n }\n\n async terminate(): Promise<void> {\n await this.interrupt();\n // OpenClaw session 落盘可保留;phonon 侧标记 terminated 即可。\n }\n\n private resolveSessionFile(): string | undefined {\n const sessionsJson = join(homedir(), \".openclaw\", \"agents\", this.openclawAgent, \"sessions\", \"sessions.json\");\n try {\n if (existsSync(sessionsJson)) {\n const sessions = JSON.parse(readFileSync(sessionsJson, \"utf8\")) as Record<string, { sessionId?: string }>;\n const id = sessions[this.sessionKey]?.sessionId;\n if (id) {\n const p = join(homedir(), \".openclaw\", \"agents\", this.openclawAgent, \"sessions\", `${id}.jsonl`);\n if (existsSync(p)) return p;\n }\n }\n } catch {\n // fall through\n }\n return undefined;\n }\n\n private run(args: string[], signal?: AbortSignal, environment?: Record<string, string>): Promise<string | null> {\n return new Promise((resolve, reject) => {\n const child = spawn(\"openclaw\", args, { cwd: this.cwd, env: { ...process.env, ...(environment ?? {}) } as NodeJS.ProcessEnv });\n this.current = child;\n let out = \"\";\n let err = \"\";\n let killed = false;\n child.stdout.on(\"data\", (d) => (out += d.toString()));\n child.stderr.on(\"data\", (d) => (err += d.toString()));\n const onAbort = () => {\n killed = true;\n child.kill(\"SIGTERM\");\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n child.on(\"error\", reject);\n child.on(\"close\", (code) => {\n signal?.removeEventListener(\"abort\", onAbort);\n this.current = undefined;\n if (killed) return resolve(null);\n if (code === 0) resolve(out);\n else reject(new Error(`openclaw exited ${code}: ${err.slice(0, 500)}`));\n });\n });\n }\n}\n\nexport class OpenClawAdapter implements AgentAdapter {\n readonly name = \"openclaw\";\n readonly capabilities = OPENCLAW_CAPABILITIES;\n /** 默认驱动哪个 OpenClaw agent(可被 session agentConfig.openclawAgent 覆盖)。 */\n private defaultAgent: string;\n\n constructor(opts: { defaultAgent?: string } = {}) {\n this.defaultAgent = opts.defaultAgent ?? \"main\";\n }\n\n async discover(): Promise<AgentDescriptor> {\n return (await this.discoverAgents())[0]!;\n }\n\n async discoverAgents(): Promise<AgentDescriptor[]> {\n // 探测 openclaw 是否可用 + 版本\n const version = await this.probeVersion();\n const available = version !== null;\n if (!available) {\n return [{\n agentId: \"openclaw\" as AgentDescriptor[\"agentId\"],\n displayName: \"OpenClaw\",\n adapter: \"openclaw\",\n available: false,\n unavailableReason: \"openclaw CLI not found\",\n models: [],\n capabilities: OPENCLAW_CAPABILITIES,\n scannedAt: new Date().toISOString(),\n }];\n }\n // spawn 版不枚举多 agent(Gateway 版才枚举):只报 defaultAgent\n return [{\n agentId: `openclaw:${this.defaultAgent}` as AgentDescriptor[\"agentId\"],\n displayName: `OpenClaw / ${this.defaultAgent}`,\n adapter: \"openclaw\",\n available: true,\n ...(version ? { version } : {}),\n models: [\n { id: \"github-copilot/claude-opus-4.8\", displayName: \"Claude Opus 4.8\", available: true },\n { id: \"github-copilot/gpt-5.5\", displayName: \"GPT-5.5\", available: true },\n ],\n capabilities: OPENCLAW_CAPABILITIES,\n scannedAt: new Date().toISOString(),\n }];\n }\n\n async createSession(params: CreateSessionParams): Promise<AdapterSession> {\n const openclawAgent =\n (params.agentConfig?.openclawAgent as string) ??\n (params.agentId?.includes(\":\") ? params.agentId.split(\":\")[1]! : this.defaultAgent);\n return new OpenClawSession(params.sessionId, params.model, params.cwd, openclawAgent);\n }\n\n private probeVersion(): Promise<string | null> {\n return new Promise((resolve) => {\n const child = spawn(\"openclaw\", [\"--version\"]);\n let out = \"\";\n child.stdout.on(\"data\", (d) => (out += d.toString()));\n child.on(\"error\", () => resolve(null));\n child.on(\"close\", (code) => resolve(code === 0 ? out.trim() : null));\n });\n }\n}\n","import { copyFile, rename, readFile, writeFile } from \"node:fs/promises\";\n\nexport interface DropToolIOResult {\n filesChanged: number;\n recordsChanged: number;\n blocksRemoved: number;\n bytesBefore: number;\n bytesAfter: number;\n backups: string[];\n}\n\nexport interface DropToolIOOptions {\n /** 保留最近 N 个 tool call 及其对应 result/中间块;默认 3。 */\n keepRecentToolCalls?: number;\n /**\n * 文件级算好的「保留集」(按对象引用)。\n * 用引用集而非 id,能正确保留**没有 id 的最近 tool 块**(item 3 修复)。\n */\n keepToolBlocks?: Set<unknown>;\n /** 兼容旧路径:按 id 保留(仍支持,但 keepToolBlocks 优先)。 */\n keepToolCallIds?: Set<string>;\n}\n\nexport function dropToolIOFromValue(value: unknown, options: DropToolIOOptions = {}): { value: unknown; changed: boolean; removed: number } {\n if (Array.isArray(value)) {\n let changed = false;\n let removed = 0;\n const out: unknown[] = [];\n for (const item of value) {\n if (isToolBlock(item) && !shouldKeepToolBlock(item, options)) {\n changed = true;\n removed++;\n continue;\n }\n const r = dropToolIOFromValue(item, options);\n changed ||= r.changed;\n removed += r.removed;\n out.push(r.value);\n }\n return { value: out, changed, removed };\n }\n if (value && typeof value === \"object\") {\n if (isToolBlock(value) && !shouldKeepToolBlock(value, options)) return { value: undefined, changed: true, removed: 1 };\n let changed = false;\n let removed = 0;\n const out: Record<string, unknown> = { ...(value as Record<string, unknown>) };\n for (const [k, v] of Object.entries(out)) {\n if (isToolBlock(v) && !shouldKeepToolBlock(v, options)) {\n delete out[k];\n changed = true;\n removed++;\n continue;\n }\n const r = dropToolIOFromValue(v, options);\n changed ||= r.changed;\n removed += r.removed;\n out[k] = r.value;\n }\n return { value: out, changed, removed };\n }\n return { value, changed: false, removed: 0 };\n}\n\nfunction shouldKeepToolBlock(value: unknown, options: DropToolIOOptions): boolean {\n if (options.keepToolBlocks?.has(value)) return true;\n const id = toolBlockId(value);\n return !!id && !!options.keepToolCallIds?.has(id);\n}\n\nfunction toolBlockId(value: unknown): string | undefined {\n if (!value || typeof value !== \"object\") return undefined;\n const o = value as Record<string, unknown>;\n const id = o.id ?? o.toolCallId ?? o.tool_call_id ?? o.tool_use_id ?? o.call_id;\n return typeof id === \"string\" && id.length > 0 ? id : undefined;\n}\n\nfunction isToolCall(value: unknown): boolean {\n if (!value || typeof value !== \"object\") return false;\n const t = (value as Record<string, unknown>).type;\n return t === \"tool_use\" || t === \"tool_call\" || t === \"function_call\";\n}\n\n/** 按文档顺序收集所有 tool 块的对象引用(块是原子单位,命中即不再深入)。 */\nfunction collectToolBlocks(value: unknown, out: unknown[]): void {\n if (isToolBlock(value)) { out.push(value); return; }\n if (Array.isArray(value)) { for (const item of value) collectToolBlocks(item, out); return; }\n if (value && typeof value === \"object\") { for (const v of Object.values(value)) collectToolBlocks(v, out); }\n}\n\n/**\n * 文件级计算「保留集」:保留最近 keepRecent 个 tool **call** 起、直到末尾的所有 tool 块\n * (含中间的 result、以及没有 id 的块)。基于位置而非 id —— 这样最近但无 id 的块也能保留。\n */\nexport function computeKeepToolBlocks(records: unknown[], keepRecent: number): Set<unknown> {\n if (keepRecent <= 0) return new Set();\n const blocks: unknown[] = [];\n for (const r of records) collectToolBlocks(r, blocks);\n if (blocks.length === 0) return new Set();\n const callIdx: number[] = [];\n blocks.forEach((b, i) => { if (isToolCall(b)) callIdx.push(i); });\n if (callIdx.length === 0) {\n // 没有明确的 call 块:退化为保留末尾 keepRecent 个任意 tool 块\n return new Set(blocks.slice(Math.max(0, blocks.length - keepRecent)));\n }\n const cutoff = callIdx[Math.max(0, callIdx.length - keepRecent)]!;\n return new Set(blocks.slice(cutoff));\n}\n\nfunction isToolBlock(value: unknown): boolean {\n if (!value || typeof value !== \"object\") return false;\n const o = value as Record<string, unknown>;\n const type = typeof o.type === \"string\" ? o.type : \"\";\n // Anthropic / Claude Code / OpenClaw content blocks.\n if (type === \"tool_use\" || type === \"tool_result\") return true;\n // Phonon/OpenClaw trajectory style events; keep ordinary text/message records.\n if (type === \"tool_call\" || type === \"tool_result_delta\") return true;\n // Codex response_item / OpenAI Responses style.\n if (type === \"function_call\" || type === \"function_call_output\" || type === \"custom_tool_call\" || type === \"custom_tool_call_output\" || type === \"local_shell_call\") return true;\n const role = typeof o.role === \"string\" ? o.role : \"\";\n // Some providers encode tool-return messages by role/name instead of content block type.\n if (role === \"tool\") return true;\n return false;\n}\n\nexport async function dropToolIOFromJsonlFiles(files: string[], options: DropToolIOOptions = {}): Promise<DropToolIOResult> {\n const result: DropToolIOResult = { filesChanged: 0, recordsChanged: 0, blocksRemoved: 0, bytesBefore: 0, bytesAfter: 0, backups: [] };\n const stamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const keepRecent = options.keepRecentToolCalls ?? 3;\n for (const file of files) {\n const before = await readFile(file, \"utf8\");\n result.bytesBefore += Buffer.byteLength(before);\n const lines = before.split(/\\n/);\n const parsed: unknown[] = [];\n for (const line of lines) {\n if (!line.trim()) { parsed.push(undefined); continue; }\n try {\n parsed.push(JSON.parse(line) as unknown);\n } catch {\n parsed.push(undefined);\n }\n }\n // 文件级保留集(按引用,覆盖最近 keepRecent 个 call 起的所有 tool 块)。\n const keepToolBlocks = computeKeepToolBlocks(parsed, keepRecent);\n let fileChanged = false;\n const out: string[] = [];\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!;\n if (!line.trim()) {\n out.push(line);\n continue;\n }\n const obj = parsed[i];\n if (obj === undefined) {\n out.push(line); // 不可解析行原样保留\n continue;\n }\n const r = dropToolIOFromValue(obj, { ...options, keepToolBlocks });\n if (r.changed) {\n fileChanged = true;\n result.recordsChanged++;\n result.blocksRemoved += r.removed;\n }\n out.push(JSON.stringify(r.value));\n }\n const after = out.join(\"\\n\");\n result.bytesAfter += Buffer.byteLength(after);\n if (fileChanged) {\n const backup = `${file}.bak-${stamp}`;\n await copyFile(file, backup);\n await writeFile(`${file}.tmp-${stamp}`, after);\n await rename(`${file}.tmp-${stamp}`, file);\n result.filesChanged++;\n result.backups.push(backup);\n }\n }\n return result;\n}\n","import { WebSocket } from \"ws\";\nimport { randomUUID } from \"node:crypto\";\n\n/**\n * OpenClaw Gateway WebSocket 客户端(传输层)。\n *\n * 借鉴 LMA src/openclaw-client.ts 的传输层(握手 + RPC + 事件路由),\n * 不抄其飞书业务逻辑。协议帧:{type:\"req\"|\"res\"|\"event\", id, method, params/payload}。\n *\n * 握手:连上 → 收 connect.challenge(event) → 发 connect(req, operator scopes + token) → hello-ok。\n */\n\nconst GATEWAY_PROTOCOL_MIN = 1;\nconst GATEWAY_PROTOCOL_MAX = 10;\n\nexport interface GatewayConfig {\n /** ws 或 http URL(http 会自动转 ws)。 */\n baseUrl: string;\n token: string;\n}\n\ninterface Pending {\n resolve: (v: unknown) => void;\n reject: (e: unknown) => void;\n timer: NodeJS.Timeout;\n}\n\n/** Gateway 事件回调:method=事件名(agent/chat/...),payload=事件体。 */\nexport type GatewayEventHandler = (event: string, payload: Record<string, unknown>) => void;\n\nexport class GatewayClient {\n private ws: WebSocket | null = null;\n private connected = false;\n private config: GatewayConfig;\n private pending = new Map<string, Pending>();\n private eventHandlers = new Set<GatewayEventHandler>();\n private connectPromise: Promise<void> | null = null;\n\n constructor(config: GatewayConfig) {\n this.config = config;\n }\n\n onEvent(handler: GatewayEventHandler): void {\n this.eventHandlers.add(handler);\n }\n\n isConnected(): boolean {\n return this.connected;\n }\n\n connect(): Promise<void> {\n if (this.connectPromise) return this.connectPromise;\n this.connectPromise = this.doConnect();\n return this.connectPromise;\n }\n\n private doConnect(): Promise<void> {\n return new Promise((resolve, reject) => {\n const wsUrl = this.config.baseUrl.replace(/^http/, \"ws\");\n const ws = new WebSocket(wsUrl);\n this.ws = ws;\n let handshakeDone = false;\n\n ws.on(\"message\", (raw: Buffer) => {\n let frame: Record<string, unknown>;\n try {\n frame = JSON.parse(raw.toString());\n } catch {\n return;\n }\n\n if (!handshakeDone) {\n if (frame.type === \"event\" && frame.event === \"connect.challenge\") {\n ws.send(\n JSON.stringify({\n type: \"req\",\n id: \"connect-1\",\n method: \"connect\",\n params: {\n minProtocol: GATEWAY_PROTOCOL_MIN,\n maxProtocol: GATEWAY_PROTOCOL_MAX,\n client: { id: \"gateway-client\", version: \"0.0.1\", platform: \"linux\", mode: \"backend\" },\n role: \"operator\",\n scopes: [\"operator.read\", \"operator.write\", \"operator.admin\"],\n auth: { token: this.config.token },\n userAgent: \"agent-phonon/0.0.1\",\n },\n }),\n );\n } else if (frame.type === \"res\" && frame.ok && (frame.payload as { type?: string })?.type === \"hello-ok\") {\n handshakeDone = true;\n this.connected = true;\n resolve();\n } else if (frame.type === \"res\" && !frame.ok) {\n reject(new Error(`handshake failed: ${JSON.stringify(frame.error)}`));\n }\n return;\n }\n\n // 响应\n if (frame.type === \"res\" && frame.id) {\n const p = this.pending.get(frame.id as string);\n if (p) {\n this.pending.delete(frame.id as string);\n clearTimeout(p.timer);\n if (frame.ok) p.resolve(frame.payload);\n else p.reject(new Error(`RPC error: ${JSON.stringify(frame.error)}`));\n }\n return;\n }\n\n // 事件 → 分发给所有 handler\n if (frame.type === \"event\" && typeof frame.event === \"string\") {\n for (const h of this.eventHandlers) {\n try {\n h(frame.event, (frame.payload as Record<string, unknown>) ?? {});\n } catch {\n /* ignore handler error */\n }\n }\n }\n });\n\n ws.on(\"error\", (err) => {\n if (!handshakeDone) reject(err);\n });\n ws.on(\"close\", () => {\n this.connected = false;\n this.connectPromise = null;\n for (const [, p] of this.pending) {\n clearTimeout(p.timer);\n p.reject(new Error(\"gateway connection closed\"));\n }\n this.pending.clear();\n });\n });\n }\n\n /** 发一个 Gateway RPC。 */\n async rpc(method: string, params: unknown, timeoutMs = 120000): Promise<Record<string, unknown>> {\n if (!this.connected) await this.connect();\n return new Promise((resolve, reject) => {\n const id = randomUUID();\n const timer = setTimeout(() => {\n this.pending.delete(id);\n reject(new Error(`RPC timeout: ${method}`));\n }, timeoutMs);\n this.pending.set(id, { resolve: resolve as (v: unknown) => void, reject, timer });\n this.ws!.send(JSON.stringify({ type: \"req\", id, method, params }));\n });\n }\n\n close(): void {\n this.ws?.close();\n this.ws = null;\n this.connected = false;\n }\n}\n","import type {\n AgentAdapter,\n AdapterSession,\n CreateSessionParams,\n SendOptions,\n} from \"../adapter.js\";\nimport type { AgentCapabilities, AgentDescriptor, StreamEvent, ContextItem, ModelInfo } from \"@agent-phonon/protocol\";\nimport { GatewayClient, type GatewayConfig } from \"../gateway-client.js\";\nimport { randomUUID } from \"node:crypto\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { dropToolIOFromJsonlFiles } from \"../custom-compress.js\";\n\n/**\n * OpenClaw adapter(Gateway WS 版,design D10)。\n *\n * 连 OpenClaw Gateway 的 WebSocket(参考 LMA 传输层),拿到完整能力:\n * - chat 事件 state=delta(增量流)→ verbosity=messages/trace 的流式\n * - chat 事件 state=final → turn 终态\n * - sessions.compact(原生压缩)、chat.abort(中断)、chat.inject(注入)\n * - sessions.messages.subscribe(订阅自发输出,cron/心跳冒泡)→ proactiveOutput\n *\n * 实测(2026-06-20,直连本机 Gateway 18789):\n * - 握手 client.id 必须是 \"gateway-client\"\n * - chat.send 必须带 idempotencyKey\n * - 多 agent 共享 Gateway,事件按 sessionKey 区分,不串台\n */\n\nconst CAPABILITIES: AgentCapabilities = {\n nativeSession: true,\n nativeCompression: true, // sessions.compact\n contextInjection: true, // chat.inject\n proactiveOutput: true, // sessions.messages.subscribe\n modelSwitch: true, // sessions.patch model\n interrupt: true, // chat.abort(真中断,非 kill 进程)\n injectMidTurn: false,\n skillManagement: true,\n hooks: [\"pre_tool\", \"pre_command\"],\n streaming: true, // chat delta\n limits: { maxConcurrentSessions: 4, maxContextTokens: 1048576 },\n};\n\nclass GatewaySession implements AdapterSession {\n readonly sessionId: string;\n model: string;\n private gw: GatewayClient;\n private sessionKey: string;\n private openclawAgent: string;\n /** 当前活动 turn 的 emit/runId 跟踪。 */\n private activeTurn?: { turnId: string; emit: (e: StreamEvent) => void; verbosity: string; done: () => void; acc: string };\n /** 自发输出水槽(无 active turn 时用,D16 unsolicited)。 */\n private unsolicitedSink?: (event: StreamEvent) => void;\n private unsolicitedSeq = 0;\n\n setUnsolicitedSink(sink: (event: StreamEvent) => void): void {\n this.unsolicitedSink = sink;\n }\n\n constructor(gw: GatewayClient, sessionId: string, model: string, openclawAgent: string) {\n this.gw = gw;\n this.sessionId = sessionId;\n this.model = model;\n this.openclawAgent = openclawAgent;\n this.sessionKey = `agent:${openclawAgent}:phonon-${sessionId}`;\n }\n\n get key(): string {\n return this.sessionKey;\n }\n\n /** 接收 Gateway 事件(由 adapter 路由进来,已按 sessionKey 过滤)。 */\n handleEvent(event: string, payload: Record<string, unknown>): void {\n const turn = this.activeTurn;\n const now = new Date().toISOString();\n\n if (event !== \"chat\") return;\n const state = payload.state as string;\n\n // 无 active turn 的 chat 输出 = 自发(D16 unsolicited):OpenClaw cron/定时/心跳(修 P0#7)\n if (!turn) {\n if (state === \"final\") {\n const text =\n (payload.message as { text?: string })?.text ?? (payload.finalText as string) ?? \"\";\n if (text && this.unsolicitedSink) {\n this.unsolicitedSink({\n type: \"message\",\n sessionId: this.sessionId,\n turnId: `u-${Date.now()}-${this.unsolicitedSeq++}`,\n origin: \"unsolicited\",\n source: (payload.source as string) ?? \"openclaw\",\n seq: 0,\n at: now,\n role: \"assistant\",\n text,\n delta: false,\n } as StreamEvent);\n }\n }\n return;\n }\n\n if (state === \"delta\") {\n const deltaText = payload.deltaText as string | undefined;\n if (deltaText) {\n turn.acc += deltaText;\n if (turn.verbosity === \"messages\" || turn.verbosity === \"tools\" || turn.verbosity === \"trace\") {\n turn.emit({\n type: \"message\", sessionId: this.sessionId, turnId: turn.turnId, seq: 0, at: now,\n role: \"assistant\", text: deltaText, delta: true,\n } as StreamEvent);\n }\n }\n } else if (state === \"final\") {\n // final 文本优先取 payload,没有则用累积的 delta\n const finalText =\n (payload.message as { text?: string })?.text ??\n (payload.finalText as string) ??\n turn.acc;\n turn.emit({\n type: \"result\", sessionId: this.sessionId, turnId: turn.turnId, seq: 0, at: now,\n text: finalText, status: \"completed\", final: true,\n } as StreamEvent);\n turn.done();\n this.activeTurn = undefined;\n }\n }\n\n async send(input: string, opts: SendOptions): Promise<void> {\n const { turnId, emit } = opts;\n let message = input;\n if (opts.skills && opts.skills.length > 0) {\n message = `[必须本轮加载并使用这些 skill: ${opts.skills.join(\", \")}]\\n\\n${input}`;\n }\n\n await new Promise<void>((resolve) => {\n let settled = false;\n const finish = () => {\n if (settled) return;\n settled = true;\n clearTimeout(guard);\n resolve();\n };\n this.activeTurn = { turnId, emit, verbosity: opts.verbosity, done: finish, acc: \"\" };\n this.gw\n .rpc(\"chat.send\", {\n sessionKey: this.sessionKey,\n message,\n deliver: false,\n idempotencyKey: randomUUID(),\n }, 1800000)\n .catch((err) => {\n emit({\n type: \"error\", sessionId: this.sessionId, turnId, seq: 0, at: new Date().toISOString(),\n message: (err as Error)?.message ?? \"chat.send failed\", status: \"failed\", final: true,\n } as StreamEvent);\n this.activeTurn = undefined;\n finish();\n });\n // 兜底超时:30 分钟没 final 就强制收尾\n const guard = setTimeout(() => {\n if (this.activeTurn?.turnId === turnId) {\n emit({\n type: \"result\", sessionId: this.sessionId, turnId, seq: 0, at: new Date().toISOString(),\n text: \"\", status: \"timeout\", final: true,\n } as StreamEvent);\n this.activeTurn = undefined;\n finish();\n }\n }, 1800000);\n });\n }\n\n async interrupt(): Promise<void> {\n await this.gw.rpc(\"chat.abort\", { sessionKey: this.sessionKey }, 5000).catch(() => {});\n }\n\n async switchModel(model: string): Promise<{ warnings?: string[] }> {\n this.model = model;\n await this.gw.rpc(\"sessions.patch\", { key: this.sessionKey, model }, 10000).catch(() => {});\n return {};\n }\n\n async inject(context: ContextItem[]): Promise<void> {\n if (context.length === 0) return;\n const message = context.map((c) => `[${c.role}] ${c.content}`).join(\"\\n\");\n await this.gw.rpc(\"chat.inject\", { sessionKey: this.sessionKey, message }, 10000).catch(() => {});\n }\n\n async compressCustom(strategy = \"dropToolIO\", options?: { keepRecentToolCalls?: number }): Promise<{ summary?: string; filesChanged?: number; recordsChanged?: number; blocksRemoved?: number; bytesBefore?: number; bytesAfter?: number; backups?: string[] }> {\n if (strategy !== \"dropToolIO\") throw new Error(`unsupported custom compression strategy: ${strategy}`);\n const file = this.resolveSessionFile();\n if (!file) throw new Error(`OpenClaw session file not found for ${this.sessionKey}`);\n const r = await dropToolIOFromJsonlFiles([file], options);\n return { summary: `dropToolIO removed ${r.blocksRemoved} tool blocks from ${r.filesChanged} files`, ...r };\n }\n\n async compressNative(): Promise<{ summary?: string }> {\n await this.gw.rpc(\"sessions.compact\", { key: this.sessionKey }, 600000).catch(() => {});\n return { summary: \"compacted via sessions.compact\" };\n }\n\n private resolveSessionFile(): string | undefined {\n const sessionsJson = join(homedir(), \".openclaw\", \"agents\", this.openclawAgent, \"sessions\", \"sessions.json\");\n try {\n if (existsSync(sessionsJson)) {\n const sessions = JSON.parse(readFileSync(sessionsJson, \"utf8\")) as Record<string, { sessionId?: string }>;\n const id = sessions[this.sessionKey]?.sessionId;\n if (id) {\n const p = join(homedir(), \".openclaw\", \"agents\", this.openclawAgent, \"sessions\", `${id}.jsonl`);\n if (existsSync(p)) return p;\n }\n }\n } catch {\n // fall through\n }\n return undefined;\n }\n\n async terminate(): Promise<void> {\n await this.interrupt();\n // 不删 transcript:留痕。仅停活动。\n }\n\n async describe(): Promise<{ contextWindow?: number; usedTokens?: number; compactions?: number }> {\n try {\n const d = await this.gw.rpc(\"sessions.describe\", { key: this.sessionKey }, 8000);\n const sess = (d.session ?? {}) as Record<string, unknown>;\n return {\n contextWindow: typeof sess.contextTokens === \"number\" ? sess.contextTokens : undefined,\n usedTokens: typeof sess.usedContextTokens === \"number\" ? sess.usedContextTokens : undefined,\n compactions: typeof sess.compactions === \"number\" ? sess.compactions : undefined,\n };\n } catch {\n return {};\n }\n }\n}\n\nexport class OpenClawGatewayAdapter implements AgentAdapter {\n readonly name = \"openclaw\";\n readonly capabilities = CAPABILITIES;\n private gw: GatewayClient;\n private defaultAgent: string;\n private sessions = new Map<string, GatewaySession>(); // sessionKey → session\n /** agentId(openclaw:sub) → workspace 路径(从 agents.list 缓存,用于 global skill 目录)。 */\n private workspaceCache = new Map<string, string>();\n\n constructor(opts: { gateway: GatewayConfig; defaultAgent?: string }) {\n this.gw = new GatewayClient(opts.gateway);\n this.defaultAgent = opts.defaultAgent ?? \"main\";\n // 路由 Gateway 事件到对应 session(按 sessionKey 过滤,不串台)\n this.gw.onEvent((event, payload) => {\n const sk = payload.sessionKey as string | undefined;\n if (!sk) return;\n const session = this.sessions.get(sk);\n session?.handleEvent(event, payload);\n });\n }\n\n async discoverAgents(): Promise<AgentDescriptor[]> {\n let connected = false;\n try {\n await this.gw.connect();\n connected = this.gw.isConnected();\n } catch {\n connected = false;\n }\n if (!connected) {\n return [\n {\n agentId: \"openclaw\" as AgentDescriptor[\"agentId\"],\n displayName: \"OpenClaw\",\n adapter: \"openclaw\",\n available: false,\n unavailableReason: \"OpenClaw Gateway not reachable\",\n models: [],\n capabilities: CAPABILITIES,\n scannedAt: new Date().toISOString(),\n },\n ];\n }\n\n // 枚举该 Gateway 下所有 OpenClaw agent(按 workspace 分)\n let subAgents: Array<{ id: string; workspace?: string; model?: { primary?: string } | string }> = [];\n try {\n const r = await this.gw.rpc(\"agents.list\", {}, 8000);\n subAgents = (r.agents as typeof subAgents) ?? [];\n } catch {\n subAgents = [{ id: this.defaultAgent }];\n }\n if (subAgents.length === 0) subAgents = [{ id: this.defaultAgent }];\n\n const now = new Date().toISOString();\n const gatewayModels = await this.listGatewayModels();\n return subAgents.map((a) => {\n if (a.workspace) this.workspaceCache.set(`openclaw:${a.id}`, a.workspace);\n const primaryModel =\n typeof a.model === \"string\" ? a.model : a.model?.primary;\n // 优先报 Gateway 的完整可用模型目录;拿不到时退回 agents.list 的 primary。\n const models = gatewayModels.length > 0 ? gatewayModels : (primaryModel ? [{ id: primaryModel, available: true }] : []);\n return {\n // 复合 agentId:openclaw:<subAgentId>(design D32)\n agentId: `openclaw:${a.id}` as AgentDescriptor[\"agentId\"],\n displayName: `OpenClaw / ${a.id}`,\n adapter: \"openclaw\",\n available: true,\n models,\n capabilities: CAPABILITIES,\n scannedAt: now,\n } satisfies AgentDescriptor;\n });\n }\n\n private async listGatewayModels(): Promise<ModelInfo[]> {\n try {\n const r = await this.gw.rpc(\"models.list\", { view: \"all\" }, 8000);\n const rows = Array.isArray(r.models) ? r.models as Array<Record<string, unknown>> : [];\n const models: ModelInfo[] = [];\n const seen = new Set<string>();\n for (const row of rows) {\n const id = typeof row.key === \"string\" ? row.key : (typeof row.id === \"string\" ? row.id : undefined);\n if (!id || seen.has(id)) continue;\n if (row.available === false || row.missing === true) continue;\n seen.add(id);\n const contextWindow = typeof row.contextWindow === \"number\"\n ? row.contextWindow\n : (typeof row.contextTokens === \"number\" ? row.contextTokens : undefined);\n models.push({\n id,\n ...(typeof row.name === \"string\" ? { displayName: row.name } : {}),\n ...(contextWindow && contextWindow > 0 ? { contextWindow } : {}),\n available: true,\n });\n }\n return models;\n } catch {\n return [];\n }\n }\n\n async createSession(params: CreateSessionParams): Promise<AdapterSession> {\n await this.gw.connect();\n // 从复合 agentId 解出 OpenClaw sub-agent:openclaw:phonon → phonon\n const subAgent =\n (params.agentConfig?.openclawAgent as string) ??\n (params.agentId.includes(\":\") ? params.agentId.split(\":\")[1]! : this.defaultAgent);\n const session = new GatewaySession(this.gw, params.sessionId, params.model, subAgent);\n // sessions.create 失败要外显(修 P0#6),不能静默吞\n try {\n await this.gw.rpc(\"sessions.create\", { key: session.key, model: params.model }, 15000);\n } catch (err) {\n throw new Error(`OpenClaw sessions.create failed: ${(err as Error)?.message ?? \"?\"}`);\n }\n // 订阅自发输出(proactiveOutput);订阅失败不致命,记警告即可\n await this.gw.rpc(\"sessions.messages.subscribe\", { key: session.key }, 10000).catch((e) => {\n console.warn(`[openclaw-gateway] subscribe failed for ${session.key}: ${(e as Error)?.message}`);\n });\n this.sessions.set(session.key, session);\n return session;\n }\n\n /** 关闭 Gateway 连接(daemon 退出时)。 */\n close(): void {\n this.gw.close();\n }\n\n /** OpenClaw 某 sub-agent 的 global skill 目录 = 该 agent workspace/skills。 */\n globalSkillDir(agentId: string): string | undefined {\n const ws = this.workspaceCache.get(agentId);\n return ws ? `${ws}/skills` : undefined;\n }\n}\n","import { WebSocket } from \"ws\";\nimport { PhononConnection } from \"./index.js\";\nimport { AdapterRegistry } from \"./session-engine.js\";\nimport { PROTOCOL_VERSION } from \"@agent-phonon/protocol\";\nimport type { RpcTransport } from \"./rpc.js\";\n\n/**\n * phonon 拨出客户端(design §6):主动连到一个 server URL。\n *\n * 真实场景:连你的 Azure 服务端。测试场景:连项目内 test-server。\n * 拨出后发 connect.hello,server 回 welcome(含 tenantId),随后由 PhononConnection 处理 session.*。\n */\nexport class PhononClient {\n private ws?: WebSocket;\n private conn?: PhononConnection;\n private registry: AdapterRegistry;\n private serverUrl: string;\n private deviceId: string;\n private deviceKey?: string;\n private resolveProjectCwd?: (project: string) => string;\n private trustLocal?: boolean;\n private dbPath?: string;\n private store?: import(\"./store.js\").PhononStore;\n private policy?: import(\"@agent-phonon/protocol\").TenantPolicy;\n private obs?: import(\"./observability.js\").ObsBus;\n private workspaceRoot?: string;\n private started = false;\n private backoffMs = 1000;\n private reconnectTimer?: ReturnType<typeof setTimeout>;\n\n constructor(opts: {\n serverUrl: string;\n deviceId: string;\n registry: AdapterRegistry;\n resolveProjectCwd?: (project: string) => string;\n /** 本地自用:放宽 policy(允许写操作 + 受控根为 allowedProjectRoots)。 */\n trustLocal?: boolean;\n workspaceRoot?: string;\n /** sqlite 文件路径(多连接可共享同一 store)。 */\n dbPath?: string;\n store?: import(\"./store.js\").PhononStore;\n /** 可选:policy 覆盖。 */\n policy?: import(\"@agent-phonon/protocol\").TenantPolicy;\n /** 可观测事件总线。 */\n obs?: import(\"./observability.js\").ObsBus;\n /** 设备鉴权 key(随 connect.hello 发送)。 */\n deviceKey?: string;\n }) {\n this.serverUrl = opts.serverUrl;\n this.deviceId = opts.deviceId;\n this.deviceKey = opts.deviceKey;\n this.registry = opts.registry;\n this.resolveProjectCwd = opts.resolveProjectCwd;\n this.trustLocal = opts.trustLocal;\n this.workspaceRoot = opts.workspaceRoot;\n this.dbPath = opts.dbPath;\n this.store = opts.store;\n this.policy = opts.policy;\n this.obs = opts.obs;\n }\n\n /** 连接并完成握手,resolve 后即可接收 server 的 session.* 下发。 */\n connect(): Promise<{ tenantId: string }> {\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(this.serverUrl);\n this.ws = ws;\n\n const transport: RpcTransport = {\n send: (data) => ws.send(data),\n close: () => ws.close(),\n };\n\n ws.on(\"open\", async () => {\n // 握手前先建连接处理器,但 tenantId 要等 welcome;先用占位,再在 welcome 后重建\n // 简化:先发 hello 作为一个 request,拿到 welcome.tenantId 后再建 PhononConnection。\n try {\n // 临时 peer 仅用于 hello/welcome\n const { RpcPeer } = await import(\"./rpc.js\");\n const tmpPeer = new RpcPeer(transport, () => {\n throw new Error(\"not ready\");\n });\n // 把 message 暂时喂给 tmpPeer\n const tmpListener = (raw: Buffer) => tmpPeer.handle(raw.toString());\n ws.on(\"message\", tmpListener);\n\n const welcome = (await tmpPeer.request(\"connect.hello\", {\n protocolVersion: PROTOCOL_VERSION,\n deviceId: this.deviceId as never,\n features: [],\n ...(this.deviceKey ? { auth: { deviceKey: this.deviceKey } } : {}),\n at: new Date().toISOString(),\n })) as { tenantId: string };\n\n // 切换到正式连接处理器\n ws.off(\"message\", tmpListener);\n const conn = new PhononConnection({\n tenantId: welcome.tenantId,\n transport,\n registry: this.registry,\n resolveProjectCwd: this.resolveProjectCwd,\n trustLocal: this.trustLocal,\n workspaceRoot: this.workspaceRoot,\n dbPath: this.dbPath,\n store: this.store,\n policy: this.policy,\n obs: this.obs,\n });\n this.conn = conn;\n ws.on(\"message\", (raw: Buffer) => conn.handle(raw.toString()));\n this.backoffMs = 1000; // 连上重置 backoff\n // 重连补发(D29):server welcome.ackedSeqs → resumeFrom\n const wAck = (welcome as { ackedSeqs?: Array<{ sessionId: string; lastSeq: number }> }).ackedSeqs;\n if (wAck && wAck.length > 0) {\n conn.replayPending(wAck.map((a) => ({ sessionId: a.sessionId, fromSeq: a.lastSeq })));\n }\n resolve({ tenantId: welcome.tenantId });\n } catch (err) {\n reject(err);\n }\n });\n\n ws.on(\"error\", (err) => {\n if (!this.started) reject(err);\n });\n ws.on(\"close\", () => {\n this.conn?.onClose();\n this.conn = undefined; // 清 conn,health 不误报 connected(修 B8)\n if (this.started) this.scheduleReconnect();\n });\n });\n }\n\n /**\n * 长期运行:连上后自动保持,断线指数退避重连(bug-bash P1)。\n * 首次连接失败也进重试(不抛)。\n */\n async start(): Promise<void> {\n this.started = true;\n try {\n await this.connect();\n } catch {\n this.scheduleReconnect();\n }\n }\n\n private scheduleReconnect(): void {\n if (!this.started || this.reconnectTimer) return;\n const delay = this.backoffMs;\n this.backoffMs = Math.min(this.backoffMs * 2, 30000); // 上限 30s\n this.reconnectTimer = setTimeout(async () => {\n this.reconnectTimer = undefined;\n try {\n await this.connect();\n } catch {\n this.scheduleReconnect();\n }\n }, delay);\n }\n\n close(): void {\n this.started = false; // 停止重连\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n this.ws?.close();\n }\n\n /** 本连接的 PhononConnection(HookBridge 路由用)。 */\n get connection(): PhononConnection | undefined {\n return this.conn;\n }\n}\n","import { createServer, type Server } from \"node:http\";\nimport type { PhononConnection } from \"./index.js\";\n\n/**\n * HITL Bridge(design §8 / B 阶段)。\n *\n * phonon-core 起一个本地 HTTP 端点,给 OpenClaw plugin 调:\n * plugin before_tool_call → POST /hook/before_tool_call { sessionKey, toolName, params }\n * → bridge 找到该 sessionKey 对应的 PhononConnection(tenant)\n * → conn.fireHook(...) 发 hook.fired 给 server,阻塞等 server 的 hook.resolve(= RPC 响应)\n * ← server 裁决\n * ← bridge 返回 decision 给 plugin\n *\n * server 的 hook.resolve 裁决直接作为 hook.fired 的 RPC 响应回来(hook.fired 是 request)。\n * 这样 plugin↔core↔server 三段阻塞链打通,HITL 闭环。\n */\n\n/** sessionKey → 该 session 所属连接 + phonon sessionId 的解析器。 */\nexport type HookRouteResolver = (sessionKey: string) => { conn: PhononConnection; sessionId: string } | undefined;\n\nexport class HookBridge {\n private server?: Server;\n private resolveRoute: HookRouteResolver;\n private hookSeq = 1;\n /** 可选本地鉴权 token(P1):plugin 请求需带 Authorization: Bearer <token>。 */\n private token?: string;\n\n constructor(resolveRoute: HookRouteResolver, opts?: { token?: string }) {\n this.resolveRoute = resolveRoute;\n this.token = opts?.token;\n }\n\n listen(port = 4318, host = \"127.0.0.1\"): Promise<number> {\n return new Promise((resolve) => {\n const server = createServer((req, res) => this.onRequest(req, res));\n this.server = server;\n server.listen(port, host, () => {\n const addr = server.address();\n resolve(typeof addr === \"object\" && addr ? addr.port : port);\n });\n });\n }\n\n private async onRequest(\n req: import(\"node:http\").IncomingMessage,\n res: import(\"node:http\").ServerResponse,\n ): Promise<void> {\n if (req.method !== \"POST\" || !req.url?.startsWith(\"/hook/\")) {\n res.writeHead(404).end();\n return;\n }\n // 本地鉴权(P1):配了 token 则验 Authorization: Bearer\n if (this.token) {\n const auth = req.headers[\"authorization\"];\n if (auth !== `Bearer ${this.token}`) {\n res.writeHead(401, { \"content-type\": \"application/json\" }).end(JSON.stringify({ action: \"continue\", reason: \"unauthorized\" }));\n return;\n }\n }\n // 去掉 query string(修 P2#18)\n const hookType = req.url.slice(\"/hook/\".length).split(\"?\")[0]!; // e.g. before_tool_call\n let body = \"\";\n req.on(\"data\", (c) => (body += c));\n req.on(\"end\", async () => {\n let payload: { sessionKey?: string; toolName?: string; params?: unknown };\n try {\n payload = JSON.parse(body);\n } catch {\n res.writeHead(400).end(JSON.stringify({ action: \"continue\", reason: \"bad json\" }));\n return;\n }\n const sessionKey = payload.sessionKey;\n const route = sessionKey ? this.resolveRoute(sessionKey) : undefined;\n if (!route) {\n // 未知 session → fail-open 放行\n res.writeHead(200, { \"content-type\": \"application/json\" }).end(JSON.stringify({ action: \"continue\" }));\n return;\n }\n try {\n // 发 hook.fired 给 server,阻塞等裁决(hook.fired 是 request,响应即裁决)\n const decision = (await route.conn.fireHook({\n sessionId: route.sessionId,\n hookId: `h-${Date.now()}-${this.hookSeq++}`,\n hookType: mapHookType(hookType),\n payload: {\n toolName: payload.toolName,\n command: typeof payload.params === \"object\" && payload.params ? (payload.params as { command?: string }).command : undefined,\n extra: payload.params as Record<string, unknown> | undefined,\n },\n at: new Date().toISOString(),\n })) as { action?: string; reason?: string; patch?: Record<string, unknown> };\n\n // server 的 hook.resolve 结果 → bridge decision(保留 applied 等)\n const action = (decision?.action as string) ?? \"continue\";\n res.writeHead(200, { \"content-type\": \"application/json\" }).end(\n JSON.stringify({ action, reason: decision?.reason, patch: decision?.patch }),\n );\n } catch (err) {\n // server 不裁决/超时 → fail-open\n res.writeHead(200, { \"content-type\": \"application/json\" }).end(\n JSON.stringify({ action: \"continue\", reason: `bridge error: ${(err as Error)?.message ?? \"?\"}` }),\n );\n }\n });\n }\n\n close(): Promise<void> {\n return new Promise((resolve) => {\n if (!this.server) return resolve();\n this.server.close(() => resolve());\n });\n }\n}\n\n/** OpenClaw hook 名 → phonon 归一化 HookType。 */\nfunction mapHookType(openclawHook: string): string {\n switch (openclawHook) {\n case \"before_tool_call\":\n return \"pre_tool\";\n case \"before_command\":\n return \"pre_command\";\n default:\n return \"pre_tool\";\n }\n}\n","import { DatabaseSync } from \"node:sqlite\";\nimport { existsSync, statSync, rmSync } from \"node:fs\";\n\nexport interface SqliteDropResult {\n filesChanged: number;\n recordsChanged: number;\n blocksRemoved: number;\n bytesBefore: number;\n bytesAfter: number;\n backups: string[];\n}\n\nexport interface SqliteRow {\n /** 行主键(用于 mutateRow 定位)。 */\n id: string | number;\n /** 是否属于「工具行」(参与裁剪)。 */\n isTool: boolean;\n /**\n * 是否是「工具调用锚点」行(用于 keep-recent 计数)。\n * 不传则退化为 isTool。Hermes 里一次调用跨两行(assistant 带 tool_calls + role=tool 结果),\n * 只有 assistant-带-tool_calls 才是锚点,避免把「保留最近 1 次调用」误算成只留结果行。\n */\n isToolCall?: boolean;\n /** 透传给 mutateRow 的任意附加字段(如 role,让 adapter 决定删行还是清列)。 */\n [k: string]: unknown;\n}\n\n/**\n * 通用「按行裁剪工具 IO」的 sqlite 压缩器,给 OpenCode / Hermes 这类把会话存进\n * sqlite 的 runtime 用。语义与 dropToolIOFromJsonlFiles 对齐:\n * - 只动「工具行」(isTool=true),纯文本/推理/普通消息行不碰\n * - 保留最近 keepRecentToolCalls 个工具行(position-based,与 item 3 一致)\n * - 旧工具行交给 mutateRow 处理:可整行删除,也可只清空工具相关列(保留同行的正文)\n *\n * 安全要点:\n * - 用 `VACUUM INTO` 生成一致性备份(正确处理 WAL;file copy 会漏掉 -wal)\n * - busy_timeout 等锁而非立刻失败(state.db 可能被 agent 进程并发持有)\n * - 改动包在 IMMEDIATE 事务里,失败回滚\n * - 不对主库做 VACUUM(独占锁、对热库不安全);改用 best-effort wal_checkpoint\n */\nexport async function dropToolIORowsSqlite(opts: {\n dbPath: string;\n selectRows: (db: DatabaseSync) => SqliteRow[];\n /** 处理一条需要裁剪的旧工具行:删除整行或清空工具列。 */\n mutateRow: (db: DatabaseSync, row: SqliteRow) => void;\n keepRecentToolCalls?: number;\n}): Promise<SqliteDropResult> {\n const { dbPath } = opts;\n const result: SqliteDropResult = { filesChanged: 0, recordsChanged: 0, blocksRemoved: 0, bytesBefore: 0, bytesAfter: 0, backups: [] };\n if (!existsSync(dbPath)) throw new Error(`sqlite session db not found: ${dbPath}`);\n const keepRecent = opts.keepRecentToolCalls ?? 3;\n const before = fileSize(dbPath);\n const stamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const backup = `${dbPath}.bak-${stamp}`;\n\n const db = new DatabaseSync(dbPath);\n try {\n db.exec(\"PRAGMA busy_timeout = 5000;\");\n db.exec(\"PRAGMA foreign_keys = ON;\");\n\n const rows = opts.selectRows(db);\n const toolIdx: number[] = [];\n const callIdx: number[] = [];\n rows.forEach((r, i) => {\n if (r.isTool) toolIdx.push(i);\n if (r.isToolCall ?? r.isTool) callIdx.push(i);\n });\n if (toolIdx.length === 0) {\n result.bytesBefore = before;\n result.bytesAfter = before;\n return result; // 无工具行可裁,不备份、不改动\n }\n\n // 一致性备份(含 WAL 状态)。VACUUM INTO 要求目标文件不存在。\n db.exec(`VACUUM INTO '${backup.replace(/'/g, \"''\")}'`);\n result.backups.push(backup);\n\n // keep-recent 锚定在「工具调用」行上:保留最近 N 次调用起的所有工具行。\n const keepFromIndex = keepRecent > 0 && callIdx.length > 0\n ? callIdx[Math.max(0, callIdx.length - keepRecent)]!\n : (keepRecent > 0 ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY);\n\n db.exec(\"BEGIN IMMEDIATE\");\n let removed = 0;\n try {\n for (let i = 0; i < rows.length; i++) {\n const r = rows[i]!;\n if (!r.isTool) continue;\n if (i >= keepFromIndex) continue; // 最近的工具行保留\n opts.mutateRow(db, r);\n removed++;\n }\n db.exec(\"COMMIT\");\n } catch (e) {\n db.exec(\"ROLLBACK\");\n throw e;\n }\n // 热库不做主库 VACUUM(独占锁);best-effort 把 WAL 落盘。\n try { db.exec(\"PRAGMA wal_checkpoint(TRUNCATE);\"); } catch { /* best-effort */ }\n\n result.blocksRemoved = removed;\n result.recordsChanged = removed;\n result.filesChanged = removed > 0 ? 1 : 0;\n result.bytesBefore = before;\n if (removed === 0) {\n // 没实际改动:删掉刚生成的备份,保持干净。\n try { rmSync(backup, { force: true }); } catch { /* ignore */ }\n result.backups = [];\n }\n return result;\n } finally {\n try { db.close(); } catch { /* ignore */ }\n result.bytesAfter = fileSize(dbPath);\n }\n}\n\nfunction fileSize(p: string): number {\n try { return statSync(p).size; } catch { return 0; }\n}\n","import { spawn } from \"node:child_process\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { existsSync, readdirSync, statSync } from \"node:fs\";\nimport { dropToolIOFromJsonlFiles } from \"../custom-compress.js\";\nimport type {\n AgentAdapter,\n AdapterSession,\n CreateSessionParams,\n SendOptions,\n} from \"../adapter.js\";\nimport type { AgentCapabilities, AgentDescriptor, StreamEvent, ContextItem, ModelInfo } from \"@agent-phonon/protocol\";\n\n/**\n * Codex adapter(design D10,单 agent runtime)。\n *\n * 调用(详见 docs/agent-cli-integration.md):\n * codex exec - --json -c model_provider=<id> -c model_providers.<id>.base_url=...\n * -c model_providers.<id>.wire_api=responses --model X\n * --dangerously-bypass-approvals-and-sandbox\n * prompt 走 stdin(argv 用 \"-\");resume:codex exec resume <thread_id> - --json ...\n *\n * 网关由调用方通过 CodexEnv 传入(baseUrl/apiKey/wireApi),adapter 不绑定任何特定网关;\n * 用 -c 临时覆盖 provider(不动用户的 ~/.codex/config.toml)。\n */\n\nconst CAPABILITIES: AgentCapabilities = {\n nativeSession: true, // exec resume <thread_id>\n nativeCompression: false,\n contextInjection: true, // 拼进下轮 prompt\n proactiveOutput: false,\n modelSwitch: true,\n interrupt: true, // kill\n injectMidTurn: false,\n skillManagement: false,\n hooks: [\"pre_command\"],\n streaming: true, // --json 事件流\n limits: { maxConcurrentSessions: 4 },\n};\n\n/**\n * 定位 Codex rollout 会话文件。\n * 文件名形如 sessions/YYYY/MM/DD/rollout-<ts>-<thread_id>.jsonl,后缀 uuid == thread_id。\n * 取匹配 thread_id 里 mtime 最新的一个(同 thread 可能跨多次 exec resume)。\n */\nexport function resolveCodexSessionFile(threadId: string, codexHome = join(homedir(), \".codex\")): string | undefined {\n const root = join(codexHome, \"sessions\");\n if (!existsSync(root)) return undefined;\n const hits: Array<{ path: string; mtime: number }> = [];\n const walk = (dir: string): void => {\n let names: string[];\n try { names = readdirSync(dir); } catch { return; }\n for (const name of names) {\n const full = join(dir, name);\n let st;\n try { st = statSync(full); } catch { continue; }\n if (st.isDirectory()) walk(full);\n else if (name.endsWith(`-${threadId}.jsonl`)) hits.push({ path: full, mtime: st.mtimeMs });\n }\n };\n walk(root);\n if (hits.length === 0) return undefined;\n hits.sort((a, b) => b.mtime - a.mtime);\n return hits[0]!.path;\n}\n\nexport interface CodexEnv {\n /** Codex executable path. Prefer an absolute path when running under systemd/launchd. */\n binPath?: string;\n /** Optional OpenAI-compatible endpoint override. Omit to use the user's native Codex config. */\n baseUrl?: string;\n /** Optional API key for baseUrl. Omit to use the user's native Codex config. */\n apiKey?: string;\n /** `default` means let Codex use the user's configured default. */\n defaultModel: string;\n /** 可选:由用户配置/上层配置发现到的真实可用模型。 */\n models?: ModelInfo[];\n /** wire_api:responses 或 chat(取决于网关/模型支持)。 */\n wireApi?: \"responses\" | \"chat\";\n /** -c model_provider 的 provider id(中性默认)。 */\n providerId?: string;\n /** provider 显示名(默认 phonon-gateway)。 */\n providerName?: string;\n}\n\nclass CodexSession implements AdapterSession {\n readonly sessionId: string;\n model: string;\n private cwd: string;\n private env: CodexEnv;\n private threadId?: string; // Codex thread_id(= 会话),从 thread.started 抓\n private current?: ReturnType<typeof spawn>;\n private pendingInject: string[] = [];\n\n constructor(sessionId: string, model: string, cwd: string, env: CodexEnv) {\n this.sessionId = sessionId;\n this.model = model;\n this.cwd = cwd;\n this.env = env;\n }\n\n private providerArgs(): string[] {\n if (!this.env.baseUrl || !this.env.apiKey) return [];\n const id = this.env.providerId ?? \"phonon_gateway\";\n const name = this.env.providerName ?? \"phonon-gateway\";\n return [\n \"-c\", `model_provider=${id}`,\n \"-c\", `model_providers.${id}.name=${name}`,\n \"-c\", `model_providers.${id}.base_url=${this.env.baseUrl}`,\n \"-c\", `model_providers.${id}.wire_api=${this.env.wireApi ?? \"responses\"}`,\n \"-c\", `model_providers.${id}.env_key=OPENAI_API_KEY`,\n ];\n }\n\n async send(input: string, opts: SendOptions): Promise<void> {\n const { turnId, emit } = opts;\n let prompt = input;\n if (this.pendingInject.length > 0) {\n prompt = this.pendingInject.join(\"\\n\") + \"\\n\\n\" + prompt;\n this.pendingInject = [];\n }\n if (opts.skills && opts.skills.length > 0) {\n prompt = `[本轮请使用这些能力: ${opts.skills.join(\", \")}]\\n\\n${prompt}`;\n }\n\n const args = this.threadId\n ? [\"exec\", \"resume\", this.threadId, \"-\", \"--json\", ...this.providerArgs(), ...(this.model !== \"default\" ? [\"--model\", this.model] : []), \"--dangerously-bypass-approvals-and-sandbox\"]\n : [\"exec\", \"-\", \"--json\", ...this.providerArgs(), ...(this.model !== \"default\" ? [\"--model\", this.model] : []), \"--dangerously-bypass-approvals-and-sandbox\"];\n\n await this.run(args, prompt, turnId, emit, opts);\n }\n\n private run(args: string[], stdin: string, turnId: string, emit: (e: StreamEvent) => void, opts: SendOptions): Promise<void> {\n return new Promise((resolve) => {\n const child = spawn(this.env.binPath ?? \"codex\", args, {\n cwd: this.cwd,\n env: { ...process.env, ...(opts.environment ?? {}), ...(this.env.apiKey ? { OPENAI_API_KEY: this.env.apiKey } : {}) } as NodeJS.ProcessEnv,\n });\n this.current = child;\n let buf = \"\";\n let acc = \"\";\n let settled = false;\n const finish = (status: \"completed\" | \"failed\" | \"interrupted\" | \"timeout\", text: string, message?: string) => {\n if (settled) return;\n settled = true;\n clearTimeout(guard);\n this.current = undefined;\n if (status === \"failed\") {\n emit({ type: \"error\", sessionId: this.sessionId, turnId, seq: 0, at: new Date().toISOString(), message: message ?? \"codex failed\", status: \"failed\", final: true } as StreamEvent);\n } else {\n emit({ type: \"result\", sessionId: this.sessionId, turnId, seq: 0, at: new Date().toISOString(), text, status, final: true } as StreamEvent);\n }\n resolve();\n };\n const guard = setTimeout(() => finish(\"timeout\", acc), 1800000);\n opts.signal?.addEventListener(\"abort\", () => { child.kill(\"SIGTERM\"); finish(\"interrupted\", acc); }, { once: true });\n\n child.stdout.on(\"data\", (d) => {\n buf += d.toString();\n let nl;\n while ((nl = buf.indexOf(\"\\n\")) >= 0) {\n const line = buf.slice(0, nl).trim();\n buf = buf.slice(nl + 1);\n if (!line) continue;\n let ev: Record<string, unknown>;\n try { ev = JSON.parse(line); } catch { continue; }\n this.handleEvent(ev, turnId, emit, (t) => (acc += t));\n }\n });\n child.on(\"error\", (e) => finish(\"failed\", \"\", e.message));\n child.on(\"close\", (code) => {\n if (settled) return;\n finish(code === 0 ? \"completed\" : \"failed\", acc, code !== 0 ? `codex exited ${code}` : undefined);\n });\n\n child.stdin.write(stdin);\n child.stdin.end();\n });\n }\n\n /** 解析 Codex JSON 事件流 → phonon StreamEvent。 */\n private handleEvent(ev: Record<string, unknown>, turnId: string, emit: (e: StreamEvent) => void, addText: (t: string) => void): void {\n const now = new Date().toISOString();\n const type = ev.type as string;\n if (type === \"thread.started\") {\n this.threadId = ev.thread_id as string; // 记录会话 id 供 resume\n } else if (type === \"item.completed\") {\n const item = ev.item as { type?: string; text?: string; name?: string; command?: string } | undefined;\n if (item?.type === \"agent_message\" && typeof item.text === \"string\") {\n addText(item.text);\n emit({ type: \"message\", sessionId: this.sessionId, turnId, seq: 0, at: now, role: \"assistant\", text: item.text, delta: true } as StreamEvent);\n } else if (item?.type === \"command_execution\") {\n emit({ type: \"tool_call\", sessionId: this.sessionId, turnId, seq: 0, at: now, toolName: \"command_execution\", args: { command: item.command } } as StreamEvent);\n }\n }\n // turn.completed 由 close 收尾\n }\n\n async interrupt(): Promise<void> {\n if (this.current) { this.current.kill(\"SIGTERM\"); this.current = undefined; }\n }\n async switchModel(model: string): Promise<{ warnings?: string[] }> { this.model = model; return {}; }\n async inject(context: ContextItem[]): Promise<void> {\n for (const c of context) this.pendingInject.push(`[${c.role}] ${c.content}`);\n }\n\n /**\n * 自定义压缩(dropToolIO):编辑 Codex rollout JSONL,删掉旧的 function_call /\n * function_call_output 等工具记录,保留 message/reasoning 等文本,默认保留最近 3 个工具调用。\n */\n async compressCustom(strategy = \"dropToolIO\", options?: { keepRecentToolCalls?: number }): Promise<{ summary?: string; filesChanged?: number; recordsChanged?: number; blocksRemoved?: number; bytesBefore?: number; bytesAfter?: number; backups?: string[] }> {\n if (strategy !== \"dropToolIO\") throw new Error(`unsupported custom compression strategy: ${strategy}`);\n if (!this.threadId) throw new Error(\"Codex session has no thread_id yet (no turn run); nothing to compress\");\n const file = resolveCodexSessionFile(this.threadId);\n if (!file) throw new Error(`Codex rollout file not found for thread ${this.threadId}`);\n const r = await dropToolIOFromJsonlFiles([file], options);\n return { summary: `dropToolIO removed ${r.blocksRemoved} tool records from Codex rollout`, ...r };\n }\n\n async terminate(): Promise<void> { await this.interrupt(); }\n}\n\nexport class CodexAdapter implements AgentAdapter {\n readonly name = \"codex\";\n readonly capabilities = CAPABILITIES;\n private env: CodexEnv;\n\n constructor(opts: { env: CodexEnv }) {\n this.env = opts.env;\n }\n\n async discoverAgents(): Promise<AgentDescriptor[]> {\n const version = await this.probeVersion();\n const available = version !== null;\n return [{\n agentId: \"codex\" as AgentDescriptor[\"agentId\"],\n displayName: \"Codex\",\n adapter: \"codex\",\n available,\n ...(available ? {} : { unavailableReason: \"codex CLI not found\" }),\n ...(version ? { version } : {}),\n models: this.env.models?.length\n ? this.env.models\n : [{ id: this.env.defaultModel, available: true }],\n capabilities: CAPABILITIES,\n scannedAt: new Date().toISOString(),\n }];\n }\n\n async createSession(params: CreateSessionParams): Promise<AdapterSession> {\n return new CodexSession(params.sessionId, params.model, params.cwd, this.env);\n }\n\n private probeVersion(): Promise<string | null> {\n return new Promise((resolve) => {\n const child = spawn(this.env.binPath ?? \"codex\", [\"--version\"]);\n let out = \"\";\n child.stdout.on(\"data\", (d) => (out += d.toString()));\n child.on(\"error\", () => resolve(null));\n child.on(\"close\", (code) => resolve(code === 0 ? out.trim() : null));\n });\n }\n}\n","import { spawn } from \"node:child_process\";\nimport { DatabaseSync } from \"node:sqlite\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { dropToolIORowsSqlite } from \"../sqlite-compress.js\";\nimport type {\n AgentAdapter,\n AdapterSession,\n CreateSessionParams,\n SendOptions,\n} from \"../adapter.js\";\nimport type { AgentCapabilities, AgentDescriptor, StreamEvent, ContextItem } from \"@agent-phonon/protocol\";\n\n/**\n * OpenCode adapter(design D10,单 agent runtime)。\n *\n * 调用:`opencode run <message> --format json [-m provider/model] [-s <sessionID>]`。\n * --format json 输出 raw JSON 事件流(step_start / text / tool 等,每事件带 sessionID)。\n * session 用 OpenCode 返回的 ses_ id,后续 -s 恢复。\n *\n * 方案 A:用 OpenCode 现有 provider 配置(opencode.json)。model 由 config/调用方传。\n * binary 路径可配(默认探测 ~/.opencode/bin/opencode 或 PATH)。\n */\n\nconst CAPABILITIES: AgentCapabilities = {\n nativeSession: true, // -s <sessionID> / -c continue\n nativeCompression: false,\n contextInjection: true,\n proactiveOutput: false,\n modelSwitch: true, // -m\n interrupt: true,\n injectMidTurn: false,\n skillManagement: false,\n hooks: [\"pre_command\"],\n streaming: true, // --format json 事件流\n limits: { maxConcurrentSessions: 4 },\n};\n\nexport interface OpenCodeEnv {\n /** opencode binary 路径(默认探测)。 */\n binPath?: string;\n /** 默认模型(provider/model 格式,如 opencode/deepseek-v4-flash-free)。 */\n defaultModel?: string;\n}\n\nfunction resolveBin(configured?: string): string {\n if (configured) return configured;\n const standard = join(homedir(), \".opencode\", \"bin\", \"opencode\");\n if (existsSync(standard)) return standard;\n return \"opencode\"; // PATH\n}\n\n/** OpenCode 会话库路径(part 表存消息块)。 */\nexport function resolveOpenCodeDbPath(): string {\n const xdg = process.env.XDG_DATA_HOME;\n const base = xdg ? join(xdg, \"opencode\") : join(homedir(), \".local\", \"share\", \"opencode\");\n return join(base, \"opencode.db\");\n}\n\nclass OpenCodeSession implements AdapterSession {\n readonly sessionId: string;\n model: string;\n private cwd: string;\n private bin: string;\n private ocSessionId?: string; // OpenCode ses_ id(从事件抓,供 -s resume)\n private current?: ReturnType<typeof spawn>;\n private pendingInject: string[] = [];\n\n constructor(sessionId: string, model: string, cwd: string, bin: string) {\n this.sessionId = sessionId;\n this.model = model;\n this.cwd = cwd;\n this.bin = bin;\n }\n\n async send(input: string, opts: SendOptions): Promise<void> {\n const { turnId, emit } = opts;\n let message = input;\n if (this.pendingInject.length > 0) {\n message = this.pendingInject.join(\"\\n\") + \"\\n\\n\" + message;\n this.pendingInject = [];\n }\n if (opts.skills && opts.skills.length > 0) {\n message = `[本轮请使用这些能力: ${opts.skills.join(\", \")}]\\n\\n${message}`;\n }\n\n const args = [\"run\", \"--format\", \"json\", \"--dangerously-skip-permissions\"];\n if (this.model) args.push(\"--model\", this.model);\n if (this.ocSessionId) args.push(\"--session\", this.ocSessionId); // 持续会话\n args.push(message); // prompt 作为位置参数放最后\n\n await this.run(args, turnId, emit, opts);\n }\n\n private run(args: string[], turnId: string, emit: (e: StreamEvent) => void, opts: SendOptions): Promise<void> {\n return new Promise((resolve) => {\n // 关键:stdin 设 ignore(=DEVNULL),否则 OpenCode 检测到 stdin pipe 会等交互输入卡死\n const child = spawn(this.bin, args, { cwd: this.cwd, stdio: [\"ignore\", \"pipe\", \"pipe\"], env: { ...process.env, ...(opts.environment ?? {}) } as NodeJS.ProcessEnv });\n this.current = child;\n let buf = \"\";\n let acc = \"\";\n let settled = false;\n const finish = (status: \"completed\" | \"failed\" | \"interrupted\" | \"timeout\", text: string, message?: string) => {\n if (settled) return;\n settled = true;\n clearTimeout(guard);\n this.current = undefined;\n if (status === \"failed\") {\n emit({ type: \"error\", sessionId: this.sessionId, turnId, seq: 0, at: new Date().toISOString(), message: message ?? \"opencode failed\", status: \"failed\", final: true } as StreamEvent);\n } else {\n emit({ type: \"result\", sessionId: this.sessionId, turnId, seq: 0, at: new Date().toISOString(), text, status, final: true } as StreamEvent);\n }\n resolve();\n };\n const guard = setTimeout(() => finish(\"timeout\", acc), 1800000);\n opts.signal?.addEventListener(\"abort\", () => { child.kill(\"SIGTERM\"); finish(\"interrupted\", acc); }, { once: true });\n\n child.stdout.on(\"data\", (d) => {\n buf += d.toString();\n let nl;\n while ((nl = buf.indexOf(\"\\n\")) >= 0) {\n const line = buf.slice(0, nl).trim();\n buf = buf.slice(nl + 1);\n if (!line) continue;\n let ev: Record<string, unknown>;\n try { ev = JSON.parse(line); } catch { continue; }\n this.handleEvent(ev, turnId, emit, (t) => (acc += t));\n }\n });\n child.on(\"error\", (e) => finish(\"failed\", \"\", e.message));\n child.on(\"close\", (code) => {\n if (settled) return;\n finish(code === 0 ? \"completed\" : \"failed\", acc, code !== 0 ? `opencode exited ${code}` : undefined);\n });\n });\n }\n\n /** 解析 OpenCode JSON 事件 → phonon StreamEvent。 */\n private handleEvent(ev: Record<string, unknown>, turnId: string, emit: (e: StreamEvent) => void, addText: (t: string) => void): void {\n const now = new Date().toISOString();\n const type = ev.type as string;\n // 记录 OpenCode session id(首次出现)供 resume\n const sid = ev.sessionID as string | undefined;\n if (sid && !this.ocSessionId) this.ocSessionId = sid;\n\n const part = ev.part as Record<string, unknown> | undefined;\n if (type === \"text\" && typeof part?.text === \"string\") {\n addText(part.text);\n emit({ type: \"message\", sessionId: this.sessionId, turnId, seq: 0, at: now, role: \"assistant\", text: part.text, delta: true } as StreamEvent);\n } else if (type === \"tool\" || type === \"tool_use\") {\n emit({ type: \"tool_call\", sessionId: this.sessionId, turnId, seq: 0, at: now, toolName: String(part?.tool ?? part?.name ?? \"?\"), args: part?.input } as StreamEvent);\n } else if (type === \"error\") {\n const err = ev.error as { data?: { message?: string }; name?: string } | undefined;\n const msg = err?.data?.message ?? err?.name ?? \"opencode error\";\n // 中间 error 事件(非终态)当作 message 上报;真正终态由 close 统一处理\n emit({ type: \"message\", sessionId: this.sessionId, turnId, seq: 0, at: now, role: \"system\", text: `[error] ${msg}`, delta: false } as StreamEvent);\n addText(`[error] ${msg}`);\n }\n }\n\n async interrupt(): Promise<void> {\n if (this.current) { this.current.kill(\"SIGTERM\"); this.current = undefined; }\n }\n async switchModel(model: string): Promise<{ warnings?: string[] }> { this.model = model; return {}; }\n async inject(context: ContextItem[]): Promise<void> {\n for (const c of context) this.pendingInject.push(`[${c.role}] ${c.content}`);\n }\n\n /**\n * 自定义压缩(dropToolIO):在 OpenCode 的 opencode.db 里删本 session 旧的 type='tool'\n * part 行,保留 text/reasoning/step 等文本,默认保留最近 3 个工具调用。\n * 改动前整库备份。\n */\n async compressCustom(strategy = \"dropToolIO\", options?: { keepRecentToolCalls?: number }): Promise<{ summary?: string; filesChanged?: number; recordsChanged?: number; blocksRemoved?: number; bytesBefore?: number; bytesAfter?: number; backups?: string[] }> {\n if (strategy !== \"dropToolIO\") throw new Error(`unsupported custom compression strategy: ${strategy}`);\n if (!this.ocSessionId) throw new Error(\"OpenCode session id unknown yet (no turn run); nothing to compress\");\n const dbPath = resolveOpenCodeDbPath();\n const sid = this.ocSessionId;\n const r = await dropToolIORowsSqlite({\n dbPath,\n keepRecentToolCalls: options?.keepRecentToolCalls,\n selectRows: (db: DatabaseSync) => {\n const rows = db.prepare(\"SELECT id, data FROM part WHERE session_id = ? ORDER BY time_created ASC, id ASC\").all(sid) as Array<{ id: string; data: string }>;\n return rows.map((row) => {\n let type = \"\";\n try { type = (JSON.parse(row.data) as { type?: string }).type ?? \"\"; } catch { /* ignore */ }\n return { id: row.id, isTool: type === \"tool\" };\n });\n },\n mutateRow: (db: DatabaseSync, row: { id: string | number }) => { db.prepare(\"DELETE FROM part WHERE id = ?\").run(row.id); },\n });\n return { summary: `dropToolIO removed ${r.blocksRemoved} tool parts from OpenCode session ${sid}`, ...r };\n }\n\n async terminate(): Promise<void> { await this.interrupt(); }\n}\n\nexport class OpenCodeAdapter implements AgentAdapter {\n readonly name = \"opencode\";\n readonly capabilities = CAPABILITIES;\n private bin: string;\n private defaultModel?: string;\n\n constructor(opts: { env?: OpenCodeEnv } = {}) {\n this.bin = resolveBin(opts.env?.binPath);\n this.defaultModel = opts.env?.defaultModel;\n }\n\n async discoverAgents(): Promise<AgentDescriptor[]> {\n const version = await this.probeVersion();\n const available = version !== null;\n return [{\n agentId: \"opencode\" as AgentDescriptor[\"agentId\"],\n displayName: \"OpenCode\",\n adapter: \"opencode\",\n available,\n ...(available ? {} : { unavailableReason: \"opencode CLI not found\" }),\n ...(version ? { version } : {}),\n models: this.defaultModel\n ? [{ id: this.defaultModel, available: true }]\n : [{ id: \"default\", displayName: \"OpenCode default (from config)\", available: true }],\n capabilities: CAPABILITIES,\n scannedAt: new Date().toISOString(),\n }];\n }\n\n async createSession(params: CreateSessionParams): Promise<AdapterSession> {\n const model = params.model && params.model !== \"default\" ? params.model : (this.defaultModel ?? \"\");\n return new OpenCodeSession(params.sessionId, model, params.cwd, this.bin);\n }\n\n private probeVersion(): Promise<string | null> {\n return new Promise((resolve) => {\n const child = spawn(this.bin, [\"--version\"]);\n let out = \"\";\n child.stdout.on(\"data\", (d) => (out += d.toString()));\n child.on(\"error\", () => resolve(null));\n child.on(\"close\", (code) => resolve(code === 0 ? out.trim() : null));\n });\n }\n}\n","import { spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { DatabaseSync } from \"node:sqlite\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { dropToolIORowsSqlite } from \"../sqlite-compress.js\";\nimport type {\n AgentAdapter,\n AdapterSession,\n CreateSessionParams,\n SendOptions,\n} from \"../adapter.js\";\nimport type { AgentCapabilities, AgentDescriptor, StreamEvent, ContextItem } from \"@agent-phonon/protocol\";\n\n/**\n * Hermes adapter(design D10/D32,**多 agent runtime**,同 OpenClaw)。\n *\n * Hermes profile = 独立 agent(各自 config.yaml/.env/SOUL.md/skills/workspace)。\n * 一个 Hermes 安装 = 一个 runtime,里面多个 profile = 多个 agent。\n * 复合 agentId:hermes:<profile>(如 hermes:default)。\n *\n * 调用:`HERMES_PROFILE=<profile> hermes -z <prompt> -m <model> --yolo --accept-hooks\n * [--continue <name>]`。-z/--oneshot 纯文本输出(非流式)。\n * 枚举 profile:`hermes profile list`。\n *\n * 方案 A:用 Hermes 现有 provider 配置(不强制网关)。全自动:--yolo + --accept-hooks。\n */\n\nconst CAPABILITIES: AgentCapabilities = {\n nativeSession: true, // --resume / --pass-session-id\n nativeCompression: false,\n contextInjection: true, // 拼进下轮 prompt\n proactiveOutput: false,\n modelSwitch: true, // -m 每轮可变\n interrupt: true, // kill\n injectMidTurn: false,\n skillManagement: true, // hermes skills\n hooks: [\"pre_command\"],\n streaming: false, // -z 是纯文本一次性输出,非流式 → 用 final 事件\n limits: { maxConcurrentSessions: 4 },\n};\n\nexport interface HermesEnv {\n /** Hermes executable path. Prefer an absolute path when running under systemd/launchd. */\n binPath?: string;\n /** 默认模型(如 anthropic/claude-opus-4.6 或 provider 自带格式)。 */\n defaultModel?: string;\n /** provider 覆盖(如 anthropic / openrouter;不传用 Hermes config 默认)。 */\n provider?: string;\n /** 额外 toolsets。 */\n toolsets?: string;\n}\n\nclass HermesSession implements AdapterSession {\n readonly sessionId: string;\n model: string;\n private cwd: string;\n private env: HermesEnv;\n private profile: string;\n private hermesSessionId: string;\n private convName: string;\n private started = false;\n private current?: ReturnType<typeof spawn>;\n private pendingInject: string[] = [];\n\n constructor(sessionId: string, model: string, cwd: string, env: HermesEnv, profile: string) {\n this.sessionId = sessionId;\n this.model = model;\n this.cwd = cwd;\n this.env = env;\n this.profile = profile;\n this.hermesSessionId = randomUUID();\n this.convName = `phonon-${sessionId.replace(/[^a-zA-Z0-9_-]/g, \"\")}`;\n }\n\n async send(input: string, opts: SendOptions): Promise<void> {\n const { turnId, emit } = opts;\n let prompt = input;\n if (this.pendingInject.length > 0) {\n prompt = this.pendingInject.join(\"\\n\") + \"\\n\\n\" + prompt;\n this.pendingInject = [];\n }\n if (opts.skills && opts.skills.length > 0) {\n prompt = `[本轮请使用这些能力: ${opts.skills.join(\", \")}]\\n\\n${prompt}`;\n }\n\n const args = [\"-z\", prompt];\n if (this.model) args.push(\"-m\", this.model);\n if (this.env.provider) args.push(\"--provider\", this.env.provider);\n if (this.env.toolsets) args.push(\"-t\", this.env.toolsets);\n // 全自动模式:phonon 让 agent 自动跑,不等人授权\n args.push(\"--yolo\", \"--accept-hooks\");\n // 持续会话:用 phonon sessionId 作为 Hermes 会话名,--continue <name> 恢复/创建\n // (--continue 接会话名,首轮创建、后续恢复)\n args.push(\"--continue\", this.convName);\n this.started = true;\n\n await this.run(args, turnId, emit, opts);\n }\n\n private run(args: string[], turnId: string, emit: (e: StreamEvent) => void, opts: SendOptions): Promise<void> {\n return new Promise((resolve) => {\n const child = spawn(this.env.binPath ?? \"hermes\", args, {\n cwd: this.cwd,\n env: { ...process.env, ...(opts.environment ?? {}), HERMES_PROFILE: this.profile } as NodeJS.ProcessEnv,\n });\n this.current = child;\n let out = \"\";\n let err = \"\";\n let settled = false;\n const finish = (status: \"completed\" | \"failed\" | \"interrupted\" | \"timeout\", text: string, message?: string) => {\n if (settled) return;\n settled = true;\n clearTimeout(guard);\n this.current = undefined;\n if (status === \"failed\") {\n emit({ type: \"error\", sessionId: this.sessionId, turnId, seq: 0, at: new Date().toISOString(), message: message ?? \"hermes failed\", status: \"failed\", final: true } as StreamEvent);\n } else {\n // -z 是一次性文本:作为一条 message + result 终态\n if (text) emit({ type: \"message\", sessionId: this.sessionId, turnId, seq: 0, at: new Date().toISOString(), role: \"assistant\", text, delta: false } as StreamEvent);\n emit({ type: \"result\", sessionId: this.sessionId, turnId, seq: 0, at: new Date().toISOString(), text, status, final: true } as StreamEvent);\n }\n resolve();\n };\n const guard = setTimeout(() => finish(\"timeout\", out), 1800000);\n opts.signal?.addEventListener(\"abort\", () => { child.kill(\"SIGTERM\"); finish(\"interrupted\", out); }, { once: true });\n\n child.stdout.on(\"data\", (d) => (out += d.toString()));\n child.stderr.on(\"data\", (d) => (err += d.toString()));\n child.on(\"error\", (e) => finish(\"failed\", \"\", e.message));\n child.on(\"close\", (code) => {\n if (settled) return;\n finish(code === 0 ? \"completed\" : \"failed\", out.trim(), code !== 0 ? `hermes exited ${code}: ${err.slice(0, 300)}` : undefined);\n });\n });\n }\n\n async interrupt(): Promise<void> {\n if (this.current) { this.current.kill(\"SIGTERM\"); this.current = undefined; }\n }\n async switchModel(model: string): Promise<{ warnings?: string[] }> { this.model = model; return {}; }\n async inject(context: ContextItem[]): Promise<void> {\n for (const c of context) this.pendingInject.push(`[${c.role}] ${c.content}`);\n }\n\n /**\n * 自定义压缩(dropToolIO):在 Hermes 的 state.db 里裁本 session 旧工具 IO。\n * Hermes 把 assistant 叙述与 tool_calls 存在同一行,所以:\n * - role='tool' 的纯工具返回行 → 整行删\n * - assistant 行带 tool_calls → 只清空 tool_calls/tool_call_id/tool_name 列,保留 content/reasoning\n * 默认保留最近 3 个工具调用;VACUUM INTO 一致性备份。\n */\n async compressCustom(strategy = \"dropToolIO\", options?: { keepRecentToolCalls?: number }): Promise<{ summary?: string; filesChanged?: number; recordsChanged?: number; blocksRemoved?: number; bytesBefore?: number; bytesAfter?: number; backups?: string[] }> {\n if (strategy !== \"dropToolIO\") throw new Error(`unsupported custom compression strategy: ${strategy}`);\n if (!this.started) throw new Error(\"Hermes session not started yet (no turn run); nothing to compress\");\n const dbPath = resolveHermesDbPath();\n if (!existsSync(dbPath)) throw new Error(`Hermes state.db not found: ${dbPath}`);\n const dbSessionId = resolveHermesSessionByTitle(dbPath, this.convName);\n if (!dbSessionId) throw new Error(`Hermes session not found for title ${this.convName}`);\n const r = await dropToolIORowsSqlite({\n dbPath,\n keepRecentToolCalls: options?.keepRecentToolCalls,\n selectRows: (db: DatabaseSync) => {\n const rows = db.prepare(\"SELECT id, role, tool_calls FROM messages WHERE session_id = ? ORDER BY id ASC\").all(dbSessionId) as Array<{ id: number; role: string; tool_calls: string | null }>;\n return rows.map((row) => {\n const hasToolCalls = row.tool_calls != null && row.tool_calls !== \"\" && row.tool_calls !== \"[]\" && row.tool_calls !== \"null\";\n return {\n id: row.id,\n role: row.role,\n isTool: row.role === \"tool\" || hasToolCalls,\n // 调用锚点 = assistant 带 tool_calls。role=tool 是结果行,不作为 keep-recent 计数点。\n isToolCall: hasToolCalls,\n };\n });\n },\n mutateRow: (db: DatabaseSync, row) => {\n if (row.role === \"tool\") {\n db.prepare(\"DELETE FROM messages WHERE id = ?\").run(row.id);\n } else {\n // assistant 行:只清空工具列,保留推理/正文\n db.prepare(\"UPDATE messages SET tool_calls = NULL, tool_call_id = NULL, tool_name = NULL WHERE id = ?\").run(row.id);\n }\n },\n });\n return { summary: `dropToolIO trimmed ${r.blocksRemoved} tool rows from Hermes session ${dbSessionId}`, ...r };\n }\n\n async terminate(): Promise<void> { await this.interrupt(); }\n}\n\n/** Hermes 状态库路径(默认 ~/.hermes/state.db,可被 HERMES_HOME 覆盖)。 */\nexport function resolveHermesDbPath(): string {\n const home = process.env.HERMES_HOME || join(homedir(), \".hermes\");\n return join(home, \"state.db\");\n}\n\n/**\n * 复现 Hermes 的 resolve_session_by_title:优先取 \"title #N\" 谱系里最新的,否则精确匹配。\n * 这样定位与 CLI 的 --continue <name> 一致,避免误删其它会话。\n */\nexport function resolveHermesSessionByTitle(dbPath: string, title: string): string | undefined {\n const db = new DatabaseSync(dbPath);\n try {\n db.exec(\"PRAGMA busy_timeout = 5000;\");\n const escaped = title.replace(/\\\\/g, \"\\\\\\\\\").replace(/%/g, \"\\\\%\").replace(/_/g, \"\\\\_\");\n const numbered = db.prepare(\"SELECT id FROM sessions WHERE title LIKE ? ESCAPE '\\\\' ORDER BY started_at DESC LIMIT 1\").get(`${escaped} #%`) as { id: string } | undefined;\n if (numbered?.id) return numbered.id;\n const exact = db.prepare(\"SELECT id FROM sessions WHERE title = ? LIMIT 1\").get(title) as { id: string } | undefined;\n return exact?.id;\n } finally {\n try { db.close(); } catch { /* ignore */ }\n }\n}\n\nexport class HermesAdapter implements AgentAdapter {\n readonly name = \"hermes\";\n readonly capabilities = CAPABILITIES;\n private env: HermesEnv;\n private defaultProfile: string;\n\n constructor(opts: { env?: HermesEnv; defaultProfile?: string } = {}) {\n this.env = opts.env ?? {};\n this.defaultProfile = opts.defaultProfile ?? \"default\";\n }\n\n async discoverAgents(): Promise<AgentDescriptor[]> {\n const version = await this.probeVersion();\n const available = version !== null;\n if (!available) {\n return [{\n agentId: \"hermes\" as AgentDescriptor[\"agentId\"],\n displayName: \"Hermes\",\n adapter: \"hermes\",\n available: false,\n unavailableReason: \"hermes CLI not found\",\n models: [],\n capabilities: CAPABILITIES,\n scannedAt: new Date().toISOString(),\n }];\n }\n // 枚举所有 profile = 多个 agent(D32,同 OpenClaw)\n const profiles = await this.listProfiles();\n const now = new Date().toISOString();\n return profiles.map((p) => ({\n agentId: `hermes:${p.name}` as AgentDescriptor[\"agentId\"],\n displayName: `Hermes / ${p.name}`,\n adapter: \"hermes\",\n available: true,\n ...(version ? { version } : {}),\n models: p.model\n ? [{ id: p.model, available: true }]\n : (this.env.defaultModel ? [{ id: this.env.defaultModel, available: true }] : [{ id: \"default\", displayName: \"Hermes default\", available: true }]),\n capabilities: CAPABILITIES,\n scannedAt: now,\n }));\n }\n\n async createSession(params: CreateSessionParams): Promise<AdapterSession> {\n // 从复合 agentId 解出 profile:hermes:default → default\n const profile = params.agentId.includes(\":\") ? params.agentId.split(\":\")[1]! : this.defaultProfile;\n const model = params.model && params.model !== \"default\" ? params.model : (this.env.defaultModel ?? \"\");\n return new HermesSession(params.sessionId, model, params.cwd, this.env, profile);\n }\n\n /** 枚举 Hermes profile(去 ANSI 色解析 profile list)。 */\n private listProfiles(): Promise<Array<{ name: string; model?: string }>> {\n return new Promise((resolve) => {\n const child = spawn(this.env.binPath ?? \"hermes\", [\"profile\", \"list\"]);\n let out = \"\";\n child.stdout.on(\"data\", (d) => (out += d.toString()));\n child.on(\"error\", () => resolve([{ name: this.defaultProfile }]));\n child.on(\"close\", () => {\n const clean = out.replace(/\\u001b\\[[0-9;]*m/g, \"\");\n const names: Array<{ name: string; model?: string }> = [];\n for (const line of clean.split(\"\\n\")) {\n const m = line.match(/^\\s*[\\u25c6\\u25cf\\s]*([a-z0-9][a-z0-9_-]*)\\s+(\\S.*)?$/i);\n if (m && m[1] && !/^(Profile|Distribution|Model|Gateway|Alias)$/i.test(m[1])) {\n const rest = (m[2] ?? \"\").trim().split(/\\s{2,}/);\n names.push({ name: m[1], model: rest[0] || undefined });\n }\n }\n resolve(names.length > 0 ? names : [{ name: this.defaultProfile }]);\n });\n });\n }\n\n private probeVersion(): Promise<string | null> {\n return new Promise((resolve) => {\n const child = spawn(this.env.binPath ?? \"hermes\", [\"--version\"]);\n let out = \"\";\n child.stdout.on(\"data\", (d) => (out += d.toString()));\n child.on(\"error\", () => resolve(null));\n child.on(\"close\", (code) => resolve(code === 0 ? out.trim().split(\"\\n\")[0] ?? \"hermes\" : null));\n });\n }\n}\n","import { EventEmitter } from \"node:events\";\n\n/**\n * 可观测性核心(design D34 / bug-bash B5)。\n *\n * 产品理念:可观测性是放权的前提——人愿意让 agent 自动干活,前提是关键时刻能掀盖看里面。\n * 黑盒不可放权,可观测才敢放权。\n *\n * 统一「可观测事件」源头 + 多消费者(结构化日志 / audit 落库 / 指标 / HTTP 端点)。\n */\n\n/** 事件类别。 */\nexport type ObsCategory =\n | \"daemon\" // daemon 起停\n | \"connection\" // 到 server 的连接状态\n | \"adapter\" // adapter 可用性\n | \"session\" // session 生命周期\n | \"turn\" // 一轮对话/任务\n | \"tool\" // agent 工具调用(最贴「agent 在干什么」)\n | \"hitl\" // 人在回路拦截\n | \"stream\" // 流式输出(含自发)\n | \"error\"; // 错误\n\nexport type ObsLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\n/** 统一可观测事件。 */\nexport interface ObsEvent {\n ts: string; // ISO 时间\n category: ObsCategory;\n level: ObsLevel;\n /** 事件名,如 \"session.create\" / \"turn.start\" / \"tool.call\" / \"hitl.fired\"。 */\n event: string;\n /** 关联标识(便于按维度过滤/回溯)。 */\n tenantId?: string;\n sessionId?: string;\n agentId?: string;\n projectId?: string;\n turnId?: string;\n /** 人类可读摘要。 */\n msg?: string;\n /** 结构化附加数据。 */\n data?: Record<string, unknown>;\n}\n\n/**\n * 事件总线:进程内唯一事件源。各组件 emit,多消费者 on。\n */\nexport class ObsBus extends EventEmitter {\n emitEvent(e: Omit<ObsEvent, \"ts\"> & { ts?: string }): void {\n const full: ObsEvent = { ts: e.ts ?? new Date().toISOString(), ...e };\n this.emit(\"event\", full);\n }\n onEvent(handler: (e: ObsEvent) => void): void {\n this.on(\"event\", handler);\n }\n}\n\n/**\n * 极简结构化 JSON logger(零依赖,符合单设备原则)。\n * 从 ObsBus 消费,每事件一行 JSON 写 stdout(或注入的 sink)。\n */\nexport class StructuredLogger {\n private minLevel: ObsLevel;\n private sink: (line: string) => void;\n private static order: Record<ObsLevel, number> = { debug: 0, info: 1, warn: 2, error: 3 };\n\n constructor(opts?: { level?: ObsLevel; sink?: (line: string) => void }) {\n this.minLevel = opts?.level ?? \"info\";\n this.sink = opts?.sink ?? ((l) => process.stdout.write(l + \"\\n\"));\n }\n\n attach(bus: ObsBus): void {\n bus.onEvent((e) => this.write(e));\n }\n\n write(e: ObsEvent): void {\n if (StructuredLogger.order[e.level] < StructuredLogger.order[this.minLevel]) return;\n this.sink(JSON.stringify(e));\n }\n}\n\n/**\n * 实时指标(counters + gauges)。从 ObsBus 消费维护,HTTP /metrics 读取。\n */\nexport class Metrics {\n private counters = new Map<string, number>();\n private gauges = new Map<string, number>();\n private startedAt = Date.now();\n\n attach(bus: ObsBus): void {\n bus.onEvent((e) => this.observe(e));\n }\n\n private observe(e: ObsEvent): void {\n this.inc(`events_total{category=\"${e.category}\"}`);\n if (e.event === \"session.create\") this.inc(\"sessions_created_total\");\n if (e.event === \"session.terminate\") this.inc(\"sessions_terminated_total\");\n if (e.event === \"turn.start\") this.inc(\"turns_started_total\");\n if (e.event === \"turn.end\") this.inc(\"turns_ended_total\");\n if (e.event === \"tool.call\") this.inc(\"tool_calls_total\");\n if (e.event === \"hitl.fired\") this.inc(\"hitl_fired_total\");\n if (e.event.startsWith(\"hitl.\") && e.data?.action === \"abort\") this.inc(\"hitl_blocked_total\");\n if (e.level === \"error\") this.inc(\"errors_total\");\n }\n\n inc(key: string, by = 1): void {\n this.counters.set(key, (this.counters.get(key) ?? 0) + by);\n }\n setGauge(key: string, v: number): void {\n this.gauges.set(key, v);\n }\n\n /** Prometheus 文本格式快照。 */\n prometheus(): string {\n const lines: string[] = [`phonon_uptime_seconds ${Math.floor((Date.now() - this.startedAt) / 1000)}`];\n for (const [k, v] of this.counters) lines.push(`phonon_${k} ${v}`);\n for (const [k, v] of this.gauges) lines.push(`phonon_${k} ${v}`);\n return lines.join(\"\\n\") + \"\\n\";\n }\n\n /** JSON 快照。 */\n json(): Record<string, unknown> {\n return {\n uptimeSeconds: Math.floor((Date.now() - this.startedAt) / 1000),\n counters: Object.fromEntries(this.counters),\n gauges: Object.fromEntries(this.gauges),\n };\n }\n}\n\n/**\n * Audit sink:从 ObsBus 消费 → 落 sqlite audit_events(可观测回溯)。\n */\nexport class AuditSink {\n private store: { auditAdd: (e: { ts: string; category: string; level: string; event: string; tenantId?: string; sessionId?: string; agentId?: string; projectId?: string; turnId?: string; msg?: string; data?: string }) => void };\n constructor(store: { auditAdd: (e: { ts: string; category: string; level: string; event: string; tenantId?: string; sessionId?: string; agentId?: string; projectId?: string; turnId?: string; msg?: string; data?: string }) => void }) {\n this.store = store;\n }\n attach(bus: ObsBus): void {\n bus.onEvent((e) => {\n try {\n this.store.auditAdd({\n ts: e.ts, category: e.category, level: e.level, event: e.event,\n tenantId: e.tenantId, sessionId: e.sessionId, agentId: e.agentId,\n projectId: e.projectId, turnId: e.turnId, msg: e.msg,\n data: e.data ? JSON.stringify(e.data) : undefined,\n });\n } catch {\n /* audit 不能拖垫主流程 */\n }\n });\n }\n}\n","import { spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { writeFileSync, rmSync, mkdtempSync, existsSync } from \"node:fs\";\nimport { tmpdir, homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { dropToolIOFromJsonlFiles } from \"../custom-compress.js\";\nimport type {\n AgentAdapter,\n AdapterSession,\n CreateSessionParams,\n SendOptions,\n} from \"../adapter.js\";\nimport type { AgentCapabilities, AgentDescriptor, StreamEvent, ContextItem, ModelInfo } from \"@agent-phonon/protocol\";\n\n/**\n * Claude Code adapter(design D10,单 agent runtime)。\n *\n * 调用方式(详见 docs/agent-cli-integration.md):\n * claude -p --output-format stream-json --input-format stream-json --verbose\n * --permission-mode bypassPermissions --settings <env-json>\n * [--model X] [--session-id <uuid> | --resume <uuid>]\n * prompt 走 stdin envelope(不是 argv),剥离 CLAUDECODE env,\n * 认证用 --settings 注入完整 ANTHROPIC env 集(CC Switch 范式)。\n *\n * 单 agent runtime:discoverAgents 只返回一个 claude-code。\n */\n\nconst CAPABILITIES: AgentCapabilities = {\n nativeSession: true, // --session-id / --resume\n nativeCompression: false, // 无原生 compact,core custom 兜底\n contextInjection: true, // --append-system-prompt / stdin\n proactiveOutput: false, // 一次性,无自发输出\n modelSwitch: true, // --model 每轮可变\n interrupt: true, // kill 子进程\n injectMidTurn: false,\n skillManagement: true, // Claude Code 有 skills(/skill-name)\n hooks: [\"pre_tool\", \"pre_command\"],\n streaming: true, // stream-json 真流式\n limits: { maxConcurrentSessions: 4 },\n};\n\nexport interface ClaudeCodeEnv {\n /** Claude executable path. Prefer an absolute path when running under systemd/launchd. */\n binPath?: string;\n /** Optional Anthropic-compatible endpoint override. Omit to use the user's native Claude Code login/config. */\n baseUrl?: string;\n /** Optional auth token for baseUrl. Omit to use the user's native Claude Code login/config. */\n authToken?: string;\n /** 默认模型;`default` means let Claude Code use the user's configured default. */\n defaultModel: string;\n /** 可选:由用户配置/上层配置发现到的真实可用模型。 */\n models?: ModelInfo[];\n}\n\n/**\n * 写 settings 到临时 0600 文件(避免 token 进 argv 被 ps 看到,bug-bash#2 B4)。\n * 返回文件路径;调用方负责用后删(cleanup)。\n */\nfunction writeSettingsFile(env: ClaudeCodeEnv, model: string): string | undefined {\n if (!env.baseUrl || !env.authToken) return undefined;\n const dir = mkdtempSync(join(tmpdir(), \"phonon-cc-\"));\n const file = join(dir, \"settings.json\");\n const content = JSON.stringify({\n env: {\n ANTHROPIC_BASE_URL: env.baseUrl,\n ANTHROPIC_AUTH_TOKEN: env.authToken,\n ...(model !== \"default\" ? {\n ANTHROPIC_MODEL: model,\n ANTHROPIC_DEFAULT_OPUS_MODEL: model,\n ANTHROPIC_DEFAULT_SONNET_MODEL: model,\n ANTHROPIC_DEFAULT_HAIKU_MODEL: model,\n } : {}),\n CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: \"1\",\n },\n });\n writeFileSync(file, content, { mode: 0o600 });\n return file;\n}\n\nclass ClaudeCodeSession implements AdapterSession {\n readonly sessionId: string;\n model: string;\n private uuid: string; // Claude Code session UUID\n private cwd: string;\n private env: ClaudeCodeEnv;\n private started = false; // 是否已建过(决定 --session-id vs --resume)\n private current?: ReturnType<typeof spawn>;\n private pendingInject: string[] = [];\n private settingsPath?: string;\n\n /** 本轮 settings 临时文件路径(每次 send 重建,finish 时删)。 */\n private settingsFile(): string | undefined {\n this.settingsPath = writeSettingsFile(this.env, this.model);\n return this.settingsPath;\n }\n\n constructor(sessionId: string, model: string, cwd: string, env: ClaudeCodeEnv) {\n this.sessionId = sessionId;\n this.model = model;\n this.cwd = cwd;\n this.env = env;\n this.uuid = randomUUID();\n }\n\n async send(input: string, opts: SendOptions): Promise<void> {\n const { turnId, emit } = opts;\n let prompt = input;\n if (this.pendingInject.length > 0) {\n prompt = this.pendingInject.join(\"\\n\") + \"\\n\\n\" + prompt;\n this.pendingInject = [];\n }\n if (opts.skills && opts.skills.length > 0) {\n prompt = `[必须本轮加载并使用这些 skill: ${opts.skills.join(\", \")}]\\n\\n${prompt}`;\n }\n\n const args = [\n \"-p\",\n \"--output-format\", \"stream-json\",\n \"--input-format\", \"stream-json\",\n \"--verbose\",\n // 最高权限:bypassPermissions 跳过所有权限确认;不限定 allowedTools = 所有工具可用\n // (phonon 定位:全自动执行,牺牲安全换自动化)\n \"--permission-mode\", \"bypassPermissions\",\n ];\n const settings = this.settingsFile();\n if (settings) args.push(\"--settings\", settings);\n if (this.model !== \"default\") args.push(\"--model\", this.model);\n // 首轮 --session-id,后续 --resume(持续会话)\n if (this.started) args.push(\"--resume\", this.uuid);\n else args.push(\"--session-id\", this.uuid);\n this.started = true;\n\n const envelope = JSON.stringify({\n type: \"user\",\n message: { role: \"user\", content: [{ type: \"text\", text: prompt }] },\n }) + \"\\n\";\n\n await this.run(args, envelope, turnId, emit, opts);\n }\n\n private run(args: string[], stdin: string, turnId: string, emit: (e: StreamEvent) => void, opts: SendOptions): Promise<void> {\n return new Promise((resolve) => {\n // 剥离 CLAUDECODE* env(避免外层污染)\n const childEnv: Record<string, string> = {};\n for (const [k, v] of Object.entries(process.env)) {\n if (k === \"CLAUDECODE\" || k.startsWith(\"CLAUDECODE_\") || k.startsWith(\"CLAUDE_CODE_\")) continue;\n if (v !== undefined) childEnv[k] = v;\n }\n\n const child = spawn(this.env.binPath ?? \"claude\", args, { cwd: this.cwd, env: { ...childEnv, ...(opts.environment ?? {}) } });\n this.current = child;\n let buf = \"\";\n let acc = \"\";\n let settled = false;\n const finish = (status: \"completed\" | \"failed\" | \"interrupted\" | \"timeout\", text: string, message?: string) => {\n if (settled) return;\n settled = true;\n clearTimeout(guard);\n this.current = undefined;\n // 清理 settings 临时文件(含 token)\n if (this.settingsPath) {\n try { rmSync(this.settingsPath, { force: true }); rmSync(join(this.settingsPath, \"..\"), { recursive: true, force: true }); } catch { /* ignore */ }\n this.settingsPath = undefined;\n }\n if (status === \"failed\") {\n emit({ type: \"error\", sessionId: this.sessionId, turnId, seq: 0, at: new Date().toISOString(), message: message ?? \"claude failed\", status: \"failed\", final: true } as StreamEvent);\n } else {\n emit({ type: \"result\", sessionId: this.sessionId, turnId, seq: 0, at: new Date().toISOString(), text, status, final: true } as StreamEvent);\n }\n resolve();\n };\n\n const guard = setTimeout(() => finish(\"timeout\", acc), 1800000);\n opts.signal?.addEventListener(\"abort\", () => { child.kill(\"SIGTERM\"); finish(\"interrupted\", acc); }, { once: true });\n\n child.stdout.on(\"data\", (d) => {\n buf += d.toString();\n let nl;\n while ((nl = buf.indexOf(\"\\n\")) >= 0) {\n const line = buf.slice(0, nl).trim();\n buf = buf.slice(nl + 1);\n if (!line) continue;\n let ev: Record<string, unknown>;\n try { ev = JSON.parse(line); } catch { continue; }\n this.handleStreamEvent(ev, turnId, emit, (t) => (acc += t));\n }\n });\n child.stderr.on(\"data\", () => { /* stream-json 已含错误 */ });\n child.on(\"error\", (e) => finish(\"failed\", \"\", e.message));\n child.on(\"close\", (code) => {\n if (settled) return;\n finish(code === 0 ? \"completed\" : \"failed\", acc, code !== 0 ? `claude exited ${code}` : undefined);\n });\n\n child.stdin.write(stdin);\n child.stdin.end();\n });\n }\n\n /** 解析 Claude Code stream-json 事件 → phonon StreamEvent(流式 + 工具)。 */\n private handleStreamEvent(ev: Record<string, unknown>, turnId: string, emit: (e: StreamEvent) => void, addText: (t: string) => void): void {\n const now = new Date().toISOString();\n const type = ev.type as string;\n if (type === \"assistant\") {\n const msg = ev.message as { content?: Array<Record<string, unknown>> } | undefined;\n for (const block of msg?.content ?? []) {\n if (block.type === \"text\" && typeof block.text === \"string\") {\n addText(block.text);\n emit({ type: \"message\", sessionId: this.sessionId, turnId, seq: 0, at: now, role: \"assistant\", text: block.text, delta: true } as StreamEvent);\n } else if (block.type === \"tool_use\") {\n emit({ type: \"tool_call\", sessionId: this.sessionId, turnId, seq: 0, at: now, toolName: String(block.name ?? \"?\"), args: block.input, toolCallId: String(block.id ?? \"\") } as StreamEvent);\n }\n }\n } else if (type === \"user\") {\n // tool_result 回传\n const msg = ev.message as { content?: Array<Record<string, unknown>> } | undefined;\n for (const block of msg?.content ?? []) {\n if (block.type === \"tool_result\") {\n emit({ type: \"tool_result\", sessionId: this.sessionId, turnId, seq: 0, at: now, toolName: \"\", toolCallId: String(block.tool_use_id ?? \"\"), ok: !block.is_error, output: block.content } as StreamEvent);\n }\n }\n }\n // type === \"result\" 由 close 统一收尾(避免重复终态)\n }\n\n async compressCustom(strategy = \"dropToolIO\", options?: { keepRecentToolCalls?: number }): Promise<{ summary?: string; filesChanged?: number; recordsChanged?: number; blocksRemoved?: number; bytesBefore?: number; bytesAfter?: number; backups?: string[] }> {\n if (strategy !== \"dropToolIO\") throw new Error(`unsupported custom compression strategy: ${strategy}`);\n const file = this.resolveSessionFile();\n if (!file) throw new Error(`Claude Code session file not found for ${this.uuid}`);\n const r = await dropToolIOFromJsonlFiles([file], options);\n return { summary: `dropToolIO removed ${r.blocksRemoved} tool blocks from ${r.filesChanged} files`, ...r };\n }\n\n private resolveSessionFile(): string | undefined {\n const projectDir = this.cwd.replace(/\\\\/g, \"-\").replace(/\\//g, \"-\");\n const file = join(homedir(), \".claude\", \"projects\", projectDir, `${this.uuid}.jsonl`);\n return existsSync(file) ? file : undefined;\n }\n\n async interrupt(): Promise<void> {\n if (this.current) { this.current.kill(\"SIGTERM\"); this.current = undefined; }\n }\n async switchModel(model: string): Promise<{ warnings?: string[] }> { this.model = model; return {}; }\n async inject(context: ContextItem[]): Promise<void> {\n for (const c of context) this.pendingInject.push(`[${c.role}] ${c.content}`);\n }\n async terminate(): Promise<void> { await this.interrupt(); }\n}\n\nexport class ClaudeCodeAdapter implements AgentAdapter {\n readonly name = \"claude-code\";\n readonly capabilities = CAPABILITIES;\n private env: ClaudeCodeEnv;\n\n constructor(opts: { env: ClaudeCodeEnv }) {\n this.env = opts.env;\n }\n\n async discoverAgents(): Promise<AgentDescriptor[]> {\n const version = await this.probeVersion();\n const available = version !== null;\n return [{\n agentId: \"claude-code\" as AgentDescriptor[\"agentId\"],\n displayName: \"Claude Code\",\n adapter: \"claude-code\",\n available,\n ...(available ? {} : { unavailableReason: \"claude CLI not found\" }),\n ...(version ? { version } : {}),\n models: this.env.models?.length\n ? this.env.models\n : [{ id: this.env.defaultModel, available: true }],\n capabilities: CAPABILITIES,\n scannedAt: new Date().toISOString(),\n }];\n }\n\n async createSession(params: CreateSessionParams): Promise<AdapterSession> {\n return new ClaudeCodeSession(params.sessionId, params.model, params.cwd, this.env);\n }\n\n private probeVersion(): Promise<string | null> {\n return new Promise((resolve) => {\n const child = spawn(this.env.binPath ?? \"claude\", [\"--version\"]);\n let out = \"\";\n child.stdout.on(\"data\", (d) => (out += d.toString()));\n child.on(\"error\", () => resolve(null));\n child.on(\"close\", (code) => resolve(code === 0 ? out.trim() : null));\n });\n }\n}\n","import { readFileSync, existsSync, mkdirSync, writeFileSync, chmodSync } from \"node:fs\";\nimport type { ModelInfo } from \"@agent-phonon/protocol\";\nimport { homedir, hostname } from \"node:os\";\nimport { join, dirname } from \"node:path\";\n\n/**\n * daemon 配置(bug-bash B4)。\n *\n * 一个 daemon 进程:一个设备 id、一个共享 sqlite、一个 HookBridge,\n * 注册若干 adapter,连接若干 server(每个 server = 一个 tenant 连接)。\n */\nexport interface ServerConfig {\n /** 服务端 ws/http URL。 */\n url: string;\n /** 本地自用放宽 policy(默认 false)。 */\n trustLocal?: boolean;\n /** 该连接的可选 device key(鉴权由 server 做,phonon 仅携带)。 */\n deviceKey?: string;\n}\n\nexport interface AdapterConfig {\n /** adapter 类型:openclaw-gateway | openclaw-cli。 */\n type: \"openclaw-gateway\" | \"openclaw-cli\" | \"claude-code\" | \"codex\" | \"hermes\" | \"opencode\";\n /** OpenClaw Gateway WS URL(openclaw-gateway 用)。 */\n gatewayUrl?: string;\n /** Gateway token(openclaw-gateway 用;缺省从 ~/.openclaw/openclaw.json 读)。 */\n gatewayToken?: string;\n /** 默认 OpenClaw sub-agent。 */\n defaultAgent?: string;\n /** claude-code:网关 baseUrl/token/默认模型。 */\n claudeBinPath?: string;\n claudeBaseUrl?: string;\n claudeAuthToken?: string;\n claudeDefaultModel?: string;\n claudeModels?: ModelInfo[];\n /** codex:网关 baseUrl(/v1)/key/默认模型/wireApi。 */\n codexBinPath?: string;\n codexBaseUrl?: string;\n codexApiKey?: string;\n codexDefaultModel?: string;\n codexModels?: ModelInfo[];\n codexWireApi?: \"responses\" | \"chat\";\n /** hermes:默认模型/provider(用现有 hermes config)。 */\n hermesBinPath?: string;\n hermesModel?: string;\n hermesProvider?: string;\n /** opencode:binary 路径/默认模型。 */\n opencodeBinPath?: string;\n opencodeModel?: string;\n}\n\nexport interface DaemonConfig {\n deviceId: string;\n /** sqlite 文件路径。 */\n dbPath: string;\n /** 受控项目根。 */\n workspaceRoot: string;\n /** 结构化日志级别。 */\n logLevel?: \"debug\" | \"info\" | \"warn\" | \"error\";\n hookBridge?: { port?: number; token?: string };\n /** 可观测 HTTP 服务。 */\n obs?: { enabled?: boolean; port?: number; token?: string };\n adapters: AdapterConfig[];\n servers: ServerConfig[];\n}\n\nconst DEFAULT_DIR = join(homedir(), \".agent-phonon\");\nexport const DEFAULT_CONFIG_PATH = process.env.PHONON_CONFIG ?? join(DEFAULT_DIR, \"config.json\");\n\nexport function defaultConfig(): DaemonConfig {\n return {\n deviceId: `dev-${hostname()}`,\n dbPath: join(DEFAULT_DIR, \"phonon.db\"),\n workspaceRoot: join(homedir(), \"phonon-projects\"),\n hookBridge: { port: 4318 },\n obs: { enabled: true, port: 4319 },\n adapters: [{ type: \"openclaw-gateway\", gatewayUrl: \"ws://127.0.0.1:18789\", defaultAgent: \"main\" }],\n servers: [],\n };\n}\n\nexport function loadConfig(path = DEFAULT_CONFIG_PATH): DaemonConfig {\n if (!existsSync(path)) {\n throw new Error(`config not found at ${path} — run 'agent-phonon init' first`);\n }\n const raw = JSON.parse(readFileSync(path, \"utf8\")) as Partial<DaemonConfig>;\n const d = defaultConfig();\n return {\n deviceId: raw.deviceId ?? d.deviceId,\n dbPath: raw.dbPath ?? d.dbPath,\n workspaceRoot: raw.workspaceRoot ?? d.workspaceRoot,\n hookBridge: { ...d.hookBridge, ...raw.hookBridge },\n obs: { ...d.obs, ...raw.obs },\n logLevel: raw.logLevel ?? d.logLevel,\n adapters: raw.adapters ?? d.adapters,\n servers: raw.servers ?? d.servers,\n };\n}\n\nexport function writeConfig(cfg: DaemonConfig, path = DEFAULT_CONFIG_PATH): void {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(cfg, null, 2), { mode: 0o600 });\n try { chmodSync(path, 0o600); } catch { /* best-effort */ } // 含 token,限制权限(bug-bash#2)\n}\n\n/** 脱敏配置(用于打印/日志,不露 token/key)。 */\nexport function redactConfig(cfg: DaemonConfig): DaemonConfig {\n const mask = (v?: string): string | undefined => (v ? `***${v.slice(-4)}` : v);\n return {\n ...cfg,\n hookBridge: cfg.hookBridge ? { ...cfg.hookBridge, token: mask(cfg.hookBridge.token) } : cfg.hookBridge,\n obs: cfg.obs ? { ...cfg.obs, token: mask(cfg.obs.token) } : cfg.obs,\n adapters: cfg.adapters.map((a) => ({\n ...a,\n gatewayToken: mask(a.gatewayToken),\n claudeAuthToken: mask(a.claudeAuthToken),\n codexApiKey: mask(a.codexApiKey),\n })),\n servers: cfg.servers.map((s) => ({ ...s, deviceKey: mask(s.deviceKey) })),\n };\n}\n\n/** 从 ~/.openclaw/openclaw.json 读 Gateway token(adapter 缺省)。 */\nexport function readOpenClawGatewayToken(): string | undefined {\n try {\n const p = join(homedir(), \".openclaw\", \"openclaw.json\");\n const cfg = JSON.parse(readFileSync(p, \"utf8\"));\n return cfg?.gateway?.auth?.token;\n } catch {\n return undefined;\n }\n}\n","import { spawnSync } from \"node:child_process\";\nimport { existsSync, cpSync, mkdirSync, rmSync, writeFileSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { AdapterRegistry, OpenClawGatewayAdapter, ClaudeCodeAdapter, CodexAdapter, HermesAdapter, OpenCodeAdapter } from \"@agent-phonon/core\";\nimport { loadConfig, writeConfig, readOpenClawGatewayToken, type AdapterConfig, type DaemonConfig } from \"./config.js\";\n\n/**\n * CLI 辅助命令(让 phonon 真正可用):doctor / discover / adapter / plugin。\n */\n\nfunction probe(bin: string, args: string[] = [\"--version\"]): { ok: boolean; out: string } {\n const r = spawnSync(bin, args, { timeout: 8000 });\n return { ok: r.status === 0, out: (r.stdout?.toString() ?? \"\").trim().split(\"\\n\")[0] ?? \"\" };\n}\n\nfunction commandPath(bin: string): string | undefined {\n const candidates = [\n join(homedir(), \".npm-global\", \"bin\", bin),\n join(homedir(), \".local\", \"bin\", bin),\n join(homedir(), \".bun\", \"bin\", bin),\n join(homedir(), \".cargo\", \"bin\", bin),\n `/opt/homebrew/bin/${bin}`,\n `/usr/local/bin/${bin}`,\n `/usr/bin/${bin}`,\n ];\n for (const p of candidates) if (existsSync(p)) return p;\n const r = spawnSync(\"bash\", [\"-lc\", `command -v ${bin}`], { timeout: 3000 });\n const out = (r.stdout?.toString() ?? \"\").trim().split(\"\\n\")[0];\n return r.status === 0 && out ? out : undefined;\n}\n\nfunction gatewayReachable(url: string): boolean {\n // 简单 TCP 探测:用 node 连一下 ws 端口\n try {\n const u = new URL(url.replace(/^ws/, \"http\"));\n const r = spawnSync(\"bash\", [\"-c\", `exec 3<>/dev/tcp/${u.hostname}/${u.port || 80} && echo ok`], { timeout: 3000 });\n return r.status === 0;\n } catch {\n return false;\n }\n}\n\nfunction openCodeBin(): string {\n const bundled = join(homedir(), \".opencode\", \"bin\", \"opencode\");\n return existsSync(bundled) ? bundled : \"opencode\";\n}\n\nexport function autoDetectAdapters(adapters: AdapterConfig[]): AdapterConfig[] {\n const out = [...adapters];\n const has = (type: AdapterConfig[\"type\"]): boolean => out.some((a) => a.type === type);\n\n if (!has(\"hermes\")) {\n const hermesPath = commandPath(\"hermes\");\n if (hermesPath && probe(hermesPath).ok) out.push({ type: \"hermes\", hermesBinPath: hermesPath });\n }\n\n const ocBin = openCodeBin();\n if (!has(\"opencode\") && probe(ocBin).ok) out.push({ type: \"opencode\", opencodeBinPath: ocBin === \"opencode\" ? undefined : ocBin });\n\n for (const a of out) {\n if (a.type === \"hermes\" && !a.hermesBinPath) a.hermesBinPath = commandPath(\"hermes\");\n if (a.type === \"claude-code\" && !a.claudeBinPath) a.claudeBinPath = commandPath(\"claude\");\n if (a.type === \"codex\" && !a.codexBinPath) a.codexBinPath = commandPath(\"codex\");\n }\n\n if (!has(\"claude-code\")) {\n const claudePath = commandPath(\"claude\");\n if (claudePath && probe(claudePath).ok) out.push({ type: \"claude-code\", claudeBinPath: claudePath, claudeDefaultModel: \"default\" });\n }\n if (!has(\"codex\")) {\n const codexPath = commandPath(\"codex\");\n if (codexPath && probe(codexPath).ok) out.push({ type: \"codex\", codexBinPath: codexPath, codexDefaultModel: \"default\" });\n }\n\n return out;\n}\n\n/** doctor:体检本机 agent 可用性 + Gateway + 插件。 */\nexport function cmdDoctor(): void {\n console.log(\"agent-phonon doctor\\n\");\n // OpenClaw Gateway\n const gwToken = readOpenClawGatewayToken();\n const gwUrl = \"ws://127.0.0.1:18789\";\n const gwOk = gatewayReachable(gwUrl);\n console.log(`OpenClaw Gateway (${gwUrl}): ${gwOk ? \"✓ reachable\" : \"✗ unreachable\"}${gwToken ? \" (token found)\" : \" (no token in ~/.openclaw/openclaw.json)\"}`);\n // OpenClaw plugin\n const pluginDir = join(homedir(), \".openclaw\", \"extensions\", \"agent-phonon-hitl\");\n console.log(`OpenClaw HITL plugin: ${existsSync(pluginDir) ? \"✓ installed\" : \"✗ not installed (run: agent-phonon plugin install openclaw)\"}`);\n // CLI agents\n console.log(\"\\nCLI agents:\");\n for (const [name, bin] of [[\"Claude Code\", \"claude\"], [\"Codex\", \"codex\"], [\"Hermes\", \"hermes\"]] as const) {\n const p = probe(bin);\n console.log(` ${name} (${bin}): ${p.ok ? \"✓ \" + p.out : \"✗ not found\"}`);\n }\n // OpenCode (often not in PATH)\n const ocBin = openCodeBin();\n const oc = probe(ocBin);\n console.log(` OpenCode (${ocBin}): ${oc.ok ? \"✓ \" + oc.out : \"✗ not found\"}`);\n // config\n console.log(\"\");\n try {\n const cfg = loadConfig();\n const effective = autoDetectAdapters(cfg.adapters);\n console.log(`config: ${cfg.adapters.length} configured adapter(s), ${effective.length} effective adapter(s), ${cfg.servers.length} server(s)`);\n } catch {\n console.log(\"config: not initialized (run: agent-phonon init)\");\n }\n}\n\n/** discover:不启 daemon,直接列本机可用 agent(按已配 adapter)。 */\nexport async function cmdDiscover(): Promise<void> {\n let cfg: DaemonConfig;\n try { cfg = loadConfig(); } catch { console.error(\"config not initialized — run 'agent-phonon init' first\"); process.exit(1); return; }\n const reg = buildRegistry(cfg.adapters);\n const nested = await Promise.all(reg.all().map((a) => a.discoverAgents()));\n const agents = nested.flat();\n console.log(`discovered ${agents.length} agent(s):\\n`);\n for (const a of agents) {\n console.log(` ${a.available ? \"✓\" : \"✗\"} ${a.agentId} (${a.displayName})${a.available ? \"\" : \" — \" + (a.unavailableReason ?? \"unavailable\")}`);\n if (a.models.length) console.log(` models: ${a.models.map((m) => m.id).join(\", \")}`);\n }\n}\n\n/** 从 adapter 配置构造 registry(discover/doctor 用)。 */\nexport function buildRegistry(adapters: AdapterConfig[]): AdapterRegistry {\n const reg = new AdapterRegistry();\n for (const a of autoDetectAdapters(adapters)) {\n if (a.type === \"openclaw-gateway\") {\n const token = a.gatewayToken ?? readOpenClawGatewayToken();\n if (token) reg.register(new OpenClawGatewayAdapter({ gateway: { baseUrl: a.gatewayUrl ?? \"ws://127.0.0.1:18789\", token }, defaultAgent: a.defaultAgent ?? \"main\" }));\n } else if (a.type === \"claude-code\") {\n reg.register(new ClaudeCodeAdapter({ env: { binPath: a.claudeBinPath, baseUrl: a.claudeBaseUrl, authToken: a.claudeAuthToken, defaultModel: a.claudeDefaultModel ?? \"default\", models: a.claudeModels } }));\n } else if (a.type === \"codex\") {\n reg.register(new CodexAdapter({ env: { binPath: a.codexBinPath, baseUrl: a.codexBaseUrl, apiKey: a.codexApiKey, defaultModel: a.codexDefaultModel ?? \"default\", models: a.codexModels, wireApi: a.codexWireApi ?? \"responses\" } }));\n } else if (a.type === \"hermes\") {\n reg.register(new HermesAdapter({ env: { binPath: a.hermesBinPath, defaultModel: a.hermesModel, provider: a.hermesProvider } }));\n } else if (a.type === \"opencode\") {\n reg.register(new OpenCodeAdapter({ env: { binPath: a.opencodeBinPath, defaultModel: a.opencodeModel } }));\n }\n }\n return reg;\n}\n\n/** adapter add:往 config 加一个 adapter。 */\nexport function cmdAdapterAdd(type: string, opts: Record<string, string | undefined>): void {\n const cfg = loadConfig();\n let a: AdapterConfig;\n switch (type) {\n case \"openclaw\":\n case \"openclaw-gateway\":\n a = { type: \"openclaw-gateway\", gatewayUrl: opts.gatewayUrl ?? \"ws://127.0.0.1:18789\", gatewayToken: opts.token, defaultAgent: opts.defaultAgent ?? \"main\" };\n break;\n case \"claude-code\":\n a = { type: \"claude-code\", claudeBinPath: opts.bin, claudeBaseUrl: opts.baseUrl, claudeAuthToken: opts.token, claudeDefaultModel: opts.model ?? \"default\" };\n break;\n case \"codex\":\n a = { type: \"codex\", codexBinPath: opts.bin, codexBaseUrl: opts.baseUrl, codexApiKey: opts.apiKey, codexDefaultModel: opts.model ?? \"default\", codexWireApi: (opts.wireApi as \"responses\" | \"chat\") ?? \"responses\" };\n break;\n case \"hermes\":\n a = { type: \"hermes\", hermesBinPath: opts.bin, hermesModel: opts.model, hermesProvider: opts.provider };\n break;\n case \"opencode\":\n a = { type: \"opencode\", opencodeBinPath: opts.bin, opencodeModel: opts.model };\n break;\n default:\n return fail(`unknown adapter type: ${type} (openclaw|claude-code|codex|hermes|opencode)`);\n }\n // 去重:同 type 覆盖\n cfg.adapters = cfg.adapters.filter((x) => x.type !== a.type);\n cfg.adapters.push(a);\n writeConfig(cfg);\n console.log(`added ${a.type} adapter (${cfg.adapters.length} total)`);\n}\n\nexport function cmdAdapterList(): void {\n const cfg = loadConfig();\n const effective = autoDetectAdapters(cfg.adapters);\n if (effective.length === 0) { console.log(\"(no adapters available)\"); return; }\n for (const a of effective) {\n const auto = cfg.adapters.some((x) => x.type === a.type) ? \"\" : \" [auto]\";\n console.log(`- ${a.type}${a.defaultAgent ? ` (agent: ${a.defaultAgent})` : \"\"}${auto}`);\n }\n}\n\n/** plugin install:装 OpenClaw HITL 插件(导出干净产物 + force 安装)。 */\nexport function cmdPluginInstall(which: string): void {\n if (which !== \"openclaw\") return fail(`plugin install supports: openclaw (got: ${which})`);\n // 找到 monorepo 里的 openclaw-plugin 包\n const here = dirname(fileURLToPath(import.meta.url));\n const pluginSrc = join(here, \"..\", \"..\", \"openclaw-plugin\");\n if (!existsSync(join(pluginSrc, \"dist\", \"index.js\"))) {\n return fail(`plugin not built. Run: cd ${pluginSrc} && pnpm build`);\n }\n // 导出干净产物(避免 pnpm workspace node_modules symlink 触发安全扫描)\n const dist = join(homedir(), \".agent-phonon\", \"openclaw-plugin-dist\");\n rmSync(dist, { recursive: true, force: true });\n mkdirSync(dist, { recursive: true });\n cpSync(join(pluginSrc, \"dist\"), join(dist, \"dist\"), { recursive: true });\n cpSync(join(pluginSrc, \"openclaw.plugin.json\"), join(dist, \"openclaw.plugin.json\"));\n const pkg = JSON.parse(readFileSync(join(pluginSrc, \"package.json\"), \"utf8\")) as Record<string, unknown>;\n delete pkg.devDependencies;\n writeFileSync(join(dist, \"package.json\"), JSON.stringify(pkg, null, 2));\n console.log(`exported clean plugin → ${dist}`);\n const r = spawnSync(\"openclaw\", [\"plugins\", \"install\", \"--force\", dist], { stdio: \"inherit\" });\n if (r.status === 0) console.log(\"\\n✓ installed. Restart OpenClaw Gateway to load: systemctl --user restart openclaw-gateway.service\");\n else fail(\"openclaw plugins install failed\");\n}\n\nfunction fail(msg: string): void {\n console.error(\"error:\", msg);\n process.exit(1);\n}\n","import { createServer, type Server } from \"node:http\";\nimport type { ObsBus, ObsEvent, Metrics, PhononStore } from \"@agent-phonon/core\";\n\n/**\n * 可观测性 HTTP 服务(design D34 / B5)。\n *\n * 产品理念:可观测性是放权的前提。人放权让 agent 自动干活,但关键时刻要能掀盖看里面。\n *\n * 端点:\n * GET /health daemon/连接/db/adapter 健康(人/监控看「活没活」)\n * GET /metrics Prometheus 文本指标\n * GET /metrics.json JSON 指标\n * GET /sessions 当前每个 agent 在干什么的实时快照(「不是黑盒」的心脏)\n * GET /events 审计时间线(最近 N 条,可 ?session= ?category= 过滤)\n * GET /stream SSE 实时事件流(人盯着看 agent 实时动作)\n */\nexport interface ObsServerDeps {\n bus: ObsBus;\n metrics: Metrics;\n store: PhononStore;\n /** 健康快照提供者(daemon 注入)。 */\n health: () => Record<string, unknown>;\n /** 所有连接的 session 快照(daemon 注入)。 */\n sessions: () => Array<Record<string, unknown>>;\n /** 可选 bearer token。 */\n token?: string;\n}\n\nexport class ObsServer {\n private server?: Server;\n private deps: ObsServerDeps;\n private actualPort = 0;\n /** SSE 客户端。 */\n private sseClients = new Set<import(\"node:http\").ServerResponse>();\n\n constructor(deps: ObsServerDeps) {\n this.deps = deps;\n // 实时事件广播到 SSE 客户端\n deps.bus.onEvent((e: ObsEvent) => this.broadcast(e));\n }\n\n listen(port = 4319, host = \"127.0.0.1\"): Promise<number> {\n return new Promise((resolve) => {\n const server = createServer((req, res) => this.handle(req, res));\n this.server = server;\n server.listen(port, host, () => {\n const addr = server.address();\n this.actualPort = typeof addr === \"object\" && addr ? addr.port : port;\n resolve(this.actualPort);\n });\n });\n }\n\n private authed(req: import(\"node:http\").IncomingMessage): boolean {\n if (!this.deps.token) return true;\n return req.headers[\"authorization\"] === `Bearer ${this.deps.token}`;\n }\n\n private handle(req: import(\"node:http\").IncomingMessage, res: import(\"node:http\").ServerResponse): void {\n const url = new URL(req.url ?? \"/\", \"http://localhost\");\n const path = url.pathname;\n\n if (!this.authed(req)) {\n res.writeHead(401).end(\"unauthorized\");\n return;\n }\n\n if (path === \"/health\") {\n const h = this.deps.health();\n const ok = h.ok !== false;\n res.writeHead(ok ? 200 : 503, { \"content-type\": \"application/json\" }).end(JSON.stringify(h, null, 2));\n return;\n }\n if (path === \"/metrics\") {\n res.writeHead(200, { \"content-type\": \"text/plain; version=0.0.4\" }).end(this.deps.metrics.prometheus());\n return;\n }\n if (path === \"/metrics.json\") {\n res.writeHead(200, { \"content-type\": \"application/json\" }).end(JSON.stringify(this.deps.metrics.json(), null, 2));\n return;\n }\n if (path === \"/sessions\") {\n res.writeHead(200, { \"content-type\": \"application/json\" }).end(JSON.stringify(this.deps.sessions(), null, 2));\n return;\n }\n if (path === \"/events\") {\n const rows = this.deps.store.auditQuery({\n sessionId: url.searchParams.get(\"session\") ?? undefined,\n category: url.searchParams.get(\"category\") ?? undefined,\n limit: Number(url.searchParams.get(\"limit\") ?? 200),\n });\n res.writeHead(200, { \"content-type\": \"application/json\" }).end(JSON.stringify(rows, null, 2));\n return;\n }\n if (path === \"/stream\") {\n res.writeHead(200, {\n \"content-type\": \"text/event-stream\",\n \"cache-control\": \"no-cache\",\n connection: \"keep-alive\",\n });\n res.write(\": connected\\n\\n\");\n this.sseClients.add(res);\n req.on(\"close\", () => this.sseClients.delete(res));\n return;\n }\n if (path === \"/\") {\n res.writeHead(200, { \"content-type\": \"application/json\" }).end(\n JSON.stringify({ service: \"agent-phonon obs\", endpoints: [\"/health\", \"/metrics\", \"/metrics.json\", \"/sessions\", \"/events\", \"/stream\"] }, null, 2),\n );\n return;\n }\n res.writeHead(404).end(\"not found\");\n }\n\n private broadcast(e: ObsEvent): void {\n if (this.sseClients.size === 0) return;\n const line = `data: ${JSON.stringify(e)}\\n\\n`;\n for (const c of this.sseClients) {\n try {\n c.write(line);\n } catch {\n this.sseClients.delete(c);\n }\n }\n }\n\n get port(): number {\n return this.actualPort;\n }\n\n close(): Promise<void> {\n return new Promise((resolve) => {\n for (const c of this.sseClients) c.end();\n this.sseClients.clear();\n if (!this.server) return resolve();\n this.server.close(() => resolve());\n });\n }\n}\n","import {\n AdapterRegistry,\n PhononClient,\n PhononStore,\n HookBridge,\n OpenClawGatewayAdapter,\n OpenClawAdapter,\n ClaudeCodeAdapter,\n CodexAdapter,\n HermesAdapter,\n OpenCodeAdapter,\n ObsBus,\n StructuredLogger,\n Metrics,\n AuditSink,\n type PhononConnection,\n} from \"@agent-phonon/core\";\nimport { type DaemonConfig, readOpenClawGatewayToken } from \"./config.js\";\nimport { autoDetectAdapters } from \"./commands.js\";\nimport { ObsServer } from \"./obs-server.js\";\n\n/**\n * PhononDaemon(bug-bash B4):设备侧常驻服务。\n *\n * 一个进程管理:共享 sqlite store、adapter registry、HookBridge,\n * 以及到多个 server 的多条 PhononClient 连接(每个 server = 一个 tenant)。\n *\n * HookBridge 跨所有连接路由:sessionKey → 找到 owns 该 session 的连接。\n */\nexport class PhononDaemon {\n private cfg: DaemonConfig;\n private store: PhononStore;\n private registry = new AdapterRegistry();\n private clients: PhononClient[] = [];\n private bridge?: HookBridge;\n private gatewayAdapters: OpenClawGatewayAdapter[] = [];\n private obs = new ObsBus();\n private metrics = new Metrics();\n private obsServer?: ObsServer;\n private startedAt = Date.now();\n\n constructor(cfg: DaemonConfig) {\n this.cfg = cfg;\n this.store = new PhononStore(cfg.dbPath);\n // 可观测堆栈:结构化日志 + 指标 + audit 落库,都从同一 ObsBus 消费\n new StructuredLogger({ level: cfg.logLevel ?? \"info\" }).attach(this.obs);\n this.metrics.attach(this.obs);\n new AuditSink(this.store).attach(this.obs);\n this.registerAdapters();\n }\n\n private registerAdapters(): void {\n for (const a of autoDetectAdapters(this.cfg.adapters)) {\n if (a.type === \"openclaw-gateway\") {\n const token = a.gatewayToken ?? readOpenClawGatewayToken();\n if (!token) {\n console.warn(\"[daemon] openclaw-gateway adapter skipped: no Gateway token\");\n continue;\n }\n const ad = new OpenClawGatewayAdapter({\n gateway: { baseUrl: a.gatewayUrl ?? \"ws://127.0.0.1:18789\", token },\n defaultAgent: a.defaultAgent ?? \"main\",\n });\n this.gatewayAdapters.push(ad);\n this.registry.register(ad);\n } else if (a.type === \"claude-code\") {\n this.registry.register(new ClaudeCodeAdapter({ env: { binPath: a.claudeBinPath, baseUrl: a.claudeBaseUrl, authToken: a.claudeAuthToken, defaultModel: a.claudeDefaultModel ?? \"default\", models: a.claudeModels } }));\n } else if (a.type === \"codex\") {\n this.registry.register(new CodexAdapter({ env: { binPath: a.codexBinPath, baseUrl: a.codexBaseUrl, apiKey: a.codexApiKey, defaultModel: a.codexDefaultModel ?? \"default\", models: a.codexModels, wireApi: a.codexWireApi ?? \"responses\" } }));\n } else if (a.type === \"hermes\") {\n this.registry.register(new HermesAdapter({ env: { binPath: a.hermesBinPath, defaultModel: a.hermesModel, provider: a.hermesProvider } }));\n } else if (a.type === \"opencode\") {\n this.registry.register(new OpenCodeAdapter({ env: { binPath: a.opencodeBinPath, defaultModel: a.opencodeModel } }));\n } else if (a.type === \"openclaw-cli\") {\n this.registry.register(new OpenClawAdapter({ defaultAgent: a.defaultAgent ?? \"main\" }));\n }\n }\n }\n\n /** 启动:起 HookBridge + 连所有 server(带自动重连)。 */\n async start(): Promise<void> {\n this.obs.emitEvent({ category: \"daemon\", level: \"info\", event: \"daemon.start\", msg: `device=${this.cfg.deviceId}` });\n\n // HookBridge:跨所有连接路由 sessionKey\n this.bridge = new HookBridge(\n (sessionKey: string) => this.routeHook(sessionKey),\n this.cfg.hookBridge?.token ? { token: this.cfg.hookBridge.token } : undefined,\n );\n const port = await this.bridge.listen(this.cfg.hookBridge?.port ?? 4318);\n console.log(`[daemon] HookBridge on :${port}`);\n\n // 可观测 HTTP 服务(人/监控看状态)\n if (this.cfg.obs?.enabled !== false) {\n this.obsServer = new ObsServer({\n bus: this.obs,\n metrics: this.metrics,\n store: this.store,\n token: this.cfg.obs?.token,\n health: () => this.health(),\n sessions: () => this.allSessions(),\n });\n const obsPort = await this.obsServer.listen(this.cfg.obs?.port ?? 4319);\n console.log(`[daemon] obs server on http://127.0.0.1:${obsPort} (/health /metrics /sessions /events /stream)`);\n }\n\n if (this.cfg.servers.length === 0) {\n console.warn(\"[daemon] no servers configured — idle. Add servers to config and restart.\");\n }\n for (const s of this.cfg.servers) {\n const client = new PhononClient({\n serverUrl: s.url,\n deviceId: this.cfg.deviceId,\n registry: this.registry,\n store: this.store,\n obs: this.obs,\n trustLocal: s.trustLocal,\n workspaceRoot: this.cfg.workspaceRoot,\n deviceKey: s.deviceKey,\n resolveProjectCwd: (p) => p,\n });\n this.clients.push(client);\n void client.start(); // 长期运行 + 自动重连\n this.obs.emitEvent({ category: \"connection\", level: \"info\", event: \"connection.dial\", msg: `connecting to ${s.url}` });\n console.log(`[daemon] connecting to ${s.url}…`);\n }\n }\n\n /** 健康快照(/health)。 */\n private health(): Record<string, unknown> {\n const connections = this.clients.map((c, i) => ({\n server: this.cfg.servers[i]?.url,\n connected: !!c.connection,\n outboxSize: c.connection?.outboxSize ?? 0,\n }));\n const anyDown = connections.some((c) => !c.connected) && this.cfg.servers.length > 0;\n return {\n ok: !anyDown,\n deviceId: this.cfg.deviceId,\n uptimeSeconds: Math.floor((Date.now() - this.startedAt) / 1000),\n adapters: this.registry.all().map((a) => a.name),\n connections,\n hookBridge: !!this.bridge,\n };\n }\n\n /** 所有连接的 session 快照(/sessions)。 */\n private allSessions(): Array<Record<string, unknown>> {\n const out: Array<Record<string, unknown>> = [];\n for (const c of this.clients) {\n const conn = c.connection;\n if (conn) out.push(...conn.sessionsSnapshot());\n }\n return out;\n }\n\n /** 可观测 HTTP 服务实际端口(测试/外部查询)。 */\n get obsPort(): number {\n return this.obsServer?.port ?? 0;\n }\n\n /** HookBridge 路由:找到 owns 该 session 的连接。sessionKey 形如 agent:<sub>:phonon-<sessionId>。 */\n private routeHook(sessionKey: string): { conn: PhononConnection; sessionId: string } | undefined {\n const m = sessionKey.match(/phonon-(s-\\d+-\\d+)$/);\n const sessionId = m?.[1];\n if (!sessionId) return undefined;\n for (const c of this.clients) {\n const conn = c.connection;\n if (conn?.ownsSession(sessionId)) return { conn, sessionId };\n }\n return undefined;\n }\n\n async stop(): Promise<void> {\n this.obs.emitEvent({ category: \"daemon\", level: \"info\", event: \"daemon.stop\" });\n for (const c of this.clients) c.close();\n for (const a of this.gatewayAdapters) a.close();\n await this.bridge?.close();\n await this.obsServer?.close();\n this.store.close();\n }\n}\n","#!/usr/bin/env node\nimport { PhononDaemon } from \"./daemon.js\";\nimport {\n loadConfig,\n defaultConfig,\n writeConfig,\n redactConfig,\n DEFAULT_CONFIG_PATH,\n type DaemonConfig,\n} from \"./config.js\";\nimport { existsSync } from \"node:fs\";\nimport { cmdDoctor, cmdDiscover, cmdAdapterAdd, cmdAdapterList, cmdPluginInstall } from \"./commands.js\";\n\n/**\n * agent-phonon CLI(bug-bash B4)。\n * agent-phonon init 生成默认配置\n * agent-phonon start 启动 daemon(前台;systemd 托管)\n * agent-phonon server add <url> [--trust-local] 加一个 server 连接\n * agent-phonon server list 列已配 server\n * agent-phonon config 打印当前配置路径与内容\n */\nconst [cmd, ...args] = process.argv.slice(2);\n\nfunction flag(name: string): boolean {\n return args.includes(`--${name}`);\n}\nfunction opt(name: string): string | undefined {\n const i = args.indexOf(`--${name}`);\n return i >= 0 ? args[i + 1] : undefined;\n}\n\nasync function main(): Promise<void> {\n switch (cmd) {\n case \"init\": {\n if (existsSync(DEFAULT_CONFIG_PATH) && !flag(\"force\")) {\n console.error(`config already exists at ${DEFAULT_CONFIG_PATH} (use --force to overwrite)`);\n process.exit(1);\n }\n writeConfig(defaultConfig());\n console.log(`wrote default config → ${DEFAULT_CONFIG_PATH}`);\n console.log(\"Add a server: agent-phonon server add ws://your-server:port --trust-local\");\n break;\n }\n case \"server\": {\n const sub = args[0];\n const cfg = loadConfig();\n if (sub === \"add\") {\n const url = args[1];\n if (!url) {\n console.error(\"usage: agent-phonon server add <url> [--trust-local] [--device-key <key>]\");\n process.exit(1);\n }\n cfg.servers.push({ url, trustLocal: flag(\"trust-local\"), deviceKey: opt(\"device-key\") });\n writeConfig(cfg);\n console.log(`added server ${url} (${cfg.servers.length} total)`);\n } else if (sub === \"list\") {\n if (cfg.servers.length === 0) console.log(\"(no servers configured)\");\n for (const s of cfg.servers) console.log(`- ${s.url}${s.trustLocal ? \" [trustLocal]\" : \"\"}`);\n } else {\n console.error(\"usage: agent-phonon server add|list\");\n process.exit(1);\n }\n break;\n }\n case \"config\": {\n const cfg = loadConfig();\n console.log(`config: ${DEFAULT_CONFIG_PATH}`);\n // 默认脱敏;--show-secrets 才明文(bug-bash#2)\n console.log(JSON.stringify(flag(\"show-secrets\") ? cfg : redactConfig(cfg), null, 2));\n break;\n }\n case \"start\": {\n const cfg: DaemonConfig = loadConfig();\n const daemon = new PhononDaemon(cfg);\n await daemon.start();\n console.log(`[agent-phonon] daemon started (device=${cfg.deviceId}, servers=${cfg.servers.length})`);\n const shutdown = async () => {\n console.log(\"\\n[agent-phonon] shutting down…\");\n await daemon.stop();\n process.exit(0);\n };\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n // 保持前台\n await new Promise(() => {});\n break;\n }\n case \"doctor\":\n cmdDoctor();\n break;\n case \"discover\":\n await cmdDiscover();\n // Some adapters keep background sockets/handles (e.g. OpenClaw Gateway).\n // discover is a one-shot CLI command, so exit explicitly after printing.\n process.exit(0);\n case \"adapter\": {\n const sub = args[0];\n if (sub === \"add\") cmdAdapterAdd(args[1] ?? \"\", { gatewayUrl: opt(\"gateway-url\"), token: opt(\"token\"), defaultAgent: opt(\"agent\"), baseUrl: opt(\"base-url\"), apiKey: opt(\"api-key\"), model: opt(\"model\"), provider: opt(\"provider\"), wireApi: opt(\"wire-api\"), bin: opt(\"bin\") });\n else if (sub === \"list\") cmdAdapterList();\n else { console.error(\"usage: agent-phonon adapter add <type> | list\"); process.exit(1); }\n break;\n }\n case \"plugin\": {\n const sub = args[0];\n if (sub === \"install\") cmdPluginInstall(args[1] ?? \"\");\n else { console.error(\"usage: agent-phonon plugin install openclaw\"); process.exit(1); }\n break;\n }\n default:\n console.log(\"agent-phonon — device daemon for scheduling local AI agents\\n\");\n console.log(\"setup:\");\n console.log(\" init generate default config\");\n console.log(\" doctor check agent availability / Gateway / plugin\");\n console.log(\" adapter add <type> [opts] configure an adapter override (auto-detect covers common local agents)\");\n console.log(\" adapter list list configured + auto-detected adapters\");\n console.log(\" plugin install openclaw install OpenClaw HITL plugin\");\n console.log(\" server add <url> [--trust-local] [--device-key <k>]\");\n console.log(\" server list\");\n console.log(\" config [--show-secrets] show config (redacted by default)\");\n console.log(\"\\nrun:\");\n console.log(\" discover list available agents (without starting daemon)\");\n console.log(\" start start the daemon (systemd-managed)\");\n console.log(\"\\nadapter add examples:\");\n console.log(\" agent-phonon adapter add openclaw --agent phonon\");\n console.log(\" agent-phonon adapter add codex --base-url https://gw/v1 --api-key <k> --model gpt-5.5\");\n console.log(\" agent-phonon adapter add hermes\");\n break;\n }\n}\n\nmain().catch((err) => {\n console.error(\"[agent-phonon]\", (err as Error)?.message ?? err);\n process.exit(1);\n});\n"],"mappings":"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","names":["z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","resolve","resolve","args","flag","mkdir","rm","readdir","stat","existsSync","join","resolve","readFile","resolve","homedir","mkdirSync","dirname","join","existsSync","key","mkdirSync","dirname","join","mkdir","readdir","lstat","writeFile","basename","dirname","join","resolve","sep","probe","type","execFile","promisify","execFileAsync","execFile","promisify","execFileAsync","cmd","spawn","existsSync","readFileSync","homedir","join","readFile","writeFile","type","args","join","homedir","existsSync","readFileSync","resolve","spawn","resolve","randomUUID","existsSync","readFileSync","homedir","join","resolve","randomUUID","join","homedir","existsSync","readFileSync","WebSocket","resolve","WebSocket","RpcPeer","resolve","DatabaseSync","existsSync","spawn","homedir","join","existsSync","statSync","CAPABILITIES","join","homedir","existsSync","statSync","args","resolve","spawn","type","spawn","DatabaseSync","homedir","join","existsSync","CAPABILITIES","join","homedir","existsSync","args","resolve","spawn","type","spawn","randomUUID","DatabaseSync","homedir","join","existsSync","CAPABILITIES","randomUUID","args","resolve","spawn","existsSync","join","homedir","DatabaseSync","EventEmitter","spawn","randomUUID","writeFileSync","rmSync","existsSync","tmpdir","homedir","join","CAPABILITIES","join","tmpdir","writeFileSync","randomUUID","args","resolve","spawn","rmSync","type","homedir","existsSync","readFileSync","existsSync","mkdirSync","writeFileSync","chmodSync","homedir","hostname","join","dirname","existsSync","mkdirSync","rmSync","writeFileSync","readFileSync","homedir","join","dirname","args","join","homedir","existsSync","type","dirname","rmSync","mkdirSync","readFileSync","writeFileSync","createServer","resolve","existsSync","existsSync"]}
|
|
1
|
+
{"version":3,"sources":["../../protocol/src/schemas/common.ts","../../protocol/src/schemas/capabilities.ts","../../protocol/src/schemas/discovery.ts","../../protocol/src/schemas/session.ts","../../protocol/src/schemas/stream.ts","../../protocol/src/schemas/hook.ts","../../protocol/src/schemas/document.ts","../../protocol/src/schemas/interaction.ts","../../protocol/src/schemas/project.ts","../../protocol/src/schemas/skill.ts","../../protocol/src/schemas/policy.ts","../../protocol/src/schemas/connect.ts","../../protocol/src/schemas/device.ts","../../protocol/src/schemas/file.ts","../../protocol/src/schemas/env.ts","../../protocol/src/schemas/jsonrpc.ts","../../protocol/src/schemas/methods.ts","../../protocol/src/index.ts","../../core/src/rpc.ts","../../core/src/session-engine.ts","../../core/src/index.ts","../../core/src/project-manager.ts","../../core/src/skill-manager.ts","../../core/src/policy.ts","../../core/src/idempotency.ts","../../core/src/outbox.ts","../../core/src/store.ts","../../core/src/secret-box.ts","../../core/src/file-manager.ts","../../core/src/resources.ts","../../core/src/device-info.ts","../../core/src/env-manager.ts","../../core/src/adapters/openclaw.ts","../../core/src/custom-compress.ts","../../core/src/gateway-client.ts","../../core/src/adapters/openclaw-gateway.ts","../../core/src/client.ts","../../core/src/hook-bridge.ts","../../core/src/sqlite-compress.ts","../../core/src/adapters/codex.ts","../../core/src/adapters/opencode.ts","../../core/src/adapters/hermes.ts","../../core/src/observability.ts","../../core/src/adapters/claude-code.ts","../src/config.ts","../src/commands.ts","../src/obs-server.ts","../src/daemon.ts","../src/cli.ts"],"sourcesContent":["import { z } from \"zod\";\n\n/**\n * agent-phonon wire protocol — shared primitives.\n *\n * 设计参考 docs/design.md。本文件定义全协议复用的基础类型:\n * 协议版本、各类 ID、verbosity、错误码。\n */\n\n/** 协议语义版本。device 与 server 握手时比对(见 connect.hello)。 */\nexport const PROTOCOL_VERSION = \"0.1.0\" as const;\n\n// ---------------------------------------------------------------------------\n// ID 原语(全部是不透明字符串,调用方不应解析其结构)\n// ---------------------------------------------------------------------------\n\n/** phonon 侧全局唯一的 session id(归属某一 tenant)。 */\nexport const SessionId = z.string().min(1).brand<\"SessionId\">();\nexport type SessionId = z.infer<typeof SessionId>;\n\n/** discovery 返回的 agent 标识,也是 session.create 的 `agent` 入参。 */\nexport const AgentId = z.string().min(1).brand<\"AgentId\">();\nexport type AgentId = z.infer<typeof AgentId>;\n\n/** 项目标识(项目 = 目录 + Git)。所有 session 必须绑定一个项目。 */\nexport const ProjectId = z.string().min(1).brand<\"ProjectId\">();\nexport type ProjectId = z.infer<typeof ProjectId>;\n\n/** 本地配置赋予的稳定租户 id(= 一条服务端连接,见 design D13)。 */\nexport const TenantId = z.string().min(1).brand<\"TenantId\">();\nexport type TenantId = z.infer<typeof TenantId>;\n\n/** 设备自身标识(一台设备一个,用于服务端区分多设备,但 phonon 不感知其他设备)。 */\nexport const DeviceId = z.string().min(1).brand<\"DeviceId\">();\nexport type DeviceId = z.infer<typeof DeviceId>;\n\n// ---------------------------------------------------------------------------\n// Verbosity — 控制 session 返回内容的多少(design §4)\n// ---------------------------------------------------------------------------\n\n/**\n * 4 档详细度,create 时设定、send 可覆盖:\n * - final : 仅最终结果\n * - messages : 每轮消息\n * - tools : 含工具调用\n * - trace : 全量(含思考)\n */\nexport const Verbosity = z.enum([\"final\", \"messages\", \"tools\", \"trace\"]);\nexport type Verbosity = z.infer<typeof Verbosity>;\n\n// ---------------------------------------------------------------------------\n// 错误码 — JSON-RPC error.data.code 用(design 中提到的归一化错误)\n// ---------------------------------------------------------------------------\n\n/**\n * 应用级错误码(区别于 JSON-RPC 传输级 code)。\n * 放在 JSON-RPC error 对象的 `data.appCode` 字段,便于调用方稳定判别。\n */\nexport const PhononErrorCode = z.enum([\n // 协议/握手\n \"errProtocolMismatch\", // device 与 server 协议版本不兼容\n \"errUnauthorized\", // device key 无效(注:终端用户鉴权在 server,不在此)\n // 租户隔离(design §6 / D13)\n \"errSessionNotInTenant\", // 跨租户访问 session\n \"errTenantQuotaExceeded\", // 触达 per-tenant 配额\n \"errDeviceQuotaExceeded\", // 触达全局配额\n // 发现 / agent 绑定(design §5 / D14 / D15)\n \"errAgentUnavailable\", // 目标 agent 不存在或不可用\n \"errModelUnavailable\", // 模型不在该 agent 的可用列表内\n // session 生命周期\n \"errSessionNotFound\",\n \"errSessionTerminated\", // 操作了已结束的 session\n \"errSessionBusy\", // session 正忙(如上一轮未结束)\n // 能力\n \"errCapabilityUnsupported\", // adapter 不支持该操作(如 native 压缩缺失)\n // hook / HITL\n \"errHookResolveInvalid\", // hook.resolve 的裁决非法\n \"errHookTimeout\", // 等待服务端裁决超时\n // 项目 / skill(D23-D26)\n \"errProjectNotFound\",\n \"errProjectExists\", // 同名/同路径项目已存在\n \"errProjectHasActiveSessions\", // 项目下还有 active session(remove 拦)\n \"errSkillNotFound\",\n \"errSkillScopeInvalid\", // scope=project 但缺 projectId 等\n \"errSkillInstallFailed\",\n // git / worktree(D25)\n \"errWorktreeNotFound\",\n \"errWorktreeHasChanges\", // 未提交变更,非 force 不清\n \"errWorktreeInUse\", // worktree 还有 active session\n \"errBranchNotMerged\", // 分支未合并,非 force 不删\n \"errBranchInUse\", // 分支仍被某 worktree 检出\n // 文档 / 上传(D20)\n \"errDocumentTooLarge\", // 超 maxUploadBytes\n \"errDocumentPathDenied\", // 路径不在项目范围 / 命中 deny\n // 本地 policy(D27)\n \"errPolicyDenied\", // 被设备本地安全策略拦截\n // 幂等\n \"errDuplicateRequest\", // clientRequestId 重复(已处理过)\n // 通用\n \"errInvalidParams\",\n \"errInternal\",\n]);\nexport type PhononErrorCode = z.infer<typeof PhononErrorCode>;\n\n/** 统一附在 JSON-RPC error.data 上的结构。 */\nexport const PhononErrorData = z.object({\n appCode: PhononErrorCode,\n /** 可选的人类可读补充(不用于程序判别)。 */\n detail: z.string().optional(),\n /** 可选:相关 session/agent/tenant,便于服务端定位。 */\n sessionId: SessionId.optional(),\n agentId: AgentId.optional(),\n tenantId: TenantId.optional(),\n});\nexport type PhononErrorData = z.infer<typeof PhononErrorData>;\n\n/** ISO-8601 时间戳字符串(统一用字符串,避免时区/精度歧义)。 */\nexport const Timestamp = z.string().datetime({ offset: true });\nexport type Timestamp = z.infer<typeof Timestamp>;\n","import { z } from \"zod\";\n\n/**\n * Hook 类型 — 归一化的拦截点(design §8)。\n * adapter 负责把各家原生 hook 点(Codex hooks / Claude Code PreToolUse /\n * OpenClaw 审批…)映射成这些归一化类型。\n */\nexport const HookType = z.enum([\n \"pre_tool\", // 工具调用前\n \"post_tool\", // 工具调用后\n \"pre_command\", // 执行 shell/命令前(rm/git push 等危险操作)\n \"pre_file_write\", // 写文件前\n \"pre_network\", // 发起网络/外部请求前\n \"session_start\", // 会话开始\n \"session_end\", // 会话结束\n \"notification\", // agent 主动通知(无需裁决,纯告知)\n]);\nexport type HookType = z.infer<typeof HookType>;\n\n/**\n * Adapter 能力声明(design §7)。\n * adapter 不假装统一,而是声明自己原生支持什么,phonon core 据此补齐缺口。\n * 这份能力随 discovery 一起暴露给服务端,服务端先知能力再决定怎么用。\n */\nexport const AgentCapabilities = z.object({\n /** 原生 session / resume(无则由 core 用注册表模拟)。 */\n nativeSession: z.boolean(),\n /** 原生上下文压缩(决定 session.compress mode=native 是否可用)。 */\n nativeCompression: z.boolean(),\n /** 原生上下文注入。 */\n contextInjection: z.boolean(),\n /**\n * 是否会**主动/非请求触发地输出**(design 订阅模型)。\n * OpenClaw 这类有 cron/心跳/定时任务,同一 session 内会不定期自发冲泡 → true;\n * Codex 这类一次性,流到结果就结束 → false。\n * server 据此判断哪些 session 需要长期保持监听。\n */\n proactiveOutput: z.boolean(),\n /** 是否支持同会话中途切换模型(design D16)。 */\n modelSwitch: z.boolean(),\n /** 是否支持打断正在进行的 turn(session.interrupt / whenBusy=interrupt,D18)。 */\n interrupt: z.boolean(),\n /** 是否支持中途插入输入(下一次 tool call 边界,whenBusy=inject,D18)。 */\n injectMidTurn: z.boolean(),\n /** 是否支持给该 agent 安装/卸载 skill(skill.* 接口,D24)。 */\n skillManagement: z.boolean(),\n /** 原生支持的 hook 点(其余由 core 尽力补齐或不支持)。 */\n hooks: z.array(HookType),\n /** 是否支持流式输出。 */\n streaming: z.boolean(),\n /**\n * 可选调度限制(P2-13):server 据此做调度/背压。\n */\n limits: z\n .object({\n maxConcurrentSessions: z.number().int().positive().optional(),\n maxContextTokens: z.number().int().positive().optional(),\n maxMessageBytes: z.number().int().positive().optional(),\n })\n .optional(),\n});\nexport type AgentCapabilities = z.infer<typeof AgentCapabilities>;\n","import { z } from \"zod\";\nimport { AgentId, Timestamp } from \"./common.js\";\nimport { AgentCapabilities } from \"./capabilities.js\";\n\n/**\n * Agent / 模型发现(design §5 / D14)。\n *\n * 发现 = 内部扫描机制(非协议)+ 对外暴露接口(属协议)。本文件只定义\n * **对外接口**的数据形状:服务端借此感知「这台设备上哪些 agent 可用、\n * 各自哪些模型可用」。\n */\n\n/** 单个模型的可用性描述。 */\nexport const ModelInfo = z.object({\n /** 模型 id,session.create 的 `model` 入参取自这里。 */\n id: z.string().min(1),\n /** 展示名(可选)。 */\n displayName: z.string().optional(),\n /** 上下文窗口(token,若已知)。注意:以 phonon 实测/配置为准,不盲信后端返回。 */\n contextWindow: z.number().int().positive().optional(),\n /** 该模型当前是否可用(如鉴权过期会变 false)。 */\n available: z.boolean().default(true),\n});\nexport type ModelInfo = z.infer<typeof ModelInfo>;\n\n/** 单个 agent 的发现条目。 */\nexport const AgentDescriptor = z.object({\n agentId: AgentId,\n /** 展示名,如 \"Claude Code\" / \"OpenClaw\"。 */\n displayName: z.string().min(1),\n /** 适配器内部名,如 \"openclaw\" / \"claude-code\"。 */\n adapter: z.string().min(1),\n /** 整体是否可用(已安装 + 可执行 + 凭证就绪)。 */\n available: z.boolean(),\n /** 不可用时的原因(如 \"not_installed\" / \"not_logged_in\" / \"no_credentials\")。 */\n unavailableReason: z.string().optional(),\n /** agent 自身版本(若可探测)。 */\n version: z.string().optional(),\n /** 可用模型列表。 */\n models: z.array(ModelInfo),\n /** 能力声明(随 discovery 暴露,见 §7)。 */\n capabilities: AgentCapabilities,\n /** 最近一次扫描时间。 */\n scannedAt: Timestamp.optional(),\n});\nexport type AgentDescriptor = z.infer<typeof AgentDescriptor>;\n\n// --- discovery.list ---\nexport const DiscoveryListParams = z.object({\n /** 可选:只看可用的。 */\n availableOnly: z.boolean().optional(),\n});\nexport type DiscoveryListParams = z.infer<typeof DiscoveryListParams>;\n\nexport const DiscoveryListResult = z.object({\n agents: z.array(AgentDescriptor),\n});\nexport type DiscoveryListResult = z.infer<typeof DiscoveryListResult>;\n\n// --- discovery.get ---\nexport const DiscoveryGetParams = z.object({\n agentId: AgentId,\n});\nexport type DiscoveryGetParams = z.infer<typeof DiscoveryGetParams>;\n\nexport const DiscoveryGetResult = z.object({\n agent: AgentDescriptor,\n});\nexport type DiscoveryGetResult = z.infer<typeof DiscoveryGetResult>;\n\n// --- discovery.changed (phonon -> server 主动推送,notification) ---\nexport const DiscoveryChangedParams = z.object({\n /** 变更类型:agent 上/下线、模型增减、能力变化。 */\n kind: z.enum([\"agent_added\", \"agent_removed\", \"agent_updated\", \"models_changed\"]),\n agentId: AgentId,\n /** 变更后的完整快照(可选,便于服务端直接更新缓存)。 */\n snapshot: AgentDescriptor.optional(),\n at: Timestamp,\n});\nexport type DiscoveryChangedParams = z.infer<typeof DiscoveryChangedParams>;\n","import { z } from \"zod\";\nimport { AgentId, ProjectId, SessionId, Timestamp, Verbosity } from \"./common.js\";\n\n/**\n * L1 Session 协议原语(design §4)。\n *\n * 铁律:session 必须绑定 agent(D15)。每条 session 天生属于某个 agent + model,\n * 这是 session 的一等身份,不是可选配置。发任务 = 在 session 里对话。\n */\n\n/** session 状态。 */\n/**\n * session 状态(design D19)。\n * - idle : 活着、空闲、就绪可接 send(create 后初始态;turn 结束/interrupt 后回到这)\n * - running : agent 正在执行一个 turn\n * - paused : 挂起(重启后从 DB 恢复、原生 ref 尚未 re-attach;或被显式暂停),需恢复才能用\n * - terminated : 已结束销毁\n */\nexport const SessionStatus = z.enum([\"idle\", \"running\", \"paused\", \"terminated\"]);\nexport type SessionStatus = z.infer<typeof SessionStatus>;\n\n/**\n * 上下文条目 —— 用于 initialContext / inject。\n * 设计成「角色 + 文本」的最小通用形态,具体 adapter 自行翻译成原生格式。\n */\nexport const ContextItem = z.object({\n role: z.enum([\"system\", \"user\", \"assistant\"]),\n content: z.string(),\n});\nexport type ContextItem = z.infer<typeof ContextItem>;\n\n// ---------------------------------------------------------------------------\n// session.create\n// ---------------------------------------------------------------------------\nexport const SessionCreateParams = z.object({\n /** 可选:幂等键(P0-3,断线重发去重)。 */\n clientRequestId: z.string().optional(),\n /** 必填:绑定的项目(所有 session 必须有项目目录,D23)。 */\n project: ProjectId,\n /** 可选:跑在哪个 worktree(缺省用项目主工作区,D25)。 */\n worktreeId: z.string().optional(),\n /** 必填:绑定的 agent(来自 discovery 的 agentId)。 */\n agent: AgentId,\n /** 必填:绑定的模型(必须在该 agent 的可用模型列表内)。 */\n model: z.string().min(1),\n /** 透传给 adapter 的 agent 私有配置(cwd、工具白名单、thinking 等)。 */\n agentConfig: z.record(z.unknown()).optional(),\n /** 初始上下文设置(system prompt / 预置对话)。 */\n initialContext: z.array(ContextItem).optional(),\n /** 默认返回详细度,send 可覆盖。默认 messages。 */\n verbosity: Verbosity.default(\"messages\"),\n /** 可选:调用方自带的标签,便于服务端侧对账(phonon 原样回显)。 */\n clientTag: z.string().optional(),\n});\nexport type SessionCreateParams = z.infer<typeof SessionCreateParams>;\n\nexport const SessionCreateResult = z.object({\n sessionId: SessionId,\n /** 回显绑定身份,方便调用方确认。 */\n project: ProjectId,\n agent: AgentId,\n model: z.string(),\n status: SessionStatus,\n createdAt: Timestamp,\n});\nexport type SessionCreateResult = z.infer<typeof SessionCreateResult>;\n\n// ---------------------------------------------------------------------------\n// session.send —— 发任务 = 对话;结果以流式 events 异步返回(见 stream.ts)\n// ---------------------------------------------------------------------------\n\n/**\n * 忙碌处理模式(D18)—— 新消息进来时上一轮还没结束怎么办:\n * - queue :等待,上一轮结束后自动发送积压消息(默认,最安全)。\n * - interrupt:中断当前 turn(session 存活),再发新消息;需 capability.interrupt。\n * - inject :不中断,在下一次 tool call 边界插入输入让 agent 接着处理;\n * 需 capability.injectMidTurn(agent 原生接口或通过 hook 实现)。\n * 不论哪种模式,**消息不丢**:要么按序送达、要么明确拒绝并告知原因。\n */\nexport const WhenBusy = z.enum([\"queue\", \"interrupt\", \"inject\"]);\nexport type WhenBusy = z.infer<typeof WhenBusy>;\n\nexport const SessionSendParams = z.object({\n sessionId: SessionId,\n /** 用户输入 / 任务内容。 */\n input: z.string(),\n /**\n * 可选:幂等键(P0-3)。服务端断线重发同一 send 时带相同值,\n * phonon 去重,避免 agent 收两遍同样消息;重复回 `errDuplicateRequest` 或原 turnId。\n */\n clientRequestId: z.string().optional(),\n /**\n * 可选:本轮指定要用的 skill(D26)。每项可是简单名字(string),\n * 或结构体 {name,version?,scope?,force?}(P2-12,消除同名 global/project 歧义)。\n * phonon 保证:(1) skill 在 agent 能访问到的位置;(2) 上下文注入强制加载指令。\n * 优先级:send 指定 > project skill > global skill。\n */\n skills: z\n .array(\n z.union([\n z.string(),\n z.object({\n name: z.string().min(1),\n version: z.string().optional(),\n scope: z.enum([\"global\", \"project\"]).optional(),\n force: z.boolean().optional(),\n }),\n ]),\n )\n .optional(),\n /** 可选:覆盖本轮详细度。 */\n verbosity: Verbosity.optional(),\n /**\n * 忙碌时的处理模式(D18)。缺省 queue。\n * 若选的模式该 agent 不支持(看 capability)且未设 fallback → errCapabilityUnsupported。\n */\n whenBusy: WhenBusy.default(\"queue\"),\n /**\n * 可选:降级模式(P1-11)。当 whenBusy 该 agent 不支持时,不报错而自动降级为它,\n * 保证自动化编排连贯。如 whenBusy=\"inject\", fallback=\"queue\"。\n */\n fallback: WhenBusy.optional(),\n /**\n * 可选:本轮关联 id。phonon 会把该轮所有 stream.event 标上同一 turnId,\n * 调用方据此聚合流式输出。缺省由 phonon 生成并在 ack 中返回。\n */\n turnId: z.string().optional(),\n});\nexport type SessionSendParams = z.infer<typeof SessionSendParams>;\n\n/** send 的同步 ack(真正的内容走 stream.event 异步推)。 */\nexport const SessionSendAck = z.object({\n sessionId: SessionId,\n turnId: z.string(),\n accepted: z.literal(true),\n /**\n * 本次 send 的实际处由:\n * - started :立即开始执行(session 空闲)\n * - queued :已排队(whenBusy=queue 且正忙)\n * - interrupted:已中断上一轮并开始本轮(whenBusy=interrupt)\n * - injected :将在下一 tool call 边界插入(whenBusy=inject)\n */\n disposition: z.enum([\"started\", \"queued\", \"interrupted\", \"injected\"]),\n /** queued 时的队列位置(从 1 起)。 */\n queuePosition: z.number().int().positive().optional(),\n});\nexport type SessionSendAck = z.infer<typeof SessionSendAck>;\n\n// ---------------------------------------------------------------------------\n// session.interrupt —— 打断当前正在进行的 turn(session 存活,D18)\n// 区别于 session.terminate(销毁整个 session)。\n// P0-2:interrupt 后 phonon 必须为被打断的 turn 发一条终态 stream.event\n// { type:\"result\", final:true, status:\"interrupted\" },服务端状态机才不悬空。\n// ---------------------------------------------------------------------------\nexport const SessionInterruptParams = z.object({\n sessionId: SessionId,\n /** 可选:中断原因(传给 agent / 记录)。 */\n reason: z.string().optional(),\n});\nexport type SessionInterruptParams = z.infer<typeof SessionInterruptParams>;\n\nexport const SessionInterruptResult = z.object({\n sessionId: SessionId,\n /** 被中断的 turn(若当时有在跑的)。 */\n interruptedTurnId: z.string().optional(),\n /** 中断后 session 状态(通常回到 active 空闲)。 */\n status: SessionStatus,\n});\nexport type SessionInterruptResult = z.infer<typeof SessionInterruptResult>;\n\n// ---------------------------------------------------------------------------\n// session.inject —— 上下文注入\n// ---------------------------------------------------------------------------\nexport const SessionInjectParams = z.object({\n sessionId: SessionId,\n context: z.array(ContextItem),\n});\nexport type SessionInjectParams = z.infer<typeof SessionInjectParams>;\n\nexport const SessionInjectResult = z.object({\n sessionId: SessionId,\n injected: z.number().int().nonnegative(),\n});\nexport type SessionInjectResult = z.infer<typeof SessionInjectResult>;\n\n// ---------------------------------------------------------------------------\n// session.compress —— 压缩双模(design §4 / D7)\n// ---------------------------------------------------------------------------\nexport const CompressMode = z.enum([\"native\", \"custom\"]);\nexport type CompressMode = z.infer<typeof CompressMode>;\n\nexport const SessionCompressParams = z.object({\n sessionId: SessionId,\n /** native = 透传 agent 原生压缩;custom = phonon 自有压缩引擎。 */\n mode: CompressMode,\n /**\n * custom 模式下的策略名(P2-15)。**server-private:phonon 不做协议层枚举校验**,\n * 透传给 adapter/压缩引擎自行解释(如 summary / truncate_keep_recent)。\n */\n strategy: z.string().optional(),\n /** dropToolIO 策略:保留最近 N 个 tool call 及其 result,默认 3。 */\n keepRecentToolCalls: z.number().int().nonnegative().optional(),\n});\nexport type SessionCompressParams = z.infer<typeof SessionCompressParams>;\n\nexport const SessionCompressResult = z.object({\n sessionId: SessionId,\n mode: CompressMode,\n /** 压缩前后的 token 估算(若可得)。 */\n tokensBefore: z.number().int().nonnegative().optional(),\n tokensAfter: z.number().int().nonnegative().optional(),\n /** 简短摘要/说明。 */\n summary: z.string().optional(),\n});\nexport type SessionCompressResult = z.infer<typeof SessionCompressResult>;\n\n// ---------------------------------------------------------------------------\n// session.terminate\n// ---------------------------------------------------------------------------\nexport const SessionTerminateParams = z.object({\n sessionId: SessionId,\n /**\n * 可选:销毁会话时顺手清理其专用 worktree(P1-10)。\n * 仅当该 session 跑在一个专为它建的 worktree 上才生效;主工作区不清。\n */\n cleanWorktree: z.boolean().default(false),\n});\nexport type SessionTerminateParams = z.infer<typeof SessionTerminateParams>;\n\nexport const SessionTerminateResult = z.object({\n sessionId: SessionId,\n status: z.literal(\"terminated\"),\n /** 若 cleanWorktree 且确实清了,返回被清理的 worktreeId。 */\n cleanedWorktreeId: z.string().optional(),\n});\nexport type SessionTerminateResult = z.infer<typeof SessionTerminateResult>;\n\n// ---------------------------------------------------------------------------\n// session.switchModel —— 同会话中途切换模型(design D16)\n// agent 绑定不可变,但 model 可换:某模型不行了就换另一个。\n// ---------------------------------------------------------------------------\nexport const SessionSwitchModelParams = z.object({\n sessionId: SessionId,\n /** 新模型,必须在该 session 绑定 agent 的可用模型列表内。 */\n model: z.string().min(1),\n /**\n * running 时的策略(P1-8):\n * - reject(默认) :running 时拒绝切换,避免 adapter 状态不一致\n * - afterCurrentTurn:等当前 turn 结束后再切\n * - interrupt :打断当前 turn 立即切\n * idle 时忽略此参数,直接切。\n */\n whenRunning: z.enum([\"reject\", \"afterCurrentTurn\", \"interrupt\"]).default(\"reject\"),\n});\nexport type SessionSwitchModelParams = z.infer<typeof SessionSwitchModelParams>;\n\nexport const SessionSwitchModelResult = z.object({\n sessionId: SessionId,\n /** 切换前的模型(便于调用方记录/回滚)。 */\n previousModel: z.string(),\n model: z.string(),\n /**\n * 可选警告(P1-8 / Minimax):adapter 发现潜在不兼容(系统提示格式/tool schema 变化)\n * 时填入,server 据此决定是否继续。\n */\n warnings: z.array(z.string()).optional(),\n /** 若 whenRunning=afterCurrentTurn 且当时 running,表示已排期未立即生效。 */\n deferred: z.boolean().optional(),\n});\nexport type SessionSwitchModelResult = z.infer<typeof SessionSwitchModelResult>;\n\n// ---------------------------------------------------------------------------\n// session.status / session.list —— 始终携带 agent 身份\n// ---------------------------------------------------------------------------\nexport const SessionMeta = z.object({\n sessionId: SessionId,\n /** 绑定的项目(一等身份,D23)。 */\n project: ProjectId,\n /** 绑定的 agent 身份,全程携带。 */\n agent: AgentId,\n model: z.string(),\n status: SessionStatus,\n /** 当 status=running 时,正在执行的 turnId(服务端据此知道「在跑哪一轮」)。 */\n currentTurnId: z.string().optional(),\n /** 队列中等待的 send 数(whenBusy=queue 积压,D18)。 */\n queuedCount: z.number().int().nonnegative().optional(),\n /**\n * 上下文信息(D33)——adapter 能提供时填,便于 server 监控上下文压力。\n */\n context: z\n .object({\n /** 上下文窗口总容量(token)。 */\n contextWindow: z.number().int().nonnegative().optional(),\n /** 已用上下文(token,若可估)。 */\n usedTokens: z.number().int().nonnegative().optional(),\n /** 已用上下文占比 0-100。 */\n usagePercent: z.number().min(0).max(100).optional(),\n /** 已发生的压缩次数。 */\n compactions: z.number().int().nonnegative().optional(),\n })\n .optional(),\n verbosity: Verbosity,\n clientTag: z.string().optional(),\n createdAt: Timestamp,\n lastActiveAt: Timestamp.optional(),\n});\nexport type SessionMeta = z.infer<typeof SessionMeta>;\n\nexport const SessionStatusParams = z.object({\n sessionId: SessionId,\n});\nexport type SessionStatusParams = z.infer<typeof SessionStatusParams>;\n\nexport const SessionStatusResult = SessionMeta;\nexport type SessionStatusResult = z.infer<typeof SessionStatusResult>;\n\nexport const SessionListParams = z.object({\n /** 可选:按项目过滤。 */\n project: ProjectId.optional(),\n /** 可选:按 agent 过滤。 */\n agent: AgentId.optional(),\n /** 可选:按状态过滤。 */\n status: SessionStatus.optional(),\n /** 可选:分页上限(P2-14)。 */\n limit: z.number().int().positive().max(500).optional(),\n /** 可选:分页游标(上一页返回的 nextCursor)。 */\n cursor: z.string().optional(),\n});\nexport type SessionListParams = z.infer<typeof SessionListParams>;\n\nexport const SessionListResult = z.object({\n sessions: z.array(SessionMeta),\n /** 下一页游标;缺省/null 表示已到末尾。 */\n nextCursor: z.string().optional(),\n});\nexport type SessionListResult = z.infer<typeof SessionListResult>;\n","import { z } from \"zod\";\nimport { SessionId, Timestamp } from \"./common.js\";\n\n/**\n * 流式事件(design §4 / §6 / 订阅模型)——phonon → server 异步推送。\n *\n * 关键:session 不只是「请求-响应」,还是一条**可订阅的持续输出流**。\n * 输出分两种来源(origin):\n * - solicited :某次 session.send 触发的响应(用 send 返回的 turnId)。\n * - unsolicited:agent 自发输出(OpenClaw 的 cron/定时/心跳),无 send 触发;\n * turnId 由 phonon 生成,source 标明冲泡来源。\n *\n * “create 即订阅”:server 拥有的 session 的**所有** stream.event(含自发)都自动\n * 推给该 tenant 连接,无需显式 subscribe。Codex 一次性 session 流到 result final 就停;\n * OpenClaw 持久 session 即使不 send 也会持续往上冒。\n *\n * 不同事件对应不同 verbosity 档位:\n * final → 只会收到 result\n * messages → message + result\n * tools → message + tool_call + tool_result + result\n * trace → 以上 + thinking + token delta\n */\n\n/** 输出来源:请求触发 vs agent 自发。 */\nexport const StreamOrigin = z.enum([\"solicited\", \"unsolicited\"]);\nexport type StreamOrigin = z.infer<typeof StreamOrigin>;\n\n/** 事件种类。 */\nexport const StreamEventType = z.enum([\n \"message\", // 一条完整/增量消息文本\n \"thinking\", // 思考过程(trace 档)\n \"tool_call\", // agent 发起工具调用\n \"tool_result\", // 工具返回\n \"token\", // 增量 token(流式打字机,trace/可选)\n \"result\", // 本轮最终结果(终止事件)\n \"error\", // 本轮出错(终止事件)\n]);\nexport type StreamEventType = z.infer<typeof StreamEventType>;\n\nconst StreamEventBase = z.object({\n sessionId: SessionId,\n /**\n * 本轮关联 id。solicited 事件用 send 返回的 turnId;\n * unsolicited(自发)事件由 phonon 生成,server 从事件中首次见到。\n */\n turnId: z.string(),\n /** 输出来源:默认 solicited;agent 自发为 unsolicited。 */\n origin: StreamOrigin.default(\"solicited\"),\n /** unsolicited 时的冲泡来源标签,如 \"cron\" / \"scheduled\" / \"heartbeat\"。 */\n source: z.string().optional(),\n /** 单调递增序号(按 session),保证调用方可排序/去重。 */\n seq: z.number().int().nonnegative(),\n at: Timestamp,\n});\n\nexport const StreamMessageEvent = StreamEventBase.extend({\n type: z.literal(\"message\"),\n role: z.enum([\"assistant\", \"user\", \"system\"]).default(\"assistant\"),\n text: z.string(),\n /** 是否为增量分片(true 表示需要与同 turn 的后续 message 拼接)。 */\n delta: z.boolean().default(false),\n});\n\nexport const StreamThinkingEvent = StreamEventBase.extend({\n type: z.literal(\"thinking\"),\n text: z.string(),\n delta: z.boolean().default(false),\n});\n\nexport const StreamToolCallEvent = StreamEventBase.extend({\n type: z.literal(\"tool_call\"),\n toolName: z.string(),\n /** 工具入参(原样透传,结构由 agent/工具决定)。 */\n args: z.unknown().optional(),\n /** 工具调用 id,用于和 tool_result 配对。 */\n toolCallId: z.string().optional(),\n});\n\nexport const StreamToolResultEvent = StreamEventBase.extend({\n type: z.literal(\"tool_result\"),\n toolName: z.string(),\n toolCallId: z.string().optional(),\n ok: z.boolean(),\n /** 工具输出(可能被截断,取决于 verbosity/大小限制)。 */\n output: z.unknown().optional(),\n});\n\nexport const StreamTokenEvent = StreamEventBase.extend({\n type: z.literal(\"token\"),\n text: z.string(),\n});\n\nexport const StreamResultEvent = StreamEventBase.extend({\n type: z.literal(\"result\"),\n /** 本轮最终文本结果。 */\n text: z.string(),\n /** 可选 usage 统计。 */\n usage: z\n .object({\n inputTokens: z.number().int().nonnegative().optional(),\n outputTokens: z.number().int().nonnegative().optional(),\n })\n .optional(),\n /**\n * 本轮终态(P0-2)——每个 turn 必须有明确终态,服务端状态机才不会悬空:\n * completed 正常完成\n * interrupted 被 session.interrupt 打断\n * aborted 被 hook abort / 主动中止\n * failed 出错终止(详情另见 error 事件)\n * timeout 超时\n */\n status: z.enum([\"completed\", \"interrupted\", \"aborted\", \"failed\", \"timeout\"]).default(\"completed\"),\n /** 标记本轮结束。 */\n final: z.literal(true),\n});\n\nexport const StreamErrorEvent = StreamEventBase.extend({\n type: z.literal(\"error\"),\n message: z.string(),\n /** 可选应用错误码(与 common.PhononErrorCode 对齐)。 */\n appCode: z.string().optional(),\n /** 终态(与 result.status 对齐,错误场景通常 failed/aborted/timeout)。 */\n status: z.enum([\"failed\", \"aborted\", \"timeout\", \"interrupted\"]).default(\"failed\"),\n final: z.literal(true),\n});\n\n// ---------------------------------------------------------------------------\n// stream.ack —— server → phonon,确认已收到 seq <= lastSeq(P0-4)\n// 让 phonon 能清理 outbox / 控制背压;可按 session 粒度或全局。\n// ---------------------------------------------------------------------------\nexport const StreamAckParams = z.object({\n /** 按 session 确认;缺省表示该连接全局。 */\n sessionId: SessionId.optional(),\n /** 已收到的最大连续 seq(含);phonon 可清理 <= 此值的 outbox。 */\n lastSeq: z.number().int().nonnegative(),\n});\nexport type StreamAckParams = z.infer<typeof StreamAckParams>;\n\n/** 流式事件联合体(phonon → server,方法名 stream.event)。 */\nexport const StreamEvent = z.discriminatedUnion(\"type\", [\n StreamMessageEvent,\n StreamThinkingEvent,\n StreamToolCallEvent,\n StreamToolResultEvent,\n StreamTokenEvent,\n StreamResultEvent,\n StreamErrorEvent,\n]);\nexport type StreamEvent = z.infer<typeof StreamEvent>;\n","import { z } from \"zod\";\nimport { SessionId, Timestamp } from \"./common.js\";\nimport { HookType } from \"./capabilities.js\";\nimport { ContextItem } from \"./session.js\";\n\n/**\n * Hook / 人在回路 HITL(design §8)。\n *\n * 核心:phonon 自己不实现人在回路,只做事件中转 + 阻塞等裁决。\n * phonon → server : hook.fired (到 hook 点抛事件)\n * server → phonon : hook.resolve (裁决;服务端决定是否问真人、怎么问、等多久)\n */\n\n/** hook 触发载荷(phonon → server)。 */\nexport const HookFiredParams = z.object({\n sessionId: SessionId,\n /** 本次 hook 的唯一 id,hook.resolve 用它配对。 */\n hookId: z.string().min(1),\n hookType: HookType,\n /** 触发上下文:被拦截的操作详情(命令、工具名、参数、文件路径等)。 */\n payload: z\n .object({\n toolName: z.string().optional(),\n command: z.string().optional(),\n filePath: z.string().optional(),\n url: z.string().optional(),\n /** 其余 adapter 特定字段。 */\n extra: z.record(z.unknown()).optional(),\n })\n .default({}),\n /** 该 turn 的关联 id(若在某轮对话内触发)。 */\n turnId: z.string().optional(),\n at: Timestamp,\n});\nexport type HookFiredParams = z.infer<typeof HookFiredParams>;\n\n/**\n * 裁决动作(server → phonon)。\n * - continue : 放行,照常执行\n * - inject : 先注入上下文再继续(用 context 字段)\n * - modify : 用修改后的参数继续(用 patch 字段,如改写命令)\n * - abort : 中止该操作(可带原因)\n */\nexport const HookAction = z.enum([\"continue\", \"inject\", \"modify\", \"abort\"]);\nexport type HookAction = z.infer<typeof HookAction>;\n\nexport const HookResolveParams = z.object({\n sessionId: SessionId,\n /** 必须与对应 hook.fired 的 hookId 一致。 */\n hookId: z.string().min(1),\n action: HookAction,\n /** action=inject 时:要注入的上下文。 */\n context: z.array(ContextItem).optional(),\n /** action=modify 时:对被拦截操作的修改(结构与该 hook 的 payload 对应)。 */\n patch: z.record(z.unknown()).optional(),\n /** action=abort 时:可选原因,会回传给 agent / 记录。 */\n reason: z.string().optional(),\n});\nexport type HookResolveParams = z.infer<typeof HookResolveParams>;\n\nexport const HookResolveResult = z.object({\n sessionId: SessionId,\n hookId: z.string(),\n applied: z.boolean(),\n});\nexport type HookResolveResult = z.infer<typeof HookResolveResult>;\n","import { z } from \"zod\";\nimport { SessionId, Timestamp } from \"./common.js\";\n\n/**\n * 文档交换协议(design 平面③ / D20)。\n *\n * 场景:agent 需要/被要求发送本地文档时,在输出里 emit 一个**指令**(skill 教的格式,\n * 见 DocumentDirective),phonon 解析后**负责读取本地文件**,打包成附件/其他形式发到服务端。\n * 也就是说:agent 只说「路径」,读盘 + 传输由 phonon 这一层兜。\n *\n * 两个层次要分清:\n * - DocumentDirective :agent ↔ phonon 的指令(含本地 path,skill 教)\n * - document.send :phonon ↔ server 的线协议(含真实内容/附件)\n */\n\n/** 文档用途/形式。 */\nexport const DocumentKind = z.enum([\n \"attachment\", // 通用附件\n \"document\", // 富文本文档(如 .md → 服务端可转云文档)\n \"image\", // 图片\n \"file\", // 其他普通文件\n]);\nexport type DocumentKind = z.infer<typeof DocumentKind>;\n\n/** 内容承载方式:小文件内联,大文件用 ref 走分块传输(具体待定)。 */\nexport const DocumentContent = z.union([\n z.object({ encoding: z.literal(\"base64\"), data: z.string() }),\n z.object({ encoding: z.literal(\"utf8\"), data: z.string() }),\n z.object({ ref: z.string() }), // 分块传输句柄(大文件,开放问题)\n]);\nexport type DocumentContent = z.infer<typeof DocumentContent>;\n\n/**\n * agent 在输出里 emit 的指令格式(skill 教)——只含本地路径与元信息,\n * phonon 据此读本地文件。**不直接进线协议。**\n *\n * 安全(D27 policy):默认 **project-scoped**——路径必须在绑定项目/worktree 目录内,\n * 越界需 tenant policy 显式 `allowExternalDocuments`;命中 denyPathPatterns 一律拒。\n */\nexport const DocumentDirective = z.object({\n /** 文件路径(默认相对于项目/worktree 根;绝对路径需 policy 允许且在范围内)。 */\n path: z.string().min(1),\n /** 可选:覆盖文件名(默认取 path 的 basename)。 */\n name: z.string().optional(),\n kind: DocumentKind.optional(),\n caption: z.string().optional(),\n});\nexport type DocumentDirective = z.infer<typeof DocumentDirective>;\n\n/** 单个文档的线上描述(phonon 读完本地文件后封装)。 */\nexport const DocumentDescriptor = z.object({\n name: z.string().min(1),\n /** 相对项目根的路径(审计/去重用;不暴露设备绝对路径)。 */\n relativePath: z.string().optional(),\n mimeType: z.string().optional(),\n kind: DocumentKind.default(\"file\"),\n caption: z.string().optional(),\n sizeBytes: z.number().int().nonnegative().optional(),\n /** 内容 sha256(完整性校验 / 去重)。 */\n sha256: z.string().optional(),\n content: DocumentContent,\n});\nexport type DocumentDescriptor = z.infer<typeof DocumentDescriptor>;\n\n// --- document.send(phonon → server)---\nexport const DocumentSendParams = z.object({\n /** 关联会话(通常有;纯设备级发送可省)。 */\n sessionId: SessionId.optional(),\n /** 关联轮次(若在某轮对话内触发)。 */\n turnId: z.string().optional(),\n documents: z.array(DocumentDescriptor).min(1),\n at: Timestamp,\n});\nexport type DocumentSendParams = z.infer<typeof DocumentSendParams>;\n\nexport const DocumentSendResult = z.object({\n delivered: z.array(\n z.object({\n name: z.string(),\n ok: z.boolean(),\n /** 服务端落地引用(如云文档 token / 附件 id)。 */\n serverRef: z.string().optional(),\n error: z.string().optional(),\n }),\n ),\n});\nexport type DocumentSendResult = z.infer<typeof DocumentSendResult>;\n\n// ===========================================================================\n// 大文件:凭证上传(P1-6 / Gemini#2)\n// 不走 WS 发文件主体(避免内存暴涨/断线重传痛),而是:\n// phonon → document.prepare_upload {filename,size,mime,sha256}\n// server → 返回一个 HTTP 上传地址(预签名 URL / 一次性 token)\n// phonon 本地跑标准 HTTP POST(multipart/流式/断点续传)\n// 上传成功后用 document.send 用 ref 关联回 session\n// ===========================================================================\nexport const DocumentPrepareUploadParams = z.object({\n sessionId: SessionId.optional(),\n turnId: z.string().optional(),\n filename: z.string().min(1),\n sizeBytes: z.number().int().nonnegative(),\n mimeType: z.string().optional(),\n sha256: z.string().optional(),\n kind: DocumentKind.default(\"file\"),\n at: Timestamp,\n});\nexport type DocumentPrepareUploadParams = z.infer<typeof DocumentPrepareUploadParams>;\n\nexport const DocumentPrepareUploadResult = z.object({\n /** 上传句柄,上传成功后回填到 DocumentContent.ref。 */\n uploadRef: z.string(),\n /** server 给的 HTTP 上传地址(预签名 URL 等)。 */\n uploadUrl: z.string(),\n /** HTTP 方法(默认 PUT)。 */\n method: z.enum([\"PUT\", \"POST\"]).default(\"PUT\"),\n /** 需携带的额外请求头。 */\n headers: z.record(z.string()).optional(),\n /** 上传地址过期时间。 */\n expiresAt: Timestamp.optional(),\n});\nexport type DocumentPrepareUploadResult = z.infer<typeof DocumentPrepareUploadResult>;\n","import { z } from \"zod\";\nimport { SessionId, Timestamp } from \"./common.js\";\n\n/**\n * 人机交互协议(design 平面③ / D21)。\n *\n * 场景:HITL 时、或 agent 主动想问人,发一个**可交互卡片/表单**(抽象结构),\n * phonon → server 渲染给人(飞书卡片/网页/TG 按钮…由服务端决定,复用「甩锅服务端」原则),\n * 人填完 → 原路返回 → 注入回 agent。\n *\n * 两个层次:\n * - InteractionDirective :agent emit 的表单定义(skill 教,让任何模型都能发)\n * - interaction.request :phonon → server 线协议(带 requestId,阻塞等回填)\n * - interaction.response :server → phonon 线协议(人填完的值)\n *\n * 表单只定义**抽象字段结构**,不绑定任何渲染方式——服务端自由渲染。\n */\n\n/** 字段类型(抽象,渲染由服务端决定)。 */\nexport const FieldType = z.enum([\n \"text\", // 单行文本\n \"textarea\", // 多行文本\n \"number\",\n \"boolean\", // 开关/勾选\n \"select\", // 单选\n \"multiselect\", // 多选\n \"date\",\n]);\nexport type FieldType = z.infer<typeof FieldType>;\n\nexport const FormFieldOption = z.object({\n label: z.string(),\n value: z.string(),\n});\nexport type FormFieldOption = z.infer<typeof FormFieldOption>;\n\n/**\n * 表单字段——按 type 的 discriminated union(P2-16)。\n * 每种类型携自己的 defaultValue 类型与专属字段,避免「select 该传 string 还是 string[]」的歧义。\n */\nconst FieldBase = { key: z.string().min(1), label: z.string().min(1), required: z.boolean().default(false), help: z.string().optional() };\n\nexport const FormField = z.discriminatedUnion(\"type\", [\n z.object({ ...FieldBase, type: z.literal(\"text\"), placeholder: z.string().optional(), defaultValue: z.string().optional() }),\n z.object({ ...FieldBase, type: z.literal(\"textarea\"), placeholder: z.string().optional(), defaultValue: z.string().optional() }),\n z.object({ ...FieldBase, type: z.literal(\"number\"), defaultValue: z.number().optional() }),\n z.object({ ...FieldBase, type: z.literal(\"boolean\"), defaultValue: z.boolean().optional() }),\n z.object({ ...FieldBase, type: z.literal(\"select\"), options: z.array(FormFieldOption), defaultValue: z.string().optional() }),\n z.object({ ...FieldBase, type: z.literal(\"multiselect\"), options: z.array(FormFieldOption), defaultValue: z.array(z.string()).optional() }),\n z.object({ ...FieldBase, type: z.literal(\"date\"), defaultValue: z.string().optional() }),\n]);\nexport type FormField = z.infer<typeof FormField>;\n\n/** 表单/卡片定义(抽象)。 */\nexport const InteractionForm = z.object({\n title: z.string().min(1),\n /** 卡片正文/说明(可选)。 */\n description: z.string().optional(),\n fields: z.array(FormField).default([]),\n /** 提交/操作按钮;纯通知类可只放一个「知道了」。 */\n submitLabel: z.string().default(\"提交\"),\n cancelLabel: z.string().optional(),\n});\nexport type InteractionForm = z.infer<typeof InteractionForm>;\n\n/**\n * agent emit 的指令(skill 教)——和 interaction.request 结构基本一致,\n * 但不带 requestId(由 phonon 生成)。\n */\nexport const InteractionDirective = z.object({\n form: InteractionForm,\n /** 是否阻塞等待人回填(true=问答;false=纯通知不等)。 */\n blocking: z.boolean().default(true),\n /** 关联 hookId(若由 HITL hook 触发,便于和 hook.resolve 合流)。 */\n hookId: z.string().optional(),\n});\nexport type InteractionDirective = z.infer<typeof InteractionDirective>;\n\n// --- interaction.request(phonon → server)---\nexport const InteractionRequestParams = z.object({\n /** 本次交互唯一 id,response 用它配对。 */\n requestId: z.string().min(1),\n sessionId: SessionId.optional(),\n turnId: z.string().optional(),\n form: InteractionForm,\n blocking: z.boolean().default(true),\n /** 关联 hookId(HITL 场景)。 */\n hookId: z.string().optional(),\n /**\n * 可选超时(秒,P1-5)。超时后 phonon 以 timeout 收尾本次交互,agent 按预设继续。\n * 0 或缺省 = 不超时(人可能去开会/带娃,长期挂起)。\n */\n timeoutSeconds: z.number().int().nonnegative().optional(),\n at: Timestamp,\n});\nexport type InteractionRequestParams = z.infer<typeof InteractionRequestParams>;\n\n/** 人机交互的生命周期状态(P1-5):pending → submitted | cancelled | timeout。 */\nexport const InteractionStatus = z.enum([\"pending\", \"submitted\", \"cancelled\", \"timeout\"]);\nexport type InteractionStatus = z.infer<typeof InteractionStatus>;\n\n/** 阻塞模式下,request 的最终结果(人填完后服务端回的)。 */\nexport const InteractionRequestResult = z.object({\n requestId: z.string(),\n /** 结果状态:submit | cancel | timeout。 */\n action: z.enum([\"submit\", \"cancel\", \"timeout\"]),\n /** 提交时各字段值(key → 值)。 */\n values: z.record(z.union([z.string(), z.array(z.string()), z.boolean(), z.number()])).optional(),\n});\nexport type InteractionRequestResult = z.infer<typeof InteractionRequestResult>;\n\n// --- interaction.cancel(server → phonon 或 phonon 内部):主动取消一个 pending 交互 ---\nexport const InteractionCancelParams = z.object({\n requestId: z.string().min(1),\n reason: z.string().optional(),\n});\nexport type InteractionCancelParams = z.infer<typeof InteractionCancelParams>;\n\nexport const InteractionCancelResult = z.object({\n requestId: z.string(),\n cancelled: z.boolean(),\n});\nexport type InteractionCancelResult = z.infer<typeof InteractionCancelResult>;\n\n/**\n * server → phonon 的回填(非阻塞模式或异步回填走这个 notification;\n * 阻塞模式可直接用 interaction.request 的 result 返回,二选一,实现可都支持)。\n */\nexport const InteractionResponseParams = z.object({\n requestId: z.string().min(1),\n action: z.enum([\"submit\", \"cancel\", \"timeout\"]),\n values: z.record(z.union([z.string(), z.array(z.string()), z.boolean(), z.number()])).optional(),\n at: Timestamp,\n});\nexport type InteractionResponseParams = z.infer<typeof InteractionResponseParams>;\n","import { z } from \"zod\";\nimport { ProjectId, Timestamp } from \"./common.js\";\n\n/**\n * 项目管理协议(design D23)。\n *\n * 一个项目 = 一个目录 + Git。所有 session 必须绑定一个项目(projectId)。\n * 项目是磁盘上的客观目录,**设备级共享、不受 tenant 隔离**——不同 tenant 都能看到/用\n * 同一项目,在其下各干各的;冲突风险用户自担。(隔离发生在会话/任务层,不在文件层。)\n */\n\n/** 项目描述。 */\nexport const ProjectDescriptor = z.object({\n projectId: ProjectId,\n /** 展示名。 */\n name: z.string().min(1),\n /** 项目目录的绝对路径(设备本地)。 */\n path: z.string().min(1),\n /** 是否已 git init。 */\n git: z.boolean().default(true),\n /** 当前分支(若有)。 */\n branch: z.string().optional(),\n /** 可选:远端 URL。 */\n remote: z.string().optional(),\n createdAt: Timestamp,\n});\nexport type ProjectDescriptor = z.infer<typeof ProjectDescriptor>;\n\n// --- project.create ---\nexport const ProjectCreateParams = z.object({\n /** 可选:幂等键(P0-3)。 */\n clientRequestId: z.string().optional(),\n name: z.string().min(1),\n /**\n * 可选:指定目录路径。缺省由 phonon 在受控工作区下按 name 生成\n * (避免服务端越权指定任意本地路径)。\n */\n path: z.string().optional(),\n /** 是否 git init(默认 true,项目 = 目录 + Git)。 */\n git: z.boolean().default(true),\n /** 可选:初始化时设置的远端。 */\n remote: z.string().optional(),\n});\nexport type ProjectCreateParams = z.infer<typeof ProjectCreateParams>;\n\nexport const ProjectCreateResult = z.object({\n project: ProjectDescriptor,\n});\nexport type ProjectCreateResult = z.infer<typeof ProjectCreateResult>;\n\n// --- project.list ---\nexport const ProjectListParams = z.object({}).default({});\nexport type ProjectListParams = z.infer<typeof ProjectListParams>;\n\nexport const ProjectListResult = z.object({\n projects: z.array(ProjectDescriptor),\n});\nexport type ProjectListResult = z.infer<typeof ProjectListResult>;\n\n// --- project.get ---\nexport const ProjectGetParams = z.object({ projectId: ProjectId });\nexport type ProjectGetParams = z.infer<typeof ProjectGetParams>;\n\nexport const ProjectGetResult = z.object({ project: ProjectDescriptor });\nexport type ProjectGetResult = z.infer<typeof ProjectGetResult>;\n\n// --- project.remove ---\nexport const ProjectRemoveParams = z.object({\n projectId: ProjectId,\n /**\n * 是否删除物理目录。默认 false(仅从 phonon 解绑/注销,保留磁盘文件,防误删)。\n * true 才真正删目录——危险操作,需 policy allowDeleteFiles。\n */\n deleteFiles: z.boolean().default(false),\n /**\n * 有 active session 绑定本项目时的处理(P1-7 / Minimax#5):\n * - reject(默认):还有 active session → errProjectHasActiveSessions\n * - cascade :级联 terminate 所有 active session 再移除\n */\n whenActiveSessions: z.enum([\"reject\", \"cascade\"]).default(\"reject\"),\n});\nexport type ProjectRemoveParams = z.infer<typeof ProjectRemoveParams>;\n\nexport const ProjectRemoveResult = z.object({\n projectId: ProjectId,\n removed: z.literal(true),\n filesDeleted: z.boolean(),\n /** cascade 时被级联 terminate 的 session。 */\n terminatedSessions: z.array(z.string()).optional(),\n});\nexport type ProjectRemoveResult = z.infer<typeof ProjectRemoveResult>;\n\n// ===========================================================================\n// Git / worktree 子能力(D25)\n// worktree = 同一仓库的多个工作目录,天然适配「多 tenant/session 在同一项目各干各的」。\n// ===========================================================================\n\n/** worktree 描述。 */\nexport const WorktreeDescriptor = z.object({\n /** worktree 标识(phonon 生成)。 */\n worktreeId: z.string().min(1),\n projectId: ProjectId,\n /** worktree 的工作目录路径。 */\n path: z.string().min(1),\n /** 该 worktree 检出的分支。 */\n branch: z.string().min(1),\n /** 是否是主工作区(项目本体目录)。 */\n isPrimary: z.boolean().default(false),\n createdAt: Timestamp.optional(),\n});\nexport type WorktreeDescriptor = z.infer<typeof WorktreeDescriptor>;\n\n// --- project.worktree.create:基于某 branch 创建 worktree ---\nexport const WorktreeCreateParams = z.object({\n /** 可选:幂等键(P0-3)。 */\n clientRequestId: z.string().optional(),\n projectId: ProjectId,\n /** 基于哪个已有 branch 创建(检出点)。 */\n baseBranch: z.string().min(1),\n /**\n * 可选:新建并检出的分支名。缺省则直接检出 baseBranch\n * (注:同一 branch 不能被两个 worktree 同时检出,所以多开并发时通常传 newBranch)。\n */\n newBranch: z.string().optional(),\n /** 可选:指定 worktree 路径;缺省由 phonon 在受控区生成。 */\n path: z.string().optional(),\n});\nexport type WorktreeCreateParams = z.infer<typeof WorktreeCreateParams>;\n\nexport const WorktreeCreateResult = z.object({\n worktree: WorktreeDescriptor,\n});\nexport type WorktreeCreateResult = z.infer<typeof WorktreeCreateResult>;\n\n// --- project.worktree.list ---\nexport const WorktreeListParams = z.object({ projectId: ProjectId });\nexport type WorktreeListParams = z.infer<typeof WorktreeListParams>;\n\nexport const WorktreeListResult = z.object({\n worktrees: z.array(WorktreeDescriptor),\n});\nexport type WorktreeListResult = z.infer<typeof WorktreeListResult>;\n\n// --- project.worktree.remove:清理 worktree ---\nexport const WorktreeRemoveParams = z.object({\n projectId: ProjectId,\n worktreeId: z.string().min(1),\n /**\n * 是否强制清理(P1-7)。默认 false:\n * 有未提交变更 → errWorktreeHasChanges;还有 active/running session 绑定 → errWorktreeInUse。\n * force=true 才允许硬删,但会连带影响返回 affectedSessions。\n */\n force: z.boolean().default(false),\n});\nexport type WorktreeRemoveParams = z.infer<typeof WorktreeRemoveParams>;\n\nexport const WorktreeRemoveResult = z.object({\n worktreeId: z.string(),\n removed: z.literal(true),\n /** 被连带影响(被迫 terminate)的 session(force 硬删时)。 */\n affectedSessions: z.array(z.string()).optional(),\n});\nexport type WorktreeRemoveResult = z.infer<typeof WorktreeRemoveResult>;\n\n// --- project.git.deleteBranch:删除(已合并的)branch ---\nexport const GitDeleteBranchParams = z.object({\n projectId: ProjectId,\n branch: z.string().min(1),\n /**\n * 是否强制删除(P1-7)。默认 false:\n * 未合并 → errBranchNotMerged;仍被某 worktree 检出 → errBranchInUse。\n * force=true 强删未合并(git branch -D),返回 affectedWorktrees。\n */\n force: z.boolean().default(false),\n});\nexport type GitDeleteBranchParams = z.infer<typeof GitDeleteBranchParams>;\n\nexport const GitDeleteBranchResult = z.object({\n branch: z.string(),\n deleted: z.literal(true),\n wasMerged: z.boolean().optional(),\n /** 被连带影响的 worktree(force 硬删时)。 */\n affectedWorktrees: z.array(z.string()).optional(),\n});\nexport type GitDeleteBranchResult = z.infer<typeof GitDeleteBranchResult>;\n","import { z } from \"zod\";\nimport { AgentId, ProjectId, Timestamp } from \"./common.js\";\n\n/**\n * Skill 管理协议(design D24)。\n *\n * 给指定 agent 安装/卸载 skill,支持两级 scope:\n * - global : agent 全局,对该 agent 所有项目可见\n * - project : 项目级,仅对某 projectId 可见(需 projectId)\n *\n * 每个 agent 靠 capability `skillManagement` 声明是否支持;不支持 → errCapabilityUnsupported。\n */\n\nexport const SkillScope = z.enum([\"global\", \"project\"]);\nexport type SkillScope = z.infer<typeof SkillScope>;\n\n/** skill 来源:内联内容、本地路径、或远端引用。 */\nexport const SkillSource = z.union([\n z.object({ kind: z.literal(\"inline\"), files: z.record(z.string()) }), // path → content\n z.object({\n kind: z.literal(\"archive\"),\n /** v0 先支持 tar.gz;zip/archiveUrl 后续再加,避免安全边界没收稳。 */\n format: z.literal(\"tar.gz\"),\n contentBase64: z.string().min(1),\n /** 强烈建议传;phonon 会校验内容 hash,防传输/供应链篡改。 */\n sha256: z.string().optional(),\n /** 可选大小提示,便于 policy/日志;实际大小以 decode 后为准。 */\n sizeBytes: z.number().int().positive().optional(),\n }),\n z.object({ kind: z.literal(\"localPath\"), path: z.string().min(1) }),\n z.object({\n kind: z.literal(\"url\"),\n url: z.string().min(1),\n /** 可选:内容校验和(P2-12 / 供应链可信度)。url 装需 policy allowUrlSkillInstall。 */\n sha256: z.string().optional(),\n }),\n]);\nexport type SkillSource = z.infer<typeof SkillSource>;\n\n/** 已安装 skill 的描述。 */\nexport const SkillDescriptor = z.object({\n /** skill 名/key。 */\n name: z.string().min(1),\n /** 归属哪个 agent。 */\n agent: AgentId,\n scope: SkillScope,\n /** scope=project 时所属项目。 */\n projectId: ProjectId.optional(),\n /** 版本(P2-12,同名冲突可辨)。 */\n version: z.string().optional(),\n /** 内容 hash(P2-12,可复现/防篡改)。 */\n hash: z.string().optional(),\n /** 适配的 agent(某些 skill 只适 OpenClaw 不适 Codex)。 */\n compatibleAgents: z.array(AgentId).optional(),\n /** 来源是否可信(本地/内联=可信,url=需校验)。 */\n sourceTrusted: z.boolean().optional(),\n /** 安装落地路径(设备本地)。 */\n installedPath: z.string().optional(),\n installedAt: Timestamp.optional(),\n});\nexport type SkillDescriptor = z.infer<typeof SkillDescriptor>;\n\n// --- skill.install ---\nexport const SkillInstallParams = z\n .object({\n /** 目标 agent。 */\n agent: AgentId,\n name: z.string().min(1),\n scope: SkillScope,\n /** scope=project 时必填。 */\n projectId: ProjectId.optional(),\n source: SkillSource,\n })\n .refine((v) => v.scope !== \"project\" || !!v.projectId, {\n message: \"scope=project requires projectId\",\n path: [\"projectId\"],\n });\nexport type SkillInstallParams = z.infer<typeof SkillInstallParams>;\n\nexport const SkillInstallResult = z.object({\n skill: SkillDescriptor,\n});\nexport type SkillInstallResult = z.infer<typeof SkillInstallResult>;\n\n// --- skill.uninstall ---\nexport const SkillUninstallParams = z\n .object({\n agent: AgentId,\n name: z.string().min(1),\n scope: SkillScope,\n projectId: ProjectId.optional(),\n })\n .refine((v) => v.scope !== \"project\" || !!v.projectId, {\n message: \"scope=project requires projectId\",\n path: [\"projectId\"],\n });\nexport type SkillUninstallParams = z.infer<typeof SkillUninstallParams>;\n\nexport const SkillUninstallResult = z.object({\n agent: AgentId,\n name: z.string(),\n scope: SkillScope,\n uninstalled: z.literal(true),\n});\nexport type SkillUninstallResult = z.infer<typeof SkillUninstallResult>;\n\n// --- skill.list ---\nexport const SkillListParams = z.object({\n /** 可选:按 agent 过滤。 */\n agent: AgentId.optional(),\n /** 可选:按 scope 过滤。 */\n scope: SkillScope.optional(),\n /** 可选:按项目过滤(看某项目可见的 skill)。 */\n projectId: ProjectId.optional(),\n});\nexport type SkillListParams = z.infer<typeof SkillListParams>;\n\nexport const SkillListResult = z.object({\n skills: z.array(SkillDescriptor),\n});\nexport type SkillListResult = z.infer<typeof SkillListResult>;\n","import { z } from \"zod\";\nimport { AgentId, ProjectId } from \"./common.js\";\n\n/**\n * 本地安全策略(design D27 / review P0-1)。\n *\n * phonon 不做终端用户鉴权(那是服务端的事),但**必须有设备主人配置的本地授权边界**——\n * 否则任意接入的 server 都能让本地 agent 读任意文件、装任意 skill、删 worktree。\n *\n * 这是「设备 policy」,不是「用户鉴权」。每个 tenant 一份,phonon 在执行前据此拦截。\n * 这些是本地配置,不进 device→server 的线协议;放协议包是为了类型共享与校验。\n */\n\n/** 单个 tenant 的本地授权边界。 */\nexport const TenantPolicy = z.object({\n /** 允许操作的项目根目录白名单(绝对路径)。document/project 路径必须落在其下。 */\n allowedProjectRoots: z.array(z.string()).default([]),\n /** 允许使用的 agent 白名单;空 = 不限制。 */\n allowedAgents: z.array(AgentId).default([]),\n /** 允许的方法白名单;空 = 全允许。用它可表达「只读租户」(只放查询类方法)。 */\n allowedMethods: z.array(z.string()).default([]),\n /** 是否允许全局 skill 安装(影响该 agent 所有项目,危险)。默认 false。 */\n allowGlobalSkillInstall: z.boolean().default(false),\n /** 是否允许从 url 安装 skill(供应链入口,危险)。默认 false。 */\n allowUrlSkillInstall: z.boolean().default(false),\n /** 是否允许物理删盘(project.remove deleteFiles / worktree force 等)。默认 false。 */\n allowDeleteFiles: z.boolean().default(false),\n /** document.send 是否允许发送项目/worktree 目录之外的文件。默认 false(project-scoped)。 */\n allowExternalDocuments: z.boolean().default(false),\n /** env.list reveal=true 是否允许返回环境变量明文。默认 false(只能脱敏查看)。 */\n allowEnvReveal: z.boolean().default(false),\n /** 单文件上传上限(字节);超出走 prepare_upload 或拒绝。 */\n maxUploadBytes: z.number().int().positive().optional(),\n /** 敏感路径黑名单(即使在 allowedProjectRoots 内也拒绝,如 .ssh/.aws/.env)。 */\n denyPathPatterns: z.array(z.string()).default([\n \"**/.ssh/**\",\n \"**/.aws/**\",\n \"**/.env\",\n \"**/.git/config\",\n \"**/id_rsa*\",\n \"**/*.pem\",\n \"**/openclaw.json\",\n ]),\n});\nexport type TenantPolicy = z.infer<typeof TenantPolicy>;\n\n/** policy 默认值(最严格:白名单空、写操作全关)。 */\nexport const DEFAULT_TENANT_POLICY: TenantPolicy = TenantPolicy.parse({});\n\n/**\n * 校验一个绝对路径是否落在某项目根白名单内(不含 deny 匹配)。\n * 真实 glob/deny 匹配由 core 实现;这里给协议层一个轻量前缀检查骨架。\n */\nexport function isPathUnderRoots(absPath: string, roots: readonly string[]): boolean {\n if (roots.length === 0) return false;\n const norm = absPath.replace(/\\\\/g, \"/\");\n return roots.some((r) => {\n const root = r.replace(/\\\\/g, \"/\").replace(/\\/+$/, \"\");\n return norm === root || norm.startsWith(root + \"/\");\n });\n}\n\n/** policy 拒绝时的归一化结果(core 用,便于回 errPolicyDenied)。 */\nexport const PolicyDecision = z.object({\n allowed: z.boolean(),\n /** 拒绝原因(如 \"path_outside_project\" / \"url_skill_disabled\" / \"delete_not_allowed\")。 */\n reason: z.string().optional(),\n /** 关联 projectId(若适用)。 */\n projectId: ProjectId.optional(),\n});\nexport type PolicyDecision = z.infer<typeof PolicyDecision>;\n","import { z } from \"zod\";\nimport { DeviceId, TenantId, Timestamp } from \"./common.js\";\n\n/**\n * 连接握手(design §6)。\n *\n * phonon 拨出连接后,首先发 connect.hello 表明:协议版本、设备身份。\n * device key 的鉴权由传输层/服务端处理(如 WS header / 首帧),不在业务 params 里明文带。\n * server 回 connect.welcome 确认,并可下发 tenant 绑定与服务端能力。\n */\n\nexport const ConnectHelloParams = z.object({\n /** 本端协议版本(= PROTOCOL_VERSION)。 */\n protocolVersion: z.string(),\n /** 设备标识(服务端用于区分多设备)。 */\n deviceId: DeviceId,\n /** phonon 实现版本(软件版本,便于服务端兼容处理)。 */\n phononVersion: z.string().optional(),\n /** 本端声明支持的可选特性开关,便于前向兼容。 */\n features: z.array(z.string()).default([]),\n /** 设备鉴权(可选):server 据此验证设备身份。也可走传输层 header。 */\n auth: z.object({ deviceKey: z.string() }).optional(),\n /**\n * 重连时携带(P0-4):phonon 本地 outbox 中每个 session 尚未被 ack 的起始 seq,\n * 让 server 知道哪些要补发 / 从哪重放。首次连接可省略。\n */\n resumeFrom: z\n .array(z.object({ sessionId: z.string(), fromSeq: z.number().int().nonnegative() }))\n .optional(),\n at: Timestamp,\n});\nexport type ConnectHelloParams = z.infer<typeof ConnectHelloParams>;\n\nexport const ConnectWelcomeResult = z.object({\n /** 服务端协议版本。 */\n protocolVersion: z.string(),\n /** 服务端为本连接分配/确认的租户身份(= 一条服务端连接,design D13)。 */\n tenantId: TenantId,\n /** 服务端声明支持的可选特性。 */\n features: z.array(z.string()).default([]),\n /**\n * 重连时服务端告知「我各 session 最后收到的 seq」(P0-4),\n * phonon 据此从 outbox 精确补发(> lastSeq 的),避免重复/遗漏。\n */\n ackedSeqs: z\n .array(z.object({ sessionId: z.string(), lastSeq: z.number().int().nonnegative() }))\n .optional(),\n at: Timestamp,\n});\nexport type ConnectWelcomeResult = z.infer<typeof ConnectWelcomeResult>;\n","import { z } from \"zod\";\n\n/**\n * 设备级信息与可观测协议。\n *\n * device.info:相对静态的 OS/机器信息,用于服务端按需调度。\n * device.resources:运行时资源快照,用于 debug,不做资源调度或限制。\n */\n\nexport const DeviceInfoParams = z.object({}).default({});\nexport type DeviceInfoParams = z.infer<typeof DeviceInfoParams>;\n\nexport const DeviceInfoResult = z.object({\n at: z.string().datetime({ offset: true }),\n hostname: z.string(),\n os: z.object({\n platform: z.enum([\"aix\", \"darwin\", \"freebsd\", \"linux\", \"openbsd\", \"sunos\", \"win32\", \"cygwin\", \"netbsd\"]).or(z.string()),\n type: z.string(),\n release: z.string(),\n arch: z.string(),\n }),\n runtime: z.object({\n node: z.string().optional(),\n }).optional(),\n /** 便于 server 做粗粒度任务路由:ios-development/windows-desktop-development/nvidia-gpu 等。 */\n capabilities: z.array(z.string()).default([]),\n});\nexport type DeviceInfoResult = z.infer<typeof DeviceInfoResult>;\n\nexport const DeviceResourcesParams = z.object({}).default({});\nexport type DeviceResourcesParams = z.infer<typeof DeviceResourcesParams>;\n\nexport const DeviceResourcesResult = z.object({\n at: z.string().datetime({ offset: true }),\n cpu: z.object({\n loadavg: z.array(z.number()).length(3).optional(),\n cores: z.number().int().positive().optional(),\n usagePercent: z.number().min(0).max(100).optional(),\n }).optional(),\n memory: z.object({\n totalBytes: z.number().nonnegative(),\n freeBytes: z.number().nonnegative(),\n usedBytes: z.number().nonnegative(),\n usagePercent: z.number().min(0).max(100).optional(),\n }),\n disk: z.object({\n path: z.string(),\n totalBytes: z.number().nonnegative().optional(),\n freeBytes: z.number().nonnegative().optional(),\n usedBytes: z.number().nonnegative().optional(),\n usagePercent: z.number().min(0).max(100).optional(),\n }).optional(),\n gpu: z.array(z.object({\n name: z.string().optional(),\n memoryTotalBytes: z.number().nonnegative().optional(),\n memoryUsedBytes: z.number().nonnegative().optional(),\n utilizationPercent: z.number().min(0).max(100).optional(),\n })).optional(),\n process: z.object({\n pid: z.number().int().positive(),\n uptimeSeconds: z.number().nonnegative(),\n rssBytes: z.number().nonnegative().optional(),\n heapUsedBytes: z.number().nonnegative().optional(),\n heapTotalBytes: z.number().nonnegative().optional(),\n }).optional(),\n});\nexport type DeviceResourcesResult = z.infer<typeof DeviceResourcesResult>;\n","import { z } from \"zod\";\nimport { ProjectId } from \"./common.js\";\n\n/**\n * 受控工作区文件读写协议。\n *\n * 与 document.send 不同:document.send 是 agent 主动把产物发给 server;\n * file.* 是 server 主动读写本地 project/worktree 内文件。\n */\n\nexport const FileEncoding = z.enum([\"utf8\", \"base64\"]);\nexport type FileEncoding = z.infer<typeof FileEncoding>;\n\nexport const FileScope = z.object({\n projectId: ProjectId,\n /** 可选:指定 worktree;缺省为项目主目录。 */\n worktreeId: z.string().min(1).optional(),\n});\nexport type FileScope = z.infer<typeof FileScope>;\n\nconst RelativePath = z.string().min(1).refine((p) => !p.startsWith(\"/\") && !p.includes(\"\\0\"), {\n message: \"path must be a relative path\",\n});\n\nexport const FileStat = z.object({\n path: z.string(),\n type: z.enum([\"file\", \"directory\", \"symlink\", \"other\"]),\n sizeBytes: z.number().nonnegative(),\n modifiedAt: z.string().datetime({ offset: true }).optional(),\n});\nexport type FileStat = z.infer<typeof FileStat>;\n\nexport const FileReadParams = FileScope.extend({\n path: RelativePath,\n encoding: FileEncoding.default(\"utf8\"),\n /** 可选:最大读取字节数,避免误读超大文件。 */\n maxBytes: z.number().int().positive().optional(),\n});\nexport type FileReadParams = z.infer<typeof FileReadParams>;\n\nexport const FileReadResult = z.object({\n path: z.string(),\n encoding: FileEncoding,\n data: z.string(),\n sizeBytes: z.number().nonnegative(),\n truncated: z.boolean().default(false),\n});\nexport type FileReadResult = z.infer<typeof FileReadResult>;\n\nexport const FileWriteParams = FileScope.extend({\n /** 可选:幂等键。 */\n clientRequestId: z.string().optional(),\n path: RelativePath,\n encoding: FileEncoding.default(\"utf8\"),\n data: z.string(),\n /** 缺省 true;false 时若文件已存在则报错。 */\n overwrite: z.boolean().default(true),\n /** 是否自动创建父目录。 */\n createDirs: z.boolean().default(true),\n});\nexport type FileWriteParams = z.infer<typeof FileWriteParams>;\n\nexport const FileWriteResult = z.object({\n path: z.string(),\n sizeBytes: z.number().nonnegative(),\n written: z.literal(true),\n});\nexport type FileWriteResult = z.infer<typeof FileWriteResult>;\n\nexport const FileListParams = FileScope.extend({\n path: RelativePath.default(\".\"),\n recursive: z.boolean().default(false),\n limit: z.number().int().positive().max(10000).default(500),\n});\nexport type FileListParams = z.infer<typeof FileListParams>;\n\nexport const FileListResult = z.object({\n path: z.string(),\n entries: z.array(FileStat),\n truncated: z.boolean().default(false),\n});\nexport type FileListResult = z.infer<typeof FileListResult>;\n\nexport const FileStatParams = FileScope.extend({ path: RelativePath });\nexport type FileStatParams = z.infer<typeof FileStatParams>;\nexport const FileStatResult = z.object({ stat: FileStat });\nexport type FileStatResult = z.infer<typeof FileStatResult>;\n\nexport const FileMkdirParams = FileScope.extend({\n /** 可选:幂等键。 */\n clientRequestId: z.string().optional(),\n path: RelativePath,\n recursive: z.boolean().default(true),\n});\nexport type FileMkdirParams = z.infer<typeof FileMkdirParams>;\nexport const FileMkdirResult = z.object({ path: z.string(), created: z.literal(true) });\nexport type FileMkdirResult = z.infer<typeof FileMkdirResult>;\n","import { z } from \"zod\";\nimport { ProjectId, AgentId } from \"./common.js\";\n\n/** Skill / agent 执行环境变量配置。明文存储在设备本地,list 默认脱敏。 */\nexport const EnvScope = z.enum([\"global\", \"project\", \"skill\"]);\nexport type EnvScope = z.infer<typeof EnvScope>;\n\nconst EnvTargetBase = z.object({\n scope: EnvScope,\n projectId: ProjectId.optional(),\n agent: AgentId.optional(),\n skillName: z.string().min(1).optional(),\n});\n\nfunction withEnvTargetRefine<T extends z.ZodTypeAny>(schema: T): T {\n return schema\n .refine((v: unknown) => (v as { scope?: string; projectId?: string }).scope !== \"project\" || !!(v as { projectId?: string }).projectId, { message: \"project scope requires projectId\", path: [\"projectId\"] })\n .refine((v: unknown) => {\n const x = v as { scope?: string; projectId?: string; agent?: string; skillName?: string };\n return x.scope !== \"skill\" || (!!x.projectId && !!x.agent && !!x.skillName);\n }, { message: \"skill scope requires projectId+agent+skillName\", path: [\"skillName\"] }) as unknown as T;\n}\n\nexport const EnvTarget = withEnvTargetRefine(EnvTargetBase);\nexport type EnvTarget = z.infer<typeof EnvTargetBase>;\n\nexport const EnvVarDescriptor = withEnvTargetRefine(EnvTargetBase.extend({\n name: z.string().min(1),\n value: z.string().optional(),\n redacted: z.boolean().default(true),\n updatedAt: z.string().datetime({ offset: true }).optional(),\n}));\nexport type EnvVarDescriptor = z.infer<typeof EnvVarDescriptor>;\n\nexport const EnvSetParams = withEnvTargetRefine(EnvTargetBase.extend({\n clientRequestId: z.string().optional(),\n name: z.string().min(1),\n value: z.string(),\n /** 可选:如果是 secret,list 默认永远脱敏。默认 true。 */\n secret: z.boolean().default(true),\n}));\nexport type EnvSetParams = z.infer<typeof EnvSetParams>;\nexport const EnvSetResult = z.object({ variable: EnvVarDescriptor });\nexport type EnvSetResult = z.infer<typeof EnvSetResult>;\n\nexport const EnvListParams = EnvTargetBase.partial().extend({\n /** 默认 false;true 需要本地 policy allowEnvReveal。 */\n reveal: z.boolean().default(false),\n});\nexport type EnvListParams = z.infer<typeof EnvListParams>;\nexport const EnvListResult = z.object({ variables: z.array(EnvVarDescriptor) });\nexport type EnvListResult = z.infer<typeof EnvListResult>;\n\nexport const EnvDeleteParams = withEnvTargetRefine(EnvTargetBase.extend({\n clientRequestId: z.string().optional(),\n name: z.string().min(1),\n}));\nexport type EnvDeleteParams = z.infer<typeof EnvDeleteParams>;\nexport const EnvDeleteResult = z.object({ deleted: z.literal(true), name: z.string() });\nexport type EnvDeleteResult = z.infer<typeof EnvDeleteResult>;\n","import { z } from \"zod\";\nimport { PhononErrorData } from \"./common.js\";\n\n/**\n * JSON-RPC 2.0 信封(design D2)。\n *\n * 单条 WebSocket 上双向跑 JSON-RPC 2.0:两端皆可作 requester。\n * - server → phonon:session.* / discovery.* / hook.resolve\n * - phonon → server:stream.event / hook.fired / discovery.changed / connect.hello\n *\n * 这里只定义「信封」的通用形状;具体方法的 params/result 由 methods.ts 绑定。\n */\n\nexport const JsonRpcVersion = z.literal(\"2.0\");\n\n/** 请求 id:字符串或数字(JSON-RPC 允许两者;notification 无 id)。 */\nexport const JsonRpcId = z.union([z.string(), z.number()]);\nexport type JsonRpcId = z.infer<typeof JsonRpcId>;\n\n/** 请求(需要响应)。 */\nexport const JsonRpcRequest = z.object({\n jsonrpc: JsonRpcVersion,\n id: JsonRpcId,\n method: z.string(),\n params: z.unknown().optional(),\n});\nexport type JsonRpcRequest = z.infer<typeof JsonRpcRequest>;\n\n/** 通知(不需要响应,无 id)——用于 stream.event / hook.fired / discovery.changed。 */\nexport const JsonRpcNotification = z.object({\n jsonrpc: JsonRpcVersion,\n method: z.string(),\n params: z.unknown().optional(),\n});\nexport type JsonRpcNotification = z.infer<typeof JsonRpcNotification>;\n\n/** 成功响应。 */\nexport const JsonRpcSuccess = z.object({\n jsonrpc: JsonRpcVersion,\n id: JsonRpcId,\n result: z.unknown(),\n});\nexport type JsonRpcSuccess = z.infer<typeof JsonRpcSuccess>;\n\n/** JSON-RPC error 对象;data 携带 phonon 应用级错误结构。 */\nexport const JsonRpcErrorObject = z.object({\n /** JSON-RPC 传输级 code(-32700..-32600 保留;应用错误用 data.appCode 判别)。 */\n code: z.number().int(),\n message: z.string(),\n data: PhononErrorData.optional(),\n});\nexport type JsonRpcErrorObject = z.infer<typeof JsonRpcErrorObject>;\n\n/** 失败响应。 */\nexport const JsonRpcError = z.object({\n jsonrpc: JsonRpcVersion,\n id: JsonRpcId.nullable(),\n error: JsonRpcErrorObject,\n});\nexport type JsonRpcError = z.infer<typeof JsonRpcError>;\n\n/** 任意一条 JSON-RPC 报文。 */\nexport const JsonRpcMessage = z.union([\n JsonRpcRequest,\n JsonRpcNotification,\n JsonRpcSuccess,\n JsonRpcError,\n]);\nexport type JsonRpcMessage = z.infer<typeof JsonRpcMessage>;\n\n/** 标准 JSON-RPC 传输级错误码。 */\nexport const JSON_RPC_CODES = {\n parseError: -32700,\n invalidRequest: -32600,\n methodNotFound: -32601,\n invalidParams: -32602,\n internalError: -32603,\n /** 应用级错误统一用这个 code,细分看 data.appCode。 */\n applicationError: -32000,\n} as const;\n","import { z } from \"zod\";\nimport {\n ConnectHelloParams,\n ConnectWelcomeResult,\n} from \"./connect.js\";\nimport {\n DiscoveryListParams,\n DiscoveryListResult,\n DiscoveryGetParams,\n DiscoveryGetResult,\n DiscoveryChangedParams,\n} from \"./discovery.js\";\nimport {\n SessionCreateParams,\n SessionCreateResult,\n SessionSendParams,\n SessionSendAck,\n SessionInjectParams,\n SessionInjectResult,\n SessionCompressParams,\n SessionCompressResult,\n SessionSwitchModelParams,\n SessionSwitchModelResult,\n SessionInterruptParams,\n SessionInterruptResult,\n SessionTerminateParams,\n SessionTerminateResult,\n SessionStatusParams,\n SessionStatusResult,\n SessionListParams,\n SessionListResult,\n} from \"./session.js\";\nimport { StreamEvent, StreamAckParams } from \"./stream.js\";import {\n HookFiredParams,\n HookResolveParams,\n HookResolveResult,\n} from \"./hook.js\";\nimport { DocumentSendParams, DocumentSendResult, DocumentPrepareUploadParams, DocumentPrepareUploadResult } from \"./document.js\";\nimport {\n InteractionRequestParams,\n InteractionRequestResult,\n InteractionResponseParams,\n InteractionCancelParams,\n InteractionCancelResult,\n} from \"./interaction.js\";\nimport {\n ProjectCreateParams,\n ProjectCreateResult,\n ProjectListParams,\n ProjectListResult,\n ProjectGetParams,\n ProjectGetResult,\n ProjectRemoveParams,\n ProjectRemoveResult,\n WorktreeCreateParams,\n WorktreeCreateResult,\n WorktreeListParams,\n WorktreeListResult,\n WorktreeRemoveParams,\n WorktreeRemoveResult,\n GitDeleteBranchParams,\n GitDeleteBranchResult,\n} from \"./project.js\";\nimport {\n SkillInstallParams,\n SkillInstallResult,\n SkillUninstallParams,\n SkillUninstallResult,\n SkillListParams,\n SkillListResult,\n} from \"./skill.js\";\nimport { DeviceInfoParams, DeviceInfoResult, DeviceResourcesParams, DeviceResourcesResult } from \"./device.js\";\nimport {\n FileReadParams,\n FileReadResult,\n FileWriteParams,\n FileWriteResult,\n FileListParams,\n FileListResult,\n FileStatParams,\n FileStatResult,\n FileMkdirParams,\n FileMkdirResult,\n} from \"./file.js\";\nimport { EnvSetParams, EnvSetResult, EnvListParams, EnvListResult, EnvDeleteParams, EnvDeleteResult } from \"./env.js\";\n\n/**\n * 方法注册表(design 全协议的单一事实来源)。\n *\n * 每个方法声明:\n * - direction: 谁是 requester\n * s2p = server → phonon (服务端下发操作)\n * p2s = phonon → server (设备上报结果/事件/发现)\n * - kind: \"request\"(需响应)| \"notification\"(无响应)\n * - params / result 的 zod schema\n *\n * core 与 client-sdk 都 import 本表,确保两端对齐、可机器校验。\n */\n\nconst z_void = z.undefined();\n\nexport const METHODS = {\n // --- 握手(phonon 拨出后先发)---\n \"connect.hello\": {\n direction: \"p2s\",\n kind: \"request\",\n params: ConnectHelloParams,\n result: ConnectWelcomeResult,\n },\n\n // --- 设备级信息与可观测(server 查询)---\n \"device.info\": {\n direction: \"s2p\",\n kind: \"request\",\n params: DeviceInfoParams,\n result: DeviceInfoResult,\n },\n \"device.resources\": {\n direction: \"s2p\",\n kind: \"request\",\n params: DeviceResourcesParams,\n result: DeviceResourcesResult,\n },\n\n // --- 发现(server 查询;phonon 主动推变更)---\n \"discovery.list\": {\n direction: \"s2p\",\n kind: \"request\",\n params: DiscoveryListParams,\n result: DiscoveryListResult,\n },\n \"discovery.get\": {\n direction: \"s2p\",\n kind: \"request\",\n params: DiscoveryGetParams,\n result: DiscoveryGetResult,\n },\n \"discovery.changed\": {\n direction: \"p2s\",\n kind: \"notification\",\n params: DiscoveryChangedParams,\n result: z_void,\n },\n\n // --- session 原语(server 下发)---\n \"session.create\": {\n direction: \"s2p\",\n kind: \"request\",\n params: SessionCreateParams,\n result: SessionCreateResult,\n },\n \"session.send\": {\n direction: \"s2p\",\n kind: \"request\",\n params: SessionSendParams,\n result: SessionSendAck,\n },\n \"session.inject\": {\n direction: \"s2p\",\n kind: \"request\",\n params: SessionInjectParams,\n result: SessionInjectResult,\n },\n \"session.compress\": {\n direction: \"s2p\",\n kind: \"request\",\n params: SessionCompressParams,\n result: SessionCompressResult,\n },\n \"session.switchModel\": {\n direction: \"s2p\",\n kind: \"request\",\n params: SessionSwitchModelParams,\n result: SessionSwitchModelResult,\n },\n \"session.interrupt\": {\n direction: \"s2p\",\n kind: \"request\",\n params: SessionInterruptParams,\n result: SessionInterruptResult,\n },\n \"session.terminate\": {\n direction: \"s2p\",\n kind: \"request\",\n params: SessionTerminateParams,\n result: SessionTerminateResult,\n },\n \"session.status\": {\n direction: \"s2p\",\n kind: \"request\",\n params: SessionStatusParams,\n result: SessionStatusResult,\n },\n \"session.list\": {\n direction: \"s2p\",\n kind: \"request\",\n params: SessionListParams,\n result: SessionListResult,\n },\n\n // --- 流式结果(phonon 上推;无响应)---\n \"stream.event\": {\n direction: \"p2s\",\n kind: \"notification\",\n params: StreamEvent,\n result: z_void,\n },\n // --- 流式 ack(server 确认 seq,phonon 据此清 outbox,P0-4)---\n \"stream.ack\": {\n direction: \"s2p\",\n kind: \"notification\",\n params: StreamAckParams,\n result: z_void,\n },\n\n // --- hook / HITL ---\n \"hook.fired\": {\n direction: \"p2s\",\n kind: \"request\", // phonon 发起、阻塞等 server 裁决\n params: HookFiredParams,\n result: HookResolveResult,\n },\n \"hook.resolve\": {\n direction: \"s2p\",\n kind: \"request\",\n params: HookResolveParams,\n result: HookResolveResult,\n },\n\n // --- 文档交换(agent emit 指令 → phonon 读本地文件 → 上传,平面③ / D20)---\n \"document.send\": {\n direction: \"p2s\",\n kind: \"request\",\n params: DocumentSendParams,\n result: DocumentSendResult,\n },\n \"document.prepare_upload\": {\n direction: \"p2s\",\n kind: \"request\", // 大文件凭证上传(P1-6)\n params: DocumentPrepareUploadParams,\n result: DocumentPrepareUploadResult,\n },\n\n // --- 人机交互(表单/卡片,agent主动或HITL发起,平面③ / D21)---\n \"interaction.request\": {\n direction: \"p2s\",\n kind: \"request\", // blocking 时阻塞等人回填\n params: InteractionRequestParams,\n result: InteractionRequestResult,\n },\n \"interaction.response\": {\n direction: \"s2p\",\n kind: \"notification\", // 异步/非阻塞回填走这条\n params: InteractionResponseParams,\n result: z_void,\n },\n \"interaction.cancel\": {\n direction: \"s2p\",\n kind: \"request\", // 主动取消一个 pending 交互(P1-5)\n params: InteractionCancelParams,\n result: InteractionCancelResult,\n },\n\n // --- 项目管理(目录 + Git;server 下发,D23)---\n \"project.create\": {\n direction: \"s2p\",\n kind: \"request\",\n params: ProjectCreateParams,\n result: ProjectCreateResult,\n },\n \"project.list\": {\n direction: \"s2p\",\n kind: \"request\",\n params: ProjectListParams,\n result: ProjectListResult,\n },\n \"project.get\": {\n direction: \"s2p\",\n kind: \"request\",\n params: ProjectGetParams,\n result: ProjectGetResult,\n },\n \"project.remove\": {\n direction: \"s2p\",\n kind: \"request\",\n params: ProjectRemoveParams,\n result: ProjectRemoveResult,\n },\n\n // --- worktree / git 子能力(D25)---\n \"project.worktree.create\": {\n direction: \"s2p\",\n kind: \"request\",\n params: WorktreeCreateParams,\n result: WorktreeCreateResult,\n },\n \"project.worktree.list\": {\n direction: \"s2p\",\n kind: \"request\",\n params: WorktreeListParams,\n result: WorktreeListResult,\n },\n \"project.worktree.remove\": {\n direction: \"s2p\",\n kind: \"request\",\n params: WorktreeRemoveParams,\n result: WorktreeRemoveResult,\n },\n \"project.git.deleteBranch\": {\n direction: \"s2p\",\n kind: \"request\",\n params: GitDeleteBranchParams,\n result: GitDeleteBranchResult,\n },\n\n // --- 受控工作区文件读写(server 下发,project/worktree scoped)---\n \"file.read\": {\n direction: \"s2p\",\n kind: \"request\",\n params: FileReadParams,\n result: FileReadResult,\n },\n \"file.write\": {\n direction: \"s2p\",\n kind: \"request\",\n params: FileWriteParams,\n result: FileWriteResult,\n },\n \"file.list\": {\n direction: \"s2p\",\n kind: \"request\",\n params: FileListParams,\n result: FileListResult,\n },\n \"file.stat\": {\n direction: \"s2p\",\n kind: \"request\",\n params: FileStatParams,\n result: FileStatResult,\n },\n \"file.mkdir\": {\n direction: \"s2p\",\n kind: \"request\",\n params: FileMkdirParams,\n result: FileMkdirResult,\n },\n\n // --- 环境变量配置(skill/agent 运行环境,默认脱敏)---\n \"env.set\": {\n direction: \"s2p\",\n kind: \"request\",\n params: EnvSetParams,\n result: EnvSetResult,\n },\n \"env.list\": {\n direction: \"s2p\",\n kind: \"request\",\n params: EnvListParams,\n result: EnvListResult,\n },\n \"env.delete\": {\n direction: \"s2p\",\n kind: \"request\",\n params: EnvDeleteParams,\n result: EnvDeleteResult,\n },\n\n // --- skill 管理(给 agent 装/卸 skill,global|project 两级,D24)---\n \"skill.install\": {\n direction: \"s2p\",\n kind: \"request\",\n params: SkillInstallParams,\n result: SkillInstallResult,\n },\n \"skill.uninstall\": {\n direction: \"s2p\",\n kind: \"request\",\n params: SkillUninstallParams,\n result: SkillUninstallResult,\n },\n \"skill.list\": {\n direction: \"s2p\",\n kind: \"request\",\n params: SkillListParams,\n result: SkillListResult,\n },\n} as const;\n\nexport type MethodName = keyof typeof METHODS;\nexport type MethodSpec = (typeof METHODS)[MethodName];\n\n/** 取某方法的 params 类型。 */\nexport type ParamsOf<M extends MethodName> = z.infer<(typeof METHODS)[M][\"params\"]>;\n/** 取某方法的 result 类型。 */\nexport type ResultOf<M extends MethodName> = z.infer<(typeof METHODS)[M][\"result\"]>;\n\n/** 运行时校验某方法的 params。 */\nexport function parseParams<M extends MethodName>(\n method: M,\n data: unknown,\n): ParamsOf<M> {\n return METHODS[method].params.parse(data) as ParamsOf<M>;\n}\n\n/** 运行时校验某方法的 result。 */\nexport function parseResult<M extends MethodName>(\n method: M,\n data: unknown,\n): ResultOf<M> {\n return METHODS[method].result.parse(data) as ResultOf<M>;\n}\n\n/** 全部方法名(运行时数组)。 */\nexport const METHOD_NAMES = Object.keys(METHODS) as MethodName[];\n","/**\n * @agent-phonon/protocol\n *\n * agent-phonon 的线协议——phonon 设备与服务端之间的唯一契约。\n * zod schema + 类型 + 方法注册表的单一事实来源(design docs/design.md)。\n */\n\nexport * from \"./schemas/common.js\";\nexport * from \"./schemas/capabilities.js\";\nexport * from \"./schemas/discovery.js\";\nexport * from \"./schemas/session.js\";\nexport * from \"./schemas/stream.js\";\nexport * from \"./schemas/hook.js\";\nexport * from \"./schemas/document.js\";\nexport * from \"./schemas/interaction.js\";\nexport * from \"./schemas/project.js\";\nexport * from \"./schemas/skill.js\";\nexport * from \"./schemas/policy.js\";\nexport * from \"./schemas/connect.js\";\nexport * from \"./schemas/device.js\";\nexport * from \"./schemas/file.js\";\nexport * from \"./schemas/env.js\";\nexport * from \"./schemas/jsonrpc.js\";\nexport * from \"./schemas/methods.js\";\n","import { EventEmitter } from \"node:events\";\nimport {\n JSON_RPC_CODES,\n type JsonRpcId,\n type MethodName,\n type ParamsOf,\n type ResultOf,\n} from \"@agent-phonon/protocol\";\n\n/**\n * 双向 JSON-RPC 2.0 peer(design D2)。\n *\n * 抽象掉传输:构造时传入一个 send 函数(把字符串发出去)和把收到的字符串喂给 handle()。\n * 两端皆可作 requester。core 与 test-server 都用它。\n */\n\nexport interface RpcTransport {\n /** 把一条 JSON 文本发出去。 */\n send(data: string): void;\n /** 关闭传输。 */\n close(): void;\n}\n\n/** 方法处理器:收到对端请求时调用,返回 result(或抛错)。 */\nexport type RpcHandler = (method: string, params: unknown) => Promise<unknown> | unknown;\n\ninterface Pending {\n resolve: (v: unknown) => void;\n reject: (e: unknown) => void;\n timer?: ReturnType<typeof setTimeout>;\n}\n\nexport class RpcPeer extends EventEmitter {\n private transport: RpcTransport;\n private handler: RpcHandler;\n private pending = new Map<string | number, Pending>();\n private nextId = 1;\n\n constructor(transport: RpcTransport, handler: RpcHandler) {\n super();\n this.transport = transport;\n this.handler = handler;\n }\n\n /** 发一个请求(需要响应),强类型版本。 */\n async request<M extends MethodName>(method: M, params: ParamsOf<M>): Promise<ResultOf<M>> {\n return this.requestRaw(method, params) as Promise<ResultOf<M>>;\n }\n\n /** 发一个请求(弱类型,内部用)。 */\n /** 发一个请求(弱类型,内部用)。timeoutMs 缺省 120s,0=不超时。 */\n requestRaw(method: string, params: unknown, timeoutMs = 120000): Promise<unknown> {\n const id = this.nextId++;\n const msg = { jsonrpc: \"2.0\", id, method, params };\n return new Promise((resolve, reject) => {\n const timer =\n timeoutMs > 0\n ? setTimeout(() => {\n this.pending.delete(id);\n reject(new PhononError(\"errInternal\", `RPC timeout: ${method}`));\n }, timeoutMs)\n : undefined;\n this.pending.set(id, { resolve, reject, timer });\n this.transport.send(JSON.stringify(msg));\n });\n }\n\n /** 发一个通知(不需要响应)。 */\n notify<M extends MethodName>(method: M, params: ParamsOf<M>): void {\n this.notifyRaw(method, params);\n }\n\n notifyRaw(method: string, params: unknown): void {\n this.transport.send(JSON.stringify({ jsonrpc: \"2.0\", method, params }));\n }\n\n /** 喂入一条收到的文本。 */\n async handle(data: string): Promise<void> {\n let msg: Record<string, unknown>;\n try {\n msg = JSON.parse(data);\n } catch {\n this.sendError(null, JSON_RPC_CODES.parseError, \"parse error\");\n return;\n }\n\n // 响应(成功/失败)\n if ((\"result\" in msg || \"error\" in msg) && \"id\" in msg) {\n const p = this.pending.get(msg.id as string | number);\n if (!p) return;\n this.pending.delete(msg.id as string | number);\n if (p.timer) clearTimeout(p.timer);\n if (\"error\" in msg && msg.error) {\n p.reject(msg.error);\n } else {\n p.resolve((msg as { result: unknown }).result);\n }\n return;\n }\n\n // 请求 / 通知\n if (typeof msg.method === \"string\") {\n const isNotification = !(\"id\" in msg) || msg.id === undefined || msg.id === null;\n try {\n const result = await this.handler(msg.method, msg.params);\n if (!isNotification) {\n this.transport.send(\n JSON.stringify({ jsonrpc: \"2.0\", id: msg.id as JsonRpcId, result: result ?? null }),\n );\n }\n } catch (err) {\n if (!isNotification) {\n const appCode = (err as { appCode?: string })?.appCode;\n const message = (err as Error)?.message ?? \"internal error\";\n this.transport.send(\n JSON.stringify({\n jsonrpc: \"2.0\",\n id: msg.id as JsonRpcId,\n error: {\n code: JSON_RPC_CODES.applicationError,\n message,\n ...(appCode ? { data: { appCode } } : {}),\n },\n }),\n );\n }\n }\n return;\n }\n }\n\n private sendError(id: JsonRpcId | null, code: number, message: string): void {\n this.transport.send(JSON.stringify({ jsonrpc: \"2.0\", id, error: { code, message } }));\n }\n\n /** 连接断开时:拒绝所有 pending,避免悬挂。 */\n rejectAllPending(reason: string): void {\n for (const [, p] of this.pending) {\n if (p.timer) clearTimeout(p.timer);\n p.reject(new Error(reason));\n }\n this.pending.clear();\n }\n}\n\n/** 带 appCode 的应用错误,handler 抛它,peer 会编码进 JSON-RPC error.data。 */\nexport class PhononError extends Error {\n appCode: string;\n constructor(appCode: string, message?: string) {\n super(message ?? appCode);\n this.appCode = appCode;\n }\n}\n","import type {\n AgentAdapter,\n AdapterSession,\n} from \"./adapter.js\";\nimport type { ContextItem, StreamEvent } from \"@agent-phonon/protocol\";\nimport { PhononError } from \"./rpc.js\";\n\n/** adapter 注册表:runtime name → adapter 实例。复合 agentId 按 runtime 前缀路由。 */\nexport class AdapterRegistry {\n private adapters = new Map<string, AgentAdapter>();\n\n register(adapter: AgentAdapter): void {\n this.adapters.set(adapter.name, adapter);\n }\n\n /** 按 runtime name 取。 */\n get(name: string): AgentAdapter | undefined {\n return this.adapters.get(name);\n }\n\n /**\n * 按完整 agentId 路由到 runtime adapter。\n * agentId 形如 \"openclaw:phonon\" → runtime \"openclaw\";单 agent runtime \"codex\" → \"codex\"。\n */\n resolve(agentId: string): AgentAdapter | undefined {\n const runtime = agentId.includes(\":\") ? agentId.split(\":\")[0]! : agentId;\n return this.adapters.get(runtime);\n }\n\n all(): AgentAdapter[] {\n return [...this.adapters.values()];\n }\n}\n\n/** 引擎内 session 记录。 */\ninterface SessionRecord {\n sessionId: string;\n tenantId: string;\n project: string;\n worktreeId?: string;\n agent: string;\n model: string;\n adapterName: string;\n adapterSession: AdapterSession;\n status: \"idle\" | \"running\" | \"paused\" | \"terminated\";\n /** 重启恢复后的游离态:无 live adapterSession,需 reattach 或 recreate。 */\n detached?: boolean;\n verbosity: \"final\" | \"messages\" | \"tools\" | \"trace\";\n currentTurnId?: string;\n /** 当前 turn 的 AbortController(interrupt 用,传给 adapter)。 */\n abort?: AbortController;\n /** 已发终态事件的 turnId(去重,避免双终态)。 */\n terminalTurns: Set<string>;\n queue: string[];\n seq: number;\n createdAt: string;\n lastActiveAt?: string;\n}\n\n/** 流式事件订阅回调(core 用它转发给对应 tenant 连接)。 */\nexport type StreamSink = (event: StreamEvent) => void;\n\n/**\n * Session 引擎(L1,design §4)。\n * 只认 sessionId,不感知 tenant 隔离(隔离在 L2 dispatch);但记录 tenantId 便于 L2 校验。\n */\nexport class SessionEngine {\n private sessions = new Map<string, SessionRecord>();\n private registry: AdapterRegistry;\n private sink: StreamSink;\n private idSeq = 1;\n /** 可观测事件总线(可选)。 */\n private obs?: import(\"./observability.js\").ObsBus;\n\n constructor(registry: AdapterRegistry, sink: StreamSink, obs?: import(\"./observability.js\").ObsBus, store?: import(\"./store.js\").PhononStore) {\n this.registry = registry;\n this.sink = sink;\n this.obs = obs;\n this.store = store;\n if (store) this.restoreSessions(store);\n }\n\n /** 重启恢复(功能缺口):从 sqlite 加载未 terminated 的 session,恢复为 paused(游离态)。\n * native-session adapter 可在下次 send 时 reattach;否则标记 needsRecreate。 */\n private restoreSessions(store: import(\"./store.js\").PhononStore): void {\n for (const row of store.loadSessions()) {\n const sessionId = row.session_id as string;\n if (this.sessions.has(sessionId)) continue;\n this.sessions.set(sessionId, {\n sessionId,\n tenantId: row.tenant_id as string,\n project: (row.project_id as string) ?? \"\",\n worktreeId: (row.worktree_id as string) ?? undefined,\n agent: row.agent_id as string,\n model: row.model as string,\n adapterName: (row.agent_id as string).split(\":\")[0] ?? (row.agent_id as string),\n adapterSession: undefined as never, // 游离:无 live session\n status: \"paused\",\n detached: true,\n verbosity: (row.verbosity as \"messages\") ?? \"messages\",\n terminalTurns: new Set(),\n queue: [],\n seq: 0,\n createdAt: row.created_at as string,\n lastActiveAt: (row.last_active as string) ?? undefined,\n });\n }\n }\n\n private store?: import(\"./store.js\").PhononStore;\n\n /** 持久化 session 元数据(bug-bash#2 B6)。 */\n private persist(rec: SessionRecord): void {\n this.store?.upsertSession({\n sessionId: rec.sessionId, tenantId: rec.tenantId, projectId: rec.project,\n worktreeId: rec.worktreeId, agent: rec.agent, model: rec.model,\n status: rec.status, verbosity: rec.verbosity, createdAt: rec.createdAt, lastActive: rec.lastActiveAt,\n });\n }\n\n private emit2(category: \"session\" | \"turn\" | \"tool\" | \"stream\" | \"error\", level: \"debug\" | \"info\" | \"warn\" | \"error\", event: string, rec: { sessionId: string; tenantId: string; agent: string; project: string } | undefined, extra?: { turnId?: string; msg?: string; data?: Record<string, unknown> }): void {\n this.obs?.emitEvent({\n category, level, event,\n tenantId: rec?.tenantId, sessionId: rec?.sessionId, agentId: rec?.agent, projectId: rec?.project,\n turnId: extra?.turnId, msg: extra?.msg, data: extra?.data,\n });\n }\n\n /** 校验 sessionId 是否属于某 tenant(L2 dispatch 用,D13)。 */\n assertTenant(sessionId: string, tenantId: string): SessionRecord {\n const rec = this.sessions.get(sessionId);\n if (!rec) throw new PhononError(\"errSessionNotFound\", `session ${sessionId} not found`);\n if (rec.tenantId !== tenantId)\n throw new PhononError(\"errSessionNotInTenant\", `session ${sessionId} not in tenant`);\n return rec;\n }\n\n async create(params: {\n tenantId: string;\n project: string;\n worktreeId?: string;\n cwd: string;\n agent: string;\n model: string;\n verbosity: \"final\" | \"messages\" | \"tools\" | \"trace\";\n agentConfig?: Record<string, unknown>;\n initialContext?: ContextItem[];\n }): Promise<{ sessionId: string; status: string; createdAt: string }> {\n const adapter = this.registry.resolve(params.agent);\n if (!adapter) throw new PhononError(\"errAgentUnavailable\", `agent ${params.agent} not found`);\n\n const sessionId = `s-${Date.now()}-${this.idSeq++}`;\n const adapterSession = await adapter.createSession({\n sessionId,\n agentId: params.agent,\n model: params.model,\n cwd: params.cwd,\n agentConfig: params.agentConfig,\n initialContext: params.initialContext,\n });\n\n // 自发输出水槽(D16):adapter 在无 active turn 时的输出走这里,core 统一打 seq 后转发\n adapterSession.setUnsolicitedSink?.((event) => {\n const rec = this.sessions.get(sessionId);\n if (rec) this.sink({ ...event, seq: rec.seq++ } as StreamEvent);\n });\n\n const createdAt = new Date().toISOString();\n this.sessions.set(sessionId, {\n sessionId,\n tenantId: params.tenantId,\n project: params.project,\n worktreeId: params.worktreeId,\n agent: params.agent,\n model: params.model,\n adapterName: params.agent,\n adapterSession,\n status: \"idle\",\n verbosity: params.verbosity,\n terminalTurns: new Set(),\n queue: [],\n seq: 0,\n createdAt,\n });\n const rec0 = this.sessions.get(sessionId)!;\n this.persist(rec0);\n this.emit2(\"session\", \"info\", \"session.create\", rec0, { msg: `session ${sessionId} on ${params.agent} (${params.model})`, data: { model: params.model } });\n return { sessionId, status: \"idle\", createdAt };\n }\n\n /** 可选:reattach 时解析 project cwd(由 connection 注入)。 */\n resolveCwdForReattach?: (projectId: string) => string;\n\n /** 重新附着游离 session(重启恢复后首次使用)。\n * native-session adapter 重建会复用原生会话(如 OpenClaw sessionKey / Claude --resume)。 */\n private async reattach(rec: SessionRecord): Promise<void> {\n const adapter = this.registry.resolve(rec.agent);\n if (!adapter) throw new PhononError(\"errAgentUnavailable\", `agent ${rec.agent} unavailable for reattach`);\n const cwd = this.resolveCwdForReattach?.(rec.project) ?? rec.project;\n rec.adapterSession = await adapter.createSession({\n sessionId: rec.sessionId, agentId: rec.agent, model: rec.model, cwd,\n });\n rec.adapterSession.setUnsolicitedSink?.((event) => {\n const r = this.sessions.get(rec.sessionId);\n if (r) this.sink({ ...event, seq: r.seq++ } as StreamEvent);\n });\n rec.detached = false;\n rec.status = \"idle\";\n this.emit2(\"session\", \"info\", \"session.reattach\", rec, { msg: `reattached ${rec.sessionId}` });\n }\n\n async send(\n tenantId: string,\n sessionId: string,\n input: string,\n opts: {\n verbosity?: \"final\" | \"messages\" | \"tools\" | \"trace\";\n turnId?: string;\n skills?: string[];\n whenBusy?: \"queue\" | \"interrupt\" | \"inject\";\n fallback?: \"queue\" | \"interrupt\" | \"inject\";\n environment?: Record<string, string>;\n },\n ): Promise<{ turnId: string; disposition: string; queuePosition?: number }> {\n const rec = this.assertTenant(sessionId, tenantId);\n if (rec.status === \"terminated\")\n throw new PhononError(\"errSessionTerminated\", \"session terminated\");\n // 重启恢复:游离 session 首次 send 时 reattach(重建 adapterSession)\n if (rec.detached) await this.reattach(rec);\n\n const turnId = opts.turnId ?? `t-${Date.now()}-${this.idSeq++}`;\n const verbosity = opts.verbosity ?? rec.verbosity;\n const payload = JSON.stringify({ turnId, input, verbosity, skills: opts.skills, environment: opts.environment });\n\n if (rec.status === \"running\") {\n // 忙碌处理(D18)。whenBusy 不支持时走 fallback。\n let mode = opts.whenBusy ?? \"queue\";\n const adapter = this.registry.resolve(rec.agent);\n if (mode === \"interrupt\" && !adapter?.capabilities.interrupt) mode = opts.fallback ?? \"queue\";\n if (mode === \"inject\" && !adapter?.capabilities.injectMidTurn) mode = opts.fallback ?? \"queue\";\n\n if (mode === \"interrupt\") {\n await this.interrupt(tenantId, sessionId);\n // 中断后立即跑本轮\n } else {\n // queue(默认):FIFO 排队,上轮结束自动出队\n rec.queue.push(payload);\n return { turnId, disposition: \"queued\", queuePosition: rec.queue.length };\n }\n }\n\n rec.status = \"running\";\n rec.currentTurnId = turnId;\n rec.lastActiveAt = new Date().toISOString();\n this.emit2(\"turn\", \"info\", \"turn.start\", rec, { turnId, msg: `turn ${turnId} started`, data: { input: input.slice(0, 200) } });\n this.persist(rec);\n void this.runTurn(rec, input, turnId, verbosity, opts.skills, opts.environment);\n return { turnId, disposition: \"started\" };\n }\n\n private async runTurn(\n rec: SessionRecord,\n input: string,\n turnId: string,\n verbosity: \"final\" | \"messages\" | \"tools\" | \"trace\",\n skills?: string[],\n environment?: Record<string, string>,\n ): Promise<void> {\n const abort = new AbortController();\n rec.abort = abort;\n const emit = (event: StreamEvent) => {\n const t = (event as { type?: string }).type;\n // 终态事件去重(避免双终态):engine 统一发,adapter 重复发的丢弃\n const isFinal = (event as { final?: boolean }).final === true;\n if (isFinal) {\n if (rec.terminalTurns.has(turnId)) return; // 已有终态,丢\n rec.terminalTurns.add(turnId);\n // 限制集合大小(避免无限增长)\n if (rec.terminalTurns.size > 200) {\n const first = rec.terminalTurns.values().next().value;\n if (first !== undefined) rec.terminalTurns.delete(first);\n }\n }\n // 可观测:工具调用事件\n if (t === \"tool_call\") {\n this.emit2(\"tool\", \"info\", \"tool.call\", rec, { turnId, msg: `tool ${(event as { toolName?: string }).toolName}`, data: { toolName: (event as { toolName?: string }).toolName } });\n } else if (t === \"tool_result\") {\n this.emit2(\"tool\", \"debug\", \"tool.result\", rec, { turnId, data: { toolName: (event as { toolName?: string }).toolName } });\n }\n this.sink({ ...event, seq: rec.seq++ } as StreamEvent);\n };\n try {\n await rec.adapterSession.send(input, { turnId, verbosity, skills, environment, emit, signal: abort.signal });\n } catch (err) {\n emit({\n type: \"error\",\n sessionId: rec.sessionId,\n turnId,\n seq: 0,\n at: new Date().toISOString(),\n message: (err as Error)?.message ?? \"turn failed\",\n status: \"failed\",\n final: true,\n } as StreamEvent);\n } finally {\n // 竞态守卫:只有本 turn 仍是当前 turn 才能收尾(避免旧 turn 覆盖新 turn 状态)\n if (rec.currentTurnId === turnId && rec.status !== \"terminated\") {\n rec.abort = undefined;\n rec.status = \"idle\";\n rec.currentTurnId = undefined;\n this.persist(rec);\n this.emit2(\"turn\", \"info\", \"turn.end\", rec, { turnId, msg: `turn ${turnId} ended` });\n const next = rec.queue.shift();\n if (next) {\n const n = JSON.parse(next) as { turnId: string; input: string; verbosity: typeof verbosity; skills?: string[]; environment?: Record<string, string> };\n rec.status = \"running\";\n rec.currentTurnId = n.turnId;\n rec.lastActiveAt = new Date().toISOString();\n void this.runTurn(rec, n.input, n.turnId, n.verbosity, n.skills, n.environment);\n }\n }\n }\n }\n\n async interrupt(tenantId: string, sessionId: string, reason?: string): Promise<{ interruptedTurnId?: string; status: string }> {\n const rec = this.assertTenant(sessionId, tenantId);\n const turnId = rec.currentTurnId;\n // 先发 engine 统一终态(标记 terminalTurns),确保 interrupted 是唯一终态;\n // 后续 adapter 被 kill 重发的 failed/close 会被 runTurn.emit 去重。\n if (turnId && !rec.terminalTurns.has(turnId)) {\n rec.terminalTurns.add(turnId);\n this.sink({\n type: \"result\",\n sessionId,\n turnId,\n seq: rec.seq++,\n at: new Date().toISOString(),\n text: \"\",\n status: \"interrupted\",\n final: true,\n } as StreamEvent);\n }\n // 再触发 abort + 停底层执行\n rec.abort?.abort();\n if (!rec.detached && rec.adapterSession?.interrupt) await rec.adapterSession.interrupt(reason);\n if (!turnId && rec.status !== \"terminated\") rec.status = \"idle\";\n return { interruptedTurnId: turnId, status: rec.status === \"running\" ? \"idle\" : rec.status };\n }\n\n async switchModel(tenantId: string, sessionId: string, model: string): Promise<{ previousModel: string; model: string; warnings?: string[] }> {\n const rec = this.assertTenant(sessionId, tenantId);\n if (rec.status === \"running\")\n throw new PhononError(\"errSessionBusy\", \"cannot switch model while running (whenRunning=reject)\");\n const previousModel = rec.model;\n let warnings: string[] | undefined;\n if (!rec.detached && rec.adapterSession?.switchModel) {\n const r = await rec.adapterSession.switchModel(model);\n warnings = r.warnings;\n }\n rec.model = model;\n rec.adapterSession.model = model;\n return { previousModel, model, warnings };\n }\n\n async inject(tenantId: string, sessionId: string, context: ContextItem[]): Promise<{ injected: number }> {\n const rec = this.assertTenant(sessionId, tenantId);\n if (!rec.detached && rec.adapterSession?.inject) await rec.adapterSession.inject(context);\n return { injected: context.length };\n }\n\n async compress(\n tenantId: string,\n sessionId: string,\n mode: \"native\" | \"custom\",\n strategy?: string,\n options?: { keepRecentToolCalls?: number },\n ): Promise<{ mode: string; summary?: string; filesChanged?: number; recordsChanged?: number; blocksRemoved?: number; bytesBefore?: number; bytesAfter?: number; backups?: string[] }> {\n const rec = this.assertTenant(sessionId, tenantId);\n if (mode === \"native\") {\n const adapter = this.registry.resolve(rec.agent);\n if (!adapter?.capabilities.nativeCompression)\n throw new PhononError(\"errCapabilityUnsupported\", \"native compression not supported by this agent\");\n if (!rec.detached && rec.adapterSession?.compressNative) {\n const r = await rec.adapterSession.compressNative();\n return { mode, summary: r.summary };\n }\n return { mode, summary: \"native compress requested\" };\n }\n if (!rec.detached && rec.adapterSession?.compressCustom) {\n const r = await rec.adapterSession.compressCustom(strategy ?? \"dropToolIO\", options);\n return { mode, ...r };\n }\n throw new PhononError(\"errCapabilityUnsupported\", `custom compression not supported by adapter ${rec.agent}`);\n }\n\n /** 实时快照:当前所有 session 在干什么(可观测 /sessions 用)。 */\n snapshot(tenantId?: string): Array<Record<string, unknown>> {\n const out: Array<Record<string, unknown>> = [];\n for (const rec of this.sessions.values()) {\n if (tenantId && rec.tenantId !== tenantId) continue;\n out.push({\n sessionId: rec.sessionId,\n tenantId: rec.tenantId,\n agent: rec.agent,\n model: rec.model,\n project: rec.project,\n status: rec.status, // idle/running/paused/terminated\n currentTurnId: rec.currentTurnId,\n queued: rec.queue.length,\n lastActiveAt: rec.lastActiveAt,\n });\n }\n return out;\n }\n\n async terminate(tenantId: string, sessionId: string): Promise<{ status: \"terminated\" }> {\n const rec = this.assertTenant(sessionId, tenantId);\n if (!rec.detached) await rec.adapterSession?.terminate();\n rec.status = \"terminated\";\n this.persist(rec);\n this.emit2(\"session\", \"info\", \"session.terminate\", rec, { msg: `session ${sessionId} terminated` });\n return { status: \"terminated\" };\n }\n\n async status(tenantId: string, sessionId: string) {\n const rec = this.assertTenant(sessionId, tenantId);\n const meta = this.toMeta(rec);\n // 补充上下文信息(adapter 能提供时,D33);detached/游离 session 无 live adapterSession,跳过\n if (!rec.detached && rec.adapterSession?.describe) {\n try {\n const ctx = await rec.adapterSession.describe();\n if (ctx.contextWindow !== undefined && ctx.usedTokens !== undefined && ctx.usagePercent === undefined && ctx.contextWindow > 0) {\n ctx.usagePercent = Math.min(100, Math.max(0, (ctx.usedTokens / ctx.contextWindow) * 100));\n }\n if (ctx.contextWindow !== undefined || ctx.usedTokens !== undefined || ctx.usagePercent !== undefined || ctx.compactions !== undefined) {\n return { ...meta, context: ctx };\n }\n } catch {\n /* ignore */\n }\n }\n return meta;\n }\n\n /** server ack 了 seq≤lastSeq(P0-4)。v0 内存模型 no-op;接 sqlite outbox 后在此清理。 */\n ackStream(_sessionId: string | undefined, _lastSeq: number): void {\n // TODO: 接 outbox 持久化后清理 <= lastSeq\n }\n\n /** server 回填 interaction(P1-5)。v0:如果有等待者则 resolve。 */\n private interactionWaiters = new Map<string, (v: unknown) => void>();\n resolveInteraction(requestId: string, payload: unknown): void {\n const w = this.interactionWaiters.get(requestId);\n if (w) {\n w(payload);\n this.interactionWaiters.delete(requestId);\n }\n }\n registerInteractionWaiter(requestId: string, resolve: (v: unknown) => void): void {\n this.interactionWaiters.set(requestId, resolve);\n }\n\n list(\n tenantId: string,\n filter?: { project?: string; agent?: string; status?: string; limit?: number; cursor?: string },\n ): { sessions: ReturnType<SessionEngine[\"toMeta\"]>[]; nextCursor?: string } {\n const all = [];\n for (const rec of this.sessions.values()) {\n if (rec.tenantId !== tenantId) continue; // tenant 隔离\n if (filter?.project && rec.project !== filter.project) continue;\n if (filter?.agent && rec.agent !== filter.agent) continue;\n if (filter?.status && rec.status !== filter.status) continue;\n all.push(rec);\n }\n // 稳定排序(按 createdAt),游标分页(P2#14)\n all.sort((a, b) => a.createdAt.localeCompare(b.createdAt) || a.sessionId.localeCompare(b.sessionId));\n const start = filter?.cursor ? Math.max(0, all.findIndex((r) => r.sessionId === filter.cursor) + 1) : 0;\n const limit = filter?.limit;\n const page = limit ? all.slice(start, start + limit) : all.slice(start);\n const last = page[page.length - 1];\n const hasMore = limit !== undefined && start + page.length < all.length;\n return {\n sessions: page.map((rec) => this.toMeta(rec)),\n ...(hasMore && last ? { nextCursor: last.sessionId } : {}),\n };\n }\n\n /** 某 project 下的 active(idle/running/paused) session ids(bug-bash P0#8)。 */\n activeSessionsForProject(projectId: string): string[] {\n const out: string[] = [];\n for (const rec of this.sessions.values()) {\n if (rec.project === projectId && rec.status !== \"terminated\") out.push(rec.sessionId);\n }\n return out;\n }\n\n /** 某 worktree 上的 active session ids。 */\n activeSessionsForWorktree(worktreeId: string): string[] {\n const out: string[] = [];\n for (const rec of this.sessions.values()) {\n if (rec.worktreeId === worktreeId && rec.status !== \"terminated\") out.push(rec.sessionId);\n }\n return out;\n }\n\n private toMeta(rec: SessionRecord) {\n return {\n sessionId: rec.sessionId,\n project: rec.project,\n ...(rec.worktreeId ? { worktreeId: rec.worktreeId } : {}),\n agent: rec.agent,\n model: rec.model,\n status: rec.status,\n currentTurnId: rec.currentTurnId,\n queuedCount: rec.queue.length,\n verbosity: rec.verbosity,\n createdAt: rec.createdAt,\n lastActiveAt: rec.lastActiveAt,\n };\n }\n}\n","import { SessionEngine, AdapterRegistry } from \"./session-engine.js\";\nimport { RpcPeer, PhononError, type RpcTransport } from \"./rpc.js\";\nimport { ProjectManager } from \"./project-manager.js\";\nimport { SkillManager } from \"./skill-manager.js\";\nimport { PolicyEnforcer } from \"./policy.js\";\nimport { IdempotencyStore } from \"./idempotency.js\";\nimport { Outbox } from \"./outbox.js\";\nimport { PhononStore } from \"./store.js\";\nimport { FileManager } from \"./file-manager.js\";\nimport { collectDeviceResources } from \"./resources.js\";\nimport { collectDeviceInfo } from \"./device-info.js\";\nimport { EnvManager } from \"./env-manager.js\";\nimport type { AgentAdapter } from \"./adapter.js\";\nimport { PROTOCOL_VERSION, parseParams, METHODS, type StreamEvent, type TenantPolicy, type MethodName } from \"@agent-phonon/protocol\";\n\n/** 改状态的方法(幂等适用)。 */\nconst MUTATING_METHODS = new Set<string>([\n \"session.create\",\n \"session.send\",\n \"project.create\",\n \"project.remove\",\n \"project.worktree.create\",\n \"project.worktree.remove\",\n \"project.git.deleteBranch\",\n \"skill.install\",\n \"skill.uninstall\",\n \"file.write\",\n \"file.mkdir\",\n \"env.set\",\n \"env.delete\",\n]);\n\n/**\n * 设备侧 daemon 的「一条连接处理器」(L2 dispatch,design §6)。\n *\n * 一个 PhononConnection = 一条到某 server 的连接 = 一个 tenant。\n * 它把 server 下发的 session.* 路由到 SessionEngine,并在交给 L1 前做 tenant 校验;\n * 同时把 engine 产出的 stream.event 推回 server。\n *\n * 真实场景:phonon 主动拨出连真 server。\n * 测试场景:test-server 主动连进来,或 phonon 连 test-server——传输无关,靠 RpcTransport 抽象。\n */\nexport class PhononConnection {\n readonly tenantId: string;\n private engine: SessionEngine;\n private peer: RpcPeer;\n private registry: AdapterRegistry;\n private projects: ProjectManager;\n private skills: SkillManager;\n private policy: PolicyEnforcer;\n private idempotency: IdempotencyStore;\n private outbox: Outbox;\n private store: PhononStore;\n private files: FileManager;\n private env: EnvManager;\n private obs?: import(\"./observability.js\").ObsBus;\n /** 该 tenant 绑定的默认项目工作目录解析器(v0 简化:projectId 即绝对路径或映射)。 */\n private resolveProjectCwd: (project: string) => string;\n\n constructor(opts: {\n tenantId: string;\n transport: RpcTransport;\n registry: AdapterRegistry;\n resolveProjectCwd?: (project: string) => string;\n policy?: Partial<TenantPolicy>;\n trustLocal?: boolean;\n workspaceRoot?: string;\n /** sqlite 文件路径(缺省内存库)。 */\n dbPath?: string;\n /** 或直接注入已有 store(多连接共享)。 */\n store?: PhononStore;\n /** 可观测事件总线(可选)。 */\n obs?: import(\"./observability.js\").ObsBus;\n }) {\n this.tenantId = opts.tenantId;\n this.registry = opts.registry;\n this.policy = new PolicyEnforcer({ policy: opts.policy, trustLocal: opts.trustLocal, workspaceRoot: opts.workspaceRoot });\n // 持久化(D6):projects/skills/worktrees/outbox 落 sqlite;dbPath 缺省内存库\n this.store = opts.store ?? new PhononStore(opts.dbPath ?? \":memory:\");\n this.idempotency = new IdempotencyStore({ store: this.store });\n\n // 先建 engine(ProjectManager 要用它查 active session)\n this.outbox = new Outbox({ store: this.store, tenantId: opts.tenantId });\n this.engine = new SessionEngine(opts.registry, (event: StreamEvent) => {\n // 下行可靠投递(D29):先入 outbox(含 sqlite)再发;server ack 后清理\n this.outbox.enqueue(event);\n this.peer.notifyRaw(\"stream.event\", event);\n }, opts.obs, this.store);\n this.engine.resolveCwdForReattach = (projectId) => this.resolveProjectCwd(projectId);\n this.obs = opts.obs;\n\n this.projects = new ProjectManager(\n (projectId) => this.engine.activeSessionsForProject(projectId), // 真实 active 查询(修 P0#8)\n {\n assertProjectPath: (p) => this.policy.assertProjectPath(p),\n assertDeleteFiles: () => this.policy.assertDeleteFiles(),\n store: this.store,\n workspaceRoot: this.policy.workspaceRoot, // 与 policy 一致,避免路径校验冲突\n hasActiveSessionsForWorktree: (wtId) => this.engine.activeSessionsForWorktree(wtId), // 精确查询(B8)\n },\n );\n this.skills = new SkillManager(\n opts.registry,\n (projectId) => {\n try {\n return this.projects.get(projectId).path;\n } catch {\n return undefined;\n }\n },\n this.store,\n );\n this.files = new FileManager({ resolveCwd: (projectId, worktreeId) => this.projects.resolveCwd(projectId, worktreeId) });\n this.env = new EnvManager(this.store, { allowReveal: () => this.policy.allowEnvReveal() });\n this.resolveProjectCwd = opts.resolveProjectCwd ?? ((p) => this.projects.resolveCwd(p));\n\n this.peer = new RpcPeer(opts.transport, (method, params) => this.dispatch(method, params));\n }\n\n /** 喂入收到的文本。 */\n handle(data: string): Promise<void> {\n return this.peer.handle(data);\n }\n\n /** 连接断开:拒绝 pending RPC;outbox 保留供重连补发。 */\n onClose(reason = \"connection closed\"): void {\n this.peer.rejectAllPending(reason);\n }\n\n /** 重连后补发未 ack 的 stream.event(D29)。resumeFrom = server welcome.ackedSeqs 转换。 */\n replayPending(resumeFrom?: Array<{ sessionId: string; fromSeq: number }>): number {\n const events = this.outbox.pending(resumeFrom);\n for (const e of events) this.peer.notifyRaw(\"stream.event\", e);\n return events.length;\n }\n\n /** outbox 待投递事件数(监控用)。 */\n get outboxSize(): number {\n return this.outbox.size;\n }\n\n /** 当前 session 实时快照(可观测 /sessions)。 */\n sessionsSnapshot(): Array<Record<string, unknown>> {\n return this.engine.snapshot(this.tenantId);\n }\n\n // ---- p2s 主动发起(phonon → server,平面③ + HITL)----\n\n /** 发本地文档给 server(document.send,D20)。adapter 解析 directive 后调用。 */\n async sendDocument(params: unknown): Promise<unknown> {\n return this.peer.requestRaw(\"document.send\", params);\n }\n\n /** 请求大文件上传凭证(document.prepare_upload,P1-6)。 */\n async prepareUpload(params: unknown): Promise<unknown> {\n return this.peer.requestRaw(\"document.prepare_upload\", params);\n }\n\n /** 主动通知 server:agent 可用性变化(discovery.changed,D14)。 */\n notifyDiscoveryChanged(params: unknown): void {\n this.peer.notifyRaw(\"discovery.changed\", params);\n }\n\n /** 发可交互表单给 server,阻塞等人填(interaction.request,D21/P1-5)。 */\n async requestInteraction(params: unknown): Promise<unknown> {\n return this.peer.requestRaw(\"interaction.request\", params);\n }\n\n /** 报 hook 事件并阻塞等 server 裁决(hook.fired,design §8,HITL)。 */\n async fireHook(params: unknown): Promise<unknown> {\n const p = (params ?? {}) as { sessionId?: string; hookType?: string; payload?: { toolName?: string } };\n this.obs?.emitEvent({\n category: \"hitl\", level: \"info\", event: \"hitl.fired\",\n tenantId: this.tenantId, sessionId: p.sessionId,\n msg: `HITL ${p.hookType} for tool ${p.payload?.toolName ?? \"?\"}`,\n data: { hookType: p.hookType, toolName: p.payload?.toolName },\n });\n const res = (await this.peer.requestRaw(\"hook.fired\", params)) as { action?: string };\n this.obs?.emitEvent({\n category: \"hitl\", level: res?.action === \"abort\" ? \"warn\" : \"info\", event: \"hitl.resolved\",\n tenantId: this.tenantId, sessionId: p.sessionId,\n msg: `HITL decision: ${res?.action ?? \"continue\"}`, data: { action: res?.action },\n });\n return res;\n }\n\n /** 某 phonon sessionId 是否属于本连接(tenant)——HookBridge 路由用。 */\n ownsSession(sessionId: string): boolean {\n try {\n this.engine.assertTenant(sessionId, this.tenantId);\n return true;\n } catch {\n return false;\n }\n }\n\n /** server → phonon 方法分发(L2 dispatch)。 */\n private async dispatch(method: string, params: unknown): Promise<unknown> {\n let p = (params ?? {}) as Record<string, unknown>;\n // 协议级参数校验(bug-bash#2 B6):s2p 方法过 zod,非法参数 → errInvalidParams\n if (method in METHODS && (METHODS as Record<string, { direction: string }>)[method]?.direction === \"s2p\") {\n try {\n p = parseParams(method as MethodName, params) as Record<string, unknown>;\n } catch (err) {\n throw new PhononError(\"errInvalidParams\", `invalid params for ${method}: ${(err as Error)?.message?.slice(0, 200)}`);\n }\n }\n // 只读租户 / 方法白名单(policy)\n this.policy.assertMethodAllowed(method);\n // 幂等:改状态请求带 clientRequestId 则去重(D28 / P0#2)\n const crid = p.clientRequestId as string | undefined;\n if (crid && MUTATING_METHODS.has(method)) {\n return this.idempotency.run(this.tenantId, method, crid, () => this.dispatchInner(method, p));\n }\n return this.dispatchInner(method, p);\n }\n\n private async dispatchInner(method: string, p: Record<string, unknown>): Promise<unknown> {\n switch (method) {\n case \"device.info\":\n return collectDeviceInfo();\n case \"device.resources\":\n return collectDeviceResources(this.policy.workspaceRoot);\n case \"discovery.list\": {\n // 聚合所有 runtime 的 sub-agents(OpenClaw 多 agent / Codex 单 agent)\n const nested = await Promise.all(this.registry.all().map((a) => a.discoverAgents()));\n return { agents: nested.flat() };\n }\n case \"discovery.get\": {\n const adapter = this.registry.resolve(p.agentId as string);\n if (!adapter) throw new PhononError(\"errAgentUnavailable\", `agent ${p.agentId} not found`);\n const agents = await adapter.discoverAgents();\n const found = agents.find((a) => a.agentId === p.agentId) ?? agents[0];\n return { agent: found };\n }\n case \"session.create\": {\n // worktreeId 指定时,cwd = 该 worktree 路径(修 P0#12)\n let cwd = this.resolveProjectCwd(p.project as string);\n if (p.worktreeId) {\n const wt = this.projects.worktreeList(p.project as string).find((w) => w.worktreeId === p.worktreeId);\n if (wt) cwd = wt.path;\n }\n const r = await this.engine.create({\n tenantId: this.tenantId,\n project: p.project as string,\n worktreeId: p.worktreeId as string | undefined,\n cwd,\n agent: p.agent as string,\n model: p.model as string,\n verbosity: (p.verbosity as \"messages\") ?? \"messages\",\n agentConfig: p.agentConfig as Record<string, unknown> | undefined,\n initialContext: p.initialContext as never,\n });\n return { sessionId: r.sessionId, project: p.project, agent: p.agent, model: p.model, status: r.status, createdAt: r.createdAt };\n }\n case \"session.send\": {\n const meta = await this.engine.status(this.tenantId, p.sessionId as string);\n const r = await this.engine.send(this.tenantId, p.sessionId as string, p.input as string, {\n verbosity: p.verbosity as never,\n turnId: p.turnId as string | undefined,\n skills: (p.skills as string[]) ?? undefined,\n environment: this.env.resolveForExecution({ projectId: meta.project, agent: meta.agent, skills: (p.skills as string[]) ?? undefined }),\n whenBusy: p.whenBusy as never,\n fallback: p.fallback as never,\n });\n return { sessionId: p.sessionId, turnId: r.turnId, accepted: true, disposition: r.disposition, queuePosition: r.queuePosition };\n }\n case \"session.interrupt\": {\n const r = await this.engine.interrupt(this.tenantId, p.sessionId as string, p.reason as string | undefined);\n return { sessionId: p.sessionId, interruptedTurnId: r.interruptedTurnId, status: r.status };\n }\n case \"session.switchModel\": {\n const r = await this.engine.switchModel(this.tenantId, p.sessionId as string, p.model as string);\n return { sessionId: p.sessionId, previousModel: r.previousModel, model: r.model, warnings: r.warnings };\n }\n case \"session.inject\": {\n const r = await this.engine.inject(this.tenantId, p.sessionId as string, p.context as never);\n return { sessionId: p.sessionId, injected: r.injected };\n }\n case \"session.compress\": {\n const r = await this.engine.compress(this.tenantId, p.sessionId as string, (p.mode as \"native\" | \"custom\") ?? \"native\", p.strategy as string | undefined, { keepRecentToolCalls: p.keepRecentToolCalls as number | undefined });\n return { sessionId: p.sessionId, mode: r.mode, summary: r.summary };\n }\n case \"session.terminate\": {\n const r = await this.engine.terminate(this.tenantId, p.sessionId as string);\n return { sessionId: p.sessionId, status: r.status };\n }\n case \"session.status\":\n return this.engine.status(this.tenantId, p.sessionId as string);\n case \"session.list\":\n return this.engine.list(this.tenantId, p as never);\n\n // ---- project (D23/D25) ----\n case \"project.create\": {\n const r = await this.projects.create({ name: p.name as string, path: p.path as string | undefined, git: p.git as boolean | undefined, remote: p.remote as string | undefined });\n return { project: { projectId: r.projectId, name: r.name, path: r.path, git: r.git, createdAt: r.createdAt } };\n }\n case \"project.list\":\n return { projects: this.projects.list().map((r) => ({ projectId: r.projectId, name: r.name, path: r.path, git: r.git, createdAt: r.createdAt })) };\n case \"project.get\": {\n const r = this.projects.get(p.projectId as string);\n return { project: { projectId: r.projectId, name: r.name, path: r.path, git: r.git, createdAt: r.createdAt } };\n }\n case \"project.remove\": {\n const r = await this.projects.remove(p.projectId as string, { deleteFiles: p.deleteFiles as boolean, whenActiveSessions: p.whenActiveSessions as \"reject\" | \"cascade\" });\n // cascade:真正 terminate 被级联的 session(修 B8:之前只返回列表不 terminate)\n if (r.terminatedSessions) {\n for (const sid of r.terminatedSessions) {\n await this.engine.terminate(this.tenantId, sid).catch(() => {});\n }\n }\n return { projectId: p.projectId, removed: true, filesDeleted: r.filesDeleted, terminatedSessions: r.terminatedSessions };\n }\n case \"project.worktree.create\": {\n const r = await this.projects.worktreeCreate({ projectId: p.projectId as string, baseBranch: p.baseBranch as string, newBranch: p.newBranch as string | undefined, path: p.path as string | undefined });\n return { worktree: r };\n }\n case \"project.worktree.list\":\n return { worktrees: this.projects.worktreeList(p.projectId as string) };\n case \"project.worktree.remove\": {\n const r = await this.projects.worktreeRemove({ projectId: p.projectId as string, worktreeId: p.worktreeId as string, force: p.force as boolean });\n return { worktreeId: p.worktreeId, removed: true, affectedSessions: r.affectedSessions };\n }\n case \"project.git.deleteBranch\": {\n const r = await this.projects.deleteBranch({ projectId: p.projectId as string, branch: p.branch as string, force: p.force as boolean });\n return { branch: p.branch, deleted: true, wasMerged: r.wasMerged, affectedWorktrees: r.affectedWorktrees };\n }\n\n // ---- file workspace IO (project/worktree scoped) ----\n case \"file.read\":\n return this.files.read(p as { projectId: string; worktreeId?: string; path: string; encoding?: \"utf8\" | \"base64\"; maxBytes?: number });\n case \"file.write\":\n return this.files.write(p as { projectId: string; worktreeId?: string; path: string; encoding?: \"utf8\" | \"base64\"; data: string; overwrite?: boolean; createDirs?: boolean });\n case \"file.list\":\n return this.files.list(p as { projectId: string; worktreeId?: string; path?: string; recursive?: boolean; limit?: number });\n case \"file.stat\":\n return this.files.stat(p as { projectId: string; worktreeId?: string; path: string });\n case \"file.mkdir\":\n return this.files.mkdir(p as { projectId: string; worktreeId?: string; path: string; recursive?: boolean });\n\n case \"env.set\":\n return this.env.set(p as { scope: \"global\" | \"project\" | \"skill\"; projectId?: string; agent?: string; skillName?: string; name: string; value: string; secret?: boolean });\n case \"env.list\":\n return this.env.list(p as { scope?: \"global\" | \"project\" | \"skill\"; projectId?: string; agent?: string; skillName?: string; reveal?: boolean });\n case \"env.delete\":\n return this.env.delete(p as { scope: \"global\" | \"project\" | \"skill\"; projectId?: string; agent?: string; skillName?: string; name: string });\n\n // ---- skill (D24 + 边界规则) ----\n case \"skill.install\": {\n // policy:global 装 / url 源 检查(P0-1)\n if ((p.scope as string) === \"global\") this.policy.assertGlobalSkillInstall();\n const src = p.source as { kind?: string } | undefined;\n if (src?.kind === \"url\") this.policy.assertUrlSkillInstall();\n const r = await this.skills.install({\n agent: p.agent as string, name: p.name as string,\n scope: p.scope as \"global\" | \"project\", projectId: p.projectId as string | undefined,\n source: p.source as never,\n allowUrl: true, // policy 已在上面把关\n });\n return { skill: r };\n }\n case \"skill.uninstall\": {\n await this.skills.uninstall({ agent: p.agent as string, name: p.name as string, scope: p.scope as \"global\" | \"project\", projectId: p.projectId as string | undefined });\n return { agent: p.agent, name: p.name, scope: p.scope, uninstalled: true };\n }\n case \"skill.list\":\n return { skills: this.skills.list({ agent: p.agent as string | undefined, scope: p.scope as \"global\" | \"project\" | undefined, projectId: p.projectId as string | undefined }) };\n\n // ---- 连接/可靠性(s2p) ----\n case \"stream.ack\": {\n // server 确认已收 seq≤lastSeq → phonon 清 outbox(D29 / P0-4)。\n this.outbox.ack(p.sessionId as string | undefined, p.lastSeq as number);\n return null;\n }\n case \"interaction.response\": {\n // server 回填人机交互结果(P1-5)→ 路由回对应 session/turn。v0 记录即可。\n this.engine.resolveInteraction?.(p.requestId as string, p as never);\n return null;\n }\n case \"interaction.cancel\": {\n // server 主动取消一个 pending 交互(P1-5)。\n this.engine.resolveInteraction?.(p.requestId as string, { action: \"cancel\", requestId: p.requestId });\n return { requestId: p.requestId, cancelled: true };\n }\n case \"hook.resolve\": {\n // server 主动下发裁决(异步路径;同步路径是 hook.fired 的 RPC 响应)。\n return { sessionId: p.sessionId, hookId: p.hookId, applied: true };\n }\n default:\n throw new PhononError(\"errInvalidParams\", `method not implemented in v0 core: ${method}`);\n }\n }\n}\n\nexport { SessionEngine, AdapterRegistry, RpcPeer, PhononError, PROTOCOL_VERSION };\nexport type { AgentAdapter, RpcTransport };\nexport * from \"./adapter.js\";\nexport { OpenClawAdapter } from \"./adapters/openclaw.js\";\nexport { OpenClawGatewayAdapter } from \"./adapters/openclaw-gateway.js\";\nexport { GatewayClient } from \"./gateway-client.js\";\nexport type { GatewayConfig } from \"./gateway-client.js\";\nexport { PhononClient } from \"./client.js\";\nexport { HookBridge } from \"./hook-bridge.js\";\nexport type { HookRouteResolver } from \"./hook-bridge.js\";\nexport { ProjectManager } from \"./project-manager.js\";\nexport { SkillManager } from \"./skill-manager.js\";\nexport { PolicyEnforcer } from \"./policy.js\";\nexport { IdempotencyStore } from \"./idempotency.js\";\nexport { Outbox } from \"./outbox.js\";\nexport { PhononStore } from \"./store.js\";\nexport { SecretBox } from \"./secret-box.js\";\nexport { FileManager } from \"./file-manager.js\";\nexport { EnvManager } from \"./env-manager.js\";\nexport { dropToolIOFromJsonlFiles, dropToolIOFromValue, computeKeepToolBlocks } from \"./custom-compress.js\";\nexport { dropToolIORowsSqlite } from \"./sqlite-compress.js\";\nexport { resolveCodexSessionFile } from \"./adapters/codex.js\";\nexport { resolveOpenCodeDbPath } from \"./adapters/opencode.js\";\nexport { resolveHermesDbPath, resolveHermesSessionByTitle } from \"./adapters/hermes.js\";\nexport { collectDeviceResources } from \"./resources.js\";\nexport { collectDeviceInfo } from \"./device-info.js\";\nexport { ObsBus, StructuredLogger, Metrics, AuditSink } from \"./observability.js\";\nexport type { ObsEvent, ObsCategory, ObsLevel } from \"./observability.js\";\nexport { ClaudeCodeAdapter } from \"./adapters/claude-code.js\";\nexport type { ClaudeCodeEnv } from \"./adapters/claude-code.js\";\nexport { CodexAdapter } from \"./adapters/codex.js\";\nexport type { CodexEnv } from \"./adapters/codex.js\";\nexport { HermesAdapter } from \"./adapters/hermes.js\";\nexport type { HermesEnv } from \"./adapters/hermes.js\";\nexport { OpenCodeAdapter } from \"./adapters/opencode.js\";\nexport type { OpenCodeEnv } from \"./adapters/opencode.js\";\n","import { spawn } from \"node:child_process\";\nimport { mkdir, rm, readdir, stat } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join, resolve, basename } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { PhononError } from \"./rpc.js\";\n\n/**\n * 项目管理(design §8c / D23 + D25)。\n *\n * 一个项目 = 一个目录 + Git。core 直接跑 git 命令实现 worktree/分支操作。\n * 项目设备级共享、不受 tenant 隔离(D23 修正)。\n * 持久化 v0 用内存表 + 磁盘探测;后续接 sqlite。\n */\n\nexport interface ProjectRecord {\n projectId: string;\n name: string;\n path: string;\n git: boolean;\n createdAt: string;\n}\n\nexport interface WorktreeRecord {\n worktreeId: string;\n projectId: string;\n path: string;\n branch: string;\n isPrimary: boolean;\n createdAt: string;\n}\n\n/** 受控工作区根:项目缺省建在这里下面(避免 server 越权指定任意路径,P0-1)。 */\nfunction defaultWorkspaceRoot(): string {\n return process.env.PHONON_PROJECTS_ROOT ?? join(homedir(), \"phonon-projects\");\n}\n\nfunction runGit(cwd: string, args: string[], timeoutMs = 30000): Promise<string> {\n return new Promise((resolveP, reject) => {\n const child = spawn(\"git\", args, { cwd });\n let out = \"\";\n let err = \"\";\n const timer = setTimeout(() => {\n child.kill(\"SIGTERM\");\n reject(new PhononError(\"errInternal\", `git ${args[0]} timeout`));\n }, timeoutMs);\n child.stdout.on(\"data\", (d) => (out += d.toString()));\n child.stderr.on(\"data\", (d) => (err += d.toString()));\n child.on(\"error\", (e) => {\n clearTimeout(timer);\n reject(new PhononError(\"errInternal\", `git spawn failed: ${e.message}`));\n });\n child.on(\"close\", (code) => {\n clearTimeout(timer);\n if (code === 0) resolveP(out.trim());\n else reject(new PhononError(\"errInternal\", `git ${args.join(\" \")} exited ${code}: ${err.slice(0, 300)}`));\n });\n });\n}\n\nexport class ProjectManager {\n private projects = new Map<string, ProjectRecord>();\n private worktrees = new Map<string, WorktreeRecord>();\n private idSeq = 1;\n /** 查询某 project 是否有 active session(由 engine 注入)。 */\n private hasActiveSessions: (projectId: string) => string[];\n /** 查询某 worktree 是否有 active session(bug-bash#2 B8)。 */\n private hasActiveSessionsForWorktree: (worktreeId: string) => string[];\n /** 可选 policy 校验回调(bug-bash P0-1)。 */\n private assertProjectPath?: (path: string) => void;\n private assertDeleteFiles?: () => void;\n\n constructor(\n hasActiveSessions: (projectId: string) => string[] = () => [],\n hooks?: { assertProjectPath?: (path: string) => void; assertDeleteFiles?: () => void; store?: import(\"./store.js\").PhononStore; workspaceRoot?: string; hasActiveSessionsForWorktree?: (worktreeId: string) => string[] },\n ) {\n this.hasActiveSessions = hasActiveSessions;\n this.hasActiveSessionsForWorktree = hooks?.hasActiveSessionsForWorktree ?? (() => []);\n this.assertProjectPath = hooks?.assertProjectPath;\n this.assertDeleteFiles = hooks?.assertDeleteFiles;\n this.store = hooks?.store;\n this.workspaceRoot = hooks?.workspaceRoot;\n // 重启恢复:从 sqlite 加载已有 project/worktree\n if (this.store) {\n for (const p of this.store.loadProjects()) this.projects.set(p.projectId, p);\n for (const w of this.store.loadWorktrees()) this.worktrees.set(w.worktreeId, w);\n }\n }\n\n private store?: import(\"./store.js\").PhononStore;\n /** 受控项目根(与 PolicyEnforcer.workspaceRoot 一致,避免路径校验不一致)。 */\n private workspaceRoot?: string;\n\n /** 解析 projectId → 工作目录(session.create / file.* 用)。 */\n resolveCwd(projectId: string, worktreeId?: string): string {\n if (worktreeId) {\n const wt = this.worktrees.get(worktreeId);\n if (!wt || wt.projectId !== projectId) throw new PhononError(\"errWorktreeNotFound\", `worktree ${worktreeId} not found`);\n return wt.path;\n }\n const rec = this.projects.get(projectId);\n return rec?.path ?? projectId; // 兼容:未注册时把 projectId 当路径\n }\n\n async create(params: { name: string; path?: string; git?: boolean; remote?: string }): Promise<ProjectRecord> {\n const projectId = `proj-${Date.now()}-${this.idSeq++}`;\n const root = this.workspaceRoot ?? defaultWorkspaceRoot();\n const path = params.path ? resolve(params.path) : join(root, params.name);\n // 路径校验(P0-1):policy 执行越界拒绝(不再「记风险但放行」)\n if (this.assertProjectPath) this.assertProjectPath(path);\n if (existsSync(path) && (await readdir(path)).length > 0) {\n // 目录已存在且非空:当作既有项目接管,不报错\n } else {\n await mkdir(path, { recursive: true });\n }\n const git = params.git !== false;\n if (git && !existsSync(join(path, \".git\"))) {\n await runGit(path, [\"init\"]);\n if (params.remote) await runGit(path, [\"remote\", \"add\", \"origin\", params.remote]).catch(() => {});\n }\n const rec: ProjectRecord = { projectId, name: params.name, path, git, createdAt: new Date().toISOString() };\n this.projects.set(projectId, rec);\n this.store?.upsertProject(rec);\n return rec;\n }\n\n list(): ProjectRecord[] {\n return [...this.projects.values()];\n }\n\n get(projectId: string): ProjectRecord {\n const rec = this.projects.get(projectId);\n if (!rec) throw new PhononError(\"errProjectNotFound\", `project ${projectId} not found`);\n return rec;\n }\n\n async remove(projectId: string, opts: { deleteFiles?: boolean; whenActiveSessions?: \"reject\" | \"cascade\" }): Promise<{ filesDeleted: boolean; terminatedSessions?: string[] }> {\n const rec = this.get(projectId);\n const active = this.hasActiveSessions(projectId);\n let terminatedSessions: string[] | undefined;\n if (active.length > 0) {\n if ((opts.whenActiveSessions ?? \"reject\") === \"reject\")\n throw new PhononError(\"errProjectHasActiveSessions\", `project has ${active.length} active sessions`);\n terminatedSessions = active; // cascade:调用方负责 terminate(engine 注入回调)\n }\n let filesDeleted = false;\n if (opts.deleteFiles) {\n if (this.assertDeleteFiles) this.assertDeleteFiles(); // policy:allowDeleteFiles\n await rm(rec.path, { recursive: true, force: true });\n filesDeleted = true;\n }\n this.projects.delete(projectId);\n this.store?.deleteProject(projectId);\n // 清理该 project 的 worktree 记录\n for (const [id, wt] of this.worktrees) if (wt.projectId === projectId) this.worktrees.delete(id);\n return { filesDeleted, terminatedSessions };\n }\n\n // ---- worktree (D25) ----\n async worktreeCreate(params: { projectId: string; baseBranch: string; newBranch?: string; path?: string }): Promise<WorktreeRecord> {\n const proj = this.get(params.projectId);\n const worktreeId = `wt-${Date.now()}-${this.idSeq++}`;\n const wtPath = params.path ? resolve(params.path) : join(proj.path, \"..\", `${proj.name}-${params.newBranch ?? params.baseBranch}`.replace(/\\//g, \"-\"));\n // 自定义 worktree path 同样走 policy 路径校验(bug-bash#2 B8)\n if (params.path && this.assertProjectPath) this.assertProjectPath(wtPath);\n const branch = params.newBranch ?? params.baseBranch;\n const args = [\"worktree\", \"add\"];\n if (params.newBranch) args.push(\"-b\", params.newBranch);\n args.push(wtPath, params.baseBranch);\n await runGit(proj.path, args);\n const rec: WorktreeRecord = { worktreeId, projectId: params.projectId, path: wtPath, branch, isPrimary: false, createdAt: new Date().toISOString() };\n this.worktrees.set(worktreeId, rec);\n this.store?.upsertWorktree(rec);\n return rec;\n }\n\n worktreeList(projectId: string): WorktreeRecord[] {\n return [...this.worktrees.values()].filter((w) => w.projectId === projectId);\n }\n\n async worktreeRemove(params: { projectId: string; worktreeId: string; force?: boolean }): Promise<{ affectedSessions?: string[] }> {\n const proj = this.get(params.projectId);\n const wt = this.worktrees.get(params.worktreeId);\n if (!wt) throw new PhononError(\"errWorktreeNotFound\", `worktree ${params.worktreeId} not found`);\n // 精确到该 worktree 的 active session(不是整个 project,bug-bash#2 B8)\n const active = this.hasActiveSessionsForWorktree(params.worktreeId).filter(Boolean);\n if (active.length > 0 && !params.force)\n throw new PhononError(\"errWorktreeInUse\", \"worktree has active sessions\");\n const args = [\"worktree\", \"remove\", wt.path];\n if (params.force) args.push(\"--force\");\n await runGit(proj.path, args).catch((e) => {\n if (String(e?.message).includes(\"contains modified\") || String(e?.message).includes(\"not empty\"))\n throw new PhononError(\"errWorktreeHasChanges\", \"worktree has uncommitted changes (use force)\");\n throw e;\n });\n this.worktrees.delete(params.worktreeId);\n this.store?.deleteWorktree(params.worktreeId);\n return { affectedSessions: params.force ? active : undefined };\n }\n\n async deleteBranch(params: { projectId: string; branch: string; force?: boolean }): Promise<{ wasMerged: boolean; affectedWorktrees?: string[] }> {\n const proj = this.get(params.projectId);\n const inUse = this.worktreeList(params.projectId).filter((w) => w.branch === params.branch);\n if (inUse.length > 0 && !params.force)\n throw new PhononError(\"errBranchInUse\", \"branch is checked out by a worktree\");\n const flag = params.force ? \"-D\" : \"-d\";\n try {\n await runGit(proj.path, [\"branch\", flag, params.branch]);\n } catch (e) {\n if (String((e as Error)?.message).includes(\"not fully merged\"))\n throw new PhononError(\"errBranchNotMerged\", \"branch not merged (use force)\");\n throw e;\n }\n return { wasMerged: !params.force, affectedWorktrees: inUse.length ? inUse.map((w) => w.worktreeId) : undefined };\n }\n}\n\nexport { runGit };\n","import { mkdir, rm, writeFile, readdir, stat, mkdtemp, lstat } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join, resolve, sep } from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { createHash } from \"node:crypto\";\nimport { PhononError } from \"./rpc.js\";\nimport type { AdapterRegistry } from \"./session-engine.js\";\n\n/**\n * Skill 管理(design D24 + 安全边界规则)。\n *\n * 安装位置规则:\n * - project scope → 装到 <project>/.agent/skills/<name>/ —— **runtime 无关**,谁用这个 project 都看得到\n * - global scope → **依赖 runtime**,装到对应 runtime 的全局 skill 目录\n * (adapter.globalSkillDir(agentId) 提供;OpenClaw = 该 sub-agent workspace/skills)\n *\n * phonon 自己管一套安装逻辑;global 位置交给各 adapter(只有它知道自己 runtime skill 目录)。\n */\n\nexport interface SkillRecord {\n name: string;\n agent: string;\n scope: \"global\" | \"project\";\n projectId?: string;\n version?: string;\n hash?: string;\n installedPath: string;\n installedAt: string;\n}\n\ntype SkillSource =\n | { kind: \"inline\"; files: Record<string, string> }\n | { kind: \"archive\"; format: \"tar.gz\"; contentBase64: string; sha256?: string; sizeBytes?: number }\n | { kind: \"localPath\"; path: string }\n | { kind: \"url\"; url: string; sha256?: string };\n\nconst execFileAsync = promisify(execFile);\n\nexport class SkillManager {\n private skills: SkillRecord[] = [];\n private registry: AdapterRegistry;\n /** projectId → 项目目录解析(core 注入)。 */\n private resolveProjectPath: (projectId: string) => string | undefined;\n private store?: import(\"./store.js\").PhononStore;\n\n constructor(\n registry: AdapterRegistry,\n resolveProjectPath: (projectId: string) => string | undefined,\n store?: import(\"./store.js\").PhononStore,\n ) {\n this.registry = registry;\n this.resolveProjectPath = resolveProjectPath;\n this.store = store;\n if (this.store) for (const s of this.store.loadSkills()) this.skills.push(s);\n }\n\n /** 计算安装目标目录(核心边界规则)。 */\n private targetDir(params: { agent: string; name: string; scope: \"global\" | \"project\"; projectId?: string }): string {\n // 防路径穿越(bug-bash#2 B8):skill name 限定安全字符\n if (!/^[a-zA-Z0-9._-]+$/.test(params.name) || params.name === \".\" || params.name === \"..\") {\n throw new PhononError(\"errSkillScopeInvalid\", `invalid skill name: ${params.name}`);\n }\n if (params.scope === \"project\") {\n if (!params.projectId) throw new PhononError(\"errSkillScopeInvalid\", \"project scope requires projectId\");\n const projPath = this.resolveProjectPath(params.projectId);\n if (!projPath) throw new PhononError(\"errProjectNotFound\", `project ${params.projectId} not found`);\n // project scope → <project>/.agent/skills/<name>,runtime 无关\n return join(projPath, \".agent\", \"skills\", params.name);\n }\n // global scope → adapter 提供的 runtime skill 目录\n const adapter = this.registry.resolve(params.agent);\n if (!adapter) throw new PhononError(\"errAgentUnavailable\", `agent ${params.agent} not found`);\n if (!adapter.globalSkillDir) throw new PhononError(\"errCapabilityUnsupported\", `runtime does not support global skills`);\n const dir = adapter.globalSkillDir(params.agent);\n if (!dir) throw new PhononError(\"errCapabilityUnsupported\", `no global skill dir for ${params.agent}`);\n return join(dir, params.name);\n }\n\n async install(params: {\n agent: string;\n name: string;\n scope: \"global\" | \"project\";\n projectId?: string;\n source: SkillSource;\n allowUrl?: boolean;\n }): Promise<SkillRecord> {\n const dest = this.targetDir(params);\n await mkdir(dest, { recursive: true });\n\n let hash: string | undefined;\n const hasher = createHash(\"sha256\");\n\n if (params.source.kind === \"inline\") {\n for (const [rel, content] of Object.entries(params.source.files)) {\n const full = resolve(dest, rel);\n // 防路径穿越:写入目标必须在 dest 内(bug-bash#2 B8)\n if (full !== dest && !full.startsWith(dest + sep)) {\n throw new PhononError(\"errSkillInstallFailed\", `inline file path escapes skill dir: ${rel}`);\n }\n await mkdir(join(full, \"..\"), { recursive: true });\n await writeFile(full, content);\n hasher.update(rel).update(content);\n }\n hash = hasher.digest(\"hex\");\n } else if (params.source.kind === \"archive\") {\n hash = await this.installArchive(params.source, dest);\n } else if (params.source.kind === \"localPath\") {\n // 复制本地目录(用 cp -r 的等价:递归读写)\n await this.copyDir(params.source.path, dest, hasher);\n hash = hasher.digest(\"hex\");\n } else {\n // url:受 policy 控制(P0-1 allowUrlSkillInstall),v0 默认拒\n if (!params.allowUrl)\n throw new PhononError(\"errPolicyDenied\", \"url skill install disabled by policy (allowUrlSkillInstall)\");\n throw new PhononError(\"errSkillInstallFailed\", \"url install not implemented in v0\");\n }\n\n const rec: SkillRecord = {\n name: params.name,\n agent: params.agent,\n scope: params.scope,\n projectId: params.projectId,\n hash,\n installedPath: dest,\n installedAt: new Date().toISOString(),\n };\n // 去重:同 agent+scope+name(+project) 覆盖\n this.skills = this.skills.filter(\n (s) => !(s.agent === rec.agent && s.scope === rec.scope && s.name === rec.name && s.projectId === rec.projectId),\n );\n this.skills.push(rec);\n this.store?.upsertSkill(rec);\n return rec;\n }\n\n async uninstall(params: { agent: string; name: string; scope: \"global\" | \"project\"; projectId?: string }): Promise<void> {\n const dest = this.targetDir(params);\n if (existsSync(dest)) await rm(dest, { recursive: true, force: true });\n this.skills = this.skills.filter(\n (s) => !(s.agent === params.agent && s.scope === params.scope && s.name === params.name && s.projectId === params.projectId),\n );\n this.store?.deleteSkill(params);\n }\n\n list(filter?: { agent?: string; scope?: \"global\" | \"project\"; projectId?: string }): SkillRecord[] {\n return this.skills.filter((s) => {\n if (filter?.agent && s.agent !== filter.agent) return false;\n if (filter?.scope && s.scope !== filter.scope) return false;\n if (filter?.projectId && s.projectId !== filter.projectId) return false;\n return true;\n });\n }\n\n private async installArchive(source: Extract<SkillSource, { kind: \"archive\" }>, dest: string): Promise<string> {\n if (source.format !== \"tar.gz\") throw new PhononError(\"errSkillInstallFailed\", `unsupported archive format: ${source.format}`);\n const buf = Buffer.from(source.contentBase64, \"base64\");\n const hash = createHash(\"sha256\").update(buf).digest(\"hex\");\n if (source.sha256 && source.sha256 !== hash) throw new PhononError(\"errSkillInstallFailed\", \"archive sha256 mismatch\");\n\n const tmp = await mkdtemp(join(tmpdir(), \"phonon-skill-\"));\n const archive = join(tmp, \"skill.tar.gz\");\n const staging = join(tmp, \"staging\");\n await mkdir(staging, { recursive: true });\n try {\n await writeFile(archive, buf, { mode: 0o600 });\n const { stdout } = await execFileAsync(\"tar\", [\"-tzf\", archive], { timeout: 10000, maxBuffer: 10 * 1024 * 1024 });\n for (const entry of stdout.split(/\\n/).filter(Boolean)) this.assertArchiveEntrySafe(entry);\n await execFileAsync(\"tar\", [\"-xzf\", archive, \"-C\", staging], { timeout: 30000, maxBuffer: 10 * 1024 * 1024 });\n await this.assertNoSymlinks(staging);\n await this.copyDir(staging, dest, createHash(\"sha256\"));\n return hash;\n } finally {\n await rm(tmp, { recursive: true, force: true });\n }\n }\n\n private assertArchiveEntrySafe(entry: string): void {\n const normalized = entry.replace(/\\\\/g, \"/\");\n if (normalized.startsWith(\"/\") || normalized === \"..\" || normalized.startsWith(\"../\") || normalized.includes(\"/../\") || normalized.includes(\"\\0\")) {\n throw new PhononError(\"errSkillInstallFailed\", `unsafe archive entry: ${entry}`);\n }\n }\n\n private async assertNoSymlinks(root: string): Promise<void> {\n const entries = await readdir(root, { withFileTypes: true });\n for (const e of entries) {\n const p = join(root, e.name);\n const s = await lstat(p);\n if (s.isSymbolicLink()) throw new PhononError(\"errSkillInstallFailed\", `archive contains symlink: ${e.name}`);\n if (s.isDirectory()) await this.assertNoSymlinks(p);\n }\n }\n\n private async copyDir(src: string, dest: string, hasher: ReturnType<typeof createHash>): Promise<void> {\n if (!existsSync(src)) throw new PhononError(\"errSkillNotFound\", `source ${src} not found`);\n const entries = await readdir(src, { withFileTypes: true });\n for (const e of entries) {\n const s = join(src, e.name);\n const d = join(dest, e.name);\n if (e.isDirectory()) {\n await mkdir(d, { recursive: true });\n await this.copyDir(s, d, hasher);\n } else {\n const { readFile } = await import(\"node:fs/promises\");\n const content = await readFile(s);\n await writeFile(d, content);\n hasher.update(e.name).update(content);\n }\n }\n }\n}\n","import { resolve } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { TenantPolicy, DEFAULT_TENANT_POLICY, isPathUnderRoots, type TenantPolicy as TenantPolicyT } from \"@agent-phonon/protocol\";\nimport { PhononError } from \"./rpc.js\";\n\n/**\n * 本地安全策略执行器(design D27 / bug-bash P0-1)。\n *\n * 协议定义了 TenantPolicy,但 v0 dispatch 没真执行。这里把它落地:\n * 每个 PhononConnection 持一个 PolicyEnforcer,在 project/skill/document/destructive\n * 操作入口强制检查,违反抛 errPolicyDenied / errDocumentPathDenied。\n *\n * 默认最严格(DEFAULT_TENANT_POLICY):白名单空、写操作全关、敏感路径黑名单。\n * 但为了不破坏「单设备本地自用」的开箱体验,构造时可传宽松默认(trustLocal)。\n */\nexport class PolicyEnforcer {\n readonly policy: TenantPolicyT;\n /** 受控工作区根(项目缺省建在这下面)。 */\n readonly workspaceRoot: string;\n\n constructor(opts?: { policy?: Partial<TenantPolicyT>; workspaceRoot?: string; trustLocal?: boolean }) {\n this.workspaceRoot = opts?.workspaceRoot ?? process.env.PHONON_PROJECTS_ROOT ?? `${homedir()}/phonon-projects`;\n if (opts?.policy) {\n this.policy = TenantPolicy.parse(opts.policy);\n } else if (opts?.trustLocal) {\n // 本地自用:允许写操作 + 受控根作为默认 allowedProjectRoots\n this.policy = TenantPolicy.parse({\n allowedProjectRoots: [this.workspaceRoot],\n allowDeleteFiles: true,\n allowGlobalSkillInstall: true,\n allowUrlSkillInstall: false, // url 装仍默认禁(供应链风险)\n allowExternalDocuments: false,\n });\n } else {\n this.policy = DEFAULT_TENANT_POLICY;\n }\n }\n\n /** 项目路径是否允许(落在 allowedProjectRoots 或受控根下)。 */\n assertProjectPath(path: string): void {\n const abs = resolve(path);\n const roots = [this.workspaceRoot, ...this.policy.allowedProjectRoots];\n if (!isPathUnderRoots(abs, roots)) {\n throw new PhononError(\"errPolicyDenied\", `project path outside allowed roots: ${abs}`);\n }\n }\n\n /** 文档路径是否允许(默认 project-scoped;外部需 allowExternalDocuments)。 */\n assertDocumentPath(absPath: string, projectRoot: string | undefined): void {\n const abs = resolve(absPath);\n // deny 黑名单优先(即使在项目内也拒)\n for (const pat of this.policy.denyPathPatterns) {\n if (matchGlob(abs, pat)) throw new PhononError(\"errDocumentPathDenied\", `denied by pattern ${pat}`);\n }\n if (projectRoot && isPathUnderRoots(abs, [projectRoot])) return; // 项目内放行\n if (this.policy.allowExternalDocuments) return;\n throw new PhononError(\"errDocumentPathDenied\", `document path outside project: ${abs}`);\n }\n\n assertDeleteFiles(): void {\n if (!this.policy.allowDeleteFiles) throw new PhononError(\"errPolicyDenied\", \"deleteFiles disabled by policy\");\n }\n\n assertGlobalSkillInstall(): void {\n if (!this.policy.allowGlobalSkillInstall) throw new PhononError(\"errPolicyDenied\", \"global skill install disabled by policy\");\n }\n\n assertUrlSkillInstall(): void {\n if (!this.policy.allowUrlSkillInstall) throw new PhononError(\"errPolicyDenied\", \"url skill install disabled by policy\");\n }\n\n assertMethodAllowed(method: string): void {\n if (this.policy.allowedMethods.length > 0 && !this.policy.allowedMethods.includes(method)) {\n throw new PhononError(\"errPolicyDenied\", `method ${method} not in allowedMethods (read-only tenant)`);\n }\n }\n\n allowEnvReveal(): boolean {\n return !!this.policy.allowEnvReveal;\n }\n\n assertUploadSize(bytes: number): void {\n if (this.policy.maxUploadBytes !== undefined && bytes > this.policy.maxUploadBytes) {\n throw new PhononError(\"errDocumentTooLarge\", `${bytes} bytes exceeds maxUploadBytes ${this.policy.maxUploadBytes}`);\n }\n }\n}\n\n/** 极简 glob 匹配(仅支持 ** 和 *),用于 denyPathPatterns。 */\nfunction matchGlob(path: string, pattern: string): boolean {\n const norm = path.replace(/\\\\/g, \"/\");\n const re = new RegExp(\n \"^\" +\n pattern\n .replace(/\\\\/g, \"/\")\n .replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\")\n .replace(/\\*\\*/g, \"\\u0000\") // 占位\n .replace(/\\*/g, \"[^/]*\")\n .replace(/\\u0000/g, \".*\") +\n \"$\",\n );\n return re.test(norm);\n}\n\nexport { matchGlob };\n","/**\n * 幂等存储(design D28 / bug-bash P0#2)。\n *\n * 协议定义了 clientRequestId,但 v0 dispatch 没去重。这里实现:\n * tenantId + method + clientRequestId → 缓存的 result(或 in-flight promise)\n * 断线重发同一请求时返回缓存结果,不重复执行(不丢 + 不重)。\n *\n * v0 内存版,带 TTL + 上限;后续可接 sqlite。\n */\ninterface Entry {\n promise: Promise<unknown>;\n at: number;\n}\n\nexport class IdempotencyStore {\n private map = new Map<string, Entry>();\n private ttlMs: number;\n private max: number;\n private store?: { idempotencyGet: (k: string) => string | undefined; idempotencyPut: (k: string, r: string) => void };\n\n constructor(opts?: { ttlMs?: number; max?: number; store?: { idempotencyGet: (k: string) => string | undefined; idempotencyPut: (k: string, r: string) => void } }) {\n this.ttlMs = opts?.ttlMs ?? 10 * 60 * 1000; // 10 分钟\n this.max = opts?.max ?? 5000;\n this.store = opts?.store;\n }\n\n private key(tenantId: string, method: string, clientRequestId: string): string {\n return `${tenantId}\\u0000${method}\\u0000${clientRequestId}`;\n }\n\n /**\n * 若该 (tenant,method,clientRequestId) 已见过,返回其结果;否则执行 fn 并缓存。\n * 内存 + sqlite 两级:跨重启也去重(功能缺口)。clientRequestId 为空不去重。\n */\n async run<T>(\n tenantId: string,\n method: string,\n clientRequestId: string | undefined,\n fn: () => Promise<T>,\n ): Promise<T> {\n if (!clientRequestId) return fn();\n this.gc();\n const k = this.key(tenantId, method, clientRequestId);\n const existing = this.map.get(k);\n if (existing) return existing.promise as Promise<T>;\n // sqlite 二级:跨重启命中则直接返回缓存结果\n const persisted = this.store?.idempotencyGet(k);\n if (persisted !== undefined) return JSON.parse(persisted) as T;\n const promise = fn();\n this.map.set(k, { promise, at: Date.now() });\n // 成功落 sqlite(跨重启);失败不缓存(允许重试)\n promise.then(\n (r) => { try { this.store?.idempotencyPut(k, JSON.stringify(r)); } catch { /* ignore */ } },\n () => this.map.delete(k),\n );\n return promise;\n }\n\n private gc(): void {\n const now = Date.now();\n if (this.map.size < this.max && now % 16 !== 0) return; // 抽样 GC\n for (const [k, v] of this.map) {\n if (now - v.at > this.ttlMs) this.map.delete(k);\n }\n // 仍超限:删最旧\n if (this.map.size >= this.max) {\n const sorted = [...this.map.entries()].sort((a, b) => a[1].at - b[1].at);\n for (let i = 0; i < sorted.length - this.max + 1; i++) this.map.delete(sorted[i]![0]);\n }\n }\n}\n","import type { StreamEvent } from \"@agent-phonon/protocol\";\n\n/**\n * 下行 outbox(design D29 / bug-bash P1)。\n *\n * stream.event 先入 outbox 再发;server 用 stream.ack{lastSeq} 确认后清理 <= lastSeq。\n * 连接断开期间事件继续缓存;重连后按 seq 补发未 ack 的。\n *\n * v0 内存版,带上限(超限丢最旧 + 计数告警)。后续可接 sqlite outbox_events 表。\n *\n * 注意:seq 是 per-session 单调递增(engine 打的),outbox 按 (sessionId, seq) 索引。\n */\ninterface Buffered {\n sessionId: string;\n seq: number;\n event: StreamEvent;\n}\n\nexport class Outbox {\n private buffer: Buffered[] = [];\n private maxEvents: number;\n private droppedCount = 0;\n /** per-session 已 ack 的最大 seq。 */\n private acked = new Map<string, number>();\n private store?: import(\"./store.js\").PhononStore;\n private tenantId?: string;\n\n constructor(opts?: { maxEvents?: number; store?: import(\"./store.js\").PhononStore; tenantId?: string }) {\n this.maxEvents = opts?.maxEvents ?? 10000;\n this.store = opts?.store;\n this.tenantId = opts?.tenantId;\n if (this.store && this.tenantId) {\n for (const r of this.store.outboxLoad(this.tenantId)) {\n this.buffer.push({ sessionId: r.sessionId, seq: r.seq, event: JSON.parse(r.payload) as StreamEvent });\n }\n }\n }\n\n /** 记录一个待投递事件(已带 seq)。返回是否触发超限丢弃。 */\n enqueue(event: StreamEvent): void {\n const sessionId = (event as { sessionId: string }).sessionId;\n const seq = (event as { seq: number }).seq;\n this.buffer.push({ sessionId, seq, event });\n this.store?.outboxAdd(this.tenantId ?? \"\", sessionId, seq, JSON.stringify(event), new Date().toISOString());\n if (this.buffer.length > this.maxEvents) {\n this.buffer.shift(); // 丢最旧\n this.droppedCount++;\n }\n }\n\n /** server ack 了某 session 的 seq <= lastSeq → 清理。 */\n ack(sessionId: string | undefined, lastSeq: number): void {\n if (sessionId) {\n const prev = this.acked.get(sessionId) ?? -1;\n if (lastSeq > prev) this.acked.set(sessionId, lastSeq);\n this.buffer = this.buffer.filter((b) => !(b.sessionId === sessionId && b.seq <= lastSeq));\n } else {\n // 全局 ack(无 sessionId):按 seq 清所有 session 中 <= lastSeq 的(少用)\n this.buffer = this.buffer.filter((b) => b.seq > lastSeq);\n }\n this.store?.outboxAck(this.tenantId ?? \"\", sessionId, lastSeq);\n }\n\n /**\n * 重连补发:返回所有未 ack 的事件(按 seq 排序),由调用方重新 send。\n * resumeFrom 可指定每个 session 从哪个 seq 开始(server 告知 ackedSeqs)。\n */\n pending(resumeFrom?: Array<{ sessionId: string; fromSeq: number }>): StreamEvent[] {\n let items = [...this.buffer];\n if (resumeFrom && resumeFrom.length > 0) {\n const map = new Map(resumeFrom.map((r) => [r.sessionId, r.fromSeq]));\n items = items.filter((b) => {\n const from = map.get(b.sessionId);\n return from === undefined || b.seq > from;\n });\n }\n items.sort((a, b) => a.seq - b.seq);\n return items.map((b) => b.event);\n }\n\n get size(): number {\n return this.buffer.length;\n }\n\n get dropped(): number {\n return this.droppedCount;\n }\n}\n","import { DatabaseSync } from \"node:sqlite\";\nimport { mkdirSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { SecretBox } from \"./secret-box.js\";\n\n/**\n * 本地持久化(design D6 / bug-bash B3)。\n *\n * 用 Node 原生 `node:sqlite`(Node 22.5+,零第三方依赖、免编译)。\n * daemon 重启后 projects/skills/worktrees/sessions 元数据/outbox/幂等不丢。\n *\n * v0 落这些表:projects, worktrees, skills, sessions, outbox_events,\n * idempotency, pending_interactions。tenant/inbox_queue 后续按需。\n */\nexport class PhononStore {\n private db: DatabaseSync;\n /** env 变量值 at-rest 加密(AES-256-GCM)。密钥文件与库同目录、0600。 */\n private secrets: SecretBox;\n\n constructor(dbPath: string) {\n if (dbPath !== \":memory:\") mkdirSync(dirname(dbPath), { recursive: true });\n this.db = new DatabaseSync(dbPath);\n this.db.exec(\"PRAGMA journal_mode = WAL;\");\n this.db.exec(\"PRAGMA foreign_keys = ON;\");\n // 设备密钥:内存库用进程内随机密钥;落盘库用同目录 device.key(0600)。\n this.secrets = SecretBox.fromKeyFile(dbPath === \":memory:\" ? undefined : join(dirname(dbPath), \"device.key\"));\n this.migrate();\n }\n\n private migrate(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS projects (\n project_id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n path TEXT NOT NULL,\n git INTEGER NOT NULL DEFAULT 1,\n remote TEXT,\n created_at TEXT NOT NULL\n );\n CREATE TABLE IF NOT EXISTS worktrees (\n worktree_id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL,\n path TEXT NOT NULL,\n branch TEXT NOT NULL,\n is_primary INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL\n );\n CREATE TABLE IF NOT EXISTS skills (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n agent_id TEXT NOT NULL,\n name TEXT NOT NULL,\n scope TEXT NOT NULL,\n project_id TEXT,\n version TEXT,\n hash TEXT,\n installed_path TEXT NOT NULL,\n installed_at TEXT NOT NULL,\n UNIQUE(agent_id, scope, name, project_id)\n );\n CREATE TABLE IF NOT EXISTS sessions (\n session_id TEXT PRIMARY KEY,\n tenant_id TEXT NOT NULL,\n project_id TEXT,\n worktree_id TEXT,\n agent_id TEXT NOT NULL,\n model TEXT NOT NULL,\n status TEXT NOT NULL,\n verbosity TEXT NOT NULL,\n created_at TEXT NOT NULL,\n last_active TEXT\n );\n CREATE TABLE IF NOT EXISTS outbox_events (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n tenant_id TEXT NOT NULL,\n session_id TEXT NOT NULL,\n seq INTEGER NOT NULL,\n payload TEXT NOT NULL,\n created_at TEXT NOT NULL\n );\n CREATE INDEX IF NOT EXISTS idx_outbox_tenant ON outbox_events(tenant_id, session_id, seq);\n CREATE TABLE IF NOT EXISTS idempotency (\n k TEXT PRIMARY KEY,\n result TEXT NOT NULL,\n created_at INTEGER NOT NULL\n );\n CREATE TABLE IF NOT EXISTS pending_interactions (\n request_id TEXT PRIMARY KEY,\n session_id TEXT,\n turn_id TEXT,\n form TEXT NOT NULL,\n status TEXT NOT NULL,\n timeout_seconds INTEGER,\n created_at TEXT NOT NULL\n );\n CREATE TABLE IF NOT EXISTS audit_events (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n ts TEXT NOT NULL,\n category TEXT NOT NULL,\n level TEXT NOT NULL,\n event TEXT NOT NULL,\n tenant_id TEXT,\n session_id TEXT,\n agent_id TEXT,\n project_id TEXT,\n turn_id TEXT,\n msg TEXT,\n data TEXT\n );\n CREATE INDEX IF NOT EXISTS idx_audit_ts ON audit_events(ts);\n CREATE INDEX IF NOT EXISTS idx_audit_session ON audit_events(session_id, ts);\n CREATE TABLE IF NOT EXISTS env_vars (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n scope TEXT NOT NULL,\n project_id TEXT,\n agent_id TEXT,\n skill_name TEXT,\n name TEXT NOT NULL,\n value TEXT NOT NULL,\n secret INTEGER NOT NULL DEFAULT 1,\n updated_at TEXT NOT NULL\n );\n CREATE INDEX IF NOT EXISTS idx_env_scope ON env_vars(scope, project_id, agent_id, skill_name);\n CREATE UNIQUE INDEX IF NOT EXISTS idx_env_unique ON env_vars(scope, IFNULL(project_id,''), IFNULL(agent_id,''), IFNULL(skill_name,''), name);\n `);\n }\n\n // ---- projects ----\n upsertProject(r: { projectId: string; name: string; path: string; git: boolean; remote?: string; createdAt: string }): void {\n this.db\n .prepare(\n `INSERT INTO projects(project_id,name,path,git,remote,created_at)\n VALUES(?,?,?,?,?,?)\n ON CONFLICT(project_id) DO UPDATE SET name=excluded.name, path=excluded.path, git=excluded.git, remote=excluded.remote`,\n )\n .run(r.projectId, r.name, r.path, r.git ? 1 : 0, r.remote ?? null, r.createdAt);\n }\n deleteProject(projectId: string): void {\n this.db.prepare(\"DELETE FROM projects WHERE project_id=?\").run(projectId);\n this.db.prepare(\"DELETE FROM worktrees WHERE project_id=?\").run(projectId);\n }\n loadProjects(): Array<{ projectId: string; name: string; path: string; git: boolean; remote?: string; createdAt: string }> {\n return (this.db.prepare(\"SELECT * FROM projects\").all() as Record<string, unknown>[]).map((row) => ({\n projectId: row.project_id as string,\n name: row.name as string,\n path: row.path as string,\n git: (row.git as number) === 1,\n remote: (row.remote as string) ?? undefined,\n createdAt: row.created_at as string,\n }));\n }\n\n // ---- worktrees ----\n upsertWorktree(r: { worktreeId: string; projectId: string; path: string; branch: string; isPrimary: boolean; createdAt: string }): void {\n this.db\n .prepare(\n `INSERT INTO worktrees(worktree_id,project_id,path,branch,is_primary,created_at)\n VALUES(?,?,?,?,?,?) ON CONFLICT(worktree_id) DO NOTHING`,\n )\n .run(r.worktreeId, r.projectId, r.path, r.branch, r.isPrimary ? 1 : 0, r.createdAt);\n }\n deleteWorktree(worktreeId: string): void {\n this.db.prepare(\"DELETE FROM worktrees WHERE worktree_id=?\").run(worktreeId);\n }\n loadWorktrees(): Array<{ worktreeId: string; projectId: string; path: string; branch: string; isPrimary: boolean; createdAt: string }> {\n return (this.db.prepare(\"SELECT * FROM worktrees\").all() as Record<string, unknown>[]).map((row) => ({\n worktreeId: row.worktree_id as string,\n projectId: row.project_id as string,\n path: row.path as string,\n branch: row.branch as string,\n isPrimary: (row.is_primary as number) === 1,\n createdAt: row.created_at as string,\n }));\n }\n\n // ---- skills ----\n upsertSkill(r: { agent: string; name: string; scope: string; projectId?: string; version?: string; hash?: string; installedPath: string; installedAt: string }): void {\n this.db\n .prepare(\n `INSERT INTO skills(agent_id,name,scope,project_id,version,hash,installed_path,installed_at)\n VALUES(?,?,?,?,?,?,?,?)\n ON CONFLICT(agent_id,scope,name,project_id) DO UPDATE SET version=excluded.version, hash=excluded.hash, installed_path=excluded.installed_path, installed_at=excluded.installed_at`,\n )\n .run(r.agent, r.name, r.scope, r.projectId ?? null, r.version ?? null, r.hash ?? null, r.installedPath, r.installedAt);\n }\n deleteSkill(r: { agent: string; name: string; scope: string; projectId?: string }): void {\n this.db\n .prepare(\"DELETE FROM skills WHERE agent_id=? AND name=? AND scope=? AND IFNULL(project_id,'')=IFNULL(?,'')\")\n .run(r.agent, r.name, r.scope, r.projectId ?? null);\n }\n loadSkills(): Array<{ agent: string; name: string; scope: \"global\" | \"project\"; projectId?: string; version?: string; hash?: string; installedPath: string; installedAt: string }> {\n return (this.db.prepare(\"SELECT * FROM skills\").all() as Record<string, unknown>[]).map((row) => ({\n agent: row.agent_id as string,\n name: row.name as string,\n scope: row.scope as \"global\" | \"project\",\n projectId: (row.project_id as string) ?? undefined,\n version: (row.version as string) ?? undefined,\n hash: (row.hash as string) ?? undefined,\n installedPath: row.installed_path as string,\n installedAt: row.installed_at as string,\n }));\n }\n\n // ---- sessions(元数据,OpenClaw 原生可 resume)----\n upsertSession(r: { sessionId: string; tenantId: string; projectId?: string; worktreeId?: string; agent: string; model: string; status: string; verbosity: string; createdAt: string; lastActive?: string }): void {\n this.db\n .prepare(\n `INSERT INTO sessions(session_id,tenant_id,project_id,worktree_id,agent_id,model,status,verbosity,created_at,last_active)\n VALUES(?,?,?,?,?,?,?,?,?,?)\n ON CONFLICT(session_id) DO UPDATE SET model=excluded.model, status=excluded.status, last_active=excluded.last_active`,\n )\n .run(r.sessionId, r.tenantId, r.projectId ?? null, r.worktreeId ?? null, r.agent, r.model, r.status, r.verbosity, r.createdAt, r.lastActive ?? null);\n }\n loadSessions(): Array<Record<string, unknown>> {\n return this.db.prepare(\"SELECT * FROM sessions WHERE status != 'terminated'\").all() as Record<string, unknown>[];\n }\n\n // ---- outbox ----\n outboxAdd(tenantId: string, sessionId: string, seq: number, payload: string, createdAt: string): void {\n this.db.prepare(\"INSERT INTO outbox_events(tenant_id,session_id,seq,payload,created_at) VALUES(?,?,?,?,?)\").run(tenantId, sessionId, seq, payload, createdAt);\n }\n outboxAck(tenantId: string, sessionId: string | undefined, lastSeq: number): void {\n if (sessionId) this.db.prepare(\"DELETE FROM outbox_events WHERE tenant_id=? AND session_id=? AND seq<=?\").run(tenantId, sessionId, lastSeq);\n else this.db.prepare(\"DELETE FROM outbox_events WHERE tenant_id=? AND seq<=?\").run(tenantId, lastSeq);\n }\n outboxLoad(tenantId: string): Array<{ sessionId: string; seq: number; payload: string }> {\n return (this.db.prepare(\"SELECT session_id,seq,payload FROM outbox_events WHERE tenant_id=? ORDER BY seq\").all(tenantId) as Record<string, unknown>[]).map((r) => ({\n sessionId: r.session_id as string,\n seq: r.seq as number,\n payload: r.payload as string,\n }));\n }\n\n // ---- env vars(设备本地环境变量配置,默认脱敏返回)----\n envSet(r: { scope: string; projectId?: string; agent?: string; skillName?: string; name: string; value: string; secret?: boolean; updatedAt: string }): void {\n this.envDelete(r);\n // 落库前加密 value(at-rest)。\n const stored = this.secrets.encrypt(r.value);\n this.db.prepare(\n `INSERT INTO env_vars(scope,project_id,agent_id,skill_name,name,value,secret,updated_at)\n VALUES(?,?,?,?,?,?,?,?)`,\n ).run(r.scope, r.projectId ?? null, r.agent ?? null, r.skillName ?? null, r.name, stored, r.secret === false ? 0 : 1, r.updatedAt);\n }\n envDelete(r: { scope: string; projectId?: string; agent?: string; skillName?: string; name: string }): void {\n this.db.prepare(\"DELETE FROM env_vars WHERE scope=? AND IFNULL(project_id,'')=IFNULL(?,'') AND IFNULL(agent_id,'')=IFNULL(?,'') AND IFNULL(skill_name,'')=IFNULL(?,'') AND name=?\")\n .run(r.scope, r.projectId ?? null, r.agent ?? null, r.skillName ?? null, r.name);\n }\n envList(filter?: { scope?: string; projectId?: string; agent?: string; skillName?: string }): Array<{ scope: string; projectId?: string; agent?: string; skillName?: string; name: string; value: string; secret: boolean; updatedAt: string }> {\n const where: string[] = [];\n const params: unknown[] = [];\n if (filter?.scope) { where.push(\"scope=?\"); params.push(filter.scope); }\n if (filter?.projectId) { where.push(\"project_id=?\"); params.push(filter.projectId); }\n if (filter?.agent) { where.push(\"agent_id=?\"); params.push(filter.agent); }\n if (filter?.skillName) { where.push(\"skill_name=?\"); params.push(filter.skillName); }\n const sql = `SELECT * FROM env_vars ${where.length ? \"WHERE \" + where.join(\" AND \") : \"\"} ORDER BY scope, project_id, agent_id, skill_name, name`;\n return (this.db.prepare(sql).all(...(params as never[])) as Record<string, unknown>[]).map((row) => ({\n scope: row.scope as string,\n projectId: (row.project_id as string) ?? undefined,\n agent: (row.agent_id as string) ?? undefined,\n skillName: (row.skill_name as string) ?? undefined,\n name: row.name as string,\n value: this.secrets.decrypt(row.value as string),\n secret: (row.secret as number) === 1,\n updatedAt: row.updated_at as string,\n }));\n }\n\n close(): void {\n this.db.close();\n }\n\n // ---- audit 事件时间线(可观测回溯)----\n auditAdd(e: {\n ts: string; category: string; level: string; event: string;\n tenantId?: string; sessionId?: string; agentId?: string; projectId?: string; turnId?: string;\n msg?: string; data?: string;\n }): void {\n this.db\n .prepare(\n `INSERT INTO audit_events(ts,category,level,event,tenant_id,session_id,agent_id,project_id,turn_id,msg,data)\n VALUES(?,?,?,?,?,?,?,?,?,?,?)`,\n )\n .run(e.ts, e.category, e.level, e.event, e.tenantId ?? null, e.sessionId ?? null, e.agentId ?? null, e.projectId ?? null, e.turnId ?? null, e.msg ?? null, e.data ?? null);\n }\n\n /** 查 audit 时间线(最近 N 条,可按 session/category 过滤)。 */\n auditQuery(opts?: { sessionId?: string; category?: string; limit?: number }): Array<Record<string, unknown>> {\n const where: string[] = [];\n const params: unknown[] = [];\n if (opts?.sessionId) { where.push(\"session_id=?\"); params.push(opts.sessionId); }\n if (opts?.category) { where.push(\"category=?\"); params.push(opts.category); }\n const sql = `SELECT * FROM audit_events ${where.length ? \"WHERE \" + where.join(\" AND \") : \"\"} ORDER BY id DESC LIMIT ?`;\n params.push(opts?.limit ?? 200);\n return this.db.prepare(sql).all(...(params as never[])) as Record<string, unknown>[];\n }\n\n // ---- idempotency(跨重启去重)----\n idempotencyGet(key: string): string | undefined {\n const row = this.db.prepare(\"SELECT result FROM idempotency WHERE k=?\").get(key) as { result?: string } | undefined;\n return row?.result;\n }\n idempotencyPut(key: string, result: string): void {\n this.db.prepare(\"INSERT INTO idempotency(k,result,created_at) VALUES(?,?,?) ON CONFLICT(k) DO NOTHING\").run(key, result, Date.now());\n }\n}\n","import { createCipheriv, createDecipheriv, randomBytes } from \"node:crypto\";\nimport { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\n\n/**\n * 设备本地 secret 加密(env 变量 at-rest 加密)。\n *\n * - AES-256-GCM,每条 value 独立随机 IV。\n * - 设备密钥存独立文件(0600),与 sqlite 库分离,方便单独保护/轮换。\n * - 落库格式:`enc:v1:<base64(iv|tag|ciphertext)>`,带前缀便于识别与平滑迁移\n * (老的明文值没有前缀 → 读时原样返回,写时才升级为密文)。\n */\n\nconst PREFIX = \"enc:v1:\";\nconst IV_LEN = 12;\nconst TAG_LEN = 16;\nconst KEY_LEN = 32;\n\nexport class SecretBox {\n private key: Buffer;\n\n constructor(key: Buffer) {\n if (key.length !== KEY_LEN) throw new Error(`SecretBox key must be ${KEY_LEN} bytes`);\n this.key = key;\n }\n\n /**\n * 从密钥文件加载,缺失则生成(0600)。`:memory:`/缺省路径用进程内随机密钥\n * (测试/纯内存场景,不落盘也就不需要持久密钥)。\n */\n static fromKeyFile(keyPath: string | undefined): SecretBox {\n if (!keyPath || keyPath === \":memory:\") return new SecretBox(randomBytes(KEY_LEN));\n if (existsSync(keyPath)) {\n const raw = readFileSync(keyPath, \"utf8\").trim();\n const key = Buffer.from(raw, \"base64\");\n if (key.length === KEY_LEN) return new SecretBox(key);\n // 文件存在但内容异常:不静默覆盖(可能是误配),直接报错让人介入。\n throw new Error(`invalid device key at ${keyPath} (expected ${KEY_LEN}-byte base64)`);\n }\n const key = randomBytes(KEY_LEN);\n mkdirSync(dirname(keyPath), { recursive: true });\n writeFileSync(keyPath, key.toString(\"base64\"), { mode: 0o600 });\n try { chmodSync(keyPath, 0o600); } catch { /* best-effort on platforms without chmod */ }\n return new SecretBox(key);\n }\n\n /** 是否已是本方案的密文。 */\n static isEncrypted(value: string): boolean {\n return value.startsWith(PREFIX);\n }\n\n encrypt(plain: string): string {\n const iv = randomBytes(IV_LEN);\n const cipher = createCipheriv(\"aes-256-gcm\", this.key, iv);\n const ct = Buffer.concat([cipher.update(plain, \"utf8\"), cipher.final()]);\n const tag = cipher.getAuthTag();\n return PREFIX + Buffer.concat([iv, tag, ct]).toString(\"base64\");\n }\n\n /** 解密;非本方案前缀的值视为历史明文,原样返回(平滑迁移)。 */\n decrypt(value: string): string {\n if (!SecretBox.isEncrypted(value)) return value;\n const raw = Buffer.from(value.slice(PREFIX.length), \"base64\");\n const iv = raw.subarray(0, IV_LEN);\n const tag = raw.subarray(IV_LEN, IV_LEN + TAG_LEN);\n const ct = raw.subarray(IV_LEN + TAG_LEN);\n const decipher = createDecipheriv(\"aes-256-gcm\", this.key, iv);\n decipher.setAuthTag(tag);\n return Buffer.concat([decipher.update(ct), decipher.final()]).toString(\"utf8\");\n }\n}\n","import { mkdir, readFile, readdir, lstat, realpath, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, join, resolve, sep } from \"node:path\";\nimport { PhononError } from \"./rpc.js\";\n\nexport interface FileScopeResolver {\n resolveCwd(projectId: string, worktreeId?: string): string;\n}\n\ntype StatEntry = { path: string; type: \"file\" | \"directory\" | \"symlink\" | \"other\"; sizeBytes: number; modifiedAt: string };\n\nexport class FileManager {\n constructor(private resolver: FileScopeResolver) {}\n\n /**\n * Realpath of the deepest existing ancestor, with any non-existent suffix re-appended.\n * Lets us containment-check write/mkdir targets that don't exist yet, while still\n * resolving symlinks in the existing portion of the path.\n */\n private async realpathBoundary(abs: string): Promise<string> {\n const suffix: string[] = [];\n let cur = abs;\n for (;;) {\n try {\n const real = await realpath(cur);\n return suffix.length ? resolve(real, ...suffix) : real;\n } catch (e) {\n if ((e as NodeJS.ErrnoException)?.code !== \"ENOENT\") throw e;\n const parent = dirname(cur);\n if (parent === cur) return abs; // hit fs root, nothing left to resolve\n suffix.unshift(basename(cur));\n cur = parent;\n }\n }\n }\n\n /**\n * Resolve a project-relative path to an absolute path, enforcing that it stays\n * inside the project/worktree root — including via symlinks (defeats `evil -> /etc`).\n *\n * followFinal=true (read/write/mkdir/list-base): the final component is resolved too,\n * so a final symlink pointing outside is rejected (readFile/writeFile would follow it).\n * followFinal=false (stat): the final component is NOT resolved, so an in-project symlink\n * can be lstat'd and reported as \"symlink\" without being followed. Middle-of-path\n * symlinks are still resolved and rejected.\n */\n private async resolvePath(projectId: string, worktreeId: string | undefined, rel: string, followFinal = true): Promise<string> {\n if (rel.includes(\"\\0\") || rel.startsWith(\"/\") || rel === \"\") {\n throw new PhononError(\"errInvalidParams\", \"file path must be a non-empty relative path\");\n }\n // Normalize the root through realpath too, so both sides are comparable on\n // platforms where the workspace itself sits under a symlink (e.g. macOS /tmp).\n const root = await this.realpathBoundary(resolve(this.resolver.resolveCwd(projectId, worktreeId)));\n const abs = resolve(root, rel);\n // 1) lexical containment — fast reject of ../ escapes.\n if (abs !== root && !abs.startsWith(root + sep)) {\n throw new PhononError(\"errPolicyDenied\", `file path escapes project/worktree: ${rel}`);\n }\n // 2) realpath containment — defeats symlink escape (string prefix check alone is insufficient).\n // For stat we probe the parent dir so an in-project symlink entry can still be reported.\n const probe = !followFinal && abs !== root ? dirname(abs) : abs;\n const real = await this.realpathBoundary(probe);\n if (real !== root && !real.startsWith(root + sep)) {\n throw new PhononError(\"errPolicyDenied\", `file path escapes project/worktree via symlink: ${rel}`);\n }\n return abs;\n }\n\n async read(params: { projectId: string; worktreeId?: string; path: string; encoding?: \"utf8\" | \"base64\"; maxBytes?: number }) {\n const abs = await this.resolvePath(params.projectId, params.worktreeId, params.path);\n const buf = await readFile(abs);\n const max = params.maxBytes;\n const out = max && buf.length > max ? buf.subarray(0, max) : buf;\n const encoding = params.encoding ?? \"utf8\";\n return {\n path: params.path,\n encoding,\n data: encoding === \"base64\" ? out.toString(\"base64\") : out.toString(\"utf8\"),\n sizeBytes: buf.length,\n truncated: !!max && buf.length > max,\n };\n }\n\n async write(params: { projectId: string; worktreeId?: string; path: string; encoding?: \"utf8\" | \"base64\"; data: string; overwrite?: boolean; createDirs?: boolean }) {\n const abs = await this.resolvePath(params.projectId, params.worktreeId, params.path);\n if (params.createDirs ?? true) await mkdir(dirname(abs), { recursive: true });\n const content = params.encoding === \"base64\" ? Buffer.from(params.data, \"base64\") : Buffer.from(params.data, \"utf8\");\n await writeFile(abs, content, { flag: params.overwrite === false ? \"wx\" : \"w\" });\n return { path: params.path, sizeBytes: content.length, written: true as const };\n }\n\n async mkdir(params: { projectId: string; worktreeId?: string; path: string; recursive?: boolean }) {\n const abs = await this.resolvePath(params.projectId, params.worktreeId, params.path);\n await mkdir(abs, { recursive: params.recursive ?? true });\n return { path: params.path, created: true as const };\n }\n\n async stat(params: { projectId: string; worktreeId?: string; path: string }) {\n const abs = await this.resolvePath(params.projectId, params.worktreeId, params.path, false);\n return { stat: await this.lstatOne(abs, params.path) };\n }\n\n async list(params: { projectId: string; worktreeId?: string; path?: string; recursive?: boolean; limit?: number }) {\n const baseRel = params.path ?? \".\";\n const limit = params.limit ?? 500;\n const baseAbs = await this.resolvePath(params.projectId, params.worktreeId, baseRel);\n const entries: StatEntry[] = [];\n const walk = async (absDir: string, relDir: string): Promise<void> => {\n if (entries.length >= limit) return;\n const names = await readdir(absDir);\n for (const name of names) {\n if (entries.length >= limit) return;\n const childRel = relDir === \".\" ? name : `${relDir}/${name}`;\n const childAbs = join(absDir, name);\n const s = await this.lstatOne(childAbs, childRel);\n entries.push(s);\n // Only descend into REAL directories. lstat reports symlinks as \"symlink\",\n // so symlinked dirs are never followed (also avoids symlink-cycle loops).\n if (params.recursive && s.type === \"directory\") await walk(childAbs, childRel);\n }\n };\n await walk(baseAbs, baseRel);\n return { path: baseRel, entries, truncated: entries.length >= limit };\n }\n\n private async lstatOne(abs: string, rel: string): Promise<StatEntry> {\n const s = await lstat(abs);\n const type = s.isSymbolicLink() ? \"symlink\" : s.isFile() ? \"file\" : s.isDirectory() ? \"directory\" : \"other\";\n return { path: rel, type, sizeBytes: s.size, modifiedAt: s.mtime.toISOString() };\n }\n}\n","import { cpus, freemem, loadavg, totalmem } from \"node:os\";\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst execFileAsync = promisify(execFile);\n\n/** 设备资源监控:debug 用,不做资源调度。 */\nexport async function collectDeviceResources(path = process.cwd()) {\n const total = totalmem();\n const free = freemem();\n const used = Math.max(0, total - free);\n const mem = process.memoryUsage();\n const disk = await diskUsage(path).catch(() => undefined);\n const gpu = await gpuInfo().catch(() => undefined);\n return {\n at: new Date().toISOString(),\n cpu: { loadavg: loadavg(), cores: cpus().length },\n memory: { totalBytes: total, freeBytes: free, usedBytes: used, usagePercent: total ? (used / total) * 100 : undefined },\n disk,\n gpu,\n process: { pid: process.pid, uptimeSeconds: process.uptime(), rssBytes: mem.rss, heapUsedBytes: mem.heapUsed, heapTotalBytes: mem.heapTotal },\n };\n}\n\nasync function diskUsage(path: string) {\n const { stdout } = await execFileAsync(\"df\", [\"-Pk\", path], { timeout: 3000 });\n const lines = stdout.trim().split(/\\n/);\n const row = lines[lines.length - 1]?.trim().split(/\\s+/);\n if (!row || row.length < 6) return { path };\n const totalBytes = Number(row[1]) * 1024;\n const usedBytes = Number(row[2]) * 1024;\n const freeBytes = Number(row[3]) * 1024;\n return { path, totalBytes, freeBytes, usedBytes, usagePercent: totalBytes ? (usedBytes / totalBytes) * 100 : undefined };\n}\n\nasync function gpuInfo() {\n const { stdout } = await execFileAsync(\"nvidia-smi\", [\"--query-gpu=name,memory.total,memory.used,utilization.gpu\", \"--format=csv,noheader,nounits\"], { timeout: 3000 });\n return stdout.trim().split(/\\n/).filter(Boolean).map((line) => {\n const [name, totalMb, usedMb, util] = line.split(\",\").map((s) => s.trim());\n return {\n name,\n memoryTotalBytes: Number(totalMb) * 1024 * 1024,\n memoryUsedBytes: Number(usedMb) * 1024 * 1024,\n utilizationPercent: Number(util),\n };\n });\n}\n","import { arch, hostname, platform, release, type } from \"node:os\";\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst execFileAsync = promisify(execFile);\n\n/**\n * 相对静态的设备信息,用于服务端做调度决策。\n * 例如:iOS/macOS 开发任务优先派给 darwin 设备,Windows 桌面开发派给 win32 设备。\n */\nexport async function collectDeviceInfo() {\n const base = {\n at: new Date().toISOString(),\n hostname: hostname(),\n os: {\n platform: platform(),\n type: type(),\n release: release(),\n arch: arch(),\n },\n runtime: {\n node: process.version,\n },\n capabilities: await inferCapabilities(),\n };\n return base;\n}\n\nasync function inferCapabilities(): Promise<string[]> {\n const caps = new Set<string>();\n const p = platform();\n if (p === \"darwin\") {\n caps.add(\"macos\");\n caps.add(\"ios-development\");\n }\n if (p === \"win32\") {\n caps.add(\"windows\");\n caps.add(\"windows-desktop-development\");\n }\n if (p === \"linux\") caps.add(\"linux\");\n if (await commandExists(\"git\")) caps.add(\"git\");\n if (await commandExists(\"node\")) caps.add(\"node\");\n if (await commandExists(\"python3\")) caps.add(\"python\");\n if (await commandExists(\"xcodebuild\")) caps.add(\"xcode\");\n if (await commandExists(\"swift\")) caps.add(\"swift\");\n if (await commandExists(\"powershell\") || await commandExists(\"pwsh\")) caps.add(\"powershell\");\n if (await commandExists(\"nvidia-smi\")) caps.add(\"nvidia-gpu\");\n return [...caps].sort();\n}\n\nasync function commandExists(cmd: string): Promise<boolean> {\n try {\n const which = platform() === \"win32\" ? \"where\" : \"which\";\n await execFileAsync(which, [cmd], { timeout: 1500 });\n return true;\n } catch {\n return false;\n }\n}\n","import { PhononError } from \"./rpc.js\";\nimport type { PhononStore } from \"./store.js\";\n\ntype Scope = \"global\" | \"project\" | \"skill\";\n\nexport interface EnvTarget {\n scope: Scope;\n projectId?: string;\n agent?: string;\n skillName?: string;\n}\n\nfunction redact(value: string): string {\n if (value.length <= 4) return \"****\";\n return `****${value.slice(-4)}`;\n}\n\nfunction validateName(name: string): void {\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)) throw new PhononError(\"errInvalidParams\", `invalid env var name: ${name}`);\n}\n\nexport class EnvManager {\n constructor(private store: PhononStore, private opts: { allowReveal: () => boolean }) {}\n\n set(params: EnvTarget & { name: string; value: string; secret?: boolean }) {\n validateName(params.name);\n const updatedAt = new Date().toISOString();\n this.store.envSet({ ...params, updatedAt });\n return { variable: this.describe({ ...params, updatedAt, secret: params.secret !== false }, false) };\n }\n\n delete(params: EnvTarget & { name: string }) {\n validateName(params.name);\n this.store.envDelete(params);\n return { deleted: true as const, name: params.name };\n }\n\n list(filter: Partial<EnvTarget> & { reveal?: boolean }) {\n const reveal = !!filter.reveal;\n if (reveal && !this.opts.allowReveal()) throw new PhononError(\"errPolicyDenied\", \"env reveal disabled by policy\");\n const rows = this.store.envList(filter);\n return { variables: rows.map((r) => this.describe(r, reveal)) };\n }\n\n /** 返回本次执行应该注入的环境变量:global < project < skill。 */\n resolveForExecution(params: { projectId?: string; agent?: string; skills?: string[] }): Record<string, string> {\n const env: Record<string, string> = {};\n for (const r of this.store.envList({ scope: \"global\" })) env[r.name] = r.value;\n if (params.projectId) for (const r of this.store.envList({ scope: \"project\", projectId: params.projectId })) env[r.name] = r.value;\n if (params.projectId && params.agent && params.skills) {\n for (const skillName of params.skills) {\n for (const r of this.store.envList({ scope: \"skill\", projectId: params.projectId, agent: params.agent, skillName })) env[r.name] = r.value;\n }\n }\n return env;\n }\n\n private describe(r: { scope: string; projectId?: string; agent?: string; skillName?: string; name: string; value: string; secret?: boolean; updatedAt?: string }, reveal: boolean) {\n return {\n scope: r.scope,\n projectId: r.projectId,\n agent: r.agent,\n skillName: r.skillName,\n name: r.name,\n value: reveal ? r.value : redact(r.value),\n redacted: !reveal,\n updatedAt: r.updatedAt,\n };\n }\n}\n","import { spawn } from \"node:child_process\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { dropToolIOFromJsonlFiles } from \"../custom-compress.js\";\nimport type {\n AgentAdapter,\n AdapterSession,\n CreateSessionParams,\n SendOptions,\n} from \"../adapter.js\";\nimport type { AgentCapabilities, AgentDescriptor, StreamEvent, ContextItem } from \"@agent-phonon/protocol\";\n\n/**\n * OpenClaw adapter(design D10,第一个 adapter)。\n *\n * 驱动 `openclaw agent --local --json --session-key <key> --message <text> [--model <id>]`。\n * 实测(2026-06-20):\n * - --session-key 给持续会话,同 key 跨调用记忆上下文 → nativeSession=true\n * - --json 输出 { payloads:[{text}], meta:{ finalAssistantVisibleText, ... } }\n * - --model 覆盖模型 → modelSwitch=true(下一轮生效)\n * OpenClaw adapter 极薄(design D8):直接调 CLI,把最终文本封成 result 事件。\n */\n\nconst OPENCLAW_CAPABILITIES: AgentCapabilities = {\n nativeSession: true, // --session-key resume\n nativeCompression: true, // OpenClaw 有 /compact\n contextInjection: true, // 可在 message 前注入\n proactiveOutput: true, // OpenClaw 有 cron/心跳,会自发输出\n modelSwitch: true, // --model 覆盖\n interrupt: false, // CLI 一次性调用,靠 core 兜底 kill 子进程\n injectMidTurn: false,\n skillManagement: true, // OpenClaw 有 skills 目录\n hooks: [\"pre_tool\", \"pre_command\"],\n streaming: false, // --json 是一次性返回,非增量流(v0 用 final 事件)\n limits: { maxConcurrentSessions: 4, maxContextTokens: 1048576 },\n};\n\ninterface OpenClawJson {\n payloads?: Array<{ text?: string }>;\n meta?: {\n finalAssistantVisibleText?: string;\n aborted?: boolean;\n stopReason?: string;\n };\n}\n\nclass OpenClawSession implements AdapterSession {\n readonly sessionId: string;\n model: string;\n private sessionKey: string;\n private cwd: string;\n private openclawAgent: string;\n private current?: ReturnType<typeof spawn>;\n /** 暂存的注入上下文(下次 send 拼进 input,不单独跑一轮,修 P0#13)。 */\n private pendingInject: string[] = [];\n\n constructor(sessionId: string, model: string, cwd: string, openclawAgent = \"main\") {\n this.sessionId = sessionId;\n this.model = model;\n this.cwd = cwd;\n this.openclawAgent = openclawAgent;\n // 用 phonon sessionId 派生稳定的 OpenClaw session-key\n this.sessionKey = `agent:${openclawAgent}:phonon-${sessionId}`;\n }\n\n async send(input: string, opts: SendOptions): Promise<void> {\n const { turnId, emit } = opts;\n\n let message = input;\n // 暂存的注入先拼进本轮(避免单独 turn,P0#13)\n if (this.pendingInject.length > 0) {\n message = this.pendingInject.join(\"\\n\") + \"\\n\\n\" + message;\n this.pendingInject = [];\n }\n // 若指定了 skill,在 message 前注入强制加载指令(D26 方式2)\n if (opts.skills && opts.skills.length > 0) {\n message = `[必须本轮加载并使用这些 skill: ${opts.skills.join(\", \")}]\\n\\n${message}`;\n }\n\n const args = [\n \"agent\",\n \"--local\",\n \"--agent\",\n this.openclawAgent,\n \"--json\",\n \"--session-key\",\n this.sessionKey,\n \"--message\",\n message,\n \"--model\",\n this.model,\n ];\n\n const stdout = await this.run(args, opts.signal, opts.environment);\n if (stdout === null) {\n // 被 interrupt\n emit({\n type: \"result\",\n sessionId: this.sessionId,\n turnId,\n seq: 0,\n at: new Date().toISOString(),\n text: \"\",\n status: \"interrupted\",\n final: true,\n } as StreamEvent);\n return;\n }\n\n let parsed: OpenClawJson | undefined;\n try {\n parsed = JSON.parse(stdout) as OpenClawJson;\n } catch {\n // 解析失败也要给终态\n }\n const text =\n parsed?.meta?.finalAssistantVisibleText ?? parsed?.payloads?.[0]?.text ?? stdout.slice(0, 2000);\n\n emit({\n type: \"result\",\n sessionId: this.sessionId,\n turnId,\n seq: 0,\n at: new Date().toISOString(),\n text,\n status: parsed?.meta?.aborted ? \"aborted\" : \"completed\",\n final: true,\n } as StreamEvent);\n }\n\n async interrupt(): Promise<void> {\n if (this.current) {\n this.current.kill(\"SIGTERM\");\n this.current = undefined;\n }\n }\n\n async switchModel(model: string): Promise<{ warnings?: string[] }> {\n this.model = model;\n return {};\n }\n\n async inject(context: ContextItem[]): Promise<void> {\n // OpenClaw spawn 版没有 transcript append API:暂存到下次 send 拼进 input,\n // 不单独跑一轮(修 P0#13:之前会产生额外 turn)。\n if (context.length === 0) return;\n for (const c of context) this.pendingInject.push(`[${c.role}] ${c.content}`);\n }\n\n async compressCustom(strategy = \"dropToolIO\", options?: { keepRecentToolCalls?: number }): Promise<{ summary?: string; filesChanged?: number; recordsChanged?: number; blocksRemoved?: number; bytesBefore?: number; bytesAfter?: number; backups?: string[] }> {\n if (strategy !== \"dropToolIO\") throw new Error(`unsupported custom compression strategy: ${strategy}`);\n const file = this.resolveSessionFile();\n if (!file) throw new Error(`OpenClaw session file not found for ${this.sessionKey}`);\n const r = await dropToolIOFromJsonlFiles([file], options);\n return { summary: `dropToolIO removed ${r.blocksRemoved} tool blocks from ${r.filesChanged} files`, ...r };\n }\n\n async compressNative(): Promise<{ summary?: string }> {\n await this.run([\n \"agent\", \"--local\", \"--agent\", this.openclawAgent, \"--json\",\n \"--session-key\", this.sessionKey,\n \"--message\", \"/compact\",\n \"--model\", this.model,\n ]);\n return { summary: \"compacted via OpenClaw /compact\" };\n }\n\n async terminate(): Promise<void> {\n await this.interrupt();\n // OpenClaw session 落盘可保留;phonon 侧标记 terminated 即可。\n }\n\n private resolveSessionFile(): string | undefined {\n const sessionsJson = join(homedir(), \".openclaw\", \"agents\", this.openclawAgent, \"sessions\", \"sessions.json\");\n try {\n if (existsSync(sessionsJson)) {\n const sessions = JSON.parse(readFileSync(sessionsJson, \"utf8\")) as Record<string, { sessionId?: string }>;\n const id = sessions[this.sessionKey]?.sessionId;\n if (id) {\n const p = join(homedir(), \".openclaw\", \"agents\", this.openclawAgent, \"sessions\", `${id}.jsonl`);\n if (existsSync(p)) return p;\n }\n }\n } catch {\n // fall through\n }\n return undefined;\n }\n\n private run(args: string[], signal?: AbortSignal, environment?: Record<string, string>): Promise<string | null> {\n return new Promise((resolve, reject) => {\n const child = spawn(\"openclaw\", args, { cwd: this.cwd, env: { ...process.env, ...(environment ?? {}) } as NodeJS.ProcessEnv });\n this.current = child;\n let out = \"\";\n let err = \"\";\n let killed = false;\n child.stdout.on(\"data\", (d) => (out += d.toString()));\n child.stderr.on(\"data\", (d) => (err += d.toString()));\n const onAbort = () => {\n killed = true;\n child.kill(\"SIGTERM\");\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n child.on(\"error\", reject);\n child.on(\"close\", (code) => {\n signal?.removeEventListener(\"abort\", onAbort);\n this.current = undefined;\n if (killed) return resolve(null);\n if (code === 0) resolve(out);\n else reject(new Error(`openclaw exited ${code}: ${err.slice(0, 500)}`));\n });\n });\n }\n}\n\nexport class OpenClawAdapter implements AgentAdapter {\n readonly name = \"openclaw\";\n readonly capabilities = OPENCLAW_CAPABILITIES;\n /** 默认驱动哪个 OpenClaw agent(可被 session agentConfig.openclawAgent 覆盖)。 */\n private defaultAgent: string;\n\n constructor(opts: { defaultAgent?: string } = {}) {\n this.defaultAgent = opts.defaultAgent ?? \"main\";\n }\n\n async discover(): Promise<AgentDescriptor> {\n return (await this.discoverAgents())[0]!;\n }\n\n async discoverAgents(): Promise<AgentDescriptor[]> {\n // 探测 openclaw 是否可用 + 版本\n const version = await this.probeVersion();\n const available = version !== null;\n if (!available) {\n return [{\n agentId: \"openclaw\" as AgentDescriptor[\"agentId\"],\n displayName: \"OpenClaw\",\n adapter: \"openclaw\",\n available: false,\n unavailableReason: \"openclaw CLI not found\",\n models: [],\n capabilities: OPENCLAW_CAPABILITIES,\n scannedAt: new Date().toISOString(),\n }];\n }\n // spawn 版不枚举多 agent(Gateway 版才枚举):只报 defaultAgent\n return [{\n agentId: `openclaw:${this.defaultAgent}` as AgentDescriptor[\"agentId\"],\n displayName: `OpenClaw / ${this.defaultAgent}`,\n adapter: \"openclaw\",\n available: true,\n ...(version ? { version } : {}),\n models: [\n { id: \"github-copilot/claude-opus-4.8\", displayName: \"Claude Opus 4.8\", available: true },\n { id: \"github-copilot/gpt-5.5\", displayName: \"GPT-5.5\", available: true },\n ],\n capabilities: OPENCLAW_CAPABILITIES,\n scannedAt: new Date().toISOString(),\n }];\n }\n\n async createSession(params: CreateSessionParams): Promise<AdapterSession> {\n const openclawAgent =\n (params.agentConfig?.openclawAgent as string) ??\n (params.agentId?.includes(\":\") ? params.agentId.split(\":\")[1]! : this.defaultAgent);\n return new OpenClawSession(params.sessionId, params.model, params.cwd, openclawAgent);\n }\n\n private probeVersion(): Promise<string | null> {\n return new Promise((resolve) => {\n const child = spawn(\"openclaw\", [\"--version\"]);\n let out = \"\";\n child.stdout.on(\"data\", (d) => (out += d.toString()));\n child.on(\"error\", () => resolve(null));\n child.on(\"close\", (code) => resolve(code === 0 ? out.trim() : null));\n });\n }\n}\n","import { copyFile, rename, readFile, writeFile } from \"node:fs/promises\";\n\nexport interface DropToolIOResult {\n filesChanged: number;\n recordsChanged: number;\n blocksRemoved: number;\n bytesBefore: number;\n bytesAfter: number;\n backups: string[];\n}\n\nexport interface DropToolIOOptions {\n /** 保留最近 N 个 tool call 及其对应 result/中间块;默认 3。 */\n keepRecentToolCalls?: number;\n /**\n * 文件级算好的「保留集」(按对象引用)。\n * 用引用集而非 id,能正确保留**没有 id 的最近 tool 块**(item 3 修复)。\n */\n keepToolBlocks?: Set<unknown>;\n /** 兼容旧路径:按 id 保留(仍支持,但 keepToolBlocks 优先)。 */\n keepToolCallIds?: Set<string>;\n}\n\nexport function dropToolIOFromValue(value: unknown, options: DropToolIOOptions = {}): { value: unknown; changed: boolean; removed: number } {\n if (Array.isArray(value)) {\n let changed = false;\n let removed = 0;\n const out: unknown[] = [];\n for (const item of value) {\n if (isToolBlock(item) && !shouldKeepToolBlock(item, options)) {\n changed = true;\n removed++;\n continue;\n }\n const r = dropToolIOFromValue(item, options);\n changed ||= r.changed;\n removed += r.removed;\n out.push(r.value);\n }\n return { value: out, changed, removed };\n }\n if (value && typeof value === \"object\") {\n if (isToolBlock(value) && !shouldKeepToolBlock(value, options)) return { value: undefined, changed: true, removed: 1 };\n let changed = false;\n let removed = 0;\n const out: Record<string, unknown> = { ...(value as Record<string, unknown>) };\n for (const [k, v] of Object.entries(out)) {\n if (isToolBlock(v) && !shouldKeepToolBlock(v, options)) {\n delete out[k];\n changed = true;\n removed++;\n continue;\n }\n const r = dropToolIOFromValue(v, options);\n changed ||= r.changed;\n removed += r.removed;\n out[k] = r.value;\n }\n return { value: out, changed, removed };\n }\n return { value, changed: false, removed: 0 };\n}\n\nfunction shouldKeepToolBlock(value: unknown, options: DropToolIOOptions): boolean {\n if (options.keepToolBlocks?.has(value)) return true;\n const id = toolBlockId(value);\n return !!id && !!options.keepToolCallIds?.has(id);\n}\n\nfunction toolBlockId(value: unknown): string | undefined {\n if (!value || typeof value !== \"object\") return undefined;\n const o = value as Record<string, unknown>;\n const id = o.id ?? o.toolCallId ?? o.tool_call_id ?? o.tool_use_id ?? o.call_id;\n return typeof id === \"string\" && id.length > 0 ? id : undefined;\n}\n\nfunction isToolCall(value: unknown): boolean {\n if (!value || typeof value !== \"object\") return false;\n const t = (value as Record<string, unknown>).type;\n return t === \"tool_use\" || t === \"tool_call\" || t === \"function_call\";\n}\n\n/** 按文档顺序收集所有 tool 块的对象引用(块是原子单位,命中即不再深入)。 */\nfunction collectToolBlocks(value: unknown, out: unknown[]): void {\n if (isToolBlock(value)) { out.push(value); return; }\n if (Array.isArray(value)) { for (const item of value) collectToolBlocks(item, out); return; }\n if (value && typeof value === \"object\") { for (const v of Object.values(value)) collectToolBlocks(v, out); }\n}\n\n/**\n * 文件级计算「保留集」:保留最近 keepRecent 个 tool **call** 起、直到末尾的所有 tool 块\n * (含中间的 result、以及没有 id 的块)。基于位置而非 id —— 这样最近但无 id 的块也能保留。\n */\nexport function computeKeepToolBlocks(records: unknown[], keepRecent: number): Set<unknown> {\n if (keepRecent <= 0) return new Set();\n const blocks: unknown[] = [];\n for (const r of records) collectToolBlocks(r, blocks);\n if (blocks.length === 0) return new Set();\n const callIdx: number[] = [];\n blocks.forEach((b, i) => { if (isToolCall(b)) callIdx.push(i); });\n if (callIdx.length === 0) {\n // 没有明确的 call 块:退化为保留末尾 keepRecent 个任意 tool 块\n return new Set(blocks.slice(Math.max(0, blocks.length - keepRecent)));\n }\n const cutoff = callIdx[Math.max(0, callIdx.length - keepRecent)]!;\n return new Set(blocks.slice(cutoff));\n}\n\nfunction isToolBlock(value: unknown): boolean {\n if (!value || typeof value !== \"object\") return false;\n const o = value as Record<string, unknown>;\n const type = typeof o.type === \"string\" ? o.type : \"\";\n // Anthropic / Claude Code / OpenClaw content blocks.\n if (type === \"tool_use\" || type === \"tool_result\") return true;\n // Phonon/OpenClaw trajectory style events; keep ordinary text/message records.\n if (type === \"tool_call\" || type === \"tool_result_delta\") return true;\n // Codex response_item / OpenAI Responses style.\n if (type === \"function_call\" || type === \"function_call_output\" || type === \"custom_tool_call\" || type === \"custom_tool_call_output\" || type === \"local_shell_call\") return true;\n const role = typeof o.role === \"string\" ? o.role : \"\";\n // Some providers encode tool-return messages by role/name instead of content block type.\n if (role === \"tool\") return true;\n return false;\n}\n\nexport async function dropToolIOFromJsonlFiles(files: string[], options: DropToolIOOptions = {}): Promise<DropToolIOResult> {\n const result: DropToolIOResult = { filesChanged: 0, recordsChanged: 0, blocksRemoved: 0, bytesBefore: 0, bytesAfter: 0, backups: [] };\n const stamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const keepRecent = options.keepRecentToolCalls ?? 3;\n for (const file of files) {\n const before = await readFile(file, \"utf8\");\n result.bytesBefore += Buffer.byteLength(before);\n const lines = before.split(/\\n/);\n const parsed: unknown[] = [];\n for (const line of lines) {\n if (!line.trim()) { parsed.push(undefined); continue; }\n try {\n parsed.push(JSON.parse(line) as unknown);\n } catch {\n parsed.push(undefined);\n }\n }\n // 文件级保留集(按引用,覆盖最近 keepRecent 个 call 起的所有 tool 块)。\n const keepToolBlocks = computeKeepToolBlocks(parsed, keepRecent);\n let fileChanged = false;\n const out: string[] = [];\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!;\n if (!line.trim()) {\n out.push(line);\n continue;\n }\n const obj = parsed[i];\n if (obj === undefined) {\n out.push(line); // 不可解析行原样保留\n continue;\n }\n const r = dropToolIOFromValue(obj, { ...options, keepToolBlocks });\n if (r.changed) {\n fileChanged = true;\n result.recordsChanged++;\n result.blocksRemoved += r.removed;\n }\n out.push(JSON.stringify(r.value));\n }\n const after = out.join(\"\\n\");\n result.bytesAfter += Buffer.byteLength(after);\n if (fileChanged) {\n const backup = `${file}.bak-${stamp}`;\n await copyFile(file, backup);\n await writeFile(`${file}.tmp-${stamp}`, after);\n await rename(`${file}.tmp-${stamp}`, file);\n result.filesChanged++;\n result.backups.push(backup);\n }\n }\n return result;\n}\n","import { WebSocket } from \"ws\";\nimport { randomUUID } from \"node:crypto\";\n\n/**\n * OpenClaw Gateway WebSocket 客户端(传输层)。\n *\n * 借鉴 LMA src/openclaw-client.ts 的传输层(握手 + RPC + 事件路由),\n * 不抄其飞书业务逻辑。协议帧:{type:\"req\"|\"res\"|\"event\", id, method, params/payload}。\n *\n * 握手:连上 → 收 connect.challenge(event) → 发 connect(req, operator scopes + token) → hello-ok。\n */\n\nconst GATEWAY_PROTOCOL_MIN = 1;\nconst GATEWAY_PROTOCOL_MAX = 10;\n\nexport interface GatewayConfig {\n /** ws 或 http URL(http 会自动转 ws)。 */\n baseUrl: string;\n token: string;\n}\n\ninterface Pending {\n resolve: (v: unknown) => void;\n reject: (e: unknown) => void;\n timer: NodeJS.Timeout;\n}\n\n/** Gateway 事件回调:method=事件名(agent/chat/...),payload=事件体。 */\nexport type GatewayEventHandler = (event: string, payload: Record<string, unknown>) => void;\n\nexport class GatewayClient {\n private ws: WebSocket | null = null;\n private connected = false;\n private config: GatewayConfig;\n private pending = new Map<string, Pending>();\n private eventHandlers = new Set<GatewayEventHandler>();\n private connectPromise: Promise<void> | null = null;\n\n constructor(config: GatewayConfig) {\n this.config = config;\n }\n\n onEvent(handler: GatewayEventHandler): void {\n this.eventHandlers.add(handler);\n }\n\n isConnected(): boolean {\n return this.connected;\n }\n\n connect(): Promise<void> {\n if (this.connectPromise) return this.connectPromise;\n this.connectPromise = this.doConnect();\n return this.connectPromise;\n }\n\n private doConnect(): Promise<void> {\n return new Promise((resolve, reject) => {\n const wsUrl = this.config.baseUrl.replace(/^http/, \"ws\");\n const ws = new WebSocket(wsUrl);\n this.ws = ws;\n let handshakeDone = false;\n\n ws.on(\"message\", (raw: Buffer) => {\n let frame: Record<string, unknown>;\n try {\n frame = JSON.parse(raw.toString());\n } catch {\n return;\n }\n\n if (!handshakeDone) {\n if (frame.type === \"event\" && frame.event === \"connect.challenge\") {\n ws.send(\n JSON.stringify({\n type: \"req\",\n id: \"connect-1\",\n method: \"connect\",\n params: {\n minProtocol: GATEWAY_PROTOCOL_MIN,\n maxProtocol: GATEWAY_PROTOCOL_MAX,\n client: { id: \"gateway-client\", version: \"0.0.1\", platform: \"linux\", mode: \"backend\" },\n role: \"operator\",\n scopes: [\"operator.read\", \"operator.write\", \"operator.admin\"],\n auth: { token: this.config.token },\n userAgent: \"agent-phonon/0.0.1\",\n },\n }),\n );\n } else if (frame.type === \"res\" && frame.ok && (frame.payload as { type?: string })?.type === \"hello-ok\") {\n handshakeDone = true;\n this.connected = true;\n resolve();\n } else if (frame.type === \"res\" && !frame.ok) {\n reject(new Error(`handshake failed: ${JSON.stringify(frame.error)}`));\n }\n return;\n }\n\n // 响应\n if (frame.type === \"res\" && frame.id) {\n const p = this.pending.get(frame.id as string);\n if (p) {\n this.pending.delete(frame.id as string);\n clearTimeout(p.timer);\n if (frame.ok) p.resolve(frame.payload);\n else p.reject(new Error(`RPC error: ${JSON.stringify(frame.error)}`));\n }\n return;\n }\n\n // 事件 → 分发给所有 handler\n if (frame.type === \"event\" && typeof frame.event === \"string\") {\n for (const h of this.eventHandlers) {\n try {\n h(frame.event, (frame.payload as Record<string, unknown>) ?? {});\n } catch {\n /* ignore handler error */\n }\n }\n }\n });\n\n ws.on(\"error\", (err) => {\n if (!handshakeDone) reject(err);\n });\n ws.on(\"close\", () => {\n this.connected = false;\n this.connectPromise = null;\n for (const [, p] of this.pending) {\n clearTimeout(p.timer);\n p.reject(new Error(\"gateway connection closed\"));\n }\n this.pending.clear();\n });\n });\n }\n\n /** 发一个 Gateway RPC。 */\n async rpc(method: string, params: unknown, timeoutMs = 120000): Promise<Record<string, unknown>> {\n if (!this.connected) await this.connect();\n return new Promise((resolve, reject) => {\n const id = randomUUID();\n const timer = setTimeout(() => {\n this.pending.delete(id);\n reject(new Error(`RPC timeout: ${method}`));\n }, timeoutMs);\n this.pending.set(id, { resolve: resolve as (v: unknown) => void, reject, timer });\n this.ws!.send(JSON.stringify({ type: \"req\", id, method, params }));\n });\n }\n\n close(): void {\n this.ws?.close();\n this.ws = null;\n this.connected = false;\n }\n}\n","import type {\n AgentAdapter,\n AdapterSession,\n CreateSessionParams,\n SendOptions,\n} from \"../adapter.js\";\nimport type { AgentCapabilities, AgentDescriptor, StreamEvent, ContextItem, ModelInfo } from \"@agent-phonon/protocol\";\nimport { GatewayClient, type GatewayConfig } from \"../gateway-client.js\";\nimport { randomUUID } from \"node:crypto\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { dropToolIOFromJsonlFiles } from \"../custom-compress.js\";\n\n/**\n * OpenClaw adapter(Gateway WS 版,design D10)。\n *\n * 连 OpenClaw Gateway 的 WebSocket(参考 LMA 传输层),拿到完整能力:\n * - chat 事件 state=delta(增量流)→ verbosity=messages/trace 的流式\n * - chat 事件 state=final → turn 终态\n * - sessions.compact(原生压缩)、chat.abort(中断)、chat.inject(注入)\n * - sessions.messages.subscribe(订阅自发输出,cron/心跳冒泡)→ proactiveOutput\n *\n * 实测(2026-06-20,直连本机 Gateway 18789):\n * - 握手 client.id 必须是 \"gateway-client\"\n * - chat.send 必须带 idempotencyKey\n * - 多 agent 共享 Gateway,事件按 sessionKey 区分,不串台\n */\n\nconst CAPABILITIES: AgentCapabilities = {\n nativeSession: true,\n nativeCompression: true, // sessions.compact\n contextInjection: true, // chat.inject\n proactiveOutput: true, // sessions.messages.subscribe\n modelSwitch: true, // sessions.patch model\n interrupt: true, // chat.abort(真中断,非 kill 进程)\n injectMidTurn: false,\n skillManagement: true,\n hooks: [\"pre_tool\", \"pre_command\"],\n streaming: true, // chat delta\n limits: { maxConcurrentSessions: 4, maxContextTokens: 1048576 },\n};\n\nclass GatewaySession implements AdapterSession {\n readonly sessionId: string;\n model: string;\n private gw: GatewayClient;\n private sessionKey: string;\n private openclawAgent: string;\n /** 当前活动 turn 的 emit/runId 跟踪。 */\n private activeTurn?: { turnId: string; emit: (e: StreamEvent) => void; verbosity: string; done: () => void; acc: string };\n /** 自发输出水槽(无 active turn 时用,D16 unsolicited)。 */\n private unsolicitedSink?: (event: StreamEvent) => void;\n private unsolicitedSeq = 0;\n\n setUnsolicitedSink(sink: (event: StreamEvent) => void): void {\n this.unsolicitedSink = sink;\n }\n\n constructor(gw: GatewayClient, sessionId: string, model: string, openclawAgent: string) {\n this.gw = gw;\n this.sessionId = sessionId;\n this.model = model;\n this.openclawAgent = openclawAgent;\n this.sessionKey = `agent:${openclawAgent}:phonon-${sessionId}`;\n }\n\n get key(): string {\n return this.sessionKey;\n }\n\n /** 接收 Gateway 事件(由 adapter 路由进来,已按 sessionKey 过滤)。 */\n handleEvent(event: string, payload: Record<string, unknown>): void {\n const turn = this.activeTurn;\n const now = new Date().toISOString();\n\n if (event !== \"chat\") return;\n const state = payload.state as string;\n\n // 无 active turn 的 chat 输出 = 自发(D16 unsolicited):OpenClaw cron/定时/心跳(修 P0#7)\n if (!turn) {\n if (state === \"final\") {\n const text =\n (payload.message as { text?: string })?.text ?? (payload.finalText as string) ?? \"\";\n if (text && this.unsolicitedSink) {\n this.unsolicitedSink({\n type: \"message\",\n sessionId: this.sessionId,\n turnId: `u-${Date.now()}-${this.unsolicitedSeq++}`,\n origin: \"unsolicited\",\n source: (payload.source as string) ?? \"openclaw\",\n seq: 0,\n at: now,\n role: \"assistant\",\n text,\n delta: false,\n } as StreamEvent);\n }\n }\n return;\n }\n\n if (state === \"delta\") {\n const deltaText = payload.deltaText as string | undefined;\n if (deltaText) {\n turn.acc += deltaText;\n if (turn.verbosity === \"messages\" || turn.verbosity === \"tools\" || turn.verbosity === \"trace\") {\n turn.emit({\n type: \"message\", sessionId: this.sessionId, turnId: turn.turnId, seq: 0, at: now,\n role: \"assistant\", text: deltaText, delta: true,\n } as StreamEvent);\n }\n }\n } else if (state === \"final\") {\n // final 文本优先取 payload,没有则用累积的 delta\n const finalText =\n (payload.message as { text?: string })?.text ??\n (payload.finalText as string) ??\n turn.acc;\n turn.emit({\n type: \"result\", sessionId: this.sessionId, turnId: turn.turnId, seq: 0, at: now,\n text: finalText, status: \"completed\", final: true,\n } as StreamEvent);\n turn.done();\n this.activeTurn = undefined;\n }\n }\n\n async send(input: string, opts: SendOptions): Promise<void> {\n const { turnId, emit } = opts;\n let message = input;\n if (opts.skills && opts.skills.length > 0) {\n message = `[必须本轮加载并使用这些 skill: ${opts.skills.join(\", \")}]\\n\\n${input}`;\n }\n\n await new Promise<void>((resolve) => {\n let settled = false;\n const finish = () => {\n if (settled) return;\n settled = true;\n clearTimeout(guard);\n resolve();\n };\n this.activeTurn = { turnId, emit, verbosity: opts.verbosity, done: finish, acc: \"\" };\n this.gw\n .rpc(\"chat.send\", {\n sessionKey: this.sessionKey,\n message,\n deliver: false,\n idempotencyKey: randomUUID(),\n }, 1800000)\n .catch((err) => {\n emit({\n type: \"error\", sessionId: this.sessionId, turnId, seq: 0, at: new Date().toISOString(),\n message: (err as Error)?.message ?? \"chat.send failed\", status: \"failed\", final: true,\n } as StreamEvent);\n this.activeTurn = undefined;\n finish();\n });\n // 兜底超时:30 分钟没 final 就强制收尾\n const guard = setTimeout(() => {\n if (this.activeTurn?.turnId === turnId) {\n emit({\n type: \"result\", sessionId: this.sessionId, turnId, seq: 0, at: new Date().toISOString(),\n text: \"\", status: \"timeout\", final: true,\n } as StreamEvent);\n this.activeTurn = undefined;\n finish();\n }\n }, 1800000);\n });\n }\n\n async interrupt(): Promise<void> {\n await this.gw.rpc(\"chat.abort\", { sessionKey: this.sessionKey }, 5000).catch(() => {});\n }\n\n async switchModel(model: string): Promise<{ warnings?: string[] }> {\n this.model = model;\n await this.gw.rpc(\"sessions.patch\", { key: this.sessionKey, model }, 10000).catch(() => {});\n return {};\n }\n\n async inject(context: ContextItem[]): Promise<void> {\n if (context.length === 0) return;\n const message = context.map((c) => `[${c.role}] ${c.content}`).join(\"\\n\");\n await this.gw.rpc(\"chat.inject\", { sessionKey: this.sessionKey, message }, 10000).catch(() => {});\n }\n\n async compressCustom(strategy = \"dropToolIO\", options?: { keepRecentToolCalls?: number }): Promise<{ summary?: string; filesChanged?: number; recordsChanged?: number; blocksRemoved?: number; bytesBefore?: number; bytesAfter?: number; backups?: string[] }> {\n if (strategy !== \"dropToolIO\") throw new Error(`unsupported custom compression strategy: ${strategy}`);\n const file = this.resolveSessionFile();\n if (!file) throw new Error(`OpenClaw session file not found for ${this.sessionKey}`);\n const r = await dropToolIOFromJsonlFiles([file], options);\n return { summary: `dropToolIO removed ${r.blocksRemoved} tool blocks from ${r.filesChanged} files`, ...r };\n }\n\n async compressNative(): Promise<{ summary?: string }> {\n await this.gw.rpc(\"sessions.compact\", { key: this.sessionKey }, 600000).catch(() => {});\n return { summary: \"compacted via sessions.compact\" };\n }\n\n private resolveSessionFile(): string | undefined {\n const sessionsJson = join(homedir(), \".openclaw\", \"agents\", this.openclawAgent, \"sessions\", \"sessions.json\");\n try {\n if (existsSync(sessionsJson)) {\n const sessions = JSON.parse(readFileSync(sessionsJson, \"utf8\")) as Record<string, { sessionId?: string }>;\n const id = sessions[this.sessionKey]?.sessionId;\n if (id) {\n const p = join(homedir(), \".openclaw\", \"agents\", this.openclawAgent, \"sessions\", `${id}.jsonl`);\n if (existsSync(p)) return p;\n }\n }\n } catch {\n // fall through\n }\n return undefined;\n }\n\n async terminate(): Promise<void> {\n await this.interrupt();\n // 不删 transcript:留痕。仅停活动。\n }\n\n async describe(): Promise<{ contextWindow?: number; usedTokens?: number; compactions?: number }> {\n try {\n const d = await this.gw.rpc(\"sessions.describe\", { key: this.sessionKey }, 8000);\n const sess = (d.session ?? {}) as Record<string, unknown>;\n return {\n contextWindow: typeof sess.contextTokens === \"number\" ? sess.contextTokens : undefined,\n usedTokens: typeof sess.usedContextTokens === \"number\" ? sess.usedContextTokens : undefined,\n compactions: typeof sess.compactions === \"number\" ? sess.compactions : undefined,\n };\n } catch {\n return {};\n }\n }\n}\n\nexport class OpenClawGatewayAdapter implements AgentAdapter {\n readonly name = \"openclaw\";\n readonly capabilities = CAPABILITIES;\n private gw: GatewayClient;\n private defaultAgent: string;\n private sessions = new Map<string, GatewaySession>(); // sessionKey → session\n /** agentId(openclaw:sub) → workspace 路径(从 agents.list 缓存,用于 global skill 目录)。 */\n private workspaceCache = new Map<string, string>();\n\n constructor(opts: { gateway: GatewayConfig; defaultAgent?: string }) {\n this.gw = new GatewayClient(opts.gateway);\n this.defaultAgent = opts.defaultAgent ?? \"main\";\n // 路由 Gateway 事件到对应 session(按 sessionKey 过滤,不串台)\n this.gw.onEvent((event, payload) => {\n const sk = payload.sessionKey as string | undefined;\n if (!sk) return;\n const session = this.sessions.get(sk);\n session?.handleEvent(event, payload);\n });\n }\n\n async discoverAgents(): Promise<AgentDescriptor[]> {\n let connected = false;\n try {\n await this.gw.connect();\n connected = this.gw.isConnected();\n } catch {\n connected = false;\n }\n if (!connected) {\n return [\n {\n agentId: \"openclaw\" as AgentDescriptor[\"agentId\"],\n displayName: \"OpenClaw\",\n adapter: \"openclaw\",\n available: false,\n unavailableReason: \"OpenClaw Gateway not reachable\",\n models: [],\n capabilities: CAPABILITIES,\n scannedAt: new Date().toISOString(),\n },\n ];\n }\n\n // 枚举该 Gateway 下所有 OpenClaw agent(按 workspace 分)\n let subAgents: Array<{ id: string; workspace?: string; model?: { primary?: string } | string }> = [];\n try {\n const r = await this.gw.rpc(\"agents.list\", {}, 8000);\n subAgents = (r.agents as typeof subAgents) ?? [];\n } catch {\n subAgents = [{ id: this.defaultAgent }];\n }\n if (subAgents.length === 0) subAgents = [{ id: this.defaultAgent }];\n\n const now = new Date().toISOString();\n const gatewayModels = await this.listGatewayModels();\n return subAgents.map((a) => {\n if (a.workspace) this.workspaceCache.set(`openclaw:${a.id}`, a.workspace);\n const primaryModel =\n typeof a.model === \"string\" ? a.model : a.model?.primary;\n // 优先报 Gateway 的完整可用模型目录;拿不到时退回 agents.list 的 primary。\n const models = gatewayModels.length > 0 ? gatewayModels : (primaryModel ? [{ id: primaryModel, available: true }] : []);\n return {\n // 复合 agentId:openclaw:<subAgentId>(design D32)\n agentId: `openclaw:${a.id}` as AgentDescriptor[\"agentId\"],\n displayName: `OpenClaw / ${a.id}`,\n adapter: \"openclaw\",\n available: true,\n models,\n capabilities: CAPABILITIES,\n scannedAt: now,\n } satisfies AgentDescriptor;\n });\n }\n\n private async listGatewayModels(): Promise<ModelInfo[]> {\n try {\n const r = await this.gw.rpc(\"models.list\", { view: \"all\" }, 8000);\n const rows = Array.isArray(r.models) ? r.models as Array<Record<string, unknown>> : [];\n const models: ModelInfo[] = [];\n const seen = new Set<string>();\n for (const row of rows) {\n const id = typeof row.key === \"string\" ? row.key : (typeof row.id === \"string\" ? row.id : undefined);\n if (!id || seen.has(id)) continue;\n if (row.available === false || row.missing === true) continue;\n seen.add(id);\n const contextWindow = typeof row.contextWindow === \"number\"\n ? row.contextWindow\n : (typeof row.contextTokens === \"number\" ? row.contextTokens : undefined);\n models.push({\n id,\n ...(typeof row.name === \"string\" ? { displayName: row.name } : {}),\n ...(contextWindow && contextWindow > 0 ? { contextWindow } : {}),\n available: true,\n });\n }\n return models;\n } catch {\n return [];\n }\n }\n\n async createSession(params: CreateSessionParams): Promise<AdapterSession> {\n await this.gw.connect();\n // 从复合 agentId 解出 OpenClaw sub-agent:openclaw:phonon → phonon\n const subAgent =\n (params.agentConfig?.openclawAgent as string) ??\n (params.agentId.includes(\":\") ? params.agentId.split(\":\")[1]! : this.defaultAgent);\n const session = new GatewaySession(this.gw, params.sessionId, params.model, subAgent);\n // sessions.create 失败要外显(修 P0#6),不能静默吞\n try {\n await this.gw.rpc(\"sessions.create\", { key: session.key, model: params.model }, 15000);\n } catch (err) {\n throw new Error(`OpenClaw sessions.create failed: ${(err as Error)?.message ?? \"?\"}`);\n }\n // 订阅自发输出(proactiveOutput);订阅失败不致命,记警告即可\n await this.gw.rpc(\"sessions.messages.subscribe\", { key: session.key }, 10000).catch((e) => {\n console.warn(`[openclaw-gateway] subscribe failed for ${session.key}: ${(e as Error)?.message}`);\n });\n this.sessions.set(session.key, session);\n return session;\n }\n\n /** 关闭 Gateway 连接(daemon 退出时)。 */\n close(): void {\n this.gw.close();\n }\n\n /** OpenClaw 某 sub-agent 的 global skill 目录 = 该 agent workspace/skills。 */\n globalSkillDir(agentId: string): string | undefined {\n const ws = this.workspaceCache.get(agentId);\n return ws ? `${ws}/skills` : undefined;\n }\n}\n","import { WebSocket } from \"ws\";\nimport { PhononConnection } from \"./index.js\";\nimport { AdapterRegistry } from \"./session-engine.js\";\nimport { PROTOCOL_VERSION } from \"@agent-phonon/protocol\";\nimport type { RpcTransport } from \"./rpc.js\";\n\n/**\n * phonon 拨出客户端(design §6):主动连到一个 server URL。\n *\n * 真实场景:连你的 Azure 服务端。测试场景:连项目内 test-server。\n * 拨出后发 connect.hello,server 回 welcome(含 tenantId),随后由 PhononConnection 处理 session.*。\n */\nexport class PhononClient {\n private ws?: WebSocket;\n private conn?: PhononConnection;\n private registry: AdapterRegistry;\n private serverUrl: string;\n private deviceId: string;\n private deviceKey?: string;\n private resolveProjectCwd?: (project: string) => string;\n private trustLocal?: boolean;\n private dbPath?: string;\n private store?: import(\"./store.js\").PhononStore;\n private policy?: import(\"@agent-phonon/protocol\").TenantPolicy;\n private obs?: import(\"./observability.js\").ObsBus;\n private workspaceRoot?: string;\n private started = false;\n private backoffMs = 1000;\n private reconnectTimer?: ReturnType<typeof setTimeout>;\n\n constructor(opts: {\n serverUrl: string;\n deviceId: string;\n registry: AdapterRegistry;\n resolveProjectCwd?: (project: string) => string;\n /** 本地自用:放宽 policy(允许写操作 + 受控根为 allowedProjectRoots)。 */\n trustLocal?: boolean;\n workspaceRoot?: string;\n /** sqlite 文件路径(多连接可共享同一 store)。 */\n dbPath?: string;\n store?: import(\"./store.js\").PhononStore;\n /** 可选:policy 覆盖。 */\n policy?: import(\"@agent-phonon/protocol\").TenantPolicy;\n /** 可观测事件总线。 */\n obs?: import(\"./observability.js\").ObsBus;\n /** 设备鉴权 key(随 connect.hello 发送)。 */\n deviceKey?: string;\n }) {\n this.serverUrl = opts.serverUrl;\n this.deviceId = opts.deviceId;\n this.deviceKey = opts.deviceKey;\n this.registry = opts.registry;\n this.resolveProjectCwd = opts.resolveProjectCwd;\n this.trustLocal = opts.trustLocal;\n this.workspaceRoot = opts.workspaceRoot;\n this.dbPath = opts.dbPath;\n this.store = opts.store;\n this.policy = opts.policy;\n this.obs = opts.obs;\n }\n\n /** 连接并完成握手,resolve 后即可接收 server 的 session.* 下发。 */\n connect(): Promise<{ tenantId: string }> {\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(this.serverUrl);\n this.ws = ws;\n\n const transport: RpcTransport = {\n send: (data) => ws.send(data),\n close: () => ws.close(),\n };\n\n ws.on(\"open\", async () => {\n // 握手前先建连接处理器,但 tenantId 要等 welcome;先用占位,再在 welcome 后重建\n // 简化:先发 hello 作为一个 request,拿到 welcome.tenantId 后再建 PhononConnection。\n try {\n // 临时 peer 仅用于 hello/welcome\n const { RpcPeer } = await import(\"./rpc.js\");\n const tmpPeer = new RpcPeer(transport, () => {\n throw new Error(\"not ready\");\n });\n // 把 message 暂时喂给 tmpPeer\n const tmpListener = (raw: Buffer) => tmpPeer.handle(raw.toString());\n ws.on(\"message\", tmpListener);\n\n const welcome = (await tmpPeer.request(\"connect.hello\", {\n protocolVersion: PROTOCOL_VERSION,\n deviceId: this.deviceId as never,\n features: [],\n ...(this.deviceKey ? { auth: { deviceKey: this.deviceKey } } : {}),\n at: new Date().toISOString(),\n })) as { tenantId: string };\n\n // 切换到正式连接处理器\n ws.off(\"message\", tmpListener);\n const conn = new PhononConnection({\n tenantId: welcome.tenantId,\n transport,\n registry: this.registry,\n resolveProjectCwd: this.resolveProjectCwd,\n trustLocal: this.trustLocal,\n workspaceRoot: this.workspaceRoot,\n dbPath: this.dbPath,\n store: this.store,\n policy: this.policy,\n obs: this.obs,\n });\n this.conn = conn;\n ws.on(\"message\", (raw: Buffer) => conn.handle(raw.toString()));\n this.backoffMs = 1000; // 连上重置 backoff\n // 重连补发(D29):server welcome.ackedSeqs → resumeFrom\n const wAck = (welcome as { ackedSeqs?: Array<{ sessionId: string; lastSeq: number }> }).ackedSeqs;\n if (wAck && wAck.length > 0) {\n conn.replayPending(wAck.map((a) => ({ sessionId: a.sessionId, fromSeq: a.lastSeq })));\n }\n resolve({ tenantId: welcome.tenantId });\n } catch (err) {\n reject(err);\n }\n });\n\n ws.on(\"error\", (err) => {\n if (!this.started) reject(err);\n });\n ws.on(\"close\", () => {\n this.conn?.onClose();\n this.conn = undefined; // 清 conn,health 不误报 connected(修 B8)\n if (this.started) this.scheduleReconnect();\n });\n });\n }\n\n /**\n * 长期运行:连上后自动保持,断线指数退避重连(bug-bash P1)。\n * 首次连接失败也进重试(不抛)。\n */\n async start(): Promise<void> {\n this.started = true;\n try {\n await this.connect();\n } catch {\n this.scheduleReconnect();\n }\n }\n\n private scheduleReconnect(): void {\n if (!this.started || this.reconnectTimer) return;\n const delay = this.backoffMs;\n this.backoffMs = Math.min(this.backoffMs * 2, 30000); // 上限 30s\n this.reconnectTimer = setTimeout(async () => {\n this.reconnectTimer = undefined;\n try {\n await this.connect();\n } catch {\n this.scheduleReconnect();\n }\n }, delay);\n }\n\n close(): void {\n this.started = false; // 停止重连\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n this.ws?.close();\n }\n\n /** 本连接的 PhononConnection(HookBridge 路由用)。 */\n get connection(): PhononConnection | undefined {\n return this.conn;\n }\n}\n","import { createServer, type Server } from \"node:http\";\nimport type { PhononConnection } from \"./index.js\";\n\n/**\n * HITL Bridge(design §8 / B 阶段)。\n *\n * phonon-core 起一个本地 HTTP 端点,给 OpenClaw plugin 调:\n * plugin before_tool_call → POST /hook/before_tool_call { sessionKey, toolName, params }\n * → bridge 找到该 sessionKey 对应的 PhononConnection(tenant)\n * → conn.fireHook(...) 发 hook.fired 给 server,阻塞等 server 的 hook.resolve(= RPC 响应)\n * ← server 裁决\n * ← bridge 返回 decision 给 plugin\n *\n * server 的 hook.resolve 裁决直接作为 hook.fired 的 RPC 响应回来(hook.fired 是 request)。\n * 这样 plugin↔core↔server 三段阻塞链打通,HITL 闭环。\n */\n\n/** sessionKey → 该 session 所属连接 + phonon sessionId 的解析器。 */\nexport type HookRouteResolver = (sessionKey: string) => { conn: PhononConnection; sessionId: string } | undefined;\n\nexport class HookBridge {\n private server?: Server;\n private resolveRoute: HookRouteResolver;\n private hookSeq = 1;\n /** 可选本地鉴权 token(P1):plugin 请求需带 Authorization: Bearer <token>。 */\n private token?: string;\n\n constructor(resolveRoute: HookRouteResolver, opts?: { token?: string }) {\n this.resolveRoute = resolveRoute;\n this.token = opts?.token;\n }\n\n listen(port = 4318, host = \"127.0.0.1\"): Promise<number> {\n return new Promise((resolve) => {\n const server = createServer((req, res) => this.onRequest(req, res));\n this.server = server;\n server.listen(port, host, () => {\n const addr = server.address();\n resolve(typeof addr === \"object\" && addr ? addr.port : port);\n });\n });\n }\n\n private async onRequest(\n req: import(\"node:http\").IncomingMessage,\n res: import(\"node:http\").ServerResponse,\n ): Promise<void> {\n if (req.method !== \"POST\" || !req.url?.startsWith(\"/hook/\")) {\n res.writeHead(404).end();\n return;\n }\n // 本地鉴权(P1):配了 token 则验 Authorization: Bearer\n if (this.token) {\n const auth = req.headers[\"authorization\"];\n if (auth !== `Bearer ${this.token}`) {\n res.writeHead(401, { \"content-type\": \"application/json\" }).end(JSON.stringify({ action: \"continue\", reason: \"unauthorized\" }));\n return;\n }\n }\n // 去掉 query string(修 P2#18)\n const hookType = req.url.slice(\"/hook/\".length).split(\"?\")[0]!; // e.g. before_tool_call\n let body = \"\";\n req.on(\"data\", (c) => (body += c));\n req.on(\"end\", async () => {\n let payload: { sessionKey?: string; toolName?: string; params?: unknown };\n try {\n payload = JSON.parse(body);\n } catch {\n res.writeHead(400).end(JSON.stringify({ action: \"continue\", reason: \"bad json\" }));\n return;\n }\n const sessionKey = payload.sessionKey;\n const route = sessionKey ? this.resolveRoute(sessionKey) : undefined;\n if (!route) {\n // 未知 session → fail-open 放行\n res.writeHead(200, { \"content-type\": \"application/json\" }).end(JSON.stringify({ action: \"continue\" }));\n return;\n }\n try {\n // 发 hook.fired 给 server,阻塞等裁决(hook.fired 是 request,响应即裁决)\n const decision = (await route.conn.fireHook({\n sessionId: route.sessionId,\n hookId: `h-${Date.now()}-${this.hookSeq++}`,\n hookType: mapHookType(hookType),\n payload: {\n toolName: payload.toolName,\n command: typeof payload.params === \"object\" && payload.params ? (payload.params as { command?: string }).command : undefined,\n extra: payload.params as Record<string, unknown> | undefined,\n },\n at: new Date().toISOString(),\n })) as { action?: string; reason?: string; patch?: Record<string, unknown> };\n\n // server 的 hook.resolve 结果 → bridge decision(保留 applied 等)\n const action = (decision?.action as string) ?? \"continue\";\n res.writeHead(200, { \"content-type\": \"application/json\" }).end(\n JSON.stringify({ action, reason: decision?.reason, patch: decision?.patch }),\n );\n } catch (err) {\n // server 不裁决/超时 → fail-open\n res.writeHead(200, { \"content-type\": \"application/json\" }).end(\n JSON.stringify({ action: \"continue\", reason: `bridge error: ${(err as Error)?.message ?? \"?\"}` }),\n );\n }\n });\n }\n\n close(): Promise<void> {\n return new Promise((resolve) => {\n if (!this.server) return resolve();\n this.server.close(() => resolve());\n });\n }\n}\n\n/** OpenClaw hook 名 → phonon 归一化 HookType。 */\nfunction mapHookType(openclawHook: string): string {\n switch (openclawHook) {\n case \"before_tool_call\":\n return \"pre_tool\";\n case \"before_command\":\n return \"pre_command\";\n default:\n return \"pre_tool\";\n }\n}\n","import { DatabaseSync } from \"node:sqlite\";\nimport { existsSync, statSync, rmSync } from \"node:fs\";\n\nexport interface SqliteDropResult {\n filesChanged: number;\n recordsChanged: number;\n blocksRemoved: number;\n bytesBefore: number;\n bytesAfter: number;\n backups: string[];\n}\n\nexport interface SqliteRow {\n /** 行主键(用于 mutateRow 定位)。 */\n id: string | number;\n /** 是否属于「工具行」(参与裁剪)。 */\n isTool: boolean;\n /**\n * 是否是「工具调用锚点」行(用于 keep-recent 计数)。\n * 不传则退化为 isTool。Hermes 里一次调用跨两行(assistant 带 tool_calls + role=tool 结果),\n * 只有 assistant-带-tool_calls 才是锚点,避免把「保留最近 1 次调用」误算成只留结果行。\n */\n isToolCall?: boolean;\n /** 透传给 mutateRow 的任意附加字段(如 role,让 adapter 决定删行还是清列)。 */\n [k: string]: unknown;\n}\n\n/**\n * 通用「按行裁剪工具 IO」的 sqlite 压缩器,给 OpenCode / Hermes 这类把会话存进\n * sqlite 的 runtime 用。语义与 dropToolIOFromJsonlFiles 对齐:\n * - 只动「工具行」(isTool=true),纯文本/推理/普通消息行不碰\n * - 保留最近 keepRecentToolCalls 个工具行(position-based,与 item 3 一致)\n * - 旧工具行交给 mutateRow 处理:可整行删除,也可只清空工具相关列(保留同行的正文)\n *\n * 安全要点:\n * - 用 `VACUUM INTO` 生成一致性备份(正确处理 WAL;file copy 会漏掉 -wal)\n * - busy_timeout 等锁而非立刻失败(state.db 可能被 agent 进程并发持有)\n * - 改动包在 IMMEDIATE 事务里,失败回滚\n * - 不对主库做 VACUUM(独占锁、对热库不安全);改用 best-effort wal_checkpoint\n */\nexport async function dropToolIORowsSqlite(opts: {\n dbPath: string;\n selectRows: (db: DatabaseSync) => SqliteRow[];\n /** 处理一条需要裁剪的旧工具行:删除整行或清空工具列。 */\n mutateRow: (db: DatabaseSync, row: SqliteRow) => void;\n keepRecentToolCalls?: number;\n}): Promise<SqliteDropResult> {\n const { dbPath } = opts;\n const result: SqliteDropResult = { filesChanged: 0, recordsChanged: 0, blocksRemoved: 0, bytesBefore: 0, bytesAfter: 0, backups: [] };\n if (!existsSync(dbPath)) throw new Error(`sqlite session db not found: ${dbPath}`);\n const keepRecent = opts.keepRecentToolCalls ?? 3;\n const before = fileSize(dbPath);\n const stamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const backup = `${dbPath}.bak-${stamp}`;\n\n const db = new DatabaseSync(dbPath);\n try {\n db.exec(\"PRAGMA busy_timeout = 5000;\");\n db.exec(\"PRAGMA foreign_keys = ON;\");\n\n const rows = opts.selectRows(db);\n const toolIdx: number[] = [];\n const callIdx: number[] = [];\n rows.forEach((r, i) => {\n if (r.isTool) toolIdx.push(i);\n if (r.isToolCall ?? r.isTool) callIdx.push(i);\n });\n if (toolIdx.length === 0) {\n result.bytesBefore = before;\n result.bytesAfter = before;\n return result; // 无工具行可裁,不备份、不改动\n }\n\n // 一致性备份(含 WAL 状态)。VACUUM INTO 要求目标文件不存在。\n db.exec(`VACUUM INTO '${backup.replace(/'/g, \"''\")}'`);\n result.backups.push(backup);\n\n // keep-recent 锚定在「工具调用」行上:保留最近 N 次调用起的所有工具行。\n const keepFromIndex = keepRecent > 0 && callIdx.length > 0\n ? callIdx[Math.max(0, callIdx.length - keepRecent)]!\n : (keepRecent > 0 ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY);\n\n db.exec(\"BEGIN IMMEDIATE\");\n let removed = 0;\n try {\n for (let i = 0; i < rows.length; i++) {\n const r = rows[i]!;\n if (!r.isTool) continue;\n if (i >= keepFromIndex) continue; // 最近的工具行保留\n opts.mutateRow(db, r);\n removed++;\n }\n db.exec(\"COMMIT\");\n } catch (e) {\n db.exec(\"ROLLBACK\");\n throw e;\n }\n // 热库不做主库 VACUUM(独占锁);best-effort 把 WAL 落盘。\n try { db.exec(\"PRAGMA wal_checkpoint(TRUNCATE);\"); } catch { /* best-effort */ }\n\n result.blocksRemoved = removed;\n result.recordsChanged = removed;\n result.filesChanged = removed > 0 ? 1 : 0;\n result.bytesBefore = before;\n if (removed === 0) {\n // 没实际改动:删掉刚生成的备份,保持干净。\n try { rmSync(backup, { force: true }); } catch { /* ignore */ }\n result.backups = [];\n }\n return result;\n } finally {\n try { db.close(); } catch { /* ignore */ }\n result.bytesAfter = fileSize(dbPath);\n }\n}\n\nfunction fileSize(p: string): number {\n try { return statSync(p).size; } catch { return 0; }\n}\n","import { spawn } from \"node:child_process\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { existsSync, readdirSync, statSync } from \"node:fs\";\nimport { dropToolIOFromJsonlFiles } from \"../custom-compress.js\";\nimport type {\n AgentAdapter,\n AdapterSession,\n CreateSessionParams,\n SendOptions,\n} from \"../adapter.js\";\nimport type { AgentCapabilities, AgentDescriptor, StreamEvent, ContextItem, ModelInfo } from \"@agent-phonon/protocol\";\n\n/**\n * Codex adapter(design D10,单 agent runtime)。\n *\n * 调用(详见 docs/agent-cli-integration.md):\n * codex exec - --json -c model_provider=<id> -c model_providers.<id>.base_url=...\n * -c model_providers.<id>.wire_api=responses --model X\n * --dangerously-bypass-approvals-and-sandbox\n * prompt 走 stdin(argv 用 \"-\");resume:codex exec resume <thread_id> - --json ...\n *\n * 网关由调用方通过 CodexEnv 传入(baseUrl/apiKey/wireApi),adapter 不绑定任何特定网关;\n * 用 -c 临时覆盖 provider(不动用户的 ~/.codex/config.toml)。\n */\n\nconst CAPABILITIES: AgentCapabilities = {\n nativeSession: true, // exec resume <thread_id>\n nativeCompression: false,\n contextInjection: true, // 拼进下轮 prompt\n proactiveOutput: false,\n modelSwitch: true,\n interrupt: true, // kill\n injectMidTurn: false,\n skillManagement: false,\n hooks: [\"pre_command\"],\n streaming: true, // --json 事件流\n limits: { maxConcurrentSessions: 4 },\n};\n\n/**\n * 定位 Codex rollout 会话文件。\n * 文件名形如 sessions/YYYY/MM/DD/rollout-<ts>-<thread_id>.jsonl,后缀 uuid == thread_id。\n * 取匹配 thread_id 里 mtime 最新的一个(同 thread 可能跨多次 exec resume)。\n */\nexport function resolveCodexSessionFile(threadId: string, codexHome = join(homedir(), \".codex\")): string | undefined {\n const root = join(codexHome, \"sessions\");\n if (!existsSync(root)) return undefined;\n const hits: Array<{ path: string; mtime: number }> = [];\n const walk = (dir: string): void => {\n let names: string[];\n try { names = readdirSync(dir); } catch { return; }\n for (const name of names) {\n const full = join(dir, name);\n let st;\n try { st = statSync(full); } catch { continue; }\n if (st.isDirectory()) walk(full);\n else if (name.endsWith(`-${threadId}.jsonl`)) hits.push({ path: full, mtime: st.mtimeMs });\n }\n };\n walk(root);\n if (hits.length === 0) return undefined;\n hits.sort((a, b) => b.mtime - a.mtime);\n return hits[0]!.path;\n}\n\nexport interface CodexEnv {\n /** Codex executable path. Prefer an absolute path when running under systemd/launchd. */\n binPath?: string;\n /** Optional OpenAI-compatible endpoint override. Omit to use the user's native Codex config. */\n baseUrl?: string;\n /** Optional API key for baseUrl. Omit to use the user's native Codex config. */\n apiKey?: string;\n /** `default` means let Codex use the user's configured default. */\n defaultModel: string;\n /** 可选:由用户配置/上层配置发现到的真实可用模型。 */\n models?: ModelInfo[];\n /** wire_api:responses 或 chat(取决于网关/模型支持)。 */\n wireApi?: \"responses\" | \"chat\";\n /** -c model_provider 的 provider id(中性默认)。 */\n providerId?: string;\n /** provider 显示名(默认 phonon-gateway)。 */\n providerName?: string;\n}\n\nclass CodexSession implements AdapterSession {\n readonly sessionId: string;\n model: string;\n private cwd: string;\n private env: CodexEnv;\n private threadId?: string; // Codex thread_id(= 会话),从 thread.started 抓\n private current?: ReturnType<typeof spawn>;\n private pendingInject: string[] = [];\n\n constructor(sessionId: string, model: string, cwd: string, env: CodexEnv) {\n this.sessionId = sessionId;\n this.model = model;\n this.cwd = cwd;\n this.env = env;\n }\n\n private providerArgs(): string[] {\n if (!this.env.baseUrl || !this.env.apiKey) return [];\n const id = this.env.providerId ?? \"phonon_gateway\";\n const name = this.env.providerName ?? \"phonon-gateway\";\n return [\n \"-c\", `model_provider=${id}`,\n \"-c\", `model_providers.${id}.name=${name}`,\n \"-c\", `model_providers.${id}.base_url=${this.env.baseUrl}`,\n \"-c\", `model_providers.${id}.wire_api=${this.env.wireApi ?? \"responses\"}`,\n \"-c\", `model_providers.${id}.env_key=OPENAI_API_KEY`,\n ];\n }\n\n async send(input: string, opts: SendOptions): Promise<void> {\n const { turnId, emit } = opts;\n let prompt = input;\n if (this.pendingInject.length > 0) {\n prompt = this.pendingInject.join(\"\\n\") + \"\\n\\n\" + prompt;\n this.pendingInject = [];\n }\n if (opts.skills && opts.skills.length > 0) {\n prompt = `[本轮请使用这些能力: ${opts.skills.join(\", \")}]\\n\\n${prompt}`;\n }\n\n const args = this.threadId\n ? [\"exec\", \"resume\", this.threadId, \"-\", \"--json\", ...this.providerArgs(), ...(this.model !== \"default\" ? [\"--model\", this.model] : []), \"--dangerously-bypass-approvals-and-sandbox\"]\n : [\"exec\", \"-\", \"--json\", ...this.providerArgs(), ...(this.model !== \"default\" ? [\"--model\", this.model] : []), \"--dangerously-bypass-approvals-and-sandbox\"];\n\n await this.run(args, prompt, turnId, emit, opts);\n }\n\n private run(args: string[], stdin: string, turnId: string, emit: (e: StreamEvent) => void, opts: SendOptions): Promise<void> {\n return new Promise((resolve) => {\n const child = spawn(this.env.binPath ?? \"codex\", args, {\n cwd: this.cwd,\n shell: process.platform === \"win32\",\n env: { ...process.env, ...(opts.environment ?? {}), ...(this.env.apiKey ? { OPENAI_API_KEY: this.env.apiKey } : {}) } as NodeJS.ProcessEnv,\n });\n this.current = child;\n let buf = \"\";\n let acc = \"\";\n let settled = false;\n const finish = (status: \"completed\" | \"failed\" | \"interrupted\" | \"timeout\", text: string, message?: string) => {\n if (settled) return;\n settled = true;\n clearTimeout(guard);\n this.current = undefined;\n if (status === \"failed\") {\n emit({ type: \"error\", sessionId: this.sessionId, turnId, seq: 0, at: new Date().toISOString(), message: message ?? \"codex failed\", status: \"failed\", final: true } as StreamEvent);\n } else {\n emit({ type: \"result\", sessionId: this.sessionId, turnId, seq: 0, at: new Date().toISOString(), text, status, final: true } as StreamEvent);\n }\n resolve();\n };\n const guard = setTimeout(() => finish(\"timeout\", acc), 1800000);\n opts.signal?.addEventListener(\"abort\", () => { child.kill(\"SIGTERM\"); finish(\"interrupted\", acc); }, { once: true });\n\n child.stdout.on(\"data\", (d) => {\n buf += d.toString();\n let nl;\n while ((nl = buf.indexOf(\"\\n\")) >= 0) {\n const line = buf.slice(0, nl).trim();\n buf = buf.slice(nl + 1);\n if (!line) continue;\n let ev: Record<string, unknown>;\n try { ev = JSON.parse(line); } catch { continue; }\n this.handleEvent(ev, turnId, emit, (t) => (acc += t));\n }\n });\n child.on(\"error\", (e) => finish(\"failed\", \"\", e.message));\n child.on(\"close\", (code) => {\n if (settled) return;\n finish(code === 0 ? \"completed\" : \"failed\", acc, code !== 0 ? `codex exited ${code}` : undefined);\n });\n\n child.stdin.write(stdin);\n child.stdin.end();\n });\n }\n\n /** 解析 Codex JSON 事件流 → phonon StreamEvent。 */\n private handleEvent(ev: Record<string, unknown>, turnId: string, emit: (e: StreamEvent) => void, addText: (t: string) => void): void {\n const now = new Date().toISOString();\n const type = ev.type as string;\n if (type === \"thread.started\") {\n this.threadId = ev.thread_id as string; // 记录会话 id 供 resume\n } else if (type === \"item.completed\") {\n const item = ev.item as { type?: string; text?: string; name?: string; command?: string } | undefined;\n if (item?.type === \"agent_message\" && typeof item.text === \"string\") {\n addText(item.text);\n emit({ type: \"message\", sessionId: this.sessionId, turnId, seq: 0, at: now, role: \"assistant\", text: item.text, delta: true } as StreamEvent);\n } else if (item?.type === \"command_execution\") {\n emit({ type: \"tool_call\", sessionId: this.sessionId, turnId, seq: 0, at: now, toolName: \"command_execution\", args: { command: item.command } } as StreamEvent);\n }\n }\n // turn.completed 由 close 收尾\n }\n\n async interrupt(): Promise<void> {\n if (this.current) { this.current.kill(\"SIGTERM\"); this.current = undefined; }\n }\n async switchModel(model: string): Promise<{ warnings?: string[] }> { this.model = model; return {}; }\n async inject(context: ContextItem[]): Promise<void> {\n for (const c of context) this.pendingInject.push(`[${c.role}] ${c.content}`);\n }\n\n /**\n * 自定义压缩(dropToolIO):编辑 Codex rollout JSONL,删掉旧的 function_call /\n * function_call_output 等工具记录,保留 message/reasoning 等文本,默认保留最近 3 个工具调用。\n */\n async compressCustom(strategy = \"dropToolIO\", options?: { keepRecentToolCalls?: number }): Promise<{ summary?: string; filesChanged?: number; recordsChanged?: number; blocksRemoved?: number; bytesBefore?: number; bytesAfter?: number; backups?: string[] }> {\n if (strategy !== \"dropToolIO\") throw new Error(`unsupported custom compression strategy: ${strategy}`);\n if (!this.threadId) throw new Error(\"Codex session has no thread_id yet (no turn run); nothing to compress\");\n const file = resolveCodexSessionFile(this.threadId);\n if (!file) throw new Error(`Codex rollout file not found for thread ${this.threadId}`);\n const r = await dropToolIOFromJsonlFiles([file], options);\n return { summary: `dropToolIO removed ${r.blocksRemoved} tool records from Codex rollout`, ...r };\n }\n\n async terminate(): Promise<void> { await this.interrupt(); }\n}\n\nexport class CodexAdapter implements AgentAdapter {\n readonly name = \"codex\";\n readonly capabilities = CAPABILITIES;\n private env: CodexEnv;\n\n constructor(opts: { env: CodexEnv }) {\n this.env = opts.env;\n }\n\n async discoverAgents(): Promise<AgentDescriptor[]> {\n const version = await this.probeVersion();\n const available = version !== null;\n return [{\n agentId: \"codex\" as AgentDescriptor[\"agentId\"],\n displayName: \"Codex\",\n adapter: \"codex\",\n available,\n ...(available ? {} : { unavailableReason: \"codex CLI not found\" }),\n ...(version ? { version } : {}),\n models: this.env.models?.length\n ? this.env.models\n : [{ id: this.env.defaultModel, available: true }],\n capabilities: CAPABILITIES,\n scannedAt: new Date().toISOString(),\n }];\n }\n\n async createSession(params: CreateSessionParams): Promise<AdapterSession> {\n return new CodexSession(params.sessionId, params.model, params.cwd, this.env);\n }\n\n private probeVersion(): Promise<string | null> {\n return new Promise((resolve) => {\n const child = spawn(this.env.binPath ?? \"codex\", [\"--version\"], { shell: process.platform === \"win32\" });\n let out = \"\";\n child.stdout.on(\"data\", (d) => (out += d.toString()));\n child.on(\"error\", () => resolve(null));\n child.on(\"close\", (code) => resolve(code === 0 ? out.trim() : null));\n });\n }\n}\n","import { spawn } from \"node:child_process\";\nimport { DatabaseSync } from \"node:sqlite\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { dropToolIORowsSqlite } from \"../sqlite-compress.js\";\nimport type {\n AgentAdapter,\n AdapterSession,\n CreateSessionParams,\n SendOptions,\n} from \"../adapter.js\";\nimport type { AgentCapabilities, AgentDescriptor, StreamEvent, ContextItem } from \"@agent-phonon/protocol\";\n\n/**\n * OpenCode adapter(design D10,单 agent runtime)。\n *\n * 调用:`opencode run <message> --format json [-m provider/model] [-s <sessionID>]`。\n * --format json 输出 raw JSON 事件流(step_start / text / tool 等,每事件带 sessionID)。\n * session 用 OpenCode 返回的 ses_ id,后续 -s 恢复。\n *\n * 方案 A:用 OpenCode 现有 provider 配置(opencode.json)。model 由 config/调用方传。\n * binary 路径可配(默认探测 ~/.opencode/bin/opencode 或 PATH)。\n */\n\nconst CAPABILITIES: AgentCapabilities = {\n nativeSession: true, // -s <sessionID> / -c continue\n nativeCompression: false,\n contextInjection: true,\n proactiveOutput: false,\n modelSwitch: true, // -m\n interrupt: true,\n injectMidTurn: false,\n skillManagement: false,\n hooks: [\"pre_command\"],\n streaming: true, // --format json 事件流\n limits: { maxConcurrentSessions: 4 },\n};\n\nexport interface OpenCodeEnv {\n /** opencode binary 路径(默认探测)。 */\n binPath?: string;\n /** 默认模型(provider/model 格式,如 opencode/deepseek-v4-flash-free)。 */\n defaultModel?: string;\n}\n\nfunction resolveBin(configured?: string): string {\n if (configured) return configured;\n const standard = join(homedir(), \".opencode\", \"bin\", \"opencode\");\n if (existsSync(standard)) return standard;\n return \"opencode\"; // PATH\n}\n\n/** OpenCode 会话库路径(part 表存消息块)。 */\nexport function resolveOpenCodeDbPath(): string {\n const xdg = process.env.XDG_DATA_HOME;\n const base = xdg ? join(xdg, \"opencode\") : join(homedir(), \".local\", \"share\", \"opencode\");\n return join(base, \"opencode.db\");\n}\n\nclass OpenCodeSession implements AdapterSession {\n readonly sessionId: string;\n model: string;\n private cwd: string;\n private bin: string;\n private ocSessionId?: string; // OpenCode ses_ id(从事件抓,供 -s resume)\n private current?: ReturnType<typeof spawn>;\n private pendingInject: string[] = [];\n\n constructor(sessionId: string, model: string, cwd: string, bin: string) {\n this.sessionId = sessionId;\n this.model = model;\n this.cwd = cwd;\n this.bin = bin;\n }\n\n async send(input: string, opts: SendOptions): Promise<void> {\n const { turnId, emit } = opts;\n let message = input;\n if (this.pendingInject.length > 0) {\n message = this.pendingInject.join(\"\\n\") + \"\\n\\n\" + message;\n this.pendingInject = [];\n }\n if (opts.skills && opts.skills.length > 0) {\n message = `[本轮请使用这些能力: ${opts.skills.join(\", \")}]\\n\\n${message}`;\n }\n\n const args = [\"run\", \"--format\", \"json\", \"--dangerously-skip-permissions\"];\n if (this.model) args.push(\"--model\", this.model);\n if (this.ocSessionId) args.push(\"--session\", this.ocSessionId); // 持续会话\n args.push(message); // prompt 作为位置参数放最后\n\n await this.run(args, turnId, emit, opts);\n }\n\n private run(args: string[], turnId: string, emit: (e: StreamEvent) => void, opts: SendOptions): Promise<void> {\n return new Promise((resolve) => {\n // 关键:stdin 设 ignore(=DEVNULL),否则 OpenCode 检测到 stdin pipe 会等交互输入卡死\n const child = spawn(this.bin, args, { cwd: this.cwd, stdio: [\"ignore\", \"pipe\", \"pipe\"], env: { ...process.env, ...(opts.environment ?? {}) } as NodeJS.ProcessEnv });\n this.current = child;\n let buf = \"\";\n let acc = \"\";\n let settled = false;\n const finish = (status: \"completed\" | \"failed\" | \"interrupted\" | \"timeout\", text: string, message?: string) => {\n if (settled) return;\n settled = true;\n clearTimeout(guard);\n this.current = undefined;\n if (status === \"failed\") {\n emit({ type: \"error\", sessionId: this.sessionId, turnId, seq: 0, at: new Date().toISOString(), message: message ?? \"opencode failed\", status: \"failed\", final: true } as StreamEvent);\n } else {\n emit({ type: \"result\", sessionId: this.sessionId, turnId, seq: 0, at: new Date().toISOString(), text, status, final: true } as StreamEvent);\n }\n resolve();\n };\n const guard = setTimeout(() => finish(\"timeout\", acc), 1800000);\n opts.signal?.addEventListener(\"abort\", () => { child.kill(\"SIGTERM\"); finish(\"interrupted\", acc); }, { once: true });\n\n child.stdout.on(\"data\", (d) => {\n buf += d.toString();\n let nl;\n while ((nl = buf.indexOf(\"\\n\")) >= 0) {\n const line = buf.slice(0, nl).trim();\n buf = buf.slice(nl + 1);\n if (!line) continue;\n let ev: Record<string, unknown>;\n try { ev = JSON.parse(line); } catch { continue; }\n this.handleEvent(ev, turnId, emit, (t) => (acc += t));\n }\n });\n child.on(\"error\", (e) => finish(\"failed\", \"\", e.message));\n child.on(\"close\", (code) => {\n if (settled) return;\n finish(code === 0 ? \"completed\" : \"failed\", acc, code !== 0 ? `opencode exited ${code}` : undefined);\n });\n });\n }\n\n /** 解析 OpenCode JSON 事件 → phonon StreamEvent。 */\n private handleEvent(ev: Record<string, unknown>, turnId: string, emit: (e: StreamEvent) => void, addText: (t: string) => void): void {\n const now = new Date().toISOString();\n const type = ev.type as string;\n // 记录 OpenCode session id(首次出现)供 resume\n const sid = ev.sessionID as string | undefined;\n if (sid && !this.ocSessionId) this.ocSessionId = sid;\n\n const part = ev.part as Record<string, unknown> | undefined;\n if (type === \"text\" && typeof part?.text === \"string\") {\n addText(part.text);\n emit({ type: \"message\", sessionId: this.sessionId, turnId, seq: 0, at: now, role: \"assistant\", text: part.text, delta: true } as StreamEvent);\n } else if (type === \"tool\" || type === \"tool_use\") {\n emit({ type: \"tool_call\", sessionId: this.sessionId, turnId, seq: 0, at: now, toolName: String(part?.tool ?? part?.name ?? \"?\"), args: part?.input } as StreamEvent);\n } else if (type === \"error\") {\n const err = ev.error as { data?: { message?: string }; name?: string } | undefined;\n const msg = err?.data?.message ?? err?.name ?? \"opencode error\";\n // 中间 error 事件(非终态)当作 message 上报;真正终态由 close 统一处理\n emit({ type: \"message\", sessionId: this.sessionId, turnId, seq: 0, at: now, role: \"system\", text: `[error] ${msg}`, delta: false } as StreamEvent);\n addText(`[error] ${msg}`);\n }\n }\n\n async interrupt(): Promise<void> {\n if (this.current) { this.current.kill(\"SIGTERM\"); this.current = undefined; }\n }\n async switchModel(model: string): Promise<{ warnings?: string[] }> { this.model = model; return {}; }\n async inject(context: ContextItem[]): Promise<void> {\n for (const c of context) this.pendingInject.push(`[${c.role}] ${c.content}`);\n }\n\n /**\n * 自定义压缩(dropToolIO):在 OpenCode 的 opencode.db 里删本 session 旧的 type='tool'\n * part 行,保留 text/reasoning/step 等文本,默认保留最近 3 个工具调用。\n * 改动前整库备份。\n */\n async compressCustom(strategy = \"dropToolIO\", options?: { keepRecentToolCalls?: number }): Promise<{ summary?: string; filesChanged?: number; recordsChanged?: number; blocksRemoved?: number; bytesBefore?: number; bytesAfter?: number; backups?: string[] }> {\n if (strategy !== \"dropToolIO\") throw new Error(`unsupported custom compression strategy: ${strategy}`);\n if (!this.ocSessionId) throw new Error(\"OpenCode session id unknown yet (no turn run); nothing to compress\");\n const dbPath = resolveOpenCodeDbPath();\n const sid = this.ocSessionId;\n const r = await dropToolIORowsSqlite({\n dbPath,\n keepRecentToolCalls: options?.keepRecentToolCalls,\n selectRows: (db: DatabaseSync) => {\n const rows = db.prepare(\"SELECT id, data FROM part WHERE session_id = ? ORDER BY time_created ASC, id ASC\").all(sid) as Array<{ id: string; data: string }>;\n return rows.map((row) => {\n let type = \"\";\n try { type = (JSON.parse(row.data) as { type?: string }).type ?? \"\"; } catch { /* ignore */ }\n return { id: row.id, isTool: type === \"tool\" };\n });\n },\n mutateRow: (db: DatabaseSync, row: { id: string | number }) => { db.prepare(\"DELETE FROM part WHERE id = ?\").run(row.id); },\n });\n return { summary: `dropToolIO removed ${r.blocksRemoved} tool parts from OpenCode session ${sid}`, ...r };\n }\n\n async terminate(): Promise<void> { await this.interrupt(); }\n}\n\nexport class OpenCodeAdapter implements AgentAdapter {\n readonly name = \"opencode\";\n readonly capabilities = CAPABILITIES;\n private bin: string;\n private defaultModel?: string;\n\n constructor(opts: { env?: OpenCodeEnv } = {}) {\n this.bin = resolveBin(opts.env?.binPath);\n this.defaultModel = opts.env?.defaultModel;\n }\n\n async discoverAgents(): Promise<AgentDescriptor[]> {\n const version = await this.probeVersion();\n const available = version !== null;\n return [{\n agentId: \"opencode\" as AgentDescriptor[\"agentId\"],\n displayName: \"OpenCode\",\n adapter: \"opencode\",\n available,\n ...(available ? {} : { unavailableReason: \"opencode CLI not found\" }),\n ...(version ? { version } : {}),\n models: this.defaultModel\n ? [{ id: this.defaultModel, available: true }]\n : [{ id: \"default\", displayName: \"OpenCode default (from config)\", available: true }],\n capabilities: CAPABILITIES,\n scannedAt: new Date().toISOString(),\n }];\n }\n\n async createSession(params: CreateSessionParams): Promise<AdapterSession> {\n const model = params.model && params.model !== \"default\" ? params.model : (this.defaultModel ?? \"\");\n return new OpenCodeSession(params.sessionId, model, params.cwd, this.bin);\n }\n\n private probeVersion(): Promise<string | null> {\n return new Promise((resolve) => {\n const child = spawn(this.bin, [\"--version\"]);\n let out = \"\";\n child.stdout.on(\"data\", (d) => (out += d.toString()));\n child.on(\"error\", () => resolve(null));\n child.on(\"close\", (code) => resolve(code === 0 ? out.trim() : null));\n });\n }\n}\n","import { spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { DatabaseSync } from \"node:sqlite\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { dropToolIORowsSqlite } from \"../sqlite-compress.js\";\nimport type {\n AgentAdapter,\n AdapterSession,\n CreateSessionParams,\n SendOptions,\n} from \"../adapter.js\";\nimport type { AgentCapabilities, AgentDescriptor, StreamEvent, ContextItem } from \"@agent-phonon/protocol\";\n\n/**\n * Hermes adapter(design D10/D32,**多 agent runtime**,同 OpenClaw)。\n *\n * Hermes profile = 独立 agent(各自 config.yaml/.env/SOUL.md/skills/workspace)。\n * 一个 Hermes 安装 = 一个 runtime,里面多个 profile = 多个 agent。\n * 复合 agentId:hermes:<profile>(如 hermes:default)。\n *\n * 调用:`HERMES_PROFILE=<profile> hermes -z <prompt> -m <model> --yolo --accept-hooks\n * [--continue <name>]`。-z/--oneshot 纯文本输出(非流式)。\n * 枚举 profile:`hermes profile list`。\n *\n * 方案 A:用 Hermes 现有 provider 配置(不强制网关)。全自动:--yolo + --accept-hooks。\n */\n\nconst CAPABILITIES: AgentCapabilities = {\n nativeSession: true, // --resume / --pass-session-id\n nativeCompression: false,\n contextInjection: true, // 拼进下轮 prompt\n proactiveOutput: false,\n modelSwitch: true, // -m 每轮可变\n interrupt: true, // kill\n injectMidTurn: false,\n skillManagement: true, // hermes skills\n hooks: [\"pre_command\"],\n streaming: false, // -z 是纯文本一次性输出,非流式 → 用 final 事件\n limits: { maxConcurrentSessions: 4 },\n};\n\nexport interface HermesEnv {\n /** Hermes executable path. Prefer an absolute path when running under systemd/launchd. */\n binPath?: string;\n /** 默认模型(如 anthropic/claude-opus-4.6 或 provider 自带格式)。 */\n defaultModel?: string;\n /** provider 覆盖(如 anthropic / openrouter;不传用 Hermes config 默认)。 */\n provider?: string;\n /** 额外 toolsets。 */\n toolsets?: string;\n}\n\nclass HermesSession implements AdapterSession {\n readonly sessionId: string;\n model: string;\n private cwd: string;\n private env: HermesEnv;\n private profile: string;\n private hermesSessionId: string;\n private convName: string;\n private started = false;\n private current?: ReturnType<typeof spawn>;\n private pendingInject: string[] = [];\n\n constructor(sessionId: string, model: string, cwd: string, env: HermesEnv, profile: string) {\n this.sessionId = sessionId;\n this.model = model;\n this.cwd = cwd;\n this.env = env;\n this.profile = profile;\n this.hermesSessionId = randomUUID();\n this.convName = `phonon-${sessionId.replace(/[^a-zA-Z0-9_-]/g, \"\")}`;\n }\n\n async send(input: string, opts: SendOptions): Promise<void> {\n const { turnId, emit } = opts;\n let prompt = input;\n if (this.pendingInject.length > 0) {\n prompt = this.pendingInject.join(\"\\n\") + \"\\n\\n\" + prompt;\n this.pendingInject = [];\n }\n if (opts.skills && opts.skills.length > 0) {\n prompt = `[本轮请使用这些能力: ${opts.skills.join(\", \")}]\\n\\n${prompt}`;\n }\n\n const args = [\"-z\", prompt];\n if (this.model) args.push(\"-m\", this.model);\n if (this.env.provider) args.push(\"--provider\", this.env.provider);\n if (this.env.toolsets) args.push(\"-t\", this.env.toolsets);\n // 全自动模式:phonon 让 agent 自动跑,不等人授权\n args.push(\"--yolo\", \"--accept-hooks\");\n // 持续会话:用 phonon sessionId 作为 Hermes 会话名,--continue <name> 恢复/创建\n // (--continue 接会话名,首轮创建、后续恢复)\n args.push(\"--continue\", this.convName);\n this.started = true;\n\n await this.run(args, turnId, emit, opts);\n }\n\n private run(args: string[], turnId: string, emit: (e: StreamEvent) => void, opts: SendOptions): Promise<void> {\n return new Promise((resolve) => {\n const child = spawn(this.env.binPath ?? \"hermes\", args, {\n cwd: this.cwd,\n shell: process.platform === \"win32\",\n env: { ...process.env, ...(opts.environment ?? {}), HERMES_PROFILE: this.profile } as NodeJS.ProcessEnv,\n });\n this.current = child;\n let out = \"\";\n let err = \"\";\n let settled = false;\n const finish = (status: \"completed\" | \"failed\" | \"interrupted\" | \"timeout\", text: string, message?: string) => {\n if (settled) return;\n settled = true;\n clearTimeout(guard);\n this.current = undefined;\n if (status === \"failed\") {\n emit({ type: \"error\", sessionId: this.sessionId, turnId, seq: 0, at: new Date().toISOString(), message: message ?? \"hermes failed\", status: \"failed\", final: true } as StreamEvent);\n } else {\n // -z 是一次性文本:作为一条 message + result 终态\n if (text) emit({ type: \"message\", sessionId: this.sessionId, turnId, seq: 0, at: new Date().toISOString(), role: \"assistant\", text, delta: false } as StreamEvent);\n emit({ type: \"result\", sessionId: this.sessionId, turnId, seq: 0, at: new Date().toISOString(), text, status, final: true } as StreamEvent);\n }\n resolve();\n };\n const guard = setTimeout(() => finish(\"timeout\", out), 1800000);\n opts.signal?.addEventListener(\"abort\", () => { child.kill(\"SIGTERM\"); finish(\"interrupted\", out); }, { once: true });\n\n child.stdout.on(\"data\", (d) => (out += d.toString()));\n child.stderr.on(\"data\", (d) => (err += d.toString()));\n child.on(\"error\", (e) => finish(\"failed\", \"\", e.message));\n child.on(\"close\", (code) => {\n if (settled) return;\n finish(code === 0 ? \"completed\" : \"failed\", out.trim(), code !== 0 ? `hermes exited ${code}: ${err.slice(0, 300)}` : undefined);\n });\n });\n }\n\n async interrupt(): Promise<void> {\n if (this.current) { this.current.kill(\"SIGTERM\"); this.current = undefined; }\n }\n async switchModel(model: string): Promise<{ warnings?: string[] }> { this.model = model; return {}; }\n async inject(context: ContextItem[]): Promise<void> {\n for (const c of context) this.pendingInject.push(`[${c.role}] ${c.content}`);\n }\n\n /**\n * 自定义压缩(dropToolIO):在 Hermes 的 state.db 里裁本 session 旧工具 IO。\n * Hermes 把 assistant 叙述与 tool_calls 存在同一行,所以:\n * - role='tool' 的纯工具返回行 → 整行删\n * - assistant 行带 tool_calls → 只清空 tool_calls/tool_call_id/tool_name 列,保留 content/reasoning\n * 默认保留最近 3 个工具调用;VACUUM INTO 一致性备份。\n */\n async compressCustom(strategy = \"dropToolIO\", options?: { keepRecentToolCalls?: number }): Promise<{ summary?: string; filesChanged?: number; recordsChanged?: number; blocksRemoved?: number; bytesBefore?: number; bytesAfter?: number; backups?: string[] }> {\n if (strategy !== \"dropToolIO\") throw new Error(`unsupported custom compression strategy: ${strategy}`);\n if (!this.started) throw new Error(\"Hermes session not started yet (no turn run); nothing to compress\");\n const dbPath = resolveHermesDbPath();\n if (!existsSync(dbPath)) throw new Error(`Hermes state.db not found: ${dbPath}`);\n const dbSessionId = resolveHermesSessionByTitle(dbPath, this.convName);\n if (!dbSessionId) throw new Error(`Hermes session not found for title ${this.convName}`);\n const r = await dropToolIORowsSqlite({\n dbPath,\n keepRecentToolCalls: options?.keepRecentToolCalls,\n selectRows: (db: DatabaseSync) => {\n const rows = db.prepare(\"SELECT id, role, tool_calls FROM messages WHERE session_id = ? ORDER BY id ASC\").all(dbSessionId) as Array<{ id: number; role: string; tool_calls: string | null }>;\n return rows.map((row) => {\n const hasToolCalls = row.tool_calls != null && row.tool_calls !== \"\" && row.tool_calls !== \"[]\" && row.tool_calls !== \"null\";\n return {\n id: row.id,\n role: row.role,\n isTool: row.role === \"tool\" || hasToolCalls,\n // 调用锚点 = assistant 带 tool_calls。role=tool 是结果行,不作为 keep-recent 计数点。\n isToolCall: hasToolCalls,\n };\n });\n },\n mutateRow: (db: DatabaseSync, row) => {\n if (row.role === \"tool\") {\n db.prepare(\"DELETE FROM messages WHERE id = ?\").run(row.id);\n } else {\n // assistant 行:只清空工具列,保留推理/正文\n db.prepare(\"UPDATE messages SET tool_calls = NULL, tool_call_id = NULL, tool_name = NULL WHERE id = ?\").run(row.id);\n }\n },\n });\n return { summary: `dropToolIO trimmed ${r.blocksRemoved} tool rows from Hermes session ${dbSessionId}`, ...r };\n }\n\n async terminate(): Promise<void> { await this.interrupt(); }\n}\n\n/** Hermes 状态库路径(默认 ~/.hermes/state.db,可被 HERMES_HOME 覆盖)。 */\nexport function resolveHermesDbPath(): string {\n const home = process.env.HERMES_HOME || join(homedir(), \".hermes\");\n return join(home, \"state.db\");\n}\n\n/**\n * 复现 Hermes 的 resolve_session_by_title:优先取 \"title #N\" 谱系里最新的,否则精确匹配。\n * 这样定位与 CLI 的 --continue <name> 一致,避免误删其它会话。\n */\nexport function resolveHermesSessionByTitle(dbPath: string, title: string): string | undefined {\n const db = new DatabaseSync(dbPath);\n try {\n db.exec(\"PRAGMA busy_timeout = 5000;\");\n const escaped = title.replace(/\\\\/g, \"\\\\\\\\\").replace(/%/g, \"\\\\%\").replace(/_/g, \"\\\\_\");\n const numbered = db.prepare(\"SELECT id FROM sessions WHERE title LIKE ? ESCAPE '\\\\' ORDER BY started_at DESC LIMIT 1\").get(`${escaped} #%`) as { id: string } | undefined;\n if (numbered?.id) return numbered.id;\n const exact = db.prepare(\"SELECT id FROM sessions WHERE title = ? LIMIT 1\").get(title) as { id: string } | undefined;\n return exact?.id;\n } finally {\n try { db.close(); } catch { /* ignore */ }\n }\n}\n\nexport class HermesAdapter implements AgentAdapter {\n readonly name = \"hermes\";\n readonly capabilities = CAPABILITIES;\n private env: HermesEnv;\n private defaultProfile: string;\n\n constructor(opts: { env?: HermesEnv; defaultProfile?: string } = {}) {\n this.env = opts.env ?? {};\n this.defaultProfile = opts.defaultProfile ?? \"default\";\n }\n\n async discoverAgents(): Promise<AgentDescriptor[]> {\n const version = await this.probeVersion();\n const available = version !== null;\n if (!available) {\n return [{\n agentId: \"hermes\" as AgentDescriptor[\"agentId\"],\n displayName: \"Hermes\",\n adapter: \"hermes\",\n available: false,\n unavailableReason: \"hermes CLI not found\",\n models: [],\n capabilities: CAPABILITIES,\n scannedAt: new Date().toISOString(),\n }];\n }\n // 枚举所有 profile = 多个 agent(D32,同 OpenClaw)\n const profiles = await this.listProfiles();\n const now = new Date().toISOString();\n return profiles.map((p) => ({\n agentId: `hermes:${p.name}` as AgentDescriptor[\"agentId\"],\n displayName: `Hermes / ${p.name}`,\n adapter: \"hermes\",\n available: true,\n ...(version ? { version } : {}),\n models: p.model\n ? [{ id: p.model, available: true }]\n : (this.env.defaultModel ? [{ id: this.env.defaultModel, available: true }] : [{ id: \"default\", displayName: \"Hermes default\", available: true }]),\n capabilities: CAPABILITIES,\n scannedAt: now,\n }));\n }\n\n async createSession(params: CreateSessionParams): Promise<AdapterSession> {\n // 从复合 agentId 解出 profile:hermes:default → default\n const profile = params.agentId.includes(\":\") ? params.agentId.split(\":\")[1]! : this.defaultProfile;\n const model = params.model && params.model !== \"default\" ? params.model : (this.env.defaultModel ?? \"\");\n return new HermesSession(params.sessionId, model, params.cwd, this.env, profile);\n }\n\n /** 枚举 Hermes profile(去 ANSI 色解析 profile list)。 */\n private listProfiles(): Promise<Array<{ name: string; model?: string }>> {\n return new Promise((resolve) => {\n const child = spawn(this.env.binPath ?? \"hermes\", [\"profile\", \"list\"], { shell: process.platform === \"win32\" });\n let out = \"\";\n child.stdout.on(\"data\", (d) => (out += d.toString()));\n child.on(\"error\", () => resolve([{ name: this.defaultProfile }]));\n child.on(\"close\", () => {\n const clean = out.replace(/\\u001b\\[[0-9;]*m/g, \"\");\n const names: Array<{ name: string; model?: string }> = [];\n for (const line of clean.split(\"\\n\")) {\n const m = line.match(/^\\s*[\\u25c6\\u25cf\\s]*([a-z0-9][a-z0-9_-]*)\\s+(\\S.*)?$/i);\n if (m && m[1] && !/^(Profile|Distribution|Model|Gateway|Alias)$/i.test(m[1])) {\n const rest = (m[2] ?? \"\").trim().split(/\\s{2,}/);\n names.push({ name: m[1], model: rest[0] || undefined });\n }\n }\n resolve(names.length > 0 ? names : [{ name: this.defaultProfile }]);\n });\n });\n }\n\n private probeVersion(): Promise<string | null> {\n return new Promise((resolve) => {\n const child = spawn(this.env.binPath ?? \"hermes\", [\"--version\"], { shell: process.platform === \"win32\" });\n let out = \"\";\n child.stdout.on(\"data\", (d) => (out += d.toString()));\n child.on(\"error\", () => resolve(null));\n child.on(\"close\", (code) => resolve(code === 0 ? out.trim().split(\"\\n\")[0] ?? \"hermes\" : null));\n });\n }\n}\n","import { EventEmitter } from \"node:events\";\n\n/**\n * 可观测性核心(design D34 / bug-bash B5)。\n *\n * 产品理念:可观测性是放权的前提——人愿意让 agent 自动干活,前提是关键时刻能掀盖看里面。\n * 黑盒不可放权,可观测才敢放权。\n *\n * 统一「可观测事件」源头 + 多消费者(结构化日志 / audit 落库 / 指标 / HTTP 端点)。\n */\n\n/** 事件类别。 */\nexport type ObsCategory =\n | \"daemon\" // daemon 起停\n | \"connection\" // 到 server 的连接状态\n | \"adapter\" // adapter 可用性\n | \"session\" // session 生命周期\n | \"turn\" // 一轮对话/任务\n | \"tool\" // agent 工具调用(最贴「agent 在干什么」)\n | \"hitl\" // 人在回路拦截\n | \"stream\" // 流式输出(含自发)\n | \"error\"; // 错误\n\nexport type ObsLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\n/** 统一可观测事件。 */\nexport interface ObsEvent {\n ts: string; // ISO 时间\n category: ObsCategory;\n level: ObsLevel;\n /** 事件名,如 \"session.create\" / \"turn.start\" / \"tool.call\" / \"hitl.fired\"。 */\n event: string;\n /** 关联标识(便于按维度过滤/回溯)。 */\n tenantId?: string;\n sessionId?: string;\n agentId?: string;\n projectId?: string;\n turnId?: string;\n /** 人类可读摘要。 */\n msg?: string;\n /** 结构化附加数据。 */\n data?: Record<string, unknown>;\n}\n\n/**\n * 事件总线:进程内唯一事件源。各组件 emit,多消费者 on。\n */\nexport class ObsBus extends EventEmitter {\n emitEvent(e: Omit<ObsEvent, \"ts\"> & { ts?: string }): void {\n const full: ObsEvent = { ts: e.ts ?? new Date().toISOString(), ...e };\n this.emit(\"event\", full);\n }\n onEvent(handler: (e: ObsEvent) => void): void {\n this.on(\"event\", handler);\n }\n}\n\n/**\n * 极简结构化 JSON logger(零依赖,符合单设备原则)。\n * 从 ObsBus 消费,每事件一行 JSON 写 stdout(或注入的 sink)。\n */\nexport class StructuredLogger {\n private minLevel: ObsLevel;\n private sink: (line: string) => void;\n private static order: Record<ObsLevel, number> = { debug: 0, info: 1, warn: 2, error: 3 };\n\n constructor(opts?: { level?: ObsLevel; sink?: (line: string) => void }) {\n this.minLevel = opts?.level ?? \"info\";\n this.sink = opts?.sink ?? ((l) => process.stdout.write(l + \"\\n\"));\n }\n\n attach(bus: ObsBus): void {\n bus.onEvent((e) => this.write(e));\n }\n\n write(e: ObsEvent): void {\n if (StructuredLogger.order[e.level] < StructuredLogger.order[this.minLevel]) return;\n this.sink(JSON.stringify(e));\n }\n}\n\n/**\n * 实时指标(counters + gauges)。从 ObsBus 消费维护,HTTP /metrics 读取。\n */\nexport class Metrics {\n private counters = new Map<string, number>();\n private gauges = new Map<string, number>();\n private startedAt = Date.now();\n\n attach(bus: ObsBus): void {\n bus.onEvent((e) => this.observe(e));\n }\n\n private observe(e: ObsEvent): void {\n this.inc(`events_total{category=\"${e.category}\"}`);\n if (e.event === \"session.create\") this.inc(\"sessions_created_total\");\n if (e.event === \"session.terminate\") this.inc(\"sessions_terminated_total\");\n if (e.event === \"turn.start\") this.inc(\"turns_started_total\");\n if (e.event === \"turn.end\") this.inc(\"turns_ended_total\");\n if (e.event === \"tool.call\") this.inc(\"tool_calls_total\");\n if (e.event === \"hitl.fired\") this.inc(\"hitl_fired_total\");\n if (e.event.startsWith(\"hitl.\") && e.data?.action === \"abort\") this.inc(\"hitl_blocked_total\");\n if (e.level === \"error\") this.inc(\"errors_total\");\n }\n\n inc(key: string, by = 1): void {\n this.counters.set(key, (this.counters.get(key) ?? 0) + by);\n }\n setGauge(key: string, v: number): void {\n this.gauges.set(key, v);\n }\n\n /** Prometheus 文本格式快照。 */\n prometheus(): string {\n const lines: string[] = [`phonon_uptime_seconds ${Math.floor((Date.now() - this.startedAt) / 1000)}`];\n for (const [k, v] of this.counters) lines.push(`phonon_${k} ${v}`);\n for (const [k, v] of this.gauges) lines.push(`phonon_${k} ${v}`);\n return lines.join(\"\\n\") + \"\\n\";\n }\n\n /** JSON 快照。 */\n json(): Record<string, unknown> {\n return {\n uptimeSeconds: Math.floor((Date.now() - this.startedAt) / 1000),\n counters: Object.fromEntries(this.counters),\n gauges: Object.fromEntries(this.gauges),\n };\n }\n}\n\n/**\n * Audit sink:从 ObsBus 消费 → 落 sqlite audit_events(可观测回溯)。\n */\nexport class AuditSink {\n private store: { auditAdd: (e: { ts: string; category: string; level: string; event: string; tenantId?: string; sessionId?: string; agentId?: string; projectId?: string; turnId?: string; msg?: string; data?: string }) => void };\n constructor(store: { auditAdd: (e: { ts: string; category: string; level: string; event: string; tenantId?: string; sessionId?: string; agentId?: string; projectId?: string; turnId?: string; msg?: string; data?: string }) => void }) {\n this.store = store;\n }\n attach(bus: ObsBus): void {\n bus.onEvent((e) => {\n try {\n this.store.auditAdd({\n ts: e.ts, category: e.category, level: e.level, event: e.event,\n tenantId: e.tenantId, sessionId: e.sessionId, agentId: e.agentId,\n projectId: e.projectId, turnId: e.turnId, msg: e.msg,\n data: e.data ? JSON.stringify(e.data) : undefined,\n });\n } catch {\n /* audit 不能拖垫主流程 */\n }\n });\n }\n}\n","import { spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { writeFileSync, rmSync, mkdtempSync, existsSync } from \"node:fs\";\nimport { tmpdir, homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { dropToolIOFromJsonlFiles } from \"../custom-compress.js\";\nimport type {\n AgentAdapter,\n AdapterSession,\n CreateSessionParams,\n SendOptions,\n} from \"../adapter.js\";\nimport type { AgentCapabilities, AgentDescriptor, StreamEvent, ContextItem, ModelInfo } from \"@agent-phonon/protocol\";\n\n/**\n * Claude Code adapter(design D10,单 agent runtime)。\n *\n * 调用方式(详见 docs/agent-cli-integration.md):\n * claude -p --output-format stream-json --input-format stream-json --verbose\n * --permission-mode bypassPermissions --settings <env-json>\n * [--model X] [--session-id <uuid> | --resume <uuid>]\n * prompt 走 stdin envelope(不是 argv),剥离 CLAUDECODE env,\n * 认证用 --settings 注入完整 ANTHROPIC env 集(CC Switch 范式)。\n *\n * 单 agent runtime:discoverAgents 只返回一个 claude-code。\n */\n\nconst CAPABILITIES: AgentCapabilities = {\n nativeSession: true, // --session-id / --resume\n nativeCompression: false, // 无原生 compact,core custom 兜底\n contextInjection: true, // --append-system-prompt / stdin\n proactiveOutput: false, // 一次性,无自发输出\n modelSwitch: true, // --model 每轮可变\n interrupt: true, // kill 子进程\n injectMidTurn: false,\n skillManagement: true, // Claude Code 有 skills(/skill-name)\n hooks: [\"pre_tool\", \"pre_command\"],\n streaming: true, // stream-json 真流式\n limits: { maxConcurrentSessions: 4 },\n};\n\nexport interface ClaudeCodeEnv {\n /** Claude executable path. Prefer an absolute path when running under systemd/launchd. */\n binPath?: string;\n /** Optional Anthropic-compatible endpoint override. Omit to use the user's native Claude Code login/config. */\n baseUrl?: string;\n /** Optional auth token for baseUrl. Omit to use the user's native Claude Code login/config. */\n authToken?: string;\n /** 默认模型;`default` means let Claude Code use the user's configured default. */\n defaultModel: string;\n /** 可选:由用户配置/上层配置发现到的真实可用模型。 */\n models?: ModelInfo[];\n}\n\n/**\n * 写 settings 到临时 0600 文件(避免 token 进 argv 被 ps 看到,bug-bash#2 B4)。\n * 返回文件路径;调用方负责用后删(cleanup)。\n */\nfunction writeSettingsFile(env: ClaudeCodeEnv, model: string): string | undefined {\n if (!env.baseUrl || !env.authToken) return undefined;\n const dir = mkdtempSync(join(tmpdir(), \"phonon-cc-\"));\n const file = join(dir, \"settings.json\");\n const content = JSON.stringify({\n env: {\n ANTHROPIC_BASE_URL: env.baseUrl,\n ANTHROPIC_AUTH_TOKEN: env.authToken,\n ...(model !== \"default\" ? {\n ANTHROPIC_MODEL: model,\n ANTHROPIC_DEFAULT_OPUS_MODEL: model,\n ANTHROPIC_DEFAULT_SONNET_MODEL: model,\n ANTHROPIC_DEFAULT_HAIKU_MODEL: model,\n } : {}),\n CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: \"1\",\n },\n });\n writeFileSync(file, content, { mode: 0o600 });\n return file;\n}\n\nclass ClaudeCodeSession implements AdapterSession {\n readonly sessionId: string;\n model: string;\n private uuid: string; // Claude Code session UUID\n private cwd: string;\n private env: ClaudeCodeEnv;\n private started = false; // 是否已建过(决定 --session-id vs --resume)\n private current?: ReturnType<typeof spawn>;\n private pendingInject: string[] = [];\n private settingsPath?: string;\n\n /** 本轮 settings 临时文件路径(每次 send 重建,finish 时删)。 */\n private settingsFile(): string | undefined {\n this.settingsPath = writeSettingsFile(this.env, this.model);\n return this.settingsPath;\n }\n\n constructor(sessionId: string, model: string, cwd: string, env: ClaudeCodeEnv) {\n this.sessionId = sessionId;\n this.model = model;\n this.cwd = cwd;\n this.env = env;\n this.uuid = randomUUID();\n }\n\n async send(input: string, opts: SendOptions): Promise<void> {\n const { turnId, emit } = opts;\n let prompt = input;\n if (this.pendingInject.length > 0) {\n prompt = this.pendingInject.join(\"\\n\") + \"\\n\\n\" + prompt;\n this.pendingInject = [];\n }\n if (opts.skills && opts.skills.length > 0) {\n prompt = `[必须本轮加载并使用这些 skill: ${opts.skills.join(\", \")}]\\n\\n${prompt}`;\n }\n\n const args = [\n \"-p\",\n \"--output-format\", \"stream-json\",\n \"--input-format\", \"stream-json\",\n \"--verbose\",\n // 最高权限:bypassPermissions 跳过所有权限确认;不限定 allowedTools = 所有工具可用\n // (phonon 定位:全自动执行,牺牲安全换自动化)\n \"--permission-mode\", \"bypassPermissions\",\n ];\n const settings = this.settingsFile();\n if (settings) args.push(\"--settings\", settings);\n if (this.model !== \"default\") args.push(\"--model\", this.model);\n // 首轮 --session-id,后续 --resume(持续会话)\n if (this.started) args.push(\"--resume\", this.uuid);\n else args.push(\"--session-id\", this.uuid);\n this.started = true;\n\n const envelope = JSON.stringify({\n type: \"user\",\n message: { role: \"user\", content: [{ type: \"text\", text: prompt }] },\n }) + \"\\n\";\n\n await this.run(args, envelope, turnId, emit, opts);\n }\n\n private run(args: string[], stdin: string, turnId: string, emit: (e: StreamEvent) => void, opts: SendOptions): Promise<void> {\n return new Promise((resolve) => {\n // 剥离 CLAUDECODE* env(避免外层污染)\n const childEnv: Record<string, string> = {};\n for (const [k, v] of Object.entries(process.env)) {\n if (k === \"CLAUDECODE\" || k.startsWith(\"CLAUDECODE_\") || k.startsWith(\"CLAUDE_CODE_\")) continue;\n if (v !== undefined) childEnv[k] = v;\n }\n\n const child = spawn(this.env.binPath ?? \"claude\", args, { cwd: this.cwd, shell: process.platform === \"win32\", env: { ...childEnv, ...(opts.environment ?? {}) } });\n this.current = child;\n let buf = \"\";\n let acc = \"\";\n let settled = false;\n const finish = (status: \"completed\" | \"failed\" | \"interrupted\" | \"timeout\", text: string, message?: string) => {\n if (settled) return;\n settled = true;\n clearTimeout(guard);\n this.current = undefined;\n // 清理 settings 临时文件(含 token)\n if (this.settingsPath) {\n try { rmSync(this.settingsPath, { force: true }); rmSync(join(this.settingsPath, \"..\"), { recursive: true, force: true }); } catch { /* ignore */ }\n this.settingsPath = undefined;\n }\n if (status === \"failed\") {\n emit({ type: \"error\", sessionId: this.sessionId, turnId, seq: 0, at: new Date().toISOString(), message: message ?? \"claude failed\", status: \"failed\", final: true } as StreamEvent);\n } else {\n emit({ type: \"result\", sessionId: this.sessionId, turnId, seq: 0, at: new Date().toISOString(), text, status, final: true } as StreamEvent);\n }\n resolve();\n };\n\n const guard = setTimeout(() => finish(\"timeout\", acc), 1800000);\n opts.signal?.addEventListener(\"abort\", () => { child.kill(\"SIGTERM\"); finish(\"interrupted\", acc); }, { once: true });\n\n child.stdout.on(\"data\", (d) => {\n buf += d.toString();\n let nl;\n while ((nl = buf.indexOf(\"\\n\")) >= 0) {\n const line = buf.slice(0, nl).trim();\n buf = buf.slice(nl + 1);\n if (!line) continue;\n let ev: Record<string, unknown>;\n try { ev = JSON.parse(line); } catch { continue; }\n this.handleStreamEvent(ev, turnId, emit, (t) => (acc += t));\n }\n });\n child.stderr.on(\"data\", () => { /* stream-json 已含错误 */ });\n child.on(\"error\", (e) => finish(\"failed\", \"\", e.message));\n child.on(\"close\", (code) => {\n if (settled) return;\n finish(code === 0 ? \"completed\" : \"failed\", acc, code !== 0 ? `claude exited ${code}` : undefined);\n });\n\n child.stdin.write(stdin);\n child.stdin.end();\n });\n }\n\n /** 解析 Claude Code stream-json 事件 → phonon StreamEvent(流式 + 工具)。 */\n private handleStreamEvent(ev: Record<string, unknown>, turnId: string, emit: (e: StreamEvent) => void, addText: (t: string) => void): void {\n const now = new Date().toISOString();\n const type = ev.type as string;\n if (type === \"assistant\") {\n const msg = ev.message as { content?: Array<Record<string, unknown>> } | undefined;\n for (const block of msg?.content ?? []) {\n if (block.type === \"text\" && typeof block.text === \"string\") {\n addText(block.text);\n emit({ type: \"message\", sessionId: this.sessionId, turnId, seq: 0, at: now, role: \"assistant\", text: block.text, delta: true } as StreamEvent);\n } else if (block.type === \"tool_use\") {\n emit({ type: \"tool_call\", sessionId: this.sessionId, turnId, seq: 0, at: now, toolName: String(block.name ?? \"?\"), args: block.input, toolCallId: String(block.id ?? \"\") } as StreamEvent);\n }\n }\n } else if (type === \"user\") {\n // tool_result 回传\n const msg = ev.message as { content?: Array<Record<string, unknown>> } | undefined;\n for (const block of msg?.content ?? []) {\n if (block.type === \"tool_result\") {\n emit({ type: \"tool_result\", sessionId: this.sessionId, turnId, seq: 0, at: now, toolName: \"\", toolCallId: String(block.tool_use_id ?? \"\"), ok: !block.is_error, output: block.content } as StreamEvent);\n }\n }\n }\n // type === \"result\" 由 close 统一收尾(避免重复终态)\n }\n\n async compressCustom(strategy = \"dropToolIO\", options?: { keepRecentToolCalls?: number }): Promise<{ summary?: string; filesChanged?: number; recordsChanged?: number; blocksRemoved?: number; bytesBefore?: number; bytesAfter?: number; backups?: string[] }> {\n if (strategy !== \"dropToolIO\") throw new Error(`unsupported custom compression strategy: ${strategy}`);\n const file = this.resolveSessionFile();\n if (!file) throw new Error(`Claude Code session file not found for ${this.uuid}`);\n const r = await dropToolIOFromJsonlFiles([file], options);\n return { summary: `dropToolIO removed ${r.blocksRemoved} tool blocks from ${r.filesChanged} files`, ...r };\n }\n\n private resolveSessionFile(): string | undefined {\n const projectDir = this.cwd.replace(/\\\\/g, \"-\").replace(/\\//g, \"-\");\n const file = join(homedir(), \".claude\", \"projects\", projectDir, `${this.uuid}.jsonl`);\n return existsSync(file) ? file : undefined;\n }\n\n async interrupt(): Promise<void> {\n if (this.current) { this.current.kill(\"SIGTERM\"); this.current = undefined; }\n }\n async switchModel(model: string): Promise<{ warnings?: string[] }> { this.model = model; return {}; }\n async inject(context: ContextItem[]): Promise<void> {\n for (const c of context) this.pendingInject.push(`[${c.role}] ${c.content}`);\n }\n async terminate(): Promise<void> { await this.interrupt(); }\n}\n\nexport class ClaudeCodeAdapter implements AgentAdapter {\n readonly name = \"claude-code\";\n readonly capabilities = CAPABILITIES;\n private env: ClaudeCodeEnv;\n\n constructor(opts: { env: ClaudeCodeEnv }) {\n this.env = opts.env;\n }\n\n async discoverAgents(): Promise<AgentDescriptor[]> {\n const version = await this.probeVersion();\n const available = version !== null;\n return [{\n agentId: \"claude-code\" as AgentDescriptor[\"agentId\"],\n displayName: \"Claude Code\",\n adapter: \"claude-code\",\n available,\n ...(available ? {} : { unavailableReason: \"claude CLI not found\" }),\n ...(version ? { version } : {}),\n models: this.env.models?.length\n ? this.env.models\n : [{ id: this.env.defaultModel, available: true }],\n capabilities: CAPABILITIES,\n scannedAt: new Date().toISOString(),\n }];\n }\n\n async createSession(params: CreateSessionParams): Promise<AdapterSession> {\n return new ClaudeCodeSession(params.sessionId, params.model, params.cwd, this.env);\n }\n\n private probeVersion(): Promise<string | null> {\n return new Promise((resolve) => {\n const child = spawn(this.env.binPath ?? \"claude\", [\"--version\"], { shell: process.platform === \"win32\" });\n let out = \"\";\n child.stdout.on(\"data\", (d) => (out += d.toString()));\n child.on(\"error\", () => resolve(null));\n child.on(\"close\", (code) => resolve(code === 0 ? out.trim() : null));\n });\n }\n}\n","import { readFileSync, existsSync, mkdirSync, writeFileSync, chmodSync } from \"node:fs\";\nimport type { ModelInfo } from \"@agent-phonon/protocol\";\nimport { homedir, hostname } from \"node:os\";\nimport { join, dirname } from \"node:path\";\n\n/**\n * daemon 配置(bug-bash B4)。\n *\n * 一个 daemon 进程:一个设备 id、一个共享 sqlite、一个 HookBridge,\n * 注册若干 adapter,连接若干 server(每个 server = 一个 tenant 连接)。\n */\nexport interface ServerConfig {\n /** 服务端 ws/http URL。 */\n url: string;\n /** 本地自用放宽 policy(默认 false)。 */\n trustLocal?: boolean;\n /** 该连接的可选 device key(鉴权由 server 做,phonon 仅携带)。 */\n deviceKey?: string;\n}\n\nexport interface AdapterConfig {\n /** adapter 类型:openclaw-gateway | openclaw-cli。 */\n type: \"openclaw-gateway\" | \"openclaw-cli\" | \"claude-code\" | \"codex\" | \"hermes\" | \"opencode\";\n /** OpenClaw Gateway WS URL(openclaw-gateway 用)。 */\n gatewayUrl?: string;\n /** Gateway token(openclaw-gateway 用;缺省从 ~/.openclaw/openclaw.json 读)。 */\n gatewayToken?: string;\n /** 默认 OpenClaw sub-agent。 */\n defaultAgent?: string;\n /** claude-code:网关 baseUrl/token/默认模型。 */\n claudeBinPath?: string;\n claudeBaseUrl?: string;\n claudeAuthToken?: string;\n claudeDefaultModel?: string;\n claudeModels?: ModelInfo[];\n /** codex:网关 baseUrl(/v1)/key/默认模型/wireApi。 */\n codexBinPath?: string;\n codexBaseUrl?: string;\n codexApiKey?: string;\n codexDefaultModel?: string;\n codexModels?: ModelInfo[];\n codexWireApi?: \"responses\" | \"chat\";\n /** hermes:默认模型/provider(用现有 hermes config)。 */\n hermesBinPath?: string;\n hermesModel?: string;\n hermesProvider?: string;\n /** opencode:binary 路径/默认模型。 */\n opencodeBinPath?: string;\n opencodeModel?: string;\n}\n\nexport interface DaemonConfig {\n deviceId: string;\n /** sqlite 文件路径。 */\n dbPath: string;\n /** 受控项目根。 */\n workspaceRoot: string;\n /** 结构化日志级别。 */\n logLevel?: \"debug\" | \"info\" | \"warn\" | \"error\";\n hookBridge?: { port?: number; token?: string };\n /** 可观测 HTTP 服务。 */\n obs?: { enabled?: boolean; port?: number; token?: string };\n adapters: AdapterConfig[];\n servers: ServerConfig[];\n}\n\nconst DEFAULT_DIR = join(homedir(), \".agent-phonon\");\nexport const DEFAULT_CONFIG_PATH = process.env.PHONON_CONFIG ?? join(DEFAULT_DIR, \"config.json\");\n\nexport function defaultConfig(): DaemonConfig {\n return {\n deviceId: `dev-${hostname()}`,\n dbPath: join(DEFAULT_DIR, \"phonon.db\"),\n workspaceRoot: join(homedir(), \"phonon-projects\"),\n hookBridge: { port: 4318 },\n obs: { enabled: true, port: 4319 },\n adapters: [{ type: \"openclaw-gateway\", gatewayUrl: \"ws://127.0.0.1:18789\", defaultAgent: \"main\" }],\n servers: [],\n };\n}\n\nexport function loadConfig(path = DEFAULT_CONFIG_PATH): DaemonConfig {\n if (!existsSync(path)) {\n throw new Error(`config not found at ${path} — run 'agent-phonon init' first`);\n }\n const raw = JSON.parse(readFileSync(path, \"utf8\")) as Partial<DaemonConfig>;\n const d = defaultConfig();\n return {\n deviceId: raw.deviceId ?? d.deviceId,\n dbPath: raw.dbPath ?? d.dbPath,\n workspaceRoot: raw.workspaceRoot ?? d.workspaceRoot,\n hookBridge: { ...d.hookBridge, ...raw.hookBridge },\n obs: { ...d.obs, ...raw.obs },\n logLevel: raw.logLevel ?? d.logLevel,\n adapters: raw.adapters ?? d.adapters,\n servers: raw.servers ?? d.servers,\n };\n}\n\nexport function writeConfig(cfg: DaemonConfig, path = DEFAULT_CONFIG_PATH): void {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(cfg, null, 2), { mode: 0o600 });\n try { chmodSync(path, 0o600); } catch { /* best-effort */ } // 含 token,限制权限(bug-bash#2)\n}\n\n/** 脱敏配置(用于打印/日志,不露 token/key)。 */\nexport function redactConfig(cfg: DaemonConfig): DaemonConfig {\n const mask = (v?: string): string | undefined => (v ? `***${v.slice(-4)}` : v);\n return {\n ...cfg,\n hookBridge: cfg.hookBridge ? { ...cfg.hookBridge, token: mask(cfg.hookBridge.token) } : cfg.hookBridge,\n obs: cfg.obs ? { ...cfg.obs, token: mask(cfg.obs.token) } : cfg.obs,\n adapters: cfg.adapters.map((a) => ({\n ...a,\n gatewayToken: mask(a.gatewayToken),\n claudeAuthToken: mask(a.claudeAuthToken),\n codexApiKey: mask(a.codexApiKey),\n })),\n servers: cfg.servers.map((s) => ({ ...s, deviceKey: mask(s.deviceKey) })),\n };\n}\n\n/** 从 ~/.openclaw/openclaw.json 读 Gateway token(adapter 缺省)。 */\nexport function readOpenClawGatewayToken(): string | undefined {\n try {\n const p = join(homedir(), \".openclaw\", \"openclaw.json\");\n const cfg = JSON.parse(readFileSync(p, \"utf8\"));\n return cfg?.gateway?.auth?.token;\n } catch {\n return undefined;\n }\n}\n","import { spawnSync } from \"node:child_process\";\nimport { existsSync, cpSync, mkdirSync, rmSync, writeFileSync, readFileSync } from \"node:fs\";\nimport { homedir, platform } from \"node:os\";\nimport { join, dirname, delimiter } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { AdapterRegistry, OpenClawGatewayAdapter, ClaudeCodeAdapter, CodexAdapter, HermesAdapter, OpenCodeAdapter } from \"@agent-phonon/core\";\nimport { loadConfig, writeConfig, readOpenClawGatewayToken, type AdapterConfig, type DaemonConfig } from \"./config.js\";\n\n/**\n * CLI 辅助命令(让 phonon 真正可用):doctor / discover / adapter / plugin。\n */\n\nfunction probe(bin: string, args: string[] = [\"--version\"]): { ok: boolean; out: string } {\n const r = spawnSync(bin, args, { timeout: 8000, shell: platform() === \"win32\" });\n return { ok: r.status === 0, out: (r.stdout?.toString() ?? \"\").trim().split(\"\\n\")[0] ?? \"\" };\n}\n\nfunction executableNames(bin: string): string[] {\n if (platform() !== \"win32\") return [bin];\n const exts = (process.env.PATHEXT ?? \".COM;.EXE;.BAT;.CMD\")\n .split(\";\")\n .map((e) => e.toLowerCase());\n return [bin, ...exts.map((e) => `${bin}${e}`), ...exts.map((e) => `${bin}${e.toUpperCase()}`)];\n}\n\nexport function commandPath(bin: string): string | undefined {\n const home = homedir();\n const appData = process.env.APPDATA;\n const localAppData = process.env.LOCALAPPDATA;\n const dirs = [\n join(home, \".npm-global\", \"bin\"),\n join(home, \".local\", \"bin\"),\n join(home, \".bun\", \"bin\"),\n join(home, \".cargo\", \"bin\"),\n ...(appData ? [join(appData, \"npm\")] : []),\n ...(localAppData ? [join(localAppData, \"Programs\"), join(localAppData, \"Microsoft\", \"WindowsApps\")] : []),\n \"/opt/homebrew/bin\",\n \"/usr/local/bin\",\n \"/usr/bin\",\n ...(process.env.PATH ?? \"\").split(delimiter).filter(Boolean),\n ];\n for (const dir of dirs) {\n for (const name of executableNames(bin)) {\n const p = join(dir, name);\n if (existsSync(p)) return p;\n }\n }\n\n const r = platform() === \"win32\"\n ? spawnSync(\"where.exe\", [bin], { timeout: 3000 })\n : spawnSync(\"sh\", [\"-lc\", `command -v ${bin}`], { timeout: 3000 });\n const out = (r.stdout?.toString() ?? \"\").trim().split(/\\r?\\n/)[0];\n return r.status === 0 && out ? out : undefined;\n}\n\nfunction gatewayReachable(url: string): boolean {\n // 简单 TCP 探测:用 node 连一下 ws 端口\n try {\n const u = new URL(url.replace(/^ws/, \"http\"));\n const r = spawnSync(\"bash\", [\"-c\", `exec 3<>/dev/tcp/${u.hostname}/${u.port || 80} && echo ok`], { timeout: 3000 });\n return r.status === 0;\n } catch {\n return false;\n }\n}\n\nfunction openCodeBin(): string {\n const bundledDir = join(homedir(), \".opencode\", \"bin\");\n for (const name of executableNames(\"opencode\")) {\n const p = join(bundledDir, name);\n if (existsSync(p)) return p;\n }\n return commandPath(\"opencode\") ?? \"opencode\";\n}\n\nexport function autoDetectAdapters(adapters: AdapterConfig[]): AdapterConfig[] {\n const out = [...adapters];\n const has = (type: AdapterConfig[\"type\"]): boolean => out.some((a) => a.type === type);\n\n if (!has(\"hermes\")) {\n const hermesPath = commandPath(\"hermes\");\n if (hermesPath && probe(hermesPath).ok) out.push({ type: \"hermes\", hermesBinPath: hermesPath });\n }\n\n const ocBin = openCodeBin();\n if (!has(\"opencode\") && probe(ocBin).ok) out.push({ type: \"opencode\", opencodeBinPath: ocBin === \"opencode\" ? undefined : ocBin });\n\n for (const a of out) {\n if (a.type === \"hermes\" && !a.hermesBinPath) a.hermesBinPath = commandPath(\"hermes\");\n if (a.type === \"claude-code\" && !a.claudeBinPath) a.claudeBinPath = commandPath(\"claude\");\n if (a.type === \"codex\" && !a.codexBinPath) a.codexBinPath = commandPath(\"codex\");\n }\n\n if (!has(\"claude-code\")) {\n const claudePath = commandPath(\"claude\");\n if (claudePath && probe(claudePath).ok) out.push({ type: \"claude-code\", claudeBinPath: claudePath, claudeDefaultModel: \"default\" });\n }\n if (!has(\"codex\")) {\n const codexPath = commandPath(\"codex\");\n if (codexPath && probe(codexPath).ok) out.push({ type: \"codex\", codexBinPath: codexPath, codexDefaultModel: \"default\" });\n }\n\n return out;\n}\n\n/** doctor:体检本机 agent 可用性 + Gateway + 插件。 */\nexport function cmdDoctor(): void {\n console.log(\"agent-phonon doctor\\n\");\n // OpenClaw Gateway\n const gwToken = readOpenClawGatewayToken();\n const gwUrl = \"ws://127.0.0.1:18789\";\n const gwOk = gatewayReachable(gwUrl);\n console.log(`OpenClaw Gateway (${gwUrl}): ${gwOk ? \"✓ reachable\" : \"✗ unreachable\"}${gwToken ? \" (token found)\" : \" (no token in ~/.openclaw/openclaw.json)\"}`);\n // OpenClaw plugin\n const pluginDir = join(homedir(), \".openclaw\", \"extensions\", \"agent-phonon-hitl\");\n console.log(`OpenClaw HITL plugin: ${existsSync(pluginDir) ? \"✓ installed\" : \"✗ not installed (run: agent-phonon plugin install openclaw)\"}`);\n // CLI agents\n console.log(\"\\nCLI agents:\");\n for (const [name, bin] of [[\"Claude Code\", \"claude\"], [\"Codex\", \"codex\"], [\"Hermes\", \"hermes\"]] as const) {\n const p = probe(bin);\n console.log(` ${name} (${bin}): ${p.ok ? \"✓ \" + p.out : \"✗ not found\"}`);\n }\n // OpenCode (often not in PATH)\n const ocBin = openCodeBin();\n const oc = probe(ocBin);\n console.log(` OpenCode (${ocBin}): ${oc.ok ? \"✓ \" + oc.out : \"✗ not found\"}`);\n // config\n console.log(\"\");\n try {\n const cfg = loadConfig();\n const effective = autoDetectAdapters(cfg.adapters);\n console.log(`config: ${cfg.adapters.length} configured adapter(s), ${effective.length} effective adapter(s), ${cfg.servers.length} server(s)`);\n } catch {\n console.log(\"config: not initialized (run: agent-phonon init)\");\n }\n}\n\n/** discover:不启 daemon,直接列本机可用 agent(按已配 adapter)。 */\nexport async function cmdDiscover(): Promise<void> {\n let cfg: DaemonConfig;\n try { cfg = loadConfig(); } catch { console.error(\"config not initialized — run 'agent-phonon init' first\"); process.exit(1); return; }\n const reg = buildRegistry(cfg.adapters);\n const nested = await Promise.all(reg.all().map((a) => a.discoverAgents()));\n const agents = nested.flat();\n console.log(`discovered ${agents.length} agent(s):\\n`);\n for (const a of agents) {\n console.log(` ${a.available ? \"✓\" : \"✗\"} ${a.agentId} (${a.displayName})${a.available ? \"\" : \" — \" + (a.unavailableReason ?? \"unavailable\")}`);\n if (a.models.length) console.log(` models: ${a.models.map((m) => m.id).join(\", \")}`);\n }\n}\n\n/** 从 adapter 配置构造 registry(discover/doctor 用)。 */\nexport function buildRegistry(adapters: AdapterConfig[]): AdapterRegistry {\n const reg = new AdapterRegistry();\n for (const a of autoDetectAdapters(adapters)) {\n if (a.type === \"openclaw-gateway\") {\n const token = a.gatewayToken ?? readOpenClawGatewayToken();\n if (token) reg.register(new OpenClawGatewayAdapter({ gateway: { baseUrl: a.gatewayUrl ?? \"ws://127.0.0.1:18789\", token }, defaultAgent: a.defaultAgent ?? \"main\" }));\n } else if (a.type === \"claude-code\") {\n reg.register(new ClaudeCodeAdapter({ env: { binPath: a.claudeBinPath, baseUrl: a.claudeBaseUrl, authToken: a.claudeAuthToken, defaultModel: a.claudeDefaultModel ?? \"default\", models: a.claudeModels } }));\n } else if (a.type === \"codex\") {\n reg.register(new CodexAdapter({ env: { binPath: a.codexBinPath, baseUrl: a.codexBaseUrl, apiKey: a.codexApiKey, defaultModel: a.codexDefaultModel ?? \"default\", models: a.codexModels, wireApi: a.codexWireApi ?? \"responses\" } }));\n } else if (a.type === \"hermes\") {\n reg.register(new HermesAdapter({ env: { binPath: a.hermesBinPath, defaultModel: a.hermesModel, provider: a.hermesProvider } }));\n } else if (a.type === \"opencode\") {\n reg.register(new OpenCodeAdapter({ env: { binPath: a.opencodeBinPath, defaultModel: a.opencodeModel } }));\n }\n }\n return reg;\n}\n\n/** adapter add:往 config 加一个 adapter。 */\nexport function cmdAdapterAdd(type: string, opts: Record<string, string | undefined>): void {\n const cfg = loadConfig();\n let a: AdapterConfig;\n switch (type) {\n case \"openclaw\":\n case \"openclaw-gateway\":\n a = { type: \"openclaw-gateway\", gatewayUrl: opts.gatewayUrl ?? \"ws://127.0.0.1:18789\", gatewayToken: opts.token, defaultAgent: opts.defaultAgent ?? \"main\" };\n break;\n case \"claude-code\":\n a = { type: \"claude-code\", claudeBinPath: opts.bin, claudeBaseUrl: opts.baseUrl, claudeAuthToken: opts.token, claudeDefaultModel: opts.model ?? \"default\" };\n break;\n case \"codex\":\n a = { type: \"codex\", codexBinPath: opts.bin, codexBaseUrl: opts.baseUrl, codexApiKey: opts.apiKey, codexDefaultModel: opts.model ?? \"default\", codexWireApi: (opts.wireApi as \"responses\" | \"chat\") ?? \"responses\" };\n break;\n case \"hermes\":\n a = { type: \"hermes\", hermesBinPath: opts.bin, hermesModel: opts.model, hermesProvider: opts.provider };\n break;\n case \"opencode\":\n a = { type: \"opencode\", opencodeBinPath: opts.bin, opencodeModel: opts.model };\n break;\n default:\n return fail(`unknown adapter type: ${type} (openclaw|claude-code|codex|hermes|opencode)`);\n }\n // 去重:同 type 覆盖\n cfg.adapters = cfg.adapters.filter((x) => x.type !== a.type);\n cfg.adapters.push(a);\n writeConfig(cfg);\n console.log(`added ${a.type} adapter (${cfg.adapters.length} total)`);\n}\n\nexport function cmdAdapterList(): void {\n const cfg = loadConfig();\n const effective = autoDetectAdapters(cfg.adapters);\n if (effective.length === 0) { console.log(\"(no adapters available)\"); return; }\n for (const a of effective) {\n const auto = cfg.adapters.some((x) => x.type === a.type) ? \"\" : \" [auto]\";\n console.log(`- ${a.type}${a.defaultAgent ? ` (agent: ${a.defaultAgent})` : \"\"}${auto}`);\n }\n}\n\n/** plugin install:装 OpenClaw HITL 插件(导出干净产物 + force 安装)。 */\nexport function cmdPluginInstall(which: string): void {\n if (which !== \"openclaw\") return fail(`plugin install supports: openclaw (got: ${which})`);\n // 找到 monorepo 里的 openclaw-plugin 包\n const here = dirname(fileURLToPath(import.meta.url));\n const pluginSrc = join(here, \"..\", \"..\", \"openclaw-plugin\");\n if (!existsSync(join(pluginSrc, \"dist\", \"index.js\"))) {\n return fail(`plugin not built. Run: cd ${pluginSrc} && pnpm build`);\n }\n // 导出干净产物(避免 pnpm workspace node_modules symlink 触发安全扫描)\n const dist = join(homedir(), \".agent-phonon\", \"openclaw-plugin-dist\");\n rmSync(dist, { recursive: true, force: true });\n mkdirSync(dist, { recursive: true });\n cpSync(join(pluginSrc, \"dist\"), join(dist, \"dist\"), { recursive: true });\n cpSync(join(pluginSrc, \"openclaw.plugin.json\"), join(dist, \"openclaw.plugin.json\"));\n const pkg = JSON.parse(readFileSync(join(pluginSrc, \"package.json\"), \"utf8\")) as Record<string, unknown>;\n delete pkg.devDependencies;\n writeFileSync(join(dist, \"package.json\"), JSON.stringify(pkg, null, 2));\n console.log(`exported clean plugin → ${dist}`);\n const r = spawnSync(\"openclaw\", [\"plugins\", \"install\", \"--force\", dist], { stdio: \"inherit\" });\n if (r.status === 0) console.log(\"\\n✓ installed. Restart OpenClaw Gateway to load: systemctl --user restart openclaw-gateway.service\");\n else fail(\"openclaw plugins install failed\");\n}\n\nfunction fail(msg: string): void {\n console.error(\"error:\", msg);\n process.exit(1);\n}\n","import { createServer, type Server } from \"node:http\";\nimport type { ObsBus, ObsEvent, Metrics, PhononStore } from \"@agent-phonon/core\";\n\n/**\n * 可观测性 HTTP 服务(design D34 / B5)。\n *\n * 产品理念:可观测性是放权的前提。人放权让 agent 自动干活,但关键时刻要能掀盖看里面。\n *\n * 端点:\n * GET /health daemon/连接/db/adapter 健康(人/监控看「活没活」)\n * GET /metrics Prometheus 文本指标\n * GET /metrics.json JSON 指标\n * GET /sessions 当前每个 agent 在干什么的实时快照(「不是黑盒」的心脏)\n * GET /events 审计时间线(最近 N 条,可 ?session= ?category= 过滤)\n * GET /stream SSE 实时事件流(人盯着看 agent 实时动作)\n */\nexport interface ObsServerDeps {\n bus: ObsBus;\n metrics: Metrics;\n store: PhononStore;\n /** 健康快照提供者(daemon 注入)。 */\n health: () => Record<string, unknown>;\n /** 所有连接的 session 快照(daemon 注入)。 */\n sessions: () => Array<Record<string, unknown>>;\n /** 可选 bearer token。 */\n token?: string;\n}\n\nexport class ObsServer {\n private server?: Server;\n private deps: ObsServerDeps;\n private actualPort = 0;\n /** SSE 客户端。 */\n private sseClients = new Set<import(\"node:http\").ServerResponse>();\n\n constructor(deps: ObsServerDeps) {\n this.deps = deps;\n // 实时事件广播到 SSE 客户端\n deps.bus.onEvent((e: ObsEvent) => this.broadcast(e));\n }\n\n listen(port = 4319, host = \"127.0.0.1\"): Promise<number> {\n return new Promise((resolve) => {\n const server = createServer((req, res) => this.handle(req, res));\n this.server = server;\n server.listen(port, host, () => {\n const addr = server.address();\n this.actualPort = typeof addr === \"object\" && addr ? addr.port : port;\n resolve(this.actualPort);\n });\n });\n }\n\n private authed(req: import(\"node:http\").IncomingMessage): boolean {\n if (!this.deps.token) return true;\n return req.headers[\"authorization\"] === `Bearer ${this.deps.token}`;\n }\n\n private handle(req: import(\"node:http\").IncomingMessage, res: import(\"node:http\").ServerResponse): void {\n const url = new URL(req.url ?? \"/\", \"http://localhost\");\n const path = url.pathname;\n\n if (!this.authed(req)) {\n res.writeHead(401).end(\"unauthorized\");\n return;\n }\n\n if (path === \"/health\") {\n const h = this.deps.health();\n const ok = h.ok !== false;\n res.writeHead(ok ? 200 : 503, { \"content-type\": \"application/json\" }).end(JSON.stringify(h, null, 2));\n return;\n }\n if (path === \"/metrics\") {\n res.writeHead(200, { \"content-type\": \"text/plain; version=0.0.4\" }).end(this.deps.metrics.prometheus());\n return;\n }\n if (path === \"/metrics.json\") {\n res.writeHead(200, { \"content-type\": \"application/json\" }).end(JSON.stringify(this.deps.metrics.json(), null, 2));\n return;\n }\n if (path === \"/sessions\") {\n res.writeHead(200, { \"content-type\": \"application/json\" }).end(JSON.stringify(this.deps.sessions(), null, 2));\n return;\n }\n if (path === \"/events\") {\n const rows = this.deps.store.auditQuery({\n sessionId: url.searchParams.get(\"session\") ?? undefined,\n category: url.searchParams.get(\"category\") ?? undefined,\n limit: Number(url.searchParams.get(\"limit\") ?? 200),\n });\n res.writeHead(200, { \"content-type\": \"application/json\" }).end(JSON.stringify(rows, null, 2));\n return;\n }\n if (path === \"/stream\") {\n res.writeHead(200, {\n \"content-type\": \"text/event-stream\",\n \"cache-control\": \"no-cache\",\n connection: \"keep-alive\",\n });\n res.write(\": connected\\n\\n\");\n this.sseClients.add(res);\n req.on(\"close\", () => this.sseClients.delete(res));\n return;\n }\n if (path === \"/\") {\n res.writeHead(200, { \"content-type\": \"application/json\" }).end(\n JSON.stringify({ service: \"agent-phonon obs\", endpoints: [\"/health\", \"/metrics\", \"/metrics.json\", \"/sessions\", \"/events\", \"/stream\"] }, null, 2),\n );\n return;\n }\n res.writeHead(404).end(\"not found\");\n }\n\n private broadcast(e: ObsEvent): void {\n if (this.sseClients.size === 0) return;\n const line = `data: ${JSON.stringify(e)}\\n\\n`;\n for (const c of this.sseClients) {\n try {\n c.write(line);\n } catch {\n this.sseClients.delete(c);\n }\n }\n }\n\n get port(): number {\n return this.actualPort;\n }\n\n close(): Promise<void> {\n return new Promise((resolve) => {\n for (const c of this.sseClients) c.end();\n this.sseClients.clear();\n if (!this.server) return resolve();\n this.server.close(() => resolve());\n });\n }\n}\n","import {\n AdapterRegistry,\n PhononClient,\n PhononStore,\n HookBridge,\n OpenClawGatewayAdapter,\n OpenClawAdapter,\n ClaudeCodeAdapter,\n CodexAdapter,\n HermesAdapter,\n OpenCodeAdapter,\n ObsBus,\n StructuredLogger,\n Metrics,\n AuditSink,\n type PhononConnection,\n} from \"@agent-phonon/core\";\nimport { type DaemonConfig, readOpenClawGatewayToken } from \"./config.js\";\nimport { autoDetectAdapters } from \"./commands.js\";\nimport { ObsServer } from \"./obs-server.js\";\n\n/**\n * PhononDaemon(bug-bash B4):设备侧常驻服务。\n *\n * 一个进程管理:共享 sqlite store、adapter registry、HookBridge,\n * 以及到多个 server 的多条 PhononClient 连接(每个 server = 一个 tenant)。\n *\n * HookBridge 跨所有连接路由:sessionKey → 找到 owns 该 session 的连接。\n */\nexport class PhononDaemon {\n private cfg: DaemonConfig;\n private store: PhononStore;\n private registry = new AdapterRegistry();\n private clients: PhononClient[] = [];\n private bridge?: HookBridge;\n private gatewayAdapters: OpenClawGatewayAdapter[] = [];\n private obs = new ObsBus();\n private metrics = new Metrics();\n private obsServer?: ObsServer;\n private startedAt = Date.now();\n\n constructor(cfg: DaemonConfig) {\n this.cfg = cfg;\n this.store = new PhononStore(cfg.dbPath);\n // 可观测堆栈:结构化日志 + 指标 + audit 落库,都从同一 ObsBus 消费\n new StructuredLogger({ level: cfg.logLevel ?? \"info\" }).attach(this.obs);\n this.metrics.attach(this.obs);\n new AuditSink(this.store).attach(this.obs);\n this.registerAdapters();\n }\n\n private registerAdapters(): void {\n for (const a of autoDetectAdapters(this.cfg.adapters)) {\n if (a.type === \"openclaw-gateway\") {\n const token = a.gatewayToken ?? readOpenClawGatewayToken();\n if (!token) {\n console.warn(\"[daemon] openclaw-gateway adapter skipped: no Gateway token\");\n continue;\n }\n const ad = new OpenClawGatewayAdapter({\n gateway: { baseUrl: a.gatewayUrl ?? \"ws://127.0.0.1:18789\", token },\n defaultAgent: a.defaultAgent ?? \"main\",\n });\n this.gatewayAdapters.push(ad);\n this.registry.register(ad);\n } else if (a.type === \"claude-code\") {\n this.registry.register(new ClaudeCodeAdapter({ env: { binPath: a.claudeBinPath, baseUrl: a.claudeBaseUrl, authToken: a.claudeAuthToken, defaultModel: a.claudeDefaultModel ?? \"default\", models: a.claudeModels } }));\n } else if (a.type === \"codex\") {\n this.registry.register(new CodexAdapter({ env: { binPath: a.codexBinPath, baseUrl: a.codexBaseUrl, apiKey: a.codexApiKey, defaultModel: a.codexDefaultModel ?? \"default\", models: a.codexModels, wireApi: a.codexWireApi ?? \"responses\" } }));\n } else if (a.type === \"hermes\") {\n this.registry.register(new HermesAdapter({ env: { binPath: a.hermesBinPath, defaultModel: a.hermesModel, provider: a.hermesProvider } }));\n } else if (a.type === \"opencode\") {\n this.registry.register(new OpenCodeAdapter({ env: { binPath: a.opencodeBinPath, defaultModel: a.opencodeModel } }));\n } else if (a.type === \"openclaw-cli\") {\n this.registry.register(new OpenClawAdapter({ defaultAgent: a.defaultAgent ?? \"main\" }));\n }\n }\n }\n\n /** 启动:起 HookBridge + 连所有 server(带自动重连)。 */\n async start(): Promise<void> {\n this.obs.emitEvent({ category: \"daemon\", level: \"info\", event: \"daemon.start\", msg: `device=${this.cfg.deviceId}` });\n\n // HookBridge:跨所有连接路由 sessionKey\n this.bridge = new HookBridge(\n (sessionKey: string) => this.routeHook(sessionKey),\n this.cfg.hookBridge?.token ? { token: this.cfg.hookBridge.token } : undefined,\n );\n const port = await this.bridge.listen(this.cfg.hookBridge?.port ?? 4318);\n console.log(`[daemon] HookBridge on :${port}`);\n\n // 可观测 HTTP 服务(人/监控看状态)\n if (this.cfg.obs?.enabled !== false) {\n this.obsServer = new ObsServer({\n bus: this.obs,\n metrics: this.metrics,\n store: this.store,\n token: this.cfg.obs?.token,\n health: () => this.health(),\n sessions: () => this.allSessions(),\n });\n const obsPort = await this.obsServer.listen(this.cfg.obs?.port ?? 4319);\n console.log(`[daemon] obs server on http://127.0.0.1:${obsPort} (/health /metrics /sessions /events /stream)`);\n }\n\n if (this.cfg.servers.length === 0) {\n console.warn(\"[daemon] no servers configured — idle. Add servers to config and restart.\");\n }\n for (const s of this.cfg.servers) {\n const client = new PhononClient({\n serverUrl: s.url,\n deviceId: this.cfg.deviceId,\n registry: this.registry,\n store: this.store,\n obs: this.obs,\n trustLocal: s.trustLocal,\n workspaceRoot: this.cfg.workspaceRoot,\n deviceKey: s.deviceKey,\n resolveProjectCwd: (p) => p,\n });\n this.clients.push(client);\n void client.start(); // 长期运行 + 自动重连\n this.obs.emitEvent({ category: \"connection\", level: \"info\", event: \"connection.dial\", msg: `connecting to ${s.url}` });\n console.log(`[daemon] connecting to ${s.url}…`);\n }\n }\n\n /** 健康快照(/health)。 */\n private health(): Record<string, unknown> {\n const connections = this.clients.map((c, i) => ({\n server: this.cfg.servers[i]?.url,\n connected: !!c.connection,\n outboxSize: c.connection?.outboxSize ?? 0,\n }));\n const anyDown = connections.some((c) => !c.connected) && this.cfg.servers.length > 0;\n return {\n ok: !anyDown,\n deviceId: this.cfg.deviceId,\n uptimeSeconds: Math.floor((Date.now() - this.startedAt) / 1000),\n adapters: this.registry.all().map((a) => a.name),\n connections,\n hookBridge: !!this.bridge,\n };\n }\n\n /** 所有连接的 session 快照(/sessions)。 */\n private allSessions(): Array<Record<string, unknown>> {\n const out: Array<Record<string, unknown>> = [];\n for (const c of this.clients) {\n const conn = c.connection;\n if (conn) out.push(...conn.sessionsSnapshot());\n }\n return out;\n }\n\n /** 可观测 HTTP 服务实际端口(测试/外部查询)。 */\n get obsPort(): number {\n return this.obsServer?.port ?? 0;\n }\n\n /** HookBridge 路由:找到 owns 该 session 的连接。sessionKey 形如 agent:<sub>:phonon-<sessionId>。 */\n private routeHook(sessionKey: string): { conn: PhononConnection; sessionId: string } | undefined {\n const m = sessionKey.match(/phonon-(s-\\d+-\\d+)$/);\n const sessionId = m?.[1];\n if (!sessionId) return undefined;\n for (const c of this.clients) {\n const conn = c.connection;\n if (conn?.ownsSession(sessionId)) return { conn, sessionId };\n }\n return undefined;\n }\n\n async stop(): Promise<void> {\n this.obs.emitEvent({ category: \"daemon\", level: \"info\", event: \"daemon.stop\" });\n for (const c of this.clients) c.close();\n for (const a of this.gatewayAdapters) a.close();\n await this.bridge?.close();\n await this.obsServer?.close();\n this.store.close();\n }\n}\n","#!/usr/bin/env node\nimport { PhononDaemon } from \"./daemon.js\";\nimport {\n loadConfig,\n defaultConfig,\n writeConfig,\n redactConfig,\n DEFAULT_CONFIG_PATH,\n type DaemonConfig,\n} from \"./config.js\";\nimport { existsSync } from \"node:fs\";\nimport { cmdDoctor, cmdDiscover, cmdAdapterAdd, cmdAdapterList, cmdPluginInstall } from \"./commands.js\";\n\n/**\n * agent-phonon CLI(bug-bash B4)。\n * agent-phonon init 生成默认配置\n * agent-phonon start 启动 daemon(前台;systemd 托管)\n * agent-phonon server add <url> [--trust-local] 加一个 server 连接\n * agent-phonon server list 列已配 server\n * agent-phonon config 打印当前配置路径与内容\n */\nconst [cmd, ...args] = process.argv.slice(2);\n\nfunction flag(name: string): boolean {\n return args.includes(`--${name}`);\n}\nfunction opt(name: string): string | undefined {\n const i = args.indexOf(`--${name}`);\n return i >= 0 ? args[i + 1] : undefined;\n}\n\nasync function main(): Promise<void> {\n switch (cmd) {\n case \"init\": {\n if (existsSync(DEFAULT_CONFIG_PATH) && !flag(\"force\")) {\n console.error(`config already exists at ${DEFAULT_CONFIG_PATH} (use --force to overwrite)`);\n process.exit(1);\n }\n writeConfig(defaultConfig());\n console.log(`wrote default config → ${DEFAULT_CONFIG_PATH}`);\n console.log(\"Add a server: agent-phonon server add ws://your-server:port --trust-local\");\n break;\n }\n case \"server\": {\n const sub = args[0];\n const cfg = loadConfig();\n if (sub === \"add\") {\n const url = args[1];\n if (!url) {\n console.error(\"usage: agent-phonon server add <url> [--trust-local] [--device-key <key>]\");\n process.exit(1);\n }\n cfg.servers.push({ url, trustLocal: flag(\"trust-local\"), deviceKey: opt(\"device-key\") });\n writeConfig(cfg);\n console.log(`added server ${url} (${cfg.servers.length} total)`);\n } else if (sub === \"list\") {\n if (cfg.servers.length === 0) console.log(\"(no servers configured)\");\n for (const s of cfg.servers) console.log(`- ${s.url}${s.trustLocal ? \" [trustLocal]\" : \"\"}`);\n } else {\n console.error(\"usage: agent-phonon server add|list\");\n process.exit(1);\n }\n break;\n }\n case \"config\": {\n const cfg = loadConfig();\n console.log(`config: ${DEFAULT_CONFIG_PATH}`);\n // 默认脱敏;--show-secrets 才明文(bug-bash#2)\n console.log(JSON.stringify(flag(\"show-secrets\") ? cfg : redactConfig(cfg), null, 2));\n break;\n }\n case \"start\": {\n const cfg: DaemonConfig = loadConfig();\n const daemon = new PhononDaemon(cfg);\n await daemon.start();\n console.log(`[agent-phonon] daemon started (device=${cfg.deviceId}, servers=${cfg.servers.length})`);\n const shutdown = async () => {\n console.log(\"\\n[agent-phonon] shutting down…\");\n await daemon.stop();\n process.exit(0);\n };\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n // 保持前台\n await new Promise(() => {});\n break;\n }\n case \"doctor\":\n cmdDoctor();\n break;\n case \"discover\":\n await cmdDiscover();\n // Some adapters keep background sockets/handles (e.g. OpenClaw Gateway).\n // discover is a one-shot CLI command, so exit explicitly after printing.\n process.exit(0);\n case \"adapter\": {\n const sub = args[0];\n if (sub === \"add\") cmdAdapterAdd(args[1] ?? \"\", { gatewayUrl: opt(\"gateway-url\"), token: opt(\"token\"), defaultAgent: opt(\"agent\"), baseUrl: opt(\"base-url\"), apiKey: opt(\"api-key\"), model: opt(\"model\"), provider: opt(\"provider\"), wireApi: opt(\"wire-api\"), bin: opt(\"bin\") });\n else if (sub === \"list\") cmdAdapterList();\n else { console.error(\"usage: agent-phonon adapter add <type> | list\"); process.exit(1); }\n break;\n }\n case \"plugin\": {\n const sub = args[0];\n if (sub === \"install\") cmdPluginInstall(args[1] ?? \"\");\n else { console.error(\"usage: agent-phonon plugin install openclaw\"); process.exit(1); }\n break;\n }\n default:\n console.log(\"agent-phonon — device daemon for scheduling local AI agents\\n\");\n console.log(\"setup:\");\n console.log(\" init generate default config\");\n console.log(\" doctor check agent availability / Gateway / plugin\");\n console.log(\" adapter add <type> [opts] configure an adapter override (auto-detect covers common local agents)\");\n console.log(\" adapter list list configured + auto-detected adapters\");\n console.log(\" plugin install openclaw install OpenClaw HITL plugin\");\n console.log(\" server add <url> [--trust-local] [--device-key <k>]\");\n console.log(\" server list\");\n console.log(\" config [--show-secrets] show config (redacted by default)\");\n console.log(\"\\nrun:\");\n console.log(\" discover list available agents (without starting daemon)\");\n console.log(\" start start the daemon (systemd-managed)\");\n console.log(\"\\nadapter add examples:\");\n console.log(\" agent-phonon adapter add openclaw --agent phonon\");\n console.log(\" agent-phonon adapter add codex --base-url https://gw/v1 --api-key <k> --model gpt-5.5\");\n console.log(\" agent-phonon adapter add hermes\");\n break;\n }\n}\n\nmain().catch((err) => {\n console.error(\"[agent-phonon]\", (err as Error)?.message ?? err);\n process.exit(1);\n});\n"],"mappings":"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","names":["z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","resolve","resolve","args","flag","mkdir","rm","readdir","stat","existsSync","join","resolve","readFile","resolve","homedir","mkdirSync","dirname","join","existsSync","key","mkdirSync","dirname","join","mkdir","readdir","lstat","writeFile","basename","dirname","join","resolve","sep","probe","type","execFile","promisify","execFileAsync","execFile","promisify","execFileAsync","cmd","spawn","existsSync","readFileSync","homedir","join","readFile","writeFile","type","args","join","homedir","existsSync","readFileSync","resolve","spawn","resolve","randomUUID","existsSync","readFileSync","homedir","join","resolve","randomUUID","join","homedir","existsSync","readFileSync","WebSocket","resolve","WebSocket","RpcPeer","resolve","DatabaseSync","existsSync","spawn","homedir","join","existsSync","statSync","CAPABILITIES","join","homedir","existsSync","statSync","args","resolve","spawn","type","spawn","DatabaseSync","homedir","join","existsSync","CAPABILITIES","join","homedir","existsSync","args","resolve","spawn","type","spawn","randomUUID","DatabaseSync","homedir","join","existsSync","CAPABILITIES","randomUUID","args","resolve","spawn","existsSync","join","homedir","DatabaseSync","EventEmitter","spawn","randomUUID","writeFileSync","rmSync","existsSync","tmpdir","homedir","join","CAPABILITIES","join","tmpdir","writeFileSync","randomUUID","args","resolve","spawn","rmSync","type","homedir","existsSync","readFileSync","existsSync","mkdirSync","writeFileSync","chmodSync","homedir","hostname","join","dirname","existsSync","mkdirSync","rmSync","writeFileSync","readFileSync","homedir","platform","join","dirname","args","platform","homedir","join","existsSync","type","dirname","rmSync","mkdirSync","readFileSync","writeFileSync","createServer","resolve","existsSync","existsSync"]}
|