@xiaoso/dsh-tool-plus 0.1.2-beta.1 → 0.1.2-rc.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.
package/README.en.md CHANGED
@@ -41,6 +41,17 @@ Install **both** the plugin and the presets:
41
41
  dsh plugin --profile web add @xiaoso/dsh-tool-plus
42
42
  ```
43
43
 
44
+ ### Choosing a version
45
+
46
+ The plugin version maps one-to-one to the dsh version — pick the install command that matches your dsh:
47
+
48
+ | Plugin version (dist-tag) | Matching dsh version | Install command |
49
+ | --- | --- | --- |
50
+ | 0.1.2-rc.1 (`next`) | dsh v0.1.2-rc.1 (`next`) | `dsh plugin --profile web add @xiaoso/dsh-tool-plus@next` |
51
+ | 0.1.2 (`latest`) | dsh v0.1.1-rc.2 | `dsh plugin --profile web add @xiaoso/dsh-tool-plus` |
52
+
53
+ The plugin's `next` version number stays in lockstep with dsh's `next` (currently both 0.1.2-rc.1); installing without a tag gets the `latest` stable release.
54
+
44
55
  ### Install from GitHub
45
56
 
46
57
  Track the latest development build:
@@ -110,7 +121,7 @@ Works out of the box, no configuration needed. Common tweaks: background thresho
110
121
  - **dsh CLI**: installed globally, `npm i -g @deepseek-ai/dsh`
111
122
  - **Node.js** ≥ 22.19 or ≥ 24
112
123
  - **Git Bash** (recommended): serves as the bash execution environment on Windows
113
- - Targets DeepSeek Harness `dsh` v0.1.1-rc.2 (pre-release; interfaces may change)
124
+ - Version mapping: `next` (0.1.2-rc.1) targets dsh v0.1.2-rc.1; `latest` (0.1.2) targets dsh v0.1.1-rc.2 (pre-release; interfaces may change — see “Choosing a version” under Installation)
114
125
 
115
126
  ## Notes
116
127
 
package/README.md CHANGED
@@ -41,6 +41,17 @@ DeepSeek Harness 基础工具增强:持久 bash、结构化 read、多模式 e
41
41
  dsh plugin --profile web add @xiaoso/dsh-tool-plus
42
42
  ```
43
43
 
44
+ ### 版本选择
45
+
46
+ 插件版本与 dsh 版本一一对应,按你的 dsh 版本选择安装:
47
+
48
+ | 插件版本(dist-tag) | 对应 dsh 版本 | 安装命令 |
49
+ | --- | --- | --- |
50
+ | 0.1.2-rc.1(`next`) | dsh v0.1.2-rc.1(`next`) | `dsh plugin --profile web add @xiaoso/dsh-tool-plus@next` |
51
+ | 0.1.2(`latest`) | dsh v0.1.1-rc.2 | `dsh plugin --profile web add @xiaoso/dsh-tool-plus` |
52
+
53
+ 插件与 dsh 的 `next` 版本号保持一致(当前均为 0.1.2-rc.1);不带 tag 安装的是 `latest` 稳定版。
54
+
44
55
  ### 从 GitHub 安装
45
56
 
46
57
  跟踪最新开发版:
@@ -106,7 +117,7 @@ npx @xiaoso/dsh-tool-plus-presets
106
117
  - **dsh CLI**:需全局安装,`npm i -g @deepseek-ai/dsh`
107
118
  - **Node.js** ≥ 22.19 或 ≥ 24
108
119
  - **Git Bash**(推荐):Windows 上作为 bash 执行环境
109
- - 适用于 DeepSeek Harness `dsh` v0.1.1-rc.2(pre-release,接口可能变动)
120
+ - 版本对应:`next`(0.1.2-rc.1)适用于 dsh v0.1.2-rc.1;`latest`(0.1.2)适用于 dsh v0.1.1-rc.2(pre-release,接口可能变动,详见安装章节「版本选择」)
110
121
 
111
122
  ## 注意事项
112
123
 
package/lib/client.js CHANGED
@@ -2713,11 +2713,11 @@ window.__ModuleLoader__.load({
2713
2713
  editFuzzyThreshold: "模糊匹配阈值",
2714
2714
  editFuzzyThresholdHint: "相似度阈值,低于该值不视为命中。",
2715
2715
  editEnforceSeenLines: "已见行守卫",
2716
- editEnforceSeenLinesHint: "拒绝锚定在先前 read/search 从未完整展示过的行上的编辑。",
2716
+ editEnforceSeenLinesHint: "禁止修改此前读取或搜索从未完整展示过的行。",
2717
2717
  grepContextBefore: "匹配前上下文行数",
2718
- grepContextBeforeHint: "每个匹配前展示的上下文行数。",
2718
+ grepContextBeforeHint: "每个匹配结果上方连带显示几行,方便对照命中处的前后文。",
2719
2719
  grepContextAfter: "匹配后上下文行数",
2720
- grepContextAfterHint: "每个匹配后展示的上下文行数。",
2720
+ grepContextAfterHint: "每个匹配结果下方连带显示几行,方便对照命中处的前后文。",
2721
2721
  grepCaseDefault: "大小写敏感(默认)",
2722
2722
  grepCaseDefaultHint: "开启(默认)时按大小写严格匹配;关闭后忽略大小写。调用时显式传 case 参数会覆盖此默认。",
2723
2723
  grepGitignoreDefault: "跳过被忽略的文件(默认)",
@@ -2774,7 +2774,7 @@ window.__ModuleLoader__.load({
2774
2774
  rmSafeReasonRuntimeNotEffective: "运行时未生效",
2775
2775
  useShellCommandWrapper: "用 bash -c 包裹命令",
2776
2776
  useShellCommandWrapperHint: "把每条命令用 bash -c 包裹,以获得完整的 bash 环境。",
2777
- outputTruncateStrategy: "截断按",
2777
+ outputTruncateStrategy: "截断单位",
2778
2778
  outputTruncateStrategyHint: "后台任务完成消息达到阈值时的截断单位:按字节或按行。切换后下方显示对应单位的配置。",
2779
2779
  outputTruncateTriggerBytes: "字节触发阈值",
2780
2780
  outputTruncateTriggerBytesHint: "完成文本超过该字节数才截断(按字节策略时生效)。",
@@ -2903,11 +2903,11 @@ window.__ModuleLoader__.load({
2903
2903
  editFuzzyThreshold: "Fuzzy threshold",
2904
2904
  editFuzzyThresholdHint: "Similarity threshold below which a match is not accepted.",
2905
2905
  editEnforceSeenLines: "Seen-line guard",
2906
- editEnforceSeenLinesHint: "Reject edits anchored on lines a prior read/search never displayed in full.",
2906
+ editEnforceSeenLinesHint: "Reject edits on lines a previous read or search never displayed in full.",
2907
2907
  grepContextBefore: "Context lines before match",
2908
- grepContextBeforeHint: "Context lines shown before each match.",
2908
+ grepContextBeforeHint: "Lines shown above each match so you can see the context around a hit.",
2909
2909
  grepContextAfter: "Context lines after match",
2910
- grepContextAfterHint: "Context lines shown after each match.",
2910
+ grepContextAfterHint: "Lines shown below each match so you can see the context around a hit.",
2911
2911
  grepCaseDefault: "Case-sensitive (default)",
2912
2912
  grepCaseDefaultHint: "When on (default), matches strictly by case; when off, case is ignored. An explicit case argument on the call overrides this default.",
2913
2913
  grepGitignoreDefault: "Skip ignored files (default)",
@@ -2964,7 +2964,7 @@ window.__ModuleLoader__.load({
2964
2964
  rmSafeReasonRuntimeNotEffective: "not effective at runtime",
2965
2965
  useShellCommandWrapper: "Wrap commands in bash -c",
2966
2966
  useShellCommandWrapperHint: "Wrap every command in bash -c for a full bash environment.",
2967
- outputTruncateStrategy: "Truncate by",
2967
+ outputTruncateStrategy: "Truncate unit",
2968
2968
  outputTruncateStrategyHint: "Unit used when a background completion message crosses its threshold: bytes or lines. Switching shows the matching unit's settings below.",
2969
2969
  outputTruncateTriggerBytes: "Byte trigger threshold",
2970
2970
  outputTruncateTriggerBytesHint: "Truncate only when the completion text exceeds this many bytes (byte strategy).",
package/lib/index.mjs CHANGED
@@ -3,7 +3,7 @@ __installBunShim();
3
3
  import { n as fs_promises_shim_exports, t as exists } from "./fs-promises-shim-Bx0fpxuk.mjs";
4
4
  import { i as setRuntimeLogger, n as systemChromiumCandidatesForTest, r as runtimeLogger } from "./launch-DwpE70Pv.mjs";
5
5
  import { $ as peekFile, A as formatAge, C as error, F as $envpos, I as $flag, M as formatCount, P as $env, Q as isProbablyBinary, S as debug, T as warn, U as getAutoQaDbPath, V as VERSION, X as getRemoteDir, Y as getPuppeteerDir, b as isEnotdir, c as combineSignals, d as $which, j as formatBytes$1, k as installBunShim, l as exec, p as readImageMetadata, q as getInstallId, tt as untilAborted, u as render, v as hasFsCode, y as isEnoent } from "./src-D_e1qMwi.mjs";
6
- import { C as truncateToWidth$1, S as replaceTabs, _ as formatCodeFrameLine, a as fetchBinary, b as LRUCache, c as getParallelExtractContent, d as convertFileWithMarkit, f as Settings, g as capParseErrors, h as OMP_DEFAULTS, i as convertWithMarkit, l as ensureTool, m as settings, o as extractWithParallel, p as isSettingsInitialized, s as findParallelApiKey, u as CONVERTIBLE_EXTENSIONS, v as formatParseErrors, x as padding, y as shortenPath } from "./utils-BSVzHGnp.mjs";
6
+ import { C as truncateToWidth$1, S as replaceTabs, _ as formatCodeFrameLine, a as fetchBinary, b as LRUCache, c as getParallelExtractContent, d as convertFileWithMarkit, f as Settings, g as capParseErrors, h as OMP_DEFAULTS, i as convertWithMarkit, l as ensureTool, m as settings, o as extractWithParallel, p as isSettingsInitialized, s as findParallelApiKey, u as CONVERTIBLE_EXTENSIONS, v as formatParseErrors, x as padding, y as shortenPath } from "./utils-DavJ8_XP.mjs";
7
7
  import { t as sanitizeText } from "./sanitize-text-CfcXzw5X.mjs";
8
8
  import { n as isRecord$2 } from "./type-guards-B9VVjRDK.mjs";
9
9
  import { n as ToolError, r as throwIfAborted, t as ToolAbortError } from "./tool-errors-DoyxivAR.mjs";
@@ -25,7 +25,6 @@ import { fileURLToPath } from "node:url";
25
25
  import { scheduler } from "node:timers/promises";
26
26
  import { randomBytes } from "node:crypto";
27
27
  import z from "@deepseek-ai/schemastery";
28
- import { installSettingsSection, settingsNamespace } from "@deepseek-ai/dsh-settings";
29
28
  import { type } from "@oh-my-pi/omptype";
30
29
  import { DatabaseSync } from "node:sqlite";
31
30
  //#region src/tools/bash/shell-tokenize.ts
@@ -3986,7 +3985,7 @@ TOOL_PLUS_FIELDS.map((field) => field.name);
3986
3985
  //#endregion
3987
3986
  //#region src/config/settings.ts
3988
3987
  /** Settings namespace of this plugin, served to the web Plugins page. */
3989
- const BASH_PLUS_SETTINGS_NS = settingsNamespace("tool-plus");
3988
+ const BASH_PLUS_SETTINGS_NS = "tool-plus";
3990
3989
  /** OMP-parity defaults for the completion-message truncation policy. */
3991
3990
  const DEFAULT_OUTPUT_TRUNCATE = {
3992
3991
  strategy: "bytes",
@@ -4202,15 +4201,17 @@ function resolveConfig(config) {
4202
4201
  */
4203
4202
  function installBashPlusSettings(ctx, entry, onSource) {
4204
4203
  let currentSource;
4205
- installSettingsSection(ctx, BASH_PLUS_SETTINGS_NS, Config, entry, {
4206
- setSource: (current) => {
4207
- currentSource = current;
4208
- onSource(() => resolveConfig(current()));
4209
- },
4210
- onChange: () => {
4211
- const source = currentSource;
4212
- if (source) onSource(() => resolveConfig(source()));
4213
- }
4204
+ ctx.inject(["settings"], (settingsCtx) => {
4205
+ settingsCtx.settings.installSection(ctx, BASH_PLUS_SETTINGS_NS, Config, entry, {
4206
+ setSource: (current) => {
4207
+ currentSource = current;
4208
+ onSource(() => resolveConfig(current()));
4209
+ },
4210
+ onChange: () => {
4211
+ const source = currentSource;
4212
+ if (source) onSource(() => resolveConfig(source()));
4213
+ }
4214
+ });
4214
4215
  });
4215
4216
  }
4216
4217
  //#endregion
@@ -4533,7 +4534,7 @@ function installBrowserProbeRpc(ctx, deps) {
4533
4534
  }
4534
4535
  };
4535
4536
  };
4536
- disposer = connectionCtx.connection.rpc.handle(TOOL_PLUS_RPC_CHANNEL, handler, { authority: "loopback" });
4537
+ disposer = connectionCtx.connection.rpc.handle(TOOL_PLUS_RPC_CHANNEL, handler);
4537
4538
  } catch {
4538
4539
  disposer = void 0;
4539
4540
  }
@@ -14856,7 +14857,7 @@ let specialHandlersPromise;
14856
14857
  * requires a special handler, so we keep them out of the cold-startup graph.
14857
14858
  */
14858
14859
  function loadSpecialHandlers() {
14859
- specialHandlersPromise ??= import("./scrapers-B06jrsU7.mjs").then((m) => m.specialHandlers);
14860
+ specialHandlersPromise ??= import("./scrapers-C0RpKnkf.mjs").then((m) => m.specialHandlers);
14860
14861
  return specialHandlersPromise;
14861
14862
  }
14862
14863
  /**
@@ -3,7 +3,7 @@ __installBunShim();
3
3
  import { n as fs_promises_shim_exports } from "./fs-promises-shim-Bx0fpxuk.mjs";
4
4
  import { B as USER_AGENT, G as getDocsRsCacheDir, N as formatNumber, P as $env, T as warn, c as combineSignals, j as formatBytes, l as exec, s as Snowflake, x as parseFrontmatter, y as isEnoent } from "./src-D_e1qMwi.mjs";
5
5
  import { V as tryParseJson } from "./utils-fnV2zzp3.mjs";
6
- import { a as fetchBinary, c as getParallelExtractContent, i as convertWithMarkit, l as ensureTool, m as settings, n as asRecord, o as extractWithParallel, r as asString, s as findParallelApiKey, t as asNumber } from "./utils-BSVzHGnp.mjs";
6
+ import { a as fetchBinary, c as getParallelExtractContent, i as convertWithMarkit, l as ensureTool, m as settings, n as asRecord, o as extractWithParallel, r as asString, s as findParallelApiKey, t as asNumber } from "./utils-DavJ8_XP.mjs";
7
7
  import { n as isRecord } from "./type-guards-B9VVjRDK.mjs";
8
8
  import { r as throwIfAborted, t as ToolAbortError } from "./tool-errors-DoyxivAR.mjs";
9
9
  import { c as getLocalizedText, d as looksLikeHtml, i as decodeHtmlEntities, l as htmlToBasicMarkdown, o as formatIsoDate, r as buildResult, s as formatMediaDuration, u as loadPage } from "./types-BUO0JXO-.mjs";
@@ -7202,7 +7202,7 @@ const settings = {
7202
7202
  };
7203
7203
  //#endregion
7204
7204
  //#region package.json
7205
- var version = "0.1.2-beta.1";
7205
+ var version = "0.1.2-rc.1";
7206
7206
  /** `.tmp` files older than this are treated as orphaned writes and swept. */
7207
7207
  const TMP_ORPHAN_MAX_AGE_MS = 3e5;
7208
7208
  function markitConversionCacheKey(bytes, extension) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xiaoso/dsh-tool-plus",
3
3
  "description": "Oh My Pi bash runtime ported as a deepseek-harness tool plugin: persistent shell session, output minimizer, managed background jobs, command interception",
4
- "version": "0.1.2-beta.1",
4
+ "version": "0.1.2-rc.1",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "deepseek-harness",
@@ -30,7 +30,7 @@
30
30
  "type": "module",
31
31
  "publishConfig": {
32
32
  "access": "public",
33
- "tag": "beta"
33
+ "tag": "next"
34
34
  },
35
35
  "engines": {
36
36
  "node": "^22.19.0 || >=24.0.0"
@@ -64,7 +64,6 @@
64
64
  },
65
65
  "client": {
66
66
  "inject": [
67
- "@deepseek-ai/dsh-client-runtime",
68
67
  "@deepseek-ai/dsh-client-locale",
69
68
  "@deepseek-ai/dsh-client-ui-settings"
70
69
  ],
@@ -80,26 +79,26 @@
80
79
  "postinstall": "node scripts/patch-pi-natives.mjs"
81
80
  },
82
81
  "peerDependencies": {
83
- "@deepseek-ai/cordis": "^4.0.1",
84
- "@deepseek-ai/dsh-agent": "^0.1.1-rc.2",
85
- "@deepseek-ai/dsh-attachment": "^0.1.1-rc.2",
86
- "@deepseek-ai/dsh-client-connection": "^0.1.1-rc.2",
87
- "@deepseek-ai/dsh-fs": "^0.1.1-rc.2",
88
- "@deepseek-ai/dsh-jobs": "^0.1.1-rc.2",
89
- "@deepseek-ai/dsh-llm": "^0.1.1-rc.2",
90
- "@deepseek-ai/dsh-sandbox": "^0.1.1-rc.2",
91
- "@deepseek-ai/dsh-session": "^0.1.1-rc.2",
92
- "@deepseek-ai/dsh-settings": "^0.1.1-rc.2",
93
- "@deepseek-ai/dsh-shell": "^0.1.1-rc.2",
94
- "@deepseek-ai/dsh-shell-env": "^0.1.1-rc.2",
95
- "@deepseek-ai/dsh-system-prompt": "^0.1.1-rc.2",
96
- "@deepseek-ai/dsh-tools": "^0.1.1-rc.2"
82
+ "@deepseek-ai/cordis": "4.0.2",
83
+ "@deepseek-ai/dsh-agent": "0.1.2-rc.1",
84
+ "@deepseek-ai/dsh-attachment": "0.1.2-rc.1",
85
+ "@deepseek-ai/dsh-client-connection": "0.1.2-rc.1",
86
+ "@deepseek-ai/dsh-fs": "0.1.2-rc.1",
87
+ "@deepseek-ai/dsh-jobs": "0.1.2-rc.1",
88
+ "@deepseek-ai/dsh-llm": "0.1.2-rc.1",
89
+ "@deepseek-ai/dsh-sandbox": "0.1.2-rc.1",
90
+ "@deepseek-ai/dsh-session": "0.1.2-rc.1",
91
+ "@deepseek-ai/dsh-settings": "0.1.2-rc.1",
92
+ "@deepseek-ai/dsh-shell": "0.1.2-rc.1",
93
+ "@deepseek-ai/dsh-shell-env": "0.1.2-rc.1",
94
+ "@deepseek-ai/dsh-system-prompt": "0.1.2-rc.1",
95
+ "@deepseek-ai/dsh-tools": "0.1.2-rc.1"
97
96
  },
98
97
  "optionalPeerDependencies": {
99
98
  "sharp": ">=0.33"
100
99
  },
101
100
  "dependencies": {
102
- "@deepseek-ai/schemastery": "^3.18.1",
101
+ "@deepseek-ai/schemastery": "3.18.2",
103
102
  "@oh-my-pi/omptype": "17.3.5",
104
103
  "@oh-my-pi/pi-agent-core": "17.3.5",
105
104
  "@oh-my-pi/pi-ai": "17.3.5",
@@ -113,27 +112,27 @@
113
112
  "yaml": "^2.9.0"
114
113
  },
115
114
  "devDependencies": {
116
- "@deepseek-ai/cordis": "^4.0.1",
117
- "@deepseek-ai/dsh-agent": "^0.1.1-rc.2",
118
- "@deepseek-ai/dsh-client-connection": "^0.1.1-rc.2",
119
- "@deepseek-ai/dsh-client-locale": "^0.1.1-rc.2",
120
- "@deepseek-ai/dsh-client-runtime": "^0.1.1-rc.2",
121
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.1-rc.2",
122
- "@deepseek-ai/dsh-client-ui-settings": "^0.1.1-rc.2",
123
- "@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.1-rc.2",
124
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.1-rc.2",
125
- "@deepseek-ai/dsh-fs-local": "0.1.1-rc.2",
126
- "@deepseek-ai/dsh-jobs": "^0.1.1-rc.2",
127
- "@deepseek-ai/dsh-jobs-local": "^0.1.1-rc.2",
128
- "@deepseek-ai/dsh-llm": "^0.1.1-rc.2",
129
- "@deepseek-ai/dsh-session": "^0.1.1-rc.2",
130
- "@deepseek-ai/dsh-settings": "^0.1.1-rc.2",
131
- "@deepseek-ai/dsh-shell": "^0.1.1-rc.2",
132
- "@deepseek-ai/dsh-shell-env": "^0.1.1-rc.2",
133
- "@deepseek-ai/dsh-system-prompt": "^0.1.1-rc.2",
134
- "@deepseek-ai/dsh-tool-jobs": "^0.1.1-rc.2",
135
- "@deepseek-ai/dsh-tool-str-replace-editor": "0.1.1-rc.2",
136
- "@deepseek-ai/dsh-tools": "^0.1.1-rc.2",
115
+ "@deepseek-ai/cordis": "4.0.2",
116
+ "@deepseek-ai/dsh-agent": "0.1.2-rc.1",
117
+ "@deepseek-ai/dsh-client-connection": "0.1.2-rc.1",
118
+ "@deepseek-ai/dsh-client-locale": "0.1.2-rc.1",
119
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.2-rc.1",
120
+ "@deepseek-ai/dsh-client-ui-renderer": "0.1.2-rc.1",
121
+ "@deepseek-ai/dsh-client-ui-settings": "0.1.2-rc.1",
122
+ "@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.2-rc.1",
123
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.2-rc.1",
124
+ "@deepseek-ai/dsh-fs-local": "0.1.2-rc.1",
125
+ "@deepseek-ai/dsh-jobs": "0.1.2-rc.1",
126
+ "@deepseek-ai/dsh-jobs-local": "0.1.2-rc.1",
127
+ "@deepseek-ai/dsh-llm": "0.1.2-rc.1",
128
+ "@deepseek-ai/dsh-session": "0.1.2-rc.1",
129
+ "@deepseek-ai/dsh-settings": "0.1.2-rc.1",
130
+ "@deepseek-ai/dsh-shell": "0.1.2-rc.1",
131
+ "@deepseek-ai/dsh-shell-env": "0.1.2-rc.1",
132
+ "@deepseek-ai/dsh-system-prompt": "0.1.2-rc.1",
133
+ "@deepseek-ai/dsh-tool-jobs": "0.1.2-rc.1",
134
+ "@deepseek-ai/dsh-tool-str-replace-editor": "0.1.2-rc.1",
135
+ "@deepseek-ai/dsh-tools": "0.1.2-rc.1",
137
136
  "@types/node": "^22.19.0",
138
137
  "@types/react": "^19.0.0",
139
138
  "@types/react-dom": "^19.0.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xiaoso/dsh-tool-plus-presets",
3
- "version": "0.1.2-beta.1",
3
+ "version": "0.1.2-rc.1",
4
4
  "description": "Agent-preset installer for dsh-tool-plus: installs the standard / PTC enhanced preset templates into a DeepSeek Harness home.",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -25,7 +25,7 @@
25
25
  "type": "module",
26
26
  "publishConfig": {
27
27
  "access": "public",
28
- "tag": "beta"
28
+ "tag": "next"
29
29
  },
30
30
  "bin": {
31
31
  "dsh-tool-plus-presets": "./install-presets.mjs"