Files
codecraft/server/src/update.rs
T
Richard ZinkandClaude Opus 5.5 1f69d63b09 Status LEDs, image model selection, backup restore, provider test, monthly versions
- Sidebar: three status LEDs (server, models, MCP) with an overview popover (/api/status)
- Images: preview stage, purpose-based model choice and reference images
  (Nano Banana Pro edit refines the chosen preview)
- Settings: restore a stored or uploaded backup (staged, applied on restart)
- Provider form: test connection; saving or reloading re-checks the status at once
- opencode Zen/Go: send x-opencode-session with a stable id per conversation
- Releases are named vYYYYMM-NNNNN; scripts/release.sh numbers, tags, builds and publishes
- Fix: backups made in the same second no longer overwrite each other

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 09:31:24 +01:00

47 lines
1.4 KiB
Rust

//! Version information and a daily check for new releases.
use crate::app::App;
use serde_json::{Value, json};
use std::sync::{Arc, Mutex};
use std::time::Duration;
pub use codecraft_core::version::VERSION;
/// Git commit the image was built from (Docker build arg GIT_COMMIT).
pub fn commit() -> &'static str {
option_env!("CODECRAFT_COMMIT").unwrap_or("")
}
#[derive(Default)]
pub struct UpdateState {
pub latest: Mutex<Option<Value>>,
}
use codecraft_core::version::newer;
async fn check(app: &App) -> Option<Value> {
let url = app.config().server.update_url.clone();
if url.is_empty() {
return None;
}
let v: Value = crate::provider::http_client().get(&url).timeout(Duration::from_secs(20)).send().await.ok()?.json().await.ok()?;
let tag = v["tag_name"].as_str()?.to_string();
if !newer(&tag, VERSION) {
return None;
}
Some(json!({"version": tag.trim_start_matches('v'), "url": v["html_url"], "notes": v["body"].as_str().unwrap_or("").chars().take(4000).collect::<String>(), "published_at": v["published_at"]}))
}
pub fn spawn_checker(app: Arc<App>) {
tokio::spawn(async move {
tokio::time::sleep(Duration::from_secs(60)).await;
loop {
let found = check(&app).await;
*app.update.latest.lock().unwrap() = found;
tokio::time::sleep(Duration::from_secs(24 * 3600)).await;
}
});
}