dsh-shuttle:在 DSH 與 Codex、Claude Code 之間雙向遷移對話記錄

前言

如果你同時使用 Codex、Claude Code、Pi、Reasonix、OpenCode 和 DSH,會遇到一個具體問題:對話記錄分散在各個工具自己的存儲裏,格式互不兼容。想在 DSH 裏繼續之前的對話,或者把 DSH 會話交給其他工具接着用,基本只能手工整理。

下面介紹的 dsh-shuttle 解決的就是這個問題。它是一個 DeepSeek Harness 插件,同時提供離線 CLI,在 DSH 與這五類工具之間雙向遷移對話記錄。DSH 的理念是「一切皆插件」,對話遷移這類能力同樣以插件形式接入,而不是改動 DSH 本體。

這是什麼

dsh-shuttle 倉庫爲 omdsh-dev/dsh-shuttle,包名 @deepseek-ai/dsh-shuttle,由 omdsh-dev 維護,採用 MIT 許可證,當前版本 0.1.0。它支持在 DSH 與 Codex、Claude Code、Pi、Reasonix、OpenCode 之間雙向遷移對話記錄,既可以作爲插件在 DSH 內使用,也可以作爲獨立 CLI 離線運行。

遷移的工作方式

遷移前,每個來源會先投影爲一個 provider-neutral 的中間模型,再轉換成 DSH 事件或目標平臺的原生導入格式。在目標支持的前提下,文本、推理內容、工具調用與結果、時間戳、工作目錄以及 provider/model 身份都會保留。

並非所有數據都可移植:Provider 私有回放狀態、緩存數據、UI-only 事件、token 分塊與數據庫索引不在遷移範圍內。二進制/圖片附件在無法安全複製字節時,會變成文本佔位符。

安全設計

寫入類操作有幾條硬性約束:

  • 默認 dry-run,帶 --apply 才真正執行寫入;
  • 已存在的 DSH ID 與目標文件會被跳過,從不覆蓋;
  • 讀取有大小/數量上限,且不遞歸符號鏈接目錄;
  • DSH 寫入使用 ctx.sessionPersistence,JSONL 與 SQLite 後端均可工作;
  • OpenCode 通過官方 export/import JSON envelope 處理,從不直接編輯其數據庫;
  • Shuttle 從不刪除源歷史。

安裝與啓用

README 沒有給出具體安裝命令,只說明通過常規 DSH 插件工作流安裝本包。安裝後,捆綁的 cordis.patch.yml 會掛載 ctx.shuttlemigrate-conversations 技能,插件導出標準的 nameinjectConfigapply 符號。

運行環境爲 Node ^22.19.0 || >=24.0.0,包管理器 pnpm@11.7.0。使用 CLI 前需要先構建:

pnpm install
pnpm build

構建後 CLI 入口爲 lib/cli.js,package.json 中註冊的 bin 命令名是 dsh-shuttle

通過 Settings UI 遷移

打開 Settings → Conversation migration,可以看到兩個獨立的導入/導出單元,不需要手工拼命令:

  1. Import to DSH 中選擇來源平臺,可選設置來源路徑與數量上限;
  2. Export from DSH 中選擇目標平臺、DSH 任務、目標路徑與範圍;
  3. 每個單元單獨預覽。Settings 預覽使用專用 Remote API,不會創建 DSH 會話,也不會寫目標文件;
  4. 查看該單元的報告,勾選確認後執行導入或導出。

執行按鈕只在當前表單成功預覽後可用;更改任何遷移輸入都會使預覽失效。

斜槓命令 /shuttle

在存在交互式 DSH 命令服務的環境中,可以在會話輸入裏輸入 /shuttle 查看幫助並執行導入/導出,結果直接顯示在 UI,不會發送給模型:

/shuttle import codex
/shuttle import codex --source "~/.codex/sessions" --apply
/shuttle export pi --destination "~/.pi/agent/sessions"
/shuttle export opencode --session <id> --destination /tmp/opencode --apply

不帶 --apply 時都是預覽。導出默認針對當前 UI 會話,可以通過重複 --session--all 改變選擇。

CLI 用法

CLI 提供 import/export 兩個子命令,支持 --from/--to--source--destination--session(可重複)、--all--apply--dsh-root。流程是先構建,再預覽,確認報告後加 --apply 寫入。

先看導入。默認 DSH 存儲爲 $DSH_HOME/sessions~/.dsh/sessions,可用 --dsh-root 覆蓋:

node lib/cli.js import --from codex
node lib/cli.js import --from claude-code --source ~/.claude/projects
node lib/cli.js import --from pi --source ~/.pi/agent/sessions
node lib/cli.js import --from reasonix --source ~/.reasonix

檢查 JSON 報告後,加 --apply 重複執行同一命令完成寫入。

導出方向:

node lib/cli.js export --to codex --session <id> --destination ~/.codex/sessions --apply
node lib/cli.js export --to pi --destination ~/.pi/agent/sessions --apply
node lib/cli.js export --to reasonix --destination ~/.reasonix --apply

重複 --session 可選擇多個會話;省略它則導出至配置的 maxSessions 上限。

OpenCode 的讀寫配合它自己的 export/import 命令完成:

opencode export <session-id> > /tmp/opencode-session.json
node lib/cli.js import --from opencode --source /tmp/opencode-session.json --apply

node lib/cli.js export --to opencode --session <dsh-session-id> \
  --destination /tmp/dsh-opencode --apply
opencode import /tmp/dsh-opencode/<dsh-session-id>.opencode.json

Reasonix 方向,如果寫入後它的目錄裏沒有顯示新的權威 JSONL 會話,運行一次 reasonix sessions reindex

插件 API 與配置

插件暴露兩個 API,同樣遵循先預覽、後寫入的模式:

const preview = await ctx.shuttle.importConversations({
  from: 'codex',
  source: '/path/to/.codex/sessions',
})

await ctx.shuttle.importConversations({
  from: 'codex',
  source: '/path/to/.codex/sessions',
  apply: true,
})

await ctx.shuttle.exportConversations({
  to: 'claude-code',
  sessionIds: ['session-id'],
  destination: '/path/to/.claude/projects',
  apply: true,
})

兩個配置項控制讀取上限:

配置項 默認值 含義
maxFileBytes 64 MiB 單個外部工件的最大尺寸
maxSessions 500 每次操作的最大工件/會話數

適用場景與注意事項

它適合在多個編碼智能體之間切換、想把歷史會話集中到 DSH,或需要把 DSH 會話交給其他工具繼續使用的開發者。使用前注意兩點:

  • Codex 與 Claude Code 不承諾穩定的公開磁盤轉錄 schema。讀取器是寬容的,但這兩家升級後需要重新預覽;導出的 Codex/Claude JSONL 匹配當前觀察到的 envelope,未來客戶端可能需要顯式導入器或適配器更新。
  • 插件以當前 dsh 進程的權限運行,安裝前應檢查源碼與許可證(MIT)。

結尾

經過上面的步驟,分散在各家工具裏的對話記錄就變成了可遷移的數據;默認預覽、從不覆蓋的設計讓每次寫入都可控。代碼與文檔見 GitHub 倉庫:

https://github.com/omdsh-dev/dsh-shuttle

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜