@@ -38,6 +38,7 @@ mod telegram;
3838mod todo;
3939mod tool;
4040mod tui;
41+ mod update;
4142mod usage;
4243mod util;
4344
@@ -481,26 +482,63 @@ async fn main() -> Result<()> {
481482 let auto_update = args. auto_update ;
482483
483484 if check_updates {
484- // Spawn update check in background to avoid blocking startup
485- std:: thread:: spawn ( move || {
486- if let Some ( update_available) = check_for_updates ( ) {
487- if update_available {
488- if auto_update {
489- eprintln ! ( "Update available - auto-updating..." ) ;
490- if let Err ( e) = run_auto_update ( ) {
485+ if update:: is_release_build ( ) {
486+ // Release build: check GitHub Releases for newer version
487+ std:: thread:: spawn ( move || {
488+ match update:: check_and_maybe_update ( auto_update) {
489+ update:: UpdateCheckResult :: UpdateAvailable {
490+ current,
491+ latest,
492+ ..
493+ } => {
494+ eprintln ! (
495+ "\n 📦 Update available: {} → {}. Run `jcode update` to install.\n " ,
496+ current, latest
497+ ) ;
498+ }
499+ update:: UpdateCheckResult :: UpdateInstalled { version, path } => {
500+ eprintln ! (
501+ "✅ Updated to {}. Restarting from {}..." ,
502+ version,
503+ path. display( )
504+ ) ;
505+ // Exec into the new binary
506+ use std:: os:: unix:: process:: CommandExt ;
507+ let args: Vec < String > = std:: env:: args ( ) . skip ( 1 ) . collect ( ) ;
508+ let err = ProcessCommand :: new ( & path)
509+ . args ( & args)
510+ . arg ( "--no-update" )
511+ . exec ( ) ;
512+ eprintln ! ( "Failed to exec new binary: {}" , err) ;
513+ }
514+ update:: UpdateCheckResult :: Error ( e) => {
515+ logging:: info ( & format ! ( "Update check failed: {}" , e) ) ;
516+ }
517+ update:: UpdateCheckResult :: NoUpdate => { }
518+ }
519+ } ) ;
520+ } else {
521+ // Dev build: check git remote for updates
522+ std:: thread:: spawn ( move || {
523+ if let Some ( update_available) = check_for_updates ( ) {
524+ if update_available {
525+ if auto_update {
526+ eprintln ! ( "Update available - auto-updating..." ) ;
527+ if let Err ( e) = run_auto_update ( ) {
528+ eprintln ! (
529+ "Auto-update failed: {}. Continuing with current version." ,
530+ e
531+ ) ;
532+ }
533+ } else {
491534 eprintln ! (
492- "Auto-update failed: {}. Continuing with current version." ,
493- e
535+ "\n 📦 Update available! Run `jcode update` or `/reload` to update.\n "
494536 ) ;
495537 }
496- } else {
497- eprintln ! (
498- "\n 📦 Update available! Run `jcode update` or `/reload` to update.\n "
499- ) ;
500538 }
501539 }
502- }
503- } ) ;
540+ } ) ;
541+ }
504542 }
505543
506544 if let Err ( e) = run_main ( args) . await {
@@ -2375,12 +2413,34 @@ fn run_auto_update() -> Result<()> {
23752413
23762414/// Run the update process (manual)
23772415fn run_update ( ) -> Result < ( ) > {
2416+ if update:: is_release_build ( ) {
2417+ eprintln ! ( "Checking GitHub for latest release..." ) ;
2418+ match update:: check_for_update_blocking ( ) {
2419+ Ok ( Some ( release) ) => {
2420+ eprintln ! (
2421+ "Downloading {} → {}..." ,
2422+ env!( "JCODE_VERSION" ) ,
2423+ release. tag_name
2424+ ) ;
2425+ let path = update:: download_and_install_blocking ( & release) ?;
2426+ eprintln ! ( "✅ Updated to {} at {}" , release. tag_name, path. display( ) ) ;
2427+ eprintln ! ( "Restart jcode to use the new version." ) ;
2428+ }
2429+ Ok ( None ) => {
2430+ eprintln ! ( "Already up to date ({})" , env!( "JCODE_VERSION" ) ) ;
2431+ }
2432+ Err ( e) => {
2433+ anyhow:: bail!( "Update check failed: {}" , e) ;
2434+ }
2435+ }
2436+ return Ok ( ( ) ) ;
2437+ }
2438+
23782439 let repo_dir =
23792440 get_repo_dir ( ) . ok_or_else ( || anyhow:: anyhow!( "Could not find jcode repository" ) ) ?;
23802441
23812442 eprintln ! ( "Updating jcode from {}..." , repo_dir. display( ) ) ;
23822443
2383- // Git pull
23842444 eprintln ! ( "Pulling latest changes..." ) ;
23852445 let pull = ProcessCommand :: new ( "git" )
23862446 . args ( [ "pull" ] )
@@ -2391,7 +2451,6 @@ fn run_update() -> Result<()> {
23912451 anyhow:: bail!( "git pull failed" ) ;
23922452 }
23932453
2394- // Cargo build --release
23952454 eprintln ! ( "Building..." ) ;
23962455 let build = ProcessCommand :: new ( "cargo" )
23972456 . args ( [ "build" , "--release" ] )
@@ -2406,7 +2465,6 @@ fn run_update() -> Result<()> {
24062465 eprintln ! ( "Warning: install failed: {}" , e) ;
24072466 }
24082467
2409- // Get new version hash
24102468 let hash = ProcessCommand :: new ( "git" )
24112469 . args ( [ "rev-parse" , "--short" , "HEAD" ] )
24122470 . current_dir ( & repo_dir)
0 commit comments