docs(i18n): align single-exe terminology

Add canonical Chinese bindings for build target, deploy root, peer
dependency, serving surface, wheel, wrapper, and VFS so future translations
have one source of truth. Apply the existing runtime, plugin, artifact, and
pipeline bindings throughout every Chinese counterpart touched by this PR.

Require the first Chinese use of peer dependency to retain the English term
so readers can map it back to the package-manager concept without
reintroducing mixed prose throughout the document.

Rewrite mixed-language prose where the English term is not an identifier,
while retaining package names, paths, flags, pkg, single-exe, and other
literal names exactly. Explain VFS on first use and keep technical constraints
readable without inventing compatibility terminology.

Describe single-executable worker support as implemented behavior, including
the filesystem-string entry contract and CommonJS worker artifact required by
the pkg loader, and remove the obsolete bundled-but-unsupported limitation.

Regenerate pairing fingerprints and the generated catalog reference so the
mechanical documentation gates validate the revised English and Chinese
pairs. This keeps the terminology table authoritative and prevents the two
languages from drifting as the runtime documentation evolves.
This commit is contained in:
Tianyi Cui
2026-07-13 21:03:25 +08:00
parent ebcfab1621
commit b49c37f83a
11 changed files with 69 additions and 62 deletions

View File

@@ -212,7 +212,7 @@ export interface Config {
}
```
Source: [`packages/code-runtime/code-runtime-worker/src/index.ts:29`](../packages/code-runtime/code-runtime-worker/src/index.ts)
Source: [`packages/code-runtime/code-runtime-worker/src/index.ts:30`](../packages/code-runtime/code-runtime-worker/src/index.ts)
## `@deepseek-ai/dsh-compact-basic`

View File

@@ -22,6 +22,7 @@
| RAG | RAG | 首次出现可写检索增强生成RAG |
| SDK | SDK | |
| SSE | SSE | 首次出现可写SSEServer-Sent Events |
| VFS | VFS | 首次出现写虚拟文件系统VFS |
| agent | agent | 首次出现可写agent智能体 |
| agent loop | agent loop | |
| backlog | backlog | 双语翻译语境指待翻清单 |
@@ -52,6 +53,7 @@
| block | 块 | |
| background task | 后台任务 | |
| backend | 后端 | |
| build target | 构建目标 | |
| capability | 能力 | |
| cancel | 取消 | |
| checkpoint | 检查点 | |
@@ -66,6 +68,7 @@
| coverage | 覆盖率 | |
| crash recovery | 崩溃恢复 | |
| dispose | dispose | 首次出现可写dispose释放资源正文优先保留英文 |
| deploy root | 部署根目录 | |
| durability | 持久性 | |
| enforcement frontier | 强制边界 | i18n 机制词manifest `required` 清单所划的门禁生效范围 |
| event log | 事件日志 | |
@@ -95,6 +98,7 @@
| module | 模块 | |
| orphan | 孤立 | git 官方中文同译(如「孤立分支」);指英文源已不存在的 `.zh.md`;不要译作:孤儿 |
| pairing | 配对 | |
| peer dependency | 对等依赖 | 首次出现写对等依赖peer dependency |
| permission | 权限 | |
| persistence | 持久化 | |
| pipeline | 流水线 | |
@@ -110,6 +114,7 @@
| runtime | 运行时 | |
| sandbox | 沙箱 | |
| service | 服务 | |
| serving surface | 对外服务接口 | |
| session | 会话 | |
| session event | 会话事件 | |
| smoke test | 冒烟测试 | |
@@ -133,4 +138,6 @@
| turn | 轮次 | |
| typecheck | 类型检查 | |
| vocabulary | 词汇 | |
| wheel | wheel 包 | |
| workflow | 工作流 | |
| wrapper | 包装层 | |

View File

@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write
2026-07-10-single-file-executable-sdk-runtime-distribution.md: 511f5f2cf8b43aac5960dfe4630f489ec3dc5086
2026-07-10-single-file-executable-sdk-runtime-distribution.zh.md: 6774fc7ec2d9439154305ba0ae35dceeff922a4a
2026-07-10-single-file-executable-sdk-runtime-distribution.md: ac392a80310e70c846e80b6660bab22e01acfeb2
2026-07-10-single-file-executable-sdk-runtime-distribution.zh.md: 021ca6a1c5c4b4214bf9dc16931c5b32a7117c9b

View File

@@ -58,7 +58,7 @@ The exe's "must be explicitly configured" hard semantic is unchanged; the zero-c
## Disposition of worker-style plugins
`dsh-workflow-workerthread` and `dsh-code-runtime-worker` are supported inside the exe. Their built entries convert the sibling worker URL with `fileURLToPath()` and pass the resulting filesystem string to `Worker`, which is the form pkg's Worker hook resolves inside the VFS. The workflow engine keeps its data-URL bootstrap for unbuilt source execution; only its built sibling entry uses the filesystem string. The custom-config executable smoke loads both backends, invokes a real `run_code` call and a zero-agent `workflow` call, and requires each worker to return `42` from inside pkg's VFS.
`dsh-workflow-workerthread` and `dsh-code-runtime-worker` are supported inside the exe. Their built hosts convert the sibling `lib/worker.cjs` URL with `fileURLToPath()` and pass the resulting filesystem string to `Worker`, which is the form pkg's Worker hook resolves inside the VFS. The worker entries are CommonJS because that hook compiles VFS worker files as CommonJS. The workflow engine keeps its data-URL bootstrap for unbuilt source execution; only its built sibling entry uses the filesystem string. The custom-config executable smoke loads both backends, invokes a real `run_code` call and a zero-agent `workflow` call, and requires each worker to return `42` from inside pkg's VFS.
## Testing

View File

@@ -6,80 +6,80 @@ Status: implemented
## 问题
DeepSeek Harness 需要为 Python 库专门提供一个免安装 Node、可直接在目标平台运行的 SDK 分发形态:一个单文件可执行程序(下称 exe对外提供 stdio JSON-RPC 服务面`HarnessSdkServer`Python SDK 的对端),且实际启动的插件与配置完全由 exe 外部输入的 `cordis.yml` 决定。
DeepSeek Harness 需要为 Python 库专门提供一种无需安装 Node、可直接在目标平台运行的 SDK 分发形态:一个单文件可执行程序(下称 exe通过 stdio 提供 JSON-RPC 对外服务接口`HarnessSdkServer`Python SDK 的对端),且实际启动的插件与配置完全由 exe 外部输入的 `cordis.yml` 决定。
- 与 Python SDK 通信的 JSONRPC 协议已经过验证
- 需要提供标准化 cordis.yml 加载所有插件ESModule)的能力
- 与 Python SDK 通信的 JSON-RPC 协议已经过验证
- 需要提供通过标准化 `cordis.yml` 加载所有插件ES 模块)的能力
- 分发物要自带 Node 运行时,并支持本地源码链接的调试模式
## 决策
### 打包路线:@yao-pkg/pkg 的 `--sea` 模式
exe 用 [@yao-pkg/pkg](https://github.com/yao-pkg/pkg)vercel/pkg 归档后的活跃维护 fork**`--sea`enhanced SEA模式**打包。相比 Node 原生 SEApkg 在其上加 `/snapshot` VFS 与运行时模块钩子ESM 入口原样交给 Node 默认 ESM loader不依赖任何 ESM→CJS 转译。
> 实测macos-arm64、node24 target、pkg 6.21.0VFS 内裸包名 ESM 动态 import含顶层 await、CJS 互操作、`node:sqlite`、集合外包名 fail loud、VFS 外磁盘 ESM import 全部通过,`import.meta.url` 原样为 `file:///snapshot/...`。
exe 使用 [@yao-pkg/pkg](https://github.com/yao-pkg/pkg)vercel/pkg 归档后的活跃维护 fork**`--sea`enhanced SEA模式**打包。相比 Node 原生 SEApkg 在其上`/snapshot` 虚拟文件系统(VFS与运行时模块钩子,ESM 入口原样交给 Node 默认 ESM loader不依赖任何 ESM→CJS 转译。
> 实测macos-arm64、node24 构建目标、pkg 6.21.0VFS 内裸包名 ESM 动态 `import()`(含顶层 `await`、CJS 互操作、`node:sqlite`、集合外包名明确报错、VFS 外磁盘 ESM `import()` 全部通过,`import.meta.url` 原样为 `file:///snapshot/...`。
`--sea` 要求 target ≥ node22exe 统一以 node24 为 target次 pkg 调用只打一个 target,多平台各调一次。
`--sea` 要求构建目标 ≥ node22exe 统一以 node24 为构建目标;每次 pkg 调用只打一个构建目标,多平台各调一次。
术语提醒pkg 的 `/snapshot` VFS 与本仓库测试体系的「snapshot」ACP replay goldens`$DSH_SNAPSHOT`)无关,本文用VFS指前者。
术语提醒pkg 的 `/snapshot` VFS 与本仓库测试体系的“快照”ACP 回放 golden、`$DSH_SNAPSHOT`)无关,本文用VFS指前者。
### serving 面是插件ui/jsonrpc + ui/jsonrpc-agent 两包
### 对外服务接口也是插件ui/jsonrpc + ui/jsonrpc-agent 两包
确定性协议实现(`server.ts` / `transport.ts`)按 `ui/acp` + `ui/acp-agent` 的既有模式落为两包——serving 面本身也是插件:
确定性协议实现(`server.ts` / `transport.ts`)按 `ui/acp` + `ui/acp-agent` 的既有模式落为两包——对外服务接口本身也是插件:
- [`packages/ui/jsonrpc`](../../../../packages/ui/jsonrpc/README.md)`@deepseek-ai/dsh-jsonrpc`):纯协议插件apply 时在进程 stdio 上挂 `HarnessSdkServer` + 行式 JSON-RPC transportdisposal `ctx.effect()`。是否服务由 `cordis.yml` 决定;一份 yml 没挂它就是一个不 serve 的合法进程。协议级退出归插件`shutdown` 请求应答后 dispose 自身 fiber `exit(0)`HMR 式卸载只停服务不退进程)。
- [`packages/ui/jsonrpc-agent`](../../../../packages/ui/jsonrpc-agent/README.md)`@deepseek-ai/dsh-jsonrpc-agent`薄 app bin——`installFailLoud` + `loadEnv` + 配置发现 + [`dsh-app-boot`](../../../../packages/ui/app-boot/src/index.ts) 的 `boot()`boot 完即毕server 由 yml 里`dsh-jsonrpc` 条目带起。依赖只有 app-boot。进程级退出归 binstdin EOF/SIGTERM → dispose 后 0SIGINT → 130
- [`packages/ui/jsonrpc`](../../../../packages/ui/jsonrpc/README.md)`@deepseek-ai/dsh-jsonrpc`):纯协议插件;执行 `apply`在进程 stdio 上挂 `HarnessSdkServer` 与按行传输的 JSON-RPC 层,资源释放`ctx.effect()`。是否提供服务由 `cordis.yml` 决定;未挂载该插件的配置会启动一个不提供此服务的合法进程。协议级退出归插件所有(应答 `shutdown` 请求后 dispose 自身 fiber,再调用 `exit(0)`HMR 式卸载只停服务不退进程)。
- [`packages/ui/jsonrpc-agent`](../../../../packages/ui/jsonrpc-agent/README.md)`@deepseek-ai/dsh-jsonrpc-agent`轻量应用入口——`installFailLoud` + `loadEnv` + 配置发现 + [`dsh-app-boot`](../../../../packages/ui/app-boot/src/index.ts) 的 `boot()``boot()` 完成后入口即完成,服务器由 `cordis.yml``dsh-jsonrpc` 条目启动。它只依赖 `app-boot`。进程级退出归 `bin` 所有stdin EOF/SIGTERM → dispose 后返回 0SIGINT → 130
配置发现通道,缺失即报错:`DSH_CORDIS_CONFIG` 环境变量优先SDK 客户端约定argv 位置参数次之;无任何默认路径或内置回退——实际启动的插件由外部 cordis.yml 决定是硬语义。
配置发现有两个通道,缺失时立即报错:优先使用 `DSH_CORDIS_CONFIG` 环境变量SDK 客户端约定),其次使用 argv 位置参数;没有默认路径或内置回退——实际启动的插件由外部 `cordis.yml` 决定是硬语义。
### 插件解析VFS 装真实包树,闭包清单即 deploy root
### 插件解析VFS 装真实包树,闭包清单就是部署根目录
exe 的 VFS 内是**构建产物形态的真实包树**(各包 `lib/` + 真实 `node_modules`Loader 解析插件名走标准动态 `import()`:裸包名从 VFS 内 Loader 位置沿 `node_modules` 向上解析,然落在 VFS 内。封闭集不需要白名单代码——集合就是 VFS 装了什么,引用集合外的名字 import 失败。
exe 的 VFS 内是**构建产物形态的真实包树**(各包 `lib/` + 真实 `node_modules`。loader 通过标准动态 `import()` 解析插件名:裸包名从 VFS 内 loader 所在位置沿 `node_modules` 向上解析,然落在 VFS 内。封闭集不需要白名单代码——VFS 中安装了什么,集合中就有什么;`import()` 集合外的名称会失败。
deploy root 是 [`python/sdk-runtime/package.json`](../../../../python/sdk-runtime/package.json)`dsh-jsonrpc-agent-pkg`pnpm workspace 成员、零代码纯依赖清单)——「exe 装什么插件」与「Python runtime 分发什么」的合一事实源。 exe 加插件 = 清单加一行依赖再重打包。[`scripts/verify-runtime-closure.ts`](../../../../scripts/verify-runtime-closure.ts) 遍历该清单覆盖的全部 workspace 包,要求每个非 optional workspace peer 显式列在 runtime root,并报告引用包 → 缺失 peer」的完整链路CI static、pre-push 与 single-exe 构建都会在打包前运行该门禁。deploy 还会按各包 `files` 打包,因此 tsdown 拆出的共享 chunk 必须被 `files` 覆盖。
部署根目录是 [`python/sdk-runtime/package.json`](../../../../python/sdk-runtime/package.json)`dsh-jsonrpc-agent-pkg`pnpm 工作区成员、零代码纯依赖清单)也是“exe 安装哪些插件”与“Python 运行时分发什么”的统一事实源。 exe 加插件,就是在清单中增加一行依赖后重新打包。[`scripts/verify-runtime-closure.ts`](../../../../scripts/verify-runtime-closure.ts) 遍历该清单覆盖的全部工作区包要求每个非可选的工作区对等依赖peer dependency都显式列在运行时根目录,并报告引用包 → 缺失对等依赖”的完整链路CI 静态检查、pre-push 与 single-exe 构建都会在打包前运行该门禁。部署还会依据各包 `files` 字段打包,因此 tsdown 拆出的共享分片必须被 `files` 覆盖。
### 构建管线与产物
[`scripts/build-exe-for-python-sdk.ts`](../../../../scripts/build-exe-for-python-sdk.ts)runtime 闭包校验 → `pnpm run build` →(清空后)`pnpm --filter dsh-jsonrpc-agent-pkg deploy --legacy --prod --config.node-linker=hoisted --config.auto-install-peers=false --config.link-workspace-packages=true` **直** `python/sdk-runtime/src/deepseek_harness_runtime/runtime/node/`→ 注入 pkg 配置(`bin` 指闭包内 `node_modules/@deepseek-ai/dsh-jsonrpc-agent/lib/bin.js``assets` 全量 glob——动态 import 对 pkg 静态分析不可见,必须显式全量打入)→ 每 target 一次 `pkg --sea` → 可执行文件 `dsh-jsonrpc-agent-pkg-<platform>-<arch>` `dist-exe/` 并拷回 runtime 目录。CI 把它们作为测试中间输入,只保留对应平台 wheel。deploy 四 flag 均有实测依据:`--legacy` 是未开 inject-workspace-packages 时的必选路径;hoisted 产出符号链接文件树pkg VFS 最稳物理保证 cordis 实例);关 peer 自动安装避免未发布包名触发 registry 解析link-workspace-packages 让闭包指向 workspace/vendor 源。
[`scripts/build-exe-for-python-sdk.ts`](../../../../scripts/build-exe-for-python-sdk.ts)运行时闭包校验 → `pnpm run build` →(清空后)`pnpm --filter dsh-jsonrpc-agent-pkg deploy --legacy --prod --config.node-linker=hoisted --config.auto-install-peers=false --config.link-workspace-packages=true` **直接写入** `python/sdk-runtime/src/deepseek_harness_runtime/runtime/node/` → 注入 pkg 配置(`bin`闭包内 `node_modules/@deepseek-ai/dsh-jsonrpc-agent/lib/bin.js``assets` 使用全量 glob,因为动态 `import()` 对 pkg 静态分析不可见,必须显式打入全部内容)→ 每个构建目标调用一次 `pkg --sea` → 可执行文件 `dsh-jsonrpc-agent-pkg-<platform>-<arch>` 写入 `dist-exe/`并拷回运行时目录。CI 将这些文件作为测试中间输入,只保留对应平台 wheel 包。四个部署标志都有实测依据:未启用 `inject-workspace-packages` 时必须使用 `--legacy``hoisted` 产出符号链接文件树(pkg VFS 最稳定,并从物理保证只有一个 Cordis 实例);关闭对等依赖自动安装避免未发布包名触发注册表解析;`link-workspace-packages` 让闭包指向工作区/vendor 源
CI[`.github/workflows/build-exe-for-python-sdk.yml`](../../../../.github/workflows/build-exe-for-python-sdk.yml)仅显式触发——`workflow_dispatch` 手动派发,或给 PR `build-exe` 标签linux-x64 / linux-arm64`ubuntu-24.04-arm`/ macos-arm64 三平台原生构建,并缓存 `~/.pkg-cache`macOS ad-hoc 签名由 pkg 处理。每个平台都以 mock SSE 模型分别通过默认配置和自定义 `cordis.yml` 驱动 SDK NDJSON JSON-RPC 直接驱动 exe校验 JSONL 与最终响应最后把 release 形态的 wheel 安装到干净 venv 中并在不传 `runtime_bin` 的情况下运行Linux 还检查 GLIBC 依赖并在 manylinux 2.28 容器中运行。整次运行只保留 4 个产物,每个只含一个发布文件:平台无关的 SDK wheel 3 个原生 runtime wheel裸 exe 源码 bundle 只作为测试中间输入。[`.gitlab-ci.yml`](../../../../.gitlab-ci.yml) 只接受版本与根目录 `package.json` 匹配的 `python-vX.Y.Z` tag 流水线,构建一个 SDK wheel 3 个原生 runtime wheel再由单个串行 job 校验并发布这 4 个文件到项目 PyPI 注册表。Windows 是非目标
CI 使用 [`.github/workflows/build-exe-for-python-sdk.yml`](../../../../.github/workflows/build-exe-for-python-sdk.yml)且只允许显式触发:手动派发 `workflow_dispatch`,或给 PR 添加 `build-exe` 标签linux-x64linux-arm64`ubuntu-24.04-arm` macos-arm64 三平台分别进行原生构建,并缓存 `~/.pkg-cache`macOS ad-hoc 签名由 pkg 处理。每个平台都使用模拟 SSE 模型分别通过默认配置和自定义 `cordis.yml` 驱动 SDK通过 NDJSON JSON-RPC 直接驱动 exe校验 JSONL 与最终响应最后把发布形态的 wheel 安装到干净 venv 中并在不传 `runtime_bin` 的情况下运行Linux 还检查 GLIBC 依赖并在 manylinux 2.28 容器中运行。整次运行只保留 4 个产物,每个产物只含一个发布文件:平台无关的 SDK wheel 包和 3 个原生运行时 wheel;裸 exe 源码只作为测试中间输入。[`.gitlab-ci.yml`](../../../../.gitlab-ci.yml) 只接受版本与根目录 `package.json` 匹配的 `python-vX.Y.Z` 标签流水线,构建一个 SDK wheel 包和 3 个原生运行时 wheel,再由单个串行任务校验并这 4 个文件发布到项目 PyPI 注册表。Windows 不在目标范围内
### Python SDK 分发双载体exe 为生产、node 为开发
### Python SDK 分发双载体exe 用于生产,`node` 用于开发
Python SDK 位于 [`python/`](../../../../python/README.md)`python/sdk`客户端+ `python/sdk-runtime`运行时载体包。runtime 包数据目录三类内容:检入的默认 `runtime/cordis.yml`、构建注入的平台 exe构建注入的 `runtime/node/` 闭包树。`resolve_bundled_launch_args()` 自动解析**只找 exe**node 载体仅显式 `DSH_RUNTIME_MODE=node` 启用( `runtime/node/node_modules/@deepseek-ai/dsh-jsonrpc-agent/lib/bin.js`,需系统 node ≥22.19),定位本仓库成员的开发验证通道,不 wheel 分发
Python SDK 位于 [`python/`](../../../../python/README.md)`python/sdk`客户端`python/sdk-runtime`运行时载体包。运行时包的数据目录包含三类内容:检入的默认 `runtime/cordis.yml`、构建注入的平台 exe,以及构建注入的 `runtime/node/` 闭包树。`resolve_bundled_launch_args()` 自动解析**只找 exe**`node` 载体仅显式设置 `DSH_RUNTIME_MODE=node` 启用(运行 `runtime/node/node_modules/@deepseek-ai/dsh-jsonrpc-agent/lib/bin.js`,需系统 Node ≥22.19),定位本仓库成员的开发验证通道,不 wheel 分发。
[`scripts/build-python-release.py`](../../../../scripts/build-python-release.py) 从仓库根目录 `package.json` 读取权威的稳定 `X.Y.Z`以该版本暂存两个包,同时让 SDK 精确依赖 `deepseek-harness-runtime-bin==X.Y.Z`。可选的 `python-vX.Y.Z` 发布 tag 只是一项一致性断言,与仓库版本不同时会被拒绝;源码 `pyproject.toml` 中的开发占位版本从不决定发布版本。SDK 是 `py3-none-any` wheel只提供 wheel 的 runtime 包恰好包含一个 exetag `py3-none-manylinux_2_28_x86_64``py3-none-manylinux_2_28_aarch64``py3-none-macosx_11_0_arm64`。其 Hatch 钩子拒绝 sdist、通用 tag、混合可执行载荷以及不支持的平台。
[`scripts/build-python-release.py`](../../../../scripts/build-python-release.py) 从仓库根目录 `package.json` 读取权威的稳定版本 `X.Y.Z`,以该版本暂存两个包,让 SDK 精确依赖 `deepseek-harness-runtime-bin==X.Y.Z`。可选的 `python-vX.Y.Z` 发布标签只是一项一致性断言,与仓库版本不同时会被拒绝;源码 `pyproject.toml` 中的开发占位版本从不决定发布版本。SDK 是 `py3-none-any` wheel;只提供 wheel 包的运行时包恰好包含一个 exe标签`py3-none-manylinux_2_28_x86_64``py3-none-manylinux_2_28_aarch64``py3-none-macosx_11_0_arm64`。其 Hatch 钩子拒绝 sdist、通用标签、混合可执行载荷以及不支持的平台。
exe必须显式配置的硬语义不变;零配置体验由 wrapper 恢复:调用方没 `cordis`、没显式指定 runtime、环境无 `DSH_CORDIS_CONFIG` 时,客户端检入的默认 `cordis.yml`agent-core + 预载 llm-deepseek + JSONL 持久化 + bash-local + `dsh-jsonrpc` serving 条目,`!!js` 环境变量兜底)显式注入 `DSH_CORDIS_CONFIG`
exe必须显式配置的硬语义不变;零配置体验由包装层恢复:调用方没有提供 `cordis`、没显式指定运行时,且环境中没有 `DSH_CORDIS_CONFIG` 时,客户端检入的默认 `cordis.yml``agent-core` + 预载`llm-deepseek` + JSONL 持久化 + `bash-local` + `dsh-jsonrpc` 对外服务条目,并通过 `!!js` 使用环境变量兜底)显式注入 `DSH_CORDIS_CONFIG`
### 命名血统
`@deepseek-ai/dsh-jsonrpc-agent`(包)→ `dsh-jsonrpc-agent`bin`dsh-jsonrpc-agent-pkg`(闭包清单;无 scope 前缀,刻意避开 constraints 对 `@deepseek-ai/dsh-*` 的包形状规则)→ `dsh-jsonrpc-agent-pkg-<platform>-<arch>`exe 产物)。wire `serverInfo.name` 保持 `deepseek-harness-sdk-runtime`协议稳定值Python dist 名为 `deepseek-harness` / `deepseek-harness-runtime-bin`
`@deepseek-ai/dsh-jsonrpc-agent`(包)→ `dsh-jsonrpc-agent``bin`)→ `dsh-jsonrpc-agent-pkg`(闭包清单;没有作用域前缀,刻意避开 `constraints``@deepseek-ai/dsh-*` 的包形状规则)→ `dsh-jsonrpc-agent-pkg-<platform>-<arch>`exe 产物)。协议字段 `serverInfo.name` 保持 `deepseek-harness-sdk-runtime`协议稳定值Python 分发名为 `deepseek-harness` / `deepseek-harness-runtime-bin`
## 工作线程插件
exe 内支持 `dsh-workflow-workerthread``dsh-code-runtime-worker`。两个后端构建入口都通过 `fileURLToPath()` 转换相邻 worker 的 URL再将所得文件系统字符串传给 `Worker`pkg 的 Worker 钩子可以用这种形式解析 VFS 内文件。工作流引擎在未构建的源码执行中仍保留 data URL 引导程序,只有构建后的相邻入口使用文件系统字符串。自定义配置的可执行文件冒烟测试会加载两个后端,实际调用 `run_code` 与不启动 agent 的 `workflow`,并要求两个 worker 都从 pkg 的 VFS 内返回 `42`
exe 内支持 `dsh-workflow-workerthread``dsh-code-runtime-worker`。两个后端构建后的宿主都通过 `fileURLToPath()` 转换相邻 `lib/worker.cjs` 的 URL再将所得文件系统字符串传给 `Worker`pkg 的 Worker 钩子可以用这种形式解析 VFS 内文件。该钩子会把 VFS 内的工作线程文件作为 CommonJS 编译,所以工作线程入口采用 CommonJS。工作流引擎在未构建的源码执行中仍保留 `data:` URL 引导程序,只有构建后的相邻入口使用文件系统字符串。自定义配置的可执行文件冒烟测试会加载两个后端,实际调用 `run_code` 与不启动 agent 的 `workflow`,并要求两个工作线程都从 pkg 的 VFS 内返回 `42`
## 测试
验证面分三层。机制层:`--sea` 链路的实测结论内嵌在决策各节VFS 内 ESM 动态 import、cordis 实例、fail-loud 配置链路、`node:sqlite`、macOS ad-hoc 签名可运行。SDK 层:完整的 keyless pytest 套件以假运行时对端覆盖客户端协议、子进程清理、绝对 cwd 传递、双载体启动与载体解析;根 CI 在 Python 3.10 上运行全部用例。端到端层:每个平台构建都通过默认 SDK 路径、自定义配置和直接二进制协议对着 mock 端点完成一个轮次,并校验最终文本与 JSONL。自定义配置还会通过打包进 VFS 的真实 worker 文件执行 `run_code` 和不启动 agent 的 `workflow`。随后把平台 wheel 安装进干净 venv在不传 `runtime_bin` 的情况下运行。JSON-RPC 协议不在 ACP snapshot 体系内,无 snapshot 层(点名后的明确空缺,非遗漏)。
验证面分三层。机制层:`--sea` 链路的实测结论内嵌在决策各节VFS 内 ESM 动态 `import()`、单一 Cordis 实例、明确报错的配置链路、`node:sqlite`、macOS ad-hoc 签名可运行。SDK 层:完整的无密钥 pytest 套件以假运行时对端覆盖客户端协议、子进程清理、绝对 `cwd` 传递、双载体启动与载体解析;根 CI 在 Python 3.10 上运行全部用例。端到端层:每个平台构建都通过默认 SDK 路径、自定义配置和直接二进制协议,对模拟端点完成一个轮次,并校验最终文本与 JSONL。自定义配置还会通过打包进 VFS 的真实工作线程文件执行 `run_code` 和不启动 agent 的 `workflow`。随后把平台 wheel 安装进干净 venv在不传 `runtime_bin` 的情况下运行。JSON-RPC 协议不在 ACP 快照体系内,因此没有快照层(这是明确指出的空缺,非遗漏)。
手工驱动注意bin stdin EOF 为「客户端已走」并立即 dispose短命管道会中止在飞回合——管道驱动必须保持 stdin 打开到回合结束。
手工驱动注意:`bin` stdin EOF 视为“客户端已离开”并立即 dispose短命管道会中止进行中的轮次——管道驱动必须保持 stdin 打开,直到轮次结束。
## 曾考虑的替代方案
**Node 原生 SEA 裸用** 注入主脚本必须是 CJS 单文件blob 内文件系统与模块解析,动态 import 裸包名无从解析,只能把插件静态编译进主脚本并手工注册——绕过标准模块解析、插件集合被硬编码,与配置决定一切相悖。最终路线实为「官方 SEA 基 + pkg 的 VFS/模块钩子层」,否掉的是裸用而非 SEA 本身。
**裸用 Node 原生 SEA。** 注入主脚本必须是 CJS 单文件blob 内没有文件系统与模块解析,因此动态 `import()` 无法解析裸包名;只能把插件静态编译进主脚本并手工注册。这会绕过标准模块解析并硬编码插件集合,与配置决定一切相悖。最终路线实际是“官方 SEA 基 + pkg 的 VFS/模块钩子层”;否决的是裸用方式,而不是 SEA 本身。
**pkg standard 模式。** PoC 判死,非取舍:它把 ESM 经 esbuild CJS + V8 字节码,运行时 vm 编译未接动态 import 回调,任何 `import()` 一律抛 `ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING``--options experimental-require-module` 无效;依赖社区补丁 Node 二进制macos-arm64 预编译,现场源码编译约 10 分钟)。本仓库架构零可行性
**pkg 标准模式。** PoC 证明该模式不可行,而非权衡后放弃:它通过 esbuild 将 ESM 转为 CJS + V8 字节码,运行时 VM 编译没有接入动态 `import()` 回调,任何 `import()` 都会抛出 `ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING``--options experimental-require-module` 无效;此外,它依赖社区补丁 Node 二进制macos-arm64 没有预编译版本,现场源码编译约 10 分钟)。该模式不适用于本仓库架构。
**每包 ESM→CJS 预打包进 VFS。** 保持真实解析语义、只降级模块格式的折中;`--sea` 直接通过实测,这层构建复杂度无需引入。
**jsonrpc-agent 背全量闭包依赖。** app bin 声明 53+它不 import 的依赖,打包清单」冒充真实依赖关系,迫使 constraints 为其cordis-in-dependencies 与 files-通配两个例外。闭包清单python 侧的清单包上,constraints 无需任何例外bin 保持与 acp-agent 同构的正常包形状。
**jsonrpc-agent 承担完整闭包依赖。** 应用入口将声明 53 个以上自身并不 `import()` 的依赖,使“打包清单”伪装成真实依赖关系,还会迫使 `constraints` 为其增加 `cordis-in-dependencies``files` 通配两个例外。闭包清单Python 侧的清单包后,`constraints` 不需要任何例外,`bin` 也能保持与 acp-agent 同构的正常包形状。
**开放插件集(磁盘加载用户插件)。** 本期封闭集PoC 顺带证实 VFS 外磁盘 ESM import 可行(经 `ctx.baseUrl` 相对路径通道),列为后续演进,需另解外部插件与 exe 内 cordis 实例的共享问题。
**开放插件集(磁盘加载用户插件)。** 本期采用封闭集PoC 同时证实,可以通过 `ctx.baseUrl` 相对路径通道从 VFS 外的磁盘 `import()` ESM。该能力列为后续演进,届时还需解决外部插件与 exe 内 Cordis 实例的共享问题。
## 后果
**买到的**:目标平台零依赖单文件分发;插件语义与源码运行严格一致(同一棵真实包树,无转译无注册表);serving 面、插件集配置三者全部收敛到 `cordis.yml` + 一份依赖清单两个事实源exe 与 node 双载体同树同语义,开发验证不必等打包;官方 Node 二进制消除了补丁二进制供应链顾虑。
**买到的**:目标平台零依赖单文件分发;插件语义与源码运行严格一致(同一棵真实包树,无转译无注册表);对外服务接口、插件集配置全部收敛到 `cordis.yml` 一份依赖清单两个事实源exe 与 `node` 双载体使用同一棵树和相同语义,开发验证无需等待打包;官方 Node 二进制消除了补丁二进制供应链顾虑。
**付出的**:产物 174MB且源码原样进 blob字节码混淆闭源分发诉求需另行评估pkg 的 VFS/模块钩子层仍社区维护(构建脚本钉死 `@yao-pkg/pkg@6.21.0`,升级显式改动);`--sea` 每个 target 调用一次(与 CI 每平台一匹配,本地多平台构建串行)。
**付出的**:产物 174MB且源码原样进 blob没有字节码混淆闭源分发诉求需另行评估pkg 的 VFS/模块钩子层仍社区维护(构建脚本钉死 `@yao-pkg/pkg@6.21.0`,升级需要显式改动);`--sea` 每个构建目标调用一次(与 CI 每平台一个任务相匹配,本地多平台构建串行执行)。