ds-harness-remote 0.4.4 → 0.4.5

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 CHANGED
@@ -135,7 +135,7 @@ use the native `/remote` slash command:
135
135
  `connection` 服务。安装插件并启动 `dsh-tui` 后,使用原生 `/remote` Slash Command:
136
136
 
137
137
  ```sh
138
- dsh plugin --profile dsh-tui add ds-harness-remote@0.4.4
138
+ dsh plugin --profile dsh-tui add ds-harness-remote@0.4.5
139
139
  ```
140
140
 
141
141
  ```text
@@ -198,7 +198,7 @@ Add the package to the `web` profile through DSH's plugin manager:
198
198
  通过 DSH 插件管理命令将包加入 `web` profile:
199
199
 
200
200
  ```sh
201
- dsh plugin --profile web add ds-harness-remote@0.4.4
201
+ dsh plugin --profile web add ds-harness-remote@0.4.5
202
202
  ```
203
203
 
204
204
  Do not run npm directly; it does not configure the DSH profile.
@@ -210,11 +210,11 @@ Alternatively, install the pinned GitHub release in DSH Desktop or with the CLI:
210
210
  也可以在 DSH Desktop 中安装固定版本的 GitHub Release,或使用命令行安装:
211
211
 
212
212
  ```text
213
- github:liguobao/ds-harness-remote#v0.4.4
213
+ github:liguobao/ds-harness-remote#v0.4.5
214
214
  ```
215
215
 
216
216
  ```sh
217
- dsh plugin --profile web add "github:liguobao/ds-harness-remote#v0.4.4"
217
+ dsh plugin --profile web add "github:liguobao/ds-harness-remote#v0.4.5"
218
218
  ```
219
219
 
220
220
  GitHub / 项目地址:<https://github.com/liguobao/ds-harness-remote>
@@ -1761,6 +1761,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
1761
1761
  associationSaved: "Associated. Restart Harness to apply.",
1762
1762
  signedOut: "Signed out. Restart Harness to disconnect this mode.",
1763
1763
  remoteRequestFailed: "Remote mode request failed.",
1764
+ remoteControlUnavailable: "Remote plugin control is still starting. Restart DSH if it stays unavailable.",
1764
1765
  switchTarget: "Switch Local / Remote Harness target",
1765
1766
  harnessTarget: "Harness target",
1766
1767
  close: "Close",
@@ -1963,6 +1964,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
1963
1964
  associationSaved: "\u5173\u8054\u6210\u529F\u3002\u91CD\u542F Harness \u540E\u751F\u6548\u3002",
1964
1965
  signedOut: "\u5DF2\u9000\u51FA\u6388\u6743\u3002\u91CD\u542F Harness \u540E\u5C06\u65AD\u5F00\u6B64\u6A21\u5F0F\u3002",
1965
1966
  remoteRequestFailed: "\u8FDC\u7A0B\u6A21\u5F0F\u8BF7\u6C42\u5931\u8D25\u3002",
1967
+ remoteControlUnavailable: "Remote \u63D2\u4EF6\u63A7\u5236\u901A\u9053\u4ECD\u5728\u542F\u52A8\uFF1B\u5982\u679C\u4E00\u76F4\u4E0D\u53EF\u7528\uFF0C\u8BF7\u91CD\u542F DSH\u3002",
1966
1968
  switchTarget: "\u5207\u6362\u672C\u5730\u6216\u8FDC\u7A0B Harness",
1967
1969
  harnessTarget: "Harness \u76EE\u6807",
1968
1970
  close: "\u5173\u95ED",
@@ -2119,7 +2121,22 @@ Minimum version required to store current data is: ` + bestVersion + `.
2119
2121
  refreshQrCode: "\u5237\u65B0\u4E8C\u7EF4\u7801",
2120
2122
  codexVirtualWorkspace: "CodeX \u5DE5\u4F5C\u533A",
2121
2123
  codexVirtualSessions: "Sessions"
2122
- }, defaultPreferredTransports = ["lan", "p2p", "turn", "relay"];
2124
+ }, defaultPreferredTransports = ["lan", "p2p", "turn", "relay"], controlRouteBackoffStepsMs = [1e3, 2e3, 5e3, 1e4, 3e4], ControlRouteUnavailableError = class extends Error {
2125
+ constructor(message) {
2126
+ super(message), this.name = "ControlRouteUnavailableError";
2127
+ }
2128
+ };
2129
+ function controlRouteUnavailableStatus() {
2130
+ return {
2131
+ mode: "local",
2132
+ available: !1,
2133
+ controlUnavailable: !0,
2134
+ connected: !1,
2135
+ transport: "Disconnected",
2136
+ remoteFeatures: { commandList: !1, fileViewer: !1, codex: !1 },
2137
+ hostAuthorizationAvailable: !1
2138
+ };
2139
+ }
2123
2140
  function normalizedPreferredTransports(value) {
2124
2141
  return value === void 0 || value.length === 0 ? [...defaultPreferredTransports] : [...value];
2125
2142
  }
@@ -3483,16 +3500,18 @@ Minimum version required to store current data is: ` + bestVersion + `.
3483
3500
  window.__DS_HARNESS_REMOTE_CLIENT_ACTIVE__ = !0, ctx.effect(() => () => {
3484
3501
  window.__DS_HARNESS_REMOTE_CLIENT_ACTIVE__ = !1;
3485
3502
  }, "ds-harness-remote: client singleton");
3486
- let t = ctx.locale.bind(localeNamespace), control = async (endpoint, payload = {}) => {
3503
+ let t = ctx.locale.bind(localeNamespace), controlRouteRetryAfter = 0, controlRouteBackoffIndex = 0, control = async (endpoint, payload = {}) => {
3504
+ if (endpoint === "status" && Date.now() < controlRouteRetryAfter)
3505
+ return controlRouteUnavailableStatus();
3487
3506
  let result;
3488
- for (let attempt = 0; ; attempt += 1)
3489
- try {
3490
- result = await ctx.connection.rpc.call(CONTROL_RPC_PREFIX, endpoint, payload);
3491
- break;
3492
- } catch (reason) {
3493
- if (attempt >= 19 || !isPendingControlRoute(reason)) throw reason;
3494
- await delay(100);
3495
- }
3507
+ try {
3508
+ result = await ctx.connection.rpc.call(CONTROL_RPC_PREFIX, endpoint, payload), controlRouteRetryAfter = 0, controlRouteBackoffIndex = 0;
3509
+ } catch (reason) {
3510
+ if (!isMissingControlRoute(reason)) throw reason;
3511
+ let delayMs = controlRouteBackoffStepsMs[Math.min(controlRouteBackoffIndex, controlRouteBackoffStepsMs.length - 1)];
3512
+ if (controlRouteBackoffIndex += 1, controlRouteRetryAfter = Date.now() + delayMs, endpoint === "status") return controlRouteUnavailableStatus();
3513
+ throw new ControlRouteUnavailableError(t("remoteControlUnavailable"));
3514
+ }
3496
3515
  if (!result.ok) throw new Error(result.error?.message ?? t("remoteRequestFailed"));
3497
3516
  return result.value;
3498
3517
  };
@@ -3564,11 +3583,8 @@ Minimum version required to store current data is: ` + bestVersion + `.
3564
3583
  inject: () => ({ control })
3565
3584
  }, RemotePluginOptions));
3566
3585
  }
3567
- function isPendingControlRoute(reason) {
3568
- return reason instanceof Error && reason.message.startsWith(`transport failure for ${CONTROL_RPC_PREFIX}/`) && reason.message.endsWith(": HTTP 405");
3569
- }
3570
- function delay(ms) {
3571
- return new Promise((resolve) => window.setTimeout(resolve, ms));
3586
+ function isMissingControlRoute(reason) {
3587
+ return reason instanceof Error && reason.message.startsWith(`transport failure for ${CONTROL_RPC_PREFIX}/`) && (reason.message.endsWith(": HTTP 404") || reason.message.endsWith(": HTTP 405"));
3572
3588
  }
3573
3589
  function messageOf(reason) {
3574
3590
  return reason instanceof Error ? reason.message : String(reason);
package/dist/client.js CHANGED
@@ -1761,6 +1761,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
1761
1761
  associationSaved: "Associated. Restart Harness to apply.",
1762
1762
  signedOut: "Signed out. Restart Harness to disconnect this mode.",
1763
1763
  remoteRequestFailed: "Remote mode request failed.",
1764
+ remoteControlUnavailable: "Remote plugin control is still starting. Restart DSH if it stays unavailable.",
1764
1765
  switchTarget: "Switch Local / Remote Harness target",
1765
1766
  harnessTarget: "Harness target",
1766
1767
  close: "Close",
@@ -1963,6 +1964,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
1963
1964
  associationSaved: "\u5173\u8054\u6210\u529F\u3002\u91CD\u542F Harness \u540E\u751F\u6548\u3002",
1964
1965
  signedOut: "\u5DF2\u9000\u51FA\u6388\u6743\u3002\u91CD\u542F Harness \u540E\u5C06\u65AD\u5F00\u6B64\u6A21\u5F0F\u3002",
1965
1966
  remoteRequestFailed: "\u8FDC\u7A0B\u6A21\u5F0F\u8BF7\u6C42\u5931\u8D25\u3002",
1967
+ remoteControlUnavailable: "Remote \u63D2\u4EF6\u63A7\u5236\u901A\u9053\u4ECD\u5728\u542F\u52A8\uFF1B\u5982\u679C\u4E00\u76F4\u4E0D\u53EF\u7528\uFF0C\u8BF7\u91CD\u542F DSH\u3002",
1966
1968
  switchTarget: "\u5207\u6362\u672C\u5730\u6216\u8FDC\u7A0B Harness",
1967
1969
  harnessTarget: "Harness \u76EE\u6807",
1968
1970
  close: "\u5173\u95ED",
@@ -2119,7 +2121,22 @@ Minimum version required to store current data is: ` + bestVersion + `.
2119
2121
  refreshQrCode: "\u5237\u65B0\u4E8C\u7EF4\u7801",
2120
2122
  codexVirtualWorkspace: "CodeX \u5DE5\u4F5C\u533A",
2121
2123
  codexVirtualSessions: "Sessions"
2122
- }, defaultPreferredTransports = ["lan", "p2p", "turn", "relay"];
2124
+ }, defaultPreferredTransports = ["lan", "p2p", "turn", "relay"], controlRouteBackoffStepsMs = [1e3, 2e3, 5e3, 1e4, 3e4], ControlRouteUnavailableError = class extends Error {
2125
+ constructor(message) {
2126
+ super(message), this.name = "ControlRouteUnavailableError";
2127
+ }
2128
+ };
2129
+ function controlRouteUnavailableStatus() {
2130
+ return {
2131
+ mode: "local",
2132
+ available: !1,
2133
+ controlUnavailable: !0,
2134
+ connected: !1,
2135
+ transport: "Disconnected",
2136
+ remoteFeatures: { commandList: !1, fileViewer: !1, codex: !1 },
2137
+ hostAuthorizationAvailable: !1
2138
+ };
2139
+ }
2123
2140
  function normalizedPreferredTransports(value) {
2124
2141
  return value === void 0 || value.length === 0 ? [...defaultPreferredTransports] : [...value];
2125
2142
  }
@@ -3483,16 +3500,18 @@ Minimum version required to store current data is: ` + bestVersion + `.
3483
3500
  window.__DS_HARNESS_REMOTE_CLIENT_ACTIVE__ = !0, ctx.effect(() => () => {
3484
3501
  window.__DS_HARNESS_REMOTE_CLIENT_ACTIVE__ = !1;
3485
3502
  }, "ds-harness-remote: client singleton");
3486
- let t = ctx.locale.bind(localeNamespace), control = async (endpoint, payload = {}) => {
3503
+ let t = ctx.locale.bind(localeNamespace), controlRouteRetryAfter = 0, controlRouteBackoffIndex = 0, control = async (endpoint, payload = {}) => {
3504
+ if (endpoint === "status" && Date.now() < controlRouteRetryAfter)
3505
+ return controlRouteUnavailableStatus();
3487
3506
  let result;
3488
- for (let attempt = 0; ; attempt += 1)
3489
- try {
3490
- result = await ctx.connection.rpc.call(CONTROL_RPC_PREFIX, endpoint, payload);
3491
- break;
3492
- } catch (reason) {
3493
- if (attempt >= 19 || !isPendingControlRoute(reason)) throw reason;
3494
- await delay(100);
3495
- }
3507
+ try {
3508
+ result = await ctx.connection.rpc.call(CONTROL_RPC_PREFIX, endpoint, payload), controlRouteRetryAfter = 0, controlRouteBackoffIndex = 0;
3509
+ } catch (reason) {
3510
+ if (!isMissingControlRoute(reason)) throw reason;
3511
+ let delayMs = controlRouteBackoffStepsMs[Math.min(controlRouteBackoffIndex, controlRouteBackoffStepsMs.length - 1)];
3512
+ if (controlRouteBackoffIndex += 1, controlRouteRetryAfter = Date.now() + delayMs, endpoint === "status") return controlRouteUnavailableStatus();
3513
+ throw new ControlRouteUnavailableError(t("remoteControlUnavailable"));
3514
+ }
3496
3515
  if (!result.ok) throw new Error(result.error?.message ?? t("remoteRequestFailed"));
3497
3516
  return result.value;
3498
3517
  };
@@ -3564,11 +3583,8 @@ Minimum version required to store current data is: ` + bestVersion + `.
3564
3583
  inject: () => ({ control })
3565
3584
  }, RemotePluginOptions));
3566
3585
  }
3567
- function isPendingControlRoute(reason) {
3568
- return reason instanceof Error && reason.message.startsWith(`transport failure for ${CONTROL_RPC_PREFIX}/`) && reason.message.endsWith(": HTTP 405");
3569
- }
3570
- function delay(ms) {
3571
- return new Promise((resolve) => window.setTimeout(resolve, ms));
3586
+ function isMissingControlRoute(reason) {
3587
+ return reason instanceof Error && reason.message.startsWith(`transport failure for ${CONTROL_RPC_PREFIX}/`) && (reason.message.endsWith(": HTTP 404") || reason.message.endsWith(": HTTP 405"));
3572
3588
  }
3573
3589
  function messageOf(reason) {
3574
3590
  return reason instanceof Error ? reason.message : String(reason);