Four-source migration wizard for DeepSeek Harness: move Claude Code, Codex, OpenCode and Hermes sessions, memories, skills, instructions and slash commands into DSH (/move wizard + resumable sessions, approval-gated, idempotent).
在 DeepSeek Harness 终端运行:
dsh plugin --profile web add perrylink/dsh-claude-movenpm i -g dsh1024 once, then dsh1024 plugin --profile web add dsh-claude-move (counts toward the deepseek1024.com install ranking).Migrate Claude Code, Codex, OpenCode and Hermes into DeepSeek Harness — copy sessions, memories, skills, instructions and slash commands as resumable DSH sessions, copy-only and approval-gated.
Keep your Claude Code history when you move: one install, resumable sessions, live sync with a running Claude Code, and a four-source migration wizard.
dsh 0.1.5-rc.1 (web profile, session format V3); peer dependencies require >=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0. Verified against dsh-v0.1.5-rc.1 on 2026-09-10. Node ^22.19 || >=24.0.1.2-rc.1 (adapted 2026-09-04): the session envelope keeps its ignorable field for stored-log read compatibility only - Session.append still cannot stamp it, so audit-gate behavior is unchanged.sessionPersistence runtime shim, feature-detected by API shape (never by version): the legacy API (create/append/readFrom, list() returning headers) and the handle seam (create returning a SessionHandle, list()/stat() returning snapshots) both work. The handle seam is published on the alpha line (@deepseek-ai/dsh-session-persistence / -jsonl 0.1.5-rc.1), so the compat workflow covers it. On the handle path every append is followed by flush() (durability barrier) and a paired close() (single-writer ownership); headers are stamped with the backend's current format version plus an explicit isSeeded; missing assistant model sources fall back to the provider; and since 0.4.5 synthesized assistant/message events carry stream: [] when the backend format version is >= 2 — V3's Session.fromRestore asserts Array.isArray(data.stream), so without it a log was written and readable but could not be resumed. Import-scan cleanup refuses to run when a listed element's header.id cannot be resolved, so imports.json is never silently cleared.dsh <= 0.1.2-rc.1 (upgrading is one-way; re-import from the source transcript is the fallback).| Surface | Used | Fallback when absent |
|---|---|---|
Host services (tools / sessionPersistence / workspaceRegistry / commands / systemPrompt / skills / webServer) |
required where listed | optional services register reactively; missing fs fails loud |
sessionPersistence dual baseline: legacy listSnapshots / readFrom / append vs handle open / stat / snapshot list() |
feature-detected at runtime (API shape, never version) | the header.id resolution guard aborts the scan loudly instead of silently clearing imports.json |
streamText-capable fs / ctx.jobs / ctx.agents.resume |
feature-detected | whole-file read with loud rejection / own job map / handoff inject |
Client shell services (sessions.refresh/open, workspaces.refresh) |
feature-detected at panel apply | full-page reload |
Newer platform capabilities are never hard requirements — the plugin stays bootable on the oldest supported line (0.1.2-rc.1). |
claude_scan locates the Claude data root ($CLAUDE_CONFIG_DIR, fallback ~/.claude) and indexes every project/session, memory, skill, global CLAUDE.md and settings.json, with incremental caching and parallel scanning (scanConcurrency).import_claude turns transcripts into balanced, resumable DSH sessions (turn/start → step/start → user/message → assistant/message → tool/call → tool/result → step/end → turn/end), repairs interrupted tool calls, and stream-imports transcripts larger than maxTranscriptBytes in chunks.claudecode workspace — every imported session lands in a dedicated workspace (default $DSH_HOME/claudecode); workspaceMode: 'per-project' restores one-workspace-per-project grouping.force: true saves an extra full copy under a new id).CLAUDE.md injected early./move plus move_detect / move_preview / move_run migrate Claude Code, Codex, OpenCode and Hermes, approval-gated and idempotent (move.json)./claude-import-all, /resume-claude, /claude-move-reset, /claude-export, and a floating migration panel.claude_export (or /claude-export <sessionId>) writes a DSH session back out as a resumable Claude Code JSONL transcript (user/assistant/tool turns, thinking + tool_use/tool_result pairing, best-effort cwd mapping), so history can leave DSH again./move # one-shot wizard: detect → preview → execute → report (all four sources)
move_detect # scan Claude Code / Codex / OpenCode / Hermes
move_preview # per-item plan: new | unchanged | changed | conflict (with diff) | unsupported
move_run # execute behind the approval gate; conflict resolution:
# skip | overwrite | rename | merge (default skip — never guesses)
~/.claude), Codex (~/.codex), OpenCode (data + config roots), Hermes (skills/memory roots); each source has its own parser + mapper.AGENTS.md (one marked section per item); skills → real DSH skills (SKILL.md bundles copied verbatim, other formats converted); slash commands → registered DSH commands (rebuilt from move.json after a restart); sessions → resumable DSH sessions (the same importers as phase 1).$DSH_HOME/claude-move/move.json (digest / targetDigest / appliedAt); re-runs skip unchanged items and force re-applies them.ctx.approval first; anything but allowed-once means zero writes.# 1. install the bundle into your profile
dsh plugin --profile web add "github:PerryLink/dsh-claude-move#master"
# or from npm (published releases)
dsh plugin --profile web add dsh-claude-move
# 2. restart and verify the row
dsh --profile web --dump-config | grep -A4 'id: claude-move'
Then, in any DSH session, run one command:
/claude-import-all # scan → copy every Claude session → report
No DSH restart is needed after importing — refresh the open Web page once and click any imported session to continue.
master): dsh plugin --profile web add "github:PerryLink/dsh-claude-move#master" — pure ESM, no prepare or allowBuilds step.dsh plugin --profile web add dsh-claude-move.npm pack in this repo, then dsh plugin --profile web add ./dsh-claude-move-<version>.tgz.claude-move row from the profile's bundles and restart dsh. Imported sessions stay in DSH's data directory; the plugin only writes its cache ($DSH_HOME/claude-move/) and the claudecode workspace folder, and never touches Claude source data.~/.claude (read-only)
├─ projects/*/*.jsonl ──→ resumable DSH sessions, grouped in one "claudecode" workspace (default)
├─ projects/*/memory/ ──→ live system-prompt memory section (re-read per request)
├─ skills/** ──→ real DSH skills
└─ CLAUDE.md + settings ──→ early prompt section + config suggestions (never auto-applied)
| In Claude Code | Lands in DSH as |
|---|---|
Session transcripts (projects/*/*.jsonl) |
Balanced, resumable DSH sessions — full-fidelity user/assistant/tool/thinking mapping with interrupted-tool-call repair — grouped into one claudecode workspace or one per project |
Memory files (projects/*/memory/*.md) |
A live system-prompt context section, re-read on every request (feedback > project > reference > user) |
Skills (~/.claude/skills/**) |
Real DSH skills (kebab-case names, collision suffixes, max 30 by default; README.md/MEMORY.md and files without a description are skipped) |
CLAUDE.md (global + per-project) |
An early prompt section; the project file wins |
settings.json |
DSH configuration suggestions with an explicit unmappable-keys list |
| Project state (directory, git branch & dirty count) | Shown in the scan index, the Web panel badges, and the /resume-claude handoff |
Call the tools in any session with the plugin mounted:
claude_scan # full scan (incremental cache)
claude_scan { path: "~/.claude/projects/<slug>" } # partial scan
claude_scan { refresh: true } # skip cache, rescan everything
claude_scan { projectsLimit: 10, sessionsLimit: 5, fields: "brief" } # trim output
import_claude { path: "~/.claude/projects/<slug>/<sessionId>.jsonl" } # one session
import_claude { path: "~/.claude/projects" } # directory (recursive)
import_claude { path: "all" } # everything
# Re-run any time: unchanged files are skipped, grown transcripts append only the new turns.
# Files over maxTranscriptBytes are stream-imported in chunks (no memory ceiling).
import_claude { path: "...", force: true } # fresh full copy (previous copy kept)
claude_export { sessionId: "<dsh-session-id>" } # write a DSH session back to Claude JSONL
claude_export { sessionId: "...", path: "~/.claude/projects/<slug>/<id>.jsonl" } # explicit target
Commands (user-triggered, no model turn):
/claude-import-all # one-shot: scan → import everything → report → inject into the current session
/resume-claude latest # continue the most recent Claude session
/resume-claude <sessionId> # by source session id or import-<src> id
/resume-claude <keyword> # match titles; multiple matches are listed, never guessed
/claude-move-reset # reset the plugin cache (bookmarks + import map); imported sessions are kept
/claude-export <sessionId> [path] # export a DSH session to a resumable Claude JSONL transcript
Web panel: a floating migration panel with the project/session tree, status badges (not imported / imported / imported-with-new-turns / source missing / directory missing / git dirty), keyword filter, paged rendering, per-session "Import & continue" + "Open session" + "Refresh session list", batch import with a live progress bar and cancel, and a cache-reset button. Texts follow the browser language (zh/en). Served through the plugin's own /api/claude-move/* JSON routes on the public ctx.webServer seam.
You do not need to restart DSH. Imports land durably through the public sessionPersistence service the moment they complete:
session.list / workspace.list RPCs, the CLI, any new page load) show the imported sessions under the claudecode workspace immediately./resume-claude, or click the session in the list. Re-running the import at any time syncs only the new turns into the same sessions.All optional, overridable in cordis.yml.
| Key | Default | Meaning |
|---|---|---|
claudeHome |
$CLAUDE_CONFIG_DIR or ~/.claude |
Claude data root |
workspaceMode |
claudecode |
claudecode (one dedicated workspace) · per-project (one workspace per source cwd) |
claudecodeDir |
$DSH_HOME/claudecode |
The claudecode workspace folder (the only folder the plugin ever creates) |
scanGit |
true |
Git probe level: true (full) · 'branch' (zero git calls) · false |
gitTimeoutMs |
5000 |
Git subprocess timeout |
scanConcurrency |
8 |
Parallel project scan cap |
maxTranscriptBytes |
67108864 |
Stream-import threshold (chunked above) |
excludeProjects |
[] |
Slug substrings to skip |
enableMemory |
true |
Inject memories as a live prompt section |
memoryMaxBytes |
8192 |
Memory section cap |
memoryScope |
current-project |
current-project · all (current first) |
enableSkills |
true |
Register Claude skills as DSH skills |
maxSkills |
30 |
Skill count cap |
extraSkillDirs |
[] |
Extra skill directories |
enableInstructions |
true |
Inject global + project CLAUDE.md |
resumeMaxChars |
2048 |
Handoff summary char cap |
resumeMode |
inject |
inject (handoff summary) · agents (ctx.agents.resume) |
enableWebPanel |
true |
Register the /api/claude-move/* panel routes |
importConcurrency |
4 |
Parallel read+convert per batch |
requireApproval |
true |
Wizard writes ask ctx.approval (allowed-once only) |
codexHome |
$CODEX_HOME or ~/.codex |
Codex data root |
opencodeDataHome |
platform XDG data dir/opencode | OpenCode data root |
opencodeConfigHome |
platform XDG config dir/opencode | OpenCode config root |
hermesHome |
$HERMES_HOME or ~/.hermes |
Hermes data root |
skillsDir |
$DSH_HOME/skills |
Wizard skill target |
agentsMdPath |
$DSH_HOME/AGENTS.md |
Wizard memory/instruction target |
moveWorkspaceMode |
per-source |
per-source · single workspace grouping for wizard imports |
enableExport |
true |
Register the claude_export tool and /claude-export command |
exportDir |
$DSH_HOME/claude-export |
Default export folder (explicit path always wins) |
| Surface | Kind | Notes |
|---|---|---|
claude_scan |
tool | Structured index of projects/sessions/memories/skills/settings |
import_claude |
tool | Import one session, a directory, or all (incremental, force for a fresh copy) |
claude_export |
tool | Export a DSH session to a resumable Claude Code JSONL transcript |
move_detect / move_preview / move_run |
tools | Four-source wizard: scan, per-item plan with diffs, execute behind approval |
/claude-import-all |
command | Scan → import everything → report |
/resume-claude |
command | Continue a Claude session (latest, id, or keyword) |
/claude-move-reset |
command | Reset the plugin cache (imported sessions kept) |
/claude-export |
command | Export a DSH session to a resumable Claude JSONL transcript |
/move |
command | One-shot four-source wizard |
| Web migration panel | client | Floating panel with progress, cancel, paging, open session |
filesystem:read and filesystem:write.~/.claude (transcripts, memories, skills, CLAUDE.md, settings.json) — strictly read-only — and the project directories it imports into.sessionPersistence service (create + append only, never delete/rewrite/archive), workspace-registry records, its cache under $DSH_HOME/claude-move/, the claudecode workspace folder, and exported .jsonl files under $DSH_HOME/claude-export/ (or an explicit target path).create + append only).sessionPersistence / workspaceRegistry / tools / commands / systemPrompt / skills / webServer; no engine or UI changes.permission/permission-mode/queue-operation records are counted, not imported.allowed-once means zero writes.custom-title/ai-title/first prompt; Claude summary records are reported but not mapped to DSH compaction nodes (synthesizing a valid compaction transaction would fabricate its seq range and checkpoint message).thinking blocks are kept as reasoning content but never enter the resume handoff.repaired.synthesized.fs.streamText surface, transcripts larger than maxTranscriptBytes fail loudly instead of partial import.workspaceMode: 'per-project', sessions whose source directory was deleted still import, but workspace attach fails (left ungrouped; workspace.attached: false plus a reason). The default claudecode workspace does not depend on the source directory.sourceShrunk; use force: true for a fresh full copy.claude_scan returns the structured index, import_claude returns per-file summaries with positions of warnings, and claude_export returns the export summary (target path + turn/message/tool counts). Tool results are themselves logged tool/result events, so everything is reconstructable.CLAUDE.md sections are registered on ctx.systemPrompt (prompt assembly, rebuildable from the session log).dsh --profile <p> --dump-config should print # == dsh-claude-move; re-run dsh plugin --profile <p> add ....dsh plugin add contain only dsh-base — add @deepseek-ai/dsh-web-app to dsh.profile.bundles. Installing into the existing web profile needs nothing.enableWebPanel: true and a web server is composed; check the boot log for FAILED fibers.maxTranscriptBytes or import that file individually.dsh console; the plugin logs [claude-move]-prefixed errors for workspace/import-map issues.This project is licensed under the Apache License 2.0; the following MIT-licensed components retain their own licenses (full text in THIRD_PARTY_NOTICES.md):
npm install # peer deps: @deepseek-ai/dsh-tools@>=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0, @deepseek-ai/cordis, schemastery
npm test # node --test test/*.test.mjs
CI runs the full suite on Node 22 across Linux/macOS/Windows via GitHub Actions (test.yml).
deepseek-harness, dsh-plugin, claude-code, migration, session-import, resume
README.md (and any description-less .md) being misregistered as a skill, which broke DSH's skill load.This project is one of the 37 DeepSeek Harness plugins maintained by PerryLink. If this one helps you, the others likely will too:
| Plugin | One-liner |
|---|---|
| dsh-auto-review | Second-model auto-review on the approval chain, fail-closed by default |
| dsh-background-agents | Durable background child agents with a Web UI sidebar, messaging and interrupt |
| dsh-budget | Cost governance for DeepSeek Harness: budgets, carbon, and latency in one panel. |
| dsh-checkpoint-rewind | Claude Code /rewind-equivalent: snapshots, session forks, one-shot restore |
| dsh-click | Cross-platform native desktop control for DeepSeek Harness — Windows first. |
| dsh-composer-history | Terminal-style input history for the web composer: arrows, Ctrl+R search |
| dsh-data-quality | Dataset quality checks and citation cross-checks (the optional numeric bridge consumed here) |
| dsh-defend | Prompt-injection, jailbreak, and secret-leak defense for DeepSeek Harness. |
| dsh-doublecheck | Engineering-discipline guard: requirements grill, test gates, adversary review |
| dsh-draw | Unified static-image generation routing for DeepSeek Harness. |
| dsh-fast | Read-only performance diagnostics for DeepSeek Harness. |
| dsh-fund-research | Deterministic research reports for Chinese public mutual funds |
| dsh-github | GitHub PR/issues integration for DSH, every write gated by approval |
| dsh-industry-research | Industry research orchestration that seals its deliverables through this plugin's ctx.researchReport.assemble |
| dsh-library | Local document knowledge base for DeepSeek Harness. |
| dsh-local-ai | Local-model (Ollama) integration for DeepSeek Harness. |
| dsh-lsp-actions | LSP diagnostics, formatting, completion, code actions and rename over language servers |
| dsh-mask | PII masking middleware: anonymize at the model boundary, restore at the display layer |
| dsh-mcp-panel | Read-only MCP runtime panel: /mcp command + Settings tab with status, tools and errors |
| dsh-memento | Approval-gated cross-session memory: ctx.memory seam + SQLite + memory tool |
| dsh-observe | OpenTelemetry and Langfuse observability exporter for DeepSeek Harness. |
| dsh-output-styles | Claude Code outputStyles-equivalent runtime style switching |
| dsh-reach | Multi-channel approval/question bridge: WeChat/Telegram/Feishu, session console |
| dsh-permission-rules | Claude Code-style declarative allow/deny/ask permission rules with audit |
| dsh-personal-directive | Personal directive injector with top-bar toggle (framework edition) |
| dsh-plugin-guide | Plugin-development knowledge base as an on-demand agent skill |
| dsh-research-report | Verifiable research-report engine: content-addressed evidence ledger and sealed versions |
| dsh-score | Multi-dimensional quality scoring for DeepSeek Harness plugins. |
| dsh-session-pin | Pin sessions in the Web sidebar with durable ordering |
| dsh-session-sync | Cross-device session sync for DeepSeek Harness — a dedicated git mirror of your session store. |
| dsh-skill-pack-security | Security-audit skill pack: secret scan, dependency and supply-chain review |
| dsh-talk | Voice-first session loop for DeepSeek Harness: talk to it, hear it answer. |
| dsh-test-drive | Isolated install-and-smoke test drives for DeepSeek Harness plugins. |
| dsh-ticktick | TickTick/Dida365 task bridge: session-header panel + 11 tools |
| dsh-translate | Vendor parameter translation and deterministic JSON repair for DeepSeek Harness. |
| dsh-wechat | WeChat ↔ DSH bridge (Tencent iLink bot): text/image/file/voice, approvals in chat |
All PerryLink plugins are browsable in the built-in DSH Desktop Market: Market → Sources → add source → paste https://perrylink-dsh-catalog.perrylink.workers.dev/catalog-source.json → select it. Installation still goes through the Market's npm-identity verification and your confirmation.
Apache License 2.0 © 2026 dsh-claude-move contributors
登录后即可为该插件评分和评价。
还没有人评价这个插件,来抢个沙发吧!