weapp-vite 6.14.0 → 6.14.1

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 CHANGED
@@ -209,7 +209,21 @@ wv ide preview --project ./dist/build/mp-weixin
209
209
  `weapp-vite` 已集成 `@weapp-vite/mcp`:
210
210
 
211
211
  - 默认不自动启动 MCP 服务(可通过配置开启自动启动)
212
- - 也可以手动启动 MCP Server
212
+ - 优先推荐直接生成客户端配置,而不是手写 MCP 地址
213
+
214
+ ```sh
215
+ wv mcp init codex
216
+ wv mcp init claude-code
217
+ wv mcp init cursor
218
+ ```
219
+
220
+ 检查配置是否可用:
221
+
222
+ ```sh
223
+ wv mcp doctor codex
224
+ ```
225
+
226
+ 仍然需要手动启动 MCP Server 时:
213
227
 
214
228
  ```sh
215
229
  weapp-vite mcp
@@ -1,4 +1,4 @@
1
- import { i as getCompilerContext, u as getRouteRuntimeGlobalKeys } from "./createContext-BolxgJjC.mjs";
1
+ import { i as getCompilerContext, u as getRouteRuntimeGlobalKeys } from "./createContext-DT4tLA1C.mjs";
2
2
  //#region src/auto-routes.ts
3
3
  const ROUTE_RUNTIME_OVERRIDE_KEY = Symbol.for("weapp-vite.route-runtime");
4
4
  function createGetter(resolver) {
package/dist/cli.mjs CHANGED
@@ -1,6 +1,6 @@
1
- import { S as isPathInside, _ as DEFAULT_MP_PLATFORM, b as resolveMiniPlatform, c as createSharedBuildConfig, d as resolveWeappConfigFile, f as checkRuntime, g as createCjsConfigLoadError, h as parseCommentJson, l as SHARED_CHUNK_VIRTUAL_PREFIX, m as loadViteConfigFile, n as syncProjectSupportFiles, p as getProjectConfigFileName, r as syncManagedTsconfigBootstrapFiles, s as formatBytes, t as createCompilerContext, v as getDefaultIdeProjectRoot, x as shouldPassPlatformArgToIdeOpen, y as normalizeMiniPlatform } from "./createContext-BolxgJjC.mjs";
1
+ import { S as isPathInside, _ as DEFAULT_MP_PLATFORM, b as resolveMiniPlatform, c as createSharedBuildConfig, d as resolveWeappConfigFile, f as checkRuntime, g as createCjsConfigLoadError, h as parseCommentJson, l as SHARED_CHUNK_VIRTUAL_PREFIX, m as loadViteConfigFile, n as syncProjectSupportFiles, p as getProjectConfigFileName, r as syncManagedTsconfigBootstrapFiles, s as formatBytes, t as createCompilerContext, v as getDefaultIdeProjectRoot, x as shouldPassPlatformArgToIdeOpen, y as normalizeMiniPlatform } from "./createContext-DT4tLA1C.mjs";
2
2
  import { r as logger_default, t as colors } from "./logger-CgxdNjvb.mjs";
3
- import { m as VERSION } from "./file-Ej-4GoYg.mjs";
3
+ import { m as VERSION } from "./file-BkvmW6_2.mjs";
4
4
  import { a as resolveWeappMcpConfig, o as startWeappViteMcpServer } from "./mcp-DRlj32v4.mjs";
5
5
  import { createRequire } from "node:module";
6
6
  import { defu, fs } from "@weapp-core/shared";
@@ -8,6 +8,7 @@ import path, { posix } from "pathe";
8
8
  import process from "node:process";
9
9
  import fs$1 from "node:fs/promises";
10
10
  import { build, createServer } from "vite";
11
+ import os from "node:os";
11
12
  import { execFile } from "node:child_process";
12
13
  import { Buffer } from "node:buffer";
13
14
  import fs$2 from "node:fs";
@@ -18,6 +19,8 @@ import { closeSharedMiniProgram, connectOpenedAutomator, formatRetryHotkeyPrompt
18
19
  import { generateJs, generateJson, generateWxml, generateWxss } from "@weapp-core/schematics";
19
20
  import { determineAgent } from "@vercel/detect-agent";
20
21
  import { initConfig } from "@weapp-core/init";
22
+ import { createInterface } from "node:readline/promises";
23
+ import { clearTimeout, setTimeout as setTimeout$1 } from "node:timers";
21
24
  import { emitKeypressEvents } from "node:readline";
22
25
  //#region src/analyze/subpackages/classifier.ts
23
26
  const VIRTUAL_MODULE_INDICATOR = "\0";
@@ -1133,7 +1136,9 @@ function registerBuildCommand(cli) {
1133
1136
  configFile,
1134
1137
  inlineConfig,
1135
1138
  cliPlatform: targets.rawPlatform,
1136
- projectConfigPath: options.projectConfig
1139
+ projectConfigPath: options.projectConfig,
1140
+ syncSupportFiles: false,
1141
+ preloadAppEntry: false
1137
1142
  });
1138
1143
  const { buildService, configService, webService } = ctx;
1139
1144
  logRuntimeTarget(targets, { resolvedConfigPlatform: configService.platform });
@@ -1604,6 +1609,278 @@ function registerInitCommand(cli) {
1604
1609
  });
1605
1610
  }
1606
1611
  //#endregion
1612
+ //#region src/cli/mcpClient.ts
1613
+ const CODEX_BLOCK_PREFIX = "# >>> weapp-vite mcp ";
1614
+ const CODEX_BLOCK_SUFFIX = " >>>";
1615
+ const CODEX_BLOCK_END_PREFIX = "# <<< weapp-vite mcp ";
1616
+ const CODEX_BLOCK_END_SUFFIX = " <<<";
1617
+ const DEFAULT_HTTP_TIMEOUT_MS = 1500;
1618
+ const WORKSPACE_FOLDER_TOKEN = "${workspaceFolder}";
1619
+ const REG_CodexUrl = /^\s*url\s*=\s*"([^"]+)"/m;
1620
+ const REG_CodexCommand = /^\s*command\s*=\s*"([^"]+)"/m;
1621
+ const REG_CodexArgs = /^\s*args\s*=\s*\[([^\]]*)\]/m;
1622
+ const REG_FirstTomlString = /"([^"]+)"/;
1623
+ function resolveTargetWorkspaceRoot(target) {
1624
+ if (target.client === "cursor") return path.dirname(path.dirname(target.configPath));
1625
+ if (target.client === "claude-code") return path.dirname(target.configPath);
1626
+ return process.cwd();
1627
+ }
1628
+ function escapeRegExp(value) {
1629
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1630
+ }
1631
+ function renderTomlString(value) {
1632
+ return JSON.stringify(value);
1633
+ }
1634
+ function sanitizeServerNameSegment(value) {
1635
+ return value.trim().toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/-{2,}/g, "-").replace(/^-|-$/g, "");
1636
+ }
1637
+ function resolveServerName(workspaceRoot) {
1638
+ return `weapp-vite-${sanitizeServerNameSegment(path.basename(workspaceRoot)) || "project"}`;
1639
+ }
1640
+ function resolveNodeBinCommand() {
1641
+ return process.execPath || "node";
1642
+ }
1643
+ function resolveProjectCliBin(workspaceRoot) {
1644
+ return path.join(workspaceRoot, "node_modules", "weapp-vite", "bin", "weapp-vite.js");
1645
+ }
1646
+ function renderCommandArgs(args) {
1647
+ return args.map(renderTomlString).join(", ");
1648
+ }
1649
+ function renderCodexBlock(serverName, entry) {
1650
+ const startMarker = `${CODEX_BLOCK_PREFIX}${serverName}${CODEX_BLOCK_SUFFIX}`;
1651
+ const endMarker = `${CODEX_BLOCK_END_PREFIX}${serverName}${CODEX_BLOCK_END_SUFFIX}`;
1652
+ if (entry.url) return `${startMarker}
1653
+ [mcp_servers.${serverName}]
1654
+ url = ${renderTomlString(entry.url)}
1655
+ ${endMarker}
1656
+ `;
1657
+ return `${startMarker}
1658
+ [mcp_servers.${serverName}]
1659
+ command = ${renderTomlString(entry.command ?? resolveNodeBinCommand())}
1660
+ args = [${renderCommandArgs(entry.args ?? [])}]
1661
+ ${endMarker}
1662
+ `;
1663
+ }
1664
+ function renderJsonPreview(serverName, entry) {
1665
+ return `${JSON.stringify({ mcpServers: { [serverName]: entry } }, null, 2)}
1666
+ `;
1667
+ }
1668
+ function resolveCommandEntry(client, workspaceRoot) {
1669
+ const binPath = resolveProjectCliBin(workspaceRoot);
1670
+ if (client === "cursor") return {
1671
+ command: "node",
1672
+ args: [
1673
+ `${WORKSPACE_FOLDER_TOKEN}/node_modules/weapp-vite/bin/weapp-vite.js`,
1674
+ "mcp",
1675
+ "--workspace-root",
1676
+ WORKSPACE_FOLDER_TOKEN
1677
+ ]
1678
+ };
1679
+ return {
1680
+ command: resolveNodeBinCommand(),
1681
+ args: [
1682
+ binPath,
1683
+ "mcp",
1684
+ "--workspace-root",
1685
+ workspaceRoot
1686
+ ]
1687
+ };
1688
+ }
1689
+ function resolveHttpEntry(client, url) {
1690
+ if (client === "claude-code") return {
1691
+ type: "http",
1692
+ url
1693
+ };
1694
+ return { url };
1695
+ }
1696
+ function resolveCodexBlockPattern(serverName) {
1697
+ const startMarker = `${CODEX_BLOCK_PREFIX}${serverName}${CODEX_BLOCK_SUFFIX}`;
1698
+ const endMarker = `${CODEX_BLOCK_END_PREFIX}${serverName}${CODEX_BLOCK_END_SUFFIX}`;
1699
+ return new RegExp(`${escapeRegExp(startMarker)}[\\s\\S]*?${escapeRegExp(endMarker)}\\n?`, "g");
1700
+ }
1701
+ function upsertCodexManagedBlock(content, serverName, block) {
1702
+ const withoutExisting = content.trimEnd().replace(resolveCodexBlockPattern(serverName), "").trimEnd();
1703
+ if (!withoutExisting) return block;
1704
+ return `${withoutExisting}\n\n${block}`;
1705
+ }
1706
+ function parseJsonConfig(content, configPath) {
1707
+ if (!content.trim()) return {};
1708
+ try {
1709
+ return JSON.parse(content);
1710
+ } catch (error) {
1711
+ const message = error instanceof Error ? error.message : String(error);
1712
+ throw new Error(`无法解析 MCP 配置文件 ${configPath}:${message}`);
1713
+ }
1714
+ }
1715
+ function resolveTarget(client, workspaceRoot) {
1716
+ const serverName = resolveServerName(workspaceRoot);
1717
+ if (client === "codex") return {
1718
+ client,
1719
+ configPath: path.join(os.homedir(), ".codex", "config.toml"),
1720
+ displayName: "Codex",
1721
+ serverName
1722
+ };
1723
+ if (client === "claude-code") return {
1724
+ client,
1725
+ configPath: path.join(workspaceRoot, ".mcp.json"),
1726
+ displayName: "Claude Code",
1727
+ serverName
1728
+ };
1729
+ return {
1730
+ client,
1731
+ configPath: path.join(workspaceRoot, ".cursor", "mcp.json"),
1732
+ displayName: "Cursor",
1733
+ serverName
1734
+ };
1735
+ }
1736
+ function resolveSupportedMcpClient(input) {
1737
+ if (input === "codex" || input === "claude-code" || input === "cursor") return input;
1738
+ throw new Error(`不支持的 MCP 客户端:${input}。当前仅支持 codex、claude-code、cursor。`);
1739
+ }
1740
+ function buildMcpClientConfigPlan(options) {
1741
+ const workspaceRoot = path.resolve(options.workspaceRoot);
1742
+ const target = resolveTarget(options.client, workspaceRoot);
1743
+ const entry = options.transport === "http" ? resolveHttpEntry(options.client, options.url ?? "") : resolveCommandEntry(options.client, workspaceRoot);
1744
+ if (options.transport === "http" && !entry.url) throw new Error("HTTP 模式缺少 MCP 服务地址,请使用 --url 指定或在当前项目中检测到可用地址。");
1745
+ return {
1746
+ entry,
1747
+ preview: target.client === "codex" ? renderCodexBlock(target.serverName, entry) : renderJsonPreview(target.serverName, entry),
1748
+ target,
1749
+ transport: options.transport
1750
+ };
1751
+ }
1752
+ async function writeMcpClientConfig(plan) {
1753
+ await fs.ensureDir(path.dirname(plan.target.configPath));
1754
+ const existing = await fs.readFile(plan.target.configPath, "utf8").catch(() => "");
1755
+ if (plan.target.client === "codex") {
1756
+ const nextContent = upsertCodexManagedBlock(existing, plan.target.serverName, plan.preview);
1757
+ await fs.writeFile(plan.target.configPath, nextContent, "utf8");
1758
+ return;
1759
+ }
1760
+ const parsed = parseJsonConfig(existing, plan.target.configPath);
1761
+ const nextConfig = {
1762
+ ...parsed,
1763
+ mcpServers: {
1764
+ ...parsed.mcpServers ?? {},
1765
+ [plan.target.serverName]: plan.entry
1766
+ }
1767
+ };
1768
+ await fs.writeFile(plan.target.configPath, `${JSON.stringify(nextConfig, null, 2)}\n`, "utf8");
1769
+ }
1770
+ async function probeHttpEndpoint(url) {
1771
+ const controller = new AbortController();
1772
+ const timer = setTimeout$1(() => {
1773
+ controller.abort();
1774
+ }, DEFAULT_HTTP_TIMEOUT_MS);
1775
+ try {
1776
+ return (await fetch(url, {
1777
+ method: "GET",
1778
+ signal: controller.signal
1779
+ })).status > 0;
1780
+ } catch {
1781
+ return false;
1782
+ } finally {
1783
+ clearTimeout(timer);
1784
+ controller.abort();
1785
+ }
1786
+ }
1787
+ async function inspectJsonConfig(target) {
1788
+ if (!await fs.pathExists(target.configPath)) return {
1789
+ configExists: false,
1790
+ configPath: target.configPath,
1791
+ displayName: target.displayName,
1792
+ issues: [`未找到配置文件:${target.configPath}`],
1793
+ serverName: target.serverName
1794
+ };
1795
+ const entry = parseJsonConfig(await fs.readFile(target.configPath, "utf8"), target.configPath).mcpServers?.[target.serverName];
1796
+ if (!entry) return {
1797
+ configExists: true,
1798
+ configPath: target.configPath,
1799
+ displayName: target.displayName,
1800
+ issues: [`配置文件中未找到服务器 ${target.serverName}`],
1801
+ serverName: target.serverName
1802
+ };
1803
+ const transport = entry.url ? "http" : "command";
1804
+ const issues = [];
1805
+ let httpReachable;
1806
+ if (transport === "command") {
1807
+ const normalizedBin = (entry.args?.[0])?.replaceAll(WORKSPACE_FOLDER_TOKEN, resolveTargetWorkspaceRoot(target));
1808
+ if (!normalizedBin || !await fs.pathExists(normalizedBin)) issues.push(`未找到本地 CLI 入口:${normalizedBin ?? "缺少 args[0]"}`);
1809
+ } else if (entry.url) {
1810
+ httpReachable = await probeHttpEndpoint(entry.url);
1811
+ if (!httpReachable) issues.push(`HTTP MCP 地址不可达:${entry.url}`);
1812
+ }
1813
+ return {
1814
+ configExists: true,
1815
+ configPath: target.configPath,
1816
+ displayName: target.displayName,
1817
+ httpReachable,
1818
+ issues,
1819
+ serverName: target.serverName,
1820
+ transport
1821
+ };
1822
+ }
1823
+ async function inspectCodexConfig(target) {
1824
+ if (!await fs.pathExists(target.configPath)) return {
1825
+ configExists: false,
1826
+ configPath: target.configPath,
1827
+ displayName: target.displayName,
1828
+ issues: [`未找到配置文件:${target.configPath}`],
1829
+ serverName: target.serverName
1830
+ };
1831
+ const blockMatch = (await fs.readFile(target.configPath, "utf8")).match(resolveCodexBlockPattern(target.serverName));
1832
+ if (!blockMatch?.[0]) return {
1833
+ configExists: true,
1834
+ configPath: target.configPath,
1835
+ displayName: target.displayName,
1836
+ issues: [`未找到 weapp-vite 生成的 Codex 配置区块:${target.serverName}`],
1837
+ serverName: target.serverName
1838
+ };
1839
+ const block = blockMatch[0];
1840
+ const issues = [];
1841
+ const urlMatch = block.match(REG_CodexUrl);
1842
+ const commandMatch = block.match(REG_CodexCommand);
1843
+ const argsMatch = block.match(REG_CodexArgs);
1844
+ if (urlMatch?.[1]) {
1845
+ const reachable = await probeHttpEndpoint(urlMatch[1]);
1846
+ if (!reachable) issues.push(`HTTP MCP 地址不可达:${urlMatch[1]}`);
1847
+ return {
1848
+ configExists: true,
1849
+ configPath: target.configPath,
1850
+ displayName: target.displayName,
1851
+ httpReachable: reachable,
1852
+ issues,
1853
+ serverName: target.serverName,
1854
+ transport: "http"
1855
+ };
1856
+ }
1857
+ const binPath = (argsMatch?.[1]?.match(REG_FirstTomlString))?.[1];
1858
+ if (!commandMatch?.[1]) issues.push("Codex 配置区块缺少 command 字段");
1859
+ if (!binPath || !await fs.pathExists(binPath)) issues.push(`未找到本地 CLI 入口:${binPath ?? "缺少 args[0]"}`);
1860
+ return {
1861
+ configExists: true,
1862
+ configPath: target.configPath,
1863
+ displayName: target.displayName,
1864
+ issues,
1865
+ serverName: target.serverName,
1866
+ transport: "command"
1867
+ };
1868
+ }
1869
+ async function inspectMcpClientConfig(options) {
1870
+ const target = resolveTarget(options.client, path.resolve(options.workspaceRoot));
1871
+ if (target.client === "codex") return await inspectCodexConfig(target);
1872
+ return await inspectJsonConfig(target);
1873
+ }
1874
+ function formatMcpQuickStart(options) {
1875
+ const suffix = options.transport === "http" && options.httpUrl ? ` --transport http --url ${options.httpUrl}` : "";
1876
+ return [
1877
+ "在 AI 工具中接入 weapp-vite MCP:",
1878
+ ` - Codex: wv mcp init codex${suffix}`,
1879
+ ` - Claude Code: wv mcp init claude-code${suffix}`,
1880
+ ` - Cursor: wv mcp init cursor${suffix}`
1881
+ ];
1882
+ }
1883
+ //#endregion
1607
1884
  //#region src/cli/commands/mcp.ts
1608
1885
  function resolvePort(port) {
1609
1886
  if (typeof port === "number" && Number.isInteger(port)) return port;
@@ -1612,17 +1889,109 @@ function resolvePort(port) {
1612
1889
  if (Number.isInteger(parsed)) return parsed;
1613
1890
  }
1614
1891
  }
1892
+ async function resolveHttpUrl(options) {
1893
+ if (options.url?.trim()) return options.url.trim();
1894
+ const workspaceRoot = options.workspaceRoot ? path.resolve(options.workspaceRoot) : process.cwd();
1895
+ const originalCwd = process.cwd();
1896
+ try {
1897
+ if (workspaceRoot !== originalCwd) process.chdir(workspaceRoot);
1898
+ const resolved = resolveWeappMcpConfig((await loadConfig(resolveConfigFile(options)))?.config?.weapp?.mcp);
1899
+ return `http://${resolved.host}:${resolved.port}${resolved.endpoint}`;
1900
+ } catch {
1901
+ const resolved = resolveWeappMcpConfig(void 0);
1902
+ return `http://${resolved.host}:${resolved.port}${resolved.endpoint}`;
1903
+ } finally {
1904
+ if (process.cwd() !== originalCwd) process.chdir(originalCwd);
1905
+ }
1906
+ }
1907
+ async function confirmWrite() {
1908
+ if (!process.stdin.isTTY || !process.stdout.isTTY) return false;
1909
+ const rl = createInterface({
1910
+ input: process.stdin,
1911
+ output: process.stdout
1912
+ });
1913
+ try {
1914
+ const normalized = (await rl.question("是否写入配置文件?(Y/n) ")).trim().toLowerCase();
1915
+ return normalized === "" || normalized === "y" || normalized === "yes";
1916
+ } finally {
1917
+ rl.close();
1918
+ }
1919
+ }
1920
+ function resolveClientTransport(transport) {
1921
+ return transport === "http" ? "http" : "command";
1922
+ }
1923
+ async function handlePrint(clientName, options, write = false) {
1924
+ const client = resolveSupportedMcpClient(clientName);
1925
+ const workspaceRoot = options.workspaceRoot ?? process.cwd();
1926
+ const transport = resolveClientTransport(options.transport);
1927
+ const plan = buildMcpClientConfigPlan({
1928
+ client,
1929
+ transport,
1930
+ url: transport === "http" ? await resolveHttpUrl(options) : void 0,
1931
+ workspaceRoot
1932
+ });
1933
+ logger_default.info(`${plan.target.displayName} 配置文件:${plan.target.configPath}`);
1934
+ logger_default.info(`服务器名称:${plan.target.serverName}`);
1935
+ process.stdout.write(`${plan.preview}\n`);
1936
+ if (!write) return;
1937
+ if (options.yes || await confirmWrite()) {
1938
+ await writeMcpClientConfig(plan);
1939
+ logger_default.success(`已写入 ${plan.target.displayName} MCP 配置。`);
1940
+ logger_default.info(`请重启 ${plan.target.displayName},然后执行:wv mcp doctor ${client}`);
1941
+ return;
1942
+ }
1943
+ logger_default.info("已取消写入。");
1944
+ }
1945
+ async function handleDoctor(clientName, options) {
1946
+ const result = await inspectMcpClientConfig({
1947
+ client: resolveSupportedMcpClient(clientName),
1948
+ workspaceRoot: options.workspaceRoot ?? process.cwd()
1949
+ });
1950
+ logger_default.info(`${result.displayName} 配置文件:${result.configPath}`);
1951
+ logger_default.info(`服务器名称:${result.serverName}`);
1952
+ if (!result.configExists || result.issues.length > 0) {
1953
+ for (const issue of result.issues) logger_default.warn(issue);
1954
+ throw new Error("MCP 客户端配置检查未通过。");
1955
+ }
1956
+ if (result.transport) logger_default.info(`传输模式:${result.transport}`);
1957
+ if (result.httpReachable !== void 0) logger_default.info(`HTTP 服务可达:${result.httpReachable ? "是" : "否"}`);
1958
+ logger_default.success("MCP 客户端配置检查通过。");
1959
+ }
1960
+ async function handleServer(options) {
1961
+ const resolvedTransport = options.transport === "http" ? "streamable-http" : options.transport;
1962
+ await startWeappViteMcpServer({
1963
+ endpoint: options.endpoint,
1964
+ host: options.host,
1965
+ port: resolvePort(options.port),
1966
+ transport: resolvedTransport,
1967
+ unref: options.unref,
1968
+ workspaceRoot: options.workspaceRoot
1969
+ });
1970
+ for (const line of formatMcpQuickStart({
1971
+ httpUrl: resolvedTransport === "streamable-http" ? `http://${options.host ?? "127.0.0.1"}:${resolvePort(options.port) ?? 3088}${options.endpoint ?? "/mcp"}` : void 0,
1972
+ transport: resolvedTransport === "streamable-http" ? "http" : "command"
1973
+ })) logger_default.info(line);
1974
+ }
1615
1975
  function registerMcpCommand(cli) {
1616
- cli.command("mcp", "start weapp-vite MCP server").option("--transport <type>", "[string] stdio | streamable-http", { default: "stdio" }).option("--host <host>", "[string] streamable-http host").option("--port <port>", "[number] streamable-http port").option("--endpoint <path>", "[string] streamable-http endpoint path").option("--unref", "[boolean] unref HTTP server to not block process exit").option("--workspace-root <path>", "[string] workspace root path, defaults to auto detect from cwd").action(async (options) => {
1617
- const { startWeappViteMcpServer } = await import("./mcp.mjs");
1618
- await startWeappViteMcpServer({
1619
- endpoint: options.endpoint,
1620
- host: options.host,
1621
- port: resolvePort(options.port),
1622
- transport: options.transport,
1623
- unref: options.unref,
1624
- workspaceRoot: options.workspaceRoot
1625
- });
1976
+ cli.command("mcp [...args]", "start weapp-vite MCP server or manage MCP client onboarding").option("--transport <type>", "[string] stdio | streamable-http | command | http", { default: "stdio" }).option("--host <host>", "[string] streamable-http host").option("--port <port>", "[number] streamable-http port").option("--endpoint <path>", "[string] streamable-http endpoint path").option("--unref", "[boolean] unref HTTP server to not block process exit").option("--url <url>", "[string] explicit HTTP MCP url").option("--workspace-root <path>", "[string] workspace root path, defaults to cwd").option("-y, --yes", "[boolean] write config without prompt").action(async (args, options) => {
1977
+ const [subcommand, client] = args;
1978
+ if (subcommand === "init") {
1979
+ if (!client) throw new Error("缺少客户端名称,请使用:wv mcp init <codex|claude-code|cursor>");
1980
+ await handlePrint(client, options, true);
1981
+ return;
1982
+ }
1983
+ if (subcommand === "print") {
1984
+ if (!client) throw new Error("缺少客户端名称,请使用:wv mcp print <codex|claude-code|cursor>");
1985
+ await handlePrint(client, options, false);
1986
+ return;
1987
+ }
1988
+ if (subcommand === "doctor") {
1989
+ if (!client) throw new Error("缺少客户端名称,请使用:wv mcp doctor <codex|claude-code|cursor>");
1990
+ await handleDoctor(client, options);
1991
+ return;
1992
+ }
1993
+ if (subcommand) throw new Error(`未知的 mcp 子命令:${subcommand}`);
1994
+ await handleServer(options);
1626
1995
  });
1627
1996
  }
1628
1997
  //#endregion
@@ -1682,7 +2051,7 @@ function registerPrepareCommand(cli) {
1682
2051
  }
1683
2052
  //#endregion
1684
2053
  //#region package.json
1685
- var version = "6.14.0";
2054
+ var version = "6.14.1";
1686
2055
  //#endregion
1687
2056
  //#region src/cli/devHotkeys.ts
1688
2057
  const DEV_SCREENSHOT_DIR = ".tmp/weapp-vite-dev-screenshots";
@@ -1917,6 +2286,10 @@ function startDevHotkeys(options) {
1917
2286
  workspaceRoot: options.cwd
1918
2287
  });
1919
2288
  logger_default.success(`[dev action] MCP 服务已启动:${colors.cyan(url)}`);
2289
+ for (const line of formatMcpQuickStart({
2290
+ httpUrl: url,
2291
+ transport: "http"
2292
+ })) logger_default.info(line);
1920
2293
  return `MCP 已启动 (${url})`;
1921
2294
  };
1922
2295
  const runAction = (label, pendingLabel, action) => {
@@ -2467,6 +2840,10 @@ async function maybeAutoStartMcpServer(argv, cliOptions) {
2467
2840
  const mcpUrl = `http://${resolvedMcp.host}:${resolvedMcp.port}${resolvedMcp.endpoint}`;
2468
2841
  logger_default.success("MCP 服务已自动启动:");
2469
2842
  logger_default.info(` ➜ ${colors.cyan(mcpUrl)}`);
2843
+ for (const line of formatMcpQuickStart({
2844
+ httpUrl: mcpUrl,
2845
+ transport: "http"
2846
+ })) logger_default.info(line);
2470
2847
  } catch (error) {
2471
2848
  const message = error instanceof Error ? error.message : String(error);
2472
2849
  if (REG_EADDRINUSE.test(message)) {
@@ -413,7 +413,7 @@ interface WeappInjectWeapiConfig {
413
413
  replaceWx?: boolean;
414
414
  globalName?: string;
415
415
  }
416
- type WeappInjectRequestGlobalsTarget = 'fetch' | 'Headers' | 'Request' | 'Response' | 'AbortController' | 'AbortSignal' | 'XMLHttpRequest';
416
+ type WeappInjectRequestGlobalsTarget = 'fetch' | 'Headers' | 'Request' | 'Response' | 'AbortController' | 'AbortSignal' | 'XMLHttpRequest' | 'WebSocket';
417
417
  /**
418
418
  * @description 请求相关全局对象注入配置
419
419
  */
@@ -1269,6 +1269,7 @@ interface RuntimeState {
1269
1269
  resolvedResolverComponents: Map<string, string>;
1270
1270
  matcher?: (input: string) => boolean;
1271
1271
  matcherKey: string;
1272
+ version: number;
1272
1273
  };
1273
1274
  build: {
1274
1275
  queue: PQueue;
@@ -1279,10 +1280,15 @@ interface RuntimeState {
1279
1280
  };
1280
1281
  json: {
1281
1282
  cache: FileCache<any>;
1283
+ emittedSource: Map<string, string>;
1284
+ };
1285
+ asset: {
1286
+ emittedBuffer: Map<string, Buffer>;
1282
1287
  };
1283
1288
  css: {
1284
1289
  importerToDependencies: Map<string, Set<string>>;
1285
1290
  dependencyToImporters: Map<string, Set<string>>;
1291
+ emittedSource: Map<string, string>;
1286
1292
  };
1287
1293
  watcher: {
1288
1294
  rollupWatcherMap: Map<string, WatcherInstance>;
@@ -1293,6 +1299,8 @@ interface RuntimeState {
1293
1299
  importerMap: Map<string, Set<string>>;
1294
1300
  tokenMap: Map<string, ScanWxmlResult>;
1295
1301
  componentsMap: Map<string, ComponentsMap>;
1302
+ aggregatedComponentsMap: Map<string, ComponentsMap>;
1303
+ templatePathMap: Map<string, string>;
1296
1304
  cache: FileCache<ScanWxmlResult>;
1297
1305
  emittedCode: Map<string, string>;
1298
1306
  };
@@ -1360,11 +1368,13 @@ interface WxmlService {
1360
1368
  importerMap: Map<string, Set<string>>;
1361
1369
  tokenMap: Map<string, ScanWxmlResult>;
1362
1370
  wxmlComponentsMap: Map<string, ComponentsMap>;
1371
+ aggregatedComponentsMap: Map<string, ComponentsMap>;
1363
1372
  addDeps: (filepath: string, deps?: string[]) => Promise<void>;
1364
1373
  setDeps: (filepath: string, deps?: string[]) => Promise<void>;
1365
1374
  collectDepsFromToken: (filepath: string, deps?: ScanWxmlResult['deps']) => string[];
1366
1375
  getImporters: (filepath: string) => Set<string>;
1367
1376
  getAllDeps: () => Set<string>;
1377
+ getAggregatedComponents: (filepathOrBaseName: string) => ComponentsMap | undefined;
1368
1378
  clearAll: () => void;
1369
1379
  analyze: (wxml: string) => ScanWxmlResult;
1370
1380
  scan: (filepath: string) => Promise<ScanWxmlResult | undefined>;
@@ -1379,6 +1389,8 @@ interface ResolverAutoImportMatch {
1379
1389
  type AutoImportMatch = LocalAutoImportMatch | ResolverAutoImportMatch;
1380
1390
  interface AutoImportService {
1381
1391
  reset: () => void;
1392
+ getVersion: () => number;
1393
+ runInBatch: <T>(task: () => T | Promise<T>) => Promise<T>;
1382
1394
  registerPotentialComponent: (filePath: string) => Promise<void>;
1383
1395
  removePotentialComponent: (filePath: string) => void;
1384
1396
  resolve: (componentName: string, importerBaseName?: string) => AutoImportMatch | undefined;
package/dist/config.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { An as createWeappViteHostMeta, Dn as WeappViteHostMeta, En as WEAPP_VITE_HOST_NAME, Mn as resolveWeappViteHostMeta, On as WeappViteRuntime, _ as definePageJson, a as UserConfigFnNoEnvPlain, c as UserConfigFnPromise, d as Component, f as Page, g as defineComponentJson, h as defineAppJson, i as UserConfigFnNoEnv, jn as isWeappViteHost, kn as applyWeappViteHostMeta, l as defineConfig, m as Theme, n as UserConfigExport, nt as WeappViteConfig, o as UserConfigFnObject, p as Sitemap, r as UserConfigFn, s as UserConfigFnObjectPlain, t as UserConfig, u as App, v as defineSitemapJson, y as defineThemeJson } from "./config-bkgtM4wZ.mjs";
1
+ import { An as createWeappViteHostMeta, Dn as WeappViteHostMeta, En as WEAPP_VITE_HOST_NAME, Mn as resolveWeappViteHostMeta, On as WeappViteRuntime, _ as definePageJson, a as UserConfigFnNoEnvPlain, c as UserConfigFnPromise, d as Component, f as Page, g as defineComponentJson, h as defineAppJson, i as UserConfigFnNoEnv, jn as isWeappViteHost, kn as applyWeappViteHostMeta, l as defineConfig, m as Theme, n as UserConfigExport, nt as WeappViteConfig, o as UserConfigFnObject, p as Sitemap, r as UserConfigFn, s as UserConfigFnObjectPlain, t as UserConfig, u as App, v as defineSitemapJson, y as defineThemeJson } from "./config-GqcM7sq1.mjs";
2
2
  export { App, Component, Page, Sitemap, Theme, UserConfig, UserConfigExport, UserConfigFn, UserConfigFnNoEnv, UserConfigFnNoEnvPlain, UserConfigFnObject, UserConfigFnObjectPlain, UserConfigFnPromise, WEAPP_VITE_HOST_NAME, WeappViteConfig, WeappViteHostMeta, WeappViteRuntime, applyWeappViteHostMeta, createWeappViteHostMeta, defineAppJson, defineComponentJson, defineConfig, definePageJson, defineSitemapJson, defineThemeJson, isWeappViteHost, resolveWeappViteHostMeta };