pi 定的 A(2026-09-15)。要点是:**契约的逃逸口不是豁免清单,而是 `resolveWorkspaceCwd(workspace, fallback)` 的第二个参数** —— 平台兜底值本来就该由平台侧传进去。 四个桥对照很清楚: | 桥 | 平台兜底值在哪 | 怎么交给共用函数 | |----------|--------------------------------------------------|------------------| | opencode | 自己的 `index.js` | 传 `directory` | | zcode | 自己的 `src/index.mjs`(`zcodeSessionFallback`) | 传进去 | | dsh | 共用的 `mailSessionFallback`(写死 `.dsh`) | 直接用 | | pi | **原来造在共用模块里**(本次出的错) | → 现在也传进去 | ⇒ `docs/PLUGIN-CONTRACT.md` 第 1150 行**不用改、也不该加旁路**:pi 只是唯一一个把平台值 造在共用模块里的,挪回平台侧就恢复了规矩。 **改动(与 pi 预测的形状一致)**:`workspace.js` 删掉那 15 行、`pool.mjs`/`worker.mjs` 各改一行 import,外加新文件 `src/paths.mjs`。`git diff --stat` 实测 `15 -` / `3 +-` / `3 +-` —— 没有多余改动。 **为什么新家是 `src/paths.mjs` 而不是 `lib/sandbox.js`**(pi 给了两个选项,我选前者): `lib/` 按契约是"**候选共用**"目录,把一个 pi 专有文件放进去**正是这次出事的形状** —— 下一个人会问"它为什么不在 `ALL_LIBS` 里"。`src/` 下同名文件不会引起这个问题。 父子同源(worker 的沙箱 rw 由父进程算)由"两边 import 同一个模块"继续满足。 **验收四条(pi 给的,逐条实测)**: 1. `cmp opencode/lib/workspace.js pi/lib/workspace.js` **相同**; `check-shared-libs.sh` **exit 0**;`install.sh --check` **exit 0** ✓ 2. 测试数**不降**:491 → **496**(+5,见下)✓ 3. 给 `piMailFallback` **补测试**(原先一条都没有 —— 这正是当初的不对称: 四个桥 `npm test` 全绿、只有 `check-shared-libs` 抓得到)→ 新增 `test/pi-paths.test.mjs` 5 条 ✓ 4. 四个调用点改 import 后 diff 只应是 import 行 + 删掉的那 15 行 ✓ **新测试为什么是独立文件**:`test/workspace.test.mjs` 在四个桥里**逐字节相同** (md5 一致,属共用测试),往里加 pi 专有断言会把共用测试也弄分叉 —— 与 `lib/` 同一条规矩。 **判据含结构断言 + 行为断言**,并已按纪律先验区分力: · 变异 1(把 `piMailFallback` 塞回共用模块 = 本次分叉的形状)⇒ 结构判据**变红**; · 变异 2(把 `.pi` 改成 `.dsh`)⇒ 三条行为判据**变红**; 两次变异都用 `cp` 恢复并以 `cmp` 校验一致。 ★ 顺带记下 pi 指出的一条:`check-deploy-drift.mjs` 的判据 ① 是我扩到"比全部 133 个文件"的, 所以这次分叉**它能抓到** —— 但 `check-shared-libs` 先红了,说明两道门的分工是对的。
54 lines
2.8 KiB
JavaScript
54 lines
2.8 KiB
JavaScript
/**
|
||
* pi 平台专有的路径常量。
|
||
*
|
||
* # 为什么这个文件在 `src/` 而不在 `lib/`
|
||
*
|
||
* 按 `docs/PLUGIN-CONTRACT.md` 第六节,`lib/` 是**候选共用**目录:里面的文件在四个桥里
|
||
* **逐字节相同**,由 `deploy/check-shared-libs.sh` 校验并纳入 `install.sh` 门禁。
|
||
* 而本文件的内容**按定义就是平台专有的**(目录名写死 `.pi`),
|
||
* 所以它不能住 `lib/` —— 否则下一个人会问"它为什么不在 `ALL_LIBS` 里"。
|
||
*
|
||
* # 这一搬是有来历的(别再搬回去)
|
||
*
|
||
* `piMailFallback` 原先定义在共用的 `lib/workspace.js` 里,于是 pi 那一份与
|
||
* opencode / dsh / zcode 三份**不再逐字节相同**,`check-shared-libs.sh` 变红:
|
||
*
|
||
* 共用模块已分叉:lib/workspace.js(plugins/opencode-mail-bridge vs plugins/pi-mail-bridge)
|
||
*
|
||
* 契约的逃逸口**不是豁免清单**,而是共用函数 `resolveWorkspaceCwd(workspace, fallback)`
|
||
* 的**第二个参数** —— 平台兜底值本来就该由平台侧传进去。四个桥对照一下就很清楚:
|
||
*
|
||
* | 桥 | 平台兜底值在哪 | 怎么交给共用函数 |
|
||
* |----------|---------------------------------------------|--------------------|
|
||
* | opencode | 自己的 `index.js` | 传 `directory` |
|
||
* | zcode | 自己的 `src/index.mjs`(`zcodeSessionFallback`) | 传进去 |
|
||
* | dsh | 共用的 `mailSessionFallback`(写死 `.dsh`) | 直接用 |
|
||
* | pi | **这里** | 传进去 |
|
||
*
|
||
* ⇒ `doc 1150` 不用改、也不该加旁路:pi 只是唯一一个把平台值**造在共用模块里**的,
|
||
* 把它挪回平台侧就恢复了规矩。(共用 `workspace.js` 里那个 `.dsh` 常量仍是它保真的
|
||
* 唯一一份,与本节不矛盾:规矩保的是"**只有一份**",不是"不许有平台数据"。)
|
||
*
|
||
* # 为什么父子共用这一个文件
|
||
*
|
||
* `pool.mjs`(父)与 `worker.mjs`(子)**必须算出同一个兜底目录**:
|
||
* worker 的沙箱 `rw` 清单由父进程算(`lib/sandbox.js`),
|
||
* 父进程猜一个目录而 worker 落在另一个,症状是"**界内也写不了**"。
|
||
* 所以兜底值收成这一处,两边 import 同一个函数。
|
||
*/
|
||
|
||
import { homedir } from 'node:os';
|
||
import { join } from 'node:path';
|
||
|
||
/**
|
||
* 没有可用 `to_workspace` 时的兜底目录(pi 专用)。
|
||
*
|
||
* 目录名是 `.pi` 而不是 `.dsh`:pi 的会话落进 `~/.dsh/` 会让人以为是 DSH 在干活。
|
||
*
|
||
* @param {string|undefined} sessionKey 会话标识;空值收敛成 `default`
|
||
* @returns {string} `~/.pi/mail-sessions/<key>`
|
||
*/
|
||
export function piMailFallback(sessionKey) {
|
||
return join(homedir(), '.pi', 'mail-sessions', String(sessionKey || 'default'));
|
||
}
|