dsh-chat-import

85Star13Fork1Issue1Watching

把 15 种外部 AI 编程 agent(Claude Code/Codex/ChatGPT/Cursor/opencode 等)的对话历史全保真导入为可继续的 DSH 会话,并支持反向导出与跨机器迁移。

语言
JavaScript
License
MIT
分支
main
agentai-agentsautomationchatgptclaude-codecodexcursordeepseek

安装

$ dsh plugin --profile web add github:Nwflower/dsh-chat-import

在终端中运行以上命令,通过 dsh CLI 安装此插件。可在右上角切换 Profile。 第一次用 dsh?看这篇新手教程

一句话定位

把 Claude Code、Codex、ChatGPT、Cursor、opencode、ZCode、Grok Build、Hermes 等 15 种外部 AI 编程 agent 的本地对话历史(以及任意本地 JSONL)全保真地导入为可在 DSH 中继续聊天的会话,同时支持反向导出到 Claude Code/Codex/Kimi 和跨机器可移植备份。

核心能力

  • 导入 15 种来源的本地历史:Claude Code / Codex-ChatGPT CLI / ChatGPT 网页导出 / Cursor / Gemini CLI / Reasonix / opencode / ZCode / Grok Build / OpenClaw / Pi Coding Agent / Hermes / Kimi CLI&Code / Qoder CLI,加上 DSH 自身会话日志与任意本地 JSONL
  • 保留工具调用与结果、思考块、标题、模型与时间戳;ChatGPT 导出支持分支还原,opencode/zcode/pi 尊重源端压缩摘要并可选全量
  • 幂等且增量:源文件未变跳过、增长只追加新增轮、缩小主动报告;force:true 用新 id 另存完整副本
  • 反向矩阵:DSH 会话可导出为 Claude Code JSONL、Codex rollout、Kimi wire,以及带 SHA-256 双指纹的可移植交换包
  • 反向同步:sync_to_claude 把 DSH 新增轮次增量写回 Claude Code JSONL,带防覆盖守卫,从不静默覆盖
  • 浏览器侧边栏:「导入会话」按钮 + 工作区分组的浏览面板 + 单选/多选导入,共享只读发现缓存
  • 配套工具:导入 agent/skill 配置、生成 MCP 镜像片段、配置迁移建议、verify_session 结构校验、doctor 健康检查、sync_to_claude/export_bundle/restore_bundle

技术实现

  • 语言: JavaScript ESM(纯 ESM、零构建,源码即发布产物)
  • 关键依赖: @deepseek-ai/cordis (DSH 插件框架)、@deepseek-ai/dsh-tools (DSH 工具注册 API)、@deepseek-ai/dsh-client-locale (侧边栏文案多语言)、fzstd (DSH 会话日志 .zstd 解压)
  • 架构模式: 原生 Cordis 插件,通过 apply(ctx) 注册 22 个 DSH 工具并延迟挂载浏览器面板路由(ctx.inject(['webServer']));lib/convert/*lib/export/* 保持零 DSH 依赖纯函数,可独立单测;lib/*.mjs(消费 ctx 的 host 面)负责编排与落盘
  • 入口文件: index.mjs(薄组合层)+ lib/tools.mjs(22 个工具注册)+ cordis.patch.yml(profile bundle insert)

适用场景

  • 已经在 Claude Code / Codex / Cursor 等工具里积累了大量上下文,切换到 DSH 后想无缝接着聊而不是从头开始
  • 想跨 AI 编码工具搬运会话(Claude ↔ DSH ↔ Codex ↔ Kimi)做备份或多平台对照
  • 多台机器迁移时希望带会话一起走,且不破坏源文件、不丢失工作区归组
  • 想把外部 agent 的自定义 prompt、skill、配置统一迁移到 DSH 的 skills 目录

前置依赖与兼容性

依赖最低版本说明
DeepSeek Harness (dsh-tools)0.1.0-rc.6+peer @deepseek-ai/dsh-tools ^0.1.0-rc.6,测试基于 dsh 0.1.0-rc.6
@deepseek-ai/cordis^4.0.1peer 依赖,DSH 插件框架
@deepseek-ai/dsh-client-locale>=0.1.0-rc.6peer 依赖,侧边栏面板文案多语言
react>=18.0.0peer 依赖,侧边栏 Bundle 渲染
Node.js>=22.13engines.node,首个内置 node:sqlite 的版本
平台跨平台macOS / Windows / Linux 均可;opencode / zcode / hermes 三个 SQLite 来源依赖 node:sqlite,CI 在 Linux 跑测试通过

安装方式

dsh plugin --profile web add github:Nwflower/dsh-chat-import

配置项

本插件无需在 profile 中预先声明配置;行为通过调用参数与环境变量控制。下表是工具调用的常用参数与环境变量。

配置类型说明默认值
pathstring源文件或源目录路径(单文件或目录批量)必填
forcebooleantrue 时即便已导入也以新 id 另存完整副本false
budgetinteger上下文预算(token 数);优先级:本参数 > DSH_IMPORT_CONTEXT_BUDGET > 动态模型窗口 > 550k未设
preview / dryRunbooleantrue 时只解析不写盘,零副作用false
sessionIdstring覆盖目标 DSH 会话 id(单文件模式)import-<源id>
recursiveboolean目录模式是否递归子目录true
expectedHashstring源文件期望 SHA-256(小写 hex),不匹配则拒绝落盘未设
restampbooleantrue 时把会话时间戳平移到当前时间(保持相对间隔)false
workspaceModestringauto/per-project 按 cwd 或源目录归组;dedicated 全部挂到同一个工作区auto
workspaceDirstringworkspaceMode=dedicated 时的工作区目录$DSH_HOME/dsh-chat-import-workspace
DSH_IMPORT_CONTEXT_BUDGETenv上下文预算 token 数(整库导入预算链)未设
DSH_IMPORT_SESSION_HINTenv=0 时关闭新会话起始的迁移提示
DSH_IMPORT_CONTEXT_BRIDGEenv=1 时把 Claude memory/CLAUDE.md/skills 桥接到当前 agent

导入侧边栏面板路由、命令面(/import/resume-claude 等)在 web/profile 组合下自动启用;headless / 无 webServer 服务的 profile 下不会挂载面板路由,但 16 个导入工具照常可用。

常见问题

Q: 安装后要不要配置什么才能用?

A: 装好后重启 dsh 即可,插件默认消费 host 公开服务。如果机器上没装对应 agent 的本地数据目录,导入工具在缺路径时直接报错,不会自动创建。

Q: 会改写我原本的 Claude Code / Codex 历史文件吗?

A: 不会。源 transcript 和 SQLite 数据库全程只读;导入结果只往 DSH 会话目录里追加新事件,导入元数据写到 $DSH_HOME/dsh-chat-import/imports.jsonsync_to_claude 会追加写回到 Claude Code 文件,但带防覆盖守卫(源缩小或被外部修改会跳过并上报),force:true 才重锚定。

Q: 重复导入同一份历史会不会产生重复会话?

A: 不会。源文件 mtime/size 未变会幂等跳过,完全不再读源数据;源文件增长则只追加新增轮次到同一会话;源文件缩小会被检测并报告。force:true 可以跳过幂等检查,用新 id 另存完整副本。

Q: 导入的会话能接着聊天吗,工具面板正常吗?

A: 能。导入时尽量走 host 的 agents.create 路径并挂载默认 preset scope 和默认模型,工具面与原生 DSH 会话一致,刷新会话列表即可接着聊;若 agents 服务不可用则自动回退到 sessionPersistence,不会因此中断。

Q: 我有上百个历史,想一次全导怎么办?

A: 浏览器侧边栏点「导入会话」打开面板,按工作区分组浏览 + 多选导入;或在 DSH 会话里直接跑 scan_discover() 看清单,再依次调用 import_<source>({ path: "<数据根>" })。目录路径会递归扫描,每个 transcript 各成一个会话。

Q: 怎么撤销已导入的会话?

A: 用 retract_import({ sessionId })(或 sourcePath),插件只移除 registry 记录并返回手动删除工件路径的引导,从不调用任何删除。按引导手动删工件后再 force:true 重导就能得到全新会话。

Q: 在另一台机器上能接着导过来的会话聊吗?

A: 能。用 export_bundle({ sessionId }) 导出 .dshbundle.json(带 SHA-256 双指纹 + 跨机器落点信息),复制到另一台机器后跑 restore_bundle({ path });原 cwd 在新机器不可达时会回退到 bundle 文件所在目录并在结果里上报 cwdAvailable:false,不会静默归到「未分组」。

Q: 报「TOOL_RUNTIME_SCHEDULER 缺失」怎么办?

A: 这是 host 的 @deepseek-ai/dsh-tools 版本低于 0.1.0-rc.6 时插件主动抛错(防止用旧 ABI 注册工具污染会话历史)。升级 host 即可。

上手难度

入门 — 装好插件重启 DSH 即可用默认参数导入单文件;面板浏览 + 多选导入不写代码。复杂场景(预算裁剪、跨机器迁移、专用工作区)涉及 1-2 个额外参数,看 README 即可上手。

已知问题与限制

  • node:sqlite 首次可用版本是 Node 22.13;Windows / Linux / macOS 均可,但宿主环境必须满足 >=22.13
  • import_dshexport_bundle 走相同的转换器,但 DSH 自身历史默认不进入 scan_discover 的 15 种自动根(需要显式 path 或 format)
  • Kimi 子代理会话在父 wire 中以 SubagentEvent 形式记录时被跳过;需要单独导入子代理目录或新布局 agents/<agentId>/wire.jsonl
  • Cursor agent transcript 不包含 tool_result,只导入 tool_use 调用历史
  • sync_to_claude 默认严格守卫(源缩小 / 外部修改 / tail 失配 / 并发写者均跳过并报告);force:true 会重锚定水印与链尾,可能覆盖外部修改
  • 浏览器面板路由依赖 host 的 webServer 服务晚挂载,headless / 无 webServer 服务的 profile 不挂载面板但导入工具照常可用