weapp-vite 7.4.0 → 7.6.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 (126) hide show
  1. package/README.md +59 -3
  2. package/THIRD_PARTY_NOTICES.md +60 -0
  3. package/bin/bootstrap.js +14 -1
  4. package/dist/action-B3YZMA-h.mjs +255 -0
  5. package/dist/action-BELcDNNv.mjs +139 -0
  6. package/dist/action-BOk3vGI7.mjs +1110 -0
  7. package/dist/action-DlC6JYpt.mjs +95 -0
  8. package/dist/action-zEDY7oh_.mjs +247 -0
  9. package/dist/adapters-CcHrsYaj.mjs +1 -0
  10. package/dist/analyze-DN79YOAH.mjs +184 -0
  11. package/dist/artifacts-BOyC9Fy-.mjs +106 -0
  12. package/dist/assets-C5_YYXNk.mjs +637 -0
  13. package/dist/auto-import-components/resolvers.mjs +1 -2
  14. package/dist/auto-import-presets/wevu-router.mjs +1 -2
  15. package/dist/auto-import-presets/wevu.mjs +1 -2
  16. package/dist/auto-routes.mjs +2 -1
  17. package/dist/budget-CTLOHwgI.d.mts +177 -0
  18. package/dist/budget-EOeEycc_.mjs +65 -0
  19. package/dist/builtProject-C29udgXY.mjs +541 -0
  20. package/dist/chunkStrategy-DY_LZIIe.mjs +1448 -0
  21. package/dist/classifier-DBJY__kg.mjs +88 -0
  22. package/dist/cli-acceptance.d.mts +1 -0
  23. package/dist/cli-acceptance.mjs +21 -0
  24. package/dist/cli.mjs +519 -5049
  25. package/dist/compatibility.mjs +1 -2
  26. package/dist/{config-Dbvj5yK7.d.mts → config-Bf6DWhyb.d.mts} +220 -76
  27. package/dist/config.d.mts +3 -3
  28. package/dist/config.mjs +1 -1
  29. package/dist/{constants-WOsG3Eqd.mjs → constants-DEZdcsMn.mjs} +1 -1
  30. package/dist/{createContext-UOEgeYnA.mjs → createCompilerContextInstance-aYwi8wQt.mjs} +36862 -32020
  31. package/dist/createContext-tApLtII-.mjs +15 -0
  32. package/dist/dashboard/analyze.d.mts +48 -0
  33. package/dist/dashboard/analyze.mjs +3 -0
  34. package/dist/dashboard/vite.d.mts +1 -1
  35. package/dist/dashboard.d.mts +3 -2
  36. package/dist/dashboard.mjs +1748 -1
  37. package/dist/dashboardTransport-C_Y6jMp-.mjs +16 -0
  38. package/dist/dashboardViteBridge-DCGR43aM.mjs +302 -0
  39. package/dist/dev-C2fgr_Xd.mjs +67 -0
  40. package/dist/devProvider-D-hTfsEO.mjs +3027 -0
  41. package/dist/docs/README.md +59 -3
  42. package/dist/docs/ai-workflows.md +4 -0
  43. package/dist/docs/doctor.md +38 -0
  44. package/dist/docs/getting-started.md +3 -1
  45. package/dist/docs/index.md +3 -1
  46. package/dist/docs/mcp.md +104 -1
  47. package/dist/docs/testing.md +29 -2
  48. package/dist/docs/troubleshooting.md +16 -0
  49. package/dist/docs/uni-app-component-libraries.md +8 -7
  50. package/dist/docs/upload.md +40 -3
  51. package/dist/docs/vite-plugin.md +171 -0
  52. package/dist/docs/vue-sfc.md +42 -0
  53. package/dist/docs/weapp-config.md +54 -0
  54. package/dist/docs/wevu-authoring.md +10 -0
  55. package/dist/doctor-worker.d.mts +1 -0
  56. package/dist/doctor-worker.mjs +60 -0
  57. package/dist/doctor.d.mts +144 -0
  58. package/dist/doctor.mjs +850 -0
  59. package/dist/engine-C66J0HLz.mjs +54 -0
  60. package/dist/eslint.mjs +1 -2
  61. package/dist/{file-giE9UMZa.mjs → file-CcIOmqhC.mjs} +58 -24
  62. package/dist/file-DtcteQ4G.mjs +1 -0
  63. package/dist/files-BqxFIPRp.mjs +45 -0
  64. package/dist/forwardConsole-B0Reo8Lf.mjs +511 -0
  65. package/dist/getInstance-BAIaU2y9.mjs +1 -0
  66. package/dist/getInstance-Dt9IQDKr.mjs +28 -0
  67. package/dist/history-BIiRCzbq.mjs +784 -0
  68. package/dist/i18n.d.mts +1 -1
  69. package/dist/index-D5rgBzYZ.d.mts +740 -0
  70. package/dist/index.d.mts +12 -10
  71. package/dist/index.mjs +3 -2
  72. package/dist/json.d.mts +1 -1
  73. package/dist/json.mjs +1 -2
  74. package/dist/lib-DjccSI1B.mjs +143 -0
  75. package/dist/lifecycle-C36WSbQS.mjs +413 -0
  76. package/dist/loadConfig-BWIsDXR4.mjs +59 -0
  77. package/dist/loadConfig-D-BpBgsk.mjs +1 -0
  78. package/dist/logBuildAppFinish-ChjwATMv.mjs +57 -0
  79. package/dist/logger-DGn5iEVN.mjs +1 -0
  80. package/dist/mcp-CYgX9HpO.mjs +86 -0
  81. package/dist/{mcp-BG6TliEg.mjs → mcp-Cj8Maqo6.mjs} +16 -7
  82. package/dist/mcp.d.mts +6 -3
  83. package/dist/mcp.mjs +1 -2
  84. package/dist/mcpClient-DVLvFLZv.mjs +287 -0
  85. package/dist/metadata-hwF7QRcS.mjs +59 -0
  86. package/dist/nodeEnv-BmH8UZPR.mjs +7 -0
  87. package/dist/openIde-CroqOgk5.mjs +648 -0
  88. package/dist/options-jqFwfD1G.mjs +34 -0
  89. package/dist/package-Cmakyy3J.mjs +4 -0
  90. package/dist/path-CYYIQGS7.mjs +44 -0
  91. package/dist/{platform-DTWs5QRi.mjs → platform-CnkySBKz.mjs} +1 -1
  92. package/dist/processCleanup-BQn2kTcK.mjs +19 -0
  93. package/dist/protocol-Cg6Jdlvb.mjs +141 -0
  94. package/dist/reader-sh_POQ9-.mjs +93 -0
  95. package/dist/realpathScope-Tf9mz-fh.mjs +23 -0
  96. package/dist/report-hyonPGbZ.mjs +107 -0
  97. package/dist/resolvedId-CiDl7SC1.mjs +60 -0
  98. package/dist/{resolvers-icNxkpcy.mjs → resolvers-Dod-euqX.mjs} +4 -1
  99. package/dist/resolvers.mjs +1 -2
  100. package/dist/runtime-CLUhQsdA.mjs +43 -0
  101. package/dist/{runtime-Ee2HY6gR.d.mts → runtime-DpVf714f.d.mts} +1 -1
  102. package/dist/runtime.d.mts +1 -1
  103. package/dist/runtime.mjs +1 -2
  104. package/dist/schematics-kO26eQRT.mjs +91 -0
  105. package/dist/session-D3zsdzIy.mjs +452 -0
  106. package/dist/test.d.mts +1 -0
  107. package/dist/test.mjs +204 -45
  108. package/dist/{types-CgZn5X6j.d.mts → types-D-kfuyVa.d.mts} +1 -2
  109. package/dist/types-D0FFexRF.d.mts +39 -0
  110. package/dist/types.d.mts +3 -3
  111. package/dist/{upload-D0RcEWrq.mjs → upload-DozK8UdN.mjs} +278 -15
  112. package/dist/upload-worker.mjs +136 -3
  113. package/dist/utils-Dy51PYAC.mjs +1034 -0
  114. package/dist/vite.d.mts +9 -0
  115. package/dist/vite.mjs +309 -0
  116. package/dist/volar.d.mts +2 -2
  117. package/dist/web-apis.mjs +1 -2
  118. package/dist/wxs-BT8btflA.mjs +112 -0
  119. package/dist/wxs-Z4VQDeJ_.mjs +1 -0
  120. package/package.json +80 -48
  121. package/dist/adapters-BwnMMIZR.mjs +0 -2
  122. package/dist/dashboard-BzaVesmQ.mjs +0 -558
  123. package/dist/file-D19nbDoN.mjs +0 -2
  124. package/dist/getInstance-CYF1vl5l.mjs +0 -2
  125. package/dist/index-DbqVupg0.d.mts +0 -246
  126. package/dist/logger-mt4mSTqV.mjs +0 -2
package/README.md CHANGED
@@ -14,6 +14,20 @@
14
14
 
15
15
  <p>&nbsp;</p>
16
16
 
17
+ ## Node.js 支持范围
18
+
19
+ 框架及编译依赖链要求 `^22.18.0 || ^24.11.0 || >=26.0.0`:Node 22 至少 22.18.0、Node 24 至少 24.11.0,或 Node 26 及以上版本;不支持 Node 20、23、25。这是 Babel 8 与必需构建依赖支持范围的交集,不能通过关闭 engines 校验恢复旧版本支持。
20
+
21
+ 升级已有项目时先升级 Node.js,再重新安装依赖。CLI 会在加载编译依赖前检查实际 Node 版本;`prepare` 也会明确拒绝不支持的环境。直接通过 Vite 或程序 API 消费时同样需要遵守包的 `engines.node`。
22
+
23
+ `create-weapp-vite` 自身依赖要求更高:Node 22 至少 22.22.2、Node 24 至少 24.15.0,或 Node 26 及以上版本。新建项目按脚手架要求选择 Node,不要将框架最低版本误认为脚手架最低版本。
24
+
25
+ 发布候选在构建环境中打包,再在独立临时消费者中以严格 engines/peer 校验安装;CI 覆盖 Linux、Windows、macOS 的 Node 22.18.0、24.11.0、26.0.0 及 22/24 当前补丁版本,验证原生和 SFC 构建、prepare 与公开类型。
26
+
27
+ ## 普通 Vite 与 Vite+
28
+
29
+ 独立项目继续使用 `wv dev/build`,不需要注册插件或安装 Vite+。采用普通 Vite / Vite+ 时,在顶层 `weapp` 配置旁注册 `weapp-vite/vite` 的 `weapp()`,使用原生 `vite dev/build` / `vp dev/build`。当前插件开放微信 TS/Vue/React 生产构建、原生 `build --watch` 与实验性 classic/stateful 开发;通过 `weapp.hmr.runtime` 选择模式,已支持普通分包、独立分包与 worker,其他高级目标仍在分阶段对齐。Vite+ 需要配套 core alias 与依赖覆盖,详见[标准插件指南](https://vite.weapp.dev/guide/vite-plugin.html)。
30
+
17
31
  ## 使用文档地址: [vite.weapp.dev](https://vite.weapp.dev)
18
32
 
19
33
  ## Features
@@ -64,11 +78,27 @@ wv build -p web
64
78
 
65
79
  `web` 是浏览器 runtime 的规范平台名,`h5` 仅作为向后兼容别名保留;未选择 Web 平台时不改变现有小程序构建。完整配置和兼容边界见 [Web 运行时配置](https://vite.weapp.dev/config/web) 与 [`@weapp-vite/web`](https://vite.weapp.dev/packages/web)。
66
80
 
81
+ ### 可选 Hub 工作台
82
+
83
+ `wv dev --ui` / `wv build --ui` 保持独立 Dashboard。安装可选面板包 `@weapp-vite/dashboard` 后,可显式启用 DevFrame 1.2 的官方 Hub,无需安装 Vite DevTools:
84
+
85
+ ```bash
86
+ wv dev --ui-host hub
87
+ wv build --ui-host hub
88
+ wv analyze --ui-host hub
89
+ ```
90
+
91
+ `--ui-host` 只接受 `standalone` 和 `hub`,并隐式启用 UI;不传 UI 参数时,`dev` / `build` 不新增服务。Hub 入口为 `/__devframes/`,Dashboard 面板仍为 `/__weapp-vite/`,共用 loopback 服务、OTP 认证、报告控制器和原生连接。Hub 提供停靠面板与内建设置,不安装终端或其他默认工具;语言设置不自动翻译自定义 Dashboard。
92
+
93
+ Dashboard dock 与 Hub 品牌使用与官网相同图案的包内 SVG 字符串,以 data URL 提供。源码入口和发布产物均无需 SVG loader、官网目录或外部图标服务。
94
+
95
+ Hub 的 `/__devframes/__mcp` 聚合端点保持关闭,但与独立模式一样发布 Dashboard scoped MCP 实例,地址为 `/__weapp-vite/__mcp`,不继承其他插件的工具或 Resources。`analyze --json`、`--markdown`、`--report` 等输出选项优先级保持不变;Hub 不是离线报告导出。完整参数见 [CLI 指南](https://vite.weapp.dev/guide/cli#可选-hub-工作台)。
96
+
67
97
  ### Dashboard 嵌入 Vite DevTools
68
98
 
69
99
  `weapp-vite/dashboard` 是 Node 端共享核心;CLI 独立工作台与 Vite DevTools 复用同一个 `DevframeDefinition` 和 `@weapp-vite/dashboard` 面板。可选适配器位于 `weapp-vite/dashboard/vite`,使用官方 `createPluginFromDevframe`,不会由普通包入口或 CLI 自动加载。
70
100
 
71
- 接入方安装 `@weapp-vite/dashboard`、`@vitejs/devtools` 和 `@vitejs/devtools-kit`。当前接入按 Vite `8.3.0`、DevTools / Kit `0.7.6`、Devframe `1.1.0` 验证;Kit 是可选 peer,宿主依赖不进入小程序产物。
101
+ 接入方安装 `@weapp-vite/dashboard`、`@vitejs/devtools` 和 `@vitejs/devtools-kit`。当前接入使用 Vite `8.3.4`、DevTools / Kit `0.8.0`、Devframe `1.2.5`;Kit 是可选 peer,宿主依赖不进入小程序产物。
72
102
 
73
103
  ```ts
74
104
  import type { DevToolsConfig } from '@vitejs/devtools/config'
@@ -103,12 +133,21 @@ export function createDashboardHost(snapshot: DashboardAnalyzeSnapshot, roots: D
103
133
 
104
134
  每个控制器只同时挂载到一个逻辑宿主。适配器记录成功安装的 Vite 配置身份,并仅在该配置拥有的环境关闭时释放核心。成功重启将所有权移交给新配置,旧实例和未安装的失败候选的清理都不会误释放当前控制器;替换前的资源校验失败时,旧宿主仍可查询和更新。首次 setup 失败或 SDK 安装开始后的失败会释放核心,不承诺回滚部分安装。自行使用 `dashboard.definition` 对接其他 Devframe 宿主时,调用方必须负责最终关闭和启动失败时的 `dashboard.dispose()`。核心不启动服务器,也不拥有外部宿主的认证、Origin 或 MCP 策略;共享宿主不是只读沙箱。
105
135
 
106
- DevTools `0.7.6` 自身存在程序化重启边界:重复使用同一个 `DevTools()` 返回值时,旧实例关闭可能同时关闭新实例的 WebSocket;不安装 Dashboard 也能复现。应在每次重载的 Vite 配置中重新调用 `DevTools()`,不要把该 SDK 插件实例长期缓存在复用的 inline 配置里。上述重启验证使用重新创建的 SDK 宿主和保留的 Dashboard 控制器,不代表修复了上游传输问题。
136
+ DevTools 自身存在程序化重启边界:重复使用同一个 `DevTools()` 返回值时,旧实例关闭可能同时关闭新实例的 WebSocket;不安装 Dashboard 也能复现。应在每次重载的 Vite 配置中重新调用 `DevTools()`,不要把该 SDK 插件实例长期缓存在复用的 inline 配置里。上述重启验证使用重新创建的 SDK 宿主和保留的 Dashboard 控制器,不代表修复了上游传输问题。
107
137
 
108
138
  面板默认位于 `/__weapp-vite/`,自定义目录与应用 `base` 独立。前端复用宿主连接或从页面相对位置发现元数据,复制视图链接保留目录和查询参数但排除认证 fragment。适配器只在开发模式挂载,生产构建不要求可选面板资源,也不导出报告。以上入口仅用于 Node 开发 / 构建宿主,不应导入小程序 AppService。
109
139
 
110
140
  仓库内可通过 `apps/dashboard-ui-lab` 的 `dev:inspector` 与 `dev:inspector:host` 验证两种宿主,详见其 [实验说明](../../apps/dashboard-ui-lab/README.md)。
111
141
 
142
+ ### Dashboard MCP
143
+
144
+ CLI 的 standalone 与 Hub 模式均向 AI 提供摘要/预算、包与产物/模块检索、重复分析、构建比较、最近事件与受限文件片段,并提供调查列表、详情和领取/提案/开始/回报四个元数据动作。页面与工具共享报告、产物及 `weapp-vite/dashboard/analyze` 纯计算,缺失基线或测量不会假造增减。实际监听后可通过 `devframe connect` 发现 scoped 实例;MCP 校验 loopback 对端与 Origin,浏览器使用 OTP。本机模式不区分本机用户,请勿通过代理、隧道或端口转发对外发布。
145
+
146
+ 「对象检查」以真实包 → 产物 → 模块关系浏览完整报告,选择与显式筛选分离,证据/内容/变化/调查共用一个上下文区。浏览器提交绑定报告的调查,外部 Agent 回传提案后需用户明确授权;执行仍在外部,回执不能代替更新报告上的人工复验。创建、取消、授权和复验不暴露为 Agent 工具,也不提供通用 shared-state、任意文件写入或命令执行。
147
+
148
+ 旧 revision 请求与旧提案授权会被拒绝。嵌入 Vite DevTools 时仍由宿主决定是否开放 MCP;现有 `wv mcp`、REST 与微信 IDE 自动化入口保持不变。客户端配置、任务版本和领取令牌用法见 [随包 MCP 指南](docs/mcp.md#dashboard-证据查询与对象调查devframe)。
149
+
150
+
112
151
  ### Vue 项目
113
152
 
114
153
  ```typescript
@@ -377,6 +416,7 @@ wv build --upload -p weapp
377
416
  # 独立 upload 命令仍支持多个小程序目标;all 在此表示六端
378
417
  wv upload --platform jd,swan
379
418
  wv upload --platform all --dry-run
419
+ wv upload --platform xhs,tt --json --timeout 180
380
420
 
381
421
  # 内置本地自动版本演练,不修改版本或锁文件
382
422
  wv upload -p xhs,tt --mode test --bump patch --git-desc --dry-run
@@ -388,6 +428,8 @@ wv upload -p xhs,tt --mode test --bump patch --git-desc --dry-run
388
428
 
389
429
  `build -p all --upload` 保持“小程序 + Web”语义,等两个后端都构建成功后只上传小程序;独立 `wv upload -p all` 才是六端逐一构建上传,首次失败停止。`--dry-run` 只构建并校验产物,不校验凭据、不调用 SDK。
390
430
 
431
+ 独立 `upload --json` 将单个结构化报告写入 stdout,构建日志与官方进度进入 stderr;失败保留前序成功、当前错误和后续 `not-run` 条目,并以非零状态退出。`--timeout <秒>` 只限制各平台 SDK worker,不包含构建。SDK 开始后超时或中断标记远端结果未确认;终止本地进程不能取消远端任务,不自动重试。六端可选结果与进度差异见[结果、进度与本地超时](https://vite.weapp.dev/guide/upload.html#report)。这两个选项不适用于 `build --upload`、`preview` 或 IDE 上传。
432
+
391
433
  多个平台可用一份 `weapp.multiPlatform.projectConfigs` 映射集中配置 AppID,公共字段用对象展开复用,不必手工维护六份原生 JSON。构建器在代码输出目录内生成对应项目配置;原生文件方式仍可使用。完整配置见[一份配置与批量上传](https://vite.weapp.dev/guide/upload.html#batch)。
392
434
 
393
435
  官方工具按目标安装,凭据只使用环境变量,不在 `weapp.upload` 中配置。完整的项目配置、AppID、凭据获取与环境文件、上传、预览、批量操作、CI 与排障见[小程序上传与预览指南](https://vite.weapp.dev/guide/upload.html):[小红书](https://vite.weapp.dev/guide/upload/xhs.html)、[抖音](https://vite.weapp.dev/guide/upload/tt.html)、[微信](https://vite.weapp.dev/guide/upload/weapp.html)、[支付宝与淘宝边界](https://vite.weapp.dev/guide/upload/alipay.html)、[京东](https://vite.weapp.dev/guide/upload/jd.html)、[百度](https://vite.weapp.dev/guide/upload/swan.html)。本地速查见 `dist/docs/upload.md`;淘宝暂不支持,不要用 `-p alipay` 替代。
@@ -443,7 +485,7 @@ wv upload -p ./dist -v 1.2.3 -d "release"
443
485
 
444
486
  每次旧顶层调用只警告一次未来移除,不要求立即改写脚本;若只想保留 IDE 行为,改为 `wv ide upload -p ./dist -v 1.2.3 -d "release"`,该显式入口不警告。若迁移到 SDK,先在**源码项目根**安装 `miniprogram-ci`、配置 AppID、代码上传私钥与 IP 白名单,再执行 `wv build --upload -p weapp --uv 1.2.3 --desc "release"`。SDK 会重新构建、使用新凭据,不复用 IDE 登录;不要把旧 `--project` 的产物目录直接作为 `[root]`。
445
487
 
446
- `-p` 有 `--version/-v`、`--project`、`--appid`、`--ext-appid` 或 `--info-output/-i` 等旧标记时才表示 IDE 项目目录,否则表示平台,不猜测路径。旧标记与 SDK 的 `--platform`、`--uv`、`--bump`、`--git-desc`、`--dry-run`(含其 `--no-*` 形式)混用,在 IDE、编译或版本修改前报错;SDK dry-run/自动版本不适用于 IDE。`--desc` 共用,`-d` 只在旧调用中是说明,原生命令中仍是 debug。
488
+ `-p` 有 `--version/-v`、`--project`、`--appid`、`--ext-appid` 或 `--info-output/-i` 等旧标记时才表示 IDE 项目目录,否则表示平台,不猜测路径。旧标记与 SDK 的 `--platform`、`--uv`、`--bump`、`--git-desc`、`--dry-run`、`--json`、`--timeout`(含其 `--no-*` 形式)混用,在 IDE、编译或版本修改前报错;SDK 专属选项不适用于 IDE。`--desc` 共用,`-d` 只在旧调用中是说明,原生命令中仍是 debug。
447
489
 
448
490
  `wv upload --help` 查看 SDK 帮助;`wv help upload` 保留旧 IDE 帮助并提示未来弃用;`wv ide help upload` 不弃用、不警告。等号写法、选项值与 `--` 边界等完整规则见[旧上传兼容与迁移](https://vite.weapp.dev/guide/cli.html#legacy-upload)。
449
491
 
@@ -540,3 +582,17 @@ const artifact = await buildTestArtifact({ cwd: process.cwd() })
540
582
  [MIT](./LICENSE)
541
583
 
542
584
  <!-- "//------":""esbuild": "^0.21.3",", -->
585
+
586
+ ## 实验性标准 Vite 插件
587
+
588
+ `weapp-vite/vite` 导出 `weapp()`,通过 `plugins: [weapp()]` 和顶层 `weapp` 配置接入原生 `vite build` / `vp build`。当前开放微信 TS/Vue/React 生产构建、原生 build watch 与实验性 classic/stateful 开发;已支持普通分包、独立分包与 worker,其他高级目标继续分阶段对齐。配置、Vite+ alias 与未开放能力见 [标准插件指南](https://vite.weapp.dev/guide/vite-plugin)。离线说明随包发布在 `dist/docs/vite-plugin.md`。
589
+
590
+ ## AI 改动验收
591
+
592
+ 通过 `wv accept --inspect --json` 检查环境;审阅配置后运行 `wv accept --trust --json`。现有 MCP 同时提供验收启动、状态、取消和报告工具,无需模型 Key。[接入指南](https://vite.weapp.dev/guide/acceptance)。独立 `weapp-agent` CLI 同仓维护并保留原命令。
593
+
594
+ ## 微信开发者工具多版本
595
+
596
+ 默认使用本机已安装的最新 Stable。用 `wv ide devtools list` 查看安装,`wv ide devtools add "<path-to-cli>"` 登记自定义位置;`wv open --devtools-channel=nightly` 或 `wv build --open --devtools-channel=rc --devtools-version=<version>` 明确选择测试版本。旧 `cliPath` 和路径环境变量继续固定安装,显式渠道/版本可覆盖继承配置。官方版本查询不阻塞默认选择,`--require-official-latest` 可启用严格检查。
597
+
598
+ 仓库包可用 `pnpm e2e:ide:matrix --targets=stable,rc,nightly --suite=ide-smoke` 串行测试已有安装。矩阵记录实际 IDE、基础库和资源清理结果;缺失、未登录、失败或未完成项返回非零。安装与登录由用户完成。同一账号切换安装后可能需要重新扫码;矩阵以非交互模式记录“需要重新登录”并继续其他版本,无需预备多个账号。完整 CLI、编程接口和 MCP 用法见 [weapp-ide-cli 文档](https://vite.weapp.dev/packages/weapp-ide-cli)。
@@ -0,0 +1,60 @@
1
+ # 第三方软件声明
2
+
3
+ weapp-vite 的 JavaScript 产物包含以下 MIT 许可的软件,完整许可证保留如下。
4
+
5
+ ## Chokidar 5.0.0
6
+
7
+ 此副本包含本地监听生命周期修补:目录注册与扫描的资源归属、删除重建的节流释放、
8
+ 文件订阅的异步结果隔离,以及同步关闭或取消监听时的资源清理。
9
+
10
+ ```text
11
+ The MIT License (MIT)
12
+
13
+ Copyright (c) 2012 Paul Miller (https://paulmillr.com), Elan Shanker
14
+
15
+ Permission is hereby granted, free of charge, to any person obtaining a copy
16
+ of this software and associated documentation files (the “Software”), to deal
17
+ in the Software without restriction, including without limitation the rights
18
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19
+ copies of the Software, and to permit persons to whom the Software is
20
+ furnished to do so, subject to the following conditions:
21
+
22
+ The above copyright notice and this permission notice shall be included in
23
+ all copies or substantial portions of the Software.
24
+
25
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
31
+ THE SOFTWARE.
32
+ ```
33
+
34
+ ## readdirp 5.1.1
35
+
36
+ 此依赖随 Chokidar 打包,保留上游实现。
37
+
38
+ ```text
39
+ MIT License
40
+
41
+ Copyright (c) 2012-2019 Thorsten Lorenz, Paul Miller (https://paulmillr.com)
42
+
43
+ Permission is hereby granted, free of charge, to any person obtaining a copy
44
+ of this software and associated documentation files (the "Software"), to deal
45
+ in the Software without restriction, including without limitation the rights
46
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
47
+ copies of the Software, and to permit persons to whom the Software is
48
+ furnished to do so, subject to the following conditions:
49
+
50
+ The above copyright notice and this permission notice shall be included in all
51
+ copies or substantial portions of the Software.
52
+
53
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
54
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
55
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
56
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
57
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
58
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
59
+ SOFTWARE.
60
+ ```
package/bin/bootstrap.js CHANGED
@@ -1,3 +1,9 @@
1
+ import { readFileSync } from 'node:fs'
2
+ // eslint-disable-next-line e18e/ban-dependencies -- 启动检查使用与发布 engines 完全相同的 npm semver 语义。
3
+ import satisfies from 'semver/functions/satisfies.js'
4
+
5
+ const { engines } = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'))
6
+
1
7
  export function isPrepareCommand(argv) {
2
8
  return Array.isArray(argv) && argv[0] === 'prepare'
3
9
  }
@@ -105,9 +111,16 @@ export function guardPrepareProcessExit(argv) {
105
111
  export async function runWeappViteCLI(options = {}) {
106
112
  const {
107
113
  argv = getGlobalProcess().argv.slice(2),
108
- importer = () => import('../dist/cli.mjs'),
114
+ nodeVersion = getGlobalProcess().versions.node,
115
+ importer = () => ['accept', 'mcp'].includes(argv[0])
116
+ ? import('../dist/cli-acceptance.mjs')
117
+ : import('../dist/cli.mjs'),
109
118
  write = message => getGlobalProcess().stderr.write(`\n WARN ${message}\n\n`),
110
119
  } = options
120
+ // 在加载 Babel 等依赖前校验同一份发布声明;prepare 的容错不能吞掉不受支持的运行时。
121
+ if (!satisfies(nodeVersion, engines.node)) {
122
+ throw new Error(`weapp-vite requires Node.js ${engines.node}; current version is ${nodeVersion}. Please upgrade Node.js before running this command.`)
123
+ }
111
124
  const restorePrepareGuard = guardPrepareProcessExit(argv)
112
125
  const restoreKnownNoiseGuard = guardKnownLocalPkgResolveNoise()
113
126
 
@@ -0,0 +1,255 @@
1
+ import { c as getBackendForCapability } from "./createCompilerContextInstance-aYwi8wQt.mjs";
2
+ import { t as VERSION } from "./constants-DEZdcsMn.mjs";
3
+ import { r as logger_default } from "./logger-DGn5iEVN.mjs";
4
+ import { i as resolveRuntimeTargets } from "./runtime-CLUhQsdA.mjs";
5
+ import { n as openIde, r as resolveIdeCommandContext } from "./openIde-CroqOgk5.mjs";
6
+ import { o as resolveConfigFile, r as filterDuplicateOptions } from "./options-jqFwfD1G.mjs";
7
+ import { a as startForwardConsoleBridge, i as resolveForwardConsoleOptions, o as readLatestHmrProfileSummary } from "./forwardConsole-B0Reo8Lf.mjs";
8
+ import process from "node:process";
9
+ import { bootstrapWechatDevtoolsSettings, connectOpenedAutomator, defaultCustomConfigFilePath, detectWechatDevtoolsServicePort, getWechatIdeTestAccounts, getWechatIdeTicket, getWechatIdeToolInfo, queryWechatIdeLogin, refreshWechatIdeTicket, resolveCliPath, resolveProjectAutomatorPort, setWechatIdeTicket } from "weapp-ide-cli";
10
+ //#region src/cli/commands/ide/action.ts
11
+ async function runIdeDoctor(projectPath, options) {
12
+ const resolvedCli = await resolveCliPath();
13
+ const servicePort = await detectWechatDevtoolsServicePort().then((result) => ({
14
+ ...result,
15
+ error: void 0
16
+ })).catch((error) => ({
17
+ servicePortEnabled: void 0,
18
+ servicePort: void 0,
19
+ error
20
+ }));
21
+ const cliCheck = resolvedCli.cliPath ? {
22
+ status: "ok",
23
+ value: {
24
+ path: resolvedCli.cliPath,
25
+ source: resolvedCli.source
26
+ }
27
+ } : {
28
+ fix: "执行 `weapp config set cliPath <path-to-cli>` 配置微信开发者工具 CLI。",
29
+ message: "未找到可用的微信开发者工具 CLI。",
30
+ status: "failed",
31
+ value: { source: resolvedCli.source }
32
+ };
33
+ const servicePortCheck = servicePort.servicePortEnabled === false ? {
34
+ fix: "在微信开发者工具中打开:设置 -> 安全设置 -> 服务端口。",
35
+ message: "微信开发者工具服务端口已关闭。",
36
+ status: "failed",
37
+ value: servicePort
38
+ } : servicePort.error ? {
39
+ fix: "执行 `wv ide doctor --json` 查看底层错误,并确认微信开发者工具已安装。",
40
+ message: servicePort.error instanceof Error ? servicePort.error.message : String(servicePort.error),
41
+ status: "warning"
42
+ } : {
43
+ status: servicePort.servicePortEnabled === true ? "ok" : "unknown",
44
+ value: {
45
+ enabled: servicePort.servicePortEnabled ?? null,
46
+ port: servicePort.servicePort ?? null
47
+ }
48
+ };
49
+ let loginCheck = {
50
+ fix: "打开微信开发者工具完成登录后重试。",
51
+ message: "暂未确认登录状态。",
52
+ status: "unknown"
53
+ };
54
+ if (resolvedCli.cliPath) try {
55
+ const result = await queryWechatIdeLogin(resolvedCli.cliPath, { timeout: 3e3 });
56
+ loginCheck = result.status === "success" ? {
57
+ status: result.login ? "ok" : "warning",
58
+ value: result.login,
59
+ ...result.login ? {} : { message: "原生 CLI 明确返回未登录,请打开微信开发者工具完成登录。" }
60
+ } : {
61
+ status: "unknown",
62
+ message: `登录查询未确认状态(${result.reason}),不能据此认定未登录。`
63
+ };
64
+ } catch {
65
+ loginCheck = {
66
+ message: "登录查询执行失败,登录状态仍未确认。",
67
+ status: "unknown"
68
+ };
69
+ }
70
+ const projectCheck = projectPath ? {
71
+ status: "ok",
72
+ value: projectPath
73
+ } : {
74
+ fix: "在项目目录执行命令,或显式传入 `wv ide doctor <project-root>`。",
75
+ message: "未解析到微信开发者工具项目目录。",
76
+ status: "warning"
77
+ };
78
+ let automatorCheck = {
79
+ message: projectPath ? "当前项目没有可连接的已打开 automator 会话。" : "缺少项目目录,跳过 automator 检查。",
80
+ status: "unknown"
81
+ };
82
+ let toolCheck = {
83
+ message: "当前没有可读取的 DevTools Tool.getInfo。",
84
+ status: "unknown"
85
+ };
86
+ if (projectPath) try {
87
+ const miniProgram = await connectOpenedAutomator({
88
+ projectPath,
89
+ port: resolveProjectAutomatorPort(projectPath),
90
+ timeout: 3e3
91
+ });
92
+ automatorCheck = {
93
+ status: "ok",
94
+ value: true
95
+ };
96
+ try {
97
+ if (typeof miniProgram.toolInfo === "function") toolCheck = {
98
+ status: "ok",
99
+ value: await miniProgram.toolInfo()
100
+ };
101
+ } catch {
102
+ toolCheck = {
103
+ status: "warning",
104
+ message: "项目自动化连接已建立,但 Tool.getInfo 未能返回工具信息;宿主版本仍未确认。",
105
+ fix: "确认目标项目模拟器就绪后重新运行 doctor;此结果不证明登录失效。"
106
+ };
107
+ } finally {
108
+ miniProgram.disconnect?.();
109
+ }
110
+ } catch (error) {
111
+ automatorCheck = {
112
+ fix: "先执行 `wv open` 打开项目;若服务端口已开启,关闭多余 DevTools 窗口后重试。",
113
+ message: error instanceof Error ? error.message : String(error),
114
+ status: "warning"
115
+ };
116
+ }
117
+ const report = {
118
+ checks: {
119
+ automator: automatorCheck,
120
+ cli: cliCheck,
121
+ login: loginCheck,
122
+ project: projectCheck,
123
+ servicePort: servicePortCheck,
124
+ tool: toolCheck
125
+ },
126
+ configFile: defaultCustomConfigFilePath,
127
+ nodeVersion: process.version,
128
+ platform: process.platform,
129
+ weappViteVersion: VERSION
130
+ };
131
+ const output = JSON.stringify(report, null, 2);
132
+ if (options.json) process.stdout.write(`${output}\n`);
133
+ else logger_default.info(output);
134
+ if (options.strict && Object.values(report.checks).some((check) => check.status === "failed")) throw new Error("微信开发者工具环境诊断未通过,请根据 doctor 输出修复失败项后重试。");
135
+ return report;
136
+ }
137
+ async function waitForTermination(cleanup) {
138
+ await new Promise((resolve) => {
139
+ const signals = ["SIGINT", "SIGTERM"];
140
+ let cleaning = false;
141
+ const handlers = /* @__PURE__ */ new Map();
142
+ const teardown = async () => {
143
+ if (cleaning) return;
144
+ cleaning = true;
145
+ for (const signal of signals) process.off(signal, handlers.get(signal));
146
+ await cleanup();
147
+ resolve();
148
+ };
149
+ for (const signal of signals) {
150
+ const handler = () => {
151
+ teardown();
152
+ };
153
+ handlers.set(signal, handler);
154
+ process.on(signal, handler);
155
+ }
156
+ });
157
+ }
158
+ function formatIdeOutput(data, options) {
159
+ if (options.json) return JSON.stringify(data, null, 2);
160
+ return JSON.stringify(data, null, 2);
161
+ }
162
+ /**
163
+ * @description 执行 ide 子命令。
164
+ */
165
+ async function runIdeCommand(action, root, options) {
166
+ if (action !== "logs" && action !== "setup" && action !== "info" && action !== "test-accounts" && action !== "ticket" && action !== "ticket:set" && action !== "ticket:refresh" && action !== "doctor") throw new Error(`未知 ide 子命令: ${action ?? "(empty)"}`);
167
+ filterDuplicateOptions(options);
168
+ const configFile = resolveConfigFile(options);
169
+ const targets = resolveRuntimeTargets(options);
170
+ const ideBackend = getBackendForCapability(targets, "miniprogram", "ide");
171
+ if (!ideBackend) throw new Error("`weapp-vite ide` 当前仅支持小程序平台。");
172
+ const resolved = await resolveIdeCommandContext({
173
+ configFile,
174
+ mode: options.mode ?? "development",
175
+ platform: ideBackend.platform,
176
+ projectPath: root,
177
+ cliPlatform: targets.rawPlatform
178
+ });
179
+ if (action !== "doctor" && resolved.platform !== "weapp") throw new Error("`weapp-vite ide logs` 当前仅支持微信小程序平台。");
180
+ if (action === "doctor") {
181
+ await runIdeDoctor(resolved.projectPath, options);
182
+ return;
183
+ }
184
+ const projectPath = resolved.projectPath;
185
+ if (!projectPath) throw new Error("无法解析微信开发者工具项目目录,请显式传入 root 或检查 project.config.json。");
186
+ if (action === "setup") {
187
+ const result = await bootstrapWechatDevtoolsSettings({
188
+ projectPath,
189
+ trustProject: options.trustProject
190
+ });
191
+ logger_default.info(`已完成微信开发者工具配置预热:扫描实例 ${result.touchedInstanceCount} 个,检测服务端口配置 ${result.detectedSecurityCount} 处,写入项目信任 ${result.trustedProjectCount} 处。`);
192
+ return;
193
+ }
194
+ if (options.open) await openIde(resolved.platform, projectPath, {
195
+ openRecovery: options.openRecovery,
196
+ trustProject: options.trustProject,
197
+ openStrategy: options.ideOpenStrategy
198
+ });
199
+ if (action === "info") {
200
+ const result = await getWechatIdeToolInfo({ projectPath });
201
+ logger_default.info(formatIdeOutput(result, options));
202
+ return;
203
+ }
204
+ if (action === "test-accounts") {
205
+ const result = await getWechatIdeTestAccounts({ projectPath });
206
+ logger_default.info(formatIdeOutput(result, options));
207
+ return;
208
+ }
209
+ if (action === "ticket") {
210
+ const result = await getWechatIdeTicket({ projectPath });
211
+ logger_default.info(formatIdeOutput(result, options));
212
+ return;
213
+ }
214
+ if (action === "ticket:set") {
215
+ if (!options.ticket) throw new Error("`weapp-vite ide ticket:set` 需要提供 --ticket。");
216
+ await setWechatIdeTicket({
217
+ projectPath,
218
+ ticket: options.ticket
219
+ });
220
+ logger_default.info(`已设置微信开发者工具 ticket:${options.ticket}`);
221
+ return;
222
+ }
223
+ if (action === "ticket:refresh") {
224
+ await refreshWechatIdeTicket({ projectPath });
225
+ logger_default.info("已刷新微信开发者工具 ticket。");
226
+ return;
227
+ }
228
+ const forwardConsoleOptions = await resolveForwardConsoleOptions({
229
+ ...resolved.weappViteConfig,
230
+ forwardConsole: resolved.weappViteConfig?.forwardConsole === false ? { enabled: true } : {
231
+ ...typeof resolved.weappViteConfig?.forwardConsole === "object" ? resolved.weappViteConfig.forwardConsole : {},
232
+ enabled: true
233
+ }
234
+ });
235
+ const latestHmrSummary = await readLatestHmrProfileSummary({
236
+ cwd: resolved.cwd ?? process.cwd(),
237
+ relativeCwd: (value) => resolved.cwd ? value.replace(`${resolved.cwd}/`, "") : value,
238
+ weappViteConfig: resolved.weappViteConfig
239
+ });
240
+ if (latestHmrSummary) logger_default.info(latestHmrSummary.line);
241
+ const session = await startForwardConsoleBridge({
242
+ projectPath,
243
+ port: resolveProjectAutomatorPort(projectPath),
244
+ agentName: void 0,
245
+ logLevels: forwardConsoleOptions.logLevels,
246
+ unhandledErrors: forwardConsoleOptions.unhandledErrors,
247
+ onReadyMessage: "[forwardConsole] 已进入持续监听模式,按 Ctrl+C 退出。"
248
+ });
249
+ await waitForTermination(async () => {
250
+ logger_default.info("[forwardConsole] 正在关闭日志桥接...");
251
+ await session.close();
252
+ });
253
+ }
254
+ //#endregion
255
+ export { runIdeCommand };
@@ -0,0 +1,139 @@
1
+ import { r as logger_default } from "./logger-DGn5iEVN.mjs";
2
+ import { o as resolveConfigFile } from "./options-jqFwfD1G.mjs";
3
+ import { c as startWeappViteMcpServer, s as resolveWeappMcpConfig } from "./mcp-Cj8Maqo6.mjs";
4
+ import { a as inspectMcpClientConfig, i as resolveSupportedMcpClient, n as buildMcpClientConfigPlan, r as formatMcpQuickStart, t as writeMcpClientConfig } from "./mcpClient-DVLvFLZv.mjs";
5
+ import process from "node:process";
6
+ import path from "pathe";
7
+ import { runWithSuspendedSharedInput } from "weapp-ide-cli";
8
+ import { createInterface } from "node:readline/promises";
9
+ //#region src/cli/commands/mcp/action.ts
10
+ function resolvePort(port) {
11
+ if (typeof port === "number" && Number.isInteger(port)) return port;
12
+ if (typeof port === "string" && port.trim()) {
13
+ const parsed = Number.parseInt(port, 10);
14
+ if (Number.isInteger(parsed)) return parsed;
15
+ }
16
+ }
17
+ async function resolveHttpUrl(options) {
18
+ if (options.url?.trim()) return options.url.trim();
19
+ const workspaceRoot = options.workspaceRoot ? path.resolve(options.workspaceRoot) : process.cwd();
20
+ const originalCwd = process.cwd();
21
+ try {
22
+ if (workspaceRoot !== originalCwd) process.chdir(workspaceRoot);
23
+ const configFile = resolveConfigFile(options);
24
+ const { loadConfig } = await import("./loadConfig-D-BpBgsk.mjs");
25
+ const loaded = await loadConfig(configFile);
26
+ const resolved = resolveWeappMcpConfig(loaded?.config?.weapp?.mcp);
27
+ return `http://${resolved.host}:${resolved.port}${resolved.endpoint}`;
28
+ } catch {
29
+ const resolved = resolveWeappMcpConfig(void 0);
30
+ return `http://${resolved.host}:${resolved.port}${resolved.endpoint}`;
31
+ } finally {
32
+ if (process.cwd() !== originalCwd) process.chdir(originalCwd);
33
+ }
34
+ }
35
+ async function confirmWrite() {
36
+ if (!process.stdin.isTTY || !process.stdout.isTTY) return false;
37
+ return await runWithSuspendedSharedInput(async () => {
38
+ const rl = createInterface({
39
+ input: process.stdin,
40
+ output: process.stdout
41
+ });
42
+ try {
43
+ const normalized = (await rl.question("是否写入配置文件?(Y/n) ")).trim().toLowerCase();
44
+ return normalized === "" || normalized === "y" || normalized === "yes";
45
+ } finally {
46
+ rl.close();
47
+ }
48
+ });
49
+ }
50
+ function resolveClientTransport(transport) {
51
+ return transport === "http" ? "http" : "command";
52
+ }
53
+ async function handlePrint(clientName, options, write = false) {
54
+ const client = resolveSupportedMcpClient(clientName);
55
+ const workspaceRoot = options.workspaceRoot ?? process.cwd();
56
+ const transport = resolveClientTransport(options.transport);
57
+ const httpUrl = transport === "http" ? await resolveHttpUrl(options) : void 0;
58
+ const plan = buildMcpClientConfigPlan({
59
+ client,
60
+ transport,
61
+ url: httpUrl,
62
+ workspaceRoot
63
+ });
64
+ logger_default.info(`${plan.target.displayName} 配置文件:${plan.target.configPath}`);
65
+ logger_default.info(`服务器名称:${plan.target.serverName}`);
66
+ process.stdout.write(`${plan.preview}\n`);
67
+ if (!write) return;
68
+ if (options.yes || await confirmWrite()) {
69
+ await writeMcpClientConfig(plan);
70
+ logger_default.success(`已写入 ${plan.target.displayName} MCP 配置。`);
71
+ logger_default.info(`请重启 ${plan.target.displayName},然后执行:wv mcp doctor ${client}`);
72
+ return;
73
+ }
74
+ logger_default.info("已取消写入。");
75
+ }
76
+ async function handleDoctor(clientName, options) {
77
+ const client = resolveSupportedMcpClient(clientName);
78
+ const result = await inspectMcpClientConfig({
79
+ client,
80
+ workspaceRoot: options.workspaceRoot ?? process.cwd()
81
+ });
82
+ logger_default.info(`${result.displayName} 配置文件:${result.configPath}`);
83
+ logger_default.info(`服务器名称:${result.serverName}`);
84
+ if (!result.configExists || result.issues.length > 0) {
85
+ for (const issue of result.issues) logger_default.warn(issue);
86
+ throw new Error("MCP 客户端配置检查未通过。");
87
+ }
88
+ if (result.transport) logger_default.info(`传输模式:${result.transport}`);
89
+ if (result.httpReachable !== void 0) logger_default.info(`HTTP 服务可达:${result.httpReachable ? "是" : "否"}`);
90
+ logger_default.success("MCP 客户端配置检查通过。");
91
+ }
92
+ async function handleServer(options) {
93
+ const resolvedTransport = options.transport === "http" ? "streamable-http" : options.transport === "command" ? void 0 : options.transport;
94
+ const handle = await startWeappViteMcpServer({
95
+ endpoint: options.endpoint,
96
+ host: options.host,
97
+ port: resolvePort(options.port),
98
+ restEndpoint: options.rest === false ? false : options.restEndpoint,
99
+ transport: resolvedTransport,
100
+ unref: options.unref,
101
+ workspaceRoot: options.workspaceRoot
102
+ });
103
+ const shutdown = async () => {
104
+ process.off("SIGINT", shutdown);
105
+ process.off("SIGTERM", shutdown);
106
+ process.stdin.off("end", shutdown);
107
+ await handle.close?.();
108
+ };
109
+ process.once("SIGINT", shutdown);
110
+ process.once("SIGTERM", shutdown);
111
+ if (resolvedTransport !== "streamable-http") process.stdin.once("end", shutdown);
112
+ for (const line of formatMcpQuickStart({
113
+ httpUrl: resolvedTransport === "streamable-http" ? `http://${options.host ?? "127.0.0.1"}:${resolvePort(options.port) ?? 3088}${options.endpoint ?? "/mcp"}` : void 0,
114
+ transport: resolvedTransport === "streamable-http" ? "http" : "command"
115
+ })) logger_default.info(line);
116
+ }
117
+ /** 执行 MCP 子命令,注册与帮助阶段不加载服务依赖。 */
118
+ async function runMcpCommand(args, options) {
119
+ const [subcommand, client] = args;
120
+ if (subcommand === "init") {
121
+ if (!client) throw new Error("缺少客户端名称,请使用:wv mcp init <codex|claude-code|cursor>");
122
+ await handlePrint(client, options, true);
123
+ return;
124
+ }
125
+ if (subcommand === "print") {
126
+ if (!client) throw new Error("缺少客户端名称,请使用:wv mcp print <codex|claude-code|cursor>");
127
+ await handlePrint(client, options, false);
128
+ return;
129
+ }
130
+ if (subcommand === "doctor") {
131
+ if (!client) throw new Error("缺少客户端名称,请使用:wv mcp doctor <codex|claude-code|cursor>");
132
+ await handleDoctor(client, options);
133
+ return;
134
+ }
135
+ if (subcommand) throw new Error(`未知的 mcp 子命令:${subcommand}`);
136
+ await handleServer(options);
137
+ }
138
+ //#endregion
139
+ export { runMcpCommand };