dsh-thinking-language-zh
ayanJava111
deepseek harness思考过程中文插件
PROJECT TOPICS
PROJECT README
English | 中文
Import chat history and memory from other AI agents into DeepSeek Harness.
Switching harnesses should not mean losing your context. dsh-migrate reads the transcripts and memory stores other agents leave on disk and writes them as native DeepSeek Harness session logs — searchable, inspectable in the Trajectory view, and resumable (--fork-style continue) as if they had been recorded by DSH itself.
It works two ways: a /migrate slash command inside DSH, and a standalone CLI (npx @ersss/dsh-migrate) that scans the whole machine and previews with a dry run before writing anything.
| Agent | Sessions | Memory |
|---|---|---|
| Claude Code | ~/.claude/projects/**.jsonl (text, thinking, tool_use/tool_result) |
~/.claude/CLAUDE.md, project memory/*.md |
| Codex CLI | ~/.codex/sessions/**/rollout-*.jsonl (messages, reasoning, function calls) |
~/.codex/AGENTS.md, instructions.md |
| Gemini CLI | ~/.gemini/tmp/**/chats/session-*.json (messages, thoughts, toolCalls) |
~/.gemini/GEMINI.md |
| Cursor | ~/.cursor/projects/*/agent-transcripts/*/*.jsonl (text, tool_use; results live in Cursor's bubble store and are not recorded) |
— |
| Kimi CLI | ~/.kimi/sessions/*/*/wire.jsonl (text, thinking, tool calls; cwd recovered via kimi.json) |
— |
| ChatGPT (web export) | conversations.json from the data export (DAG-mapped threads; tool messages folded to text) |
— |
| Cline / Roo Code | VS Code globalStorage/*/tasks/*/api_conversation_history.json |
— |
| OpenCode | ~/.local/share/opencode/** message/part JSON files |
— |
| Aider | **/.aider.chat.history.md (bounded scan) |
CONVENTIONS.md files |
| Hermes Agent | ~/.hermes/state.db (SQLite sessions+messages, read-only) |
~/.hermes/memories/MEMORY.md, USER.md |
| OpenClaw | ~/.openclaw/agents/*/agent/openclaw-agent.sqlite (transcript_events, read-only) |
workspace MEMORY.md, memory/*.md |
Every adapter is tolerant: malformed lines and unknown row types are skipped, never fatal. Missing fields degrade gracefully (unknown model → imported, unknown cwd → the _no-cwd project).
# 1. Install the plugin into your DSH web profile
dsh plugin --profile web add @ersss/dsh-migrate
# 2. Restart DSH
dsh web
The package declares a dsh.bundle patch layer, so installing it does two things at once:
/migrate slash command, and$DSH_HOME/sessions-imported in raw-JSONL mode — a dedicated root for imported logs that never mixes with the default store's encoding.Heads-up: the bundled patch relocates the default session root, which means sessions you recorded before installing the plugin stay in the old
sessions/root and stop being listed. If you have existing DSH sessions you still want listed, either merge the patch's two rows into$DSH_HOME/profiles/web/cordis.patch.ymland keep both roots by alternating--patch, or simply run the CLI with--outpointed at your live root (raw JSONL reads fine under a zstd root only if the root was created withcompression: 'none'). Fresh installs are unaffected.
From inside DSH (Web UI, TUI, headless):
/migrate list # show what each agent has on disk
/migrate run # import everything
/migrate run --source claude-code --limit 10
From a terminal, without DSH running (also the right choice for big archives):
npx @ersss/dsh-migrate list
npx @ersss/dsh-migrate run # → $DSH_HOME/sessions-imported
npx @ersss/dsh-migrate run --out /path/to/root # anywhere you like
npx @ersss/dsh-migrate run --write-instructions . # also fold memory into ./AGENTS.md
Imported sessions appear in the sidebar grouped by their original project directory, and in the Trajectory view with their full event stream — prompts, reasoning, tool calls, and results.
DSH's session log is an append-only JSONL event stream (SESSION_FORMAT_VERSION 0). For every source session, dsh-migrate writes one log:
$DSH_HOME/sessions-imported/--<project>--/<id>/session.jsonl
{"type":"session","version":0,"id":"…","createdAt":…,"delegationDepth":0,"cwd":"…"}
{"type":"turn/start","seq":0,"time":…,"data":{"turn":1}}
{"type":"user/message","seq":1,…,"data":{"role":"user","source":{"kind":"user","via":"dsh-migrate:claude-code"},"content":[{"type":"text","text":"…"}]},"surfaceOp":"append"}
{"type":"step/start",…} {"type":"assistant/message",…} {"type":"tool/call",…} {"type":"tool/result",…} {"type":"step/end",…}
{"type":"turn/end",…,"data":{"turn":1,"reason":{"kind":"completed"}}}
…
{"type":"session/end-seed",…} ← marks the log as imported seed history
Mapping decisions, briefly:
turn/start…turn/end bracket. Tool-result-only user rows (Claude Code, Cline) attach to the pending tool/call instead of opening a turn.user/message events; assistant text/reasoning/tool-calls become one assistant/message per step; tool results become tool/result paired by call id.provider: "dsh-migrate:anthropic", model: "claude-fable-5"). Imported user messages are kind: "user" — required for the trajectory view and history derivation — with the importer declared on the merge-extensible via channel (via: "dsh-migrate:claude-code").importedSource / importedSourceId, so imported sessions are filterable without walking the event stream.--write-instructions <project> additionally folds them into that project's AGENTS.md between <!-- dsh-migrate … --> markers (idempotent re-runs).wx (no overwrite). A colliding id is retried with a fresh one; existing logs are never modified.The trailing session/end-seed event makes the whole imported log seed history: when you continue an imported session, DSH replays the log as inherited context, then starts a clean live segment — the model sees the prior conversation exactly as DSH would have logged it. The agent preset and tools of the current runtime apply; tools the old agent had and DSH does not simply become history.
SubagentEvent are skipped (import subagents/<id>/wire.jsonl directly if you want them).mode=ro&immutable=1), so a running Hermes/OpenClaw gateway is never disturbed. OpenClaw imports every session_window; resets/rollover windows appear as separate sessions (they were separate transcripts upstream too).$DSH_MIGRATE_SCAN (path-list), ~/projects, ~/code, ~/dev, ~/work, and a shallow $HOME sweep — its history files live inside projects, so a fixed home-relative path cannot find them.npm install
npm run build # tsc → dist/
npm test # fixture-driven end-to-end tests (real DSH codec replay)
The test suite replays produced logs through the actual @deepseek-ai/dsh-session codec (decodeStorageRecord + foldSurface) vendored from a live DSH profile, so format regressions fail loudly.
One adapter = one file in src/formats/ implementing:
interface SourceAdapter {
key: string
label: string
detect(home: string): Promise<DiscoveredSource | undefined>
readSessions(home: string, options?: { limit?: number }): Promise<IrSession[]>
readMemories(home: string): Promise<IrMemory[]>
}
Register it in src/formats/index.ts and add a fixture test. See src/formats/claude-code.ts for the reference implementation.
MIT
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。