Skip to content

Commit 4483e0d

Browse files
committed
Add interactive update prompt and mobile version check
- Replace auto-update with Y/n confirmation prompt on startup - Add MinAppVersion constant for app compatibility check - Handle mobile-info control message with app version - Send update-required to mobile if app version is too old
1 parent 4d6a173 commit 4483e0d

4 files changed

Lines changed: 64 additions & 19 deletions

File tree

commands_info.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package main
22

33
import (
44
"encoding/json"
5+
"fmt"
56
"net"
67
"runtime"
78
)
@@ -45,3 +46,41 @@ func (d *Daemon) sendCLIInfo() {
4546
d.sendControlMessage("cli-info:" + string(infoJSON))
4647
}
4748

49+
// handleMobileInfo processes mobile-info control message and checks app version compatibility
50+
func (d *Daemon) handleMobileInfo(args string) {
51+
var info struct {
52+
AppVersion string `json:"app_version"`
53+
}
54+
if err := json.Unmarshal([]byte(args), &info); err != nil {
55+
fmt.Printf("%s[mobile-info] Invalid JSON: %v%s\n", dim, err, reset)
56+
return
57+
}
58+
59+
fmt.Printf("%s[mobile-info] App version: %s%s\n", dim, info.AppVersion, reset)
60+
61+
appVer, err := parseSemver(info.AppVersion)
62+
if err != nil {
63+
return
64+
}
65+
minVer, err := parseSemver(MinAppVersion)
66+
if err != nil {
67+
return
68+
}
69+
70+
// App is too old if its version is lower than MinAppVersion
71+
if appVer.Major < minVer.Major ||
72+
(appVer.Major == minVer.Major && appVer.Minor < minVer.Minor) ||
73+
(appVer.Major == minVer.Major && appVer.Minor == minVer.Minor && appVer.Patch < minVer.Patch) {
74+
msg := map[string]string{
75+
"min_app_version": MinAppVersion,
76+
"cli_version": Version,
77+
"message": fmt.Sprintf("Please update the app to at least v%s", MinAppVersion),
78+
}
79+
msgJSON, err := json.Marshal(msg)
80+
if err != nil {
81+
return
82+
}
83+
d.sendControlMessage("update-required:" + string(msgJSON))
84+
}
85+
}
86+

commands_terminal.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ func (d *Daemon) handleControlMessage(msg string) {
5353

5454
case "file-upload-cancel":
5555
d.handleChunkedUploadCancel(args)
56+
57+
case "mobile-info":
58+
d.handleMobileInfo(args)
5659
}
5760
}
5861

types.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ var (
3737
RelayURL = "wss://aipilot-relay.softwarity.io"
3838
)
3939

40+
// MinAppVersion is the minimum mobile app version required by this CLI
41+
var MinAppVersion = "1.0.0"
42+
4043
// ChunkedUpload tracks a file being uploaded in chunks
4144
type ChunkedUpload struct {
4245
FileName string

update.go

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,7 @@ func cleanupOldBinary() {
192192
}
193193
}
194194

195-
// checkUpdateOnStartup checks for updates at startup.
196-
// Patch: download in background, applied on next launch.
197-
// Minor/Major: blocking download + restart.
195+
// checkUpdateOnStartup checks for updates at startup and prompts the user.
198196
func checkUpdateOnStartup() {
199197
current, err := parseSemver(Version)
200198
if err != nil {
@@ -231,23 +229,25 @@ func checkUpdateOnStartup() {
231229
return
232230
}
233231

234-
if updateType == "patch" {
235-
// Non-blocking: download in background, applied on next launch
236-
fmt.Printf("%s⬆ %s available, downloading in background...%s\n", dim, latest.String(), reset)
237-
go func() {
238-
downloadAndReplace(downloadURL, exePath)
239-
}()
240-
} else {
241-
// Blocking: minor/major update
242-
fmt.Printf("%s⬆ Update %s → %s available%s\n", cyan, current.String(), latest.String(), reset)
243-
fmt.Printf("%s Updating...%s\n", cyan, reset)
244-
if err := downloadAndReplace(downloadURL, exePath); err != nil {
245-
fmt.Printf("%s Update failed: %v%s\n", yellow, err, reset)
246-
return
247-
}
248-
fmt.Printf("%s ✓ Updated to %s. Restarting...%s\n", green, latest.String(), reset)
249-
restartSelf(exePath)
232+
fmt.Printf("%s⬆ Update available: %s → %s (%s)%s\n", cyan, current.String(), latest.String(), updateType, reset)
233+
fmt.Printf(" Update now? [Y/n] ")
234+
235+
var answer string
236+
fmt.Scanln(&answer)
237+
answer = strings.TrimSpace(strings.ToLower(answer))
238+
239+
if answer == "n" || answer == "no" {
240+
fmt.Printf("%s Skipped.%s\n", dim, reset)
241+
return
242+
}
243+
244+
fmt.Printf("%s Updating...%s\n", cyan, reset)
245+
if err := downloadAndReplace(downloadURL, exePath); err != nil {
246+
fmt.Printf("%s Update failed: %v%s\n", yellow, err, reset)
247+
return
250248
}
249+
fmt.Printf("%s ✓ Updated to %s. Restarting...%s\n", green, latest.String(), reset)
250+
restartSelf(exePath)
251251
}
252252

253253
// forceUpdate performs a blocking update check and install (--update flag)

0 commit comments

Comments
 (0)