weapp-vite 7.5.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.
- package/README.md +8 -2
- package/THIRD_PARTY_NOTICES.md +60 -0
- package/dist/action-B3YZMA-h.mjs +255 -0
- package/dist/action-BELcDNNv.mjs +139 -0
- package/dist/action-BOk3vGI7.mjs +1110 -0
- package/dist/action-DlC6JYpt.mjs +95 -0
- package/dist/action-zEDY7oh_.mjs +247 -0
- package/dist/{analyze-ZJUvEdaY.mjs → analyze-DN79YOAH.mjs} +1 -65
- package/dist/artifacts-BOyC9Fy-.mjs +106 -0
- package/dist/assets-C5_YYXNk.mjs +637 -0
- package/dist/auto-routes.mjs +2 -2
- package/dist/{budget-BD7VqLCl.d.mts → budget-CTLOHwgI.d.mts} +1 -2
- package/dist/budget-EOeEycc_.mjs +65 -0
- package/dist/builtProject-C29udgXY.mjs +541 -0
- package/dist/{chunkStrategy-DRA5WpB-.mjs → chunkStrategy-DY_LZIIe.mjs} +15 -3
- package/dist/{package-7swhyLmf.mjs → classifier-DBJY__kg.mjs} +4 -7
- package/dist/cli-acceptance.mjs +1 -1
- package/dist/cli.mjs +110 -4506
- package/dist/{config-V0L-IAJf.d.mts → config-Bf6DWhyb.d.mts} +136 -49
- package/dist/config.d.mts +2 -2
- package/dist/{createCompilerContextInstance-DJH_P_nZ.mjs → createCompilerContextInstance-aYwi8wQt.mjs} +15235 -9523
- package/dist/{createContext-BqYzHhY9.mjs → createContext-tApLtII-.mjs} +6 -3
- package/dist/dashboard/analyze.d.mts +1 -1
- package/dist/dashboard/analyze.mjs +3 -1
- package/dist/dashboard/vite.d.mts +1 -1
- package/dist/dashboard.d.mts +2 -2
- package/dist/dashboard.mjs +1749 -1
- package/dist/dashboardTransport-C_Y6jMp-.mjs +16 -0
- package/dist/{dashboardViteBridge-Dy3nAD4m.mjs → dashboardViteBridge-DCGR43aM.mjs} +8 -5
- package/dist/{dev-fR5GiJRO.mjs → dev-C2fgr_Xd.mjs} +5 -1
- package/dist/devProvider-D-hTfsEO.mjs +3027 -0
- package/dist/docs/README.md +8 -2
- package/dist/docs/mcp.md +10 -0
- package/dist/docs/troubleshooting.md +8 -0
- package/dist/docs/vue-sfc.md +25 -2
- package/dist/doctor-worker.mjs +3 -2
- package/dist/doctor.d.mts +2 -2
- package/dist/doctor.mjs +15 -13
- package/dist/engine-C66J0HLz.mjs +54 -0
- package/dist/{file-sC3jD7Fh.mjs → file-CcIOmqhC.mjs} +47 -19
- package/dist/file-DtcteQ4G.mjs +1 -0
- package/dist/forwardConsole-B0Reo8Lf.mjs +511 -0
- package/dist/getInstance-BAIaU2y9.mjs +1 -0
- package/dist/{getInstance-DiGSzBNI.mjs → getInstance-Dt9IQDKr.mjs} +1 -1
- package/dist/history-BIiRCzbq.mjs +784 -0
- package/dist/i18n.d.mts +1 -1
- package/dist/{index-C9HjUX5c.d.mts → index-D5rgBzYZ.d.mts} +1 -2
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +2 -2
- package/dist/json.d.mts +1 -1
- package/dist/lib-DjccSI1B.mjs +143 -0
- package/dist/{lifecycle-BROTlwSL.mjs → lifecycle-C36WSbQS.mjs} +120 -27
- package/dist/{loadConfig-C3BQhz7F.mjs → loadConfig-BWIsDXR4.mjs} +1 -1
- package/dist/loadConfig-D-BpBgsk.mjs +1 -0
- package/dist/logBuildAppFinish-ChjwATMv.mjs +57 -0
- package/dist/mcp-CYgX9HpO.mjs +86 -0
- package/dist/mcp.d.mts +1 -1
- package/dist/mcpClient-DVLvFLZv.mjs +287 -0
- package/dist/{processCleanup-B6KA30Zc.mjs → metadata-hwF7QRcS.mjs} +1 -19
- package/dist/nodeEnv-BmH8UZPR.mjs +7 -0
- package/dist/openIde-CroqOgk5.mjs +648 -0
- package/dist/options-jqFwfD1G.mjs +34 -0
- package/dist/package-Cmakyy3J.mjs +4 -0
- package/dist/path-CYYIQGS7.mjs +44 -0
- package/dist/processCleanup-BQn2kTcK.mjs +19 -0
- package/dist/{protocol-vg8HGJ4n.mjs → protocol-Cg6Jdlvb.mjs} +42 -39
- package/dist/reader-sh_POQ9-.mjs +93 -0
- package/dist/realpathScope-Tf9mz-fh.mjs +23 -0
- package/dist/report-hyonPGbZ.mjs +107 -0
- package/dist/{path-doV773b7.mjs → resolvedId-CiDl7SC1.mjs} +3 -46
- package/dist/runtime-CLUhQsdA.mjs +43 -0
- package/dist/{runtime-Ee2HY6gR.d.mts → runtime-DpVf714f.d.mts} +1 -1
- package/dist/runtime.d.mts +1 -1
- package/dist/schematics-kO26eQRT.mjs +91 -0
- package/dist/{session-PskhD-nZ.mjs → session-D3zsdzIy.mjs} +71 -9
- package/dist/test.mjs +10 -8
- package/dist/{types-CgZn5X6j.d.mts → types-D-kfuyVa.d.mts} +1 -2
- package/dist/types-D0FFexRF.d.mts +39 -0
- package/dist/types.d.mts +2 -2
- package/dist/{upload-D4msblBf.mjs → upload-DozK8UdN.mjs} +109 -5
- package/dist/upload-worker.mjs +1 -1
- package/dist/{utils-CJSCgEj6.mjs → utils-Dy51PYAC.mjs} +56 -116
- package/dist/vite.d.mts +1 -1
- package/dist/vite.mjs +51 -12
- package/dist/wxs-BT8btflA.mjs +112 -0
- package/dist/wxs-Z4VQDeJ_.mjs +1 -0
- package/package.json +52 -46
- package/dist/dashboard-DvqF3Key.mjs +0 -1842
- package/dist/devProvider-BGBkw28J.mjs +0 -1050
- package/dist/file-DRb4eWqw.mjs +0 -1
- package/dist/getInstance-SiE6WZRh.mjs +0 -1
- package/dist/loadConfig-VGtBF4qm.mjs +0 -1
- package/dist/mcp-D3Yh24Cj.mjs +0 -529
package/README.md
CHANGED
|
@@ -98,7 +98,7 @@ Hub 的 `/__devframes/__mcp` 聚合端点保持关闭,但与独立模式一样
|
|
|
98
98
|
|
|
99
99
|
`weapp-vite/dashboard` 是 Node 端共享核心;CLI 独立工作台与 Vite DevTools 复用同一个 `DevframeDefinition` 和 `@weapp-vite/dashboard` 面板。可选适配器位于 `weapp-vite/dashboard/vite`,使用官方 `createPluginFromDevframe`,不会由普通包入口或 CLI 自动加载。
|
|
100
100
|
|
|
101
|
-
接入方安装 `@weapp-vite/dashboard`、`@vitejs/devtools` 和 `@vitejs/devtools-kit
|
|
101
|
+
接入方安装 `@weapp-vite/dashboard`、`@vitejs/devtools` 和 `@vitejs/devtools-kit`。当前接入使用 Vite `8.3.4`、DevTools / Kit `0.8.0`、Devframe `1.2.5`;Kit 是可选 peer,宿主依赖不进入小程序产物。
|
|
102
102
|
|
|
103
103
|
```ts
|
|
104
104
|
import type { DevToolsConfig } from '@vitejs/devtools/config'
|
|
@@ -133,7 +133,7 @@ export function createDashboardHost(snapshot: DashboardAnalyzeSnapshot, roots: D
|
|
|
133
133
|
|
|
134
134
|
每个控制器只同时挂载到一个逻辑宿主。适配器记录成功安装的 Vite 配置身份,并仅在该配置拥有的环境关闭时释放核心。成功重启将所有权移交给新配置,旧实例和未安装的失败候选的清理都不会误释放当前控制器;替换前的资源校验失败时,旧宿主仍可查询和更新。首次 setup 失败或 SDK 安装开始后的失败会释放核心,不承诺回滚部分安装。自行使用 `dashboard.definition` 对接其他 Devframe 宿主时,调用方必须负责最终关闭和启动失败时的 `dashboard.dispose()`。核心不启动服务器,也不拥有外部宿主的认证、Origin 或 MCP 策略;共享宿主不是只读沙箱。
|
|
135
135
|
|
|
136
|
-
DevTools
|
|
136
|
+
DevTools 自身存在程序化重启边界:重复使用同一个 `DevTools()` 返回值时,旧实例关闭可能同时关闭新实例的 WebSocket;不安装 Dashboard 也能复现。应在每次重载的 Vite 配置中重新调用 `DevTools()`,不要把该 SDK 插件实例长期缓存在复用的 inline 配置里。上述重启验证使用重新创建的 SDK 宿主和保留的 Dashboard 控制器,不代表修复了上游传输问题。
|
|
137
137
|
|
|
138
138
|
面板默认位于 `/__weapp-vite/`,自定义目录与应用 `base` 独立。前端复用宿主连接或从页面相对位置发现元数据,复制视图链接保留目录和查询参数但排除认证 fragment。适配器只在开发模式挂载,生产构建不要求可选面板资源,也不导出报告。以上入口仅用于 Node 开发 / 构建宿主,不应导入小程序 AppService。
|
|
139
139
|
|
|
@@ -590,3 +590,9 @@ const artifact = await buildTestArtifact({ cwd: process.cwd() })
|
|
|
590
590
|
## AI 改动验收
|
|
591
591
|
|
|
592
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
|
+
```
|
|
@@ -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 };
|