Files
DevFlow/src-tauri/src/lib.rs
绝尘 bd6a41fe6e 新增: 批次工作落地(推进链/评估闭环/事件总线/并发/加固) + 技术债清理 + 文档整理
后端:
- 工作流推进链(D-03):advance_task/状态机/闸门走 df-nodes Node trait,conditions 条件引擎扩展
- 想法评估闭环:启发式评分+对抗评估,df-ideas/scoring + df-storage/idea_eval_repo + idea 前端打通
- 全局事件数据总线:df-ai/context+context_helpers+augmentation 跨模块解耦
- AI planner/plan_hint/intent:aichat B 路线并行多轮基础
- patch_file 加固(TD-03/04):读改写整体锁防 lost update,expected_hash 合约闭环
- 压缩超时兜底(F-15 卡死根治)
- F-09 多会话并发:LlmConcurrency per-conv + streamingGuard 前端守护 + verify 脚本
- 知识注入 DRY/skills/audit 扩展

清理:
- aichat 技术债(误报 allow/死导入/过时注释 30 项)
- URGENT.md 删除(11 项加急全解决/迁 todo)
- 文档整理(todo/待决策/待审查/ARCHITECTURE/INDEX + 总线/技术债审查新文档)
2026-06-21 20:51:26 +08:00

203 lines
10 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! DevFlow Tauri 入口 — 初始化 AppState 并注册全部 IPC 命令
mod commands;
mod state;
use tauri::{Emitter, Listener, Manager};
use state::AppState;
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_opener::init())
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_window_state::Builder::default().build())
.setup(|app| {
// 数据库放在系统应用数据目录 <app_data_dir> 下dev/release 拆分):
// Dev 模式 devflow-dev.db可随意改动/清空Build 模式 devflow.db长期保留真实运行数据
let db_name = if cfg!(debug_assertions) { "devflow-dev.db" } else { "devflow.db" };
let data_dir = app.path().app_data_dir()?;
std::fs::create_dir_all(&data_dir)?;
let db_path = data_dir.join(db_name);
// 初始化全局状态(打开数据库 + 执行迁移)
let app_state = tauri::async_runtime::block_on(AppState::init(&db_path))?;
// FR-S1:启动一次性迁移 DB 明文 api_key → OS keyring(失败保留明文下次重试,非阻断)
if let Err(e) = tauri::async_runtime::block_on(
commands::ai::secret::migrate_secrets_to_keyring(&app_state.ai_providers),
) {
tracing::warn!("[FR-S1] 启动密钥迁移失败(非阻断): {}", e);
}
// B-260616-01: L0 握手 — 提前 clone ai_session(Arc),因 manage() 会 move app_state
let session_for_handshake = app_state.ai_session.clone();
app.manage(app_state);
// B-260616-01: L0 握手 — 监听前端就绪事件,清除 HMR/刷新导致的残留 generating 状态
let app_handle = app.handle().clone();
app.listen("ai-client-ready", move |_event| {
let session_arc = session_for_handshake.clone();
let app_h = app_handle.clone();
tauri::async_runtime::spawn(async move {
let mut session = session_arc.lock().await;
// F-260616-09 B 批8(设计 §3 batch8 + §5.2):遍历 per_conv(HashMap)清多 conv
// 残留 generating(HMR/dev 热载场景多 conv 并发跑 loop 致多 conv 卡 generating)。
// 批4:per_conv 唯一真相源,删顶层 session.generating 双写复位(顶层字段已退役)。
let dirty_convs: Vec<String> = session
.per_conv
.iter()
.filter(|(_, c)| c.generating)
.map(|(id, _)| id.clone())
.collect();
let was_generating = !dirty_convs.is_empty();
// 复位每个残留 generating 的 conv(批8 多 conv 全覆盖)。
for cid in &dirty_convs {
if let Some(conv) = session.per_conv.get_mut(cid) {
conv.generating = false;
}
}
// BUG-260619-06 修复: clear 致冷启动 restore 重建审批丢失(restore 填充后 clear 无条件清空,
// 重启后待审批工具全丢)。改 retain 仅清非 recovered(本次会话/HMR 死 pending),
// 保留 restore 重建(recovered=true,audit.rs:331),对齐 switchConversation retain 保护意图。
// 阶段3a 单真相源合并:单表按 !recovered retain(kind 不区分,path 审批恢复恒无)。
session.pending_approvals.retain(|_, a| !a.recovered);
drop(session);
if was_generating {
// 补偿事件:每个残留 conv 各发一个 AiCompleted(按 conversation_id 路由),
// 前端 useAiEvents.ts:133-140 按 conv_id 各归各复位 streaming/generatingConvId。
for cid in &dirty_convs {
let _ = app_h.emit(
"ai-chat-event",
commands::ai::AiChatEvent::AiCompleted {
total_tokens: 0,
prompt_tokens: 0,
completion_tokens: 0,
incomplete: None,
conversation_id: Some(cid.clone()),
},
);
}
}
tracing::info!(
"[L0-handshake] 前端重连握手完成, was_generating={}, dirty_convs={:?}",
was_generating,
dirty_convs
);
});
});
Ok(())
})
.invoke_handler(tauri::generate_handler![
// 项目
commands::project::list_projects,
commands::project::create_project,
commands::project::import_project,
commands::project::get_project,
commands::project::update_project,
commands::project::delete_project,
commands::project::list_deleted_projects,
commands::project::restore_project,
commands::project::purge_project,
commands::project::scan_project_stack,
commands::project::check_path_binding,
commands::project::relocate_project_path,
commands::project::check_path_exists,
commands::project::scan_project_with_ai,
commands::project::scan_directory_for_projects,
commands::project::import_projects_batch,
// 任务
commands::task::list_tasks,
commands::task::create_task,
commands::task::update_task,
commands::task::delete_task,
commands::task::restore_task,
commands::task::get_task_by_id,
commands::task::advance_task,
// 灵感
commands::idea::list_ideas,
commands::idea::create_idea,
commands::idea::update_idea,
commands::idea::delete_idea,
commands::idea::evaluate_idea,
commands::idea::list_idea_evaluations,
commands::idea::promote_idea,
// 工作流
commands::workflow::run_workflow,
commands::workflow::list_workflow_executions,
commands::workflow::get_workflow_execution,
commands::workflow::approve_human_approval,
commands::workflow::cancel_workflow_node,
// AI 聊天
commands::ai::ai_chat_send,
commands::ai::ai_regenerate,
commands::ai::ai_chat_edit,
commands::ai::ai_chat_force_send,
commands::ai::ai_chat_stop,
commands::ai::ai_approve,
// F-260616-03达 max_iterations 暂停态续/停(消费 AiMaxRoundsReached前端操作卡留 batch45
commands::ai::ai_continue_loop,
commands::ai::ai_stop_loop,
commands::ai::ai_pending_tool_calls,
commands::ai::ai_chat_clear,
commands::ai::ai_is_generating,
// F-15 阶段2 手动上下文管理:分段归档 + LLM 压缩
commands::ai::ai_chat_clear_context,
commands::ai::ai_chat_compress_context,
commands::ai::ai_list_providers,
commands::ai::ai_save_provider,
commands::ai::ai_set_provider,
commands::ai::ai_delete_provider,
// F-260614-04c: 负载均衡池可编辑层(enabled/weight 轻量更新 + caps 重建)
commands::ai::ai_update_provider_pool,
// F-01 阶段5:测试连接拉取模型列表 + 单模型探测
commands::ai::ai_fetch_models,
commands::ai::ai_probe_model,
// AI 对话管理
commands::ai::ai_conversation_create,
commands::ai::ai_conversation_list,
commands::ai::ai_conversation_switch,
commands::ai::ai_conversation_delete,
commands::ai::ai_conversation_rename,
commands::ai::ai_conversation_archive,
commands::ai::ai_conversation_set_pinned,
commands::ai::ai_conversation_export,
commands::ai::ai_list_skills,
// 核心设计6: 热重载技能(invalidate + 重扫,不重启生效)
commands::ai::ai_reload_skills,
commands::ai::ai_set_concurrency_config,
commands::ai::ai_set_agent_max_iterations,
commands::ai::ai_set_agent_max_retries,
// F-260619-03 Phase A: AI 工具文件访问授权目录白名单
commands::ai::ai_get_allowed_dirs,
commands::ai::ai_set_allowed_dirs,
// F-260619-03 Phase B: 路径授权弹窗决策(消费 AiDirAuthRequired 挂起)
commands::ai::ai_authorize_dir,
// 审批历史面板(AE-2025-08:查 ai_tool_executions 表,敏感字段截断)
commands::ai::audit::list_tool_executions,
// 知识库
commands::knowledge::knowledge_list,
commands::knowledge::knowledge_get,
commands::knowledge::knowledge_search,
commands::knowledge::knowledge_create,
commands::knowledge::knowledge_update_status,
commands::knowledge::knowledge_record_reuse,
commands::knowledge::knowledge_list_candidates,
commands::knowledge::knowledge_archive,
commands::knowledge::knowledge_retry_embedding,
commands::knowledge::knowledge_get_config,
commands::knowledge::knowledge_save_config,
commands::knowledge::knowledge_extract_now,
commands::knowledge::knowledge_get_detail,
commands::knowledge::knowledge_update,
commands::knowledge::knowledge_events,
// 通用应用设置 KV(前端 localStorage 迁移目标)
commands::settings::settings_get,
commands::settings::settings_set,
commands::settings::settings_get_all,
commands::settings::settings_delete,
])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}