@linxin666/dsh-remote-web-ui 0.3.6 → 0.3.9

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.
Files changed (238) hide show
  1. package/README.i18n.yaml +2 -2
  2. package/README.md +77 -468
  3. package/README.zh.md +83 -113
  4. package/lib/client.js +955 -203
  5. package/lib/client.js.map +1 -1
  6. package/lib/index.js +1136 -1466
  7. package/lib/types/client/FooterRemoteEntry.d.ts +6 -7
  8. package/lib/types/client/FooterRemoteEntry.d.ts.map +1 -1
  9. package/lib/types/client/FooterRemoteEntry.js +1 -1
  10. package/lib/types/client/RemoteEntry.d.ts +7 -4
  11. package/lib/types/client/RemoteEntry.d.ts.map +1 -1
  12. package/lib/types/client/RemoteEntry.js +7 -10
  13. package/lib/types/client/RemotePanel.d.ts +2 -2
  14. package/lib/types/client/RemotePanel.d.ts.map +1 -1
  15. package/lib/types/client/RemotePanel.js +2 -2
  16. package/lib/types/client/RemoteSettingsCard.d.ts +9 -5
  17. package/lib/types/client/RemoteSettingsCard.d.ts.map +1 -1
  18. package/lib/types/client/RemoteSettingsCard.js +56 -3
  19. package/lib/types/client/deep-link.d.ts +10 -13
  20. package/lib/types/client/deep-link.d.ts.map +1 -1
  21. package/lib/types/client/deep-link.js +14 -74
  22. package/lib/types/client/index.d.ts +2 -6
  23. package/lib/types/client/index.d.ts.map +1 -1
  24. package/lib/types/client/index.js +73 -39
  25. package/lib/types/client/locales.d.ts +26 -12
  26. package/lib/types/client/locales.d.ts.map +1 -1
  27. package/lib/types/client/locales.js +36 -22
  28. package/lib/types/client/mobile-adapt.d.ts +40 -0
  29. package/lib/types/client/mobile-adapt.d.ts.map +1 -0
  30. package/lib/types/client/mobile-adapt.js +967 -0
  31. package/lib/types/client/pair-api.d.ts +24 -6
  32. package/lib/types/client/pair-api.d.ts.map +1 -1
  33. package/lib/types/client/pair-api.js +9 -14
  34. package/lib/types/client/remote-channel.d.ts +3 -0
  35. package/lib/types/client/remote-channel.d.ts.map +1 -1
  36. package/lib/types/client/remote-channel.js +35 -3
  37. package/lib/types/client/settings-form.d.ts +35 -43
  38. package/lib/types/client/settings-form.d.ts.map +1 -1
  39. package/lib/types/client/settings-form.js +60 -53
  40. package/lib/types/firewall.d.ts +75 -0
  41. package/lib/types/firewall.d.ts.map +1 -0
  42. package/lib/types/firewall.js +184 -0
  43. package/lib/types/gate.d.ts +11 -5
  44. package/lib/types/gate.d.ts.map +1 -1
  45. package/lib/types/gate.js +11 -5
  46. package/lib/types/index.d.ts +39 -10
  47. package/lib/types/index.d.ts.map +1 -1
  48. package/lib/types/index.js +206 -58
  49. package/lib/types/inner-auth.d.ts +32 -0
  50. package/lib/types/inner-auth.d.ts.map +1 -0
  51. package/lib/types/inner-auth.js +72 -0
  52. package/lib/types/lan-bind-plan.d.ts +55 -0
  53. package/lib/types/lan-bind-plan.d.ts.map +1 -0
  54. package/lib/types/lan-bind-plan.js +60 -0
  55. package/lib/types/lan-bind.d.ts +69 -0
  56. package/lib/types/lan-bind.d.ts.map +1 -0
  57. package/lib/types/lan-bind.js +128 -0
  58. package/lib/types/loopback-proxy.d.ts +9 -2
  59. package/lib/types/loopback-proxy.d.ts.map +1 -1
  60. package/lib/types/loopback-proxy.js +24 -2
  61. package/lib/types/pairing.d.ts +15 -3
  62. package/lib/types/pairing.d.ts.map +1 -1
  63. package/lib/types/pairing.js +20 -6
  64. package/lib/types/remote-api.d.ts +30 -13
  65. package/lib/types/remote-api.d.ts.map +1 -1
  66. package/lib/types/remote-api.js +55 -42
  67. package/lib/types/remote-channel-boot.d.ts +21 -2
  68. package/lib/types/remote-channel-boot.d.ts.map +1 -1
  69. package/lib/types/remote-channel-boot.js +65 -3
  70. package/lib/types/remote-channel-rules.d.ts +8 -0
  71. package/lib/types/remote-channel-rules.d.ts.map +1 -1
  72. package/lib/types/remote-channel-rules.js +9 -2
  73. package/lib/types/remote-methods.d.ts +45 -11
  74. package/lib/types/remote-methods.d.ts.map +1 -1
  75. package/lib/types/remote-methods.js +56 -27
  76. package/lib/types/remote-presence-pet.d.ts +51 -0
  77. package/lib/types/remote-presence-pet.d.ts.map +1 -0
  78. package/lib/types/remote-presence-pet.js +101 -0
  79. package/lib/types/routes.d.ts +76 -4
  80. package/lib/types/routes.d.ts.map +1 -1
  81. package/lib/types/routes.js +336 -19
  82. package/lib/types/tunnel.d.ts.map +1 -1
  83. package/lib/types/tunnel.js +7 -1
  84. package/package.json +20 -18
  85. package/src/client/FooterRemoteEntry.tsx +9 -10
  86. package/src/client/RemoteEntry.tsx +13 -14
  87. package/src/client/RemotePanel.tsx +5 -16
  88. package/src/client/RemoteSettingsCard.tsx +72 -13
  89. package/src/client/deep-link.ts +14 -75
  90. package/src/client/index.ts +77 -39
  91. package/src/client/locales.ts +36 -22
  92. package/src/client/mobile-adapt.ts +913 -0
  93. package/src/client/pair-api.ts +26 -15
  94. package/src/client/remote-channel.ts +31 -3
  95. package/src/client/settings-form.ts +78 -92
  96. package/src/dsh-home.ts +1 -1
  97. package/src/firewall.ts +230 -0
  98. package/src/gate.ts +11 -5
  99. package/src/index.ts +235 -65
  100. package/src/inner-auth.ts +85 -0
  101. package/src/lan-bind-plan.ts +81 -0
  102. package/src/lan-bind.ts +145 -0
  103. package/src/loopback-proxy.ts +34 -0
  104. package/src/pairing.persist.test.ts +1 -1
  105. package/src/pairing.ts +20 -6
  106. package/src/remote-api.ts +67 -45
  107. package/src/remote-channel-boot.ts +70 -3
  108. package/src/remote-channel-rules.ts +17 -2
  109. package/src/remote-methods.ts +58 -27
  110. package/src/remote-presence-pet.ts +129 -0
  111. package/src/routes.ts +358 -19
  112. package/src/tunnel.ts +7 -1
  113. package/assets/apple-touch-icon.png +0 -0
  114. package/assets/mobile-icon-192.png +0 -0
  115. package/assets/mobile-icon-512.png +0 -0
  116. package/assets/mobile-service-worker.js +0 -63
  117. package/lib/mobile.js +0 -17658
  118. package/lib/mobile.js.map +0 -1
  119. package/lib/types/mobile/PairRequiredView.d.ts +0 -7
  120. package/lib/types/mobile/PairRequiredView.d.ts.map +0 -1
  121. package/lib/types/mobile/PairRequiredView.js +0 -28
  122. package/lib/types/mobile/PairRequiredView.test.d.ts +0 -2
  123. package/lib/types/mobile/PairRequiredView.test.d.ts.map +0 -1
  124. package/lib/types/mobile/PairRequiredView.test.js +0 -24
  125. package/lib/types/mobile/api.d.ts +0 -145
  126. package/lib/types/mobile/api.d.ts.map +0 -1
  127. package/lib/types/mobile/api.js +0 -103
  128. package/lib/types/mobile/index.d.ts +0 -10
  129. package/lib/types/mobile/index.d.ts.map +0 -1
  130. package/lib/types/mobile/index.js +0 -38
  131. package/lib/types/mobile/markdown.d.ts +0 -34
  132. package/lib/types/mobile/markdown.d.ts.map +0 -1
  133. package/lib/types/mobile/markdown.js +0 -285
  134. package/lib/types/mobile/markdown.test.d.ts +0 -2
  135. package/lib/types/mobile/markdown.test.d.ts.map +0 -1
  136. package/lib/types/mobile/markdown.test.js +0 -79
  137. package/lib/types/mobile/messages.d.ts +0 -149
  138. package/lib/types/mobile/messages.d.ts.map +0 -1
  139. package/lib/types/mobile/messages.js +0 -561
  140. package/lib/types/mobile/messages.test.d.ts +0 -2
  141. package/lib/types/mobile/messages.test.d.ts.map +0 -1
  142. package/lib/types/mobile/messages.test.js +0 -356
  143. package/lib/types/mobile/mobile-styles.d.ts +0 -6
  144. package/lib/types/mobile/mobile-styles.d.ts.map +0 -1
  145. package/lib/types/mobile/mobile-styles.js +0 -1438
  146. package/lib/types/mobile/mobile-theme.d.ts +0 -22
  147. package/lib/types/mobile/mobile-theme.d.ts.map +0 -1
  148. package/lib/types/mobile/mobile-theme.js +0 -70
  149. package/lib/types/mobile/mobile-theme.test.d.ts +0 -2
  150. package/lib/types/mobile/mobile-theme.test.d.ts.map +0 -1
  151. package/lib/types/mobile/mobile-theme.test.js +0 -71
  152. package/lib/types/mobile/mux.d.ts +0 -128
  153. package/lib/types/mobile/mux.d.ts.map +0 -1
  154. package/lib/types/mobile/mux.js +0 -305
  155. package/lib/types/mobile/mux.test.d.ts +0 -2
  156. package/lib/types/mobile/mux.test.d.ts.map +0 -1
  157. package/lib/types/mobile/mux.test.js +0 -267
  158. package/lib/types/mobile/pairing.d.ts +0 -31
  159. package/lib/types/mobile/pairing.d.ts.map +0 -1
  160. package/lib/types/mobile/pairing.js +0 -62
  161. package/lib/types/mobile/rpc.d.ts +0 -38
  162. package/lib/types/mobile/rpc.d.ts.map +0 -1
  163. package/lib/types/mobile/rpc.js +0 -83
  164. package/lib/types/mobile/theme-toggle.d.ts +0 -12
  165. package/lib/types/mobile/theme-toggle.d.ts.map +0 -1
  166. package/lib/types/mobile/theme-toggle.js +0 -26
  167. package/lib/types/mobile/views/App.d.ts +0 -57
  168. package/lib/types/mobile/views/App.d.ts.map +0 -1
  169. package/lib/types/mobile/views/App.js +0 -150
  170. package/lib/types/mobile/views/App.test.d.ts +0 -2
  171. package/lib/types/mobile/views/App.test.d.ts.map +0 -1
  172. package/lib/types/mobile/views/App.test.js +0 -52
  173. package/lib/types/mobile/views/ChatView.d.ts +0 -63
  174. package/lib/types/mobile/views/ChatView.d.ts.map +0 -1
  175. package/lib/types/mobile/views/ChatView.js +0 -821
  176. package/lib/types/mobile/views/ChatView.stream.test.d.ts +0 -2
  177. package/lib/types/mobile/views/ChatView.stream.test.d.ts.map +0 -1
  178. package/lib/types/mobile/views/ChatView.stream.test.js +0 -236
  179. package/lib/types/mobile/views/ChatView.test.d.ts +0 -2
  180. package/lib/types/mobile/views/ChatView.test.d.ts.map +0 -1
  181. package/lib/types/mobile/views/ChatView.test.js +0 -718
  182. package/lib/types/mobile/views/SessionListView.d.ts +0 -27
  183. package/lib/types/mobile/views/SessionListView.d.ts.map +0 -1
  184. package/lib/types/mobile/views/SessionListView.js +0 -139
  185. package/lib/types/mobile/views/SessionListView.test.d.ts +0 -2
  186. package/lib/types/mobile/views/SessionListView.test.d.ts.map +0 -1
  187. package/lib/types/mobile/views/SessionListView.test.js +0 -167
  188. package/lib/types/mobile/views/WorkspaceView.d.ts +0 -21
  189. package/lib/types/mobile/views/WorkspaceView.d.ts.map +0 -1
  190. package/lib/types/mobile/views/WorkspaceView.js +0 -93
  191. package/lib/types/mobile/views/WorkspaceView.test.d.ts +0 -2
  192. package/lib/types/mobile/views/WorkspaceView.test.d.ts.map +0 -1
  193. package/lib/types/mobile/views/WorkspaceView.test.js +0 -183
  194. package/lib/types/mobile-api.d.ts +0 -65
  195. package/lib/types/mobile-api.d.ts.map +0 -1
  196. package/lib/types/mobile-api.js +0 -404
  197. package/lib/types/mobile-pending.d.ts +0 -38
  198. package/lib/types/mobile-pending.d.ts.map +0 -1
  199. package/lib/types/mobile-pending.js +0 -59
  200. package/lib/types/mobile-pwa.d.ts +0 -6
  201. package/lib/types/mobile-pwa.d.ts.map +0 -1
  202. package/lib/types/mobile-pwa.js +0 -17
  203. package/lib/types/mobile-routes.d.ts +0 -13
  204. package/lib/types/mobile-routes.d.ts.map +0 -1
  205. package/lib/types/mobile-routes.js +0 -217
  206. package/lib/types/paired-model-catalog.d.ts +0 -17
  207. package/lib/types/paired-model-catalog.d.ts.map +0 -1
  208. package/lib/types/paired-model-catalog.js +0 -311
  209. package/src/mobile/PairRequiredView.test.tsx +0 -28
  210. package/src/mobile/PairRequiredView.tsx +0 -58
  211. package/src/mobile/api.ts +0 -229
  212. package/src/mobile/index.tsx +0 -41
  213. package/src/mobile/markdown.test.ts +0 -91
  214. package/src/mobile/markdown.ts +0 -291
  215. package/src/mobile/messages.test.ts +0 -402
  216. package/src/mobile/messages.ts +0 -685
  217. package/src/mobile/mobile-styles.ts +0 -1439
  218. package/src/mobile/mobile-theme.test.ts +0 -84
  219. package/src/mobile/mobile-theme.ts +0 -76
  220. package/src/mobile/mux.test.ts +0 -314
  221. package/src/mobile/mux.ts +0 -336
  222. package/src/mobile/pairing.ts +0 -77
  223. package/src/mobile/rpc.ts +0 -90
  224. package/src/mobile/theme-toggle.tsx +0 -47
  225. package/src/mobile/views/App.test.tsx +0 -62
  226. package/src/mobile/views/App.tsx +0 -213
  227. package/src/mobile/views/ChatView.stream.test.tsx +0 -268
  228. package/src/mobile/views/ChatView.test.tsx +0 -816
  229. package/src/mobile/views/ChatView.tsx +0 -1342
  230. package/src/mobile/views/SessionListView.test.tsx +0 -207
  231. package/src/mobile/views/SessionListView.tsx +0 -244
  232. package/src/mobile/views/WorkspaceView.test.tsx +0 -227
  233. package/src/mobile/views/WorkspaceView.tsx +0 -245
  234. package/src/mobile-api.ts +0 -418
  235. package/src/mobile-pending.ts +0 -88
  236. package/src/mobile-pwa.ts +0 -19
  237. package/src/mobile-routes.ts +0 -231
  238. package/src/paired-model-catalog.ts +0 -272
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Remote-presence to pet-visibility link (user requirement): while at least
3
+ * one paired device is online (an active phone mirror session), the
4
+ * host-global pet is hidden through the pet's OWN hide switch (the
5
+ * PetService.setVisible RPC, the same one the pet's hide button uses);
6
+ * once the last device stays offline past a grace window, the pet is
7
+ * restored. The pet plugin is optional: without it (or on any pet failure)
8
+ * the link is a no-op - the remote-control feature never depends on the
9
+ * pet being installed.
10
+ *
11
+ * The visibility is host-global by design (the pet is host-global, no
12
+ * session dimension): the desktop and the phone share one pet, so the link
13
+ * hides it while the operator is away on a phone mirror and restores it
14
+ * when the mirror ends. A manual user hide is respected: if the pet is
15
+ * already hidden when the first device comes online, nothing is recorded
16
+ * and nothing is restored later.
17
+ */
18
+ /** Default restore grace: the presence sweep flips a device offline after
19
+ * ~25 s, and a phone that was briefly backgrounded should not flicker the
20
+ * pet; 2 minutes keeps the restore stable. */
21
+ const DEFAULT_RESTORE_AFTER_MS = 120_000;
22
+ const nodeTimers = { setTimeout, clearTimeout };
23
+ /**
24
+ * Start the presence link. Returns the disposer (withdraws the state
25
+ * subscription and cancels a pending restore).
26
+ * @param deps - pairing stream + pet seam (+ test seams).
27
+ */
28
+ export function startRemotePresencePet(deps) {
29
+ const restoreAfterMs = deps.restoreAfterMs ?? DEFAULT_RESTORE_AFTER_MS;
30
+ const timers = deps.timers ?? nodeTimers;
31
+ let previousOnline = false;
32
+ let hiddenByRemote = false;
33
+ let restoreTimer;
34
+ let disposed = false;
35
+ const clearRestore = () => {
36
+ if (restoreTimer !== undefined) {
37
+ timers.clearTimeout(restoreTimer);
38
+ restoreTimer = undefined;
39
+ }
40
+ };
41
+ const scheduleRestore = () => {
42
+ clearRestore();
43
+ restoreTimer = timers.setTimeout(() => {
44
+ restoreTimer = undefined;
45
+ restoreAfterTick();
46
+ }, restoreAfterMs);
47
+ };
48
+ const restoreAfterTick = () => {
49
+ if (disposed || !hiddenByRemote)
50
+ return;
51
+ const pet = deps.pet();
52
+ if (pet === undefined)
53
+ return;
54
+ hiddenByRemote = false;
55
+ void pet.setVisible(true).catch(() => {
56
+ // The pet bridge failed (e.g. the pet host was mid-reload): the pet
57
+ // stays whatever it is; the next connect/disconnect cycle re-evaluates.
58
+ });
59
+ };
60
+ const hideForRemote = () => {
61
+ if (hiddenByRemote)
62
+ return;
63
+ const pet = deps.pet();
64
+ if (pet === undefined)
65
+ return;
66
+ void pet.state().then((value) => {
67
+ if (disposed || hiddenByRemote)
68
+ return;
69
+ const visible = value.display?.visible;
70
+ if (visible !== true)
71
+ return;
72
+ hiddenByRemote = true;
73
+ return pet.setVisible(false).catch(() => {
74
+ // Hide failed: leave the flag unset so a later transition retries.
75
+ hiddenByRemote = false;
76
+ });
77
+ }, () => {
78
+ // The state read failed; do not record a hide we never performed.
79
+ });
80
+ };
81
+ const handle = (snapshot) => {
82
+ const online = snapshot.phase === 'connected' && snapshot.onlineCount > 0;
83
+ if (online && !previousOnline) {
84
+ cancelRestoreAndClear();
85
+ hideForRemote();
86
+ }
87
+ else if (!online && previousOnline) {
88
+ scheduleRestore();
89
+ }
90
+ previousOnline = online;
91
+ };
92
+ const cancelRestoreAndClear = () => {
93
+ clearRestore();
94
+ };
95
+ const unsubscribe = deps.onState(handle);
96
+ return () => {
97
+ disposed = true;
98
+ unsubscribe();
99
+ clearRestore();
100
+ };
101
+ }
@@ -3,9 +3,14 @@
3
3
  * under /api: the webserver matches exact paths before the connection
4
4
  * plugin's /api prefix, so these handlers own the full response lifecycle
5
5
  * and apply their own trust fence (loopback-only for control endpoints;
6
- * loopback-or-LAN for the phone-facing accept/heartbeat/status). The
7
- * cookie set on accept is the device identity the api/gate listener checks
8
- * on every other /api request.
6
+ * loopback-or-LAN for the phone-facing accept/heartbeat/status). The cookie
7
+ * set on accept is the device identity the plugin's own surfaces enforce:
8
+ * the /remote channel gate and the api/gate listener. Alongside the JSON
9
+ * family sit the phone-facing top-level pages (exact routes /pair-accept,
10
+ * /pair-app, /pair-app.sw.js) with their own LAN-or-public fence. Note that
11
+ * on the 0.1.2-alpha.2 cohort nothing emits api/gate — direct /api is
12
+ * governed by the harness fence + browser auth — while the /remote channel
13
+ * always enforces the pairing cookie itself.
9
14
  */
10
15
  import type { IncomingMessage, ServerResponse } from 'node:http';
11
16
  import type { WebRoute } from '@deepseek-ai/dsh-host-webserver';
@@ -26,6 +31,16 @@ import { type PairingService, type PairingSnapshot } from './pairing.ts';
26
31
  * browser markers are same-origin.
27
32
  */
28
33
  export declare function isTrustedApiRequest(request: IncomingMessage, trustedHosts: readonly string[]): boolean;
34
+ /**
35
+ * The rate-limit bucket key for one accept attempt (pure; unit-tested).
36
+ * The first client-visible XFF hop separates buckets behind the auto-tunnel
37
+ * (every internet client arrives from 127.0.0.1 there) — but only for
38
+ * loopback peers, since a direct LAN client can rotate the header freely.
39
+ * @param socketIp - the socket peer address.
40
+ * @param forwarded - the first XFF hop, already trimmed, if any.
41
+ * @param bucket - page (GET /pair-accept) vs api (POST /api/pair/accept).
42
+ */
43
+ export declare function acceptLimitKey(socketIp: string, forwarded: string | undefined, bucket: 'page' | 'api'): string;
29
44
  /**
30
45
  * The host authority of a configured public base URL, e.g. `foo.trycloudflare.com`
31
46
  * from `https://foo.trycloudflare.com`. Undefined when the URL does not parse —
@@ -35,6 +50,38 @@ export declare function isTrustedApiRequest(request: IncomingMessage, trustedHos
35
50
  * @returns the `host[:port]` authority the fence should trust.
36
51
  */
37
52
  export declare function publicHostOf(url: string | undefined): string | undefined;
53
+ /**
54
+ * The cookieless device credential: pass the device id from the /pair-app
55
+ * URL into sessionStorage (and localStorage for tab reloads) before any app
56
+ * script runs - same key the boot patch and the channel gate read. The
57
+ * replaceState to '/' hides the credential URL from the address bar and
58
+ * leaves the SPA at its canonical root path. The reopen service worker is
59
+ * registered in the same breath: later navigations to '/' (history,
60
+ * bookmark, tab restore) must not fall through to the harness index gate,
61
+ * which the cookieless flow can never satisfy.
62
+ */
63
+ export declare const APP_DEVICE_STORAGE_KEY = "dsh-remote-device";
64
+ export declare function appShellCaptureScript(deviceId: string): string;
65
+ /** Patch the official index document with the device-capture script. */
66
+ export declare function patchAppShell(html: string, deviceId: string): string;
67
+ /**
68
+ * The reopen service worker served at PAIR_PATHS.appServiceWorker. A paired
69
+ * phone comes back to `/` from history, bookmarks, or tab restore; the
70
+ * harness fallback seat answers that navigation with its browser-auth 401,
71
+ * and the cookieless mobile flow never holds a browser-auth cookie. The
72
+ * worker owns navigations to `/` instead: network-first through /pair-app
73
+ * (which validates the device cookie and refreshes its presence), the
74
+ * cached shell for offline opens, and a pass-through of the original
75
+ * request when the plugin no longer answers. Plain-HTTP LAN origins are not
76
+ * secure contexts, so the worker never registers there — the LAN reopen
77
+ * path stays "scan a fresh QR", which is cheap in-network.
78
+ *
79
+ * Kept as a plain string (same pattern as the capture script): it must load
80
+ * with no build step, run on every JS engine that ships service workers,
81
+ * and be assertable as source in tests. Bump SHELL_CACHE when the storage
82
+ * layout changes so old caches are pruned on activate.
83
+ */
84
+ export declare function appServiceWorkerScript(): string;
38
85
  /** Route paths (exact matches under /api). */
39
86
  export declare const PAIR_PATHS: {
40
87
  readonly issue: "/api/pair/issue";
@@ -44,6 +91,16 @@ export declare const PAIR_PATHS: {
44
91
  readonly heartbeat: "/api/pair/heartbeat";
45
92
  readonly status: "/api/pair/status";
46
93
  readonly events: "/api/pair/events";
94
+ readonly lanBind: "/api/pair/lan-bind";
95
+ /** Top-level accept-and-redirect entry the QR link points at. */
96
+ readonly acceptPage: "/pair-accept";
97
+ /** The cookieless app landing: serves the official shell for a paired device. */
98
+ readonly appPage: "/pair-app";
99
+ /**
100
+ * The reopen service worker (registered by the capture script). Root-level
101
+ * path so its default script-directory scope already covers `/`.
102
+ */
103
+ readonly appServiceWorker: "/pair-app.sw.js";
47
104
  };
48
105
  /**
49
106
  * /api/pair request payload contracts. Each POST endpoint validates its body
@@ -54,7 +111,6 @@ export declare const PAIR_PATHS: {
54
111
  * are tolerated exactly as the previous manual reads ignored them.
55
112
  */
56
113
  export declare const issuePayloadSchema: z.ZodObject<{
57
- workspaceId: z.ZodOptional<z.ZodString>;
58
114
  address: z.ZodOptional<z.ZodString>;
59
115
  }, z.core.$strip>;
60
116
  export declare const acceptPayloadSchema: z.ZodObject<{
@@ -86,6 +142,22 @@ export interface PairRoutesDeps {
86
142
  lanAddresses: readonly string[];
87
143
  /** Current desktop gate policy, re-read for every status response. */
88
144
  requirePairingForLan?: boolean | (() => boolean);
145
+ /**
146
+ * LAN-bind facts for the settings card (managed patch block state, live
147
+ * bind host/port, firewall summary). Re-read per request so a hot-reloaded
148
+ * rebind and a fresh toggle round are both reflected without a restart.
149
+ * The route is loopback-only; undefined drops it (tests).
150
+ */
151
+ lanBindStatus?: () => Record<string, unknown>;
152
+ /**
153
+ * The official index document to serve on the /pair-app landing. The
154
+ * plugin fetches it from the inner loopback with its own credential and
155
+ * patches it with the device-capture script, so a paired device loads
156
+ * the app shell WITHOUT passing the harness index gate - the mobile flow
157
+ * then needs no browser cookie at all (the channel gate accepts the
158
+ * cookieless header/query credential). Undefined drops the route (tests).
159
+ */
160
+ indexDocument?: (deviceId: string) => Promise<string | undefined>;
89
161
  }
90
162
  /**
91
163
  * Build the /api/pair route family.
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAA;AAC/D,OAAO,EAAE,CAAC,EAAgB,MAAM,KAAK,CAAA;AACrC,OAAO,EAA0B,KAAK,cAAc,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAA;AAIhG;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CA6BtG;AAKD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAOxE;AAKD,8CAA8C;AAC9C,eAAO,MAAM,UAAU;;;;;;;;CAQb,CAAA;AAEV;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB;;;iBAG7B,CAAA;AACF,eAAO,MAAM,mBAAmB;;iBAE9B,CAAA;AACF,eAAO,MAAM,mBAAmB;;iBAE9B,CAAA;AACF,eAAO,MAAM,uBAAuB,gCAA6B,CAAA;AAoBjE,gDAAgD;AAChD,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAElD;;OAEG;gBACS,OAAO,EAAE,cAAc;IAInC,4DAA4D;IAC5D,IAAI,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,IAAI;IAiBrD,kEAAkE;IAClE,IAAI,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI;IAYrC,wCAAwC;IACxC,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF;AAED,6CAA6C;AAC7C,MAAM,WAAW,cAAc;IAC7B,2BAA2B;IAC3B,OAAO,EAAE,cAAc,CAAA;IACvB,0EAA0E;IAC1E,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;IAC/B,sEAAsE;IACtE,oBAAoB,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,CAAA;CACjD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,QAAQ,EAAE,CAkO3D"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAA;AAC/D,OAAO,EAAE,CAAC,EAAgB,MAAM,KAAK,CAAA;AACrC,OAAO,EAA0B,KAAK,cAAc,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAA;AAKhG;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CA6BtG;AAKD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAK9G;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAOxE;AAKD;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,sBAAsB,CAAA;AAEzD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAI9D;AAED,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMpE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAoD/C;AA4BD,8CAA8C;AAC9C,eAAO,MAAM,UAAU;;;;;;;;;IASrB,iEAAiE;;IAEjE,iFAAiF;;IAEjF;;;OAGG;;CAEK,CAAA;AAEV;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB;;iBAE7B,CAAA;AACF,eAAO,MAAM,mBAAmB;;iBAE9B,CAAA;AACF,eAAO,MAAM,mBAAmB;;iBAE9B,CAAA;AACF,eAAO,MAAM,uBAAuB,gCAA6B,CAAA;AAoBjE,gDAAgD;AAChD,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAElD;;OAEG;gBACS,OAAO,EAAE,cAAc;IAInC,4DAA4D;IAC5D,IAAI,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,IAAI;IAiBrD,kEAAkE;IAClE,IAAI,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI;IAYrC,wCAAwC;IACxC,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF;AAED,6CAA6C;AAC7C,MAAM,WAAW,cAAc;IAC7B,2BAA2B;IAC3B,OAAO,EAAE,cAAc,CAAA;IACvB,0EAA0E;IAC1E,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;IAC/B,sEAAsE;IACtE,oBAAoB,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,CAAA;IAChD;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7C;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;CAClE;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,QAAQ,EAAE,CAmY3D"}