🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

四源会话迁移 PerryLink/dsh-claude-move

DeepSeek Harnessv0.4.18
PerryLink7 天前有提交已提供中文文档扫描:含敏感能力

DeepSeek Harness 四源迁移向导:把 Claude Code、Codex、OpenCode 和 Hermes 的会话、记忆、技能、指令和斜杠命令搬进 DSH(/move 向导 + 可续传会话,审批把关,幂等)。

45.8/100
综合分
29
GitHub 星标
722
npm 周下载
—/5
用户评分

数据截至 2026/10/27 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add dsh-claude-move
npm 源 · dsh-claude-move 的发布者账号已校验与本仓库一致

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · ui
装得上吗
本站已在 dsh 0.2.1-rc.2 下真实安装成功
非静态推断
L5 · 运行时冒烟等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 7 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查✓ 自动检查通过
展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✓npm 包dsh-claude-move @ 0.4.18
✓Node 引擎要求 ^22.19.0 || >=24.0.0 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/30 04:31:53

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件发起外部网络请求
查看扫描证据(共 89 处,展示前 65 条)
  • 读取本地文件
    index.mjs:467
    dirExists: typeof cwd === 'string' && existsSync(cwd),
  • 读取本地文件
    index.mjs:483
    index.claudeHomeExists = existsSync(claudeHome)
  • 读取本地文件
    index.mjs:555
    raw = await readFile(file, 'utf8')
  • 写入本地文件
    index.mjs:902
    await mkdir(dir, { recursive: true })
  • 写入本地文件
    index.mjs:933
    await mkdir(dir, { recursive: true })
  • 写入本地文件
    index.mjs:1909
    await mkdir(path.dirname(target), { recursive: true })
  • 写入本地文件
    index.mjs:1910
    await writeFile(target, result.lines.map((l) => l + '\n').join(''), 'utf8')
  • 读取本地文件
    index.mjs:2033
    const st = statSync(importsPath)
  • 读取本地文件
    index.mjs:2037
    const st = statSync(indexPath)
  • 读取本地文件
    index.mjs:2046
    const parsed = JSON.parse(readFileSync(importsPath, 'utf8'))
  • 写入本地文件
    index.mjs:2881
    await mkdir(path.dirname(p), { recursive: true })
  • 写入本地文件
    index.mjs:2882
    await writeFile(p, content, 'utf8')
  • 发起网络请求
    index.mjs:2961
    return await service.request({
  • 发起网络请求
    client/client.js:266
    const res = await fetch(url, options)
  • 读取本地文件
    lib/discovery.mjs:90
    const content = await readFile(file, 'utf8')
  • 读取本地文件
    lib/discovery.mjs:118
    entries = await readdir(skillsDir, { withFileTypes: true })
  • 读取本地文件
    lib/discovery.mjs:143
    const content = await readFile(file, 'utf8')
  • 读取本地文件
    lib/discovery.mjs:163
    const s = await stat(file)
  • 读取本地文件
    lib/discovery.mjs:182
    if (!existsSync(path.join(cwd, '.git'))) return null
  • 读取本地文件
    lib/discovery.mjs:214
    statResult = await stat(file)
  • 写入本地文件
    lib/discovery.mjs:552
    await mkdir(path.dirname(file), { recursive: true })
  • 写入本地文件
    lib/discovery.mjs:554
    await writeFile(tmp, JSON.stringify(value), 'utf8')
  • 写入本地文件
    lib/discovery.mjs:555
    await rename(tmp, file)
  • 删除本地文件
    lib/discovery.mjs:614
    await unlink(path.join(cacheDir, name))
  • 读取本地文件
    lib/context.mjs:57
    const st = statSync(file)
  • 读取本地文件
    lib/context.mjs:63
    const text = readFileSync(file, 'utf8')
  • 读取本地文件
    lib/context.mjs:83
    entries = readdirSync(dir)
  • 读取本地文件
    lib/context.mjs:155
    return typeof file === 'string' && file.length > 0 && existsSync(file)
  • 读取本地文件
    lib/skills-provider.mjs:55
    const content = await readFile(file, 'utf8')
  • 读取本地文件
    lib/skills-provider.mjs:89
    entries = await readdir(root, { withFileTypes: true })
  • 写入本地文件
    lib/manifest.mjs:19
    await mkdir(path.dirname(file), { recursive: true })
  • 写入本地文件
    lib/manifest.mjs:21
    await writeFile(tmp, JSON.stringify(value, null, 2), 'utf8')
  • 写入本地文件
    lib/manifest.mjs:22
    await rename(tmp, file)
  • 读取本地文件
    lib/manifest.mjs:32
    const raw = await readFile(manifestPath(cacheDir), 'utf8')
  • 读取本地文件
    lib/sources/claude/parser.mjs:44
    raw = await readFile(assertAllowedRead(whitelist(detection.home), file), 'utf8')
  • 读取本地文件
    lib/sources/claude/parser.mjs:126
    content = await readFile(assertAllowedRead(whitelist(home), memory.path), 'utf8')
  • 读取本地文件
    lib/sources/claude/parser.mjs:145
    content = await readFile(assertAllowedRead(whitelist(home), skill.path), 'utf8')
  • 读取本地文件
    lib/sources/claude/parser.mjs:167
    const content = await readFile(assertAllowedRead(whitelist(home), globalClaudeMd.path), 'utf8')
  • 读取本地文件
    lib/sources/claude/mapper.mjs:61
    const content = await readFile(memory.file, 'utf8')
  • 读取本地文件
    lib/sources/claude/mapper.mjs:79
    const content = await readFile(instruction.file, 'utf8')
  • 读取本地文件
    lib/sources/codex/parser.mjs:106
    await access(p)
  • 读取本地文件
    lib/sources/codex/parser.mjs:127
    const content = await readFile(abs, 'utf8')
  • 读取本地文件
    lib/sources/codex/parser.mjs:150
    const rl = createInterface({ input: createReadStream(abs), crlfDelay: Infinity })
  • 读取本地文件
    lib/sources/codex/parser.mjs:217
    entries = await readdir(assertAllowedRead(roots, dir), { recursive: true })
  • 读取本地文件
    lib/sources/codex/parser.mjs:242
    entries = await readdir(assertAllowedRead(roots, dir), { withFileTypes: true })
  • 读取本地文件
    lib/sources/codex/parser.mjs:274
    entries = await readdir(assertAllowedRead(roots, dir), { withFileTypes: true })
  • 读取本地文件
    lib/sources/codex/mapper.mjs:41
    return await readFile(assertAllowedRead(roots, file), 'utf8')
  • 读取本地文件
    lib/sources/opencode/parser.mjs:129
    names = (await readdir(sessionDir)).filter((n) => n.endsWith('.json'))
  • 读取本地文件
    lib/sources/opencode/parser.mjs:136
    const raw = await readFile(assertAllowedRead(whitelist(detection.home), path.join(sessionDir, name)), 'utf8')
  • 读取本地文件
    lib/sources/opencode/parser.mjs:149
    const entries = await readdir(assertAllowedRead(whitelist(detection.home), msgDir))
  • 读取本地文件
    lib/sources/opencode/parser.mjs:180
    detection.homeExists = existsSync(home) || existsSync(configHome)
  • 读取本地文件
    lib/sources/opencode/parser.mjs:185
    if (existsSync(dbPath)) {
  • 读取本地文件
    lib/sources/opencode/parser.mjs:196
    const entries = await readdir(assertAllowedRead(roots, agentDir), { withFileTypes: true })
  • 读取本地文件
    lib/sources/opencode/mapper.mjs:71
    const content = await readFile(command.file, 'utf8')
  • 读取本地文件
    lib/sources/opencode/mapper.mjs:86
    const content = await readFile(instruction.file, 'utf8')
  • 读取本地文件
    lib/sources/hermes/parser.mjs:53
    content = await readFile(assertAllowedRead(roots, file), { encoding: 'utf8', ...(signal ? { signal } : {}) })
  • 读取本地文件
    lib/sources/hermes/parser.mjs:81
    entries = await readdir(dir, { withFileTypes: true, ...(signal ? { signal } : {}) })
  • 读取本地文件
    lib/sources/hermes/parser.mjs:120
    content = await readFile(assertAllowedRead(roots, file), { encoding: 'utf8', ...(signal ? { signal } : {}) })
  • 读取本地文件
    lib/sources/hermes/parser.mjs:148
    detection.homeExists = existsSync(home)
  • 读取本地文件
    lib/sources/hermes/mapper.mjs:44
    const content = readFileSync(assertAllowedRead(roots, memory.file), 'utf8')
  • 读取本地文件
    lib/sources/opencode/convert.mjs:65
    session = JSON.parse(await readFile(sessionFile, 'utf8'))
  • 读取本地文件
    lib/sources/opencode/convert.mjs:72
    names = (await readdir(messageDir)).filter((n) => n.startsWith('msg_') && n.endsWith('.json')).sort()
  • 读取本地文件
    lib/sources/opencode/convert.mjs:78
    const msg = JSON.parse(await readFile(path.join(messageDir, name), 'utf8'))
  • 读取本地文件
    lib/sources/opencode/convert.mjs:83
    partNames = (await readdir(partDir)).filter((n) => n.startsWith('prt_') && n.endsWith('.json')).sort()
  • 读取本地文件
    lib/sources/opencode/convert.mjs:89
    parts.push(JSON.parse(await readFile(path.join(partDir, pn), 'utf8')))
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/cordis-plugin-include@deepseek-ai/cordis-plugin-loader@deepseek-ai/cosmokit@deepseek-ai/dsh-agent@deepseek-ai/dsh-attachment@deepseek-ai/dsh-brand@deepseek-ai/dsh-commands@deepseek-ai/dsh-invariants@deepseek-ai/dsh-llm@deepseek-ai/dsh-sandbox@deepseek-ai/dsh-scope
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

界面预览

2 张 · 点击查看大图

功能亮点

  • 迁移四源会话数据
  • 搬移记忆技能指令
  • 支持续传与审批

README

由 DeepSeek 最新模型翻译生成
🚚 dsh-claude-move - 1024 store channel:先执行一次 npm i -g dsh1024,再执行 dsh1024 plugin --profile web add dsh-claude-move(计入 deepseek1024.com 的安装排名)。 把 Claude Code、Codex、OpenCode 和 Hermes 迁移到 DeepSeek Harness —— 复制会话、记忆、技能、指令和斜杠命令,转成可恢复的 DSH 会话;只复制,且需审批。 迁移时保留 Claude Code 的历史:一次安装、会话可恢复、与运行中的 Claude Code 实时同步,还有四来源迁移向导。 dsh-doctor DSH Market English · 简体中文 · Español · Português · हिन्दी dsh plugin --profile <name> add dsh-claude-move dsh-claude-move 工作流示意图:调用 → 插件 → 结果。 工作流概览:调用 → 插件 → 结果。下面的示例都使用真实的命令接口。
展开完整文档(README 剩余 1 节)
🚚 dsh-claude-move

- 1024 store channel:先执行一次 npm i -g dsh1024,再执行 dsh1024 plugin --profile web add dsh-claude-move(计入 deepseek1024.com 的安装排名)。

把 Claude Code、Codex、OpenCode 和 Hermes 迁移到 DeepSeek Harness —— 复制会话、记忆、技能、指令和斜杠命令,转成可恢复的 DSH 会话;只复制,且需审批。

迁移时保留 Claude Code 的历史:一次安装、会话可恢复、与运行中的 Claude Code 实时同步,还有四来源迁移向导。

dsh-doctor
DSH Market

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

dsh plugin --profile <name> add dsh-claude-move

dsh-claude-move 工作流示意图:调用 → 插件 → 结果。

工作流概览:调用 → 插件 → 结果。下面的示例都使用真实的命令接口。

安装与卸载

- git 渠道(最新 master):dsh plugin --profile web add "github:PerryLink/dsh-claude-move#master" —— 纯 ESM,无需 prepare 或 allowBuilds 步骤。
- npm 渠道(已发布版本):dsh plugin --profile web add dsh-claude-move。
- tarball 渠道:在本仓库执行 npm pack,然后执行 dsh plugin --profile web add ./dsh-claude-move-<version>.tgz。
- 卸载:从配置档的 bundles 中删掉 claude-move 这一行,然后重启 dsh。导入的会话仍留在 DSH 的数据目录里;插件只写自己的缓存($DSH_HOME/claude-move/)和 claudecode 工作区文件夹,绝不碰 Claude 的源数据。

兼容性

- 目标版本 dsh 0.1.6-alpha.2(web 配置档,会话格式 V3);peer dependencies 和 engines.dsh 接受六条款区间,直到 >=0.2.1-0 <0.3.0;0.2.1 这条线静态兼容(没有记录运行时验证)。验证时间 2026-09-18(checkJs 类型门禁 + 287 条断言,38 个测试套件)。宿主没有暴露 sessions.open() 时,面板的「打开会话」按钮现在渲染为禁用状态并带说明性 title,不再直接消失。Node ^22.19 || >=24。
0.1.2-rc.1(适配于 2026-09-04):会话信封保留可忽略字段,只为兼容已存日志的读取——Session.append 仍然无法写入该字段,所以审计门禁行为不变。
- 0.4.0 提供双基线 sessionPersistence 运行时 shim,按 API 形状做特性检测(绝不按版本号):旧版 API(create/append/readFrom,list() 返回 headers)和 handle 接缝(create 返回 SessionHandle,list()/stat() 返回快照)都能工作。handle 接缝发布在 alpha 线(@deepseek-ai/dsh-session-persistence / -jsonl 0.1.5-rc.2),所以兼容工作流覆盖了它。走 handle 路径时,每次 append 之后都跟一次 flush()(持久化屏障)和配对的 close()(单写者所有权);headers 打上后端当前格式版本,外加显式的 isSeeded;缺少 assistant 模型来源时回退到服务商;从 0.4.5 起,后端格式版本 >= 2 时合成的 assistant/message 事件带 stream: []——V3 的 Session.fromRestore 会断言 Array.isArray(data.stream),没有它日志虽然写得出、读得回,却无法恢复。导入扫描清理时,只要列出的元素 header.id 解析不了就拒绝执行,所以 imports.json 绝不会被悄悄清空。
- 最近一次针对全新 tarball 安装的验证:真实扫描、真实批量导入(重复导入幂等)、工作区挂载和持久化产物均已确认;macOS/Linux 由 CI 矩阵覆盖。导入的日志使用会话格式 V3,dsh <= 0.1.2-rc.1 读不了(升级是单向的;回退办法是从源 transcript 重新导入)。

兼容性矩阵(仅公开接缝)

| 接口面 | 使用情况 | 缺失时的回退 |
| 宿主服务(tools / sessionPersistence / workspaceRegistry / commands / systemPrompt / skills / webServer) | 列出的位置为必需 | 可选服务按需注册;缺少 fs 直接报错 |
| sessionPersistence 双基线:旧版 listSnapshots / readFrom / append 对比句柄 open / stat / 快照 list() | 运行时探测特性(看 API 形态,绝不看版本号) | header.id 解析守卫会大声中止扫描,而不是悄悄清空 imports.json |
| 支持 streamText 的 fs / ctx.jobs / ctx.agents.resume | 探测特性 | 整文件读取并大声拒绝 / 自带 job 映射 / 交接注入 |
| 客户端外壳服务(sessions.refresh/open、workspaces.refresh) | 面板应用时探测特性 | 整页重载 |
| 更新的平台能力从来不是硬性要求——插件在最老的受支持版本线(0.1.2-rc.1)上仍能启动。 | | |

你能得到什么

1. 自动发现 —— claude_scan 定位 Claude 数据根目录($CLAUDE_CONFIG_DIR,回退到 ~/.claude),为每个项目/会话、记忆、技能、全局 CLAUDE.md 和 settings.json 建立索引,带增量缓存和并行扫描(scanConcurrency)。
2. 全保真导入 —— import_claude 把转录记录转成平衡、可恢复的 DSH 会话(turn/start → step/start → user/message → assistant/message → tool/call → tool/result → step/end → turn/end),修复中断的工具调用,对超过 maxTranscriptBytes 的转录记录分块流式导入。
3. 一个 claudecode 工作区 —— 每个导入的会话都落在专用工作区(默认 $DSH_HOME/claudecode);workspaceMode: 'per-project' 恢复「每个项目一个工作区」的分组方式。
4. 只复制、增量 —— 两边都不会移动、改写或删除任何东西;重跑只追加新轮次(force: true 会在新 id 下额外保存一份完整副本)。
5. 个人上下文,始终新鲜 —— 记忆作为实时提示词段落注入,Claude 技能注册为真正的 DSH 技能(全局 + 项目级),全局 + 项目 CLAUDE.md 提前注入。
6. 四源迁移向导 —— /move 加上 move_detect / move_preview / move_run 迁移 Claude Code、Codex、OpenCode 和 Hermes,需审批放行,幂等(move.json)。
7. Web 面板与命令 —— /claude-import-all、/resume-claude、/claude-move-reset、/claude-export,以及浮动迁移面板。
8. 双向导出 —— claude_export(或 /claude-export <sessionId>)把 DSH 会话写回为可恢复的 Claude Code JSONL 转录记录(user/assistant/tool 轮次,thinking + tool_use/tool_result 配对,尽力映射 cwd),历史因此能再次离开 DSH。

四源迁移向导

/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 Code(~/.claude)、Codex(~/.codex)、OpenCode(数据根目录 + 配置根目录)、Hermes(技能/记忆根目录);每个来源都有自己的解析器和映射器。
- 映射 — 记忆/指令 → DSH 全局 AGENTS.md 中只追加的托管区段(每项一个带标记的区段);技能 → 真正的 DSH 技能(SKILL.md 包原样复制,其他格式转换);斜杠命令 → 注册为 DSH 命令(重启后从 move.json 重建);会话 → 可恢复的 DSH 会话(与第一阶段相同的导入器)。
- 幂等 — 每个已应用的方案都记录在 $DSH_HOME/claude-move/move.json(digest / targetDigest / appliedAt);重复运行会跳过未变更的项,force 则重新应用。
- 需审批 — 任何会写入内容的运行都先询问 ctx.approval;只要不是 allowed-once,就零写入。

快速开始

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'

然后,在任意 DSH 会话里运行一条命令:

/claude-import-all # scan → copy every Claude session → report

导入后无需重启 DSH —— 刷新打开的 Web 页面一次,点击任意已导入的会话即可继续。

迁移哪些内容

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

| Claude Code 中 | 在 DSH 中落地为 |
| 会话记录(projects//.jsonl) | 均衡、可恢复的 DSH 会话 —— 完整保真映射 user/assistant/tool/thinking,并修复中断的工具调用 —— 归入一个 claudecode 工作区,或每个项目一个 |
| 记忆文件(projects//memory/.md) | 实时的系统提示词上下文区段,每次请求都重新读取(feedback > project > reference > user) |
| 技能(~/.claude/skills/*) | 真正的 DSH 技能(kebab-case 名称,冲突时加后缀,默认最多 30 个;跳过 README.md/MEMORY.md 以及没有描述的文件) |
| CLAUDE.md(全局 + 每个项目) | 靠前的提示词区段;项目文件优先 |
| settings.json | DSH 配置建议,附带明确的无法映射键列表 |
| 项目状态(目录、git 分支与脏文件数) | 显示在扫描索引、Web 面板徽标和 /resume-claude 交接中 |

用法

挂载插件后,在任意会话中调用这些工具:

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" } # 精简输出

import_claude { path: "~/.claude/projects/<slug>/<sessionId>.jsonl" } # 单个会话
import_claude { path: "~/.claude/projects" } # 目录(递归)
import_claude { path: "all" } # 全部
随时可重跑:未变动的文件跳过,增长的记录只追加新轮次。
超过 maxTranscriptBytes 的文件按块流式导入(无内存上限)。
import_claude { path: "...", force: true } # 全新完整复制(保留旧副本)

claude_export { sessionId: "<dsh-session-id>" } # 把 DSH 会话写回 Claude JSONL
claude_export { sessionId: "...", path: "~/.claude/projects/<slug>/<id>.jsonl" } # 指定目标路径

命令(用户触发,不消耗模型轮次):

/claude-import-all # 一次性:扫描 → 导入全部 → 报告 → 注入当前会话 /resume-claude latest # 继续最近的 Claude 会话 /resume-claude <sessionId> # 按源会话 id 或 import-<src> id /resume-claude <keyword> # 匹配标题;多个匹配会列出,绝不猜测 /claude-move-reset # 重置插件缓存(书签 + 导入映射);已导入的会话保留 /claude-export <sessionId> [path] # 把 DSH 会话导出为可恢复的 Claude JSONL 记录

Web 面板:浮动迁移面板,含项目/会话树、状态徽章(未导入 / 已导入 / 已导入且有新轮次 / 源缺失 / 目录缺失 / git 脏)、关键词过滤、分页渲染、每个会话的「导入并继续」+「打开会话」+「刷新会话列表」、带实时进度条和取消的批量导入,以及缓存重置按钮。文案跟随浏览器语言(zh/en)。通过插件自己的 /api/claude-move/ JSON 路由,走公开的 ctx.webServer 接口对外提供。

导入之后

不需要重启 DSH。 导入完成的那一刻,就通过公开的 sessionPersistence 服务持久落盘:

- 服务端列表(session.list / workspace.list RPC、命令行、任何新页面加载)会立刻在 claudecode 工作区下显示导入的会话。
- 面板会自行刷新已打开页面的会话列表,并为每个导入的会话提供打开会话按钮。
- 导入的会话可以立即打开、阅读、继续——用 /resume-claude,或在列表里点该会话。随时重跑导入,只会把新轮次同步进同一批会话。

示例

这些是插件的真实入口;安装一次,然后调用其中一个。

详细示例

命令

~~~sh
import_claude

输入

~~~json
{ "path": "test/fixtures/simple.jsonl" }

输出

~~~text
已导入 1 轮对话(2 条消息、0 次工具调用)→ 会话 import-sess-simple-001。

摘自 README.md:138 (Usage); test/fixtures/simple.jsonl:1-2; index.mjs:1708 (renderImport)

失败分支

输入

~~~text
resolveImportTarget('', '/home/user/.claude') // empty path

输出

~~~text
Error: path 必填:单个 .jsonl、目录、"~/.claude/projects" 或 "all"

来源:plugins/dsh-claude-move/index.mjs:744-746; plugins/dsh-claude-move/test/import.test.mjs:158-161; plugins/dsh-claude-move/README.md:132-145

简短示例

- import_claude
- claude_export

配置

全部可选,可在 cordis.yml 中覆盖。

| 键 | 默认值 | 含义 |
| claudeHome | $CLAUDE_CONFIG_DIR 或 ~/.claude | Claude 数据根目录 |
| workspaceMode | claudecode | claudecode(一个专用工作区)· per-project(每个源 cwd 一个工作区) |
| claudecodeDir | $DSH_HOME/claudecode | claudecode 工作区文件夹(插件唯一会创建的文件夹) |
| scanGit | true | Git 探测级别:true(完整)· 'branch'(不调用 git)· false |
| gitTimeoutMs | 5000 | Git 子进程超时 |
| scanConcurrency | 8 | 并行扫描项目数上限 |
| maxTranscriptBytes | 67108864 | 流式导入阈值(超过则分块) |
| excludeProjects | [] | 要跳过的 slug 子串 |
| enableMemory | true | 把记忆作为实时提示词段落注入 |
| memoryMaxBytes | 8192 | 记忆段落上限 |
| memoryScope | current-project | current-project · all(当前项目优先) |
| enableSkills | true | 把 Claude 技能注册为 DSH 技能 |
| maxSkills | 30 | 技能数量上限 |
| extraSkillDirs | [] | 额外技能目录 |
| enableInstructions | true | 注入全局和项目 CLAUDE.md |
| resumeMaxChars | 2048 | 交接摘要字符上限 |
| resumeMode | inject | inject(交接摘要)· agents(ctx.agents.resume) |
| enableWebPanel | true | 注册 /api/claude-move/ 面板路由 |
| importConcurrency | 4 | 每批并行读取和转换数 |
| requireApproval | true | 向导写入时请求 ctx.approval(仅允许一次) |
| codexHome | $CODEX_HOME 或 ~/.codex | Codex 数据根目录 |
| opencodeDataHome | 平台 XDG 数据目录/opencode | OpenCode 数据根目录 |
| opencodeConfigHome | 平台 XDG 配置目录/opencode | OpenCode 配置根目录 |
| hermesHome | $HERMES_HOME 或 ~/.hermes | Hermes 数据根目录 |
| skillsDir | $DSH_HOME/skills | 向导技能目标位置 |
| agentsMdPath | $DSH_HOME/AGENTS.md | 向导记忆/指令目标位置 |
| moveWorkspaceMode | per-source | 向导导入的工作区分组方式:per-source · single |
| enableExport | true | 注册 claude_export 工具和 /claude-export 命令 |
| exportDir | $DSH_HOME/claude-export | 默认导出文件夹(显式 path 始终优先) |

工具与入口

| 入口 | 类型 | 说明 |
| claude_scan | 工具 | 项目/会话/记忆/技能/设置的结构化索引 |
| import_claude | 工具 | 导入单个会话、目录或 all(增量,force 用于全新复制) |
| claude_export | 工具 | 把 DSH 会话导出为可恢复的 Claude Code JSONL 转录 |
| move_detect / move_preview / move_run | 工具 | 四源向导:扫描、逐项生成带差异的计划、审批后执行 |
| /claude-import-all | 命令 | 扫描 → 全部导入 → 报告 |
| /resume-claude | 命令 | 继续 Claude 会话(最新、id 或关键词) |
| /claude-move-reset | 命令 | 重置插件缓存(已导入的会话保留) |
| /claude-export | 命令 | 把 DSH 会话导出为可恢复的 Claude JSONL 转录 |
| /move | 命令 | 一次性四源向导 |
| Web 迁移面板 | 客户端 | 浮动面板,带进度、取消、分页、打开会话 |

权限与数据

- 权限:workshop 清单声明了 filesystem:read 和 filesystem:write。
- 读取 ~/.claude(转录、记忆、技能、CLAUDE.md、settings.json)——严格只读——以及它导入到的项目目录。
- 写入 DSH 会话日志,走公开的 sessionPersistence 服务(只创建 + 追加,绝不删除/改写/归档)、workspace-registry 记录、$DSH_HOME/claude-move/ 下的缓存、claudecode 工作区文件夹,以及 $DSH_HOME/claude-export/ 下导出的 .jsonl 文件(或显式指定的目标路径)。
- 绝不修改 Claude 源文件、碰其他应用的数据、访问网络。不读取也不传输任何凭据。

安全边界

- 源文件只读;DSH 日志只追加(仅 create + append)。
- 外部转录是不可信输入——其中的内容一律不执行;system/developer/thinking 内容绝不进入恢复交接。
- 只用公开服务——sessionPersistence / workspaceRegistry / tools / commands / systemPrompt / skills / webServer;不改引擎,也不改 UI。
- 密钥只按位置报告(file:line:kind);permission/permission-mode/queue-operation 记录只计数,不导入。
- 向导写入需审批——只要不是 allowed-once,就零写入。

已知限制

- 标题取自 custom-title/ai-title/首条提示词;Claude 的 summary 记录会报告,但不映射到 DSH 压缩节点(合成一条合法的压缩事务会伪造它的 seq 范围和检查点消息)。
- thinking 块保留为 reasoning 内容,但绝不进入恢复交接。
- 中断的工具调用用合成的错误结果修复(绝不丢弃),报告为 repaired.synthesized。
- 权限类记录只计数,不导入;DSH 权限预设建议在报告中生成。
- 宿主没有流式 fs.streamText 接口时,超过 maxTranscriptBytes 的转录会直接报错,不做部分导入。
- 在 workspaceMode: 'per-project' 下,源目录已被删除的会话仍会导入,但工作区挂载会失败(保持未分组;workspace.attached: false,并附带 reason)。默认的 claudecode 工作区不依赖源目录。
- 如果 transcript 被截断或原地重置(轮次少于记录的导入量),重新导入会跳过它并报告 sourceShrunk;用 force: true 做一次全新的完整复制。
- Web 面板是零构建的浮动面板,由插件自己的 JSON 路由驱动;它不使用 shell 的内部 UI 槽位系统。

模型体验

- 面向模型的表面是工具的描述/模式和它们的输出:claude_scan 返回结构化索引,import_claude 返回逐文件摘要并标出警告位置,claude_export 返回导出摘要(目标路径 + 轮次/消息/工具计数)。工具结果本身也会记录为 tool/result 事件,所以一切都可以重建。
- 没有隐藏的面向模型文本;memory/CLAUDE.md 部分注册在 ctx.systemPrompt 上(提示词组装,可从会话日志重建)。

故障排查

- 行不生效:dsh --profile --dump-config 应打印 # == dsh-claude-move;重新运行 dsh plugin --profile add ...。
- Web 启动但静默挂起:由 dsh plugin add 初始化的新配置档只包含 dsh-base —— 把 @deepseek-ai/dsh-web-app 加到 dsh.profile.bundles。安装到已有的 web 配置档则无需任何操作。
- 面板路由 404:只有在 enableWebPanel: true 且组合了 web 服务器时才会提供这些路由;检查启动日志中的 FAILED fibers。
- 导入失败并提示 "transcript 过大":调高 maxTranscriptBytes,或单独导入该文件。
- 导入成功但侧边栏没有显示新会话:页面已经打开 —— 点一次面板的刷新按钮(或重新加载页面)。永远不需要重启 DSH。
- 日志:启动失败会打印到 dsh 控制台;插件会记录带 [claude-move] 前缀的错误,涉及工作区/导入映射问题。

归属(开源组件)

本项目采用 Apache License 2.0 许可;以下 MIT 许可的组件保留各自的许可证(全文见 THIRD_PARTY_NOTICES.md):

- 转换核心来自 Nwflower/dsh-chat-import(MIT)。
- 发现约定与安全模型来自 Demogorgon314/dsh-resume-plugin(MIT)。
- 记忆/技能注入与 frontmatter 解析模式来自 YYTbit/dsh-plugin-claude-bridge(MIT)。

开发

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 通过 GitHub Actions 在 Linux/macOS/Windows 上于 Node 22 运行完整测试套件(test.yml)。

主题

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

贡献者

- @PerryLink — 创建者兼维护者:导入流水线、四来源迁移向导、Web 面板、文档、CI/CD 与发布。
- @OLDnana1 — 定位了工具调用中断导致的数据损坏根因,该问题会让导入的会话在恢复时永久返回 HTTP 400。
- @GooodWei — 发现 README.md(以及任何没有描述信息的 .md)会被错误注册为技能,进而破坏 DSH 的技能加载。

PerryLink DSH 插件家族

本项目属于 PerryLink 的 DeepSeek Harness 插件家族。下面这份名单默认折叠,好让每个 README 的首屏都保持简短;展开即可看到每一行及其状态。

展开全部插件

| 插件 | 状态 |
| dsh-aqua-input-check | |
| dsh-archive-check | |
| dsh-auto-review | |
| dsh-autotier | |
| dsh-bid-ca-precheck | |
| dsh-bid-qual-check | |
| dsh-cert-mcp | |
| dsh-checkpoint-rewind | |
| dsh-click | |
| dsh-composer-history | |
| dsh-contract-stance | |
| dsh-customs-doc-check | |
| dsh-data-quality | |
| dsh-demurrage-ledger | |
| dsh-doublecheck | |
| dsh-drill-script-check | |
| dsh-eia-guide-check | |
| dsh-emergency-plan | |
| dsh-essay-rubric-check | |
| dsh-evidence-check | |
| dsh-export-ctl-check | |
| dsh-fast | |
| dsh-fmea-table-check | |
| dsh-forecast-penalty | |
| dsh-fund-research | |
| dsh-github | |
| dsh-gongwen-flow-check | |
| dsh-gongwen-word-check | |
| dsh-guard-plan-qc | |
| dsh-hazchem-check | |
| dsh-hazplan-check | |
| dsh-hidden-risk-map | |
| dsh-hs-classify | |
| dsh-icd-rule-check | |
| dsh-industry-research | |
| dsh-lawcite-adapter | |
| dsh-laya | |
| dsh-lc-doc-check | |
| dsh-learning-gap-check | |
| dsh-library | |
| dsh-local-ai | |
| dsh-lsp-actions | |
| dsh-mask | |
| dsh-mcp-panel | |
| dsh-medrec-qc | |
| dsh-memento | |
| dsh-nsfc-form-check | |
| dsh-nurse-record-check | |
| dsh-observe | |
| dsh-origin-rvc-check | |
| dsh-ota-review-check | |
| dsh-output-styles | |
| dsh-paper-doc-adapter | |
| dsh-permission-rules | |
| dsh-permit-report-check | |
| dsh-pipeline-check | |
| dsh-pleading-draft | |
| dsh-plugin-doctor | |
| dsh-plugin-guide | |
| dsh-plugin-kit | |
| dsh-plugin-upgrade | |
| dsh-policy-brief-draft | |
| dsh-power-loss-split | |
| dsh-power-ticket-check | |
| dsh-ppap-check | |
| dsh-protest-deadline | |
| dsh-railway-window | |
| dsh-repair-order-qc | |
| dsh-research-report | |
| dsh-review-reply-check | |
| dsh-rulefile-check | |

| dsh-safety-brief-check | |
| dsh-score | |
| dsh-session-sync | |
| dsh-site-log-check | |
| dsh-skill-pack-security | |
| dsh-soe-decision-check | |
| dsh-soilwater-check | |
| dsh-sop-sync-check | |
| dsh-spc-gbt-adapter | |
| dsh-talk | |
| dsh-tender-extract | |
| dsh-tender-matrix | |
| dsh-test-drive | |
| dsh-ticktick | |
| dsh-translate | |
| dsh-warranty-calc | |
| dsh-budget | 🧊 FROZEN — see the repo README |
| dsh-claude-move | 🧊 FROZEN — see the repo README |
| dsh-defend | 🧊 FROZEN — see the repo README |
| dsh-draw | 🧊 FROZEN — see the repo README |
| dsh-reach | 🧊 FROZEN — see the repo README |
| dsh-background-agents | 🚫 RETIRED — see the repo README |
| dsh-session-pin | 🚫 RETIRED — see the repo README |
| dsh-team-rooms | 🚫 RETIRED — see the repo README |

License

Apache License 2.0 © 2026 dsh-claude-move contributors
预览分享卡片长什么样 ↓PerryLink/dsh-claude-move
分享 · DeepSeek Harness Hub
PerryLink/dsh-claude-move

DeepSeek Harness 四源迁移向导:把 Claude Code、Codex、OpenCode 和 Hermes 的会话、记忆、技能、指令和斜杠命令搬进 DSH(/move 向导 + 可续传会话,审批把关,幂等)。

回到顶部