dsh-mobile 0.8.1 → 0.8.3

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 (41) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/CONTRIBUTORS.md +30 -2
  3. package/README.en.md +7 -5
  4. package/README.md +7 -5
  5. package/SECURITY.md +1 -1
  6. package/THIRD_PARTY_NOTICES.md +1 -1
  7. package/apps/mobile/README.md +8 -4
  8. package/apps/mobile/README.zh-CN.md +8 -4
  9. package/apps/mobile/release.json +3 -3
  10. package/docs/ATTACH_EXISTING_FRPS.en.md +2 -0
  11. package/docs/ATTACH_EXISTING_FRPS.md +2 -0
  12. package/docs/CLIENT_MODULES.en.md +6 -2
  13. package/docs/CLIENT_MODULES.md +6 -2
  14. package/docs/CONNECTION_DIAGNOSTICS.en.md +56 -0
  15. package/docs/CONNECTION_DIAGNOSTICS.md +56 -0
  16. package/docs/IROH.en.md +7 -1
  17. package/docs/IROH.md +7 -1
  18. package/docs/MOBILE_PLUGIN_ADAPTATION.en.md +1 -1
  19. package/docs/MOBILE_PLUGIN_ADAPTATION.md +1 -1
  20. package/docs/README.md +1 -0
  21. package/docs/SKIN_COMPATIBILITY.en.md +1 -1
  22. package/docs/SKIN_COMPATIBILITY.md +1 -1
  23. package/docs/SLOW_CONNECTIONS.en.md +6 -2
  24. package/docs/SLOW_CONNECTIONS.md +6 -2
  25. package/lib/cli.js +6 -12
  26. package/lib/cli.js.map +1 -1
  27. package/lib/client.js +772 -248
  28. package/lib/client.js.map +1 -1
  29. package/lib/extension-worker-runtime.mjs +4 -8
  30. package/lib/extension-worker-runtime.mjs.map +1 -1
  31. package/lib/index.d.mts +19 -89
  32. package/lib/index.mjs +397 -273
  33. package/lib/index.mjs.map +1 -1
  34. package/lib/mobile-compat.js +2 -2
  35. package/lib/mobile-compat.js.map +1 -1
  36. package/lib/mobile-layout.js +116 -33
  37. package/lib/mobile-layout.js.map +1 -1
  38. package/package.json +9 -7
  39. package/packages/question-fixes/lib/client.js +1 -2
  40. package/packages/question-fixes/lib/index.mjs +1 -2
  41. package/packages/question-fixes/package.json +1 -1
package/docs/IROH.md CHANGED
@@ -20,7 +20,7 @@ iroh 用加密直连(打不通时走中继)代替公网域名和隧道账号
20
20
  4. 点 **生成 iroh 配对二维码**,用完整版 App 扫描。描述符绑定 sidecar 的 6 位码、网关的一次性 token 和固定 CA;再次生成会替换旧配对窗口,手机通过 iroh 上的普通 pair 接口核销网关 token。
21
21
  5. 关闭或切换通道会停止自有进程与网关,不删除已保存的配对。独立实验 App 的包名不同,其 Keystore 凭据不会自动迁移到本 App。
22
22
 
23
- 未安装组件时不显示主操作按钮;安装后,开关、生成二维码和复制配对链接三个按钮保持同排。复制按钮在没有有效配对内容时置灰,生成后才可用,重复复制不会重新生成配对码。
23
+ 未安装组件时不显示主操作按钮;安装后,开关、生成二维码和复制配对链接三个按钮保持同排。复制按钮在没有有效配对内容时置灰;从插件 0.8.3 起,已有有效配对内容但二维码图片未生成时,也可复制并粘贴到 App 的 iroh 配对页。重复复制不会重新生成配对码。
24
24
 
25
25
  需要回收组件占用空间时,先关闭 iroh 远程访问,再展开组件详情,选择 **移除已下载的 iroh 组件**。它只删除本插件下载的固定版本程序,不删除身份、配对或外部伴随包;再次使用时可重新安装或复用已校验的外部副本。运行中不允许清理,直接调用管理 API 也会被拒绝。
26
26
 
@@ -45,6 +45,12 @@ iroh 身份和证书必须存放在仅当前用户或受信系统账户可写的
45
45
  | `iroh_start_timeout` | 查看 DSH 日志中的 iroh 错误及网络连接,确认固定组件可运行;不要反复重新配对来替代进程排查 |
46
46
  | 通道 `ready` 但手机连不上 | 检查 App 是否为完整版、设备是否支持打包的 ABI,以及描述符是否有效;电脑就绪不等于手机已连通,连接中继服务也不等于数据一定经过中继 |
47
47
 
48
+ ## 通道就绪但移动定制加载失败
49
+
50
+ 电脑端 `ready` 只表示本地组件和端点已准备好,不保证手机的清单、CSS、脚本及事件流都已正常加载。会话可用但定制加载失败时,分别查看页面提示与同一时段的脱敏 HTTP 日志;清单不可用与定制资源加载失败需要分开定位。`parser/400/other` 不足以确定请求格式问题,连接重置的 `transport` 记录也不是服务端拒绝请求的证据。采样含义见[慢链路诊断](SLOW_CONNECTIONS.md)。
51
+
52
+ 二维码扫描失败但复制内容可配对时,请分别说明扫描入口、App 版本与生成后经过的时间,不要上传原始描述符、二维码或配对密钥。该现象不能仅凭通道就绪判为已解决,也不应通过关闭证书验证、清除现有配对或修改全局代理来排查。
53
+
48
54
  ## VPN/代理与网络环境
49
55
 
50
56
  iroh 直连优先、中继兜底。直连使用 QUIC/UDP,发现和中继还要求相应网络服务可达。以下环境因素**可能**干扰连接,属于排查方向,并非每一种 VPN 或网络都已确认存在的故障机制:
@@ -130,7 +130,7 @@ Verify actual visibility, focus and `document.elementFromPoint()` while the draw
130
130
 
131
131
  When a third-party panel is open in the main slot, the mobile layer provides three safety measures:
132
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;
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. The built-in plugin-manager page's cards open through a title button whose overlay already owns the whole card hit area, so those title buttons keep their compact size instead of being floored;
134
134
  - a panel root that is `width:100vw` or a fixed pixel width is capped to the available width instead of overflowing;
135
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
136
 
@@ -130,7 +130,7 @@ h('button', { className: 'icon-button', 'aria-label': label }, h(Icon, { 'aria-h
130
130
 
131
131
  主槽打开第三方插件面板时,移动层会做三件兜底的事:
132
132
 
133
- - 粗指针下,面板中的普通按钮、选择框和文本输入控件获得 **44×44 CSS px 的最小布局尺寸**。这会改变控件盒子及其视觉尺寸,不是不可见的命中区扩展;开关、复选框、范围滑块等控件保持自有几何,多行输入由面板自己处理;
133
+ - 粗指针下,面板中的普通按钮、选择框和文本输入控件获得 **44×44 CSS px 的最小布局尺寸**。这会改变控件盒子及其视觉尺寸,不是不可见的命中区扩展;开关、复选框、范围滑块等控件保持自有几何,多行输入由面板自己处理。DSH 内置插件管理页的卡片通过标题按钮打开详情,其覆盖层已拥有整张卡片的命中区,因此这类标题按钮保持紧凑尺寸、不参与最小尺寸兜底;
134
134
  - 面板根若是 `width:100vw` 或固定像素宽,会被收进可用宽度,不再横向溢出;
135
135
  - 面板内容区可以滚动并阻止滚动链,不把整个主区也变成第二层滚动容器;插件自己的滚动容器仍是第一选择。
136
136
 
package/docs/README.md CHANGED
@@ -28,6 +28,7 @@
28
28
 
29
29
  | 功能 | 中文 | English | 使用状态 |
30
30
  | --- | --- | --- | --- |
31
+ | 区分电脑、DNS、出口与手机的诊断证据 | [连接诊断](CONNECTION_DIAGNOSTICS.md) | [Connection diagnostics](CONNECTION_DIAGNOSTICS.en.md) | 分层报告为 0.8.2 候选;不代表手机路径已验收 |
31
32
  | 核对移动字号、字体与 App 页面缩放 | [显示大小](MOBILE_COMPOSER_TOOLBAR.md#显示大小与可用空间) | [Display size](MOBILE_COMPOSER_TOOLBAR.en.md#display-size-and-available-space) | 字体按主题能力显示;App 缩放与网页字号独立 |
32
33
  | 为移动页面选择加载模块 | [模块设置](CLIENT_MODULES.md) | [Module settings](CLIENT_MODULES.en.md) | 电脑默认与设备覆盖分别保存,不自动刷新会话 |
33
34
  | 允许受控路由网络访问 LAN Gateway | [额外可信网段](TRUSTED_NETWORKS.md) | [Trusted networks](TRUSTED_NETWORKS.en.md) | 不建立 VPN,不自动扩大防火墙规则 |
@@ -25,4 +25,4 @@ For example, the published `maid-atelier` 0.1.7 package mounts its background in
25
25
 
26
26
  An isolated DSH 0.2.0-rc.2 combination with Mobile 0.6.4 and the published npm `maid-atelier` 0.1.7 reproduces the see-through navy sidebar, unreadable dark labels, missing background and a blank populated Trajectory view. The trace data remains present: a broad skin rule changes the mobile root to a column Flex layout and collapses the content region to zero height. Plugin 0.6.5 protects the plugin-owned root's Grid geometry and fixes this blank trace, without changing the skin's palette, shadows or decoration mounting.
27
27
 
28
- This skin binds light sidebar labels to the stock `sidebarCol`, absent from the mobile layout. Missing backgrounds and some text-contrast problems still need skin adaptation; the trace fix does not resolve them. Device-level exclusion restores default mobile presentation while preserving the computer skin. Plugin 0.6.4 and earlier do not contain the layout protection.
28
+ This skin binds light sidebar labels to the stock `sidebarCol`, absent from the mobile layout. Missing backgrounds and some text-contrast problems still need skin adaptation; the trace fix does not resolve them. Device-level selection stops optional client modules from loading, not host-injected page styles, so it does not guarantee a default appearance. This device setting does not change the computer's installed plugins or loading choices. Plugin 0.6.4 and earlier do not contain the layout protection.
@@ -25,4 +25,4 @@ DSH Mobile 在已认证的移动页面中使用专用根布局,继续渲染 DS
25
25
 
26
26
  在 DSH 0.2.0-rc.2、Mobile 0.6.4 与正式 npm `maid-atelier` 0.1.7 的隔离组合中,已复现深蓝侧栏透底、深色文字难读、背景缺失和有内容会话的轨迹空白。轨迹数据没有丢失:皮肤的宽泛根布局规则把移动容器改为纵向 Flex,内容区域高度缩为 0。插件 0.6.5 保护自有根容器的 Grid 几何规则,修复该轨迹空白,不改皮肤配色、阴影或装饰挂载。
27
27
 
28
- 该皮肤把浅色侧栏文字绑定到原生 `sidebarCol`;移动布局没有该节点。缺失背景及部分文字对比度仍需皮肤适配,不能视为已随轨迹修复解决。按上面的设备模块选择排除皮肤后,移动页面可恢复默认样式,电脑皮肤保持。插件 0.6.4 及更早版本不包含这项布局保护。
28
+ 该皮肤把浅色侧栏文字绑定到原生 `sidebarCol`;移动布局没有该节点。缺失背景及部分文字对比度仍需皮肤适配,不能视为已随轨迹修复解决。设备模块选择只能阻止可选客户端模块加载,不能移除服务端注入的整页样式,因此不保证恢复默认外观;电脑上的插件安装和加载选择不受该设备设置影响。插件 0.6.4 及更早版本不包含这项布局保护。
@@ -8,6 +8,8 @@ Start with the actual channel rather than treating every delay as a DSH heartbea
8
8
 
9
9
  ## Identify the stage that fails
10
10
 
11
+ Component readiness, system DNS and computer egress are distinct observations, not proof of phone or public-route failure. See [connection diagnostics](CONNECTION_DIAGNOSTICS.en.md) for layered reports and the same-tailnet Funnel limitation.
12
+
11
13
  First record the DSH, DSH Mobile plugin and Android app versions. On the computer, check the current channel under **Mobile Access → Diagnostics**, then inspect DSH startup logs and the browser's developer tools under Network → WS and update the component involved. The plugin and app release independently; their version numbers do not need to match. Remove Tokens, Cookies, and complete pairing URLs before sharing logs.
12
14
 
13
15
  - **WebSocket never connects**: check for `101 Switching Protocols` and errors such as `401`, `403`, `404`, or `502`. Authentication, Host/Origin checks, proxy upgrade support, paths, and version differences can all cause this. Heartbeat adjustments do not resolve these failures. Allow blocked third-party plugin paths individually in Connection diagnostics; DSH's built-in paths do not need to be added again.
@@ -30,7 +32,7 @@ Success and failure each have one fixed sampling slot: the first result is immed
30
32
 
31
33
  Plugin 0.6.13 and later distinguish request receive timeouts as `408 request_timeout` and oversized headers as `431 headers_too_large`; other malformed HTTP requests remain `400 bad_request`. Older versions may return 400 with the same short JSON for all of them, so a status and a 24-byte body do not identify the cause.
32
34
 
33
- The `http failure` diagnostics distinguish three per-Gateway categories: `parser` for HTTP parsing/receive failures, `target` for invalid request targets, and `upstream` for an authenticated `POST /api/session/prompt` rejected upstream. The first event of each kind is immediate; repeats aggregate for 30 seconds, with `suppressed` counting earlier suppressed events of that kind. Logs exclude raw errors, request bodies, raw packets, Cookies, Tokens, queries and arbitrary URLs. No record does not establish success.
35
+ The `http failure` diagnostics distinguish four per-Gateway categories: `parser` for HTTP parsing/receive failures, `transport` for connection resets and other fixed transport errors, `target` for invalid request targets, and `upstream` for an authenticated `POST /api/session/prompt` rejected upstream. `transport` has no HTTP status and does not establish a returned 400; parser code `other` does not identify the cause either. The first event of each kind is immediate; repeats aggregate for 30 seconds. `suppressed` counts earlier suppressed events of that kind, not necessarily the same code, path or device. Logs exclude raw errors, request bodies, raw packets, Cookies, Tokens, queries and arbitrary URLs. No record does not establish success.
34
36
 
35
37
  `slow api` samples authenticated, forwarded `/api/` requests taking at least 3 seconds: a bounded method, a fixed route category such as `/api/session` (unknown categories become `/api/other`), the status and `durationMs`. The duration spans entry into upstream forwarding until the response closes, including a client-abandoned response; it is a proxy wait, not a measurement of upstream processing time or proof of the slow layer. Logs exclude path suffixes such as Session IDs, query strings, request bodies and arbitrary raw paths. Each Gateway records its first event immediately and aggregates subsequent samples within 30 seconds. This changes no timeout, retry or caching policy.
36
38
 
@@ -44,7 +46,9 @@ Plugin 0.6.15 and later repair the idle cutoff and gzip buffering for new dedica
44
46
 
45
47
  A page view does not migrate to a new authentication Session. Native renewal may retain the WebView and draft without restoring the old module-event stream. A new Session using the old view receives `409 mobile_document_view_invalid`; loading the dedicated page again obtains a new view. This does not require removing a pairing or automatically refresh the current Session.
46
48
 
47
- An ordinary message bubble and cleared draft can precede `POST /api/session/prompt`: they are an optimistic local echo, not Host acceptance. If no corresponding request appears, retain redacted request timing, status codes and DSH logs to distinguish a request never started by the browser, proxy rejection and Host acceptance. The plugin does not automatically replay messages, approvals or other writes; check the Session before retrying an operation with an unknown outcome.
49
+ On some older DSH versions, a message bubble and cleared draft can precede `POST /api/session/prompt`: they are an optimistic local echo, not Host acceptance. If no corresponding request appears, retain redacted request timing, status codes and DSH logs to distinguish a request never started by the browser, proxy rejection and Host acceptance. The plugin does not automatically replay messages, approvals or other writes; check the Session before retrying an operation with an unknown outcome.
50
+
51
+ In controlled HTTP 400 tests on DSH 0.2.2-rc.1, staying in the same Session showed a send error and restored the text and image draft. Leaving while the request was still pending could lose that draft on return, including in stock DSH without Mobile installed. On a slow link, wait for the current Session to show the send result before switching. If the result is unknown, check whether the message arrived before retrying. This does not identify the original rejection reported in [#234](https://github.com/saya-ch/dsh-mobile/issues/234).
48
52
 
49
53
  ## Slow transfers can exceed the default deadlines
50
54
 
@@ -8,6 +8,8 @@
8
8
 
9
9
  ## 先判断重连发生在哪一步
10
10
 
11
+ 电脑诊断中的组件就绪、系统 DNS 和当前出口是不同证据,不能据此直接判定手机或公网故障。分层报告和同 tailnet Funnel 的限制见[连接诊断](CONNECTION_DIAGNOSTICS.md)。
12
+
11
13
  先记录 DSH、DSH Mobile 插件和 Android App 的版本,再在电脑端 **移动访问 → 诊断** 检查当前通道;查看 DSH 启动日志和浏览器开发者工具的 Network → WS,按问题涉及的组件更新。插件与 App 独立发版,版本号不必相同。分享日志时去掉 Token、Cookie 和完整配对地址。
12
14
 
13
15
  - **WebSocket 没有连接成功**:检查请求是否获得 `101 Switching Protocols`,并留意 `401`、`403`、`404`、`502` 等错误。认证、Host/Origin、反向代理升级支持、连接路径或版本差异都可能造成这种情况。调整心跳不能解决这些问题;第三方插件被拦截的路径可在连接诊断中按需允许,不必把 DSH 内置路径全部重新添加。
@@ -30,7 +32,7 @@
30
32
 
31
33
  插件 0.6.13 起把请求接收超时区分为 `408 request_timeout`,请求头过大区分为 `431 headers_too_large`;其他非法 HTTP 请求仍为 `400 bad_request`。旧版可能把这几类情况都返回成 400 和相同的短 JSON,因此状态码与“24 字节”不足以定位原因。
32
34
 
33
- `http failure` 日志按网关区分 `parser`、`target`、`upstream` 三类:分别表示 HTTP 解析/接收失败、非法请求目标、已认证的 `POST /api/session/prompt` 被上游拒绝。每类首条立即记录,后续 30 秒内聚合,下一条的 `suppressed` 是此前被抑制的同类数量。日志不保留原始报错、请求正文、原始包、Cookie、Token、查询参数或任意 URL;不记录某条也不能证明它成功。
35
+ `http failure` 日志按网关区分 `parser`、`transport`、`target`、`upstream` 四类:分别表示 HTTP 解析/接收失败、连接重置等传输错误、非法请求目标、已认证的 `POST /api/session/prompt` 被上游拒绝。`transport` 没有 HTTP 状态,不表示服务端返回了 400;`parser` 的 `other` 也不足以确定具体原因。每类首条立即记录,后续 30 秒内聚合,下一条的 `suppressed` 是此前被抑制的同类数量,不保证来自相同错误码、路径或设备。日志不保留原始报错、请求正文、原始包、Cookie、Token、查询参数或任意 URL;不记录某条也不能证明它成功。
34
36
 
35
37
  `slow api` 日志采样已认证并转发、耗时至少 3 秒的 `/api/` 请求:固定方法、`/api/session` 等固定路由类别(未知类别归为 `/api/other`)、状态和 `durationMs`。耗时从进入上游代理转发算到响应关闭,包含客户端中途放弃的响应;它是代理等待时间,不是上游处理耗时,也不能单凭该数字确定哪一层慢。日志不保留会话 ID 等路径后缀、查询参数、请求正文或任意原始路径,每个网关首条立即记录、后续采样在 30 秒窗口内聚合。不改变超时、重试或缓存策略。
36
38
 
@@ -44,7 +46,9 @@
44
46
 
45
47
  页面标识不会迁移到新的认证 Session:原生续期即使保留了当前 WebView 和草稿,也不代表旧模块通知流已恢复。新 Session 使用旧标识会收到 `409 mobile_document_view_invalid`;重新加载专用页面会取得新标识。这个限制不要求删除配对,也不会主动刷新当前会话。
46
48
 
47
- 普通消息的气泡和清空草稿可能先于 `POST /api/session/prompt`,属于本地乐观回显,不是 Host 受理确认。若找不到对应请求,请保留脱敏后的请求时序、状态码及 DSH 日志,区分浏览器未发起、代理拒绝与 Host 已受理。插件不会自动重放消息、审批或其他写请求;结果不明时先确认会话,避免重复副作用。
49
+ 部分旧版 DSH 的消息气泡和清空草稿可能先于 `POST /api/session/prompt`,属于本地乐观回显,不是 Host 受理确认。若找不到对应请求,请保留脱敏后的请求时序、状态码及 DSH 日志,区分浏览器未发起、代理拒绝与 Host 已受理。插件不会自动重放消息、审批或其他写请求;结果不明时先确认会话,避免重复副作用。
50
+
51
+ 在 DSH 0.2.2-rc.1 的受控 HTTP 400 测试中,留在原会话时,发送失败会显示提示并恢复文本和图片草稿。但请求仍挂起时切走会话,返回后草稿可能无法恢复;不装 Mobile 的 DSH 也能复现。慢链路上,发送后请等到当前会话确认结果再切换;若结果不明,先检查消息是否已送达再决定是否重试。这不代表已经查明 [#234](https://github.com/saya-ch/dsh-mobile/issues/234) 报告中的原始拒绝原因。
48
52
 
49
53
  ## 慢速传输可能超过默认等待时间
50
54
 
package/lib/cli.js CHANGED
@@ -8,7 +8,7 @@ import { generate } from "selfsigned";
8
8
  import { performance } from "node:perf_hooks";
9
9
  import "@deepseek-ai/cordis";
10
10
  import "@deepseek-ai/schemastery";
11
- //#region src/exec-file.ts
11
+ // src/exec-file.ts
12
12
  /** Capture both output streams even when a desktop host wraps execFile without Node's promisify metadata. */
13
13
  function execFileText(file, args, options = {}) {
14
14
  return new Promise((resolve, reject) => {
@@ -32,8 +32,7 @@ function execFileText(file, args, options = {}) {
32
32
  });
33
33
  });
34
34
  }
35
- //#endregion
36
- //#region src/private-file.ts
35
+ // src/private-file.ts
37
36
  let userSidTask;
38
37
  function commandFailureDetails(error) {
39
38
  if (error === null || typeof error !== "object") return {};
@@ -153,8 +152,7 @@ Object.freeze([
153
152
  [3758096384n, 4],
154
153
  [4026531840n, 4]
155
154
  ]);
156
- //#endregion
157
- //#region src/managed-setup.ts
155
+ // src/managed-setup.ts
158
156
  const VIRTUAL_INTERFACE_MARKERS = [
159
157
  "bridge",
160
158
  "docker",
@@ -511,8 +509,7 @@ async function refreshManagedServerCertificate(setup, address) {
511
509
  keyFile: setup.tls.keyFile
512
510
  });
513
511
  }
514
- //#endregion
515
- //#region src/lan-setup.ts
512
+ // src/lan-setup.ts
516
513
  const FIREWALL_TCP_RULE = "DSH Mobile HTTPS";
517
514
  const FIREWALL_UDP_RULE = "DSH Mobile Discovery";
518
515
  async function runElevatedPowerShell(script) {
@@ -603,8 +600,7 @@ Object.freeze({
603
600
  assetBytes: 33554432,
604
601
  assetDepth: 8
605
602
  });
606
- //#endregion
607
- //#region src/extensions.ts
603
+ // src/extensions.ts
608
604
  /** A controlled business failure returned by an extension action or route. */
609
605
  var MobileExtensionError = class extends Error {
610
606
  code;
@@ -621,8 +617,7 @@ function assertExtensionId(value) {
621
617
  if (typeof value !== "string" || !/^[a-z][a-z0-9-]{0,63}$/u.test(value)) throw new MobileExtensionError("invalid_manifest", "extension id is invalid");
622
618
  return value;
623
619
  }
624
- //#endregion
625
- //#region src/cli.ts
620
+ // src/cli.ts
626
621
  function parseOptions(args) {
627
622
  let address;
628
623
  let port = 3443;
@@ -816,7 +811,6 @@ main().catch((error) => {
816
811
  console.error(error instanceof Error ? error.message : String(error));
817
812
  process.exitCode = 1;
818
813
  });
819
- //#endregion
820
814
  export {};
821
815
 
822
816
  //# sourceMappingURL=cli.js.map