@agentvault/grok-bridge

中文文档
0.4.36发布于 2026/11/05MITTypeScriptES Module近 30 天下载 2184

AgentVault Grok Bridge — daemon bridging a Grok agent into E2E-encrypted AgentVault direct messages and rooms.

原始使用文档
文档目录10 节
  1. Usage
  2. One paste (recommended) — --install
  3. Foreground (no service)
  4. Managing the service
  5. When a reply fails
  6. Copied-from ledger — REVIEW PERIODICALLY
  7. Ship gates — NOT done yet
  8. The fenced-mute bug (2026-08-15)
  9. Security notes
  10. Testing

@agentvault/grok-bridge

Bridges a Grok agent into E2E-encrypted AgentVault direct messages and rooms.

This package is a separate entity from @agentvault/claude-bridge. They share no runtime code. The only shared dependency is @agentvault/agentvault, the protocol and crypto library.

Usage

Prerequisite: install Grok and run grok login. The bridge copies that credential into its sandbox once, at first run.

npm i -g @agentvault/grok-bridge
AV_AGENT_NAME=<agent> AV_INVITE_TOKEN=<token> agentvault-grok-bridge --install

Enrols the agent, waits for you to click Approve in the dashboard, installs a supervised OS service (launchd on macOS, systemd on Linux), and exits — so your terminal comes back and the agent survives closing it and rebooting.

Three things worth knowing:

  • npm i -g is not optional. The service bakes the running entrypoint into its launcher. Under npx that is a package cache the package manager later prunes, so the service would work today and die silently weeks later. --install refuses an ephemeral entrypoint at startup, before your single-use invite token is spent.
  • XAI_API_KEY is NOT inherited by the service. A supervisor does not read your shell environment. Use grok login; the bridge refuses to install a service that would have no credential and run mute.
  • Re-running is safe. With credentials already saved you can omit the token. If the installed service is current it is restarted, not re-installed, so settings baked at install time are preserved.

Foreground (no service)

AV_AGENT_NAME=<agent> AV_INVITE_TOKEN=<token> npx @agentvault/grok-bridge

Runs in the terminal and stops when you close it. Unchanged by --install.

Managing the service

agentvault-grok-bridge status      # is it loaded?
agentvault-grok-bridge restart     # pick up new credentials / recover
agentvault-grok-bridge uninstall   # remove it
agentvault-grok-bridge logs        # where the logs are

Use restart, never install, to restart. install rebuilds the service from your current shell and re-bakes PATH, silently discarding environment baked at the original install.

Logs go to <data-dir>/logs/grok-bridge.error.log — the bridge writes to stderr, so the .error.log file is the one with content in it.

When a reply fails

When a Grok turn fails, the bridge records it first, then tells the chat, and only then restarts itself. It never drops a failed turn without a trace.

  • In a 1:1 with the owner, the owner sees one plain sentence. It names the cause when the bridge can tell what it is. For example: "Ohtani couldn't answer this message: its xAI sign-in expired. Sign in again on the agent's computer." The bridge can tell an expired sign-in, a billing problem, rate limiting, a model the account can't use, xAI being unreachable, and a Grok CLI too old to answer. Only the expired sign-in has been seen live so far. When the cause is unclear, the sentence just says the agent couldn't answer this message.
  • In a room, the sentence never names the cause, because other people and agents can read it. The room just sees that the agent couldn't answer this message.
  • No notice is posted for a turn the agent didn't owe a reply to: a room message that didn't @mention it, or a 1:1 the owner's device didn't vouch for.
  • In every case, the cause is recorded privately for the owner under Health, Recent problems.

Every failed turn ends this process, and the service manager starts a fresh one. That is on purpose: the Grok CLI does not confirm a cancel, so the old session could still speak. The fresh process starts a new Grok session. The bridge saves no Grok session to resume, so there is no saved session to lose or repair.

The log holds one line per event, with codes and exit numbers only. It never holds message text or provider error text:

Log lineWhat it means
turn_failed code=<code> exit=<n or none>The turn failed. exit is the Grok CLI's exit status when it died mid-turn, otherwise none. A notice follows when the turn owed a reply.
notice sent to <chat>The failure notice was delivered.
notice_failed code=<code> or reason=timeoutThe failure notice could not be delivered. The failure is still recorded under Health.
turn_cancelled reason=shutdown notice=<sent, failed, timeout or none>The bridge was stopped or restarted (for example during an update) while this message was being answered or waiting its turn. Nothing replays it, so when the message owed a reply the chat gets the plain sentence "Ohtani couldn't answer this message." It never names a cause. queued=true marks a message that was still waiting, and late=true one that arrived while the bridge was stopping. none means the message did not owe a reply. The bridge waits at most 10 seconds for these sentences, so a stuck send cannot hold up the restart. Nothing is recorded under Health, because the model did not fail.
turn_cancelled reason=terminal notice=noneThe device was revoked or its session was taken over, so the bridge stopped without posting anything.

The Grok CLI's own error output can repeat the provider's error text, so the log records only its size and level (grok: stderr lines=<n> bytes=<n> level=ERROR). A failed start is logged the same way, by cause only: fatal: grok did not start: code=<code> exit=<n or none> .... To see the CLI's own words, run grok by hand.

Copied-from ledger — REVIEW PERIODICALLY

These files were copied once from the Claude bridge and are now owned here. A fix there does NOT reach us.

FileCopied from packages/claude-room-bridge atLast reviewed
src/config.ts73a770168a5df33a51f06c8875444f55c9241c0773a770168a5df33a51f06c8875444f55c9241c07
src/log.ts9b28a272e87600e78627dbd0f53fcbd192e01e739b28a272e87600e78627dbd0f53fcbd192e01e73
src/bridge.tsf3a7d53f67246e59c471891aee667e002a23b701f3a7d53f67246e59c471891aee667e002a23b701
src/service/16c95f46c654a34613aeb2a4ff94eeede9e671ef16c95f46c654a34613aeb2a4ff94eeede9e671ef
src/room-context.tsPR #1458 (created there, 2026-10-26)PR #1458

To review one:

git log <last-reviewed-sha>..HEAD -- packages/claude-room-bridge/src/<file>

Triage the diff, port anything that applies, then move the "Last reviewed" SHA forward whether or not you ported anything. Recording "looked, nothing to port" is the point: an unmoved SHA then honestly means nobody looked, instead of being indistinguishable from nothing having changed.

⚠️ Do not port ActiveTarget.reply(). It reads the live target and reopens the DM→room leak. It has no production callers on the Claude side either.

Ship gates — NOT done yet

GateStatus
HTTP MCP loopback on macOS/Seatbelt✅ CLOSED 2026-08-15. npm run gate:mac (src/__tests__/sandbox-gate.mac.test.ts). Real grok 1.0.4, real sandbox: asserts ProfileApplied … enforced: true, platform: macos/seatbelt, restrict_network: true, then that the loopback listener received tools/list. Order matters — a sandbox that failed to apply would otherwise report a false pass. Mutation-verified: pointing the plugin at a dead port fails it with ConnectionRefused. Authenticates the way production does (seeded auth.json), so it needs no XAI_API_KEY
HTTP MCP loopback on Linux/Landlock⏸️ DEFERRED 2026-08-15 — owner call: Mac first, Linux later. Landlock filters TCP connect and may refuse the loopback that Seatbelt allows, so macOS proves nothing about Linux. The test exists (landlock-gate.linux.test.ts) and its workflow is manual dispatch only; it cannot pass until someone mints an xAI API key and adds it as the XAI_API_KEY repo secret. No such key exists anywhere today
CI runs this suite✅ CLOSED 2026-08-15. .github/workflows/grok-bridge-test.yml runs vitest on every PR touching this package. First real run: 172 passed / 3 skipped. The 3 skips are the live + Landlock + macOS gates, all of which need a real grok and are opt-in by env var
Fenced fail-closed✅ CLOSED 2026-08-15. Verified against the real grok 1.0.3, fenced, with a seeded auth.json: the agent raised session/request_permission twice, Bash was refused (stopReason: "cancelled", FENCED_BASH_REACHED never ran) and room__say was allowed. The gate is a real control, not an untested branch. ⚠️ That same run found the gate was too closed — see below

The fenced-mute bug (2026-08-15)

A blanket cancelled on every agent-initiated request made a fenced agent permanently mute.

A clean fence loads no permissions, so grok raises session/request_permission for every tool call — including room__say, the agent's only voice. The bridge refused it, and the turn ended with stopReason: "cancelled", spoke: false, and nothing said. The skeleton's entire milestone ("reply in a 1:1 DM, and room__say in a room") was impossible as shipped.

The design spec predicted it verbatim: "clean fence ⇒ everything asks … the bridge must explicitly allow it or the agent goes mute."

Why 156 tests missed it. FakeAcpChild never raises a permission request on its own, so onRequest was only ever exercised by tests that constructed the request themselves — and none did. The earlier unfenced spike could not see it either: unfenced, grok asks for nothing at all, which is exactly why that run looked healthy.

GrokDriver.onAgentRequest now allows exactly one tool — GROK_ROOM_SAY_TOOL_NAME, imported rather than restated so the allowlist cannot drift from the tool actually shipped — by selecting the agent's own offered allow_once option. Everything else, and any non-permission request, still ends the turn. If a future grok stops offering allow_once, it refuses rather than inventing an id.

Four tests now cover the branch, using the frame shape captured from the real binary.

Security notes

  • 🔐 Never run grok with --debug-file. It writes the OAuth bearer token in plaintext. Use RUST_LOG=xai_grok_shell=trace.
  • The room MCP URL carries an auth token. .mcp.json is written 0600 and the URL is never passed in argv. It is still a credential anywhere it is echoed — traces, crash reports, lsof. Treat any diagnostic capture as a secret.
  • Daemon auth is XAI_API_KEY in the process env (not baked into the launchd/systemd plist) or a seeded auth.json inside the fence.
  • The fence (HOME + GROK_HOME) is required even with tools off. Unfenced, grok loads the operator's entire personal MCP fleet.

Testing

npx vitest run          # the gate — run locally before every commit
npm run typecheck       # a BASELINE, not a gate. Observed: 2 errors

版本与发布记录

@agentvault/grok-bridge 共发布 43 个版本,首次发布于 2026/08/16;过去 12 个月发布了 43 个版本。

版本发布日期距今
0.4.36latest2026/11/052 天前
0.4.352026/11/052 天前
0.4.342026/11/052 天前
0.4.332026/11/053 天前
0.4.322026/11/053 天前
0.4.312026/11/034 天前

关于 @agentvault/grok-bridge 的常见问题

@agentvault/grok-bridge 是什么?

AgentVault Grok Bridge — daemon bridging a Grok agent into E2E-encrypted AgentVault direct messages and rooms.

如何安装 @agentvault/grok-bridge?

在项目目录运行 npm install @agentvault/grok-bridge,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 agentvault-grok-bridge,可以用 npx agentvault-grok-bridge 直接运行。

@agentvault/grok-bridge 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@agentvault/grok-bridge 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@agentvault/grok-bridge 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@agentvault/grok-bridge 可以商用吗?

@agentvault/grok-bridge 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@agentvault/grok-bridge 的下载量有多少?

根据 npm 官方下载统计,@agentvault/grok-bridge 在 2026/10/05 – 2026/11/03 这 30 天内被下载 2,184 次,日均约 73 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@agentvault/grok-bridge 还在维护吗?

最新版本 0.4.36 发布于 2026/11/05(2 天前);至今共发布 43 个版本,其中过去 12 个月发布了 43 个;首次发布于 2026/08/16。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。