"添加前端模板和运行代码模块"

This commit is contained in:
Codex
2026-06-01 13:43:09 +08:00
parent 24045274ad
commit 8092c4b1f8
587 changed files with 99761 additions and 0 deletions

View File

@@ -0,0 +1,109 @@
---
description:
globs:
alwaysApply: false
---
# 代码执行流程
本项目的核心功能是执行JavaScript、TypeScript和Python代码并捕获执行结果。以下是代码执行的主要流程
## 代码执行模型
项目使用模块化的代码执行模型,定义在[src/model/code_run_model.rs](mdc:src/model/code_run_model.rs)中:
```rust
/// 执行结果,包含js/python 执行结果,和打印的log日志
#[derive(Debug, Serialize, Deserialize)]
pub struct CodeScriptExecutionResult {
//js/python 执行结果
pub result: Option<Value>,
//js/python 打印的log日志
pub logs: Vec<String>,
// 是否执行成功,ture:默认值,执行成功
#[serde(skip_serializing)]
pub success: bool,
//如果执行错误的话,错误信息
#[serde(skip_serializing)]
pub error: Option<String>,
}
/// 代码执行器
pub struct CodeExecutor;
impl CodeExecutor {
/// 执行代码
pub async fn execute(
code: &str,
language: LanguageScript,
) -> Result<CodeScriptExecutionResult> {
Self::execute_with_params(code, language, None).await
}
/// 执行代码并传递参数
pub async fn execute_with_params(
code: &str,
language: LanguageScript,
params: Option<serde_json::Value>,
) -> Result<CodeScriptExecutionResult> {
match language {
LanguageScript::Js => JsRunner::new().run_with_params(code, params).await,
LanguageScript::Ts => TsRunner::new().run_with_params(code, params).await,
LanguageScript::Python => PythonRunner::new().run_with_params(code, params).await,
}
}
}
```
## 语言特定执行器
### JavaScript执行器
JavaScript代码通过[JsRunner](mdc:src/deno_runner/js_runner.rs)执行:
1. 准备JavaScript代码添加日志捕获和handler函数执行逻辑
2. 使用代码哈希值缓存处理过的代码
3. 使用Deno执行代码
4. 解析执行结果
### TypeScript执行器
TypeScript代码通过[TsRunner](mdc:src/deno_runner/ts_runner.rs)执行:
1. 准备TypeScript代码添加日志捕获和handler函数执行逻辑
2. 使用代码哈希值缓存处理过的代码
3. 使用Deno执行代码
4. 解析执行结果
### Python执行器
Python代码通过[PythonRunner](mdc:src/python_runner/python_runner.rs)执行:
1. 分析Python代码的依赖
2. 准备Python代码添加日志捕获和handler/main函数执行逻辑
3. 使用代码哈希值缓存处理过的代码
4. 使用uv在隔离环境中执行Python代码
5. 解析执行结果
## 参数传递
参数通过JSON格式传递给脚本
1. JavaScript/TypeScript参数直接传递给handler函数
2. Python参数通过环境变量`INPUT_JSON`传递然后在脚本中解析并传递给handler或main函数
## 结果处理
执行结果通过[CodeScriptExecutionResult](mdc:src/model/code_run_model.rs)结构体表示,包含:
- result: 执行结果通过handler/main函数返回
- logs: 执行过程中的日志
- success: 执行是否成功
- error: 执行错误(如果有)
## 缓存机制
为了提高性能,项目使用[CodeFileCache](mdc:src/cache)缓存处理过的代码:
1. 计算代码的哈希值
2. 检查是否存在对应的缓存
3. 如果存在,直接使用缓存;否则处理代码并缓存结果

View File

@@ -0,0 +1,72 @@
---
description:
globs:
alwaysApply: false
---
# 项目依赖
本项目使用多个Rust库来实现其功能。以下是主要依赖项及其用途
## Cargo.toml
```toml
[dependencies]
tokio = { version = "1.32", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
log = "0.4"
env_logger = "0.10"
anyhow = "1.0"
tempfile = "3.8"
regex = "1.9"
clap = { version = "4.4", features = ["derive"] }
thiserror = "1.0"
```
## 主要依赖项
### 异步运行时
- [tokio](https://crates.io/crates/tokio): 异步运行时,用于支持异步/await语法和并发执行
### 序列化/反序列化
- [serde](https://crates.io/crates/serde): 通用序列化/反序列化框架
- [serde_json](https://crates.io/crates/serde_json): JSON序列化/反序列化支持
### 错误处理
- [anyhow](https://crates.io/crates/anyhow): 简化错误处理的库
- [thiserror](https://crates.io/crates/thiserror): 用于定义自定义错误类型
### 日志记录
- [log](https://crates.io/crates/log): 日志记录接口
- [env_logger](https://crates.io/crates/env_logger): 基于环境变量的日志记录器
### 命令行参数解析
- [clap](https://crates.io/crates/clap): 命令行参数解析库,支持派生宏
### 其他工具
- [rmcp](https://crates.io/crates/rmcp): Model Context Protocol (MCP) SDK
- [tempfile](https://crates.io/crates/tempfile): 临时文件创建和管理
- [regex](https://crates.io/crates/regex): 正则表达式支持
## 外部依赖
除了Rust库外本项目还依赖以下外部工具
1. [Deno](https://deno.land/): 现代JavaScript和TypeScript运行时用于执行JavaScript代码
2. [uv](https://github.com/astral-sh/uv): Python包管理器和隔离环境工具用于安全执行Python代码
## 安装外部依赖
```bash
# 安装Deno
curl -fsSL https://deno.land/x/install/install.sh | sh
# 安装uv
curl -fsSL https://astral.sh/uv/install.sh | sh
```

View File

@@ -0,0 +1,101 @@
---
description:
globs:
alwaysApply: false
---
# 错误处理
本项目使用[anyhow](mdc:https:/crates.io/crates/anyhow)和[thiserror](mdc:https:/crates.io/crates/thiserror)库进行错误处理,错误类型定义在[error.rs](mdc:src/error.rs)中。
## 错误类型
```rust
#[derive(Error, Debug)]
pub enum AppError {
#[error("Failed to execute code: {0}")]
ExecutionError(String),
#[error("Failed to parse output: {0}")]
ParseError(String),
#[error("Failed to create temporary file: {0}")]
IoError(#[from] std::io::Error),
#[error("Failed to parse JSON: {0}")]
JsonError(#[from] serde_json::Error),
#[error("Missing required field: {0}")]
MissingField(String),
#[error("Unsupported language: {0}")]
UnsupportedLanguage(String),
#[error("Handler function not found")]
HandlerNotFound,
#[error("MCP error: {0}")]
McpError(String),
#[error("{0}")]
Other(String),
}
pub type AppResult<T> = Result<T, AppError>;
```
## 错误处理流程
1. 在代码执行过程中使用`anyhow::Result`类型传递错误
2. 使用`?`操作符传播错误
3. 使用`context`方法添加错误上下文
4. 在`main`函数中处理所有未捕获的错误
## 示例
```rust
// 读取代码文件
fn get_code(args: &CodeArgs) -> Result<String> {
if let Some(file) = &args.file {
fs::read_to_string(file).context("Failed to read code file")
} else if let Some(code) = &args.code {
Ok(code.clone())
} else {
anyhow::bail!("Either file or code must be provided")
}
}
// 执行JavaScript代码
fn execute_js(code: &str, show_logs: bool) -> Result<ExecutionResult> {
// Prepare the JavaScript code with wrapped handler
let wrapped_code = prepare_js_code(code, show_logs);
// Create a temporary file
let mut temp_file = NamedTempFile::new()?;
write!(temp_file.as_file_mut(), "{}", wrapped_code)?;
// Execute with Deno
let output = Command::new("deno")
.arg("run")
.arg("--allow-all")
.arg(temp_file.path())
.output()
.context("Failed to execute Deno")?;
// Parse the output
parse_execution_output(&output.stdout, &output.stderr)
}
```
## 错误输出
执行结果中的错误通过`ExecutionResult`结构体的`error`字段返回,并在`print_result`函数中输出:
```rust
fn print_result(result: ExecutionResult) {
// ...
if let Some(error) = result.error {
eprintln!("Error: {}", error);
}
}
```

View File

@@ -0,0 +1,138 @@
---
description:
globs:
alwaysApply: false
---
# 示例代码
本项目包含JavaScript和Python的示例代码用于测试代码执行功能。
## JavaScript示例
[examples/test_js.js](mdc:examples/test_js.js)是一个简单的JavaScript示例包含
```javascript
// Sample JavaScript file with handler function
// Log some debug information
console.log("Initializing JavaScript test...");
// Define a simple add function
function add(a, b) {
console.log(`Adding ${a} + ${b}`);
return a + b;
}
// Some processing
const numbers = [1, 2, 3, 4, 5];
console.log("Processing numbers:", numbers);
// Handler function that will be called to get the result
function handler() {
console.log("Handler function called");
// Calculate sum
const sum = numbers.reduce((acc, num) => add(acc, num), 0);
console.log("Final calculation completed");
return `The sum of [${numbers.join(", ")}] is ${sum}`;
}
```
执行这个示例将输出:
```
--- Logs ---
Initializing JavaScript test...
Processing numbers: [1,2,3,4,5]
Handler function called
Adding 0 + 1
Adding 1 + 2
Adding 3 + 3
Adding 6 + 4
Adding 10 + 5
Final calculation completed
------------
Result: The sum of [1, 2, 3, 4, 5] is 15
```
## Python示例
[examples/test_python.py](mdc:examples/test_python.py)是一个简单的Python示例包含
```python
#!/usr/bin/env python3
# Sample Python file with handler function
import time
# Log some debug information
print("Initializing Python test...")
# Define a simple function
def multiply(a, b):
print(f"Multiplying {a} * {b}")
return a * b
# Some processing
numbers = [1, 2, 3, 4, 5]
print(f"Processing numbers: {numbers}")
# Handler function that will be called to get the result
def handler():
print("Handler function called")
# Calculate product
product = 1
for num in numbers:
product = multiply(product, num)
print("Final calculation completed")
return f"The product of {numbers} is {product}"
# This part won't be executed when the code is run through the MCP runner
if __name__ == "__main__":
print("Running directly, calling handler...")
result = handler()
print(f"Result: {result}")
```
执行这个示例将输出:
```
--- Logs ---
Handler function called
Multiplying 1 * 1
Multiplying 1 * 2
Multiplying 2 * 3
Multiplying 6 * 4
Multiplying 24 * 5
Final calculation completed
------------
Result: The product of [1, 2, 3, 4, 5] is 120
```
## 如何创建自己的示例
创建自己的示例代码时,需要遵循以下规则:
1. 必须包含一个名为`handler`的函数,作为执行结果的返回点
2. `handler`函数的返回值将作为执行结果
3. 使用`console.log`JavaScript或`print`Python输出日志
4. 可以定义其他函数和变量,它们将在执行过程中被使用
示例:
```javascript
// JavaScript示例
function handler() {
return "Hello from JavaScript!";
}
```
```python
# Python示例
def handler():
return "Hello from Python!"
```

View File

@@ -0,0 +1,98 @@
---
description:
globs:
alwaysApply: false
---
# 测试脚本示例指南
本项目包含多种语言的测试脚本示例,位于`fixtures`目录下。这些示例展示了如何编写可被本工具执行的JavaScript、TypeScript和Python脚本。
## JavaScript示例
### 基本执行
[test_js.js](mdc:fixtures/test_js.js) - 基本的JavaScript执行示例
- 展示了如何使用`console.log`输出日志
- 定义了`handler`函数作为执行结果的返回点
### 参数传递
[test_js_params.js](mdc:fixtures/test_js_params.js) - 带参数的JavaScript执行示例
- 展示了如何接收和处理传入的参数
- 演示了如何根据参数执行不同的逻辑
### 函数示例
[rfunction_test1.js](mdc:fixtures/rfunction_test1.js) - 函数式JavaScript示例
- 展示了如何定义和使用函数
- 演示了如何处理和返回复杂数据结构
## TypeScript示例
### 基本执行
[test_ts.ts](mdc:fixtures/test_ts.ts) - 基本的TypeScript执行示例
- 展示了TypeScript的类型定义
- 定义了带类型的`handler`函数
### 参数传递
[test_ts_params.ts](mdc:fixtures/test_ts_params.ts) - 带参数的TypeScript执行示例
- 展示了如何定义参数类型
- 演示了TypeScript中的类型安全参数处理
## Python示例
### 基本执行
[test_python.py](mdc:fixtures/test_python.py) - 基本的Python执行示例
- 使用`handler`函数作为执行结果的返回点
- 展示了如何使用Python进行基本计算和日志输出
### 参数传递
[test_python_params.py](mdc:fixtures/test_python_params.py) - 带参数的Python执行示例
- 展示了如何接收和处理传入的参数
- 演示了如何返回包含多个字段的结果
### 类型示例
[test_python_types.py](mdc:fixtures/test_python_types.py) - 不同返回类型的Python示例
- 展示了如何返回不同类型的值(字符串、数字、布尔值、列表、字典等)
- 演示了不同类型在JSON序列化中的处理方式
### 函数示例
[rfunction_python.py](mdc:fixtures/rfunction_python.py) - 函数式Python示例
- 展示了如何定义和使用Python函数
- 演示了如何处理和返回复杂数据结构
## 使用示例
以下是如何使用这些示例脚本的命令:
```bash
# 执行基本JavaScript示例
cargo run -- --show-logs js -f fixtures/test_js.js
# 执行带参数的JavaScript示例
cargo run -- --show-logs js -f fixtures/test_js_params.js -p '{"name":"User"}'
# 执行基本TypeScript示例
cargo run -- --show-logs ts -f fixtures/test_ts.ts
# 执行带参数的TypeScript示例
cargo run -- --show-logs ts -f fixtures/test_ts_params.ts -p '{"a":10, "b":20, "name":"User"}'
# 执行基本Python示例
cargo run -- --show-logs python -f fixtures/test_python.py
# 执行带参数的Python示例
cargo run -- --show-logs python -f fixtures/test_python_params.py -p '{"a":10, "b":20}'
# 执行不同类型的Python示例
cargo run -- --show-logs python -f fixtures/test_python_types.py -p '{"type":"string"}'
cargo run -- --show-logs python -f fixtures/test_python_types.py -p '{"type":"number"}'
cargo run -- --show-logs python -f fixtures/test_python_types.py -p '{"type":"list"}'
cargo run -- --show-logs python -f fixtures/test_python_types.py -p '{"type":"dict"}'
```

View File

@@ -0,0 +1,146 @@
---
description:
globs:
alwaysApply: false
---
# MCP SDK集成
本项目支持Model Context Protocol (MCP) SDK集成允许通过标准化协议执行代码。MCP相关功能主要在[mcp.rs](mdc:src/mcp.rs)中实现。
## 核心数据结构
```rust
#[derive(Serialize, Deserialize, Debug)]
pub struct CodeExecutionParams {
pub code: String,
pub language: String,
pub show_logs: bool,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct CodeExecutionResult {
pub logs: Vec<String>,
pub result: Option<String>,
pub error: Option<String>,
}
```
## JavaScript执行
MCP中的JavaScript执行使用以下包装代码
```javascript
// MCP SDK integration for JavaScript
// Note: MCP SDK is not required for basic functionality
// Log capture setup
const logs = [];
const originalConsoleLog = console.log;
console.log = function() {
const message = Array.from(arguments).map(arg =>
typeof arg === 'object' && arg !== null ? JSON.stringify(arg) : String(arg)
).join(' ');
logs.push(message);
if (show_logs) {
originalConsoleLog.apply(console, arguments);
}
};
async function mcpExecute() {
try {
// User code here
// Execute handler
let result = null;
if (typeof handler === 'function') {
result = await handler();
}
return {
logs: logs,
result: result !== undefined ? String(result) : null,
error: null
};
} catch (error) {
return {
logs: logs,
result: null,
error: error.toString()
};
}
}
// Execute and return results
mcpExecute().then(result => {
originalConsoleLog(JSON.stringify(result));
});
```
## Python执行
MCP中的Python执行使用以下包装代码
```python
# MCP SDK integration for Python
# Note: MCP SDK is not required for basic functionality
import sys
import json
import io
from contextlib import redirect_stdout
# Store logs
logs = []
# Create custom stdout to capture logs
class LogCapture(io.StringIO):
def write(self, text):
if text.strip():
logs.append(text.rstrip())
if show_logs:
sys.__stdout__.write(text)
def mcp_execute():
try:
// User code here
// Execute handler function and capture result
result = None
with redirect_stdout(LogCapture()):
if 'handler' in globals() and callable(handler):
result = handler()
return {
"logs": logs,
"result": str(result) if result is not None else None,
"error": None
}
except Exception as e:
return {
"logs": logs,
"result": None,
"error": str(e)
}
# Execute and print results
result = mcp_execute()
print(json.dumps(result))
```
## 执行流程
MCP执行流程由[execute_with_mcp](mdc:src/mcp.rs#L138)函数处理:
1. 创建临时文件并写入包装后的代码
2. 根据语言类型选择执行命令Deno或uv
3. 执行代码并捕获输出
4. 解析JSON格式的执行结果
5. 如果无法解析JSON则返回原始输出
## 使用方法
在命令行中使用`--use-mcp`参数启用MCP SDK集成
```bash
cargo run -- --use-mcp js -c "function handler() { return 'Hello from MCP JS'; }"
cargo run -- --use-mcp python -f examples/test_python.py
```

View File

@@ -0,0 +1,50 @@
---
description:
globs:
alwaysApply: false
---
# 项目概述
这是一个使用Rust开发的命令行工具用于执行JavaScript、TypeScript和Python代码。该工具支持以下功能
1. 执行JavaScript代码使用Deno运行时
2. 执行TypeScript代码使用Deno运行时
3. 执行Python代码使用uv提供隔离环境
4. 捕获并区分脚本中的日志输出和执行结果
5. 支持JavaScript/TypeScript的handler函数和Python的handler/main函数作为执行结果的返回点
6. 通过环境变量传递参数给脚本
7. 可以通过参数控制是否显示日志输出
8. 支持MCP SDK集成
## 主要文件
- [src/main.rs](mdc:src/main.rs) - 应用程序入口点,处理命令行参数和执行流程
- [src/lib.rs](mdc:src/lib.rs) - 库入口点,导出模块和类型
- [src/model/code_run_model.rs](mdc:src/model/code_run_model.rs) - 代码执行模型和结果处理
- [src/deno_runner/js_runner.rs](mdc:src/deno_runner/js_runner.rs) - JavaScript代码执行器
- [src/deno_runner/ts_runner.rs](mdc:src/deno_runner/ts_runner.rs) - TypeScript代码执行器
- [src/python_runner/python_runner.rs](mdc:src/python_runner/python_runner.rs) - Python代码执行器
- [src/cache/](mdc:src/cache) - 代码缓存管理
- [fixtures/](mdc:fixtures) - 测试脚本示例
## 使用示例
```bash
# 执行JavaScript文件
cargo run -- --show-logs js -f fixtures/test_js.js
# 执行TypeScript文件
cargo run -- --show-logs ts -f fixtures/test_ts.ts
# 执行Python文件
cargo run -- --show-logs python -f fixtures/test_python.py
# 带参数执行Python文件
cargo run -- --show-logs python -f fixtures/test_python_params.py -p '{"a":10, "b":20}'
# 直接执行JavaScript代码
cargo run -- js -c "function handler(input) { return 'Hello from JS: ' + input.name; }" -p '{"name":"User"}'
# 直接执行Python代码
cargo run -- python -c "def handler(args): return 'Hello from Python: ' + args.get('name', 'Guest')" -p '{"name":"User"}'
```

View File

@@ -0,0 +1,143 @@
---
description:
globs:
alwaysApply: false
---
# Python代码执行
本项目使用`uv`在隔离环境中执行Python代码提供安全可靠的执行环境。以下是Python代码执行的详细流程
## Python运行器
Python代码通过[PythonRunner](mdc:src/python_runner/python_runner.rs)执行,实现了`RunCode`特性:
```rust
pub struct PythonRunner;
impl RunCode for PythonRunner {
async fn run(&self, code: &str) -> Result<CodeScriptExecutionResult> {
// 实现代码...
}
async fn run_with_params(&self, code: &str, params: Option<serde_json::Value>) -> Result<CodeScriptExecutionResult> {
// 实现代码...
}
}
```
## 依赖解析
Python代码的依赖通过[python_dependencies.rs](mdc:src/python_runner/dependencies/python_dependencies.rs)解析:
1. 使用Pest解析器分析Python代码中的import语句
2. 支持常规import语句和importlib动态导入
3. 提取所有导入的模块名称
```rust
pub fn parse_import(python_code: &str) -> Result<Vec<String>> {
// 使用Pest解析器分析Python代码
let pairs = ImportParser::parse(Rule::file, &input)?;
// 提取模块名称
let mut imported_modules = Vec::new();
// 处理各种import语句...
Ok(imported_modules)
}
```
## 代码准备
Python代码在执行前需要进行包装添加日志捕获和函数执行逻辑
```rust
fn prepare_python_code(&self, code: &str, show_logs: bool) -> String {
// 创建包装代码,包括:
// 1. 日志捕获
// 2. 参数解析
// 3. 执行handler或main函数
// 4. 结果格式化
}
```
包装代码主要功能:
1. 捕获标准输出作为日志
2. 从环境变量`INPUT_JSON`解析参数
3. 优先执行`handler`函数,如果不存在则执行`main`函数
4. 将执行结果和日志格式化为JSON
## 参数传递
参数通过环境变量`INPUT_JSON`传递给Python脚本
```rust
// 将参数序列化为JSON字符串
let params_json = match params {
Some(p) => serde_json::to_string(&p)?,
None => "{}".to_string(),
};
// 通过环境变量传递参数
execute_command.env("INPUT_JSON", &params_json);
```
在Python脚本中参数通过以下方式获取
```python
# 从环境变量获取输入参数
args = {}
try:
input_json = os.environ.get('INPUT_JSON')
if input_json:
args = json.loads(input_json)
except Exception as e:
print(f"解析输入参数失败: {e}")
```
## 执行流程
1. 计算代码哈希值,检查缓存
2. 如果缓存存在,直接使用;否则:
- 分析代码依赖
- 准备包装后的代码
- 保存到缓存
3. 使用`uv`命令在隔离环境中执行代码:
```rust
let mut execute_command = Command::new("uv");
execute_command
.arg("run")
.arg("-s") // 明确指定作为脚本运行
.arg("--isolated") // 在隔离环境中运行
.arg("-p")
.arg("python3") // 指定Python解释器
.env("INPUT_JSON", &params_json) // 通过环境变量传递参数
.arg(&temp_path)
```
4. 解析执行结果,提取日志和返回值
## 结果处理
执行结果通过JSON格式返回包含三个字段
- `logs`: 执行过程中的日志数组
- `result`: 执行结果(可能是字符串、数字、布尔值、对象等)
- `error`: 执行错误(如果有)
```json
{
"logs": ["日志1", "日志2", ...],
"result": "执行结果",
"error": null
}
```
## 支持的返回类型
Python脚本可以返回多种类型的值
1. 字符串
2. 数字
3. 布尔值
4. 列表/数组
5. 字典/对象
6. None/null
所有复杂类型列表、字典都会被序列化为JSON字符串。