@spaceflow/cli
Advanced tools
+81
-5
| #!/usr/bin/env node | ||
| import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs"; | ||
| import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs"; | ||
| import { join, resolve as external_path_resolve } from "path"; | ||
@@ -67,2 +67,77 @@ import { execSync } from "child_process"; | ||
| /** | ||
| * 读取 JSON 文件(不存在或解析失败时返回 null) | ||
| */ function readJsonFile(path) { | ||
| if (!existsSync(path)) { | ||
| return null; | ||
| } | ||
| try { | ||
| return JSON.parse(readFileSync(path, "utf-8")); | ||
| } catch { | ||
| return null; | ||
| } | ||
| } | ||
| /** | ||
| * 标准化 dependencies(仅保留 string 值) | ||
| */ function normalizeDependencies(value) { | ||
| if (!value || typeof value !== "object") { | ||
| return {}; | ||
| } | ||
| const result = {}; | ||
| for (const [name, version] of Object.entries(value)){ | ||
| if (typeof version === "string") { | ||
| result[name] = version; | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| /** | ||
| * 比较 .spaceflowrc 与 .spaceflow/package.json 依赖是否一致 | ||
| * 说明: | ||
| * - 只比较双方都存在的依赖(交集) | ||
| * - 交集中任一依赖版本不一致即判定不一致 | ||
| */ function isDependencyVersionConsistent(rcDeps, packageDeps) { | ||
| const commonKeys = Object.keys(rcDeps).filter((key)=>Object.prototype.hasOwnProperty.call(packageDeps, key)); | ||
| for (const key of commonKeys){ | ||
| if (rcDeps[key] !== packageDeps[key]) { | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
| /** | ||
| * 若 .spaceflowrc 与 .spaceflow/package.json 的依赖版本不一致,删除 .spaceflow 目录 | ||
| */ function resetSpaceflowDirOnDependencyMismatch(projectRoot, spaceflowDir) { | ||
| if (!existsSync(spaceflowDir)) { | ||
| return; | ||
| } | ||
| const rcPath = join(projectRoot, ".spaceflowrc"); | ||
| const rcConfig = readJsonFile(rcPath); | ||
| if (existsSync(rcPath) && !rcConfig) { | ||
| console.warn("⚠ .spaceflowrc 解析失败,跳过 .spaceflow 依赖一致性检查"); | ||
| return; | ||
| } | ||
| const rcConfigSafe = rcConfig || {}; | ||
| const rcDeps = normalizeDependencies(rcConfigSafe.dependencies); | ||
| const pkgPath = join(spaceflowDir, "package.json"); | ||
| const pkg = readJsonFile(pkgPath); | ||
| if (existsSync(pkgPath) && !pkg) { | ||
| console.warn("⚠ .spaceflow/package.json 解析失败,跳过 .spaceflow 依赖一致性检查"); | ||
| return; | ||
| } | ||
| const pkgSafe = pkg || {}; | ||
| const pkgDeps = normalizeDependencies(pkgSafe.dependencies); | ||
| if (isDependencyVersionConsistent(rcDeps, pkgDeps)) { | ||
| return; | ||
| } | ||
| console.warn("⚠ 检测到 .spaceflowrc 与 .spaceflow/package.json 依赖版本不一致,删除 .spaceflow 目录重建"); | ||
| try { | ||
| rmSync(spaceflowDir, { | ||
| recursive: true, | ||
| force: true | ||
| }); | ||
| } catch (error) { | ||
| console.warn(`⚠ 删除 .spaceflow 目录失败: ${error instanceof Error ? error.message : String(error)}`); | ||
| } | ||
| } | ||
| /** | ||
| * 生成 .spaceflow/bin/index.js 内容 | ||
@@ -163,3 +238,3 @@ * | ||
| name: "spaceflow-meta", | ||
| version: "0.40.0" | ||
| version: "0.41.0" | ||
| }); | ||
@@ -176,3 +251,3 @@ await client.connect(transport); | ||
| name: "spaceflow", | ||
| version: "0.40.0" | ||
| version: "0.41.0" | ||
| }); | ||
@@ -326,3 +401,3 @@ // 缓存已连接的项目 MCP Client(按 cwd) | ||
| await server.connect(transport); | ||
| console.error(`[spaceflow] MCP Meta Server 已启动 (v${"0.40.0"})`); | ||
| console.error(`[spaceflow] MCP Meta Server 已启动 (v${"0.41.0"})`); | ||
| // 保持进程运行 | ||
@@ -359,2 +434,3 @@ await new Promise((resolve)=>{ | ||
| const spaceflowDir = join(projectRoot, SPACEFLOW_DIR); | ||
| resetSpaceflowDirOnDependencyMismatch(projectRoot, spaceflowDir); | ||
| ensureSpaceflowPackageJson(spaceflowDir, projectRoot); | ||
@@ -367,3 +443,3 @@ // 3. 确保依赖已安装 | ||
| // 4. CLI 版本号(由 rspack DefinePlugin 在构建时注入) | ||
| const cliVersion = "0.40.0"; | ||
| const cliVersion = "0.41.0"; | ||
| // 5. 读取外部扩展列表 | ||
@@ -370,0 +446,0 @@ const extNames = readExternalExtensions(projectRoot); |
+1
-1
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"cli.js","sources":["webpack://@spaceflow/cli/./src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\ndeclare const __CLI_VERSION__: string;\n\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from \"fs\";\nimport { join, resolve } from \"path\";\nimport { execSync } from \"child_process\";\nimport {\n SPACEFLOW_DIR,\n findProjectRoot,\n ensureSpaceflowPackageJson,\n ensureDependencies,\n getExtensionDependencies,\n loadEnvFiles,\n getEnvFilePaths,\n} from \"@spaceflow/shared\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StdioClientTransport } from \"@modelcontextprotocol/sdk/client/stdio.js\";\nimport { z } from \"zod\";\n\n/**\n * Spaceflow CLI — 壳子入口\n *\n * 职责:\n * 1. 确保 .spaceflow/ 目录、package.json、.gitignore 完整\n * 2. 确保依赖已安装(pnpm install)\n * 3. 读取外部扩展列表\n * 4. 生成 .spaceflow/bin/index.js(静态 import 入口文件)\n * 5. spawn 子进程执行 node .spaceflow/bin/index.js\n */\n\n/**\n * 获取有效工作目录\n * 优先使用 SPACEFLOW_CWD 环境变量(MCP 场景由编辑器注入),否则 process.cwd()\n * 注意:不做 findProjectRoot,避免改变 .spaceflow 目录定位逻辑\n */\nfunction getEffectiveCwd(): string {\n return resolve(process.env.SPACEFLOW_CWD || process.cwd());\n}\n\n/**\n * 从 spaceflow.json / .spaceflowrc 读取外部扩展包名列表\n */\nfunction readExternalExtensions(cwd: string): string[] {\n const deps = getExtensionDependencies(cwd, { local: true });\n return Object.keys(deps);\n}\n\n/**\n * 生成 .spaceflow/bin/index.js 内容\n *\n * 使用 dynamic import 加载扩展,确保 i18n 在扩展模块执行前已初始化\n * (扩展在 import 阶段就会调用 t() 获取 description,必须先初始化 i18n)\n */\nfunction generateIndexContent(extensions: string[], version: string): string {\n const dynamicImports = extensions\n .map(\n (name) => ` import('${name}').then(m => m.default || m.extension || m).catch(() => null),`,\n )\n .join(\"\\n\");\n\n return `import { exec, initCliI18n } from '@spaceflow/core';\n\nasync function bootstrap() {\n // 初始化 i18n,再加载扩展(扩展 import 时会调用 t() 获取翻译)\n initCliI18n();\n\n const results = await Promise.all([\n${dynamicImports}\n ]);\n const extensions = results.filter(Boolean);\n\n await exec(extensions, { cliVersion: '${version}' });\n}\n\nbootstrap().catch((err) => {\n console.error(err);\n process.exit(1);\n});\n`;\n}\n\n/**\n * 生成 .spaceflow/bin/index.js 文件\n */\nfunction generateBinFile(spaceflowDir: string, extensions: string[], version: string): string {\n const binDir = join(spaceflowDir, \"bin\");\n const indexPath = join(binDir, \"index.js\");\n\n if (!existsSync(binDir)) {\n mkdirSync(binDir, { recursive: true });\n }\n\n const content = generateIndexContent(extensions, version);\n\n // 仅在内容变化时写入\n if (existsSync(indexPath)) {\n const existing = readFileSync(indexPath, \"utf-8\");\n if (existing === content) {\n return indexPath;\n }\n }\n\n writeFileSync(indexPath, content, \"utf-8\");\n return indexPath;\n}\n\n/**\n * 执行生成的 index.js\n */\nfunction executeIndexFile(indexPath: string, projectRoot: string): void {\n try {\n execSync(`node \"${indexPath}\" ${process.argv.slice(2).join(\" \")}`, {\n stdio: \"inherit\",\n env: { ...process.env, SPACEFLOW_CWD: projectRoot },\n });\n } catch (error: any) {\n // execSync 在子进程非零退出时抛出错误\n // 子进程的 stdout/stderr 已通过 stdio: \"inherit\" 输出\n process.exit(error.status || 1);\n }\n}\n\n/**\n * 检测是否为 MCP 代理模式(纯 mcp,不带 --inspector)\n * 纯 mcp → 启动 meta-tool MCP server(代理模式)\n * mcp --inspector → 走正常命令调用流程\n */\nfunction isMcpCommand(): boolean {\n const args = process.argv.slice(2);\n // SPACEFLOW_MCP_PROXY=1 表示当前是被 meta-tool 代理 spawn 的子进程,走正常命令调用流程\n return args.includes(\"mcp\") && !args.includes(\"--inspector\") && !process.env.SPACEFLOW_MCP_PROXY;\n}\n\n/**\n * 创建一个连接到指定项目 mcp server 的 MCP Client\n * spawn cli.js 自身,子进程走完整命令调用流程(初始化 .spaceflow → mcp server)\n * @param cwd 项目根目录\n */\nasync function connectProjectMcpClient(cwd: string): Promise<Client> {\n const resolvedCwd = resolve(cwd);\n const cliPath = process.argv[1];\n const transport = new StdioClientTransport({\n command: \"node\",\n args: [cliPath, \"mcp\"],\n cwd: resolvedCwd,\n env: { ...process.env, SPACEFLOW_CWD: resolvedCwd, SPACEFLOW_MCP_PROXY: \"1\" },\n });\n const client = new Client({ name: \"spaceflow-meta\", version: __CLI_VERSION__ });\n await client.connect(transport);\n return client;\n}\n\n/**\n * 启动 Meta-tool MCP Server\n * 注册 list_tools 和 call_tool 两个元工具\n * 通过 MCP Client SDK 与子进程 mcp server 通信\n */\nasync function startMcpMetaServer(): Promise<void> {\n const server = new McpServer({ name: \"spaceflow\", version: __CLI_VERSION__ });\n\n // 缓存已连接的项目 MCP Client(按 cwd)\n const clientCache = new Map<string, Client>();\n\n async function getProjectClient(cwd: string): Promise<Client> {\n const resolvedCwd = findProjectRoot(cwd);\n let client = clientCache.get(resolvedCwd);\n if (!client) {\n client = await connectProjectMcpClient(resolvedCwd);\n clientCache.set(resolvedCwd, client);\n }\n return client;\n }\n\n // Meta-tool 1: list_tools\n server.registerTool(\n \"list_tools\",\n {\n description: \"列出指定项目目录下可用的 Spaceflow MCP 工具列表\",\n inputSchema: z.object({\n cwd: z.string().describe(\"项目根目录的绝对路径\"),\n }),\n },\n async ({ cwd }) => {\n try {\n const client = await getProjectClient(cwd);\n const { tools } = await client.listTools();\n return {\n content: [\n {\n type: \"text\" as const,\n text: JSON.stringify(\n tools.map((t) => ({\n name: t.name,\n description: t.description,\n inputSchema: t.inputSchema,\n })),\n null,\n 2,\n ),\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Error: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n\n // Meta-tool 2: call_tool\n server.registerTool(\n \"call_tool\",\n {\n description: \"调用指定项目目录下的 Spaceflow MCP 工具\",\n inputSchema: z.object({\n cwd: z.string().describe(\"项目根目录的绝对路径\"),\n tool_name: z.string().describe(\"要调用的工具名称\"),\n tool_args: z.string().optional().describe(\"工具参数(JSON 字符串)\"),\n }),\n },\n async ({ cwd, tool_name, tool_args }) => {\n try {\n const client = await getProjectClient(cwd);\n const args = tool_args ? JSON.parse(tool_args) : {};\n const result = await client.callTool({ name: tool_name, arguments: args });\n // 直接返回底层 mcp server 的结果\n return result as any;\n } catch (error) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Error: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n\n // Meta-tool 3: list_resources\n server.registerTool(\n \"list_resources\",\n {\n description: \"列出指定项目目录下可用的 Spaceflow MCP 资源列表\",\n inputSchema: z.object({\n cwd: z.string().describe(\"项目根目录的绝对路径\"),\n }),\n },\n async ({ cwd }) => {\n try {\n const client = await getProjectClient(cwd);\n const { resources } = await client.listResources();\n return {\n content: [\n {\n type: \"text\" as const,\n text: JSON.stringify(\n resources.map((r) => ({\n name: r.name,\n uri: r.uri,\n description: r.description,\n mimeType: r.mimeType,\n })),\n null,\n 2,\n ),\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Error: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n\n // Meta-tool 4: read_resource\n server.registerTool(\n \"read_resource\",\n {\n description: \"读取指定项目目录下的 Spaceflow MCP 资源内容\",\n inputSchema: z.object({\n cwd: z.string().describe(\"项目根目录的绝对路径\"),\n uri: z.string().describe(\"资源 URI(如 spaceflow://config)\"),\n }),\n },\n async ({ cwd, uri }) => {\n try {\n const client = await getProjectClient(cwd);\n const result = await client.readResource({ uri });\n const texts = result.contents.map((c) => (\"text\" in c ? c.text : JSON.stringify(c)));\n return {\n content: [\n {\n type: \"text\" as const,\n text: texts.join(\"\\n\"),\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Error: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n\n // 启动 stdio 传输\n const transport = new StdioServerTransport();\n await server.connect(transport);\n\n console.error(`[spaceflow] MCP Meta Server 已启动 (v${__CLI_VERSION__})`);\n\n // 保持进程运行\n await new Promise<void>((resolve) => {\n process.stdin.on(\"close\", resolve);\n process.on(\"SIGINT\", () => {\n resolve();\n process.exit(0);\n });\n process.on(\"SIGTERM\", () => {\n resolve();\n process.exit(0);\n });\n });\n}\n\n// ---- 主流程 ----\n\n// 检测是否为 mcp 命令:直接启动 meta-tool MCP server\nif (isMcpCommand()) {\n startMcpMetaServer().catch((err) => {\n console.error(err);\n process.exit(1);\n });\n} else {\n // 正常 CLI 流程\n // 0. 解析有效工作目录\n // effectiveCwd: 用户实际所在目录(保持 process.cwd() 不变,build 等命令依赖它)\n // projectRoot: .spaceflowrc 所在目录(决定 .spaceflow 目录位置和配置读取)\n const effectiveCwd = getEffectiveCwd();\n const projectRoot = findProjectRoot(effectiveCwd);\n\n // 1. 先加载 .env 文件,确保 process.env 在子进程(含 schema 模块求值)前已就绪\n loadEnvFiles(getEnvFilePaths(projectRoot));\n\n // 2. 确保 .spaceflow/ 目录结构完整(目录 + package.json + .gitignore)\n const spaceflowDir = join(projectRoot, SPACEFLOW_DIR);\n ensureSpaceflowPackageJson(spaceflowDir, projectRoot);\n\n // 3. 确保依赖已安装\n // MCP 代理模式下使用 pipe 避免 pnpm install 输出污染 stdout(MCP 协议通道)\n ensureDependencies(spaceflowDir, process.env.SPACEFLOW_MCP_PROXY ? { stdio: \"pipe\" } : undefined);\n\n // 4. CLI 版本号(由 rspack DefinePlugin 在构建时注入)\n const cliVersion = __CLI_VERSION__;\n\n // 5. 读取外部扩展列表\n const extNames = readExternalExtensions(projectRoot);\n\n // 6. 生成 .spaceflow/bin/index.js\n const indexPath = generateBinFile(spaceflowDir, extNames, cliVersion);\n\n // 7. 执行生成的入口文件(传 projectRoot 作为 SPACEFLOW_CWD,保持 process.cwd() 不变)\n executeIndexFile(indexPath, projectRoot);\n}\n"],"names":["existsSync","readFileSync","writeFileSync","mkdirSync","join","resolve","execSync","SPACEFLOW_DIR","findProjectRoot","ensureSpaceflowPackageJson","ensureDependencies","getExtensionDependencies","loadEnvFiles","getEnvFilePaths","McpServer","StdioServerTransport","Client","StdioClientTransport","z","getEffectiveCwd","process","readExternalExtensions","cwd","deps","Object","generateIndexContent","extensions","version","dynamicImports","name","generateBinFile","spaceflowDir","binDir","indexPath","content","existing","executeIndexFile","projectRoot","error","isMcpCommand","args","connectProjectMcpClient","resolvedCwd","cliPath","transport","client","__CLI_VERSION__","startMcpMetaServer","server","clientCache","Map","getProjectClient","tools","JSON","t","Error","String","tool_name","tool_args","result","resources","r","uri","texts","c","console","Promise","err","effectiveCwd","undefined","cliVersion","extNames"],"mappings":"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"} | ||
| {"version":3,"file":"cli.js","sources":["webpack://@spaceflow/cli/./src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\ndeclare const __CLI_VERSION__: string;\n\nimport { existsSync, readFileSync, writeFileSync, mkdirSync, rmSync } from \"fs\";\nimport { join, resolve } from \"path\";\nimport { execSync } from \"child_process\";\nimport {\n SPACEFLOW_DIR,\n findProjectRoot,\n ensureSpaceflowPackageJson,\n ensureDependencies,\n getExtensionDependencies,\n loadEnvFiles,\n getEnvFilePaths,\n} from \"@spaceflow/shared\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StdioClientTransport } from \"@modelcontextprotocol/sdk/client/stdio.js\";\nimport { z } from \"zod\";\n\n/**\n * Spaceflow CLI — 壳子入口\n *\n * 职责:\n * 1. 确保 .spaceflow/ 目录、package.json、.gitignore 完整\n * 2. 确保依赖已安装(pnpm install)\n * 3. 读取外部扩展列表\n * 4. 生成 .spaceflow/bin/index.js(静态 import 入口文件)\n * 5. spawn 子进程执行 node .spaceflow/bin/index.js\n */\n\n/**\n * 获取有效工作目录\n * 优先使用 SPACEFLOW_CWD 环境变量(MCP 场景由编辑器注入),否则 process.cwd()\n * 注意:不做 findProjectRoot,避免改变 .spaceflow 目录定位逻辑\n */\nfunction getEffectiveCwd(): string {\n return resolve(process.env.SPACEFLOW_CWD || process.cwd());\n}\n\n/**\n * 从 spaceflow.json / .spaceflowrc 读取外部扩展包名列表\n */\nfunction readExternalExtensions(cwd: string): string[] {\n const deps = getExtensionDependencies(cwd, { local: true });\n return Object.keys(deps);\n}\n\n/**\n * 读取 JSON 文件(不存在或解析失败时返回 null)\n */\nfunction readJsonFile<T>(path: string): T | null {\n if (!existsSync(path)) {\n return null;\n }\n try {\n return JSON.parse(readFileSync(path, \"utf-8\")) as T;\n } catch {\n return null;\n }\n}\n\n/**\n * 标准化 dependencies(仅保留 string 值)\n */\nfunction normalizeDependencies(value: unknown): Record<string, string> {\n if (!value || typeof value !== \"object\") {\n return {};\n }\n const result: Record<string, string> = {};\n for (const [name, version] of Object.entries(value)) {\n if (typeof version === \"string\") {\n result[name] = version;\n }\n }\n return result;\n}\n\n/**\n * 比较 .spaceflowrc 与 .spaceflow/package.json 依赖是否一致\n * 说明:\n * - 只比较双方都存在的依赖(交集)\n * - 交集中任一依赖版本不一致即判定不一致\n */\nfunction isDependencyVersionConsistent(\n rcDeps: Record<string, string>,\n packageDeps: Record<string, string>,\n): boolean {\n const commonKeys = Object.keys(rcDeps).filter((key) =>\n Object.prototype.hasOwnProperty.call(packageDeps, key),\n );\n for (const key of commonKeys) {\n if (rcDeps[key] !== packageDeps[key]) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * 若 .spaceflowrc 与 .spaceflow/package.json 的依赖版本不一致,删除 .spaceflow 目录\n */\nfunction resetSpaceflowDirOnDependencyMismatch(projectRoot: string, spaceflowDir: string): void {\n if (!existsSync(spaceflowDir)) {\n return;\n }\n\n const rcPath = join(projectRoot, \".spaceflowrc\");\n const rcConfig = readJsonFile<Record<string, unknown>>(rcPath);\n if (existsSync(rcPath) && !rcConfig) {\n console.warn(\"⚠ .spaceflowrc 解析失败,跳过 .spaceflow 依赖一致性检查\");\n return;\n }\n const rcConfigSafe = rcConfig || {};\n const rcDeps = normalizeDependencies(rcConfigSafe.dependencies);\n\n const pkgPath = join(spaceflowDir, \"package.json\");\n const pkg = readJsonFile<Record<string, unknown>>(pkgPath);\n if (existsSync(pkgPath) && !pkg) {\n console.warn(\"⚠ .spaceflow/package.json 解析失败,跳过 .spaceflow 依赖一致性检查\");\n return;\n }\n const pkgSafe = pkg || {};\n const pkgDeps = normalizeDependencies(pkgSafe.dependencies);\n\n if (isDependencyVersionConsistent(rcDeps, pkgDeps)) {\n return;\n }\n\n console.warn(\n \"⚠ 检测到 .spaceflowrc 与 .spaceflow/package.json 依赖版本不一致,删除 .spaceflow 目录重建\",\n );\n try {\n rmSync(spaceflowDir, { recursive: true, force: true });\n } catch (error) {\n console.warn(\n `⚠ 删除 .spaceflow 目录失败: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n\n/**\n * 生成 .spaceflow/bin/index.js 内容\n *\n * 使用 dynamic import 加载扩展,确保 i18n 在扩展模块执行前已初始化\n * (扩展在 import 阶段就会调用 t() 获取 description,必须先初始化 i18n)\n */\nfunction generateIndexContent(extensions: string[], version: string): string {\n const dynamicImports = extensions\n .map(\n (name) => ` import('${name}').then(m => m.default || m.extension || m).catch(() => null),`,\n )\n .join(\"\\n\");\n\n return `import { exec, initCliI18n } from '@spaceflow/core';\n\nasync function bootstrap() {\n // 初始化 i18n,再加载扩展(扩展 import 时会调用 t() 获取翻译)\n initCliI18n();\n\n const results = await Promise.all([\n${dynamicImports}\n ]);\n const extensions = results.filter(Boolean);\n\n await exec(extensions, { cliVersion: '${version}' });\n}\n\nbootstrap().catch((err) => {\n console.error(err);\n process.exit(1);\n});\n`;\n}\n\n/**\n * 生成 .spaceflow/bin/index.js 文件\n */\nfunction generateBinFile(spaceflowDir: string, extensions: string[], version: string): string {\n const binDir = join(spaceflowDir, \"bin\");\n const indexPath = join(binDir, \"index.js\");\n\n if (!existsSync(binDir)) {\n mkdirSync(binDir, { recursive: true });\n }\n\n const content = generateIndexContent(extensions, version);\n\n // 仅在内容变化时写入\n if (existsSync(indexPath)) {\n const existing = readFileSync(indexPath, \"utf-8\");\n if (existing === content) {\n return indexPath;\n }\n }\n\n writeFileSync(indexPath, content, \"utf-8\");\n return indexPath;\n}\n\n/**\n * 执行生成的 index.js\n */\nfunction executeIndexFile(indexPath: string, projectRoot: string): void {\n try {\n execSync(`node \"${indexPath}\" ${process.argv.slice(2).join(\" \")}`, {\n stdio: \"inherit\",\n env: { ...process.env, SPACEFLOW_CWD: projectRoot },\n });\n } catch (error: any) {\n // execSync 在子进程非零退出时抛出错误\n // 子进程的 stdout/stderr 已通过 stdio: \"inherit\" 输出\n process.exit(error.status || 1);\n }\n}\n\n/**\n * 检测是否为 MCP 代理模式(纯 mcp,不带 --inspector)\n * 纯 mcp → 启动 meta-tool MCP server(代理模式)\n * mcp --inspector → 走正常命令调用流程\n */\nfunction isMcpCommand(): boolean {\n const args = process.argv.slice(2);\n // SPACEFLOW_MCP_PROXY=1 表示当前是被 meta-tool 代理 spawn 的子进程,走正常命令调用流程\n return args.includes(\"mcp\") && !args.includes(\"--inspector\") && !process.env.SPACEFLOW_MCP_PROXY;\n}\n\n/**\n * 创建一个连接到指定项目 mcp server 的 MCP Client\n * spawn cli.js 自身,子进程走完整命令调用流程(初始化 .spaceflow → mcp server)\n * @param cwd 项目根目录\n */\nasync function connectProjectMcpClient(cwd: string): Promise<Client> {\n const resolvedCwd = resolve(cwd);\n const cliPath = process.argv[1];\n const transport = new StdioClientTransport({\n command: \"node\",\n args: [cliPath, \"mcp\"],\n cwd: resolvedCwd,\n env: { ...process.env, SPACEFLOW_CWD: resolvedCwd, SPACEFLOW_MCP_PROXY: \"1\" },\n });\n const client = new Client({ name: \"spaceflow-meta\", version: __CLI_VERSION__ });\n await client.connect(transport);\n return client;\n}\n\n/**\n * 启动 Meta-tool MCP Server\n * 注册 list_tools 和 call_tool 两个元工具\n * 通过 MCP Client SDK 与子进程 mcp server 通信\n */\nasync function startMcpMetaServer(): Promise<void> {\n const server = new McpServer({ name: \"spaceflow\", version: __CLI_VERSION__ });\n\n // 缓存已连接的项目 MCP Client(按 cwd)\n const clientCache = new Map<string, Client>();\n\n async function getProjectClient(cwd: string): Promise<Client> {\n const resolvedCwd = findProjectRoot(cwd);\n let client = clientCache.get(resolvedCwd);\n if (!client) {\n client = await connectProjectMcpClient(resolvedCwd);\n clientCache.set(resolvedCwd, client);\n }\n return client;\n }\n\n // Meta-tool 1: list_tools\n server.registerTool(\n \"list_tools\",\n {\n description: \"列出指定项目目录下可用的 Spaceflow MCP 工具列表\",\n inputSchema: z.object({\n cwd: z.string().describe(\"项目根目录的绝对路径\"),\n }),\n },\n async ({ cwd }) => {\n try {\n const client = await getProjectClient(cwd);\n const { tools } = await client.listTools();\n return {\n content: [\n {\n type: \"text\" as const,\n text: JSON.stringify(\n tools.map((t) => ({\n name: t.name,\n description: t.description,\n inputSchema: t.inputSchema,\n })),\n null,\n 2,\n ),\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Error: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n\n // Meta-tool 2: call_tool\n server.registerTool(\n \"call_tool\",\n {\n description: \"调用指定项目目录下的 Spaceflow MCP 工具\",\n inputSchema: z.object({\n cwd: z.string().describe(\"项目根目录的绝对路径\"),\n tool_name: z.string().describe(\"要调用的工具名称\"),\n tool_args: z.string().optional().describe(\"工具参数(JSON 字符串)\"),\n }),\n },\n async ({ cwd, tool_name, tool_args }) => {\n try {\n const client = await getProjectClient(cwd);\n const args = tool_args ? JSON.parse(tool_args) : {};\n const result = await client.callTool({ name: tool_name, arguments: args });\n // 直接返回底层 mcp server 的结果\n return result as any;\n } catch (error) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Error: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n\n // Meta-tool 3: list_resources\n server.registerTool(\n \"list_resources\",\n {\n description: \"列出指定项目目录下可用的 Spaceflow MCP 资源列表\",\n inputSchema: z.object({\n cwd: z.string().describe(\"项目根目录的绝对路径\"),\n }),\n },\n async ({ cwd }) => {\n try {\n const client = await getProjectClient(cwd);\n const { resources } = await client.listResources();\n return {\n content: [\n {\n type: \"text\" as const,\n text: JSON.stringify(\n resources.map((r) => ({\n name: r.name,\n uri: r.uri,\n description: r.description,\n mimeType: r.mimeType,\n })),\n null,\n 2,\n ),\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Error: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n\n // Meta-tool 4: read_resource\n server.registerTool(\n \"read_resource\",\n {\n description: \"读取指定项目目录下的 Spaceflow MCP 资源内容\",\n inputSchema: z.object({\n cwd: z.string().describe(\"项目根目录的绝对路径\"),\n uri: z.string().describe(\"资源 URI(如 spaceflow://config)\"),\n }),\n },\n async ({ cwd, uri }) => {\n try {\n const client = await getProjectClient(cwd);\n const result = await client.readResource({ uri });\n const texts = result.contents.map((c) => (\"text\" in c ? c.text : JSON.stringify(c)));\n return {\n content: [\n {\n type: \"text\" as const,\n text: texts.join(\"\\n\"),\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Error: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n\n // 启动 stdio 传输\n const transport = new StdioServerTransport();\n await server.connect(transport);\n\n console.error(`[spaceflow] MCP Meta Server 已启动 (v${__CLI_VERSION__})`);\n\n // 保持进程运行\n await new Promise<void>((resolve) => {\n process.stdin.on(\"close\", resolve);\n process.on(\"SIGINT\", () => {\n resolve();\n process.exit(0);\n });\n process.on(\"SIGTERM\", () => {\n resolve();\n process.exit(0);\n });\n });\n}\n\n// ---- 主流程 ----\n\n// 检测是否为 mcp 命令:直接启动 meta-tool MCP server\nif (isMcpCommand()) {\n startMcpMetaServer().catch((err) => {\n console.error(err);\n process.exit(1);\n });\n} else {\n // 正常 CLI 流程\n // 0. 解析有效工作目录\n // effectiveCwd: 用户实际所在目录(保持 process.cwd() 不变,build 等命令依赖它)\n // projectRoot: .spaceflowrc 所在目录(决定 .spaceflow 目录位置和配置读取)\n const effectiveCwd = getEffectiveCwd();\n const projectRoot = findProjectRoot(effectiveCwd);\n\n // 1. 先加载 .env 文件,确保 process.env 在子进程(含 schema 模块求值)前已就绪\n loadEnvFiles(getEnvFilePaths(projectRoot));\n\n // 2. 确保 .spaceflow/ 目录结构完整(目录 + package.json + .gitignore)\n const spaceflowDir = join(projectRoot, SPACEFLOW_DIR);\n resetSpaceflowDirOnDependencyMismatch(projectRoot, spaceflowDir);\n ensureSpaceflowPackageJson(spaceflowDir, projectRoot);\n\n // 3. 确保依赖已安装\n // MCP 代理模式下使用 pipe 避免 pnpm install 输出污染 stdout(MCP 协议通道)\n ensureDependencies(spaceflowDir, process.env.SPACEFLOW_MCP_PROXY ? { stdio: \"pipe\" } : undefined);\n\n // 4. CLI 版本号(由 rspack DefinePlugin 在构建时注入)\n const cliVersion = __CLI_VERSION__;\n\n // 5. 读取外部扩展列表\n const extNames = readExternalExtensions(projectRoot);\n\n // 6. 生成 .spaceflow/bin/index.js\n const indexPath = generateBinFile(spaceflowDir, extNames, cliVersion);\n\n // 7. 执行生成的入口文件(传 projectRoot 作为 SPACEFLOW_CWD,保持 process.cwd() 不变)\n executeIndexFile(indexPath, projectRoot);\n}\n"],"names":["existsSync","readFileSync","writeFileSync","mkdirSync","rmSync","join","resolve","execSync","SPACEFLOW_DIR","findProjectRoot","ensureSpaceflowPackageJson","ensureDependencies","getExtensionDependencies","loadEnvFiles","getEnvFilePaths","McpServer","StdioServerTransport","Client","StdioClientTransport","z","getEffectiveCwd","process","readExternalExtensions","cwd","deps","Object","readJsonFile","path","JSON","normalizeDependencies","value","result","name","version","isDependencyVersionConsistent","rcDeps","packageDeps","commonKeys","key","resetSpaceflowDirOnDependencyMismatch","projectRoot","spaceflowDir","rcPath","rcConfig","console","rcConfigSafe","pkgPath","pkg","pkgSafe","pkgDeps","error","Error","String","generateIndexContent","extensions","dynamicImports","generateBinFile","binDir","indexPath","content","existing","executeIndexFile","isMcpCommand","args","connectProjectMcpClient","resolvedCwd","cliPath","transport","client","__CLI_VERSION__","startMcpMetaServer","server","clientCache","Map","getProjectClient","tools","t","tool_name","tool_args","resources","r","uri","texts","c","Promise","err","effectiveCwd","undefined","cliVersion","extNames"],"mappings":"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"} |
+1
-1
| { | ||
| "name": "@spaceflow/cli", | ||
| "version": "0.40.0", | ||
| "version": "0.41.0", | ||
| "description": "Spaceflow CLI 工具", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
43158
20.26%422
21.97%