隔离环境开发调试插件,验证后一键晋级正式版
33.2/100
综合分
3
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/8/21 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
自动兼容检查有告警:npm 同名包「dsh-forge」归属 dushaobindoudou/dsh-forge,装到的可能不是本插件。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add zhn1100/dsh-forge该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:仅索引
是什么
dsh 原生插件 · dev
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 79 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查⚠ 装前注意npm 同名包「dsh-forge」归属 dushaobindoudou/dsh-forge,装到的可能不是本插件
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✓npm 包dsh-forge @ 0.0.1
✓Node 引擎要求 ^22.19.0 || >=24.0.0 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/17 10:23:58
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件
查看扫描证据(共 91 处,展示前 58 条)
- 执行外部命令来自配置/变量src/cli.ts:63
const child = spawn(command, args, { - 写入本地文件src/cli.ts:115
await chmod(root, 0o700) - 读取本地文件src/cli.ts:116
const entries = await readdir(root, { withFileTypes: true }) - 写入本地文件src/cli.ts:121
else await chmod(path, 0o600) - 读取本地文件src/cli.ts:127
const exists = await stat(target).then(() => true, () => false) - 写入本地文件src/cli.ts:129
if (exists) await rename(target, `${target}.backup-${Date.now()}`) - 写入本地文件src/cli.ts:131
await mkdir(dirname(target), { recursive: true, mode: 0o700 }) - 写入本地文件src/cli.ts:138
await mkdir(extracted) - 删除本地文件递归src/cli.ts:144
await rm(temporary, { recursive: true, force: true }) - 读取本地文件src/cli.ts:147
const composition = await readFile(compositionPath, 'utf8') - 写入本地文件src/cli.ts:148
await writeFile(compositionPath, `${composition.trimEnd()}\n\n# DSH Forge model-facing control-plane consumers.\n- id: forge-tools\n name: dsh-forge/ - 读取本地文件src/cli.ts:165
const before = await readFile(workspacePath, 'utf8') - 读取本地文件src/cli.ts:182
const bytes = await readFile(generated) - 读取本地文件src/cli.ts:185
const existing = await stat(artifact).catch(() => undefined) - 删除本地文件递归src/cli.ts:190
await rm(staging, { recursive: true, force: true }) - 写入本地文件src/experiment-store.ts:52
await mkdir(dirname(path), { recursive: true }) - 写入本地文件src/experiment-store.ts:54
await writeFile(temporary, `${JSON.stringify(experiment, null, 2)}\n`, { encoding: 'utf8', mode: 0o600 }) - 写入本地文件src/experiment-store.ts:55
await rename(temporary, path) - 读取本地文件src/experiment-store.ts:80
return JSON.parse(await readFile(this.path(id), 'utf8')) as Experiment - 读取本地文件src/experiment-store.ts:84
const names = await readdir(this.root).catch(() => []) - 读取本地文件src/experiment-store.ts:88
experiments.push(JSON.parse(await readFile(join(this.root, name), 'utf8')) as Experiment) - 写入本地文件src/home-sync.ts:68
await mkdir(dirname(path), { recursive: true, mode: 0o700 }) - 写入本地文件src/home-sync.ts:71
await writeFile(temporary, data, { mode }) - 写入本地文件src/home-sync.ts:72
await rename(temporary, path) - 写入本地文件src/home-sync.ts:73
await chmod(path, mode) - 删除本地文件src/home-sync.ts:75
await rm(temporary, { force: true }).catch(() => undefined) - 读取本地文件src/home-sync.ts:82
const value = JSON.parse(await readFile(path, 'utf8')) as Partial<SyncManifest> - 读取本地文件src/home-sync.ts:107
const destinationMetadata = await lstat(destination).catch(() => undefined) - 写入本地文件src/home-sync.ts:111
await mkdir(destination, { recursive: true, mode: 0o700 }) - 读取本地文件src/home-sync.ts:130
const sourceMetadata = await lstat(source).catch(() => undefined) - 读取本地文件src/home-sync.ts:150
metadata = await lstat(sourcePath) - 读取本地文件src/home-sync.ts:160
const target = await lstat(destinationPath).catch(() => undefined) - 写入本地文件src/home-sync.ts:166
await mkdir(destinationPath, { recursive: true, mode: metadata.mode & 0o777 }) - 读取本地文件src/home-sync.ts:167
const children = await readdir(sourcePath) - 读取本地文件src/index.ts:126
const metadata = await stat(path).catch(() => undefined) - 读取本地文件src/index.ts:149
const profileManifest = await readFile(join(home, 'profiles', 'forge', 'package.json'), 'utf8').then( - 读取本地文件src/index.ts:159
const forgeDependency = profileManifest && (JSON.parse(await readFile(join(home, 'profiles', 'forge', 'package.json'), 'utf8')) as { dependencies?: Re - 读取本地文件src/index.ts:160
const installedMetadata = await lstat(join(home, 'profiles', 'forge', 'node_modules', 'dsh-forge')).catch(() => undefined) - 读取本地文件src/indexer.ts:12
const entries = await readdir(current, { withFileTypes: true }) - 执行外部命令固定命令src/indexer.ts:210
const result = spawnSync('git', ['-C', root, ...args], { encoding: 'utf8' }) - 读取本地文件src/indexer.ts:217
const rootStat = await stat(root) - 读取本地文件src/indexer.ts:229
const text = await readFile(absolute, 'utf8').catch(() => '') - 读取本地文件src/indexer.ts:246
const rootManifest = JSON.parse(await readFile(join(root, 'package.json'), 'utf8')) as { version?: string } - 写入本地文件src/indexer.ts:268
await mkdir(dirname(output), { recursive: true }) - 写入本地文件src/indexer.ts:269
await writeFile(output, `${JSON.stringify(index)}\n`, { encoding: 'utf8', mode: 0o600 }) - 写入本地文件src/indexer.ts:273
await mkdir(dirname(destination), { recursive: true }) - 读取本地文件src/indexer.ts:275
await stat(join(destination, '.git')) - 执行外部命令固定命令src/indexer.ts:277
const clone = spawnSync('git', ['clone', '--filter=blob:none', REPOSITORY, destination], { encoding: 'utf8' }) - 执行外部命令固定命令src/indexer.ts:280
const fetch = spawnSync('git', ['-C', destination, 'fetch', '--prune', 'origin'], { encoding: 'utf8' }) - 执行外部命令固定命令src/indexer.ts:283
const checkout = spawnSync('git', ['-C', destination, 'checkout', '--detach', resolved], { encoding: 'utf8' }) - 读取本地文件src/knowledge-store.ts:73
const metadata = await stat(this.indexPath).catch(() => undefined) - 读取本地文件src/knowledge-store.ts:78
const parsed = JSON.parse(await readFile(this.indexPath, 'utf8')) as KnowledgeIndex - 写入本地文件src/promoter.ts:15
await mkdir(dirname(path), { recursive: true }) - 写入本地文件src/promoter.ts:16
await writeFile(path, content, { encoding: 'utf8', mode: 0o600, flag: 'wx' }) - 读取本地文件src/promoter.ts:24
const exists = await stat(destination).then(() => true, () => false) - 执行外部命令固定命令src/verifier.ts:12
const child = spawn('pnpm', ['run', script], { cwd: root, env: process.env, stdio: ['ignore', 'pipe', 'pipe'] }) - 读取本地文件src/verifier.ts:44
const metadata = await stat(root) - 读取本地文件src/verifier.ts:46
const manifest = JSON.parse(await readFile(resolve(root, 'package.json'), 'utf8')) as { scripts?: Record<string, string> }
扫描于 2026/11/3(0 天前) · 范围 全包扫描(包内未声明入口) · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-system-prompt@deepseek-ai/dsh-tools给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 隔离环境开发调试
- 验证后一键晋级正式版
- 可复现开发环境
可复现的 DeepSeek Harness 插件开发环境
README
由 DeepSeek 最新模型翻译生成DSH Forge
面向 DeepSeek Harness 的独立插件开发环境。它把源码参考、运行时检查、实验记录、验证和正式化流程收进一个可复现的 Forge Profile,同时避免污染日常使用的 DSH 环境。
当前版本针对 @deepseek-ai/dsh@0.1.0-rc.6,参考源码固定在官方提交 47f943859bef60e4160492346772ded9b24f765a。本项目不是 DeepSeek 官方项目。
能做什么
- 建立独立的 ~/.dsh-forge Home、forge Profile 和开发者 Agent Preset。
- 本地索引 Harness 文档、源码符号、Service、事件、工具、Config 和示例。
- 管理可恢复的插件实验、验证状态与 Promotion scaffold。
- 提供受限的 quick、package、full 验证流程。
- 每次启动安全同步普通 ~/.dsh 中的用户配置,同时保护 Forge 本地修改。
- 每次启动镜像普通 ~/.dsh 各 Profile 通过 cordis.patch.yml insert 声明的 out-of-tree 插件(包目录 + Forge Profile 注册),让主线的插件在 Forge 环境同样可用。
展开完整文档(README 剩余 1 节)
DSH Forge 面向 DeepSeek Harness 的独立插件开发环境。它把源码参考、运行时检查、实验记录、验证和正式化流程收进一个可复现的 Forge Profile,同时避免污染日常使用的 DSH 环境。 当前版本针对 @deepseek-ai/dsh@0.1.0-rc.6,参考源码固定在官方提交 47f943859bef60e4160492346772ded9b24f765a。本项目不是 DeepSeek 官方项目。 能做什么 - 建立独立的 ~/.dsh-forge Home、forge Profile 和开发者 Agent Preset。 - 本地索引 Harness 文档、源码符号、Service、事件、工具、Config 和示例。 - 管理可恢复的插件实验、验证状态与 Promotion scaffold。 - 提供受限的 quick、package、full 验证流程。 - 每次启动安全同步普通 ~/.dsh 中的用户配置,同时保护 Forge 本地修改。 - 每次启动镜像普通 ~/.dsh 各 Profile 通过 cordis.patch.yml insert 声明的 out-of-tree 插件(包目录 + Forge Profile 注册),让主线的插件在 Forge 环境同样可用。 - 使用 SHA-256 内容寻址 tarball 安装自身,避免复用旧包缓存。 - 将 Cordis、System Prompt 和 Tools 保持为宿主提供的可选 peer,避免 Profile 内重复运行时破坏 Symbol 身份。 - 升级时先由 DSH 正常移除旧 Forge 依赖再安装新工件,避免 lockfile 保留旧 peer 绑定。 安装 需要 Node.js ^22.19.0 或 >=24,以及 pnpm。 git clone https://github.com/zhn1100/dsh-forge.git cd dsh-forge pnpm install pnpm run verify node lib/cli.js install 安装程序不会写入普通 ~/.dsh,默认目标为 ~/.dsh-forge。 启动 在需要开发插件的工作区运行: DSH_HOME="$HOME/.dsh-forge" npx @deepseek-ai/dsh@0.1.0-rc.6 --profile forge Forge Profile 默认监听 127.0.0.1:3188(与主线 dsh 的 3080 错开,可同时运行);需要其他端口时用 --port 覆盖。 打开 Web UI 后选择 DSH Forge 开发者 Preset。 工作区边界 Forge 启动时同步的是 ~/.dsh → ~/.dsh-forge 的用户态数据,不同步当前工作文件夹的源码。 - 从工作区 A 切换到工作区 B,不会复制 A 的代码到 B。 - A、B 的修改互不影响,但共享同一个 Forge 配置和控制面。 - forge/、profiles/、.agent-presets/ 和 cordis.patch.yml 永不参与 Home 同步(唯一例外:主线 Profile 通过 insert 声明的 out-of-tree 插件会镜像到 ~/.dsh-forge/profiles/node_modules/ 并在 Forge Profile 的 cordis.patch.yml 注册)。 - Forge 侧已修改或删除的文件不会被覆盖;源端删除也不会传播。 同步基线保存在 ~/.dsh-forge/forge/home-sync-manifest.json。如需使用其他上游 Home,可显式设置 DSH_FORGE_SOURCE_HOME。 常用命令 环境检查 DSH_HOME="$HOME/.dsh-forge" node lib/cli.js doctor 重建指定 Harness revision 的知识索引 DSH_HOME="$HOME/.dsh-forge" node lib/cli.js sync --revision 搜索本地索引 DSH_HOME="$HOME/.dsh-forge" node lib/cli.js search "Service.init" 验证当前插件项目 node lib/cli.js verify --root . --level full 完整设计和安全边界见 任务书。 开发验证 pnpm run verify 验证包括类型检查、测试、构建和包结构检查。动态 Cordis Package 仍属于显式信任边界;Forge 提供隔离和恢复能力,但不将其包装成强安全沙箱。 License MIT
预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
zhn1100/dsh-forge
隔离环境开发调试插件,验证后一键晋级正式版
相关插件 · 开发 / 工程
隐私简历生成器reactive-resume/reactive-resume
Reactive Resume 已迁至 GitHub 上的…
★ 45,288已汉化MCP
71.7
长时任务执行闭环AMAP-ML/LongHorizon-Harness
面向 Computer-Use Agent 的 Loop Engineering
★ 1,764已汉化DSH
70.5
多代理编排运行时Enderfga/claw-orchestrator
面向编程智能体的运行时。把 Claude Code、Codex、Antigravity、Grok…
★ 586已汉化MCP
69.4
记忆进化插件csyangwen/dsh-memory-evolve
dsh-memory-evolve 使用场景指南
★ 461已汉化DSH
67.9
原生编程智能体paean-ai/deeptide
由 DeepSeek 打造,为 DeepSeek 而生。
★ 1,107已汉化DSH
67.7
多引擎接力台emo-xiaoyu/harness-mix
macOS/Linux 已加入源码构建与启动适配;目标系统的完整桌面验收仍需在对应机器执行。安装方式、Linux…
★ 419已汉化DSH
66.8
这是你的仓库?认领条目