dsh-mobile 0.6.0 → 0.6.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/CHANGELOG.md +8 -0
- package/CONTRIBUTORS.md +3 -3
- package/README.en.md +15 -7
- package/README.md +15 -7
- package/docs/CADDY_MANAGED.en.md +25 -3
- package/docs/CADDY_MANAGED.md +24 -2
- package/lib/client.js +30 -16
- package/lib/client.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Notable changes are recorded here. GitHub Releases provide the downloadable packages and generated commit notes.
|
|
4
4
|
|
|
5
|
+
## 0.6.1 - 2026-10-08
|
|
6
|
+
|
|
7
|
+
- Reorganize the remote HTTPS origin, external proxy and managed Caddy forms with native radio groups, responsive fields, separate actions and matching Chinese, English and Italian labels. Thanks @abworks-dev for [#184](https://github.com/saya-ch/dsh-mobile/pull/184).
|
|
8
|
+
- Add pinned, reproducible Caddy review builds: Go 1.26.6, xcaddy 0.4.7, Caddy 2.11.6 and Tencent Cloud DNS 0.4.3, with locked source/dependency inputs, fresh private caches, two-build byte comparison and complete artifact checks. Isolated native Windows/Linux tests cover installation, restart, rollback, TLS, pairing, API, WebSocket and cleanup. Thanks @abworks-dev for [#185](https://github.com/saya-ch/dsh-mobile/pull/185); original author commits are retained alongside maintainer fixes.
|
|
9
|
+
- Find Windows Git Bash from the active Git installation rather than a fixed path. Keep missing-shell, timeout and signal failures distinct from expected nonzero command exits, and prevent shell startup environment variables from changing test behavior.
|
|
10
|
+
- Keep official managed Caddy installation disabled. Review builds and optional TEST prereleases do not enable the production component table or establish public DNS-01/ACME issuance and public-route readiness. Existing external proxies and remote providers are unchanged. See [Caddy status](docs/CADDY_MANAGED.en.md).
|
|
11
|
+
- Synchronize Android release metadata to 0.6.1 (build 77). Native features and the pairing/renewal protocol are unchanged from 0.6.0; the official APK uses the established package and signer, preserving pairings on same-signer upgrades.
|
|
12
|
+
|
|
5
13
|
## 0.6.0 - 2026-10-07
|
|
6
14
|
|
|
7
15
|
Add mobile page module management, Android launcher choices, fixed device ordering and improved scanning, alongside connection, layout and WebView compatibility fixes. Update the plugin and Android app together. Original community commits are preserved alongside maintainer fixes; see [Contributors](CONTRIBUTORS.md).
|
package/CONTRIBUTORS.md
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# 贡献者 / Contributors
|
|
2
2
|
|
|
3
|
-
GitHub 的 [Contributors 图表](https://github.com/saya-ch/dsh-mobile/graphs/contributors) 按进入默认分支的提交自动统计,无法手动加入仅提交 issue 或 PR 提案的成员。本页按截至 2026-10-
|
|
3
|
+
GitHub 的 [Contributors 图表](https://github.com/saya-ch/dsh-mobile/graphs/contributors) 按进入默认分支的提交自动统计,无法手动加入仅提交 issue 或 PR 提案的成员。本页按截至 2026-10-08 的实际参与方式感谢社区成员;仓库维护者与自动依赖更新仍可在 GitHub 历史记录中查看。
|
|
4
4
|
|
|
5
|
-
GitHub's Contributors graph counts commits on the default branch; issue reports and PR proposals cannot be manually added to it. This page credits community members by how they contributed, through 2026-10-
|
|
5
|
+
GitHub's Contributors graph counts commits on the default branch; issue reports and PR proposals cannot be manually added to it. This page credits community members by how they contributed, through 2026-10-08. The repository maintainer and automated dependency updates remain visible in GitHub's history.
|
|
6
6
|
|
|
7
7
|
## 已合并 PR / Merged PRs
|
|
8
8
|
|
|
9
9
|
| 社区成员 / Community member | 已合并 PR / Merged PRs |
|
|
10
10
|
| --- | --- |
|
|
11
11
|
| [@1624318455](https://github.com/1624318455) | [#93](https://github.com/saya-ch/dsh-mobile/pull/93) |
|
|
12
|
-
| [@abworks-dev](https://github.com/abworks-dev) | [#91](https://github.com/saya-ch/dsh-mobile/pull/91), [#98](https://github.com/saya-ch/dsh-mobile/pull/98), [#99](https://github.com/saya-ch/dsh-mobile/pull/99), [#152](https://github.com/saya-ch/dsh-mobile/pull/152) |
|
|
12
|
+
| [@abworks-dev](https://github.com/abworks-dev) | [#91](https://github.com/saya-ch/dsh-mobile/pull/91), [#98](https://github.com/saya-ch/dsh-mobile/pull/98), [#99](https://github.com/saya-ch/dsh-mobile/pull/99), [#152](https://github.com/saya-ch/dsh-mobile/pull/152), [#184](https://github.com/saya-ch/dsh-mobile/pull/184), [#185](https://github.com/saya-ch/dsh-mobile/pull/185) |
|
|
13
13
|
| [@ayiejosh](https://github.com/ayiejosh) | [#109](https://github.com/saya-ch/dsh-mobile/pull/109), [#110](https://github.com/saya-ch/dsh-mobile/pull/110), [#116](https://github.com/saya-ch/dsh-mobile/pull/116), [#117](https://github.com/saya-ch/dsh-mobile/pull/117), [#119](https://github.com/saya-ch/dsh-mobile/pull/119), [#124](https://github.com/saya-ch/dsh-mobile/pull/124), [#125](https://github.com/saya-ch/dsh-mobile/pull/125), [#133](https://github.com/saya-ch/dsh-mobile/pull/133), [#136](https://github.com/saya-ch/dsh-mobile/pull/136) |
|
|
14
14
|
| [@chintoleung](https://github.com/chintoleung) | [#104](https://github.com/saya-ch/dsh-mobile/pull/104), [#147](https://github.com/saya-ch/dsh-mobile/pull/147), [#148](https://github.com/saya-ch/dsh-mobile/pull/148), [#158](https://github.com/saya-ch/dsh-mobile/pull/158), [#161](https://github.com/saya-ch/dsh-mobile/pull/161), [#162](https://github.com/saya-ch/dsh-mobile/pull/162), [#167](https://github.com/saya-ch/dsh-mobile/pull/167) |
|
|
15
15
|
| [@cjxh21](https://github.com/cjxh21) | [#154](https://github.com/saya-ch/dsh-mobile/pull/154), [#155](https://github.com/saya-ch/dsh-mobile/pull/155) |
|
package/README.en.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="https://raw.githubusercontent.com/saya-ch/dsh-mobile/main/assets/brand/repository-hero.png" alt="Use DeepSeek Harness from a phone" width="100%">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/saya-ch/dsh-mobile/main/assets/brand/repository-hero.png?v=0bfc8f909993" alt="Use DeepSeek Harness from a phone" width="100%">
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<h1 align="center">DSH Mobile</h1>
|
|
@@ -31,14 +31,14 @@
|
|
|
31
31
|
|
|
32
32
|
> DSH Mobile is a DeepSeek Harness community plugin; the native app supports Android only.
|
|
33
33
|
>
|
|
34
|
-
> **Current stable release: 0.6.
|
|
34
|
+
> **Current stable release: 0.6.1**. Improve remote HTTPS settings and pinned Caddy builds with cross-platform checks. The Android app receives a matching version, retaining 0.6.0's module management, icon choices, device ordering and scanning improvements. [Release notes](CHANGELOG.md#061---2026-10-08).
|
|
35
35
|
>
|
|
36
|
-
> **Upgrade reminder**: update the plugin and Android app together to 0.6.
|
|
36
|
+
> **Upgrade reminder**: update the plugin and Android app together to 0.6.1. Older official apps with the same signer can be upgraded in place while keeping pairings. [Compatibility notes](#compatibility).
|
|
37
37
|
|
|
38
38
|
<p align="center">
|
|
39
|
-
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/v0.6.
|
|
40
|
-
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/v0.6.
|
|
41
|
-
<sub><a href="https://github.com/saya-ch/dsh-mobile/releases/tag/v0.6.
|
|
39
|
+
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/v0.6.1/dsh-mobile-android-v0.6.1.apk"><img src="https://raw.githubusercontent.com/saya-ch/dsh-mobile/main/assets/brand/app-icon-rounded.svg" alt="DSH Mobile Android app icon" width="72" height="72"></a><br>
|
|
40
|
+
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/v0.6.1/dsh-mobile-android-v0.6.1.apk"><strong>Download Android app 0.6.1</strong></a><br>
|
|
41
|
+
<sub><a href="https://github.com/saya-ch/dsh-mobile/releases/tag/v0.6.1">Release notes and checksums</a></sub>
|
|
42
42
|
</p>
|
|
43
43
|
|
|
44
44
|
DSH Mobile is a DeepSeek Harness plugin that lets a mobile browser or the Android app connect over a protected LAN or an optional Tailscale Funnel, cpolar, cloudflared, self-hosted FRP, or own reverse-proxy remote path. Both routes reach the same sessions, Workspaces, messages, and tools. The computer manages their switches and pairing authorizations separately; the Android app lists paired computers together. The plugin does not modify DeepSeek Harness source.
|
|
@@ -71,6 +71,14 @@ Model-search and pairing-page input sizes are corrected, and Android Back naviga
|
|
|
71
71
|
|
|
72
72
|
</details>
|
|
73
73
|
|
|
74
|
+
## 0.6.1 update
|
|
75
|
+
|
|
76
|
+
- **Remote settings**: clearer HTTPS origin, external-proxy and managed-Caddy form groups, fields and actions, including narrow-window layouts.
|
|
77
|
+
- **Builds and checks**: pinned Caddy inputs, Windows/Linux double-build comparison and isolated TLS, pairing, API, WebSocket and cleanup tests; corrected Windows Git Bash discovery and test-failure classification. [Caddy status](docs/CADDY_MANAGED.en.md)
|
|
78
|
+
- **Android app**: version-aligned 0.6.1 (build 77) with unchanged native features and pairing protocol, using the established release signer. Existing pairings do not need to be recreated.
|
|
79
|
+
|
|
80
|
+
Thanks [@abworks-dev](https://github.com/abworks-dev) for [#184](https://github.com/saya-ch/dsh-mobile/pull/184) and [#185](https://github.com/saya-ch/dsh-mobile/pull/185). Official managed Caddy installation remains unavailable. See the complete [changelog](CHANGELOG.md#061---2026-10-08).
|
|
81
|
+
|
|
74
82
|
## 0.6.0 update
|
|
75
83
|
|
|
76
84
|
This update focuses on module management, app personalization and mobile access. See the complete [changelog](CHANGELOG.md#060---2026-10-07).
|
|
@@ -438,7 +446,7 @@ On macOS, local network, cloudflared, self-hosted FRP and the own reverse proxy
|
|
|
438
446
|
|
|
439
447
|
Existing apps (0.3.3 and later) do not need re-pairing. cpolar users should use app 0.3.15 or later because earlier apps may time out before a slow first load over the free route finishes; earlier apps also use a different status-bar strategy. The 0.4.0 app adds the multi-device list, startup behavior, and computer-side revocation status; older apps continue to connect to their saved single device. App 0.1.3 or earlier requires reinstalling and pairing again.
|
|
440
448
|
|
|
441
|
-
|
|
449
|
+
App 0.6.1 (build 77) retains 0.6.0's native features and pairing/renewal protocol; existing pairings do not need to be recreated, and normally working older apps can continue connecting. Update the plugin and app together to retain 0.6.0's icon choices, scanning improvements, device ordering, switching shortcut and earlier fixes.
|
|
442
450
|
|
|
443
451
|
GitHub Release APKs use a stable signing certificate, so an older official APK with the same signer can be upgraded in place while retaining pairings. A locally built Debug APK with a different signer cannot be overwritten by the official APK; plan to pair again when switching between them.
|
|
444
452
|
|
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="https://raw.githubusercontent.com/saya-ch/dsh-mobile/main/assets/brand/repository-hero.png" alt="用手机使用电脑中的 DeepSeek Harness" width="100%">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/saya-ch/dsh-mobile/main/assets/brand/repository-hero.png?v=0bfc8f909993" alt="用手机使用电脑中的 DeepSeek Harness" width="100%">
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<h1 align="center">DSH Mobile</h1>
|
|
@@ -31,14 +31,14 @@
|
|
|
31
31
|
|
|
32
32
|
> DSH Mobile 是 DeepSeek Harness 社区插件,原生 App 仅支持 Android。
|
|
33
33
|
>
|
|
34
|
-
> **当前正式版本:0.6.
|
|
34
|
+
> **当前正式版本:0.6.1**。优化远程 HTTPS 配置表单,完善 Caddy 固定构建与跨平台验证;Android App 同步版本,保留 0.6.0 的模块管理、图标选择、设备排序与扫码改进。[更新记录](CHANGELOG.md#061---2026-10-08)。
|
|
35
35
|
>
|
|
36
|
-
> **升级提醒**:请同步更新插件与 Android App 至 0.6.
|
|
36
|
+
> **升级提醒**:请同步更新插件与 Android App 至 0.6.1;同一正式签名的旧 App 可原位升级并保留配对。[兼容说明](#兼容性)。
|
|
37
37
|
|
|
38
38
|
<p align="center">
|
|
39
|
-
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/v0.6.
|
|
40
|
-
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/v0.6.
|
|
41
|
-
<sub><a href="https://github.com/saya-ch/dsh-mobile/releases/tag/v0.6.
|
|
39
|
+
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/v0.6.1/dsh-mobile-android-v0.6.1.apk"><img src="https://raw.githubusercontent.com/saya-ch/dsh-mobile/main/assets/brand/app-icon-rounded.svg" alt="DSH Mobile 安卓应用图标" width="72" height="72"></a><br>
|
|
40
|
+
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/v0.6.1/dsh-mobile-android-v0.6.1.apk"><strong>下载 Android App 0.6.1</strong></a><br>
|
|
41
|
+
<sub><a href="https://github.com/saya-ch/dsh-mobile/releases/tag/v0.6.1">版本说明与校验文件</a></sub>
|
|
42
42
|
</p>
|
|
43
43
|
|
|
44
44
|
DSH Mobile 是一个 DeepSeek Harness 插件,让手机浏览器或 Android App 通过局域网,或可选的 Tailscale Funnel、cpolar、cloudflared、自建 FRP 或自有反向代理远程通道连接电脑,继续使用同一份会话、工作区、消息和工具。电脑端分别启停局域网与远程访问、分别管理配对授权;Android App 统一显示已配对电脑。插件不修改 DeepSeek Harness 源码。
|
|
@@ -71,6 +71,14 @@ DSH Mobile 是一个 DeepSeek Harness 插件,让手机浏览器或 Android App
|
|
|
71
71
|
|
|
72
72
|
</details>
|
|
73
73
|
|
|
74
|
+
## 0.6.1 更新
|
|
75
|
+
|
|
76
|
+
- **远程配置**:重新整理 HTTPS 地址、自备代理与托管 Caddy 的表单分组、字段和操作按钮,小窗口下也能清楚区分配置方式。
|
|
77
|
+
- **构建与验证**:固定 Caddy 构建输入,增加 Windows/Linux 双构建一致性及隔离 TLS、配对、API、WebSocket 和清理检查,修正 Windows Git Bash 路径与测试失败分类。[Caddy 状态](docs/CADDY_MANAGED.md)
|
|
78
|
+
- **Android App**:同步为 0.6.1(build 77),原生功能与配对协议不变,沿用正式签名;已有配对无需重建。
|
|
79
|
+
|
|
80
|
+
感谢 [@abworks-dev](https://github.com/abworks-dev) 的 [#184](https://github.com/saya-ch/dsh-mobile/pull/184) 与 [#185](https://github.com/saya-ch/dsh-mobile/pull/185)。托管 Caddy 仍未开放正式安装;完整记录见 [CHANGELOG](CHANGELOG.md#061---2026-10-08)。
|
|
81
|
+
|
|
74
82
|
## 0.6.0 更新
|
|
75
83
|
|
|
76
84
|
本次更新聚焦模块管理、App 个性化与移动访问体验;完整记录见 [CHANGELOG](CHANGELOG.md#060---2026-10-07)。
|
|
@@ -439,7 +447,7 @@ macOS 上局域网、cloudflared、自建 FRP 与自有反向代理可用;Funn
|
|
|
439
447
|
|
|
440
448
|
现有 App(0.3.3 及更新)无需重新配对;cpolar 用户应使用 0.3.15 或更新 App,较早版本可能在免费线路的慢速首次加载完成前超时;更早的 App 还使用不同的状态栏策略。App 0.4.0 才支持多设备列表、启动行为设置和电脑端撤销状态同步;旧版 App 仍可连接已保存的单台设备。App 0.1.3 及更早版本需卸载重装并重新配对。
|
|
441
449
|
|
|
442
|
-
0.6.0
|
|
450
|
+
0.6.1(build 77)的原生功能与配对、续期协议延续 0.6.0,已有配对无需重建;旧 App 的正常连接可继续使用。建议同步升级插件与 App,以保留 0.6.0 的图标选择、扫码改进、设备排序、切换快捷方式及此前修复。
|
|
443
451
|
|
|
444
452
|
GitHub Release 的正式 APK 使用固定签名,可从同一签名的旧正式版原位升级并保留配对。自行构建的 Debug APK 若使用不同签名,不能直接覆盖安装正式版;切换前请准备重新配对。
|
|
445
453
|
|
package/docs/CADDY_MANAGED.en.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[中文](CADDY_MANAGED.md)
|
|
4
4
|
|
|
5
|
-
> Managed mode and its isolated tests are integrated, but no pinned component
|
|
5
|
+
> Managed mode and its isolated tests are integrated, but no official pinned component is available. Installation and connection remain disabled. Existing external HTTPS proxy mode is unaffected.
|
|
6
6
|
|
|
7
7
|
## Requirements
|
|
8
8
|
|
|
@@ -34,6 +34,28 @@ Stopping access or changing provider waits for Caddy and Gateway termination, re
|
|
|
34
34
|
|
|
35
35
|
## Maintainer build and validation
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
Run these build and validation tools from a source checkout of this repository. The npm plugin package does not include these maintenance scripts; ordinary users do not need to compile Caddy.
|
|
38
38
|
|
|
39
|
-
The
|
|
39
|
+
The [builder](<../scripts/build-caddy-component.mjs>) fixes Go 1.26.6, xcaddy v0.4.7, Caddy v2.11.6 and Tencent Cloud DNS v0.4.3. The [input lock](<../scripts/caddy-component-lock.json>) freezes source revisions and compiled dependency versions/checksums. Each build uses fresh private compiler AND module caches, normal Go checksum verification, source-origin checks and retained-module verification. Unknown dependencies, replacements, wrong native settings or compiler versions fail closed before executing the generated Caddy.
|
|
40
|
+
|
|
41
|
+
Use the exact Go compiler (optionally through `GO_BINARY`); output directories must be new and absolute:
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
node scripts/build-caddy-component.mjs --output-dir /absolute/new/first
|
|
45
|
+
node scripts/build-caddy-component.mjs --output-dir /absolute/new/second
|
|
46
|
+
node scripts/compare-caddy-builds.mjs --first /absolute/new/first --second /absolute/new/second --target linux-x64
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Windows uses native absolute paths and `--target win32-x64`. Reproducibility means identical executable bytes/size/SHA-256, not identical OS images or every rendered metadata/license file. The [workflow](<../.github/workflows/caddy-component.yml>) natively builds twice on Windows/Linux x64, validates complete evidence and tests the actually installed binary with an independent manifest. Tests cover real default inspection/promotion, no-redownload restart, corrupt-download rollback, TLS/pairing/API/WSS, durable device credentials and stopped-process owned cleanup while neighboring/pairing data survives. Other targets remain unreviewed.
|
|
50
|
+
|
|
51
|
+
PR and normal dispatch runs are read-only review-artifact builds. Only an explicit manual opt-in on an existing `caddy-component-2.11.6-tencentcloud-0.4.3-review.N` tag in the authorized `abworks-dev/dsh-mobile` fork can publish a **TEST prerelease**, after both native jobs pass:
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
gh workflow run caddy-component.yml --repo abworks-dev/dsh-mobile --ref caddy-component-2.11.6-tencentcloud-0.4.3-review.1 -f publish_review_prerelease=true
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Component tags never start with `v`, avoiding the plugin release trigger. The separate write-permission job refuses occupied releases, creates a non-latest draft prerelease without asset clobbering, verifies an authenticated download of every draft asset against prepared bytes, then publishes. Assets include platform-distinct raw executables, manifests, build/module/version/license records, double-build proof, source-commit/run identity and SHA256SUMS. The [verifier](<../scripts/verify-caddy-release.mjs>) checks **every published asset** through GitHub metadata and the actual installer's HTTPS/validated-redirect downloader before emitting a review-only catalog. A failed post-publication check leaves the labelled prerelease public, fails the job and emits no catalog; it does not silently delete or roll back a release. Artifact retention is 14 days; release assets are separate.
|
|
58
|
+
|
|
59
|
+
The public custom-download endpoint returned v2.11.7 when v2.11.6 was requested; dynamic latest downloads are not a trust source. Versioned GitHub URLs can still be replaced by repository owners: exact reviewed byte/hash pins, not URL spelling or a remotely supplied checksum alone, define the content boundary. A fork catalog is only a review candidate; it never automatically populates the [production table](<../src/caddy-component.ts>). Official production installation stays disabled until maintainers publish and review their own distribution.
|
|
60
|
+
|
|
61
|
+
Isolated tests use ephemeral loopback listeners and a private internal CA with `skip_install_trust`; no system trust, production DNS or existing proxy is changed. They **do not establish public DNS-01/ACME issuance or public-route readiness**. Those need a separately authorized dedicated test hostname, least-privilege DNS credentials and actual reachable ingress.
|
package/docs/CADDY_MANAGED.md
CHANGED
|
@@ -34,6 +34,28 @@ Android App / 浏览器 → 公网 HTTPS 域名(Caddy 终止 TLS)
|
|
|
34
34
|
|
|
35
35
|
## 维护者构建与验证
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
以下构建和验证工具需在本仓库源码 checkout 中运行;npm 插件包不包含这些维护脚本,也不需要普通用户自行编译 Caddy。
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
[构建脚本](<../scripts/build-caddy-component.mjs>) 固定 Go 1.26.6、xcaddy v0.4.7、Caddy v2.11.6 和腾讯云 DNS v0.4.3。[输入锁](<../scripts/caddy-component-lock.json>) 固定源码提交和编译依赖版本/校验和。每次构建使用全新的私有编译缓存及模块缓存,执行 Go 校验和、源码来源与保留模块校验;未知依赖、替换模块、编译器或原生设置漂移会在运行生成的 Caddy 前拒绝。
|
|
40
|
+
|
|
41
|
+
选择精确 Go 编译器(可用 `GO_BINARY`),输出目录必须是全新绝对路径:
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
node scripts/build-caddy-component.mjs --output-dir /absolute/new/first
|
|
45
|
+
node scripts/build-caddy-component.mjs --output-dir /absolute/new/second
|
|
46
|
+
node scripts/compare-caddy-builds.mjs --first /absolute/new/first --second /absolute/new/second --target linux-x64
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Windows 使用原生绝对路径和 `--target win32-x64`。可复现指二进制字节、大小、SHA-256 一致,不保证操作系统镜像或所有元数据/许可证文本逐字一致。[工作流](<../.github/workflows/caddy-component.yml>) 在 Windows/Linux x64 分别独立构建两次,审核完整产物,并使用独立 manifest 测试真正安装后的二进制:默认版本/模块检查、目录提升、无重复下载的重启、损坏下载回滚、TLS/配对/API/WSS、持久设备凭据与停止后清理,保留邻近文件及配对数据。其他架构仍未审核。
|
|
50
|
+
|
|
51
|
+
PR 和普通手动运行只产生只读审查产物。只有授权的 `abworks-dev/dsh-mobile` fork 上已有 `caddy-component-2.11.6-tencentcloud-0.4.3-review.N` 标签,经明确手动启用且两个原生任务均通过,才发布 **TEST 预发布版**:
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
gh workflow run caddy-component.yml --repo abworks-dev/dsh-mobile --ref caddy-component-2.11.6-tencentcloud-0.4.3-review.1 -f publish_review_prerelease=true
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
组件标签不以 `v` 开头,避免触发插件正式发布。独立写权限任务拒绝已有 Release,创建非 latest 的预发布草稿,不覆盖资产;下载所有草稿资产与准备字节逐一对比后才公开。产物包括区分平台的原始二进制、manifest、编译/模块/版本/许可证证据、双构建证明、源码提交/运行标识和 SHA256SUMS。[发布后验证器](<../scripts/verify-caddy-release.mjs>) 用 GitHub 元数据及安装器实际 HTTPS/受限重定向下载链路复核 **所有公开资产**,成功后才输出仅供审核的目录。公开后验证失败会保留已公开的标记预发布版、使任务失败且不输出校验目录,不擅自删除或回滚 Release。CI 产物保留 14 天,Release 资产另行保存。
|
|
58
|
+
|
|
59
|
+
公开定制下载端点曾在请求 v2.11.6 时返回 v2.11.7,动态最新版不能成为信任来源。版本化 GitHub URL 仍可被仓库所有者替换;信任边界是审核过的精确大小/哈希,而非 URL 名称或远端自报校验和。fork 的目录只是审核候选,不会自动写入[生产组件表](<../src/caddy-component.ts>);正式安装仍等待维护者发布并审核官方分发。
|
|
60
|
+
|
|
61
|
+
隔离测试仅用回环随机端口、私有内部 CA 和 `skip_install_trust`,不修改系统信任、生产 DNS 或现有代理。**不等于真实公网 DNS-01/ACME 签发或公网路由验收**;后者需要另行授权专用测试域名、最小权限 DNS 凭据和可达入口。
|
package/lib/client.js
CHANGED
|
@@ -1150,6 +1150,8 @@ window.__ModuleLoader__.load({
|
|
|
1150
1150
|
originCopyBackend: "Copy backend address",
|
|
1151
1151
|
originBackendCopied: "HTTP backend address copied.",
|
|
1152
1152
|
originPurge: "Clear proxy settings",
|
|
1153
|
+
originHttpsTitle: "HTTPS remote access",
|
|
1154
|
+
originHttpsMode: "HTTPS handling",
|
|
1153
1155
|
caddyModeManaged: "Managed Caddy (plugin handles HTTPS and certificates)",
|
|
1154
1156
|
caddyModeExternal: "I already run my own reverse proxy",
|
|
1155
1157
|
caddySectionTitle: "Managed Caddy upstream",
|
|
@@ -1205,6 +1207,8 @@ window.__ModuleLoader__.load({
|
|
|
1205
1207
|
originCopyBackend: "Copia indirizzo backend",
|
|
1206
1208
|
originBackendCopied: "Indirizzo backend HTTP copiato.",
|
|
1207
1209
|
originPurge: "Cancella impostazioni proxy",
|
|
1210
|
+
originHttpsTitle: "Accesso remoto HTTPS",
|
|
1211
|
+
originHttpsMode: "Gestione HTTPS",
|
|
1208
1212
|
caddyModeManaged: "Caddy gestito (il plugin gestisce HTTPS e certificati)",
|
|
1209
1213
|
caddyModeExternal: "Uso già il mio reverse proxy",
|
|
1210
1214
|
caddySectionTitle: "Upstream Caddy gestito",
|
|
@@ -1260,6 +1264,8 @@ window.__ModuleLoader__.load({
|
|
|
1260
1264
|
originCopyBackend: "复制后端地址",
|
|
1261
1265
|
originBackendCopied: "已复制 HTTP 后端地址。",
|
|
1262
1266
|
originPurge: "清除代理配置",
|
|
1267
|
+
originHttpsTitle: "HTTPS 远程接入",
|
|
1268
|
+
originHttpsMode: "HTTPS 接入方式",
|
|
1263
1269
|
caddyModeManaged: "托管 Caddy(插件负责 HTTPS 与证书)",
|
|
1264
1270
|
caddyModeExternal: "我已自行配置反向代理",
|
|
1265
1271
|
caddySectionTitle: "托管 Caddy 上游",
|
|
@@ -6176,14 +6182,14 @@ window.__ModuleLoader__.load({
|
|
|
6176
6182
|
const originSetup = element("section", "dsh-mobile-control__origin-setup");
|
|
6177
6183
|
originSetup.hidden = true;
|
|
6178
6184
|
const originSetupTitle = element("h3", "dsh-mobile-control__section-title");
|
|
6179
|
-
originSetupTitle.textContent = t("
|
|
6185
|
+
originSetupTitle.textContent = t("originHttpsTitle");
|
|
6180
6186
|
const originHelp = element("p", "dsh-mobile-control__component-note");
|
|
6181
6187
|
originHelp.id = "dsh-mobile-origin-help";
|
|
6182
6188
|
originHelp.textContent = t("originHelp");
|
|
6183
6189
|
const originWarning = element("p", "dsh-mobile-control__origin-warning");
|
|
6184
6190
|
originWarning.textContent = t("originWarning");
|
|
6185
6191
|
const originFields = element("div", "dsh-mobile-control__origin-fields");
|
|
6186
|
-
const originPublicLabel = element("label", "dsh-mobile-control__field");
|
|
6192
|
+
const originPublicLabel = element("label", "dsh-mobile-control__field dsh-mobile-control__field--full");
|
|
6187
6193
|
originPublicLabel.textContent = t("originPublicOrigin");
|
|
6188
6194
|
const originPublic = element("input");
|
|
6189
6195
|
originPublic.type = "url";
|
|
@@ -6204,7 +6210,7 @@ window.__ModuleLoader__.load({
|
|
|
6204
6210
|
originPort.max = "65535";
|
|
6205
6211
|
originPort.step = "1";
|
|
6206
6212
|
originPort.value = "3444";
|
|
6207
|
-
const originCidrsLabel = element("label", "dsh-mobile-control__field");
|
|
6213
|
+
const originCidrsLabel = element("label", "dsh-mobile-control__field dsh-mobile-control__field--full");
|
|
6208
6214
|
originCidrsLabel.textContent = t("originAllowedCidrs");
|
|
6209
6215
|
const originCidrs = element("input");
|
|
6210
6216
|
originCidrs.type = "text";
|
|
@@ -6248,14 +6254,15 @@ window.__ModuleLoader__.load({
|
|
|
6248
6254
|
originCopyBackend.type = "button";
|
|
6249
6255
|
originCopyBackend.textContent = t("originCopyBackend");
|
|
6250
6256
|
originBackend.append(originBackendLabel, originBackendAddress, originCopyBackend);
|
|
6251
|
-
|
|
6252
|
-
const
|
|
6253
|
-
|
|
6257
|
+
const caddyModeRow = element("fieldset", "dsh-mobile-control__origin-modes");
|
|
6258
|
+
const caddyModeLegend = element("legend");
|
|
6259
|
+
caddyModeLegend.textContent = t("originHttpsMode");
|
|
6260
|
+
const caddyModeManagedLabel = element("label", "dsh-mobile-control__origin-mode");
|
|
6254
6261
|
const caddyModeManaged = element("input");
|
|
6255
6262
|
caddyModeManaged.type = "radio";
|
|
6256
6263
|
caddyModeManaged.name = "caddy-mode";
|
|
6257
6264
|
caddyModeManaged.value = "managed";
|
|
6258
|
-
const caddyModeExternalLabel = element("label", "dsh-mobile-
|
|
6265
|
+
const caddyModeExternalLabel = element("label", "dsh-mobile-control__origin-mode");
|
|
6259
6266
|
const caddyModeExternal = element("input");
|
|
6260
6267
|
caddyModeExternal.type = "radio";
|
|
6261
6268
|
caddyModeExternal.name = "caddy-mode";
|
|
@@ -6266,10 +6273,11 @@ window.__ModuleLoader__.load({
|
|
|
6266
6273
|
caddyExternalText.textContent = t("caddyModeExternal");
|
|
6267
6274
|
caddyModeManagedLabel.append(caddyModeManaged, caddyManagedText);
|
|
6268
6275
|
caddyModeExternalLabel.append(caddyModeExternal, caddyExternalText);
|
|
6269
|
-
caddyModeRow.append(
|
|
6270
|
-
const caddyForm = element("div", "dsh-mobile-
|
|
6276
|
+
caddyModeRow.append(caddyModeLegend, caddyModeExternalLabel, caddyModeManagedLabel);
|
|
6277
|
+
const caddyForm = element("div", "dsh-mobile-control__caddy-form");
|
|
6271
6278
|
caddyForm.hidden = true;
|
|
6272
|
-
const
|
|
6279
|
+
const caddyFields = element("div", "dsh-mobile-control__origin-fields");
|
|
6280
|
+
const caddyDomainLabel = element("label", "dsh-mobile-control__field dsh-mobile-control__field--full");
|
|
6273
6281
|
caddyDomainLabel.textContent = t("caddyDomain");
|
|
6274
6282
|
const caddyDomain = element("input");
|
|
6275
6283
|
caddyDomain.type = "url";
|
|
@@ -6277,7 +6285,7 @@ window.__ModuleLoader__.load({
|
|
|
6277
6285
|
caddyDomain.maxLength = 512;
|
|
6278
6286
|
caddyDomain.autocomplete = "off";
|
|
6279
6287
|
caddyDomain.spellcheck = false;
|
|
6280
|
-
const caddyProviderLabel = element("label", "dsh-mobile-control__field");
|
|
6288
|
+
const caddyProviderLabel = element("label", "dsh-mobile-control__field dsh-mobile-control__field--full");
|
|
6281
6289
|
caddyProviderLabel.textContent = t("caddyDnsProvider");
|
|
6282
6290
|
const caddyProvider = element("select");
|
|
6283
6291
|
const caddyProviderOption = document.createElement("option");
|
|
@@ -6296,7 +6304,7 @@ window.__ModuleLoader__.load({
|
|
|
6296
6304
|
caddySecretKey.type = "password";
|
|
6297
6305
|
caddySecretKey.autocomplete = "off";
|
|
6298
6306
|
caddySecretKey.spellcheck = false;
|
|
6299
|
-
const caddyPortLabel = element("label", "dsh-mobile-control__field");
|
|
6307
|
+
const caddyPortLabel = element("label", "dsh-mobile-control__field dsh-mobile-control__field--full");
|
|
6300
6308
|
caddyPortLabel.textContent = t("caddyListenPort");
|
|
6301
6309
|
const caddyPort = element("input");
|
|
6302
6310
|
caddyPort.type = "number";
|
|
@@ -6310,7 +6318,7 @@ window.__ModuleLoader__.load({
|
|
|
6310
6318
|
caddySecretIdLabel.append(caddySecretId);
|
|
6311
6319
|
caddySecretKeyLabel.append(caddySecretKey);
|
|
6312
6320
|
caddyPortLabel.append(caddyPort);
|
|
6313
|
-
|
|
6321
|
+
caddyFields.append(caddyDomainLabel, caddyProviderLabel, caddySecretIdLabel, caddySecretKeyLabel, caddyPortLabel);
|
|
6314
6322
|
const caddyInstall = element("button", "dsh-mobile-control__primary");
|
|
6315
6323
|
caddyInstall.type = "button";
|
|
6316
6324
|
caddyInstall.textContent = t("caddyInstall");
|
|
@@ -6330,8 +6338,10 @@ window.__ModuleLoader__.load({
|
|
|
6330
6338
|
caddyFeedback.setAttribute("role", "status");
|
|
6331
6339
|
caddyFeedback.setAttribute("aria-live", "polite");
|
|
6332
6340
|
caddyFeedback.hidden = true;
|
|
6333
|
-
|
|
6334
|
-
|
|
6341
|
+
const caddyActions = element("div", "dsh-mobile-control__actions dsh-mobile-control__caddy-actions");
|
|
6342
|
+
caddyActions.append(caddyInstall, caddySave, caddyPurgeButton);
|
|
6343
|
+
caddyForm.append(caddyFields, caddyInstallNote, caddyStatus, caddyActions, caddyFeedback);
|
|
6344
|
+
originSetup.append(originSetupTitle, caddyModeRow, originHelp, originWarning, originFields, originFeedback, originFormActions, caddyForm, originBackend);
|
|
6335
6345
|
const tailscaleInfo = element("details", "dsh-mobile-control__details");
|
|
6336
6346
|
const tailscaleInfoSummary = element("summary");
|
|
6337
6347
|
tailscaleInfoSummary.textContent = t("tailscaleHelp");
|
|
@@ -10036,7 +10046,11 @@ window.__ModuleLoader__.load({
|
|
|
10036
10046
|
.dsh-mobile-control__manage-row{display:flex;justify-content:space-between;gap:8px;margin-top:10px}.dsh-mobile-control__manage{flex:1 1 0;min-width:0;min-height:36px;padding:6px 8px;border:1px solid var(--dsw-alias-border-l3,#cfd5dd);border-radius:10px;background:transparent;color:inherit;font:12px/1.3 system-ui;cursor:pointer}.dsh-mobile-control__devices{margin-top:10px;border:1px solid var(--dsw-alias-border-l2,#e1e5eb);border-radius:10px;padding:8px;max-height:220px;overflow-y:auto}.dsh-mobile-control__device-empty{color:var(--dsw-alias-label-secondary,#606873);font-size:12px;margin:0}.dsh-mobile-control__device{display:flex;align-items:center;gap:8px;padding:6px 2px}.dsh-mobile-control__device + .dsh-mobile-control__device{border-top:1px solid var(--dsw-alias-border-l2,#e1e5eb)}.dsh-mobile-control__device-label{flex:1 1 0;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px}.dsh-mobile-control__device-meta{flex:none;color:var(--dsw-alias-label-secondary,#606873);font-size:11px;white-space:nowrap}.dsh-mobile-control__device-revoke{flex:none;min-height:36px;padding:4px 8px;border:1px solid var(--dsw-alias-state-error-primary,#dc2626);border-radius:8px;background:transparent;color:var(--dsw-alias-label-primary,#dc2626);font:12px/1.2 system-ui;cursor:pointer}.dsh-mobile-control__ws-paths{margin:10px 0 0;padding:12px;border:1px solid var(--dsw-alias-border-l2,#dbe1e8);border-radius:13px;background:var(--dsw-alias-bg-layer-2,#fff)}.dsh-mobile-control__ws-paths-list{margin:0 0 8px;padding:0;list-style:none}.dsh-mobile-control__ws-paths-empty{color:var(--dsw-alias-label-secondary,#606873);font-size:12px}.dsh-mobile-control__ws-paths-item{display:flex;align-items:center;gap:8px;padding:6px 0}.dsh-mobile-control__ws-paths-item + .dsh-mobile-control__ws-paths-item{border-top:1px solid var(--dsw-alias-border-l2,#e1e5eb)}.dsh-mobile-control__ws-paths-item code{flex:1 1 0;min-width:0;overflow:hidden;font:11px/1.4 ui-monospace,SFMono-Regular,Consolas,monospace;text-overflow:ellipsis;white-space:nowrap}.dsh-mobile-control__ws-paths-remove{flex:none;min-height:36px;padding:4px 8px;border:1px solid var(--dsw-alias-border-l3,#cfd5dd);border-radius:8px;background:transparent;color:inherit;font:12px/1.2 system-ui;cursor:pointer}.dsh-mobile-control__trigger,.dsh-mobile-control__diagnostic-entry{position:relative}.dsh-mobile-control__ws-dot{position:absolute;top:2px;right:2px;z-index:1;min-width:16px;height:16px;padding:0 4px;border-radius:999px;background:var(--dsw-alias-state-error-primary,#dc2626);color:#fff;font:650 11px/16px system-ui;text-align:center;cursor:pointer}.dsh-mobile-control__ws-dot::after{content:'';position:absolute;inset:-5px}.dsh-mobile-control__ws-sr-status{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.dsh-mobile-control__ws-paths-row{display:flex;gap:8px}.dsh-mobile-control__ws-paths-row .dsh-mobile-control__primary{width:auto;flex:none;padding:9px 14px;border-radius:10px}.dsh-mobile-control__ws-paths-group{padding:6px 0}.dsh-mobile-control__ws-paths-group + .dsh-mobile-control__ws-paths-group{border-top:1px solid var(--dsw-alias-border-l2,#e1e5eb)}.dsh-mobile-control__ws-paths-group-head{display:flex;align-items:center;gap:8px}.dsh-mobile-control__ws-count{flex:none;padding:1px 7px;border-radius:999px;background:var(--dsw-alias-state-business-tertiary,#e8f0ff);color:var(--dsw-alias-label-primary,#1d4ed8);font:650 11px/1.6 system-ui}.dsh-mobile-control__ws-paths-item.is-child{padding-left:12px}.dsh-mobile-control__ws-paths-group-head .dsh-mobile-control__primary,.dsh-mobile-control__ws-paths-item .dsh-mobile-control__primary{width:auto;flex:none;min-height:36px;padding:6px 12px;border-radius:10px}.dsh-mobile-control__ws-paths-row input{flex:1 1 0;min-width:0;box-sizing:border-box;min-height:44px;padding:9px 10px;border:1px solid var(--dsw-alias-border-l3,#cfd5dd);border-radius:10px;background:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-primary,#16181d);font:16px/1.4 system-ui}.dsh-mobile-control__ws-paths-row button{flex:none}.dsh-mobile-control__ws-paths-detected-title{margin:0 0 2px;font:600 12px/1.4 system-ui}.dsh-mobile-control__ws-paths-advanced{margin-top:8px}.dsh-mobile-control__ws-paths-advanced summary{cursor:pointer;color:var(--dsw-alias-label-secondary,#606873);font:12px/1.4 system-ui;user-select:none}.dsh-mobile-control__ws-paths-advanced summary:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary,currentColor);outline-offset:2px;border-radius:4px}.dsh-mobile-control__ws-paths-advanced[open] summary{margin-bottom:6px}.dsh-mobile-control__ws-paths-advanced .dsh-mobile-control__status{margin:6px 0 0}
|
|
10037
10047
|
@media (max-width:359px){.dsh-mobile-control__provider{min-height:68px}}@media (prefers-reduced-motion:reduce){.dsh-mobile-control__provider,.dsh-mobile-control__cpolar-connect{transition:none}.dsh-mobile-control__diagnostic-summary.is-running .dsh-mobile-control__diagnostic-summary-icon::before,.dsh-mobile-control__diagnostic-checks{animation:none}}
|
|
10038
10048
|
|
|
10039
|
-
.dsh-mobile-control__origin-setup{margin:0;padding:12px;border:1px solid var(--dsw-alias-border-l2,#dbe1e8);border-radius:13px;background:var(--dsw-alias-bg-layer-2,#fff)}.dsh-mobile-control__origin-setup[hidden],.dsh-mobile-control__origin-
|
|
10049
|
+
.dsh-mobile-control__origin-setup{margin:0;padding:12px;border:1px solid var(--dsw-alias-border-l2,#dbe1e8);border-radius:13px;background:var(--dsw-alias-bg-layer-2,#fff)}.dsh-mobile-control__origin-setup[hidden],.dsh-mobile-control__origin-setup [hidden]{display:none}
|
|
10050
|
+
/* Mode choices are not text fields; preserve native radio sizing and keyboard behavior. */
|
|
10051
|
+
.dsh-mobile-control__origin-modes{min-width:0;margin:0 0 14px;padding:0;border:0}.dsh-mobile-control__origin-modes legend{margin:0 0 8px;padding:0;color:var(--dsw-alias-label-secondary,#606873);font:600 12px/1.4 system-ui}.dsh-mobile-control__origin-mode{display:flex;box-sizing:border-box;min-height:44px;align-items:center;gap:10px;padding:10px;border:1px solid var(--dsw-alias-border-l2,#dbe1e8);border-radius:10px;background:var(--dsw-alias-bg-layer-1,#f3f5f8);font:12px/1.5 system-ui;cursor:pointer}.dsh-mobile-control__origin-mode+.dsh-mobile-control__origin-mode{margin-top:8px}.dsh-mobile-control__origin-mode:has(input:checked){border-color:var(--dsw-alias-label-primary-bluish,#2563eb)}.dsh-mobile-control__origin-mode:focus-within{outline:2px solid var(--dsw-alias-state-business-primary,#2563eb);outline-offset:2px}.dsh-mobile-control__origin-mode:has(input:disabled){cursor:wait;opacity:.55}.dsh-mobile-control__origin-mode input[type=radio]{flex:0 0 18px;box-sizing:border-box;width:18px;height:18px;min-height:18px;margin:0;padding:0;accent-color:var(--dsw-alias-label-primary-bluish,#2563eb)}.dsh-mobile-control__origin-mode span{min-width:0;overflow-wrap:anywhere}
|
|
10052
|
+
/* Base the columns on the card width, not the desktop viewport behind the popup. */
|
|
10053
|
+
.dsh-mobile-control__origin-fields{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,140px),1fr));gap:12px}.dsh-mobile-control__origin-fields>.dsh-mobile-control__field{min-width:0;grid-column:auto;font-size:12px}.dsh-mobile-control__origin-fields>.dsh-mobile-control__field--full{grid-column:1/-1}.dsh-mobile-control__origin-fields select{box-sizing:border-box;width:100%;min-height:44px;padding:9px 10px;border:1px solid var(--dsw-alias-border-l3,#cfd5dd);border-radius:10px;background:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-primary,#16181d);font:16px/1.4 system-ui}.dsh-mobile-control__origin-fields select:disabled{cursor:not-allowed;opacity:.55}.dsh-mobile-control__caddy-form{display:grid;gap:12px}.dsh-mobile-control__caddy-form>.dsh-mobile-control__component-note,.dsh-mobile-control__caddy-form>.dsh-mobile-control__component-status,.dsh-mobile-control__caddy-form>.dsh-mobile-control__origin-feedback{margin:0;overflow-wrap:anywhere}.dsh-mobile-control__origin-setup .dsh-mobile-control__actions.dsh-mobile-control__caddy-actions{grid-template-columns:minmax(0,1fr);margin:0}.dsh-mobile-control__caddy-actions button{box-sizing:border-box;min-width:0;min-height:44px;padding:10px 12px;border-radius:10px;font:600 12px/1.4 system-ui;cursor:pointer}.dsh-mobile-control__origin-warning{margin:12px 0;padding:10px 12px;border-left:3px solid var(--dsw-alias-state-warn-primary,#a56810);border-radius:4px;background:var(--dsw-alias-bg-layer-1,#f3f5f8);color:var(--dsw-alias-label-primary,#384152);font-size:12px;line-height:1.6}.dsh-mobile-control__origin-feedback{font-size:12px;line-height:1.6;overflow-wrap:anywhere}.dsh-mobile-control__origin-feedback.is-error{color:var(--dsw-alias-state-error-primary,#bc3030)}.dsh-mobile-control__origin-fields input[aria-invalid=true]{border-color:var(--dsw-alias-state-error-primary,#bc3030)}.dsh-mobile-control__origin-backend{display:flex;min-width:0;flex-direction:column;align-items:stretch;gap:8px;margin-top:12px;padding-top:12px;border-top:1px solid var(--dsw-alias-border-l2,#dbe1e8)}.dsh-mobile-control__origin-backend button{align-self:flex-start;min-height:44px}.dsh-mobile-control__self-hosted-body .is-origin{margin-top:8px}
|
|
10040
10054
|
`;
|
|
10041
10055
|
/** Mount the desktop control or mobile feature enhancements. */
|
|
10042
10056
|
function apply(ctx) {
|