逐步搭建插件树,观察状态与事件流变化
32.2/100
综合分
3
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/22 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
自动兼容检查未通过:缺少 main/exports/bin 入口声明;仓库 package.json 标记 private,未发布到 npm,需从源码安装。以下命令仍可尝试,但可能失败。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add Maidang1/dsh该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · model
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 11 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装缺少 main/exports/bin 入口声明;仓库 package.json 标记 private,未发布到 npm,需从源码安装
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✗npm 包harness-explorer(未发布到 npm,仅可源码安装)
✓Node 引擎要求 >=22.19.0 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✗入口文件缺少入口声明
源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/22 11:43:48
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件读取剪贴板或密钥环境变量发起外部网络请求
查看扫描证据(共 89 处,展示前 57 条)
- 发起网络请求apps/explorer/src/lib/api.ts:98
const response = await fetch(path, { - 读取本地文件apps/explorer/src/lib/lesson-data.ts:19
if (!existsSync(LESSONS_JSON)) return null - 读取本地文件apps/explorer/src/lib/lesson-data.ts:20
return LessonBuild.parse(JSON.parse(readFileSync(LESSONS_JSON, 'utf8'))) - 读取本地文件apps/local-server/src/catalog.ts:51
const module = await readFile(stage.module, 'utf8').catch(() => null) - 读取本地文件apps/local-server/src/catalog.ts:67
const onDisk = await Promise.all(entry.files.map(async file => ({ path: file.path, content: await readFile(join(root, file.path), 'utf8').catch(() => - 读取本地文件apps/local-server/src/catalog.ts:71
const module = await readFile(stage.module, 'utf8').catch(() => null) - 读取本地文件apps/local-server/src/catalog.ts:84
for (const name of readdirSync(dir).filter(file => file.endsWith('.json')).sort()) { - 读取本地文件apps/local-server/src/catalog.ts:85
const value = parse(JSON.parse(readFileSync(join(dir, name), 'utf8'))) - 读取本地文件apps/local-server/src/catalog.ts:95
if (!existsSync(path)) return {} - 写入本地文件apps/local-server/src/controller.ts:270
mkdirSync(dshHome, { recursive: true }) - 执行外部命令来自配置/变量apps/local-server/src/controller.ts:272
const child = fork(workerPath, [], { execArgv, stdio: ['ignore', 'pipe', 'pipe', 'ipc'], env }) - 读取本地文件apps/local-server/src/inspect-package.ts:34
const source = readFileSync(entry, 'utf8') - 读取密钥环境变量apps/local-server/src/main.ts:41
...process.env.EXPLORER_TOKEN ? { launchToken: process.env.EXPLORER_TOKEN } : {}, - 发起网络请求apps/local-server/src/packages.ts:85
const response = await fetch(url, { headers: { accept: 'application/json' } }) - 执行外部命令固定命令apps/local-server/src/packages.ts:126
execFile('npm', args, { cwd, timeout: timeoutMs, env: scrubbedEnv() }, (error, _stdout, stderr) => { - 读取本地文件apps/local-server/src/packages.ts:237
persisted = JSON.parse(await readFile(join(this.installRoot, 'installed.json'), 'utf8')) as InstalledPackage[] - 写入本地文件apps/local-server/src/packages.ts:327
await writeFile(join(this.installRoot, 'installed.json'), `${JSON.stringify(this.installed, null, 2)}\n`) - 读取本地文件apps/local-server/src/packages.ts:333
const manifest = JSON.parse(await readFile(join(this.repoRoot, 'node_modules', name, 'package.json'), 'utf8')) as { version?: string } - 读取本地文件apps/local-server/src/packages.ts:380
readFile(join(path, 'package.json'), 'utf8'), - 读取本地文件apps/local-server/src/packages.ts:381
readFile(join(this.repoRoot, 'node_modules', name, 'package.json'), 'utf8'), - 读取本地文件apps/local-server/src/packages.ts:396
if (!existsSync(modules)) return - 读取本地文件apps/local-server/src/packages.ts:397
for (const entry of await readdir(modules, { withFileTypes: true })) { - 删除本地文件递归apps/local-server/src/packages.ts:405
if (await this.duplicateOfRepo(pkg.name, pkg.path)) await rm(pkg.path, { recursive: true, force: true }) - 写入本地文件apps/local-server/src/packages.ts:448
mkdirSync(this.dshHome, { recursive: true }) - 执行外部命令来自配置/变量apps/local-server/src/packages.ts:451
const child = fork(inspector, [entry], { execArgv: ['--import', import.meta.resolve('tsx')], stdio: ['ignore', 'pipe', 'pipe', 'ipc'], env }) - 写入本地文件apps/local-server/src/packages.ts:499
await mkdir(this.installRoot, { recursive: true }) - 写入本地文件apps/local-server/src/packages.ts:501
await writeFile(join(this.installRoot, 'package.json'), JSON.stringify({ private: true })) - 读取本地文件apps/local-server/src/server.ts:330
if (!dir || !existsSync(dir)) { - 读取本地文件apps/local-server/src/server.ts:348
const isFile = (candidate: string) => existsSync(candidate) && statSync(candidate).isFile() - 读取本地文件apps/local-server/src/server.ts:348
const isFile = (candidate: string) => existsSync(candidate) && statSync(candidate).isFile() - 读取本地文件apps/local-server/src/server.ts:352
response.end(readFileSync(path)) - 写入本地文件apps/local-server/src/store.ts:123
await mkdir(join(path, '..'), { recursive: true }) - 写入本地文件apps/local-server/src/store.ts:126
await writeFile(temp, JSON.stringify(value, null, 2) + '\n') - 写入本地文件apps/local-server/src/store.ts:127
await rename(temp, path) - 读取本地文件apps/local-server/src/store.ts:131
if (!existsSync(path)) throw new NotFoundError(`not found: ${path.slice(this.root.length + 1)}`) - 读取本地文件apps/local-server/src/store.ts:132
return schema.parse(JSON.parse(await readFile(path, 'utf8'))) - 读取本地文件apps/local-server/src/store.ts:145
const current = existsSync(path) ? await this.getDraft(draft.id) : null - 读取本地文件apps/local-server/src/store.ts:164
if (!existsSync(path)) await this.writeJson(path, full) - 读取本地文件apps/local-server/src/store.ts:199
if (!existsSync(path)) await this.writeJson(path, value) - 写入本地文件apps/local-server/src/store.ts:208
await mkdir(join(path, '..'), { recursive: true }) - 写入本地文件apps/local-server/src/store.ts:209
await appendFile(path, lines.join('\n') + '\n') - 读取本地文件apps/local-server/src/store.ts:216
if (!existsSync(dir)) throw new NotFoundError(`run ${runId} not found`) - 删除本地文件递归apps/local-server/src/store.ts:393
await rm(this.path('runs', safeName(runId)), { recursive: true, force: true }) - 删除本地文件apps/local-server/src/store.ts:413
await rm(join(dir, name), { force: true }) - 读取本地文件packages/lesson-kit/src/build.ts:60
for (const path of inputs) files.push({ path, content: await readFile(join(options.repoRoot, path), 'utf8') }) - 读取本地文件packages/lesson-kit/src/build.ts:86
const moduleHash = sha256(await readFile(outfile, 'utf8')) - 读取本地文件packages/lesson-kit/src/build.ts:134
for (const group of await readdir(join(upstreamDir, 'packages'), { withFileTypes: true })) { - 读取本地文件packages/lesson-kit/src/build.ts:136
for (const entry of await readdir(join(upstreamDir, 'packages', group.name), { withFileTypes: true })) { - 读取本地文件packages/lesson-kit/src/build.ts:139
const manifest = await readFile(join(upstreamDir, dir, 'package.json'), 'utf8').catch(() => null) - 读取本地文件packages/lesson-kit/src/build.ts:149
return readFile(join(upstreamDir, path), 'utf8').catch(() => { - 写入本地文件packages/lesson-kit/src/build.ts:329
await mkdir(options.outDir, { recursive: true }) - 写入本地文件packages/lesson-kit/src/build.ts:330
await writeFile(join(options.outDir, 'lessons.json'), JSON.stringify(result, null, 2) + '\n') - 读取本地文件packages/lesson-kit/src/verify.ts:126
const source = await readFile(join(upstreamDir, file.path), 'utf8').catch(() => null) - 读取本地文件packages/lesson-kit/src/verify.ts:135
source = await readFile(join(upstreamDir, ref.path), 'utf8') - 读取本地文件packages/teaching-plugins/src/upstream.ts:17
const lock = JSON.parse(readFileSync(new URL('../../../upstream-lock.json', import.meta.url), 'utf8')) as { commit: string } - 读取本地文件packages/teaching-plugins/src/upstream.ts:63
manifest = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')) as typeof manifest - 读取本地文件packages/teaching-plugins/src/upstream.ts:83
sourceHash: sha256(readFileSync(module, 'utf8')),
扫描于 2026/11/1(0 天前) · 范围 全包扫描 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-agent@deepseek-ai/dsh-agent-loop@deepseek-ai/dsh-credentials@deepseek-ai/dsh-launch-environment@deepseek-ai/dsh-llm@deepseek-ai/dsh-llm-deepseek@deepseek-ai/dsh-llm-deepseek-api-key@deepseek-ai/dsh-scope@deepseek-ai/dsh-session@deepseek-ai/dsh-session-projection@deepseek-ai/dsh-system-prompt给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
README
由 DeepSeek 最新模型翻译生成Harness Explorer
面向首次阅读 DeepSeek Harness 源码的交互式学习实验台。从最小插件树开始,逐个添加插件,用 Code Hike 逐步构建插件代码,观察状态、事件和数据流的变化,理解每个插件的内部代码架构。
应用由本地 Node.js 命令启动,浏览器承载插件树、Code Hike、时间线、回放与对比。Node 在独立子进程中执行插件,运行事实通过统一轨迹驱动可视化;不用 mock 数据或预设动画代替实际执行。确定性模型用于无密钥教学和重复验证,真实模型通过本机环境中的 DeepSeek 凭据接入。
项目运行上游发布的对话内核,不是完整的 DeepSeek Harness:session、session-projection、system-prompt、tools、agent、agent-loop、llm 与 DeepSeek 适配器直接执行 npm 上的 @deepseek-ai/dsh-@0.2.1-rc.2(固定 commit 687f282e 的发布,标签 dsh-v0.2.1-rc.2,不复制不改写),Cordis 框架复用 @deepseek-ai/cordis@4.0.5(与该 commit 中的 vendor 源码逐字节一致);prompt-contributor、tool-guard、calculator 与确定性模型适配器
展开完整文档(README 剩余 1 节)
Harness Explorer 面向首次阅读 DeepSeek Harness 源码的交互式学习实验台。从最小插件树开始,逐个添加插件,用 Code Hike 逐步构建插件代码,观察状态、事件和数据流的变化,理解每个插件的内部代码架构。 应用由本地 Node.js 命令启动,浏览器承载插件树、Code Hike、时间线、回放与对比。Node 在独立子进程中执行插件,运行事实通过统一轨迹驱动可视化;不用 mock 数据或预设动画代替实际执行。确定性模型用于无密钥教学和重复验证,真实模型通过本机环境中的 DeepSeek 凭据接入。 项目运行上游发布的对话内核,不是完整的 DeepSeek Harness:session、session-projection、system-prompt、tools、agent、agent-loop、llm 与 DeepSeek 适配器直接执行 npm 上的 @deepseek-ai/dsh-@0.2.1-rc.2(固定 commit 687f282e 的发布,标签 dsh-v0.2.1-rc.2,不复制不改写),Cordis 框架复用 @deepseek-ai/cordis@4.0.5(与该 commit 中的 vendor 源码逐字节一致);prompt-contributor、tool-guard、calculator 与确定性模型适配器 llm-scripted 是本项目编写的教学插件,行为由契约测试约束,并链接到固定 commit 的上游源码。决定与差异见 0002。 快速开始 需要 Node.js 22.19 或更高版本与 pnpm 10。 pnpm install pnpm build # 构建课程(类型检查、打包阶段模块、生成 lessons.json)与界面 pnpm explorer # 启动本地服务,终端打印带一次性令牌的链接 用终端打印的链接打开浏览器。服务只绑定 127.0.0.1,令牌换取会话 cookie 后失效;运行记录保存在项目根目录的 .explorer/。界面的插件库可以从 npm 安装其他 @deepseek-ai/dsh-@0.2.1-rc.2 附加包,安装进 .explorer/packages/。上游包读写的 DSH_HOME 被限定在 .explorer/dsh-home/,实验台不接触本机的 ~/.dsh。 真实模型模式需要在启动 pnpm explorer 的环境中设置 DEEPSEEK_API_KEY(可选 DEEPSEEK_BASE_URL)。密钥只在 Node 进程内使用,不进入浏览器、轨迹或导出文件。 学习闭环 1. 整体组合:运行最小对话组合,查看插件树(组合、依赖、运行数据三个图层)、执行轨迹与模型请求。 2. 回放:移动回放游标查看任意位置的状态;回放从不重新执行插件。 3. 对比:选两次请求或两次运行,查看 system、messages、tools 的差异与可比条件。 4. 插件实现:从实例进入课程,按阶段阅读 Code Hike 代码增量、内部架构与上游对照,运行当前阶段并查看它自己的结果。 5. 导出与导入:运行可导出为 JSON,在另一份仓库中只读回放。 现有课程: | 课程 | 内容 | 验证等级 | | prompt-contributor | 依赖声明、提示词片段注册、effect 自动清理、作用域覆盖 | contract-verified | | tool-guard | tools/pre-execute 的 around 中间件:委托、洋葱顺序、短路拒绝 | contract-verified | | system-prompt | 配置、作用域片段、动态输入、组装与渲染(上游原文导读) | contract-verified | 开发命令 | 命令 | 作用 | | pnpm typecheck | 全部包与界面的 TypeScript 检查 | | pnpm test | 契约、轨迹、运行宿主与内容构建测试(Vitest) | | pnpm lesson:new <plugin-id> | 生成新课程骨架(阶段源码、课程内容、组合与场景),制作流程见 课程制作指南 | | pnpm lessons:build | 构建课程,展示代码与执行模块共用同一 sourceHash | | pnpm lessons:verify | 在打包后的模块上运行每个可执行课程阶段 | | pnpm lessons:verify-upstream | 对固定 commit 核对上游源码引用(会克隆上游到 .cache/,或使用 UPSTREAM_DIR) | | pnpm build:ui | Next.js 静态导出界面 | | pnpm test:e2e | Playwright 浏览器端到端测试(需先 pnpm build) | | pnpm check | 按 CI 的顺序依次运行以上全部检查,任一失败即停止并返回非零退出码 | 目录 apps/explorer Next.js 界面(静态导出,由本地服务同源托管) apps/local-server 控制服务:API、SSE、运行仓库、npm 附加包安装、每次运行一个子进程 packages/contracts Zod schema 与共享类型 packages/teaching-runtime 场景执行器、观测适配、确定性设施 packages/teaching-plugins 上游内核阶段定义(src/upstream.ts)与教学插件各阶段源码 packages/trace 记录器、回放、轨迹缓冲 packages/lesson-kit 课程构建与校验 content/plugins 课程讲解、架构与上游映射 fixtures 组合、场景、确定性模型脚本 docs 设计文档、契约与技术决定 文档 从 文档总览 开始;各任务的完成情况见 实施状态索引,行为契约及其测试见 docs/contracts,技术决定见 docs/decisions(0001 上游基线与复用范围、0002 直接运行上游发布的内核包)。 1. 产品设计与范围 2. 系统架构与状态数据模型 3. Code Hike 与插件教学内容实现 4. 分阶段实施计划与任务验收 5. 行为一致性验证与发布标准 6. 上游依据与待验证事项 7. 内核插件课程方案 来源与许可 学习对象:deepseek-ai/deepseek-harness(MIT)。内核插件 @deepseek-ai/dsh-*@0.2.1-rc.2 与框架包 @deepseek-ai/cordis、@deepseek-ai/cosmokit、@deepseek-ai/schemastery 均以 MIT 许可从 npm 原样引入。prompt-contributor、tool-guard、calculator 与 llm-scripted 是本项目编写的教学插件;内核课程在构建时从固定 commit 的检出读取上游原文展示,仓库不保存这些源码副本。许可证原文与依赖说明见 第三方声明。
预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
Maidang1/dsh
逐步搭建插件树,观察状态与事件流变化
相关插件 · 模型接入
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