diff --git a/README.md b/README.md index f4ca876..8d5c85f 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ - 当前 App Server heartbeat discovery 已新增 `thread/list / thread/loaded/list` 线程可见性摘要,设备详情页会展示线程总数、已加载线程、活跃线程和最新更新时间;metadata 只保留非归档线程的 `id / name / sourceKind / status / updatedAt / loaded` 轻量目录,不保存 cwd、本地路径、turn 内容、用户正文或内部 prompt。 - 当前 App Server heartbeat discovery 已新增 `thread/turns/list` turn 运行态摘要,设备详情页会展示总轮次、运行中轮次、完成轮次和最新 turn 更新时间;请求固定使用 `itemsView=notLoaded`,metadata 只保留每个线程的 turn 计数、最近状态和更新时间,不保存 turn id、items、用户输入、模型输出或内部 prompt。 - 当前 App Server heartbeat discovery 已支持 `skills/extraRoots/set` 共享 Skill 根目录下发摘要,设备详情页会展示“共享 Skill 根”;metadata 不保存根目录绝对路径、Skill 文件路径、token 或配置原文。 +- 当前 App Server heartbeat discovery 已支持 `hooks/list` 钩子治理摘要,设备详情页会展示“Hook”;metadata 只保留 hook 数、启用数、受管 / 可信 / 修改 / 未信任计数、warning / error 计数和事件 / handler 类型,不保存 hook key、command、sourcePath、statusMessage、hash、error message 或本地路径。 - `GET http://127.0.0.1:4317/api/v1/skills` 正常,已返回本机扫描到的 Codex Skill - `POST http://127.0.0.1:4317/api/v1/heartbeat` 正常,且会顺带触发 `thread-context` 上报 - `local-agent` 当前每 5 秒轮询一次本机 Skill lifecycle 请求;默认打开 `skillLifecycleEnabled=true`。远程 `install` 或带 `sourceUrl` 的更新必须命中 `skillLifecycleAllowedSources` 或 `skillLifecycleTrustedSources`,为空时只允许既有本地 Skill 的 `update / rollback / uninstall / version_lock`;请求携带 `checksum / expectedChecksum` 时会校验 `manifest.json` 或 `SKILL.md` 的 sha256,失败会清理半安装目录或尽量恢复备份。卸载 / 更新 / 回滚前会在 `skillsDir/.boss-skill-backups` 保留备份,卸载仍限制在 `skillsDir` 目录内,版本锁写入 `.boss-skill-locks.json` diff --git a/docs/architecture/ai_handoff_index_cn.md b/docs/architecture/ai_handoff_index_cn.md index b760bae..95f1126 100644 --- a/docs/architecture/ai_handoff_index_cn.md +++ b/docs/architecture/ai_handoff_index_cn.md @@ -153,7 +153,7 @@ - Web 和原生 Android 当前都已经接上“新设备导入草稿 -> 勾选 -> 决议预览 -> 应用导入”的前台页面;已绑定生产设备继续保留 heartbeat 自动导入链路 - 原生首页的刷新失败策略当前已改成按当前 tab 独立判错,不会再因为 `设备 / 设置 / OTA` 的旁路请求失败把会话页刷新一并判成失败 - 当前量产方向已经明确为“Boss 企业控制面 + 可插拔执行协议”:多租户、权限、审批、审计、备份、回退和 Skill 治理由 Boss 承担,Codex App Server / Codex MCP / Codex CLI / Computer Use / 业务系统 API 都作为 provider 接入;详见 `docs/architecture/enterprise_ai_ops_architecture_cn.md` -- 当前 Codex App Server 已完成十七批接入:boss-agent 默认开启 `local-agent/codex-app-server-runner.mjs` 作为 Codex 绑定入口,优先走 `codex app-server` stdio,也可灰度连接 `ws://127.0.0.1:` 或 `unix://PATH` 同机长驻 App Server;长驻连接支持 `Authorization: Bearer `,配置上优先使用 `codexAppServerAuthTokenFile`。turn 启动前失败才回退 CLI,turn 启动后不重复执行;桌面远程控制默认先走 `codex-computer-use`,失败后回退 `cua-driver-computer-use`。2026-06-03 已按本机 `codex-cli 0.136.0-alpha.2` 生成协议快照 `docs/protocol-snapshots/codex-app-server/0.136.0-alpha.2/`,并把 `turn/plan/updated`、`turn/diff/updated`、`item/started|completed`、`thread/started`、`item/*/requestApproval`、`item/autoApprovalReview/*`、`guardianWarning`、`serverRequest/resolved`、`item/fileChange/patchUpdated`、`thread/status/changed`、`thread/realtime/*`、`model/rerouted`、`thread/tokenUsage/updated`、`mcpServer/startupStatus/updated`、`remoteControl/status/changed`、`windowsSandbox/setupCompleted`、`thread/goal/*`、`thread/settings/updated`、`thread/compacted`、`account/updated`、`account/rateLimits/updated`、`model/verification`、`warning`、`configWarning`、`deprecationNotice`、`ThreadItem.collabToolCall`、`ThreadItem.contextCompaction`、`mcpToolCall`、`dynamicToolCall`、`webSearch`、`imageView`、`imageGeneration`、`hook/started|completed`、`enteredReviewMode`、`exitedReviewMode`、`commandExecution`、`ThreadItem.plan`、`ThreadItem.reasoning.summary` 归一到 Boss `execution_progress` 卡片;realtime 只保留状态、文本摘要和计数,运行状态只保留模型切换、上下文用量、MCP 状态、远控连接摘要和 Windows 沙箱准备状态,线程配置只保留目标、模型、审批、沙箱、协作模式和压缩状态,线程协作只保留工具名、状态、目标类型、目标数量和智能体状态集合,工具活动只保留类型、名称、状态和安全摘要,图像生成只保留状态与安全文件名,钩子生命周期只保留事件名、处理器类型、状态、来源、执行模式和耗时,思考摘要只保留官方 summary 文本和状态,账号状态只保留认证方式、套餐、额度窗口、积分余额和模型校验摘要,不保存 SDP、音频原始数据、raw item、remote installationId、cwd、turnId、配置文件路径、collab 源/目标线程 ID、collab receiverThreadIds、collab prompt、agentsStates 私有消息、共享 Skill 根绝对路径、tool arguments/result/contentItems、web URL token、命令正文/输出、raw reasoning content、reasoning item id、imageGeneration revisedPrompt/result、hook sourcePath/statusMessage/entries、Windows sandbox sourcePath/samplePaths/本地绝对路径或未清洗密钥。heartbeat 已能缓存 `model/list / skills/list / skills/extraRoots/set / plugin/list / app/list / modelProvider/capabilities/read / experimentalFeature/list / collaborationMode/list / permissionProfile/list / mcpServerStatus/list / account/read / account/rateLimits/read / config/read / configRequirements/read / externalAgentConfig/detect / thread/list / thread/loaded/list / thread/turns/list` 的能力摘要;同批已补 `turn/steer` 活跃 turn 干预和 `POST /api/v1/projects/[projectId]/thread-collaboration` 服务端线程协作排队入口。MCP、权限、账号、配置、外部 Agent、线程、turn 和 Skill extra roots discovery 只保留安全摘要,不保存 resource URI、权限文件规则、工具参数、邮箱、完整 config、本地路径、迁移描述、turn id、turn items、用户正文、模型输出、共享 Skill 根绝对路径或 token。 +- 当前 Codex App Server 已完成十八批接入:boss-agent 默认开启 `local-agent/codex-app-server-runner.mjs` 作为 Codex 绑定入口,优先走 `codex app-server` stdio,也可灰度连接 `ws://127.0.0.1:` 或 `unix://PATH` 同机长驻 App Server;长驻连接支持 `Authorization: Bearer `,配置上优先使用 `codexAppServerAuthTokenFile`。turn 启动前失败才回退 CLI,turn 启动后不重复执行;桌面远程控制默认先走 `codex-computer-use`,失败后回退 `cua-driver-computer-use`。2026-06-03 已按本机 `codex-cli 0.136.0-alpha.2` 生成协议快照 `docs/protocol-snapshots/codex-app-server/0.136.0-alpha.2/`,并把 `turn/plan/updated`、`turn/diff/updated`、`item/started|completed`、`thread/started`、`item/*/requestApproval`、`item/autoApprovalReview/*`、`guardianWarning`、`serverRequest/resolved`、`item/fileChange/patchUpdated`、`thread/status/changed`、`thread/realtime/*`、`model/rerouted`、`thread/tokenUsage/updated`、`mcpServer/startupStatus/updated`、`remoteControl/status/changed`、`windowsSandbox/setupCompleted`、`thread/goal/*`、`thread/settings/updated`、`thread/compacted`、`account/updated`、`account/rateLimits/updated`、`model/verification`、`warning`、`configWarning`、`deprecationNotice`、`ThreadItem.collabToolCall`、`ThreadItem.contextCompaction`、`mcpToolCall`、`dynamicToolCall`、`webSearch`、`imageView`、`imageGeneration`、`hook/started|completed`、`enteredReviewMode`、`exitedReviewMode`、`commandExecution`、`ThreadItem.plan`、`ThreadItem.reasoning.summary` 归一到 Boss `execution_progress` 卡片;realtime 只保留状态、文本摘要和计数,运行状态只保留模型切换、上下文用量、MCP 状态、远控连接摘要和 Windows 沙箱准备状态,线程配置只保留目标、模型、审批、沙箱、协作模式和压缩状态,线程协作只保留工具名、状态、目标类型、目标数量和智能体状态集合,工具活动只保留类型、名称、状态和安全摘要,图像生成只保留状态与安全文件名,钩子生命周期只保留事件名、处理器类型、状态、来源、执行模式和耗时,思考摘要只保留官方 summary 文本和状态,账号状态只保留认证方式、套餐、额度窗口、积分余额和模型校验摘要,不保存 SDP、音频原始数据、raw item、remote installationId、cwd、turnId、配置文件路径、collab 源/目标线程 ID、collab receiverThreadIds、collab prompt、agentsStates 私有消息、共享 Skill 根绝对路径、hook key/command/sourcePath/statusMessage/hash/error message、tool arguments/result/contentItems、web URL token、命令正文/输出、raw reasoning content、reasoning item id、imageGeneration revisedPrompt/result、hook sourcePath/statusMessage/entries、Windows sandbox sourcePath/samplePaths/本地绝对路径或未清洗密钥。heartbeat 已能缓存 `model/list / skills/list / skills/extraRoots/set / hooks/list / plugin/list / app/list / modelProvider/capabilities/read / experimentalFeature/list / collaborationMode/list / permissionProfile/list / mcpServerStatus/list / account/read / account/rateLimits/read / config/read / configRequirements/read / externalAgentConfig/detect / thread/list / thread/loaded/list / thread/turns/list` 的能力摘要;同批已补 `turn/steer` 活跃 turn 干预和 `POST /api/v1/projects/[projectId]/thread-collaboration` 服务端线程协作排队入口。MCP、权限、账号、配置、外部 Agent、线程、turn、Hook 和 Skill extra roots discovery 只保留安全摘要,不保存 resource URI、权限文件规则、工具参数、邮箱、完整 config、本地路径、迁移描述、turn id、turn items、用户正文、模型输出、hook 命令、共享 Skill 根绝对路径或 token。 - 当前 boss-agent 已支持 Mac OTA:`local-agent/boss-agent-ota-runner.mjs` 默认开启,每 5 分钟检查服务端最新包;状态页可手动检查或下载并安装,安装时保留原绑定配置,只更新版本号和本机 runtime 路径。最新验证版本为 `20260516221619`,已在 MacBook Air `macbook-air` 上确认 OTA 下载校验、暂存、覆盖安装后不会误切到默认 `config.cloud.json`。正式分发脚本已预留 Developer ID 公证路径:`BOSS_AGENT_NOTARIZE=1` 配合 notary profile 或 Apple ID 凭据。 - 当前量产治理已补设备撤权和任务可靠性底座:`revoke_device` 会清空设备 token、标记离线并阻断 heartbeat / 任务认领 / Skill 同步 / 日志上报 / boss-agent OTA;`MasterAgentTask` claim 会记录 attempt 和 lease,运行中任务可按租约重试,超过上限转 `timed_out`,用户或管理员可通过 cancel 接口转 `canceled` 且迟到 complete 不覆盖终态。 - 当前群聊 `dispatch_execution` 完成回写已补幂等,重复完成不会再向群聊重复追加结果 diff --git a/docs/architecture/api_and_service_inventory_cn.md b/docs/architecture/api_and_service_inventory_cn.md index 0766fe2..07fd831 100644 --- a/docs/architecture/api_and_service_inventory_cn.md +++ b/docs/architecture/api_and_service_inventory_cn.md @@ -117,12 +117,13 @@ - 当前 `RemoteRuntimeAdapter` 还负责拦截固定模式的线程内部环境提示;命中后会直接改写成失败,避免把只读/cwd 这类脏文本写进聊天记录 - 当前普通单线程 `conversation_reply` 在真正执行 `codex exec resume` 前,会先把 Boss 用户消息镜像进目标 Codex Desktop rollout;定位优先走 `state_5.sqlite`,不可用时回退扫描 `~/.codex/sessions`,并按 `sourceMessageId` 去重 - 当前 Codex Desktop 同步新增常驻刷新桥:`scripts/codex-desktop-refresh-bridge-daemon.mjs` 通过 launchd 监听 `127.0.0.1:4318`,暴露 `POST /api/v1/codex-desktop/refresh`、`GET /api/v1/codex-desktop/events`、`GET /api/v1/codex-desktop/events/recent` 和 `GET /api/v1/codex-desktop/capabilities`;`local-agent` 会优先调用 refresh endpoint,失败时回退到 `scripts/codex-desktop-refresh-hint.mjs` 命令式刷新。SSE 事件只包含线程引用、消息 ID、状态、deep link 等安全元数据,不包含用户正文或内部 prompt;`scripts/codex-desktop-event-consumer.mjs` 可作为 Desktop 插件/IPC 接入前的订阅 smoke;`scripts/codex-desktop-integration-probe.mjs` 负责只读探测 Codex.app 能力 -- 当前新增 Codex App Server runner:`local-agent/codex-app-server-runner.mjs`。boss-agent 默认配置 `codexAppServerEnabled=true`,会接管 `conversation_reply / dispatch_execution`;它默认通过 stdio 启动 `codex app-server`,也支持 `codexAppServerTransport=ws + codexAppServerUrl=ws://127.0.0.1:` 或 `codexAppServerTransport=unix + codexAppServerUrl=unix:///absolute/path.sock` 连接同机长驻 App Server,bearer token 可通过 `codexAppServerAuthTokenFile` 读取并在握手时发送 `Authorization: Bearer `。runner 执行 `initialize -> thread/resume|thread/start -> turn/start|turn/steer`,并把 `item/agentMessage/delta` 或 `item/completed` 归一成 Boss 任务回复;当 App Server 对单个 JSON-RPC 请求返回 `-32001 / retry later` 时,runner 会做最多 3 次指数退避重试。turn 启动前失败可回退 CLI,turn 启动后失败不回退,避免重复执行。2026-05-31 起,runner 会把 `turn/plan/updated`、`turn/diff/updated`、`item/started|completed`、`thread/started` 归一成 `executionProgress.steps / branch / artifacts / agents`,把 `item/*/requestApproval`、`item/autoApprovalReview/*`、`guardianWarning`、`serverRequest/resolved`、`item/fileChange/patchUpdated` 归一成 `executionProgress.approvals / warnings / fileChanges`,把 `thread/status/changed`、`thread/realtime/started|transcript|outputAudio|itemAdded|error|closed` 归一成 `executionProgress.threadStatus / realtime`,把 `model/rerouted`、`thread/tokenUsage/updated`、`mcpServer/startupStatus/updated`、`remoteControl/status/changed` 归一成 `executionProgress.modelRoute / tokenUsage / mcpServers / remoteControl`,并把 `thread/goal/*`、`thread/settings/updated`、`thread/compacted`、`account/updated`、`account/rateLimits/updated`、`model/verification`、`warning`、`configWarning`、`deprecationNotice`、`ThreadItem.collabToolCall`、`ThreadItem.contextCompaction`、`mcpToolCall`、`dynamicToolCall`、`webSearch`、`imageView`、`imageGeneration`、`hook/started|completed`、`windowsSandbox/setupCompleted`、`enteredReviewMode`、`exitedReviewMode`、`commandExecution`、`ThreadItem.plan`、`ThreadItem.reasoning.summary` 归一成线程配置、账号状态、模型校验、安全提醒、线程协作、上下文压缩、工具活动、图片产物、钩子生命周期、Windows 沙箱准备状态、计划步骤和思考摘要;新版 `ThreadItem.collabToolCall.receiverThreadIds / agentsStates` 只归一为目标数量和 agent 状态集合。服务端 complete 回写会与本地 Git/GitHub 进度合并,且不保存 SDP、音频 base64、raw realtime item、remote installationId、cwd、turnId、配置路径、collab 源/目标线程 ID、receiverThreadIds、collab prompt、agentsStates 私有消息、tool arguments/result/contentItems、web URL token、命令正文/输出、raw reasoning content、reasoning item id、imageGeneration revisedPrompt/result、hook sourcePath/statusMessage/entries、Windows sandbox sourcePath/samplePaths/本地绝对路径或未清洗的 MCP 错误。heartbeat 同时支持按 TTL 拉取 `model/list / skills/list / plugin/list / app/list / modelProvider/capabilities/read`,并把摘要保存在 `capabilities.codexAppServer.metadata`。 +- 当前新增 Codex App Server runner:`local-agent/codex-app-server-runner.mjs`。boss-agent 默认配置 `codexAppServerEnabled=true`,会接管 `conversation_reply / dispatch_execution`;它默认通过 stdio 启动 `codex app-server`,也支持 `codexAppServerTransport=ws + codexAppServerUrl=ws://127.0.0.1:` 或 `codexAppServerTransport=unix + codexAppServerUrl=unix:///absolute/path.sock` 连接同机长驻 App Server,bearer token 可通过 `codexAppServerAuthTokenFile` 读取并在握手时发送 `Authorization: Bearer `。runner 执行 `initialize -> thread/resume|thread/start -> turn/start|turn/steer`,并把 `item/agentMessage/delta` 或 `item/completed` 归一成 Boss 任务回复;当 App Server 对单个 JSON-RPC 请求返回 `-32001 / retry later` 时,runner 会做最多 3 次指数退避重试。turn 启动前失败可回退 CLI,turn 启动后失败不回退,避免重复执行。2026-05-31 起,runner 会把 `turn/plan/updated`、`turn/diff/updated`、`item/started|completed`、`thread/started` 归一成 `executionProgress.steps / branch / artifacts / agents`,把 `item/*/requestApproval`、`item/autoApprovalReview/*`、`guardianWarning`、`serverRequest/resolved`、`item/fileChange/patchUpdated` 归一成 `executionProgress.approvals / warnings / fileChanges`,把 `thread/status/changed`、`thread/realtime/started|transcript|outputAudio|itemAdded|error|closed` 归一成 `executionProgress.threadStatus / realtime`,把 `model/rerouted`、`thread/tokenUsage/updated`、`mcpServer/startupStatus/updated`、`remoteControl/status/changed` 归一成 `executionProgress.modelRoute / tokenUsage / mcpServers / remoteControl`,并把 `thread/goal/*`、`thread/settings/updated`、`thread/compacted`、`account/updated`、`account/rateLimits/updated`、`model/verification`、`warning`、`configWarning`、`deprecationNotice`、`ThreadItem.collabToolCall`、`ThreadItem.contextCompaction`、`mcpToolCall`、`dynamicToolCall`、`webSearch`、`imageView`、`imageGeneration`、`hook/started|completed`、`windowsSandbox/setupCompleted`、`enteredReviewMode`、`exitedReviewMode`、`commandExecution`、`ThreadItem.plan`、`ThreadItem.reasoning.summary` 归一成线程配置、账号状态、模型校验、安全提醒、线程协作、上下文压缩、工具活动、图片产物、钩子生命周期、Windows 沙箱准备状态、计划步骤和思考摘要;新版 `ThreadItem.collabToolCall.receiverThreadIds / agentsStates` 只归一为目标数量和 agent 状态集合。服务端 complete 回写会与本地 Git/GitHub 进度合并,且不保存 SDP、音频 base64、raw realtime item、remote installationId、cwd、turnId、配置路径、collab 源/目标线程 ID、receiverThreadIds、collab prompt、agentsStates 私有消息、tool arguments/result/contentItems、web URL token、命令正文/输出、raw reasoning content、reasoning item id、imageGeneration revisedPrompt/result、hook sourcePath/statusMessage/entries、Windows sandbox sourcePath/samplePaths/本地绝对路径或未清洗的 MCP 错误。heartbeat 同时支持按 TTL 拉取 `model/list / skills/list / hooks/list / plugin/list / app/list / modelProvider/capabilities/read`,并把摘要保存在 `capabilities.codexAppServer.metadata`。 - App Server heartbeat discovery 现在还会按 TTL 拉取 `experimentalFeature/list / collaborationMode/list / permissionProfile/list / mcpServerStatus/list`,写入 `capabilities.codexAppServer.metadata.experimentalFeatures / collaborationModes / permissionProfiles / mcpServers`。这些字段用于 APP/后台治理页展示 Codex 当前可用的实验特性、多 Agent/协作模式、权限 profile 和 MCP 服务健康;MCP 请求固定使用 `detail=toolsAndAuthOnly`,服务端状态里不保存 resource URI、工具参数、permission profile 文件规则、本地路径或密钥。 - App Server heartbeat discovery 现在还会按 TTL 拉取 `account/read / account/rateLimits/read / config/read / configRequirements/read / externalAgentConfig/detect`,写入 `capabilities.codexAppServer.metadata.accountSummary / rateLimitSummary / appConfigSummary / configRequirements / externalAgentMigration`。这些字段用于 APP/后台展示账号、额度、App 配置、企业托管要求和外部 Agent 迁移候选摘要;当前只做观测,不通过 Boss 远程写 `config.toml` 或执行外部 Agent 导入,且不保存邮箱、完整 config、API key、本地路径或迁移描述。 - App Server heartbeat discovery 现在还会按 TTL 拉取 `thread/list / thread/loaded/list`,写入 `capabilities.codexAppServer.metadata.threadSummary`。该字段用于 APP/后台展示 Codex 当前可见线程数量、加载态、活跃态和非归档线程轻量目录;目录只保留 `id / name / sourceKind / status / updatedAt / loaded`,不保存 cwd、本地路径、turn 内容、用户正文或内部 prompt。 - App Server heartbeat discovery 现在还会按 TTL 对非归档可见线程拉取 `thread/turns/list`,写入 `capabilities.codexAppServer.metadata.threadTurnSummary`。该字段用于 APP/后台展示 Codex 当前线程 turn 运行态;请求固定 `itemsView=notLoaded`,只保留 turn 计数、运行中 / 完成计数、最近状态和更新时间,不保存 turn id、items、用户正文、模型输出或内部 prompt。 - App Server heartbeat discovery 现在支持 `skills/extraRoots/set`:配置 `codexAppServerSkillExtraRoots` 或环境变量 `BOSS_CODEX_APP_SERVER_SKILL_EXTRA_ROOTS` 后,runner 会先把共享 Skill 根下发给 App Server,再刷新 `skills/list`,并写入 `capabilities.codexAppServer.metadata.skillExtraRootsSummary`。该字段用于 APP/后台展示企业共享 Skill 根是否已下发;只保留数量、basename 和状态,不保存根目录绝对路径、Skill 文件路径或配置原文。 +- App Server heartbeat discovery 现在支持 `hooks/list`,写入 `capabilities.codexAppServer.metadata.hookSummary`。该字段用于 APP/后台展示本机 Codex hook 治理状态;只保留 workspace 数、hook 数、启用数、受管 / 可信 / 修改 / 未信任计数、warning / error 计数和事件 / handler 类型,不保存 hook key、command、sourcePath、statusMessage、hash、error message 或本地路径。 - 当前 Codex App Server runner 已新增第一版 Boss Inter-Thread Broker:任务携带 `intentCategory=thread_collaboration`、`sourceCodexThreadRef` 和 `targetCodexThreadRef` 时,会先 `thread/read` 源线程,再通过 `thread/inject_items` 向目标线程注入受控摘要,最后 `turn/start` 目标线程;服务端入口是 `POST /api/v1/projects/[projectId]/thread-collaboration`,负责权限、源/目标线程校验和任务排队。这不是假设官方线程 P2P,而是 Boss 自己做线程协作编排。 - 当前 boss-agent Mac OTA 已接入:`local-agent/boss-agent-ota-runner.mjs` 会用设备 token 调 Boss 服务端 `/api/v1/boss-agent/ota` 检查最新 Mac 运行包,`/api/v1/boss-agent/ota/apply` 会下载 `boss-agent-mac-latest.zip`、校验 sha256、暂存安装 wrapper,并拉起本机安装器;安装脚本会保留绑定配置并只更新版本号与本机 runtime 路径。安装器会优先沿用当前 LaunchAgent active config,并保留所有 `config*.json`,避免多电脑场景中误绑定到默认设备配置。当前最新验证包为 `20260516221619`;构建脚本支持 `BOSS_AGENT_NOTARIZE=1` 的 Developer ID 公证路径。 - 当前 `local-agent` 还新增了两条统一电脑控制 runtime: diff --git a/docs/architecture/codex_server_progress_card_cn.md b/docs/architecture/codex_server_progress_card_cn.md index 3ff8d1a..f59df52 100644 --- a/docs/architecture/codex_server_progress_card_cn.md +++ b/docs/architecture/codex_server_progress_card_cn.md @@ -13,16 +13,16 @@ Codex App Server 是更适合 Boss 长期接入的协议层,因为它面向富 - approvals - streamed agent events - Thread / Turn / Item -- model/list、skills/list、skills/extraRoots/set、plugin/list、app/list +- model/list、skills/list、skills/extraRoots/set、hooks/list、plugin/list、app/list - command execution、file change、tool input、MCP tool-call approvals Boss 不能直接把 App Server 原始 Thread / Turn / Item 字段写进业务层。当前第一批已经新增 `local-agent/codex-app-server-runner.mjs`,把 App Server 的 `thread/resume | thread/start -> turn/start -> item/agentMessage/delta -> turn/completed` 映射成 Boss 的普通任务完成回写。 2026-05-31 已继续把 `turn/plan/updated`、`turn/diff/updated`、`item/started|completed`、`thread/started` 这类协议事件归一化为 Boss `execution_progress` 的步骤、分支变更、产物和后台智能体。同日第二批补齐 `item/*/requestApproval`、`item/autoApprovalReview/*`、`guardianWarning`、`serverRequest/resolved` 和 `item/fileChange/patchUpdated` 的安全摘要映射,APP 只展示审批状态、风险提醒和文件路径,不展示完整命令、diff、系统提示词或密钥。第三批已把 `thread/status/changed` 与 `thread/realtime/*` 归一成 `executionProgress.threadStatus / realtime`,APP 只展示活跃/等待审批/等待用户输入、realtime 文本摘要、音频片段计数和关闭/错误原因;第四批已把 `model/rerouted`、`thread/tokenUsage/updated`、`mcpServer/startupStatus/updated` 和 `remoteControl/status/changed` 归一成 `executionProgress.modelRoute / tokenUsage / mcpServers / remoteControl`,用于 APP “运行状态”区块。 -2026-06-01 第五批已把 `thread/goal/updated|cleared`、`thread/settings/updated` 和 `thread/compacted` 归一成 `executionProgress.threadGoal / threadSettings / compaction`,用于 APP “线程配置”区块;第六批已把 `account/updated`、`account/rateLimits/updated`、`model/verification`、`warning`、`configWarning`、`deprecationNotice` 归一成 `executionProgress.accountStatus / modelVerification / warnings`;第七批已把官方 `ThreadItem.collabToolCall` 归一成 `executionProgress.threadCollaboration`,并按官方建议把新版 `ThreadItem.contextCompaction` 映射回 `executionProgress.compaction`;第八批已把 `mcpToolCall`、`dynamicToolCall`、`webSearch`、`imageView`、`enteredReviewMode`、`exitedReviewMode` 和 `commandExecution` 归一成 `executionProgress.toolActivities`;第九批已把官方 `ThreadItem.plan` 的最终 `item/completed` 文本映射为 `executionProgress.steps`,并把 `ThreadItem.reasoning.summary` 映射为 `executionProgress.reasoningSummary`;第十批已把 `ThreadItem.imageGeneration` 安全映射为 `executionProgress.toolActivities` 的图像生成活动和 `executionProgress.artifacts` 的图片产物;第十一批已把 `hook/started|completed` 安全映射为 `executionProgress.toolActivities` 的钩子活动,供 APP 以“钩子”轻卡展示企业治理和插件生命周期状态;第十二批已把 `windowsSandbox/setupCompleted` 安全映射为 `executionProgress.windowsSandbox`,供 APP 在“运行状态”里展示 Windows 沙箱准备状态、setup mode 和脱敏错误摘要;第十三批已把 heartbeat discovery 扩展到 `experimentalFeature/list`、`collaborationMode/list`、`permissionProfile/list` 和 `mcpServerStatus/list`,供设备详情、APP 和 PC 后台看到实验特性、协作模式、权限 Profile 与 MCP 服务摘要;第十四批已把 `account/read`、`account/rateLimits/read`、`config/read`、`configRequirements/read` 和 `externalAgentConfig/detect` 纳入 heartbeat discovery,用于展示账号、套餐、额度、App 配置、托管要求和外部 Agent 迁移候选摘要;第十五批已把 `thread/list` 和 `thread/loaded/list` 纳入 heartbeat discovery,用于展示线程总数、已加载线程、活跃线程、归档线程和非归档可见线程轻量目录;第十六批已把 `thread/turns/list` 纳入 heartbeat discovery,用于展示总轮次、运行中轮次、完成轮次和每个非归档线程的最近 turn 状态摘要;第十七批已按 `codex-cli 0.136.0-alpha.2` 补齐 `skills/extraRoots/set`,支持把企业共享 Skill 根下发给 App Server 后再拉取 `skills/list`,并把新版 `ThreadItem.collabToolCall.receiverThreadIds / agentsStates` 安全映射成目标数量和 agent 状态集合。 +2026-06-01 第五批已把 `thread/goal/updated|cleared`、`thread/settings/updated` 和 `thread/compacted` 归一成 `executionProgress.threadGoal / threadSettings / compaction`,用于 APP “线程配置”区块;第六批已把 `account/updated`、`account/rateLimits/updated`、`model/verification`、`warning`、`configWarning`、`deprecationNotice` 归一成 `executionProgress.accountStatus / modelVerification / warnings`;第七批已把官方 `ThreadItem.collabToolCall` 归一成 `executionProgress.threadCollaboration`,并按官方建议把新版 `ThreadItem.contextCompaction` 映射回 `executionProgress.compaction`;第八批已把 `mcpToolCall`、`dynamicToolCall`、`webSearch`、`imageView`、`enteredReviewMode`、`exitedReviewMode` 和 `commandExecution` 归一成 `executionProgress.toolActivities`;第九批已把官方 `ThreadItem.plan` 的最终 `item/completed` 文本映射为 `executionProgress.steps`,并把 `ThreadItem.reasoning.summary` 映射为 `executionProgress.reasoningSummary`;第十批已把 `ThreadItem.imageGeneration` 安全映射为 `executionProgress.toolActivities` 的图像生成活动和 `executionProgress.artifacts` 的图片产物;第十一批已把 `hook/started|completed` 安全映射为 `executionProgress.toolActivities` 的钩子活动,供 APP 以“钩子”轻卡展示企业治理和插件生命周期状态;第十二批已把 `windowsSandbox/setupCompleted` 安全映射为 `executionProgress.windowsSandbox`,供 APP 在“运行状态”里展示 Windows 沙箱准备状态、setup mode 和脱敏错误摘要;第十三批已把 heartbeat discovery 扩展到 `experimentalFeature/list`、`collaborationMode/list`、`permissionProfile/list` 和 `mcpServerStatus/list`,供设备详情、APP 和 PC 后台看到实验特性、协作模式、权限 Profile 与 MCP 服务摘要;第十四批已把 `account/read`、`account/rateLimits/read`、`config/read`、`configRequirements/read` 和 `externalAgentConfig/detect` 纳入 heartbeat discovery,用于展示账号、套餐、额度、App 配置、托管要求和外部 Agent 迁移候选摘要;第十五批已把 `thread/list` 和 `thread/loaded/list` 纳入 heartbeat discovery,用于展示线程总数、已加载线程、活跃线程、归档线程和非归档可见线程轻量目录;第十六批已把 `thread/turns/list` 纳入 heartbeat discovery,用于展示总轮次、运行中轮次、完成轮次和每个非归档线程的最近 turn 状态摘要;第十七批已按 `codex-cli 0.136.0-alpha.2` 补齐 `skills/extraRoots/set`,支持把企业共享 Skill 根下发给 App Server 后再拉取 `skills/list`,并把新版 `ThreadItem.collabToolCall.receiverThreadIds / agentsStates` 安全映射成目标数量和 agent 状态集合;第十八批已把 `hooks/list` 纳入 heartbeat discovery,用于展示本机 Codex hook 数、启用数、信任状态和 warning/error 计数。 -`thread/realtime/sdp`、音频 base64、原始 realtime item、remote installationId、thread settings 的 `cwd`、compaction `turnId`、collaboration settings 内部 prompt、collabToolCall 源/目标线程 ID、`receiverThreadIds`、`agentsStates.message`、共享 Skill 根绝对路径、tool arguments/result/contentItems、web URL token、命令正文/输出、raw reasoning `content`、reasoning item id、imageGeneration 原始 result/revisedPrompt、hook id/sourcePath/statusMessage/entries、Windows sandbox sourcePath/samplePaths、本地绝对路径、permission profile 文件规则、MCP resource URI、账号邮箱、API key、完整 config、外部 Agent 迁移描述、turn id、turn items、turn 内容、用户正文、模型输出和未清洗的 MCP 错误不入账。 +`thread/realtime/sdp`、音频 base64、原始 realtime item、remote installationId、thread settings 的 `cwd`、compaction `turnId`、collaboration settings 内部 prompt、collabToolCall 源/目标线程 ID、`receiverThreadIds`、`agentsStates.message`、共享 Skill 根绝对路径、hook key/command/sourcePath/statusMessage/hash/error message、tool arguments/result/contentItems、web URL token、命令正文/输出、raw reasoning `content`、reasoning item id、imageGeneration 原始 result/revisedPrompt、hook id/sourcePath/statusMessage/entries、Windows sandbox sourcePath/samplePaths、本地绝对路径、permission profile 文件规则、MCP resource URI、账号邮箱、API key、完整 config、外部 Agent 迁移描述、turn id、turn items、turn 内容、用户正文、模型输出和未清洗的 MCP 错误不入账。 官方文档入口:`https://developers.openai.com/codex/app-server` @@ -41,10 +41,10 @@ Boss 不能直接把 App Server 原始 Thread / Turn / Item 字段写进业务 - 本机 `codex --version`:`codex-cli 0.136.0-alpha.2` - 本机 `codex app-server --help` 已可用;本机 help 当前显示 `--listen` 支持 `stdio://`、`unix://`、`unix://PATH`、`ws://IP:PORT` 和 `off` - 本机 `codex app-server --help` 当前已经支持 `--ws-auth capability-token|signed-bearer-token`、`--ws-token-file`、`--ws-token-sha256`、`--ws-shared-secret-file`、issuer/audience/clock-skew 等 WebSocket 认证参数 -- 本机协议快照已生成到 `docs/protocol-snapshots/codex-app-server/0.136.0-alpha.2/`,共识别 138 个协议方法;确认支持 `thread/inject_items`、`thread/rollback`、`thread/goal/*`、`turn/steer`、`command/exec`、`thread/realtime/*`、`account/*`、`model/verification`、`configWarning`、`deprecationNotice`、`model/list` 和 `skills/extraRoots/set` +- 本机协议快照已生成到 `docs/protocol-snapshots/codex-app-server/0.136.0-alpha.2/`,共识别 138 个协议方法;确认支持 `thread/inject_items`、`thread/rollback`、`thread/goal/*`、`turn/steer`、`command/exec`、`thread/realtime/*`、`account/*`、`model/verification`、`configWarning`、`deprecationNotice`、`model/list`、`skills/extraRoots/set` 和 `hooks/list` - Boss 当前默认仍以 `stdio` 作为本机 agent 接入方式;`ws://127.0.0.1:` 和 `unix://PATH` 本地长驻 transport 已可灰度接入,WebSocket/Unix WebSocket handshake 支持 `Authorization: Bearer `;非 loopback signed bearer/JWT、自动重连和健康探测仍保留为后续增强,不直接替换当前稳定链路 - 官方文档提示 WebSocket ingress 满载时会返回 JSON-RPC `-32001 / Server overloaded; retry later.`;Boss runner 已对该错误做最多 3 次指数退避重试,避免长驻连接瞬时拥塞直接把用户任务打失败 -- Boss heartbeat 已新增 App Server 能力发现缓存:按 `codexAppServerDiscoveryTtlMs` 拉取 `model/list`、`modelProvider/capabilities/read`、`skills/list`、`plugin/list`、`app/list`、`experimentalFeature/list`、`collaborationMode/list`、`permissionProfile/list`、`mcpServerStatus/list`、`account/read`、`account/rateLimits/read`、`config/read`、`configRequirements/read`、`externalAgentConfig/detect`、`thread/list`、`thread/loaded/list` 和 `thread/turns/list`;配置了 `codexAppServerSkillExtraRoots` / `BOSS_CODEX_APP_SERVER_SKILL_EXTRA_ROOTS` 时,会先调用 `skills/extraRoots/set` 再拉取 `skills/list`,归一成设备 `capabilities.codexAppServer.metadata`;发现失败只记录 warn,不阻塞心跳。MCP discovery 使用 `detail=toolsAndAuthOnly`,turn discovery 固定 `itemsView=notLoaded`,账号、配置、线程和 Skill extra root discovery 只保留安全摘要,不保存邮箱、resource URI、工具参数、完整 config、本地路径、迁移描述、turn id、turn items、用户正文、模型输出或共享 Skill 根绝对路径。 +- Boss heartbeat 已新增 App Server 能力发现缓存:按 `codexAppServerDiscoveryTtlMs` 拉取 `model/list`、`modelProvider/capabilities/read`、`skills/list`、`hooks/list`、`plugin/list`、`app/list`、`experimentalFeature/list`、`collaborationMode/list`、`permissionProfile/list`、`mcpServerStatus/list`、`account/read`、`account/rateLimits/read`、`config/read`、`configRequirements/read`、`externalAgentConfig/detect`、`thread/list`、`thread/loaded/list` 和 `thread/turns/list`;配置了 `codexAppServerSkillExtraRoots` / `BOSS_CODEX_APP_SERVER_SKILL_EXTRA_ROOTS` 时,会先调用 `skills/extraRoots/set` 再拉取 `skills/list`,归一成设备 `capabilities.codexAppServer.metadata`;发现失败只记录 warn,不阻塞心跳。MCP discovery 使用 `detail=toolsAndAuthOnly`,turn discovery 固定 `itemsView=notLoaded`,账号、配置、线程、Hook 和 Skill extra root discovery 只保留安全摘要,不保存邮箱、resource URI、工具参数、完整 config、本地路径、迁移描述、turn id、turn items、用户正文、模型输出、hook 命令或共享 Skill 根绝对路径。 - Boss 第一批只用 App Server 做任务级 provider,不直接复用 ChatGPT Mobile 到 Codex App 的官方 relay;官方移动控制链路仍属于 ChatGPT App 与 Codex App 同账号/工作区之间的产品能力,不是第三方 Boss 可以稳定依赖的私有通道 下一轮再核对版本时,不要只看 npm 包版本号;必须同时读取 App Server schema / TypeScript 定义,并把 protocol snapshot 保存到 `docs/protocol-snapshots/codex-app-server//`。 @@ -150,6 +150,7 @@ UI 参考: - 新增 App Server 过载退避:单个 JSON-RPC 请求收到 `-32001` 或 `retry later` 文案时,会在同一个任务生命周期内重试,超出上限后才进入失败/CLI fallback 判定 - 新增 App Server capability discovery:`local-agent` 会把可用模型、默认/快速/深度模型建议、provider 能力、Skill、Plugin、App 摘要写入设备 heartbeat;Web 设备详情已显示 App Server、模型和扩展数量,为后续 APP/后台模型配置页提供真实数据来源 - 新增 App Server 共享 Skill 根下发:配置 `codexAppServerSkillExtraRoots` 或 `BOSS_CODEX_APP_SERVER_SKILL_EXTRA_ROOTS` 后,runner 会在 discovery 阶段调用 `skills/extraRoots/set`,再刷新 `skills/list`;设备详情页展示“共享 Skill 根:N 个 · 已下发/下发失败”,metadata 只保存数量、basename 和状态,不保存绝对路径 +- 新增 App Server Hook 治理 discovery:runner 会调用 `hooks/list` 并写入 `hookSummary`,设备详情页展示“Hook:N 个 · 启用 N 个 · 警告 N 个”;metadata 只保存计数、事件名和 handler 类型,不保存 hook key、command、sourcePath、statusMessage、hash、error message 或本地路径 后续建议按两步继续: diff --git a/docs/architecture/current_runtime_and_deploy_status_cn.md b/docs/architecture/current_runtime_and_deploy_status_cn.md index bb890f0..020bded 100644 --- a/docs/architecture/current_runtime_and_deploy_status_cn.md +++ b/docs/architecture/current_runtime_and_deploy_status_cn.md @@ -35,12 +35,13 @@ - `launchd` 已安装:`~/Library/LaunchAgents/com.hyzq.boss.local-agent.plist` - 当前执行底座抽象层已落地在 `src/lib/execution/`,并已补齐 `ExecutionBackend / PromptAssembler / PermissionPolicy / RemoteRuntimeAdapter / OrchestrationBackend` 默认实现 - 当前生产主链仍然沿用 `local-agent -> codex exec resume -> /api/v1/master-agent/tasks/[taskId]/complete`,执行底座重构以“先抽象、不改行为”为准 -- 当前 Codex server 调研结论已记录在 `docs/architecture/codex_server_progress_card_cn.md`:长期优先方向更新为 `Codex App Server / Remote Control -> Inter-Thread Broker -> CodexMcpBackendAdapter -> codex exec resume` 的分层 provider 策略;当前 boss-agent 默认打开 `Codex App Server` runner 作为 Codex 绑定入口,Boss 仍保留 `codex exec resume` 兜底,并继续用 `execution_progress` 结构化进度卡作为 APP 可见执行态。本机 `codex-cli 0.136.0-alpha.2` 协议快照已生成到 `docs/protocol-snapshots/codex-app-server/0.136.0-alpha.2/`,确认支持 WebSocket auth、`thread/inject_items`、`turn/steer`、`thread/realtime/*`、`thread/goal/*`、`thread/settings/updated`、`thread/compacted`、`ThreadItem.contextCompaction`、`ThreadItem.collabToolCall`、`account/*`、`model/verification`、`configWarning`、`deprecationNotice`、`command/exec`、`model/list` 和 `skills/extraRoots/set` +- 当前 Codex server 调研结论已记录在 `docs/architecture/codex_server_progress_card_cn.md`:长期优先方向更新为 `Codex App Server / Remote Control -> Inter-Thread Broker -> CodexMcpBackendAdapter -> codex exec resume` 的分层 provider 策略;当前 boss-agent 默认打开 `Codex App Server` runner 作为 Codex 绑定入口,Boss 仍保留 `codex exec resume` 兜底,并继续用 `execution_progress` 结构化进度卡作为 APP 可见执行态。本机 `codex-cli 0.136.0-alpha.2` 协议快照已生成到 `docs/protocol-snapshots/codex-app-server/0.136.0-alpha.2/`,确认支持 WebSocket auth、`thread/inject_items`、`turn/steer`、`thread/realtime/*`、`thread/goal/*`、`thread/settings/updated`、`thread/compacted`、`ThreadItem.contextCompaction`、`ThreadItem.collabToolCall`、`account/*`、`model/verification`、`configWarning`、`deprecationNotice`、`command/exec`、`model/list`、`skills/extraRoots/set` 和 `hooks/list` - 当前 App Server 能力发现已新增治理摘要:local-agent 会在 heartbeat discovery 中拉取 `experimentalFeature/list / collaborationMode/list / permissionProfile/list / mcpServerStatus/list`,并把实验特性、协作模式、权限 Profile 与 MCP 服务状态写入设备 `codexAppServer.metadata`;设备详情页会显示“治理”摘要。该链路只保留安全摘要,不保存 MCP resource URI、permission profile 文件规则、本地路径、token 或工具参数。 - 当前 App Server 能力发现已新增账号与配置摘要:local-agent 会在 heartbeat discovery 中拉取 `account/read / account/rateLimits/read / config/read / configRequirements/read / externalAgentConfig/detect`,并把账号登录方式、套餐、额度使用率、App 配置计数、托管要求数量和外部 Agent 迁移候选数量写入设备 `codexAppServer.metadata`;设备详情页会显示“账号 / 配置”摘要。该链路只读不写,不保存账号邮箱、完整 config、API key、本地路径或迁移描述。 - 当前 App Server 能力发现已新增线程可见性摘要:local-agent 会在 heartbeat discovery 中拉取 `thread/list / thread/loaded/list`,并把线程总数、已加载线程数、活跃线程数、归档线程数、最新更新时间和非归档线程轻量目录写入设备 `codexAppServer.metadata.threadSummary`;设备详情页会显示“线程”摘要。该链路不保存 cwd、本地路径、turn 内容、用户正文或内部 prompt。 - 当前 App Server 能力发现已新增 turn 运行态摘要:local-agent 会在 heartbeat discovery 中对非归档可见线程拉取 `thread/turns/list`,请求固定 `itemsView=notLoaded`,并把总轮次、运行中轮次、完成轮次、最新 turn 更新时间和每个线程的最近 turn 状态写入设备 `codexAppServer.metadata.threadTurnSummary`;设备详情页会显示“轮次”摘要。该链路不保存 turn id、turn items、用户正文、模型输出或内部 prompt。 - 当前 App Server 能力发现已支持共享 Skill 根目录下发:配置 `codexAppServerSkillExtraRoots` / `BOSS_CODEX_APP_SERVER_SKILL_EXTRA_ROOTS` 时,local-agent 会先调用 `skills/extraRoots/set`,再刷新 `skills/list`,并把 `skillExtraRootsSummary` 写入设备 `codexAppServer.metadata`;设备详情页会显示“共享 Skill 根”。该链路只保存数量、basename 和状态,不保存根目录绝对路径、Skill 文件路径或配置原文。 +- 当前 App Server 能力发现已新增 Hook 治理摘要:local-agent 会在 heartbeat discovery 中拉取 `hooks/list`,并把 hook 数、启用数、受管 / 可信 / 修改 / 未信任计数、warning / error 计数写入设备 `codexAppServer.metadata.hookSummary`;设备详情页会显示“Hook”。该链路不保存 hook key、command、sourcePath、statusMessage、hash、error message 或本地路径。 - 当前量产 B+ 架构开发文档已新增:`docs/architecture/enterprise_ai_ops_architecture_cn.md`。该文档把 PPT 中的主 Agent / 业务 Agent / 老板端 / 经理端 / 员工端 / 治理层 / 系统层 / 设备层 / 执行层 / 接入层整理成后续产品架构约束,并明确数据库备份、业务回退、Codex 协议扩展和 Skill 治理方向;它是规划文档,不代表当前全部已落地 - 当前 `claw-code` 已以最小 `ClawBackendAdapter` 形式接入执行底座,但默认关闭;只有显式配置 `BOSS_CLAW_*` 且可用性探测通过时,`master-agent` 当前对话中才会出现并允许选择 `claw-runtime` - 当前已新增最小 `Telegram Gateway`:Boss 当前可直接暴露 Telegram webhook,把 Telegram 私聊或受控群聊文本桥接进 `master-agent` 或按群 / Topic 路由到指定 Boss 项目,并在主 Agent 异步任务完成后自动回推 Telegram;配置入口已接到 Web `/me/telegram` 和原生 Android `我的 > Telegram 接入` @@ -255,7 +256,7 @@ cd /Users/kris/code/boss - 当前已新增 Boss 自有 Inter-Thread Broker 第一版:服务端入口 `POST /api/v1/projects/[projectId]/thread-collaboration` 会创建带源/目标 Codex 线程引用的协作任务;App Server runner 执行 `thread/read(source) -> thread/inject_items(target) -> turn/start(target)`,用于让一个线程的结论受控进入另一个线程,不依赖官方任意线程 P2P 互聊能力 - 当前 `local-agent` 对 `dispatch_execution` 任务会按 `orchestrationBackendId` 分流:默认走 `codex exec resume`;当任务显式选择 `omx-team` 且本机 `omxEnabled + omxCommand/omxArgs` 可用时,会改走 `OMX Team Runtime` JSON 协议执行并回写 `rawThreadReply / replyBody` - 当前 `local-agent` 会在 Codex 任务执行中和完成时回传 `executionProgress`:服务端把同一任务的进度卡从 queued / running 更新到 completed / failed,Android 原生聊天页会显示“进度 / 线程状态 / 实时状态 / 线程配置 / 线程协作 / 工具活动 / 思考摘要 / 账号状态 / 运行状态 / 安全提醒 / 审批状态 / 文件变更 / 分支详情 / 生成结果 / 后台智能体”。2026-05-31 起,Codex App Server 的 `turn/plan/updated`、`turn/diff/updated`、`item/started|completed`、`thread/started` 会直接映射为进度步骤、变更统计、生成产物和后台智能体;第二批已把 `item/*/requestApproval`、`item/autoApprovalReview/*`、`guardianWarning`、`serverRequest/resolved`、`item/fileChange/patchUpdated` 映射为审批、安全提醒和文件变更摘要;第三批已把 `thread/status/changed` 与 `thread/realtime/*` 安全映射为线程状态和实时状态摘要;第四批已把 `model/rerouted`、`thread/tokenUsage/updated`、`mcpServer/startupStatus/updated`、`remoteControl/status/changed` 安全映射为运行状态摘要;第五批已把 `thread/goal/*`、`thread/settings/updated` 和 `thread/compacted` 映射为线程配置摘要;第六批已把 `account/updated`、`account/rateLimits/updated`、`model/verification`、`warning`、`configWarning`、`deprecationNotice` 映射为账号状态、模型校验和安全提醒摘要;第七批已把 `ThreadItem.collabToolCall` 和 `ThreadItem.contextCompaction` 映射为线程协作和上下文压缩摘要;第八批已把 `mcpToolCall`、`dynamicToolCall`、`webSearch`、`imageView`、`enteredReviewMode`、`exitedReviewMode`、`commandExecution` 映射为工具活动摘要;第九批已把 `ThreadItem.plan` 和 `ThreadItem.reasoning.summary` 映射为计划步骤与思考摘要;第十批已把 `ThreadItem.imageGeneration` 映射为图像生成工具活动和图片产物;第十一批已把 `hook/started|completed` 映射为钩子生命周期工具活动;第十二批已把 `windowsSandbox/setupCompleted` 映射为 Windows 沙箱准备状态摘要;第十七批已把新版 `ThreadItem.collabToolCall.receiverThreadIds / agentsStates` 安全映射为线程协作目标数量和 agent 状态集合。所有进度均通过 `POST /api/v1/master-agent/tasks/[taskId]/progress` 实时刷新;字段白名单会剥离 cwd、turnId、配置文件路径、内部 prompt、collab 源/目标线程 ID、receiverThreadIds、agentsStates 私有消息、共享 Skill 根绝对路径、tool arguments/result、web URL token、命令正文/输出、raw reasoning content、reasoning item id、图像生成 revisedPrompt/result、hook sourcePath/statusMessage/entries、Windows sandbox sourcePath/samplePaths/本地绝对路径和未清洗密钥,complete 回写仍会携带最终进度兜底 -- 当前 `local-agent` heartbeat 已新增 Codex App Server capability discovery:按 TTL 拉取模型、provider 能力、Skill、Plugin、App 摘要,写入 `capabilities.codexAppServer.metadata`;Web 设备详情会展示 App Server 连接状态、模型数量、默认/快速/深度模型和扩展数量 +- 当前 `local-agent` heartbeat 已新增 Codex App Server capability discovery:按 TTL 拉取模型、provider 能力、Skill、Hook、Plugin、App 摘要,写入 `capabilities.codexAppServer.metadata`;Web 设备详情会展示 App Server 连接状态、模型数量、默认/快速/深度模型、扩展数量和 Hook 治理摘要 - 当前 `MasterAgentTask` 已具备服务端租约和取消基础状态机:claim 会写入 `attemptCount / maxAttempts / leaseExpiresAt`,运行中任务租约过期后可被重新认领,超过重试上限会转 `timed_out`;`POST /api/v1/master-agent/tasks/[taskId]/cancel` 会把任务转 `canceled`,迟到的成功 complete 不会覆盖终态 - 当前 `local-agent` 对 `browser_control / desktop_control` 已从占位骨架升级成外部 runtime 桥:当本机配置了 `browserControlEnabled + browserControlCommand` 或 `computerUseEnabled + computerUseCommand` 时,会把标准化 JSON 请求透传给外部进程,并解析单行 JSON 结果;未启用时会 fail closed,返回明确的 runtime disabled 错误,不再假装执行成功 - 远程电脑控制链路当前已有可复用压测基线:`npm run stress:remote-control` 可按参数压测 `local-agent -> MasterAgentTask -> browser_control / desktop_control runtime -> complete 回写` 全链路;`npm run stress:remote-control:ci` 固定 120 条链路任务和 360 条 runtime 并发任务,并用 p95 延迟预算判断是否退化。压测报告可通过 `--report-json=PATH` 落盘,便于后续接入真实 macOS AX / Windows UIA helper 后复用同一套稳定性判断。 diff --git a/docs/protocol-snapshots/codex-app-server/0.136.0-alpha.2/manifest.json b/docs/protocol-snapshots/codex-app-server/0.136.0-alpha.2/manifest.json index 95f9db4..645b47c 100644 --- a/docs/protocol-snapshots/codex-app-server/0.136.0-alpha.2/manifest.json +++ b/docs/protocol-snapshots/codex-app-server/0.136.0-alpha.2/manifest.json @@ -1,5 +1,5 @@ { - "generatedAt": "2026-06-03T02:34:58.137Z", + "generatedAt": "2026-06-03T02:51:37.230Z", "codexVersion": "0.136.0-alpha.2", "codexVersionRaw": "codex-cli 0.136.0-alpha.2", "codexBin": "codex", @@ -156,6 +156,7 @@ "commandExec": true, "realtimeThread": true, "modelList": true, - "skillsExtraRoots": true + "skillsExtraRoots": true, + "hooksList": true } } diff --git a/local-agent/codex-app-server-runner.mjs b/local-agent/codex-app-server-runner.mjs index 7c3344c..dab1e9f 100644 --- a/local-agent/codex-app-server-runner.mjs +++ b/local-agent/codex-app-server-runner.mjs @@ -1221,6 +1221,30 @@ function normalizeDiscoverySkillExtraRootsSummary(roots, result) { }; } +function normalizeDiscoveryHookSummary(result) { + const entries = asArray(result?.data); + const hooks = entries.flatMap((entry) => asArray(entry?.hooks)); + const eventNames = Array.from( + new Set(hooks.map((hook) => safeProgressText(hook?.eventName, 80)).filter(Boolean)), + ).sort(); + const handlerTypes = Array.from( + new Set(hooks.map((hook) => safeProgressText(hook?.handlerType, 80)).filter(Boolean)), + ).sort(); + return { + workspaceCount: entries.length, + hookCount: hooks.length, + enabledHookCount: hooks.filter((hook) => hook?.enabled !== false).length, + managedHookCount: hooks.filter((hook) => Boolean(hook?.isManaged)).length, + trustedHookCount: hooks.filter((hook) => safeProgressText(hook?.trustStatus, 40) === "trusted").length, + modifiedHookCount: hooks.filter((hook) => safeProgressText(hook?.trustStatus, 40) === "modified").length, + untrustedHookCount: hooks.filter((hook) => safeProgressText(hook?.trustStatus, 40) === "untrusted").length, + warningCount: entries.reduce((sum, entry) => sum + asArray(entry?.warnings).length, 0), + errorCount: entries.reduce((sum, entry) => sum + asArray(entry?.errors).length, 0), + eventNames: eventNames.slice(0, 12), + handlerTypes: handlerTypes.slice(0, 12), + }; +} + function normalizeDiscoveryPlugins(result) { return asArray(result?.marketplaces) .flatMap((marketplace) => asArray(marketplace?.plugins)) @@ -1618,6 +1642,7 @@ export async function discoverCodexAppServerCapabilities(runnerConfig) { modelResult, providerCapabilities, skillsResult, + hooksResult, pluginResult, appsResult, experimentalFeaturesResult, @@ -1635,6 +1660,7 @@ export async function discoverCodexAppServerCapabilities(runnerConfig) { safeRequest(request, "model/list", { includeHidden: false, limit }), safeRequest(request, "modelProvider/capabilities/read", {}), safeRequest(request, "skills/list", { cwds: [cwd], forceReload: false }), + safeRequest(request, "hooks/list", { cwds: [cwd] }), safeRequest(request, "plugin/list", { cwds: [cwd] }), safeRequest(request, "app/list", { limit }), safeRequest(request, "experimentalFeature/list", { limit }), @@ -1698,6 +1724,7 @@ export async function discoverCodexAppServerCapabilities(runnerConfig) { configRequirements: normalizeDiscoveryConfigRequirements(configRequirementsResult), externalAgentMigration: normalizeDiscoveryExternalAgentMigration(externalAgentConfigResult), skillExtraRootsSummary: normalizeDiscoverySkillExtraRootsSummary(skillExtraRoots, skillExtraRootsResult), + hookSummary: normalizeDiscoveryHookSummary(hooksResult), threadSummary, threadTurnSummary: normalizeDiscoveryThreadTurnSummary(threadTurnResults, limit), errors: [ @@ -1709,6 +1736,7 @@ export async function discoverCodexAppServerCapabilities(runnerConfig) { skillExtraRootsResult?.__bossError ? `skills/extraRoots/set:${safeRuntimeDiagnosticText(skillExtraRootsResult.__bossError)}` : undefined, + hooksResult?.__bossError ? `hooks/list:${safeRuntimeDiagnosticText(hooksResult.__bossError)}` : undefined, pluginResult?.__bossError ? `plugin/list:${safeRuntimeDiagnosticText(pluginResult.__bossError)}` : undefined, appsResult?.__bossError ? `app/list:${safeRuntimeDiagnosticText(appsResult.__bossError)}` : undefined, experimentalFeaturesResult?.__bossError diff --git a/scripts/codex-app-server-protocol-snapshot.mjs b/scripts/codex-app-server-protocol-snapshot.mjs index a36d840..dce7f41 100644 --- a/scripts/codex-app-server-protocol-snapshot.mjs +++ b/scripts/codex-app-server-protocol-snapshot.mjs @@ -113,6 +113,7 @@ function buildSupportMatrix({ helpText, methods }) { realtimeThread: methods.some((method) => method.startsWith("thread/realtime/")), modelList: methodSet.has("model/list"), skillsExtraRoots: methodSet.has("skills/extraRoots/set"), + hooksList: methodSet.has("hooks/list"), }; } diff --git a/src/components/app-ui.tsx b/src/components/app-ui.tsx index 272d1c7..c328f32 100644 --- a/src/components/app-ui.tsx +++ b/src/components/app-ui.tsx @@ -120,6 +120,7 @@ export function buildDeviceWorkspaceDetailCards(workspace: DeviceWorkspaceView) const codexConfigRequirements = objectFromMetadata(codexAppServerMetadata.configRequirements); const codexExternalAgentMigration = objectFromMetadata(codexAppServerMetadata.externalAgentMigration); const codexSkillExtraRootsSummary = objectFromMetadata(codexAppServerMetadata.skillExtraRootsSummary); + const codexHookSummary = objectFromMetadata(codexAppServerMetadata.hookSummary); const codexThreadSummary = objectFromMetadata(codexAppServerMetadata.threadSummary); const codexThreadTurnSummary = objectFromMetadata(codexAppServerMetadata.threadTurnSummary); @@ -163,6 +164,9 @@ export function buildDeviceWorkspaceDetailCards(workspace: DeviceWorkspaceView) ? "下发失败" : "未配置" }`, + codexHooks: `Hook:${numberFromMetadata(codexHookSummary.hookCount)} 个 · 启用 ${numberFromMetadata( + codexHookSummary.enabledHookCount, + )} 个 · 警告 ${numberFromMetadata(codexHookSummary.warningCount)} 个`, codexThreads: `线程:${numberFromMetadata(codexThreadSummary.threadCount)} 个 · 已加载 ${numberFromMetadata( codexThreadSummary.loadedThreadCount, )} 个 · 活跃 ${numberFromMetadata(codexThreadSummary.activeThreadCount)} 个 · 最新 ${minuteTimestampFromMetadata( @@ -816,6 +820,9 @@ export function DeviceEditorCard({
{detailCards.capabilities.items.codexSkillRoots}
+
+ {detailCards.capabilities.items.codexHooks} +
{detailCards.capabilities.items.codexThreads}
diff --git a/tests/codex-app-server-protocol-snapshot-script.test.mjs b/tests/codex-app-server-protocol-snapshot-script.test.mjs index 15eabea..d169932 100644 --- a/tests/codex-app-server-protocol-snapshot-script.test.mjs +++ b/tests/codex-app-server-protocol-snapshot-script.test.mjs @@ -38,6 +38,7 @@ if (args[0] === "app-server" && args[1] === "generate-json-schema") { { properties: { method: { const: "thread/start" } } }, { properties: { method: { const: "thread/inject_items" } } }, { properties: { method: { const: "skills/extraRoots/set" } } }, + { properties: { method: { const: "hooks/list" } } }, { properties: { method: { const: "turn/start" } } } ] }, null, 2)); @@ -45,7 +46,7 @@ if (args[0] === "app-server" && args[1] === "generate-json-schema") { } if (args[0] === "app-server" && args[1] === "generate-ts") { const out = args[args.indexOf("--out") + 1]; - writeGenerated(out, "ClientRequest.ts", 'export type ClientRequest = { "method": "thread/start" } | { "method": "skills/extraRoots/set" } | { "method": "turn/start" };\\n'); + writeGenerated(out, "ClientRequest.ts", 'export type ClientRequest = { "method": "thread/start" } | { "method": "skills/extraRoots/set" } | { "method": "hooks/list" } | { "method": "turn/start" };\\n'); process.exit(0); } console.error("unexpected args " + args.join(" ")); @@ -78,7 +79,14 @@ process.exit(2); assert.equal(manifest.supports.unixTransport, true); assert.equal(manifest.supports.threadInjectItems, true); assert.equal(manifest.supports.skillsExtraRoots, true); - assert.deepEqual(manifest.methods, ["skills/extraRoots/set", "thread/inject_items", "thread/start", "turn/start"]); + assert.equal(manifest.supports.hooksList, true); + assert.deepEqual(manifest.methods, [ + "hooks/list", + "skills/extraRoots/set", + "thread/inject_items", + "thread/start", + "turn/start", + ]); assert.match( await readFile(path.join(outDir, "0.135.0-alpha.1", "app-server-help.txt"), "utf8"), /ws:\/\/IP:PORT/, diff --git a/tests/device-detail-capabilities-route.test.ts b/tests/device-detail-capabilities-route.test.ts index f35620a..8175654 100644 --- a/tests/device-detail-capabilities-route.test.ts +++ b/tests/device-detail-capabilities-route.test.ts @@ -105,6 +105,19 @@ test("device detail exposes Codex App Server discovered model and extension summ rootCount: 2, rootLabels: ["boss-shared-skills", "team-skills"], }, + hookSummary: { + workspaceCount: 1, + hookCount: 2, + enabledHookCount: 1, + managedHookCount: 1, + trustedHookCount: 1, + modifiedHookCount: 1, + untrustedHookCount: 0, + warningCount: 1, + errorCount: 1, + eventNames: ["PreToolUse", "SessionStart"], + handlerTypes: ["command", "prompt"], + }, threadSummary: { threadCount: 3, loadedThreadCount: 2, @@ -156,6 +169,7 @@ test("device detail exposes Codex App Server discovered model and extension summ assert.equal(cards.capabilities.items.codexAccount, "账号:chatgpt · 套餐 pro · 额度 42%"); assert.equal(cards.capabilities.items.codexConfig, "配置:App 2 个 · 已启用 1 个 · 托管要求 2 个 · 外部迁移 3 项"); assert.equal(cards.capabilities.items.codexSkillRoots, "共享 Skill 根:2 个 · 已下发"); + assert.equal(cards.capabilities.items.codexHooks, "Hook:2 个 · 启用 1 个 · 警告 1 个"); assert.equal(cards.capabilities.items.codexThreads, "线程:3 个 · 已加载 2 个 · 活跃 1 个 · 最新 2026-06-03 16:20"); assert.equal(cards.capabilities.items.codexTurns, "轮次:3 个 · 运行中 1 个 · 完成 2 个 · 最新 2026-06-03 16:21"); }); diff --git a/tests/fixtures/codex-app-server-runtime.mjs b/tests/fixtures/codex-app-server-runtime.mjs index 4472ca3..241d7a7 100644 --- a/tests/fixtures/codex-app-server-runtime.mjs +++ b/tests/fixtures/codex-app-server-runtime.mjs @@ -120,6 +120,63 @@ rl.on("line", (line) => { return; } + if (message.method === "hooks/list") { + send({ + id: message.id, + result: { + data: [ + { + cwd: "/Users/kris/code/boss", + hooks: [ + { + key: "session-start-private-key-should-not-leak", + eventName: "SessionStart", + handlerType: "command", + matcher: null, + command: "echo token=sk-secret-should-not-leak", + timeoutSec: 30, + statusMessage: "private hook status should not leak", + sourcePath: "/Users/kris/code/boss/.codex/hooks/private-hook.toml", + source: "project", + pluginId: null, + displayOrder: 1, + enabled: true, + isManaged: true, + currentHash: "hash-secret-should-not-leak", + trustStatus: "trusted", + }, + { + key: "pre-tool-private-key-should-not-leak", + eventName: "PreToolUse", + handlerType: "prompt", + matcher: "Bash", + command: null, + timeoutSec: 10, + statusMessage: "modified hook status should not leak", + sourcePath: "/Users/kris/.codex/hooks/private-user-hook.toml", + source: "user", + pluginId: "private-plugin-should-not-leak", + displayOrder: 2, + enabled: false, + isManaged: false, + currentHash: "modified-hash-secret-should-not-leak", + trustStatus: "modified", + }, + ], + warnings: ["private hook warning should not leak"], + errors: [ + { + path: "/Users/kris/code/boss/.codex/hooks/broken-hook.toml", + message: "private hook error token=sk-secret-should-not-leak", + }, + ], + }, + ], + }, + }); + return; + } + if (message.method === "plugin/list") { send({ id: message.id, diff --git a/tests/local-agent-codex-app-server-runner.test.mjs b/tests/local-agent-codex-app-server-runner.test.mjs index 5234686..bf620cc 100644 --- a/tests/local-agent-codex-app-server-runner.test.mjs +++ b/tests/local-agent-codex-app-server-runner.test.mjs @@ -73,6 +73,19 @@ test("codex app-server discovery includes governance and MCP summaries without l rootCount: 2, rootLabels: ["boss-shared-skills", "team-skills"], }); + assert.deepEqual(metadata.hookSummary, { + workspaceCount: 1, + hookCount: 2, + enabledHookCount: 1, + managedHookCount: 1, + trustedHookCount: 1, + modifiedHookCount: 1, + untrustedHookCount: 0, + warningCount: 1, + errorCount: 1, + eventNames: ["PreToolUse", "SessionStart"], + handlerTypes: ["command", "prompt"], + }); assert.equal(metadata.threadSummary.threadCount, 3); assert.equal(metadata.threadSummary.loadedThreadCount, 2); assert.equal(metadata.threadSummary.activeThreadCount, 1); @@ -117,6 +130,14 @@ test("codex app-server discovery includes governance and MCP summaries without l assert.equal(serialized.includes("private active turn text should not leak"), false); assert.equal(serialized.includes("private item content should not leak"), false); assert.equal(serialized.includes("private idle turn text should not leak"), false); + assert.equal(serialized.includes("private-hook.toml"), false); + assert.equal(serialized.includes("private-user-hook.toml"), false); + assert.equal(serialized.includes("broken-hook.toml"), false); + assert.equal(serialized.includes("private hook status"), false); + assert.equal(serialized.includes("private hook warning"), false); + assert.equal(serialized.includes("private hook error"), false); + assert.equal(serialized.includes("session-start-private-key"), false); + assert.equal(serialized.includes("sk-secret-should-not-leak"), false); }); function encodeWsTextFrame(value) {