DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

BaiZhi967 /

BaiZhi967/dsh-plugin-zcode-import

Verified

DSH 会话导入插件:按工作区浏览本地 ZCode 的会话,勾选或整工作区导入 DeepSeek Harness · Import local ZCode conversations into DeepSeek Harness

★ 1 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@d9e4ed25

dsh-plugin-zcode-import banner

dsh-plugin-zcode-import

English | 中文

license stars node

把本地 ZCode 的会话导入 DeepSeek Harness:设置面板里多一页「会话导入」,左边列出 ZCode 的工作区,右边列出该工作区的对话,勾选几条或整个工作区一键导入。导入后就是原生 DSH 会话——出现在左侧会话列表对应工作区下,能打开、能继续对话,不是导出一份文本。

  • 直接读 ZCode 的 db.sqlite,只读打开,不改动、不迁移 ZCode 的任何数据;
  • 会话 id 由 ZCode 的 UUID 派生,重复导入会被识别为「已存在」,不会产生副本;
  • 全量导入很快:30 个会话约 3 秒(本机实测)。

✨ 功能

能力 说明
设置页入口 设置面板新增「会话导入」页(与「通用 / 模型 / 插件」同级),无需命令行
工作区列表 按 session.directory 自动聚合出 ZCode 工作区,显示会话数、最近更新时间;目录已被删除的会标黄提示
对话列表 选中工作区后列出其对话:标题、更新时间、消息条数、是否已导入;子代理会话默认折叠
部分导入 勾选任意几条 → 「导入选中会话」;「全选未导入」一键勾选
整工作区导入 「导入整个工作区」一次导入该工作区全部对话
进度与明细 导入过程有进度条 + 当前标题,结束后逐条列出「已导入 / 已存在 / 跳过 / 失败」及原因
内容完整 文本、思考(reasoning)、工具调用与工具结果全部还原成 DSH 的 tool/call + tool/result
自动建工作区 目标目录在 DSH 里还没有工作区时自动创建并挂载,导入完即出现在侧栏
热重载 改 impl.js 后 POST /__reload 即可生效,不用重启 DSH;客户端改动由 DSH 模块热更新送达页面

📦 安装

# 从 GitHub 安装(本仓库)
dsh plugin --profile web add github:BaiZhi967/dsh-plugin-zcode-import
dsh --profile web

本地开发(clone 下来改):

git clone https://github.com/BaiZhi967/dsh-plugin-zcode-import.git
cd dsh-plugin-zcode-import

# 在插件目录的「父目录」执行,dsh 会把相对路径锚定到调用目录
dsh plugin --profile web add ../dsh-plugin-zcode-import
dsh --profile web

也可以直接写进 profile 的 cordis.patch.yml:

- insert:
    - id: zcode-import
      name: dsh-plugin-zcode-import

环境要求:DSH >= 0.1.6-alpha.2、Node >= 22.19.0(用到内置 node:sqlite,需 Node 22.5+;本插件按 22.19 起算)。

装好后刷新一次页面,打开 设置 → 会话导入。

🚀 用法

  1. 设置 → 会话导入:顶部会显示识别到的 ZCode 数据目录;
  2. 左栏点一个工作区;
  3. 右栏勾选要导入的对话,点 导入选中会话;或直接点 导入整个工作区;
  4. 进度条跑完看「导入明细」,然后关掉设置——会话已经在左侧列表里了。

导入的会话可以像平常一样打开、继续提问、归档或删除。删掉导入的会话不会影响 ZCode 原数据。

自定义 ZCode 位置

默认读 <用户目录>/.zcode。非标准安装用任一方式指定:

# 环境变量
setx ZCODE_HOME "D:\path\to\.zcode"
# 或者写在 profile 的 cordis.patch.yml 里
- insert:
    - id: zcode-import
      name: dsh-plugin-zcode-import
      config:
        root: D:\path\to\.zcode

🔍 它是怎么工作的

ZCode 侧的数据结构

ZCode 把会话存在 <ZCode 根>/cli/db/db.sqlite:

表 内容
session 会话元数据。没有工作区表——工作区就是 directory 字段的去重分组;task_type 区分 interactive(真人对话)与 subagent_child(子代理)
message 一条消息一行,data JSON 含 role 与 semantics.origin/kind(real_user / agent_runtime / system)
part 真正的内容:text、reasoning、tool(state.input + state.output 同时含调用与结果)、step-start、step-finish、timeline、file

导入时会跳过运行时注入的提醒(todo_reminder、background_notification 等)和空的时间线标记。

DSH 侧的数据结构

DSH 会话是追加式事件日志:sessions/<projectKey(cwd)>/<session-id>/session.v3.jsonl.zstd,zstd 多帧、首帧是 header、后续每帧是事件行。一条对话的事件序列是:

turn/start → step/start → user/message → assistant/message(含 stream)
           → tool/call + tool/result … → step/end → turn/end

两个容易踩的校验点:user/message | assistant/message | tool/result 必须带 surfaceOp: "append",而 tool/call 必须不带。归属工作区由 storages/workspace.json 的 sessionIds 记录,并且会拿 header 里的 cwd 做校验。

导入路径

不手写 session.v3.jsonl.zstd——写入路径不做校验,而读取路径是 fail-closed 的,很容易做出「能列出但打不开」的会话。走运行时 API:

ZCode db.sqlite (只读)
      │  lib/zcode-source.js
      ▼
转换器 lib/convert.js  ──►  DSH 事件数组
      ▼
ctx.sessionPersistence.create(header) → append(events) → flush() → close()
      ▼
ctx.workspaceRegistry.create(cwd) + Workspace.attachSession(sessionId)

会话 id 由 ZCode 的 sess_<uuid> / sess_subagent_agent_<uuid> 派生为 session-<uuid>,所以重复导入会命中 stat() 判定为「已存在」,并补挂到工作区,而不是再存一份。

结构

dsh-plugin-zcode-import/
├── entry.js           # 宿主入口:只承载路由 + 热重载外壳
├── impl.js            # 宿主实现:工作区/对话列表、导入任务、落盘与挂载
├── client.js          # 客户端:设置页「会话导入」(locale 文案 + 主题令牌)
├── lib/
│   ├── zcode-source.js  # 只读打开 db.sqlite,列工作区/对话、读消息与 part
│   └── convert.js       # ZCode 消息/part → DSH 会话事件
├── tools/
│   ├── check-conversion.mjs  # 离线自检:转换 + 格式回环校验
│   └── verify-stored.mjs     # 落盘校验:用官方格式目录重读已导入会话
├── cordis.patch.yml   # bundle 补丁:向 profile 插入插件行
└── package.json       # dsh.bundle.patch + dsh.client 声明
设置页「会话导入」(client.js)
        │  同源 HTTP(回环地址)
        ▼
GET  /zcode-import/api/{status,workspaces,sessions}
POST /zcode-import/api/import          → { jobId }
GET  /zcode-import/api/job?id=…        → 进度与逐条结果
        ▼
impl.js ──► sessionPersistence / workspaceRegistry

宿主侧有意拆成两个文件:加载过的 ESM 模块会在宿主进程里被永久缓存,所以 entry.js 保持极简、逻辑放 impl.js,由它用带缓存参数的动态 import() 拉取——替换 impl.js 后一次 POST /__reload 就能生效。

本地 API

路由前缀 /zcode-import/api,仅监听 DSH 自己的回环地址:

方法 作用
GET /status ZCode 根目录、数据库路径、是否可用
GET /workspaces 工作区列表(?includeSubagents=1 带上子代理会话)
GET /sessions?path= 某工作区的对话列表,含 imported 标记
POST /import {path, sessionIds[]},空数组 = 整个工作区 → {jobId}
GET /job?id= 任务进度、逐条结果
GET /__reload 开发用:重新加载 impl.js

✅ 验证

仓库自带两个校验脚本,都用 DSH 官方格式目录(@deepseek-ai/dsh-session-format-catalog)做判据,而不是自说自话:

# 1) 转换器自检:把每个 ZCode 会话转成事件后编码成物理行、再走官方还原路径读回来
node tools/check-conversion.mjs 500

# 2) 落盘校验:把已导入的 session.v3.jsonl.zstd 逐帧解开、用官方目录还原
node tools/verify-stored.mjs "<DSH_HOME>/sessions"

本机实测(403 个真人会话 / 2.4 GB 级数据库):

项目 结果
转换 + 格式回环 403 / 403 通过,0 失败,共 236,060 个事件
已导入会话落盘还原 44 / 44 通过,0 失败
真机导入 MoTTEavl 6 个、PowerHuman 30 个,0 失败;30 个约 3 秒

脚本会自动定位 DSH 自带的 @deepseek-ai/dsh-session-format-catalog(依次尝试直接 import、DSH_CHECKOUT 环境变量、全局 npm 目录)。定位失败时按提示设置 DSH_CHECKOUT 指向 DSH 安装目录即可。

⚠️ 说明与限制

  • 只读:ZCode 数据库以 readOnly 打开,插件不写、不删、不迁移 ZCode 数据。
  • 图片/附件:ZCode 里的 file 类 part 只保留文件名占位文本;二进制附件不会搬运。
  • 模型来源:导入的 assistant 消息保留 ZCode 里记录的 provider / model 名(如 GLM-5.3)作为来源标注;这只影响展示,重新提问时用你当前选择的模型。
  • 子代理会话:默认不列出(ZCode 里 2642 个会话中 2237 个是子代理)。需要时用 ?includeSubagents=1。
  • 正在运行的会话:导入的是 ZCode 数据库里的既存记录,ZCode 之后新产生的对话需要再导一次(重复的会被跳过)。

📄 License

MIT © 2026 BaiZhi967

—/ 5

No ratings yet

Verified DSH bundle

Commit d9e4ed2589cc

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout