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

桌面智能体工作台 MicroSpotlight/OpenHarness

DeepSeek Harness
MicroSpotlight73 天前有提交已提供中文文档扫描:高危

免装 Node 环境,双击即用 AI 智能体

33.7/100
综合分
5
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/9/18 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

自动兼容检查未通过:缺少 main/exports/bin 入口声明;仓库 package.json 标记 private,未发布到 npm,需从源码安装。以下命令仍可尝试,但可能失败。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add MicroSpotlight/OpenHarness
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · ui
装得上吗
本站已在 dsh 0.2.1-rc.2 下真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 73 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装

缺少 main/exports/bin 入口声明;仓库 package.json 标记 private,未发布到 npm,需从源码安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✗npm 包openharness(未发布到 npm,仅可源码安装)
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✗入口文件缺少入口声明

源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/24 17:57:39

🔴 安全扫描发现高危能力自动 · 静态分析源码
v2.7.0
🔴 扫描:高危尚无人工评估

静态扫描发现安装期即执行代码,或命令参数由运行时变量拼接(参数来源无法静态判定,从严处理)。

安装时即执行脚本可执行外部命令读写/删除本地文件写入剪贴板(不计风险)发起外部网络请求
查看扫描证据(共 55 处,展示前 46 条)
  • 执行外部命令来自配置/变量
    scripts/setup-runtime.mjs:84
    const result = spawnSync(command, args, {
  • 读取本地文件
    scripts/setup-runtime.mjs:100
    return (await stat(path)).isFile();
  • 读取本地文件
    scripts/setup-runtime.mjs:108
    return (await stat(path)).isDirectory();
  • 发起网络请求
    scripts/setup-runtime.mjs:115
    const response = await fetch(url, { redirect: "follow" });
  • 写入本地文件
    scripts/setup-runtime.mjs:117
    await writeFile(output, Buffer.from(await response.arrayBuffer()));
  • 读取本地文件
    scripts/setup-runtime.mjs:121
    return createHash("sha256").update(await readFile(path)).digest("hex");
  • 读取本地文件
    scripts/setup-runtime.mjs:125
    const info = await stat(path);
  • 读取本地文件
    scripts/setup-runtime.mjs:128
    for (const entry of await readdir(path, { withFileTypes: true })) {
  • 读取本地文件
    scripts/setup-runtime.mjs:152
    hash.update(await readFile(file));
  • 写入本地文件
    scripts/setup-runtime.mjs:178
    await mkdir(RUNTIME_DIR, { recursive: true });
  • 删除本地文件
    scripts/setup-runtime.mjs:179
    await rm(join(RUNTIME_DIR, target.os === "win32" ? "node" : "node.exe"), { force: true });
  • 写入本地文件
    scripts/setup-runtime.mjs:195
    await copyFile(source, nodePath);
  • 写入本地文件
    scripts/setup-runtime.mjs:196
    if (target.os !== "win32") await chmod(nodePath, 0o755);
  • 写入本地文件
    scripts/setup-runtime.mjs:197
    await writeFile(NODE_STAMP, `${expectedStamp}\n`);
  • 删除本地文件递归
    scripts/setup-runtime.mjs:199
    await rm(downloadDir, { recursive: true, force: true });
  • 删除本地文件递归
    scripts/setup-runtime.mjs:267
    await rm(join(DSH_DIR, "node_modules", packagePath), { recursive: true, force: true });
  • 删除本地文件递归
    scripts/setup-runtime.mjs:329
    await rm(DSH_DIR, { recursive: true, force: true });
  • 写入本地文件
    scripts/setup-runtime.mjs:330
    await mkdir(DSH_DIR, { recursive: true });
  • 删除本地文件
    scripts/setup-runtime.mjs:375
    await rm(RUNTIME_STAMP, { force: true });
  • 删除本地文件
    scripts/setup-runtime.mjs:382
    await rm(RUNTIME_STAMP, { force: true });
  • 写入剪贴板
    docs/site.js:350
    await navigator.clipboard.writeText(command);
  • 发起网络请求
    docs/site.js:386
    const response = await fetch("latest.json", { cache: "no-cache" });
  • 读取本地文件
    runtime/native-bridge/lib/managed-runtime.js:268
    access(this.configuration.nodePath, executableMode),
  • 读取本地文件
    runtime/native-bridge/lib/managed-runtime.js:269
    access(this.configuration.dshEntry, fsConstants.R_OK),
  • 读取本地文件
    runtime/native-bridge/lib/managed-runtime.js:270
    access(this.configuration.packageManagerLauncher, executableMode),
  • 读取本地文件
    scripts/brand-runtime.mjs:19
    return readFileSync(resolve(packagesRoot, relativePath), "utf8");
  • 写入本地文件
    scripts/brand-runtime.mjs:23
    writeFileSync(resolve(packagesRoot, relativePath), content);
  • 读取本地文件
    scripts/brand-runtime.mjs:194
    let indexHtml = readFileSync(indexPath, "utf8");
  • 写入本地文件
    scripts/brand-runtime.mjs:207
    writeFileSync(indexPath, indexHtml);
  • 读取本地文件
    scripts/brand-runtime.mjs:210
    const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
  • 写入本地文件
    scripts/brand-runtime.mjs:223
    writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
  • 写入本地文件
    scripts/brand-runtime.mjs:225
    copyFileSync(
  • 读取本地文件
    scripts/build-tauri.mjs:45
    await readFile(new URL("../src-tauri/tauri.conf.json", import.meta.url), "utf8"),
  • 执行外部命令固定命令
    scripts/build-tauri.mjs:59
    const child = spawn(
  • 删除本地文件递归
    scripts/managed-runtime.test.mjs:22
    t.after(() => rmSync(root, { recursive: true, force: true }));
  • 写入本地文件
    scripts/managed-runtime.test.mjs:28
    mkdirSync(packageManagerBinDirectory, { recursive: true });
  • 写入本地文件
    scripts/managed-runtime.test.mjs:29
    mkdirSync(dshHome, { recursive: true });
  • 写入本地文件
    scripts/managed-runtime.test.mjs:34
    writeFileSync(launcher, process.platform === "win32" ? "@echo off\r\n" : "#!/bin/sh\n");
  • 写入本地文件
    scripts/managed-runtime.test.mjs:35
    if (process.platform !== "win32") chmodSync(launcher, 0o755);
  • 写入本地文件
    scripts/managed-runtime.test.mjs:36
    writeFileSync(
  • 读取本地文件
    scripts/managed-runtime.test.mjs:218
    descendantPid = Number.parseInt(readFileSync(marker, "utf8"), 10);
  • 读取本地文件
    scripts/update-manifest.mjs:260
    return requireString(await readFile(path, "utf8"), label);
  • 读取本地文件
    scripts/update-manifest.mjs:264
    const artifact = await stat(path);
  • 读取本地文件
    scripts/update-manifest.mjs:277
    notes: await readFile(options["notes-file"], "utf8"),
  • 写入本地文件
    scripts/update-manifest.mjs:303
    await writeFile(options.output, `${JSON.stringify(manifest, null, 2)}\n`, "utf8");
  • 读取本地文件
    scripts/update-manifest.mjs:307
    validateUpdateManifest(JSON.parse(await readFile(path, "utf8")));
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 免装Node环境
  • 双击启动桌面应用
  • 内置运行时与WebUI

DeepSeek Harness 桌面应用,把运行时和 Web UI 打包进 Tauri 窗口,无需 Node.js 或命令行配置。

README

由 DeepSeek 最新模型翻译生成
OpenHarness OpenHarness 是一个支持 macOS、Windows 和 Linux 的原生 AI Agent 桌面应用。它将开源 Agent Harness 的 Web UI 和已发布的 @deepseek-ai/dsh 运行时打包进独立的 Tauri 应用,日常使用无需另行安装 Node.js 或命令行工具。 OpenHarness 由 MicroSpotlight 独立开发。为避免与 DeepSeek 品牌产生混淆、防止用户将本应用误认为 DeepSeek 官方产品,并降低商标与著作权方面的侵权风险,本项目重新定义了独立的产品名称、应用图标、Bundle ID、桌面宿主标识和视觉主题,不继承上游项目的品牌素材,也不暗示本项目获得 DeepSeek 的官方认可或与其存在隶属关系。
展开完整文档(README 剩余 1 节)
OpenHarness

OpenHarness 是一个支持 macOS、Windows 和 Linux 的原生 AI Agent 桌面应用。它将开源 Agent Harness 的 Web UI 和已发布的 @deepseek-ai/dsh 运行时打包进独立的 Tauri 应用,日常使用无需另行安装 Node.js 或命令行工具。

OpenHarness 由 MicroSpotlight 独立开发。为避免与 DeepSeek 品牌产生混淆、防止用户将本应用误认为 DeepSeek 官方产品,并降低商标与著作权方面的侵权风险,本项目重新定义了独立的产品名称、应用图标、Bundle ID、桌面宿主标识和视觉主题,不继承上游项目的品牌素材,也不暗示本项目获得 DeepSeek 的官方认可或与其存在隶属关系。

功能

- 通过 macOS、Windows 和 Linux 原生桌面窗口使用 Agent Web UI
- 内置 Node.js 和锁定版本的 Agent 运行时
- 为 macOS、Windows 和 Linux 提供 arm64/x64 原生安装包
- 自动选择本机回环端口,避免端口冲突
- 与上游工具共用 ~/.dsh 中的配置、凭据、会话和插件
- 在 设置 → 插件 中内置插件发现,支持目录搜索、分类筛选、已安装识别和可升级判断
- 在 App 内安装或升级插件,目标固定到精确包版本或 Git commit,并支持取消、失败回滚、安装后验证以及需要激活时的受管重启
- 内置 pnpm 执行环境,插件管理不依赖系统安装的 Node.js 或 pnpm
- 桌面启动器默认关闭内置运行时的遥测
- 系统托盘常驻:顶层展示 5 个优先会话,「更多会话」展示 20 个最近会话并可查看全部
- 单实例锁:重复启动会聚焦已运行实例
- 后端崩溃自动重启(指数退避),连续失败弹原生错误提示窗
- 单业务窗口:选择或新建会话时复用并聚焦主窗口
- 窗口和原生菜单跟随应用的深色/浅色外观与语言设置
- macOS 和 Linux 启动时限时从登录 shell 加载 PATH 和 DEEPSEEK_API_KEY 等 DEEPSEEK_* 环境变量注入后端(从桌面启动也能找到用户工具和 token;已继承的 DeepSeek 环境变量优先)

系统要求

- macOS 15.0 或更高版本(Apple Silicon 或 Intel)
- Windows 10 1709 或更高版本(x64 或 arm64),并安装 Microsoft Edge WebView2 Runtime;推荐使用 Windows 11
- Linux x64 或 arm64,kernel 4.18+、glibc 2.35+、WebKitGTK 4.1;支持基线为 Ubuntu 22.04+ 和 Debian 12+
- 至少一个内置运行时支持的模型服务商凭据

安装

Homebrew(macOS)

通过 MicroSpotlight Homebrew Tap 安装:

brew install --cask microspotlight/tap/openharness

Cask 会根据当前 Mac 自动选择 Apple Silicon 或 Intel 版本。

直接下载

从 GitHub Releases 下载对应平台的安装包:

- macOS Apple Silicon:OpenHarness__arm64.dmg
- macOS Intel:OpenHarness__x64.dmg
- Windows x64:OpenHarness__x64-setup.exe
- Windows arm64:OpenHarness__arm64-setup.exe
- Linux x64:OpenHarness__amd64.AppImage 或 OpenHarness__amd64.deb
- Linux arm64:OpenHarness__arm64.AppImage 或 OpenHarness__arm64.deb

macOS 打开 DMG 后将 OpenHarness 拖入 Applications(应用程序);Windows 运行 NSIS 安装器;Linux 可安装 Debian 包,或为 AppImage 添加执行权限后直接启动。

macOS 安装包已使用 Developer ID 签名并完成公证。Windows 安装器当前尚未进行 Authenticode 签名,因此系统可能显示发布者警告。

使用

OpenHarness 会在可用的本机回环端口上启动内置 Agent 服务,并在原生窗口中打开 Web UI。
在应用中配置模型服务商后,即可像使用上游 dsh web 命令一样使用该界面。

应用与上游命令行工具共用 ~/.dsh 目录,因此已有的凭据、配置、会话和插件可以在两种入口之间直接复用。Harness 本身的使用方式请参考上游用户指南。

插件

打开 设置 → 插件 → 发现插件,可以搜索 OpenHarness 插件目录,按分类或能力筛选,查看发布者和兼容性信息,并在不离开 App 的情况下安装或升级插件。OpenHarness 会严格展示已安装、可升级、本地版本更新、身份冲突和需要重启等状态,不根据显示名称进行模糊猜测。

插件变更写入 ~/.dsh 下的 web profile。浏览器只提交插件名称、操作、目录版本和 Catalog revision;内置 Find Plugin Host 会重新读取并校验目录,推导精确 npm 版本或 Git commit,快照 profile,执行变更,验证实际安装结果,并在失败时恢复元数据。操作可以取消,刷新页面后也能恢复当前进度。

OpenHarness 不在 Rust 中实现目录或安装策略。桌面 App 通过 Cordis 提供受管运行时服务,底层使用随应用打包的 Node.js、DSH 和 pnpm,并负责输出上限、超时、单一包操作互斥、完整进程树取消和 Supervisor 受管重启。目录信任、安装意图、已安装身份匹配、回滚和激活仍由 Find Plugin 负责。

可以在只读的 OpenHarness 插件市场中搜索公共目录;安装和升级仍需在 App 内完成。插件目录和发现组件分别维护在 openharness-plugins 与 openharness-find-plugin 仓库。

工作原理

1. Tauri 使用内置 Node.js 和已发布的 @deepseek-ai/dsh 包启动服务,同时加载 OpenHarness Native Bridge 与 Find Plugin,并自动选择端口。
2. 运行时自动选择可用的本机端口,并输出对应的回环地址。
3. OpenHarness 校验该地址后,在原生 webview 中打开它。
4. Native Bridge 为当前 web profile 注册受管插件运行时,并向包操作提供内置 pnpm 环境。
5. 插件请求重启时,DSH 子进程使用受管退出码退出,OpenHarness Supervisor 立即启动新的后端 generation。
6. 关闭窗口时将其隐藏到系统托盘;从应用菜单或托盘选择「退出」时,终止内置运行时进程。

桌面宿主不会复刻或重新实现上游 Web UI。运行时由 scripts/setup-runtime.mjs 按锁文件组装,再通过 scripts/brand-runtime.mjs 应用 OpenHarness 独立的名称、图标和主题。

从源码构建

请先安装 Rust、Bun 以及对应平台的原生工具链:

- macOS:Xcode Command Line Tools
- Windows:包含 C++ 工作负载的 Visual Studio Build Tools 和 WebView2
- Linux:WebKitGTK 4.1 及其他 Tauri Linux 前置依赖

然后执行:

git clone https://github.com/MicroSpotlight/OpenHarness.git
cd OpenHarness
bun install --frozen-lockfile
bun run build

bun install 会通过 postinstall 自动组装内置运行时;需要手动校验或重建时,
执行 bun run setup:runtime。

构建产物位于 src-tauri/target/release/bundle/。

本地开发:

bun run dev

仓库结构

.
|-- .github/workflows/ 跨平台发版与 Pages 自动化
|-- assets/ OpenHarness 图标源文件
|-- frontend/dist/ Tauri 启动占位页
|-- runtime/ 锁定运行时、Native Bridge、Find Plugin 与 pnpm launcher
|-- scripts/ 运行时组装、品牌、发版与签名脚本
-- src-tauri/ Rust 宿主与 Tauri 配置

src-tauri/runtime/ 由脚本在本地生成,不纳入 Git。

隐私

OpenHarness 的桌面宿主不增加遥测,并会明确关闭内置运行时的遥测。提示词、附件和模型请求仍会发送给用户主动配置的模型服务商;本地 Harness 数据继续保存在 ~/.dsh。

与上游项目的关系

DeepSeek Harness 是 OpenHarness 内置的上游运行时组件。该上游组件单独采用 MIT License;OpenHarness 原创代码仍采用 Apache License 2.0。本仓库中对 DeepSeek Harness 的引用仅用于说明和归属该依赖。
为避免与上游项目及其品牌产生混淆,OpenHarness 使用完全独立的产品标识。

参与贡献

上游运行时或 Web UI 的改动应提交到上游仓库;插件目录条目属于 openharness-plugins,发现和安装编排属于 openharness-find-plugin,桌面受管运行时与 Supervisor 改动属于本仓库。

版权与许可证

Copyright 2026 MicroSpotlight.

- OpenHarness 原创桌面宿主代码:Apache License 2.0
- 内置的上游 @deepseek-ai/dsh 组件: MIT License

以下版权声明仅适用于内置的上游组件:

Copyright (c) 2026 DeepSeek

上游 MIT 许可证全文会随 npm 包保留,并进入最终应用包。其他内置依赖仍分别遵循各自的许可证。归属信息请参阅 NOTICE。
预览分享卡片长什么样 ↓MicroSpotlight/OpenHarness
分享 · DeepSeek Harness Hub
MicroSpotlight/OpenHarness

免装 Node 环境,双击即用 AI 智能体

这是你的仓库?认领条目

回到顶部