本地插件定制 ishanshmalviya5/dsh-local-plugins
DeepSeek 客户端v0.3.0把插件改成自己的版本,更新重装都不丢改动
34.2/100
综合分
6
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/23 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
相关生态插件(非 dsh 原生,按其对应运行时安装)
git clone https://github.com/ishanshmalviya5/dsh-local-plugins.git状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
生态应用
桌面端 / Web 外壳,不以 dsh plugin add 安装
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 10 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装engines.node 要求 >=26,不满足 Node 22.19.0
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✓npm 包dsh-local-plugins @ 0.3.0
✗Node 引擎要求 >=26 · 基线 Node 22.19 不满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/23 15:53:59
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件写入剪贴板(不计风险)发起外部网络请求
查看扫描证据(共 148 处,展示前 116 条)
- 发起网络请求client/client.js:41
const res = await fetch(`${API}/${action}`, { - 写入剪贴板client/client.js:179
await navigator.clipboard.writeText(text); - 读取本地文件lib/env.js:22
return JSON.parse(readFileSync(file, 'utf8')); - 读取本地文件lib/env.js:26
try { lstatSync(p); return true; } catch { return false; } - 读取本地文件lib/env.js:34
if (existsSync(pj)) { - 读取本地文件lib/env.js:95
return readdirSync(scopeDir).filter((n) => !n.startsWith('.')).map((n) => `@deepseek-ai/${n}`).sort(); - 读取本地文件lib/actions.js:145
if (existsSync(env.repoDir(name))) throw fail(`A folder for ${name} already exists at ${env.repoDir(name)} (from an earlier add, or moved back from th - 读取本地文件lib/actions.js:180
if (lstatSync(loc.path).isSymbolicLink()) throw fail(`${loc.path} is already a symlink (something else manages it), so it cannot be migrated. Nothing - 删除本地文件递归lib/actions.js:189
rmSync(dir, { recursive: true, force: true }); - 写入本地文件lib/actions.js:206
mkdirSync(env.root, { recursive: true }); - 写入本地文件lib/actions.js:214
renameSync(tmp, env.repoDir(name)); - 删除本地文件递归lib/actions.js:220
rmSync(tmp, { recursive: true, force: true }); - 删除本地文件递归lib/actions.js:233
rmSync(env.repoDir(name), { recursive: true, force: true }); - 读取本地文件lib/actions.js:291
try { stat = lstatSync(p.core.path); } catch { } - 删除本地文件递归lib/actions.js:338
rmSync(join(work, 'node_modules'), { recursive: true, force: true }); - 删除本地文件递归lib/actions.js:340
rmSync(work, { recursive: true, force: true }); - 写入本地文件lib/actions.js:377
mkdirSync(env.workDir, { recursive: true }); - 删除本地文件递归lib/actions.js:414
rmSync(join(work, 'node_modules'), { recursive: true, force: true }); - 读取本地文件lib/actions.js:549
const pkg = JSON.parse(readFileSync(file, 'utf8')); - 写入本地文件lib/actions.js:561
writeFileSync(file, `${JSON.stringify(pkg, null, 2)}\n`); - 写入本地文件lib/actions.js:672
mkdirSync(env.trashDir, { recursive: true, mode: 0o700 }); - 写入本地文件lib/actions.js:677
renameSync(env.repoDir(name), trash); - 读取本地文件lib/actions.js:697
if (!existsSync(path)) return 0; - 读取本地文件lib/actions.js:708
const listDir = (d) => { try { return readdirSync(d); } catch { return []; } }; - 写入本地文件lib/ops.js:14
mkdirSync(dirname(file), { recursive: true, mode: 0o700 }); - 写入本地文件lib/ops.js:15
try { if (statSync(file).size > LOG_MAX) renameSync(file, `${file}.1`); } catch { } - 读取本地文件lib/ops.js:15
try { if (statSync(file).size > LOG_MAX) renameSync(file, `${file}.1`); } catch { } - 写入本地文件lib/ops.js:16
appendFileSync(file, `${JSON.stringify({ id: op.id, kind: op.kind, plugin: op.target, action: op.request?.action ?? null, commit: op.result?.deployedS - 读取本地文件lib/registry.js:109
raw = readFileSync(file, 'utf8'); - 读取本地文件lib/registry.js:137
try { const v = JSON.parse(readFileSync(file, 'utf8')).version; return Number.isInteger(v) ? v : null; } catch { return null; } - 写入本地文件lib/registry.js:145
if (!existsSync(bak)) copyFileSync(file, bak); - 读取本地文件lib/registry.js:145
if (!existsSync(bak)) copyFileSync(file, bak); - 写入本地文件lib/registry.js:151
mkdirSync(dirname(file), { recursive: true, mode: 0o700 }); - 写入本地文件lib/registry.js:154
writeFileSync(tmp, `${JSON.stringify({ ...reg, version: CURRENT_VERSION }, null, 2)}\n`, { mode: 0o600 }); - 写入本地文件lib/registry.js:157
renameSync(tmp, file); - 写入本地文件lib/registry.js:158
try { chmodSync(file, 0o600); } catch { } - 写入本地文件lib/registry.js:178
if (existsSync(file)) { kept = `${file}.corrupt-${new Date().toISOString().replace(/[:.]/g, '-')}`; copyFileSync(file, kept); } - 读取本地文件lib/registry.js:178
if (existsSync(file)) { kept = `${file}.corrupt-${new Date().toISOString().replace(/[:.]/g, '-')}`; copyFileSync(file, kept); } - 执行外部命令固定命令lib/registry.js:185
const gitq = (dir, ...args) => { try { return execFileSync('git', ['-C', dir, ...args], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).tri - 读取本地文件lib/registry.js:194
try { dirs = readdirSync(env.root, { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith('.')); } catch { return out; } - 读取本地文件lib/registry.js:197
if (!existsSync(join(dir, '.git')) || !gitq(dir, 'rev-parse', '--verify', '--quiet', 'local') || !gitq(dir, 'rev-parse', '--verify', '--quiet', 'upstr - 写入本地文件lib/repo.js:16
await mkdir(infoDir, { recursive: true }); - 写入本地文件lib/repo.js:17
await appendFile(join(infoDir, 'exclude'), '\n# dsh-local-plugins\nnode_modules\n'); - 读取本地文件lib/repo.js:22
for (const entry of await readdir(dir)) { - 删除本地文件递归lib/repo.js:24
await rm(join(dir, entry), { recursive: true, force: true }); - 写入本地文件lib/repo.js:30
await mkdir(dir, { recursive: true }); - 读取本地文件lib/repo.js:86
for (const entry of await readdir(dir)) if (!skip(entry)) await rm(join(dir, entry), { recursive: true, force: true }); - 删除本地文件递归lib/repo.js:86
for (const entry of await readdir(dir)) if (!skip(entry)) await rm(join(dir, entry), { recursive: true, force: true }); - 删除本地文件递归lib/repo.js:105
await rm(tmp, { recursive: true, force: true }); - 读取本地文件lib/sources.js:62
return existsSync(dir) ? dir : null; - 读取本地文件lib/sources.js:70
return (await readdir(dir)).filter((f) => f.endsWith('.tgz')).map((f) => f.slice(0, -4)).sort(compareVersions); - 读取本地文件lib/sources.js:138
try { pkg = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')); } catch (err) { throw Object.assign(new Error(`the package has no readable pa - 读取本地文件lib/sources.js:166
for (const name of await readdir(dir)) { - 读取本地文件lib/sources.js:168
const st = await lstat(p); - 读取本地文件lib/sources.js:170
const target = resolve(dirname(p), await readlink(p)); - 写入本地文件lib/sources.js:201
await mkdir(ex); - 删除本地文件递归lib/sources.js:212
await rm(tmp, { recursive: true, force: true }); - 读取本地文件lib/deploy.js:41
const scripts = JSON.parse(readFileSync(join(pkgDir, 'package.json'), 'utf8')).scripts ?? {}; - 读取本地文件lib/deploy.js:49
try { entries = readdirSync(nm); } catch { return found; } - 读取本地文件lib/deploy.js:52
if (e.startsWith('@')) { try { for (const s of readdirSync(join(nm, e))) check(join(nm, e, s), `${e}/${s}`); } catch { } } else check(join(nm, e), e) - 读取本地文件lib/deploy.js:59
const missing = Object.keys(pkg.dependencies ?? {}).filter((d) => !existsSync(join(dir, 'node_modules', d, 'package.json'))); - 读取本地文件lib/deploy.js:95
const missing = [...wanted].filter((f) => !existsSync(join(dir, f))); - 读取本地文件lib/deploy.js:100
for (const e of readdirSync(d, { withFileTypes: true })) { - 写入本地文件lib/deploy.js:137
renameSync(tmp, link); - 删除本地文件lib/deploy.js:139
if (!isCrash(err)) rmSync(tmp, { force: true }); - 写入本地文件lib/deploy.js:167
mkdirSync(dst, { recursive: true }); - 删除本地文件lib/deploy.js:171
rmSync(dst, { force: true }); - 写入本地文件lib/deploy.js:181
mkdirSync(target, { recursive: true }); - 删除本地文件递归lib/deploy.js:238
rmSync(join(dir, 'node_modules'), { recursive: true, force: true }); - 写入本地文件lib/deploy.js:278
mkdirSync(env.deployedDir, { recursive: true }); - 写入本地文件lib/deploy.js:281
writeFileSync(join(snap, READY), `${sha}\n`); - 删除本地文件递归lib/deploy.js:285
rmSync(snap, { recursive: true, force: true }); - 写入本地文件lib/deploy.js:293
mkdirSync(env.deployedDir, { recursive: true }); - 删除本地文件lib/deploy.js:323
try { unlinkSync(env.stableLink(plugin.name)); } catch { } - 读取本地文件lib/link.js:24
if (!lstatSync(path).isSymbolicLink()) return false; - 删除本地文件递归lib/link.js:53
rmSync(installed, { recursive: true, force: true }); - 写入本地文件lib/link.js:54
mkdirSync(dirname(installed), { recursive: true }); - 删除本地文件递归lib/link.js:81
rmSync(join(env.profileDir, 'node_modules', plugin.name), { recursive: true, force: true }); - 写入本地文件lib/link.js:92
renameSync(from, to); - 删除本地文件递归lib/link.js:96
rmSync(from, { recursive: true, force: true }); - 删除本地文件递归lib/link.js:104
rmSync(nestedDst, { recursive: true, force: true }); - 读取本地文件lib/link.js:105
if (existsSync(nestedSrc) && !lstatSync(plugin.core.path).isSymbolicLink()) { - 读取本地文件lib/link.js:105
if (existsSync(nestedSrc) && !lstatSync(plugin.core.path).isSymbolicLink()) { - 写入本地文件lib/link.js:106
mkdirSync(dirname(nestedDst), { recursive: true }); - 删除本地文件lib/link.js:120
if (st?.isSymbolicLink()) unlinkSync(path); - 写入本地文件lib/link.js:124
mkdirSync(env.backupDir, { recursive: true }); - 删除本地文件递归lib/link.js:125
rmSync(backup, { recursive: true, force: true }); - 读取本地文件lib/link.js:142
if (plugin.core.backup && existsSync(plugin.core.backup)) { - 写入本地文件lib/link.js:146
mkdirSync(path, { recursive: true }); - 读取本地文件lib/link.js:154
try { return lstatSync(p); } catch { return null; } - 读取本地文件lib/gitstate.js:18
if (!existsSync(join(dir, '.git'))) return null; - 写入本地文件lib/txn.js:40
mkdirSync(env.txnDir, { recursive: true, mode: 0o700 }); - 写入本地文件lib/txn.js:42
writeFileSync(tmp, JSON.stringify(txn, null, 2), { mode: 0o600 }); - 写入本地文件lib/txn.js:45
renameSync(tmp, file(env, txn.id)); - 删除本地文件lib/txn.js:64
rmSync(file(env, txn.id), { force: true }); - 读取本地文件lib/txn.js:70
try { names = readdirSync(env.txnDir).filter((n) => n.endsWith('.json')); } catch { return []; } - 读取本地文件lib/txn.js:72
try { return { ...JSON.parse(readFileSync(join(env.txnDir, n), 'utf8')), file: join(env.txnDir, n) }; } catch (err) { return { id: n, corrupt: true, e - 读取本地文件lib/recovery.js:21
const lstatSafe = (p) => { try { return lstatSync(p); } catch { return null; } }; - 读取本地文件lib/recovery.js:34
try { return readFileSync(join(dir, READY), 'utf8').trim() || null; } catch { return null; } - 读取本地文件lib/recovery.js:40
return existsSync(t) ? t : null; - 读取本地文件lib/recovery.js:50
if (!existsSync(d)) { if (d === env.root) mkdirSync(d, { recursive: true, mode: 0o700 }); else continue; } - 写入本地文件lib/recovery.js:50
if (!existsSync(d)) { if (d === env.root) mkdirSync(d, { recursive: true, mode: 0o700 }); else continue; } - 读取本地文件lib/recovery.js:51
const st = statSync(d); - 写入本地文件lib/recovery.js:52
if ((st.mode & 0o077) !== 0) { chmodSync(d, 0o700); fixed.push(d); log?.(`made ${d} private (0700)`); } - 读取本地文件lib/recovery.js:72
try { names = readdirSync(dir); } catch { continue; } - 删除本地文件lib/recovery.js:78
if (st.isSymbolicLink() || st.isFile()) { unlinkSync(p); note(`stale temp ${n}`); } - 删除本地文件递归lib/recovery.js:86
if (m && Date.now() - Number(m[1]) > 10 * 60_000) { rmSync(join(env.root, n), { recursive: true, force: true }); note(`abandoned download ${n}`); } - 删除本地文件递归lib/recovery.js:108
rmSync(join(p, 'node_modules'), { recursive: true, force: true }); - 删除本地文件递归lib/recovery.js:110
rmSync(p, { recursive: true, force: true }); - 删除本地文件lib/recovery.js:140
rmSync(t.file, { force: true }); - 删除本地文件lib/recovery.js:210
unlinkSync(path); - 写入本地文件lib/recovery.js:277
writeFileSync(join(target, READY), `${p.deployedSha}\n`); - 执行外部命令来自配置/变量lib/run.js:51
const child = spawn(file, args, { - 写入本地文件lib/restart.js:52
mkdirSync(logDir, { recursive: true }); - 执行外部命令来自配置/变量lib/restart.js:54
const helper = spawn(process.execPath, ['-e', helperCode({ file: process.execPath, args, cwd: process.cwd(), logFile, port })], { - 读取本地文件lib/syntax-check.mjs:18
try { src = readFileSync(file, 'utf8').replace(/^#!.*/, ''); } catch (e) { bad.push({ file, message: `unreadable: ${e.message}` }); continue; }
扫描于 2026/11/1(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
把编辑过的 dsh 插件保存为本地 git 仓库,通过原子符号链接切换部署已提交的快照。
README
由 DeepSeek 最新模型翻译生成dsh-local-plugins
定制任意 dsh 插件——内置插件也行——更新、损坏或重装时都不丢改动。
设置 → Local Plugins:列出你定制的每个插件、用大白话写的状态,以及你接下来大概率想做的操作
能拿它做什么
| 你想…… | 你点…… | 你得到…… |
| 修好或微调插件,并留住改动 | + Add → Migrate,编辑,Commit,Apply | 改动在 dsh 里跑起来,更新和重装都不丢 |
| 拿到作者的新版本,又不丢自己的微调 | Update | 新版本加上你的改动;两边改了同一行会先问你,期间不会出问题 |
| 改动出问题时回退 | Deploy older commit…
展开完整文档(README 剩余 1 节)
dsh-local-plugins 定制任意 dsh 插件——内置插件也行——更新、损坏或重装时都不丢改动。 设置 → Local Plugins:列出你定制的每个插件、用大白话写的状态,以及你接下来大概率想做的操作 能拿它做什么 | 你想…… | 你点…… | 你得到…… | | 修好或微调插件,并留住改动 | + Add → Migrate,编辑,Commit,Apply | 改动在 dsh 里跑起来,更新和重装都不丢 | | 拿到作者的新版本,又不丢自己的微调 | Update | 新版本加上你的改动;两边改了同一行会先问你,期间不会出问题 | | 改动出问题时回退 | Deploy older commit… | 立刻回到早先的版本 | | 定制 dsh 内置功能(比如某个模型服务商) | 同样的步骤,作用在内置插件上 | 你的版本跑起来;Unlink 还原原版 | | 让 AI 智能体安全地改插件 | Work on it | 智能体在该插件目录里打开,上下文已填好;它不能开启任何东西——只有你能 | | 整理提交历史,让更新更省事 | Squash my changes | 智能体把你的提交全部压成一个,叠在原始发布版之上;先建备份分支,并检查代码没变 | | 把依赖固定到更新的版本 | Dependency overrides → Apply override | 覆盖项保存、部署并检查:真正装上了才显示 ✔ | | dsh 升级或重装后恢复 | Reapply all | 你的定制重新开启 | | 试某个确切版本 | + Add,name@1.2.3(或 …#v1.2.0) | 就是那个版本,而且固定不动 | | 看自己相对原版改了什么 | 看卡片 | 「相对原版改了 3 个文件」,以及当前正在跑的是什么 | | 不再定制某个插件 | Unlink,想的话再 Delete… | 原版回来了;你的成果留在回收站文件夹里,可以恢复 | | 把成果也存到别处 | 它就是个普通 git 文件夹:~/.dsh/local-plugins/<plugin> | 加自己的 git remote 推上去 | 出问题时,它会告诉你当前配置是否仍然安全、下一步该做什么——不会只甩一句「失败」。 Apply 失败:什么都没开启,面板会告诉你下一步做什么 安装(2 分钟) 1. 在终端里执行(如果你用的是别的配置档,把 web 换成你的配置档名): dsh plugin --profile web add github:ishanshmalviya5/dsh-local-plugins 2. 重启 dsh web。 3. 打开 Settings → Local Plugins。 需要 git、npm 和 Node 26 或更新版本,系统为 macOS 或 Linux(详情)。 你的第一次定制 1. + Add → Migrate,挑一个你已经在用的插件。你之前手动改过的内容都会保留,作为起点。 2. 动手改——编辑 ~/.dsh/local-plugins/<plugin> 里的文件,或者点 Work on it,让 AI 智能体陪你一起改。 3. Commit,然后 Apply,再重启 dsh web。 整个循环就这些。在你点 Apply 之前,dsh 不会有任何变化;如果新版本构建不出来,或者过不了检查,旧版本照常运行。 更多场景 作者发布了新版本 点 Check now(dsh 启动后不久也会自动检查一次)。有新版本的插件会显示 Update available,点 Update。你的改动和新版本会自动合并。如果你和作者改了同样的行,卡片会列出这些文件,由你来选:修好它们(或点 Fix with agent)再点 Finish update,或者点 Abort 放弃这次尝试。整个过程里正在运行的插件不受影响,什么时候 Apply 由你决定。 一次有冲突的更新:涉及哪些文件,以及三个安全选项 某次改动把事情搞砸了 点 Deploy older commit…,挑一个能用的版本。如果 dsh 本身在你应用了某个改动之后立刻开始出问题,它会自己发现,把上一个能用的版本放回去,并弹出提示——你的改动已经保存好,你可以用 Work on it 去修。 如果 dsh 完全起不来,在终端里运行下面这条命令,把所有原始插件放回去:node ~/.dsh/local-plugins/.deployed/dsh-local-plugins/scripts/undo.mjs --all 我在定制一个内置插件,现在想退出 Unlink (restore original) 会把原始、未改动的插件还给 dsh。你的版本仍留在列表里(标为 Not applied),想切回来随时点 Apply。 我想从列表里删掉一个插件 先 Unlink,再 Delete… 并输入它的名字。你的工作成果会移到 ~/.dsh/local-plugins/.trash/,不会被抹掉。把文件夹移回来,点 Repair installation 就能恢复。 我不知道现在是什么状态 点 Repair installation。它会找出所有对不上的地方(比如崩溃之后,或者 dsh 升级之后),能安全修的直接修,修不了的告诉你,并且绝不会删掉你的工作成果。Recent operations 显示跑过哪些操作、花了多久,还有日志;Disk usage 显示每个插件占用的空间,并让你先预览再清理旧版本。 最近操作与磁盘占用 使用精确版本 npm 插件:name、name@1.2.3 或 name@beta。git 来源的插件:网址、github:owner/repo 或 git@host:owner/repo,末尾可选 #v1.2.0(某个发布版本)、#branch 或 #commit。锁定到发布版本或 commit 后,它永远不会自己变动。 各标签的含义 | 标签 | 含义 | 你要做什么 | | Applied | dsh 正在运行你的最新版本 | 什么都不用做 | | Changes pending | 你有更新的改动或未提交的改动,尚未运行 | Commit,然后 Apply | | Update available | 作者发布了更新版本 | Update | | Conflict | 某次更新涉及一些文件,需要你决定 | Finish update 或 Abort | | Link lost / Reapply required | dsh 升级或重装了 | Reapply all(可放心重复执行) | | Broken | 记录与文件对不上 | Repair installation | | Disabled | 它让 dsh 崩溃,已被移出,好让 dsh 能启动 | Work on it,修好,Commit,Apply | | Not applied | 你在跟踪它,但 dsh 用的是普通插件 | 想用自己的版本时点 Apply | 控制权始终在你手里 * 脚本需要你同意。 有些插件想以你的完整权限运行安装或构建脚本。这项默认关闭;你可以选 Allow this time 或 Always allow for this plugin,发布者变更时会再次询问。 插件正在请求权限:尚未上线任何内容 * 你的工作不会悄悄丢失。 取消关联、删除、回滚和崩溃恢复都会把你的改动留在某个地方,随时能取回。 * 只有完成并检查过的版本才会被启用 —— 绝不会是改了一半的版本。 * 它只与你跟踪的来源通信(插件的 git 或 npm 源)。 如何保证这些:Security · Recovery · How it works。 兼容性 —— dsh-local-plugins 0.3.0 | 平台 | 状态 | | macOS(Apple silicon),Node 26 | ✅ 支持。 已对真实 dsh 手工端到端测试,也在 CI 中测试 | | Linux(Ubuntu),Node 26 | 🟡 CI 中 lint、全部单元测试和包检查均通过。尚未对真实 dsh 做端到端测试 | | Linux,Node 22 / 24 | 🟡 CI 结果相同,但超出支持范围(需要 Node 26 或更新版本) | | Windows | ❌ 不支持 —— 它会明确提示,并且不启动 | 基于 dsh 0.2.0-rc.2 构建并测试。从 0.1 版本升级无需你做任何事:插件保持原样(详见 CHANGELOG)。 须知 * 如果某个插件在这款插件加载之前就让 dsh 崩溃,它自己修不了 —— 请用上面的 undo.mjs 命令。 * 上线前的检查只确认文件完整可读,不会先运行插件。 * 内置插件跟随 dsh 自带的版本,而不是更新的 npm 发布版。 * 它一次只做一件事;它忙的时候你点了,它会让你稍等。 面向开发者 HTTP API · 状态规则 · 故障排查 · 性能 · 发布检查清单 · 开发 欢迎贡献,AI 辅助的贡献也欢迎:先读 CONTRIBUTING.md(编码智能体另见 AGENTS.md)。 许可证 MIT — 见 LICENSE。
预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
ishanshmalviya5/dsh-local-plugins
把插件改成自己的版本,更新重装都不丢改动
相关插件 · 开发 / 工程
隐私简历生成器reactive-resume/reactive-resume
Reactive Resume 已迁至 GitHub 上的…
★ 45,125已汉化MCP
71.7
AI 架构文档生成器sopaco/deepwiki-rs
🚀 Litho 已进化为 Terrain —— 给你的 AI 智能体一张会呼吸的代码库地图。
★ 3,157已汉化DSH
70.8
长时任务执行闭环AMAP-ML/LongHorizon-Harness
面向 Computer-Use Agent 的 Loop Engineering
★ 1,764已汉化DSH
70.5
AI 编程纪律方法包GanyuanRan/Aegis
让 AI 编程 agent 变得可信:少返工、更安全、说“完成”前先给证据。
★ 1,384已汉化DSH
69.6
多代理编排运行时Enderfga/claw-orchestrator
面向编程智能体的运行时。把 Claude Code、Codex、Antigravity、Grok…
★ 586已汉化MCP
69.4
记忆进化插件csyangwen/dsh-memory-evolve
dsh-memory-evolve 使用场景指南
★ 461已汉化DSH
67.9