weapp-ide-cli 6.1.9 → 6.2.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 +18 -0
- package/dist/automator-BkZZsGtn.js +1 -0
- package/dist/automator-CRpB6_pA.js +576 -0
- package/dist/automator-session-gWEsSs_A.js +558 -0
- package/dist/{cli-2sY1sAVq.js → cli-ChMQqi5w.js} +1219 -52
- package/dist/cli.js +3 -3
- package/dist/commands-C1PF1B4P.js +528 -0
- package/dist/commands-CZVPfkE9.js +1 -0
- package/dist/devtoolsProjectOwnership-yDD6h0dO.js +1726 -0
- package/dist/index.d.ts +314 -54
- package/dist/index.js +8 -5
- package/dist/managed-Sq8y8FzP.js +212 -0
- package/dist/run-mcp-CPv8cesh.js +1 -0
- package/dist/{run-mcp-LqaWlQJ_.js → run-mcp-Dl_1TH1x.js} +18 -9
- package/dist/sessionStore-zdzy2UFM.js +605 -0
- package/package.json +12 -11
- package/dist/automator-session-fbanL2eW.js +0 -1362
- package/dist/commands-DpMG1w04.js +0 -2
- package/dist/commands-__RJ552L.js +0 -1359
- package/dist/run-mcp-C2SQ_hRJ.js +0 -2
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { a as assertWechatDevtoolsPort, t as persistAutomatorSession } from "./sessionStore-zdzy2UFM.js";
|
|
2
|
+
import { h as startWechatIdeAgent, t as beginManagedWechatProject } from "./devtoolsProjectOwnership-yDD6h0dO.js";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { withMachineE2ELease } from "@weapp-vite/devtools-runtime";
|
|
5
|
+
import { execa } from "execa";
|
|
6
|
+
import fs from "node:fs/promises";
|
|
7
|
+
import process from "node:process";
|
|
8
|
+
import { acquireAutomatorPortLease } from "@weapp-vite/miniprogram-automator";
|
|
9
|
+
//#region src/cli/projectImport.ts
|
|
10
|
+
function isRecord(value) {
|
|
11
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12
|
+
}
|
|
13
|
+
/** 使用同一安装的 skill 入口;Windows 由 execa 处理官方 cmd 包装器。 */
|
|
14
|
+
function resolveProjectImportCli(cliPath, platform = process.platform) {
|
|
15
|
+
const paths = platform === "win32" ? path.win32 : path.posix;
|
|
16
|
+
return paths.join(paths.dirname(cliPath), platform === "win32" ? "wechatide.cmd" : "wechatide");
|
|
17
|
+
}
|
|
18
|
+
/** 官方导入会重写项目根、条件页和基础库选择;窗口启动前恢复原始输入。 */
|
|
19
|
+
async function preserveProjectConfig(projectPath, fileName, run) {
|
|
20
|
+
const file = path.join(projectPath, fileName);
|
|
21
|
+
const original = await fs.readFile(file).catch((error) => {
|
|
22
|
+
if (error.code !== "ENOENT") throw error;
|
|
23
|
+
});
|
|
24
|
+
let failure;
|
|
25
|
+
let failed = false;
|
|
26
|
+
try {
|
|
27
|
+
await run();
|
|
28
|
+
} catch (error) {
|
|
29
|
+
failure = error;
|
|
30
|
+
failed = true;
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
if (original) {
|
|
34
|
+
if (!(await fs.readFile(file).catch((error) => {
|
|
35
|
+
if (error.code !== "ENOENT") throw error;
|
|
36
|
+
}))?.equals(original)) await fs.writeFile(file, original);
|
|
37
|
+
} else await fs.rm(file, { force: true });
|
|
38
|
+
} catch (error) {
|
|
39
|
+
if (failed) throw new AggregateError([failure, error], "Official import failed and fixture config restoration did not complete");
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
if (failed) throw failure;
|
|
43
|
+
}
|
|
44
|
+
/** 先完成官方项目导入,再启动受管窗口;导入不编译、不导航,也不修改私有能力记录。 */
|
|
45
|
+
async function importManagedDevtoolsProject(options) {
|
|
46
|
+
if (!options.trusted || !process.env["WEAPP_IDE_MANAGED_PROJECT_JOURNAL"]) return;
|
|
47
|
+
options.signal.throwIfAborted();
|
|
48
|
+
const projectPath = path.resolve(options.projectPath);
|
|
49
|
+
await withMachineE2ELease(() => preserveProjectConfig(projectPath, "project.config.json", () => preserveProjectConfig(projectPath, "project.private.config.json", async () => {
|
|
50
|
+
options.signal.throwIfAborted();
|
|
51
|
+
const { stdout } = await execa(resolveProjectImportCli(options.cliPath), [
|
|
52
|
+
"-c",
|
|
53
|
+
"weapp-vite-e2e",
|
|
54
|
+
"project_import",
|
|
55
|
+
"--project",
|
|
56
|
+
projectPath
|
|
57
|
+
], {
|
|
58
|
+
timeout: options.timeout,
|
|
59
|
+
cancelSignal: options.signal,
|
|
60
|
+
killDescendants: false
|
|
61
|
+
});
|
|
62
|
+
const payload = JSON.parse(stdout);
|
|
63
|
+
const result = isRecord(payload) && isRecord(payload.result) ? payload.result : void 0;
|
|
64
|
+
if (!isRecord(payload) || payload.ok !== true || payload.tool !== "project_import" || payload.clientName !== "weapp-vite-e2e" || result?.success !== true || result.projectPath !== projectPath || typeof result.alreadyImported !== "boolean" || result.taskId !== void 0 || result.status !== void 0 || result.error !== void 0) throw new Error("DEVTOOLS_PROJECT_IMPORT_INCOMPLETE: 官方项目导入未完成;请检查本地 weapp-vite-e2e 客户端授权与导入结果,未启动项目窗口。");
|
|
65
|
+
options.signal.throwIfAborted();
|
|
66
|
+
})));
|
|
67
|
+
}
|
|
68
|
+
//#endregion
|
|
69
|
+
//#region src/cli/automator/managed.ts
|
|
70
|
+
/** 受管启动持有完整窗口回执,失败清理不受启动 deadline 的短暂宽限限制。 */
|
|
71
|
+
async function launchManagedAutomator(options) {
|
|
72
|
+
const { launcher, scope, target, projectPath, sourceProjectPath, port } = options;
|
|
73
|
+
await scope.step(() => importManagedDevtoolsProject({
|
|
74
|
+
cliPath: target.cliPath,
|
|
75
|
+
projectPath,
|
|
76
|
+
trusted: options.trustProject,
|
|
77
|
+
timeout: scope.remainingMs(),
|
|
78
|
+
signal: scope.signal
|
|
79
|
+
}), { stage: "project-import" });
|
|
80
|
+
scope.throwIfAborted();
|
|
81
|
+
const portLease = await scope.step(() => acquireAutomatorPortLease(port), {
|
|
82
|
+
stage: "port-lease",
|
|
83
|
+
disposeLate: (lease) => lease.release()
|
|
84
|
+
});
|
|
85
|
+
const rawReleasePortLease = portLease.release.bind(portLease);
|
|
86
|
+
let releasedPortLease;
|
|
87
|
+
portLease.release = () => releasedPortLease ??= rawReleasePortLease();
|
|
88
|
+
const disownPortLease = scope.own(() => portLease.release(), "automator-port-lease");
|
|
89
|
+
let releasePortLeaseOnExit = true;
|
|
90
|
+
let intent;
|
|
91
|
+
let program;
|
|
92
|
+
try {
|
|
93
|
+
intent = await beginManagedWechatProject({
|
|
94
|
+
target,
|
|
95
|
+
projectPath,
|
|
96
|
+
port
|
|
97
|
+
});
|
|
98
|
+
if (!intent) throw new Error("DEVTOOLS_MANAGED_PROJECT_JOURNAL_REQUIRED: managed launch requires a project ownership journal.");
|
|
99
|
+
scope.throwIfAborted();
|
|
100
|
+
await startWechatIdeAgent({
|
|
101
|
+
target,
|
|
102
|
+
projectPath,
|
|
103
|
+
port,
|
|
104
|
+
trustProject: options.trustProject,
|
|
105
|
+
signal: scope.signal,
|
|
106
|
+
timeout: scope.remainingMs(),
|
|
107
|
+
onStarted: async (result) => await intent.confirm({
|
|
108
|
+
openedProjectWindow: result.openedProjectWindow,
|
|
109
|
+
port: result.autoPort
|
|
110
|
+
})
|
|
111
|
+
});
|
|
112
|
+
scope.throwIfAborted();
|
|
113
|
+
await assertWechatDevtoolsPort(target, port, {
|
|
114
|
+
signal: scope.signal,
|
|
115
|
+
timeout: scope.remainingMs()
|
|
116
|
+
});
|
|
117
|
+
scope.throwIfAborted();
|
|
118
|
+
const wsEndpoint = `ws://127.0.0.1:${port}`;
|
|
119
|
+
program = await launcher.connect({
|
|
120
|
+
wsEndpoint,
|
|
121
|
+
signal: scope.signal,
|
|
122
|
+
timeout: scope.remainingMs()
|
|
123
|
+
});
|
|
124
|
+
scope.throwIfAborted();
|
|
125
|
+
await program.waitForAppReady(scope.remainingMs());
|
|
126
|
+
scope.throwIfAborted();
|
|
127
|
+
Reflect.set(program, "__WEAPP_VITE_SESSION_METADATA", {
|
|
128
|
+
port,
|
|
129
|
+
projectPath,
|
|
130
|
+
wsEndpoint,
|
|
131
|
+
managedProject: {
|
|
132
|
+
id: intent.id,
|
|
133
|
+
journalPath: intent.journalPath
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
await persistAutomatorSession({
|
|
137
|
+
installationId: target.installationId,
|
|
138
|
+
signal: scope.signal,
|
|
139
|
+
port,
|
|
140
|
+
projectPath: sourceProjectPath,
|
|
141
|
+
sessionId: options.sessionId,
|
|
142
|
+
wsEndpoint
|
|
143
|
+
});
|
|
144
|
+
scope.throwIfAborted();
|
|
145
|
+
if (options.persistAsDefaultSession) {
|
|
146
|
+
await persistAutomatorSession({
|
|
147
|
+
installationId: target.installationId,
|
|
148
|
+
signal: scope.signal,
|
|
149
|
+
projectPath: sourceProjectPath,
|
|
150
|
+
wsEndpoint
|
|
151
|
+
});
|
|
152
|
+
scope.throwIfAborted();
|
|
153
|
+
}
|
|
154
|
+
const connectedProgram = program;
|
|
155
|
+
const ownedIntent = intent;
|
|
156
|
+
const rawDisconnect = connectedProgram.disconnect.bind(connectedProgram);
|
|
157
|
+
connectedProgram.disconnect = (...args) => {
|
|
158
|
+
try {
|
|
159
|
+
return rawDisconnect(...args);
|
|
160
|
+
} finally {
|
|
161
|
+
portLease.release();
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
let closing;
|
|
165
|
+
connectedProgram.close = async () => {
|
|
166
|
+
closing ??= (async () => {
|
|
167
|
+
try {
|
|
168
|
+
connectedProgram.disconnect();
|
|
169
|
+
} finally {
|
|
170
|
+
try {
|
|
171
|
+
await ownedIntent.close();
|
|
172
|
+
} finally {
|
|
173
|
+
await portLease.release();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
})().finally(() => {
|
|
177
|
+
closing = void 0;
|
|
178
|
+
});
|
|
179
|
+
return await closing;
|
|
180
|
+
};
|
|
181
|
+
releasePortLeaseOnExit = false;
|
|
182
|
+
disownPortLease();
|
|
183
|
+
return connectedProgram;
|
|
184
|
+
} catch (error) {
|
|
185
|
+
const errors = [error];
|
|
186
|
+
try {
|
|
187
|
+
program?.disconnect();
|
|
188
|
+
} catch (disconnectError) {
|
|
189
|
+
errors.push(disconnectError);
|
|
190
|
+
}
|
|
191
|
+
if (intent) {
|
|
192
|
+
try {
|
|
193
|
+
await intent.fail(error);
|
|
194
|
+
} catch (recordError) {
|
|
195
|
+
errors.push(recordError);
|
|
196
|
+
}
|
|
197
|
+
try {
|
|
198
|
+
await intent.close();
|
|
199
|
+
} catch (closeError) {
|
|
200
|
+
errors.push(closeError);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
if (releasePortLeaseOnExit) {
|
|
204
|
+
disownPortLease();
|
|
205
|
+
await portLease.release().catch((releaseError) => errors.push(releaseError));
|
|
206
|
+
}
|
|
207
|
+
if (errors.length > 1) throw new AggregateError(errors, "Managed DevTools launch failed and project cleanup did not complete.", { cause: error });
|
|
208
|
+
throw error;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
//#endregion
|
|
212
|
+
export { launchManagedAutomator };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { t as runMcpCommand } from "./run-mcp-Dl_1TH1x.js";
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import { c as withMiniProgram$1 } from "./automator-session-
|
|
2
|
-
import { Buffer } from "node:buffer";
|
|
3
|
-
import fs from "node:fs/promises";
|
|
1
|
+
import { c as withMiniProgram$1 } from "./automator-session-gWEsSs_A.js";
|
|
4
2
|
import path from "node:path";
|
|
5
|
-
import process from "node:process";
|
|
6
3
|
import { readDevtoolsElementSnapshot as readElementSnapshot, resolveDevtoolsProjectPath as resolveProjectPath, toDevtoolsSerializableValue as toSerializableValue } from "@weapp-vite/devtools-runtime";
|
|
7
|
-
import
|
|
8
|
-
import
|
|
4
|
+
import fs from "node:fs/promises";
|
|
5
|
+
import process from "node:process";
|
|
6
|
+
import { Buffer } from "node:buffer";
|
|
9
7
|
import { z } from "zod";
|
|
10
8
|
//#region src/mcp/server.ts
|
|
11
9
|
function createResolvedProjectPath(workspaceRoot, projectPath) {
|
|
@@ -16,6 +14,7 @@ function createResolvedOutputPath(workspaceRoot, outputPath) {
|
|
|
16
14
|
}
|
|
17
15
|
async function withConnectedMiniProgram(runtimeHooks, workspaceRoot, input, runner) {
|
|
18
16
|
return await runtimeHooks.withMiniProgram({
|
|
17
|
+
cliPath: input.cliPath,
|
|
19
18
|
preferOpenedSession: input.preferOpenedSession,
|
|
20
19
|
port: input.port,
|
|
21
20
|
projectPath: createResolvedProjectPath(workspaceRoot, input.projectPath),
|
|
@@ -31,9 +30,10 @@ async function withConnectedPage(runtimeHooks, workspaceRoot, input, runner) {
|
|
|
31
30
|
}
|
|
32
31
|
function defineConnectionSchema() {
|
|
33
32
|
return {
|
|
33
|
+
cliPath: z.string().trim().min(1).optional().describe("指定微信开发者工具 CLI 安装路径"),
|
|
34
34
|
projectPath: z.string().trim().min(1).describe("小程序项目路径,支持 workspaceRoot 相对路径"),
|
|
35
35
|
timeout: z.number().int().positive().optional(),
|
|
36
|
-
port: z.number().int().positive().optional(),
|
|
36
|
+
port: z.number().int().positive().max(65535).optional(),
|
|
37
37
|
preferOpenedSession: z.boolean().optional(),
|
|
38
38
|
sessionId: z.string().trim().min(1).optional()
|
|
39
39
|
};
|
|
@@ -367,6 +367,7 @@ function registerWeappIdeMcpTools(server, options) {
|
|
|
367
367
|
});
|
|
368
368
|
}
|
|
369
369
|
async function createWeappIdeMcpServer(options) {
|
|
370
|
+
const { McpServer } = await import("@modelcontextprotocol/server");
|
|
370
371
|
const server = new McpServer({
|
|
371
372
|
name: "weapp-ide-cli",
|
|
372
373
|
version: "1.0.0"
|
|
@@ -380,8 +381,12 @@ async function createWeappIdeMcpServer(options) {
|
|
|
380
381
|
//#endregion
|
|
381
382
|
//#region src/mcp/runtime.ts
|
|
382
383
|
async function startWeappIdeMcpServer(options = {}) {
|
|
384
|
+
const { serveStdio } = await import("@modelcontextprotocol/server/stdio");
|
|
383
385
|
const serverOptions = {
|
|
384
|
-
runtimeHooks: { withMiniProgram: withMiniProgram$1
|
|
386
|
+
runtimeHooks: { withMiniProgram: (input, runner) => withMiniProgram$1({
|
|
387
|
+
...input,
|
|
388
|
+
cliPath: input.cliPath ?? options.cliPath
|
|
389
|
+
}, runner) },
|
|
385
390
|
workspaceRoot: options.workspaceRoot
|
|
386
391
|
};
|
|
387
392
|
const handle = serveStdio(async () => {
|
|
@@ -415,6 +420,7 @@ function printMcpHelp() {
|
|
|
415
420
|
Start the weapp-ide-cli MCP server over stdio.
|
|
416
421
|
|
|
417
422
|
Options:
|
|
423
|
+
--cli-path <path> Select the WeChat DevTools installation
|
|
418
424
|
--workspace-root <path> Resolve relative project/output paths from this root
|
|
419
425
|
-h, --help Show this help
|
|
420
426
|
|
|
@@ -434,7 +440,10 @@ async function runMcpCommand(argv) {
|
|
|
434
440
|
printMcpHelp();
|
|
435
441
|
return;
|
|
436
442
|
}
|
|
437
|
-
await startWeappIdeMcpServer({
|
|
443
|
+
await startWeappIdeMcpServer({
|
|
444
|
+
cliPath: readOptionValue(argv, "--cli-path"),
|
|
445
|
+
workspaceRoot: readOptionValue(argv, "--workspace-root")
|
|
446
|
+
});
|
|
438
447
|
}
|
|
439
448
|
//#endregion
|
|
440
449
|
export { readElementSnapshot as a, registerWeappIdeMcpTools as i, startWeappIdeMcpServer as n, resolveProjectPath as o, createWeappIdeMcpServer as r, toSerializableValue as s, runMcpCommand as t };
|