dsh-zen-remote 2.3.10 → 2.4.0

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 (244) hide show
  1. package/CHANGELOG.md +44 -72
  2. package/README.md +94 -84
  3. package/README.zh-CN.md +90 -81
  4. package/bin/zen-remote.mjs +5 -0
  5. package/docs/interface.md +6 -6
  6. package/docs/remote-access.en.md +6 -4
  7. package/docs/remote-access.md +6 -4
  8. package/dsh-push.mjs +96 -10
  9. package/lib/adapters/dsh-better-sidebar/index.js +7 -3
  10. package/lib/adapters/dsh-better-sidebar/index.js.map +1 -1
  11. package/lib/admin-routes.js +10 -2
  12. package/lib/admin-routes.js.map +1 -1
  13. package/lib/cli/args.js +251 -0
  14. package/lib/cli/args.js.map +1 -0
  15. package/lib/cli/bootstrap.js +449 -0
  16. package/lib/cli/bootstrap.js.map +1 -0
  17. package/lib/cli/command-setup.js +484 -0
  18. package/lib/cli/command-setup.js.map +1 -0
  19. package/lib/cli/commands-client.js +359 -0
  20. package/lib/cli/commands-client.js.map +1 -0
  21. package/lib/cli/commands-host.js +1108 -0
  22. package/lib/cli/commands-host.js.map +1 -0
  23. package/lib/cli/commands-status.js +279 -0
  24. package/lib/cli/commands-status.js.map +1 -0
  25. package/lib/cli/config-writer.js +334 -0
  26. package/lib/cli/config-writer.js.map +1 -0
  27. package/lib/cli/context.js +10 -0
  28. package/lib/cli/context.js.map +1 -0
  29. package/lib/cli/i18n.js +620 -0
  30. package/lib/cli/i18n.js.map +1 -0
  31. package/lib/cli/ipc-client.js +160 -0
  32. package/lib/cli/ipc-client.js.map +1 -0
  33. package/lib/cli/ipc-server.js +464 -0
  34. package/lib/cli/ipc-server.js.map +1 -0
  35. package/lib/cli/main.js +245 -0
  36. package/lib/cli/main.js.map +1 -0
  37. package/lib/cli/qr-terminal.js +48 -0
  38. package/lib/cli/qr-terminal.js.map +1 -0
  39. package/lib/client-data/qr.js +286 -0
  40. package/lib/client-data/qr.js.map +1 -0
  41. package/lib/client-routes.js +308 -25
  42. package/lib/client-routes.js.map +1 -1
  43. package/lib/client.js +1013 -229
  44. package/lib/config.js +50 -12
  45. package/lib/config.js.map +1 -1
  46. package/lib/debug-report.js +28 -1
  47. package/lib/debug-report.js.map +1 -1
  48. package/lib/fetch-route-intercept.js +334 -26
  49. package/lib/fetch-route-intercept.js.map +1 -1
  50. package/lib/index.js +573 -366
  51. package/lib/index.js.map +1 -1
  52. package/lib/intercept.js +1833 -280
  53. package/lib/intercept.js.map +1 -1
  54. package/lib/lan-gate-server.cjs +36 -10
  55. package/lib/merge-streams.js +103 -11
  56. package/lib/merge-streams.js.map +1 -1
  57. package/lib/plugin-route-intercept.js +93 -63
  58. package/lib/plugin-route-intercept.js.map +1 -1
  59. package/lib/relay-access.js +8 -1
  60. package/lib/relay-access.js.map +1 -1
  61. package/lib/relay-client.js +133 -4
  62. package/lib/relay-client.js.map +1 -1
  63. package/lib/relay-pool.js +275 -0
  64. package/lib/relay-pool.js.map +1 -0
  65. package/lib/relay-server.js +269 -17
  66. package/lib/relay-server.js.map +1 -1
  67. package/lib/restart-fields.js +6 -4
  68. package/lib/restart-fields.js.map +1 -1
  69. package/lib/share-store.js +65 -27
  70. package/lib/share-store.js.map +1 -1
  71. package/lib/state-store.js +400 -0
  72. package/lib/state-store.js.map +1 -0
  73. package/lib/types/adapters/dsh-better-sidebar/index.d.ts +3 -2
  74. package/lib/types/adapters/dsh-better-sidebar/index.d.ts.map +1 -1
  75. package/lib/types/admin-routes.d.ts.map +1 -1
  76. package/lib/types/cli/args.d.ts +78 -0
  77. package/lib/types/cli/args.d.ts.map +1 -0
  78. package/lib/types/cli/bootstrap.d.ts +170 -0
  79. package/lib/types/cli/bootstrap.d.ts.map +1 -0
  80. package/lib/types/cli/command-setup.d.ts +72 -0
  81. package/lib/types/cli/command-setup.d.ts.map +1 -0
  82. package/lib/types/cli/commands-client.d.ts +36 -0
  83. package/lib/types/cli/commands-client.d.ts.map +1 -0
  84. package/lib/types/cli/commands-host.d.ts +82 -0
  85. package/lib/types/cli/commands-host.d.ts.map +1 -0
  86. package/lib/types/cli/commands-status.d.ts +46 -0
  87. package/lib/types/cli/commands-status.d.ts.map +1 -0
  88. package/lib/types/cli/config-writer.d.ts +92 -0
  89. package/lib/types/cli/config-writer.d.ts.map +1 -0
  90. package/lib/types/cli/context.d.ts +39 -0
  91. package/lib/types/cli/context.d.ts.map +1 -0
  92. package/lib/types/cli/i18n.d.ts +32 -0
  93. package/lib/types/cli/i18n.d.ts.map +1 -0
  94. package/lib/types/cli/ipc-client.d.ts +83 -0
  95. package/lib/types/cli/ipc-client.d.ts.map +1 -0
  96. package/lib/types/cli/ipc-server.d.ts +113 -0
  97. package/lib/types/cli/ipc-server.d.ts.map +1 -0
  98. package/lib/types/cli/main.d.ts +57 -0
  99. package/lib/types/cli/main.d.ts.map +1 -0
  100. package/lib/types/cli/qr-terminal.d.ts +17 -0
  101. package/lib/types/cli/qr-terminal.d.ts.map +1 -0
  102. package/lib/types/client/RemoteStatusIcon.d.ts.map +1 -1
  103. package/lib/types/client/current-session-report.d.ts +4 -0
  104. package/lib/types/client/current-session-report.d.ts.map +1 -1
  105. package/lib/types/client/effects/model-group-side.d.ts.map +1 -1
  106. package/lib/types/client/effects/remote-session.d.ts.map +1 -1
  107. package/lib/types/client/locales.d.ts +47 -3
  108. package/lib/types/client/locales.d.ts.map +1 -1
  109. package/lib/types/client/settings/SettingsSection.d.ts.map +1 -1
  110. package/lib/types/client/settings/settings-css.d.ts +1 -1
  111. package/lib/types/client/settings/settings-css.d.ts.map +1 -1
  112. package/lib/types/client/styles/remote-session.css.d.ts +1 -1
  113. package/lib/types/client/styles/remote-session.css.d.ts.map +1 -1
  114. package/lib/types/client/wizard/GatewayWizard.d.ts.map +1 -1
  115. package/lib/types/client/wizard/cards/ProxyCard.d.ts.map +1 -1
  116. package/lib/types/client/wizard/wizard-css.d.ts +1 -1
  117. package/lib/types/client/wizard/wizard-css.d.ts.map +1 -1
  118. package/lib/types/client-data/model-group-side.d.ts +23 -2
  119. package/lib/types/client-data/model-group-side.d.ts.map +1 -1
  120. package/lib/types/client-data/remote-status.d.ts +47 -1
  121. package/lib/types/client-data/remote-status.d.ts.map +1 -1
  122. package/lib/types/client-data/settings-form.d.ts +85 -1
  123. package/lib/types/client-data/settings-form.d.ts.map +1 -1
  124. package/lib/types/client-data/wizard.d.ts +56 -1
  125. package/lib/types/client-data/wizard.d.ts.map +1 -1
  126. package/lib/types/client-routes.d.ts +25 -1
  127. package/lib/types/client-routes.d.ts.map +1 -1
  128. package/lib/types/config.d.ts +40 -14
  129. package/lib/types/config.d.ts.map +1 -1
  130. package/lib/types/debug-report.d.ts.map +1 -1
  131. package/lib/types/fetch-route-intercept.d.ts +66 -8
  132. package/lib/types/fetch-route-intercept.d.ts.map +1 -1
  133. package/lib/types/index.d.ts +9 -2
  134. package/lib/types/index.d.ts.map +1 -1
  135. package/lib/types/intercept.d.ts +72 -10
  136. package/lib/types/intercept.d.ts.map +1 -1
  137. package/lib/types/merge-streams.d.ts +79 -1
  138. package/lib/types/merge-streams.d.ts.map +1 -1
  139. package/lib/types/plugin-route-intercept.d.ts +25 -9
  140. package/lib/types/plugin-route-intercept.d.ts.map +1 -1
  141. package/lib/types/relay-access.d.ts +3 -1
  142. package/lib/types/relay-access.d.ts.map +1 -1
  143. package/lib/types/relay-client.d.ts +23 -2
  144. package/lib/types/relay-client.d.ts.map +1 -1
  145. package/lib/types/relay-pool.d.ts +148 -0
  146. package/lib/types/relay-pool.d.ts.map +1 -0
  147. package/lib/types/relay-server.d.ts +30 -3
  148. package/lib/types/relay-server.d.ts.map +1 -1
  149. package/lib/types/restart-fields.d.ts +5 -5
  150. package/lib/types/restart-fields.d.ts.map +1 -1
  151. package/lib/types/share-store.d.ts.map +1 -1
  152. package/lib/types/state-store.d.ts +179 -0
  153. package/lib/types/state-store.d.ts.map +1 -0
  154. package/lib/types/upload-limits.d.ts +15 -0
  155. package/lib/types/upload-limits.d.ts.map +1 -1
  156. package/lib/types/virtual-id.d.ts +21 -0
  157. package/lib/types/virtual-id.d.ts.map +1 -1
  158. package/lib/types/wizard/probe.d.ts.map +1 -1
  159. package/lib/types/wizard/proxy-snippets.d.ts +3 -0
  160. package/lib/types/wizard/proxy-snippets.d.ts.map +1 -1
  161. package/lib/types/wizard/routes.d.ts +1 -0
  162. package/lib/types/wizard/routes.d.ts.map +1 -1
  163. package/lib/types/wizard/status.d.ts +9 -0
  164. package/lib/types/wizard/status.d.ts.map +1 -1
  165. package/lib/types/wizard/verify.d.ts +3 -0
  166. package/lib/types/wizard/verify.d.ts.map +1 -1
  167. package/lib/upload-limits.js +15 -0
  168. package/lib/upload-limits.js.map +1 -1
  169. package/lib/virtual-id.js +60 -0
  170. package/lib/virtual-id.js.map +1 -1
  171. package/lib/wizard/probe.js +46 -1
  172. package/lib/wizard/probe.js.map +1 -1
  173. package/lib/wizard/proxy-snippets.js +14 -1
  174. package/lib/wizard/proxy-snippets.js.map +1 -1
  175. package/lib/wizard/routes.js +23 -4
  176. package/lib/wizard/routes.js.map +1 -1
  177. package/lib/wizard/status.js +21 -0
  178. package/lib/wizard/status.js.map +1 -1
  179. package/lib/wizard/verify.js +31 -8
  180. package/lib/wizard/verify.js.map +1 -1
  181. package/package.json +8 -4
  182. package/pwa/icons/badge-96.png +0 -0
  183. package/pwa/icons/badge.svg +1 -0
  184. package/pwa/manifest.json +2 -1
  185. package/pwa/sw.js +3 -1
  186. package/scripts/check-debug-report.mjs +41 -1
  187. package/scripts/check-settings-form.mjs +14 -3
  188. package/scripts/check-settings-view.mjs +247 -0
  189. package/scripts/check-wizard-ui.mjs +37 -0
  190. package/src/adapters/dsh-better-sidebar/index.ts +7 -3
  191. package/src/admin-routes.ts +10 -2
  192. package/src/cli/args.ts +289 -0
  193. package/src/cli/bootstrap.ts +569 -0
  194. package/src/cli/command-setup.ts +540 -0
  195. package/src/cli/commands-client.ts +369 -0
  196. package/src/cli/commands-host.ts +1127 -0
  197. package/src/cli/commands-status.ts +296 -0
  198. package/src/cli/config-writer.ts +354 -0
  199. package/src/cli/context.ts +38 -0
  200. package/src/cli/i18n.ts +645 -0
  201. package/src/cli/ipc-client.ts +216 -0
  202. package/src/cli/ipc-server.ts +531 -0
  203. package/src/cli/main.ts +285 -0
  204. package/src/cli/qr-terminal.ts +49 -0
  205. package/src/client/RemoteStatusIcon.tsx +4 -1
  206. package/src/client/current-session-report.ts +28 -4
  207. package/src/client/effects/model-group-side.ts +19 -5
  208. package/src/client/effects/remote-session.ts +26 -6
  209. package/src/client/locales.ts +96 -6
  210. package/src/client/settings/SettingsSection.tsx +287 -92
  211. package/src/client/settings/settings-css.ts +18 -0
  212. package/src/client/styles/remote-session.css.ts +15 -1
  213. package/src/client/wizard/GatewayWizard.tsx +470 -109
  214. package/src/client/wizard/cards/ProxyCard.tsx +2 -1
  215. package/src/client/wizard/wizard-css.ts +23 -0
  216. package/src/client-data/model-group-side.ts +37 -10
  217. package/src/client-data/remote-status.ts +112 -17
  218. package/src/client-data/settings-form.ts +164 -8
  219. package/src/client-data/wizard.ts +112 -2
  220. package/src/client-routes.ts +334 -26
  221. package/src/config.ts +62 -16
  222. package/src/debug-report.ts +27 -1
  223. package/src/fetch-route-intercept.ts +381 -32
  224. package/src/index.ts +575 -370
  225. package/src/intercept.ts +1866 -286
  226. package/src/merge-streams.ts +155 -10
  227. package/src/plugin-route-intercept.ts +120 -71
  228. package/src/relay-access.ts +14 -3
  229. package/src/relay-client.ts +163 -5
  230. package/src/relay-pool.ts +387 -0
  231. package/src/relay-server.ts +312 -16
  232. package/src/restart-fields.ts +6 -4
  233. package/src/share-store.ts +59 -26
  234. package/src/state-store.ts +428 -0
  235. package/src/upload-limits.ts +16 -0
  236. package/src/virtual-id.ts +57 -0
  237. package/src/wizard/probe.ts +54 -2
  238. package/src/wizard/proxy-snippets.ts +17 -2
  239. package/src/wizard/routes.ts +24 -5
  240. package/src/wizard/status.ts +28 -0
  241. package/src/wizard/verify.ts +33 -11
  242. package/AGENTS.md +0 -185
  243. package/docs/adr/0001-plugin-bridge-forwards-plugin-routes.md +0 -15
  244. package/docs/adr/0002-relay-emulates-websocket.md +0 -8
@@ -0,0 +1,359 @@
1
+ /**
2
+ * CLI-3: the `client` subcommand family — `pair`, `unpair`, `list`. Every
3
+ * entry point passes the connectsRole gate FIRST (the task discipline: a
4
+ * host never dials a remote host; the message names the `setup --role
5
+ * client` switch), then drives the plugin's own pairing routes over IPC —
6
+ * the CLI never touches the relay pool or the state file directly, the
7
+ * plugin process stays the single owner.
8
+ *
9
+ * Interactivity follows the bootstrap iron rule: a missing value prompts in
10
+ * a TTY run, and a non-interactive run throws MissingRequiredOptionError
11
+ * immediately — except the one retry the SPEC pins: a WRONG pairing code in
12
+ * an interactive run falls back to re-asking ONLY the code, the already
13
+ * entered address stays put.
14
+ */
15
+ import { promptOrFail, MissingRequiredOptionError } from './bootstrap.js';
16
+ import { normalizeServerUrl } from '../client-pairing.js';
17
+ import { CLIENT_CLAIM_ROUTE, CLIENT_UNPAIR_ROUTE, CLIENT_STATUS_ROUTE } from '../client-routes.js';
18
+ import { fetchBody, plainOf, serverLineText } from './commands-status.js';
19
+ /** `client pair`'s online wait: the 10s budget is fixed, the interval is a
20
+ * test seam. */
21
+ const POLL_BUDGET_MS = 10_000;
22
+ const POLL_INTERVAL_DEFAULT_MS = 250;
23
+ const CODE_PATTERN = /^[A-Za-z0-9]{8}$/u;
24
+ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
25
+ /** The servers rows of a client/status answer, defensively filtered. */
26
+ function serversOf(body) {
27
+ const rows = body === null ? [] : Array.isArray(body.servers) ? body.servers : [];
28
+ return rows
29
+ .map((row) => plainOf(row))
30
+ .filter((row) => row !== null);
31
+ }
32
+ async function fetchStatus(ctx) {
33
+ return await fetchBody(() => ctx.ipc.request('GET', CLIENT_STATUS_ROUTE));
34
+ }
35
+ /**
36
+ * The role gate every `client *` command passes first: fresh ping (the role
37
+ * is a volatile row field), and a host/peer answers the bilingual refusal.
38
+ */
39
+ async function requireConnectsRole(ctx) {
40
+ let connects = false;
41
+ let role = 'host';
42
+ try {
43
+ const ping = await ctx.ipc.ping();
44
+ connects = ping.connects;
45
+ role = ping.role;
46
+ }
47
+ catch {
48
+ // No live plugin is no role that connects either — same refusal text.
49
+ }
50
+ if (connects)
51
+ return true;
52
+ ctx.stdout.write(`${ctx.t('err.roleGate.clientCommands', { role })}\n`);
53
+ return false;
54
+ }
55
+ /** One ask-text-or-throw: interactive runs prompt through the prompter,
56
+ * anything else raises the structured missing-option error. */
57
+ async function askText(ctx, optionName, question, validate) {
58
+ return await promptOrFail({
59
+ optionName,
60
+ interactive: ctx.interactive,
61
+ provided: undefined,
62
+ ask: async () => {
63
+ if (ctx.prompter === undefined)
64
+ throw new MissingRequiredOptionError(optionName);
65
+ return await ctx.prompter.inputText(question, undefined, validate);
66
+ },
67
+ });
68
+ }
69
+ // ===========================================================================
70
+ // client list
71
+ // ===========================================================================
72
+ /**
73
+ * `client list [--json]` — the paired-host table. `--json` echoes the pool
74
+ * status's own servers array verbatim (the machine-readable truth), the
75
+ * terminal mode prints the header count and one line per host.
76
+ */
77
+ export async function runClientListCommand(ctx) {
78
+ if (!(await requireConnectsRole(ctx)))
79
+ return 1;
80
+ const { t } = ctx;
81
+ const body = await fetchStatus(ctx);
82
+ if (body === null) {
83
+ ctx.stdout.write(`${t('clientList.fetchFailed', { error: t('status.notRunning') })}\n`);
84
+ return 1;
85
+ }
86
+ const servers = serversOf(body);
87
+ const max = typeof body.maxServers === 'number' ? body.maxServers : 8;
88
+ if (ctx.args.options.json) {
89
+ ctx.stdout.write(`${JSON.stringify({ ok: true, count: servers.length, maxServers: max, servers }, null, 2)}\n`);
90
+ return 0;
91
+ }
92
+ ctx.stdout.write(`${t('clientList.header', { count: servers.length, max })}\n`);
93
+ if (servers.length >= max)
94
+ ctx.stdout.write(` ${t('client.limitReached')}\n`);
95
+ if (servers.length === 0) {
96
+ ctx.stdout.write(` ${t('clientList.empty')}\n`);
97
+ return 0;
98
+ }
99
+ for (const row of servers) {
100
+ ctx.stdout.write(` ${serverLineText(t, row)}\n`);
101
+ const lastError = typeof row.lastError === 'string' ? row.lastError : '';
102
+ if (lastError !== '')
103
+ ctx.stdout.write(` ${t('status.client.lastError', { error: lastError })}\n`);
104
+ }
105
+ return 0;
106
+ }
107
+ // ===========================================================================
108
+ // client pair
109
+ // ===========================================================================
110
+ /** Local pre-validation of the address (SPEC: the claim route would refuse
111
+ * it anyway — failing here saves the round-trip). Interactive runs re-ask;
112
+ * a refused PROVIDED address ends the run with the reason on record. */
113
+ async function resolveHostUrl(ctx) {
114
+ const { t } = ctx;
115
+ let provided = ctx.args.target ?? ctx.args.options.hostUrl;
116
+ while (true) {
117
+ const raw = provided ?? await askText(ctx, 'host-url', t('client.prompt.hostUrl'), (value) => {
118
+ const normalized = normalizeServerUrl(value);
119
+ if (normalized.ok)
120
+ return undefined;
121
+ return t(normalized.reason === 'insecure-http' ? 'client.error.insecureHttp' : 'client.error.urlInvalid');
122
+ });
123
+ const normalized = normalizeServerUrl(raw);
124
+ if (normalized.ok)
125
+ return normalized.url;
126
+ ctx.stdout.write(`${t(normalized.reason === 'insecure-http' ? 'client.error.insecureHttp' : 'client.error.urlInvalid')}\n`);
127
+ if (!ctx.interactive || provided !== undefined)
128
+ return null;
129
+ provided = undefined; // interactive: back to the address question
130
+ }
131
+ }
132
+ /** The 8-character pairing code, same provided / prompt / refuse split.
133
+ * `ignoreProvided` is the retry path's lever: a `--code` that already failed
134
+ * one claim must never answer the re-ask — that would replay the same wrong
135
+ * code forever (the CLI-3-fix loop). */
136
+ async function resolveCode(ctx, ignoreProvided = false) {
137
+ const { t } = ctx;
138
+ let provided = ignoreProvided ? undefined : ctx.args.options.code;
139
+ while (true) {
140
+ const raw = provided ?? await askText(ctx, 'code', t('client.prompt.code'), (value) => (CODE_PATTERN.test(value) ? undefined : t('client.error.codeFormat')));
141
+ if (CODE_PATTERN.test(raw))
142
+ return raw;
143
+ ctx.stdout.write(`${t('client.error.codeFormat')}\n`);
144
+ if (!ctx.interactive || provided !== undefined)
145
+ return null;
146
+ provided = undefined;
147
+ }
148
+ }
149
+ /** The shared tail of a successful claim: wait (bounded) for the new entry
150
+ * to reach `online`, then the three lights and the peer's name. */
151
+ async function finishPair(ctx, serverUrl, claimBody) {
152
+ const { t } = ctx;
153
+ const out = ctx.stdout;
154
+ out.write(`${t('client.claimOk')}\n`);
155
+ const entryId = typeof claimBody.entryId === 'string' ? claimBody.entryId : '';
156
+ let entry = null;
157
+ if (entryId !== '') {
158
+ const interval = ctx.pollIntervalMs ?? POLL_INTERVAL_DEFAULT_MS;
159
+ const deadline = Date.now() + POLL_BUDGET_MS;
160
+ while (true) {
161
+ const status = await fetchStatus(ctx);
162
+ entry = serversOf(status).find((row) => row.entryId === entryId) ?? null;
163
+ if (entry?.state === 'online')
164
+ break;
165
+ if (Date.now() >= deadline)
166
+ break;
167
+ await sleep(interval);
168
+ }
169
+ }
170
+ const online = entry?.state === 'online';
171
+ const linkLabel = online ? t('status.online') : t('status.connecting');
172
+ out.write(`${t('client.lightCredentials', { state: t('common.done') })}\n`);
173
+ out.write(`${t('client.lightConnection', { state: linkLabel })}\n`);
174
+ out.write(`${t('client.lightSync', { state: linkLabel })}\n`);
175
+ const peerName = typeof entry?.serverName === 'string' && entry.serverName !== ''
176
+ ? entry.serverName
177
+ : typeof entry?.displayName === 'string' && entry.displayName !== '' ? entry.displayName : serverUrl;
178
+ out.write(`${t('client.pairedWith', { name: peerName })}\n`);
179
+ if (ctx.args.options.json) {
180
+ out.write(`${JSON.stringify({
181
+ ok: true,
182
+ entryId,
183
+ serverUrl,
184
+ serverName: peerName,
185
+ state: online ? 'online' : typeof entry?.state === 'string' ? entry.state : 'connecting',
186
+ }, null, 2)}\n`);
187
+ }
188
+ return 0;
189
+ }
190
+ /**
191
+ * `client pair [hostUrl] [--code <8位码>] [--name <本机名>] [--json]` — the
192
+ * full pairing flow: local address validation, name sync through the
193
+ * anti-shadowing config writer, the claim round-trip (with the SPEC's
194
+ * code-only retry in interactive runs), and the bounded wait for `online`.
195
+ */
196
+ export async function runClientPairCommand(ctx) {
197
+ if (!(await requireConnectsRole(ctx)))
198
+ return 1;
199
+ const { t, ipc, args } = ctx;
200
+ const out = ctx.stdout;
201
+ try {
202
+ const serverUrl = await resolveHostUrl(ctx);
203
+ if (serverUrl === null)
204
+ return 1;
205
+ let code = await resolveCode(ctx);
206
+ if (code === null)
207
+ return 1;
208
+ if (args.options.name !== undefined) {
209
+ const written = await ipc.writeConfig({ set: { serverName: args.options.name } });
210
+ const body = plainOf(written.body);
211
+ if (written.status !== 200 || body?.ok !== true) {
212
+ const error = plainOf(body?.error);
213
+ if (error?.code === 'env-shadowed') {
214
+ out.write(`${t('err.envShadowed', { field: String(error.field), envVar: String(error.envVar) })}\n`);
215
+ }
216
+ else {
217
+ out.write(`${t('client.error.nameWriteFailed')}\n`);
218
+ }
219
+ return 1;
220
+ }
221
+ }
222
+ out.write(`${t('client.claiming')}\n`);
223
+ while (true) {
224
+ const result = await ipc.request('POST', CLIENT_CLAIM_ROUTE, { serverUrl, code });
225
+ const body = plainOf(result.body) ?? {};
226
+ if (result.status >= 200 && result.status < 300 && body.ok === true) {
227
+ return await finishPair(ctx, serverUrl, body);
228
+ }
229
+ out.write(`${claimFailureText(t, result.status, body)}\n`);
230
+ // SPEC: only a refused CODE retries, and only the code — the address
231
+ // stays; everything else is a final verdict in any mode. role-mismatch
232
+ // belongs here too: a web-role code is not consumed by the gateway, so
233
+ // re-asking with the desktop code on the SAME address is the fix.
234
+ const retryable = body.code === 'bad-code' || body.code === 'locked' || body.code === 'role-mismatch';
235
+ if (!ctx.interactive || !retryable)
236
+ return 1;
237
+ // The failed flag value may not answer again (CLI-3-fix: the infinite
238
+ // loop) — the retry always asks the user.
239
+ code = await resolveCode(ctx, true);
240
+ if (code === null)
241
+ return 1;
242
+ }
243
+ }
244
+ catch (error) {
245
+ if (error instanceof MissingRequiredOptionError) {
246
+ out.write(`${t('err.missingOption', { option: error.optionName })}\n`);
247
+ return 1;
248
+ }
249
+ throw error;
250
+ }
251
+ }
252
+ /** One classified claim refusal → the bilingual line. */
253
+ function claimFailureText(t, status, body) {
254
+ switch (body.code) {
255
+ case 'limit-reached': return t('client.limitReached');
256
+ case 'role-mismatch': {
257
+ const message = typeof body.message === 'string' && body.message !== '' ? body.message : undefined;
258
+ return message ?? t('client.error.roleMismatch');
259
+ }
260
+ case 'bad-code': return t('client.error.badCode');
261
+ case 'locked': {
262
+ const seconds = Math.ceil(typeof body.retryAfterMs === 'number' ? body.retryAfterMs / 1000 : 0);
263
+ return t('client.error.locked', { seconds });
264
+ }
265
+ case 'unreachable': return t('client.error.unreachable');
266
+ case 'invalid': return t('client.error.urlInvalid');
267
+ case 'insecure-http': return t('client.error.insecureHttp');
268
+ default: return status >= 200 && status < 300 ? t('client.error.unexpected') : t('client.error.unreachable');
269
+ }
270
+ }
271
+ // ===========================================================================
272
+ // client unpair
273
+ // ===========================================================================
274
+ /** POST one removal and report it. `removed: 0` is the not-found verdict. */
275
+ async function unpairEntry(ctx, entry) {
276
+ const { t } = ctx;
277
+ const entryId = typeof entry.entryId === 'string' ? entry.entryId : '';
278
+ const result = await ctx.ipc.request('POST', CLIENT_UNPAIR_ROUTE, { entryId });
279
+ const body = plainOf(result.body);
280
+ if (result.status !== 200 || body?.removed !== 1) {
281
+ ctx.stdout.write(`${t('clientUnpair.notFound', { target: entryId })}\n`);
282
+ return 1;
283
+ }
284
+ if (ctx.args.options.json) {
285
+ ctx.stdout.write(`${JSON.stringify({ ok: true, removed: 1, entryId }, null, 2)}\n`);
286
+ }
287
+ else {
288
+ const name = typeof entry.displayName === 'string' && entry.displayName !== '' ? entry.displayName : entryId;
289
+ ctx.stdout.write(`${t('clientUnpair.removed', { name })}\n`);
290
+ }
291
+ return 0;
292
+ }
293
+ /**
294
+ * `client unpair [<hostUrl|entryId>|--all] [--yes] [--json]` — a target is
295
+ * matched against the pool's own status rows (entry id first, then the
296
+ * normalized address); `--all` needs `--yes` outside a TTY confirm; no
297
+ * target at all in an interactive run picks from the current list.
298
+ */
299
+ export async function runClientUnpairCommand(ctx) {
300
+ if (!(await requireConnectsRole(ctx)))
301
+ return 1;
302
+ const { t, args } = ctx;
303
+ const out = ctx.stdout;
304
+ const status = await fetchStatus(ctx);
305
+ const servers = serversOf(status);
306
+ if (args.options.all) {
307
+ if (!args.options.yes) {
308
+ if (!ctx.interactive || ctx.prompter === undefined) {
309
+ // Non-interactive without --yes must not destroy anything — the
310
+ // missing confirmation IS the missing required option.
311
+ out.write(`${t('err.missingOption', { option: 'yes' })}\n`);
312
+ return 1;
313
+ }
314
+ const sure = await ctx.prompter.confirm(t('clientUnpair.confirmAll', { count: servers.length }), false);
315
+ if (!sure) {
316
+ out.write(`${t('common.cancel')}\n`);
317
+ return 0;
318
+ }
319
+ }
320
+ const result = await ctx.ipc.request('POST', CLIENT_UNPAIR_ROUTE, { all: true });
321
+ const body = plainOf(result.body);
322
+ if (result.status !== 200 || body?.ok !== true) {
323
+ out.write(`${t('clientUnpair.failed')}\n`);
324
+ return 1;
325
+ }
326
+ const removed = typeof body.removed === 'number' ? body.removed : servers.length;
327
+ if (args.options.json) {
328
+ out.write(`${JSON.stringify({ ok: true, removed }, null, 2)}\n`);
329
+ }
330
+ else {
331
+ out.write(`${t('clientUnpair.removedAll', { count: removed })}\n`);
332
+ }
333
+ return 0;
334
+ }
335
+ const target = args.target;
336
+ if (target === undefined) {
337
+ if (!ctx.interactive || ctx.prompter === undefined) {
338
+ out.write(`${t('clientUnpair.missingTarget')}\n`);
339
+ return 1;
340
+ }
341
+ if (servers.length === 0) {
342
+ out.write(` ${t('clientList.empty')}\n`);
343
+ return 0;
344
+ }
345
+ const picked = await ctx.prompter.selectOne(t('clientUnpair.selectQuestion'), servers.map((row) => serverLineText(t, row)), 0);
346
+ const entry = servers[picked];
347
+ return entry === undefined ? 1 : await unpairEntry(ctx, entry);
348
+ }
349
+ const normalizedTarget = normalizeServerUrl(target);
350
+ const matched = servers.find((row) => row.entryId === target)
351
+ ?? servers.find((row) => normalizedTarget.ok && row.serverUrl === normalizedTarget.url)
352
+ ?? servers.find((row) => row.serverUrl === target);
353
+ if (matched === undefined) {
354
+ out.write(`${t('clientUnpair.notFound', { target })}\n`);
355
+ return 1;
356
+ }
357
+ return await unpairEntry(ctx, matched);
358
+ }
359
+ //# sourceMappingURL=commands-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands-client.js","sourceRoot":"","sources":["../../src/cli/commands-client.ts"],"names":[],"mappings":"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"}