๐Ÿšš dsh-claude-move

August 30, 2026 ยท View on GitHub

๐Ÿšš dsh-claude-move

  • 1024 store channel: npm i -g dsh1024 once, then dsh1024 plugin --profile web add dsh-claude-move (counts toward the deepseek1024.com install ranking). Gitee

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 ยท เคนเคฟเคจเฅเคฆเฅ€


Compatibility

  • Targets dsh 0.1.1-rc.2 (web profile); peer dependencies require >=0.1.0-rc.8 <0.2.0. 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)

SurfaceUsedFallback when absent
Host services (tools / sessionPersistence / workspaceRegistry / commands / systemPrompt / skills / webServer)required where listedoptional services register reactively; missing fs fails loud
sessionPersistence.listSnapshots / readFrom / streamText-capable fs / ctx.jobs / ctx.agents.resumefeature-detectedlist() / whole-file read with loud rejection / own job map / handoff inject
Client shell services (sessions.refresh/open, workspaces.refresh)feature-detected at panel applyfull-page reload
Newer platform capabilities are never hard requirements โ€” the plugin stays bootable on rc.8.

What you get

  1. Auto-discovery โ€” 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).
  2. Full-fidelity import โ€” 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.
  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, /claude-export, and a floating migration panel.
  8. Bidirectional export โ€” 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.

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

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.

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.

KeyDefaultMeaning
claudeHome$CLAUDE_CONFIG_DIR or ~/.claudeClaude data root
workspaceModeclaudecodeclaudecode (one dedicated workspace) ยท per-project (one workspace per source cwd)
claudecodeDir$DSH_HOME/claudecodeThe claudecode workspace folder (the only folder the plugin ever creates)
scanGittrueGit probe level: true (full) ยท 'branch' (zero git calls) ยท false
gitTimeoutMs5000Git subprocess timeout
scanConcurrency8Parallel project scan cap
maxTranscriptBytes67108864Stream-import threshold (chunked above)
excludeProjects[]Slug substrings to skip
enableMemorytrueInject memories as a live prompt section
memoryMaxBytes8192Memory section cap
memoryScopecurrent-projectcurrent-project ยท all (current first)
enableSkillstrueRegister Claude skills as DSH skills
maxSkills30Skill count cap
extraSkillDirs[]Extra skill directories
enableInstructionstrueInject global + project CLAUDE.md
resumeMaxChars2048Handoff summary char cap
resumeModeinjectinject (handoff summary) ยท agents (ctx.agents.resume)
enableWebPaneltrueRegister the /api/claude-move/* panel routes
importConcurrency4Parallel read+convert per batch
requireApprovaltrueWizard writes ask ctx.approval (allowed-once only)
codexHome$CODEX_HOME or ~/.codexCodex data root
opencodeDataHomeplatform XDG data dir/opencodeOpenCode data root
opencodeConfigHomeplatform XDG config dir/opencodeOpenCode config root
hermesHome$HERMES_HOME or ~/.hermesHermes data root
skillsDir$DSH_HOME/skillsWizard skill target
agentsMdPath$DSH_HOME/AGENTS.mdWizard memory/instruction target
moveWorkspaceModeper-sourceper-source ยท single workspace grouping for wizard imports
enableExporttrueRegister the claude_export tool and /claude-export command
exportDir$DSH_HOME/claude-exportDefault export folder (explicit path always wins)

Tools & surfaces

SurfaceKindNotes
claude_scantoolStructured index of projects/sessions/memories/skills/settings
import_claudetoolImport one session, a directory, or all (incremental, force for a fresh copy)
claude_exporttoolExport a DSH session to a resumable Claude Code JSONL transcript
move_detect / move_preview / move_runtoolsFour-source wizard: scan, per-item plan with diffs, execute behind approval
/claude-import-allcommandScan โ†’ import everything โ†’ report
/resume-claudecommandContinue a Claude session (latest, id, or keyword)
/claude-move-resetcommandReset the plugin cache (imported sessions kept)
/claude-exportcommandExport a DSH session to a resumable Claude JSONL transcript
/movecommandOne-shot four-source wizard
Web migration panelclientFloating 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/, the claudecode workspace folder, and exported .jsonl files under $DSH_HOME/claude-export/ (or an explicit target path).
  • 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 only โ€” sessionPersistence / 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 tools' descriptions/schemas and their outputs: 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.
  • 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.8, @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 33 DeepSeek Harness plugins maintained by PerryLink. If this one helps you, the others likely will too:

PluginOne-liner
dsh-dsh-auto-reviewSecond-model auto-review on the approval chain, fail-closed by default
dsh-dsh-background-agentsDurable background child agents with a Web UI sidebar, messaging and interrupt
dsh-dsh-budgetCost governance for DeepSeek Harness: budgets, carbon, and latency in one panel.
dsh-dsh-checkpoint-rewindClaude Code /rewind-equivalent: snapshots, session forks, one-shot restore
dsh-dsh-clickCross-platform native desktop control for DeepSeek Harness โ€” Windows first.
dsh-dsh-composer-historyTerminal-style input history for the web composer: arrows, Ctrl+R search
dsh-dsh-data-qualityDataset quality checks and citation cross-checks (the optional numeric bridge consumed here)
dsh-dsh-defendPrompt-injection, jailbreak, and secret-leak defense for DeepSeek Harness.
dsh-dsh-doublecheckEngineering-discipline guard: requirements grill, test gates, adversary review
dsh-dsh-drawUnified static-image generation routing for DeepSeek Harness.
dsh-dsh-fastRead-only performance diagnostics for DeepSeek Harness.
dsh-dsh-fund-researchDeterministic research reports for Chinese public mutual funds
dsh-dsh-githubGitHub PR/issues integration for DSH, every write gated by approval
dsh-dsh-industry-researchIndustry research orchestration that seals its deliverables through this plugin's ctx.researchReport.assemble
dsh-dsh-libraryLocal document knowledge base for DeepSeek Harness.
dsh-dsh-local-aiLocal-model (Ollama) integration for DeepSeek Harness.
dsh-dsh-lsp-actionsLSP diagnostics, formatting, completion, code actions and rename over language servers
dsh-dsh-maskPII masking middleware: anonymize at the model boundary, restore at the display layer
dsh-dsh-mcp-panelRead-only MCP runtime panel: /mcp command + Settings tab with status, tools and errors
dsh-dsh-mementoApproval-gated cross-session memory: ctx.memory seam + SQLite + memory tool
dsh-dsh-observeOpenTelemetry and Langfuse observability exporter for DeepSeek Harness.
dsh-dsh-output-stylesClaude Code outputStyles-equivalent runtime style switching
dsh-dsh-permission-rulesClaude Code-style declarative allow/deny/ask permission rules with audit
dsh-dsh-plugin-guidePlugin-development knowledge base as an on-demand agent skill
dsh-dsh-research-reportVerifiable research-report engine: content-addressed evidence ledger and sealed versions
dsh-dsh-scoreMulti-dimensional quality scoring for DeepSeek Harness plugins.
dsh-dsh-session-pinPin sessions in the Web sidebar with durable ordering
dsh-dsh-session-syncCross-device session sync for DeepSeek Harness โ€” a dedicated git mirror of your session store.
dsh-dsh-skill-pack-securitySecurity-audit skill pack: secret scan, dependency and supply-chain review
dsh-dsh-talkVoice-first session loop for DeepSeek Harness: talk to it, hear it answer.
dsh-dsh-test-driveIsolated install-and-smoke test drives for DeepSeek Harness plugins.
dsh-dsh-translateVendor parameter translation and deterministic JSON repair for DeepSeek Harness.

License

Apache License 2.0 ยฉ 2026 dsh-claude-move contributors