dsh-proxy-routing 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/lib/client.js ADDED
@@ -0,0 +1,480 @@
1
+ window.__ModuleLoader__.load({
2
+ id: "dsh-proxy-routing",
3
+ factory: (require) => {
4
+ var module = { exports: {} };
5
+ var exports = module.exports;
6
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
+ let react = require("react");
8
+ let react_jsx_runtime = require("react/jsx-runtime");
9
+ let _deepseek_ai_dsh_client_runtime_client = require("@deepseek-ai/dsh-client-runtime/client");
10
+ //#region \0dsh-proxy-routing-css:src/client/ProxySettingsRow.module.css.mjs
11
+ const css = ".BXcnvG_row{border-bottom:1px solid var(--dsw-alias-border-l2);flex-direction:column;gap:10px;padding:14px 0;display:flex}.BXcnvG_heading{justify-content:space-between;align-items:flex-start;gap:12px;display:flex}.BXcnvG_title{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:500;line-height:1.5}.BXcnvG_hint,.BXcnvG_note,.BXcnvG_message{color:var(--dsw-alias-label-tertiary);margin:3px 0 0;font-size:12px;line-height:1.5}.BXcnvG_message{color:var(--dsw-alias-label-secondary)}.BXcnvG_toggle{color:var(--dsw-alias-label-secondary);flex:none;align-items:center;gap:6px;font-size:12px;line-height:1.5;display:inline-flex}.BXcnvG_fields{grid-template-columns:minmax(110px,.8fr) minmax(150px,1.6fr) minmax(90px,.7fr);gap:8px;display:grid}.BXcnvG_field,.BXcnvG_fieldWide,.BXcnvG_fieldPort{min-width:0;color:var(--dsw-alias-label-tertiary);flex-direction:column;gap:5px;font-size:11px;line-height:1.4;display:flex}.BXcnvG_actions,.BXcnvG_candidates{flex-wrap:wrap;align-items:center;gap:7px;display:flex}.BXcnvG_candidates{color:var(--dsw-alias-label-tertiary);font-size:12px}@media (width<=560px){.BXcnvG_fields{grid-template-columns:1fr 1fr}.BXcnvG_fieldWide{grid-column:1/-1}}";
12
+ const tagId = "dsh-proxy-routing/ProxySettingsRow.module.css";
13
+ if (typeof document !== "undefined") {
14
+ let tag = document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]");
15
+ if (tag === null) {
16
+ tag = document.createElement("style");
17
+ tag.dataset.plugin = "dsh-proxy-routing";
18
+ tag.dataset.pluginCss = tagId;
19
+ document.head.appendChild(tag);
20
+ }
21
+ tag.textContent = css;
22
+ }
23
+ var ProxySettingsRow_module_css_default = {
24
+ "actions": "BXcnvG_actions",
25
+ "candidates": "BXcnvG_candidates",
26
+ "field": "BXcnvG_field",
27
+ "fieldPort": "BXcnvG_fieldPort",
28
+ "fields": "BXcnvG_fields",
29
+ "fieldWide": "BXcnvG_fieldWide",
30
+ "heading": "BXcnvG_heading",
31
+ "hint": "BXcnvG_hint",
32
+ "message": "BXcnvG_message",
33
+ "note": "BXcnvG_note",
34
+ "row": "BXcnvG_row",
35
+ "title": "BXcnvG_title",
36
+ "toggle": "BXcnvG_toggle"
37
+ };
38
+ //#endregion
39
+ //#region src/client/ProxySettingsRow.tsx
40
+ const fieldStyle = {
41
+ minWidth: 0,
42
+ height: 34,
43
+ padding: "0 10px",
44
+ border: "1px solid var(--dsw-alias-border-l2)",
45
+ borderRadius: 8,
46
+ background: "var(--dsw-alias-bg-layer-3)",
47
+ color: "var(--dsw-alias-label-primary)",
48
+ font: "inherit",
49
+ fontSize: 13
50
+ };
51
+ const actionStyle = {
52
+ minHeight: 30,
53
+ padding: "0 10px",
54
+ border: "1px solid var(--dsw-alias-border-l2)",
55
+ borderRadius: 7,
56
+ background: "var(--dsw-alias-bg-layer-3)",
57
+ color: "var(--dsw-alias-label-secondary)",
58
+ cursor: "pointer",
59
+ font: "inherit",
60
+ fontSize: 12
61
+ };
62
+ function snapshotProfile(snapshot) {
63
+ return snapshot.value?.profiles?.find((profile) => profile.id === "default") ?? snapshot.value?.profiles?.[0];
64
+ }
65
+ function useProxyDraft(snapshot) {
66
+ const profile = snapshotProfile(snapshot) ?? { id: "default" };
67
+ const [draft, setDraft] = (0, react.useState)(profile);
68
+ const [revision, setRevision] = (0, react.useState)(snapshot.revision);
69
+ (0, react.useEffect)(() => {
70
+ if (snapshot.revision === revision) return;
71
+ setRevision(snapshot.revision);
72
+ setDraft(profile);
73
+ }, [
74
+ profile,
75
+ revision,
76
+ snapshot.revision
77
+ ]);
78
+ return [draft, setDraft];
79
+ }
80
+ function endpointFromDraft(draft) {
81
+ const port = draft.port;
82
+ if (draft.protocol !== "http" && draft.protocol !== "socks5" || typeof draft.host !== "string" || draft.host.trim().length === 0 || typeof port !== "number" || !Number.isInteger(port) || port < 1 || port > 65535) return void 0;
83
+ return {
84
+ protocol: draft.protocol,
85
+ host: draft.host.trim(),
86
+ port
87
+ };
88
+ }
89
+ function endpointValid(draft) {
90
+ return endpointFromDraft(draft) !== void 0;
91
+ }
92
+ function ProxySettingsRow({ t, useStore, persist, probe, discover }) {
93
+ const settings = useStore((state) => state.snapshot);
94
+ const [draft, setDraft] = useProxyDraft(settings);
95
+ const [busy, setBusy] = (0, react.useState)(false);
96
+ const [message, setMessage] = (0, react.useState)();
97
+ const [discovered, setDiscovered] = (0, react.useState)([]);
98
+ const active = settings.value?.bindings?.agent?.kind === "profile";
99
+ const usable = settings.status === "ready" && settings.writable && !busy;
100
+ if (settings.status === "unavailable") return null;
101
+ const saveProfile = async () => {
102
+ if (!endpointValid(draft)) {
103
+ setMessage(t("invalid"));
104
+ return false;
105
+ }
106
+ setBusy(true);
107
+ setMessage(void 0);
108
+ try {
109
+ const endpoint = endpointFromDraft(draft);
110
+ if (endpoint === void 0) return false;
111
+ await persist(endpoint);
112
+ return true;
113
+ } finally {
114
+ setBusy(false);
115
+ }
116
+ };
117
+ const save = async () => {
118
+ if (!usable) return;
119
+ try {
120
+ if (await saveProfile()) setMessage(t("saved"));
121
+ } catch (error) {
122
+ setMessage(error instanceof Error ? error.message : String(error));
123
+ }
124
+ };
125
+ const toggle = async () => {
126
+ if (!usable) return;
127
+ const endpoint = endpointFromDraft(draft);
128
+ if (!active && endpoint === void 0) {
129
+ setMessage(t("invalid"));
130
+ return;
131
+ }
132
+ setBusy(true);
133
+ setMessage(void 0);
134
+ try {
135
+ await persist(active ? void 0 : endpoint, active ? { kind: "direct" } : {
136
+ kind: "profile",
137
+ profileId: "default"
138
+ });
139
+ setMessage(active ? t("disabled") : t("enabled"));
140
+ } catch (error) {
141
+ setMessage(error instanceof Error ? error.message : String(error));
142
+ } finally {
143
+ setBusy(false);
144
+ }
145
+ };
146
+ const test = async () => {
147
+ const endpoint = endpointFromDraft(draft);
148
+ if (endpoint === void 0 || busy) {
149
+ setMessage(t("invalid"));
150
+ return;
151
+ }
152
+ setBusy(true);
153
+ setMessage(t("testing"));
154
+ try {
155
+ const result = await probe(endpoint);
156
+ setMessage(result.ok ? t("testOk", { duration: result.totalMs }) : result.error ?? t("testFailed"));
157
+ } catch (error) {
158
+ setMessage(error instanceof Error ? error.message : String(error));
159
+ } finally {
160
+ setBusy(false);
161
+ }
162
+ };
163
+ const find = async () => {
164
+ if (busy) return;
165
+ setBusy(true);
166
+ setMessage(t("discovering"));
167
+ try {
168
+ const result = await discover();
169
+ setDiscovered(result.candidates);
170
+ setMessage(result.candidates.length > 0 ? t("discovered", { count: result.candidates.length }) : t("noneFound"));
171
+ } catch (error) {
172
+ setMessage(error instanceof Error ? error.message : String(error));
173
+ } finally {
174
+ setBusy(false);
175
+ }
176
+ };
177
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
178
+ className: ProxySettingsRow_module_css_default.row,
179
+ "data-proxy-settings-row": true,
180
+ children: [
181
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
182
+ className: ProxySettingsRow_module_css_default.heading,
183
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
184
+ className: ProxySettingsRow_module_css_default.title,
185
+ children: t("title")
186
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
187
+ className: ProxySettingsRow_module_css_default.hint,
188
+ children: active ? t("active") : t("direct")
189
+ })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
190
+ className: ProxySettingsRow_module_css_default.toggle,
191
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
192
+ type: "checkbox",
193
+ checked: active,
194
+ disabled: !usable,
195
+ onChange: () => {
196
+ toggle();
197
+ }
198
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: active ? t("enabledLabel") : t("disabledLabel") })]
199
+ })]
200
+ }),
201
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
202
+ className: ProxySettingsRow_module_css_default.fields,
203
+ children: [
204
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
205
+ className: ProxySettingsRow_module_css_default.field,
206
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("protocol") }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
207
+ style: fieldStyle,
208
+ value: draft.protocol ?? "",
209
+ disabled: !usable,
210
+ onChange: (event) => {
211
+ const value = event.target.value;
212
+ if (value === "http" || value === "socks5") setDraft({
213
+ ...draft,
214
+ protocol: value
215
+ });
216
+ else {
217
+ const { protocol: _protocol, ...rest } = draft;
218
+ setDraft(rest);
219
+ }
220
+ },
221
+ children: [
222
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
223
+ value: "",
224
+ children: t("chooseProtocol")
225
+ }),
226
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
227
+ value: "http",
228
+ children: "HTTP"
229
+ }),
230
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
231
+ value: "socks5",
232
+ children: "SOCKS5"
233
+ })
234
+ ]
235
+ })]
236
+ }),
237
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
238
+ className: ProxySettingsRow_module_css_default.fieldWide,
239
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("host") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
240
+ style: fieldStyle,
241
+ value: draft.host ?? "",
242
+ disabled: !usable,
243
+ placeholder: "127.0.0.1",
244
+ onChange: (event) => {
245
+ setDraft({
246
+ ...draft,
247
+ host: event.target.value
248
+ });
249
+ }
250
+ })]
251
+ }),
252
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
253
+ className: ProxySettingsRow_module_css_default.fieldPort,
254
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("port") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
255
+ style: fieldStyle,
256
+ type: "number",
257
+ min: 1,
258
+ max: 65535,
259
+ value: draft.port ?? "",
260
+ disabled: !usable,
261
+ placeholder: "7897",
262
+ onChange: (event) => {
263
+ const value = event.target.value;
264
+ if (value === "") {
265
+ const { port: _port, ...rest } = draft;
266
+ setDraft(rest);
267
+ } else setDraft({
268
+ ...draft,
269
+ port: Number(value)
270
+ });
271
+ }
272
+ })]
273
+ })
274
+ ]
275
+ }),
276
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
277
+ className: ProxySettingsRow_module_css_default.actions,
278
+ children: [
279
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
280
+ type: "button",
281
+ style: actionStyle,
282
+ disabled: busy,
283
+ onClick: () => {
284
+ find();
285
+ },
286
+ children: t("discover")
287
+ }),
288
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
289
+ type: "button",
290
+ style: actionStyle,
291
+ disabled: !endpointValid(draft) || busy,
292
+ onClick: () => {
293
+ test();
294
+ },
295
+ children: t("test")
296
+ }),
297
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
298
+ type: "button",
299
+ style: actionStyle,
300
+ disabled: !usable,
301
+ onClick: () => {
302
+ save();
303
+ },
304
+ children: t("save")
305
+ })
306
+ ]
307
+ }),
308
+ discovered.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
309
+ className: ProxySettingsRow_module_css_default.candidates,
310
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("candidateLabel") }), discovered.map((candidate) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
311
+ type: "button",
312
+ style: actionStyle,
313
+ onClick: () => {
314
+ setDraft({
315
+ ...draft,
316
+ protocol: candidate.protocol,
317
+ host: candidate.host,
318
+ port: candidate.port
319
+ });
320
+ },
321
+ children: [
322
+ candidate.protocol,
323
+ "://",
324
+ candidate.host,
325
+ ":",
326
+ candidate.port
327
+ ]
328
+ }, `${candidate.protocol}:${candidate.host}:${candidate.port}`))]
329
+ }) : null,
330
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
331
+ className: ProxySettingsRow_module_css_default.note,
332
+ children: t("manualHint")
333
+ }),
334
+ message ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
335
+ className: ProxySettingsRow_module_css_default.message,
336
+ role: "status",
337
+ children: message
338
+ }) : null
339
+ ]
340
+ });
341
+ }
342
+ //#endregion
343
+ //#region src/client/settings-store.ts
344
+ function createProxySettingsStore() {
345
+ return (0, _deepseek_ai_dsh_client_runtime_client.defineStore)({
346
+ init: () => ({ snapshot: {
347
+ status: "loading",
348
+ value: void 0,
349
+ base: void 0,
350
+ user: void 0,
351
+ revision: void 0,
352
+ writable: false,
353
+ mode: "memory"
354
+ } }),
355
+ actions: { sync: (draft, snapshot) => {
356
+ draft.snapshot = snapshot;
357
+ } }
358
+ });
359
+ }
360
+ //#endregion
361
+ //#region src/client/locales.ts
362
+ const zh = {
363
+ "title": "网络代理",
364
+ "active": "Agent 当前使用代理出口",
365
+ "direct": "Agent 当前保持直连",
366
+ "enabledLabel": "已启用",
367
+ "disabledLabel": "未启用",
368
+ "protocol": "协议",
369
+ "chooseProtocol": "选择协议",
370
+ "host": "Host",
371
+ "port": "Port",
372
+ "discover": "发现本机代理",
373
+ "test": "测试连接",
374
+ "save": "保存",
375
+ "invalid": "请填写有效的 HTTP/SOCKS5 host 和 1-65535 端口。",
376
+ "saved": "代理端点已保存。",
377
+ "enabled": "代理路由已启用。",
378
+ "disabled": "Agent 已恢复直连。",
379
+ "testing": "正在测试代理链路…",
380
+ "testOk": "代理链路正常({duration}ms)。",
381
+ "testFailed": "代理链路不可用。",
382
+ "discovering": "正在查找已运行的代理候选…",
383
+ "discovered": "发现 {count} 个候选,请点击候选填入后再测试。",
384
+ "noneFound": "未发现可用候选;请向用户询问代理地址。",
385
+ "discoverFailed": "无法执行代理发现。",
386
+ "candidateLabel": "候选:",
387
+ "manualHint": "插件只接入已经运行的代理;发现和测试不会自动启用代理。"
388
+ };
389
+ const en = {
390
+ "title": "Network Proxy",
391
+ "active": "Agent traffic currently uses the proxy route",
392
+ "direct": "Agent traffic currently stays direct",
393
+ "enabledLabel": "Enabled",
394
+ "disabledLabel": "Disabled",
395
+ "protocol": "Protocol",
396
+ "chooseProtocol": "Choose protocol",
397
+ "host": "Host",
398
+ "port": "Port",
399
+ "discover": "Find local proxy",
400
+ "test": "Test connection",
401
+ "save": "Save",
402
+ "invalid": "Enter an HTTP/SOCKS5 host and a port from 1 to 65535.",
403
+ "saved": "Proxy endpoint saved.",
404
+ "enabled": "Proxy routing enabled.",
405
+ "disabled": "Agent routing restored to direct.",
406
+ "testing": "Testing the proxy route…",
407
+ "testOk": "Proxy route is reachable ({duration}ms).",
408
+ "testFailed": "Proxy route is unavailable.",
409
+ "discovering": "Looking for an already-running local proxy…",
410
+ "discovered": "Found {count} candidates. Select one, then test it.",
411
+ "noneFound": "No usable candidate found. Ask the user for the proxy address.",
412
+ "discoverFailed": "Proxy discovery could not run.",
413
+ "candidateLabel": "Candidates:",
414
+ "manualHint": "This plugin connects to an existing proxy; discovery and testing never enable it automatically."
415
+ };
416
+ //#endregion
417
+ //#region src/client/index.ts
418
+ const SETTINGS_NS = "settings.proxyRouting";
419
+ const PROXY_ROUTING_NAMESPACE = "proxy-routing";
420
+ const PROXY_RPC_CHANNEL = "/proxy-agent";
421
+ const inject = [
422
+ "slots",
423
+ "locale",
424
+ "connection",
425
+ "remote",
426
+ "settingsScope"
427
+ ];
428
+ function valueOf(result) {
429
+ if (!result || typeof result !== "object") throw new Error("proxy diagnostic returned no result");
430
+ const answer = result;
431
+ if (answer.ok !== true) throw new Error(answer.error?.message ?? "proxy diagnostic failed");
432
+ return answer.value;
433
+ }
434
+ function apply(ctx) {
435
+ const scope = ctx.settingsScope.bind({ namespace: PROXY_ROUTING_NAMESPACE });
436
+ const store = createProxySettingsStore();
437
+ let bound;
438
+ const sync = () => {
439
+ bound?.sync(scope.getSnapshot());
440
+ };
441
+ ctx.effect(() => scope.subscribe(sync), "proxy-routing: settings snapshot");
442
+ ctx.effect(() => ctx.locale.register(SETTINGS_NS, {
443
+ zh,
444
+ en
445
+ }), "proxy-routing: settings dictionaries");
446
+ const injected = (actions) => {
447
+ bound = actions;
448
+ sync();
449
+ const connection = ctx.get("connection");
450
+ return {
451
+ persist: async (endpoint, agent) => {
452
+ const revision = scope.getSnapshot().revision;
453
+ valueOf(await connection.rpc.call(PROXY_RPC_CHANNEL, "mutate", {
454
+ ...endpoint === void 0 ? {} : { endpoint },
455
+ ...agent === void 0 ? {} : { agent },
456
+ ...revision === void 0 ? {} : { expectedRevision: revision }
457
+ }));
458
+ },
459
+ probe: async (endpoint) => valueOf(await connection.rpc.call(PROXY_RPC_CHANNEL, "probe", endpoint)),
460
+ discover: async () => valueOf(await connection.rpc.call(PROXY_RPC_CHANNEL, "discover", {}))
461
+ };
462
+ };
463
+ ctx.slots.inject("settings.general.item", () => ctx.slots.register({
464
+ name: "settings.general.item",
465
+ id: "proxy-routing",
466
+ order: 20,
467
+ locale: SETTINGS_NS,
468
+ store,
469
+ inject: injected
470
+ }, ProxySettingsRow));
471
+ }
472
+ //#endregion
473
+ exports.SETTINGS_NS = SETTINGS_NS;
474
+ exports.apply = apply;
475
+ exports.inject = inject;
476
+ return module.exports;
477
+ }
478
+ });
479
+
480
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","names":["useState","css","defineStore"],"sources":["../src/client/ProxySettingsRow.tsx","../src/client/settings-store.ts","../src/client/locales.ts","../src/client/index.ts"],"sourcesContent":["import { useEffect, useState } from 'react'\nimport type { CSSProperties, ReactNode } from 'react'\nimport type { PropsLocale, PropsRuntime, PropsStore } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { SettingsScopeSnapshot } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { createProxySettingsStore } from './settings-store.ts'\nimport css from './ProxySettingsRow.module.css'\n\nexport interface ProxySettingsRowInjected {\n persist: (endpoint: ProxyEndpoint | undefined, agent?: ProxySettings['bindings']['agent']) => Promise<void>\n probe: (endpoint: ProxyEndpoint) => Promise<ProbeResult>\n discover: () => Promise<DiscoveryResult>\n}\n\nexport type ProxySettingsRowProps =\n PropsRuntime<'settings.general.item'>\n & PropsLocale<'settings.proxyRouting'>\n & PropsStore<ReturnType<typeof createProxySettingsStore>>\n & ProxySettingsRowInjected\n\nexport interface ProxyEndpoint {\n protocol: 'http' | 'socks5'\n host: string\n port: number\n}\n\nexport interface ProxyProfile {\n id: string\n protocol?: 'http' | 'socks5'\n host?: string\n port?: number\n username?: string\n password?: string\n noProxy?: string[]\n timeout?: number\n}\n\nexport interface ProxySettings {\n version: number\n profiles: ProxyProfile[]\n bindings: {\n agent: { kind: 'direct' | 'profile'; profileId?: string }\n providers?: unknown[]\n gateway?: unknown\n gatewayPurposes?: unknown[]\n }\n gateway?: unknown\n}\n\nexport interface ProbeResult {\n ok: boolean\n connectMs: number\n totalMs: number\n httpStatus: number\n error?: string\n}\n\nexport interface DiscoveryCandidate extends ProxyEndpoint {\n source: string\n ok: boolean\n connectMs: number\n totalMs: number\n httpStatus?: number\n error?: string\n}\n\nexport interface DiscoveryResult {\n scanned: number\n candidates: DiscoveryCandidate[]\n}\n\nconst fieldStyle: CSSProperties = {\n minWidth: 0,\n height: 34,\n padding: '0 10px',\n border: '1px solid var(--dsw-alias-border-l2)',\n borderRadius: 8,\n background: 'var(--dsw-alias-bg-layer-3)',\n color: 'var(--dsw-alias-label-primary)',\n font: 'inherit',\n fontSize: 13,\n}\n\nconst actionStyle: CSSProperties = {\n minHeight: 30,\n padding: '0 10px',\n border: '1px solid var(--dsw-alias-border-l2)',\n borderRadius: 7,\n background: 'var(--dsw-alias-bg-layer-3)',\n color: 'var(--dsw-alias-label-secondary)',\n cursor: 'pointer',\n font: 'inherit',\n fontSize: 12,\n}\n\nfunction snapshotProfile(snapshot: SettingsScopeSnapshot<ProxySettings>): ProxyProfile | undefined {\n return snapshot.value?.profiles?.find(profile => profile.id === 'default') ?? snapshot.value?.profiles?.[0]\n}\n\nfunction useProxyDraft(\n snapshot: SettingsScopeSnapshot<ProxySettings>,\n): [ProxyProfile, (value: ProxyProfile) => void] {\n const profile = snapshotProfile(snapshot) ?? { id: 'default' }\n const [draft, setDraft] = useState<ProxyProfile>(profile)\n const [revision, setRevision] = useState(snapshot.revision)\n useEffect(() => {\n if (snapshot.revision === revision) return\n setRevision(snapshot.revision)\n setDraft(profile)\n }, [profile, revision, snapshot.revision])\n return [draft, setDraft]\n}\n\nfunction endpointFromDraft(draft: ProxyProfile): ProxyEndpoint | undefined {\n const port = draft.port\n if ((draft.protocol !== 'http' && draft.protocol !== 'socks5')\n || typeof draft.host !== 'string'\n || draft.host.trim().length === 0\n || typeof port !== 'number'\n || !Number.isInteger(port)\n || port < 1\n || port > 65535) return undefined\n return { protocol: draft.protocol, host: draft.host.trim(), port }\n}\n\nfunction endpointValid(draft: ProxyProfile): boolean {\n return endpointFromDraft(draft) !== undefined\n}\n\nexport function ProxySettingsRow({ t, useStore, persist, probe, discover }: ProxySettingsRowProps): ReactNode {\n const settings = useStore(state => state.snapshot)\n const [draft, setDraft] = useProxyDraft(settings)\n const [busy, setBusy] = useState(false)\n const [message, setMessage] = useState<string>()\n const [discovered, setDiscovered] = useState<DiscoveryCandidate[]>([])\n const active = settings.value?.bindings?.agent?.kind === 'profile'\n const usable = settings.status === 'ready' && settings.writable && !busy\n\n if (settings.status === 'unavailable') return null\n\n const saveProfile = async (): Promise<boolean> => {\n if (!endpointValid(draft)) {\n setMessage(t('invalid'))\n return false\n }\n setBusy(true)\n setMessage(undefined)\n try {\n const endpoint = endpointFromDraft(draft)\n if (endpoint === undefined) return false\n await persist(endpoint)\n return true\n } finally {\n setBusy(false)\n }\n }\n\n const save = async (): Promise<void> => {\n if (!usable) return\n try {\n if (await saveProfile()) setMessage(t('saved'))\n } catch (error) {\n setMessage(error instanceof Error ? error.message : String(error))\n }\n }\n\n const toggle = async (): Promise<void> => {\n if (!usable) return\n const endpoint = endpointFromDraft(draft)\n if (!active && endpoint === undefined) {\n setMessage(t('invalid'))\n return\n }\n setBusy(true)\n setMessage(undefined)\n try {\n await persist(active ? undefined : endpoint, active\n ? { kind: 'direct' }\n : { kind: 'profile', profileId: 'default' })\n setMessage(active ? t('disabled') : t('enabled'))\n } catch (error) {\n setMessage(error instanceof Error ? error.message : String(error))\n } finally {\n setBusy(false)\n }\n }\n\n const test = async (): Promise<void> => {\n const endpoint = endpointFromDraft(draft)\n if (endpoint === undefined || busy) {\n setMessage(t('invalid'))\n return\n }\n setBusy(true)\n setMessage(t('testing'))\n try {\n const result = await probe(endpoint)\n setMessage(result.ok ? t('testOk', { duration: result.totalMs }) : result.error ?? t('testFailed'))\n } catch (error) {\n setMessage(error instanceof Error ? error.message : String(error))\n } finally {\n setBusy(false)\n }\n }\n\n const find = async (): Promise<void> => {\n if (busy) return\n setBusy(true)\n setMessage(t('discovering'))\n try {\n const result = await discover()\n setDiscovered(result.candidates)\n setMessage(result.candidates.length > 0\n ? t('discovered', { count: result.candidates.length })\n : t('noneFound'))\n } catch (error) {\n setMessage(error instanceof Error ? error.message : String(error))\n } finally {\n setBusy(false)\n }\n }\n\n return (\n <div className={css.row} data-proxy-settings-row>\n <div className={css.heading}>\n <div>\n <div className={css.title}>{t('title')}</div>\n <p className={css.hint}>{active ? t('active') : t('direct')}</p>\n </div>\n <label className={css.toggle}>\n <input type=\"checkbox\" checked={active} disabled={!usable} onChange={() => { void toggle() }} />\n <span>{active ? t('enabledLabel') : t('disabledLabel')}</span>\n </label>\n </div>\n <div className={css.fields}>\n <label className={css.field}>\n <span>{t('protocol')}</span>\n <select style={fieldStyle} value={draft.protocol ?? ''} disabled={!usable} onChange={event => {\n const value = event.target.value\n if (value === 'http' || value === 'socks5') {\n setDraft({ ...draft, protocol: value })\n } else {\n const { protocol: _protocol, ...rest } = draft\n setDraft(rest)\n }\n }}>\n <option value=\"\">{t('chooseProtocol')}</option>\n <option value=\"http\">HTTP</option>\n <option value=\"socks5\">SOCKS5</option>\n </select>\n </label>\n <label className={css.fieldWide}>\n <span>{t('host')}</span>\n <input style={fieldStyle} value={draft.host ?? ''} disabled={!usable} placeholder=\"127.0.0.1\" onChange={event => { setDraft({ ...draft, host: event.target.value }) }} />\n </label>\n <label className={css.fieldPort}>\n <span>{t('port')}</span>\n <input style={fieldStyle} type=\"number\" min={1} max={65535} value={draft.port ?? ''} disabled={!usable} placeholder=\"7897\" onChange={event => {\n const value = event.target.value\n if (value === '') {\n const { port: _port, ...rest } = draft\n setDraft(rest)\n } else {\n setDraft({ ...draft, port: Number(value) })\n }\n }} />\n </label>\n </div>\n <div className={css.actions}>\n <button type=\"button\" style={actionStyle} disabled={busy} onClick={() => { void find() }}>{t('discover')}</button>\n <button type=\"button\" style={actionStyle} disabled={!endpointValid(draft) || busy} onClick={() => { void test() }}>{t('test')}</button>\n <button type=\"button\" style={actionStyle} disabled={!usable} onClick={() => { void save() }}>{t('save')}</button>\n </div>\n {discovered.length > 0 ? (\n <div className={css.candidates}>\n <span>{t('candidateLabel')}</span>\n {discovered.map(candidate => (\n <button key={`${candidate.protocol}:${candidate.host}:${candidate.port}`} type=\"button\" style={actionStyle} onClick={() => { setDraft({ ...draft, protocol: candidate.protocol, host: candidate.host, port: candidate.port }) }}>\n {candidate.protocol}://{candidate.host}:{candidate.port}\n </button>\n ))}\n </div>\n ) : null}\n <p className={css.note}>{t('manualHint')}</p>\n {message ? <p className={css.message} role=\"status\">{message}</p> : null}\n </div>\n )\n}\n","import { defineStore, type EngineStoreHandle } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { BoundActions } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { SettingsScopeSnapshot } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { ProxySettings } from './ProxySettingsRow.tsx'\n\nexport interface ProxySettingsRowState {\n snapshot: SettingsScopeSnapshot<ProxySettings>\n}\n\ntype ProxySettingsRowActions = {\n sync: (draft: ProxySettingsRowState, snapshot: SettingsScopeSnapshot<ProxySettings>) => void\n}\n\nexport function createProxySettingsStore(): EngineStoreHandle<ProxySettingsRowState, ProxySettingsRowActions> {\n return defineStore({\n init: (): ProxySettingsRowState => ({\n snapshot: {\n status: 'loading',\n value: undefined,\n base: undefined,\n user: undefined,\n revision: undefined,\n writable: false,\n mode: 'memory',\n },\n }),\n actions: {\n sync: (draft, snapshot) => { draft.snapshot = snapshot },\n },\n })\n}\n\nexport type ProxySettingsRowBoundActions = BoundActions<ReturnType<typeof createProxySettingsStore>>\n","export const zh = {\n 'title': '网络代理',\n 'active': 'Agent 当前使用代理出口',\n 'direct': 'Agent 当前保持直连',\n 'enabledLabel': '已启用',\n 'disabledLabel': '未启用',\n 'protocol': '协议',\n 'chooseProtocol': '选择协议',\n 'host': 'Host',\n 'port': 'Port',\n 'discover': '发现本机代理',\n 'test': '测试连接',\n 'save': '保存',\n 'invalid': '请填写有效的 HTTP/SOCKS5 host 和 1-65535 端口。',\n 'saved': '代理端点已保存。',\n 'enabled': '代理路由已启用。',\n 'disabled': 'Agent 已恢复直连。',\n 'testing': '正在测试代理链路…',\n 'testOk': '代理链路正常({duration}ms)。',\n 'testFailed': '代理链路不可用。',\n 'discovering': '正在查找已运行的代理候选…',\n 'discovered': '发现 {count} 个候选,请点击候选填入后再测试。',\n 'noneFound': '未发现可用候选;请向用户询问代理地址。',\n 'discoverFailed': '无法执行代理发现。',\n 'candidateLabel': '候选:',\n 'manualHint': '插件只接入已经运行的代理;发现和测试不会自动启用代理。',\n} as const\n\nexport const en = {\n 'title': 'Network Proxy',\n 'active': 'Agent traffic currently uses the proxy route',\n 'direct': 'Agent traffic currently stays direct',\n 'enabledLabel': 'Enabled',\n 'disabledLabel': 'Disabled',\n 'protocol': 'Protocol',\n 'chooseProtocol': 'Choose protocol',\n 'host': 'Host',\n 'port': 'Port',\n 'discover': 'Find local proxy',\n 'test': 'Test connection',\n 'save': 'Save',\n 'invalid': 'Enter an HTTP/SOCKS5 host and a port from 1 to 65535.',\n 'saved': 'Proxy endpoint saved.',\n 'enabled': 'Proxy routing enabled.',\n 'disabled': 'Agent routing restored to direct.',\n 'testing': 'Testing the proxy route…',\n 'testOk': 'Proxy route is reachable ({duration}ms).',\n 'testFailed': 'Proxy route is unavailable.',\n 'discovering': 'Looking for an already-running local proxy…',\n 'discovered': 'Found {count} candidates. Select one, then test it.',\n 'noneFound': 'No usable candidate found. Ask the user for the proxy address.',\n 'discoverFailed': 'Proxy discovery could not run.',\n 'candidateLabel': 'Candidates:',\n 'manualHint': 'This plugin connects to an existing proxy; discovery and testing never enable it automatically.',\n} satisfies Record<keyof typeof zh, string>\n\nexport type ProxySettingsLocaleKey = keyof typeof zh\n","import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { BoundActions } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-client-connection/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\nimport { ProxySettingsRow } from './ProxySettingsRow.tsx'\nimport type { ProxyEndpoint, ProxySettings, ProxySettingsRowInjected } from './ProxySettingsRow.tsx'\nimport { createProxySettingsStore } from './settings-store.ts'\nimport { en, zh, type ProxySettingsLocaleKey } from './locales.ts'\n\nexport const SETTINGS_NS = 'settings.proxyRouting'\nconst PROXY_ROUTING_NAMESPACE = 'proxy-routing'\nconst PROXY_RPC_CHANNEL = '/proxy-agent'\n\ntype AgentRoute = ProxySettings['bindings']['agent']\n\ntype ProxyMutationResult = { settingsRevision?: number }\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n 'settings.proxyRouting': ProxySettingsLocaleKey\n }\n}\n\nexport const inject = ['slots', 'locale', 'connection', 'remote', 'settingsScope']\n\nfunction valueOf<T>(result: unknown): T {\n if (!result || typeof result !== 'object') throw new Error('proxy diagnostic returned no result')\n const answer = result as { ok?: boolean; value?: unknown; error?: { message?: string } }\n if (answer.ok !== true) throw new Error(answer.error?.message ?? 'proxy diagnostic failed')\n return answer.value as T\n}\n\nexport function apply(ctx: ClientContext): void {\n const scope = ctx.settingsScope.bind<ProxySettings>({ namespace: PROXY_ROUTING_NAMESPACE })\n const store = createProxySettingsStore()\n let bound: BoundActions<typeof store> | undefined\n const sync = (): void => { bound?.sync(scope.getSnapshot()) }\n ctx.effect(() => scope.subscribe(sync), 'proxy-routing: settings snapshot')\n ctx.effect(() => ctx.locale.register(SETTINGS_NS, { zh, en }), 'proxy-routing: settings dictionaries')\n\n const injected = (actions: BoundActions<typeof store>): ProxySettingsRowInjected => {\n bound = actions\n sync()\n const connection = ctx.get('connection') as ConnectionHandle\n return {\n persist: async (endpoint: ProxyEndpoint | undefined, agent?: AgentRoute) => {\n const revision = scope.getSnapshot().revision\n const result = await connection.rpc.call(PROXY_RPC_CHANNEL, 'mutate', {\n ...(endpoint === undefined ? {} : { endpoint }),\n ...(agent === undefined ? {} : { agent }),\n ...(revision === undefined ? {} : { expectedRevision: revision }),\n })\n valueOf<ProxyMutationResult>(result)\n },\n probe: async (endpoint: ProxyEndpoint) => valueOf(await connection.rpc.call(PROXY_RPC_CHANNEL, 'probe', endpoint)),\n discover: async () => valueOf(await connection.rpc.call(PROXY_RPC_CHANNEL, 'discover', {})),\n }\n }\n ctx.slots.inject('settings.general.item', () => ctx.slots.register({\n name: 'settings.general.item',\n id: 'proxy-routing',\n order: 20,\n locale: SETTINGS_NS,\n store,\n inject: injected,\n }, ProxySettingsRow))\n}\n"],"mappings":"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"}