Repository Wiki
zai-org/ZCode

server-distribution.server-runtime

server-distribution.server-runtime 负责为发行包中的 agent server 解析并注入启动 wiring,使随包提供的 zcode.cjs 能够通过 Node.js 的 stdio 模式启动,同时保留显式环境变量配置的最高优先级。

Purpose and Scope

本文档覆盖发行包运行时的 agent wiring 生成与解析逻辑,重点包括:

  • BundledAgentWiring 契约中的两个环境变量;
  • createReleaseAgentWiring 的发布态 wiring 生成规则;
  • resolveBundledAgentWiring 对入口目录中 zcode.cjs 的异步探测;
  • 显式 ZCODE_AGENT_SERVER_COMMAND 覆盖、文件不存在和路径构造等边界行为;
  • wiring 最终如何表达为 Node.js 进程命令、参数 JSON 以及 app-server --stdio 启动模式。

本文不覆盖 zcodeAgentProcessManager 的完整解析链、agent server 本身的协议实现、Electron runtime 的发现逻辑,也不覆盖发行包构建流程;这些实现细节在当前源材料中没有提供,应由相应主题页面说明。

Overview

该模块解决发行包环境与开发环境之间的运行时差异。源代码注释明确指出,发行包内 Core 不位于 monorepo 中,也没有 Electron runtime,因此默认的 agent 解析链可能无法找到可执行目标。模块通过构造两个环境变量来建立一个明确的 fallback:

  1. ZCODE_AGENT_SERVER_COMMAND 指向 Node.js runtime;
  2. ZCODE_AGENT_SERVER_ARGS_JSON 指向发行包中的 zcode.cjs,并追加 app-server 与 --stdio 参数。

实现提供两条入口:

  • createReleaseAgentWiring:同步创建发布态 wiring,不检查文件是否存在;
  • resolveBundledAgentWiring:异步检查 entryDir/zcode.cjs 是否可访问,只有文件存在时才返回 wiring。

两条入口都遵循同一优先级规则:只要调用者已经提供非空白的 ZCODE_AGENT_SERVER_COMMAND,模块就返回 null,不覆盖显式配置。这里的判断使用 optional chaining、trim() 和 truthiness,因此空字符串与仅包含空白字符的值都不会被视为有效覆盖。

Architecture

运行时关系可以概括为:调用方提供入口目录、Node.js 路径和环境变量;本模块生成 BundledAgentWiring;下游进程管理器读取两个环境变量,以 Node.js 启动 zcode.cjs app-server --stdio。

文本化架构:

  • 调用方 → createReleaseAgentWiring:用于直接生成发布配置;
  • 调用方 → resolveBundledAgentWiring:用于在入口目录中探测 bundled script;
  • resolveBundledAgentWiring → node:fs/promises.access:验证 zcode.cjs 可访问;
  • 两个工厂函数 → node:path.join:构造跨平台路径;
  • 返回值 → ZCODE_AGENT_SERVER_COMMAND 与 ZCODE_AGENT_SERVER_ARGS_JSON:供 agent 进程启动链使用。

当前提供的源材料没有给出完整的调用方、进程管理器实现或依赖注入注册位置,因此不能进一步断言 wiring 被哪个具体类消费,也不能据此推断 access 的权限语义之外的启动行为。

Core Responsibilities

BundledAgentWiring 契约

BundledAgentWiring 是一个接口,要求结果同时包含两个字符串字段:

字段含义
ZCODE_AGENT_SERVER_COMMAND启动 agent server 的命令;异步 bundled 解析路径返回 process.execPath,同步发布入口由调用方提供 runtimeNode。
ZCODE_AGENT_SERVER_ARGS_JSONJSON 编码的参数数组。参数顺序为 bundled zcode.cjs 路径、app-server、--stdio。

接口没有可选字段,也没有额外的状态或错误字段。无法生成 wiring 时通过 null 表示“本模块不接管配置”,而不是抛出异常。

createReleaseAgentWiring

该函数接收 runtimeRoot、runtimeNode 和环境记录。其控制流如下:

  1. 检查 env.ZCODE_AGENT_SERVER_COMMAND 是否存在且去除空白后仍有内容;
  2. 若存在,立即返回 null,保留显式命令;
  3. 否则将 runtimeNode 直接作为命令;
  4. 使用 join(runtimeRoot, "zcode.cjs") 构造脚本路径;
  5. 使用 JSON.stringify 编码 [脚本路径, "app-server", "--stdio"];
  6. 返回完整的 BundledAgentWiring。

该入口不调用文件系统 API,因此它只负责生成配置,不验证 runtimeRoot/zcode.cjs 是否实际存在。这个行为使其适合已经由发布流程保证目录布局的场景,但当前源材料没有证明调用方是否在此前完成了打包完整性检查。

resolveBundledAgentWiring

该函数接收 entryDir 和环境记录,采用更保守的运行时探测策略:

  1. 首先应用同样的显式命令优先级规则;
  2. 通过 join(entryDir, "zcode.cjs") 得到 bundled script 路径;
  3. 调用异步 access(bundlePath);
  4. 若 access 抛出任意错误,捕获后返回 null;
  5. 若检查成功,将 process.execPath 作为命令;
  6. 将 [bundlePath, "app-server", "--stdio"] 编码为 JSON 字符串并返回。

这里的 catch 没有区分错误类型。因而不存在、权限不足、路径无效或其他导致 access 失败的情况,在本函数看来都等价于“没有可用的 bundled wiring”。源代码没有记录错误,也没有重试,因此调用方若需要诊断具体失败原因,必须在其他层提供诊断机制。

Core Flow

一次 bundled 解析的实际流程是:环境覆盖检查 → 路径拼接 → 文件可访问性检查 → 命令选择 → 参数 JSON 编码 → 返回 wiring。显式命令存在时,流程在第一步结束;bundled 文件不可访问时,流程在文件检查步骤结束。

启动参数语义

成功返回的参数数组固定为三个元素,且顺序不可交换:

  1. bundled script 的绝对或调用方语义下的路径(由 join 生成);
  2. app-server,用于选择 server 应用模式;
  3. --stdio,用于选择标准输入输出通信模式。

代码通过 JSON.stringify 保存数组,而不是返回数组本身。这意味着消费者需要按约定读取并解析 ZCODE_AGENT_SERVER_ARGS_JSON;当前源材料没有包含消费者的解析代码,因此不能补充其解析失败或类型校验行为。

Data and Path Handling

路径由 Node.js path.join 构造,而不是通过字符串拼接。这避免了调用方自行处理路径分隔符,并使 runtimeRoot、entryDir 与 zcode.cjs 之间的组合遵循运行平台的路径规则。

两个入口的路径来源不同:

  • createReleaseAgentWiring 使用调用方传入的 runtimeRoot;
  • resolveBundledAgentWiring 使用调用方传入的 entryDir,并先用该路径执行可访问性检查。

异步入口成功时命令固定为 process.execPath,这表示当前运行 Node.js 进程的可执行路径;同步入口则使用调用方传入的 runtimeNode,因此两者在命令来源上并不完全相同。不能假设 runtimeNode 一定等于 process.execPath。

Configuration and Precedence

配置项类型默认行为说明
ZCODE_AGENT_SERVER_COMMANDstring | undefined未提供或仅空白时允许 bundled fallback非空白值会使两个函数都返回 null,表示由显式配置保留控制权。
ZCODE_AGENT_SERVER_ARGS_JSONstring由模块生成内容是 JSON 数组,元素为 bundled script 路径、app-server、--stdio。
runtimeRootstring无内部默认值createReleaseAgentWiring 用它定位 zcode.cjs。
runtimeNodestring无内部默认值createReleaseAgentWiring 将其直接作为命令。
entryDirstring无内部默认值resolveBundledAgentWiring 用它定位并检查 zcode.cjs。

优先级可以表示为:显式非空白 ZCODE_AGENT_SERVER_COMMAND > bundled wiring > null(没有可用的 bundled wiring)。注释进一步说明,环境变量覆盖是默认解析链的最高优先级,因此该模块不会覆盖开发者或部署者的显式命令。

Failure Modes and Edge Cases

显式命令覆盖

当命令字段包含有效字符时,两条入口均返回 null,而不是返回包含该命令的对象。这个返回值语义很重要:它表示 bundled 逻辑主动退出,让已有的解析或配置链继续处理显式命令。调用方不应把 null 解读为启动失败。

空字符串与空白字符串

判断条件使用 env.ZCODE_AGENT_SERVER_COMMAND?.trim()。因此 undefined、空字符串和只含空白字符的字符串都会进入 bundled 逻辑。源代码没有对其他环境变量进行类似检查。

Bundled script 不存在或不可访问

resolveBundledAgentWiring 对 access 的所有异常统一返回 null。该函数不会抛出文件系统异常,也不会创建目录、修改权限或尝试其他候选路径。

同步入口不验证文件

createReleaseAgentWiring 没有文件系统检查。若 runtimeRoot 错误或 bundled script 缺失,它仍会返回 wiring;启动阶段的后续行为不在当前实现中。调用方需要明确选择该入口所需的发布前置保证。

参数序列化

JSON.stringify 对固定的三个字符串参数执行序列化。源代码没有显式处理序列化异常;对于普通字符串输入,当前逻辑没有显示的异常分支。具体下游如何解析该值,当前源材料未提供。

Concurrency and Operational Considerations

createReleaseAgentWiring 是纯同步构造逻辑,不维护模块级状态,也没有共享可变缓存。resolveBundledAgentWiring 只执行一次异步 access 检查,同样没有状态写入或重试机制,因此源码未显示出锁、并发协调或缓存失效问题。

异步检查存在典型的检查与使用之间的时间窗口:文件在 access 成功后仍可能在真正启动前被删除或变更。当前实现没有对此进行二次打开或原子启动保证。这个结论仅适用于本函数本身;实际进程启动器是否有额外保护,当前源材料没有说明。

从运行角度看,返回 null 是一种正常的 fallback 信号,而不是异常。调用方需要继续其余解析链,否则显式命令或其他运行时路径可能不会被处理。由于当前没有调用方源码,不能确定该链的具体顺序和最终错误表现。

Extension Points

该模块公开的扩展边界主要是输入而非继承或插件机制:

  • 通过 runtimeRoot 或 entryDir 改变 bundled script 的定位根目录;
  • 通过 runtimeNode 改变同步入口的 Node.js 命令;
  • 通过 ZCODE_AGENT_SERVER_COMMAND 完全绕过 bundled fallback;
  • 通过替换或扩展调用方解析链,决定何时调用同步或异步入口。

源代码没有导出策略接口、钩子、重试参数或自定义参数列表配置,因此不应假设可以通过现有 API 改写 app-server 或 --stdio 参数。

API Reference

createReleaseAgentWiring(runtimeRoot: string, runtimeNode: string, env: Record<string, string | undefined>): BundledAgentWiring | null

生成发布态 bundled agent wiring。

参数:

  • runtimeRoot:用于定位 zcode.cjs 的根目录。
  • runtimeNode:返回 wiring 中的命令字符串。
  • env:用于检查是否存在显式 ZCODE_AGENT_SERVER_COMMAND 的环境记录。

返回值:

  • BundledAgentWiring:未检测到显式命令时返回,参数为 [join(runtimeRoot, "zcode.cjs"), "app-server", "--stdio"] 的 JSON 表示。
  • null:ZCODE_AGENT_SERVER_COMMAND 去除空白后有内容时返回。

异常:

实现没有显式抛出异常分支,也没有执行文件系统操作。

resolveBundledAgentWiring(entryDir: string, env: Record<string, string | undefined>): Promise<BundledAgentWiring | null>

异步探测入口目录中的 bundled zcode.cjs,并在可访问时生成 wiring。

参数:

  • entryDir:包含 zcode.cjs 的入口目录。
  • env:用于检查显式命令覆盖的环境记录。

返回值:

  • Promise<BundledAgentWiring>:显式命令不存在且 join(entryDir, "zcode.cjs") 通过 access 检查时返回。命令为 process.execPath。
  • Promise<null>:存在显式命令,或 bundled script 的访问检查失败时返回。

异常:

access 抛出的错误会在函数内部捕获并转换为 null。其他未显示在实现中的异常行为无法从当前源材料确定。

Tests and Verification Boundaries

当前提供的源材料只包含实现和注释,没有测试文件,因此无法确认仓库是否已经覆盖以下行为:

  • 非空白显式命令返回 null;
  • 空白命令允许 fallback;
  • runtimeRoot 与 entryDir 的路径拼接;
  • 参数 JSON 的顺序和内容;
  • bundled 文件不可访问时返回 null;
  • 异步入口使用 process.execPath,同步入口使用传入的 runtimeNode。

这些行为是实现中可直接观察到的契约,但测试覆盖率、测试框架和调用方集成验证在当前材料中均未提供。不能据此声称已有自动化保证。

Source Attribution Note

本页所依据的源代码片段已在任务上下文中提供,并包含实现行号 1–48;但当前运行上下文没有提供可用于构造仓库文件链接的实际文件路径和 File Reference Base URL。因此,本页没有伪造源链接或仓库地址。按照可验证性要求,具体源文件链接应在获得真实运行时 URL 与相对路径后补充。

  • 对于 zcodeAgentProcessManager 的完整命令解析优先级,请参阅该组件对应的文档页面(当前源材料未提供具体目录链接)。
  • 对于 app-server 的 stdio 协议和服务端实现,请参阅 agent server 协议/运行时文档(当前源材料未提供具体目录链接)。
  • 对于发行包构建与 zcode.cjs 产物布局,请参阅 server distribution 构建文档(当前源材料未提供具体目录链接)。

Sources

(1 files)