Back to directory

dsh-claude-move

Curated pick

perrylink/dsh-claude-move

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).

6

stars

1

forks

Apache-2.0

License

2026-08-13

Created

2026-08-16

Last push

README

<div align="center">

🚚 dsh-claude-move

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.

License DSH plugin Node CI Version npm version npm downloads

English · 简体中文 · Español · Português · हिन्दी

</div>


Compatibility

  • Targets dsh 0.1.0-rc.6 (web profile); peer dependencies pinned to 0.1.0-rc.6. Node ^22.19 || >=24.
  • Last verified against a fresh tarball install: real scan, real batch import (idempotent re-import), workspace attach and persistence artifacts confirmed; macOS/Linux covered by the CI matrix.

Compatibility matrix (public seams only)

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.listSnapshots / readFrom / streamText-capable fs / ctx.jobs / ctx.agents.resume feature-detected list() / 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 rc.6.

What you get

  1. Auto-discoveryclaude_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).
  2. Full-fidelity importimport_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.
  3. One claudecode workspace — every imported session lands in a dedicated workspace (default $DSH_HOME/claudecode); workspaceMode: 'per-project' restores one-workspace-per-project grouping.
  4. Copy-only & incremental — nothing on either side is moved, rewritten, or deleted; re-running appends only the new turns (force: true saves an extra full copy under a new id).
  5. Personal context, always fresh — memories injected as a live prompt section, Claude skills registered as real DSH skills (global + project-level), global + project CLAUDE.md injected early.
  6. Four-source migration wizard/move plus move_detect / move_preview / move_run migrate Claude Code, Codex, OpenCode and Hermes, approval-gated and idempotent (move.json).
  7. Web panel & commands/claude-import-all, /resume-claude, /claude-move-reset, and a floating migration panel.

Four-source migration wizard

/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)
  • Sources — Claude Code (~/.claude), Codex (~/.codex), OpenCode (data + config roots), Hermes (skills/memory roots); each source has its own parser + mapper.
  • Mapping — memories/instructions → append-only managed sections in the DSH global 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).
  • Idempotent — every applied plan is recorded in $DSH_HOME/claude-move/move.json (digest / targetDigest / appliedAt); re-runs skip unchanged items and force re-applies them.
  • Approval-gated — a run that would write anything asks ctx.approval first; anything but allowed-once means zero writes.

Quick start

# 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.

Install & uninstall

  • git channel (latest master): dsh plugin --profile web add "github:PerryLink/dsh-claude-move#master" — pure ESM, no prepare or allowBuilds step.
  • npm channel (published releases): dsh plugin --profile web add dsh-claude-move.
  • tarball channel: npm pack in this repo, then dsh plugin --profile web add ./dsh-claude-move-<version>.tgz.
  • uninstall: remove the 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.

What gets migrated

~/.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

Usage

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)

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

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.

After importing

You do not need to restart DSH. Imports land durably through the public sessionPersistence service the moment they complete:

  • The server-side lists (session.list / workspace.list RPCs, the CLI, any new page load) show the imported sessions under the claudecode workspace immediately.
  • The panel refreshes the already-open page's session list itself and offers an Open session button per imported session.
  • Imported sessions can be opened, read, and resumed right away — /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.

Configuration

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

Tools & surfaces

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)
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)
/move command One-shot four-source wizard
Web migration panel client Floating panel with progress, cancel, paging, open session

Permissions & data

  • Permissions: the workshop manifest declares filesystem:read and filesystem:write.
  • Reads ~/.claude (transcripts, memories, skills, CLAUDE.md, settings.json) — strictly read-only — and the project directories it imports into.
  • Writes DSH session logs via the public sessionPersistence service (create + append only, never delete/rewrite/archive), workspace-registry records, its cache under $DSH_HOME/claude-move/, and the claudecode workspace folder.
  • Never modifies Claude source files, touches other applications' data, or accesses the network. No credentials are read or transmitted.

Security boundaries

  • Source files are read-only; DSH logs are append-only (create + append only).
  • External transcripts are untrusted input — nothing in them is executed; system/developer/thinking content never enters the resume handoff.
  • Public services onlysessionPersistence / workspaceRegistry / tools / commands / systemPrompt / skills / webServer; no engine or UI changes.
  • Secrets reported by position only (file:line:kind); permission/permission-mode/queue-operation records are counted, not imported.
  • Wizard writes are approval-gated — anything but allowed-once means zero writes.

Known limitations

  • Titles come from 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.
  • Interrupted tool calls are repaired with a synthetic error result (never dropped), reported as repaired.synthesized.
  • Permission-class records are counted, not imported; DSH permission-preset suggestions are generated in reports.
  • On hosts without a streaming fs.streamText surface, transcripts larger than maxTranscriptBytes fail loudly instead of partial import.
  • In 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.
  • If a transcript was truncated or reset in place (fewer turns than the recorded import), re-import skips it and reports sourceShrunk; use force: true for a fresh full copy.
  • The Web panel is a zero-build floating panel driven by the plugin's own JSON routes; it does not use the shell's internal UI slot system.

Model Experience

  • The model-facing surface is the two tools' descriptions/schemas and their outputs: claude_scan returns the structured index, import_claude returns per-file summaries with positions of warnings. Tool results are themselves logged tool/result events, so everything is reconstructable.
  • No hidden model-facing text; memory/CLAUDE.md sections are registered on ctx.systemPrompt (prompt assembly, rebuildable from the session log).

Troubleshooting

  • Row not effective: dsh --profile <p> --dump-config should print # == dsh-claude-move; re-run dsh plugin --profile <p> add ....
  • Web boots but hangs silently: new profiles initialized by 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.
  • Panel routes 404: they are served only when enableWebPanel: true and a web server is composed; check the boot log for FAILED fibers.
  • Import fails with "transcript 过大": raise maxTranscriptBytes or import that file individually.
  • Import succeeded but the sidebar shows no new session: the page was already open — click the panel's refresh button (or reload the page) once. No DSH restart is ever needed.
  • Logs: boot failures print to the dsh console; the plugin logs [claude-move]-prefixed errors for workspace/import-map issues.

Attribution (open-source components)

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):

Development

npm install   # peer deps: @deepseek-ai/dsh-tools@0.1.0-rc.6, @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).

Topics

deepseek-harness, dsh-plugin, claude-code, migration, session-import, resume

Contributors

  • @PerryLink — creator and maintainer: the import pipeline, the four-source migration wizard, the Web panel, docs, CI/CD and releases.
  • @OLDnana1 — root-cause analysis of the interrupted tool-call corruption that made imported sessions permanently return HTTP 400 on resume.
  • @GooodWei — identified README.md (and any description-less .md) being misregistered as a skill, which broke DSH's skill load.

This project is one of the DeepSeek Harness plugins maintained by PerryLink. If this one helps you, the others likely will too:

Plugin One-liner
dsh-mcp-panel Read-only MCP runtime panel: /mcp command + Settings tab with status, tools and errors
dsh-doublecheck Engineering-discipline guard: requirements grill, test gates, adversary review
dsh-background-agents Durable background child agents with a Web UI sidebar, messaging and interrupt
dsh-lsp-actions LSP diagnostics, formatting, completion, code actions and rename over language servers
dsh-output-styles Claude Code outputStyles-equivalent runtime style switching
dsh-checkpoint-rewind Claude Code /rewind-equivalent: snapshots, session forks, one-shot restore
dsh-permission-rules Claude Code-style declarative allow/deny/ask permission rules with audit
dsh-auto-review Second-model auto-review on the approval chain, fail-closed by default
dsh-memento Approval-gated cross-session memory: ctx.memory seam + SQLite + memory tool
dsh-skill-pack-security Security-audit skill pack: secret scan, dependency and supply-chain review
dsh-session-pin Pin sessions in the Web sidebar with durable ordering
dsh-composer-history Terminal-style input history for the web composer: arrows, Ctrl+R search
dsh-github GitHub PR/issues integration for DSH, every write gated by approval
dsh-plugin-guide Plugin-development knowledge base as an on-demand agent skill
dsh-claude-move Migrate Claude Code sessions, memory, skills and CLAUDE.md into DSH

License

Apache License 2.0 © 2026 dsh-claude-move contributors

DSH Plugins is an independent community directory of DeepSeek Harness plugins. Not affiliated with or endorsed by DeepSeek. Third-party plugins are not security-audited — review the source before installing.