JSON Schema 验证内核:validate/paths/explain/normalize 四动作,零网络零动态代码,含资源硬上限与 ReDoS 防护。
ⓘ 此插件是大仓库 omdsh-dev/dsh-toolkit 的子包,星数与活跃度统计的是整个仓库。
- 语言
- TypeScript
- License
- MIT
- 分支
- main
安装
$ dsh plugin --profile web add github:omdsh-dev/dsh-toolkit#path:packages/dsh-tool-schema在终端中运行以上命令,通过 dsh CLI 安装此插件。可在右上角切换 Profile。 第一次用 dsh?看这篇新手教程
对话式安装
帮我安装 DeepSeek Harness 插件 omdsh-dev/dsh-toolkit/packages/dsh-tool-schema:先查看仓库 https://github.com/omdsh-dev/dsh-toolkit 确认安全性,然后执行安装命令并验证插件加载成功。
把这段指令粘贴给 DSH Web GUI 里的助手,由它代你完成安装与验证。
一句话定位
dsh-tool-schema 为 DSH 助手提供独立的 JSON Schema 验证内核:用一次工具调用就能验证数据是否符合 schema、列出失败路径、解释 schema 约束或深拷贝后补 default。它把模型"目测"嵌套 schema 的不可靠环节替换成可验证、有边界的过程,全过程不联网、不执行代码。
核心能力
- validate:验证 JSON 数据是否符合 schema,输出 RFC 6901 instancePath/schemaPath 错误、schemaIssues 与截断标记
- paths:按数据路径分组返回失败位置与对应关键字摘要,便于快速报告"哪几个字段不对"
- explain:静态遍历 schema 约束树,输出人读节点列表(不构造 RegExp、不做匹配),同时报告不支持的关键字
- normalize:深拷贝数据,对 properties 中缺失字段应用显式 default 后再做完整 validate,全程不改输入
- pattern 校验在隔离 worker 内共享 1000ms 总预算运行,超时即终止,杜绝灾难性回溯阻塞宿主
- 不支持的 schema 关键字永不静默忽略,统一以 schemaIssues 暴露,strict 模式直接判失败
技术实现
- 语言: TypeScript(零运行时依赖,纯函数 + Node 内置
node:worker_threads) - 关键依赖:
node:worker_threads(pattern 隔离执行)、@deepseek-ai/dsh-tools(defineTool工具定义)、@deepseek-ai/cordis(宿主注入)、@deepseek-ai/dsh-invariants(invariants 服务) - 架构模式: 通过包内
cordis.patch.yml把插件插入 profile 的 layer stack(row idtool-schema),注册名为schema的工具;execute同步返回Promise.resolve,统一输出{ type: 'json' }+JSON.stringifyrender 文本块;validate/paths/normalize 共享validateCore,explain 走独立静态遍历;pattern 在Worker中执行,1000ms 共享预算到期 host 侧terminate() - 入口文件:
src/index.ts(apply(ctx)钩子)
适用场景
当模型需要验证 API 响应、插件 manifest、配置文件或会话事件的结构是否符合 schema、并指出具体哪个字段出错时使用本插件。它尤其适合复杂嵌套 schema(allOf/oneOf/$ref/pattern 组合)—— 这种场景下人工判断极易漏判,本插件能给出稳定排序的失败路径与 schema 问题清单,便于模型复述给用户。
前置依赖与兼容性
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| DSH | 0.1.0-rc.8 | 已在 @deepseek-ai/[email protected] 隔离 consumer 中完成全链路验证 |
| Node.js | 22.19.0 或 ≥24.0.0 | engines.node 声明 ^22.19.0 || >=24.0.0 |
| @deepseek-ai/cordis | ^4.0.1 | peer 依赖,由宿主提供 |
| @deepseek-ai/dsh-tools | ≥0.0.1-rc.1 <0.2.0 | peer 依赖,提供 defineTool |
| @deepseek-ai/dsh-invariants | ≥0.0.1-rc.1 <0.2.0 | peer 依赖,提供 invariants 服务 |
| 平台 | 跨平台 | 无 os/cpu 字段限制 |
| 原生模块 | node:worker_threads | Node 内置,无需额外编译 |
安装方式
dsh plugin --profile web add github:omdsh-dev/dsh-toolkit/packages/dsh-tool-schema
配置项
本插件无需额外配置。安装后插件自动注册到 profile 的 layer stack,工具即可直接调用,无需读取配置文件或设置环境变量。所有可调参数均通过工具调用本身的 action、data、schema、strictSchema、maxErrors 字段在每次调用时传入。
常见问题
Q: 这个插件需要任何配置吗?
A: 不需要。安装完成后插件自动注册到 profile 层,工具即可直接调用,无需编辑配置文件或设置环境变量。
Q: 跟 dsh-tool-json 的查询功能有什么区别?
A: dsh-tool-json 用于按 JMESPath 子集从 JSON 中取数据/筛选,本插件用于验证结构是否符合 schema 并定位失败路径。两者职责互补—— 先用 json 取数、再用 schema 验证结构,是常见组合。
Q: 会执行任意代码或访问网络吗?
A: 不会。验证内核是纯数据遍历,不构造 RegExp(pattern 在独立 worker 内执行)、不 eval、不访问网络、不读文件。所有对象访问用 Object.hasOwn,__proto__/constructor/prototype 只作为普通 JSON 键处理,不会产生原型链误判。
Q: schema 用了不支持的关键字会怎样?
A: 会显式报告 schemaIssue(code 为 unsupported-keyword)。strictSchema=true(默认)下直接判失败(valid:false + complete:false);strictSchema=false 下只验证已支持子集,返回 valid:null + complete:false + supportedSubsetValid,绝不会装作"全过了"。
Q: 病理正则(灾难性回溯)会卡死助手吗?
A: 不会。所有 pattern 校验在可终止的 worker 线程中共享 1000ms 总预算;超时即 worker.terminate() 并返回 pattern-timeout 错误。explain 完全不构造 RegExp、走静态扫描,天然免疫回溯。
Q: 输入大小有限制吗?
A: 有硬上限:data 与 schema 各 ≤ 256 KiB,嵌套深度 ≤ 64,schema 节点 ≤ 10000,遍历节点 ≤ 100000,错误数默认 100(最大 1000),$ref 链 ≤ 64,单 schema 内 pattern ≤ 100 个且单 pattern ≤ 16 KiB,canonical 输出 ≤ 1 MiB。超限按错误或截断(置 truncated)处理。
Q: normalize 会修改我的输入数据吗?
A: 不会。normalize 始终先对输入做深拷贝(新对象均为 Object.create(null) 防原型污染),再应用 properties 中缺失字段的显式 default,最后对结果做完整 validate。默认值必须 JSON 兼容且通过对应子 schema,否则给 default-invalid 警告并跳过,不强制类型、不删 additional properties。
Q: 怎么卸载?
A: 通过 profile 的 bundle 层管理移除:使用 dsh plugin --profile web remove tool-schema,或直接编辑 profile 的 layer stack 删除 row id 为 tool-schema 的行。
上手难度
入门 — 调用接口只需传 action + data + schema 三个字段,strictSchema/maxErrors 等可省略(默认值已内置),资源边界与超时已封装好,但需要用户对 JSON Schema 关键字(type/required/allOf/$ref 等)有基本认知。
已知问题与限制
- 资源硬上限全面生效:data/schema 各 ≤ 256 KiB,嵌套 ≤ 64,schema 节点 ≤ 10000,遍历 ≤ 100000,错误默认 100/上限 1000,
$ref链 ≤ 64,pattern ≤ 100 个/单条 ≤ 16 KiB,canonical 输出 ≤ 1 MiB(src/limits.ts:7-37) - pattern 总硬预算 1000ms,到期 worker
terminate()并报pattern-timeout,不会阻塞宿主(src/pattern-worker.ts:84-123/README.md:21-31) - canonical JSON 输出超 1 MiB 时渐进截断 errors/schemaIssues/nodes/warnings/paths/appliedDefaults 数组并置
truncated=true,不是直接拒绝(src/index.ts:58-83) format关键字按 annotation 容忍(不参与验证),即便 schema 显式写 format 也不会生效;这是 v1 的明确边界决定(src/schema-check.ts:57-73)multipleOf使用缩放/容差策略(相对容差1e-9),不承诺任意精度;极端浮点组合(如 1e308 与极小 divisor 导致q溢出为 Infinity)会一致判定为非倍数(src/validator.ts:197-203)items不支持 tuple 数组形式(schema-check 会报schema-invalid),单 schema 形式正常(src/schema-check.ts:161-170)- 仅支持本地
$ref(#与#/$defs/<token>),远程/绝对/相对路径以及 anchor 形式(#foo)一律拒绝(src/ref.ts:56-78) - 工具参数会记入会话日志(DSH 通用机制),本插件 README 明确要求不要传入敏感数据(
README.md:31)
DSH 零依赖工具包 collection —— time / encoding / json / calculator / csv / regex / markdown / diff / stat / schema 十个确定性工具,统一入口一键安装。
为什么
DSH 生态仓库持续增长,单插件在 hub 中容易被淹没;collection 分类是辨识度最高的形态。本仓库把 10 个工具插件 vendored 冻结为 pack artifact 快照(各子仓库独立演进,当前源位于 omdsh-dev 组织下),统一工程、统一测试、统一维护。
定位(官方 Profile Bundle 生态方向):本仓库是 collection 与安装辅助仓库——每个子包都是可独立安装/启用/禁用/卸载的 bundle(dsh plugin --profile <p> add <子包>);collection 提供目录、清单与批量安装脚本。meta 包 @deepseek-ai/dsh-toolkit 保留为可选的原子挂载模型(见下文两种运行模型)。
分发边界:根 meta 包保持 private: true,用于 Git/collection 分发,不代表会发布到 npm registry。根目录已提交由当前 src 构建出的 lib/index.js 与 lib/types/index.d.ts,因此从 Git 安装时不依赖消费端 lifecycle;prepack 仍会在生成 pack artifact 前执行完整构建。
工具一览
| 工具 | 能力 | 用例数 |
|---|---|---|
time | ISO 8601 / 时区 / 日历运算 / 时长差 | 65 |
encoding | base64 / url / hex / hash / UUID | 46 |
json | JMESPath 子集查询 | 66 |
calculator | 安全数学表达式求值(无 eval) | 31 |
csv | RFC 4180 解析 / 查询 / 统计(严格引号) | 50 |
regex | 测试 / 提取 / 替换 / 静态解释(worker 硬超时) | 63 |
markdown | HTML↔Markdown / GFM 表格 / 目录生成(白名单安全) | 71 |
diff | 文本/JSON/CSV/Markdown 结构化比较与 unified diff(只读) | 124 |
stat | 描述统计 / 百分位数 / 频数分布 / 相关性(零依赖确定性) | 82 |
schema | JSON Schema 验证 / 路径 / 解释 / 安全 default(零网络零动态) | 125 |
| 合计 | 723 |
架构
dsh-toolkit/
├── src/index.ts # meta 包:相对路径动态导入 10 个子包 apply(),聚合注册
├── packages/dsh-tool-* # vendored 子包(pack artifact 快照,name 保持 @deepseek-ai/dsh-tool-*)
├── scripts/
│ ├── link-deps.sh # 构建期 junction(cordis → vendor/cordis,dsh-tools → packages/core/tools)
│ ├── build-all.sh # 一键构建 10 子包 + meta 包(tsc)
│ ├── test-all.sh # 一键跑 10 子包 vitest(合计用例数)
│ ├── install.sh # meta / 逐包两种挂载模式(含 dry-run)
│ ├── install-web.sh # 独立 bundle 批量安装 → web profile
│ ├── install-headless.sh # 独立 bundle 批量安装 → headless profile
│ └── install-all.sh # web + headless 都装
├── catalog.json # collection 清单(hub collection 分类识别依据)
└── tsconfig.base.json # 共享编译配置(固化踩坑经验)
与实施文档方案 A 的工程化适配:子包为私有 Git/collection 包,peer 名解析在 profile 内不可行, 故 meta 包采用相对路径动态导入(零解析魔法、打包自足);子包 runtime 依赖 (
@deepseek-ai/dsh-tools)在 npm 独立模式(默认)下不依赖 DSH monorepo,monorepo 模式经子包构建期 junction 解析。
安装
仓库位于 omdsh-dev/dsh-toolkit(public)。
独立 bundle 模型(推荐)
每个子包独立安装、启用、禁用、卸载:
# 安装单个工具到 web profile
dsh plugin --profile web add github:omdsh-dev/dsh-tool-csv
# 一次性任务(headless)profile
dsh plugin --profile headless add github:omdsh-dev/dsh-tool-diff
批量安装(collection 辅助脚本,幂等——重复执行不会重复添加):
./scripts/install-web.sh # 全部 10 工具 → web profile
./scripts/install-headless.sh # 全部 10 工具 → headless profile(dsh run 使用面)
./scripts/install-all.sh # 两个 profile 都装
验证与运行:
dsh --profile web --dump-config | grep tool-csv # 行存在即安装成功
dsh run "使用 csv 工具解析 'a,b\n1,2'" # headless 端到端
⚠️ web 与 headless 是不同 profile:web 安装不会自动覆盖 headless;
dsh run默认使用 headless。 Windows 路径使用正斜杠(C:/...)。
npm pack tarball 安装
本地构建后用 tarball 路径安装(不依赖 GitHub):
# tarball 方式(web 为例;headless 同)
npm pack
dsh plugin --profile web add <npm pack 产物 tarball 路径>
meta bundle 模型(可选)
需要一次原子挂载全部工具时,挂载根 meta 包:
dsh plugin --profile web add github:omdsh-dev/dsh-toolkit
dsh --profile web --dump-config | grep tool-kit
⚠️ 若 profile 已单独挂载过同名插件(tool-time/.../tool-diff/tool-stat/tool-schema),挂 meta 包会注册重名报错—— 此时先移除旧插件,或用独立 bundle 模型。meta apply 具备原子性(任一子插件失败时 逆序回滚已注册工具,不残留部分状态)。
手动安装与旧版本兼容
旧场景(monorepo 集成、不支持 Profile Bundle 的旧快照或插件开发调试环境——本地 junction/symlink、手动编辑 profile 层)。
构建与测试
npm 独立模式(默认,推荐):无需 DSH monorepo;npm install(devDependencies 自包含)后即可:
npm run build:all # 10 子包 + meta 包 tsc + 产物完整性验证(无 .ts 残留导入、10+1 个 lib/index.js)
bash scripts/test-all.sh # 10 子包 vitest 全量(723 用例);任一失败整体非零退出
npm pack # prepack 自包含(build:all),tarball 含 lib + 10 个子包
monorepo 模式(可选:源码贡献/旧 snapshot):显式提供 DSH monorepo 根:
export DSH_MONOREPO=<DSH 0.1.0-rc.8(npm)安装路径> # 或作为第一个参数
bash scripts/build-all.sh # link-deps + 10 子包 + meta 包 tsc + 产物完整性验证
bash scripts/test-all.sh
prepack已指向build:all(完整构建 10 子包 + meta),保证 pack artifact 含全部运行入口;根 Git 入口由当前src预构建并提交。 本仓库只在本地验证构建、测试与 pack artifact;不要将这些结果解读为 npm registry 发布或未实际执行的 consumer/profile 验证。
同步 vendored(子仓库有更新时)
把 packages/<name> 与源仓库重新同步(src/tests/package.json/tsconfig/cordis.patch.yml/LICENSE/README.md),并在 README 标注子包版本。
新增工具
见 docs/CONTRIBUTING.md:复制模板子包 → 实现 → 测试 → build-all 验证 → 更新 catalog.json。
许可
MIT
查看使用指南 →
该插件的安装步骤、关键要点、FAQ 与兼容性说明(基于已收录字段派生)。
收录徽章
[](https://deepseek-plugin.org/plugins/omdsh-dev/dsh-toolkit/packages/dsh-tool-schema)把这段 markdown 粘贴到你的 GitHub README,链接回本插件详情页。徽章只声明已被本站收录,不代表安全认证。