Seafood-Y / CC2DSH

已收录

Import Claude Code session history into DeepSeek Harness (DSH): convert, verify, and attach conversations to workspaces with original titles restored.

main会话 查看源代码

安装

npx -y @deepseek-ai/dsh plugin --profile web add github:Seafood-Y/CC2DSH

此安装命令根据 GitHub 仓库地址生成,是未经验证的安装起点。

README

维护者编写的文档快照。

在 GitHub 查看 ↗
提交版本 f1d1b41同步于 2026年8月18日

CC2DSH

English | 中文

Claude Code → DeepSeek Harness (DSH) session importer

Migrate your Claude Code conversation history (~/.claude/projects/<project>/<session>.jsonl) into DeepSeek Harness session storage (~/.dsh/sessions/), so those conversations become visible in the DSH Web GUI — grouped into the workspaces they originally belonged to, with their original titles restored, and ready to continue chatting.

A skill/tool for the DeepSeek Harness ecosystem, built around dsh's session persistence format.

Features

  • Multi-frame zstd layout: generated session files strictly satisfy DSH's read requirements (frame 1 = exactly one header line)
  • turn/end with reason: event content passes DSH's content-level validation
  • Titles preserved: automatically takes the last ai-title from Claude records into a session/title event; the title projection is restored on attach
  • Workspace matching: reuses/creates workspaces by cwd, sessions land in their original project directories
  • Renamed-directory handling: --cwd-map OLD=NEW fixes projects that were renamed or moved after the session was recorded
  • Idempotent import: session ids match Claude's sessionId, so re-imports simply overwrite
  • Format validator: verify_session.py gates imports so one bad file can never take down the whole session list

Quick start

# 1. Convert all sessions (default output: ~/.dsh/sessions)
python3 convert_claude_to_dsh.py

# 2. Validate format and content
python3 verify_session.py

# 3. Attach to workspaces (titles are restored too; if the dsh web service was
#    started before the import, restart it first so memory matches disk)
node attach_to_workspace.mjs

Then refresh the DSH Web GUI (default http://127.0.0.1:12788) — sessions appear grouped by workspace, titled with the original Claude titles.

Usage

Convert (Claude JSONL → DSH session files)

# All sessions
python3 convert_claude_to_dsh.py

# Specific files, output to a test directory
python3 convert_claude_to_dsh.py a.jsonl b.jsonl --out /tmp/cc2dsh-test

# Fix renamed directories (example)
python3 convert_claude_to_dsh.py --cwd-map "/old/path=/new/path"

# Preview without writing
python3 convert_claude_to_dsh.py --dry-run

# List all importable Claude sessions
python3 convert_claude_to_dsh.py --list

Validate (format + content)

python3 verify_session.py                   # validate all of ~/.dsh/sessions
python3 verify_session.py /tmp/cc2dsh-test  # validate any directory

Checks: ≥2 frames, frame 1 is exactly one header line, complete event lines, every turn/end carries reason.kind, header fields present; also prints each session's title for manual review. Exit code 0 = all good.

Attach to workspaces

node attach_to_workspace.mjs           # attach all unattached sessions
node attach_to_workspace.mjs --dry-run # preview

For each session, the script uses the cwd from its header to:

  1. workspace.create(path=cwd) — create if missing, reuse if present;
  2. session.create(sessionId, workspaceId) — mount via the resume path, which also folds the logged session/title event into the title projection.

Note: attaching uses the resume path, so sessions become live agents. If the DSH service has been running since before the import (stale in-memory state), restart the dsh web service first, then run this script.

Why this tool exists (background)

DSH session files have strict format requirements, and naively compressing the whole JSONL with single-frame zstd breaks them:

  1. Multi-frame layout: session.jsonl.zstd must be a concatenation of independent zstd frames — frame 1 must decompress to exactly one session header line (newline-terminated). Single-frame compression makes DSH report corrupt Zstandard session log: first frame is not exactly one header line, which makes session.list fail entirely and the GUI session list go empty.
  2. turn/end reason: every turn/end event must carry a reason field (e.g. {"turn": 1, "reason": {"kind": "completed"}}), or DSH reports contains malformed pre-react-loop turn/end.

The converter here generates multi-frame files directly per the DSH persistence spec (dsh-session-persistence-jsonl), avoiding both failure modes at the source.

Renamed / moved directories

The cwd recorded by Claude Code is the project path at the time. If the directory was later renamed or moved, DSH workspace matching by realpath fails (workspace ... ENOENT). Fix it with --cwd-map:

python3 convert_claude_to_dsh.py \
  --cwd-map "/old/path=/new/path" \
  --cwd-map "/another/old=/another/new"

Converted sessions are then written to the new path's project directory, and the header cwd is updated accordingly.

Troubleshooting

SymptomCauseFix
Session list empty after refreshOne malformed session file makes session.list throwLocate with verify_session.py; regenerate with this converter; restart service after fixing
corrupt Zstandard session log: first frame is not exactly one header lineSingle-frame compressionRe-convert (multi-frame layout)
malformed pre-react-loop turn/end at seq Nturn/end missing reasonRe-convert (already fixed)
Sessions under "Ungrouped"Attach script not run / stale service statenode attach_to_workspace.mjs; restart service if needed
Title is workspace name or blankNo session/title eventSessions with no ai-title in source (command-only) keep no title, matching Claude
workspace ... ENOENTcwd directory renamed/deletedRe-convert with --cwd-map OLD=NEW

Files

FilePurpose
convert_claude_to_dsh.pyConverter: multi-frame zstd, turn/end reason, --cwd-map, title preservation
verify_session.pySession format/content validator
attach_to_workspace.mjsWorkspace attach script (reuse/create by cwd, restore title projections)
SKILL.mdSkill documentation (full workflow + troubleshooting)
testdata/Session backups for regression testing

Testing

The repo ships two real session backups (testdata/) for regression testing:

python3 convert_claude_to_dsh.py <path-to-jsonl> --out /tmp/cc2dsh-test
python3 verify_session.py /tmp/cc2dsh-test

The full end-to-end flow (delete → restart to take effect → re-import → attach → titles restored) has been verified against real sessions.

License

MIT

项目文件与信号

以下项目是目录快照中检测到的公开仓库信号。

文档已检测

仓库信息

开发语言
Python
许可证
未提供
最后更新
2026年8月14日 09:26

谨慎安装

请检查源代码、权限、生命周期脚本、依赖与网络访问;不受信任的插件应先在隔离环境中测试。