把 Trae 技能与对话归档进项目,随时读回继续
29.9/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/10 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add lincoo2019/dsh-trae-vault该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:待复验
是什么
dsh 原生插件 · model
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 23 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
读写/删除本地文件
查看扫描证据(共 32 处,展示前 19 条)
- 写入本地文件impl.r35.js:586
appendFileSync(target, line, 'utf8'); - 读取本地文件impl.r35.js:817
if (existsSync(join(path, vaultConfig.directory))) baseline.add(path.toLowerCase()); - 读取本地文件impl.r35.js:857
if (!existsSync(join(path, vaultConfig.directory))) { - 读取本地文件lib/skills.trae2.js:44
const info = await stat(path); - 读取本地文件lib/skills.trae2.js:120
raw = await readFile(filePath, 'utf8'); - 读取本地文件lib/skills.trae2.js:165
entries = await readdir(root, { withFileTypes: true }); - 读取本地文件lib/vault.trae2.js:375
dir = await stat(sessionDir); - 读取本地文件lib/vault.trae2.js:382
entries = await readdir(sessionDir); - 读取本地文件lib/vault.trae2.js:394
buffer = await readFile(full); - 写入本地文件lib/vault.trae2.js:760
await mkdir(dir, { recursive: true }); - 写入本地文件lib/vault.trae2.js:763
await writeFile(jsonlPath, toJsonl(stamped), 'utf8'); - 写入本地文件lib/vault.trae2.js:766
await writeFile(eventsFile, toEventsJsonl(header, events), 'utf8'); - 写入本地文件lib/vault.trae2.js:770
await writeFile(markdownPath, renderMarkdown(stamped), 'utf8'); - 写入本地文件lib/vault.trae2.js:847
await mkdir(this.root, { recursive: true }); - 写入本地文件lib/vault.trae2.js:848
await writeFile(this.indexPath, `${JSON.stringify(next, null, 2)}\n`, 'utf8'); - 读取本地文件lib/vault.trae2.js:859
const parsed = JSON.parse(await readFile(this.indexPath, 'utf8')); - 读取本地文件lib/vault.trae2.js:898
entries = await readdir(this.root, { withFileTypes: true }); - 读取本地文件lib/vault.trae2.js:912
names = await readdir(directory); - 删除本地文件递归lib/vault.trae2.js:1409
await rm(join(projectDir, name), { recursive: true, force: true });
扫描于 2026/10/31(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 归档技能与对话
- 本地会话库
- 发布可续传会话
DeepSeek Harness 插件包:Trae SKILL.md 技能服务商、项目本地会话库、把归档发布为可续传的 DSH 会话,以及导入共享的 Trae 会话。
README
由 DeepSeek 最新模型翻译生成dsh-trae-vault
一个 DeepSeek Harness 插件包,双向打通 Trae 和 DSH,让每段对话都留在它所属的项目里。
一个插件包,为 DeepSeek Harness 带来四项能力:
1. 调用 Trae 技能 —— 在 ctx.skills 上提供 trae 服务商,发现为 Trae 编写的 SKILL.md 技能包,让 Harness 的 skill 工具能像加载原生技能一样加载并调用它们。
2. 项目本地对话仓库 —— 把每段对话归档到项目文件夹里,存成规范化的 JSONL 记录,外加一份可读的 Markdown 转写,并支持按需读回。
3. 把归档发布为真实会话 —— 把归档的对话还原到 DSH 的会话存储中,侧边栏就能列出它,也能继续对话。
4. 导入共享的 Trae 对话 —— 下载 https://share.traecontent.cn/share/<id> 链接,转换成 Harness 会话格式,然后像其他会话一样归档到这个项目里。
安装
这个插件包是纯 ES 模块包,没有任何依赖,所以按路径安装,而不是从 registry 安装。
展开完整文档(README 剩余 1 节)
dsh-trae-vault
一个 DeepSeek Harness 插件包,双向打通 Trae 和 DSH,让每段对话都留在它所属的项目里。
一个插件包,为 DeepSeek Harness 带来四项能力:
1. 调用 Trae 技能 —— 在 ctx.skills 上提供 trae 服务商,发现为 Trae 编写的 SKILL.md 技能包,让 Harness 的 skill 工具能像加载原生技能一样加载并调用它们。
2. 项目本地对话仓库 —— 把每段对话归档到项目文件夹里,存成规范化的 JSONL 记录,外加一份可读的 Markdown 转写,并支持按需读回。
3. 把归档发布为真实会话 —— 把归档的对话还原到 DSH 的会话存储中,侧边栏就能列出它,也能继续对话。
4. 导入共享的 Trae 对话 —— 下载 https://share.traecontent.cn/share/<id> 链接,转换成 Harness 会话格式,然后像其他会话一样归档到这个项目里。
安装
这个插件包是纯 ES 模块包,没有任何依赖,所以按路径安装,而不是从 registry 安装。先把它克隆到一个固定位置:
git clone https://github.com/lincoo2019/dsh-trae-vault.git
然后,在存放克隆副本的目录下,把它安装到某个 DSH 配置档 —— 这一步会把包注册为配置档插件包,并把链接写进配置档的 package.json:
dsh plugin --profile <your-profile> add ./dsh-trae-vault
plugin_manager 的 install_bundle 动作在 DSH 内部做同样的事,而配置档自己的补丁层($DSH_HOME/profiles/<profile>/cordis.patch.yml)是你覆盖该行配置的地方:
- id: trae-vault
config:
vault:
autoImport: true # publish archives back as real, resumable sessions
安装时有两个实现细节很重要,两者都是实测行为,不是谨慎起见:
- 克隆副本必须留在你安装它的位置。 配置档里存的是指向这个文件夹的绝对 link:。移动或删除文件夹,DSH 就完全无法解析这个插件包 —— 它会报 cannot resolve profile bundle,插件则悄无声息地永不激活。
- 包里必须有 cordis.patch.yml。 它是该行的覆盖层;读不到它的安装会被拒绝。它已经列在 package.json 的 files 里,所以打包安装会带上它。
改完代码后,必须提高 generation 文件的 REVISION,新代码才会加载(见为什么入口是个瘦加载器)。
1. Trae 技能
查找位置
| 优先级 | 来源 | 路径 |
| 150 | trae-project | <project>/.trae/skills |
| 250 | trae-custom | 每个 skills.customDirs 条目 |
| 450 | trae-user | ~/.trae/skills |
项目根目录从会话的工作目录向上逐级查找,所以在 src/deep/inside 里启动的会话仍然能看到 <repo>/.trae/skills( walk 会在第一个包含 .trae/skills 的祖先目录停下,而不是 .git)。
同一注册表层内,rank 小的胜出。Harness 自带的 skill-filesystem 服务商给 <project>/.dsh/skills 和 <project>/.agents/skills 分别用 rank 100 和 200,所以 Trae 技能排在 .agents 前面,但排在 .dsh 后面。
为什么要自己写服务商
Harness 的文件系统服务商只扫描根目录下一层(<root>/<name>/SKILL.md)。Trae 技能包经常是分组的,比如 .trae/skills/<group>/<name>/SKILL.md,所以这个服务商递归遍历目录树(跳过 .git、node_modules、__pycache__ 之类),并用 frontmatter 里的 name 字段作为技能名。
目录发现只读 frontmatter。正文按需加载,所以改 SKILL.md 正文,下次调用就生效,不用让缓存失效。新增、重命名或删除 SKILL.md 会通过 watcher(防抖)让目录失效。
Frontmatter
name: my-skill # required, kebab-case
description: What it does # required
when-to-use: Optional hint # optional (also accepts whenToUse)
disable-model-invocation: true # optional; keeps it out of model catalogs
user-invocable: false # optional; hides it from human commands
调用相关的键用和 Harness 一样的严格布尔语法(true/false、yes/no、on/off、1/0,不区分大小写)。写法不被接受时,整个技能会被丢弃并给出警告,而不是悄悄放行某个入口。
2. 会话保管库
写到哪里
<project>/.dsh/conversations/
├── index.json # every archived conversation for this project
└── <session-id>/
├── conversation.jsonl # durable record: 1 metadata line + 1 line per message
└── conversation.md # readable transcript
每段会话收录:你的消息、助手回复(文本和工具调用)、以及截断到 maxToolResultChars 的工具结果。注入的运行时上下文默认排除;模型的推理块从不写入。
什么时候运行
- 自动:在 session/title(尽早拿到标题)和 turn/end(一轮交换的持久边界)时触发,插件激活时还会为项目里每个已打开的会话各跑一次。
- 按需:通过下面的工具触发。
读取持久日志
Harness 把会话持久化在 $DSH_HOME/sessions/<mangled-project-path>/ 下,形式是多个独立压缩的 zstd 帧拼接——每次持久写入一帧。Node 的 zstdDecompressSync 和 createZstdDecompress() 都会在第一个帧边界停下,所以 lib/zstd.js 自己按 zstd 帧头布局逐帧遍历,用 Node 内置编解码器解压每一帧。正在写入的帧会被报告出来,而不是丢掉,所以活跃会话永远不会丢失已经持久化的帧。
项目目录名完全按持久化编解码器的方式复现把它搞乱了(F:\QwenTTS_Fn2 → --F-QwenTTS_Fn2--),于是发现机制会找到已有项目的日志。日志归在别的 slug 下,但把本项目记为 cwd 的,也能被找到,这样项目被移动或改名也能覆盖。
3. 把归档发布为真实会话
归档的对话可以重新物化回 DSH 的会话存储,这样工作区侧边栏会列出它,打开和恢复都跟其他会话一样。
写入什么。 通过 ctx.sessionPersistence 新建一个会话——编码(带校验和的 zstd 帧)、头部帧、flush() 持久化屏障都由后端负责。原始会话日志绝不动:导入的会话永远是新 id 下的新文件。
用谁的 cwd。 用拥有 .dsh 文件夹的那个 vault 的项目根目录,不是归档里记录的 cwd。项目文件夹理应拥有自己 .dsh 下的对话,所以把对话文件丢进 .dsh/conversations/,它就会出现在那个工作区的侧边栏里。若信任归档自己的 cwd,它会被归到当初记录它的那个项目下,而从别的机器拷来的对话则哪个工作区都不会出现。两者不一致时,记录下来的路径会作为 origin 上报,对话仍可追溯。
忠实回放,而非重建。 导入回放归档里的逐字事件(events.jsonl)。归一化后的 transcript 不能当数据源:加载器校验 assistant/message 时依赖 transcript 不保留的字段(assertAssistantSettlementShape 要求 turn、step 和 stream 数组),所以只靠 transcript 重建的会话会打不开。序号会重新编号,从 0 起连续,sourceEventSeqs 也相应重映射。
幂等。 目标 id 由 sha256(projectRoot + sourceId) 推导,所以重复发布同一段对话会指向同一个会话并被跳过——即使归档的导入台账丢了也一样。
何时运行。 激活时,以及每次 turn/end 自动导出之后。会扫描两个来源,因为已经用过的项目磁盘上有归档,但可能没有活跃会话:
1. 每个打开的会话,各自进自己的项目文件夹;
2. ctx.workspaceRegistry 里的每个工作区——这是真实项目文件夹的有界权威列表——这样属于某个项目、但没有打开会话的归档也能被发布。
导出和发布是彼此独立的开关;autoExport 关掉时 autoImport 照样能用。
4. 导入分享出来的 Trae 对话
Trae share 链接是某段 Trae SOLO 对话的公开只读 transcript。conversation_import_share 把它变成调用方项目的一个会话:
share.traecontent.cn/api/remote/v1/share/<id> metadata
share.traecontent.cn/api/remote/v1/share/<id>/messages the turns
v
convertShare() → contiguous DSH events → SessionVault.adopt() → sidebar
事件才是事实来源。 归档里的 conversation.jsonl 由转换后的事件经 vault 自带的 normalizeConversation 派生而来,而不是另起一套并行生成,所以可读的对话记录和可导入的日志不会互相矛盾。转换结果会用 firstStructuralViolation 校验,也就是加载器执行的那套契约:每个问题对应一个 turn,每个 assistant step 都位于已打开的 step 和 turn 之内,每个对外声明的工具调用都有对应的 tool/call 和结果,session/title 只引用不同的、更早的人类 user/message 事件,step 编号遵循加载器自己的游标。
其中两条规则不是装饰——它们都是已经发布过的 bug,每一个都会让会话出现在侧边栏列表里,然后拒绝打开:
- 标题引用的是问题,不是 turn。 messageSeqs 是序列号,早一条语句读取句柄就会捕获到 turn/start。加载器会拒绝整个日志:session/title messageSeqs must cite distinct earlier human user/message events。
- step 按每个 turn 一个游标编号。 turn/start 会把加载器的 nextStep 重置为 1,每个 step/start 都必须等于它。把问题的 step 硬编码为 1,并让 assistant 的条目从 1 重新开始,会输出 1, 1, 2,并以 step/start does not match the open turn and next step 失败。
firstStructuralViolation 现在会检查这两条,所以出现回归的转换器会在 test/selfcheck.mjs 失败,而不是发布一个没人能读的会话。checks/share-verify-import.mjs 会针对存储中已有的会话重新检查这两条,checks/session-retire-broken.mjs 会报告(或退役)那些本工作区列出、但 DSH 无法打开的已存储会话——这正是两个 bug 造成的症状。
工具结果不是凭空编造的。 分享会剥掉大多数工具结果的载荷——本文所依据的分享中,38 次调用里有 18 次只留下一个状态。分享保留的内容(finish 摘要、grep 结果、文件 diff)会原样保留,其余一切都会记录为明确的 "(Trae's share does not include this call's output)",而不是记录为空成功,否则读起来就像「工具什么都没返回」。
finish 变成回复。 Trae 的智能体通过调用 finish 交出答案;把它记录为工具调用会让读者只看到一个名为 finish 的工具,却看不到答案,所以它的 summary 会作为 assistant 的文本输出。
时间按同一个偏移量读取。 Trae 用提问者的本地时钟给 turn 打时间戳,所以同一份分享会混用 +08:00 和 Z。按各自偏移量读取每个时间戳会让 turn 交错;多数时间戳一致的偏移量胜出,而会话自身的边界来自它的 turn——绝不来自 meta.created_at,那是分享发布的时间,可能晚好几周。
幂等。 归档 id 是 trae-share-<slugged share id>,发布的会话 id 由它派生,所以重新导入同一个链接会重写同一份归档,解析到同一个会话。
share:
enabled: true
apiBase: https://share.traecontent.cn # API origin, and the host links are cited from
timeoutMs: 30000
autoPublish: true # archive + publish in one call
agentPreset: standard # a share records none, and a session cannot resume without one
maxToolResultChars: 2000
headers: {} # extra request headers, when a deployment needs them
publish: false 只归档,不创建会话;之后用 conversation_publish 发布。这是整个 bundle 里唯一会联网的能力,也是唯一会读取本机之外内容的能力。
那些 -2 会话,以及实际修好了什么
导入链接分享,为同一个对话生成了两个已存会话——session-8c8624bb-… 和 session-8c8624bb-…-2——而且发生了两次,就在第一次写入后 87 ms。值得把修好的和没修的分开说,因为两者中只有一个有复现。
已修复且可复现:index.json 的更新会互相丢失。 updateIndex 和 recordImport 都是对同一个文件的读-改-写循环,而一次 publish 过程会在运行它们的同时,由这次 publish 启动的扫描也跑同样的循环。交错执行时,第二次写入基于第一次读到的状态构建,于是第一次 publish 的账本行就没了。回归测试(vault: concurrent index writes cannot lose each other)在没有修复时会失败,显示两个对话中有一个完全从索引里消失。现在这两个变更都走 queueIndexWrite,所以每次读取都发生在锁内。
第二处更窄的加固:如果账本行指向的会话已不存在,就在选定任何 id 之前把它指回派生 id(vault: a ledger naming a missing session is repaired, not left stale)。指向不存在会话的行比没有行更糟,因为它读起来像是「发布到别处了」。
未修复:采纳一个存在但读不回来的会话。 这才是真正造出 -2 名字的部分,而且能精确复现:发布一个对话,删掉已发布的会话,清掉它的账本行,再导入同一份分享。pickSessionId 只在能读回来时才保留一个被占用的 id——对于来源不明的日志,这是正确的直觉——所以读不出的产物会被跳过,副本落在它旁边,这就是 trace 里那两个 id 和 87 ms 的由来。
没修,是因为这里的状态无法判定。materialize 会给它发布的每个会话打上 cwd: this.projectRoot,所以一个由本 vault 发布、之后又失去归属的会话,和一个由归档文件夹从别的项目带进来的会话,在所有可用字段上都一模一样:同样的派生 id、同样的 cwd、同样的账本行。要区分它们,就会破坏 a session outside its workspace gets a copy under a fresh id,而那种情况这一点必须成立——悄悄复用另一个项目的会话,会让工作区显示出一段归档在别处的对话。区分依据得在会话发布时记录下来,目前还没有任何地方做这件事;这就是下一步要改的地方。
智能体工具
| 工具 | 用途 |
| conversation_list | 已归档的对话 + 已存储但未归档的会话 |
| conversation_read | 读取某段对话的记录(markdown、json 或 jsonl) |
| conversation_export | 归档当前会话、指定的活跃会话,或本项目全部活跃会话 |
| conversation_sync_from_disk | 把本项目已存储的 Harness 会话导入归档 |
| conversation_publish | 把已归档的对话实体化为真实、可恢复的 DSH 会话 |
| conversation_import_share | 导入分享的 Trae 对话(share.traecontent.cn 链接),作为本项目的一个会话 |
| conversation_workspaces | 报告工作区注册表把哪些会话归属到各个工作区 |
| trae_skill_list | 当前可调用的 Trae 技能,附来源文件 |
conversation_read 接受完整会话 id,也接受任意唯一后缀(例如 b0b7045)。
配置
可在配置档的 cordis.patch.yml 中,trae-vault 那一行下覆盖:
- id: trae-vault
config:
enabled: true
debugLog: '' # '' uses $DSH_HOME/trae-session-vault.activation.log
skills:
enabled: true
providerName: trae
customDirs: [] # extra SKILL.md roots, absolute or relative
scanUserHome: true # also scan ~/.trae/skills
watch: true
recursiveWatch: true
watchDebounceMs: 250
maxDepth: 6
vault:
enabled: true
directory: .dsh/conversations # relative to the project, or absolute
autoExport: true # archive conversations into the project
autoImport: false # publish archives back as real DSH sessions
includeRuntimeContext: false
maxToolResultChars: 2000
readGlobalSessions: true
sessionsRoot: '' # defaults to $DSH_HOME/sessions
share:
enabled: true
apiBase: https://share.traecontent.cn
timeoutMs: 30000
autoPublish: true
agentPreset: standard
maxToolResultChars: 2000
headers: {} # free-form; survives validation as written
debugLog 用 node:fs 写入,目标不可写时会故意吞掉错误——诊断绝不能弄坏激活流程。代价是:路径失效后,你悄悄失去全部追踪记录。
目录结构
| 文件 | 作用 |
| index.js | 稳定入口:解析 impl.r<REVISION>.js 并重新导出 |
| impl.r<REVISION>.js | 实现:apply、inject、Config、接线 |
| lib/skills.trae2.js | Trae 技能发现、frontmatter 解析、根目录遍历、监听 |
| lib/vault.trae2.js | 会话日志解析、规范化、归档存储、发布 |
| lib/zstd.trae2.js | 多帧 zstd 读取器 |
| lib/tools.trae2.js | 八个智能体工具 |
| lib/share.trae2.js | 分享链接解析、API 拉取、Trae→DSH 转换 |
入口为什么是个薄加载器
Harness 模块加载器按解析后的 URL 缓存模块任务,所以磁盘上替换过的 bundle 仍会继续执行它首次导入的那一代。实测行为:切换 bundle(plugin_manager 禁用/启用)并重装包,原本不会重新导入入口——REVISION 已经升到 10,进程里跑的仍是第 8 代。
index.js 依然解析带版本号的代号,所以实际在跑的是哪一代可以辨认:trace 的第一行会写明。改 REVISION 时,要同时改 impl.r<REVISION>.js。
按 URL 缓存同样作用于这一代自己的导入,这点更隐蔽,是踩了坑才测出来的。裸写 ./lib/vault.trae2.js 在进程整个生命周期里只解析成一个 URL,所以提高 REVISION 会重新加载这一代,然后把它重新接到上一代的 lib 模块上:磁盘上的文件、测试、各项检查全都一致,而运行中的插件还在用旧代码作答——替换路径修好之后,force: true 依然报「already present」。因此这一代会给每个 lib 说明符打上 ?v=<REVISION>。静态说明符没法插值,所以这个 token 是字面量;test/activation.mjs 会断言它等于 REVISION,这样忘记重新打戳会变成测试失败,而不是插件悄悄用旧代码。
bundle 还必须从存在的路径安装,DSH 才能解析它:配置档里的 link: 依赖指向一个已不存在的 checkout,bundle 就无法解析,插件会静默地永不激活。移动 checkout 之后,用 plugin_manager install_bundle(或 dsh plugin --profile <name> install)重新安装。那次安装会报 restart-required,而运行中的 Host 确实能在不重启的情况下接上新代号并注册新工具集——所以重启前先看工具列表。插件加载之前发布的会话存在于存储中,工作区注册表也会列出它,但侧边栏只能从 session/created 通知里得知它,所以要刷新页面(或用 force: true 调用 conversation_publish)才能看到。
依赖
无。Config 实现了 Host 读取的 Standard Schema 接口(Config['~standard'].validate),所以插件不需要 schema 包。这点很重要,因为链接进来的配置档 bundle 的裸导入会经由 checkout 上方碰巧存在的那个 node_modules 解析,依赖它可不是好事。
测试
node test/selfcheck.mjs # zstd, frontmatter, discovery, normalization, archive round-trip, share conversion
node test/activation.mjs # apply() against a mock context: provider, tools, export, publish, share import
../checks/config-shapes.mjs # the Config contract, tool schemas, registration guard
../checks/schema-shape.mjs # emitted output.schema against the enforced subset
全部跑在 DSH 运行时的 Node 上,不需要安装任何包。
test/fake-persistence.mjs 顶替会话存储 —— 测试从不写入真实存储 —— 同时按加载器的方式校验请求头和事件(assistant/message 必须内嵌 stream,seq 必须连续,cwd 必须是绝对路径)。mock 复刻了 dsh-tools 自己的 register() 守卫,因为缺失 output.render 和 parameters 根节点不是对象,这两种情况都曾让所有测试通过,却在 Host 里失败。
test/activation.mjs 按 DSH 的方式加载包,从 process.cwd() 取路径,所以要在包含这个文件夹的目录里运行:
cd .. && node dsh-trae-vault/test/activation.mjs
checks/config-shapes.mjs 和 checks/schema-shape.mjs 是工作区级契约检查;它们按相对路径导入包,所以只有开发检出才能用,裸克隆用不了。
分享路径可以对着线上服务端到端跑一遍:
node test/share-import-live.mjs [shareUrl]
它会拉取真实分享、转换、归档进一个临时项目文件夹,再通过一个持久化替身发布出去,替身按加载器的方式校验每个事件。剩下的 test/share-.mjs 和 test/session-.mjs 脚本都是诊断工具,各自把输入当参数传入:share-convert-real.mjs 和 share-timeline.mjs 为保存的 messages 载荷报告事件时间线,share-verify-import.mjs 按加载器契约检查已发布的会话,session-retire-broken.mjs 列出(或退役)DSH 打不开的已存会话,share-probe-msgseqs.mjs 打印转换实际产生的 emit 顺序 —— 两个 session/title 和步骤编号 bug 就是这么找出来的。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
lincoo2019/dsh-trae-vault
把 Trae 技能与对话归档进项目,随时读回继续
相关插件 · 模型接入
API 中继安全审计toby-bridges/api-relay-audit
面向 AI API 中转与 LLM 代理的本地安全审计。
★ 897已汉化DSH
69.4
免费搜索插件DDDMUC/dsh-free-search
DeepSeek Harness 免费搜索插件 —— 无需 API key,零成本,多引擎可切换。 一个给…
★ 761已汉化DSH
68.7
免费联网搜索liustack/modsearch
在官方 App 里模型能联网,切到 API 就不能了。ModSearch 把联网补回来:网页搜索、X…
★ 863已汉化DSH
68.5
OpenCode 免费模型FishBottle7/opencode2dsh
在 DSHDeepSeek Harness里原生使用 OpenCode Zen 的免费匿名模型。
★ 379已汉化DSH
67.8
AI 模型网关tingly-dev/tingly-box
Tingly Box Web UI 演示
★ 373已汉化DSH
67.4
WorkBuddy 账号池XDTrees/dsh-xdpool
把你能白嫖的模型额度接进 DSH 同一个池:WorkBuddy 多账号自动容错、十三家扫码登录、76…
★ 359已汉化DSH
67.1