新增: 初始化 DevFlow 项目仓库
Tauri 2 + Vue 3 + Vite 6 桌面应用,Rust workspace 含 13 个 crate (df-ai / df-storage / df-workflow / df-core / df-execute 等)。 核心能力:AI 聊天 agentic 循环(工具调用+人工审批)、工作流引擎、 任务/想法/项目/阶段管理、可追溯性,及配套前端组件。
This commit is contained in:
13
crates/df-execute/Cargo.toml
Normal file
13
crates/df-execute/Cargo.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "df-execute"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
df-core = { path = "../df-core" }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
async-trait = { workspace = true }
|
||||
anyhow = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
46
crates/df-execute/src/docker.rs
Normal file
46
crates/df-execute/src/docker.rs
Normal file
@@ -0,0 +1,46 @@
|
||||
//! Docker 执行器 — 在容器中运行任务
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Docker 容器执行请求
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct DockerRequest {
|
||||
/// 镜像名称
|
||||
pub image: String,
|
||||
/// 容器内执行的命令
|
||||
pub command: Option<String>,
|
||||
/// 环境变量
|
||||
pub env: std::collections::HashMap<String, String>,
|
||||
/// 挂载卷
|
||||
pub volumes: Vec<VolumeMount>,
|
||||
/// 是否在执行后自动删除容器
|
||||
pub auto_remove: bool,
|
||||
}
|
||||
|
||||
/// 卷挂载
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct VolumeMount {
|
||||
pub host_path: String,
|
||||
pub container_path: String,
|
||||
pub read_only: bool,
|
||||
}
|
||||
|
||||
/// Docker 执行结果
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct DockerResult {
|
||||
pub stdout: String,
|
||||
pub stderr: String,
|
||||
pub exit_code: Option<i32>,
|
||||
}
|
||||
|
||||
/// 在 Docker 容器中执行命令
|
||||
///
|
||||
/// TODO: 实现 Docker API 调用或 CLI 包装
|
||||
pub async fn execute(_request: DockerRequest) -> anyhow::Result<DockerResult> {
|
||||
tracing::info!("Docker 执行: TODO");
|
||||
Ok(DockerResult {
|
||||
stdout: String::new(),
|
||||
stderr: String::new(),
|
||||
exit_code: None,
|
||||
})
|
||||
}
|
||||
47
crates/df-execute/src/git_ops.rs
Normal file
47
crates/df-execute/src/git_ops.rs
Normal file
@@ -0,0 +1,47 @@
|
||||
//! Git 操作 — 克隆、提交、推送、合并等
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Git 操作类型
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GitAction {
|
||||
Clone,
|
||||
Commit,
|
||||
Push,
|
||||
Pull,
|
||||
Merge,
|
||||
Checkout,
|
||||
CreateBranch,
|
||||
}
|
||||
|
||||
/// Git 操作请求
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct GitRequest {
|
||||
/// 操作类型
|
||||
pub action: GitAction,
|
||||
/// 仓库路径(本地路径或远程 URL)
|
||||
pub repo: String,
|
||||
/// 分支名
|
||||
pub branch: Option<String>,
|
||||
/// 提交消息
|
||||
pub message: Option<String>,
|
||||
}
|
||||
|
||||
/// Git 操作结果
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct GitResult {
|
||||
pub success: bool,
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
/// 执行 Git 操作
|
||||
///
|
||||
/// TODO: 实现完整的 Git 操作(可包装 git CLI 或使用 git2 crate)
|
||||
pub async fn execute(_request: GitRequest) -> anyhow::Result<GitResult> {
|
||||
tracing::info!("Git 操作: TODO");
|
||||
Ok(GitResult {
|
||||
success: true,
|
||||
message: "TODO: 未实现".to_string(),
|
||||
})
|
||||
}
|
||||
6
crates/df-execute/src/lib.rs
Normal file
6
crates/df-execute/src/lib.rs
Normal file
@@ -0,0 +1,6 @@
|
||||
//! df-execute: 执行运行时 — Shell、Docker、SSH、Git 操作
|
||||
|
||||
pub mod docker;
|
||||
pub mod git_ops;
|
||||
pub mod shell;
|
||||
pub mod ssh;
|
||||
73
crates/df-execute/src/shell.rs
Normal file
73
crates/df-execute/src/shell.rs
Normal file
@@ -0,0 +1,73 @@
|
||||
//! Shell 执行器 — 通过 tokio::process 执行 shell 命令
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Shell 命令执行结果
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ShellResult {
|
||||
/// 标准输出
|
||||
pub stdout: String,
|
||||
/// 标准错误
|
||||
pub stderr: String,
|
||||
/// 退出码
|
||||
pub exit_code: Option<i32>,
|
||||
/// 执行耗时(毫秒)
|
||||
pub duration_ms: u64,
|
||||
}
|
||||
|
||||
/// Shell 命令执行请求
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ShellRequest {
|
||||
/// 要执行的命令
|
||||
pub command: String,
|
||||
/// 工作目录
|
||||
pub working_dir: Option<String>,
|
||||
/// 环境变量
|
||||
pub env: std::collections::HashMap<String, String>,
|
||||
/// 超时时间(秒),None 表示不超时
|
||||
pub timeout_secs: Option<u64>,
|
||||
}
|
||||
|
||||
/// 执行 Shell 命令
|
||||
///
|
||||
/// TODO: 完整实现,支持超时、环境变量、工作目录等
|
||||
pub async fn execute(request: ShellRequest) -> anyhow::Result<ShellResult> {
|
||||
let start = std::time::Instant::now();
|
||||
|
||||
let mut cmd = if cfg!(windows) {
|
||||
let mut c = tokio::process::Command::new("cmd");
|
||||
c.arg("/C").arg(&request.command);
|
||||
c
|
||||
} else {
|
||||
let mut c = tokio::process::Command::new("sh");
|
||||
c.arg("-c").arg(&request.command);
|
||||
c
|
||||
};
|
||||
|
||||
if let Some(dir) = &request.working_dir {
|
||||
cmd.current_dir(dir);
|
||||
}
|
||||
|
||||
for (key, value) in &request.env {
|
||||
cmd.env(key, value);
|
||||
}
|
||||
|
||||
let output = match request.timeout_secs {
|
||||
Some(secs) => tokio::time::timeout(
|
||||
std::time::Duration::from_secs(secs),
|
||||
cmd.output(),
|
||||
)
|
||||
.await
|
||||
.map_err(|_| anyhow::anyhow!("命令执行超时: {}秒", secs))??,
|
||||
None => cmd.output().await?,
|
||||
};
|
||||
|
||||
let duration = start.elapsed().as_millis() as u64;
|
||||
|
||||
Ok(ShellResult {
|
||||
stdout: String::from_utf8_lossy(&output.stdout).to_string(),
|
||||
stderr: String::from_utf8_lossy(&output.stderr).to_string(),
|
||||
exit_code: output.status.code(),
|
||||
duration_ms: duration,
|
||||
})
|
||||
}
|
||||
38
crates/df-execute/src/ssh.rs
Normal file
38
crates/df-execute/src/ssh.rs
Normal file
@@ -0,0 +1,38 @@
|
||||
//! SSH 执行器 — 远程命令执行
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// SSH 执行请求
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct SshRequest {
|
||||
/// 主机地址
|
||||
pub host: String,
|
||||
/// 端口
|
||||
pub port: u16,
|
||||
/// 用户名
|
||||
pub user: String,
|
||||
/// 要执行的命令
|
||||
pub command: String,
|
||||
/// 超时时间(秒)
|
||||
pub timeout_secs: Option<u64>,
|
||||
}
|
||||
|
||||
/// SSH 执行结果
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct SshResult {
|
||||
pub stdout: String,
|
||||
pub stderr: String,
|
||||
pub exit_code: Option<i32>,
|
||||
}
|
||||
|
||||
/// 通过 SSH 执行远程命令
|
||||
///
|
||||
/// TODO: 实现SSH连接(可用 ssh2 crate 或包装 ssh 命令)
|
||||
pub async fn execute(_request: SshRequest) -> anyhow::Result<SshResult> {
|
||||
tracing::info!("SSH 执行: TODO");
|
||||
Ok(SshResult {
|
||||
stdout: String::new(),
|
||||
stderr: String::new(),
|
||||
exit_code: None,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user