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

工具按需加载 lvy-jsd/dsh-tool-ultra

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

为 DeepSeek Harness 按需加载工具 —— 所有工具组织成目录,只有 Agent 主动加载的才进入上下文。

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

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

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add lvy-jsd/dsh-tool-ultra
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:需留意
是什么
dsh 原生插件 · tool
装得上吗
实装验证未通过(unknown),装前请到仓库确认最近更新与 issue
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 3 天前
档位由哪些信号合成

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

验证判据与等级说明 →
⚠︎ 实装验证未通过(unknown · 2026/11/3) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
社区实装还没有人打卡 · 装过的第一个就是你
🔴 安全扫描发现高危能力自动 · 静态分析源码
v2.7.0
🔴 扫描:高危尚无人工评估

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

安装时即执行脚本可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 60 处,展示前 60 条)
  • 读取本地文件
    scripts/link-host.mjs:19
    if (!existsSync(hostModules)) {
  • 读取本地文件
    scripts/link-host.mjs:30
    if (!existsSync(manifest)) continue
  • 读取本地文件
    scripts/link-host.mjs:31
    const peers = Object.keys(JSON.parse(readFileSync(manifest, 'utf8')).peerDependencies ?? {})
  • 读取本地文件
    scripts/link-host.mjs:34
    if (!existsSync(target)) continue
  • 写入本地文件
    scripts/link-host.mjs:36
    mkdirSync(dirname(link), { recursive: true })
  • 读取本地文件
    scripts/link-host.mjs:37
    if (existsSync(link) || isLink(link)) rmSync(link, { recursive: true, force: true })
  • 删除本地文件递归
    scripts/link-host.mjs:37
    if (existsSync(link) || isLink(link)) rmSync(link, { recursive: true, force: true })
  • 读取本地文件
    scripts/link-host.mjs:46
    return lstatSync(path).isSymbolicLink()
  • 读取本地文件
    packages/create-dsh-tool-ultra-plugin/src/cli.ts:323
    if (existsSync(target) && existsSync(join(target, 'package.json'))) {
  • 写入本地文件
    packages/create-dsh-tool-ultra-plugin/src/cli.ts:336
    mkdirSync(dirname(path), { recursive: true })
  • 写入本地文件
    packages/create-dsh-tool-ultra-plugin/src/cli.ts:337
    writeFileSync(path, body)
  • 读取本地文件
    packages/dsh-tool-ultra-attribution-scan/src/index.ts:62
    entries = await readdir(dir, { withFileTypes: true })
  • 读取本地文件
    packages/dsh-tool-ultra-attribution-scan/src/index.ts:98
    if ((await stat(file)).size > MAX_FILE_BYTES) continue
  • 读取本地文件
    packages/dsh-tool-ultra-attribution-scan/src/index.ts:99
    text = await readFile(file, 'utf8')
  • 读取本地文件
    packages/dsh-tool-ultra-classifier-llm/src/index.ts:107
    const parsed = JSON.parse(readFileSync(file, 'utf8'))
  • 写入本地文件
    packages/dsh-tool-ultra-classifier-llm/src/index.ts:119
    mkdirSync(dirname(file), { recursive: true })
  • 写入本地文件
    packages/dsh-tool-ultra-classifier-llm/src/index.ts:121
    writeFileSync(tmp, JSON.stringify(cache, null, 2))
  • 写入本地文件
    packages/dsh-tool-ultra-classifier-llm/src/index.ts:122
    renameSync(tmp, file)
  • 读取本地文件
    packages/dsh-tool-ultra-core/src/exempt.ts:60
    text = readFileSync(file, 'utf8')
  • 写入本地文件
    packages/dsh-tool-ultra-core/src/exempt.ts:79
    mkdirSync(dirname(file), { recursive: true })
  • 写入本地文件
    packages/dsh-tool-ultra-core/src/exempt.ts:82
    writeFileSync(tmp, `${JSON.stringify({ providers: config.providers, sessions: config.sessions }, null, 2)}\n`)
  • 写入本地文件
    packages/dsh-tool-ultra-core/src/exempt.ts:83
    renameSync(tmp, file)
  • 读取本地文件
    packages/dsh-tool-ultra-core/src/manifest.ts:81
    return readFileSync(file, 'utf8') === text
  • 写入本地文件
    packages/dsh-tool-ultra-core/src/manifest.ts:91
    mkdirSync(dirname(file), { recursive: true })
  • 写入本地文件
    packages/dsh-tool-ultra-core/src/manifest.ts:93
    writeFileSync(temporary, text, 'utf8')
  • 写入本地文件
    packages/dsh-tool-ultra-core/src/manifest.ts:94
    renameSync(temporary, file)
  • 读取本地文件
    packages/dsh-tool-ultra-core/src/metadata.ts:51
    return pickMetadata(JSON.parse(readFileSync(file, 'utf8')))
  • 写入本地文件
    packages/dsh-tool-ultra-core/src/metadata.ts:62
    mkdirSync(dirname(file), { recursive: true })
  • 写入本地文件
    packages/dsh-tool-ultra-core/src/metadata.ts:65
    writeFileSync(tmp, `${JSON.stringify(entries, null, 2)}\n`)
  • 写入本地文件
    packages/dsh-tool-ultra-core/src/metadata.ts:66
    renameSync(tmp, file)
  • 读取本地文件
    packages/dsh-tool-ultra-core/src/service.ts:59
    if (existsSync(candidate)) {
  • 读取本地文件
    packages/dsh-tool-ultra-core/src/service.ts:60
    const json = JSON.parse(readFileSync(candidate, 'utf8'))
  • 读取本地文件
    packages/dsh-tool-ultra-core/src/service.ts:88
    const declared = JSON.parse(readFileSync(manifestPath, 'utf8'))?.dsh?.toolCatalog
  • 读取本地文件
    packages/dsh-tool-ultra-core/src/settings.ts:44
    return pickSettings(JSON.parse(readFileSync(file, 'utf8')))
  • 写入本地文件
    packages/dsh-tool-ultra-core/src/settings.ts:55
    mkdirSync(dirname(file), { recursive: true })
  • 写入本地文件
    packages/dsh-tool-ultra-core/src/settings.ts:58
    writeFileSync(tmp, `${JSON.stringify(settings, null, 2)}\n`)
  • 写入本地文件
    packages/dsh-tool-ultra-core/src/settings.ts:59
    renameSync(tmp, file)
  • 发起网络请求
    packages/dsh-tool-ultra-pack-essentials/src/index.ts:162
    const doFetch: FetchLike = opts.fetch ?? ((url, init) => fetch(url, init as RequestInit))
  • 执行外部命令来自配置/变量
    packages/dsh-tool-ultra-pack-media/src/ffmpeg.ts:25
    execFile(file, args, { timeout: timeoutMs, windowsHide: true, maxBuffer: 4 * 1024 * 1024 }, (error, stdout, stderr) => {
  • 执行外部命令来自配置/变量
    packages/dsh-tool-ultra-pack-media/src/ffmpeg.ts:34
    const child = spawn(file, args, { stdio: ['pipe', 'ignore', 'pipe'], windowsHide: true })
  • 读取本地文件
    packages/dsh-tool-ultra-pack-media/src/files.ts:11
    return await realpath(path)
  • 写入本地文件
    packages/dsh-tool-ultra-pack-media/src/output.ts:28
    await mkdir(dir, { recursive: true })
  • 写入本地文件
    packages/dsh-tool-ultra-pack-media/src/output.ts:33
    await writeFile(path, data, { flag: 'wx' })
  • 发起网络请求
    packages/dsh-tool-ultra-pack-web/src/index.ts:199
    const doFetch: FetchLike = opts.fetch ?? ((url, init) => fetch(url, init) as unknown as Promise<FetchResponse>)
  • 发起网络请求
    packages/dsh-tool-ultra-panel/src/client.ts:511
    const res = await fetch(API, {
  • 读取本地文件
    packages/dsh-tool-ultra-persist/src/index.ts:49
    return JSON.parse(readFileSync(file, 'utf8'))
  • 删除本地文件
    packages/dsh-tool-ultra-persist/src/index.ts:65
    rmSync(file, { force: true })
  • 写入本地文件
    packages/dsh-tool-ultra-persist/src/index.ts:68
    mkdirSync(dir, { recursive: true })
  • 写入本地文件
    packages/dsh-tool-ultra-persist/src/index.ts:69
    writeFileSync(file, JSON.stringify(state, null, 2))
  • 删除本地文件
    packages/dsh-tool-ultra-persist/src/index.ts:83
    if (file) rmSync(file, { force: true })
  • 执行外部命令固定命令
    scripts/build-sidecar.mjs:29
    const run = spawnSync('cargo', args, { stdio: 'inherit' })
  • 写入本地文件
    scripts/build-sidecar.mjs:38
    mkdirSync(dirname(out), { recursive: true })
  • 写入本地文件
    scripts/build-sidecar.mjs:39
    copyFileSync(built, out)
  • 写入本地文件
    scripts/build-sidecar.mjs:40
    chmodSync(out, 0o755)
  • 执行外部命令来自配置/变量
    scripts/smoke-packs.mjs:43
    const child = spawn(client.command, client.args, { env: { ...process.env, ...client.env }, stdio: ['pipe', 'pipe', 'ignore'] })
  • 写入本地文件
    scripts/swiftnest-integration.mjs:45
    await mkdir(shared)
  • 写入本地文件
    scripts/swiftnest-integration.mjs:46
    await writeFile(join(shared, 'hello.txt'), 'hello from the laptop perch')
  • 写入本地文件
    scripts/swiftnest-integration.mjs:95
    await mkdir(join(home, 'dsh/profiles/swiftnest'), { recursive: true })
  • 写入本地文件
    scripts/swiftnest-integration.mjs:96
    await writeFile(join(home, 'dsh/profiles/swiftnest/user.patch.yml'), JSON.stringify([{ insert: [
  • 删除本地文件递归
    scripts/swiftnest-integration.mjs:173
    await rm(home, { recursive: true, force: true })
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 GitHub 仓库

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

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

按需加载 DeepSeek Harness 工具:像浏览目录一样查看所有工具,只加载你要用的。

README

由 DeepSeek 最新模型翻译生成
Tool Ultra 为 DeepSeek Harness 按需加载工具 —— 所有工具组织成目录,只有 Agent 主动加载的才进入上下文。 English · 中文 它是什么 为 DeepSeek Harness 按需加载工具:所有工具都组织成一个目录(分类 → 分组 → 工具),只有 Agent 主动加载的部分才会进入模型上下文。整体是一个小的核心加若干可替换的扩展插件。 已改名。 本项目原名 dsh-tool-manager。从 0.5.0 起,所有包从 @lvy-jsd/dsh-tool-manager-<名字> 改名为 @lvy-jsd/dsh-tool-ultra-<名字>(核心是 @lvy-jsd/dsh-tool-ultra-core)。其他都不变:入口工具、 toolCatalog 服务(另外也以 toolUltra 的名字提供)、钩子、配置和状态目录 <DSH_HOME>/tool-manager/。 已有的配置可以继续用 @lvy-jsd/dsh-tool-manager:从 0.5.0 起它只是转出新核心。旧版扩展也能和新核心一起用。
展开完整文档(README 剩余 1 节)
Tool Ultra
为 DeepSeek Harness 按需加载工具 —— 所有工具组织成目录,只有 Agent 主动加载的才进入上下文。

English · 中文

它是什么

为 DeepSeek Harness 按需加载工具:所有工具都组织成一个目录(分类 → 分组 → 工具),只有 Agent 主动加载的部分才会进入模型上下文。整体是一个小的核心加若干可替换的扩展插件。

已改名。 本项目原名 dsh-tool-manager。从 0.5.0 起,所有包从 @lvy-jsd/dsh-tool-manager-<名字> 改名为 @lvy-jsd/dsh-tool-ultra-<名字>(核心是 @lvy-jsd/dsh-tool-ultra-core)。其他都不变:入口工具、 toolCatalog 服务(另外也以 toolUltra 的名字提供)、钩子、配置和状态目录 <DSH_HOME>/tool-manager/。
已有的配置可以继续用 @lvy-jsd/dsh-tool-manager:从 0.5.0 起它只是转出新核心。旧版扩展也能和新核心一起用。

快速开始

1. 安装核心包和基于规则的分类器(可选,但推荐)
dsh plugin --profile web add @lvy-jsd/dsh-tool-ultra-core @lvy-jsd/dsh-tool-ultra-classifier-rules

2. 重启 DSH,然后问 Agent:"你有哪些工具?"
它会用 tools_ls("/") 回答 —— 是一个目录,不是 200 个工具 schema

3. 想要界面?装上面板,然后打开 设置 →"工具管理"
dsh plugin --profile web add @lvy-jsd/dsh-tool-ultra-panel

请安装带 scope 的 @lvy-jsd/… 包。 npm 上不带 scope 的 dsh-tool-manager 是另一个项目。不要两个同时安装:两者都会收窄 Agent 能看到的工具,装在一起会互相把对方的工具藏起来。

全新安装后,所有分组都归在 uncategorized 下,直到装上分类器 ——工具本身仍然可以浏览和加载,只是缺了分类。想自己写分类器见扩展。

包

| 包 | 作用 |
| @lvy-jsd/dsh-tool-ultra-core | 核心:目录、tools_ls / tools_load / tools_unload、按 Agent 的可见白名单、toolCatalog 扩展服务,外加按意图的检索与路由(tools_find / tools_route / skills_find / skills_route,BM25 + Rust 侧车)。没有扩展时所有分组都在 uncategorized 下。 |
| @lvy-jsd/dsh-tool-ultra-classifier-rules | 按内置规则和你的配置覆盖,把分组放进分类。 |
| @lvy-jsd/dsh-tool-ultra-risk-gate | 通过 DSH 的审批通道确认高危工具的加载,并支持按会话的白名单。 |
| @lvy-jsd/dsh-tool-ultra-persist | DSH 重启后保留已加载的工具,每个会话一个状态文件。 |
| @lvy-jsd/dsh-tool-ultra-panel | 网页面板:浏览目录树、查看每个活动会话已加载的工具和 token 开销,在界面上加载 / 卸载,编辑常驻工具和高危名单,编辑单个工具的元数据,以及豁免某个会话。 |
| @lvy-jsd/dsh-tool-ultra-classifier-llm | 用小模型给分组分类,每个分组一次请求,按分组及其工具描述的哈希缓存结果。 |
| @lvy-jsd/dsh-tool-ultra-capability-bridge | 一次调用加载一组具名工具:tools_load(["cap:android-debug"])。 |
| @lvy-jsd/dsh-tool-ultra-attribution-scan | 按定义这些工具的源码所属的插件包来分组。 |
| @lvy-jsd/dsh-tool-ultra-pack-essentials | 原生工具包,无需 API key:时区与日期计算、带单位的计算器(mathjs)、天气(Open-Meteo)、地点搜索(Nominatim)、维基百科。 |
| @lvy-jsd/dsh-tool-ultra-pack-web | 原生工具包:web_read 把网页正文转成干净的 Markdown(Readability + turndown),web_links 列出页面链接。默认拒绝访问内网地址。 |
| @lvy-jsd/dsh-tool-ultra-pack-mcp | 通过 DSH 的 MCP 客户端启动预设的 MCP 服务器:记忆、顺序思考、Context7、Playwright、文件系统无需 key 就能用;GitHub、SearXNG、Brave、Tavily、Firecrawl、Notion、高德地图在填好 key 后启动。用 mcp_presets 查看状态。 |
| @lvy-jsd/dsh-tool-manager-dsbot-entry | 已弃用,不再发版。在 ds-bot 的设置弹窗里加一行"工具管理",点开显示面板。 |
| @lvy-jsd/dsh-tool-manager | 旧的核心包名:转出 @lvy-jsd/dsh-tool-ultra-core,让已有配置继续可用。 |
| @lvy-jsd/create-dsh-tool-ultra-plugin | 生成你自己的扩展:npm create @lvy-jsd/dsh-tool-ultra-plugin@latest my-ext -- --type classifier。 |

设计说明见 docs/DESIGN.md。

扩展

核心之外的所有功能都是使用 toolCatalog 服务的普通插件,仓库里的 classifier-rules 就是完全按第三方的写法写的。有四个扩展点:

| 扩展点 | 用途 |
| registerClassifier({ name, priority, group?, categorize? }) | 把工具放进分组、把分组放进分类 |
| annotate(match, { group?, category?, risk?, summary? }) | 运行时元数据;package.json 里的 dsh.toolCatalog 不用写代码也能达到同样效果 |
| registerVisibilityFilter({ name, filter(agent, names) }) | 收窄某个 Agent 能看到的范围 —— 只能移除名字 |
| registerTargetResolver({ name, prefix, resolve }) | 认领一个目标前缀,例如 cap:<name> |
| registerRiskGate / registerStateProvider | 确认高危工具的加载 / 跨重启保留状态 |

钩子就是普通事件:tool-catalog/before-load(抛异常即否决)、 after-load、before-unload、after-unload、before-rebuild、 after-rebuild、state-changed。

从一个生成出来的包开始 —— 它自带一个能跑通的测试:

npm create @lvy-jsd/dsh-tool-ultra-plugin@latest my-ext -- --type classifier
cd my-ext && npm test

examples/ 里有两个完整的例子,完整接口列表在核心包的 README 和 docs/DESIGN.md 第 11 节。

开发

所有包都用 TypeScript 编写(src/),编译到 lib/(JavaScript 加 .d.ts 类型声明); lib/ 是构建产物,不进 git。根目录 tsconfig.json 列出所有包(项目引用);两个浏览器端模块(client.ts)有各自的 tsconfig.client.json,因为 DSH 把它们当作经典脚本而不是模块加载。

npm install # 同时把本机 DSH 的宿主包链接进来(scripts/link-host.mjs)
npm run build # src/.ts -> lib/.js + lib/.d.ts
npm run typecheck # 严格类型检查(tsc -b;项目引用需要声明文件,所以也会写 lib/)
node --test test/unit/.test.mjs # 纯 catalog 与注册表测试(需先构建)
node test/e2e.mjs # 启动一次性 DSH 实例;绝不碰你的正式 profile

宿主包(@deepseek-ai/)是 peer 依赖,永远不从 npm 安装(.npmrc 设了 legacy-peer-deps):插件旁边多一份 npm 的副本,会遮蔽你实际运行的 DSH。
npm install 会改为从 $DSH_APP(默认 ~/.local/share/deepseek-harness/app)链接。

许可

Apache-2.0 —— 见 LICENSE。改名为 Tool Ultra 之前的版本(@lvy-jsd/dsh-tool-manager)是 MIT。
预览分享卡片长什么样 ↓lvy-jsd/dsh-tool-ultra
分享 · DeepSeek Harness Hub
lvy-jsd/dsh-tool-ultra

为 DeepSeek Harness 按需加载工具 —— 所有工具组织成目录,只有 Agent 主动加载的才进入上下文。

这是你的仓库?认领条目

回到顶部