Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 12 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,23 @@
"build:linux:x64": "pnpm run build && electron-builder --linux --x64",
"build:linux:arm64": "pnpm run build && electron-builder --linux --arm64",
"afterSign": "scripts/notarize.js",
"installRuntime": "tiny-runtime-injector -d runtime/node -n v22.15.0 --no-docs --no-dev --no-sourcemaps",
"installRuntime:win:x64": "tiny-runtime-injector -d runtime/node -n v22.15.0 -a x64 -p win32 --no-docs --no-dev --no-sourcemaps",
"installRuntime:win:arm64": "tiny-runtime-injector -d runtime/node -n v22.15.0 -a arm64 -p win32 --no-docs --no-dev --no-sourcemaps",
"installRuntime:mac:arm64": "tiny-runtime-injector -d runtime/node -n v22.15.0 -a arm64 -p darwin --no-docs --no-dev --no-sourcemaps",
"installRuntime:mac:x64": "tiny-runtime-injector -d runtime/node -n v22.15.0 -a x64 -p darwin --no-docs --no-dev --no-sourcemaps",
"installRuntime:linux:x64": "tiny-runtime-injector -d runtime/node -n v22.15.0 -a x64 -p linux --no-docs --no-dev --no-sourcemaps",
"installRuntime:linux:arm64": "tiny-runtime-injector -d runtime/node -n v22.15.0 -a arm64 -p linux --no-docs --no-dev --no-sourcemaps",
"installRuntime": "npx -y tiny-runtime-injector --type uv --dir ./runtime/uv && npx -y tiny-runtime-injector --type bun --dir ./runtime/bun",
"installRuntime:win:x64": "npx -y tiny-runtime-injector --type uv --dir ./runtime/uv -a x64 -p win32 && npx -y tiny-runtime-injector --type bun --dir ./runtime/bun -a x64 -p win32",
"installRuntime:win:arm64": "npx -y tiny-runtime-injector --type uv --dir ./runtime/uv -a arm64 -p win32 && npx -y tiny-runtime-injector --type bun --dir ./runtime/bun -a arm64 -p win32",
"installRuntime:mac:arm64": "npx -y tiny-runtime-injector --type uv --dir ./runtime/uv -a arm64 -p darwin && npx -y tiny-runtime-injector --type bun --dir ./runtime/bun -a arm64 -p darwin",
"installRuntime:mac:x64": "npx -y tiny-runtime-injector --type uv --dir ./runtime/uv -a x64 -p darwin && npx -y tiny-runtime-injector --type bun --dir ./runtime/bun -a x64 -p darwin",
"installRuntime:linux:x64": "npx -y tiny-runtime-injector --type uv --dir ./runtime/uv -a x64 -p linux && npx -y tiny-runtime-injector --type bun --dir ./runtime/bun -a x64 -p linux",
"installRuntime:linux:arm64": "npx -y tiny-runtime-injector --type uv --dir ./runtime/uv -a arm64 -p linux && npx -y tiny-runtime-injector --type bun --dir ./runtime/bun -a arm64 -p linux",
"i18n": "i18n-check -s zh-CN -f i18next --locales src/renderer/src/i18n",
"i18n:en": "i18n-check -s en-US -f i18next --locales src/renderer/src/i18n",
"cleanRuntime": "rm -rf runtime/node"
"cleanRuntime": "rm -rf runtime/uv runtime/bun"
},
"dependencies": {
"@anthropic-ai/sdk": "^0.53.0",
"@electron-toolkit/preload": "^3.0.1",
"@electron-toolkit/utils": "^4.0.0",
"@google/genai": "^1.4.0",
"@modelcontextprotocol/sdk": "^1.12.1",
"@google/genai": "^1.5.1",
"@modelcontextprotocol/sdk": "^1.12.3",
"axios": "^1.7.9",
"better-sqlite3-multiple-ciphers": "11.10.0",
"cheerio": "^1.0.0",
Expand All @@ -75,7 +75,7 @@
"mime-types": "^2.1.35",
"nanoid": "^5.1.5",
"ollama": "^0.5.16",
"openai": "^5.2.0",
"openai": "^5.3.0",
"pdf-parse-new": "^1.3.9",
"pyodide": "^0.27.5",
"sharp": "^0.33.5",
Expand Down Expand Up @@ -120,7 +120,7 @@
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"dompurify": "^3.2.4",
"electron": "^35.4.0",
"electron": "^35.5.1",
"electron-builder": "26.0.12",
"electron-vite": "^3.1.0",
"jsdom": "^26.1.0",
Expand All @@ -135,7 +135,6 @@
"tailwind-scrollbar-hide": "^2.0.0",
"tailwindcss": "3.4.17",
"tailwindcss-animate": "^1.0.7",
"tiny-runtime-injector": "^0.0.2",
"tippy.js": "^6.3.7",
"typescript": "^5.8.3",
"vite": "^6.3.4",
Expand Down
60 changes: 30 additions & 30 deletions src/main/presenter/mcpPresenter/inMemoryServers/powerpackServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ const CODE_EXECUTION_FORBIDDEN_PATTERNS = [

export class PowerpackServer {
private server: Server
private nodeRuntimePath: string | null = null
private bunRuntimePath: string | null = null

constructor() {
// 查找内置的Node运行时路径
this.setupNodeRuntime()
// 查找内置的Bun运行时路径
this.setupBunRuntime()

// 创建服务器实例
this.server = new Server(
Expand All @@ -95,26 +95,26 @@ export class PowerpackServer {
this.setupRequestHandlers()
}

// 设置Node运行时路径
private setupNodeRuntime(): void {
// 设置Bun运行时路径
private setupBunRuntime(): void {
const runtimePath = path
.join(app.getAppPath(), 'runtime', 'node')
.join(app.getAppPath(), 'runtime', 'bun')
.replace('app.asar', 'app.asar.unpacked')

if (process.platform === 'win32') {
const nodeExe = path.join(runtimePath, 'node.exe')
if (fs.existsSync(nodeExe)) {
this.nodeRuntimePath = runtimePath
const bunExe = path.join(runtimePath, 'bun.exe')
if (fs.existsSync(bunExe)) {
this.bunRuntimePath = runtimePath
}
} else {
const nodeBin = path.join(runtimePath, 'bin', 'node')
if (fs.existsSync(nodeBin)) {
this.nodeRuntimePath = path.join(runtimePath, 'bin')
const bunBin = path.join(runtimePath, 'bun')
if (fs.existsSync(bunBin)) {
this.bunRuntimePath = runtimePath
}
}

if (!this.nodeRuntimePath) {
console.warn('未找到内置Node运行时,代码执行功能将不可用')
if (!this.bunRuntimePath) {
console.warn('未找到内置Bun运行时,代码执行功能将不可用')
}
}

Expand All @@ -138,10 +138,10 @@ export class PowerpackServer {
return `${userQuery} ${actualTime}`
}

// 执行Node代码
private async executeNodeCode(code: string, timeout: number): Promise<string> {
if (!this.nodeRuntimePath) {
throw new Error('Node运行时未找到,无法执行代码')
// 执行Bun代码
private async executeBunCode(code: string, timeout: number): Promise<string> {
if (!this.bunRuntimePath) {
throw new Error('Bun运行时未找到,无法执行代码')
}

// 检查代码安全性
Expand All @@ -158,13 +158,13 @@ export class PowerpackServer {
fs.writeFileSync(tempFile, code)

// 准备执行命令
const nodeExecutable =
const bunExecutable =
process.platform === 'win32'
? path.join(this.nodeRuntimePath, 'node.exe')
: path.join(this.nodeRuntimePath, 'node')
? path.join(this.bunRuntimePath, 'bun.exe')
: path.join(this.bunRuntimePath, 'bun')

// 执行代码并添加超时控制
const execPromise = promisify(execFile)(nodeExecutable, [tempFile], {
const execPromise = promisify(execFile)(bunExecutable, [tempFile], {
timeout,
windowsHide: true
})
Expand Down Expand Up @@ -236,16 +236,16 @@ export class PowerpackServer {
}
]

// 只有在Node运行时可用时才添加代码执行工具
if (this.nodeRuntimePath) {
// 只有在Bun运行时可用时才添加代码执行工具
if (this.bunRuntimePath) {
tools.push({
name: 'run_node_code',
description:
'Execute simple Node.js code in a secure sandbox environment. Suitable for calculations, data transformations, encryption/decryption, and network operations. ' +
'Execute simple JavaScript/TypeScript code in a secure Bun sandbox environment. Suitable for calculations, data transformations, encryption/decryption, and network operations. ' +
'The code needs to be output to the console, and the output content needs to be formatted as a string. ' +
'For security reasons, the code cannot perform file operations, modify system settings, spawn child processes, or execute external code from network. ' +
'Code execution has a timeout limit, default is 5 seconds, you can adjust it based on the estimated time of the code, generally not recommended to exceed 2 minutes. ' +
'When a problem can be solved by a simple and secure Node.js code or you have generated a simple code for the user and want to execute it, please use this tool, providing more reliable information to the user.',
'When a problem can be solved by a simple and secure JavaScript/TypeScript code or you have generated a simple code for the user and want to execute it, please use this tool, providing more reliable information to the user.',
inputSchema: zodToJsonSchema(RunNodeCodeArgsSchema)
})
}
Expand Down Expand Up @@ -335,9 +335,9 @@ export class PowerpackServer {
}

case 'run_node_code': {
// 再次检查Node运行时是否可用
if (!this.nodeRuntimePath) {
throw new Error('Node runtime is not available, cannot execute code')
// 再次检查Bun运行时是否可用
if (!this.bunRuntimePath) {
throw new Error('Bun runtime is not available, cannot execute code')
}

const parsed = RunNodeCodeArgsSchema.safeParse(args)
Expand All @@ -346,7 +346,7 @@ export class PowerpackServer {
}

const { code, timeout } = parsed.data
const result = await this.executeNodeCode(code, timeout)
const result = await this.executeBunCode(code, timeout)

return {
content: [
Expand Down
Loading