@yanglaofish/dsh-proxy-pro 1.0.9 → 1.0.10

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/lib/client.js CHANGED
@@ -179,24 +179,33 @@ window.__ModuleLoader__.load({
179
179
  function ProxyHeaderButton(props) {
180
180
  var scope = props.scope;
181
181
  var settings = useProxySnapshot(scope);
182
- var busy = useState(false);
183
- var setBusy = busy[1];
184
- // Configuration-driven: the capsule mirrors the switch, resolved locally
185
- // with zero requests. The host applies the change instantly when the
186
- // settings revision lands (and follows external system-proxy changes on
187
- // its own 30s poll), so polling here buys nothing (§17).
182
+ // Local optimistic value (2026-09-18): the capsule flips its visual
183
+ // immediately on click instead of waiting for scope.set's round-trip
184
+ // (the settings-page switch already behaves this way). null means no
185
+ // unconfirmed value — the capsule mirrors settings.value.
186
+ var optimistic = useState(null);
187
+ var setOptimistic = optimistic[1];
188
188
  var config = settings.value || {};
189
- var active = config.enabled === true && config.mode !== "none";
190
- var enabled = config.enabled === true;
189
+ var valueEnabled = config.enabled === true;
190
+ var shownEnabled = optimistic[0] !== null ? optimistic[0] : valueEnabled;
191
+ var active = shownEnabled === true && (config.mode || "system") !== "none";
191
192
  var mode = config.mode || "system";
192
193
  var modeLabel = mode === "system" ? "system" : mode === "custom" ? "custom" : "none";
194
+ // Once the host has committed the new value, drop the optimistic echo.
195
+ useEffect(function () {
196
+ if (optimistic[0] !== null && settings.ready && settings.value !== undefined && settings.value.enabled === optimistic[0]) {
197
+ setOptimistic(null);
198
+ }
199
+ }, [optimistic[0], settings.value, settings.ready]);
193
200
  function toggle() {
194
201
  if (!settings.writable) return;
195
- setBusy(true);
196
- var next = !enabled;
202
+ var next = !shownEnabled;
203
+ setOptimistic(next);
197
204
  scope.set("enabled", next).catch(function (error) {
198
205
  console.error("[dsh-proxy-pro] toggle failed:", error);
199
- }).finally(function () { setBusy(false); });
206
+ // Roll back to the committed value on failure.
207
+ setOptimistic(null);
208
+ });
200
209
  // Toggle doubles as a manual "recheck now" even when the settings
201
210
  // panel is not mounted: pulling /status makes the host re-read the
202
211
  // system facts (idempotent — snapshot refresh unless the proxy really
@@ -216,7 +225,7 @@ window.__ModuleLoader__.load({
216
225
  "data-active": active ? "true" : "false",
217
226
  "data-proxy-toggle": true,
218
227
  onClick: toggle,
219
- disabled: !settings.writable || busy[0],
228
+ disabled: !settings.writable,
220
229
  title: title,
221
230
  "aria-pressed": active,
222
231
  },
@@ -422,6 +431,7 @@ window.__ModuleLoader__.load({
422
431
  ? react.createElement("span", null, "诊断失败:" + diag.error)
423
432
  : [
424
433
  react.createElement("span", { key: "r" }, "策略判定: " + diag.route + (diag.bypassed ? "(NO_PROXY 命中)" : "")),
434
+ react.createElement("span", { key: "codes" }, "状态码: 走代理 " + ((diag.proxy && diag.proxy.status) || "—") + " · 直连 " + ((diag.direct && diag.direct.status) || "—")),
425
435
  react.createElement("span", { key: "px", className: "dsxprx-diagprobe" },
426
436
  react.createElement("span", { className: "dsxprx-diotag" }, "走代理"),
427
437
  react.createElement("span", { className: "dsxprx-verdict", "data-tone": channelBadge("proxyBadge").tone }, channelBadge("proxyBadge").text)
package/lib/index.js CHANGED
@@ -565,6 +565,7 @@ function apply(ctx, config) {
565
565
  const lines = [
566
566
  `路由: ${value.route}`,
567
567
  `NO_PROXY 命中: ${value.bypassed}`,
568
+ `状态码: 走代理 ${value.proxy?.status ?? '—'} · 直连 ${value.direct?.status ?? '—'}`,
568
569
  `走代理: ${badge(value.proxyBadge)}`,
569
570
  `直连: ${badge(value.directBadge)}`,
570
571
  `结论: ${value.short ?? '未知'}`,
package/lib/proxy-core.js CHANGED
@@ -429,14 +429,18 @@ export function classifyTargetFailure(error) {
429
429
  * 链路不通 → 截图"代理与直连均失败"误导(2026-09-18 用户实况)。
430
430
  */
431
431
  function dualBadge(probe) {
432
- const detail = (s) => String(s ?? '').replace(/^HTTP \d+ — /, '')
432
+ // Keep the HTTP code in the copy (2026-09-18 用户要求:展示原因时直接看到
433
+ // 状态码,而不是只有人话)。连接层失败没有 status,保持原文案。
434
+ const detail = (s) => String(s ?? '')
433
435
  if (!probe) return { text: '结果未知', tone: 'warn' }
434
- if (probe.verdict === 'usable') return { text: '链路通 · 目标正常响应', tone: 'ok' }
436
+ if (probe.verdict === 'usable') {
437
+ return { text: Number.isFinite(probe.status) ? `链路通 · 目标正常响应(HTTP ${probe.status})` : '链路通 · 目标正常响应', tone: 'ok' }
438
+ }
435
439
  if (probe.verdict === 'degraded') {
436
440
  return { text: `链路通 · 目标拒绝(${detail(probe.short) || '请求被拒'})`, tone: 'warn' }
437
441
  }
438
442
  if (probe.kind === 'gateway' || probe.kind === 'server-error') {
439
- return { text: `链路通 · 目标/网关报错(${detail(probe.short) || String(probe.status ?? '5xx')})`, tone: 'warn' }
443
+ return { text: `链路通 · 目标/网关报错(${detail(probe.short) || `HTTP ${probe.status ?? '5xx'}`})`, tone: 'warn' }
440
444
  }
441
445
  if (probe.kind === 'auth') return { text: '链路不通 · 代理要求认证', tone: 'bad' }
442
446
  return { text: `链路不通 · ${detail(probe.short) || '连接失败'}`, tone: 'bad' }
@@ -474,7 +478,9 @@ export function combineDualProbe(proxyProbe, directProbe) {
474
478
  || (p.verdict === 'unusable' && /NTLM|407/.test(String(p.short ?? '')))
475
479
 
476
480
  const notReachable = (probe, label) => {
477
- const detail = (probe?.short ?? '未知原因').replace(/^HTTP \d+ — /, '')
481
+ // Keep the HTTP code — the reason line should name the status
482
+ // (2026-09-18: user asked for the code to be visible where the cause is shown).
483
+ const detail = probe?.short ?? '未知原因'
478
484
  return `${label}:${detail}`
479
485
  }
480
486
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yanglaofish/dsh-proxy-pro",
3
- "version": "1.0.9",
3
+ "version": "1.0.10",
4
4
  "description": "DSH proxy manager: route model requests, web fetches and spawned tools through the Windows system proxy or a custom address; per-URL route diagnosis, one-click toggle from the conversation header, a dedicated Settings page, and keepalive-aware 407 hints.",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",