@spaceflow/cli
Advanced tools
+73
-4
@@ -162,3 +162,3 @@ #!/usr/bin/env node | ||
| name: "spaceflow-meta", | ||
| version: "0.37.0" | ||
| version: "0.38.0" | ||
| }); | ||
@@ -175,3 +175,3 @@ await client.connect(transport); | ||
| name: "spaceflow", | ||
| version: "0.37.0" | ||
| version: "0.38.0" | ||
| }); | ||
@@ -253,6 +253,75 @@ // 缓存已连接的项目 MCP Client(按 cwd) | ||
| }); | ||
| // Meta-tool 3: list_resources | ||
| server.registerTool("list_resources", { | ||
| description: "列出指定项目目录下可用的 Spaceflow MCP 资源列表", | ||
| inputSchema: z.object({ | ||
| cwd: z.string().describe("项目根目录的绝对路径") | ||
| }) | ||
| }, async ({ cwd })=>{ | ||
| try { | ||
| const client = await getProjectClient(cwd); | ||
| const { resources } = await client.listResources(); | ||
| return { | ||
| content: [ | ||
| { | ||
| type: "text", | ||
| text: JSON.stringify(resources.map((r)=>({ | ||
| name: r.name, | ||
| uri: r.uri, | ||
| description: r.description, | ||
| mimeType: r.mimeType | ||
| })), null, 2) | ||
| } | ||
| ] | ||
| }; | ||
| } catch (error) { | ||
| return { | ||
| content: [ | ||
| { | ||
| type: "text", | ||
| text: `Error: ${error instanceof Error ? error.message : String(error)}` | ||
| } | ||
| ], | ||
| isError: true | ||
| }; | ||
| } | ||
| }); | ||
| // Meta-tool 4: read_resource | ||
| server.registerTool("read_resource", { | ||
| description: "读取指定项目目录下的 Spaceflow MCP 资源内容", | ||
| inputSchema: z.object({ | ||
| cwd: z.string().describe("项目根目录的绝对路径"), | ||
| uri: z.string().describe("资源 URI(如 spaceflow://config)") | ||
| }) | ||
| }, async ({ cwd, uri })=>{ | ||
| try { | ||
| const client = await getProjectClient(cwd); | ||
| const result = await client.readResource({ | ||
| uri | ||
| }); | ||
| const texts = result.contents.map((c)=>"text" in c ? c.text : JSON.stringify(c)); | ||
| return { | ||
| content: [ | ||
| { | ||
| type: "text", | ||
| text: texts.join("\n") | ||
| } | ||
| ] | ||
| }; | ||
| } catch (error) { | ||
| return { | ||
| content: [ | ||
| { | ||
| type: "text", | ||
| text: `Error: ${error instanceof Error ? error.message : String(error)}` | ||
| } | ||
| ], | ||
| isError: true | ||
| }; | ||
| } | ||
| }); | ||
| // 启动 stdio 传输 | ||
| const transport = new StdioServerTransport(); | ||
| await server.connect(transport); | ||
| console.error(`[spaceflow] MCP Meta Server 已启动 (v${"0.37.0"})`); | ||
| console.error(`[spaceflow] MCP Meta Server 已启动 (v${"0.38.0"})`); | ||
| // 保持进程运行 | ||
@@ -296,3 +365,3 @@ await new Promise((resolve)=>{ | ||
| // 4. CLI 版本号(由 rspack DefinePlugin 在构建时注入) | ||
| const cliVersion = "0.37.0"; | ||
| const cliVersion = "0.38.0"; | ||
| // 5. 读取外部扩展列表 | ||
@@ -299,0 +368,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 getDependencies,\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 = getDependencies(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 // 启动 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","getDependencies","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","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 } from \"fs\";\nimport { join, resolve } from \"path\";\nimport { execSync } from \"child_process\";\nimport {\n SPACEFLOW_DIR,\n findProjectRoot,\n ensureSpaceflowPackageJson,\n ensureDependencies,\n getDependencies,\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 = getDependencies(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","getDependencies","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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"} |
+1
-1
| { | ||
| "name": "@spaceflow/cli", | ||
| "version": "0.37.0", | ||
| "version": "0.38.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
35839
20.27%346
24.91%