DeepSeek Harness 远程插件 · 多主机 Web/Desktop · Android 接口适配
数据截至 2026/9/18 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
dsh plugin --profile web add catcatchcatast/dsh-remote-hosts状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
安装兼容性检查需源码安装缺少 main/exports/bin 入口声明;仓库 package.json 标记 private,未发布到 npm,需从源码安装
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/13 09:40:19
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
查看扫描证据(共 66 处,展示前 62 条)
- 读取本地文件compatibility-patches/dsh-chat-import/apply.mjs:179
const packageJson = JSON.parse(await readFile(packagePath, 'utf8')) - 写入本地文件compatibility-patches/dsh-chat-import/apply.mjs:189
await writeFile(temporaryPath, data, 'utf8') - 写入本地文件compatibility-patches/dsh-chat-import/apply.mjs:190
await rename(temporaryPath, filePath) - 删除本地文件compatibility-patches/dsh-chat-import/apply.mjs:192
await rm(temporaryPath, { force: true }) - 读取本地文件compatibility-patches/dsh-chat-import/apply.mjs:211
const source = normalized(await readFile(sourcePath, 'utf8')) - 读取本地文件compatibility-patches/dsh-chat-import/apply.mjs:212
const target = normalized(await readFile(targetPath, 'utf8')) - 读取本地文件compatibility-patches/dsh-project-panorama-adapter/apply.mjs:84
const packageJson = JSON.parse(await readFile(packagePath, 'utf8')) - 读取本地文件compatibility-patches/dsh-project-panorama-adapter/apply.mjs:92
const source = await readFile(resolve(sourcePath), 'utf8') - 读取本地文件compatibility-patches/dsh-project-panorama-adapter/apply.mjs:97
const target = await readFile(targetPath, 'utf8') - 写入本地文件compatibility-patches/dsh-project-panorama-adapter/apply.mjs:102
await writeFile(temporaryPath, patched, 'utf8') - 写入本地文件compatibility-patches/dsh-project-panorama-adapter/apply.mjs:103
await rename(temporaryPath, targetPath) - 读取本地文件compatibility-patches/preset-persona-config/apply.mjs:93
const source = await readFile(resolve(sourcePath), 'utf8') - 读取本地文件compatibility-patches/preset-persona-config/apply.mjs:96
const target = await readFile(resolve(targetPath), 'utf8') - 写入本地文件compatibility-patches/preset-persona-config/apply.mjs:102
await writeFile(resolve(backupPath), target, { encoding: 'utf8', flag: 'wx' }) - 写入本地文件compatibility-patches/preset-persona-config/apply.mjs:104
await writeFile(temporaryPath, migrated, 'utf8') - 写入本地文件compatibility-patches/preset-persona-config/apply.mjs:105
await rename(temporaryPath, resolve(targetPath)) - 发起网络请求packages/browser-host-hub-rc1/src/index.js:1951
async fetch(input, init = {}) { - 执行外部命令固定命令packages/mobile-bootstrap-rc1/src/bootstrap-store.cjs:14
return execFileSync('powershell.exe', ['-NoProfile', '-NonInteractive', '-Command', script], { - 读取本地文件packages/mobile-bootstrap-rc1/src/bootstrap-store.cjs:23
const stat = fs.readFileSync(`/proc/${pid}/stat`, 'utf8') - 读取本地文件packages/mobile-bootstrap-rc1/src/bootstrap-store.cjs:24
return fs.readFileSync('/proc/sys/kernel/random/boot_id', 'utf8').trim() + ':' + stat.slice(stat.lastIndexOf(')') + 2).split(' ')[19] - 执行外部命令固定命令packages/mobile-bootstrap-rc1/src/bootstrap-store.cjs:26
return execFileSync('ps', ['-p', String(pid), '-o', 'lstart='], { encoding: 'utf8', timeout: 3000 }).trim() - 读取本地文件packages/mobile-bootstrap-rc1/src/bootstrap-store.cjs:29
const st = fs.lstatSync(target) - 读取本地文件packages/mobile-bootstrap-rc1/src/bootstrap-store.cjs:39
const st = fs.lstatSync(target) - 读取本地文件packages/mobile-bootstrap-rc1/src/bootstrap-store.cjs:49
if (fs.existsSync(dir)) { - 写入本地文件packages/mobile-bootstrap-rc1/src/bootstrap-store.cjs:57
} else fs.mkdirSync(dir, { mode: 0o700 }) - 写入本地文件packages/mobile-bootstrap-rc1/src/bootstrap-store.cjs:68
fs.writeFileSync(fd, data, 'utf8') - 读取本地文件packages/mobile-bootstrap-rc1/src/bootstrap-store.cjs:71
if (fs.existsSync(target)) { - 写入本地文件packages/mobile-bootstrap-rc1/src/bootstrap-store.cjs:75
fs.renameSync(temp, target) - 发起网络请求packages/mobile-interactions-compat-rc1/src/carrier.js:11
const exchange = await fetch(entry, { redirect: 'manual', signal: AbortSignal.any([signal, AbortSignal.timeout(10000)]) }) - 发起网络请求packages/mobile-interactions-compat-rc1/src/carrier.js:30
return fetch(url, { - 发起网络请求packages/mobile-interactions-compat-rc1/src/carrier.js:39
const response = await fetch(new URL(`/api/${endpoint}`, base), { - 执行外部命令固定命令packages/rc1-host-carriers/src/index.js:55
const child = spawn('ssh', [...sshArgs(target), target.alias, command], { windowsHide: true, stdio: ['ignore', 'pipe', 'pipe'] }) - 执行外部命令固定命令packages/rc1-host-carriers/src/index.js:94
const child = spawn('ssh', [...sshArgs(target), '-N', '-o', 'ExitOnForwardFailure=yes', '-o', 'ServerAliveInterval=15', '-o', 'ServerAliveCountMax=3', - 读取本地文件packages/remote-hosts-settings-rc1/src/index.js:18
return existsSync(join(homedir(), '.dsh-mobile', `bootstrap-${port}.json`)) - 读取本地文件packages/remote-hosts-settings-rc1/src/index.js:26
return readFileSync(path, 'utf8') - 执行外部命令固定命令packages/remote-hosts-settings-rc1/src/index.js:35
const child = spawn('ssh', ['-G', '-F', configFile, '-o', 'BatchMode=yes', alias], { - 读取本地文件packages/remote-hosts-settings-rc1/src/store.js:62
const raw = JSON.parse(await readFile(path, 'utf8')) - 写入本地文件packages/remote-hosts-settings-rc1/src/store.js:76
await mkdir(dirname(path), { recursive: true }) - 写入本地文件packages/remote-hosts-settings-rc1/src/store.js:78
await writeFile(tmp, body, { encoding: 'utf8' }) - 写入本地文件packages/remote-hosts-settings-rc1/src/store.js:79
await rename(tmp, path) - 写入本地文件packages/runtime-interface/src/local-runtime-restart.js:131
void appendFile(descriptor.logPath, `${JSON.stringify(entry)}\n`, 'utf8').catch(() => {}) - 读取本地文件packages/runtime-interface/src/managed-runtime-launcher.mjs:183
value = JSON.parse(readFileSync(path, 'utf8')) - 写入本地文件packages/runtime-interface/src/managed-runtime-launcher.mjs:295
await mkdir(dirname(path), { recursive: true }) - 删除本地文件packages/runtime-interface/src/managed-runtime-launcher.mjs:311
await unlink(path).catch(error => { - 删除本地文件packages/runtime-interface/src/managed-runtime-launcher.mjs:349
await unlink(tempPath).catch(() => {}) - 删除本地文件packages/runtime-interface/src/managed-runtime-launcher.mjs:356
await unlink(path).catch(error => { - 删除本地文件packages/runtime-interface/src/managed-runtime-launcher.mjs:383
await unlink(guardPath).catch(error => { - 读取本地文件packages/runtime-interface/src/managed-runtime-launcher.mjs:391
const value = JSON.parse(await readFile(path, 'utf8')) - 读取本地文件packages/runtime-interface/src/managed-runtime-launcher.mjs:409
const value = JSON.parse(await readFile(path, 'utf8')) - 读取本地文件packages/runtime-interface/src/managed-runtime-launcher.mjs:423
const value = JSON.parse(await readFile(path, 'utf8')) - 写入本地文件packages/runtime-interface/src/managed-runtime-launcher.mjs:449
await mkdir(dirname(path), { recursive: true }) - 写入本地文件packages/runtime-interface/src/managed-runtime-launcher.mjs:450
await writeFile(path, `${JSON.stringify(recordValue)}\n`, { encoding: 'utf8', mode: 0o600 }) - 写入本地文件packages/runtime-interface/src/managed-runtime-launcher.mjs:455
await mkdir(dirname(descriptor.logPath), { recursive: true }) - 写入本地文件packages/runtime-interface/src/managed-runtime-launcher.mjs:456
await appendFile(descriptor.logPath, `${JSON.stringify({ time: new Date().toISOString(), event, profileId: descriptor.profileId, port: descriptor.port - 写入本地文件packages/runtime-interface/src/managed-runtime-launcher.mjs:461
await mkdir(dirname(descriptor.logPath), { recursive: true }) - 执行外部命令来自配置/变量packages/runtime-interface/src/managed-runtime-launcher.mjs:550
execFile(command, args, { windowsHide: true, timeout: 1500, maxBuffer: 1024 * 1024 }, (error, stdout) => { - 删除本地文件packages/runtime-interface/src/managed-runtime-launcher.mjs:641
await unlink(descriptor.instancePath).catch(() => {}) - 读取本地文件packages/runtime-interface/src/managed-runtime-launcher.mjs:999
const descriptor = JSON.parse(await readFile(descriptorPath, 'utf8')) - 读取本地文件packages/ui-workspace-menu-compat-rc1/src/patch-client.mjs:88
const source = await readFile(input, 'utf8') - 写入本地文件packages/ui-workspace-menu-compat-rc1/src/patch-client.mjs:89
await writeFile(output, patchFormalRc1Client(source)) - 读取本地文件packages/ui-workspace-menu-compat-rc1/src/patch-project-order.mjs:49
if(process.argv[1] && import.meta.url===pathToFileURL(process.argv[1]).href)writeFileSync(process.argv[3],patchProjectOrder(readFileSync(process.argv[ - 写入本地文件packages/ui-workspace-menu-compat-rc1/src/patch-project-order.mjs:49
if(process.argv[1] && import.meta.url===pathToFileURL(process.argv[1]).href)writeFileSync(process.argv[3],patchProjectOrder(readFileSync(process.argv[
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
@deepseek-ai/cordis@deepseek-ai/dsh-atomic-write@deepseek-ai/dsh-home-paths@deepseek-ai/dsh-llm@deepseek-ai/dsh-web@deepseek-ai/schemastery给这个插件打分还没有人投票↓
功能亮点
- 多主机远程开发
- Web与桌面端支持
- Android接口适配
DSH 远程主机、远程插件、多主机 Web 与桌面端。DSH 远程插件、多主机远程开发。0.1.5-rc.2 预览版;尚未稳定到 0.1.5。联系:catcatchcatast@gmail.com
README
由 DeepSeek 最新模型翻译生成展开完整文档(README 剩余 1 节)
DSH Remote Hosts DeepSeek Harness 远程插件 · 多主机 Web/Desktop · Android 接口适配 English · 安装说明 · 兼容性 · 发布下载 · Android 客户端 在熟悉的 DSH 网页或 Desktop 中操作本机和远程电脑上的项目。DSH Remote Hosts 通过外部插件提供主机路由、浏览器连接复用和手机接口,不修改 dsh-core。 这是社区项目,并非 DeepSeek 官方产品。每台电脑仍需自行安装 DSH、登录并配置模型供应商;本项目不提供模型订阅或账号凭据。 版本状态:安装前先看 | 使用对象 | DSH 目标版本 | 状态 | | 当前公开安装入口 | 0.1.5-rc.2 | 预览版;自包含安装包见 v0.1.5-rc.2-preview.1 | | 较早的 rc.2 包集合 | 0.1.5-rc.2 | v0.1.5-rc.2-preview;只有组件包,没有已验证的单入口 | | 已有 v0.1.2-preview 下载 | 0.1.2-rc.1 | 旧版预发布附件,不是 rc.2 安装包 | | 源码保留的兼容路径 | 0.1.2-rc.1 | 需验证具体包与配置组合 | | 其他版本,包括正式版 0.1.5 | — | 未声明兼容 | 不要把旧版 v0.1.2-preview 附件当成 rc.2 升级包。 目录名中的 -rc1 是历史命名;当前运行时目标和完整包集合由 release-profile.json 定义。 可以用它做什么 - 项目保留在所属电脑,在同一个界面浏览本机和远程工作。 - 在新建项目的目录流程中选择目标主机,浏览目录、创建文件夹,并继续选择目录。 - 打开会话、跟随输出、干预运行中的任务,在多端处理审批和提问。 - 为原生 Android 客户端提供接口,避免启动时逐个订阅所有空闲会话的完整历史。 DSH Remote Hosts 连接示意 这是一张连接原理示意图,并非产品截图。图中仅有通用组件名称,不含账号、设备、主机地址或会话内容。 界面截图 实际 Web/Desktop 界面截图,展示远程插件集成后的项目与会话主机归属。 | 按项目浏览 | 按时间浏览会话 | 远程项目和会话旁显示主机标签,帮助区分操作目标。通用主机标签保留,部分项目名称沿用原图遮盖;图中主机不是安装后预置的配置。 项目优点 | 设计 | 对使用者的意义 | | 外部兼容包 | 版本适配留在官方核心之外,可随配置回滚。 | | 统一主机路由 | 项目、会话、文件和终端保持明确归属,避免目标主机混淆。 | | 单条浏览器共享连接 | 支持的逻辑订阅复用一条 WebSocket(双向长连接),普通请求继续使用 HTTP,减少长连接占用。 | | 每主机一次手机全局监听 | 非归档会话的新事件仍能到达,不预先恢复所有冷会话。 | | 历史按需且有界 | 用户打开会话或存在已确认游标缺口时读取历史,主机级重型读取最多两路。 | | 工具摘要优先 | 手机默认不传输完整工具参数、输出和差异,点击后再读取所需详情页。 | 这些是当前实现策略,不代表固定延迟或永久无故障的承诺。 功能列表 下列能力已在预览源码中实现;具体可用性还取决于匹配的 DSH 运行时、配置和主机能力。 | 领域 | 功能 | | 项目与主机 | 汇总本机/远程工作区,保留主机标签与归属;目录主机选择、浏览、新建文件夹和目标主机工作区创建。 | | 会话操作 | 创建、打开、重命名、分叉、归档、消息排队、插话、中断及重连。 | | 导航与排序 | 会话菜单内容一致;项目按最近更新的非归档会话排序,项目内较新的会话靠前。 | | 实时输出 | 浏览器共享工作区/会话订阅及全局事件;手机流式正文与子代理事件适配。 | | 审批和提问 | 自动提供决定所需上下文,批准/拒绝、多端撤销旧交互、逐题回答、跳过和自由文本。 | | 模型与订阅 | 适配运行时模型目录和选择状态、可配置模型过滤、订阅插件兼容路由;账号由相应运行时和供应商管理。 | | 手机同步 | 全局事件流、有序游标恢复、历史世代和有界冷历史读取;常规后台工作排除归档会话。 | | 工具详情 | 历史与实时事件统一分离摘要和详情引用;所选完整字段通过有界详情接口读取。审批必要内容不被懒加载隐藏。 | | 文件与终端 | 沿现有主机能力路由文件和终端操作;传输行为取决于主机实现。 | | 运行时管理 | 统一窄接口、受控启动与重启,以及已有验证证据的 Windows 启动修复。 | | 发布打包 | 按配置选择依赖闭包,生成 TGZ(插件归档)、来源哈希并包含项目 LICENSE/NOTICE。 | 深入说明:兼容契约、运行时接口、架构决策。 开始使用 使用已有 0.1.2 预览下载 v0.1.2-preview 只能按其清单搭配 0.1.2-rc.1 使用。先校验 SHA-256(文件内容哈希);INSTALL-PLAN.md 的旧版章节记录该套包。 安装当前 0.1.5-rc.2 预览版 先确认目标运行时恰好是 0.1.5-rc.2,再把自包含发布包加入运行 Web/Desktop 的配置档: dsh plugin --profile web add "https://github.com/catcatchcatast/dsh-remote-hosts/releases/download/v0.1.5-rc.2-preview.1/dsh-remote-hosts-0.1.5-rc.2.tgz" 首次启动前,把 packages/public-install-rc2/profile.patch.example.yml 中的 runtime-interface 条目合并到该配置档的 cordis.patch.yml。把示例 datasetId(历史数据集标识)换成该主机持久会话数据的稳定标识;普通重启不得改变,不同主机不得共用。 SSH 仍需单独配置并核对主机指纹,每台 DSH 只监听本机回环。主机地址和凭据不会进入安装包;config/host-profile.example.yml 只是无密钥结构示例。经原有受控入口启动后,再检查本机/远程项目、正文、中断、审批和重连。 回滚时从同一配置档删除入口包: dsh plugin --profile web remove dsh-remote-hosts 该发布入口内嵌 12 个项目自有运行包,安装时不会查询未公开的内部包名。官方 Workspace UI 转换包仍是保留上游许可证的独立可选下载;安装入口不会暗中替换官方 UI。校验值、源码构建、详细配置和隔离验收证据见 INSTALL-PLAN.md。 远程插件和配套 Android 客户端应作为匹配组合更新。 构建与验证 需要 Node.js 24 和 pnpm 11。当前工作区依赖锁定到注册表版本,不需要并列的私人 DSH 源码。 corepack enable pnpm install --frozen-lockfile pnpm run build pnpm run check 官方集成与 UI 转换测试另需精确版本的未修改输入。缺少输入的测试明确跳过,不能算作官方运行时验收通过。隔离的旧手机引导包保留独立历史构建前提。 当前本地源码检查记录:构建、接口边界检查通过,测试 307 项通过/12 项跳过。这不替代完整多主机稳定负载验收;公开入口还通过了 INSTALL-PLAN.md 记录的隔离二进制安装与启动检查。来源见 SOURCE_SNAPSHOT.md。 接下来的发布工作 - 每次公开插件附件都从最终发布提交重建并重新做隐私检查。 - 每个预发布版本保持安装清单、兼容证据、SHA-256 和回滚步骤一致。 - 继续验证 Android 与远程插件的真机组合;预览包发布不代表全部场景已验收。 不承诺新增产品功能或发布日期。未验收的 Home 专属候选和可选性能工作不列为已发布功能,也不宣称手机 300ms 首屏保证。 仓库导航 | 路径 | 职责 | | packages/runtime-interface | 官方运行时边界、正文/子代理适配与受控生命周期。 | | packages/browser-host-hub-rc1、packages/rc1-host-carriers | 浏览器路由、共享流及本机/SSH 载体。 | | packages/remote-hosts-settings-rc1、packages/ui-directory-picker-browse | 主机配置界面和目录流程。 | | packages/mobile-*-rc1 | 引导、事件、历史、交互和详情接口。 | | packages/subscriptions-compat-rc1、packages/model-menu-filter | 订阅兼容与模型目录过滤。 | | packages/ui-workspace-menu-compat-rc1 | 菜单等价和最近活动排序转换。 | | compat/android-bootstrap-mobile-session-sync | 隔离的旧主机兼容引导。 | | compatibility-patches、tools、tests | 外部使用方适配、打包和合成回归测试。 | 支持、隐私和许可证 普通问题与兼容性反馈:GitHub Issues。私人日志与安全报告:catcatchcatast@gmail.com。 不要公开令牌、私钥、授权 URL、真实 IP/主机名、设备标识或会话正文,截图也须脱敏。SSH 凭据不进入浏览器载荷;自动重连不重放发送、审批或创建等写操作。 贡献规范 · 安全政策 · 支持渠道 · 发布要求 项目自有代码使用 Apache-2.0。第三方组件,包括官方 UI 转换内容,保留原许可证和归属。见 LICENSE 与 NOTICE。 配套项目:DSH T-remote 安卓客户端。检索关键词:DSH 远程插件、DeepSeek Harness 远程主机、多主机、remote hosts、remote plugin、SSH、Tailscale。
预览分享卡片长什么样 ↓
DeepSeek Harness 远程插件 · 多主机 Web/Desktop · Android 接口适配