🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

插件源码实验台 Maidang1/dsh

DeepSeek Harness
Maidang111 天前有提交已提供中文文档扫描:含敏感能力

逐步搭建插件树,观察状态与事件流变化

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
装得上吗
本站已在 dsh 0.2.1-rc.2 下真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 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
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件读取剪贴板或密钥环境变量发起外部网络请求
查看扫描证据(共 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 的检出读取上游原文展示,仓库不保存这些源码副本。许可证原文与依赖说明见 第三方声明。
预览分享卡片长什么样 ↓Maidang1/dsh
分享 · DeepSeek Harness Hub
Maidang1/dsh

逐步搭建插件树,观察状态与事件流变化

回到顶部