dsh-provider-proxy 0.4.0 → 0.4.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.md +3 -3
- package/lib/client.js +54 -18
- package/lib/client.js.map +2 -2
- package/lib/index.js +42 -5
- package/lib/index.js.map +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -38,8 +38,8 @@ dsh plugin --profile web add dsh-provider-proxy
|
|
|
38
38
|
| 类型 | `HTTP` / `HTTPS` / `SOCKS5` |
|
|
39
39
|
| IP / 主机 | 只填主机名或 IP,不要带 `http://` 或路径 |
|
|
40
40
|
| 端口 | 1–65535 的整数 |
|
|
41
|
-
| 用户名 |
|
|
42
|
-
| 密码 |
|
|
41
|
+
| 用户名 | 可选(与密码成对填写) |
|
|
42
|
+
| 密码 | 可选(与用户名成对填写)。作为代理认证口令发给代理(`HTTP` / `HTTPS` / `SOCKS5` 均支持) |
|
|
43
43
|
|
|
44
44
|
列表只包含**已激活**的 provider(`llm.listProviders()` 能列出的那些)。仅在配置里声明、
|
|
45
45
|
但没有实际注册的可配置 provider 不显示——它的请求根本不会被发出去。
|
|
@@ -89,7 +89,7 @@ dsh plugin --profile web add dsh-provider-proxy
|
|
|
89
89
|
## 已知限制
|
|
90
90
|
|
|
91
91
|
- **SOCKS5 由 `undici` 内置的 `Socks5ProxyAgent` 实现**(RFC 1928 / RFC 1929),API 稳定性标记为 *Experimental*;`undici` 若在未来移除,需要同步调整。
|
|
92
|
-
-
|
|
92
|
+
- **代理认证字段成对填写:用户名与密码要么都填,要么都不填。** 只填任一项都会被拒绝并给出提示。SOCKS5 侧的依据是 `Socks5ProxyAgent` 仅在两者齐备时才发起认证——只填用户名会静默广告无认证,只填密码则密码根本不会被发送(对开放代理能用,对要求认证的代理必然失败,且失败原因看起来像密码错误);HTTP/HTTPS 侧基本认证本可只发用户名(`alice:`,空密码),这里仍按成对拒绝:半填的凭据几乎总是漏填,三种传输共用一条规则比「哪种传输能承载哪种组合」更好记。代价如实写明——凭据真的使用空密码的代理无法在这里配置。不合规则的配置会被拒绝,原因列在设置页的「连接诊断」面板里(该路由的「测试」也会返回同一条),而不是被静默忽略——否则在强制认证的代理端,报错会指向代理而真正原因是设置缺项。
|
|
93
93
|
- **SOCKS5 不支持 `socks://` 别名与 SOCKS5 over TLS**(`proxyTls`)。
|
|
94
94
|
- **`bypassHosts` 命中时由本机解析并连接目标**(DNS 不经过代理)。SOCKS5 下这一点后果最明显:命中的域名不再由代理端解析,本机 DNS 会暴露该次查询。
|
|
95
95
|
- **`web_search` 可以走代理,`web_fetch` 不行。** 搜索 provider(`dsh-web-search-deepseek`)用全局 `fetch`,插件通过包裹 `ctx.web.search` 把它送进代理作用域;这条成立的前提是:工具每次调用都重新取 `ctx.web.search`,且 provider 的 `search()` 是 await-to-completion(不是惰性消费的流)。`web_fetch` 则用 `undici` 自带的 `dispatcher`(来自官方的进程级 env 策略),没有 per-provider 注入点,本插件覆盖不到——需要覆盖它请改用 `HTTP_PROXY` 之类的环境变量。
|
package/lib/client.js
CHANGED
|
@@ -39,13 +39,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
39
39
|
var require_client = __commonJS({
|
|
40
40
|
"src/client.css"(exports, module2) {
|
|
41
41
|
"use strict";
|
|
42
|
-
var __dshMap = { "root": "
|
|
42
|
+
var __dshMap = { "root": "6d45ff27_root", "lead": "57c30143_lead", "empty": "b6600f2d_empty", "card": "0ba90fef_card", "cardActive": "923630a9_cardActive", "cardHead": "5af7e7c3_cardHead", "cardTitles": "8448919c_cardTitles", "name": "0b023e00_name", "id": "ffa6a1c5_id", "pillOn": "85972c09_pillOn", "pillLive": "d3644cdc_pillLive", "pillOff": "592bd7b2_pillOff", "toggle": "9efc135e_toggle", "field": "93a03683_field", "label": "0bd1d3ec_label", "hint": "52d56786_hint", "input": "f6748c5e_input", "testButton": "eb3b08bd_testButton", "diag": "4d4b11ef_diag", "diagSummary": "2e565ce0_diagSummary", "diagList": "fb9c7553_diagList" };
|
|
43
43
|
var __dshStyles = globalThis.__dshPluginStyles || (globalThis.__dshPluginStyles = /* @__PURE__ */ new Set());
|
|
44
44
|
if (!__dshStyles.has("dsh-provider-proxy/client.css")) {
|
|
45
45
|
__dshStyles.add("dsh-provider-proxy/client.css");
|
|
46
46
|
__dshStyle = document.createElement("style");
|
|
47
47
|
__dshStyle.setAttribute("data-plugin-css", "dsh-provider-proxy/client.css");
|
|
48
|
-
__dshStyle.textContent = "/* dsh-provider-proxy \u2014 provider proxy settings page.\n Tokens only: no literal colours, matching the shared --dsw-* system. */\n\n.
|
|
48
|
+
__dshStyle.textContent = "/* dsh-provider-proxy \u2014 provider proxy settings page.\n Tokens only: no literal colours, matching the shared --dsw-* system. */\n\n.6d45ff27_root {\n display: flex;\n flex-direction: column;\n gap: 12px;\n max-width: 640px;\n}\n\n.57c30143_lead {\n margin: 0 0 4px;\n font-size: 12px;\n line-height: 1.6;\n color: var(--dsw-alias-label-secondary);\n}\n\n.b6600f2d_empty {\n margin: 0;\n padding: 16px;\n border: 1px dashed var(--dsw-alias-border-l1);\n border-radius: 8px;\n font-size: 12px;\n text-align: center;\n color: var(--dsw-alias-state-idle-primary);\n}\n\n/* ---- provider card ---- */\n\n.0ba90fef_card,\n.923630a9_cardActive {\n display: flex;\n flex-direction: column;\n gap: 10px;\n padding: 12px 14px;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 10px;\n background: var(--dsw-alias-bg-layer-1);\n}\n\n.923630a9_cardActive {\n border-color: var(--dsw-alias-state-success-primary);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n.5af7e7c3_cardHead {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n}\n\n.8448919c_cardTitles {\n display: flex;\n align-items: baseline;\n gap: 8px;\n min-width: 0;\n}\n\n.0b023e00_name {\n overflow: hidden;\n font-size: 13px;\n font-weight: 600;\n white-space: nowrap;\n text-overflow: ellipsis;\n color: var(--dsw-alias-label-primary);\n}\n\n.ffa6a1c5_id {\n flex: none;\n padding: 1px 6px;\n border-radius: 4px;\n background: var(--dsw-alias-bg-layer-2);\n font-family: ui-monospace, monospace;\n font-size: 11px;\n color: var(--dsw-alias-label-secondary);\n}\n\n/* ---- status pill ---- */\n\n.85972c09_pillOn,\n.d3644cdc_pillLive,\n.592bd7b2_pillOff {\n flex: none;\n padding: 2px 8px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 500;\n white-space: nowrap;\n}\n\n.85972c09_pillOn {\n background: var(--dsw-alias-state-success-primary);\n color: var(--dsw-alias-bg-base);\n}\n\n.d3644cdc_pillLive {\n border: 1px solid var(--dsw-alias-border-l2);\n color: var(--dsw-alias-label-secondary);\n}\n\n.592bd7b2_pillOff {\n color: var(--dsw-alias-state-idle-primary);\n}\n\n/* ---- toggle ---- */\n\n.9efc135e_toggle {\n display: flex;\n align-items: center;\n gap: 8px;\n padding-top: 2px;\n font-size: 12px;\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n}\n\n.9efc135e_toggle input {\n accent-color: var(--dsw-alias-brand-primary);\n cursor: pointer;\n}\n\n/* ---- fields ---- */\n\n.93a03683_field {\n display: grid;\n grid-template-columns: 96px 1fr;\n align-items: center;\n gap: 10px;\n font-size: 12px;\n}\n\n.0bd1d3ec_label {\n color: var(--dsw-alias-label-secondary);\n}\n\n.52d56786_hint {\n grid-column: 2;\n margin-top: -2px;\n font-size: 11px;\n color: var(--dsw-alias-state-warn-primary);\n}\n\n.f6748c5e_input {\n box-sizing: border-box;\n width: 100%;\n min-width: 0;\n padding: 5px 8px;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 6px;\n outline: none;\n background: var(--dsw-alias-bg-layer-1);\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 12px;\n transition: border-color 120ms ease, background 120ms ease;\n}\n\n/* The base look of every input is INLINE too, so these three state rules only\n ever take effect as author-important declarations \u2014 same reason as the\n self-check button above. `cursor` has no inline base and needs none, and the\n hover border uses `l3` because `l1`\u2192`l2` is a 4%\u219210% black step nobody can\n see. */\n\n.f6748c5e_input:hover:not(:disabled) {\n border-color: var(--dsw-alias-border-l3) !important;\n}\n\n.f6748c5e_input:focus {\n border-color: var(--dsw-alias-brand-primary) !important;\n}\n\n.f6748c5e_input:disabled {\n color: var(--dsw-alias-state-idle-primary) !important;\n background: var(--dsw-alias-bg-layer-2) !important;\n cursor: not-allowed;\n}\n\n/* ---- self-check ---- */\n\n/* The hover state is the one thing an inline style cannot express, which is why\n this element carries a class at all. Layout stays inline.\n\n Two traps, both hit before this comment existed:\n - `!important` is load-bearing: the base border and background are INLINE, and\n the cascade sorts a style attribute after every author rule, so a plain\n declaration here would ship, match, and still lose.\n - the TOKENS must be visible ones. `bg-layer-1/2/3` all resolve to\n `neutral-bluish-00` in the light theme, so a layer swap is a no-op there, and\n `border-l1`\u2192`l2` is 4%\u219210% black on a 1px line. The app's own hovers use\n `interactive-bg-hover`; using it here is what makes the feedback exist. */\n.eb3b08bd_testButton {\n transition: border-color 120ms ease, background 120ms ease;\n}\n\n.eb3b08bd_testButton:hover:not(:disabled) {\n border-color: var(--dsw-alias-border-l3) !important;\n background: var(--dsw-alias-interactive-bg-hover) !important;\n}\n\n/* ---- diagnostics ---- */\n\n.4d4b11ef_diag {\n margin-top: 2px;\n padding: 8px 10px;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 8px;\n font-size: 11px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.2e565ce0_diagSummary {\n cursor: pointer;\n color: var(--dsw-alias-state-warn-primary);\n}\n\n.fb9c7553_diagList {\n margin: 6px 0 0;\n padding-left: 18px;\n font-family: ui-monospace, monospace;\n word-break: break-all;\n}\n";
|
|
49
49
|
document.head.appendChild(__dshStyle);
|
|
50
50
|
}
|
|
51
51
|
var __dshStyle;
|
|
@@ -197,7 +197,14 @@ async function fetchCatalog() {
|
|
|
197
197
|
if (typeof count === "number" && Number.isFinite(count)) hits[id] = count;
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
|
-
|
|
200
|
+
const problems = {};
|
|
201
|
+
const rejected = body?.problems;
|
|
202
|
+
if (rejected !== null && typeof rejected === "object") {
|
|
203
|
+
for (const [id, message] of Object.entries(rejected)) {
|
|
204
|
+
if (typeof message === "string" && message.length > 0) problems[id] = message;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return { rows, hits, problems };
|
|
201
208
|
}
|
|
202
209
|
var byName = (a, b) => a.name.localeCompare(b.name);
|
|
203
210
|
function view(route) {
|
|
@@ -288,6 +295,19 @@ var S = {
|
|
|
288
295
|
color: "var(--dsw-alias-label-secondary)",
|
|
289
296
|
wordBreak: "break-all"
|
|
290
297
|
},
|
|
298
|
+
/**
|
|
299
|
+
* A failed check is the answer, not decoration: it takes the error colour and
|
|
300
|
+
* a heavier weight, unlike the latency band colour which only tints a number
|
|
301
|
+
* that is printed anyway.
|
|
302
|
+
*/
|
|
303
|
+
testFailure: {
|
|
304
|
+
color: "var(--dsw-alias-state-error-primary, #f85149)",
|
|
305
|
+
fontWeight: "500"
|
|
306
|
+
},
|
|
307
|
+
/** A rejected route is a failure of the settings, not a warning about them. */
|
|
308
|
+
diagProblem: {
|
|
309
|
+
color: "var(--dsw-alias-state-error-primary, #f85149)"
|
|
310
|
+
},
|
|
291
311
|
advanced: {
|
|
292
312
|
marginTop: "4px",
|
|
293
313
|
fontSize: "12px"
|
|
@@ -363,13 +383,23 @@ function renderPage(ctx) {
|
|
|
363
383
|
}]))(() => {
|
|
364
384
|
void fetchCatalog().then((catalog) => catalogueSetter?.(catalog)).catch((error) => {
|
|
365
385
|
note(`provider \u5217\u8868\u83B7\u53D6\u5931\u8D25\uFF1A${error?.message ?? error}`);
|
|
366
|
-
catalogueSetter?.({ rows: [], hits: {} });
|
|
386
|
+
catalogueSetter?.({ rows: [], hits: {}, problems: {} });
|
|
367
387
|
});
|
|
368
|
-
return {
|
|
388
|
+
return {
|
|
389
|
+
rows: void 0,
|
|
390
|
+
hits: {},
|
|
391
|
+
problems: {},
|
|
392
|
+
pending: true
|
|
393
|
+
};
|
|
369
394
|
});
|
|
370
|
-
catalogueSetter = (catalog) => setState({ rows: catalog.rows, hits: catalog.hits, pending: false });
|
|
395
|
+
catalogueSetter = (catalog) => setState({ rows: catalog.rows, hits: catalog.hits, problems: catalog.problems, pending: false });
|
|
371
396
|
const published = state.rows ?? [];
|
|
372
397
|
const hits = state.hits ?? {};
|
|
398
|
+
const problems = state.problems ?? {};
|
|
399
|
+
const problemLines = Object.entries(problems).map(
|
|
400
|
+
([id, message]) => h("li", { key: `p:${id}`, style: S.diagProblem }, `${id}\uFF1A${message}`)
|
|
401
|
+
);
|
|
402
|
+
const problemCount = problemLines.length;
|
|
373
403
|
note(
|
|
374
404
|
`provider \u5217\u8868\uFF1A\u6765\u81EA Host \u5171 ${published.length} \u4E2A\uFF08${published.map((r) => r.id).join("\u3001") || "\u65E0"}\uFF09`
|
|
375
405
|
);
|
|
@@ -389,10 +419,6 @@ function renderPage(ctx) {
|
|
|
389
419
|
});
|
|
390
420
|
const body2 = await response.json();
|
|
391
421
|
setTests((current) => ({ ...current, [id]: testResultFrom(body2, t) }));
|
|
392
|
-
if (body2?.ok === true) {
|
|
393
|
-
void fetchCatalog().then((catalog) => catalogueSetter?.(catalog)).catch(() => {
|
|
394
|
-
});
|
|
395
|
-
}
|
|
396
422
|
} catch (error) {
|
|
397
423
|
setTests((current) => ({
|
|
398
424
|
...current,
|
|
@@ -470,7 +496,7 @@ function renderPage(ctx) {
|
|
|
470
496
|
// noise; the count shows once the route is on (or has counted).
|
|
471
497
|
route.enabled || (hits[row.id] ?? 0) > 0 ? h(
|
|
472
498
|
"span",
|
|
473
|
-
{
|
|
499
|
+
{ style: S.hits },
|
|
474
500
|
`${t.hitCountPrefix}${hits[row.id] ?? 0}${t.hitCountSuffix}`
|
|
475
501
|
) : null
|
|
476
502
|
),
|
|
@@ -575,7 +601,7 @@ function renderPage(ctx) {
|
|
|
575
601
|
// route is not in the Host's table, so there is nothing to test.
|
|
576
602
|
route.enabled ? h(
|
|
577
603
|
"div",
|
|
578
|
-
{
|
|
604
|
+
{ style: S.testRow, key: `${row.id}:test` },
|
|
579
605
|
h(
|
|
580
606
|
"button",
|
|
581
607
|
{
|
|
@@ -589,7 +615,7 @@ function renderPage(ctx) {
|
|
|
589
615
|
),
|
|
590
616
|
result?.pending === false ? h(
|
|
591
617
|
"span",
|
|
592
|
-
{
|
|
618
|
+
{ style: S.testResult },
|
|
593
619
|
result.ok === true ? [
|
|
594
620
|
// Only the latency carries the band colour; the exit IP
|
|
595
621
|
// stays in the secondary label colour.
|
|
@@ -599,14 +625,14 @@ function renderPage(ctx) {
|
|
|
599
625
|
`\u2713 ${typeof result.ms === "number" ? result.ms : "\u2014"} ms`
|
|
600
626
|
),
|
|
601
627
|
result.ip === void 0 ? null : ` \xB7 ${t.exitIpLabel}${result.ip}`
|
|
602
|
-
] : `\u2717 ${result.error}`
|
|
628
|
+
] : h("span", { key: "err", style: S.testFailure }, `\u2717 ${result.error}`)
|
|
603
629
|
) : null
|
|
604
630
|
) : null,
|
|
605
631
|
// Target-host rules, collapsed so the common case stays one short card.
|
|
606
632
|
h(
|
|
607
633
|
"details",
|
|
608
|
-
{
|
|
609
|
-
h("summary", {
|
|
634
|
+
{ style: S.advanced, key: `${row.id}:rules` },
|
|
635
|
+
h("summary", { style: S.advancedSummary }, t.advanced),
|
|
610
636
|
field(
|
|
611
637
|
t.onlyHosts,
|
|
612
638
|
h("input", {
|
|
@@ -653,11 +679,21 @@ function renderPage(ctx) {
|
|
|
653
679
|
color: "var(--dsw-alias-label-secondary)"
|
|
654
680
|
}
|
|
655
681
|
},
|
|
656
|
-
|
|
682
|
+
// The count is the only visible signal while the panel is collapsed: a
|
|
683
|
+
// rejected route is not a page that refuses to render, it is one that
|
|
684
|
+
// quietly does nothing.
|
|
685
|
+
h(
|
|
686
|
+
"summary",
|
|
687
|
+
{ className: import_client.default.diagSummary },
|
|
688
|
+
problemCount === 0 ? t.diagnostics : `${t.diagnostics} (${problemCount})`
|
|
689
|
+
),
|
|
657
690
|
h(
|
|
658
691
|
"ul",
|
|
659
692
|
{ className: import_client.default.diagList, style: { margin: "6px 0 0", paddingLeft: "18px" } },
|
|
660
|
-
...diagnostics.length === 0 ? [h("li", { key: "none" }, t.diagPending)] :
|
|
693
|
+
...problemCount === 0 && diagnostics.length === 0 ? [h("li", { key: "none" }, t.diagPending)] : [
|
|
694
|
+
...problemLines,
|
|
695
|
+
...diagnostics.map((line, index) => h("li", { key: `d${index}` }, line))
|
|
696
|
+
]
|
|
661
697
|
)
|
|
662
698
|
)
|
|
663
699
|
);
|
package/lib/client.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/client.css", "../src/client.ts"],
|
|
4
|
-
"sourcesContent": ["\nvar __dshMap = {\"root\":\"1b9ac577_root\",\"lead\":\"4a359f22_lead\",\"empty\":\"ffd21b3b_empty\",\"card\":\"16611c9b_card\",\"cardActive\":\"2d004466_cardActive\",\"cardHead\":\"640fee25_cardHead\",\"cardTitles\":\"f6fe8b3f_cardTitles\",\"name\":\"f9d2db09_name\",\"id\":\"c90ce2e0_id\",\"pillOn\":\"75541864_pillOn\",\"pillLive\":\"3097d90f_pillLive\",\"pillOff\":\"a58f86be_pillOff\",\"toggle\":\"e5b81c4b_toggle\",\"field\":\"f4d34839_field\",\"label\":\"a4061c91_label\",\"hint\":\"13bd3ec9_hint\",\"input\":\"851d7bd9_input\",\"diag\":\"f92a10d9_diag\",\"diagSummary\":\"5b66e072_diagSummary\",\"diagList\":\"dc8d3a6f_diagList\"};\nvar __dshStyles = (globalThis.__dshPluginStyles || (globalThis.__dshPluginStyles = new Set()));\nif (!__dshStyles.has(\"dsh-provider-proxy/client.css\")) {\n __dshStyles.add(\"dsh-provider-proxy/client.css\");\n var __dshStyle = document.createElement('style');\n __dshStyle.setAttribute('data-plugin-css', \"dsh-provider-proxy/client.css\");\n __dshStyle.textContent = \"/* dsh-provider-proxy \u2014 provider proxy settings page.\\n Tokens only: no literal colours, matching the shared --dsw-* system. */\\n\\n.1b9ac577_root {\\n display: flex;\\n flex-direction: column;\\n gap: 12px;\\n max-width: 640px;\\n}\\n\\n.4a359f22_lead {\\n margin: 0 0 4px;\\n font-size: 12px;\\n line-height: 1.6;\\n color: var(--dsw-alias-label-secondary);\\n}\\n\\n.ffd21b3b_empty {\\n margin: 0;\\n padding: 16px;\\n border: 1px dashed var(--dsw-alias-border-l1);\\n border-radius: 8px;\\n font-size: 12px;\\n text-align: center;\\n color: var(--dsw-alias-state-idle-primary);\\n}\\n\\n/* ---- provider card ---- */\\n\\n.16611c9b_card,\\n.2d004466_cardActive {\\n display: flex;\\n flex-direction: column;\\n gap: 10px;\\n padding: 12px 14px;\\n border: 1px solid var(--dsw-alias-border-l1);\\n border-radius: 10px;\\n background: var(--dsw-alias-bg-layer-1);\\n}\\n\\n.2d004466_cardActive {\\n border-color: var(--dsw-alias-state-success-primary);\\n background: var(--dsw-alias-bg-layer-2);\\n}\\n\\n.640fee25_cardHead {\\n display: flex;\\n align-items: center;\\n justify-content: space-between;\\n gap: 12px;\\n}\\n\\n.f6fe8b3f_cardTitles {\\n display: flex;\\n align-items: baseline;\\n gap: 8px;\\n min-width: 0;\\n}\\n\\n.f9d2db09_name {\\n overflow: hidden;\\n font-size: 13px;\\n font-weight: 600;\\n white-space: nowrap;\\n text-overflow: ellipsis;\\n color: var(--dsw-alias-label-primary);\\n}\\n\\n.c90ce2e0_id {\\n flex: none;\\n padding: 1px 6px;\\n border-radius: 4px;\\n background: var(--dsw-alias-bg-layer-2);\\n font-family: ui-monospace, monospace;\\n font-size: 11px;\\n color: var(--dsw-alias-label-secondary);\\n}\\n\\n/* ---- status pill ---- */\\n\\n.75541864_pillOn,\\n.3097d90f_pillLive,\\n.a58f86be_pillOff {\\n flex: none;\\n padding: 2px 8px;\\n border-radius: 999px;\\n font-size: 11px;\\n font-weight: 500;\\n white-space: nowrap;\\n}\\n\\n.75541864_pillOn {\\n background: var(--dsw-alias-state-success-primary);\\n color: var(--dsw-alias-bg-base);\\n}\\n\\n.3097d90f_pillLive {\\n border: 1px solid var(--dsw-alias-border-l2);\\n color: var(--dsw-alias-label-secondary);\\n}\\n\\n.a58f86be_pillOff {\\n color: var(--dsw-alias-state-idle-primary);\\n}\\n\\n/* ---- toggle ---- */\\n\\n.e5b81c4b_toggle {\\n display: flex;\\n align-items: center;\\n gap: 8px;\\n padding-top: 2px;\\n font-size: 12px;\\n color: var(--dsw-alias-label-primary);\\n cursor: pointer;\\n}\\n\\n.e5b81c4b_toggle input {\\n accent-color: var(--dsw-alias-brand-primary);\\n cursor: pointer;\\n}\\n\\n/* ---- fields ---- */\\n\\n.f4d34839_field {\\n display: grid;\\n grid-template-columns: 96px 1fr;\\n align-items: center;\\n gap: 10px;\\n font-size: 12px;\\n}\\n\\n.a4061c91_label {\\n color: var(--dsw-alias-label-secondary);\\n}\\n\\n.13bd3ec9_hint {\\n grid-column: 2;\\n margin-top: -2px;\\n font-size: 11px;\\n color: var(--dsw-alias-state-warn-primary);\\n}\\n\\n.851d7bd9_input {\\n box-sizing: border-box;\\n width: 100%;\\n min-width: 0;\\n padding: 5px 8px;\\n border: 1px solid var(--dsw-alias-border-l1);\\n border-radius: 6px;\\n outline: none;\\n background: var(--dsw-alias-bg-layer-1);\\n color: var(--dsw-alias-label-primary);\\n font: inherit;\\n font-size: 12px;\\n transition: border-color 120ms ease, background 120ms ease;\\n}\\n\\n.851d7bd9_input:hover:not(:disabled) {\\n border-color: var(--dsw-alias-border-l2);\\n}\\n\\n.851d7bd9_input:focus {\\n border-color: var(--dsw-alias-brand-primary);\\n}\\n\\n.851d7bd9_input:disabled {\\n color: var(--dsw-alias-state-idle-primary);\\n background: var(--dsw-alias-bg-layer-2);\\n cursor: not-allowed;\\n}\\n\\n/* ---- diagnostics ---- */\\n\\n.f92a10d9_diag {\\n margin-top: 2px;\\n padding: 8px 10px;\\n border: 1px solid var(--dsw-alias-border-l1);\\n border-radius: 8px;\\n font-size: 11px;\\n color: var(--dsw-alias-label-secondary);\\n}\\n\\n.5b66e072_diagSummary {\\n cursor: pointer;\\n color: var(--dsw-alias-state-warn-primary);\\n}\\n\\n.dc8d3a6f_diagList {\\n margin: 6px 0 0;\\n padding-left: 18px;\\n font-family: ui-monospace, monospace;\\n word-break: break-all;\\n}\\n\";\n document.head.appendChild(__dshStyle);\n}\nmodule.exports = __dshMap;\nmodule.exports.default = __dshMap;\nmodule.exports.__esModule = true;\n", "/**\r\n * dsh-provider-proxy \u2014 browser half.\r\n *\r\n * Contributes ONE settings page (a `settings.section` list entry) that lists\r\n * every known provider with its proxy switch, type, host, port and username.\r\n *\r\n * This replaces an earlier attempt to render into each provider card on the\r\n * Models page (`settings.models.provider-card`). That seat is keyed and\r\n * dispatched per provider namespace, and a third-party registration never\r\n * matched it on this build: no error, no request, simply no output. A\r\n * `settings.section` entry is a plain list contribution with an `id`, which is\r\n * the shape the shipped `dsh-llm-retry-settings` plugin uses successfully in\r\n * this same desktop profile.\r\n *\r\n * The whole bundle runs inside the client module system's lazy-CJS factory:\r\n * executing the script only REGISTERS the factory, and every side effect\r\n * (including the CSS injection) happens at materialization.\r\n */\r\n\r\n// The CSS-Modules build turns this sheet into a hashed class map AND injects it\r\n// at materialization. The binding is what the component reads; importing it for\r\n// side effects only would leave `styles` undefined at render time.\r\nimport styles from './client.css'\r\n\r\ntype Protocol = 'http' | 'https' | 'socks5'\r\n\r\ntype RouteValue = {\r\n enabled: boolean\r\n protocol: Protocol\r\n host: string\r\n port: number\r\n username: string\r\n password: string\r\n onlyHosts: string\r\n bypassHosts: string\r\n}\r\n\r\n/** The provider rows we know about, and which of them are actually live. */\r\ntype ProviderRow = { id: string; name: string; live: boolean }\r\n\r\n/**\r\n * React, resolved from the client module table.\r\n *\r\n * React is NOT a Cordis service and is not reachable from `ctx` \u2014 reading it\r\n * there produced a silently null component. The module table is the only route:\r\n * the build leaves `react` external, so this compiles to a `require(\"react\")`\r\n * inside the factory closure, answered from the shell-seeded baseline.\r\n *\r\n * Resolved lazily on first render so merely REGISTERING the bundle \u2014 which is\r\n * all a script evaluation does \u2014 never materializes React.\r\n */\r\nlet ReactCache: unknown\r\n\r\nfunction react(): any {\r\n if (ReactCache === undefined) {\r\n ReactCache = ((): unknown => {\r\n try {\r\n return require('react')\r\n } catch {\r\n return (globalThis as Record<string, unknown>).React\r\n }\r\n })()\r\n }\r\n return ReactCache\r\n}\r\n\r\nconst PROTOCOLS: Protocol[] = ['http', 'https', 'socks5']\r\n\r\n/** Our own settings namespace; the profile entry id created by the bundle patch. */\r\nconst NAMESPACE = 'provider-proxy'\r\n\r\n/**\r\n * Cordis services this half needs.\r\n *\r\n * ONLY `slots` is declared. That is the complete set this release actually\r\n * offers on a client fiber: `layout, locale, sessions, slots, theme, timer,\r\n * uiWorkspace, workspaces`.\r\n *\r\n * A declared service that never arrives leaves the fiber PENDING forever, and\r\n * that is NOT a client-only failure \u2014 it is reported as\r\n * web boot: 1 entry did not activate\r\n * dsh-provider-proxy: pending (waiting for service: settingsScope)\r\n * which fails the whole Desktop boot. `settingsScope` and `configForms` were\r\n * both guessed and both are absent here, so neither may be declared.\r\n *\r\n * Settings are therefore reached through `ctx.get(name)` \u2014 the framework's own\r\n * non-throwing lookup \u2014 and the page degrades to read-only when it is absent.\r\n */\r\nconst PLUGINS = ['slots']\r\n\r\nexport const inject = PLUGINS\r\n\r\nexport function apply(ctx: any): void {\r\n // The settings shell declares `settings.section` on its own fiber, so\r\n // `slots.inject` waits for that declaration and the contribution is removed\r\n // when the panel is torn down.\r\n ctx.slots.inject('settings.section', () =>\r\n ctx.slots.register(\r\n {\r\n name: 'settings.section',\r\n id: NAMESPACE,\r\n order: 20,\r\n label: () => (localeOf(ctx) === 'zh' ? 'Provider \u4EE3\u7406' : 'Provider \u4EE3\u7406'),\r\n },\r\n () => renderPage(ctx),\r\n ),\r\n )\r\n}\r\n\r\n/**\r\n * Pick the dictionary.\r\n *\r\n * Chinese is the default, not English: this plugin is written for a\r\n * Chinese-speaking operator, and a page that renders in the wrong language is\r\n * worse than one that never matches the shell's locale.\r\n *\r\n * `ctx.locale` is not injected \u2014 declaring a service that this release does not\r\n * provide left the fiber PENDING and failed the whole Desktop boot \u2014 so the\r\n * locale is probed with the non-throwing `ctx.get`, then the browser's own\r\n * language, and only then English.\r\n */\r\nfunction localeOf(ctx: any): string {\r\n try {\r\n const service = optionalService(ctx, 'locale')\r\n const snapshot = service?.getSnapshot?.() ?? service?.getLocale?.()\r\n const id = typeof snapshot?.locale === 'string' ? snapshot.locale : undefined\r\n if (id !== undefined) return id.toLowerCase().startsWith('zh') ? 'zh' : 'en'\r\n } catch {\r\n // fall through to the browser language\r\n }\r\n const browser = globalThis.navigator?.language\r\n if (typeof browser === 'string' && browser.toLowerCase().startsWith('zh')) return 'zh'\r\n return browser === undefined ? 'zh' : 'en'\r\n}\r\n\r\n/**\r\n * Look a service up WITHOUT declaring it in `inject`.\r\n *\r\n * `ctx.get(name)` is the framework's own optional lookup: it returns undefined\r\n * instead of throwing, and \u2014 unlike a declared service \u2014 it cannot leave the\r\n * fiber PENDING. That is what makes an optional integration safe here: this\r\n * release has no settings service at all, so the page simply shows its fields\r\n * and reports that saving is unavailable.\r\n */\r\nfunction optionalService(ctx: any, ...names: string[]): any {\r\n for (const name of names) {\r\n try {\r\n const found = typeof ctx?.get === 'function' ? ctx.get(name) : undefined\r\n if (found !== undefined && found !== null) return found\r\n } catch {\r\n // try the next spelling\r\n }\r\n }\r\n return undefined\r\n}\r\n\r\n/** The settings form for this plugin's namespace, when one exists. */\r\nfunction formOf(ctx: any): any {\r\n const forms = optionalService(ctx, 'configForms', 'settingsScope')\r\n if (forms === undefined) return undefined\r\n try {\r\n if (typeof forms.get === 'function') return forms.get(NAMESPACE)\r\n // A settingsScope-style service is already bound to one namespace.\r\n if (typeof forms.getSnapshot === 'function' || typeof forms.bind === 'function') return forms\r\n } catch {\r\n return undefined\r\n }\r\n return undefined\r\n}\r\n\r\nfunction readConfig(ctx: any): { value: any; revision: number } {\r\n const form = formOf(ctx)\r\n if (form === undefined) return { value: {}, revision: 0 }\r\n try {\r\n const snapshot = form.getSnapshot?.()\r\n return {\r\n value: snapshot?.value ?? snapshot?.user ?? {},\r\n revision: snapshot?.revision ?? 0,\r\n }\r\n } catch {\r\n return { value: {}, revision: 0 }\r\n }\r\n}\r\n\r\nasync function writeConfig(ctx: any, ops: readonly unknown[]): Promise<void> {\r\n const form = formOf(ctx)\r\n if (typeof form?.mutate !== 'function') {\r\n throw new Error('dsh-provider-proxy: settings transport unavailable')\r\n }\r\n await form.mutate(ops as any[], readConfig(ctx).revision)\r\n}\r\n\r\n/**\r\n * The provider rows, read from the Host.\r\n *\r\n * This release exposes no client-facing LLM service, so the page cannot ask for\r\n * the directory itself. The Host serves it at this same-origin endpoint, where\r\n * `ctx.llm.listProviders()` / `listConfigurableProviders()` actually live. The\r\n * list is therefore automatic \u2014 the user never types a route id.\r\n *\r\n * Only ACTIVE routes are shown. A provider this deployment merely *offers* \u2014\r\n * declared but not registered, so nothing would ever be sent through it \u2014 is\r\n * not the user's business on this page, and listing it only invites them to\r\n * configure a proxy for a route that cannot be selected. A provider that is\r\n * already configured is kept regardless, so a saved setting never silently\r\n * disappears from view.\r\n */\r\nfunction knownProviders(configured: Record<string, RouteValue>, published: ProviderRow[]): ProviderRow[] {\r\n const rows = new Map<string, ProviderRow>()\r\n for (const row of published) {\r\n if (row.live) rows.set(row.id, row)\r\n }\r\n for (const [id, route] of Object.entries(configured)) {\r\n if (rows.has(id)) continue\r\n rows.set(id, { id, name: id, live: route?.enabled === true })\r\n }\r\n return [...rows.values()].sort(byName)\r\n}\r\n\r\n/**\r\n * Where the Host publishes the live provider catalogue.\r\n */\r\nconst CATALOG_PATH = '/dsh-provider-proxy/providers'\r\n\r\n/** Where the Host runs a per-provider connection self-check. */\r\nconst TEST_PATH = '/dsh-provider-proxy/test'\r\n\r\n/**\r\n * Latency bands for the self-check result, in milliseconds.\r\n *\r\n * The colour is decoration, never information: the numeric value is always\r\n * printed, so an unknown theme token (which resolves to `unset`) costs colour,\r\n * never the reading. The `var(..., fallback)` form keeps the colours visible even\r\n * if the theme renames the token.\r\n */\r\nconst LATENCY_FAST_MS = 500\r\nconst LATENCY_SLOW_MS = 1500\r\n\r\nfunction latencyColor(ms: unknown): string {\r\n if (typeof ms !== 'number' || !Number.isFinite(ms)) return 'var(--dsw-alias-label-secondary)'\r\n if (ms <= LATENCY_FAST_MS) return 'var(--dsw-alias-state-success-primary, #2ea043)'\r\n if (ms <= LATENCY_SLOW_MS) return 'var(--dsw-alias-state-warn-primary, #d29922)'\r\n return 'var(--dsw-alias-state-error-primary, #f85149)'\r\n}\r\n\r\n/** Normalize the Host's self-check payload into the shape the card renders. */\r\nfunction testResultFrom(body: any, strings: Record<string, string>): Record<string, unknown> {\r\n const ok = body?.ok === true\r\n return {\r\n pending: false,\r\n ok,\r\n ms: typeof body?.ms === 'number' && Number.isFinite(body.ms) ? body.ms : undefined,\r\n ip: typeof body?.exitIp === 'string' && body.exitIp.length > 0 ? body.exitIp : undefined,\r\n error: ok\r\n ? undefined\r\n : typeof body?.error === 'string' && body.error.length > 0\r\n ? body.error\r\n : strings.testFailed,\r\n }\r\n}\r\n\r\n/**\r\n * The setter the lazy catalogue initializer resolves through.\r\n *\r\n * It is republished after every render, so the newest one always wins, and a\r\n * promise that settles after an unmount writes to a harmless no-op.\r\n */\r\nlet catalogueSetter: ((catalog: Catalog) => void) | undefined = () => {}\r\n\r\n/** What the Host endpoint publishes: the provider rows plus per-provider hit counts. */\r\ntype Catalog = { rows: ProviderRow[]; hits: Record<string, number> }\r\n\r\n/** Read the Host's provider catalogue. Same-origin, so no token is needed. */\r\nasync function fetchCatalog(): Promise<Catalog> {\r\n const response = await globalThis.fetch(CATALOG_PATH, { headers: { accept: 'application/json' } })\r\n if (!response.ok) throw new Error(`Host answered ${response.status}`)\r\n const body = await response.json()\r\n const list = Array.isArray(body?.providers) ? body.providers : []\r\n const rows = list\r\n .filter((row: any) => typeof row?.id === 'string' && row.id.length > 0)\r\n .map((row: any) => ({\r\n id: row.id,\r\n name: typeof row.name === 'string' && row.name.length > 0 ? row.name : row.id,\r\n live: row.live === true,\r\n }))\r\n // The Host counts requests it routed through each provider's proxy. Anything\r\n // malformed is dropped rather than rendered, so a bad payload cannot put a\r\n // non-numeric string on the page.\r\n const hits: Record<string, number> = {}\r\n const published = body?.hits\r\n if (published !== null && typeof published === 'object') {\r\n for (const [id, count] of Object.entries(published)) {\r\n if (typeof count === 'number' && Number.isFinite(count)) hits[id] = count\r\n }\r\n }\r\n return { rows, hits }\r\n}\r\n\r\nconst byName = (a: ProviderRow, b: ProviderRow): number => a.name.localeCompare(b.name)\r\n\r\nfunction view(route: Partial<RouteValue> | undefined): RouteValue {\r\n return {\r\n enabled: route?.enabled === true,\r\n protocol: PROTOCOLS.includes(route?.protocol as Protocol) ? (route!.protocol as Protocol) : 'http',\r\n host: route?.host ?? '',\r\n port: route?.port ?? 0,\r\n username: route?.username ?? '',\r\n password: route?.password ?? '',\r\n onlyHosts: route?.onlyHosts ?? '',\r\n bypassHosts: route?.bypassHosts ?? '',\r\n }\r\n}\r\n\r\n/** The provider directory, cached module-side. See renderPage. */\r\nlet directoryCache: ProviderRow[] | undefined\r\n\r\n/**\r\n * Everything the page learned about its own wiring, rendered verbatim.\r\n *\r\n * The browser side of a plugin has no other diagnostic channel \u2014 the Host log\r\n * never sees it \u2014 so a silent failure had to be diagnosed by inference. This\r\n * panel is what proved that `remote.settings` and `remote.llm` do not exist in\r\n * this release, and that the catalogue had to come from the Host endpoint.\r\n *\r\n * Cleared at the start of every render so the panel shows the CURRENT state\r\n * rather than an ever-growing log of the session.\r\n */\r\nlet diagnostics: string[] = []\r\n\r\nfunction note(message: string): void {\r\n if (!diagnostics.includes(message)) diagnostics.push(message)\r\n}\r\n\r\n/**\r\n * Layout constants, applied as INLINE styles.\r\n *\r\n * The page is rendered into the settings panel, and the CSS-Modules pipeline\r\n * that feeds the stylesheet has broken twice in ways that were invisible from\r\n * the source: the class map failed to bind at all, and a shared class prefix\r\n * silently merged two rules. Both left the page readable but laid out as one\r\n * unstyled block.\r\n *\r\n * Structure is therefore expressed as inline styles, which cannot be lost by\r\n * the bundle, and the stylesheet is kept for the purely decorative parts. A\r\n * theme token that is not defined simply resolves to `unset`, so an unknown\r\n * token costs colour, never layout.\r\n */\r\nconst S = {\r\n root: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: '12px',\r\n maxWidth: '720px',\r\n },\r\n card: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: '12px',\r\n padding: '14px 16px',\r\n marginBottom: '12px',\r\n border: '1px solid var(--dsw-alias-border-l1)',\r\n borderRadius: '10px',\r\n background: 'var(--dsw-alias-bg-layer-1)',\r\n },\r\n cardActive: {\r\n borderColor: 'var(--dsw-alias-state-success-primary)',\r\n background: 'var(--dsw-alias-bg-layer-2)',\r\n },\r\n head: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'space-between',\r\n gap: '12px',\r\n },\r\n titles: { display: 'flex', alignItems: 'baseline', gap: '8px', minWidth: '0' },\r\n name: {\r\n fontSize: '14px',\r\n fontWeight: '600',\r\n color: 'var(--dsw-alias-label-primary)',\r\n overflow: 'hidden',\r\n textOverflow: 'ellipsis',\r\n whiteSpace: 'nowrap',\r\n },\r\n id: {\r\n flex: 'none',\r\n padding: '1px 6px',\r\n borderRadius: '4px',\r\n background: 'var(--dsw-alias-bg-layer-2)',\r\n fontFamily: 'ui-monospace, monospace',\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n },\r\n hits: {\r\n flex: 'none',\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n whiteSpace: 'nowrap',\r\n },\r\n testRow: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '10px',\r\n flexWrap: 'wrap',\r\n },\r\n testButton: {\r\n padding: '5px 12px',\r\n border: '1px solid var(--dsw-alias-border-l1)',\r\n borderRadius: '6px',\r\n background: 'var(--dsw-alias-bg-layer-1)',\r\n color: 'var(--dsw-alias-label-primary)',\r\n font: 'inherit',\r\n fontSize: '12px',\r\n cursor: 'pointer',\r\n },\r\n testResult: {\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n wordBreak: 'break-all',\r\n },\r\n advanced: {\r\n marginTop: '4px',\r\n fontSize: '12px',\r\n },\r\n advancedSummary: {\r\n cursor: 'pointer',\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n },\r\n pill: {\r\n flex: 'none',\r\n padding: '2px 10px',\r\n borderRadius: '999px',\r\n fontSize: '11px',\r\n fontWeight: '500',\r\n whiteSpace: 'nowrap',\r\n },\r\n pillOn: {\r\n background: 'var(--dsw-alias-state-success-primary)',\r\n color: 'var(--dsw-alias-bg-base)',\r\n },\r\n pillLive: {\r\n border: '1px solid var(--dsw-alias-border-l2)',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n },\r\n pillOff: { color: 'var(--dsw-alias-state-idle-primary)' },\r\n toggle: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '8px',\r\n fontSize: '12px',\r\n color: 'var(--dsw-alias-label-primary)',\r\n },\r\n field: {\r\n display: 'grid',\r\n gridTemplateColumns: '88px 1fr',\r\n alignItems: 'center',\r\n gap: '10px',\r\n fontSize: '12px',\r\n },\r\n label: { color: 'var(--dsw-alias-label-secondary)' },\r\n input: {\r\n boxSizing: 'border-box',\r\n width: '100%',\r\n minWidth: '0',\r\n padding: '6px 8px',\r\n border: '1px solid var(--dsw-alias-border-l1)',\r\n borderRadius: '6px',\r\n outline: 'none',\r\n background: 'var(--dsw-alias-bg-layer-1)',\r\n color: 'var(--dsw-alias-label-primary)',\r\n font: 'inherit',\r\n fontSize: '12px',\r\n },\r\n} as const\r\n\r\nfunction renderPage(ctx: any): unknown {\r\n const React = react()\r\n if (React === undefined || typeof React.createElement !== 'function') return null\r\n\r\n const h = React.createElement\r\n const t = stringsFor(ctx)\r\n diagnostics = []\r\n\r\n // `useState` is only reached after the React check, so the early return above\r\n // cannot desync the hooks order.\r\n let snapshot: { value: any; revision: number }\r\n try {\r\n snapshot = readConfig(ctx)\r\n } catch {\r\n snapshot = { value: {}, revision: 0 }\r\n }\r\n const configured = (snapshot.value?.providers ?? {}) as Record<string, RouteValue>\r\n note(\r\n formOf(ctx) === undefined\r\n ? '\u8BBE\u7F6E\uFF1A\u672A\u627E\u5230 configForms \u670D\u52A1\uFF0C\u53EA\u80FD\u663E\u793A\u3001\u65E0\u6CD5\u4FDD\u5B58'\r\n : `\u8BBE\u7F6E\uFF1A\u6B63\u5E38\uFF08\u4FEE\u8BA2\u53F7 ${snapshot.revision}\uFF0C${Object.keys(configured).length} \u4E2A provider\uFF09`,\r\n )\r\n\r\n // The provider catalogue comes from the Host over a same-origin endpoint, so\r\n // it arrives asynchronously. The initial state is a LAZY initializer, so the\r\n // fetch starts from `useState(() => \u2026)` instead of by calling a setter during\r\n // render: a render must have no side effects, and doing so also shifted the\r\n // hook order between passes.\r\n const [state, setState] = (React.useState ?? ((fn: any) => [fn(), () => {}]))(() => {\r\n void fetchCatalog()\r\n .then(catalog => catalogueSetter?.(catalog))\r\n .catch((error: any) => {\r\n note(`provider \u5217\u8868\u83B7\u53D6\u5931\u8D25\uFF1A${error?.message ?? error}`)\r\n catalogueSetter?.({ rows: [], hits: {} })\r\n })\r\n return { rows: undefined as ProviderRow[] | undefined, hits: {} as Record<string, number>, pending: true }\r\n })\r\n // The setter is published right after the hook so the initializer's promise\r\n // can reach it. It is re-published on every render, so the latest wins.\r\n catalogueSetter = catalog => setState({ rows: catalog.rows, hits: catalog.hits, pending: false })\r\n\r\n const published = state.rows ?? []\r\n const hits = state.hits ?? {}\r\n note(\r\n `provider \u5217\u8868\uFF1A\u6765\u81EA Host \u5171 ${published.length} \u4E2A\uFF08${published.map((r: ProviderRow) => r.id).join('\u3001') || '\u65E0'}\uFF09`,\r\n )\r\n // Local draft, layered over the stored config.\r\n //\r\n // Without it a checkbox does not change until the panel remounts: the value\r\n // is read from the settings store, which only updates when the page is\r\n // rebuilt. The draft makes the control respond immediately, then reconciles\r\n // with the store so a refused write is visible rather than silently lost.\r\n const [draft, setDraft] = (React.useState ?? ((v: any) => [v, () => {}]))({})\r\n const edit = (id: string, field: string, value: unknown) =>\r\n setDraft((current: any) => ({ ...current, [id]: { ...current[id], [field]: value } }))\r\n\r\n // Self-check outcomes keyed by provider id: `{ pending: true }` while the Host\r\n // is testing, then the normalized result the card renders.\r\n const [tests, setTests] = (React.useState ?? ((v: any) => [v, () => {}]))({})\r\n\r\n /**\r\n * Run the Host's self-check for one provider.\r\n *\r\n * A SUCCESSFUL check also refreshes the catalogue: the request the check just\r\n * proved also bumped that provider's hit counter, and the count is otherwise\r\n * only read once, at mount.\r\n */\r\n const runTest = (id: string): void => {\r\n setTests((current: any) => ({ ...current, [id]: { pending: true } }))\r\n void (async () => {\r\n try {\r\n const response = await globalThis.fetch(TEST_PATH, {\r\n method: 'POST',\r\n headers: { 'content-type': 'application/json', accept: 'application/json' },\r\n body: JSON.stringify({ provider: id }),\r\n })\r\n const body = await response.json()\r\n setTests((current: any) => ({ ...current, [id]: testResultFrom(body, t) }))\r\n if (body?.ok === true) {\r\n void fetchCatalog()\r\n .then(catalog => catalogueSetter?.(catalog))\r\n .catch(() => {})\r\n }\r\n } catch (error: any) {\r\n setTests((current: any) => ({\r\n ...current,\r\n [id]: { pending: false, ok: false, error: String(error?.message ?? error) },\r\n }))\r\n }\r\n })()\r\n }\r\n\r\n const rows = knownProviders({ ...configured, ...draft }, published)\r\n\r\n /**\r\n * Persist one field. The control is already showing the new value, so this\r\n * only has to succeed quietly; a refusal is reported in the diagnostics.\r\n */\r\n const save = (id: string, field: string, value: unknown) => {\r\n void writeConfig(ctx, [{ op: 'set', path: ['providers', id, field], value }])\r\n .then(() => {\r\n note(`\u5DF2\u4FDD\u5B58 ${id}.${field} = ${JSON.stringify(value)}`)\r\n })\r\n .catch((error: any) => {\r\n note(`\u4FDD\u5B58\u5931\u8D25 ${id}.${field}\uFF1A${error?.message ?? error}`)\r\n // Drop the optimistic value so the stored state shows through again.\r\n setDraft((current: any) => {\r\n const next = { ...current }\r\n delete next[id]\r\n return next\r\n })\r\n })\r\n }\r\n\r\n /** One control: update the draft instantly, persist in the background. */\r\n const bind = (id: string, field: string) => (value: unknown) => {\r\n edit(id, field, value)\r\n save(id, field, value)\r\n }\r\n\r\n const field = (label: string, control: unknown, hint?: string): unknown =>\r\n h(\r\n 'label',\r\n { className: styles.field, style: S.field, key: label },\r\n h('span', { className: styles.label, style: S.label }, label),\r\n control,\r\n hint === undefined\r\n ? null\r\n : h(\r\n 'span',\r\n { className: styles.hint, style: { gridColumn: '2', fontSize: '11px' } },\r\n hint,\r\n ),\r\n )\r\n\r\n // ALWAYS an array: a single element is not iterable, and spreading one threw\r\n // \"Spread syntax requires ...iterable[Symbol.iterator]\" on an empty list.\r\n const body: unknown[] = rows.length === 0\r\n ? [\r\n h(\r\n 'p',\r\n {\r\n className: styles.empty,\r\n key: 'empty',\r\n style: {\r\n margin: '0',\r\n padding: '16px',\r\n border: '1px dashed var(--dsw-alias-border-l1)',\r\n borderRadius: '8px',\r\n fontSize: '12px',\r\n textAlign: 'center',\r\n color: 'var(--dsw-alias-state-idle-primary)',\r\n },\r\n },\r\n t.empty,\r\n ),\r\n ]\r\n : rows.map(row => {\r\n // The MERGED value, so a just-typed value shows immediately.\r\n const route = view({ ...configured[row.id], ...draft[row.id] })\r\n const disabled = !route.enabled\r\n const result = tests[row.id]\r\n return h(\r\n 'section',\r\n {\r\n className: route.enabled ? styles.cardActive : styles.card,\r\n style: route.enabled ? { ...S.card, ...S.cardActive } : S.card,\r\n key: row.id,\r\n },\r\n h(\r\n 'header',\r\n { className: styles.cardHead, style: S.head },\r\n h(\r\n 'div',\r\n { className: styles.cardTitles, style: S.titles },\r\n h('span', { className: styles.name, style: S.name }, row.name),\r\n h('span', { className: styles.id, style: S.id }, row.id),\r\n // A disabled route can never have hits, so \"0\" there would only add\r\n // noise; the count shows once the route is on (or has counted).\r\n route.enabled || (hits[row.id] ?? 0) > 0\r\n ? h(\r\n 'span',\r\n { className: styles.hits, style: S.hits },\r\n `${t.hitCountPrefix}${hits[row.id] ?? 0}${t.hitCountSuffix}`,\r\n )\r\n : null,\r\n ),\r\n h(\r\n 'span',\r\n {\r\n className: route.enabled ? styles.pillOn : row.live ? styles.pillLive : styles.pillOff,\r\n style: {\r\n ...S.pill,\r\n ...(route.enabled ? S.pillOn : row.live ? S.pillLive : S.pillOff),\r\n },\r\n },\r\n route.enabled ? t.on : row.live ? t.live : t.off,\r\n ),\r\n ),\r\n h(\r\n 'label',\r\n { className: styles.toggle, style: S.toggle },\r\n h('input', {\r\n type: 'checkbox',\r\n checked: route.enabled,\r\n onChange: (event: any) => bind(row.id, 'enabled')(event.target.checked === true),\r\n }),\r\n h('span', null, t.useProxy),\r\n ),\r\n field(\r\n t.protocol,\r\n h(\r\n 'select',\r\n {\r\n className: styles.input,\r\n style: S.input,\r\n disabled,\r\n value: route.protocol,\r\n onChange: (event: any) => bind(row.id, 'protocol')(event.target.value),\r\n },\r\n ...PROTOCOLS.map(protocol =>\r\n h('option', { key: protocol, value: protocol }, protocol.toUpperCase()),\r\n ),\r\n ),\r\n route.protocol === 'socks5' ? t.socks5Hint : undefined,\r\n ),\r\n field(\r\n t.host,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n disabled,\r\n placeholder: '127.0.0.1',\r\n value: route.host,\r\n onChange: (event: any) => bind(row.id, 'host')(event.target.value),\r\n }),\r\n t.hostHint,\r\n ),\r\n field(\r\n t.port,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n disabled,\r\n type: 'number',\r\n min: 1,\r\n max: 65535,\r\n placeholder: '7890',\r\n value: route.port === 0 ? '' : String(route.port),\r\n onChange: (event: any) => {\r\n const parsed = Number.parseInt(event.target.value, 10)\r\n bind(row.id, 'port')(Number.isNaN(parsed) ? 0 : parsed)\r\n },\r\n }),\r\n ),\r\n field(\r\n t.username,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n disabled,\r\n autocomplete: 'off',\r\n value: route.username,\r\n onChange: (event: any) => bind(row.id, 'username')(event.target.value),\r\n }),\r\n ),\r\n // Every transport accepts a password now: SOCKS5 hands it to\r\n // Socks5ProxyAgent as an option, HTTP/HTTPS embed it in the proxy URL\r\n // userinfo (undici turns that into Proxy-Authorization). It is stored on\r\n // the route, so it lands in the settings file with the rest of the\r\n // config; the diagnostics only ever surface a credential-free origin.\r\n field(\r\n t.password,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n disabled,\r\n type: 'password',\r\n autocomplete: 'off',\r\n value: route.password,\r\n onChange: (event: any) => bind(row.id, 'password')(event.target.value),\r\n }),\r\n route.protocol === 'socks5' ? t.passwordHint : t.passwordHintProxy,\r\n ),\r\n // The self-check only makes sense for a route that is ON; a disabled\r\n // route is not in the Host's table, so there is nothing to test.\r\n route.enabled\r\n ? h(\r\n 'div',\r\n { className: styles.testRow, style: S.testRow, key: `${row.id}:test` },\r\n h(\r\n 'button',\r\n {\r\n className: styles.testButton,\r\n style: S.testButton,\r\n type: 'button',\r\n disabled: result?.pending === true,\r\n onClick: () => runTest(row.id),\r\n },\r\n result?.pending === true ? t.testRunning : t.testButton,\r\n ),\r\n result?.pending === false\r\n ? h(\r\n 'span',\r\n { className: styles.testResult, style: S.testResult },\r\n result.ok === true\r\n ? [\r\n // Only the latency carries the band colour; the exit IP\r\n // stays in the secondary label colour.\r\n h(\r\n 'span',\r\n { key: 'lat', style: { color: latencyColor(result.ms) } },\r\n `\u2713 ${typeof result.ms === 'number' ? result.ms : '\u2014'} ms`,\r\n ),\r\n result.ip === undefined ? null : ` \u00B7 ${t.exitIpLabel}${result.ip}`,\r\n ]\r\n : `\u2717 ${result.error}`,\r\n )\r\n : null,\r\n )\r\n : null,\r\n // Target-host rules, collapsed so the common case stays one short card.\r\n h(\r\n 'details',\r\n { className: styles.advanced, style: S.advanced, key: `${row.id}:rules` },\r\n h('summary', { className: styles.advancedSummary, style: S.advancedSummary }, t.advanced),\r\n field(\r\n t.onlyHosts,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n disabled,\r\n placeholder: 'api.example.com',\r\n value: route.onlyHosts,\r\n onChange: (event: any) => bind(row.id, 'onlyHosts')(event.target.value),\r\n }),\r\n t.onlyHostsHint,\r\n ),\r\n field(\r\n t.bypassHosts,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n disabled,\r\n placeholder: 'localhost',\r\n value: route.bypassHosts,\r\n onChange: (event: any) => bind(row.id, 'bypassHosts')(event.target.value),\r\n }),\r\n t.bypassHostsHint,\r\n ),\r\n ),\r\n )\r\n })\r\n\r\n return h(\r\n 'div',\r\n { className: styles.root, style: S.root },\r\n h('p', { className: styles.lead, style: { margin: '0 0 4px', fontSize: '12px', lineHeight: '1.6', color: 'var(--dsw-alias-label-secondary)' } }, t.lead),\r\n ...body,\r\n h(\r\n 'details',\r\n {\r\n className: styles.diag,\r\n key: 'diag',\r\n style: {\r\n marginTop: '4px',\r\n padding: '8px 10px',\r\n border: '1px solid var(--dsw-alias-border-l1)',\r\n borderRadius: '8px',\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n },\r\n },\r\n h('summary', { className: styles.diagSummary }, t.diagnostics),\r\n h(\r\n 'ul',\r\n { className: styles.diagList, style: { margin: '6px 0 0', paddingLeft: '18px' } },\r\n ...(diagnostics.length === 0\r\n ? [h('li', { key: 'none' }, t.diagPending)]\r\n : diagnostics.map((line, index) => h('li', { key: `d${index}` }, line))),\r\n ),\r\n ),\r\n )\r\n}\r\n\r\nconst EN = {\r\n lead: 'Route selected model providers through your own forward proxy. Other providers stay direct.',\r\n empty: 'No providers found yet.',\r\n useProxy: 'Use a proxy for this provider',\r\n protocol: 'Type',\r\n host: 'IP / host',\r\n port: 'Port',\r\n username: 'Username',\r\n password: 'Password',\r\n hostHint: 'Host or IP only, without scheme or path.',\r\n passwordHint: 'Sent to the SOCKS5 proxy for authentication; stored with this setting.',\r\n passwordHintProxy: 'Sent to the proxy as an authentication password; stored with this setting.',\r\n hitCountPrefix: '',\r\n hitCountSuffix: ' proxied',\r\n testButton: 'Test',\r\n testRunning: 'Testing\u2026',\r\n testFailed: 'Test failed',\r\n exitIpLabel: 'exit IP ',\r\n advanced: 'Advanced: target host rules',\r\n onlyHosts: 'Proxy only',\r\n onlyHostsHint: 'Comma/space separated; when set, only requests to these hosts are proxied (suffix match, * for all).',\r\n bypassHosts: 'Bypass',\r\n bypassHostsHint: 'Comma/space separated; requests to these hosts go direct, taking priority.',\r\n socks5Hint: 'SOCKS5 tunnels the connection; the proxy resolves the target host name.',\r\n on: 'proxied',\r\n live: 'active',\r\n off: 'direct',\r\n diagnostics: 'Connection diagnostics',\r\n diagPending: '(collecting\u2026)',\r\n}\r\n\r\nconst ZH = {\r\n lead: '\u8BA9\u6307\u5B9A\u7684 provider \u8D70\u4F60\u81EA\u5DF1\u7684\u6B63\u5411\u4EE3\u7406\uFF0C\u5176\u5B83 provider \u4FDD\u6301\u76F4\u8FDE\u3002',\r\n empty: '\u6CA1\u6709\u68C0\u6D4B\u5230\u4EFB\u4F55 provider\u3002',\r\n useProxy: '\u4E3A\u8BE5 provider \u542F\u7528\u4EE3\u7406',\r\n protocol: '\u7C7B\u578B',\r\n host: 'IP / \u4E3B\u673A',\r\n port: '\u7AEF\u53E3',\r\n username: '\u7528\u6237\u540D',\r\n password: '\u5BC6\u7801',\r\n hostHint: '\u53EA\u586B\u4E3B\u673A\u540D\u6216 IP\uFF0C\u4E0D\u8981\u5E26\u534F\u8BAE\u524D\u7F00\u6216\u8DEF\u5F84\u3002',\r\n passwordHint: '\u4EC5\u4F5C\u4E3A SOCKS5 \u8BA4\u8BC1\u53E3\u4EE4\u53D1\u9001\u7ED9\u4EE3\u7406\uFF1B\u968F\u8BE5\u8BBE\u7F6E\u4E00\u8D77\u4FDD\u5B58\u3002',\r\n passwordHintProxy: '\u4F5C\u4E3A\u4EE3\u7406\u8BA4\u8BC1\u53E3\u4EE4\u53D1\u9001\u7ED9\u4EE3\u7406\uFF1B\u968F\u8BE5\u8BBE\u7F6E\u4E00\u8D77\u4FDD\u5B58\u3002',\r\n hitCountPrefix: '\u5DF2\u4EE3\u7406 ',\r\n hitCountSuffix: ' \u6B21',\r\n testButton: '\u6D4B\u8BD5',\r\n testRunning: '\u6D4B\u8BD5\u4E2D\u2026',\r\n testFailed: '\u6D4B\u8BD5\u5931\u8D25',\r\n exitIpLabel: '\u51FA\u53E3 IP ',\r\n advanced: '\u9AD8\u7EA7\uFF1A\u76EE\u6807\u57DF\u540D\u89C4\u5219',\r\n onlyHosts: '\u4EC5\u8D70\u4EE3\u7406',\r\n onlyHostsHint: '\u9017\u53F7\u6216\u7A7A\u683C\u5206\u9694\uFF1B\u975E\u7A7A\u65F6\u53EA\u6709\u5339\u914D\u8FD9\u4E9B\u4E3B\u673A\u7684\u8BF7\u6C42\u8D70\u4EE3\u7406\uFF08\u540E\u7F00\u5339\u914D\uFF0C* \u8868\u793A\u5168\u90E8\uFF09\u3002',\r\n bypassHosts: '\u76F4\u8FDE',\r\n bypassHostsHint: '\u9017\u53F7\u6216\u7A7A\u683C\u5206\u9694\uFF1B\u5339\u914D\u8FD9\u4E9B\u4E3B\u673A\u7684\u8BF7\u6C42\u76F4\u8FDE\uFF0C\u4F18\u5148\u4E8E\u4E0A\u4E00\u9879\u3002',\r\n socks5Hint: 'SOCKS5 \u4F1A\u5EFA\u7ACB\u96A7\u9053\uFF0C\u76EE\u6807\u57DF\u540D\u7531\u4EE3\u7406\u7AEF\u89E3\u6790\u3002',\r\n on: '\u8D70\u4EE3\u7406',\r\n live: '\u542F\u7528\u4E2D',\r\n off: '\u76F4\u8FDE',\r\n diagnostics: '\u8FDE\u63A5\u8BCA\u65AD',\r\n diagPending: '\uFF08\u6B63\u5728\u6536\u96C6\u2026\uFF09',\r\n}\r\n\r\n/**\r\n * Pick the dictionary for this render.\r\n *\r\n * The shell's own locale dictionary wins when it carries a translated entry, so\r\n * the page follows the application language instead of second-guessing it.\r\n * Chinese is the fallback because that is the operator's language.\r\n */\r\nfunction stringsFor(ctx: any): Record<string, string> {\r\n const language = localeOf(ctx)\r\n const bundled = language === 'zh' ? ZH : EN\r\n const translated = ((): Record<string, string> | undefined => {\r\n try {\r\n const service = optionalService(ctx, 'locale')\r\n const bound = service?.bind?.('dshProviderProxy')\r\n const value = typeof bound === 'function' ? bound('title') : undefined\r\n if (typeof value === 'string' && value.length > 0) return { title: value } as never\r\n } catch {\r\n // no locale dictionary available\r\n }\r\n return undefined\r\n })()\r\n return { ...bundled, ...(translated ?? {}) }\r\n}\r\n\r\n/**\r\n * The client module system's resolver.\r\n *\r\n * The loader calls `factory(require)` and that parameter shadows Node's\r\n * `require` inside the emitted CJS, so this describes the module-table\r\n * resolver, not Node's.\r\n */\r\ndeclare function require(specifier: string): unknown\r\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["\nvar __dshMap = {\"root\":\"6d45ff27_root\",\"lead\":\"57c30143_lead\",\"empty\":\"b6600f2d_empty\",\"card\":\"0ba90fef_card\",\"cardActive\":\"923630a9_cardActive\",\"cardHead\":\"5af7e7c3_cardHead\",\"cardTitles\":\"8448919c_cardTitles\",\"name\":\"0b023e00_name\",\"id\":\"ffa6a1c5_id\",\"pillOn\":\"85972c09_pillOn\",\"pillLive\":\"d3644cdc_pillLive\",\"pillOff\":\"592bd7b2_pillOff\",\"toggle\":\"9efc135e_toggle\",\"field\":\"93a03683_field\",\"label\":\"0bd1d3ec_label\",\"hint\":\"52d56786_hint\",\"input\":\"f6748c5e_input\",\"testButton\":\"eb3b08bd_testButton\",\"diag\":\"4d4b11ef_diag\",\"diagSummary\":\"2e565ce0_diagSummary\",\"diagList\":\"fb9c7553_diagList\"};\nvar __dshStyles = (globalThis.__dshPluginStyles || (globalThis.__dshPluginStyles = new Set()));\nif (!__dshStyles.has(\"dsh-provider-proxy/client.css\")) {\n __dshStyles.add(\"dsh-provider-proxy/client.css\");\n var __dshStyle = document.createElement('style');\n __dshStyle.setAttribute('data-plugin-css', \"dsh-provider-proxy/client.css\");\n __dshStyle.textContent = \"/* dsh-provider-proxy \u2014 provider proxy settings page.\\n Tokens only: no literal colours, matching the shared --dsw-* system. */\\n\\n.6d45ff27_root {\\n display: flex;\\n flex-direction: column;\\n gap: 12px;\\n max-width: 640px;\\n}\\n\\n.57c30143_lead {\\n margin: 0 0 4px;\\n font-size: 12px;\\n line-height: 1.6;\\n color: var(--dsw-alias-label-secondary);\\n}\\n\\n.b6600f2d_empty {\\n margin: 0;\\n padding: 16px;\\n border: 1px dashed var(--dsw-alias-border-l1);\\n border-radius: 8px;\\n font-size: 12px;\\n text-align: center;\\n color: var(--dsw-alias-state-idle-primary);\\n}\\n\\n/* ---- provider card ---- */\\n\\n.0ba90fef_card,\\n.923630a9_cardActive {\\n display: flex;\\n flex-direction: column;\\n gap: 10px;\\n padding: 12px 14px;\\n border: 1px solid var(--dsw-alias-border-l1);\\n border-radius: 10px;\\n background: var(--dsw-alias-bg-layer-1);\\n}\\n\\n.923630a9_cardActive {\\n border-color: var(--dsw-alias-state-success-primary);\\n background: var(--dsw-alias-bg-layer-2);\\n}\\n\\n.5af7e7c3_cardHead {\\n display: flex;\\n align-items: center;\\n justify-content: space-between;\\n gap: 12px;\\n}\\n\\n.8448919c_cardTitles {\\n display: flex;\\n align-items: baseline;\\n gap: 8px;\\n min-width: 0;\\n}\\n\\n.0b023e00_name {\\n overflow: hidden;\\n font-size: 13px;\\n font-weight: 600;\\n white-space: nowrap;\\n text-overflow: ellipsis;\\n color: var(--dsw-alias-label-primary);\\n}\\n\\n.ffa6a1c5_id {\\n flex: none;\\n padding: 1px 6px;\\n border-radius: 4px;\\n background: var(--dsw-alias-bg-layer-2);\\n font-family: ui-monospace, monospace;\\n font-size: 11px;\\n color: var(--dsw-alias-label-secondary);\\n}\\n\\n/* ---- status pill ---- */\\n\\n.85972c09_pillOn,\\n.d3644cdc_pillLive,\\n.592bd7b2_pillOff {\\n flex: none;\\n padding: 2px 8px;\\n border-radius: 999px;\\n font-size: 11px;\\n font-weight: 500;\\n white-space: nowrap;\\n}\\n\\n.85972c09_pillOn {\\n background: var(--dsw-alias-state-success-primary);\\n color: var(--dsw-alias-bg-base);\\n}\\n\\n.d3644cdc_pillLive {\\n border: 1px solid var(--dsw-alias-border-l2);\\n color: var(--dsw-alias-label-secondary);\\n}\\n\\n.592bd7b2_pillOff {\\n color: var(--dsw-alias-state-idle-primary);\\n}\\n\\n/* ---- toggle ---- */\\n\\n.9efc135e_toggle {\\n display: flex;\\n align-items: center;\\n gap: 8px;\\n padding-top: 2px;\\n font-size: 12px;\\n color: var(--dsw-alias-label-primary);\\n cursor: pointer;\\n}\\n\\n.9efc135e_toggle input {\\n accent-color: var(--dsw-alias-brand-primary);\\n cursor: pointer;\\n}\\n\\n/* ---- fields ---- */\\n\\n.93a03683_field {\\n display: grid;\\n grid-template-columns: 96px 1fr;\\n align-items: center;\\n gap: 10px;\\n font-size: 12px;\\n}\\n\\n.0bd1d3ec_label {\\n color: var(--dsw-alias-label-secondary);\\n}\\n\\n.52d56786_hint {\\n grid-column: 2;\\n margin-top: -2px;\\n font-size: 11px;\\n color: var(--dsw-alias-state-warn-primary);\\n}\\n\\n.f6748c5e_input {\\n box-sizing: border-box;\\n width: 100%;\\n min-width: 0;\\n padding: 5px 8px;\\n border: 1px solid var(--dsw-alias-border-l1);\\n border-radius: 6px;\\n outline: none;\\n background: var(--dsw-alias-bg-layer-1);\\n color: var(--dsw-alias-label-primary);\\n font: inherit;\\n font-size: 12px;\\n transition: border-color 120ms ease, background 120ms ease;\\n}\\n\\n/* The base look of every input is INLINE too, so these three state rules only\\n ever take effect as author-important declarations \u2014 same reason as the\\n self-check button above. `cursor` has no inline base and needs none, and the\\n hover border uses `l3` because `l1`\u2192`l2` is a 4%\u219210% black step nobody can\\n see. */\\n\\n.f6748c5e_input:hover:not(:disabled) {\\n border-color: var(--dsw-alias-border-l3) !important;\\n}\\n\\n.f6748c5e_input:focus {\\n border-color: var(--dsw-alias-brand-primary) !important;\\n}\\n\\n.f6748c5e_input:disabled {\\n color: var(--dsw-alias-state-idle-primary) !important;\\n background: var(--dsw-alias-bg-layer-2) !important;\\n cursor: not-allowed;\\n}\\n\\n/* ---- self-check ---- */\\n\\n/* The hover state is the one thing an inline style cannot express, which is why\\n this element carries a class at all. Layout stays inline.\\n\\n Two traps, both hit before this comment existed:\\n - `!important` is load-bearing: the base border and background are INLINE, and\\n the cascade sorts a style attribute after every author rule, so a plain\\n declaration here would ship, match, and still lose.\\n - the TOKENS must be visible ones. `bg-layer-1/2/3` all resolve to\\n `neutral-bluish-00` in the light theme, so a layer swap is a no-op there, and\\n `border-l1`\u2192`l2` is 4%\u219210% black on a 1px line. The app's own hovers use\\n `interactive-bg-hover`; using it here is what makes the feedback exist. */\\n.eb3b08bd_testButton {\\n transition: border-color 120ms ease, background 120ms ease;\\n}\\n\\n.eb3b08bd_testButton:hover:not(:disabled) {\\n border-color: var(--dsw-alias-border-l3) !important;\\n background: var(--dsw-alias-interactive-bg-hover) !important;\\n}\\n\\n/* ---- diagnostics ---- */\\n\\n.4d4b11ef_diag {\\n margin-top: 2px;\\n padding: 8px 10px;\\n border: 1px solid var(--dsw-alias-border-l1);\\n border-radius: 8px;\\n font-size: 11px;\\n color: var(--dsw-alias-label-secondary);\\n}\\n\\n.2e565ce0_diagSummary {\\n cursor: pointer;\\n color: var(--dsw-alias-state-warn-primary);\\n}\\n\\n.fb9c7553_diagList {\\n margin: 6px 0 0;\\n padding-left: 18px;\\n font-family: ui-monospace, monospace;\\n word-break: break-all;\\n}\\n\";\n document.head.appendChild(__dshStyle);\n}\nmodule.exports = __dshMap;\nmodule.exports.default = __dshMap;\nmodule.exports.__esModule = true;\n", "/**\r\n * dsh-provider-proxy \u2014 browser half.\r\n *\r\n * Contributes ONE settings page (a `settings.section` list entry) that lists\r\n * every known provider with its proxy switch, type, host, port and username.\r\n *\r\n * This replaces an earlier attempt to render into each provider card on the\r\n * Models page (`settings.models.provider-card`). That seat is keyed and\r\n * dispatched per provider namespace, and a third-party registration never\r\n * matched it on this build: no error, no request, simply no output. A\r\n * `settings.section` entry is a plain list contribution with an `id`, which is\r\n * the shape the shipped `dsh-llm-retry-settings` plugin uses successfully in\r\n * this same desktop profile.\r\n *\r\n * The whole bundle runs inside the client module system's lazy-CJS factory:\r\n * executing the script only REGISTERS the factory, and every side effect\r\n * (including the CSS injection) happens at materialization.\r\n */\r\n\r\n// The CSS-Modules build turns this sheet into a hashed class map AND injects it\r\n// at materialization. The binding is what the component reads; importing it for\r\n// side effects only would leave `styles` undefined at render time.\r\nimport styles from './client.css'\r\n\r\ntype Protocol = 'http' | 'https' | 'socks5'\r\n\r\ntype RouteValue = {\r\n enabled: boolean\r\n protocol: Protocol\r\n host: string\r\n port: number\r\n username: string\r\n password: string\r\n onlyHosts: string\r\n bypassHosts: string\r\n}\r\n\r\n/** The provider rows we know about, and which of them are actually live. */\r\ntype ProviderRow = { id: string; name: string; live: boolean }\r\n\r\n/**\r\n * React, resolved from the client module table.\r\n *\r\n * React is NOT a Cordis service and is not reachable from `ctx` \u2014 reading it\r\n * there produced a silently null component. The module table is the only route:\r\n * the build leaves `react` external, so this compiles to a `require(\"react\")`\r\n * inside the factory closure, answered from the shell-seeded baseline.\r\n *\r\n * Resolved lazily on first render so merely REGISTERING the bundle \u2014 which is\r\n * all a script evaluation does \u2014 never materializes React.\r\n */\r\nlet ReactCache: unknown\r\n\r\nfunction react(): any {\r\n if (ReactCache === undefined) {\r\n ReactCache = ((): unknown => {\r\n try {\r\n return require('react')\r\n } catch {\r\n return (globalThis as Record<string, unknown>).React\r\n }\r\n })()\r\n }\r\n return ReactCache\r\n}\r\n\r\nconst PROTOCOLS: Protocol[] = ['http', 'https', 'socks5']\r\n\r\n/** Our own settings namespace; the profile entry id created by the bundle patch. */\r\nconst NAMESPACE = 'provider-proxy'\r\n\r\n/**\r\n * Cordis services this half needs.\r\n *\r\n * ONLY `slots` is declared. That is the complete set this release actually\r\n * offers on a client fiber: `layout, locale, sessions, slots, theme, timer,\r\n * uiWorkspace, workspaces`.\r\n *\r\n * A declared service that never arrives leaves the fiber PENDING forever, and\r\n * that is NOT a client-only failure \u2014 it is reported as\r\n * web boot: 1 entry did not activate\r\n * dsh-provider-proxy: pending (waiting for service: settingsScope)\r\n * which fails the whole Desktop boot. `settingsScope` and `configForms` were\r\n * both guessed and both are absent here, so neither may be declared.\r\n *\r\n * Settings are therefore reached through `ctx.get(name)` \u2014 the framework's own\r\n * non-throwing lookup \u2014 and the page degrades to read-only when it is absent.\r\n */\r\nconst PLUGINS = ['slots']\r\n\r\nexport const inject = PLUGINS\r\n\r\nexport function apply(ctx: any): void {\r\n // The settings shell declares `settings.section` on its own fiber, so\r\n // `slots.inject` waits for that declaration and the contribution is removed\r\n // when the panel is torn down.\r\n ctx.slots.inject('settings.section', () =>\r\n ctx.slots.register(\r\n {\r\n name: 'settings.section',\r\n id: NAMESPACE,\r\n order: 20,\r\n label: () => (localeOf(ctx) === 'zh' ? 'Provider \u4EE3\u7406' : 'Provider \u4EE3\u7406'),\r\n },\r\n () => renderPage(ctx),\r\n ),\r\n )\r\n}\r\n\r\n/**\r\n * Pick the dictionary.\r\n *\r\n * Chinese is the default, not English: this plugin is written for a\r\n * Chinese-speaking operator, and a page that renders in the wrong language is\r\n * worse than one that never matches the shell's locale.\r\n *\r\n * `ctx.locale` is not injected \u2014 declaring a service that this release does not\r\n * provide left the fiber PENDING and failed the whole Desktop boot \u2014 so the\r\n * locale is probed with the non-throwing `ctx.get`, then the browser's own\r\n * language, and only then English.\r\n */\r\nfunction localeOf(ctx: any): string {\r\n try {\r\n const service = optionalService(ctx, 'locale')\r\n const snapshot = service?.getSnapshot?.() ?? service?.getLocale?.()\r\n const id = typeof snapshot?.locale === 'string' ? snapshot.locale : undefined\r\n if (id !== undefined) return id.toLowerCase().startsWith('zh') ? 'zh' : 'en'\r\n } catch {\r\n // fall through to the browser language\r\n }\r\n const browser = globalThis.navigator?.language\r\n if (typeof browser === 'string' && browser.toLowerCase().startsWith('zh')) return 'zh'\r\n return browser === undefined ? 'zh' : 'en'\r\n}\r\n\r\n/**\r\n * Look a service up WITHOUT declaring it in `inject`.\r\n *\r\n * `ctx.get(name)` is the framework's own optional lookup: it returns undefined\r\n * instead of throwing, and \u2014 unlike a declared service \u2014 it cannot leave the\r\n * fiber PENDING. That is what makes an optional integration safe here: this\r\n * release has no settings service at all, so the page simply shows its fields\r\n * and reports that saving is unavailable.\r\n */\r\nfunction optionalService(ctx: any, ...names: string[]): any {\r\n for (const name of names) {\r\n try {\r\n const found = typeof ctx?.get === 'function' ? ctx.get(name) : undefined\r\n if (found !== undefined && found !== null) return found\r\n } catch {\r\n // try the next spelling\r\n }\r\n }\r\n return undefined\r\n}\r\n\r\n/** The settings form for this plugin's namespace, when one exists. */\r\nfunction formOf(ctx: any): any {\r\n const forms = optionalService(ctx, 'configForms', 'settingsScope')\r\n if (forms === undefined) return undefined\r\n try {\r\n if (typeof forms.get === 'function') return forms.get(NAMESPACE)\r\n // A settingsScope-style service is already bound to one namespace.\r\n if (typeof forms.getSnapshot === 'function' || typeof forms.bind === 'function') return forms\r\n } catch {\r\n return undefined\r\n }\r\n return undefined\r\n}\r\n\r\nfunction readConfig(ctx: any): { value: any; revision: number } {\r\n const form = formOf(ctx)\r\n if (form === undefined) return { value: {}, revision: 0 }\r\n try {\r\n const snapshot = form.getSnapshot?.()\r\n return {\r\n value: snapshot?.value ?? snapshot?.user ?? {},\r\n revision: snapshot?.revision ?? 0,\r\n }\r\n } catch {\r\n return { value: {}, revision: 0 }\r\n }\r\n}\r\n\r\nasync function writeConfig(ctx: any, ops: readonly unknown[]): Promise<void> {\r\n const form = formOf(ctx)\r\n if (typeof form?.mutate !== 'function') {\r\n throw new Error('dsh-provider-proxy: settings transport unavailable')\r\n }\r\n await form.mutate(ops as any[], readConfig(ctx).revision)\r\n}\r\n\r\n/**\r\n * The provider rows, read from the Host.\r\n *\r\n * This release exposes no client-facing LLM service, so the page cannot ask for\r\n * the directory itself. The Host serves it at this same-origin endpoint, where\r\n * `ctx.llm.listProviders()` / `listConfigurableProviders()` actually live. The\r\n * list is therefore automatic \u2014 the user never types a route id.\r\n *\r\n * Only ACTIVE routes are shown. A provider this deployment merely *offers* \u2014\r\n * declared but not registered, so nothing would ever be sent through it \u2014 is\r\n * not the user's business on this page, and listing it only invites them to\r\n * configure a proxy for a route that cannot be selected. A provider that is\r\n * already configured is kept regardless, so a saved setting never silently\r\n * disappears from view.\r\n */\r\nfunction knownProviders(configured: Record<string, RouteValue>, published: ProviderRow[]): ProviderRow[] {\r\n const rows = new Map<string, ProviderRow>()\r\n for (const row of published) {\r\n if (row.live) rows.set(row.id, row)\r\n }\r\n for (const [id, route] of Object.entries(configured)) {\r\n if (rows.has(id)) continue\r\n rows.set(id, { id, name: id, live: route?.enabled === true })\r\n }\r\n return [...rows.values()].sort(byName)\r\n}\r\n\r\n/**\r\n * Where the Host publishes the live provider catalogue.\r\n */\r\nconst CATALOG_PATH = '/dsh-provider-proxy/providers'\r\n\r\n/** Where the Host runs a per-provider connection self-check. */\r\nconst TEST_PATH = '/dsh-provider-proxy/test'\r\n\r\n/**\r\n * Latency bands for the self-check result, in milliseconds.\r\n *\r\n * The colour is decoration, never information: the numeric value is always\r\n * printed, so an unknown theme token (which resolves to `unset`) costs colour,\r\n * never the reading. The `var(..., fallback)` form keeps the colours visible even\r\n * if the theme renames the token.\r\n */\r\nconst LATENCY_FAST_MS = 500\r\nconst LATENCY_SLOW_MS = 1500\r\n\r\nfunction latencyColor(ms: unknown): string {\r\n if (typeof ms !== 'number' || !Number.isFinite(ms)) return 'var(--dsw-alias-label-secondary)'\r\n if (ms <= LATENCY_FAST_MS) return 'var(--dsw-alias-state-success-primary, #2ea043)'\r\n if (ms <= LATENCY_SLOW_MS) return 'var(--dsw-alias-state-warn-primary, #d29922)'\r\n return 'var(--dsw-alias-state-error-primary, #f85149)'\r\n}\r\n\r\n/** Normalize the Host's self-check payload into the shape the card renders. */\r\nfunction testResultFrom(body: any, strings: Record<string, string>): Record<string, unknown> {\r\n const ok = body?.ok === true\r\n return {\r\n pending: false,\r\n ok,\r\n ms: typeof body?.ms === 'number' && Number.isFinite(body.ms) ? body.ms : undefined,\r\n ip: typeof body?.exitIp === 'string' && body.exitIp.length > 0 ? body.exitIp : undefined,\r\n error: ok\r\n ? undefined\r\n : typeof body?.error === 'string' && body.error.length > 0\r\n ? body.error\r\n : strings.testFailed,\r\n }\r\n}\r\n\r\n/**\r\n * The setter the lazy catalogue initializer resolves through.\r\n *\r\n * It is republished after every render, so the newest one always wins, and a\r\n * promise that settles after an unmount writes to a harmless no-op.\r\n */\r\nlet catalogueSetter: ((catalog: Catalog) => void) | undefined = () => {}\r\n\r\n/** What the Host endpoint publishes: provider rows, hit counts, rejected routes. */\r\ntype Catalog = {\r\n rows: ProviderRow[]\r\n hits: Record<string, number>\r\n problems: Record<string, string>\r\n}\r\n\r\n/** Read the Host's provider catalogue. Same-origin, so no token is needed. */\r\nasync function fetchCatalog(): Promise<Catalog> {\r\n const response = await globalThis.fetch(CATALOG_PATH, { headers: { accept: 'application/json' } })\r\n if (!response.ok) throw new Error(`Host answered ${response.status}`)\r\n const body = await response.json()\r\n const list = Array.isArray(body?.providers) ? body.providers : []\r\n const rows = list\r\n .filter((row: any) => typeof row?.id === 'string' && row.id.length > 0)\r\n .map((row: any) => ({\r\n id: row.id,\r\n name: typeof row.name === 'string' && row.name.length > 0 ? row.name : row.id,\r\n live: row.live === true,\r\n }))\r\n // The Host counts requests it routed through each provider's proxy. Anything\r\n // malformed is dropped rather than rendered, so a bad payload cannot put a\r\n // non-numeric string on the page.\r\n const hits: Record<string, number> = {}\r\n const published = body?.hits\r\n if (published !== null && typeof published === 'object') {\r\n for (const [id, count] of Object.entries(published)) {\r\n if (typeof count === 'number' && Number.isFinite(count)) hits[id] = count\r\n }\r\n }\r\n // A route the Host REFUSED (a bad port, half-filled credentials) is absent from\r\n // the provider list entirely, so this map is the only place that says why it is\r\n // missing. The Host already stripped the log prefix from it.\r\n const problems: Record<string, string> = {}\r\n const rejected = body?.problems\r\n if (rejected !== null && typeof rejected === 'object') {\r\n for (const [id, message] of Object.entries(rejected)) {\r\n if (typeof message === 'string' && message.length > 0) problems[id] = message\r\n }\r\n }\r\n return { rows, hits, problems }\r\n}\r\n\r\nconst byName = (a: ProviderRow, b: ProviderRow): number => a.name.localeCompare(b.name)\r\n\r\nfunction view(route: Partial<RouteValue> | undefined): RouteValue {\r\n return {\r\n enabled: route?.enabled === true,\r\n protocol: PROTOCOLS.includes(route?.protocol as Protocol) ? (route!.protocol as Protocol) : 'http',\r\n host: route?.host ?? '',\r\n port: route?.port ?? 0,\r\n username: route?.username ?? '',\r\n password: route?.password ?? '',\r\n onlyHosts: route?.onlyHosts ?? '',\r\n bypassHosts: route?.bypassHosts ?? '',\r\n }\r\n}\r\n\r\n/** The provider directory, cached module-side. See renderPage. */\r\nlet directoryCache: ProviderRow[] | undefined\r\n\r\n/**\r\n * Everything the page learned about its own wiring, rendered verbatim.\r\n *\r\n * The browser side of a plugin has no other diagnostic channel \u2014 the Host log\r\n * never sees it \u2014 so a silent failure had to be diagnosed by inference. This\r\n * panel is what proved that `remote.settings` and `remote.llm` do not exist in\r\n * this release, and that the catalogue had to come from the Host endpoint.\r\n *\r\n * Cleared at the start of every render so the panel shows the CURRENT state\r\n * rather than an ever-growing log of the session.\r\n */\r\nlet diagnostics: string[] = []\r\n\r\nfunction note(message: string): void {\r\n if (!diagnostics.includes(message)) diagnostics.push(message)\r\n}\r\n\r\n/**\r\n * Layout constants, applied as INLINE styles.\r\n *\r\n * The page is rendered into the settings panel, and the CSS-Modules pipeline\r\n * that feeds the stylesheet has broken twice in ways that were invisible from\r\n * the source: the class map failed to bind at all, and a shared class prefix\r\n * silently merged two rules. Both left the page readable but laid out as one\r\n * unstyled block.\r\n *\r\n * Structure is therefore expressed as inline styles, which cannot be lost by\r\n * the bundle, and the stylesheet is kept for the purely decorative parts. A\r\n * theme token that is not defined simply resolves to `unset`, so an unknown\r\n * token costs colour, never layout.\r\n */\r\nconst S = {\r\n root: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: '12px',\r\n maxWidth: '720px',\r\n },\r\n card: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: '12px',\r\n padding: '14px 16px',\r\n marginBottom: '12px',\r\n border: '1px solid var(--dsw-alias-border-l1)',\r\n borderRadius: '10px',\r\n background: 'var(--dsw-alias-bg-layer-1)',\r\n },\r\n cardActive: {\r\n borderColor: 'var(--dsw-alias-state-success-primary)',\r\n background: 'var(--dsw-alias-bg-layer-2)',\r\n },\r\n head: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'space-between',\r\n gap: '12px',\r\n },\r\n titles: { display: 'flex', alignItems: 'baseline', gap: '8px', minWidth: '0' },\r\n name: {\r\n fontSize: '14px',\r\n fontWeight: '600',\r\n color: 'var(--dsw-alias-label-primary)',\r\n overflow: 'hidden',\r\n textOverflow: 'ellipsis',\r\n whiteSpace: 'nowrap',\r\n },\r\n id: {\r\n flex: 'none',\r\n padding: '1px 6px',\r\n borderRadius: '4px',\r\n background: 'var(--dsw-alias-bg-layer-2)',\r\n fontFamily: 'ui-monospace, monospace',\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n },\r\n hits: {\r\n flex: 'none',\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n whiteSpace: 'nowrap',\r\n },\r\n testRow: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '10px',\r\n flexWrap: 'wrap',\r\n },\r\n testButton: {\r\n padding: '5px 12px',\r\n border: '1px solid var(--dsw-alias-border-l1)',\r\n borderRadius: '6px',\r\n background: 'var(--dsw-alias-bg-layer-1)',\r\n color: 'var(--dsw-alias-label-primary)',\r\n font: 'inherit',\r\n fontSize: '12px',\r\n cursor: 'pointer',\r\n },\r\n testResult: {\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n wordBreak: 'break-all',\r\n },\r\n /**\r\n * A failed check is the answer, not decoration: it takes the error colour and\r\n * a heavier weight, unlike the latency band colour which only tints a number\r\n * that is printed anyway.\r\n */\r\n testFailure: {\r\n color: 'var(--dsw-alias-state-error-primary, #f85149)',\r\n fontWeight: '500',\r\n },\r\n /** A rejected route is a failure of the settings, not a warning about them. */\r\n diagProblem: {\r\n color: 'var(--dsw-alias-state-error-primary, #f85149)',\r\n },\r\n advanced: {\r\n marginTop: '4px',\r\n fontSize: '12px',\r\n },\r\n advancedSummary: {\r\n cursor: 'pointer',\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n },\r\n pill: {\r\n flex: 'none',\r\n padding: '2px 10px',\r\n borderRadius: '999px',\r\n fontSize: '11px',\r\n fontWeight: '500',\r\n whiteSpace: 'nowrap',\r\n },\r\n pillOn: {\r\n background: 'var(--dsw-alias-state-success-primary)',\r\n color: 'var(--dsw-alias-bg-base)',\r\n },\r\n pillLive: {\r\n border: '1px solid var(--dsw-alias-border-l2)',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n },\r\n pillOff: { color: 'var(--dsw-alias-state-idle-primary)' },\r\n toggle: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '8px',\r\n fontSize: '12px',\r\n color: 'var(--dsw-alias-label-primary)',\r\n },\r\n field: {\r\n display: 'grid',\r\n gridTemplateColumns: '88px 1fr',\r\n alignItems: 'center',\r\n gap: '10px',\r\n fontSize: '12px',\r\n },\r\n label: { color: 'var(--dsw-alias-label-secondary)' },\r\n input: {\r\n boxSizing: 'border-box',\r\n width: '100%',\r\n minWidth: '0',\r\n padding: '6px 8px',\r\n border: '1px solid var(--dsw-alias-border-l1)',\r\n borderRadius: '6px',\r\n outline: 'none',\r\n background: 'var(--dsw-alias-bg-layer-1)',\r\n color: 'var(--dsw-alias-label-primary)',\r\n font: 'inherit',\r\n fontSize: '12px',\r\n },\r\n} as const\r\n\r\nfunction renderPage(ctx: any): unknown {\r\n const React = react()\r\n if (React === undefined || typeof React.createElement !== 'function') return null\r\n\r\n const h = React.createElement\r\n const t = stringsFor(ctx)\r\n diagnostics = []\r\n\r\n // `useState` is only reached after the React check, so the early return above\r\n // cannot desync the hooks order.\r\n let snapshot: { value: any; revision: number }\r\n try {\r\n snapshot = readConfig(ctx)\r\n } catch {\r\n snapshot = { value: {}, revision: 0 }\r\n }\r\n const configured = (snapshot.value?.providers ?? {}) as Record<string, RouteValue>\r\n note(\r\n formOf(ctx) === undefined\r\n ? '\u8BBE\u7F6E\uFF1A\u672A\u627E\u5230 configForms \u670D\u52A1\uFF0C\u53EA\u80FD\u663E\u793A\u3001\u65E0\u6CD5\u4FDD\u5B58'\r\n : `\u8BBE\u7F6E\uFF1A\u6B63\u5E38\uFF08\u4FEE\u8BA2\u53F7 ${snapshot.revision}\uFF0C${Object.keys(configured).length} \u4E2A provider\uFF09`,\r\n )\r\n\r\n // The provider catalogue comes from the Host over a same-origin endpoint, so\r\n // it arrives asynchronously. The initial state is a LAZY initializer, so the\r\n // fetch starts from `useState(() => \u2026)` instead of by calling a setter during\r\n // render: a render must have no side effects, and doing so also shifted the\r\n // hook order between passes.\r\n const [state, setState] = (React.useState ?? ((fn: any) => [fn(), () => {}]))(() => {\r\n void fetchCatalog()\r\n .then(catalog => catalogueSetter?.(catalog))\r\n .catch((error: any) => {\r\n note(`provider \u5217\u8868\u83B7\u53D6\u5931\u8D25\uFF1A${error?.message ?? error}`)\r\n catalogueSetter?.({ rows: [], hits: {}, problems: {} })\r\n })\r\n return {\r\n rows: undefined as ProviderRow[] | undefined,\r\n hits: {} as Record<string, number>,\r\n problems: {} as Record<string, string>,\r\n pending: true,\r\n }\r\n })\r\n // The setter is published right after the hook so the initializer's promise\r\n // can reach it. It is re-published on every render, so the latest wins.\r\n catalogueSetter = catalog =>\r\n setState({ rows: catalog.rows, hits: catalog.hits, problems: catalog.problems, pending: false })\r\n\r\n const published = state.rows ?? []\r\n const hits = state.hits ?? {}\r\n // Rendered straight from state rather than through `note()`: `diagnostics` is\r\n // cleared at the start of every render, so a note written when the catalog\r\n // arrives would not survive to the next pass.\r\n const problems = state.problems ?? {}\r\n const problemLines = Object.entries(problems).map(([id, message]) =>\r\n h('li', { key: `p:${id}`, style: S.diagProblem }, `${id}\uFF1A${message}`),\r\n )\r\n const problemCount = problemLines.length\r\n note(\r\n `provider \u5217\u8868\uFF1A\u6765\u81EA Host \u5171 ${published.length} \u4E2A\uFF08${published.map((r: ProviderRow) => r.id).join('\u3001') || '\u65E0'}\uFF09`,\r\n )\r\n // Local draft, layered over the stored config.\r\n //\r\n // Without it a checkbox does not change until the panel remounts: the value\r\n // is read from the settings store, which only updates when the page is\r\n // rebuilt. The draft makes the control respond immediately, then reconciles\r\n // with the store so a refused write is visible rather than silently lost.\r\n const [draft, setDraft] = (React.useState ?? ((v: any) => [v, () => {}]))({})\r\n const edit = (id: string, field: string, value: unknown) =>\r\n setDraft((current: any) => ({ ...current, [id]: { ...current[id], [field]: value } }))\r\n\r\n // Self-check outcomes keyed by provider id: `{ pending: true }` while the Host\r\n // is testing, then the normalized result the card renders.\r\n const [tests, setTests] = (React.useState ?? ((v: any) => [v, () => {}]))({})\r\n\r\n /**\r\n * Run the Host's self-check for one provider.\r\n *\r\n * The check is not routed traffic, so it never changes the hit count; the count\r\n * on the card is read at mount and stays put until the page reloads.\r\n */\r\n const runTest = (id: string): void => {\r\n setTests((current: any) => ({ ...current, [id]: { pending: true } }))\r\n void (async () => {\r\n try {\r\n const response = await globalThis.fetch(TEST_PATH, {\r\n method: 'POST',\r\n headers: { 'content-type': 'application/json', accept: 'application/json' },\r\n body: JSON.stringify({ provider: id }),\r\n })\r\n const body = await response.json()\r\n setTests((current: any) => ({ ...current, [id]: testResultFrom(body, t) }))\r\n } catch (error: any) {\r\n setTests((current: any) => ({\r\n ...current,\r\n [id]: { pending: false, ok: false, error: String(error?.message ?? error) },\r\n }))\r\n }\r\n })()\r\n }\r\n\r\n const rows = knownProviders({ ...configured, ...draft }, published)\r\n\r\n /**\r\n * Persist one field. The control is already showing the new value, so this\r\n * only has to succeed quietly; a refusal is reported in the diagnostics.\r\n */\r\n const save = (id: string, field: string, value: unknown) => {\r\n void writeConfig(ctx, [{ op: 'set', path: ['providers', id, field], value }])\r\n .then(() => {\r\n note(`\u5DF2\u4FDD\u5B58 ${id}.${field} = ${JSON.stringify(value)}`)\r\n })\r\n .catch((error: any) => {\r\n note(`\u4FDD\u5B58\u5931\u8D25 ${id}.${field}\uFF1A${error?.message ?? error}`)\r\n // Drop the optimistic value so the stored state shows through again.\r\n setDraft((current: any) => {\r\n const next = { ...current }\r\n delete next[id]\r\n return next\r\n })\r\n })\r\n }\r\n\r\n /** One control: update the draft instantly, persist in the background. */\r\n const bind = (id: string, field: string) => (value: unknown) => {\r\n edit(id, field, value)\r\n save(id, field, value)\r\n }\r\n\r\n const field = (label: string, control: unknown, hint?: string): unknown =>\r\n h(\r\n 'label',\r\n { className: styles.field, style: S.field, key: label },\r\n h('span', { className: styles.label, style: S.label }, label),\r\n control,\r\n hint === undefined\r\n ? null\r\n : h(\r\n 'span',\r\n { className: styles.hint, style: { gridColumn: '2', fontSize: '11px' } },\r\n hint,\r\n ),\r\n )\r\n\r\n // ALWAYS an array: a single element is not iterable, and spreading one threw\r\n // \"Spread syntax requires ...iterable[Symbol.iterator]\" on an empty list.\r\n const body: unknown[] = rows.length === 0\r\n ? [\r\n h(\r\n 'p',\r\n {\r\n className: styles.empty,\r\n key: 'empty',\r\n style: {\r\n margin: '0',\r\n padding: '16px',\r\n border: '1px dashed var(--dsw-alias-border-l1)',\r\n borderRadius: '8px',\r\n fontSize: '12px',\r\n textAlign: 'center',\r\n color: 'var(--dsw-alias-state-idle-primary)',\r\n },\r\n },\r\n t.empty,\r\n ),\r\n ]\r\n : rows.map(row => {\r\n // The MERGED value, so a just-typed value shows immediately.\r\n const route = view({ ...configured[row.id], ...draft[row.id] })\r\n const disabled = !route.enabled\r\n const result = tests[row.id]\r\n return h(\r\n 'section',\r\n {\r\n className: route.enabled ? styles.cardActive : styles.card,\r\n style: route.enabled ? { ...S.card, ...S.cardActive } : S.card,\r\n key: row.id,\r\n },\r\n h(\r\n 'header',\r\n { className: styles.cardHead, style: S.head },\r\n h(\r\n 'div',\r\n { className: styles.cardTitles, style: S.titles },\r\n h('span', { className: styles.name, style: S.name }, row.name),\r\n h('span', { className: styles.id, style: S.id }, row.id),\r\n // A disabled route can never have hits, so \"0\" there would only add\r\n // noise; the count shows once the route is on (or has counted).\r\n route.enabled || (hits[row.id] ?? 0) > 0\r\n ? h(\r\n 'span',\r\n { style: S.hits },\r\n `${t.hitCountPrefix}${hits[row.id] ?? 0}${t.hitCountSuffix}`,\r\n )\r\n : null,\r\n ),\r\n h(\r\n 'span',\r\n {\r\n className: route.enabled ? styles.pillOn : row.live ? styles.pillLive : styles.pillOff,\r\n style: {\r\n ...S.pill,\r\n ...(route.enabled ? S.pillOn : row.live ? S.pillLive : S.pillOff),\r\n },\r\n },\r\n route.enabled ? t.on : row.live ? t.live : t.off,\r\n ),\r\n ),\r\n h(\r\n 'label',\r\n { className: styles.toggle, style: S.toggle },\r\n h('input', {\r\n type: 'checkbox',\r\n checked: route.enabled,\r\n onChange: (event: any) => bind(row.id, 'enabled')(event.target.checked === true),\r\n }),\r\n h('span', null, t.useProxy),\r\n ),\r\n field(\r\n t.protocol,\r\n h(\r\n 'select',\r\n {\r\n className: styles.input,\r\n style: S.input,\r\n disabled,\r\n value: route.protocol,\r\n onChange: (event: any) => bind(row.id, 'protocol')(event.target.value),\r\n },\r\n ...PROTOCOLS.map(protocol =>\r\n h('option', { key: protocol, value: protocol }, protocol.toUpperCase()),\r\n ),\r\n ),\r\n route.protocol === 'socks5' ? t.socks5Hint : undefined,\r\n ),\r\n field(\r\n t.host,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n disabled,\r\n placeholder: '127.0.0.1',\r\n value: route.host,\r\n onChange: (event: any) => bind(row.id, 'host')(event.target.value),\r\n }),\r\n t.hostHint,\r\n ),\r\n field(\r\n t.port,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n disabled,\r\n type: 'number',\r\n min: 1,\r\n max: 65535,\r\n placeholder: '7890',\r\n value: route.port === 0 ? '' : String(route.port),\r\n onChange: (event: any) => {\r\n const parsed = Number.parseInt(event.target.value, 10)\r\n bind(row.id, 'port')(Number.isNaN(parsed) ? 0 : parsed)\r\n },\r\n }),\r\n ),\r\n field(\r\n t.username,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n disabled,\r\n autocomplete: 'off',\r\n value: route.username,\r\n onChange: (event: any) => bind(row.id, 'username')(event.target.value),\r\n }),\r\n ),\r\n // Every transport accepts a password now: SOCKS5 hands it to\r\n // Socks5ProxyAgent as an option, HTTP/HTTPS embed it in the proxy URL\r\n // userinfo (undici turns that into Proxy-Authorization). It is stored on\r\n // the route, so it lands in the settings file with the rest of the\r\n // config; the diagnostics only ever surface a credential-free origin.\r\n field(\r\n t.password,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n disabled,\r\n type: 'password',\r\n autocomplete: 'off',\r\n value: route.password,\r\n onChange: (event: any) => bind(row.id, 'password')(event.target.value),\r\n }),\r\n route.protocol === 'socks5' ? t.passwordHint : t.passwordHintProxy,\r\n ),\r\n // The self-check only makes sense for a route that is ON; a disabled\r\n // route is not in the Host's table, so there is nothing to test.\r\n route.enabled\r\n ? h(\r\n 'div',\r\n { style: S.testRow, key: `${row.id}:test` },\r\n h(\r\n 'button',\r\n {\r\n className: styles.testButton,\r\n style: S.testButton,\r\n type: 'button',\r\n disabled: result?.pending === true,\r\n onClick: () => runTest(row.id),\r\n },\r\n result?.pending === true ? t.testRunning : t.testButton,\r\n ),\r\n result?.pending === false\r\n ? h(\r\n 'span',\r\n { style: S.testResult },\r\n result.ok === true\r\n ? [\r\n // Only the latency carries the band colour; the exit IP\r\n // stays in the secondary label colour.\r\n h(\r\n 'span',\r\n { key: 'lat', style: { color: latencyColor(result.ms) } },\r\n `\u2713 ${typeof result.ms === 'number' ? result.ms : '\u2014'} ms`,\r\n ),\r\n result.ip === undefined ? null : ` \u00B7 ${t.exitIpLabel}${result.ip}`,\r\n ]\r\n : h('span', { key: 'err', style: S.testFailure }, `\u2717 ${result.error}`),\r\n )\r\n : null,\r\n )\r\n : null,\r\n // Target-host rules, collapsed so the common case stays one short card.\r\n h(\r\n 'details',\r\n { style: S.advanced, key: `${row.id}:rules` },\r\n h('summary', { style: S.advancedSummary }, t.advanced),\r\n field(\r\n t.onlyHosts,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n disabled,\r\n placeholder: 'api.example.com',\r\n value: route.onlyHosts,\r\n onChange: (event: any) => bind(row.id, 'onlyHosts')(event.target.value),\r\n }),\r\n t.onlyHostsHint,\r\n ),\r\n field(\r\n t.bypassHosts,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n disabled,\r\n placeholder: 'localhost',\r\n value: route.bypassHosts,\r\n onChange: (event: any) => bind(row.id, 'bypassHosts')(event.target.value),\r\n }),\r\n t.bypassHostsHint,\r\n ),\r\n ),\r\n )\r\n })\r\n\r\n return h(\r\n 'div',\r\n { className: styles.root, style: S.root },\r\n h('p', { className: styles.lead, style: { margin: '0 0 4px', fontSize: '12px', lineHeight: '1.6', color: 'var(--dsw-alias-label-secondary)' } }, t.lead),\r\n ...body,\r\n h(\r\n 'details',\r\n {\r\n className: styles.diag,\r\n key: 'diag',\r\n style: {\r\n marginTop: '4px',\r\n padding: '8px 10px',\r\n border: '1px solid var(--dsw-alias-border-l1)',\r\n borderRadius: '8px',\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n },\r\n },\r\n // The count is the only visible signal while the panel is collapsed: a\r\n // rejected route is not a page that refuses to render, it is one that\r\n // quietly does nothing.\r\n h(\r\n 'summary',\r\n { className: styles.diagSummary },\r\n problemCount === 0 ? t.diagnostics : `${t.diagnostics} (${problemCount})`,\r\n ),\r\n h(\r\n 'ul',\r\n { className: styles.diagList, style: { margin: '6px 0 0', paddingLeft: '18px' } },\r\n ...(problemCount === 0 && diagnostics.length === 0\r\n ? [h('li', { key: 'none' }, t.diagPending)]\r\n : [\r\n ...problemLines,\r\n ...diagnostics.map((line, index) => h('li', { key: `d${index}` }, line)),\r\n ]),\r\n ),\r\n ),\r\n )\r\n}\r\n\r\nconst EN = {\r\n lead: 'Route selected model providers through your own forward proxy. Other providers stay direct.',\r\n empty: 'No providers found yet.',\r\n useProxy: 'Use a proxy for this provider',\r\n protocol: 'Type',\r\n host: 'IP / host',\r\n port: 'Port',\r\n username: 'Username',\r\n password: 'Password',\r\n hostHint: 'Host or IP only, without scheme or path.',\r\n passwordHint: 'Sent to the SOCKS5 proxy for authentication; stored with this setting.',\r\n passwordHintProxy: 'Sent to the proxy as an authentication password; stored with this setting.',\r\n hitCountPrefix: '',\r\n hitCountSuffix: ' proxied',\r\n testButton: 'Test',\r\n testRunning: 'Testing\u2026',\r\n testFailed: 'Test failed',\r\n exitIpLabel: 'exit IP ',\r\n advanced: 'Advanced: target host rules',\r\n onlyHosts: 'Proxy only',\r\n onlyHostsHint: 'Comma/space separated; when set, only requests to these hosts are proxied (suffix match, * for all).',\r\n bypassHosts: 'Bypass',\r\n bypassHostsHint: 'Comma/space separated; requests to these hosts go direct, taking priority.',\r\n socks5Hint: 'SOCKS5 tunnels the connection; the proxy resolves the target host name.',\r\n on: 'proxied',\r\n live: 'active',\r\n off: 'direct',\r\n diagnostics: 'Connection diagnostics',\r\n diagPending: '(collecting\u2026)',\r\n}\r\n\r\nconst ZH = {\r\n lead: '\u8BA9\u6307\u5B9A\u7684 provider \u8D70\u4F60\u81EA\u5DF1\u7684\u6B63\u5411\u4EE3\u7406\uFF0C\u5176\u5B83 provider \u4FDD\u6301\u76F4\u8FDE\u3002',\r\n empty: '\u6CA1\u6709\u68C0\u6D4B\u5230\u4EFB\u4F55 provider\u3002',\r\n useProxy: '\u4E3A\u8BE5 provider \u542F\u7528\u4EE3\u7406',\r\n protocol: '\u7C7B\u578B',\r\n host: 'IP / \u4E3B\u673A',\r\n port: '\u7AEF\u53E3',\r\n username: '\u7528\u6237\u540D',\r\n password: '\u5BC6\u7801',\r\n hostHint: '\u53EA\u586B\u4E3B\u673A\u540D\u6216 IP\uFF0C\u4E0D\u8981\u5E26\u534F\u8BAE\u524D\u7F00\u6216\u8DEF\u5F84\u3002',\r\n passwordHint: '\u4EC5\u4F5C\u4E3A SOCKS5 \u8BA4\u8BC1\u53E3\u4EE4\u53D1\u9001\u7ED9\u4EE3\u7406\uFF1B\u968F\u8BE5\u8BBE\u7F6E\u4E00\u8D77\u4FDD\u5B58\u3002',\r\n passwordHintProxy: '\u4F5C\u4E3A\u4EE3\u7406\u8BA4\u8BC1\u53E3\u4EE4\u53D1\u9001\u7ED9\u4EE3\u7406\uFF1B\u968F\u8BE5\u8BBE\u7F6E\u4E00\u8D77\u4FDD\u5B58\u3002',\r\n hitCountPrefix: '\u5DF2\u4EE3\u7406 ',\r\n hitCountSuffix: ' \u6B21',\r\n testButton: '\u6D4B\u8BD5',\r\n testRunning: '\u6D4B\u8BD5\u4E2D\u2026',\r\n testFailed: '\u6D4B\u8BD5\u5931\u8D25',\r\n exitIpLabel: '\u51FA\u53E3 IP ',\r\n advanced: '\u9AD8\u7EA7\uFF1A\u76EE\u6807\u57DF\u540D\u89C4\u5219',\r\n onlyHosts: '\u4EC5\u8D70\u4EE3\u7406',\r\n onlyHostsHint: '\u9017\u53F7\u6216\u7A7A\u683C\u5206\u9694\uFF1B\u975E\u7A7A\u65F6\u53EA\u6709\u5339\u914D\u8FD9\u4E9B\u4E3B\u673A\u7684\u8BF7\u6C42\u8D70\u4EE3\u7406\uFF08\u540E\u7F00\u5339\u914D\uFF0C* \u8868\u793A\u5168\u90E8\uFF09\u3002',\r\n bypassHosts: '\u76F4\u8FDE',\r\n bypassHostsHint: '\u9017\u53F7\u6216\u7A7A\u683C\u5206\u9694\uFF1B\u5339\u914D\u8FD9\u4E9B\u4E3B\u673A\u7684\u8BF7\u6C42\u76F4\u8FDE\uFF0C\u4F18\u5148\u4E8E\u4E0A\u4E00\u9879\u3002',\r\n socks5Hint: 'SOCKS5 \u4F1A\u5EFA\u7ACB\u96A7\u9053\uFF0C\u76EE\u6807\u57DF\u540D\u7531\u4EE3\u7406\u7AEF\u89E3\u6790\u3002',\r\n on: '\u8D70\u4EE3\u7406',\r\n live: '\u542F\u7528\u4E2D',\r\n off: '\u76F4\u8FDE',\r\n diagnostics: '\u8FDE\u63A5\u8BCA\u65AD',\r\n diagPending: '\uFF08\u6B63\u5728\u6536\u96C6\u2026\uFF09',\r\n}\r\n\r\n/**\r\n * Pick the dictionary for this render.\r\n *\r\n * The shell's own locale dictionary wins when it carries a translated entry, so\r\n * the page follows the application language instead of second-guessing it.\r\n * Chinese is the fallback because that is the operator's language.\r\n */\r\nfunction stringsFor(ctx: any): Record<string, string> {\r\n const language = localeOf(ctx)\r\n const bundled = language === 'zh' ? ZH : EN\r\n const translated = ((): Record<string, string> | undefined => {\r\n try {\r\n const service = optionalService(ctx, 'locale')\r\n const bound = service?.bind?.('dshProviderProxy')\r\n const value = typeof bound === 'function' ? bound('title') : undefined\r\n if (typeof value === 'string' && value.length > 0) return { title: value } as never\r\n } catch {\r\n // no locale dictionary available\r\n }\r\n return undefined\r\n })()\r\n return { ...bundled, ...(translated ?? {}) }\r\n}\r\n\r\n/**\r\n * The client module system's resolver.\r\n *\r\n * The loader calls `factory(require)` and that parameter shadows Node's\r\n * `require` inside the emitted CJS, so this describes the module-table\r\n * resolver, not Node's.\r\n */\r\ndeclare function require(specifier: string): unknown\r\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["module", "field", "body", "styles"]
|
|
7
7
|
}
|