danglong0313
dsh-history-sync
将codex和claude项目历史同步到dsh
- Stars
- 0
- Language
- TypeScript
- Created
- Aug 15, 2026
- Updated
- Aug 16, 2026
Introduction
@danglong0313/dsh-history-sync
把本机 Codex 与 Claude Code 历史任务以只读镜像的形式单向导入 DeepSeek Harness(DSH)。插件只调用公开接口:Codex 使用 codex app-server 的 stdio 协议,Claude 使用官方 Claude Agent SDK;它不会读取、修改或重写两者的私有历史 JSONL。
功能概览
- 单向、只读镜像 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 中重新执行预览和安装验证。
安装与卸载
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;不要手工编辑它们。
升级到最新版:
dsh plugin --profile web update @danglong0313/dsh-history-sync
卸载:
dsh plugin --profile web remove @danglong0313/dsh-history-sync
在 DSH 设置中配置
安装并启动 DSH 后,打开:
设置 → 插件 → 插件配置 → History Sync
这里可以直接选择 Codex/Claude 来源、最近天数、单次任务上限、工作目录过滤、项目分组、允许实际导入和自动同步。点击“保存并应用”后无需重启 DSH;开启“自动同步”会同时退出预览模式、立即启动一次同步,并在同步完成后自动刷新左侧项目栏。
界面配置作为插件自有覆盖层保存在 stateDirectory/settings.json;同步游标和去重状态仍单独保存在 stateDirectory/state.json。两者都不会写入 cordis.patch.yml,也不会包含消息正文或密钥。卸载插件不会自动删除这些运行数据。
首次预览与手动同步
默认 previewOnly: true 且 autoSync: false。启动 Web profile,在任意 DSH 任务里执行:
/history-sync preview
预览只报告发现、选择、新建、增量和新 generation 的数量,不创建 DSH Session,也不写同步状态。确认范围后,推荐在上述 History Sync 配置卡中开启“允许实际导入”,再执行:
/history-sync run
不带参数的 /history-sync 等同于预览。自动同步默认关闭;先完成预览,再在配置卡中开启“自动同步”。插件会立即同步一次,随后按 syncIntervalMinutes 做幂等增量同步;导入的 Session 会按原工作目录出现在左侧项目/会话列表中,无需再输入命令。
高级配置与完整 patch 覆盖
普通设置请优先使用界面。部署级参数(Codex 命令、协议分页、超时、状态目录和消息纳入策略)仍可通过 profile patch 配置。DSH patch 对同一 ID 的 config 是整项替换,不是深度合并,因此覆盖时必须重述完整配置:
- 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 已包含插件:
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()。
开发验证
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 报告可复现问题。提交日志或测试数据前请先移除源码、绝对私人路径、Token、Cookie、API Key 和真实历史正文。
License
MIT