@jayyuen66/dsh-plugin-shared 0.1.1 → 0.1.2
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.
- package/README.md +3 -2
- package/README.zh.md +3 -2
- package/dist/card-apply.js +1 -1
- package/dist/http.js +1 -1
- package/dist/tool-events.js +1 -1
- package/dist/types/jsonl.d.ts +20 -1
- package/dist/types/record.d.ts +20 -1
- package/dist/types/tool-events.d.ts +14 -9
- package/package.json +13 -13
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ End users do not install or enable it separately: any consumer package pulls it
|
|
|
33
33
|
| | |
|
|
34
34
|
| --- | --- |
|
|
35
35
|
| Node.js | `^22.19.0 \|\| >=24.0.0`, the same clause as the harness root |
|
|
36
|
-
| dsh | `>=0.2.
|
|
36
|
+
| dsh | `>= 0.2.1-alpha.1`, declared as an **optional** peer (this package needs no host at import time) |
|
|
37
37
|
| Module format | ESM only. `require()` works only where Node supports `require(esm)` |
|
|
38
38
|
| Tree shaking | `"sideEffects": false` |
|
|
39
39
|
|
|
@@ -130,8 +130,9 @@ Known upstream limitation: `@deepseek-ai/dsh-llm`'s own declarations import `@de
|
|
|
130
130
|
## Quality gates
|
|
131
131
|
|
|
132
132
|
- `npm run check` = typecheck → lint → build → test (coverage thresholds 100 for lines, statements, functions and branches) → format check.
|
|
133
|
-
- `test/publish-manifest.test.ts` is the release-shape gate: every `exports` target must be inside what `files` actually ships, entries must point at build output rather than source, and `publishConfig` must not carry entry fields. One set of "internal reference" patterns scans **both planes**: **artifacts** must contain no absolute paths, home-directory references, dates, or sibling-package identifiers; **source and docs** must contain no dates and no "this round / next round" wording that only made sense during collaboration. The artifact pass cannot see comments, so the source pass is what keeps that cleanup from being a one-off.
|
|
133
|
+
- `test/publish-manifest.test.ts` is the release-shape gate: every `exports` target must be inside what `files` actually ships, entries must point at build output rather than source, and `publishConfig` must not carry entry fields. It also pins **facet/`exports` parity in both directions**: every `lib/*.ts` needs a matching subpath (a missing one means that facet is not importable by any of the nine consumer packages, while the build — which follows the builder's own entries array — stays green), and no dangling subpath may outlive its facet. `./lib/canonicalize-region-paths` is the one facet that lives in `exports` but not in the barrel, and that subpath is load-bearing: nine sibling packages' `build-*.mjs` import it, so removing it breaks all of their builds at once. One set of "internal reference" patterns scans **both planes**: **artifacts** must contain no absolute paths, home-directory references, dates, or sibling-package identifiers; **source and docs** must contain no dates and no "this round / next round" wording that only made sense during collaboration. The artifact pass cannot see comments, so the source pass is what keeps that cleanup from being a one-off.
|
|
134
134
|
- `test/build-host.test.ts` compares the bytes on disk against an in-memory build, so editing `lib/*.ts` without rebuilding goes red.
|
|
135
|
+
- `test/setup-logs.ts` (a vitest setup file) is the ledger for runtime logs: it takes over `console.*`, so the two `console.error` calls in `lib/` neither leak into the test report (that stack trace is pure noise) nor go unclaimed — every `[shared/*]` line must match a template fragment in `test/log-templates.ts` or the run goes red. Do not substitute vitest's `silent`: it only hides, and a newly added log would still go unnoticed.
|
|
135
136
|
- `.github/workflows/ci.yml` runs the gate on push and pull request across a Node matrix and on Windows; the install matrix there additionally packs, installs into a clean directory with no flags, imports every subpath and type-checks a consumer probe.
|
|
136
137
|
|
|
137
138
|
## FAQ
|
package/README.zh.md
CHANGED
|
@@ -33,7 +33,7 @@ import { readBody, sendJson } from "@jayyuen66/dsh-plugin-shared/lib/http";
|
|
|
33
33
|
| | |
|
|
34
34
|
| --- | --- |
|
|
35
35
|
| Node.js | `^22.19.0 \|\| >=24.0.0`,与 harness 根同款 |
|
|
36
|
-
| dsh | `>=0.2.
|
|
36
|
+
| dsh | `>= 0.2.1-alpha.1`,声明为 **optional** peer(本包 import 时不需要宿主在场) |
|
|
37
37
|
| 模块形态 | 仅 ESM。`require()` 只在支持 `require(esm)` 的 Node 上可用 |
|
|
38
38
|
| Tree shaking | `"sideEffects": false` |
|
|
39
39
|
|
|
@@ -130,8 +130,9 @@ sonarjs 的入口是**惰性解析**的,发生在 `definePluginConfig()` 内
|
|
|
130
130
|
## 质量门
|
|
131
131
|
|
|
132
132
|
- `npm run check` = typecheck → lint → build → test(覆盖率 lines/statements/functions/branches 四阈值 100)→ fmt:check。
|
|
133
|
-
- `test/publish-manifest.test.ts` 是发布形态门:`exports` 的每个目标都必须在 `files` 真会发出去的范围内;入口必须指编译产物而不是源码;`publishConfig`
|
|
133
|
+
- `test/publish-manifest.test.ts` 是发布形态门:`exports` 的每个目标都必须在 `files` 真会发出去的范围内;入口必须指编译产物而不是源码;`publishConfig` 不得携带入口字段。它还钉着**切面与 `exports` 的双向 parity**:每个 `lib/*.ts` 都要有对应子路径(少一条 = 该切面对 9 个消费包不可 import,而构建走的是 builder 自己的 entries 数组、不会报错),反过来也不许留悬空子路径。`./lib/canonicalize-region-paths` 正是"在 `exports` 里、不在 barrel 里"的那一枚,且这条子路径是承重的(9 个兄弟包的 `build-*.mjs` 靠它),删它会一次性打断全部构建。同一组"内部指涉"判据扫两个平面:**产物**不得出现绝对路径、家目录指涉、日期或兄弟包标识符;**源码与文档**不得出现日期与"这一轮/下一轮"这类只在协作当时成立的措辞——产物面那条看不见注释,所以必须单独扫源码,否则清理只是一次性动作、没有回归保护。
|
|
134
134
|
- `test/build-host.test.ts` 里的指纹用例比较磁盘产物与内存构建的字节,所以改了 `lib/*.ts` 忘了重建会直接红。
|
|
135
|
+
- `test/setup-logs.ts`(vitest setupFile)是算子日志的账本:它接管 `console.*`,于是 `lib/` 里那两行 `console.error` 既不会漏进测试报告(那条栈是纯噪点),又必须被用例认领——每条 `[shared/*]` 日志都要对得上 `test/log-templates.ts` 里的模板片段,否则当场红。别拿 vitest 的 `silent` 顶替:那只是不显示,新飘出来的日志照样没人看。
|
|
135
136
|
- `.github/workflows/ci.yml` 在 push 与 PR 上跨 Node 版本矩阵、并在 Windows 上跑同一道门;那边的安装矩阵还会打包、在干净目录里不带任何 flag 安装、逐子路径 import、并对消费方探针文件做类型检查。
|
|
136
137
|
|
|
137
138
|
## 常见问题
|
package/dist/card-apply.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function e(e,t,n){let r=globalThis;
|
|
1
|
+
function e(e,t,n){let r=globalThis;if(r[t]===!0)return!1;r[t]=!0;try{e.effect(()=>()=>{r[t]=void 0},n)}catch(e){throw r[t]=void 0,e}return!0}export{e as claimApply};
|
package/dist/http.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function e(e,t,n){if(e.headersSent||e.writableEnded)return;let r=JSON.stringify(n);e.writeHead(t,{"content-type":`application/json; charset=utf-8`,"cache-control":`no-store`}),e.end(r)}function t(e,t){let n=e.headers?.[t],r=Array.isArray(n)?n[0]:n;return typeof r==`string`?r:``}function n(e){let n=t(e,`sec-fetch-site`);return n!==``&&n!==`same-origin`&&n!==`none`}function r(e,t){try{return new URL(e.url??``,`http://localhost`).searchParams.get(t)}catch{return null}}function i(e,n,r){let i=t(e,r);return i!==``&&i===n}const a={"too-large":{status:413,error:`request body too large`},aborted:{status:400,error:`request body unreadable`},"bad-budget":{status:500,error:`request body limit misconfigured`}};function o(e){return Buffer.isBuffer(e)?e:Buffer.from(String(e),`utf8`)}async function s(e,n){if(!Number.isFinite(n)||n<0)return{ok:!1,reason:`bad-budget`};let r=Number(t(e,`content-length`));if(Number.isFinite(r)&&r>n)return{ok:!1,reason:`too-large`};let i=[],a=0;try{for await(let t of e){let e=o(t);if(a+=e.length,a>n)return{ok:!1,reason:`too-large`};i.push(e)}}catch{return{ok:!1,reason:`aborted`}}return{ok:!0,text:Buffer.concat(i).toString(`utf8`)}}const c=`cross-origin request rejected`;async function l(t,r,o){if(n(t))return e(r,403,{ok:!1,error:c}),null;if(o.csrf!==void 0&&!i(t,o.csrf.token,o.csrf.headerName))return e(r,403,{ok:!1,error:`invalid csrf token`}),null;let l=await s(t,o.maxBytes);if(l.ok)return l.text;let u=a[l.reason];return e(r,u.status,{ok:!1,error:u.error}),null}export{c as CROSS_ORIGIN_TEXT,i as checkCsrf,l as guardBody,n as isCrossOrigin,r as queryParam,s as readBody,e as sendJson};
|
|
1
|
+
function e(e,t,n){if(e.headersSent||e.writableEnded)return;let r=JSON.stringify(n);e.writeHead(t,{"content-type":`application/json; charset=utf-8`,"cache-control":`no-store`}),e.end(r)}function t(e,t){let n=e.headers?.[t.toLowerCase()],r=Array.isArray(n)?n[0]:n;return typeof r==`string`?r:``}function n(e){let n=t(e,`sec-fetch-site`);return n!==``&&n!==`same-origin`&&n!==`none`}function r(e,t){try{return new URL(e.url??``,`http://localhost`).searchParams.get(t)}catch{return null}}function i(e,n,r){let i=t(e,r);return i!==``&&i===n}const a={"too-large":{status:413,error:`request body too large`},aborted:{status:400,error:`request body unreadable`},"bad-budget":{status:500,error:`request body limit misconfigured`}};function o(e){return Buffer.isBuffer(e)?e:Buffer.from(String(e),`utf8`)}async function s(e,n){if(!Number.isFinite(n)||n<0)return{ok:!1,reason:`bad-budget`};let r=Number(t(e,`content-length`));if(Number.isFinite(r)&&r>n)return{ok:!1,reason:`too-large`};let i=[],a=0;try{for await(let t of e){let e=o(t);if(a+=e.length,a>n)return{ok:!1,reason:`too-large`};i.push(e)}}catch{return{ok:!1,reason:`aborted`}}return{ok:!0,text:Buffer.concat(i).toString(`utf8`)}}const c=`cross-origin request rejected`;async function l(t,r,o){if(n(t))return e(r,403,{ok:!1,error:c}),null;if(o.csrf!==void 0&&!i(t,o.csrf.token,o.csrf.headerName))return e(r,403,{ok:!1,error:`invalid csrf token`}),null;let l=await s(t,o.maxBytes);if(l.ok)return l.text;let u=a[l.reason];return e(r,u.status,{ok:!1,error:u.error}),null}export{c as CROSS_ORIGIN_TEXT,i as checkCsrf,l as guardBody,n as isCrossOrigin,r as queryParam,s as readBody,e as sendJson};
|
package/dist/tool-events.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isRecord as e}from"./record.js";function t(t){return e(t)&&t.isError===!0}function n(e){return e===!0}function r(t){return e(t.data)}function i(e){return typeof e==`string`&&e.length>0?e:void 0}function a(t){if(typeof t==`string`)try{let n=JSON.parse(t);return e(n)?n:{}}catch{return{}}return e(t)?t:{}}function
|
|
1
|
+
import{isRecord as e}from"./record.js";function t(t){return e(t)&&t.isError===!0}function n(e){return e===!0}function r(t){return e(t.data)}function i(e){return typeof e==`string`&&e.length>0?e:void 0}function a(e){return typeof e==`string`&&e.length>0?e:void 0}function o(t){if(typeof t==`string`)try{let n=JSON.parse(t);return e(n)?n:{}}catch{return{}}return e(t)?t:{}}function s(e){if(typeof e==`string`)try{return JSON.parse(e),!1}catch{return!0}return!1}function c(e,t){let n;if(!r(e))return n;if(e.type===`tool/call`){let r=a(e.data.name);r!==void 0&&(n={name:r,callId:i(e.data.callId),arguments:o(e.data.arguments),badArguments:s(e.data.arguments),seq:t})}else if(e.type===`tool/ptc-dispatch-start`){let r=i(e.data.subCallId),c=a(e.data.name);r!==void 0&&c!==void 0&&(n={name:c,callId:r,arguments:o(e.data.arguments),badArguments:s(e.data.arguments),seq:t})}return n}function l(a,o){let s;if(!r(a))return s;if(a.type===`tool/result`){let n=a.data.message,r=e(n)?n.source:void 0;s={callId:e(r)?i(r.callId):void 0,isError:t(n),seq:o}}else if(a.type===`tool/ptc-dispatch`){let e=i(a.data.subCallId);e!==void 0&&(s={callId:e,isError:n(a.data.isError),seq:o})}return s}function u(e,t){return{call:c(e,t),result:l(e,t)}}function d(t){let n=[],r=[];for(let[i,a]of t.entries())if(e(a)){let{call:e,result:t}=u(a,i);e!==void 0&&n.push(e),t!==void 0&&r.push(t)}return{calls:n,results:r}}function f(e,t){let n=e[t];return typeof n==`string`?n:void 0}function p(e){let t=e.arguments;return e.name===`str_replace_editor`?t.command===`view`?{kind:`read-view`,path:f(t,`path`)}:{kind:`write`,path:f(t,`path`)}:{kind:`write`,path:f(t,`file_path`)}}export{p as editPathOf,o as parseToolArguments,d as scanToolEvents,s as toolArgumentsBad,u as toolEventRowsOf};
|
package/dist/types/jsonl.d.ts
CHANGED
|
@@ -1,8 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 反复保留后半行段直到 UTF-8 字节数 ≤ `maxBytes`;行数 ≤2 时停手(单条超限行原样保留,
|
|
3
3
|
* 防死循环也防清空文件)。未超限直接返回入参**同一引用**,调用方可据此跳过写盘。
|
|
4
|
+
*
|
|
5
|
+
* **配额必须是有限数**(这一档由调用方保证,本函数不代为归一):
|
|
6
|
+
* - `0` 与负数**照样收缩**到 ≤2 行为止——「0 = 永不截断」是某消费方在**调用前**
|
|
7
|
+
* `maxBytes > 0` 那道触发策略的承诺,不是本函数的语义(见它自己的 jsonl-fuse 头注)。
|
|
8
|
+
* 把 0 当成「不裁」会把这个承诺写成一个假象。
|
|
9
|
+
* - `NaN` 与 `+Infinity` 让 `字节数 > maxBytes` 恒假 ⇒ 循环一次都不进,整份原样返回,
|
|
10
|
+
* 即**静默关掉收缩**。现存两个消费方都不会把这种值传进来:一个用固定常量作默认实参,
|
|
11
|
+
另一个在调用前就把非有限值与负数归一成 0。但那道归一在**消费方**,本包并不强制——
|
|
12
|
+
新增消费方时没有任何东西会提醒它。
|
|
13
|
+
*
|
|
14
|
+
* 为什么不改成 http.readBody 那样的 bad-budget 拒读:那边拒读是因为不设限等于放开内存
|
|
15
|
+
* 上限(请求体是攻击面),这边不设限只是「这次不裁」。抛错会被两个消费方各自的 catch
|
|
16
|
+
* 接走(一个上抛、一个内部吞),等于把一条清晰的预算错误变成一次静默跳过,排查方向
|
|
17
|
+
* 反而更差。形状不同的同一种错,各按各的失败模型处理。
|
|
18
|
+
*
|
|
19
|
+
* 两个消费方的具体调用点与配额归一位置记在 test/jsonl.test.ts 的同名用例里——本文件头
|
|
20
|
+
* 不能出现兄弟包标识符:那些名字会随 JSDoc 一起被 tsc 抄进 dist/types/*.d.ts 发出去,
|
|
21
|
+
* 让装了这个包的消费方以为存在一个并不存在的依赖(test/publish-manifest.test.ts 会红)。
|
|
22
|
+
*
|
|
4
23
|
* @param text 整份 JSONL 文本
|
|
5
|
-
* @param maxBytes
|
|
24
|
+
* @param maxBytes 字节上限;调用方须保证是有限数
|
|
6
25
|
* @returns 收缩后的文本
|
|
7
26
|
*/
|
|
8
27
|
export declare function shrinkJsonlTail(text: string, maxBytes: number): string;
|
package/dist/types/record.d.ts
CHANGED
|
@@ -1,4 +1,23 @@
|
|
|
1
1
|
/** 对象类型守卫:非 `null` 的 `object` 且非数组(`Record` 索引签名投影的基础)。 */
|
|
2
2
|
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* 从 `unknown` 投影单个字段;非 `Record` → `undefined`。
|
|
5
|
+
*
|
|
6
|
+
* ⚠ **取值走原型链,这是承重的,不是疏忽**:`value[key]` 不做 `hasOwn` 判定,所以原型上的
|
|
7
|
+
* 方法照样取得到。消费方正靠这一条做**能力探测**——cordis 服务对象的方法挂在原型上、不是
|
|
8
|
+
* 自有键,形如 `typeof fieldOf(settings, "describe") === "function"`、
|
|
9
|
+
* `hasMethods(fieldOf(value, "timer"), ["timeout"])`、`typeof fieldOf(session,
|
|
10
|
+
* "snapshotEvents") === "function"`(三处消费包的调用点与行号记在 test/record.test.ts)。
|
|
11
|
+
* 改成 `Object.hasOwn` 会让上面几处**一律判否**,那些包随即认不出合法的 cordis 服务——
|
|
12
|
+
* 而这类误判的表现是「能力探测静默返回 false」,不是报错,极难往这里归因。
|
|
13
|
+
*
|
|
14
|
+
* 代价是明写在这里:键名取到的是原型成员时(`fieldOf({}, "__proto__")` 交回
|
|
15
|
+
* `Object.prototype`、`fieldOf({}, "constructor")` 交回 `Object`)。这是本函数的取舍,
|
|
16
|
+
* 不是让消费方猜的属性——现存调用点的键名全是字面量,没有一处来自数据。
|
|
17
|
+
* test/record.test.ts 两侧都钉住了:原型方法取得到(承重面),自有键优先于原型键。
|
|
18
|
+
*
|
|
19
|
+
* ⚠ 本段刻意不点名兄弟包:**声明上的 JSDoc 会被 tsc 抄进 dist/types/record.d.ts 一起
|
|
20
|
+
* 发出去**,包名会让装了这个包的消费方以为存在一个并不存在的依赖
|
|
21
|
+
*(test/publish-manifest.test.ts 的产物面判据会红)。要写具体调用点就写在 test/ 里。
|
|
22
|
+
*/
|
|
4
23
|
export declare function fieldOf(value: unknown, key: string): unknown;
|
|
@@ -8,17 +8,22 @@ export type { PtcDispatchEventData, PtcDispatchStartEventData } from "@deepseek-
|
|
|
8
8
|
*/
|
|
9
9
|
export interface ToolCallRecord {
|
|
10
10
|
/**
|
|
11
|
-
* 调用名(edit/write/str_replace_editor/read/grep
|
|
11
|
+
* 调用名(edit/write/str_replace_editor/read/grep/…)——本模块的**分桶键**,必选。
|
|
12
12
|
*
|
|
13
|
-
*
|
|
14
|
-
* packages/core/
|
|
15
|
-
*
|
|
16
|
-
*
|
|
13
|
+
* 官方把它声明成必选 `string`(`tool/call` 见 packages/core/session/src/types.ts:361,
|
|
14
|
+
* PtcDispatchStartEventData.name 见 packages/core/tools/src/types.ts:15),但运行期拦不住
|
|
15
|
+
* (依据见 usableName)。所以可空性在**扫描层**就处理掉了,不带到类型面:callRecordOf 遇到
|
|
16
|
+
* 缺可用 name 的调用类事件整条跳过,与 hasObjectData 同一口径。
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
18
|
+
* 为什么不把过滤留给消费方:下游分类全建立在 name 上——editPathOf 的 str_replace_editor
|
|
19
|
+
* 只读判定、门禁侧的 EDIT_TOOLS 与 refSearchTools 名单——而 editPathOf 的兜底分支会把任何
|
|
20
|
+
* 非 str_replace_editor 的调用一律判成 write。无名调用一旦进了台账,只要它的 arguments
|
|
21
|
+
* 里有 file_path 就算成写操作。现在是靠三个消费方各自记得先判一次才没出事——那是同一条
|
|
22
|
+
* 不变式的三份手抄,漏一份就出事。
|
|
23
|
+
*
|
|
24
|
+
* 与 callId 的差别是**为什么一个必选、一个可空**:callId 由 usableCallId 兜底,且它有
|
|
25
|
+
* nc:<seq> 兜底席位(消费方的 noCallId 桶专门收那种行),缺了不影响归类;name 一旦缺了
|
|
26
|
+
* 就没法分桶、没有兜底席位,只能在入口滤掉。
|
|
22
27
|
*/
|
|
23
28
|
readonly name: string;
|
|
24
29
|
/** callId:tool/result 串联键;缺失时由调用方按 seq 造 `nc:` 键。 */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jayyuen66/dsh-plugin-shared",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "dsh 自研插件的共享工具库:tool 事件流记账扫描 + webServer HTTP 样板(sendJson/CORS/CSRF/body 限制)+ 卡片 apply 骨架 + 项目键派生 + 代理对安全截断。作为库包被 import,不由用户启用",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cordis",
|
|
@@ -104,18 +104,18 @@
|
|
|
104
104
|
"registry": "https://registry.npmjs.org"
|
|
105
105
|
},
|
|
106
106
|
"dependencies": {
|
|
107
|
-
"@deepseek-ai/cordis": "
|
|
108
|
-
"@deepseek-ai/dsh-client-locale": "0.2.
|
|
109
|
-
"@deepseek-ai/dsh-jobs": "0.2.
|
|
110
|
-
"@deepseek-ai/dsh-output-retention": "0.2.
|
|
111
|
-
"@deepseek-ai/dsh-session": "0.2.
|
|
112
|
-
"@deepseek-ai/dsh-shell": "0.2.
|
|
113
|
-
"@deepseek-ai/dsh-tools": "0.2.
|
|
107
|
+
"@deepseek-ai/cordis": "4.0.5-alpha.1",
|
|
108
|
+
"@deepseek-ai/dsh-client-locale": "0.2.1-alpha.1",
|
|
109
|
+
"@deepseek-ai/dsh-jobs": "0.2.1-alpha.1",
|
|
110
|
+
"@deepseek-ai/dsh-output-retention": "0.2.1-alpha.1",
|
|
111
|
+
"@deepseek-ai/dsh-session": "0.2.1-alpha.1",
|
|
112
|
+
"@deepseek-ai/dsh-shell": "0.2.1-alpha.1",
|
|
113
|
+
"@deepseek-ai/dsh-tools": "0.2.1-alpha.1"
|
|
114
114
|
},
|
|
115
115
|
"devDependencies": {
|
|
116
|
-
"@deepseek-ai/dsh-brand": "0.2.
|
|
117
|
-
"@deepseek-ai/dsh-llm": "0.2.
|
|
118
|
-
"@deepseek-ai/dsh-scope": "0.2.
|
|
116
|
+
"@deepseek-ai/dsh-brand": "0.2.1-alpha.1",
|
|
117
|
+
"@deepseek-ai/dsh-llm": "0.2.1-alpha.1",
|
|
118
|
+
"@deepseek-ai/dsh-scope": "0.2.1-alpha.1",
|
|
119
119
|
"@types/node": "26.6.3",
|
|
120
120
|
"@vitest/coverage-v8": "5.0.2",
|
|
121
121
|
"eslint-plugin-sonarjs": "4.2.2",
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
"vitest": "5.0.2"
|
|
129
129
|
},
|
|
130
130
|
"peerDependencies": {
|
|
131
|
-
"@deepseek-ai/dsh": "^0.2.
|
|
131
|
+
"@deepseek-ai/dsh": "^0.2.1-alpha.1"
|
|
132
132
|
},
|
|
133
133
|
"peerDependenciesMeta": {
|
|
134
134
|
"@deepseek-ai/dsh": {
|
|
@@ -137,7 +137,7 @@
|
|
|
137
137
|
},
|
|
138
138
|
"icon": "icon.svg",
|
|
139
139
|
"engines": {
|
|
140
|
-
"dsh": ">=0.2.
|
|
140
|
+
"dsh": ">=0.2.1-alpha.1",
|
|
141
141
|
"node": "^22.19.0 || >=24.0.0"
|
|
142
142
|
},
|
|
143
143
|
"scripts": {
|