All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 3m59s
All build artifacts now upload to files.command.vigilcyber.com/wraith/:
- Installer: /wraith/{ver}/Wraith_{ver}_x64-setup.exe + /wraith/latest/
- MCP bridge: /wraith/{ver}/wraith-mcp-bridge.exe + /wraith/latest/
- Update bundle: /wraith/{ver}/*.nsis.zip
- Update manifest: /wraith/update.json (Tauri updater endpoint)
- Version metadata: /wraith/{ver}/version.json + /wraith/latest/
Removed: Gitea package uploads, Gitea release creation/attachment.
Updated: tauri.conf.json updater endpoint, bridge auto-download URL,
manual update checker download URL.
CI is now: build -> sign -> upload to SeaweedFS. Done.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
86 lines
2.7 KiB
Rust
86 lines
2.7 KiB
Rust
//! MCP bridge binary self-management.
|
|
//!
|
|
//! On startup, checks if wraith-mcp-bridge exists in the data directory.
|
|
//! If missing or outdated, downloads the correct version from Gitea packages.
|
|
|
|
use std::path::PathBuf;
|
|
|
|
/// Get the expected path for the bridge binary.
|
|
pub fn bridge_path() -> PathBuf {
|
|
let dir = crate::data_directory();
|
|
if cfg!(windows) {
|
|
dir.join("wraith-mcp-bridge.exe")
|
|
} else {
|
|
dir.join("wraith-mcp-bridge")
|
|
}
|
|
}
|
|
|
|
/// Check if the bridge binary exists and is the correct version.
|
|
/// If not, download it from Gitea packages.
|
|
pub async fn ensure_bridge(app_version: &str) -> Result<(), String> {
|
|
let path = bridge_path();
|
|
let version_file = crate::data_directory().join("mcp-bridge-version");
|
|
|
|
// Check if bridge exists and version matches
|
|
if path.exists() {
|
|
if let Ok(installed_ver) = std::fs::read_to_string(&version_file) {
|
|
if installed_ver.trim() == app_version {
|
|
wraith_log!("[MCP Bridge] v{} already installed at {}", app_version, path.display());
|
|
return Ok(());
|
|
}
|
|
}
|
|
}
|
|
|
|
wraith_log!("[MCP Bridge] Downloading v{} to {}", app_version, path.display());
|
|
|
|
let binary_name = if cfg!(windows) {
|
|
"wraith-mcp-bridge.exe"
|
|
} else {
|
|
"wraith-mcp-bridge"
|
|
};
|
|
|
|
let url = format!(
|
|
"https://files.command.vigilcyber.com/wraith/{}/{}",
|
|
app_version, binary_name
|
|
);
|
|
|
|
let client = reqwest::Client::builder()
|
|
.timeout(std::time::Duration::from_secs(30))
|
|
.build()
|
|
.map_err(|e| format!("HTTP client error: {}", e))?;
|
|
|
|
let resp = client.get(&url).send().await
|
|
.map_err(|e| format!("Failed to download MCP bridge: {}", e))?;
|
|
|
|
if !resp.status().is_success() {
|
|
return Err(format!("MCP bridge download failed: HTTP {}", resp.status()));
|
|
}
|
|
|
|
let bytes = resp.bytes().await
|
|
.map_err(|e| format!("Failed to read MCP bridge response: {}", e))?;
|
|
|
|
// Write the binary
|
|
std::fs::write(&path, &bytes)
|
|
.map_err(|e| format!("Failed to write MCP bridge to {}: {}", path.display(), e))?;
|
|
|
|
// Make executable on Unix
|
|
#[cfg(unix)]
|
|
{
|
|
use std::os::unix::fs::PermissionsExt;
|
|
let mut perms = std::fs::metadata(&path)
|
|
.map_err(|e| format!("Failed to read permissions: {}", e))?
|
|
.permissions();
|
|
perms.set_mode(0o755);
|
|
std::fs::set_permissions(&path, perms)
|
|
.map_err(|e| format!("Failed to set execute permission: {}", e))?;
|
|
}
|
|
|
|
// Write version marker
|
|
std::fs::write(&version_file, app_version)
|
|
.map_err(|e| format!("Failed to write version file: {}", e))?;
|
|
|
|
wraith_log!("[MCP Bridge] v{} installed successfully ({} bytes)", app_version, bytes.len());
|
|
|
|
Ok(())
|
|
}
|