dev-manager-tauri/src-tauri/src/lib.rs
lanrtop 30d6823a1f feat: 蓝图 Buff 系统 v0.1.12
炼境可向任意被管理项目施加「蓝图 Buff」,git 提交自动同步任务进度,与 AI 工具热插拔解耦。

- 后端:blueprint_buffs 数据表 + 生命周期命令(apply/remove/get/list)
- 后端:每 5 秒轮询 git HEAD,文件路径匹配任务卡 files 字段,自动标记 📋🔵
- 后端:sync 时 Buff 触发飞轮快照,emit blueprint://changed 事件
- 前端:ProjectCard 显示  Buff 激活徽章
- 前端:GovernancePanel 新增施加/撤销 Buff 按钮,无蓝图时附带 init prompt
- 前端:BlueprintModal 监听 blueprint://changed,自动刷新并显示「刚刚更新」提示
- 修复:sync prompt 新增 🔵 状态保护规则,防止 Claude 更新时降级炼境自动标记的进度
2026-04-05 01:56:40 +09:00

256 lines
9.6 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.

mod commands;
mod db;
mod mcp_inject;
mod mcp_server;
mod models;
use git2;
use commands::{activity::*, blueprint::*, buff::{apply_blueprint_buff, remove_blueprint_buff, get_buff_status, list_buffed_projects}, canvas::*, cicd::*, devtools::*, git_ops::*, git_repos::*, github::*, groups::*, mentor::{add_project_note, get_group_mentor_report, get_mentor_context, get_project_notes, get_startup_alerts, run_startup_health_scan}, network::{get_wsl_ip, sync_wsl_proxy, get_wsl_proxy_status, clear_wsl_proxy, test_wsl_proxy_ip, test_win_proxy_ip}, project_scan::*, project_tools::*, projects::{batch_create_projects, create_project, delete_project, get_project, get_projects, scan_subfolders, update_project, update_project_tags}, proxy::*, publish::*, settings::{check_mcp_health, detect_editors, get_settings, run_health_check, search_editor_path, update_settings}, shell::*, spaces::*, tags::*, templates::*};
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_single_instance::init(|app, _argv, _cwd| {
// 第二个实例启动时,激活已有窗口
use tauri::Manager;
if let Some(w) = app.get_webview_window("main") {
let _ = w.show();
let _ = w.unminimize();
let _ = w.set_focus();
}
}))
.plugin(tauri_plugin_http::init())
.plugin(tauri_plugin_opener::init())
.plugin(tauri_plugin_updater::Builder::new().build())
.plugin(tauri_plugin_process::init())
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_shell::init())
.setup(|app| {
use tauri::{
menu::{Menu, MenuItem},
tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent},
Manager,
};
let data_dir = app.path().app_data_dir().expect("no app data dir");
db::init(data_dir);
// 禁用 libgit2 目录所有者验证,允许访问 WSL UNC 路径(\\wsl.localhost\...
unsafe {
let _ = git2::opts::set_verify_owner_validation(false);
}
// 种植内置模板(首次启动时执行)
commands::templates::seed_builtin_templates();
// ── 启动 MCP Server ───────────────────────────────────────
let mcp_port = mcp_server::read_port();
tauri::async_runtime::spawn(mcp_server::start(mcp_port));
// ── 启动健康扫描(异步,不阻塞窗口渲染)────────────────
tauri::async_runtime::spawn(async {
tokio::task::spawn_blocking(run_startup_health_scan).await.ok();
});
// ── 启动蓝图 Buff 后台轮询 ────────────────────────────
commands::buff::start_blueprint_watchers(app.handle().clone());
// ── 系统托盘 ──────────────────────────────────────────────
let show_i = MenuItem::with_id(app, "show", "显示窗口", true, None::<&str>)?;
let quit_i = MenuItem::with_id(app, "quit", "退出炼境", true, None::<&str>)?;
let menu = Menu::with_items(app, &[&show_i, &quit_i])?;
TrayIconBuilder::new()
.icon(app.default_window_icon().unwrap().clone())
.menu(&menu)
.show_menu_on_left_click(false)
.tooltip("炼境")
.on_menu_event(|app, event| match event.id.as_ref() {
"quit" => app.exit(0),
"show" => {
if let Some(w) = app.get_webview_window("main") {
let _ = w.show();
let _ = w.set_focus();
}
}
_ => {}
})
.on_tray_icon_event(|tray, event| {
// 左键单击托盘图标 → 显示/聚焦窗口
if let TrayIconEvent::Click {
button: MouseButton::Left,
button_state: MouseButtonState::Up,
..
} = event
{
let app = tray.app_handle();
if let Some(w) = app.get_webview_window("main") {
let _ = w.show();
let _ = w.set_focus();
}
}
})
.build(app)?;
// ── 关闭窗口 → 最小化到托盘 ──────────────────────────────
if let Some(window) = app.get_webview_window("main") {
let win = window.clone();
window.on_window_event(move |event| {
if let tauri::WindowEvent::CloseRequested { api, .. } = event {
api.prevent_close();
let _ = win.hide();
}
});
}
Ok(())
})
.invoke_handler(tauri::generate_handler![
// projects
get_projects,
get_project,
create_project,
update_project,
update_project_tags,
delete_project,
scan_subfolders,
batch_create_projects,
// activity
get_activity,
add_activity,
// groups
get_groups,
create_group,
update_group,
delete_group,
reorder_groups,
get_group_maps,
add_group_member,
remove_group_member,
// settings
get_settings,
update_settings,
detect_editors,
search_editor_path,
check_mcp_health,
run_health_check,
// project tools
get_project_tools,
add_project_tool,
update_project_tool,
remove_project_tool,
launch_tool,
// devtools
scan_dev_tools,
scan_wsl_dev_tools,
get_dev_tools,
save_dev_tools,
delete_dev_tool,
upsert_dev_tool,
// wsl proxy
get_wsl_ip,
sync_wsl_proxy,
get_wsl_proxy_status,
clear_wsl_proxy,
test_wsl_proxy_ip,
test_win_proxy_ip,
// v2rayn import
scan_v2rayn_nodes,
detect_v2rayn_db_path,
get_active_v2rayn_node,
// project env scan
scan_project_env,
get_project_env_tools,
save_project_env_tools,
// shell
open_editor,
open_terminal,
// git ops
git_clone,
git_status,
git_fetch,
git_pull,
git_push,
git_head_commit,
git_upstream_behind,
git_create_branch,
git_list_branches,
git_checkout_branch,
// github
github_save_account,
github_get_account,
github_get_token,
github_get_client_id,
github_logout,
github_start_oauth,
github_poll_oauth,
github_open_login_window,
// spaces
get_spaces,
create_space,
update_space,
delete_space,
set_current_space,
get_deploy_commands,
add_deploy_command,
remove_deploy_command,
execute_deploy,
// git repos registry
get_git_repos,
import_git_repos,
update_git_repo_deploy,
mount_repo,
delete_git_repo,
// publish to github
scan_local_git,
github_create_repo,
git_init_and_commit,
git_remote_set,
git_push_to_github,
register_and_link_repo,
write_gitignore,
resolve_wsl_path,
get_wsl_distros,
// project templates
list_templates,
get_template,
save_template,
delete_template,
create_project_from_template,
// tags
get_tags,
create_tag,
update_tag,
delete_tag,
get_project_tags,
set_project_tags,
get_all_project_tag_maps,
// cicd
get_cicd_config,
save_cicd_config,
generate_workflow,
// blueprint
get_blueprint,
generate_blueprint_prompt,
get_blueprint_status,
sync_blueprint_rules,
get_flywheel_stats,
generate_muhe_prompt,
archive_project_docs,
// canvas state
get_canvas_state,
save_canvas_state,
// blueprint buff
apply_blueprint_buff,
remove_blueprint_buff,
get_buff_status,
list_buffed_projects,
// mentor
get_mentor_context,
get_project_notes,
add_project_note,
get_group_mentor_report,
get_startup_alerts,
])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}