新增: 初始化 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-task/Cargo.toml
Normal file
13
crates/df-task/Cargo.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "df-task"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
df-core = { path = "../df-core" }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
anyhow = { workspace = true }
|
||||
chrono = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
74
crates/df-task/src/branch.rs
Normal file
74
crates/df-task/src/branch.rs
Normal file
@@ -0,0 +1,74 @@
|
||||
//! 分支管理 — Git 分支的创建、跟踪与生命周期
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use df_core::types::{BranchId, ProjectId, TaskId};
|
||||
|
||||
/// 分支状态
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum BranchStatus {
|
||||
/// 活跃开发中
|
||||
Active,
|
||||
/// 待合并
|
||||
ReadyToMerge,
|
||||
/// 已合并
|
||||
Merged,
|
||||
/// 已删除
|
||||
Deleted,
|
||||
}
|
||||
|
||||
/// 分支实体
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Branch {
|
||||
/// 唯一 ID
|
||||
pub id: BranchId,
|
||||
/// 分支名称
|
||||
pub name: String,
|
||||
/// 所属项目 ID
|
||||
pub project_id: ProjectId,
|
||||
/// 关联任务 ID
|
||||
pub task_id: Option<TaskId>,
|
||||
/// 基于的分支(通常是 main)
|
||||
pub base_branch: String,
|
||||
/// 当前状态
|
||||
pub status: BranchStatus,
|
||||
/// 创建时间
|
||||
pub created_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
/// 分支管理器
|
||||
pub struct BranchManager;
|
||||
|
||||
impl BranchManager {
|
||||
/// 为任务创建分支
|
||||
///
|
||||
/// TODO: 接入 df-execute 的 git_ops 执行实际的 Git 操作
|
||||
pub fn create_for_task(
|
||||
task_id: &TaskId,
|
||||
project_id: &ProjectId,
|
||||
base_branch: &str,
|
||||
) -> Branch {
|
||||
// 生成分支名称:task/{task_id 前缀}
|
||||
let short_id = &task_id[..8.min(task_id.len())];
|
||||
let branch_name = format!("task/{}", short_id);
|
||||
|
||||
Branch {
|
||||
id: df_core::types::new_id(),
|
||||
name: branch_name,
|
||||
project_id: project_id.clone(),
|
||||
task_id: Some(task_id.clone()),
|
||||
base_branch: base_branch.to_string(),
|
||||
status: BranchStatus::Active,
|
||||
created_at: chrono::Utc::now(),
|
||||
}
|
||||
}
|
||||
|
||||
/// 列出项目的所有活跃分支
|
||||
///
|
||||
/// TODO: 接入 df-execute 的 git_ops
|
||||
pub fn list_active(_project_id: &ProjectId) -> Vec<Branch> {
|
||||
// TODO: 实现
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
6
crates/df-task/src/lib.rs
Normal file
6
crates/df-task/src/lib.rs
Normal file
@@ -0,0 +1,6 @@
|
||||
//! df-task: 任务/分支管理 — 任务 CRUD、分支管理、合并协调、发布计划
|
||||
|
||||
pub mod branch;
|
||||
pub mod merge;
|
||||
pub mod release;
|
||||
pub mod task;
|
||||
91
crates/df-task/src/merge.rs
Normal file
91
crates/df-task/src/merge.rs
Normal file
@@ -0,0 +1,91 @@
|
||||
//! 合并协调器 — 分支合并、冲突检测、AI 辅助解决
|
||||
|
||||
use df_core::types::{BranchId, TaskId};
|
||||
|
||||
/// 合并状态
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum MergeStatus {
|
||||
/// 待合并
|
||||
Pending,
|
||||
/// 自动合并中
|
||||
AutoMerging,
|
||||
/// 存在冲突,等待解决
|
||||
Conflicted,
|
||||
/// 已解决冲突
|
||||
Resolved,
|
||||
/// 合并完成
|
||||
Completed,
|
||||
/// 合并失败
|
||||
Failed,
|
||||
}
|
||||
|
||||
/// 合并请求
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MergeRequest {
|
||||
pub id: String,
|
||||
pub source_branch: BranchId,
|
||||
pub target_branch: String,
|
||||
pub task_id: Option<TaskId>,
|
||||
pub status: MergeStatus,
|
||||
pub conflicts: Vec<Conflict>,
|
||||
}
|
||||
|
||||
/// 冲突信息
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Conflict {
|
||||
pub file_path: String,
|
||||
pub conflict_type: ConflictType,
|
||||
pub description: String,
|
||||
pub auto_resolvable: bool,
|
||||
}
|
||||
|
||||
/// 冲突类型
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ConflictType {
|
||||
/// 文件级别冲突(双方修改了同一文件)
|
||||
FileModified,
|
||||
/// 删除/修改冲突
|
||||
DeleteModify,
|
||||
/// 二进制文件冲突
|
||||
Binary,
|
||||
}
|
||||
|
||||
/// 合并协调器
|
||||
pub struct MergeCoordinator;
|
||||
|
||||
impl MergeCoordinator {
|
||||
/// 创建合并请求
|
||||
///
|
||||
/// TODO: 接入 Git 操作执行实际合并
|
||||
pub fn create_request(
|
||||
source_branch: BranchId,
|
||||
target_branch: String,
|
||||
task_id: Option<TaskId>,
|
||||
) -> MergeRequest {
|
||||
MergeRequest {
|
||||
id: df_core::types::new_id(),
|
||||
source_branch,
|
||||
target_branch,
|
||||
task_id,
|
||||
status: MergeStatus::Pending,
|
||||
conflicts: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// 检测冲突
|
||||
///
|
||||
/// TODO: 调用 git merge --no-commit --no-ff 检测
|
||||
pub fn detect_conflicts(_merge_request: &MergeRequest) -> Vec<Conflict> {
|
||||
// TODO: 实现冲突检测
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
/// AI 辅助解决冲突
|
||||
///
|
||||
/// TODO: 调用 df-ai 的 LLM 分析冲突并提供解决方案
|
||||
pub fn ai_resolve_conflict(_conflict: &Conflict) -> anyhow::Result<String> {
|
||||
// TODO: 实现 AI 辅助冲突解决
|
||||
tracing::warn!("AI 冲突解决尚未实现");
|
||||
Ok(String::new())
|
||||
}
|
||||
}
|
||||
132
crates/df-task/src/release.rs
Normal file
132
crates/df-task/src/release.rs
Normal file
@@ -0,0 +1,132 @@
|
||||
//! 发布计划 — 多任务合并、版本号管理、发布流程
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use df_core::types::{ProjectId, ReleaseId, TaskId};
|
||||
|
||||
/// 发布状态
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ReleaseStatus {
|
||||
/// 计划中
|
||||
Planned,
|
||||
/// 准备中(收集已完成的任务)
|
||||
Preparing,
|
||||
/// 构建中
|
||||
Building,
|
||||
/// 测试中
|
||||
Testing,
|
||||
/// 待发布
|
||||
Ready,
|
||||
/// 发布中
|
||||
Releasing,
|
||||
/// 已发布
|
||||
Released,
|
||||
/// 已回滚
|
||||
RolledBack,
|
||||
/// 已取消
|
||||
Cancelled,
|
||||
}
|
||||
|
||||
/// 版本号
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct SemanticVersion {
|
||||
pub major: u32,
|
||||
pub minor: u32,
|
||||
pub patch: u32,
|
||||
pub pre_release: Option<String>,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for SemanticVersion {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match &self.pre_release {
|
||||
Some(pre) => write!(f, "{}.{}.{}-{}", self.major, self.minor, self.patch, pre),
|
||||
None => write!(f, "{}.{}.{}", self.major, self.minor, self.patch),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 发布计划
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Release {
|
||||
/// 唯一 ID
|
||||
pub id: ReleaseId,
|
||||
/// 所属项目 ID
|
||||
pub project_id: ProjectId,
|
||||
/// 版本号
|
||||
pub version: SemanticVersion,
|
||||
/// 当前状态
|
||||
pub status: ReleaseStatus,
|
||||
/// 包含的任务 ID 列表
|
||||
pub task_ids: Vec<TaskId>,
|
||||
/// 变更日志
|
||||
pub changelog: Option<String>,
|
||||
/// 创建时间
|
||||
pub created_at: chrono::DateTime<chrono::Utc>,
|
||||
/// 发布时间
|
||||
pub released_at: Option<chrono::DateTime<chrono::Utc>>,
|
||||
}
|
||||
|
||||
/// 版本号递增类型
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum VersionBump {
|
||||
Major,
|
||||
Minor,
|
||||
Patch,
|
||||
}
|
||||
|
||||
/// 发布管理器
|
||||
pub struct ReleaseManager;
|
||||
|
||||
impl ReleaseManager {
|
||||
/// 创建发布计划
|
||||
pub fn create(
|
||||
project_id: &ProjectId,
|
||||
version: SemanticVersion,
|
||||
task_ids: Vec<TaskId>,
|
||||
) -> Release {
|
||||
Release {
|
||||
id: df_core::types::new_id(),
|
||||
project_id: project_id.clone(),
|
||||
version,
|
||||
status: ReleaseStatus::Planned,
|
||||
task_ids,
|
||||
changelog: None,
|
||||
created_at: chrono::Utc::now(),
|
||||
released_at: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// 自动生成变更日志
|
||||
///
|
||||
/// TODO: 从 Git 提交历史、任务描述中生成
|
||||
pub fn generate_changelog(_release: &mut Release) -> anyhow::Result<()> {
|
||||
// TODO: 实现
|
||||
tracing::warn!("自动变更日志生成尚未实现");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 自动递增版本号
|
||||
pub fn bump_version(current: &SemanticVersion, bump: VersionBump) -> SemanticVersion {
|
||||
match bump {
|
||||
VersionBump::Major => SemanticVersion {
|
||||
major: current.major + 1,
|
||||
minor: 0,
|
||||
patch: 0,
|
||||
pre_release: None,
|
||||
},
|
||||
VersionBump::Minor => SemanticVersion {
|
||||
major: current.major,
|
||||
minor: current.minor + 1,
|
||||
patch: 0,
|
||||
pre_release: None,
|
||||
},
|
||||
VersionBump::Patch => SemanticVersion {
|
||||
major: current.major,
|
||||
minor: current.minor,
|
||||
patch: current.patch + 1,
|
||||
pre_release: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
87
crates/df-task/src/task.rs
Normal file
87
crates/df-task/src/task.rs
Normal file
@@ -0,0 +1,87 @@
|
||||
//! 任务管理 — 任务实体与 CRUD
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use df_core::types::{BranchId, Priority, ProjectId, TaskId, TaskStatus};
|
||||
|
||||
/// 任务实体
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Task {
|
||||
/// 唯一 ID
|
||||
pub id: TaskId,
|
||||
/// 所属项目 ID
|
||||
pub project_id: ProjectId,
|
||||
/// 任务标题
|
||||
pub title: String,
|
||||
/// 任务描述
|
||||
pub description: String,
|
||||
/// 当前状态
|
||||
pub status: TaskStatus,
|
||||
/// 优先级
|
||||
pub priority: Priority,
|
||||
/// 关联分支名称
|
||||
pub branch_name: Option<String>,
|
||||
/// 关联分支 ID
|
||||
pub branch_id: Option<BranchId>,
|
||||
/// 指派人
|
||||
pub assignee: Option<String>,
|
||||
/// 标签
|
||||
pub tags: Vec<String>,
|
||||
/// 预估工时(小时)
|
||||
pub estimate_hours: Option<f64>,
|
||||
/// 实际工时(小时)
|
||||
pub actual_hours: Option<f64>,
|
||||
/// 创建时间
|
||||
pub created_at: chrono::DateTime<chrono::Utc>,
|
||||
/// 更新时间
|
||||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
/// 创建任务的输入
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct CreateTaskInput {
|
||||
pub project_id: ProjectId,
|
||||
pub title: String,
|
||||
pub description: String,
|
||||
#[serde(default)]
|
||||
pub priority: Priority,
|
||||
pub assignee: Option<String>,
|
||||
pub tags: Vec<String>,
|
||||
pub estimate_hours: Option<f64>,
|
||||
}
|
||||
|
||||
/// 任务管理器
|
||||
pub struct TaskManager;
|
||||
|
||||
impl TaskManager {
|
||||
/// 创建新任务
|
||||
///
|
||||
/// TODO: 接入存储层持久化
|
||||
pub fn create(input: CreateTaskInput) -> Task {
|
||||
let now = chrono::Utc::now();
|
||||
Task {
|
||||
id: df_core::types::new_id(),
|
||||
project_id: input.project_id,
|
||||
title: input.title,
|
||||
description: input.description,
|
||||
status: TaskStatus::Todo,
|
||||
priority: input.priority,
|
||||
branch_name: None,
|
||||
branch_id: None,
|
||||
assignee: input.assignee,
|
||||
tags: input.tags,
|
||||
estimate_hours: input.estimate_hours,
|
||||
actual_hours: None,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
}
|
||||
}
|
||||
|
||||
/// 更新任务状态
|
||||
pub fn transition_status(task: &mut Task, new_status: TaskStatus) -> anyhow::Result<()> {
|
||||
// TODO: 校验状态转换合法性
|
||||
task.status = new_status;
|
||||
task.updated_at = chrono::Utc::now();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user