@liangjiehappy/dsh-deepseekbase 0.2.2 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/lib/index.js +210 -8
  2. package/lib/skills.js +224 -0
  3. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -4,16 +4,27 @@
4
4
  * Brings deepseekbase.com data into DeepSeek Harness.
5
5
  *
6
6
  * Tools:
7
- * deepseekbase_price — official + third-party provider prices
8
- * deepseekbase_plugin — plugin search WITH sandbox test results
9
- * deepseekbase_specs — model technical specs
10
- * deepseekbase_trend — weekly token volume trend
7
+ * deepseekbase_price — official + third-party provider prices
8
+ * deepseekbase_plugin — plugin search WITH sandbox test results
9
+ * deepseekbase_specs — model technical specs
10
+ * deepseekbase_trend — weekly token volume trend
11
+ * deepseekbase_test_plugin — submit a plugin for a real sandbox install test
12
+ * deepseekbase_test_result — read an existing verdict
13
+ * deepseekbase_quota — remaining free test quota
14
+ * deepseekbase_check — static DSHIO/T 10 conformance check
15
+ *
16
+ * Skills:
17
+ * dshio-standards — the DSHIO standard text
18
+ * dshio-check — the conformance-checking workflow
11
19
  *
12
20
  * Data comes from the public MCP endpoint at https://deepseekbase.com/mcp
13
21
  * (JSON-RPC 2.0 over HTTP). Read-only, no API key required.
14
22
  */
15
23
 
16
24
  import { defineTool } from "@deepseek-ai/dsh-tools";
25
+ import { STANDARDS_SKILL, CHECK_SKILL } from "./skills.js";
26
+
27
+ const SKILLS = [STANDARDS_SKILL, CHECK_SKILL];
17
28
 
18
29
  const MCP_ENDPOINT = "https://deepseekbase.com/mcp";
19
30
  const TIMEOUT_MS = 15000;
@@ -75,7 +86,7 @@ const TEXT_OUTPUT = {
75
86
 
76
87
  export const name = "dsh-deepseekbase";
77
88
 
78
- export const inject = ["tools", "systemPrompt"];
89
+ export const inject = ["tools", "systemPrompt", "skills"];
79
90
 
80
91
  export function apply(ctx) {
81
92
  ctx.systemPrompt.section({
@@ -85,10 +96,88 @@ export function apply(ctx) {
85
96
  "Use the deepseekbase_* tools for DeepSeek pricing, plugin discovery with sandbox " +
86
97
  "test results, model specs and token-volume trends. Also use " +
87
98
  "deepseekbase_test_plugin to submit a plugin for a real sandbox install test and " +
88
- "deepseekbase_test_result to read the verdict. Data is a third-party index " +
89
- "(deepseekbase.com), not official DeepSeek output — cite it as such.",
99
+ "deepseekbase_test_result to read the verdict. deepseekbase_check runs a static " +
100
+ "DSHIO/T 10 conformance check on any plugin. Two skills are registered: " +
101
+ "dshio-standards (the standard text) and dshio-check (the checking workflow). " +
102
+ "Data is a third-party index (deepseekbase.com), not official DeepSeek output — " +
103
+ "cite it as such.",
90
104
  });
91
105
 
106
+ // ── SKILLS ───────────────────────────────────────────────────────────────
107
+ // 装本插件即获得 DSHIO 标准内容。
108
+ // 先注册内置副本(保证离线可用),再异步拉服务器最新版覆盖。
109
+ // 这样我们更新标准时,所有已装用户下次启动就同步,无需重装插件。
110
+ const skillDisposers = [];
111
+ try {
112
+ if (ctx.skills && typeof ctx.skills.register === "function") {
113
+ for (const sk of SKILLS) {
114
+ skillDisposers.push(
115
+ ctx.skills.register({
116
+ name: sk.name,
117
+ description: sk.description,
118
+ content: sk.content,
119
+ metadata: {
120
+ source: "deepseekbase",
121
+ layer: "bundled",
122
+ standard: sk.name === "dshio-standards" ? "DSHIO/T 00,10,21" : "DSHIO/T 10",
123
+ lang: "zh-Hans",
124
+ homepage: "https://deepseekbase.com/standards/",
125
+ },
126
+ ...(sk.whenToUse ? { whenToUse: sk.whenToUse } : {}),
127
+ }),
128
+ );
129
+ }
130
+
131
+ // 异步刷新:拉到新版就替换内置版
132
+ (async () => {
133
+ try {
134
+ const r = await jfetch(BASE + "/api/dshio/skills.json", {});
135
+ if (r.status !== 200 || !r.body || !Array.isArray(r.body.skills)) return;
136
+ const remote = r.body.skills.filter(
137
+ (x) => x && typeof x.name === "string" && typeof x.content === "string",
138
+ );
139
+ if (!remote.length) return;
140
+ // 只有内容确实不同才替换,避免无谓的目录失效
141
+ const same = remote.every((rs) => {
142
+ const local = SKILLS.find((l) => l.name === rs.name);
143
+ return local && local.content === rs.content;
144
+ });
145
+ if (same) return;
146
+
147
+ for (const d of skillDisposers) {
148
+ try { d(); } catch { /* ignore */ }
149
+ }
150
+ skillDisposers.length = 0;
151
+ for (const rs of remote) {
152
+ skillDisposers.push(
153
+ ctx.skills.register({
154
+ name: rs.name,
155
+ description: rs.description,
156
+ content: rs.content,
157
+ metadata: Object.assign(
158
+ {
159
+ source: "deepseekbase",
160
+ layer: "remote",
161
+ version: r.body.version,
162
+ updated: r.body.updated,
163
+ lang: "zh-Hans",
164
+ homepage: r.body.homepage || "https://dshio.org",
165
+ },
166
+ rs.metadata || {},
167
+ ),
168
+ ...(rs.whenToUse ? { whenToUse: rs.whenToUse } : {}),
169
+ }),
170
+ );
171
+ }
172
+ } catch {
173
+ /* 离线时静默保留内置副本 */
174
+ }
175
+ })();
176
+ }
177
+ } catch (e) {
178
+ // skills 服务不可用时不影响工具功能
179
+ }
180
+
92
181
  // ── TESTING HELPERS ──────────────────────────────────────────────────────
93
182
  const BASE = "https://deepseekbase.com";
94
183
  const VERSIONS = ["0.2.2-rc.1", "0.2.2-alpha.3", "0.2.1-rc.5", "0.2.1-rc.4", "0.1.1-rc.2"];
@@ -176,13 +265,54 @@ export function apply(ctx) {
176
265
  `Unsupported dsh_version "${ver}". Allowed: ${VERSIONS.join(", ")}.`,
177
266
  };
178
267
  }
268
+ const plugin = (args.plugin || "").trim();
269
+ if (!plugin) return { text: "plugin is required." };
270
+
271
+ // ── 提交前先确认包存在,避免浪费免费额度 ──
272
+ if (!plugin.startsWith("github:")) {
273
+ const regUrl =
274
+ "https://registry.npmjs.org/" +
275
+ plugin.replace("/", "%2F");
276
+ const chk = await jfetch(regUrl, {}, exec && exec.signal);
277
+ if (chk.status === 404) {
278
+ const near = await jfetch(
279
+ BASE + "/data/search-zh.json",
280
+ {},
281
+ exec && exec.signal,
282
+ );
283
+ let hint = "";
284
+ if (near.body && Array.isArray(near.body.items)) {
285
+ const base = plugin.replace(/^@[^/]+\//, "").toLowerCase();
286
+ const cands = near.body.items
287
+ .filter((x) => String(x[0] || "").toLowerCase().includes(base.slice(0, 5)))
288
+ .slice(0, 3)
289
+ .map((x) => x[0]);
290
+ if (cands.length) hint = `\nDichtbij namen: ${cands.join(", ")}`;
291
+ }
292
+ return {
293
+ text:
294
+ `"${plugin}" bestaat niet op npm (HTTP 404).\n` +
295
+ `Er is niets ingediend — je gratis quotum is NIET gebruikt.\n` +
296
+ `Controleer de pakketnaam. Volledige naam nodig, bijvoorbeeld dsh-pet of @scope/name.` +
297
+ hint,
298
+ };
299
+ }
300
+ if (chk.status !== 200) {
301
+ return {
302
+ text:
303
+ `Kon "${plugin}" niet verifiëren op npm (HTTP ${chk.status}).\n` +
304
+ `Niets ingediend. Probeer het later opnieuw of gebruik github:owner/repo.`,
305
+ };
306
+ }
307
+ }
308
+
179
309
  const r = await jfetch(
180
310
  BASE + "/test/submit",
181
311
  {
182
312
  method: "POST",
183
313
  headers: { "Content-Type": "application/json" },
184
314
  body: JSON.stringify({
185
- plugin: (args.plugin || "").trim(),
315
+ plugin,
186
316
  dsh_version: ver,
187
317
  note: (args.note || "").slice(0, 300),
188
318
  }),
@@ -306,6 +436,78 @@ export function apply(ctx) {
306
436
  }),
307
437
  );
308
438
 
439
+ // ── 8. DSHIO static conformance check ────────────────────────────────────
440
+ ctx.tools.register(
441
+ defineTool({
442
+ name: "deepseekbase_check",
443
+ description:
444
+ "Run a static DSHIO/T 10 conformance check on a DSH plugin. Returns per-clause " +
445
+ "results (clause id, pass/fail/skip/manual, evidence, fix). Static checks cover " +
446
+ "the manifest, the patch file and the profile entry structure — no sandbox needed. " +
447
+ "Clauses marked 'manual' require human judgement and are returned as a checklist, " +
448
+ "not as a verdict. Use when asked whether a plugin conforms to the DSHIO standard.",
449
+ parameters: {
450
+ plugin: {
451
+ type: "string",
452
+ required: true,
453
+ description: "npm package name or github:owner/repo to check.",
454
+ },
455
+ },
456
+ output: TEXT_OUTPUT,
457
+ isConcurrencySafe: () => true,
458
+ async execute(args, exec) {
459
+ const plugin = (args.plugin || "").trim();
460
+ if (!plugin) return { text: "plugin is required." };
461
+ const r = await jfetch(
462
+ BASE + "/api/dshio/check?plugin=" + encodeURIComponent(plugin),
463
+ {},
464
+ exec && exec.signal,
465
+ );
466
+ if (r.status === 429) {
467
+ return { text: "Rate limited (20 checks/min). Try again shortly." };
468
+ }
469
+ if (r.status !== 200 || !r.body) {
470
+ return { text: `Check failed (HTTP ${r.status}). ${String(r.text).slice(0, 200)}` };
471
+ }
472
+ const d = r.body;
473
+ if (d.error) {
474
+ return { text: `Check failed: ${d.error}` };
475
+ }
476
+ const lines = [];
477
+ lines.push(`plugin: ${d.plugin}`);
478
+ if (d.resolved) lines.push(`version: ${d.resolved.version}`);
479
+ lines.push(`baseline dsh: ${d.baseline_dsh}`);
480
+ lines.push(`standard: DSHIO/T 10 (static layer)`);
481
+ lines.push("");
482
+ const icon = { pass: "[PASS]", fail: "[FAIL]", skip: "[SKIP]", manual: "[MANUAL]" };
483
+ for (const x of d.results || []) {
484
+ lines.push(`${icon[x.status] || x.status} ${x.clause} ${x.title}`);
485
+ if (x.status === "fail") {
486
+ if (x.evidence) lines.push(` evidence: ${x.evidence}`);
487
+ if (x.fix) lines.push(` fix: ${String(x.fix).split("\n")[0]}`);
488
+ }
489
+ if (x.status === "manual" && x.guidance) {
490
+ lines.push(` check yourself: ${x.guidance}`);
491
+ }
492
+ }
493
+ const s = d.summary || {};
494
+ lines.push("");
495
+ lines.push(
496
+ `summary: pass ${s.pass || 0} / fail ${s.fail || 0} / ` +
497
+ `skip ${s.skip || 0} / manual ${s.manual || 0}`,
498
+ );
499
+ lines.push(`static conformance: ${d.conforming_static ? "YES" : "NO"}`);
500
+ if (!d.conforming_static) {
501
+ lines.push("");
502
+ lines.push("Fix the critical failures first; a sandbox test would fail anyway.");
503
+ }
504
+ lines.push("");
505
+ lines.push(`Full report: ${BASE}/plugins/${""} · standard: ${BASE}/standards/`);
506
+ return { text: lines.join("\n") };
507
+ },
508
+ }),
509
+ );
510
+
309
511
  // ── 1. Prices ────────────────────────────────────────────────────────────
310
512
  ctx.tools.register(
311
513
  defineTool({
package/lib/skills.js ADDED
@@ -0,0 +1,224 @@
1
+ // DSHIO 标准技能内容
2
+ // 装我们的插件后,模型可以直接载入这些技能来查阅标准和执行检查。
3
+
4
+ export const STANDARDS_SKILL = {
5
+ name: "dshio-standards",
6
+ description:
7
+ "DSHIO 标准体系(DSHIO/T 00 术语、DSHIO/T 10 插件标准、DSHIO/T 21 测试条件)。" +
8
+ "当用户问「符不符合 DSHIO 标准」「插件标准要求什么」「测试条件是什么」时载入本技能。" +
9
+ "本技能包含条款编号与判定规则,可直接引用条款号。",
10
+ whenToUse:
11
+ "用户询问 DSH 插件是否合规、插件应满足哪些要求、沙箱测试在什么条件下进行、" +
12
+ "或需要引用 DSHIO 标准条款号时使用。",
13
+ content: `# DSHIO 标准速查
14
+
15
+ DSHIO = DeepSeek Harness Input/Output,第三方标准体系,不是官方机构。
16
+ 标准号格式:\`DSHIO/T <序号>—<年份>\`,参照 GB/T 体例。
17
+
18
+ ## 体系结构
19
+
20
+ | 区段 | 类型 | 内容 |
21
+ |---|---|---|
22
+ | 00–09 | 基础标准 | 术语、编写规则、分类编码、评定通则 |
23
+ | 10–19 | 产品标准 | 插件、套件、工具、数据接口、主题、模型接入 |
24
+ | 20–29 | 方法标准 | 测试方法、测试条件、抽样、分级 |
25
+ | 30–39 | 管理标准 | 收录、推荐、认证、标志、申诉、修订 |
26
+
27
+ 引用单向:上层可引下层,下层不得引上层。
28
+
29
+ ## 关键原则:实施独立性
30
+
31
+ **标准不要求使用任何特定的开发工具、编程语言、构建流程或辅助库。**
32
+ 凡满足全部技术要求者即为符合,不论其如何实现。
33
+ 判定以可观测的运行时行为为准,不以源码结构为准。
34
+
35
+ 含义:
36
+ - 不强制 \`@deepseek-ai/dsh-tools\`(\`defineTool()\` 只是便捷方式,手写契约对象同样合法)
37
+ - 不强制 TypeScript
38
+ - 不强制 pnpm
39
+ - 不读源码判定
40
+
41
+ ## 术语(DSHIO/T 00)
42
+
43
+ | 术语 | 定义 | 判别条件 |
44
+ |---|---|---|
45
+ | 插件 plugin | 向 DSH 提供能力的软件单元 | 三条全满足:① \`package.json\` 有 \`dsh.bundle.patch\` ② 该字段指向的文件存在 ③ 该文件 \`insert\` 列表至少一个 entry |
46
+ | 套件 bundle | 一组插件的集合 | 作为 \`dsh.profile.bundles\` 成员出现,本身不提供能力 |
47
+ | 工具 tool | 向模型暴露的可调用函数 | \`name\`/\`description\`/\`parameters\`/\`execute\` 四字段齐全 |
48
+ | 服务 service | 向其他插件提供的可注入能力 | 以 \`inject\` 声明依赖 |
49
+ | entry | 配置树中的一个条目 | \`cordis.patch.yml\` 的 \`insert\` 列表中的一项 |
50
+ | 挂载 mount | entry 出现在合成后的配置树 | \`dsh --dump-config\` 可见 |
51
+ | 判定 verdict | 对一次测试的结论 | 五值:pass / install_failed / config_failed / installs_but_not_registered / boot_failed |
52
+
53
+ **模型无关性**:DSH 的安装、挂载、启动不依赖具体模型,因为模型接入是独立插件(\`dsh-llm-*\`)。
54
+ 所以 T0–T4 的判定在任何模型下都成立;只有 T5 依賴模型。
55
+
56
+ ## 插件标准要点(DSHIO/T 10)
57
+
58
+ ### 必须做到(critical)
59
+
60
+ | 条款 | 要求 |
61
+ |---|---|
62
+ | 5.1.1 | \`package.json\` 含 \`dsh.bundle.patch\` 字段 |
63
+ | 5.1.2 | 该字段指向的文件在包内存在 |
64
+ | 5.1.3 | patch 文件是合法 YAML(**\`@\` 开头的值必须加引号**,这是最常见错误)|
65
+ | 5.1.4 | patch 顶层是数组,至少含一个带 \`insert\` 的项 |
66
+ | 5.1.5 | 每个 entry 含非空 \`id\` 与 \`name\` |
67
+ | 5.2.2 | \`engines.dsh\` 范围包含基准版本 0.2.2-rc.1 |
68
+ | 5.2.3 | 有 \`main\` 或 \`exports\` 入口 |
69
+ | 5.3.2 | 不依赖本地绝对路径或 \`file:\` 协议 |
70
+
71
+ ### 应该做到(major)
72
+
73
+ | 条款 | 要求 |
74
+ |---|---|
75
+ | 5.2.1 | 声明 \`engines.dsh\`;缺失时按 DSH peerDependencies 判定 |
76
+ | 5.3.1 | 若声明 \`files\`,必须包含 \`lib\` 与 patch 文件 |
77
+ | 6.1.1 | 每个工具的 description 必须让人判断出「什么情况下调用它」 |
78
+ | 6.1.2 | 声明的权限与实际行为一致(不高报、不低报) |
79
+ | 6.2.1 | 不得出现红线权限组合 |
80
+
81
+ ### 红线
82
+
83
+ 同时声明 \`network\` 与(\`shell\` 或 \`filesystem\` 写权限)= 数据外泄路径 = 高风险。
84
+
85
+ ### 测试阶段(需沙箱)
86
+
87
+ | 阶段 | 网络 | 检查 |
88
+ |---|---|---|
89
+ | T1 安装 | 有网 | \`dsh plugin --profile web add <pkg>\` |
90
+ | T2 列装 | **断网** | \`dsh plugin --profile web list\` |
91
+ | T3 挂载 | **断网** | \`dsh --profile web --dump-config\` |
92
+ | T4 启动 | **断网** | profile 启动后存活 12 秒 |
93
+
94
+ T2–T4 必须 \`--network none\`:既防恶意行为外发数据,也让残留网络请求失败暴露。
95
+
96
+ ## 测试条件要点(DSHIO/T 21)
97
+
98
+ **没有固定条件的测试报告只是一人在某台机器上的印象。** 报告必须记录环境指纹:
99
+
100
+ \`\`\`
101
+ dsh=0.2.2-rc.1;img=dsh-sandbox:5.0@sha256:...;node=24.11.1;pnpm=9.15.9;mem=768m;cpu=1
102
+ \`\`\`
103
+
104
+ 固定项:DSH 版本(精确到 rc)、容器镜像 + digest、Node/pnpm 版本、内存 768MB、CPU 1 核、
105
+ 网络状态、超时(安装 180s / 验证 90s / 启动观察 12s)。
106
+
107
+ **重复次数**:对外判定至少 2 次,结果必须一致;不一致记「不稳定」,不得用于认证。
108
+
109
+ T5(模型相关)额外必须记录:模型 ID + 版本、temperature、max_tokens、
110
+ 系统提示词全文、测试提示词全文、**同一轮可用工具总数**(工具越多选错概率越高)。
111
+ T5 重复 3 次,认证用「全过」判据。
112
+
113
+ ## 判定规则
114
+
115
+ - 任何 \`critical\` 条款不符合 → 不符合标准
116
+ - 只引用有编号的条款,不要自创条款号
117
+ - 无法自动判定的条款(描述质量、权限合理性)必须标为「需人工判断」,不要替用户下结论
118
+
119
+ ## 引用格式
120
+
121
+ 引用时写:\`DSHIO/T 10—2026 第 5.2.2 条\`
122
+ 不要写:\`DSHIO-DEV\`、\`DSHIO-TEST\`(旧缩写已废止)
123
+
124
+ 标准来源:https://deepseekbase.com/standards/ · 官网 dshio.org(建设中)
125
+ 标准为第三方归纳,不是 DeepSeek 官方规范,引用时须注明。
126
+ `,
127
+ };
128
+
129
+ export const CHECK_SKILL = {
130
+ name: "dshio-check",
131
+ description:
132
+ "对某个 DSH 插件执行 DSHIO/T 10 静态符合性检查。" +
133
+ "当用户问「这个插件符不符合标准」「帮我检查我的插件」「哪里不合规」时载入本技能。" +
134
+ "检查分三层:静态(可自动)、沙箱测试(需提交)、人工判断(只能给清单)。",
135
+ whenToUse:
136
+ "用户要求检查某个插件是否符合 DSHIO 标准、想知道自己的插件哪里不合规、" +
137
+ "或要求生成合规报告时使用。",
138
+ content: `# DSHIO 插件合规检查流程
139
+
140
+ ## 三层检查,不要混为一谈
141
+
142
+ | 层 | 能判定 | 怎么得到结论 |
143
+ |---|---|---|
144
+ | **静态** | 结构合法性 | \`deepseekbase_check\` 工具,即时返回 |
145
+ | **沙箱** | 能否装/挂/启动 | \`deepseekbase_test_plugin\` 提交,几分钟出结果 |
146
+ | **人工** | 描述质量、权限合理性 | 只给清单和引导问题,**不要替用户下结论** |
147
+
148
+ ## 执行顺序
149
+
150
+ 1. 先调 \`deepseekbase_check(plugin)\` 拿静态结果
151
+ 2. 有 critical 不符合 → 直接报,不要提交沙箱测试(省额度)
152
+ 3. 静态通过 → 问用户要不要跑沙箱测试(会消耗免费额度 3 次/天)
153
+ 4. manual 类条款:列出清单,让用户自己判断
154
+
155
+ ## 怎么报告结果
156
+
157
+ **必须**:
158
+ - 引用条款号(如 \`5.2.2\`)
159
+ - 给出证据(实际值 vs 要求值)
160
+ - 给出修法(可复制粘贴的写法)
161
+ - 区分「不符合」和「需人工判断」
162
+
163
+ **禁止**:
164
+ - 说「看起来没问题」(必须有条款依据)
165
+ - 把 manual 条款判成通过或失败
166
+ - 自创条款号
167
+
168
+ ## 常见错误与修法
169
+
170
+ ### 1. \`@\` 开头未加引号(最常见)
171
+
172
+ \`\`\`yaml
173
+ # ✗ 错
174
+ - insert:
175
+ - id: foo
176
+ name: @scope/foo
177
+
178
+ # ✓ 对
179
+ - insert:
180
+ - id: foo
181
+ name: "@scope/foo"
182
+ \`\`\`
183
+
184
+ YAML 里 \`@\` 是保留指示符,不加引号会解析失败。
185
+
186
+ ### 2. \`engines.dsh\` 上界写死
187
+
188
+ \`\`\`json
189
+ // ✗ 错:排除 0.2.2-rc.1
190
+ "engines": { "dsh": ">=0.2.0-rc.2 <0.2.2-0" }
191
+
192
+ // ✓ 对:只写下界
193
+ "engines": { "dsh": ">=0.2.0-rc.2" }
194
+ \`\`\`
195
+
196
+ ### 3. files 数组漏了 patch
197
+
198
+ \`\`\`json
199
+ "files": ["lib/index.js", "cordis.patch.yml"]
200
+ \`\`\`
201
+
202
+ 只写 \`lib/index.js\` 会漏掉整个目录。
203
+
204
+ ### 4. 红线权限组合
205
+
206
+ \`\`\`json
207
+ "dsh": { "permissions": ["network", "fs-write"] } // 高危
208
+ \`\`\`
209
+
210
+ 如果确实需要,在 README 写清为什么需要 + 数据流向。
211
+
212
+ ## 示例对话
213
+
214
+ 用户:「帮我看看 dsh-pet 符不符合标准」
215
+
216
+ 正确做法:
217
+ 1. 调 \`deepseekbase_check("dsh-pet")\`
218
+ 2. 报告:「静态检查 10/10 通过。还有 2 条需人工判断:description 是否说清场景、权限是否与实际一致。要不要跑沙箱测试?(消耗 1 次免费额度,每天 3 次)」
219
+
220
+ 错误做法:
221
+ - 「dsh-pet 符合标准」← 没给条款依据,而且 manual 条款没判
222
+ - 直接跑沙箱测试 ← 没问用户,浪费额度
223
+ `,
224
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liangjiehappy/dsh-deepseekbase",
3
- "version": "0.2.2",
3
+ "version": "0.3.1",
4
4
  "description": "DeepSeek prices, plugins with sandbox test results, model specs and token trends inside DeepSeek Harness — powered by deepseekbase.com",
5
5
  "keywords": [
6
6
  "deepseek-harness",