/** * dsh:`withScope` 在**非邮件轮次**也必须声明一个合法 session_id(2026-10-02)。 * * ## 为什么 * * 服务端 `AgentMayReadSession` 收严后(`15e4fe9`),未声明 session_id 的读信 * 一律 403。而 dsh 的 `reverseMap` **只在邮件投递时**才填 ⇒ 在界面里直接对话时 * `mailSessionOf(exec)` 为空。 * * 旧写法是「取不到就原样返回 path」,那在 2026-09-15 之前是服务端的迁移期兜底; * 那个放行已作废。所以不改 = **在 dsh 界面里读不到任何信**。 * * 回落答案只能向服务端问:`session_id` 是 AgentMail 会话的 UUID, * dsh 侧的目录/会话 id 给不出它(这一点与 opencode 不同 —— 它有宿主 session id 可反查)。 * * ## 为什么默认落点是 /tmp * * 与服务端 `handler.DefaultFallbackWorkspace` 必须一致,不一致 = 永远问不到。 */ import { test } from 'node:test'; import assert from 'node:assert/strict'; import { readFileSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; const HERE = dirname(fileURLToPath(import.meta.url)); const src = readFileSync(join(HERE, '..', 'src', 'index.ts'), 'utf8'); test('★ withScope 在 mailSessionOf 为空时回落到默认会话', () => { assert.ok( /const sid = mailSessionOf\(exec\) \|\| defaultSessionId;/.test(src), 'withScope 必须有默认会话回落(否则界面里直接对话时读信一律 403)'); assert.ok( !/function withScope\(path: string, exec: any\): string \{\s*\n\s*const sid = mailSessionOf\(exec\);\s*\n\s*if \(!sid\) return path;/.test(src), 'withScope 仍是「取不到就原样返回」—— 那是 2026-09-15 前的迁移期兜底,服务端已不再放行'); }); test('默认会话在装配期问一次(不是每次 withScope 都问)', () => { assert.ok(/let defaultSessionId = '';/.test(src), '缺少 defaultSessionId 缓存'); assert.ok(/await loadDefaultSession\(\);/.test(src), '装配期应调 loadDefaultSession'); assert.ok( !/withScope[\s\S]{0,400}await\s+(client\.get|fetch)/.test(src), 'withScope 不该自己发请求:它是取值函数,IO 混进来会让「拼 URL 时顺带发 HTTP」,' + '也让判据无法用裸对象驱动'); }); test('★ 默认落点与服务端一致(不一致 = 永远问不到)', () => { const m = src.match(/const DEFAULT_FALLBACK_WORKSPACE = '([^']+)'/); assert.ok(m, '缺少 DEFAULT_FALLBACK_WORKSPACE 常量'); assert.equal(m[1], '/tmp', '必须与 handler.DefaultFallbackWorkspace 一致;不一致则桥问的 key 与服务端认的 key 不同'); }); test('问不到默认会话时不得编一个 id(那是把「不知道」记成「知道」)', () => { const m = src.match(/const loadDefaultSession = async[\s\S]*?\n \};/); assert.ok(m, '未找到 loadDefaultSession'); const body = m[0]; assert.ok( /String\(r\?\.session_id \?\? ''\)/.test(body), '应把缺失的 session_id 当空串(端点是纯只读的,没通信过就没有)'); assert.ok( !/defaultSessionId\s*=\s*['"`][0-9a-f-]{36}['"`]/.test(body), '不得硬编码或伪造一个 session_id'); assert.ok( /catch[\s\S]*?ctx\.logger\.error/.test(body), '问不到要留日志(否则「默认会话一直拿不到」这件事不可见)'); });