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

Hana 子代理桥 Nyasers/DSHana

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

DSHana:把 DeepSeek Harness 当作 HanaAgent 的子代理

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

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

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

状态速览

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

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

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

缺少 main/exports/bin 入口声明;engines.node 要求 ^22.23.4 || ^24.22.1 || ^26.12.1,不满足 Node 22.19.0;仓库 package.json 标记 private,未发布到 npm,需从源码安装

展开查看检查明细 ↓

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

✗npm 包dshana(未发布到 npm,仅可源码安装)
✗Node 引擎要求 ^22.23.4 || ^24.22.1 || ^26.12.1 · 基线 Node 22.19 不满足
✓dsh CLI 依赖未声明 dsh 版本约束
✗入口文件缺少入口声明

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

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/30 09:04:31

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

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

可执行外部命令读写/删除本地文件读取剪贴板或密钥环境变量发起外部网络请求
查看扫描证据(共 70 处,展示前 63 条)
  • 读取本地文件
    packages/bloom/src/check-parity.mts:40
    if (!existsSync(path)) return null;
  • 读取本地文件
    packages/bloom/src/check-parity.mts:41
    const text = readFileSync(path, "utf8");
  • 发起网络请求
    packages/host/src/bridge.ts:319
    const response = await fetch(sameOriginTarget(`${authorized.path}${authorized.search}`, upstream), {
  • 读取本地文件
    packages/host/src/cwd-check.ts:31
    return { ok: true, isDirectory: (await stat(path)).isDirectory() };
  • 读取本地文件
    packages/host/src/locate.ts:23
    if (!existsSync(p)) return null;
  • 读取本地文件
    packages/host/src/locate.ts:24
    const j = JSON.parse(readFileSync(p, "utf8"));
  • 读取本地文件
    packages/host/src/locate.ts:39
    if (!existsSync(join(dshPkg, "package.json"))) {
  • 读取本地文件
    packages/host/src/locate.ts:55
    if (existsSync(stableEntry)) candidates.push(stableEntry);
  • 读取本地文件
    packages/host/src/locate.ts:57
    for (const f of readdirSync(libDir)) {
  • 读取本地文件
    packages/host/src/locate.ts:91
    for (const d of readdirSync(pnpmDir)) {
  • 发起网络请求
    packages/host/src/main.ts:102
    const req = http.get(
  • 读取本地文件
    packages/host/src/main.ts:221
    if (!existsSync(join(dir, "index.js"))) missing.push(dir);
  • 读取本地文件
    packages/host/src/main.ts:224
    if (!existsSync(join(bundle, "lib", "index.js"))) missing.push(bundle);
  • 写入本地文件
    packages/host/src/main.ts:263
    const write = (payload) => writeFileSync(opts.resultPath, JSON.stringify(payload), { mode: 0o600 });
  • 读取本地文件
    packages/host/src/main.ts:297
    opts = parseRuntimeConfig(argv, (p) => readFileSync(p, "utf8"));
  • 写入本地文件
    packages/host/src/main.ts:315
    writeFileSync(opts.fatalPath, JSON.stringify({ ok: false, kind, message, causes, at: new Date().toISOString() }), { mode: 0o600 });
  • 写入本地文件
    packages/host/src/main.ts:387
    mkdirSync(dshHome, { recursive: true });
  • 读取密钥环境变量
    packages/host/src/main.ts:390
    if (!process.env.DSHANA_BUS_SECRET) process.env.DSHANA_BUS_SECRET = randomUUID();
  • 发起网络请求
    packages/host/src/main.ts:487
    const exchange = await fetch(launch, { redirect: "manual" });
  • 发起网络请求
    packages/host/src/main.ts:568
    const res = await fetch(upstreamOrigin + "/api/" + body.method, {
  • 发起网络请求
    packages/host/src/task-bridge.ts:304
    const fetchImpl = (url, init) => fetch(url, {
  • 发起网络请求
    packages/models/src/caller-model.ts:207
    const res: any = await bus.request("session:context", { sessionId: id, scope: "all" });
  • 读取本地文件
    packages/runtime/src/config.ts:54
    if (existsSync(cf)) {
  • 读取本地文件
    packages/runtime/src/config.ts:55
    const j = JSON.parse(readFileSync(cf, "utf8"));
  • 读取本地文件
    packages/runtime/src/config.ts:82
    if (existsSync(cf)) {
  • 读取本地文件
    packages/runtime/src/config.ts:83
    const j = JSON.parse(readFileSync(cf, "utf8"));
  • 发起网络请求
    packages/runtime/src/controller.ts:24
    const res = await ctx.runtime.fetch(access.runtimeId, "/_control", {
  • 读取本地文件
    packages/runtime/src/data-source.ts:266
    stored = JSON.parse(await readFile(filename, "utf8"));
  • 写入本地文件
    packages/runtime/src/data-source.ts:327
    await mkdir(ctx.dataDir, { recursive: true });
  • 写入本地文件
    packages/runtime/src/data-source.ts:329
    await writeFile(pending, JSON.stringify(next, null, 2) + "\n", { mode: 0o600 });
  • 写入本地文件
    packages/runtime/src/data-source.ts:330
    await rename(pending, filename);
  • 读取本地文件
    packages/runtime/src/data-source.ts:379
    stored = JSON.parse(readFileSync(filename, "utf8"));
  • 读取本地文件
    packages/runtime/src/legacy-migrate.ts:63
    const j = JSON.parse(readFileSync(markerPathOf(dataDir), "utf8"));
  • 写入本地文件
    packages/runtime/src/legacy-migrate.ts:72
    mkdirSync(path.dirname(markerPathOf(dataDir)), { recursive: true });
  • 写入本地文件
    packages/runtime/src/legacy-migrate.ts:74
    writeFileSync(tmp, JSON.stringify(marker, null, 2) + "\n", "utf8");
  • 写入本地文件
    packages/runtime/src/legacy-migrate.ts:75
    renameSync(tmp, markerPathOf(dataDir));
  • 读取本地文件
    packages/runtime/src/legacy-migrate.ts:86
    list = readdirSync(dir, { withFileTypes: true });
  • 读取本地文件
    packages/runtime/src/legacy-migrate.ts:108
    if (!existsSync(p)) continue;
  • 读取本地文件
    packages/runtime/src/legacy-migrate.ts:110
    const j = JSON.parse(readFileSync(p, "utf8"));
  • 读取本地文件
    packages/runtime/src/legacy-migrate.ts:130
    if (!existsSync(legacyDshHome) || !statSync(legacyDshHome).isDirectory()) {
  • 读取本地文件
    packages/runtime/src/legacy-migrate.ts:130
    if (!existsSync(legacyDshHome) || !statSync(legacyDshHome).isDirectory()) {
  • 读取本地文件
    packages/runtime/src/managed-runtime.ts:219
    (p) => readFileSync(p, "utf8"),
  • 执行外部命令来自配置/变量
    packages/runtime/src/managed-runtime.ts:220
    (cmd, args) => execFileSync(cmd, args, { encoding: "utf8", timeout: 5000, windowsHide: true }),
  • 写入本地文件
    packages/runtime/src/managed-runtime.ts:276
    mkdirSync(dir, { recursive: true });
  • 写入本地文件
    packages/runtime/src/managed-runtime.ts:278
    writeFileSync(filename, JSON.stringify(config), { mode: 0o600 });
  • 写入本地文件
    packages/runtime/src/managed-runtime.ts:279
    try { chmodSync(filename, 0o600); } catch { }
  • 读取本地文件
    packages/runtime/src/managed-runtime.ts:320
    const raw = readFileSync(fatalPath, "utf8");
  • 删除本地文件
    packages/runtime/src/managed-runtime.ts:321
    rmSync(fatalPath, { force: true });
  • 删除本地文件
    packages/runtime/src/managed-runtime.ts:469
    try { rmSync(configPath, { force: true }); } catch { }
  • 删除本地文件
    packages/runtime/src/managed-runtime.ts:470
    try { rmSync(resultPath, { force: true }); } catch { }
  • 读取本地文件
    packages/runtime/src/managed-runtime.ts:491
    const raw = readFileSync(resultPath, "utf8");
  • 读取本地文件
    packages/runtime/src/managed-runtime.ts:590
    if (existsSync(join(dir, "manifest.json"))) return dir;
  • 读取本地文件
    packages/runtime/src/managed-runtime.ts:618
    if (!existsSync(probePath)) {
  • 执行外部命令来自配置/变量
    packages/runtime/src/managed-runtime.ts:627
    const out = execFileSync(process.execPath, ["--allow-net", probePath], {
  • 删除本地文件
    packages/runtime/src/managed-runtime.ts:704
    try { rmSync(configPath, { force: true }); } catch { }
  • 删除本地文件
    packages/runtime/src/managed-runtime.ts:705
    try { rmSync(fatalPath, { force: true }); } catch { }
  • 删除本地文件
    packages/runtime/src/managed-runtime.ts:716
    setTimeout(() => { try { rmSync(configPath, { force: true }); } catch { } }, 10000);
  • 发起网络请求
    packages/ui/src/app.ts:207
    fetch(privatePrefix + "index.html", { cache: "no-store", credentials: "same-origin" })
  • 发起网络请求
    packages/ui/src/dsh-inject.ts:54
    return fetch(new Request(preserved, { ...init, credentials: "same-origin" }));
  • 发起网络请求
    packages/ui/src/dsh-inject.ts:56
    return fetch(mapRuntimeUrl(input, privateBase, pageOrigin), { ...init, credentials: "same-origin" });
  • 发起网络请求
    packages/ui/src/host-theme.ts:153
    fetch(url, { credentials: "same-origin", cache: "no-store" })
  • 发起网络请求
    packages/ui/src/surface-bridge.ts:58
    return fetch("/api/apps/" + encodeURIComponent(appId) + "/routes/" + path, opts);
  • 发起网络请求
    packages/ui/src/surface-bridge.ts:95
    return fetch(prefix, {
扫描于 2026/11/3(0 天前) · 范围 全包扫描 · 来源 GitHub 仓库

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

依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/cordis-plugin-group@deepseek-ai/dsh@deepseek-ai/dsh-host-open-in-app
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

README

由 DeepSeek 最新模型翻译生成
DSHana Hana App ID:dshana 把 DeepSeek Harness 接入 HanaAgent,作为受管子代理执行器:App 加载后拉起受管 Node runtime(ctx.runtime.start),DSH web 服务跑在里面;DSH 前端以同文档注入方式挂进 DSHana 卡。DSH 及其依赖树随包分发,运行时不需要安装任何东西。 安装 人类版 1. 拖入 zip 包:把发行包 zip(dshana-v<version>.zip,从 GitHub Releases 下载)拖进 HanaAgent 的 App 安装界面;批准安装审阅卡上的权限(共 11 项:工具暴露、子代理与任务、会话发起、模型推理、会话读取、资源读取、进程派生、运行时执行 / 本机运行 / 联网、打开外部;其中本机运行档位无文件系统隔离,审阅卡会如实标注)。 2. 打开 DSHana 卡:App 加载后自动拉起受管 runtime,卡上按三态渲染:未启动 / 启动中 / 就绪(装载 DSH Web UI)。失败会进入「需要处理」态,卡上给出原因与原始错误;打开本卡会补一次启动请求,之后由自动退避重试兜着,端口占用会自动换端口。 Agent 版 取件、核验与安装的完整流程见 dshana-install-skill/SKILL.md。
展开完整文档(README 剩余 1 节)
DSHana

Hana App ID:dshana

把 DeepSeek Harness 接入 HanaAgent,作为受管子代理执行器:App 加载后拉起受管 Node runtime(ctx.runtime.start),DSH web 服务跑在里面;DSH 前端以同文档注入方式挂进 DSHana 卡。DSH 及其依赖树随包分发,运行时不需要安装任何东西。

安装

人类版

1. 拖入 zip 包:把发行包 zip(dshana-v<version>.zip,从 GitHub Releases 下载)拖进 HanaAgent 的 App 安装界面;批准安装审阅卡上的权限(共 11 项:工具暴露、子代理与任务、会话发起、模型推理、会话读取、资源读取、进程派生、运行时执行 / 本机运行 / 联网、打开外部;其中本机运行档位无文件系统隔离,审阅卡会如实标注)。

2. 打开 DSHana 卡:App 加载后自动拉起受管 runtime,卡上按三态渲染:未启动 / 启动中 / 就绪(装载 DSH Web UI)。失败会进入「需要处理」态,卡上给出原因与原始错误;打开本卡会补一次启动请求,之后由自动退避重试兜着,端口占用会自动换端口。

Agent 版

取件、核验与安装的完整流程见 dshana-install-skill/SKILL.md。

设置

App 级设置由 App 自绘设置页承载,在宿主设置区渲染,不依赖 DSH 运行;页面分「常规」「会话模型」「主题」三节:

| 项 | 默认 | 说明 |
| 审批超时 | 30 | 常规;单位秒,无人应答即自动拒绝,填 0 禁用 |
| 任务超时 | 1800 | 常规;单位秒,单次任务超时,填 0 按缺省 1800 兜底 |
| 会话模型 | 复用调用方 | 工具建的新会话用哪个模型:复用调用方 = 用发起这次调用的会话当前在用的那条(含推理强度);自定义模型 = 固定用下面选的那条 |
| 模型 | (空) | 选「自定义模型」时出现;候选列宿主目录里的 provider 与模型 |
| 推理强度 | 留空 | 选「自定义模型」时出现,该模型支持的档位;留空沿用 DSH 当前设置 |
| 强制跟随宿主主题的面 | 仅侧栏 | 主题;勾上的面恒跟随宿主配色且覆盖带 !important,不勾的只在 DSH 偏好为 system 时跟随并让位给插件请求 |

DSH 数据固定落在 App 内置独立目录,开箱即用;共享或切换已有 DSH 目录暂不提供。

无需配置 API Key / 模型:推理经受管 runtime 内宿主 ctx.models 发起,provider 凭据不进 DSH 进程。DSH 自己那格默认模型(settings 段 agent-default-model)归 DSH 管,本 App 不读也不改;dshana 的 provider / model / reasoningEffort 参数可显式覆盖单次任务。

主题

DSH 主题偏好为 system 时跟随宿主配色,宿主切主题后已打开的页面实时跟随;在 DSH 内显式选 light/dark 时完全用 DSH Web UI 自己的主题。

例外是强制跟随宿主主题的面(设置页「主题」节,逐面一个开关,缺省只勾侧栏):这一面恒跟随宿主,无视 DSH 自己的明暗偏好,且覆盖带 !important,插件改写不了它。缺省只勾侧栏,是因为它整幅嵌在宿主框架里、四周都是宿主色。改完设置即时生效,不必重启。

排错

把现象丢给 Agent 即可(技能 dshana 里有按三态组织的排错表)。也可以直接看:

- 卡上状态与原始错误(需要处理 态会展开)
- 宿主日志面:本 App 的日志一律走 ctx.logger(不另写文件日志),DSH 子进程的 stdout/stderr 由宿主受管 runtime 捕获

License

This project is licensed under the Mozilla Public License 2.0.
See the LICENSE file for details.

This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0.
预览分享卡片长什么样 ↓Nyasers/DSHana
分享 · DeepSeek Harness Hub
Nyasers/DSHana

DSHana:把 DeepSeek Harness 当作 HanaAgent 的子代理

回到顶部