@agentrouter-top/relay-dsh-plugin-codex 0.2.2-agentrouter.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTROUTER-FORK.md +7 -0
- package/LICENSE +21 -0
- package/README.md +419 -0
- package/README.zh.md +429 -0
- package/codex-activity-wire.mjs +16 -0
- package/cordis.patch.yml +5 -0
- package/docs/dsh-0.1.2-alpha.3.md +37 -0
- package/docs/images/dsh-new-session-backends.jpg +0 -0
- package/docs/reliability-acceptance.md +85 -0
- package/docs/reliability-spec.md +305 -0
- package/docs/spec/dsh-interaction-bridge.md +168 -0
- package/docs/spec/execution-presentation.md +103 -0
- package/dsh-client-compat.d.mts +4 -0
- package/dsh-client-compat.mjs +26 -0
- package/dsh-compat.mjs +92 -0
- package/lib/client.js +37202 -0
- package/lib/client.js.map +1 -0
- package/lib/host-plugin.js +5142 -0
- package/lib/host-plugin.js.map +1 -0
- package/lib/typert.host.js +16 -0
- package/lib/typert.host.js.map +1 -0
- package/package.json +157 -0
- package/presets/relay-codex/.relay-managed +1 -0
- package/presets/relay-codex/agent.cordis.yml +3 -0
- package/presets/relay-codex/preset.yml +3 -0
- package/scripts/repair-activity-history.mjs +123 -0
package/README.zh.md
ADDED
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
# 在 DeepSeek Harness 中使用 Codex 对话
|
|
2
|
+
|
|
3
|
+
> **现已支持 DSH `0.1.2-rc.1`,并保留对 `0.1.2-alpha.3` 的兼容。** 插件 `0.2.2` 已在两个版本上完成验证。[从 npm 安装](https://www.npmjs.com/package/relay-dsh-plugin-codex) · [兼容性证据](https://github.com/yangbobo2021/Relay/tree/codex/relay-foundation/dsh-lab/dsh-0.1.2-rc.1-20260903)。
|
|
4
|
+
|
|
5
|
+
> **发布通道:** `latest` → `0.2.2`;`next` → `0.2.1-rc.1`。
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx @deepseek-ai/dsh@0.1.2-rc.1 plugin --profile web add relay-dsh-plugin-codex@0.2.2
|
|
9
|
+
npx @deepseek-ai/dsh@0.1.2-rc.1 web
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
[](https://www.npmjs.com/package/relay-dsh-plugin-codex)
|
|
13
|
+
[](https://github.com/yangbobo2021/relay-dsh-plugin-codex/actions/workflows/ci.yml)
|
|
14
|
+
[](https://www.npmjs.com/package/relay-dsh-plugin-codex)
|
|
15
|
+
[](https://github.com/yangbobo2021/relay-dsh-plugin-codex/stargazers)
|
|
16
|
+
[](LICENSE)
|
|
17
|
+
[](https://github.com/deepseek-ai/deepseek-harness)
|
|
18
|
+
[](https://www.npmjs.com/package/relay-dsh-plugin-codex/v/0.2.1)
|
|
19
|
+
|
|
20
|
+
[English](README.md) | 中文
|
|
21
|
+
|
|
22
|
+
**npm 包名:** [`relay-dsh-plugin-codex`](https://www.npmjs.com/package/relay-dsh-plugin-codex)
|
|
23
|
+
· [全部 Relay DSH 插件](https://github.com/yangbobo2021/Relay/blob/codex/relay-foundation/docs/dsh-plugins.zh.md)
|
|
24
|
+
|
|
25
|
+
**无需切换界面或维护 DSH Fork,直接在官方 DeepSeek Harness 中运行
|
|
26
|
+
Codex。**
|
|
27
|
+
|
|
28
|
+
`relay-dsh-plugin-codex` 为官方
|
|
29
|
+
[DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(DSH)Web
|
|
30
|
+
界面增加原生 **Codex 对话后端**。你可以继续使用 DSH 的工作区、对话历史、
|
|
31
|
+
输入框、审批和工具;每个 DSH Session 会持续绑定一个 Codex App Server
|
|
32
|
+
Thread。本插件可独立安装,不需要下载 Relay 仓库。
|
|
33
|
+
|
|
34
|
+
## 在官方 DSH 中立即试用
|
|
35
|
+
|
|
36
|
+
首次创建 Session 前,请先通过官方 Codex 客户端完成认证。使用 Codex CLI 时
|
|
37
|
+
可以执行:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
codex login
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
安装要求 Node.js 22.13 或更高版本,并且 `pnpm` 已加入 `PATH`。停止 DSH Web,
|
|
44
|
+
安装稳定版插件并重新启动:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npx @deepseek-ai/dsh@0.1.2-rc.1 plugin --profile web add relay-dsh-plugin-codex@latest
|
|
48
|
+
npx @deepseek-ai/dsh@0.1.2-rc.1 web
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
打开 **New Session**,选择工作区,再从模式菜单中选择 **Codex** 并发送消息。
|
|
52
|
+
|
|
53
|
+

|
|
54
|
+
|
|
55
|
+
上图来自安装了 Codex 和 Claude 插件的官方 DSH `0.1.1-rc.2`。如果只安装
|
|
56
|
+
本插件,菜单中只会新增 **Codex**。
|
|
57
|
+
|
|
58
|
+
[观看 Plugin Manager 在 38 秒内找到并安装本插件](https://github.com/yangbobo2021/Relay/blob/codex/relay-foundation/docs/media/dsh-plugin-manager-codex-install-demo.zh.mp4?raw=1)
|
|
59
|
+
· [查看全部 Relay DSH 插件](https://github.com/yangbobo2021/Relay/blob/codex/relay-foundation/docs/dsh-plugins.zh.md)
|
|
60
|
+
|
|
61
|
+
如果它能让你少切换一个界面,欢迎
|
|
62
|
+
[Star 本插件](https://github.com/yangbobo2021/relay-dsh-plugin-codex),并
|
|
63
|
+
[反馈你的 DSH 版本或安装结果](https://github.com/yangbobo2021/relay-dsh-plugin-codex/issues)。
|
|
64
|
+
这些真实信号能帮助更多 DSH 用户找到经过验证的 Codex 后端。
|
|
65
|
+
|
|
66
|
+
## 什么情况下需要这个插件?
|
|
67
|
+
|
|
68
|
+
以下情况适合安装:
|
|
69
|
+
|
|
70
|
+
- 希望直接在 DSH 中使用 Codex,而不必切换到单独的 Codex 界面;
|
|
71
|
+
- 希望保留 DSH 原生的对话历史、输入框、审批和提问;
|
|
72
|
+
- 希望一个 DSH Session 在多轮对话中持续使用同一个 Codex App Server
|
|
73
|
+
Thread;
|
|
74
|
+
- 希望在同一对话中使用 Codex 模型、reasoning effort、图片、中断以及 DSH
|
|
75
|
+
插件贡献的工具。
|
|
76
|
+
|
|
77
|
+
使用 DSH 标准 Agent 不需要安装本插件。本插件也不提供 Relay Events、文件
|
|
78
|
+
浏览和终端面板,这些能力由其他可选插件提供。
|
|
79
|
+
|
|
80
|
+
## 完整安装与兼容性说明
|
|
81
|
+
|
|
82
|
+
以下步骤已经在这些版本上实际验证:
|
|
83
|
+
|
|
84
|
+
- DeepSeek Harness `0.1.1-rc.2`,commit
|
|
85
|
+
[`b150a551`](https://github.com/deepseek-ai/deepseek-harness/commit/b150a551b8d465e31e418e1b2eaf5e79bbb7d28e)
|
|
86
|
+
- Node.js 22.13 或更高版本
|
|
87
|
+
- `pnpm` 已加入 `PATH`
|
|
88
|
+
|
|
89
|
+
DSH 当前仍是开发者预览版本,可能发生不兼容修改。本仓库会跟进官方版本,
|
|
90
|
+
并在这里记录已经验证的版本。
|
|
91
|
+
|
|
92
|
+
### 1. 准备 Codex 认证
|
|
93
|
+
|
|
94
|
+
插件会安装一个固定版本的官方 `@openai/codex` 运行时,并以 App Server 模式
|
|
95
|
+
启动它。该运行时包含 macOS、Windows、Linux 的 x64 和 arm64 原生二进制,
|
|
96
|
+
因此 DSH 不需要从自身的 `PATH` 中寻找 `codex` 命令。
|
|
97
|
+
|
|
98
|
+
Codex 仍然需要认证。首次创建 DSH Codex 会话前,请安装或打开任一官方 Codex
|
|
99
|
+
客户端并完成登录。使用 CLI 时,可以通过以下命令检查共享的本地认证状态:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
codex --version
|
|
103
|
+
codex login
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
安装及登录方式参见官方 [Codex CLI 文档](https://learn.chatgpt.com/docs/codex/cli)
|
|
107
|
+
和[认证文档](https://learn.chatgpt.com/docs/auth)。认证信息仍由 Codex 原有的
|
|
108
|
+
本地机制管理,本插件不会收集认证信息。安装本插件会提供 App Server 运行时,
|
|
109
|
+
但不会向系统全局安装 `codex` Shell 命令。
|
|
110
|
+
|
|
111
|
+
### 2. 选择安装来源并安装
|
|
112
|
+
|
|
113
|
+
修改 Profile 插件前,请先停止正在运行的 DSH Web,然后从以下来源中选择
|
|
114
|
+
一种。
|
|
115
|
+
|
|
116
|
+
#### npm 正式版
|
|
117
|
+
|
|
118
|
+
本插件发布到 npm 的正式包名是
|
|
119
|
+
[`relay-dsh-plugin-codex`](https://www.npmjs.com/package/relay-dsh-plugin-codex)。
|
|
120
|
+
使用 `@latest` 安装当前稳定版本:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
npx @deepseek-ai/dsh@0.1.2-rc.1 plugin --profile web add relay-dsh-plugin-codex@latest
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
本文更新时,`latest` 指向稳定版 `0.2.1`。最新版本请以链接中的 npm 页面
|
|
127
|
+
为准。
|
|
128
|
+
|
|
129
|
+
#### npm 预发布版(DSH 预览阶段推荐)
|
|
130
|
+
|
|
131
|
+
使用 `@next` 安装已经通过本仓库 CI 发布流程和官方 DSH 兼容性测试的最新
|
|
132
|
+
候选版本。当前候选版本还内置了跨平台 App Server 运行时,因此 DSH 不依赖
|
|
133
|
+
系统全局的 `codex` 可执行文件:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
npx @deepseek-ai/dsh@0.1.2-rc.1 plugin --profile web add relay-dsh-plugin-codex@next
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
`next` 标签继续指向 `0.2.1-rc.1`;`latest` 指向 `0.2.1`。
|
|
140
|
+
安装前请以 npm 注册表中实际发布的 dist-tag 为准。
|
|
141
|
+
|
|
142
|
+
本次预发布保留原生服务档位和恢复后的配置,修复取消轮次的迟到命令清理,
|
|
143
|
+
拒绝失效绑定上的迟到回复,并保留动态工具错误。具体配置见下文“与桌面 Codex
|
|
144
|
+
对照执行”。默认捆绑 `@openai/codex@0.153.4`,沿用原生 GPT-6 Astra 模型发现
|
|
145
|
+
和思考强度选项,不会分发或要求安装 Desktop
|
|
146
|
+
的实验版程序,也不宣称完整复刻 Desktop。
|
|
147
|
+
|
|
148
|
+
已知限制:原生命令事件偶尔缺少模型实际收到的错误文本;macOS 的 locale
|
|
149
|
+
问题可能影响 `shasum` 等工具。这两项尚未宣称修复。回滚时先停止 DSH,重新
|
|
150
|
+
安装 `relay-dsh-plugin-codex@0.2.0`,恢复曾修改的 profile 配置,再启动 DSH。
|
|
151
|
+
|
|
152
|
+
#### GitHub 开发版
|
|
153
|
+
|
|
154
|
+
如需测试尚未发布的修改,可以直接安装当前 `main` 分支:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
npx @deepseek-ai/dsh@0.1.2-rc.1 plugin --profile web add github:yangbobo2021/relay-dsh-plugin-codex#main
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
`main` 会持续变化。如需可复现的 GitHub 安装,请固定 Tag 或完整 Commit
|
|
161
|
+
SHA。例如:
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
npx @deepseek-ai/dsh@0.1.2-rc.1 plugin --profile web add github:yangbobo2021/relay-dsh-plugin-codex#v0.2.2
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
官方 DSH CLI 会在需要时初始化 `web` Profile,通过 `pnpm` 安装所选软件包,
|
|
168
|
+
并将插件加入 Bundle 配置。用户不需要下载 Relay 仓库。如果已经安装了持久
|
|
169
|
+
可用的 `dsh` 命令,可以将上述任一命令开头的
|
|
170
|
+
`npx @deepseek-ai/dsh@0.1.2-rc.1` 替换为 `dsh`。
|
|
171
|
+
|
|
172
|
+
### 3. 启动或重启 DSH Web
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
npx @deepseek-ai/dsh@0.1.2-rc.1 web
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
如果使用已经安装的命令,则执行 `dsh web`。DSH 只在启动时读取 Bundle
|
|
179
|
+
成员,因此安装、更新或删除插件后必须重启。
|
|
180
|
+
|
|
181
|
+
### 4. 新建 Codex 对话
|
|
182
|
+
|
|
183
|
+
1. 打开终端中显示的 DSH 地址,默认是 `http://127.0.0.1:3080`。
|
|
184
|
+
2. 首次启动时阅读 DSH 测试提示,然后点击 **Continue**。
|
|
185
|
+
3. 点击左侧栏的 **Add workspace**,选择允许 Codex 操作的项目目录。
|
|
186
|
+
4. 点击 **New Session**。
|
|
187
|
+
5. 打开当前显示为 **Standard mode** 的模式菜单,选择 **Codex**。
|
|
188
|
+
6. 输入消息并发送。请在发送第一条消息前选择后端;已有会话会继续使用创建
|
|
189
|
+
时选择的后端。
|
|
190
|
+
|
|
191
|
+
插件不需要单独的激活命令。安装成功并重启 DSH 后,Bundle 会自动激活,
|
|
192
|
+
并注册由插件管理的 **Codex** 模式。
|
|
193
|
+
|
|
194
|
+
### 5. 导入 Workspace 中已有的 Codex 会话
|
|
195
|
+
|
|
196
|
+
1. 点击 Workspace 列表下方、Settings 上方的 **导入会话...**,再选择 **从 Codex 导入**。
|
|
197
|
+
2. 在弹窗中确认或切换可见的 **目标 Workspace**,然后点击 **扫描会话**。
|
|
198
|
+
当前 Session 所属 Workspace 或最近 Workspace 只作为初始选项;确认前不会开始扫描。
|
|
199
|
+
3. 查看每个可导入 Codex Thread 的完整 ID、标题、源路径、最后活动时间以及
|
|
200
|
+
“可导入”或“待恢复”状态,并勾选一个、多个或全部 Thread。
|
|
201
|
+
4. 点击 **导入所选会话**。
|
|
202
|
+
5. 确认导入的 Session 已直接显示 Codex 标题并按源活动时间排列,然后打开
|
|
203
|
+
任一 Session 继续对话。
|
|
204
|
+
|
|
205
|
+
列表只显示精确属于用户所选 Workspace 的可导入 Thread;已绑定 Thread 和其他
|
|
206
|
+
Workspace 的 Thread 不可选择。标题和最后活动时间在打开 Session 前就必须可用;
|
|
207
|
+
批量导入时间不会覆盖 Codex inventory 的
|
|
208
|
+
`thread/list.updatedAt` 顺序。Codex App Server 继续负责
|
|
209
|
+
模型上下文、工具状态和压缩;DSH 只保存原生用户/助手展示历史以及一对一绑定,
|
|
210
|
+
不会复制 Codex 私有运行记录。每次打开已导入的 Session 时,插件会读取一次对应
|
|
211
|
+
的 Codex Thread,并将尚未显示的终态用户/助手 Turn 追加到 DSH 展示历史,其中
|
|
212
|
+
包括存在可见消息的 `interrupted` 和 `failed` Turn。只有 `inProgress` Turn 会等到
|
|
213
|
+
下次打开。Session 保持打开时不会后台轮询,也不会在发送消息时同步或增加手动
|
|
214
|
+
刷新入口。
|
|
215
|
+
|
|
216
|
+
## 支持的能力
|
|
217
|
+
|
|
218
|
+
- 每个 DSH Session 持续绑定一个 Codex App Server Thread
|
|
219
|
+
- 模型和 reasoning effort 选择
|
|
220
|
+
- 在 DSH 原生对话中流式显示回答和 reasoning
|
|
221
|
+
- 在新建 Session 中实时显示长时间运行的 Codex Shell 命令输出,并保留在 DSH 历史中
|
|
222
|
+
- DSH 原生审批和用户提问流程
|
|
223
|
+
- 图片、中断和会话延续
|
|
224
|
+
- 在 Codex App Server 的 `dsh` namespace 中提供通用 DSH 工具
|
|
225
|
+
- 安装独立 Relay 终端插件后,可选贡献终端传输 Provider
|
|
226
|
+
|
|
227
|
+
工具通过当前 Agent 的 DSH 工具运行时执行,并继续受到 DSH 权限和 Codex
|
|
228
|
+
审批机制约束。
|
|
229
|
+
|
|
230
|
+
## 可靠性与 App Server 生命周期
|
|
231
|
+
|
|
232
|
+
Codex App Server 进程由 DSH Host 插件负责。插件激活时、Codex 模型发现之前,
|
|
233
|
+
Host 会启动一个子进程;DSH 或插件退出时会停止它。默认子进程来自锁定版本的
|
|
234
|
+
`@openai/codex` 依赖,因此不要求系统中存在全局 `codex` 命令。
|
|
235
|
+
|
|
236
|
+
打开 **Settings → Advanced** 可以查看 Codex 是 **已连接**、**未启动**、
|
|
237
|
+
**正在启动**、**连接失败** 还是 **Codex 不可用**。如果 fork 子 Session 继承了
|
|
238
|
+
Codex 历史,却没有安全的一对一绑定,Session 标题栏会显示 **需要重新绑定**。
|
|
239
|
+
安装和连接错误会提供稳定错误码及下一步操作,不会把 `spawn codex ENOENT`
|
|
240
|
+
这样的底层错误直接当成用户提示。
|
|
241
|
+
|
|
242
|
+
在空白 New Session 中切换 Standard、Codex 和 Claude 时,模型选择会跟随对应
|
|
243
|
+
后端的能力组和默认 reasoning effort。Codex 模型发现较慢时会进行有界重试,
|
|
244
|
+
较早返回的异步结果不能覆盖用户更新的后端选择。
|
|
245
|
+
|
|
246
|
+
fork 通过 Codex App Server 的 `thread/fork` 实现。子 DSH Session 会提交继承的
|
|
247
|
+
父 Thread id 与已完成的 `lastTurnId`,并把返回的新 Thread 建立为持久的一对一
|
|
248
|
+
绑定。如果来源信息不完整、源 Thread 没有对应的 DSH Session,或 App Server
|
|
249
|
+
拒绝 fork,操作会 fail closed,绝不会回退到 `thread/start`。持久绑定 resume
|
|
250
|
+
失败时也会保留原绑定。重连后处理 pending approval 前,会再次核对 DSH Session、
|
|
251
|
+
Codex Thread、Turn、Item、request 和绑定代次;任何不匹配都会拒绝旧 approval,
|
|
252
|
+
并保留可诊断的来源信息。
|
|
253
|
+
|
|
254
|
+
完整约束见[可靠性规范](docs/reliability-spec.md)、
|
|
255
|
+
[可执行验收矩阵](docs/reliability-acceptance.md)以及审批与结构化提问的
|
|
256
|
+
[DSH 交互桥接规范](docs/spec/dsh-interaction-bridge.md)。
|
|
257
|
+
|
|
258
|
+
## 插件边界及与 Relay 的关系
|
|
259
|
+
|
|
260
|
+
本仓库在 [Relay](https://github.com/yangbobo2021/Relay) 项目中完成设计与
|
|
261
|
+
兼容性验证。Relay 是面向长时间运行 Agent、外部事件投递、可复用 DSH
|
|
262
|
+
工作台视图和多种对话后端的开源项目。
|
|
263
|
+
|
|
264
|
+
本插件可以独立安装。唯一依赖的 Relay 包是由包管理器自动安装的中立“会话
|
|
265
|
+
导入中心”;运行时不依赖 Relay 应用、Relay Events 或其他功能插件,也不会
|
|
266
|
+
替换 DSH 官方布局或安装 Files、Terminal 视图。用户可以只安装 Codex;需要
|
|
267
|
+
时,Relay 项目则可以进一步组合 Codex、Claude、事件、Wait、Monitor 和工作台
|
|
268
|
+
扩展。
|
|
269
|
+
|
|
270
|
+
可以访问或 Star Relay 仓库,关注这些更完整的工作:
|
|
271
|
+
<https://github.com/yangbobo2021/Relay>。
|
|
272
|
+
|
|
273
|
+
## 更新、检查或删除
|
|
274
|
+
|
|
275
|
+
修改 Bundle 前先停止 DSH Web,完成后重新启动。
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
# 检查插件为何被安装
|
|
279
|
+
dsh plugin --profile web why relay-dsh-plugin-codex
|
|
280
|
+
|
|
281
|
+
# 更新 npm 依赖
|
|
282
|
+
dsh plugin --profile web update relay-dsh-plugin-codex
|
|
283
|
+
|
|
284
|
+
# 删除插件
|
|
285
|
+
dsh plugin --profile web remove relay-dsh-plugin-codex
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
如果没有持久安装 `dsh` 命令,请将命令开头的 `dsh` 替换为
|
|
289
|
+
`npx @deepseek-ai/dsh@0.1.2-rc.1`。
|
|
290
|
+
|
|
291
|
+
## 常见问题
|
|
292
|
+
|
|
293
|
+
### 模式菜单中没有 Codex
|
|
294
|
+
|
|
295
|
+
先重启 DSH Web,再执行 `dsh plugin --profile web why
|
|
296
|
+
relay-dsh-plugin-codex`。如果 pnpm 找不到插件,请重新执行 npm 安装命令,
|
|
297
|
+
并查看最后显示的错误。
|
|
298
|
+
|
|
299
|
+
### 第一条消息提示认证失败或找不到可执行文件
|
|
300
|
+
|
|
301
|
+
请使用官方 Codex 客户端,以启动 DSH 的同一个操作系统用户执行 `codex
|
|
302
|
+
login`,然后重启 DSH。插件默认使用随插件安装的官方 `@openai/codex` 运行时,
|
|
303
|
+
不依赖 `PATH`。
|
|
304
|
+
|
|
305
|
+
如果错误提示随包运行时缺失,请更新或重新安装插件,让包管理器恢复当前平台
|
|
306
|
+
对应的 optional dependency。受管部署也可以明确指定其他 Codex 原生可执行文件:
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
# macOS 或 Linux
|
|
310
|
+
RELAY_CODEX_COMMAND=/absolute/path/to/codex dsh web
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
```powershell
|
|
314
|
+
# Windows PowerShell
|
|
315
|
+
$env:RELAY_CODEX_COMMAND = 'C:\absolute\path\to\codex.exe'
|
|
316
|
+
dsh web
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
DSH Bundle 配置项 `codexCommand` 的优先级高于 `RELAY_CODEX_COMMAND`。建议填写
|
|
320
|
+
原生可执行文件的绝对路径;两者都不设置时,会使用随插件发布并完成兼容性验证
|
|
321
|
+
的 Codex 版本。
|
|
322
|
+
|
|
323
|
+
### 与桌面 Codex 对照执行
|
|
324
|
+
|
|
325
|
+
`codexExecutionMode` 支持 `enhanced`(默认)和 `native`。增强模式接入
|
|
326
|
+
DSH 工具和下述执行规范;原生对照模式不注入这些动态工具和规范,用于区分
|
|
327
|
+
原生 Codex 行为与 DSH 扩展的影响。两种模式都保留 DSH 的界面、权限选择和
|
|
328
|
+
同一个 Codex Thread 的连续性。请用新建对话对照:切换模式不会删除历史上下文。
|
|
329
|
+
原生对照模式不是 Codex Desktop 的完整克隆,也不会增加账号或宿主能力。
|
|
330
|
+
|
|
331
|
+
客户端如实标识为 `relay_codex`,不声明尚未实现的 Desktop 身份证明和 MCP
|
|
332
|
+
App HTML 渲染能力。工作区依赖工具只返回已确认存在的路径,缺少运行时则明确
|
|
333
|
+
报告不可用。默认继续关闭 Shell 环境快照,避免将进程环境中的敏感值持久化。
|
|
334
|
+
|
|
335
|
+
适配器保留原生创建、恢复和设置通知返回的 `nativeSettings`,区分界面请求值
|
|
336
|
+
与原生确认值。恢复后的模型/推理设置若与 DSH 选择不同,会在下一轮正确同步。
|
|
337
|
+
原生服务意外退出时,正在执行的对话明确结束为失败;DSH 工具随所属轮次取消,
|
|
338
|
+
失效绑定上的迟到问题回复和工具结果不会被继续投递。
|
|
339
|
+
每轮开始前记录已有后台进程;取消时基于原生后台注册表清理本轮新增命令,
|
|
340
|
+
同时保留前一轮已有的后台服务。原生代码模式可能在“取消完成”之后才通知命令
|
|
341
|
+
启动,因此适配器保留被取消轮次的标记,继续通过原生 API 停止该轮迟到的命令;
|
|
342
|
+
迟到的命令、计划和 diff 通知不会把已结束的轮次重新标成运行中。清理失败明确
|
|
343
|
+
记录错误。该竞态修复通过了 20 次直接运行时及 6 次隔离 DSH 取消实测,但不代表
|
|
344
|
+
所有平台、原生版本和生命周期组合都已经通过验收。
|
|
345
|
+
|
|
346
|
+
插件会保留原生 Codex 配置或已有对话的服务档位,例如 `service_tier =
|
|
347
|
+
"priority"`。创建、分叉和开始新一轮时不发送 `serviceTier: null`,因为原生
|
|
348
|
+
App Server 将这个显式空值解释为重置到默认档位,而不是继承配置。
|
|
349
|
+
这不会自动为用户启用更高用量的档位;速度和用量仍由原生配置决定。
|
|
350
|
+
|
|
351
|
+
对照时需同时记录实际程序的 `--version`、模型、推理档位、权限和工具配置。
|
|
352
|
+
客户端名称相同不代表运行版本相同。可通过上述 `codexCommand` 在独立 DSH
|
|
353
|
+
profile 中指定参照程序;这不会自动升级默认捆绑运行时,也不保证其他平台兼容。
|
|
354
|
+
|
|
355
|
+
新建的原生 Codex 对话默认附加 Relay 自有的执行规范:限制工具发现和文件搜索
|
|
356
|
+
范围、保留命令状态和异步会话标识、并发独立检查、避免重复查询同一来源。
|
|
357
|
+
这不复制桌面客户端内部提示词,不改变工具授权或审批策略,也不重写已有或
|
|
358
|
+
导入对话的指令。可在 `relay-codex-host` 的配置中设置
|
|
359
|
+
`codexExecutionGuidance: false`,以单独验证运行版本的影响。
|
|
360
|
+
|
|
361
|
+
动态工具结果会保留工具名称、返回文本和明确的失败状态。HTTP 404 等负向查询
|
|
362
|
+
结果是否构成工具失败由来源工具决定,展示层不会把失败改成成功。
|
|
363
|
+
|
|
364
|
+
如果 Settings 显示 `CODEX_EXECUTABLE_NOT_FOUND`,请删除错误的
|
|
365
|
+
`codexCommand`/`RELAY_CODEX_COMMAND` 覆盖,或改为绝对路径。
|
|
366
|
+
`CODEX_RUNTIME_MISSING` 表示需要重新安装插件以恢复当前平台的 optional
|
|
367
|
+
dependency。**连接失败** 则表示已经找到可执行文件,但 App Server 初始化或
|
|
368
|
+
子进程运行失败。
|
|
369
|
+
|
|
370
|
+
### fork 子 Session 显示“需要重新绑定”
|
|
371
|
+
|
|
372
|
+
正常 fork 会调用 App Server `thread/fork` 并绑定返回的子 Thread。出现此状态
|
|
373
|
+
表示源 Thread/Turn 无法授权或完成该操作,例如 Turn 仍在运行、来源信息不完整,
|
|
374
|
+
或源绑定已不存在。请回到原 DSH Session 修复提示的问题后重新 Fork。插件不会
|
|
375
|
+
回退到全新的替代 Thread。
|
|
376
|
+
|
|
377
|
+
### 输入框不可用
|
|
378
|
+
|
|
379
|
+
DSH 在开始编码对话前必须选择工作区。点击 **Add workspace**,选择一个目录,
|
|
380
|
+
然后返回 **New Session**。
|
|
381
|
+
|
|
382
|
+
### 导入的 Session 提示 Codex Thread 正在被其他客户端使用
|
|
383
|
+
|
|
384
|
+
Codex 只允许一个 App Server 写入同一 Thread。在 Codex Desktop 中切换到其他
|
|
385
|
+
Thread 后,原 App Server 进程仍可能继续持有 writer。请完整退出或重启占用它的
|
|
386
|
+
Codex App、CLI 或 App Server 进程,然后在 DSH 中重试。插件会保留原有的一对一
|
|
387
|
+
绑定,绝不会创建替代 Thread。App Server 协议目前没有安全的强制接管操作。
|
|
388
|
+
打开 Session 时仍可通过 `thread/read` 同步终态展示历史;writer 所有权
|
|
389
|
+
只会阻止继续提交消息。
|
|
390
|
+
|
|
391
|
+
### 安装时提示找不到 pnpm
|
|
392
|
+
|
|
393
|
+
按照 pnpm 的[官方安装说明](https://pnpm.io/installation)安装,并在同一个
|
|
394
|
+
终端中确认 `pnpm --version` 可以执行。
|
|
395
|
+
|
|
396
|
+
### DSH 更新后插件无法启动
|
|
397
|
+
|
|
398
|
+
DSH 仍是开发者预览版本。请在
|
|
399
|
+
[GitHub Issue](https://github.com/yangbobo2021/relay-dsh-plugin-codex/issues)
|
|
400
|
+
中附上 `dsh --version` 输出、插件源码版本和启动错误。
|
|
401
|
+
|
|
402
|
+
## 开发验证
|
|
403
|
+
|
|
404
|
+
```bash
|
|
405
|
+
git clone https://github.com/yangbobo2021/relay-dsh-plugin-codex.git
|
|
406
|
+
cd relay-dsh-plugin-codex
|
|
407
|
+
npm install
|
|
408
|
+
DSH_ROOT=/path/to/deepseek-harness npm run verify
|
|
409
|
+
npm pack
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
`npm run verify` 会执行类型检查、测试和生产构建。边界测试仅允许中立的会话
|
|
413
|
+
导入中心依赖,并会阻止插件意外增加对 Relay 应用或其他功能插件的运行时依赖。
|
|
414
|
+
|
|
415
|
+
## 反馈
|
|
416
|
+
|
|
417
|
+
请通过本仓库的
|
|
418
|
+
[Issue Tracker](https://github.com/yangbobo2021/relay-dsh-plugin-codex/issues)
|
|
419
|
+
报告错误或提出功能建议。
|
|
420
|
+
|
|
421
|
+
### 已发布稳定版安装
|
|
422
|
+
|
|
423
|
+
稳定版 `0.2.1` 面向 DSH `0.1.1-rc.2`、`0.1.2-alpha.2` 和 `0.1.2-alpha.3`;可通过 npm `latest` 或 Git Tag `v0.2.1` 安装。
|
|
424
|
+
|
|
425
|
+
```sh
|
|
426
|
+
npx @deepseek-ai/dsh@0.1.2-rc.1 plugin --profile web add relay-dsh-plugin-codex@next
|
|
427
|
+
# Git tag alternative, after publication:
|
|
428
|
+
npx @deepseek-ai/dsh@0.1.2-rc.1 plugin --profile web add github:yangbobo2021/relay-dsh-plugin-codex#v0.2.2
|
|
429
|
+
```
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const CODEX_ACTIVITY_TOOL = "relay_codex_activity";
|
|
2
|
+
|
|
3
|
+
export function readActivityPayload(value) {
|
|
4
|
+
if (!value || typeof value !== "object" || value.version !== 1
|
|
5
|
+
|| typeof value.threadId !== "string" || typeof value.turnId !== "string"
|
|
6
|
+
|| typeof value.itemId !== "string"
|
|
7
|
+
|| !["started", "completed"].includes(value.phase)) return null;
|
|
8
|
+
const activity = value.activity;
|
|
9
|
+
if (!activity || typeof activity !== "object"
|
|
10
|
+
|| typeof activity.type !== "string" || typeof activity.title !== "string"
|
|
11
|
+
|| !["running", "completed", "error"].includes(activity.status)) return null;
|
|
12
|
+
for (const key of ["summary", "input", "output", "exitCode", "commandActions"]) {
|
|
13
|
+
if (activity[key] !== undefined && typeof activity[key] !== "string") return null;
|
|
14
|
+
}
|
|
15
|
+
return value;
|
|
16
|
+
}
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# DSH 三版本兼容
|
|
2
|
+
|
|
3
|
+
同一个 `0.2.1` 稳定包的兼容目标:
|
|
4
|
+
|
|
5
|
+
| DSH | 官方提交 |
|
|
6
|
+
| --- | --- |
|
|
7
|
+
| `0.1.1-rc.2` | `b150a551b8d465e31e418e1b2eaf5e79bbb7d28e` |
|
|
8
|
+
| `0.1.2-alpha.2` | `0a53fb55bea101816fa226bb964ae2bed71c343b` |
|
|
9
|
+
| `0.1.2-alpha.3` | `dd6322d604e00eec1ba5e0c8541159906a21094a` |
|
|
10
|
+
|
|
11
|
+
不按 DSH 版本分别发包;不要求旧用户先升级管理器。没有自定义精确版本白名单。
|
|
12
|
+
DSH 可选 peer 使用版本范围表达声明,不把它当成旧宿主必然执行的安装拦截。
|
|
13
|
+
稳定版通过 npm `latest` 发布;候选版 `0.2.0-rc.1` 保留在 `next` 通道。
|
|
14
|
+
|
|
15
|
+
## 本插件变更
|
|
16
|
+
|
|
17
|
+
`0.2.1` 不改变既有运行时功能;本次补丁公开记录 `0.1.2-alpha.3` 验收结果,并把发布 CI 的官方 DSH 基线更新到对应提交。
|
|
18
|
+
|
|
19
|
+
Host 工具调用 ID 在 `ToolCallId` / `CallId` 之间按可用导出选择;会话预设读取兼容两种字段;前端事件注册按实际服务装配;过程视图兼容 `useChat` 与旧 `useSession().chat`、两种 locale 命名空间及 Markdown 标签。保留新版原生过程折叠时恢复原生消息的行为。
|
|
20
|
+
|
|
21
|
+
## 验收方式与边界
|
|
22
|
+
|
|
23
|
+
开发类型检查及构建使用准备好的官方 `0.1.2-alpha.3` 源码。构建一次后,将相同 tarball
|
|
24
|
+
分别安装到三版官方 DSH 的独立临时 profile,检查 Host 启动、浏览器装配、功能注册及
|
|
25
|
+
适用的受控功能;不修改官方源码或日常运行环境。
|
|
26
|
+
跨插件结果在 Relay 的 `dsh-lab/dsh-0.1.2-alpha.3-20260901/` 中记录;插件独立测试命令:
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
npm ci --ignore-scripts
|
|
30
|
+
# 非管理器插件需要准备好的官方 DSH 源码;管理器使用锁定的 npm 开发依赖。
|
|
31
|
+
export DSH_ROOT=/path/to/prepared/official/deepseek-harness
|
|
32
|
+
npm run verify
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
三版核心回归不等于所有外部服务、平台或未来 DSH 版本均已验证。
|
|
36
|
+
Claude 真实识图/fork 仍暂缓;Codex Default 模式原生提问限制、Workbench 刷新后尺寸不保留
|
|
37
|
+
均不在本次兼容修复中关闭。公开 npm/GitHub 发布后的完整升级路径将在发布完成后再次验收。
|
|
Binary file
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Codex Reliability Acceptance
|
|
2
|
+
|
|
3
|
+
The implementation is accepted only when the specification, source, tests,
|
|
4
|
+
generated `lib/` artifacts, package contents, and this matrix agree.
|
|
5
|
+
|
|
6
|
+
| ID / scenario | Preconditions | Executable steps | Expected result | Automation / manual check | Risk covered |
|
|
7
|
+
| --- | --- | --- | --- | --- | --- |
|
|
8
|
+
| C1 Connected startup | Plugin package and current platform runtime installed. | Activate Host; wait for initialize, model/list, and account/read; dispose. | `not-started` → `starting` → `connected`; one Host-owned child; clean stop. | `plugin.test.mjs`, `session-runtime.test.mjs`; Settings shows **Connected** and a live reply completes. | Undefined process ownership, startup hang, process leak. |
|
|
9
|
+
| C2 Missing configured executable | Set `codexCommand` or `RELAY_CODEX_COMMAND` to a nonexistent absolute path. | Activate plugin; read status; request readiness. | `unavailable` + `CODEX_EXECUTABLE_NOT_FOUND`; actionable override guidance; no raw ENOENT and no Thread start. | `app-server-client.test.mjs`, `plugin.test.mjs`, `connection-status.test.mjs`; manual invalid-override check. | The reported `spawn codex ENOENT` incident. |
|
|
10
|
+
| C3 Missing runtime / unsupported target | Inject missing optional package or unsupported platform/arch. | Resolve launcher. | `CODEX_RUNTIME_MISSING` or `CODEX_PLATFORM_UNSUPPORTED`; reinstall/absolute-path action. | `codex-command.test.mjs`, `connection-status.test.mjs`. | Package-manager optional dependency and target gaps. |
|
|
11
|
+
| C4 Protocol/process failure | Executable exists; fake initialize timeout, protocol error, or early exit. | Start and wait for readiness. | `connection-failed`, not an installation diagnosis; bindings remain. | `app-server-client.test.mjs`, `connection-status.test.mjs`; manual forced-exit check. | Misdiagnosis and invisible App Server failure. |
|
|
12
|
+
| C5 Visible status | DSH Web loads plugin client. | Open Settings → Advanced; open affected Codex Session. | Localized global state; header shows non-connected/rebind state and server action/code. | Client status/route tests; manual browser screenshot. | Host-only logs that ordinary users cannot act on. |
|
|
13
|
+
| C6 Secret-safe shell environment | Start the isolated Host with a unique secret and digest-only consumer; retain the original CDX-ENV-003 Session/Thread. | Run the consumer through one shell call, scan DSH archives, Codex rollout/state and `shell_snapshots`, restart with a second secret, resume the same Session, and repeat. Also instantiate the client with explicit custom args. | Both consumers prove the exact secret reached the command and return only the fixed marker; default launch includes `features.shell_snapshot=false`; no snapshot is created and neither literal is persisted; custom args remain byte-for-byte unchanged. | `app-server-client.test.mjs`, `readme.test.mjs`; retained Session `session-249a3705-cf3e-498f-b9af-b9cbef63c1cc` / Thread `01a04c64-0bfd-7bf3-98b5-f84ae2120d40` signed-in regression. | Host environment secrets serialized into durable Codex shell snapshots, or security filtering breaking legitimate command consumers. |
|
|
14
|
+
| C7 Explicit Plugin Hook trust | Install the retained CDX-EXT-014 Plugin Hook, whose `PreToolUse` handler blocks `Bash` containing `HOOK_BLOCK_1414`; retain its original Session/Thread. Test once with default args, once with the exact official bypass flag, and once with the flag text embedded in another argument. | Start, fork, and resume Threads; in the retained Session require code mode to attempt the blocked command and inspect App Server Hook events, handler input, response text, and filesystem side effect. | Default and embedded-text cases do not bypass trust. The exact standalone flag leaves launch args unchanged and adds `config.bypass_hook_trust: true` to all three Thread lifecycle requests. The retained Session emits `hook/started` and blocked `hook/completed`, returns `PLUGIN_HOOK_BLOCKED_1414_VQMS`, creates no target file, and remains usable. | `app-server-client.test.mjs`, `session-runtime.test.mjs`; retained Session `session-9d70e178-3052-42df-88ff-6c74dcb127ad` / Thread `01a04c01-0890-7392-b74b-794c578c20f3` signed-in code-mode regression. | Installed Hooks silently skipped because launch-only trust state is lost during Thread config reload, or an implicit/substring match weakening the default trust boundary. |
|
|
15
|
+
| W1 Selective Workspace Thread import | The historical Codex home contains two DSH Workspaces, multiple unbound Threads in one Workspace, at least one bound Thread, and a Thread in the other Workspace. | In expanded and collapsed sidebars, open **Import sessions...**, choose **Import from Codex**, and confirm no scan starts on open. Change the visible Workspace selector, invoke **Scan sessions**, compare every candidate id/title/path/time/status to App Server inventory, clear selection, select exactly one eligible id, import, and rescan. Repeat the Host request with duplicate, unknown, cross-Workspace, and newly-bound ids. | The neutral hub exposes exactly one footer entry and the provider menu exposes one explicit Codex row; Codex renders no standalone footer trigger. The selector defaults current-owner then recent but the exact visible selection supplies the scan path. Candidates are unique and source-time ordered; only selected-Workspace ready/recoverable Threads appear; zero selection disables import; exactly one new binding is created; the imported id disappears while unselected ids remain. Every invalid selection creates zero bindings. | `WorkspaceImportAction.spec.tsx`, `session-import-composition.test.mjs`, `codex-import.test.mjs`, `codex-import-route.test.mjs`, `workspace-import-client.test.mjs`, `workspace-import-ui-policy.test.mjs`; combined-plugin expanded/collapsed browser screenshots. | Duplicate hub activation, horizontal footer overflow, implicit wrong-Workspace scan, aggregate-only discovery, stale UI selection, cross-Workspace disclosure, or partial mutation before validation. |
|
|
16
|
+
| M1 Backend switch | Blank Session with Standard, Codex, and Claude groups. | Standard → Codex → Claude → Codex → Standard. | Provider, default model, and effort follow each backend. | `model-selection.test.mjs`; manual model-picker check. | Model picker remains on native DSH or wrong backend. |
|
|
17
|
+
| M2 Discovery race | Delay/reorder models responses or omit Codex group initially. | Change preset while a query is pending; later expose Codex group. | Old generation cannot select; bounded retry selects current target; stop cancels timers. | `model-selection.test.mjs`. | Async overwrite and intermittent startup race. |
|
|
18
|
+
| M3 Non-blank Session | Existing Session has already sent a Turn. | Trigger preset/list updates. | No provider rewrite. | `model-selection.test.mjs`. | Existing conversation route corruption. |
|
|
19
|
+
| F1 App Server fork | Parent DSH Session owns Thread T; completed assistant replay state names T, Turn A, optional Item I; child has no binding. | Send first child continuation. | Exactly one `thread/fork(T, lastTurnId=A)`; returned child Thread C is persisted and receives the continuation; no child `thread/start`; parent T receives no child Turn. | `session-runtime.test.mjs`, `dsh-adapter.test.mjs`; real DSH fork screenshot and binding inspection. | Silent fresh Thread, child writing into parent, or lost Codex context. |
|
|
20
|
+
| F1b Fork rejection | Replay lacks A, T has no owning DSH Session, A is in progress, or App Server rejects/returns an invalid child. | Send first child continuation, then optionally retry the same stable provenance after recovery. | `CODEX_REBIND_REQUIRED` with T/A/I; zero fallback `thread/start` and zero child `turn/start`; no link before successful retry. | `dsh-adapter.test.mjs`; manual forced rejection check. | Unsafe provenance, partial-history forks, or masking protocol failure with a fresh Thread. |
|
|
21
|
+
| F2 Persisted resume failure | Link store maps DSH Session to T; resume reports missing or transient failure. | Restart adapter and ensure Thread. | T remains persisted; missing enters rebind; transient failure is retryable; zero replacement starts. | `dsh-adapter.test.mjs`. | Destructive recovery that masks broken bindings. |
|
|
22
|
+
| F3 Disconnect / pending approval / reconnect / stale replay | Approval request carries DSH Session, T/A/I, request id, and binding epoch. | Hold approval; disconnect browser; invalidate owner/binding; reconnect and answer replay. | `rejectRequest` with `CODEX_STALE_APPROVAL`; never `resolveRequest(accept)`; T/A/I named. | `dsh-adapter.test.mjs` ownership replay test; official DSH browser replay check. | Approval sent to the wrong Thread, Turn, or Item. |
|
|
23
|
+
| F4 Approval allow / deny | Official DSH Web composition provides the required `approval` and `userQuestions` Host injections; two independent Codex Sessions request outside-Workspace writes and share one untouched sentinel. | Confirm each target is absent before the approval card; choose one-time allow in the first Session and reject in the second; inspect exact bytes, sentinel, completed Turns, and follow-up usability. | Allow creates only the exact allow target after consent; reject never creates its target; sentinel is unchanged; both Turns complete and no request is auto-rejected because an interaction service is out of scope. | `host-services.test.mjs`, `dsh-adapter.test.mjs`, `session-runtime.test.mjs`; signed-in CDX-TOOL-015 browser regression. | Missing Cordis Host injection hides approval UI, converts a valid request into fail-closed rejection, or permits a pre-approval side effect. |
|
|
24
|
+
| F5 Subagent DSH tools | Root Thread T is bound to one DSH Session; during its active Turn, App Server emits a `subAgentActivity` edge from T to child C; the oracle exists only in the child-readable fixture. | Require C, not T, to call DSH `read` for `subagent-fixture/child-oracle.txt`; trace the exact marker through C to T; then repeat ownership resolution with a nested child, duplicate and conflicting edges, unbound root, missing parent, cycle, cross-Session parent, stale owner, and an ended root Turn. | C returns `CHILD_ORACLE_6842_ZKPT`; T ends with `PARENT_RECEIVED_CHILD_ORACLE_6842_ZKPT` and remains usable; invalid or expired trees execute zero DSH tools and fail closed. | `dsh-adapter.test.mjs`, `host-services.test.mjs`; signed-in CDX-TOOL-016 browser regression plus parent/child rollout inspection. | Descendant request rejected because only the root is directly bound, or a forged, stale, or cross-Session descendant gains root DSH capabilities. |
|
|
25
|
+
| R1 Public reasoning summary | Fresh High-effort business Turn whose App Server emits `summaryPartAdded` and `summaryTextDelta`. | Inspect `turn/start`, adapter chunks, persisted DSH blocks, and final answer. | `summary: auto`; one non-empty reasoning block is distinct from one non-duplicated final text block; no raw/encrypted reasoning is projected. | `session-runtime.test.mjs`, `dsh-adapter.test.mjs`; signed-in CDX-TXT-005 regression. | Empty `Think` disclosure caused by disabling App Server summaries. |
|
|
26
|
+
| R2 Empty and auxiliary reasoning | One business Turn completes with an empty reasoning item; title and compaction run as auxiliary Turns. | Consume all streams and inspect each `turn/start`. | Empty business item creates no reasoning block; auxiliary Turns use `summary: none`; business history receives no auxiliary reasoning. | `dsh-adapter.test.mjs`, `session-runtime.test.mjs`. | Blank UI controls, hidden-work leakage, and unnecessary auxiliary summary cost. |
|
|
27
|
+
| I1 Historical JPEG with `.png` name | Replay the `imageView` shape from DSH Session `session-6f78fa6a-bc1d-4be9-b15b-264d5f743c05`; the source file is named `completed-clean.png` and begins with JPEG/JFIF bytes. | Import the item, then project the following final assistant item and completed Turn. | Attachment media type is `image/jpeg`; image and final text are emitted; DSH finishes with `stop`, not `Declared image type does not match its bytes.` | `dsh-adapter.test.mjs` historical Session regression; manual replay against the retained local Session and source image. | Exact Issue #5 regression and apparent DSH interruption while Codex continues. |
|
|
28
|
+
| I2 Declared/extension type differs from bytes | Use file and generated-image inputs whose `.png` name or `data:image/png` declaration contains JPEG bytes. | Import both through the normal attachment boundary. | Both are submitted as `image/jpeg`; generated attachment name uses `.jpg`; DSH admission succeeds. | `dsh-adapter.test.mjs`. | Trusting unverified metadata over encoded content. |
|
|
29
|
+
| I3 Supported signatures | Supply PNG, JPEG, GIF, WebP, and invalid signatures. | Detect media type before DSH admission. | Four supported signatures map exactly; invalid bytes return no media type. | `dsh-adapter.test.mjs`. | Partial fix that handles only the reported JPEG case. |
|
|
30
|
+
| I4 Image failure isolation | Emit an invalid `imageView` or force DSH attachment storage to reject a valid signature, followed by final assistant text and a completed source Turn. | Consume the adapter stream. | One preview-unavailable block and warning with a stable reason code are emitted; no raw path or storage error leaks; final text remains; DSH finishes with `stop`; attachment storage is not called for unrecognized bytes. | `dsh-adapter.test.mjs`. | One malformed or rejected image aborting the whole DSH Turn. |
|
|
31
|
+
| I5 Image path boundary | Place valid or invalid image bytes outside the Workspace and access them directly or through a symlink. | Import through `imageView`. | Import is rejected before byte admission; no external file is published. | `dsh-adapter.test.mjs`. | MIME repair weakening filesystem containment. |
|
|
32
|
+
| I6 MCP image result | Replay the CDX-EXT-009 completed `mcpToolCall` shape with text, structured JSON, and one or more base64 image content entries. | Project the live Turn, inspect attachment inputs and ordered DSH blocks, reload the persisted Session, then continue without tools. Repeat with invalid base64, MIME mismatch, over 25 MiB, and storage rejection. | Every valid image reaches DSH in MCP content order with exact bytes and signature-derived media type; text/JSON are not mistaken for images; invalid entries emit sanitized placeholders; final text, Turn completion, reload rendering, and Session continuation survive. | `dsh-adapter.test.mjs`; retained CDX-EXT-009 Session `session-8027f629-ac18-4891-9413-f6309ddba5ef` and source digest `71e3ef8768ea6f1c04541bba803dff365ef41c8234c589958045eebd2f4e9d5d`. | MCP image bytes remain trapped in native tool output, become corrupted, leak as base64, reorder, or fail the whole DSH Turn. |
|
|
33
|
+
| IN1 DSH attachment input | Use the historical `user/message` shape with one `attachmentId`, no local path, and the IMG-001/002 PNG bytes. | Send through the adapter and inspect `turn/start` plus the native rollout. | Attachment is read once; exact bytes are materialized under the private Codex input root; one ordered `localImage` reaches Codex; the exact visual/OCR answer completes. | `dsh-adapter.test.mjs`, `codex-image-input.test.mjs`; signed-in IMG-001/002 regression. | UI-visible image silently dropped before Codex. |
|
|
34
|
+
| IN2 Ordered multi-image input | Use the two distinct IMG-003 DSH attachment refs in first/second order. | Send one Turn and inspect cache paths, `turn/start`, rollout, and answer. | Two distinct images are read and forwarded once in original order; exact answer is `FIRST_17>SECOND_29`. | `dsh-adapter.test.mjs`; signed-in IMG-003 regression. | Missing, duplicate, or reordered images. |
|
|
35
|
+
| IN3 Editing source continuity | Use the IMG-008 source attachment and request the established image edit. | Inspect source Turn and editing call/result. | Source appears as one conversation image and the edit produces a distinct valid artifact while preserving required foreground content. | Signed-in IMG-008 regression. | Editing tool runs without its source image. |
|
|
36
|
+
| IN4 Input admission and isolation | Exercise pure-image input, repeated bytes, metadata/signature mismatch, unavailable service, missing/corrupt/invalid/oversized data, and cancellation. | Prepare the user input. | Pure image starts; digest path is reused; signature determines extension; invalid/cancelled cases create zero Codex Threads and Turns; Workspace manifest is unchanged. | `codex-image-input.test.mjs`, `dsh-adapter.test.mjs`. | Unsafe cache writes, text-only degradation, orphan Threads, and Workspace mutation. |
|
|
37
|
+
| T1 Targeted shell interruption | A Turn owns a yielded `commandExecution` that writes a unique marker after 15 seconds; another background terminal belongs to a different Turn. | Wait for the target process id, stop the Turn, then wait at least 17 seconds. | Target process is terminated through `thread/backgroundTerminals/terminate`; marker stays absent; unrelated terminal remains; Turn is aborted and the Session remains usable. | `session-runtime.test.mjs`, `dsh-adapter.test.mjs`; signed-in App Server delayed-marker regression. | UI-only cancellation that leaves descendants running, and over-broad cleanup that kills unrelated work. |
|
|
38
|
+
| T2 Interruption cleanup failure | Make targeted terminal listing or termination fail while stopping a live Turn. | Abort the adapter stream. | The Turn reports `CODEX_TURN_INTERRUPT_CLEANUP_FAILED`, not a successful abort; diagnostic contains stable code and Thread/Turn ids without command output. | `session-runtime.test.mjs`, `dsh-adapter.test.mjs`. | False assurance after an unconfirmed process stop. |
|
|
39
|
+
| T3 Long shell output streaming | In a fresh post-upgrade Session, code mode yields `STREAM_FIRST_4102` through a raw call result, the same process later emits native `STREAM_LAST_8604`, and then completes. | Consume adapter chunks while recording source completion; inspect raw filtering, assemble/persist/reload the response, and repeat completion-only, empty, overlapping, malformed, unrelated, private, and late cases. | First marker arrives while active; both markers share one block in order and occur once; legitimate repeated output survives; completion-only output is present; empty/private/unrelated raw data creates no block; final answer and `stop` occur once; no DSH tool call is generated. A pre-upgrade Thread is documented as native-delta-only because App Server cannot retrofit raw events. | `app-server-client.test.mjs`, `session-runtime.test.mjs`, `dsh-adapter.test.mjs`; signed-in CDX-TOOL-009 delayed-marker regression plus Session reload inspection. | Backend streams but DSH hides output until completion, leaks raw context, duplicates or drops output, reruns an already-executed command, silently replaces an old Thread, or loses output after reload. |
|
|
40
|
+
| X1 Cross-platform launch | CI on macOS, Windows, Linux; empty PATH and paths with spaces. | Resolve and execute bundled launcher tests. | Six desktop target mappings; direct argument-array spawn; no shell splitting. | CI `codex-runtime` matrix; optional signed-in smoke per OS. | PATH, quoting, backslash, shell, architecture differences. |
|
|
41
|
+
| D1 Spec/package boundary | All behavior changes complete. | Run verify, build, pack, root boundary tests, and clean-reference check. | SPEC/README/code/tests/lib/package agree; official DSH reference unchanged. | Commands below plus `git diff --check`. | Documentation drift, missing artifact, upstream modification. |
|
|
42
|
+
|
|
43
|
+
## Commands
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npm ci --ignore-scripts
|
|
47
|
+
DSH_ROOT=/path/to/deepseek-harness npm run verify
|
|
48
|
+
npm pack --dry-run
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The official DSH reference must be commit
|
|
52
|
+
`b150a551b8d465e31e418e1b2eaf5e79bbb7d28e` unless the README and CI are
|
|
53
|
+
updated together for a newer validated release.
|
|
54
|
+
|
|
55
|
+
## Reddit regression sequence
|
|
56
|
+
|
|
57
|
+
1. Create a Codex DSH Session and complete a Turn so its assistant message has
|
|
58
|
+
replay state for Thread T and Turn A.
|
|
59
|
+
2. Fork the DSH Session at the stable completed boundary and open child C.
|
|
60
|
+
3. Continue in C. The plugin must call `thread/fork` with T/A, persist the
|
|
61
|
+
returned child Thread, and send the continuation only to that child. It must
|
|
62
|
+
not call `thread/start` for C or add the continuation to T.
|
|
63
|
+
4. Repeat with missing A or an in-progress A. The plugin must return
|
|
64
|
+
`CODEX_REBIND_REQUIRED`; App Server receives no fallback `thread/start` or
|
|
65
|
+
child `turn/start`.
|
|
66
|
+
5. For an explicitly bound child test fixture, pause on an App Server approval
|
|
67
|
+
carrying Thread T, Turn A, and Item I; disconnect the Web client.
|
|
68
|
+
6. Change or detach the binding before the replayed approval is answered.
|
|
69
|
+
7. Reconnect and answer the replay. The plugin must call `rejectRequest`, not
|
|
70
|
+
`resolveRequest`, and the failure must name T/A/I.
|
|
71
|
+
|
|
72
|
+
## Issue #5 regression sequence
|
|
73
|
+
|
|
74
|
+
1. Retain the original Session export and the original
|
|
75
|
+
`completed-clean.png` source file without rewriting either artifact.
|
|
76
|
+
2. Confirm the source file has a `.png` suffix while `file` and its `ff d8 ff`
|
|
77
|
+
prefix identify JPEG bytes.
|
|
78
|
+
3. Confirm plugin `0.1.2` derives `image/png` from that suffix and the retained
|
|
79
|
+
DSH Session ends with `Declared image type does not match its bytes.`
|
|
80
|
+
4. Replay the same `imageView` path and following terminal assistant item through
|
|
81
|
+
the modified adapter.
|
|
82
|
+
5. Confirm DSH receives `image/jpeg`, renders the image and terminal text, and
|
|
83
|
+
finishes normally without changing or replacing the source Codex Thread.
|
|
84
|
+
6. Repeat with malformed bytes. Confirm only the preview becomes unavailable;
|
|
85
|
+
the surrounding DSH Turn still completes.
|