dsh-mobile 0.7.1 → 0.8.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 CHANGED
@@ -2,6 +2,35 @@
2
2
 
3
3
  Notable changes are recorded here. GitHub Releases provide the downloadable packages and generated commit notes.
4
4
 
5
+ ## 0.8.1 - 2026-11-01
6
+
7
+ - Recognize the four-seat settings grid introduced in DSH 0.2.2-alpha.2. Preserve upstream navigation and grid placement while retaining Mobile's accessible close-button target; older two-column settings keep their existing mobile layout.
8
+ - Extend upstream compatibility checks to DSH 0.2.1-rc.5 and 0.2.2-alpha.2, including settings, directory selection, attachments, sidebar, compressed Workspace traffic and public push lifecycle checks. No Android App update is needed for this web-page adjustment.
9
+ - Give main-slot panels a coarse-pointer control-size floor, with a complete root opt-out and exclusions for switches, ranges and nested opted-out widgets. This changes control boxes, not invisible hit regions; fine-pointer geometry and scrolling are unchanged. Stop WebView font boosting from breaking plugin line boxes. Thanks @LUgABeEEE for [#319](https://github.com/saya-ch/dsh-mobile/pull/319).
10
+ - Add a bilingual **plugin mobile baseline** (L1/L2/L3 levels, number provenance, copy-paste stylesheet) as informative project guidance, not an official DSH standard. Thanks @LUgABeEEE for [#316](https://github.com/saya-ch/dsh-mobile/pull/316).
11
+ - Defer [#314](https://github.com/saya-ch/dsh-mobile/pull/314)'s native boot-batch cache pending request cancellation, durable-body consistency, clear-versus-download isolation and device benefit measurements. The candidate retains the published App's WebView-managed network/cache path and does not require an Android update.
12
+ - Local network: add **Change network** in the desktop LAN panel. Keep the existing CA paths, paired devices, enabled preference and additional trusted networks; update the interface and leaf certificate without rerunning first-time setup or firewall installation. Serialize changes with local control writes and shutdown, refresh addresses/QR data after success, and distinguish failed recovery from a restored configuration. [#317](https://github.com/saya-ch/dsh-mobile/issues/317)
13
+
14
+ ## 0.8.0 - 2026-10-30
15
+
16
+ - **iPhone / iPad Web Push:** add opt-in notifications for capable Safari Home Screen web apps on trusted HTTPS, targeting iOS/iPadOS 18.4+. Choose Questions, Plans, Approvals, Responses, Goals and Failures in **DSH Settings → General → Web push notifications**, and send a test without submitting a model request. No native iOS app, service worker or notification SaaS account is required. Thanks @chintoleung for [#297](https://github.com/saya-ch/dsh-mobile/pull/297).
17
+ - Add a complete Safari pairing → Add to Home Screen → notification setup guide in Chinese and English. Explain separate Home Screen login state and generating a fresh pairing code without clearing existing data. Thanks @chintoleung for [#302](https://github.com/saya-ch/dsh-mobile/pull/302).
18
+ - Keep notification consent scoped to the paired device and exact Origin, with generic lock-screen text, encrypted Apple-only delivery, bounded retries, revocation checks and restart recovery. Notification taps never answer or approve a request. Delivery is best effort; this release accepts the contributor's iPhone testing, not independent maintainer Apple-device verification. See the [Web Push guide](docs/WEB_PUSH.en.md).
19
+ - Refuse to report browser logout as completed when optional push services are unavailable but this device still has enabled persistent notification consent; retain authentication for an explicit retry instead of silently leaving notifications enabled.
20
+ - Apply private-file permissions before writing push keys or subscriptions to a replacement file; permission failure removes the empty candidate and leaves the previous state intact.
21
+ - Remember the mobile sidebar's session-list position within the current page, with separate search positions. Sessions behind DSH's **More** control are not automatically expanded; reloading clears this position memory. Thanks @abworks-dev for [#307](https://github.com/saya-ch/dsh-mobile/pull/307).
22
+ - Style Mobile's injected Gallery and Take photo actions consistently at every viewport, including when DSH supplies no native button class. Thanks @LUgABeEEE for [#312](https://github.com/saya-ch/dsh-mobile/pull/312).
23
+ - Keep in-shell dialogs above the wide navigation rail through scoped layout changes, without maintaining a third-party plugin's private class names. Thanks @LUgABeEEE for [#309](https://github.com/saya-ch/dsh-mobile/pull/309).
24
+ - Enable compression on the live `/api/remote.mux` path by default; an explicit `websocketCompression.paths: []` opts out. Savings depend on the data and network. Thanks @LUgABeEEE for [#292](https://github.com/saya-ch/dsh-mobile/pull/292).
25
+ - Compress owned static assets with explicit encoding negotiation and `Vary`, keeping 304 responses bodyless. Request the compatibility bundle by its current content digest to avoid a stale shim after updates. API responses and authenticated HTML are not added to a new offline cache. Thanks @LUgABeEEE for [#310](https://github.com/saya-ch/dsh-mobile/pull/310) and [#311](https://github.com/saya-ch/dsh-mobile/pull/311).
26
+ - Upgrade React development tooling to 19 while retaining the host-provided React runtime, with no second copy bundled. Thanks Dependabot for [#140](https://github.com/saya-ch/dsh-mobile/pull/140).
27
+ - Restore the explicit contributor credit for @qzyqmzn's [#284](https://github.com/saya-ch/dsh-mobile/pull/284), which introduced the integrated iroh transport in 0.7.0.
28
+
29
+ ## Android 0.7.1 - 2026-10-30
30
+
31
+ - Update the build toolchain to AGP 9.4.1 / Gradle 9.8.2 and WebKit integration to 1.18.0, retaining `core-ktx` 1.15.0 for compileSdk 36. Thanks Dependabot for [#304](https://github.com/saya-ch/dsh-mobile/pull/304).
32
+ - Keep the compatibility and full iroh APK variants, the established application ID and signer, and existing pairing data. This is App build 86; plugin 0.8.0's iOS Web Push does not require an Android update.
33
+
5
34
  ## 0.7.1 - 2026-10-29
6
35
 
7
36
  - Reorganize **Mobile access** into a compact channel list and configuration pane, stacked on narrow screens. Device management has its own LAN/remote tabs beside Diagnostics; keyboard focus and Escape follow the open panel.
package/CONTRIBUTORS.md CHANGED
@@ -87,7 +87,7 @@ Thanks [@jamorzzz](https://github.com/jamorzzz) for the community-auth navigatio
87
87
  | [@1624318455](https://github.com/1624318455) | [#93](https://github.com/saya-ch/dsh-mobile/pull/93) |
88
88
  | [@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), [#200](https://github.com/saya-ch/dsh-mobile/pull/200) |
89
89
  | [@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), [#226](https://github.com/saya-ch/dsh-mobile/pull/226) |
90
- | [@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), [#229](https://github.com/saya-ch/dsh-mobile/pull/229) |
90
+ | [@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), [#229](https://github.com/saya-ch/dsh-mobile/pull/229), [#297](https://github.com/saya-ch/dsh-mobile/pull/297), [#302](https://github.com/saya-ch/dsh-mobile/pull/302) |
91
91
  | [@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) |
92
92
  | [@fengfanfan-max](https://github.com/fengfanfan-max) | [#143](https://github.com/saya-ch/dsh-mobile/pull/143) |
93
93
  | [@fqf060420](https://github.com/fqf060420) | [#170](https://github.com/saya-ch/dsh-mobile/pull/170) |
@@ -95,7 +95,7 @@ Thanks [@jamorzzz](https://github.com/jamorzzz) for the community-auth navigatio
95
95
  | [@JackRushante](https://github.com/JackRushante) | [#16](https://github.com/saya-ch/dsh-mobile/pull/16) |
96
96
  | [@liudasheng](https://github.com/liudasheng) | [#100](https://github.com/saya-ch/dsh-mobile/pull/100), [#130](https://github.com/saya-ch/dsh-mobile/pull/130) |
97
97
  | [@longisland-icetea](https://github.com/longisland-icetea) | [#59](https://github.com/saya-ch/dsh-mobile/pull/59), [#60](https://github.com/saya-ch/dsh-mobile/pull/60), [#63](https://github.com/saya-ch/dsh-mobile/pull/63) |
98
- | [@qzyqmzn](https://github.com/qzyqmzn) | [#38](https://github.com/saya-ch/dsh-mobile/pull/38), [#75](https://github.com/saya-ch/dsh-mobile/pull/75) |
98
+ | [@qzyqmzn](https://github.com/qzyqmzn) | [#38](https://github.com/saya-ch/dsh-mobile/pull/38), [#75](https://github.com/saya-ch/dsh-mobile/pull/75), [#284](https://github.com/saya-ch/dsh-mobile/pull/284) |
99
99
  | [@Sanksu](https://github.com/Sanksu) | [#118](https://github.com/saya-ch/dsh-mobile/pull/118) |
100
100
  | [@StrawberryAO](https://github.com/StrawberryAO) | [#34](https://github.com/saya-ch/dsh-mobile/pull/34), [#40](https://github.com/saya-ch/dsh-mobile/pull/40) |
101
101
  | [@xhwxt](https://github.com/xhwxt) | [#105](https://github.com/saya-ch/dsh-mobile/pull/105), [#134](https://github.com/saya-ch/dsh-mobile/pull/134) |
package/README.en.md CHANGED
@@ -11,6 +11,7 @@
11
11
  <a href="https://www.npmjs.com/package/dsh-mobile"><img src="https://img.shields.io/npm/dt/dsh-mobile?label=downloads&amp;color=2563EB" alt="total npm downloads"></a>
12
12
  <a href="https://github.com/saya-ch/dsh-mobile/actions/workflows/ci.yml"><img src="https://github.com/saya-ch/dsh-mobile/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
13
13
  <a href="https://github.com/saya-ch/dsh-mobile/releases"><img src="https://img.shields.io/badge/Android-10%2B-3DDC84?logo=android&amp;logoColor=white" alt="Android 10+"></a>
14
+ <a href="#iphone-and-ipad-home-screen-web-app-pwa"><img src="https://img.shields.io/badge/iOS%20%2F%20iPadOS-PWA-111111?logo=apple&amp;logoColor=white" alt="iOS / iPadOS Home Screen web app (PWA)"></a>
14
15
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-0F172A" alt="Apache-2.0"></a>
15
16
  <a href="https://github.com/awesome-dsh-plugin/awesome-dsh-plugin"><img src="https://awesome-dsh-plugin.com/badge.svg" alt="Awesome DSH Plugin"></a>
16
17
  </p>
@@ -18,6 +19,7 @@
18
19
  <p align="center">
19
20
  <a href="#what-it-does">What it does</a> ·
20
21
  <a href="#quick-start">Quick start</a> ·
22
+ <a href="#iphone-and-ipad-home-screen-web-app-pwa">iPhone / iPad</a> ·
21
23
  <a href="#connection-guide">Connection guide</a> ·
22
24
  <a href="#extend-and-customize">Extend and customize</a> ·
23
25
  <a href="#device-management">Device management</a> ·
@@ -26,20 +28,22 @@
26
28
  <a href="#compatibility">Compatibility</a> ·
27
29
  <a href="docs/README.md">Documentation</a> ·
28
30
  <a href="#contributors">Contributors</a> ·
29
- <a href="https://github.com/saya-ch/dsh-mobile/releases/tag/v0.7.1">Release notes</a> ·
31
+ <a href="https://github.com/saya-ch/dsh-mobile/releases/tag/v0.8.1">Release notes</a> ·
30
32
  <a href="README.md">简体中文</a>
31
33
  </p>
32
34
 
33
35
  > DSH Mobile is a DeepSeek Harness community plugin; the native app supports Android only.
34
36
  >
35
- > **Current stable release: 0.7.1**. Reorganize Mobile access and device management, improve cloudflared settings, pairing expiry and folded sidebars, and add iroh component cleanup and VPN troubleshooting. The independently released Android App remains at 0.7.0; existing pairings are kept. [Plugin release notes and downloads](https://github.com/saya-ch/dsh-mobile/releases/tag/v0.7.1) · [Full changelog](CHANGELOG.md).
37
+ > **Using an iPhone or iPad?** Use Safari or [add DSH Mobile to your Home Screen as a web app (PWA)](<#iphone-and-ipad-home-screen-web-app-pwa>)—no native iOS download needed.
38
+ >
39
+ > **Current stable release: 0.8.1**. Support DSH's new settings layout, change the LAN network interface while preserving existing pairings, improve touch-control adaptation, and add mobile adaptation guidance for plugin authors. No Android app update is required. [Plugin release notes and downloads](https://github.com/saya-ch/dsh-mobile/releases/tag/v0.8.1) · [Full changelog](CHANGELOG.md).
36
40
  >
37
41
  > **Version policy**: since plugin **0.6.2**, the Android app and plugin use independent version numbers and releases. Their numbers do not need to match, and a plugin update does not imply an app update. [Compatibility notes](#compatibility).
38
42
 
39
43
  <p align="center">
40
- <a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.7.0/dsh-mobile-android-v0.7.0.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>
41
- <a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.7.0/dsh-mobile-android-v0.7.0.apk"><strong>Download Android app 0.7.0 (compatibility)</strong></a><br>
42
- <sub><a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.7.0/dsh-mobile-android-v0.7.0-iroh.apk">64-bit full APK (experimental iroh)</a> · <a href="https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.7.0">Release notes and checksums</a></sub>
44
+ <a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.7.1/dsh-mobile-android-v0.7.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>
45
+ <a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.7.1/dsh-mobile-android-v0.7.1.apk"><strong>Download Android app 0.7.1 (compatibility)</strong></a><br>
46
+ <sub><a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.7.1/dsh-mobile-android-v0.7.1-iroh.apk">64-bit full APK (experimental iroh)</a> · <a href="https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.7.1">Release notes and checksums</a></sub>
43
47
  </p>
44
48
 
45
49
  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. The full Android App also supports experimental iroh encrypted direct connections with relay fallback. The phone reaches the computer's sessions, Workspaces, messages and tools. The computer manages LAN and remote switches and pairing authorizations separately; the Android app lists paired computers together. The plugin does not modify DeepSeek Harness source.
@@ -52,11 +56,12 @@ It also lets you customize the phone from a DSH conversation: `/mobile <what you
52
56
 
53
57
  - **Continue DSH work from a phone**: the same sessions, Workspaces, messages, and tools, in real time.
54
58
  - **Customize the phone UI by talking to DSH**: request layout, interaction, or feature changes in a conversation; changed customization resources are usually picked up automatically.
55
- - **A dedicated touch layout**: session drawer, tool details, settings, question cards, and composer reorganized for phones; the app follows the system locale (Chinese/English/Italian), plugin UI follows DSH's locale.
59
+ - **A dedicated touch layout**: session drawer, tool details, settings, question cards, and composer reorganized for phones. The sidebar remembers its list position within the page instead of jumping to the top after a session switch. The app follows the system locale (Chinese/English/Italian), plugin UI follows DSH's locale.
56
60
  - **Several remote options**: Tailscale, cpolar, cloudflared quick/named tunnels, self-hosted FRP, your own reverse proxy, and experimental iroh without a domain or public port; Windows/Linux x64 can also let the plugin manage Caddy HTTPS and certificates.
57
61
  - **Pairing and multi-device**: pair once via QR code, link, or key; Wi-Fi, hotspot, or IP changes normally recover automatically; the app lists LAN and remote paired computers together, checks their reachability periodically, and lets you switch, re-pair, or delete a local record.
58
62
  - **One-click diagnostics and approval**: check versions, gateway, network interface, firewall, and the remote path with a redacted report; approve blocked third-party plugin connections per exact path.
59
- - **Task system notifications**: completion and pending-input alerts via Android system notifications, enabled from DSH General settings inside the app, with redacted lock-screen text.
63
+ - **iPhone / iPad Web Push**: add the page to your Home Screen and explicitly enable notifications in DSH General settings. Choose from six categories and receive alerts while the page is closed or the screen is locked, without conversation text on the lock screen. [Requirements and setup](docs/WEB_PUSH.en.md).
64
+ - **Android task notifications**: enable completion and pending-input alerts in DSH General settings inside the app, using its separate native notification channel with redacted lock-screen text.
60
65
  - **Defense in depth**: a private CA pinned for LAN, trusted HTTPS for public remote paths, and a remote CA pinned by the 0.4.6 app for the self-signed FRP entry. Credentials are Keystore-backed, device tokens go only to their exact Origin, and third-party WebSockets are blocked by default.
61
66
 
62
67
  A paired device can operate DSH on the computer and must be treated as fully trusted. Enable LAN access only on trusted networks, and use a reliable HTTPS channel for remote access. Revoke a lost phone from the computer immediately.
@@ -105,12 +110,25 @@ Restart DSH, then search for **dsh-mobile** under **Settings → Plugin Market**
105
110
 
106
111
  `setup` automatically selects and remembers the current LAN; Wi-Fi, hotspot, and IP changes normally recover without re-pairing. Use `--address 192.168.x.x` only when automatic selection fails. Settings, certificates, devices, and customization files live under `$DSH_HOME/mobile-access/`.
107
112
 
108
- ### Install the phone app
113
+ ### Install the Android app
109
114
 
110
- Download the official Android APK using the link above, or open the computer's pairing link in a mobile browser. Then choose LAN or remote access in the [connection guide](#connection-guide); the phone needs no separate tunnel client.
115
+ Download the official Android APK using the link above. Then choose LAN or remote access in the [connection guide](#connection-guide); the phone needs no separate tunnel client. For browser access, including iOS, follow the steps below.
111
116
 
112
117
  Registry-installed plugins check for updates when the desktop UI loads and show “Update plugin” beside the access-panel title when a newer release is available. Restart DSH after installation. The app download entry shows the latest version; local development packages are not overwritten, and Android does not check for or push app-version updates.
113
118
 
119
+ ### iPhone and iPad: Home Screen web app (PWA)
120
+
121
+ The plugin runs on the **computer**; Safari loads its mobile interface. There is no native iOS app to install.
122
+
123
+ 1. Install and enable the plugin on the computer as above. In **Mobile Access**, configure your [connection](<#connection-guide>); prefer a stable, trusted HTTPS address for a lasting Home Screen installation.
124
+ 2. Stay in that connection's panel: use **Copy pairing link** for LAN, or **Generate remote pairing QR code** then **Copy remote pairing link** for Remote. Open the resulting browser link in **Safari** and complete pairing. Use the dedicated Mobile Access link, not the computer's ordinary DSH page; Android `dsh1.`/`dsh2.` keys are not browser pairing codes.
125
+ 3. From the paired page, open Safari's **Share** menu → **Add to Home Screen**. Turn on **Open as Web App** if offered, then tap **Add**. Menu layout varies; see [Apple's iPhone instructions](<https://support.apple.com/guide/iphone/bookmark-a-website-iph42ab2f3a7/ios>).
126
+ 4. Launch the new Home Screen icon to continue the same DSH sessions and Workspaces. If it shows a **Pairing code** form, follow the [fresh-code recovery steps](<docs/WEB_PUSH.en.md#if-the-home-screen-app-shows-a-pairing-form>); Safari's first code is single-use. A normal reconnect page uses saved pairing instead. Keep existing installations and pairing/site data when troubleshooting.
127
+
128
+ You can also keep using Safari without installing an icon. The computer, DSH and Mobile Gateway must stay running and reachable; adding the web app does **not** provide offline DSH. A changing tunnel hostname does not automatically transfer pairing or push consent.
129
+
130
+ **Enable Web Push:** launch the Home Screen icon, open **DSH Settings → General → Web push notifications**, select **Enable**, allow notifications and choose your categories. This targets capable iOS/iPadOS **18.4+** Home Screen apps on trusted HTTPS; ordinary Safari tabs and the Android app do not show this entry. Notifications are optional and are not required for ordinary access. [Full guide and troubleshooting](docs/WEB_PUSH.en.md).
131
+
114
132
  ## Connection guide
115
133
 
116
134
  LAN and remote access are independent connections. Prefer LAN while the phone is near the computer for the lowest latency, and enable remote access only when leaving that network. The computer manages their switches and pairing authorizations separately; the Android app shows all paired computers together in its device list.
@@ -201,7 +219,7 @@ After selecting the channel in the panel:
201
219
  <details>
202
220
  <summary>Remote notifications, server maintenance and security limits</summary>
203
221
 
204
- > **Remote notifications**: browser `Notification` permission is granted per Origin, and a web-page system toast appears only on the device running that page. Android task reminders are a separate 0.4.0 feature: enable them under DSH **Settings → General** in the app, and keep the WebView page alive; they are not a general background push service. For reliable background delivery, use a server-side webhook or bot channel you have configured.
222
+ > **Remote notifications**: Android task reminders use the page/SSE path and need the app's WebView to remain alive. [iPhone/iPad Web Push](docs/WEB_PUSH.en.md) is explicitly enabled from a capable Safari Home Screen app and does not need an open page. Both require DSH to keep running on the computer; networks, Focus settings and platform scheduling can delay delivery, so neither is a guaranteed alarm service. Independently configured channels such as dsh-ping remain unchanged.
205
223
 
206
224
  The Funnel runtime ties the public listener to the parent process and a bounded control channel; parent exit, channel closure, or an explicit stop ends the current generation and cleans up its resources. An unregistered domain on a mainland-China VPS may be intercepted by the cloud provider; public IPv4 mode avoids that dependency. The plugin validates pinned on-demand components; locally managed configuration and binaries live under `$DSH_HOME/mobile-access/` and can be cleaned up from the panel. VPS files require separate cleanup through the self-hosted connection guide.
207
225
 
@@ -348,7 +366,8 @@ Selection priority is device choice → computer defaults → plugin configurati
348
366
  | Client | Best for | Notes |
349
367
  | --- | --- | --- |
350
368
  | Android app | Everyday use | Separate Local and Remote entries at first pairing; LAN discovery, system trust for public remote certificates, and app-pinned CA for the self-signed FRP entry |
351
- | Mobile browser | Temporary or cross-platform | Open the HTTPS origin shown by Mobile Access; a private LAN certificate may need confirmation, while a public remote certificate should not warn |
369
+ | iPhone/iPad Safari or Home Screen web app (PWA) | Everyday iOS access and optional push | [Pair in Safari and add a Home Screen icon](<#iphone-and-ipad-home-screen-web-app-pwa>); no native iOS app. Capable Home Screen apps can enable [Web Push](docs/WEB_PUSH.en.md) |
370
+ | Mobile browser | Everyday or cross-platform access | Open the HTTPS origin shown by Mobile Access; a private LAN certificate may need confirmation, while a public remote certificate should not warn. Continuing through a certificate warning does not make the page eligible for Web Push |
352
371
 
353
372
  The Android app is a thin Kotlin WebView shell and contains no frontend copy; mobile browsers load the same page. Developers can append `?frontend=stock` to an authenticated mobile URL to diagnose boot and layout behavior. This entry skips dedicated mobile boot rewriting and module selection, but installed client adaptation and authenticated customizations may still apply. It is not a plugin-free control; some API operations may be rejected, so it does not replace normal mobile access. See [skins and mobile layout](docs/SKIN_COMPATIBILITY.en.md).
354
373
 
@@ -409,6 +428,8 @@ The plugin retains DSH host peer declarations without rejecting installation or
409
428
 
410
429
  ### OS support matrix
411
430
 
431
+ This table describes the **computer running the plugin**, not the phone's OS; iPhone/iPad access uses the [browser/Home Screen route](<#iphone-and-ipad-home-screen-web-app-pwa>).
432
+
412
433
  | Channel | Windows x64 | Linux x64 | Linux arm64 | macOS |
413
434
  | --- | --- | --- | --- | --- |
414
435
  | Local network | Yes (firewall automated) | Yes (open the firewall yourself) | Yes | Yes |
@@ -424,13 +445,15 @@ On macOS, local network, cloudflared, self-hosted FRP and the own reverse proxy
424
445
 
425
446
  | DSH Mobile plugin | Verified DeepSeek Harness version |
426
447
  | --- | --- |
427
- | `0.7.1` | Isolated packed installation, mobile sidebar and breakpoint hit tests on `0.2.1-rc.3`, plus access-panel, pairing-expiry and component-cleanup checks. See [CI](https://github.com/saya-ch/dsh-mobile/actions/workflows/ci.yml) for the automated matrix; browser checks do not establish every phone, plugin or public route |
448
+ | `0.8.1` | Add packed boot, settings, directory selection, attachments, sidebar and compressed Workspace checks on `0.2.1-rc.5` and `0.2.2-alpha.2`; see [CI](https://github.com/saya-ch/dsh-mobile/actions/workflows/ci.yml) for the complete version matrix |
449
+ | `0.8.0` | Push public-contract, settings, encrypted-payload and tap-ownership checks are pinned to `0.2.1-rc.2 / rc.3`; see [CI](https://github.com/saya-ch/dsh-mobile/actions/workflows/ci.yml) for the general boot/layout matrix. iOS device results accept contributor testing; browser checks do not establish every phone, plugin or public route |
428
450
 
429
451
  <details>
430
452
  <summary>Earlier release checks</summary>
431
453
 
432
454
  | DSH Mobile plugin | Verified DeepSeek Harness version |
433
455
  | --- | --- |
456
+ | `0.7.1` | Isolated packed installation, mobile sidebar and breakpoint hit tests on `0.2.1-rc.3`, plus access-panel, pairing-expiry and component-cleanup checks |
434
457
  | `0.6.11` | Isolated packed-browser CI on `0.1.7-alpha.2`, `0.1.7-rc.1`, `0.1.7-rc.2`, `0.2.0-rc.1`, `0.2.0-rc.2`, `0.2.1-alpha.2` and `0.2.1-alpha.3`; additional real history-pagination, viewport-preservation and manual-loading checks on `0.2.0-rc.2` and `0.2.1-alpha.3`. Browser checks do not establish acceptance of every phone engine, third-party plugin or public route |
435
458
  | `0.6.12` | Packed installation, mobile boot, missing-API simulation, Workspace streaming, retained-page transport recovery and mobile settings on `0.2.1-rc.2`; authentication/resource regression with the actual community `dsh-web-startup-auth@0.1.12` on `0.2.0-rc.2`. This does not establish physical Chromium 92, arbitrary auth-plugin or public-route acceptance |
436
459
  | `0.6.13` | Packed text/image HTTP 400 recovery, Host refusal guard and error-feedback checks on `0.2.0-rc.2` and `0.2.1-rc.2`; Gateway 408/431 classification, bounded diagnostics and four Gateway factory wiring passed local tests. DSH source, iroh P2P and Android native code are outside this release |
package/README.md CHANGED
@@ -11,6 +11,7 @@
11
11
  <a href="https://www.npmjs.com/package/dsh-mobile"><img src="https://img.shields.io/npm/dt/dsh-mobile?label=downloads&color=2563EB" alt="npm 总下载量"></a>
12
12
  <a href="https://github.com/saya-ch/dsh-mobile/actions/workflows/ci.yml"><img src="https://github.com/saya-ch/dsh-mobile/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
13
13
  <a href="https://github.com/saya-ch/dsh-mobile/releases"><img src="https://img.shields.io/badge/Android-10%2B-3DDC84?logo=android&logoColor=white" alt="Android 10+"></a>
14
+ <a href="#iphone-与-ipad主屏幕-web-apppwa"><img src="https://img.shields.io/badge/iOS%20%2F%20iPadOS-PWA-111111?logo=apple&amp;logoColor=white" alt="iOS / iPadOS 主屏幕 Web App(PWA)"></a>
14
15
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-0F172A" alt="Apache-2.0"></a>
15
16
  <a href="https://github.com/awesome-dsh-plugin/awesome-dsh-plugin"><img src="https://awesome-dsh-plugin.com/badge.svg" alt="Awesome DSH Plugin"></a>
16
17
  </p>
@@ -18,6 +19,7 @@
18
19
  <p align="center">
19
20
  <a href="#能做什么">能做什么</a> ·
20
21
  <a href="#快速开始">快速开始</a> ·
22
+ <a href="#iphone-与-ipad主屏幕-web-apppwa">iPhone / iPad</a> ·
21
23
  <a href="#连接教程">连接教程</a> ·
22
24
  <a href="#扩展与自定义">扩展与自定义</a> ·
23
25
  <a href="#设备管理">设备管理</a> ·
@@ -26,20 +28,22 @@
26
28
  <a href="#兼容性">兼容性</a> ·
27
29
  <a href="docs/README.md">文档</a> ·
28
30
  <a href="#贡献者">贡献者</a> ·
29
- <a href="https://github.com/saya-ch/dsh-mobile/releases/tag/v0.7.1">更新记录</a> ·
31
+ <a href="https://github.com/saya-ch/dsh-mobile/releases/tag/v0.8.1">更新记录</a> ·
30
32
  <a href="README.en.md">English</a>
31
33
  </p>
32
34
 
33
35
  > DSH Mobile 是 DeepSeek Harness 社区插件,原生 App 仅支持 Android。
34
36
  >
35
- > **当前正式版本:0.7.1**。整理移动访问面板与设备管理,改善 cloudflared 配置、配对码有效期和折叠侧栏;新增 iroh 下载组件清理与 VPN 排障说明。Android App 继续使用独立发布的 0.7.0,现有配对无需重建。[插件更新与下载](https://github.com/saya-ch/dsh-mobile/releases/tag/v0.7.1) · [完整更新记录](CHANGELOG.md)。
37
+ > **使用 iPhone 或 iPad?** 可以用 Safari 访问,或[添加到主屏幕作为 Web App(PWA)使用](<#iphone-与-ipad主屏幕-web-apppwa>),无需下载原生 iOS App。
38
+ >
39
+ > **当前正式版本:0.8.1**。适配 DSH 新版设置布局,支持在局域网面板切换网卡并保留已有配对,改善触屏控件适配,并补充面向插件作者的移动适配指南。Android App 无需同步更新。[插件更新与下载](https://github.com/saya-ch/dsh-mobile/releases/tag/v0.8.1) · [完整更新记录](CHANGELOG.md)。
36
40
  >
37
41
  > **版本说明**:自插件 **0.6.2** 起,Android App 与插件独立编号、独立发布,版本号无需一致;插件升级不代表 App 需要同步升级。[兼容说明](#兼容性)。
38
42
 
39
43
  <p align="center">
40
- <a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.7.0/dsh-mobile-android-v0.7.0.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>
41
- <a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.7.0/dsh-mobile-android-v0.7.0.apk"><strong>下载 Android App 0.7.0(兼容版)</strong></a><br>
42
- <sub><a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.7.0/dsh-mobile-android-v0.7.0-iroh.apk">64 位完整版(含实验性 iroh)</a> · <a href="https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.7.0">版本说明与校验文件</a></sub>
44
+ <a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.7.1/dsh-mobile-android-v0.7.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>
45
+ <a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.7.1/dsh-mobile-android-v0.7.1.apk"><strong>下载 Android App 0.7.1(兼容版)</strong></a><br>
46
+ <sub><a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.7.1/dsh-mobile-android-v0.7.1-iroh.apk">64 位完整版(含实验性 iroh)</a> · <a href="https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.7.1">版本说明与校验文件</a></sub>
43
47
  </p>
44
48
 
45
49
  DSH Mobile 是一个 DeepSeek Harness 插件,让手机浏览器或 Android App 通过局域网,或可选的 Tailscale Funnel、cpolar、cloudflared、自建 FRP、自有反向代理远程通道连接电脑;Android 完整版还支持实验性 iroh 加密直连与中继。手机可以继续使用电脑上的会话、工作区、消息和工具。电脑端分别启停局域网与远程访问、分别管理配对授权;Android App 统一显示已配对电脑。插件不修改 DeepSeek Harness 源码。
@@ -52,11 +56,12 @@ DSH Mobile 是一个 DeepSeek Harness 插件,让手机浏览器或 Android App
52
56
 
53
57
  - **在手机上继续电脑端的工作**:同一份会话、工作区、消息和工具,实时同步。
54
58
  - **用对话定制手机端**:在 DSH 对话里提出布局、交互或功能需求;文件修改完成后,自定义资源通常会自动更新。
55
- - **专属触屏布局**:会话抽屉、工具详情、设置、提问卡片和输入栏都按手机重新组织;App 跟随系统语言(简/英/意),插件界面跟随 DSH 语言。
59
+ - **专属触屏布局**:会话抽屉、工具详情、设置、提问卡片和输入栏都按手机重新组织;侧栏列表在本页内记住位置,切换会话再打开不会总跳回顶部。App 跟随系统语言(简/英/意),插件界面跟随 DSH 语言。
56
60
  - **多种远程通道**:Tailscale、cpolar、cloudflared 快速/命名隧道、自建 FRP、自有反向代理,以及无需域名和公网端口的实验性 iroh;Windows/Linux x64 还可由插件托管 Caddy HTTPS 与证书。
57
61
  - **配对与多设备**:扫码、链接或密钥配对一次;切换 Wi-Fi、热点或 IP 后通常自动恢复;App 在一个列表中显示局域网和远程配对的电脑,定期检测可达状态,并支持切换、重新配对或删除本地记录。
58
62
  - **一键诊断与放行**:检查版本、网关、网卡、防火墙和远程通道,生成脱敏报告;被拦截的第三方插件连接按确切路径一键放行。
59
- - **任务系统通知**:任务完成与待输入以 Android 系统通知提醒,可在 App 内的 DSH“通用设置”中开启,锁屏文本脱敏。
63
+ - **iPhone / iPad 网页推送**:将页面添加到主屏幕后,在 DSH“通用设置”中主动开启;支持六类提醒和分类开关,页面关闭或锁屏后也可接收,锁屏文字不含会话正文。[使用条件与设置](docs/WEB_PUSH.md)。
64
+ - **Android 任务通知**:在 App 内 DSH“通用设置”中开启任务完成与待输入提醒,使用独立的原生通知通道,锁屏文本脱敏。
60
65
  - **纵深安全**:局域网固定私有 CA,公开远程入口使用受信任 HTTPS;自签 FRP 入口由 0.4.6 App 固定远程 CA。凭据存 Keystore,设备令牌只发往精确 Origin,第三方 WS 默认拦截。
61
66
 
62
67
  配对设备可以操作电脑上的 DSH,应视为完全受信任的设备。局域网只在可信网络开启;远程访问应使用可靠的 HTTPS 通道。手机丢失时,请立即从电脑端撤销设备。
@@ -105,12 +110,25 @@ dsh plugin --profile web add dshmarket
105
110
 
106
111
  `setup` 会自动选择并记住当前局域网,切换 Wi-Fi、热点或 IP 后通常自动恢复;仅在自动选择失败时使用 `--address 192.168.x.x`。设置、证书、设备和自定义文件保存在 `$DSH_HOME/mobile-access/`。
107
112
 
108
- ### 安装手机 App
113
+ ### 安装 Android App
109
114
 
110
- 从上方链接下载正式 Android APK,或用手机浏览器打开电脑端生成的配对链接。随后按[连接教程](#连接教程)选择局域网或远程访问;手机不需要安装额外的隧道客户端。
115
+ 从上方链接下载正式 Android APK。随后按[连接教程](#连接教程)选择局域网或远程访问;手机不需要安装额外的隧道客户端。包括 iOS 在内的浏览器访问方式见下文。
111
116
 
112
117
  通过 npm 安装的插件会在桌面界面加载时检查新版本,有更新时在访问面板标题右侧显示“更新插件”,安装后需重启 DSH。App 下载入口展示最新版本;本地开发包不会被自动覆盖,Android App 不会主动检查或推送版本更新。
113
118
 
119
+ ### iPhone 与 iPad:主屏幕 Web App(PWA)
120
+
121
+ 插件运行在**电脑**上,Safari 加载其移动界面,无需安装原生 iOS App。
122
+
123
+ 1. 按上文在电脑安装并启用插件,在**移动访问**中配置[连接通道](<#连接教程>);长期主屏幕安装优先使用固定、受信任的 HTTPS 地址。
124
+ 2. 留在所选通道的面板:局域网用**复制配对链接**;远程用**生成远程配对二维码**,再**复制远程配对链接**。在 **Safari** 中打开所得浏览器链接并完成配对。须使用专用移动访问链接,而非电脑的普通 DSH 页面;Android 的 `dsh1.`/`dsh2.` 密钥不是浏览器配对码。
125
+ 3. 在已配对页面打开 Safari 的**分享**菜单 → **添加到主屏幕**。如有以 Web App 打开的选项,请开启,再轻点**添加**。菜单布局随版本变化,参见 [Apple 的 iPhone 添加说明](<https://support.apple.com/guide/iphone/bookmark-a-website-iph42ab2f3a7/ios>)。
126
+ 4. 从新主屏幕图标启动,继续使用同一份 DSH 会话和工作区。若显示**配对码**表单,请按[新码恢复步骤](<docs/WEB_PUSH.md#主屏幕-app-显示配对表单时>)操作;Safari 首次使用的码只能消费一次。普通重新连接页使用已有配对,不必重新配对。排障时保留已有安装、配对和网站数据。
127
+
128
+ 不添加图标也可以继续使用 Safari。电脑、DSH 与 Mobile Gateway 须保持运行且手机能够连接;添加 Web App **不会**提供离线 DSH。隧道域名改变后,不会自动迁移配对或推送同意。
129
+
130
+ **开启网页推送:**从主屏幕图标进入 DSH,打开 **设置 → 通用设置 → 网页推送通知**,点击**启用**并允许通知,再按需选择六类提醒。目标环境为具备页面级推送能力的 iOS/iPadOS **18.4+**,需要受信任的 HTTPS;普通 Safari 标签页和 Android App 不显示此入口。通知是可选功能,不影响日常访问。[完整指南与排障](docs/WEB_PUSH.md)。
131
+
114
132
  ## 连接教程
115
133
 
116
134
  局域网和远程访问是两套相互独立的连接:在电脑附近优先使用局域网,延迟最低;离开当前网络时再启用远程访问。电脑端分别管理开关与配对授权;Android App 将所有已配对电脑集中显示在设备列表中。
@@ -130,6 +148,8 @@ dsh plugin --profile web add dshmarket
130
148
 
131
149
  局域网和 HTTPS 远程配对码会显示有效截止时间;超时后重新生成即可。生成新码会使旧码失效,**复制配对链接**复用当前有效码,不会另行作废二维码。电脑端的 **设备** 入口可查看和撤销局域网、远程两组授权;这与 App 中保存的电脑列表是不同的管理对象。
132
150
 
151
+ 局域网配置完成后,面板会显示 **更换网络**:重新扫描电脑当前网卡并确认后,插件保留私有 CA 与已配对设备,只重签服务器证书、更新监听地址与允许网段。局域网正在运行时切换会短暂断开已连接手机,需要用新的配对二维码重连;未运行时只保存配置,下次开启生效。
152
+
133
153
  侧栏底部有其他插件入口时,**移动访问**会收起为手机图标;悬停可查看名称,点击仍打开原面板。独占该区域时恢复文字显示。
134
154
 
135
155
  端口说明:`dsh web --port` 修改 DSH Web 上游端口(默认 3080),插件会自动跟随;`dsh-mobile setup --port` 修改 Mobile HTTPS 监听端口(默认 3443),配对二维码会包含实际端口。若 DSH Desktop 以 `--port 0` 随机端口启动,网关跟随的是**当前实际端口**,`mobile-access/setup.json` 里的 `upstreamOrigin` 只是首次配置的快照,插件启动时会把它更新为当前端口——排查时不要把它当成网关实际使用的上游。
@@ -201,7 +221,7 @@ dsh plugin --profile web add dshmarket
201
221
  <details>
202
222
  <summary>远程通知、服务器运维与安全限制</summary>
203
223
 
204
- > **远程通知说明**:浏览器的 `Notification` 权限按 Origin 分别授权,网页系统通知只显示在运行该网页的设备上。Android App 的任务提醒是独立的 0.4.0 功能,需要在 App 内 DSH 的 **设置 → 通用设置** 中主动开启,且依赖 WebView 页面仍存活;它不是通用的后台推送。需要可靠的后台推送时,请使用你已配置的服务端 webhook 或机器人通道。
224
+ > **远程通知说明**:Android 任务提醒使用页面/SSE 路径,须保持 App 的 WebView 存活;[iPhone/iPad 网页推送](docs/WEB_PUSH.md)则由具备能力的 Safari 主屏幕 App 主动启用,不依赖页面一直打开。两者都需要电脑端 DSH 运行,通知可能受网络、专注模式和系统调度影响,不是保证送达的警报服务。独立配置的 dsh-ping 等通道不受影响。
205
225
 
206
226
  Funnel 的运行组件把公开监听生命周期绑定到父进程和受限控制通道;父进程退出、控制通道关闭或显式停止时会结束当前代次并清理资源。中国大陆 VPS 上的未备案域名可能被云厂商拦截,此时可使用公网 IPv4 模式。插件会校验按需下载的固定版本组件;本机托管的配置与程序保存在 `$DSH_HOME/mobile-access/`,可在面板中清理。VPS 侧的文件须按自建连接指南单独清理。
207
227
 
@@ -348,7 +368,8 @@ excludedClientModules:
348
368
  | 方式 | 适合场景 | 说明 |
349
369
  | --- | --- | --- |
350
370
  | Android App | 日常使用 | 首次配对时分别提供局域网与远程入口;局域网自动发现,公开远程证书由系统验证,自签 FRP 入口由 App 固定 CA |
351
- | 手机浏览器 | 临时或跨平台访问 | 打开“移动访问”卡片显示的 HTTPS 地址;局域网私有证书可能需要手动确认,公开远程证书不应出现警告 |
371
+ | iPhone/iPad Safari 或主屏幕 Web App(PWA) | iOS 日常访问与可选推送 | [用 Safari 配对并添加主屏幕图标](<#iphone-与-ipad主屏幕-web-apppwa>),无需原生 iOS App;具备能力的主屏幕 App 可开启[网页推送](docs/WEB_PUSH.md) |
372
+ | 手机浏览器 | 日常或跨平台访问 | 打开“移动访问”卡片显示的 HTTPS 地址;局域网私有证书可能需要手动确认,公开远程证书不应出现警告。绕过证书警告不等于满足网页推送条件 |
352
373
 
353
374
  Android App 只是 Kotlin WebView 薄壳,不内置另一份网页;手机浏览器访问的是同一页面。开发者可在已认证移动地址后追加 `?frontend=stock` 诊断启动与布局行为;该入口跳过专用移动启动改写和模块选择,但仍可能加载客户端移动适配及已认证定制,并非不含插件的对照页。部分 API 操作可能被拒绝,不能代替正常移动入口。详见[皮肤与移动布局](docs/SKIN_COMPATIBILITY.md)。
354
375
 
@@ -409,6 +430,8 @@ flowchart LR
409
430
 
410
431
  ### 系统支持矩阵
411
432
 
433
+ 此表说明**运行插件的电脑系统**,不是手机系统;iPhone/iPad 使用[浏览器/主屏幕入口](<#iphone-与-ipad主屏幕-web-apppwa>)。
434
+
412
435
  | 通道 | Windows x64 | Linux x64 | Linux arm64 | macOS |
413
436
  | --- | --- | --- | --- | --- |
414
437
  | 局域网 | 支持(自动配防火墙) | 支持(防火墙自理) | 支持 | 支持 |
@@ -424,13 +447,15 @@ macOS 上局域网、cloudflared、自建 FRP 与自有反向代理可用;Funn
424
447
 
425
448
  | DSH Mobile 插件 | 已验证的 DeepSeek Harness 版本与范围 |
426
449
  | --- | --- |
427
- | `0.7.1` | `0.2.1-rc.3` 的隔离打包安装、手机侧栏与断点命中回归;另验证访问面板、配对有效期和组件清理。自动检查范围见 [CI](https://github.com/saya-ch/dsh-mobile/actions/workflows/ci.yml);浏览器检查不代表所有手机、第三方插件或公网线路已验收 |
450
+ | `0.8.1` | 新增 `0.2.1-rc.5`、`0.2.2-alpha.2` 的打包启动与设置、目录选择、附件、侧栏、压缩 Workspace 连接检查;完整版本矩阵见 [CI](https://github.com/saya-ch/dsh-mobile/actions/workflows/ci.yml) |
451
+ | `0.8.0` | 网页推送的公共接口、设置、加密载荷与点击归属检查固定在 `0.2.1-rc.2 / rc.3`;通用启动与布局矩阵见 [CI](https://github.com/saya-ch/dsh-mobile/actions/workflows/ci.yml)。iOS 真机结果采信贡献者实测;浏览器检查不代表所有手机、第三方插件或公网线路已验收 |
428
452
 
429
453
  <details>
430
454
  <summary>较早版本的验证记录</summary>
431
455
 
432
456
  | DSH Mobile 插件 | 已验证的 DeepSeek Harness 版本与范围 |
433
457
  | --- | --- |
458
+ | `0.7.1` | `0.2.1-rc.3` 的隔离打包安装、手机侧栏与断点命中回归;另验证访问面板、配对有效期和组件清理 |
434
459
  | `0.6.11` | `0.1.7-alpha.2`、`0.1.7-rc.1`、`0.1.7-rc.2`、`0.2.0-rc.1`、`0.2.0-rc.2`、`0.2.1-alpha.2`、`0.2.1-alpha.3` 的隔离打包浏览器 CI;`0.2.0-rc.2` 与 `0.2.1-alpha.3` 另通过真实历史分页、滚动位置保持和手动加载检查。浏览器检查不代表所有手机内核、第三方插件或公网线路已验收 |
435
460
  | `0.6.12` | `0.2.1-rc.2` 的打包安装、移动启动、缺失 API 模拟、工作区实时读取、保留页面的断线恢复及移动设置;`0.2.0-rc.2` 搭配实际社区认证插件 `dsh-web-startup-auth@0.1.12` 的认证与资源回归。未将 Chromium 92 真机、任意认证插件或公网线路写成已验收 |
436
461
  | `0.6.13` | `0.2.0-rc.2`、`0.2.1-rc.2` 的打包图文 HTTP 400 恢复、Host 拒绝护栏与错误提示回归;网关 408/431 分类、三类受限诊断及四种 Gateway 工厂接线通过本地测试。DSH 源码、iroh P2P 和 Android 原生代码不在本版范围 |
package/SECURITY.md CHANGED
@@ -82,6 +82,12 @@ The maintainer will acknowledge a complete report within seven days. Publication
82
82
  - Proxied GUI responses allow HTTP iframe sources for compatibility with community surfaces. HTTP content is unauthenticated and unencrypted; Android still blocks mixed HTTP content inside HTTPS pages, and browsers may block it too. Prefer HTTPS and do not treat a gateway framing allowance as a transport-security guarantee.
83
83
  - Proxied GUI responses allow same-origin and Blob audio/video through `media-src 'self' blob:`; Gateway-owned login and pairing pages do not gain Blob media permission. External media and connections remain restricted. This permits a trusted page plugin to play a same-origin file fetched into an object URL; it does not bypass browser codec support or autoplay rules. Android retains its media user-gesture requirement. Media plugins should provide a visible poster and a user-initiated playback fallback rather than assume autoplay always succeeds.
84
84
 
85
+ ## iPhone and iPad Web Push
86
+
87
+ Web Push is opt-in per paired device, browser installation and exact HTTPS Origin. Subscription endpoints, VAPID keys and notification state are private credentials stored in the Mobile state directory; do not include them in reports or backups shared publicly. The sender encrypts generic notification text and accepts only validated Apple HTTPS endpoints, with DNS pinning, certificate verification, no redirects and bounded sends. Notification references never authorize a request, reveal conversation content, or bypass the Gateway's device authentication.
88
+
89
+ Disable, logout and device revocation stop future eligible sends; already accepted notifications may still arrive. Logout must not report success while enabled consent cannot be durably disabled, including temporary loss of the optional push Host services. The explicit administrator reset affects the whole notification registry, not pairings, and is never an automatic repair. See [Web Push setup and recovery](docs/WEB_PUSH.en.md).
90
+
85
91
  ## Known limitation
86
92
 
87
93
  The current DSH HTML boot process contains inline JavaScript, revives Schemastery callbacks with `new Function`, and applies some styles dynamically. To keep the stock Web UI runnable, the gateway's Content Security Policy currently includes `script-src 'self' 'unsafe-inline' 'unsafe-eval'` and `style-src 'self' 'unsafe-inline'`. The remaining directives still restrict origins, connections, frames, objects, workers, images, and form targets, but this policy does not eliminate script-injection risk. Removing these allowances requires upstream DSH support for nonces, stable hashes, external boot resources, and a non-evaluating schema representation.
@@ -18,9 +18,11 @@ The optional managed Caddy component is not included in the npm package or Andro
18
18
 
19
19
  The experimental Rust transport is adapted from [dsh-mobile-iroh](https://github.com/saya-ch/dsh-mobile-iroh), copyright 2026 Guangqi Zhang, under the MIT License, and the host baseline preserves zexadev's MIT-licensed dsh-tether attribution. The source notices and complete licenses are retained under `native/iroh-host/` and included with the npm package. The optional sidecar is not bundled: explicit installation reuses a verified companion copy or downloads the size- and SHA-256-pinned companion release payload. Enabling the channel alone does not download it.
20
20
 
21
- The npm package declares direct runtime dependencies on [Schemastery](https://github.com/shigma/schemastery) `^3.18.1`, [@noble/hashes](https://github.com/paulmillr/noble-hashes) `1.8.0`, [bonjour-service](https://github.com/onlxltd/bonjour-service) `1.4.4`, [eventsource-parser](https://github.com/rexxars/eventsource-parser) `3.1.0`, [qrcode](https://github.com/soldair/node-qrcode) `^1.5.4`, [selfsigned](https://github.com/jfromaniello/selfsigned) `^5.5.0`, and [ws](https://github.com/websockets/ws) `8.22.0`. These packages are distributed under the MIT License; the release checkout's exact transitive versions appear in the attached CycloneDX npm SBOM.
21
+ The npm package declares direct runtime dependencies on [Schemastery](https://github.com/shigma/schemastery) `^3.18.1`, [@noble/hashes](https://github.com/paulmillr/noble-hashes) `1.8.0`, [bonjour-service](https://github.com/onlxltd/bonjour-service) `1.4.4`, [eventsource-parser](https://github.com/rexxars/eventsource-parser) `3.1.0`, [qrcode](https://github.com/soldair/node-qrcode) `^1.5.4`, [selfsigned](https://github.com/jfromaniello/selfsigned) `^5.5.0`, [ws](https://github.com/websockets/ws) `8.22.0`, and [Zod](https://zod.dev/) `4.6.7`. These packages are distributed under the MIT License; the release checkout's exact transitive versions appear in the attached CycloneDX npm SBOM.
22
22
 
23
- The Android App runtime contains [Kotlin standard library](https://github.com/JetBrains/kotlin) `2.1.0`, [kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines) `1.6.4`, [JetBrains annotations](https://github.com/JetBrains/java-annotations) `13.0`, [AndroidX Core](https://developer.android.com/jetpack/androidx/releases/core) `1.15.0`, [AndroidX WebKit](https://developer.android.com/jetpack/androidx/releases/webkit) `1.17.1`, their AndroidX transitive components, [Guava listenablefuture](https://github.com/google/guava) `1.0`, and [ZXing Core](https://github.com/zxing/zxing) `3.5.4`. These runtime libraries are distributed under the Apache License 2.0; the exact resolved tree is attached to each release as `dsh-mobile-android-v<version>-dependencies.txt`.
23
+ Browser Web Push uses [web-push](https://github.com/web-push-libs/web-push) `3.6.7`, distributed under the Mozilla Public License 2.0 (MPL-2.0), for payload encryption and VAPID signing/key generation. It remains an unmodified, external Node runtime dependency, not part of the browser bundle; its npm package supplies the covered source and license. DSH Mobile owns the bounded HTTPS transport and endpoint validation. Exact transitive versions appear in the [npm lockfile](<package-lock.json>) and release SBOM.
24
+
25
+ The Android App runtime contains [Kotlin standard library](https://github.com/JetBrains/kotlin) `2.2.10`, [kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines) `1.6.4`, [JetBrains annotations](https://github.com/JetBrains/java-annotations) `13.0`, [AndroidX Core](https://developer.android.com/jetpack/androidx/releases/core) `1.15.0`, [AndroidX WebKit](https://developer.android.com/jetpack/androidx/releases/webkit) `1.18.0`, their AndroidX transitive components, [Guava listenablefuture](https://github.com/google/guava) `1.0`, and [ZXing Core](https://github.com/zxing/zxing) `3.5.4`. These runtime libraries are distributed under the Apache License 2.0; the exact resolved tree is attached to each release as `dsh-mobile-android-v<version>-dependencies.txt`.
24
26
 
25
27
  The full Android APK packages `libdsh_mobile_iroh_android_transport.so` for arm64-v8a and x86_64, from `native/iroh-android-transport` and `native/iroh-core`. It includes the matching `org.rustls:rustls-platform-verifier` JVM component from an immutable official Maven archive, selecting its version from the Android shim entry in `native/Cargo.lock`. These transport sources retain their MIT license; the surrounding Android shell remains Apache-2.0. The compatibility APK uses `-PirohNative=false` and contains neither native libraries nor the JVM verifier dependency; it retains installation support for 32-bit devices. Both builds include the third-party notices asset.
26
28
 
@@ -4,14 +4,14 @@
4
4
 
5
5
  DeepSeek Harness is the display name of this community-maintained Android WebView app. It opens the plugin's authenticated HTTPS page rather than bundling another DSH frontend. The app and mobile browsers receive the same DSH features and computer-side mobile customizations.
6
6
 
7
- The current stable app is **0.7.0** (build 85). The npm plugin and Android App have independent versions: a plugin update does not automatically require another APK. See the [0.7.0 changes](#070-update).
7
+ The current stable app is **0.7.1** (build 86). The npm plugin and Android App have independent versions: a plugin update does not automatically require another APK. See the [0.7.1 changes](#071-update).
8
8
 
9
- Android 10 or later is supported. The local iOS experiment is not a published or supported client.
9
+ This APK supports Android 10 or later. iPhone and iPad use the [Safari Home Screen web app and optional Web Push](../../docs/WEB_PUSH.en.md), not this Android package; no native iOS app is distributed.
10
10
 
11
11
  ## Install and pair
12
12
 
13
13
  1. Install and enable the plugin using the [project quick start](../../README.en.md#quick-start). Complete LAN setup from the command line or the computer's **Mobile Access** panel.
14
- 2. Install a signed Android APK from [GitHub Releases](https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.7.0). Choose the compatibility `.apk` for existing HTTPS channels, or the full `-iroh.apk` for experimental iroh on arm64-v8a/x86_64. Both have the same package ID and official signer; install only one and upgrade in place to retain pairings. A differently signed Debug APK cannot replace it; do not uninstall or clear data just to bypass that mismatch.
14
+ 2. Install a signed Android APK from [GitHub Releases](https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.7.1). Choose the compatibility `.apk` for existing HTTPS channels, or the full `-iroh.apk` for experimental iroh on arm64-v8a/x86_64. Both have the same package ID and official signer; install only one and upgrade in place to retain pairings. A differently signed Debug APK cannot replace it; do not uninstall or clear data just to bypass that mismatch.
15
15
  3. On the computer, generate a pairing key/link under **Mobile Access → Local network**, or configure a remote provider and generate its remote pairing QR code. In the app, choose the matching connection mode and scan or paste the link.
16
16
  4. Name the computer. The app stores each LAN or remote pairing as its own record. The phone does not need a cpolar, Cloudflare or Tailscale app.
17
17
 
@@ -36,6 +36,10 @@ Page zoom changes the whole page and is separate from per-address text preferenc
36
36
 
37
37
  Deleting a local record removes its saved token and pinned CA, not the computer's authorization or every short-lived WebView cookie. Use **Mobile Access** on the computer to revoke access immediately. A full Android clear-app-data reset removes all pairings and web data and is not a normal reconnection step.
38
38
 
39
+ ## 0.7.1 update
40
+
41
+ Update AndroidX WebKit to 1.18.0 and the build toolchain to AGP 9.4.1 / Gradle 9.8.2, retaining Android API 36 and the existing pairing format. Both APK variants keep the established signer and upgrade in place. Plugin 0.8.0's iPhone/iPad Web Push is a computer-side feature, not a reason to update the Android app.
42
+
39
43
  ## 0.7.0 update
40
44
 
41
45
  App 0.7.0/build 85 adds optional experimental iroh pairing and native transport in the full APK, working with plugin 0.7.0 or later. The compatibility APK retains existing HTTPS channels without native libraries, including on 32-bit devices. Legacy updates download compatibility by default; choose the full APK explicitly when using iroh. Both retain the device list, HTTPS pairings and established signer. Records from the separate experimental App do not migrate automatically.
@@ -148,7 +152,7 @@ Computer-side `host.mjs` extensions are trusted Node.js code, separate from this
148
152
 
149
153
  ## Build
150
154
 
151
- Use Android Studio or Android SDK 36 and JDK 17. The repository includes the Gradle 9.7.1 Wrapper.
155
+ Use Android Studio or Android SDK 36 and JDK 17. The repository includes the Gradle 9.8.2 Wrapper.
152
156
 
153
157
  ```powershell
154
158
  Set-Location apps/mobile/android
@@ -170,11 +174,11 @@ Native builds also include the JVM TLS verifier matching `native/Cargo.lock`, fr
170
174
 
171
175
  Current-source Debug builds use package `io.github.sayach.dshmobile.debug` with a `-debug` version suffix. They install beside the official App with separate storage and pairings. They do not upgrade or migrate an older unsuffixed Debug installation; preserve that app and its data rather than uninstalling or clearing it to switch packages. Release builds keep `io.github.sayach.dshmobile` and the established signer.
172
176
 
173
- The verified stable release is [Android 0.7.0](https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.7.0), build 85. The compatibility and full APKs each have a matching `.sha256` asset. Both public downloads retain the established release signer and package `io.github.sayach.dshmobile`. Earlier release history belongs in [CHANGELOG](../../CHANGELOG.md).
177
+ The verified stable release is [Android 0.7.1](https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.7.1), build 86. The compatibility and full APKs each have a matching `.sha256` asset. Both public downloads retain the established release signer and package `io.github.sayach.dshmobile`. Earlier release history belongs in [CHANGELOG](../../CHANGELOG.md).
174
178
 
175
179
  ## Acceptance and known limits
176
180
 
177
- - Both public App 0.7.0 APKs passed checksum, manifest, signer, notice and alignment checks. The full APK additionally passed ABI and retained JVM TLS/JNI entry checks; compatibility contains no native libraries. Earlier arm64 development evidence covers native iroh Gateway/custom-resource traffic without ADB forwarding. The final JVM TLS dependency correction has not had a new physical-device/public-relay run; a relay socket alone does not prove relayed payload traffic.
181
+ - Both public App 0.7.1 APKs passed checksum, manifest, established-signer, notice and alignment checks. The full APK additionally passed ABI and retained JVM TLS/JNI entry checks; compatibility contains no native libraries. There is no new physical-device or public-relay run for 0.7.1. Earlier arm64 development traffic remains historical evidence, not proof that a current connection uses the relay.
178
182
 
179
183
  - App 0.6.8's public APK passed identity, checksum and established-signer verification. A matching-signer Debug upgrade opened DSH and retained the saved device; controlled slow-link fault injection was interrupted before pairing and is not counted as passed.
180
184
 
@@ -4,14 +4,14 @@
4
4
 
5
5
  DeepSeek Harness 是这个社区维护的 Android WebView App 的显示名称。它直接打开插件提供的已认证 HTTPS 页面,不打包另一套 DSH 前端;App 与手机浏览器获得相同的 DSH 功能,以及电脑端配置的移动页面定制。
6
6
 
7
- 当前正式 App 为 **0.7.0**;构建号为 85。npm 插件与 Android App 独立编号、独立更新;插件升级不代表需要重新安装 APK。此次改进见 [0.7.0 更新](#070-更新)。
7
+ 当前正式 App 为 **0.7.1**;构建号为 86。npm 插件与 Android App 独立编号、独立更新;插件升级不代表需要重新安装 APK。此次改进见 [0.7.1 更新](#071-更新)。
8
8
 
9
- 支持 Android 10 及以上系统。iOS 本地实验不属于已发布或受支持的客户端。
9
+ 此 APK 支持 Android 10 及以上系统。iPhone 和 iPad 使用 [Safari 主屏幕 Web App 与可选网页推送](../../docs/WEB_PUSH.md),不安装 Android 包;本项目不分发原生 iOS App。
10
10
 
11
11
  ## 安装与配对
12
12
 
13
13
  1. 按[项目快速开始](../../README.md#快速开始)安装并启用插件。局域网配置可通过命令行或电脑端的 **移动访问** 面板完成。
14
- 2. 从 [GitHub Releases](https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.7.0) 安装已签名 APK。原有 HTTPS 通道可选兼容版 `.apk`;arm64-v8a/x86_64 设备使用实验性 iroh 时选完整版 `-iroh.apk`。两包使用相同包名和正式签名,选一个原位升级即可保留配对;不同签名的 Debug 包不能直接覆盖正式版,不要为绕过签名不匹配而卸载或清除数据。
14
+ 2. 从 [GitHub Releases](https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.7.1) 安装已签名 APK。原有 HTTPS 通道可选兼容版 `.apk`;arm64-v8a/x86_64 设备使用实验性 iroh 时选完整版 `-iroh.apk`。两包使用相同包名和正式签名,选一个原位升级即可保留配对;不同签名的 Debug 包不能直接覆盖正式版,不要为绕过签名不匹配而卸载或清除数据。
15
15
  3. 在电脑 **移动访问 → 局域网访问** 中生成密钥/配对链接,或配置远程通道并生成远程配对二维码。在 App 选择对应方式,扫码或粘贴链接。
16
16
  4. 为电脑命名。每条局域网或远程配对单独保存;手机无需安装 cpolar、Cloudflare 或 Tailscale App。
17
17
 
@@ -36,6 +36,10 @@ DeepSeek Harness 是这个社区维护的 Android WebView App 的显示名称。
36
36
 
37
37
  删除本机记录会移除保存的设备令牌和固定 CA,不等于撤销电脑授权或清除所有 WebView 短期 Cookie。需要立即终止访问时,请在电脑的 **移动访问** 中撤销设备。Android“清除应用数据”会删除全部配对和网页数据,不是普通重连的处理步骤。
38
38
 
39
+ ## 0.7.1 更新
40
+
41
+ 更新 AndroidX WebKit 至 1.18.0,构建工具更新为 AGP 9.4.1 / Gradle 9.8.2;保留 Android API 36 和既有配对格式。两种 APK 均沿用正式签名,可原位升级。插件 0.8.0 的 iPhone/iPad 网页推送属于电脑端功能,不要求为此升级 Android App。
42
+
39
43
  ## 0.7.0 更新
40
44
 
41
45
  App 0.7.0/构建 85 在完整版中增加可选的实验性 iroh 配对和原生传输,配合插件 0.7.0 及以上版本使用。兼容版不含原生库,保留现有 HTTPS 通道并继续支持 32 位设备。旧版更新入口默认下载兼容版;使用 iroh 时请主动选择完整版。两包均保留设备列表、HTTPS 配对和原有正式签名。独立实验 App 的记录不会自动迁移。
@@ -148,7 +152,7 @@ Bridge 文件/相机操作串行执行,最长等待五分钟。取消、文
148
152
 
149
153
  ## 构建
150
154
 
151
- 使用 Android Studio 或 Android SDK 36 与 JDK 17;仓库包含 Gradle 9.7.1 Wrapper。
155
+ 使用 Android Studio 或 Android SDK 36 与 JDK 17;仓库包含 Gradle 9.8.2 Wrapper。
152
156
 
153
157
  ```powershell
154
158
  Set-Location apps/mobile/android
@@ -170,11 +174,11 @@ Set-Location apps/mobile/android
170
174
 
171
175
  当前源码的 Debug 构建使用包名 `io.github.sayach.dshmobile.debug` 与 `-debug` 版本后缀,可与正式 App 并存,存储和配对彼此独立。它不会升级或迁移旧版无后缀 Debug 应用;切换包名时应保留旧应用和数据,不要为此卸载或清除。Release 构建继续使用 `io.github.sayach.dshmobile` 与既定正式签名。
172
176
 
173
- 已核验的正式版本为 [Android 0.7.0](https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.7.0),构建 85。兼容版与完整版分别附有对应的 `.sha256` 校验文件;两个公开下载均沿用正式发布签名及包名 `io.github.sayach.dshmobile`。旧版本历史集中在 [CHANGELOG](../../CHANGELOG.md)。
177
+ 已核验的正式版本为 [Android 0.7.1](https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.7.1),构建 86。兼容版与完整版分别附有对应的 `.sha256` 校验文件;两个公开下载均沿用正式发布签名及包名 `io.github.sayach.dshmobile`。旧版本历史集中在 [CHANGELOG](../../CHANGELOG.md)。
174
178
 
175
179
  ## 验收与已知限制
176
180
 
177
- - App 0.7.0 的两份公开 APK 均通过校验值、Manifest、正式签名、许可文本和对齐检查;完整版另检查两个 ABI 及保留的 JVM TLS/JNI 入口,兼容版确认没有原生库。此前的 arm64 开发构建有不依赖 ADB 转发的原生 iroh 网关/定制资源真机链路证据;最后补齐 JVM TLS 依赖后尚未新增真机公网中继回归,不能仅凭中继连接存在宣称数据已走中继。
181
+ - App 0.7.1 的两份公开 APK 均通过校验值、Manifest、既定正式签名、许可文本和对齐检查;完整版另检查两个 ABI 及保留的 JVM TLS/JNI 入口,兼容版确认没有原生库。本版未新增真机或公网中继回归。较早 arm64 开发构建的链路记录仍属历史证据,不能据此断言当前连接的数据已经过中继。
178
182
 
179
183
  - App 0.6.8 的公开 APK 已核验身份、校验值和既定正式签名。Debug 包同签名原位升级后可打开 DSH,并保留原设备记录;受控慢链路故障注入在配对前中断,不计为通过。
180
184
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.7.0",
3
- "versionCode": 85,
4
- "releaseTag": "android-v0.7.0"
2
+ "version": "0.7.1",
3
+ "versionCode": 86,
4
+ "releaseTag": "android-v0.7.1"
5
5
  }
Binary file
Binary file
Binary file
@@ -2,6 +2,8 @@
2
2
 
3
3
  [中文](MOBILE_PLUGIN_ADAPTATION.md) · [Documentation index](README.md)
4
4
 
5
+ > The acceptance levels and where the numbers come from are in the [plugin mobile baseline](MOBILE_PLUGIN_BASELINE.en.md); this guide covers the techniques.
6
+
5
7
  This guide is for DSH plugin authors, aiming for **usable small screens without desktop regressions**. DSH Mobile provides connectivity, page layout and shared entry points; it does not rearrange every third-party plugin's internal controls. Start in a browser, then add device acceptance; an Android device is not required to begin.
6
8
 
7
9
  ## Identify where the panel is mounted
@@ -124,6 +126,22 @@ This is not a guarantee that every body child outranks every dialog. Negative va
124
126
 
125
127
  Verify actual visibility, focus and `document.elementFromPoint()` while the drawer, detail panel and settings are open, in narrow and wide layouts. The owned `smoke:plugin-portal-layers` fixture checks positive-z-index body menus and a top-layer dialog; it is not acceptance of every community plugin.
126
128
 
129
+ ## Host-provided touch floor
130
+
131
+ When a third-party panel is open in the main slot, the mobile layer provides three safety measures:
132
+
133
+ - on a coarse pointer, ordinary buttons, selects and text inputs get **44×44 CSS px minimum layout boxes**. This changes visual geometry; it is not an invisible hit-area extension. Switches, checkboxes and ranges keep their own geometry, and the panel owns multiline inputs;
134
+ - a panel root that is `width:100vw` or a fixed pixel width is capped to the available width instead of overflowing;
135
+ - the panel content can scroll and contain the gesture without also making the outer main pane a second scroll container; the plugin's own scroll container remains the first choice.
136
+
137
+ This is a **floor, not a substitute for adapting the plugin**. A panel that ships its own touch geometry opts out on its root:
138
+
139
+ ```html
140
+ <main data-dsh-adapt="off">…</main>
141
+ ```
142
+
143
+ Root opt-out also disables the sizing and outer-scroll overrides; nested groups can use the attribute to retain their own control sizes. These rules apply only to coarse pointers and leave fine-pointer geometry and scrolling unchanged. Plugin authors still own responsive adaptation; this is not a compatibility guarantee for arbitrary plugin combinations.
144
+
127
145
  ## Verification: what code checks, browsers and devices establish
128
146
 
129
147
  ### Structural checks