@dungsil/dsh-plugin-cli-proxy-api 0.2.2 → 0.3.0

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/dist/client.js CHANGED
@@ -19,12 +19,13 @@ function installStyles(css) {
19
19
  return () => style.remove();
20
20
  }
21
21
  // ../../tools/ui/src/settings.tsx
22
- /** The rc.5 settings shell has no icon slot, so decorate only the matching navigation rows. */
22
+ /** Decorate matching navigation rows in both the rc.5 and 0.2.2 settings shells. */
23
23
  function installSettingsIcon(id, labels, icon) {
24
24
  const attribute = "data-dsh-settings-icon";
25
25
  const selector = `[${attribute}="${id}"]`;
26
26
  const removeStyles = installStyles(`
27
- ${selector} > svg { display: none; }
27
+ ${selector} > svg,
28
+ ${selector} > [aria-hidden="true"]:not([data-dsh-settings-icon-glyph]) { display: none; }
28
29
  ${typeof icon === "string" ? `${selector}::before { content: ''; display: block; flex: none; width: 16px; height: 16px; background: currentColor; mask: url("data:image/svg+xml,${encodeURIComponent(icon)}") center / contain no-repeat; }` : ""}
29
30
  ${selector} > [data-dsh-settings-icon-glyph] { display: inline-flex; flex: none; }
30
31
  `);
@@ -89,6 +90,22 @@ function SettingsRow({ label, children }) {
89
90
  }), children]
90
91
  });
91
92
  }
93
+ // ../../tools/ui/src/page.tsx
94
+ function PluginPage({ children, className = "", contentClassName = "" }) {
95
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
96
+ className: `dsh-plugin-page ${className}`,
97
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
98
+ className: `dsh-plugin-page-content ${contentClassName}`,
99
+ children
100
+ })
101
+ });
102
+ }
103
+ // ../../tools/ui/src/page-styles.ts
104
+ const pageStyles = `
105
+ .dsh-plugin-page { box-sizing: border-box; height: 100%; min-height: 0; overflow: auto; padding: 24px; padding-inline-start: max(24px, var(--dsh-frame-leading-clearance, 0px)); }
106
+ .dsh-plugin-page-content { max-width: 960px; margin: 0 auto; }
107
+ .dsh-plugin-page h1 { margin: 0 0 24px; font-size: 20px; line-height: 28px; font-weight: 500; }
108
+ `;
92
109
  // src/protocol.ts
93
110
  const channel = "/api";
94
111
  const endpointPrefix = "dungsil-cli-proxy-api/";
@@ -147,18 +164,14 @@ const copy = {
147
164
  saved: "Saved · leave unchanged",
148
165
  notSaved: "Not saved",
149
166
  remove: "Remove saved key",
150
- removed: "Will be removed on save",
151
167
  serverHint: "Requires CLIProxyAPI v8. Use the server root without /v1. Remote servers require HTTPS.",
152
- keyHint: "Blank fields keep saved keys. When the URL changes, only newly entered keys are used.",
153
- save: "Save connection",
168
+ keyHint: "Changes save when you leave a field or press Enter. Blank fields keep saved keys. Changing the URL clears existing keys.",
154
169
  refresh: "Refresh",
155
170
  busy: "Working…",
156
171
  connectionLocked: "Connection could not be confirmed. Refresh the connection to enable saving.",
157
172
  error: "The request could not be confirmed. It will not be retried automatically. Refresh to check before trying again.",
158
173
  success: "Request completed. Refresh the relevant list to confirm the latest state.",
159
- savedConnection: "Connection saved and checked.",
160
174
  managementHint: "Save a management key to enable management controls.",
161
- draftHint: "Save the connection before using these controls.",
162
175
  connectionSettingsHint: "Configure the server URL and keys in Settings → CLIProxyAPI. Connection information updates automatically.",
163
176
  emptyAccounts: "No accounts available.",
164
177
  disabled: "Disabled"
@@ -216,18 +229,14 @@ const copy = {
216
229
  saved: "저장됨 · 변경하지 않음",
217
230
  notSaved: "저장되지 않음",
218
231
  remove: "저장된 키 삭제",
219
- removed: "저장 시 삭제됩니다",
220
232
  serverHint: "CLIProxyAPI v8이 필요합니다. /v1을 제외한 서버 주소를 입력하세요. 원격 서버는 HTTPS가 필요합니다.",
221
- keyHint: "빈 입력란은 기존 키를 유지합니다. URL을 바꾸면 새로 입력한 키만 사용합니다.",
222
- save: "연결 저장",
233
+ keyHint: "입력란을 벗어나거나 Enter를 누르면 자동 저장합니다. 빈 입력란은 기존 키를 유지하며, URL을 바꾸면 기존 키를 지웁니다.",
223
234
  refresh: "새로고침",
224
235
  busy: "처리 중…",
225
236
  connectionLocked: "연결 정보를 확인하지 못했습니다. 연결을 새로고침하면 저장할 수 있습니다.",
226
237
  error: "요청 결과를 확인하지 못했습니다. 자동으로 재시도하지 않습니다. 다시 시도하기 전에 새로고침하여 확인하세요.",
227
238
  success: "요청을 완료했습니다. 해당 목록을 새로고침하여 최신 상태를 확인하세요.",
228
- savedConnection: "연결을 저장하고 확인했습니다.",
229
239
  managementHint: "관리 기능을 사용하려면 관리 키를 저장하세요.",
230
- draftHint: "이 기능을 사용하기 전에 연결을 저장하세요.",
231
240
  connectionSettingsHint: "설정 → CLIProxyAPI에서 서버 주소와 키를 설정하세요. 연결 정보는 자동으로 갱신됩니다.",
232
241
  emptyAccounts: "사용 가능한 계정이 없습니다.",
233
242
  disabled: "비활성"
@@ -285,18 +294,14 @@ const copy = {
285
294
  saved: "已保存 · 保持不变",
286
295
  notSaved: "未保存",
287
296
  remove: "删除已保存的密钥",
288
- removed: "保存时将删除",
289
297
  serverHint: "需要 CLIProxyAPI v8。请输入不含 /v1 的服务器根地址。远程服务器必须使用 HTTPS。",
290
- keyHint: "空输入框保留已保存的密钥。更改 URL 后仅使用新输入的密钥。",
291
- save: "保存连接",
298
+ keyHint: "离开输入框或按 Enter 后自动保存。空输入框保留已保存的密钥,更改 URL 会清除原有密钥。",
292
299
  refresh: "刷新",
293
300
  busy: "处理中…",
294
301
  connectionLocked: "无法确认连接信息。请刷新连接以启用保存。",
295
302
  error: "无法确认请求结果。不会自动重试。请先刷新确认状态,再尝试操作。",
296
303
  success: "请求已完成。请刷新相应列表以确认最新状态。",
297
- savedConnection: "连接已保存并确认。",
298
304
  managementHint: "请保存管理密钥以启用管理功能。",
299
- draftHint: "使用这些功能前请保存连接。",
300
305
  connectionSettingsHint: "请在设置 → CLIProxyAPI 中配置服务器地址和密钥。连接信息会自动更新。",
301
306
  emptyAccounts: "没有可用账户。",
302
307
  disabled: "已禁用"
@@ -776,13 +781,10 @@ const inject = [
776
781
  "locale",
777
782
  "slots"
778
783
  ];
779
- const styles = `${settingsStyles}${quotaStyles}
784
+ const styles = `${settingsStyles}${quotaStyles}${pageStyles}
780
785
  .dsh-cli-proxy-icon { display: inline-flex; }
781
786
  .dsh-cli-proxy-icon > svg { width: 100%; height: 100%; }
782
787
  .dsh-cli-proxy { container-type: inline-size; color: var(--dsw-alias-label-primary); font: 14px/22px var(--dsw-font-family, system-ui); }
783
- .dsh-cli-proxy-page { height: 100%; min-height: 0; box-sizing: border-box; overflow-y: auto; padding: 24px; padding-inline-start: max(24px, var(--dsh-frame-leading-clearance, 0px)); }
784
- .dsh-cli-proxy-page > .dsh-cli-proxy { max-width: 960px; margin: 0 auto; }
785
- .dsh-cli-proxy h1 { font-size: 20px; line-height: 28px; font-weight: 500; margin: 0 0 24px; }
786
788
  .dsh-cli-proxy h3 { margin: 24px 0 0; font: inherit; color: var(--dsw-alias-label-secondary); }
787
789
  .dsh-cli-proxy .controls { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; min-width: 0; max-width: 65%; }
788
790
  .dsh-cli-proxy .controls > span:has(> input) { box-sizing: border-box; width: 280px; min-width: 0; max-width: 100%; }
@@ -814,8 +816,6 @@ function ProxyPage({ ctx, cache, settings = false }) {
814
816
  const [baseURL, setBaseURL] = (0, react.useState)(cachedView?.baseURL ?? "");
815
817
  const [apiKey, setAPIKey] = (0, react.useState)("");
816
818
  const [managementKey, setManagementKey] = (0, react.useState)("");
817
- const [removeAPIKey, setRemoveAPIKey] = (0, react.useState)(false);
818
- const [removeManagementKey, setRemoveManagementKey] = (0, react.useState)(false);
819
819
  const [synchronized, setSynchronized] = (0, react.useState)(!!cached);
820
820
  const [busy, setBusy] = (0, react.useState)(!cached);
821
821
  const [notice, setNotice] = (0, react.useState)();
@@ -840,8 +840,6 @@ function ProxyPage({ ctx, cache, settings = false }) {
840
840
  setSynchronized(true);
841
841
  setAPIKey("");
842
842
  setManagementKey("");
843
- setRemoveAPIKey(false);
844
- setRemoveManagementKey(false);
845
843
  setQuotaAccounts(void 0);
846
844
  setQuotas({});
847
845
  setFetchedAt(void 0);
@@ -975,14 +973,15 @@ function ProxyPage({ ctx, cache, settings = false }) {
975
973
  }
976
974
  }
977
975
  };
978
- const save = () => {
979
- if (!view || !synchronized || lock.current) return;
976
+ const save = (remove = {}) => {
977
+ if (!view || !synchronized || lock.current || !baseURL.trim()) return;
978
+ if (!draftChanged && !remove.removeAPIKey && !remove.removeManagementKey) return;
980
979
  const changedURL = baseURL.trim() !== view.baseURL;
981
980
  const payload = {
982
981
  revision: view.revision,
983
982
  baseURL: baseURL.trim(),
984
- apiKey: apiKey || (removeAPIKey || changedURL ? "" : void 0),
985
- managementKey: managementKey || (removeManagementKey || changedURL ? "" : void 0)
983
+ apiKey: remove.removeAPIKey ? "" : apiKey || (changedURL ? "" : void 0),
984
+ managementKey: remove.removeManagementKey ? "" : managementKey || (changedURL ? "" : void 0)
986
985
  };
987
986
  setAPIKey("");
988
987
  setManagementKey("");
@@ -998,10 +997,10 @@ function ProxyPage({ ctx, cache, settings = false }) {
998
997
  }
999
998
  await describe(controller);
1000
999
  ctx.emit("cli-proxy-api/connection-changed");
1001
- setNotice(saved ? "savedConnection" : "error");
1000
+ if (!saved) setNotice("error");
1002
1001
  });
1003
1002
  };
1004
- const draftChanged = !!view && (baseURL.trim() !== view.baseURL || !!apiKey || !!managementKey || removeAPIKey || removeManagementKey);
1003
+ const draftChanged = !!view && (baseURL.trim() !== view.baseURL || !!apiKey || !!managementKey);
1005
1004
  const canManage = !!view && synchronized && !draftChanged && !!view?.managementKeySaved;
1006
1005
  const managementDisabled = busy || !canManage || uncertain;
1007
1006
  const row = (label, children) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SettingsRow, {
@@ -1022,7 +1021,7 @@ function ProxyPage({ ctx, cache, settings = false }) {
1022
1021
  "aria-label": "CLIProxyAPI",
1023
1022
  "aria-busy": busy,
1024
1023
  children: [
1025
- busy && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1024
+ busy && !settings && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1026
1025
  role: "status",
1027
1026
  children: text.busy
1028
1027
  }),
@@ -1047,7 +1046,11 @@ function ProxyPage({ ctx, cache, settings = false }) {
1047
1046
  spellCheck: false,
1048
1047
  value: baseURL,
1049
1048
  disabled: busy || !synchronized,
1050
- onChange: (event) => setBaseURL(event.target.value)
1049
+ onChange: (event) => setBaseURL(event.target.value),
1050
+ onBlur: () => save(),
1051
+ onKeyDown: (event) => {
1052
+ if (event.key === "Enter" && !event.nativeEvent.isComposing) event.currentTarget.blur();
1053
+ }
1051
1054
  })),
1052
1055
  row(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
1053
1056
  htmlFor: `${id}-api`,
@@ -1058,15 +1061,13 @@ function ProxyPage({ ctx, cache, settings = false }) {
1058
1061
  autoComplete: "off",
1059
1062
  value: apiKey,
1060
1063
  disabled: busy || !synchronized,
1061
- placeholder: removeAPIKey ? text.removed : view?.apiKeySaved ? text.saved : text.notSaved,
1062
- onChange: (event) => {
1063
- setAPIKey(event.target.value);
1064
- setRemoveAPIKey(false);
1064
+ placeholder: view?.apiKeySaved ? text.saved : text.notSaved,
1065
+ onChange: (event) => setAPIKey(event.target.value),
1066
+ onBlur: () => save(),
1067
+ onKeyDown: (event) => {
1068
+ if (event.key === "Enter" && !event.nativeEvent.isComposing) event.currentTarget.blur();
1065
1069
  }
1066
- }), button(text.remove, () => {
1067
- setAPIKey("");
1068
- setRemoveAPIKey(true);
1069
- }, busy || !synchronized || !view?.apiKeySaved || removeAPIKey)] })),
1070
+ }), button(text.remove, () => save({ removeAPIKey: true }), busy || !synchronized || !view?.apiKeySaved)] })),
1070
1071
  row(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
1071
1072
  htmlFor: `${id}-management`,
1072
1073
  children: text.managementKey
@@ -1076,15 +1077,13 @@ function ProxyPage({ ctx, cache, settings = false }) {
1076
1077
  autoComplete: "off",
1077
1078
  value: managementKey,
1078
1079
  disabled: busy || !synchronized,
1079
- placeholder: removeManagementKey ? text.removed : view?.managementKeySaved ? text.saved : text.notSaved,
1080
- onChange: (event) => {
1081
- setManagementKey(event.target.value);
1082
- setRemoveManagementKey(false);
1080
+ placeholder: view?.managementKeySaved ? text.saved : text.notSaved,
1081
+ onChange: (event) => setManagementKey(event.target.value),
1082
+ onBlur: () => save(),
1083
+ onKeyDown: (event) => {
1084
+ if (event.key === "Enter" && !event.nativeEvent.isComposing) event.currentTarget.blur();
1083
1085
  }
1084
- }), button(text.remove, () => {
1085
- setManagementKey("");
1086
- setRemoveManagementKey(true);
1087
- }, busy || !synchronized || !view?.managementKeySaved || removeManagementKey)] })),
1086
+ }), button(text.remove, () => save({ removeManagementKey: true }), busy || !synchronized || !view?.managementKeySaved)] })),
1088
1087
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1089
1088
  className: "hint",
1090
1089
  children: text.keyHint
@@ -1092,11 +1091,6 @@ function ProxyPage({ ctx, cache, settings = false }) {
1092
1091
  !synchronized && !busy && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1093
1092
  role: "alert",
1094
1093
  children: text.connectionLocked
1095
- }),
1096
- row(text.connection, button(text.save, save, busy || !synchronized || !baseURL.trim())),
1097
- draftChanged && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1098
- className: "hint",
1099
- children: text.draftHint
1100
1094
  })
1101
1095
  ] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
1102
1096
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
@@ -1164,15 +1158,12 @@ function ProxyPage({ ctx, cache, settings = false }) {
1164
1158
  });
1165
1159
  }
1166
1160
  function ProxyPanel({ ctx, cache }) {
1167
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1168
- className: "dsh-cli-proxy-page",
1169
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1170
- className: "dsh-cli-proxy",
1171
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", { children: "CLIProxyAPI" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProxyPage, {
1172
- ctx,
1173
- cache
1174
- })]
1175
- })
1161
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(PluginPage, {
1162
+ contentClassName: "dsh-cli-proxy",
1163
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", { children: "CLIProxyAPI" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProxyPage, {
1164
+ ctx,
1165
+ cache
1166
+ })]
1176
1167
  });
1177
1168
  }
1178
1169
  function apply(ctx) {
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { createHash, randomUUID } from "node:crypto";
2
2
  import { clientRequestSchema } from "@deepseek-ai/dsh-client-connection";
3
3
  import { credentialRef } from "@deepseek-ai/dsh-credentials";
4
- // ../../node_modules/.pnpm/@deepseek-ai+cosmokit@1.8.6/node_modules/@deepseek-ai/cosmokit/lib/index.js
4
+ // ../../node_modules/.pnpm/@deepseek-ai+cosmokit@1.9.0/node_modules/@deepseek-ai/cosmokit/lib/index.js
5
5
  /** Return true when a value is `null` or `undefined`. */
6
6
  function isNullable(value) {
7
7
  return value === null || value === void 0;
@@ -254,7 +254,7 @@ var Time;
254
254
  }
255
255
  Time.template = template;
256
256
  })(Time || (Time = {}));
257
- // ../../node_modules/.pnpm/@deepseek-ai+schemastery@3.18.5/node_modules/@deepseek-ai/schemastery/lib/index.mjs
257
+ // ../../node_modules/.pnpm/@deepseek-ai+schemastery@3.19.0/node_modules/@deepseek-ai/schemastery/lib/index.mjs
258
258
  const kSchema = Symbol.for("schemastery");
259
259
  const kValidationError = Symbol.for("ValidationError");
260
260
  globalThis.__schemastery_index__ ??= 0;
@@ -1455,7 +1455,7 @@ function apply(ctx, config) {
1455
1455
  ctx.effect(() => () => lifetime.abort());
1456
1456
  const currentURL = () => serverURL(config.baseURL.get());
1457
1457
  const ownerEntry = () => {
1458
- const entries = ctx.configEditor.entries().filter((entry) => entry.fiber === ctx.fiber);
1458
+ const entries = ctx.configEditor.entries().filter((entry) => entry.fiber?.uid === ctx.fiber.uid);
1459
1459
  if (entries.length !== 1) throw new Error("unavailable");
1460
1460
  return entries[0];
1461
1461
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dungsil/dsh-plugin-cli-proxy-api",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "description": "CLIProxyAPI model provider and owner-only management settings for DeepSeek Harness.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -24,21 +24,20 @@
24
24
  "access": "public"
25
25
  },
26
26
  "devDependencies": {
27
- "@deepseek-ai/cordis": "4.0.5",
28
- "@deepseek-ai/dsh-app-boot": "0.2.1-rc.5",
29
- "@deepseek-ai/dsh-client-connection": "0.2.1-rc.5",
30
- "@deepseek-ai/dsh-client-locale": "0.2.1-rc.5",
31
- "@deepseek-ai/dsh-client-ui-layout": "0.2.1-rc.5",
32
- "@deepseek-ai/dsh-client-ui-primitives": "0.2.1-rc.5",
33
- "@deepseek-ai/dsh-client-ui-renderer": "0.2.1-rc.5",
34
- "@deepseek-ai/dsh-client-ui-settings": "0.2.1-rc.5",
35
- "@deepseek-ai/dsh-client-ui-sidebar": "0.2.1-rc.5",
36
- "@deepseek-ai/dsh-config-editor": "0.2.1-rc.5",
37
- "@deepseek-ai/dsh-credentials": "0.2.1-rc.5",
38
- "@deepseek-ai/dsh-credentials-local": "0.2.1-rc.5",
39
- "@deepseek-ai/dsh-llm": "0.2.1-rc.5",
40
- "@deepseek-ai/dsh-llm-pi-ai": "0.2.1-rc.5",
41
- "@deepseek-ai/schemastery": "3.18.5",
27
+ "@deepseek-ai/cordis": "4.1.0",
28
+ "@deepseek-ai/dsh-app-boot": "0.2.2-rc.1",
29
+ "@deepseek-ai/dsh-client-connection": "0.2.2-rc.1",
30
+ "@deepseek-ai/dsh-client-locale": "0.2.2-rc.1",
31
+ "@deepseek-ai/dsh-client-ui-layout": "0.2.2-rc.1",
32
+ "@deepseek-ai/dsh-client-ui-renderer": "0.2.2-rc.1",
33
+ "@deepseek-ai/dsh-client-ui-settings": "0.2.2-rc.1",
34
+ "@deepseek-ai/dsh-client-ui-sidebar": "0.2.2-rc.1",
35
+ "@deepseek-ai/dsh-config-editor": "0.2.2-rc.1",
36
+ "@deepseek-ai/dsh-credentials": "0.2.2-rc.1",
37
+ "@deepseek-ai/dsh-credentials-local": "0.2.2-rc.1",
38
+ "@deepseek-ai/dsh-llm": "0.2.2-rc.1",
39
+ "@deepseek-ai/dsh-llm-pi-ai": "0.2.2-rc.1",
40
+ "@deepseek-ai/schemastery": "3.19.0",
42
41
  "@dungsil/dsh-tsconfig": "0.0.0",
43
42
  "@dungsil/dsh-tsdown": "0.0.0",
44
43
  "@dungsil/dsh-ui": "0.0.0",
@@ -50,15 +49,15 @@
50
49
  },
51
50
  "peerDependencies": {
52
51
  "@deepseek-ai/cordis": "^4.0.5",
53
- "@deepseek-ai/dsh-client-connection": "^0.2.1-rc.5",
54
- "@deepseek-ai/dsh-client-ui-primitives": "^0.2.1-rc.5",
55
- "@deepseek-ai/dsh-config-editor": "^0.2.1-rc.5",
56
- "@deepseek-ai/dsh-credentials": "^0.2.1-rc.5",
57
- "@deepseek-ai/dsh-llm": "^0.2.1-rc.5",
58
- "@deepseek-ai/dsh-llm-pi-ai": "^0.2.1-rc.5"
52
+ "@deepseek-ai/dsh-client-connection": "^0.2.1-rc.5 || ^0.2.2-rc.1",
53
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.2.1-rc.5 || ^0.2.2-rc.1",
54
+ "@deepseek-ai/dsh-config-editor": "^0.2.1-rc.5 || ^0.2.2-rc.1",
55
+ "@deepseek-ai/dsh-credentials": "^0.2.1-rc.5 || ^0.2.2-rc.1",
56
+ "@deepseek-ai/dsh-llm": "^0.2.1-rc.5 || ^0.2.2-rc.1",
57
+ "@deepseek-ai/dsh-llm-pi-ai": "^0.2.1-rc.5 || ^0.2.2-rc.1"
59
58
  },
60
59
  "engines": {
61
- "dsh": "^0.2.1-rc.5",
60
+ "dsh": "^0.2.1-rc.5 || ^0.2.2-rc.1",
62
61
  "node": ">=24.9.0"
63
62
  },
64
63
  "dsh": {