OpenViking
volcengine
Self-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills.
PROJECT TOPICS
INSTALL REFERENCE
dsh plugin --profile web add github:Seafood-Y/CC2DSH
该命令指向仓库当前默认分支;尚无绑定当前 commit 的完整验证结果。
PROJECT README
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.
turn/end with reason: event content passes DSH's content-level validationai-title from Claude
records into a session/title event; the title projection is restored on attachcwd, sessions land in
their original project directories--cwd-map OLD=NEW fixes projects that were
renamed or moved after the session was recordedverify_session.py gates imports so one bad file can
never take down the whole session list# 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.
# 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
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.
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:
workspace.create(path=cwd) — create if missing, reuse if present;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 webservice first, then run this script.
DSH session files have strict format requirements, and naively compressing the
whole JSONL with single-frame zstd breaks them:
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.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.
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.
| Symptom | Cause | Fix |
|---|---|---|
| Session list empty after refresh | One malformed session file makes session.list throw |
Locate with verify_session.py; regenerate with this converter; restart service after fixing |
corrupt Zstandard session log: first frame is not exactly one header line |
Single-frame compression | Re-convert (multi-frame layout) |
malformed pre-react-loop turn/end at seq N |
turn/end missing reason |
Re-convert (already fixed) |
| Sessions under "Ungrouped" | Attach script not run / stale service state | node attach_to_workspace.mjs; restart service if needed |
| Title is workspace name or blank | No session/title event |
Sessions with no ai-title in source (command-only) keep no title, matching Claude |
workspace ... ENOENT |
cwd directory renamed/deleted |
Re-convert with --cwd-map OLD=NEW |
| File | Purpose |
|---|---|
convert_claude_to_dsh.py |
Converter: multi-frame zstd, turn/end reason, --cwd-map, title preservation |
verify_session.py |
Session format/content validator |
attach_to_workspace.mjs |
Workspace attach script (reuse/create by cwd, restore title projections) |
SKILL.md |
Skill documentation (full workflow + troubleshooting) |
testdata/ |
Session backups for regression 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.
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: claude-code、session-migration。