# @danglong0313/dsh-history-sync

[![npm version](https://img.shields.io/npm/v/@danglong0313/dsh-history-sync.svg)](https://www.npmjs.com/package/@danglong0313/dsh-history-sync)
[![license](https://img.shields.io/npm/l/@danglong0313/dsh-history-sync.svg)](./LICENSE)

把本机 Codex 与 Claude Code 历史任务以只读镜像的形式单向导入 DeepSeek Harness（DSH）。插件只调用公开接口：Codex 使用 `codex app-server` 的 stdio 协议，Claude 使用官方 Claude Agent SDK；它不会读取、修改或重写两者的私有历史 JSONL。

- npm：[@danglong0313/dsh-history-sync](https://www.npmjs.com/package/@danglong0313/dsh-history-sync)
- 源码：[github.com/danglong0313/dsh-history-sync](https://github.com/danglong0313/dsh-history-sync)
- 问题反馈：[GitHub Issues](https://github.com/danglong0313/dsh-history-sync/issues)

## 功能概览

- 单向、只读镜像 Codex 与 Claude Code 的用户/助手对话，不写回来源。
- 默认预览、默认不自动同步、默认只扫描最近 30 天。
- 在 `设置 → 插件 → 插件配置 → History Sync` 中直接配置和启用自动同步。
- 自动按原工作目录创建或复用 DSH Workspace，在左侧项目栏分组显示。
- 使用内容指纹、追加水位和 generation 处理重复同步、增量追加及上游历史重写。
- 过滤 system/developer、reasoning、工具调用、审批、命令输出和 Claude 控制标签，避免把协议消息当作真实聊天。

## 兼容性

- 已验证 DSH：`0.1.0-rc.6`
- Node.js：`^22.19.0` 或 `>=24`
- Claude Agent SDK：插件固定携带 `0.3.233`
- Codex：需要支持稳定 `thread/list` 与 `thread/read` 的当前官方 Codex；Windows 下可自动发现 Codex Desktop 内置程序

DSH 仍处于预发布阶段，Session 格式不保证跨预发布版本兼容。升级 DSH 后，请先在隔离 profile 中重新执行预览和安装验证。

## 安装与卸载

```powershell
dsh plugin --profile web add @danglong0313/dsh-history-sync
dsh --profile web --dump-config
```

第二条命令应显示固定 ID 为 `history-sync`、包名为 `@danglong0313/dsh-history-sync` 的配置层。`dsh plugin` 会维护 profile 的 `package.json` 与 `dsh.profile.bundles`；不要手工编辑它们。

升级到最新版：

```powershell
dsh plugin --profile web update @danglong0313/dsh-history-sync
```

卸载：

```powershell
dsh plugin --profile web remove @danglong0313/dsh-history-sync
```

## 在 DSH 设置中配置

安装并启动 DSH 后，打开：

```text
设置 → 插件 → 插件配置 → History Sync
```

这里可以直接选择 Codex/Claude 来源、最近天数、单次任务上限、工作目录过滤、项目分组、允许实际导入和自动同步。点击“保存并应用”后无需重启 DSH；开启“自动同步”会同时退出预览模式、立即启动一次同步，并在同步完成后自动刷新左侧项目栏。

界面配置作为插件自有覆盖层保存在 `stateDirectory/settings.json`；同步游标和去重状态仍单独保存在 `stateDirectory/state.json`。两者都不会写入 `cordis.patch.yml`，也不会包含消息正文或密钥。卸载插件不会自动删除这些运行数据。

## 首次预览与手动同步

默认 `previewOnly: true` 且 `autoSync: false`。启动 Web profile，在任意 DSH 任务里执行：

```text
/history-sync preview
```

预览只报告发现、选择、新建、增量和新 generation 的数量，不创建 DSH Session，也不写同步状态。确认范围后，推荐在上述 History Sync 配置卡中开启“允许实际导入”，再执行：

```text
/history-sync run
```

不带参数的 `/history-sync` 等同于预览。自动同步默认关闭；先完成预览，再在配置卡中开启“自动同步”。插件会立即同步一次，随后按 `syncIntervalMinutes` 做幂等增量同步；导入的 Session 会按原工作目录出现在左侧项目/会话列表中，无需再输入命令。

## 高级配置与完整 patch 覆盖

普通设置请优先使用界面。部署级参数（Codex 命令、协议分页、超时、状态目录和消息纳入策略）仍可通过 profile patch 配置。DSH patch 对同一 ID 的 `config` 是整项替换，不是深度合并，因此覆盖时必须重述完整配置：

```yaml
- id: history-sync
  name: '@danglong0313/dsh-history-sync'
  config:
    codexEnabled: true
    claudeEnabled: true
    autoSync: false
    syncIntervalMinutes: 60
    importDays: 30
    maxSessionsPerSync: 50
    workspaceRoots: []
    groupByWorkspace: true
    readOnly: true
    previewOnly: true
    stateDirectory: !!js dshHomePath('history-sync')
    codexCommand: auto
    codexArgs:
      - app-server
    codexPageSize: 100
    codexRequestTimeoutMs: 30000
    codexShutdownTimeoutMs: 3000
    codexSourceKinds:
      - cli
      - vscode
      - appServer
    claudePageSize: 100
    claudeIncludeSystemMessages: false
    claudeIncludeWorktrees: true
    claudeIncludeProgrammatic: true
```

字段说明：

- `codexEnabled` / `claudeEnabled`：启用对应来源，至少开启一个。
- `importDays`：只考虑最近 N 天，默认 30，不会无限扫描全部历史。
- `maxSessionsPerSync`：两种来源合并排序后，单次最多处理的任务数。
- `workspaceRoots`：可选绝对目录列表；任务工作目录必须等于或位于其中一个目录下。
- `groupByWorkspace`：为现存的原工作目录创建或复用 DSH Workspace，并把镜像 Session 加入对应项目分组。
- `readOnly`：v1 必须为 `true`；配置为 `false` 会在插件加载时失败。
- `previewOnly`：为 `true` 时拒绝实际导入。
- `stateDirectory`：插件自有界面设置、同步游标、fingerprint、pending 写前记录和 generation 状态目录；消息正文不写入这里。
- `codexSourceKinds` 默认只纳入交互式主任务（`cli`、`vscode`、`appServer`）。`exec`、`subAgent*` 和 `unknown` 容易包含自动化、子代理提示词或协议消息，只有明确需要时才应手动加入。
- `codexCommand: auto`：先使用 `DSH_HISTORY_SYNC_CODEX`，再查找 PATH；Windows 下还会通过 AppX 注册信息自动定位 Codex Desktop 内置的官方 `codex.exe`。由于 WindowsApps ACL 会阻止普通 DSH 子进程直接启动该路径，插件会把同一官方二进制缓存到 `stateDirectory/codex-bin` 后运行；也可改为官方可执行文件的绝对路径。
- 其余 Codex/Claude 字段控制官方客户端分页、超时和纳入的公开来源类型。

默认只镜像用户可见的用户文本和助手文本。Codex 的 system/developer 消息、reasoning、工具调用、审批和命令输出不会伪装成聊天消息；Claude 的 system、thinking、tool use/result，以及以 `<command-name>`、`<local-command-stdout>`、`<ide_opened_file>` 等 XML 风格控制标签开头的记录也会跳过。不完整且尚无助手回复的上游 turn 会等到完成后再导入。

界面只暴露日常、安全的字段；保存时会原子写入并立即校验。错误配置会明确拒绝，例如两个来源均关闭、相对工作目录、关闭只读模式，或在仍为预览模式时开启自动同步。

## 幂等与历史重写

每个标准化 turn 都有内容 fingerprint。重复运行不会重复追加相同消息；上游仅追加完整 turn 时，插件会继续写入同一个 DSH Session。若上游历史缩短、压缩、回退或已有内容改变，插件不会重写 DSH 的追加日志，而是创建新的 import generation，并保留旧 generation。

来源、上游任务 ID、原始工作目录、来源更新时间/修订、导入时间、导入版本、generation 与 fingerprint 保存在 `stateDirectory/state.json`。这些元数据不会伪装成可见聊天消息，也不会写入 `cordis.patch.yml`。

## 隐私与安全

**导入会在 DSH 持久化中产生第二份历史副本。** 原任务可能包含源码、命令输出、`.env` 内容、凭据或其他敏感信息；启用前请检查 DSH 的存储位置、访问权限、备份和保留策略。删除 Codex/Claude 原任务不会自动删除 DSH 副本，反之亦然。

插件不会把密钥写入 patch 或同步状态，不记录消息正文到插件日志，也不会修改 Codex、Claude 的原始历史。同步状态本身仍包含上游任务 ID和原始工作目录，应按敏感运行数据保护。

## 常见问题

### 设置中没有 History Sync

确认安装的是 `0.2.0` 或更高版本，然后完全重启 DSH。使用下列命令确认 profile 已包含插件：

```powershell
dsh --profile web --dump-config
```

### `spawn codex ENOENT` 或 Codex 无法启动

默认 `codexCommand: auto` 会先检查 `DSH_HISTORY_SYNC_CODEX` 和 PATH，再自动发现 Windows Codex Desktop。WindowsApps 中的程序无法被普通子进程直接启动时，插件会把同一官方二进制缓存到 `stateDirectory/codex-bin` 后运行。仍失败时，可以把 `codexCommand` 配置为官方 `codex.exe` 的绝对路径。

### 会话出现在“未分组”

只有来源工作目录存在且 `groupByWorkspace: true` 时，插件才能创建或复用对应 Workspace。工作目录已经删除、不可访问或来源没有提供目录时，会话仍会导入，但可能显示在“未分组”。

### 卸载后历史副本还在

卸载只移除插件包，不会删除已经导入的 DSH Session，也不会删除 `stateDirectory` 中的设置和同步状态。请先确认备份和保留需求，再从 DSH 和文件系统中分别清理不再需要的数据。

## 限制

- 这是单向历史镜像，不是双向同步，也不能从 DSH 无损恢复 Codex/Claude 的模型、工具进程、审批、沙箱或运行状态。
- DSH rc.6 没有公开的 Session 级“禁止继续对话”锁。镜像会明确标注只读并且永不写回上游，但用户仍可能在 DSH 中从该副本继续新对话；这些新内容仅属于 DSH。
- v1 在 turn 边界增量导入。尚未完成的最后一个 turn 后续发生变化时，会被视为重写并创建新 generation。
- Codex provider 使用稳定的 `thread/list` 和 `thread/read(includeTurns: true)`；不会启用实验性的分页 turn/item API。
- Claude provider 使用 `listSessions()` 和分页的 `getSessionMessages()`；当前不需要调用 `getSessionInfo()`。

## 开发验证

```powershell
npm run typecheck
npm test
npm run build
npm pack --dry-run
```

测试只使用合成的 Codex App Server 与 Claude SDK 数据，不包含真实历史、私人绝对路径或凭据。

## 版本说明

### 0.2.0

- 新增 DSH 内置“插件配置”页面。
- 支持从界面开启自动同步，并在完成后刷新左侧项目栏。
- 增加插件自有、原子写入的安全配置覆盖层。
- 保留 0.1.1 的 Windows Codex Desktop 自动发现与官方二进制缓存机制。

## 参与开发

欢迎通过 [Issues](https://github.com/danglong0313/dsh-history-sync/issues) 报告可复现问题。提交日志或测试数据前请先移除源码、绝对私人路径、Token、Cookie、API Key 和真实历史正文。

## License

MIT
