把公开发布的 Grok Bot 0.18.0 macOS 应用重建成可读 TypeScript,并把推理、沙箱、设置和用量统计都搬回你自己的 Mac。
另附一个本机 HTTP 服务 Node Agent API,让网页、CLI 或你自己的客户端调用这些 bot 和 Linux 桌面。
快速开始 · Node Agent API · 多智能体 harness · 架构 · 排障
Warning
这是非官方的研究项目,与 Anysphere、Cursor、xAI、SpaceX 均无关联,也没有得到它们的认可。这里不是原始源码,也不是官方发布版本,并且不授予上游应用的任何许可。公开分发前请先读 NOTICE.md 和 PROVENANCE.md。
![]() 暗色主题 · 单独指定模型和推理强度 |
![]() 浅色主题 · 打开电脑和休眠 |
界面支持暗色和浅色两种风格。
目录
仓库包含两样东西:
| 组成 | 是什么 | 入口 |
|---|---|---|
| Grok Node.app | 基于 Grok Bot 0.18.0 重建的 macOS 桌面应用。运行时由 source/ 下的 TypeScript 编译,界面沿用经过 checksum 固定的出厂渲染器,并加上少量可审计的补丁。推理改走本机的 Codex 登录或 OpenRouter 兼容端点,代码执行放进应用自己管理的本地 Docker 容器。 |
npm run package → dist/Grok Node.app,或下载 Releases |
| Node Agent API 0.3.0 | 独立的本机 HTTP 服务(默认 127.0.0.1:18770),自带网页工作台和 CLI。它把已经在运行的 Grok Node 里的 bot、Linux 桌面和项目操作开放成 API,不包含在 ZIP 客户端里,也不会随客户端自动启动。 |
npm run node-agent-api |
名字里的 “Node” 指节点:原版应用依赖云端会话和远端沙箱,改造后它像一个自足的节点一样跑在本机。
| 方面 | 能力 | 代码 / 文档 |
|---|---|---|
| 推理路由 | 两档 provider:codex、openrouter(界面里显示为 TokenHub),默认 openrouter |
source/shared/inference-router.ts、source/shared/node/settings/sand-settings-store.ts |
| 模型与推理强度 | TokenHub 档可以设默认模型;推理强度分 None / Low / Medium / High / Extra high / Max / Ultra;每个 bot 可以单独覆盖模型和推理强度 | source/shared/node/openrouter-proxy.ts、scripts/lib/agent-model-renderer-patch.mjs |
| 用量统计 | 按 provider 在本地累计请求数、输入/输出/缓存 token,并记录最近一次额度耗尽,数据不出本机 | source/shared/inference-router.ts |
| 本地沙箱 | 应用自己管理 grok-node-local-vm 容器。镜像按 digest 固定,端口只绑定回环地址;Shell、文件和 computer use 都在容器里执行 |
source/electron-main/box/local-docker-host-connector.ts |
| 主 Bot | 移植了官方客户端的主 Bot 选择与替换 | source/shared/node/grok-bot-main-agent.ts |
| 插件 / MCP | 两档 provider 都保留 Grok Bot 工具和 MCP 工具执行;HTTP/SSE MCP 客户端在本地容器里运行 | docs/LOCAL_HTTP_MCP.md |
| 界面语言 | 内置 English / 简体中文 | scripts/lib/language-renderer-patch.mjs |
| 隐私边界 | 打包时禁用上游更新器,默认关闭 Sentry 和遥测 | scripts/lib/build-asar.mjs、SECURITY.md |
| Agent API | Bearer 鉴权、会话与 SSE、审批与取消、整桌面/单窗口观看与接管、项目导入导出与差异、备份、多用户配额、签名 webhook | tools/node-agent-api/README.md |
Grok Node 里可以同时有多个 bot。它们能互相发消息、建群讨论、新建队友,也能派出子任务。Node Agent API 再把这些 bot 统一开放成 HTTP / SSE 接口,连到两边:沙箱电脑和你的 Mac。
1. Grok Node 内部的多 bot 机制(都在桌面应用里运行,以下名称都能在代码里找到)
| 机制 | 怎么用 |
|---|---|
| bot 之间发消息 | bot 调用 SendToAgent 工具,按 id 发给另一个 bot 或自己所在的群聊,可附图片。消息是异步的:发出后立即返回,对方在新回合里被唤醒(提示前缀 [agent]),回复也按同样方式送回实现: source/host/agents/agent-messaging.ts、source/host/runner/tools/sand-agent-management-tools.ts |
| 新建 / 修改队友 | bot 调用 CreateAgent 新建 bot(返回 id,可以直接 SendToAgent),UpdateAgent 修改名字和描述实现:同上 |
| 群聊 | 多个 bot 和用户在同一个房间里,按 @ 提及和轮次发言;群里只能放单个 bot,不能嵌套群 实现: source/host/groups/group-chat.ts、group-store.ts |
| 群发 | 用户向全部或部分 bot 群发一条消息,收到的 bot 以 [broadcast] 唤醒实现: source/host/host-gateway-api.ts(broadcastToAgents) |
| 子任务 | bot 派出 browserUse / computerUse 类型的子 agent,再用 CheckSubagent、MessageSubagent、StopSubagent 跟进实现: source/host/runner/subagent-runtime.ts、source/host/runner/tools/sand-*-subagent*.ts |
| 主 Bot | 指定一个 bot 为主 Bot(getMainAgent / setMainAgent)实现: source/shared/node/grok-bot-main-agent.ts、source/host/host-gateway-api.ts |
2. Node Agent API 把 bot 接出来
| 能力 | 接口与说明 |
|---|---|
| 列出 / 查看 bot | GET /v1/agents、GET /v1/agents/{agent_id}实现:读取 Grok Node 的 bot 列表(gateway listAgents) |
| 新建 bot | POST /v1/agents(字段 name、description;需要可访问全部 bot 的 key)实现:调用 Grok Node 的 createAgent(tools/node-agent-api/cli.mjs、grok-node.mjs) |
| 多会话并行 | POST /v1/agents/sessions:同一个 bot 可以开多个独立会话,各自有事件流、回合和审批实现: tools/node-agent-api/server.mjs、codex.mjs |
| 进入 bot 原生聊天 | 会话 backend: "grok" 时,消息直接送进该 bot 在 Grok Node 里的聊天(gateway sendPrompt)实现: tools/node-agent-api/grok-node.mjs |
Node Agent API 目前没有直接暴露 SendToAgent、群聊或群发的 HTTP 接口。bot 之间的通信发生在 Grok Node 内部;API 驱动的是单个 bot 和它的会话。
3. 两条线:沙箱电脑和本地 Mac
| 沙箱电脑 | 本地 Mac | |
|---|---|---|
| 是什么 | 应用管理的 grok-node-local-vm 容器:Linux 桌面、浏览器、终端和应用 |
你自己的 Mac:浏览器、ZCode 和本地任务 |
| 怎么操作 | GET/POST /v1/agents/sessions/{id}/applications、POST …/desktop(观看 / 接管)、POST …/handback(交还)、GET …/environment |
Codex Harness 的模型调用和工具循环在 Mac 上运行,命令和文件操作进入沙箱执行;bot 工具 node_browser、node_zcode、node_ego 操作 Mac 本机 |
-
打开 Releases,下载
Grok-Node-<版本>-mac-arm64.zip,然后核对哈希:shasum -a 256 Grok-Node-<版本>-mac-arm64.zip # 和 Release 说明里的 ZIP SHA-256 比对
-
解压后把
Grok Node.app拖进/Applications。 -
这个包只做了 ad-hoc 签名,没有经过 Apple 公证。第一次启动时按 macOS 提示右键选「打开」。
-
启动前先运行 Docker Desktop 或 OrbStack,再到 设置 → 路由(Router) 配置推理(见推理路由)。
应用底层版本始终显示
0.18.0,分发修订号以 GitHub tag(如v0.18.0-reconstructed.5)和 ZIP 文件名为准。
git clone https://github.com/tyonger-stack/GrokNode.git
cd GrokNode
git lfs install
git lfs pull # 拉取固定的 0.18.0 DMG(约 156 MB)
npm ci
npm run bootstrap # 校验 DMG 和 app.asar 的 SHA-256,抽取构建输入到 src/app/dist
npm run package # 先跑 npm run check,再编译、打补丁、ad-hoc 签名、校验
open "dist/Grok Node.app"npm run bootstrap依次尝试三个来源:本地缓存,LFS 归档(research-archives/original/0.18.0/),原始公开 URL(目前返回 HTTP 403)。也可以设置GROK_BOT_018_APP=/path/to/Grok Bot.app,直接使用已有的应用副本。- bootstrap 和打包要用到
hdiutil、plutil和 codesign,只能在 macOS 上运行。Linux 上只能跑类型检查、测试和frontend:build(见测试与 CI)。 - 本机已经安装的官方 Grok Bot 不会被覆盖。
前提:Grok Node 已经在运行,grok-node-local-vm 可用,Mac 和容器两端都装好了 Codex 0.160.0,并准备好一个 OpenAI 兼容的模型 API(详见环境要求和配置模型端点)。
# 只需执行一次:在容器里安装 Linux 端 Codex 执行包
docker exec --user box grok-node-local-vm npm install -g @openai/codex@0.160.0 --prefix /home/box/sand-data/codex-vm
# 在仓库根目录
npm ci
export NODE_AGENT_BASE_URL='https://your-openai-compatible-api.example/v1'
export NODE_AGENT_API_KEY='...' # 可选;密钥建议走环境变量,不要放在命令行
export NODE_AGENT_MODEL='YOUR_MODEL' # 可选
npm run node-agent-api -- --backend codex --port 18770 --recover true启动后会输出一行 JSON,其中包括 ui 和 owner_key_file。打开 http://127.0.0.1:18770/ui/,把 owner_key_file 文件里的密钥(默认 .lab/node-agent-shared/owner.key,权限 0600)粘贴进网页。网页只在内存里保存密钥,刷新后需要重新输入。

Node Agent API 网页工作台:左栏选 bot、会话和模型,中间看事件流并发消息,右栏观看 / 接管远程桌面和应用
| 场景 | 要求 | 依据 |
|---|---|---|
| 运行 Grok Node.app | Apple Silicon Mac;Docker Desktop、OrbStack 或兼容的本地 Docker 守护进程;Codex 登录或 OpenRouter 兼容端点的 API key | local-docker-host-connector.ts |
| 从源码构建 | 再加 Node.js 26.5.x(.node-version 为 26.5.0,engines 要求 >=26.5.0 <27)、Xcode Command Line Tools、Git LFS |
package.json、.node-version |
| Node Agent API | Node.js 26.5.x;Mac 端已登录 Codex(存在 ~/.codex/auth.json),Mac 端 Codex CLI 必须正好是 0.160.0;容器内 /home/box/sand-data/codex-vm/bin/codex 也必须是 0.160.0(版本不符直接拒绝,不会自动升级);一个 OpenAI 兼容的模型 API(地址、可选密钥、模型;配置方式见配置模型端点)。不需要 Bun,也不需要 opencodex 或其他协议包 |
tools/node-agent-api/runtime/codex.mjs、inference-config.mjs、tokenhub.mjs、shared-runtime.mjs |
Note
容器以 --platform linux/amd64 创建。在 Apple Silicon 上要靠 Docker/OrbStack 的 x86 模拟运行。
Agent API 写死了 /usr/local/bin/docker 作为 docker 路径(tools/node-agent-api/shared-runtime.mjs、cli.mjs)。如果你的 docker 只装在 /opt/homebrew/bin,需要建一个软链接。
flowchart TB
subgraph MAC["Mac:Grok Node.app"]
R["出厂渲染器(checksum 固定)<br/>+ 路由设置等窄补丁"]
P["electron-preload<br/>窄可信桥"]
M["electron-main<br/>设置 · 密钥 · 认证 · 插件生命周期"]
CO["node-agent-coordinator<br/>utilityProcess<br/>转录路由 · 流式活动 · 路由 MCP 桥"]
DC["本地 Docker 连接器"]
end
subgraph VM["Docker 容器 grok-node-local-vm(digest 固定镜像)"]
H["重建的 host(只读挂载 host-main.cjs)<br/>gateway :1340 · 推理 · 工具 · MCP · 回合执行"]
D["box-exec-daemon :1337"]
V["noVNC 桌面 :6080 / :6081"]
end
subgraph EXT["外部模型端点"]
CX["Codex 账户后端<br/>(ChatGPT 登录)"]
OR["OpenRouter 兼容端点<br/>(TokenHub,默认)"]
end
R -->|"desktop RPC"| P --> M
M -->|"utilityProcess.fork"| CO
R -->|"MessagePort 数据端口"| CO
M --> DC
DC -->|"docker run / start<br/>端口只发布到 127.0.0.1"| VM
CO -->|"HTTP /api/* + SSE<br/>127.0.0.1:1340"| H
H -->|"codex 档:Responses<br/>凭 ~/.codex 登录(只读挂载)"| CX
H -->|"openrouter 档:API key<br/>本机地址改写为 host.docker.internal"| OR
产物应用是混合式的:
- 应用运行时由
source/下的可读源码编译而来; - UI 基线沿用精修过的出厂渲染器,原始和打过补丁的渲染器分块哈希都会记录并接受校验;
- 少量确定性变换负责注入路由设置、每个 bot 的模型等界面(
scripts/lib/*-renderer-patch.mjs); - 成品使用独立的 bundle identifier
com.anysphere.sand.reconstructed,只做 ad-hoc 签名。
为什么保留出厂渲染器?分发包里没有前端源码和 source map,只有压缩过的生产分块。完整重写前端是一个大得多的独立逆向工程。frontend/ 是一份部分重建的设计工作区,可以用来理解 UI 契约,但它不是打包所用的渲染器。
下面按源码画出 Agent API 的真实调用链。Agent API 和 Codex Harness 都跑在 Mac 上;它们进入容器只靠 docker exec,桌面画面走宿主机回环端口转发进来的 noVNC。两种会话后端都在图里:codex(独立 Codex Harness,默认)和 grok(直接进入 bot 原生聊天)。
flowchart TB
%% #14(已合并):Codex provider 为 openai_compat、未配置不连默认代理;TokenHub 中继用 Node + openai-bridge.mjs,不再需要 bun / opencodex
subgraph CL["客户端"]
Client["网页工作台 /ui/ · CLI · Zcode · 自己的客户端"]
end
subgraph MAC["Mac 宿主"]
API["Node Agent API<br/>127.0.0.1:18770"]
JEV{"JEV 决策模型<br/>(规划中 / 未来版本)"}
App["Grok Node.app"]
State[("状态目录 JSON<br/>keys · sessions · tokenhub")]
Harness["codex app-server<br/>(codex 后端,Mac 子进程)"]
Docker["docker CLI<br/>exec / exec -i"]
Ports["回环端口转发<br/>127.0.0.1:6080 / 6081"]
Relay["TokenHub 中继 127.0.0.1<br/>Node + openai-bridge"]
end
subgraph BOX["Docker 容器 grok-node-local-vm(Linux)"]
Exec["codex exec-server<br/>shell · 文件 · 测试"]
Host["重建的 host<br/>gateway :1340 /api/*"]
Win["x11vnc 单窗口"]
VNC["noVNC websockify<br/>各 bot 桌面"]
end
subgraph EXT["外部模型端点"]
LLM["OpenAI 兼容 API<br/>/responses · /chat/completions"]
end
Client -->|"HTTP Bearer · SSE · WebSocket"| API
API -.- State
API -->|"JSON-RPC over stdio"| Harness
Harness -->|"environments.toml"| Docker
API -->|"grok 后端 / 名册 / 单应用"| Docker
API -->|"桌面 WebSocket(RFB 输入过滤)"| Ports
Harness -->|"providerConnection"| Relay
Docker -->|"stdio:exec-server"| Exec
Docker -->|"node -e → HTTP /api/*"| Host
Docker -->|"stdio:RFB"| Win
Ports -->|"websockify"| VNC
Harness -->|"HTTP Responses(config.toml)"| LLM
Relay -->|"HTTPS + 端点密钥"| LLM
App -->|"docker run · 挂载 host-main.cjs"| Host
%% 规划中 / 未来版本:以下虚线与虚框均未上线
API -.->|"会话路由(规划中)"| JEV
JEV -.->|"编码 / 工具型 → codex 后端"| Harness
JEV -.->|"原生对话 / 桌面型 → grok 后端"| Host
Harness <-.->|"会话上下文 / 历史互通(规划中)"| Host
classDef planned stroke-dasharray: 6 4
class JEV planned
图例:实线为已上线;虚线和虚框为规划中(未来版本)。
调用链说明(依据为 main 分支,未注明目录的文件都在 tools/node-agent-api/ 下;模型端点部分来自已合并的 #14)
| 步骤 | 说明 | 依据 |
|---|---|---|
| 1. 客户端 → API | 只监听 127.0.0.1:18770,校验 Host / Origin;REST 用 Authorization: Bearer,按 7 个 scope 授权;网页工作台由同一服务在 /ui/ 提供 |
cli.mjs:19、server.mjs:75-86,274、auth.mjs:8,63-65 |
| 2. 事件流 | GET …/events 带 Accept: text/event-stream 时返回 SSE |
server.mjs:240-245 |
| 3. 选择后端 | 会话的 backend 为 codex(Harness 适配器,默认)或 grok(原生适配器);--backend codex 时两个都装上 |
backends.mjs:5-15、server.mjs:159、cli.mjs:27-39 |
| 4. codex 后端 → app-server | 在 Mac 上启动 codex app-server 子进程,按行收发 JSON-RPC(thread/start、turn/start 等) |
runtime/harness.mjs:7,93,115-131 |
| 5. app-server → 容器执行端 | 生成 environments.toml,让 app-server 用 docker exec -i … setpriv … codex exec-server --listen stdio 进入容器执行工具 |
shared-runtime.mjs:173-176、runtime/codex.mjs:38-47 |
| 6. 模型请求 | 配了端点地址时,app-server 按 config.toml 里的 openai_compat provider 直连端点;未配置则不写 provider,也不连任何默认代理(#14) |
cli.mjs:25,36、inference-config.mjs:30-41、runtime/codex.mjs:27-31 |
| 7. TokenHub 中继 | 端点版本带密钥或用 Chat 协议时,会话带上 providerConnection,请求经本机中继转发到端点的 /responses 或 /chat/completions;中继用 Node 运行,Chat 协议由 openai-bridge.mjs 翻译(#14 起不再需要 bun / opencodex) |
codex.mjs:43-44、tokenhub.mjs:112,179-185、tokenhub-worker.mjs:6,39-45,62 |
| 8. grok 后端与 bot 名册 | docker exec <容器> node -e … 在容器里读 /home/box/sand-data/gateway.json 的 token,再 POST http://127.0.0.1:1340/api/<方法>;只允许 listAgents、sendPrompt、getAgentTranscript、createAgent 等 7 个方法。codex 后端也用这条通道查名册、建 bot |
grok-node.mjs:7-13,73,113-115、shared-runtime.mjs:23、cli.mjs:31-33 |
| 9. 整桌面画面 | POST …/desktop 签发一次性 ticket,兑换为 HttpOnly cookie;升级的 WebSocket 由 API 转连 ws://127.0.0.1:6080/websockify(或 :6081?token=<display>)。非控制者的键鼠消息被 RFB 过滤器丢弃;每个 bot 只有一个控制租约 |
desktop.mjs:36,80-84,98-138,184-247、grok-node.mjs:88-96、rfb-filter.mjs |
| 10. 单应用画面 | 本机随机端口的 WebSocket 服务为每个窗口起 docker exec -i node -e <application-stream>,在容器里对该窗口启动 x11vnc,RFB 字节走 stdio |
shared-runtime.mjs:111-131,181、application-stream.mjs |
| 11. 服务状态 | 密钥、会话、端点设置都存为 Mac 上的 JSON(默认 .lab/node-agent-shared,原子写入);Codex 会话目录默认 .lab/shared-runtime |
auth.mjs:14、store.mjs:10、persistence.mjs:16-21、cli.mjs:22,29 |
| 12. Grok Node.app 与容器 | App 用 docker run 创建容器,只读挂载重建的 host-main.cjs,把 1337/1339/1340/6080/6081/8790 发布到 127.0.0.1。Agent API 不创建、不重启容器 |
source/electron-main/box/local-docker-host-connector.ts:464-482 |
- JEV 决策模型(会话路由):自动判断普通对话该交给哪个后端,编码 / 工具型任务进 Codex Harness 会话(
codex后端),原生对话 / 桌面型任务进 Grok Node 原生聊天(grok后端)。未来版本上线,当前版本请在创建会话时用backend指定。 - 两类会话打通:Codex Harness 会话与 Grok Node 原生聊天之间互通会话上下文和历史。未来版本上线,当前版本请在创建会话时用
backend指定;两类会话的历史目前各自独立。
各 bot 使用不同桌面,但共用容器和数据。 API 的用户/bot 权限只限制请求范围,不构成共享文件系统上 bot 之间的隔离。
在 设置 → 路由(英文界面为 Settings → Router)选择新对话轮次使用的后端:
| Provider | 认证 | 说明 |
|---|---|---|
codex |
本机已有的 ChatGPT/Codex 登录(~/.codex,以只读方式挂进容器) |
不需要额外 API key |
openrouter(UI:TokenHub) |
通过桌面密钥桥保存的 API key | 默认档;可以选模型和推理强度 |
TokenHub 的 API 地址按以下顺序解析(resolveOpenRouterBaseUrl):
- 路由页 API address 中保存的值
- 环境变量
OPENROUTER_BASE_URL ~/.codex/config.toml(或$CODEX_HOME/config.toml)中的openai_base_url- 默认
https://openrouter.ai/api/v1
如果填入的是本机地址(127.0.0.1 / localhost),容器内的请求会改写到 host.docker.internal(resolveOpenRouterTransport)。
![]() Codex · 使用本机 Codex CLI 登录,并显示本地用量 |
![]() TokenHub · Local Docker VM 状态、API key、API address 和模型 |
路由页和 用量与账单 会显示本地累计的请求数和 token 数。这些只是活动记录,不能当作服务商的权威账单。
本地 Docker VM 是目前唯一的 box 运行时,也是默认值。应用在启动或切换时会做这些事:
- 检查
docker info。如果已经存在同名但不归本应用管理的容器(缺少com.grok-bot.local-vm=1标签),或者镜像不符,就报错并停止,不会替你删除; - host bundle 的 sha 或 schema 版本变化时,自动替换容器。持久卷会保留,容器临时层里的改动会丢失;
- 等待 gateway 就绪,最多 3 分钟,然后校验实际提供服务的 host 身份。
| 项目 | 值 |
|---|---|
| 容器名 | grok-node-local-vm(打包后的 Grok Node.app);开发运行时为 grok-bot-local-vm |
| 镜像 | cursorenvironments/universal@sha256:8c489b5f…(按 digest 固定,git-sha 2e44baf,Chrome 155,构建于 2026-10-21T01:03:42Z,完整地址见表下)。:sand-box-latest 标签只用来展示和兼容校验,不要换回这个会变动的标签 |
| 平台 | linux/amd64,--restart unless-stopped |
| 持久卷 | <容器名>-workspace → /workspace,<容器名>-data → /home/box/sand-data |
| 只读挂载 | 重建的 host-main.cjs → /opt/sand/sand-host/host-main.cjs、box-exec-daemon → /opt/sand/box-exec-daemon、~/.codex → /root/.codex(存在时)。挂载目标取自镜像自己的 host 目录(上游 2026-10-12 起改到 /opt/sand/sand-host,本项目已迁到该根),不是自选路径 |
| 上游自动更新 | 通过 SAND_BOX_AUTO_UPDATE=0 关闭,防止上游 host 覆盖重建版本 |
public.ecr.aws/k0i0n2g5/cursorenvironments/universal@sha256:8c489b5f7f690b38acbf991e584a474bcc15cf81ebfe858c60235761191df1bd
端口全部只绑定 127.0.0.1:
| 端口 | 用途 |
|---|---|
| 1337 | box 执行守护进程 |
| 1339 | fork desktop router |
| 1340 | host gateway |
| 6080 | 主 noVNC 桌面 |
| 6081 | fork noVNC 桌面 |
| 8790 | egress 隧道 websocket |
截图:OrbStack 中的 grok-node-local-vm 容器(端口转发与挂载)
Node Agent API 是 Grok Node 的外部适配 API,借鉴了 agents / sessions / events 的概念,但不兼容 OpenAI Agents SDK。后端实际支持哪些能力,以运行时 GET /v1/capabilities 的返回为准。
| 能力 | 接口 |
|---|---|
| 对话与任务 | bot 查询、会话、消息、SSE 事件、回合结果、审批、取消 |
| 会话执行方式 | backend: "codex"(独立 Codex Harness,默认)或 backend: "grok"(直接进入 Bot 原生聊天,用 Grok Node 自己的模型设置) |
| 模型与端点 | 获准模型清单、服务/bot 默认、TokenHub 地址/密钥/模型拉取与实际测试 |
| 桌面与单应用 | 整个桌面或单个终端/浏览器窗口的观看、接管与交还;手动传递剪贴板 |
| 项目与恢复 | 导入、Git 差异、归档导出、项目与会话备份/恢复 |
| 授权与治理 | Bearer 密钥、scope、派生 key、短期桌面 ticket、控制租约、配额、审计、签名 webhook |
启动参数(tools/node-agent-api/cli.mjs):
| 参数 | 默认值 | 说明 |
|---|---|---|
--backend codex|grok |
codex |
grok 单独启动时默认只读 |
--allow-writes true|false |
false |
仅对 --backend grok 生效,允许发送原生消息 |
--port |
18770 |
只监听 127.0.0.1 |
--state |
.lab/node-agent-shared |
密钥、会话等服务状态 |
--runtime-state |
.lab/shared-runtime |
Mac 端 Codex 会话目录 |
--container |
grok-node-local-vm |
|
--workspace |
/workspace/codex-projects/node-agent-api |
容器内共享项目 |
--base-url |
空(不连任何代理) | OpenAI 兼容端点地址,也可用 NODE_AGENT_BASE_URL,见配置模型端点 |
--api-key |
空 | 端点密钥;建议改用 NODE_AGENT_API_KEY,启动参数会出现在进程列表里 |
--wire-api chat|responses |
自动 | 端点协议,也可用 NODE_AGENT_WIRE_API |
--model |
空 | 服务默认模型,也可用 NODE_AGENT_MODEL;为空时按模型策略决定 |
--namespace |
grok-node-lab-shared |
|
--codex-bin |
— | 指定 Mac 端 codex 可执行文件 |
--recover true|false |
— | 启动前恢复残留的服务锁 |
CLI(npm run node-agent -- … 等价于 node tools/node-agent-api/client-cli.mjs …)支持的子命令有 ensure、status、desktop、codex、resume、backup、recreate:
node tools/node-agent-api/client-cli.mjs status BOT_ID
node tools/node-agent-api/client-cli.mjs codex BOT_ID
node tools/node-agent-api/client-cli.mjs resume BOT_ID --thread THREAD_ID --prompt "运行测试"
node tools/node-agent-api/client-cli.mjs desktop BOT_ID --session API_SESSION_ID --mode viewAgent API 只需要一个 OpenAI 兼容的模型 API,不需要 Bun,也不需要 opencodex 或其他协议包。什么都不配时,端点地址为空,服务不会去连任何默认代理。
1. 启动时配置(tools/node-agent-api/inference-config.mjs)。优先级:启动参数 → 环境变量 → 已保存的 tokenhub.json;空字符串视为未设置。
| 启动参数 | 环境变量 | 说明 |
|---|---|---|
--base-url |
NODE_AGENT_BASE_URL |
端点根地址,例如 https://example.com/v1 |
--api-key |
NODE_AGENT_API_KEY |
端点密钥;必须同时给地址。建议用环境变量,启动参数会出现在进程列表里 |
--model |
NODE_AGENT_MODEL |
服务默认模型 |
--wire-api |
NODE_AGENT_WIRE_API |
chat 或 responses |
| — | NODE_AGENT_MODELS |
逗号分隔的模型 id,供没有 /models 的端点使用 |
| — | NODE_AGENT_MODEL_CATALOG |
旧式 slug 目录文件路径(可选) |
export NODE_AGENT_BASE_URL='https://example.com/v1'
export NODE_AGENT_API_KEY='...'
export NODE_AGENT_MODEL='YOUR_MODEL'
npm run node-agent-api -- --backend codex --port 18770 --recover true没有指定协议时:
- 有密钥:按 Chat Completions。Mac 上的 Node 桥(
openai-bridge.mjs、tokenhub-worker.mjs)把 Codex 发出的 Responses 请求翻译成 Chat,再把流式结果译回 Responses。密钥只留在 Mac,不写入 Codex 配置,也不进入 Linux 执行进程。 - 只有地址:按 Responses 直连,不启动桥。Codex 配置里的 provider 名是
openai_compat(runtime/codex.mjs)。把地址指向自己的本地 Responses 代理也可以,服务不会替你启动那个代理。
tokenhub.json 里已经有通过接口保存的端点版本时,启动参数不会改写它;还没保存过地址时,本次启动的值会写成初始版本。
2. 运行中配置(TokenHub):owner 在网页“管理员模型设置 → TokenHub 账户与端点”里操作,或直接调接口:
| 步骤与接口 | 说明 |
|---|---|
设置端点PATCH /v1/settings/tokenhub |
字段 base_url、api_key(只写)、wire_api(chat/responses)、models(可选,模型 id 列表)。带了 base_url 但没带 wire_api 时默认 chat。地址必须是 HTTPS,或 127.0.0.1/localhost 的 HTTP。换地址会清除旧密钥。每次修改都会新建端点版本,已有会话继续用创建时的版本 |
拉取模型POST /v1/settings/tokenhub/models |
从 {base_url}/models 拉取模型列表 |
连接测试POST /v1/settings/tokenhub/test |
body model、可选 reasoning_effort。真实调用一次端点,会消耗额度;测试通过后才能授权该模型 |
授权模型PATCH /v1/settings/models |
字段 default_model、bot_defaults、allowed_models、verified_models;把测试通过的模型加入获准清单 |
模型目录按顺序取:端点 /models 的结果 → PATCH 传入的 models 或 NODE_AGENT_MODELS → NODE_AGENT_MODEL_CATALOG 指向的目录文件。都没有时返回 503 model_catalog_unavailable,已有会话的模型不受影响(models.mjs)。
密钥用 AES-256-GCM 加密,保存在 --state 目录下的 tokenhub.json,加密密钥在同目录的 tokenhub.master.key(0600)。详见 TokenHub 账户与端点。
延伸文档:
- Node Agent API 0.3.0 详细文档:完整接口索引、请求示例、单应用 VNC、恢复与排障
- 安装与运行说明
- 模型选择与默认设置 · TokenHub 账户与端点
- 后台运行与排障 · VNC 第一阶段 · 性能
- OpenAPI 3.0 契约 · 验证记录
在 Zcode 里输入“在远程电脑上的浏览器打开 baidu.com”,然后切到 Grok Node 查看同一个 bot 的桌面。(约 42 秒,中文字幕)
zcode-grok-node-baidu-demo-v2.mp4
把抽奖从「幸运三人组」改成「幸运六人组」,完成自检并发布到容器后,在远程浏览器里确认结果。(约 28 秒,中文字幕)
codex-cli-grok-node-28s-under10mb.mp4
在 Zcode 里给 bot 加上 dots 样式的桌面面板:缩略图观看、放大接管、再交还控制。
screen-recording_github_under10MB.mp4
打包后的 Grok Node.app 使用下面这套独立身份,因此可以与官方 Grok Bot 同时运行;机器上已安装的官方应用也不会被覆盖。开发运行和测试仍沿用旧的共享身份。
| 项目 | Grok Node.app |
|---|---|
| Bundle ID | com.anysphere.sand.reconstructed |
| Electron 用户目录 | ~/Library/Application Support/Grok Node |
| 数据根 | ~/.groknode |
| Docker 容器 | grok-node-local-vm |
| URL scheme | groknode;本机没有安装官方 Grok Bot 时还会注册 grokbot(打包时由 GROK_NODE_CLAIM_GROKBOT=auto|always|never 控制) |
显式设置的 SAND_DATA_ROOT / SAND_USER_DATA_DIR 优先于以上默认值。
只列出面向使用者或构建者的变量:
| 变量 | 作用 | 位置 |
|---|---|---|
GROK_BOT_018_APP |
bootstrap 时直接使用已有的 Grok Bot 0.18.0 应用 | scripts/bootstrap-runtime.mjs |
GROK_BOT_OUTPUT_APP_NAME |
自定义打包输出的应用名(默认 Grok Node.app) |
scripts/lib/config.mjs |
GROK_NODE_CLAIM_GROKBOT |
auto/always/never,控制是否注册 grokbot:// |
scripts/package-macos.mjs |
OPENROUTER_BASE_URL |
TokenHub 端点的备选来源 | source/shared/node/openrouter-proxy.ts |
CODEX_HOME |
Codex 配置目录(默认 ~/.codex) |
同上 |
SAND_DATA_ROOT / SAND_USER_DATA_DIR |
覆盖数据根和 Electron 用户目录 | source/shared/node/grok-node-identity.ts |
SAND_DOCKER_BINARY |
指定 docker 可执行文件(否则依次查找 /usr/local/bin、/opt/homebrew/bin、Docker.app 内置目录) |
local-docker-host-connector.ts |
SAND_FIRST_TOKEN_STALL_DEADLINE_MS |
首字停滞判定阈值(默认 150 秒) | docs/OPENCODEX_CHANNEL_TROUBLESHOOTING.md |
NODE_AGENT_BASE_URL / NODE_AGENT_API_KEY / NODE_AGENT_MODEL / NODE_AGENT_WIRE_API / NODE_AGENT_MODELS / NODE_AGENT_MODEL_CATALOG |
Node Agent API 的模型端点配置,见配置模型端点 | tools/node-agent-api/inference-config.mjs |
| 命令 | 作用 | 平台 |
|---|---|---|
npm run bootstrap |
校验并抽取固定的 0.18.0 构建输入 | macOS |
npm run check |
typecheck + source:typecheck + test |
任意 |
npm test |
全部 tests/*.test.mjs(含真实网络测试) |
任意 |
npm run test:offline |
排除真实网络测试(CI 使用) | 任意 |
npm run test:node-agent-api |
Agent API 离线回归 | 任意 |
npm run typecheck / npm run source:typecheck |
渲染器 / 运行时 TypeScript 检查 | 任意 |
npm run frontend:build |
构建可读的前端重建(不是打包所用渲染器) | 任意 |
npm run build |
只构建重建 ASAR(.build/app.asar),不打包应用 |
需要先 bootstrap |
npm run package |
check 之后构建、打补丁、签名并校验 dist/Grok Node.app |
macOS |
npm run verify |
校验已打包的应用 | macOS |
npm run smoke |
有时间上限的原生冒烟检查(退出码 0 通过 / 1 失败 / 2 前置条件不足) | macOS |
npm run diagnose |
OpenCodex 通道一键诊断(-- --json 输出 JSON;退出码 0/1/2 = OK/DEGRADED/DOWN) |
macOS |
npm run box:seed-apps |
把 scripts/box-apps.d/*.sh 的应用声明同步进容器 |
macOS |
npm run publication:check |
证明干净历史导出无损 | 任意 |
npm run node-agent-api / npm run node-agent |
启动 Agent API / Agent CLI | macOS(需要 Grok Node 容器) |
package:diagnostic、native:*、frontend:recover、marketplace:* 用于取证和对拍,普通贡献者一般用不到。
生成目录 .cache、.build、dist、src/app/dist、recovered、recovery、.lab 等都不纳入版本控制。
source/
electron-main/ 桌面生命周期、设置、认证、box 连接器、coordinator 所有权、RPC
electron-preload/ 暴露给 UI 的窄可信桥
host/ 推理、工具、MCP、设置与回合执行(在容器内运行)
node-agent-coordinator/ 转录路由、流式活动、表情回应、路由 MCP 桥
shared/ 共享契约、设置、协议与 provider 辅助
box-exec-daemon/ local-exec-daemon/ packages/ ...
frontend/ React/TypeScript 渲染器的部分重建与设计工作区
scripts/ bootstrap、编译、渲染器补丁、打包、签名、校验
box-apps.d/ 容器内应用声明(每次启动重新应用)
tools/
node-agent-api/ Node Agent API、网页工作台、CLI、OpenAPI
tests/ node:test 回归测试
research-archives/ Git LFS 保存的固定 0.18.0 DMG 及清单
manifests/ patches/ docs/
.github/workflows/check.yml 的内容:
- ubuntu:Node 26.5.0;
npm ci;typecheck、source:typecheck、test:offline、frontend:build、publication:check。 - macOS:应用身份与 URL scheme 等依赖 macOS 的测试。
- network(手动触发):真实网络的 web tools 测试。
在 Linux 上本地复现:
git lfs pull # 否则固定安装包的清单测试会失败(134 !== 155793020)
npm ci
npm run typecheck && npm run source:typecheck && npm run test:offline && npm run frontend:build- 所有 bot 都不回复、回复中断、左下角出现状态灯:先运行
npm run diagnose,再看 OpenCodex 通道故障排查。 - 路由页 Local Docker VM 卡片显示 Unavailable:确认 Docker/OrbStack 在运行,并检查是否有同名但不归本应用管理的容器。
- Agent API 打不开或桌面连不上:见 后台运行与排障。
- 应用可以启动,核心本地化链路可用:路由推理、已连接插件、本地 Docker 沙箱。
- 只面向一个固定的 macOS/arm64 版本(0.18.0),不提供 Windows / Intel 包,也不承诺兼容未来的 Grok Bot 版本。
- 依赖外部 provider 会话;
npm audit仍有与固定 Electron 42.1、Undici 5、AI SDK 4 等相关的告警(见 SECURITY.md)。 - 镜像固定在 digest
8c489b5f…(git-sha2e44baf,Chrome 155,构建于 2026-10-21T01:03:42Z),in-box host bundle 根目录为/opt/sand/sand-host:上游 2026-10-12 起把该根目录从/home/box/sand-host迁到/opt/sand/sand-host,重建 host 必须挂到镜像自己的启动路径上才会被 supervisor 拉起(挂错位置 = 死文件 + 上游 host 顶替,重建功能静默失效)。切换镜像时,镜像 pin 与挂载根必须一起改。
-
技术溯源与证据规则:PROVENANCE.md;法律声明:NOTICE.md;安全说明:SECURITY.md,请私下向仓库所有者报告问题。
-
固定构建输入:
平台 字节数 SHA-256 macOS arm64 155,793,020 a253ccd8aab01e083f9812a0264354c5034d8ba7f0610bbb557e82ae77d203eb校验方法见 research-archives/README.md。
-
贡献:先读 CONTRIBUTING.md;干净历史导出流程见 docs/PUBLISHING.md。





