Some checks failed
Push Check / check (push) Failing after 1m7s
- CI: pr-check 改为 push master 触发 + tsc --noEmit(原 branches: [main] 永不触发) - mcp_server.rs 拆分:mcp_tools.rs(工具schema+dispatch+实现)+ mcp_webhook.rs(webhook+测试) mcp_server.rs 从 1385 行瘦身至 145 行(纯协议路由层) - mcp_tools 新增工具 schema 完整性测试(73 passed,较之前 +2 条) - onboarding 测试版本号跟进 v1.1.0 → v1.2.0(模板版本升级后断言未同步)
392 lines
16 KiB
Rust
392 lines
16 KiB
Rust
mod commands;
|
||
mod db;
|
||
mod mcp_inject;
|
||
mod mcp_server;
|
||
mod mcp_tools;
|
||
mod mcp_webhook;
|
||
mod models;
|
||
use git2;
|
||
|
||
/// 创建不弹 CMD 窗口的子进程(Windows 专用 CREATE_NO_WINDOW 标志)。
|
||
/// 所有后台静默命令都应通过此函数创建,避免在 Windows 上频繁闪出黑框。
|
||
pub(crate) fn silent_cmd(program: &str) -> std::process::Command {
|
||
let mut cmd = std::process::Command::new(program);
|
||
#[cfg(target_os = "windows")]
|
||
{
|
||
use std::os::windows::process::CommandExt;
|
||
const CREATE_NO_WINDOW: u32 = 0x0800_0000;
|
||
cmd.creation_flags(CREATE_NO_WINDOW);
|
||
}
|
||
cmd
|
||
}
|
||
|
||
use commands::{activity::*, blueprint::*, buff::{apply_blueprint_buff, remove_blueprint_buff, get_buff_status, list_buffed_projects}, canvas::*, cicd::*, claude_config::get_beast_global_status, devtools::*, git_ops::*, git_repos::*, 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.clone());
|
||
commands::blueprint::init_user_conventions_dir(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));
|
||
|
||
// ── Gitea 远端轮询(G6):每 10 分钟拉取绑定仓库 commit ───
|
||
// 出站 HTTPS 采集,适配公网 Gitea + 内网炼境拓扑(webhook 不可达时的降级)
|
||
std::thread::spawn(|| {
|
||
std::thread::sleep(std::time::Duration::from_secs(30)); // 等 DB 与网络就绪
|
||
loop {
|
||
let _ = commands::gitea::poll_all_repos();
|
||
std::thread::sleep(std::time::Duration::from_secs(600));
|
||
}
|
||
});
|
||
|
||
// ── 启动健康扫描(异步,不阻塞窗口渲染)────────────────
|
||
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,
|
||
// global quick launch
|
||
get_global_tools,
|
||
add_global_tool,
|
||
update_global_tool,
|
||
remove_global_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,
|
||
// 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,
|
||
// 本地 git 工具
|
||
scan_local_git,
|
||
git_init_and_commit,
|
||
git_remote_set,
|
||
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,
|
||
get_user_conventions_status,
|
||
save_user_conventions,
|
||
reset_conventions_to_builtin,
|
||
// canvas state
|
||
get_canvas_state,
|
||
save_canvas_state,
|
||
// blueprint buff
|
||
apply_blueprint_buff,
|
||
remove_blueprint_buff,
|
||
get_buff_status,
|
||
list_buffed_projects,
|
||
// onboarding pack
|
||
commands::onboarding::apply_onboarding_pack,
|
||
// agent infrastructure
|
||
commands::agent_infra::scan_agent_infra_stack,
|
||
commands::agent_infra::generate_agent_infra_files,
|
||
commands::agent_infra::scan_doc_freshness,
|
||
commands::agent_infra::get_doc_freshness_cache,
|
||
commands::agent_infra::get_agent_health,
|
||
commands::commit_metrics::get_commit_stats,
|
||
commands::commit_metrics::ingest_full_git_history,
|
||
commands::commit_metrics::get_project_commit_health,
|
||
commands::commit_metrics::get_all_commit_health,
|
||
// mentor
|
||
get_mentor_context,
|
||
get_project_notes,
|
||
add_project_note,
|
||
get_group_mentor_report,
|
||
get_startup_alerts,
|
||
// user todos
|
||
commands::user_todos::get_user_todos,
|
||
commands::user_todos::add_user_todo,
|
||
commands::user_todos::toggle_user_todo,
|
||
commands::user_todos::delete_user_todo,
|
||
// servers
|
||
commands::servers::get_servers,
|
||
commands::servers::add_server,
|
||
commands::servers::edit_server,
|
||
commands::servers::delete_server,
|
||
commands::servers::link_server,
|
||
commands::servers::unlink_server,
|
||
commands::servers::get_project_server_links,
|
||
commands::servers::get_server_project_links,
|
||
// ssh config & vscode remote
|
||
commands::ssh_config::sync_ssh_config,
|
||
commands::ssh_config::get_ssh_config_status,
|
||
commands::ssh_config::check_vscode_status,
|
||
commands::ssh_config::open_vscode_remote,
|
||
commands::ssh_config::open_server_terminal,
|
||
commands::ssh_config::parse_ssh_config_entries,
|
||
commands::ssh_config::import_ssh_config_entries,
|
||
// server software & mirrors
|
||
commands::server_software::get_github_mirrors,
|
||
commands::server_software::add_github_mirror,
|
||
commands::server_software::delete_github_mirror,
|
||
commands::server_software::test_mirror_local,
|
||
commands::server_software::get_server_network_config,
|
||
commands::server_software::set_server_mirror,
|
||
commands::server_software::get_server_software_list,
|
||
commands::server_software::add_server_software,
|
||
commands::server_software::update_server_software,
|
||
commands::server_software::delete_server_software,
|
||
commands::server_software::generate_install_command,
|
||
commands::server_software::get_software_categories,
|
||
commands::server_software::add_software_category,
|
||
commands::server_software::update_software_category,
|
||
commands::server_software::delete_software_category,
|
||
// api keys
|
||
commands::api_keys::get_api_keys,
|
||
commands::api_keys::add_api_key,
|
||
commands::api_keys::edit_api_key,
|
||
commands::api_keys::delete_api_key,
|
||
// host apps
|
||
commands::host_apps::get_host_apps,
|
||
commands::host_apps::add_host_app,
|
||
commands::host_apps::edit_host_app,
|
||
commands::host_apps::delete_host_app,
|
||
// server service configs
|
||
commands::service_config::get_service_configs,
|
||
commands::service_config::add_service_config,
|
||
commands::service_config::edit_service_config,
|
||
commands::service_config::delete_service_config,
|
||
// gitea integration
|
||
commands::gitea::gitea_save_instance,
|
||
commands::gitea::gitea_list_instances,
|
||
commands::gitea::gitea_delete_instance,
|
||
commands::gitea::gitea_update_instance,
|
||
commands::gitea::gitea_test_connection,
|
||
commands::gitea::gitea_list_linked_repos,
|
||
commands::gitea::gitea_get_repo_link,
|
||
commands::gitea::gitea_create_repo,
|
||
commands::gitea::gitea_migrate_repo,
|
||
commands::gitea::gitea_link_repo,
|
||
commands::gitea::gitea_setup_webhook,
|
||
commands::gitea::gitea_unlink_repo,
|
||
commands::gitea::gitea_poll_now,
|
||
// beast status (read-only)
|
||
get_beast_global_status,
|
||
// source library
|
||
commands::source_library::get_source_categories,
|
||
commands::source_library::create_source_category,
|
||
commands::source_library::update_source_category,
|
||
commands::source_library::delete_source_category,
|
||
commands::source_library::get_source_projects,
|
||
commands::source_library::create_source_project,
|
||
commands::source_library::update_source_project,
|
||
commands::source_library::delete_source_project,
|
||
commands::source_library::get_source_versions,
|
||
commands::source_library::add_source_version,
|
||
commands::source_library::set_primary_version,
|
||
commands::source_library::delete_source_version,
|
||
commands::source_library::update_version_notes,
|
||
commands::source_library::scan_source_dir_tree,
|
||
commands::source_library::reveal_source_in_explorer,
|
||
commands::source_library::copy_source_to,
|
||
// cloud products
|
||
commands::cloud_products::get_cloud_products,
|
||
commands::cloud_products::add_cloud_product,
|
||
commands::cloud_products::edit_cloud_product,
|
||
commands::cloud_products::delete_cloud_product,
|
||
// cloud db databases
|
||
commands::cloud_db_databases::get_cloud_databases,
|
||
commands::cloud_db_databases::add_cloud_database,
|
||
commands::cloud_db_databases::edit_cloud_database,
|
||
commands::cloud_db_databases::delete_cloud_database,
|
||
// docker apps
|
||
commands::docker_apps::get_docker_apps,
|
||
commands::docker_apps::add_docker_app,
|
||
commands::docker_apps::edit_docker_app,
|
||
commands::docker_apps::delete_docker_app,
|
||
])
|
||
.run(tauri::generate_context!())
|
||
.expect("error while running tauri application");
|
||
}
|