dsh-deeppilot 0.9.15 → 0.9.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -77,8 +77,11 @@ Simulator or when the camera is unavailable. Switching between the LAN and
77
77
  public address issues a matching new QR code and string immediately, with the
78
78
  panel staying open.
79
79
 
80
- LAN access is enabled by default on the plugin's independent TCP port `3098`
81
- and is TLS-only. The plugin generates a self-signed certificate on first start
80
+ LAN access is always on (there is no switch) on the plugin's independent TCP
81
+ port `3098` and is TLS-only. After every connection the plugin tells the app
82
+ its current LAN addresses and the public Funnel address, so a paired phone
83
+ connects over the LAN on the same Wi-Fi and falls back to Funnel elsewhere,
84
+ without pairing again. The plugin generates a self-signed certificate on first start
82
85
  (key under `$DSH_HOME/deeppilot/lan-tls/`), and the pairing QR code carries its
83
86
  public-key fingerprint so the app pins that exact Host. DSH may continue
84
87
  listening only on `127.0.0.1:3080`; the plugin no longer registers any `/phone`
package/README.zh-CN.md CHANGED
@@ -64,7 +64,9 @@ DSH 重启后,打开 **设置 → DeepPilot**,开启“允许手机连接”
64
64
  与证书指纹),在 App 里粘贴一次即可完成配对,适合模拟器或相机不可用时使用;在「内网 /
65
65
  公网」之间切换会立即为所选地址生成新的二维码与配对信息,面板保持展开。
66
66
 
67
- 局域网连接默认使用插件独立的 TCP `3098` 端口,且只提供 TLS。插件首次启动时生成
67
+ 局域网连接始终开启(没有开关),使用插件独立的 TCP `3098` 端口,且只提供 TLS。每次连上后,
68
+ 插件会把当前的局域网地址和公网 Funnel 地址告诉 App:同一 Wi-Fi 下手机自动走局域网,在外自动
69
+ 改走 Funnel,不需要重新配对。插件首次启动时生成
68
70
  自签证书(私钥位于 `$DSH_HOME/deeppilot/lan-tls/`),配对二维码携带其公钥指纹,
69
71
  App 只信任与该指纹一致的主机。DSH 可以继续只监听 `127.0.0.1:3080`;插件不再在
70
72
  DSH Web 服务上注册任何 `/phone` 路由。启用系统防火墙时,请仅在你使用的网络放行
package/bin/SHA256SUMS CHANGED
@@ -1,6 +1,6 @@
1
- c79c889415f6fce13a2d0f19c94e2ceb5cbfc06ec5c841c1002092783663a6a6 ./darwin-amd64/dsh-deeppilot-tunnel
2
- affe9151e5356b574e1a85c806b198c39b5804f3a305b655cd3eb03c628ae0cc ./darwin-arm64/dsh-deeppilot-tunnel
3
- a2475a2844250a6ef03853fe64db63eb1a163d9fcd7f3f438f3ec7a142d3a044 ./linux-amd64/dsh-deeppilot-tunnel
4
- 6241de8d3c67e6e2af98e6b6040a10d9352183f893d3aed82c879a76c8b79432 ./linux-arm64/dsh-deeppilot-tunnel
5
- 9449d3c48cc11446cd0f35c030f28000b5934512512fc1d7eeaa769d8d8304f3 ./windows-amd64/dsh-deeppilot-tunnel.exe
6
- fd0c912b5b39ba8bd385cb05c39665d89519c75b6f5ddbc506b7554926f6545f ./windows-arm64/dsh-deeppilot-tunnel.exe
1
+ eecc0241e0940e901c7f0bcda96945c22dcc5b24bd27349c391231d0398e50c2 ./darwin-amd64/dsh-deeppilot-tunnel
2
+ e834c3d5e02abe0fc459b99ba3dd4f8e9b63f9f94ade402ab8bfaf34720dea86 ./darwin-arm64/dsh-deeppilot-tunnel
3
+ 1bcb0af171a9491566ec26f971930eb97a380f1a0db1d8dd55ee5e1fff46a9c5 ./linux-amd64/dsh-deeppilot-tunnel
4
+ 555846f645f3bbfcf96250d4a7e981829cfaf3e1bcda8b7854cf3b74b8cc4505 ./linux-arm64/dsh-deeppilot-tunnel
5
+ 725213a7302f325f098c6313ef38bf3a60e9b0929e4705e3f2e03e5977dca502 ./windows-amd64/dsh-deeppilot-tunnel.exe
6
+ 90cb4018d48e7e0b637d50d7725a8c1782fc93e8775b429380a979e3a8b04887 ./windows-arm64/dsh-deeppilot-tunnel.exe
@@ -34,12 +34,10 @@
34
34
  npm 不在保存配置时验证绑定;首次发布成功才证明认证可用。
35
35
  4. 新绑定必须在 **2 天内完成首次成功发布**。因此准备好新版本后再绑定;若过期,
36
36
  删除过期绑定并重新创建。先验证可信发布成功,再按需调整原有令牌发布权限。
37
- 5. **2026-10-29 实测:当前绑定只允许暂存发布。** `publish.yml` 里的 `npm publish`
38
- 不再直接公开版本,而是把它送进 staged 区(命令返回成功并提示“正在处理”,
39
- 但注册表的版本、tarball 与来源证明持续 404)。用户决定**保留暂存流程**:
40
- 每次发版由工作流暂存,维护者用 2FA 批准后才公开(步骤见第三节)。
41
- 若要恢复直接发布,需在包设置的 Trusted Publisher 中勾选 `Allow npm publish`
42
- (账户强制 2FA 时可能不可用),并同步改本节、AGENTS.md 与第 4 步的核对逻辑。
37
+ 5. **当前绑定允许直接发布(2026-11-05 起)。** 2026-10-29 实测绑定只允许暂存发布:
38
+ `npm publish` 把版本送进 staged 区,需维护者 2FA 批准后才公开(见第四节第 11 条)。
39
+ 2026-11-05 用户在 Trusted Publisher 中勾选 `Allow npm publish`,改为工作流直接公开,
40
+ 不再需要批准;首次直接发布的结果在下一次发版时核实并记入第四节。
43
41
 
44
42
  ## 三、每次发布
45
43
 
@@ -69,13 +67,11 @@
69
67
  压缩包发布跳过生命周期脚本(`--ignore-scripts`);测试、类型检查和构建已在前序
70
68
  步骤执行,打包仍执行 `prepack`(打包前构建)。发布后核对版本、分发标签、
71
69
  压缩包完整性和来源证明元数据。
72
- 6. **批准暂存版本(暂存模式下必需)。** 工作流把版本送进 staged 区后,由维护者完成
73
- 2FA 批准:在 npmjs.com 的 **Staged Packages** 标签找到
74
- `dsh-deeppilot@<版本>` → Approve;或本机 `npm login` 后
75
- `npm stage list dsh-deeppilot` → `npm stage approve <id>`。
76
- 批准即公开该版本,并按发布命令写入分发标签(`latest` / `alpha`)。
77
- 工作流末尾「核对发布版本、包完整性与来源证明」在批准前必然 404 失败、整次运行标红;
78
- 这是暂存模式的预期结果,不代表上传失败,发布证据以批准后的手工核验为准。
70
+ 6. 发布步骤直接公开版本并写入分发标签(`latest` / `alpha`),末尾核对随即通过。
71
+ 若核对持续 404、发布步骤提示进入 staged 区,说明绑定退回暂存模式:维护者在
72
+ npmjs.com 的 **Staged Packages** 标签用 2FA 批准 `dsh-deeppilot@<版本>`(或本机
73
+ `npm login` 后 `npm stage list dsh-deeppilot` → `npm stage approve <id>`),
74
+ 同一版本不能重跑工作流(`E409 Cannot publish over previously staged version`)。
79
75
  7. 确认 npm 包可安装,在全新 DSH 配置中完成安装验证后,再公开 GitHub 发布草稿。
80
76
  工作流不自动公开发布草稿;npm 上传和发布后的核对分别记录在步骤中。
81
77
 
@@ -203,6 +199,18 @@
203
199
  `/phone/health` 返回 200,`serverVersion` 为 `0.9.14`、`protocolVersion` 2、
204
200
  `dataPlane: true`;GitHub Release 在这一步通过后才公开并标记 Latest。
205
201
 
202
+ 13. `0.9.15` 的实际发布结果(2026-11-05):发布提交 `688dabc` 直接推到 `main`,
203
+ CI(运行号 `42036820848`)与 CodeQL(`42036820840`)均绿;附注标签 `v0.9.15` 指向
204
+ `688dabcc1b8c5f73664633750c47cb90fad1caac`。`publish.yml` 运行 `42037502337`
205
+ (`latest`)**整次为绿**:本次仍进入 staged 区,维护者在末尾核对的重试窗口内批准,
206
+ 并同时勾选 `Allow npm publish`,下次发版起直接公开。注册表 `latest = 0.9.15`;
207
+ 来源证明类型为 `https://slsa.dev/provenance/v1`、`gitCommit` 为该提交、工作流引用
208
+ `refs/tags/v0.9.15`、invocation 为 `42037502337`;69 个条目、解包 131,613,948 字节,
209
+ 与本地 `npm pack --dry-run` 一致。随后在全新隔离 `DSH_HOME` 中从 npm 安装
210
+ `dsh-deeppilot@0.9.15`,用真实 `0.2.2-rc.1` 宿主启动:插件自有端口 `/phone/health`
211
+ 返回 200,`serverVersion` 为 `0.9.15`、`protocolVersion` 2、`dataPlane: true`,
212
+ 日志显示按需完成通知工具已注册;GitHub Release 在这一步通过后才公开并标记 Latest。
213
+
206
214
  ## 五、官方资料
207
215
 
208
216
  1. [npm 可信发布配置与限制](https://docs.npmjs.com/trusted-publishers/)
package/lib/client.js CHANGED
@@ -572,6 +572,7 @@ window.__ModuleLoader__.load({
572
572
  "system.title": "运行信息",
573
573
  "system.description": "插件、协议与连接端点的技术信息。",
574
574
  "local.title": "局域网连接",
575
+ "local.autoRoute": "局域网连接始终开启:手机和电脑在同一 Wi-Fi 下会自动走局域网,在外面自动改走公网。",
575
576
  "local.on": "已开启:手机可通过独立端口 {port} 以 TLS 加密连接。",
576
577
  "local.off": "已关闭:不接受局域网连接。",
577
578
  "local.tlsFingerprint": "证书指纹",
@@ -747,7 +748,6 @@ window.__ModuleLoader__.load({
747
748
  "diag.settingsUnavailable": "设置表单不可用(configForms 未提供)",
748
749
  "diag.missingReportHook": "useDeepPilotReport hook 缺失",
749
750
  "diag.missingEnabledHook": "useDeepPilotEnabled hook 缺失",
750
- "diag.missingLocalEnabledHook": "useDeepPilotLocalEnabled hook 缺失",
751
751
  "diag.missingLocalPortHook": "useDeepPilotLocalPort hook 缺失",
752
752
  "diag.missingRemoteEnabledHook": "useDeepPilotRemoteEnabled hook 缺失",
753
753
  "diag.missingRemoteLimitHook": "useDeepPilotRemoteConnectionLimit hook 缺失",
@@ -759,7 +759,6 @@ window.__ModuleLoader__.load({
759
759
  "diag.missingTestRelay": "testRelay 回调缺失",
760
760
  "diag.missingTestPush": "testPush 回调缺失",
761
761
  "diag.missingSetEnabled": "setDeepPilotEnabled 回调缺失",
762
- "diag.missingSetLocal": "setDeepPilotLocalEnabled 回调缺失",
763
762
  "diag.missingSetLocalPort": "setDeepPilotLocalPort 回调缺失",
764
763
  "diag.missingSetRemote": "setDeepPilotRemoteEnabled 回调缺失",
765
764
  "diag.missingSetRemoteLimit": "setDeepPilotRemoteConnectionLimit 回调缺失",
@@ -853,6 +852,7 @@ window.__ModuleLoader__.load({
853
852
  "system.title": "Runtime information",
854
853
  "system.description": "Technical details about the plugin, protocol, and endpoints.",
855
854
  "local.title": "LAN connection",
855
+ "local.autoRoute": "LAN connections are always on: on the same Wi-Fi the phone connects over the LAN automatically, and switches to the public route when away.",
856
856
  "local.on": "On: phones connect over TLS through the independent port {port}.",
857
857
  "local.off": "Off: LAN connections are not accepted.",
858
858
  "local.tlsFingerprint": "Certificate fingerprint",
@@ -1028,7 +1028,6 @@ window.__ModuleLoader__.load({
1028
1028
  "diag.settingsUnavailable": "Settings form unavailable (configForms not provided)",
1029
1029
  "diag.missingReportHook": "useDeepPilotReport hook missing",
1030
1030
  "diag.missingEnabledHook": "useDeepPilotEnabled hook missing",
1031
- "diag.missingLocalEnabledHook": "useDeepPilotLocalEnabled hook missing",
1032
1031
  "diag.missingLocalPortHook": "useDeepPilotLocalPort hook missing",
1033
1032
  "diag.missingRemoteEnabledHook": "useDeepPilotRemoteEnabled hook missing",
1034
1033
  "diag.missingRemoteLimitHook": "useDeepPilotRemoteConnectionLimit hook missing",
@@ -1040,7 +1039,6 @@ window.__ModuleLoader__.load({
1040
1039
  "diag.missingTestRelay": "testRelay callback missing",
1041
1040
  "diag.missingTestPush": "testPush callback missing",
1042
1041
  "diag.missingSetEnabled": "setDeepPilotEnabled callback missing",
1043
- "diag.missingSetLocal": "setDeepPilotLocalEnabled callback missing",
1044
1042
  "diag.missingSetLocalPort": "setDeepPilotLocalPort callback missing",
1045
1043
  "diag.missingSetRemote": "setDeepPilotRemoteEnabled callback missing",
1046
1044
  "diag.missingSetRemoteLimit": "setDeepPilotRemoteConnectionLimit callback missing",
@@ -3917,10 +3915,6 @@ window.__ModuleLoader__.load({
3917
3915
  status: "unavailable",
3918
3916
  enabled: true
3919
3917
  });
3920
- const MISSING_LOCAL_ENABLED_HOOK = () => ({
3921
- status: "unavailable",
3922
- enabled: true
3923
- });
3924
3918
  const MISSING_LOCAL_PORT_HOOK = () => ({
3925
3919
  status: "unavailable",
3926
3920
  value: DEFAULT_LOCAL_PORT
@@ -3941,7 +3935,6 @@ window.__ModuleLoader__.load({
3941
3935
  const DIAG_KEY = {
3942
3936
  reportHook: "diag.missingReportHook",
3943
3937
  enabledHook: "diag.missingEnabledHook",
3944
- localEnabledHook: "diag.missingLocalEnabledHook",
3945
3938
  localPortHook: "diag.missingLocalPortHook",
3946
3939
  remoteEnabledHook: "diag.missingRemoteEnabledHook",
3947
3940
  remoteLimitHook: "diag.missingRemoteLimitHook",
@@ -3953,7 +3946,6 @@ window.__ModuleLoader__.load({
3953
3946
  testRelay: "diag.missingTestRelay",
3954
3947
  testPush: "diag.missingTestPush",
3955
3948
  setEnabled: "diag.missingSetEnabled",
3956
- setLocal: "diag.missingSetLocal",
3957
3949
  setLocalPort: "diag.missingSetLocalPort",
3958
3950
  setRemote: "diag.missingSetRemote",
3959
3951
  setRemoteLimit: "diag.missingSetRemoteLimit",
@@ -3968,7 +3960,6 @@ window.__ModuleLoader__.load({
3968
3960
  ["testRelay", "testRelay"],
3969
3961
  ["testPush", "testPush"],
3970
3962
  ["setEnabled", "setDeepPilotEnabled"],
3971
- ["setLocalEnabled", "setDeepPilotLocalEnabled"],
3972
3963
  ["setLocalPort", "setDeepPilotLocalPort"],
3973
3964
  ["setRemoteEnabled", "setDeepPilotRemoteEnabled"],
3974
3965
  ["setRemoteLimit", "setDeepPilotRemoteConnectionLimit"],
@@ -3989,7 +3980,6 @@ window.__ModuleLoader__.load({
3989
3980
  const can = /* @__PURE__ */ new Set();
3990
3981
  const useReport = isFn(source.useDeepPilotReport) ? source.useDeepPilotReport : MISSING_REPORT_HOOK;
3991
3982
  const useEnabled = isFn(source.useDeepPilotEnabled) ? source.useDeepPilotEnabled : MISSING_ENABLED_HOOK;
3992
- const useLocalEnabled = isFn(source.useDeepPilotLocalEnabled) ? source.useDeepPilotLocalEnabled : MISSING_LOCAL_ENABLED_HOOK;
3993
3983
  const useLocalPort = isFn(source.useDeepPilotLocalPort) ? source.useDeepPilotLocalPort : MISSING_LOCAL_PORT_HOOK;
3994
3984
  const useRemoteEnabled = isFn(source.useDeepPilotRemoteEnabled) ? source.useDeepPilotRemoteEnabled : MISSING_REMOTE_ENABLED_HOOK;
3995
3985
  const useRemoteLimit = isFn(source.useDeepPilotRemoteConnectionLimit) ? source.useDeepPilotRemoteConnectionLimit : MISSING_REMOTE_LIMIT_HOOK;
@@ -4003,9 +3993,7 @@ window.__ModuleLoader__.load({
4003
3993
  if (!isFn(source.testRelay)) diagnostics.push(t(DIAG_KEY.testRelay));
4004
3994
  if (!isFn(source.testPush)) diagnostics.push(t(DIAG_KEY.testPush));
4005
3995
  if (!isFn(source.setDeepPilotEnabled)) diagnostics.push(t(DIAG_KEY.setEnabled));
4006
- if (!isFn(source.useDeepPilotLocalEnabled)) diagnostics.push(t(DIAG_KEY.localEnabledHook));
4007
3996
  if (!isFn(source.useDeepPilotLocalPort)) diagnostics.push(t(DIAG_KEY.localPortHook));
4008
- if (!isFn(source.setDeepPilotLocalEnabled)) diagnostics.push(t(DIAG_KEY.setLocal));
4009
3997
  if (!isFn(source.setDeepPilotLocalPort)) diagnostics.push(t(DIAG_KEY.setLocalPort));
4010
3998
  if (!isFn(source.useDeepPilotRemoteEnabled)) diagnostics.push(t(DIAG_KEY.remoteEnabledHook));
4011
3999
  if (!isFn(source.setDeepPilotRemoteEnabled)) diagnostics.push(t(DIAG_KEY.setRemote));
@@ -4018,7 +4006,6 @@ window.__ModuleLoader__.load({
4018
4006
  props: {
4019
4007
  useDeepPilotReport: useReport,
4020
4008
  useDeepPilotEnabled: useEnabled,
4021
- useDeepPilotLocalEnabled: useLocalEnabled,
4022
4009
  useDeepPilotLocalPort: useLocalPort,
4023
4010
  useDeepPilotRemoteEnabled: useRemoteEnabled,
4024
4011
  useDeepPilotRemoteConnectionLimit: useRemoteLimit,
@@ -4031,7 +4018,6 @@ window.__ModuleLoader__.load({
4031
4018
  testRelay: isFn(source.testRelay) ? source.testRelay : void 0,
4032
4019
  testPush: isFn(source.testPush) ? source.testPush : void 0,
4033
4020
  setDeepPilotEnabled: isFn(source.setDeepPilotEnabled) ? source.setDeepPilotEnabled : void 0,
4034
- setDeepPilotLocalEnabled: isFn(source.setDeepPilotLocalEnabled) ? source.setDeepPilotLocalEnabled : void 0,
4035
4021
  setDeepPilotLocalPort: isFn(source.setDeepPilotLocalPort) ? source.setDeepPilotLocalPort : void 0,
4036
4022
  setDeepPilotRemoteEnabled: isFn(source.setDeepPilotRemoteEnabled) ? source.setDeepPilotRemoteEnabled : void 0,
4037
4023
  setDeepPilotRemoteConnectionLimit: isFn(source.setDeepPilotRemoteConnectionLimit) ? source.setDeepPilotRemoteConnectionLimit : void 0,
@@ -4388,9 +4374,6 @@ window.__ModuleLoader__.load({
4388
4374
  hooks.enabled = enabledState.enabled;
4389
4375
  hooks.switchReady = enabledState.status === "ready";
4390
4376
  if (enabledState.status === "unavailable") diag.push(translateWith(props.t, "diag.settingsUnavailable"));
4391
- const localEnabledState = props.useDeepPilotLocalEnabled((s) => s);
4392
- hooks.localEnabled = localEnabledState.enabled;
4393
- hooks.localSwitchReady = localEnabledState.status === "ready";
4394
4377
  const localPortState = props.useDeepPilotLocalPort((s) => s);
4395
4378
  hooks.localPort = localPortState.value;
4396
4379
  hooks.localPortReady = localPortState.status === "ready";
@@ -4408,8 +4391,6 @@ window.__ModuleLoader__.load({
4408
4391
  report: null,
4409
4392
  enabled: true,
4410
4393
  switchReady: false,
4411
- localEnabled: true,
4412
- localSwitchReady: false,
4413
4394
  localPort: DEFAULT_LOCAL_PORT,
4414
4395
  localPortReady: false,
4415
4396
  remoteEnabled: false,
@@ -4428,8 +4409,6 @@ window.__ModuleLoader__.load({
4428
4409
  const report = hooks.report;
4429
4410
  const enabled = hooks.enabled;
4430
4411
  const switchReady = hooks.switchReady;
4431
- const localEnabled = hooks.localEnabled;
4432
- const localSwitchReady = hooks.localSwitchReady;
4433
4412
  const localPort = hooks.localPort;
4434
4413
  const localPortReady = hooks.localPortReady;
4435
4414
  const remoteEnabled = hooks.remoteEnabled;
@@ -4864,14 +4843,7 @@ window.__ModuleLoader__.load({
4864
4843
  onChange: (next) => {
4865
4844
  if (can("setEnabled")) props.setDeepPilotEnabled(next);
4866
4845
  }
4867
- })), (0, react.createElement)("div", { className: "pbb-channel" }, (0, react.createElement)("div", { className: "pbb-row pbb-channelRow" }, settingsIcon("wifi"), (0, react.createElement)("div", { className: "pbb-controlText" }, (0, react.createElement)("span", { className: "pbb-controlTitle" }, translateWith(props.t, "local.title")), (0, react.createElement)("div", { className: "pbb-channelState" }, (0, react.createElement)("span", { className: localMeta?.label === "online" ? "pbb-ok" : localMeta?.label === "error" ? "pbb-bad" : void 0 }, localStateText))), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
4868
- checked: localEnabled,
4869
- label: translateWith(props.t, "local.title"),
4870
- disabled: !localSwitchReady,
4871
- onChange: (next) => {
4872
- if (can("setLocalEnabled")) props.setDeepPilotLocalEnabled(next);
4873
- }
4874
- }), (0, react.createElement)("button", {
4846
+ })), (0, react.createElement)("div", { className: "pbb-channel" }, (0, react.createElement)("div", { className: "pbb-row pbb-channelRow" }, settingsIcon("wifi"), (0, react.createElement)("div", { className: "pbb-controlText" }, (0, react.createElement)("span", { className: "pbb-controlTitle" }, translateWith(props.t, "local.title")), (0, react.createElement)("div", { className: "pbb-channelState" }, (0, react.createElement)("span", { className: localMeta?.label === "online" ? "pbb-ok" : localMeta?.label === "error" ? "pbb-bad" : void 0 }, localStateText))), (0, react.createElement)("button", {
4875
4847
  type: "button",
4876
4848
  className: "pbb-iconButton pbb-expand",
4877
4849
  "aria-label": translateWith(props.t, "local.options"),
@@ -4884,7 +4856,7 @@ window.__ModuleLoader__.load({
4884
4856
  }, translateWith(props.t, "local.errorDetails", { message: report.local.message })) : null, report !== null && report.local.tlsIdentityRegenerated === true ? (0, react.createElement)("p", { className: "pbb-diag pbb-diagBad" }, translateWith(props.t, "local.tlsRegenerated")) : null, fold(localOptionsOpen, (0, react.createElement)("div", {
4885
4857
  className: "pbb-channelBody",
4886
4858
  id: localOptionsId
4887
- }, report !== null && report.local.phase === "online" ? (0, react.createElement)("p", { className: "pbb-diag pbb-endpoint" }, report.local.endpoints.join(" · ")) : null, (0, react.createElement)("div", { className: "pbb-limitRow" }, (0, react.createElement)("div", { className: "pbb-controlText" }, (0, react.createElement)("label", {
4859
+ }, (0, react.createElement)("p", { className: "pbb-controlDescription" }, translateWith(props.t, "local.autoRoute")), report !== null && report.local.phase === "online" ? (0, react.createElement)("p", { className: "pbb-diag pbb-endpoint" }, report.local.endpoints.join(" · ")) : null, (0, react.createElement)("div", { className: "pbb-limitRow" }, (0, react.createElement)("div", { className: "pbb-controlText" }, (0, react.createElement)("label", {
4888
4860
  className: "pbb-controlTitle",
4889
4861
  htmlFor: "deeppilot-local-port"
4890
4862
  }, translateWith(props.t, "local.portTitle")), (0, react.createElement)("span", { className: "pbb-controlDescription" }, translateWith(props.t, "local.portDescription")), !localPortView.valid ? (0, react.createElement)("p", { className: "pbb-diag pbb-diagBad" }, translateWith(props.t, "local.portInvalid")) : localPortDraft.message ? (0, react.createElement)("p", { className: "pbb-diag" + (localPortDraft.failed ? " pbb-diagBad" : "") }, localPortDraft.message) : null), (0, react.createElement)("div", { className: "pbb-limitControl" }, (0, react.createElement)("input", {
@@ -5309,19 +5281,10 @@ window.__ModuleLoader__.load({
5309
5281
  if (snap?.status === "ready" && snap.value !== void 0) return snap.value.enabled !== false;
5310
5282
  return enabledStore.getSnapshot().enabled;
5311
5283
  };
5312
- const localEnabledStore = createSnapshotStore({
5313
- status: "loading",
5314
- enabled: true
5315
- });
5316
5284
  const localPortStore = createSnapshotStore({
5317
5285
  status: "loading",
5318
5286
  value: DEFAULT_LOCAL_PORT
5319
5287
  });
5320
- const lastConfirmedLocalEnabled = () => {
5321
- const snap = scope?.getSnapshot();
5322
- if (snap?.status === "ready") return snap.value?.local?.enabled !== false;
5323
- return localEnabledStore.getSnapshot().enabled;
5324
- };
5325
5288
  const lastConfirmedLocalPort = () => {
5326
5289
  const snap = scope?.getSnapshot();
5327
5290
  if (snap?.status === "ready") return normalizeLocalPort(snap.value?.local?.port);
@@ -5356,46 +5319,16 @@ window.__ModuleLoader__.load({
5356
5319
  const adoptLocal = () => {
5357
5320
  if (scope === void 0) return;
5358
5321
  const snap = scope.getSnapshot();
5359
- if (snap.status === "ready") {
5360
- localEnabledStore.set({
5361
- status: "ready",
5362
- enabled: snap.value?.local?.enabled !== false
5363
- });
5364
- localPortStore.set({
5365
- status: "ready",
5366
- value: normalizeLocalPort(snap.value?.local?.port)
5367
- });
5368
- } else if (snap.status === "unavailable") {
5369
- localEnabledStore.set({
5370
- status: "unavailable",
5371
- enabled: true
5372
- });
5373
- localPortStore.set({
5374
- status: "unavailable",
5375
- value: DEFAULT_LOCAL_PORT
5376
- });
5377
- }
5378
- };
5379
- scopeAdoptions.push(adoptLocal);
5380
- const setDeepPilotLocalEnabled = (value) => {
5381
- const previous = lastConfirmedLocalEnabled();
5382
- localEnabledStore.set({
5322
+ if (snap.status === "ready") localPortStore.set({
5383
5323
  status: "ready",
5384
- enabled: value
5324
+ value: normalizeLocalPort(snap.value?.local?.port)
5385
5325
  });
5386
- if (scope === void 0) return;
5387
- const currentLocal = scope.getSnapshot().value?.local ?? {};
5388
- scope.set("local", {
5389
- ...currentLocal,
5390
- enabled: value
5391
- }).then(() => {}, (error) => {
5392
- localEnabledStore.set({
5393
- status: "ready",
5394
- enabled: previous
5395
- });
5396
- console.error("[deeppilot] failed to persist local.enabled=" + String(value) + ": " + (error instanceof Error ? error.message : String(error)));
5326
+ else if (snap.status === "unavailable") localPortStore.set({
5327
+ status: "unavailable",
5328
+ value: DEFAULT_LOCAL_PORT
5397
5329
  });
5398
5330
  };
5331
+ scopeAdoptions.push(adoptLocal);
5399
5332
  const setDeepPilotLocalPort = async (value) => {
5400
5333
  const next = normalizeLocalPort(value);
5401
5334
  if (next !== value) throw new RangeError("local port must be an integer between 1024 and 65535");
@@ -5570,7 +5503,6 @@ window.__ModuleLoader__.load({
5570
5503
  hooks: {
5571
5504
  deepPilotReport: store,
5572
5505
  deepPilotEnabled: enabledStore,
5573
- deepPilotLocalEnabled: localEnabledStore,
5574
5506
  deepPilotLocalPort: localPortStore,
5575
5507
  deepPilotRemoteEnabled: remoteEnabledStore,
5576
5508
  deepPilotRemoteConnectionLimit: remoteConnectionLimitStore,
@@ -5585,7 +5517,6 @@ window.__ModuleLoader__.load({
5585
5517
  testRelay: testRelayConnection,
5586
5518
  testPush: sendTestPush,
5587
5519
  setDeepPilotEnabled,
5588
- setDeepPilotLocalEnabled,
5589
5520
  setDeepPilotLocalPort,
5590
5521
  setDeepPilotRemoteEnabled,
5591
5522
  setDeepPilotRemoteConnectionLimit,