# dsh-session-import-codex

[English](README.md) | 中文

这是一个独立于 DeepSeek Harness 源码树的插件和 PowerShell CLI，用于导入 Codex 对话历史。它通过官方 [Codex App Server](https://developers.openai.com/codex/app-server/) 稳定历史接口读取对话，把已结束的 turn 转换为经过验证的 Harness session event，通过目标 profile 的公开服务持久化，并按照历史工作目录创建或复用工作区。

首选用法是一次性 CLI。`/import-codex` 聊天命令继续保留，用于开发调试和按 thread id 导入。

## CLI 会导入什么

- `thread/list` 在 `archived: false` 条件下返回的全部未归档交互式 Codex 对话；
- 当前转换器能够表示的 completed、interrupted 和 failed turn；
- 默认只导入 reasoning summary，绝不导入原始 reasoning 内容；
- 目标 session 使用 `codex-<thread-id>` 形式的确定性 id。

仍处于 active 状态的对话会跳过。已存在的目标 id 不会重写 session 日志；真实迁移重跑会刷新其冷态投影，并重复执行幂等的工作区关联。单条源数据异常只会记录失败，不会中止后续批次。

导入器不会读取 Codex rollout 文件、桌面应用状态、SQLite 数据库或私有 JSONL 文件，也不会直接写 Harness 的持久化文件。

## 从 npm 安装

要求：

- Node.js `^22.19` 或 `>=24`；
- pnpm 10；
- 当前 `PATH` 中存在可用的 `codex` 命令；
- 已安装的 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) CLI，或者可从源码目录运行的 Harness CLI。

通过 Harness 安装 npm 包，这会同时更新目标 profile 的依赖与 bundle layer：

```powershell
dsh plugin --profile web add dsh-session-import-codex
```

从 Harness 源码目录运行时：

```powershell
$harnessPath = Read-Host 'Path to your DeepSeek Harness checkout'
Set-Location $harnessPath
pnpm dsh plugin --profile web add dsh-session-import-codex
```

用户不需要克隆插件源码，也不需要在安装时执行构建；npm tarball 已包含编译好的 `lib/` 文件。

## 配合 dsh-llm-codex，完整迁移 Codex 使用习惯

本插件负责把 Codex **对话历史**迁移到 DSH。如果还想把 Codex 的**登录凭证与订阅**也一并带过来，建议配合 [dsh-llm-codex](https://github.com/yequ172672/dsh-codex-subscription)（npm 包名 `dsh-llm-codex`）一起使用：它是 DSH 的 LLM 适配器插件，直接复用 Codex CLI 的本地登录凭证（`~/.codex/auth.json`），让 DSH 无需 API Key 就能继续使用 ChatGPT 订阅模型（如 `gpt-5.6-sol`）。

安装方式与上文相同：

```powershell
dsh plugin --profile web add dsh-llm-codex
```

两个插件都基于同一个 `codex login` 凭证工作：本插件用它启动 Codex App Server 读取历史，`dsh-llm-codex` 则复用订阅令牌在 DSH 内继续提供 ChatGPT 模型。两者配合即可把 Codex 的完整使用习惯迁移到 DSH：

- 对话历史与工作区 → 本插件；
- 登录凭证、订阅模型与配额 → `dsh-llm-codex`。

## 从源码开发

克隆并构建插件。锁文件会从公共 npm registry 解析开发依赖，Harness 源码目录不必与插件目录相邻。

```powershell
git clone git@github.com:xing01l/session-import-codex.git
Set-Location session-import-codex
pnpm install --frozen-lockfile
pnpm build
$pluginPath = (Get-Location).Path
Set-Location $harnessPath
pnpm dsh plugin --profile web add $pluginPath
```

## 推荐的 PowerShell 迁移流程

profile 存储目前没有公开的 profile 级写入锁，因此受支持的写入流程是离线迁移：

1. 用 `Ctrl+C` 停止目标 `dsh --profile web` 进程。
2. 先执行 dry run。
3. 再执行真实迁移。
4. 重启 Web profile。

通过 profile 中从 npm 安装的 bin 验证全部符合条件的对话，不进行写入：

```powershell
pnpm --dir "$env:USERPROFILE\.dsh\profiles\web" exec dsh-import-codex --profile web --dry-run
```

执行真实迁移：

```powershell
pnpm --dir "$env:USERPROFILE\.dsh\profiles\web" exec dsh-import-codex --profile web
```

迁移完成后执行 `dsh --profile web` 重启 Harness；从源码目录运行时使用：

```powershell
Set-Location $harnessPath
pnpm dsh --profile web
```

CLI 会在终端输出完整计数和逐 thread 失败信息。真实迁移会根据持久化 session header 中仍然存在的历史 `cwd` 创建或复用 Harness 工作区，然后关联对应 session；它不会创建已经不存在的目录。

### 从源码目录执行

```powershell
Set-Location $pluginPath
pnpm import:codex -- --profile web --dry-run
pnpm import:codex -- --profile web
```

开发环境也可以把源码目录全局链接，得到更短的命令：

```powershell
pnpm --dir $pluginPath link --global
dsh-import-codex --profile web --dry-run
```

## CLI 参数

```text
dsh-import-codex [--profile <name>] [--dry-run] [--json]
```

- `--profile <name>` 选择 Harness profile，默认是 `web`。
- `--dry-run` 验证源历史和目标冲突，不写 session、工作区或关联关系。
- `--json` 关闭人类可读的进度信息，只输出一个 JSON 文档。
- `--help` 显示帮助。

机器可读的验证示例：

```powershell
pnpm import:codex -- --profile web --dry-run --json
```

退出码：

| 退出码 | 含义 |
|---:|---|
| `0` | 批次完成，导入和工作区关联都没有失败；目标已存在和 active 跳过属于正常结果。 |
| `1` | profile 组合、启动、App Server 或整个批次发生致命错误。 |
| `2` | 批次已完成，但至少一条对话导入或工作区关联失败。 |
| `130` | 用户用 `Ctrl+C` 中断。 |

命令可以安全重复执行：确定性目标 id 会阻止重复创建 session，已有标题投影会根据持久化日志刷新，工作区关联也是幂等的。

## 聊天命令备用入口

以下是 Harness 聊天框命令，不是 PowerShell 命令：

```text
/import-codex <thread-id> --dry-run
/import-codex <thread-id>
/import-codex --all --dry-run
/import-codex --all
```

命令结果会作为紧凑状态行显示在当前聊天中。它会持久化导入的 session，但不会把当前聊天自动切换到导入的 session。使用聊天命令导入后，需要刷新一次 Web 侧边栏。

## 架构

本包仍然是普通 Harness bundle：

- `cordis.patch.yml` 插入共享导入服务和聊天命令插件；
- 独立 launcher 启动目标 profile 中不属于界面的 bundle layer；
- `cli.patch.yml` 添加启动参数插件和一次性 runner 插件；
- 真实写入时再添加 `cli.workspace.patch.yml`，组合与 Web bundle 相同的公开 storage-domain、workspace 和 session-projection-cache 插件；
- CLI 与聊天命令都消费 `ctx.codexSessionImport`；
- App Server 进程通过 `ctx.subprocess` 管理，session 通过 `ctx.sessionPersistence` 持久化，工作区通过 `ctx.workspaceRegistry` 修改。

launcher 会排除已知的 Web 和 headless 界面 bundle，因此迁移进程不会启动 HTTP 服务，也不会创建 agent 任务。

## 配置

bundle row 暴露以下 Cordis 配置：

| 字段 | 默认值 | 用途 |
|---|---:|---|
| `codexCommand` | `codex` | Codex 可执行文件名或路径。 |
| `requestTimeoutMs` | `30000` | App Server 请求超时。 |
| `shutdownGraceMs` | `3000` | App Server 优雅结束等待时间。 |
| `maxDiagnosticBytes` | `65536` | 最多捕获的进程诊断字节数。 |
| `listPageSize` | `100` | `thread/list` 分页大小。 |
| `reasoningPolicy` | `summary` | 导入已验证的摘要，或完全省略 reasoning。 |

在目标 profile 的 `cordis.patch.yml` 中覆盖 `session-import-codex` row；CLI 和聊天命令会使用同一份解析后的配置。

## 故障排查

出现 `profile "web" does not include dsh-session-import-codex`，表示该 bundle 尚未安装到目标 profile，请执行上面的 `dsh plugin ... add`。

出现 `codex` 解析或 `initialize` 错误，表示 CLI 无法启动兼容的 Codex App Server。请确认同一个 PowerShell 会话中 `codex --version` 和 `codex app-server --help` 都能执行。

退出码 `2` 表示迁移已完成但有部分失败。查看 `[import]` 和 `[workspace]` 行：导入失败通常是历史数据或 schema 暂未支持；工作区失败通常表示历史 `cwd` 已不存在。

如果使用 0.1.0 导入的 session 显示为工作区目录名而不是 Codex 对话标题，请将插件更新到 0.1.1 或更高版本，停止 Web profile，重新执行一次真实迁移命令，然后重启 Web。重跑只会重建标题投影，不会重写对话日志。

不要在目标 Web/headless profile 仍在运行时执行真实写入。先停止它，重新运行 CLI，再重启 profile。

## 开发检查

```powershell
pnpm test
pnpm typecheck
pnpm lint
pnpm build
pnpm pack --dry-run
git diff --check
```

## 维护者发布 npm 包

即使本机安装依赖使用镜像，发布也会固定到 npm 官方 registry。先确认当前版本尚未发布，再登录 npmjs 并发布；`prepublishOnly` 会执行测试、类型检查和 lint，`prepack` 会重新构建 `lib/`。

```powershell
npm view dsh-session-import-codex versions --registry=https://registry.npmjs.org/
npm login --registry=https://registry.npmjs.org/
npm whoami --registry=https://registry.npmjs.org/
pnpm publish --access public --registry=https://registry.npmjs.org/
```

必须先把对应 Git commit 推送到 `https://github.com/xing01l/session-import-codex`，再发布 npm 包。

## 参与贡献与安全报告

开发流程见 [CONTRIBUTING.md](CONTRIBUTING.md)。安全问题请按照 [SECURITY.md](SECURITY.md) 私下报告，不要在公开 Issue 中附带对话历史或凭据。

## 许可证

本项目采用 [MIT License](LICENSE) 开源。
