DSH Plugin Store
Back to home

Nwflower

dsh-chat-import

从Claude Code、Codex、Reasonix等Agent工具导入迁移历史消息,并在DeepSeek Harness(DSH)中继续对话

Stars
18
Language
JavaScript
Created
Aug 13, 2026
Updated
Aug 14, 2026
Other
GitHub repo

Introduction

English | 简体中文

dsh-chat-import

DSH Chat Import

11 agent sources, one plugin — full-fidelity import into DeepSeek Harness, seamless resume, and export / sync back to Claude Code.

npm version npm downloads license: MIT Node.js >= 22.13 CI GitHub stars Awesome DSH Plugin

Listed in: Awesome DeepSeek Harness · Awesome DSH Plugin · Awesome DSH Plugins · npm   ·   Changelog: CHANGELOG.md

dsh-chat-import imports conversation histories from Claude Code, Codex, ChatGPT, Cursor, Gemini, Reasonix, opencode, ZCode, Grok Build, OpenClaw, Pi Coding Agent and Hermes — tool calls, reasoning and all — as full-fidelity, resumable DeepSeek Harness sessions. Source files are read read-only (never rewritten), the DSH engine is never touched, and every import becomes a fresh session grouped into the workspace of its source cwd.

The reverse direction is covered too: export_claude serializes a DSH session back into a Claude Code JSONL transcript that Claude Code can load with --resume (read-only — your DSH log is never modified), and sync_to_claude incrementally appends a session's new turns back to a Claude Code file — guarded, never silently overwriting.

✨ Features

📥 Import

  • 12 sources, one plugin — one tool per source, from Claude Code JSONL and Codex rollouts to SQLite databases and session directories.
  • 🔍 Full fidelity — tool calls & results, thinking blocks, titles, models and timestamps carry over wherever the source records them.
  • 📦 Batch import — point at a directory (or a whole database) and every file / conversation becomes its own session, with a per-file summary.

▶️ Resume

  • Seamlessly resumable — open an imported session and keep chatting exactly where the source left off.
  • 🗂 Auto workspace grouping — sessions land in the workspace of their source cwd — no more "ungrouped".

🔄 Reverse

  • 📤 Export to Claude Codeexport_claude writes any DSH session (imported or native) to <outputDir>/<slug>/<uuid>.jsonl, ready for --resume.
  • 🔄 Sync backsync_to_claude appends a session's new complete turns to its Claude Code file — guarded, never overwriting.

🛡️ Protection

  • 🔁 Idempotent + incremental — re-importing an unchanged source skips it; a grown source appends only its new turns.
  • 🧮 Context budget protection — oversized sessions are trimmed to fit a safe context budget, and the trim is reported.

🗂 Supported sources

SourceStorage locationImport tool
Claude Code~/.claude/projects/<slug>/<sessionId>.jsonlimport_claude
Codex / ChatGPT CLI~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonlimport_codex
ChatGPT (web export)anywhere you saved the export — conversations.jsonimport_chatgpt
Cursor~/.cursor/projects/<slug>/agent-transcripts/<id>/<id>.jsonlimport_cursor
Gemini CLI~/.gemini/history/<slot>/chats/session-*.jsonimport_gemini
Reasonix~/.reasonix/sessions/desktop-*.jsonlimport_reasonix
opencode~/.local/share/opencode/opencode.dbimport_opencode
ZCode (z.ai CLI)~/.zcode/cli/db/db.sqliteimport_zcode
Grok Build~/.grok/sessions/<project>/<session_id>/import_grokbuild
OpenClaw~/.openclaw/agents/<agent>/sessions/*.jsonlimport_openclaw
Pi Coding Agent~/.pi/agent/sessions/--<cwd>--/<timestamp>_<uuid>.jsonlimport_pi
Hermes~/.hermes/ (Windows %LOCALAPPDATA%\hermes)import_hermes

Each import preserves what the source actually records — session id, cwd, title, model, timestamps, tool calls & results, reasoning. Sources that record less import what exists; anything a format cannot preserve is explicitly flagged in the import report.

🚀 Quick start

1. Install — add the plugin to a profile:

dsh plugin --profile web add dsh-chat-import                    # npm package
dsh plugin --profile web add -w link:/path/to/dsh-chat-import   # local checkout (symlink)

2. Import — in any DSH session, import a single file or a whole directory (the same call shape works for all 12 import tools — see the table above):

import_claude({ path: "~/.claude/projects" })

3. Resume — refresh the session list once, open the imported session, and continue chatting — it resumes exactly where the source left off.

🛠 Usage

Note: imports persist to disk immediately, but the DSH session list does not auto-refresh — refresh the page (or the session list) after importing to see the new sessions.

Import — a single file or a directory. Every import_* tool takes a path; directories are scanned recursively and each file / conversation becomes its own session:

import_claude({ path: "C:\Users\<you>\.claude\projects\<slug>\<sessionId>.jsonl" })
import_codex({ path: "C:\Users\<you>\.codex\sessions\2026\05\18\rollout-2026-05-18T21-14-16-xxxx.jsonl" })
import_chatgpt({ path: "C:\Users\<you>\Downloads\chatgpt-export\conversations.json" })
import_opencode({ path: "C:\Users\<you>\.local\share\opencode\opencode.db" })

import_chatgpt / import_opencode / import_zcode / import_hermes always return a batch result — one file / database holds all conversations, so each conversation becomes its own session in a single call.

  • preview: true (alias dryRun: true) — run the import read-only: resolve, read and convert exactly like a real import, but persist nothing (zero side effects). Drop the flag and call again to actually import.
  • force: true — create a fresh full copy under a new id (import-<sessionId>-<n>) even when the source was already imported; the old session is never modified.
  • sessionId (optional) — override the target DSH session id (default import-<source sessionId>).
  • Incremental re-import — re-importing the same source never rewrites imported history. Unchanged files are skipped (already-imported) without re-reading; grown files append only their new turns to the same session (appended); truncated files are detected and reported (sourceShrunk) — use force: true for a complete fresh copy:
import_claude({ path: "C:\Users\<you>\.claude\projects\<slug>\<sessionId>.jsonl" })
// unchanged → "already-imported" · grew → "appended" (new turns only)

Every import result reports its status and any anomalies — malformed lines, suspected secrets, per-source drops — nothing is silently swallowed.

scan_discover — read-only session discovery

scan_discover scans the known data roots of all 12 formats and returns a structured session index (title, project, path, import status) so you can preview before a batch import. Zero side effects:

scan_discover()
scan_discover({ path: "~/.codex/sessions", format: "codex", query: "import" })

list_imported_sessions & retract_import — identify & retract

list_imported_sessions() enumerates every DSH session this plugin has imported; retract_import({ sessionId }) (or sourcePath) removes its registry record and returns manual-deletion guidance. Identification and guided manual deletion only — nothing is ever deleted:

list_imported_sessions()
retract_import({ sessionId: "import-019f5f27-…" })

export_claude — DSH → Claude Code JSONL

export_claude({ sessionId }) serializes an existing DSH session (imported or native) into a Claude Code JSONL transcript, ready for --resume. It is written to <outputDir>/<slug>/<uuid>.jsonl (default ~/.claude/projects), with a fresh UUID v4 file name — an existing file is never overwritten:

export_claude({ sessionId: "import-019f5f27-…" })
export_claude({ sessionId: "…", outputDir: "D:\backup\claude-projects", dryRun: true })

sync_to_claude — incremental write-back

sync_to_claude({ sessionId }) appends a session's new complete turns back to its Claude Code file — target: "source" by default (the import source) or "copy" (the last export_claude copy). Guards report an externally modified or shrunken file instead of overwriting it; force: true re-anchors past external edits (the overridden guard is still reported):

sync_to_claude({ sessionId: "import-019f5f27-…" })
sync_to_claude({ sessionId: "…", target: "copy", dryRun: true })

🔑 Key behaviors

  • Read-only import — source transcripts and databases are never rewritten; imported DSH history is append-only (existing events are never modified).
  • Idempotent + incremental — unchanged sources are skipped without re-reading; growth appends only the new turns; truncation is detected and reported.
  • Auto workspace grouping — sessions are grouped into the workspace of their source cwd.
  • Context budget protection — imported sessions carry no provider configuration, so dsh never auto-compacts them; oversized sessions are trimmed to fit a context budget (per-message caps, then a compressed middle keeping the earliest prompts, a summary and the tail). The budget can be set per call or via the DSH_IMPORT_CONTEXT_BUDGET env var; the trim is always reported in the result.
  • Fail loudly, never silently — malformed lines and suspected secrets are counted and reported by position (line numbers / kind — content is never output); anything a source format cannot preserve is explicitly flagged in the import report.
  • Sandbox — reading source files or writing exports outside the workspace requires the session sandbox to allow the path.

⚙️ Compatibility

Targets the dsh 0.1.x line (dsh-tools ^0.1.0-rc.6, tested on dsh 0.1.0-rc.6) and requires Node.js >= 22.13 (the first release where node:sqlite is available without a flag). npm test — 335 cases.

📦 Install & uninstall

dsh plugin --profile web add dsh-chat-import        # npm package
dsh plugin --profile web add -w link:/path/to/dsh-chat-import   # local checkout (symlink)

dsh plugin folds the plugin's bundle declaration into the profile; the plugin becomes active after restarting dsh. To uninstall, remove the import-claude insert line from the profile's bundles and restart dsh. Already-imported sessions stay in the DSH data directory and are unaffected.

📄 License

MIT — see LICENSE.