Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

环境变量透传

守护进程作为后台进程运行,通常拥有精简的环境。你的终端则拥有由 shell 配置文件设置的完整环境。环境变量有两种方式可以传递给由 agent 派生的 shell 子进程。

zerocode 转发(自动)

当 zerocode 连接时,它会捕获自身的进程环境并将其作为 initialize 握手的一部分发送给守护进程。守护进程会将该快照存储在 TuiRegistry 中,并以 zerocode 的唯一 tui_id 作为键。当你打开新的聊天会话(session/new)时,守护进程会查找 zerocode 的快照,并将其克隆到 agent 的 ShellTool 中。随后,对于 agent 生成的每个 shell 子进程,该克隆都会叠加在 safe-env 基线之上:

cmd.env_clear()
  → Layer 1: SAFE_ENV_VARS + shell_env_passthrough (from daemon process)
  → Layer 2: zerocode's env snapshot (wins on conflict)

zerocode 变量在冲突时优先:你的 PATHHOME 和凭据套接字会优先于守护进程所继承的任何值。无需任何配置。

这就是为什么当你从运行着 ssh-agent 的终端启动 zerocode 时 SSH_AUTH_SOCK 能够生效,即使该守护进程是作为服务启动且没有 agent:

sh

# 终端已通过 ssh-agent 或硬件令牌(YubiKey 等)设置 SSH_AUTH_SOCK
echo $SSH_AUTH_SOCK
# /run/user/1000/gnupg/S.gpg-agent.ssh

# 守护进程作为 systemd 服务启动,其环境中没有 SSH_AUTH_SOCK。
# zerocode forwards its env at connect time, so any shell command the agent
# runs(git push、ssh、gpg-sign)会从你的终端获取 SSH_AUTH_SOCK。

zerocode 会发送其完整的环境变量。在共享或远程守护进程中,如果这会带来安全隐患,请使用 WSS 并配合专用用户账户。

多客户端连接:避免跨会话相互覆盖

每个 zerocode 实例都会获得一个唯一的 tui_idtui_ + 8 个随机十六进制字符)。该注册表是一个 HashMap<tui_id → TuiEntry>,各个条目之间完全独立:

TuiRegistry
├── "tui_a1b2c3d4"  →  { env: { PATH: "/home/alice/…", VIRTUAL_ENV: "…" } }
├── "tui_beef0042"  →  { env: { PATH: "/home/bob/…"  } }
└── "tui_cafe1234"  →  { env: { PATH: "/opt/pyenv/…" } }

当 zerocode tui_a1b2c3d4 打开一个会话时,只会克隆并使用 它自己的 环境变量快照。其他客户端的环境变量永远不会被修改。具体来说:

场景结果
从具有不同 PATH 的不同 shell 中打开两个客户端每个会话都有各自的 PATH,互不影响
客户端 A 设置了 VIRTUAL_ENV;客户端 B 没有只有来自 Client A 的会话才能看到 VIRTUAL_ENV
客户端 A 在客户端 B 的会话运行时断开连接客户端 B 不受影响;env 在会话创建时已克隆
客户端 A 使用相同的 tui_id 重新连接旧条目被移除,注册了带有新环境的新条目;已经运行的会话保留其原始克隆

最后一点很重要:get_env 返回的是一个克隆,而非引用。会话一旦创建,就拥有了自己的环境快照。源客户端的重新连接或断开连接对正在运行的会话没有任何影响。

风险配置直通(显式允许列表)

风险配置文件中的 shell_env_passthrough 用于控制将 守护进程自身的进程环境 中的哪些变量传递给 shell 子进程。当你希望无论 zerocode 是否已连接都能使用特定变量时,这非常有用,例如在守护进程自身已设置这些变量的无头服务器上。

子代理无法将此列表扩展到超出父级策略所允许的范围:添加父级列表中不存在的变量会被作为策略提权而拒绝。