@@ -28,6 +28,12 @@ type releaseInfo struct {
2828 } `json:"assets"`
2929}
3030
31+ type metadata struct {
32+ Version string `json:"version"`
33+ Commit string `json:"commit"`
34+ Date string `json:"date"`
35+ }
36+
3137func getLatestRelease () (* releaseInfo , error ) {
3238 client := & http.Client {Timeout : 5 * time .Second }
3339 resp , err := client .Get (fmt .Sprintf ("https://api.github.com/repos/%s/releases" , repo ))
@@ -47,7 +53,22 @@ func getLatestRelease() (*releaseInfo, error) {
4753
4854 latest := releases [0 ]
4955
50- // Fetch actual SHA for the tag to avoid 'master' or 'release' branch name issues
56+ // Try to fetch metadata.json from assets for precise versioning
57+ for _ , asset := range latest .Assets {
58+ if asset .Name == "metadata.json" {
59+ metaResp , err := client .Get (asset .BrowserDownloadURL )
60+ if err == nil {
61+ defer metaResp .Body .Close ()
62+ var m metadata
63+ if err := json .NewDecoder (metaResp .Body ).Decode (& m ); err == nil && m .Commit != "" {
64+ latest .ActualSHA = m .Commit
65+ return & latest , nil
66+ }
67+ }
68+ }
69+ }
70+
71+ // Fallback to tag-based SHA resolution if metadata.json is missing
5172 tagResp , err := client .Get (fmt .Sprintf ("https://api.github.com/repos/%s/git/ref/tags/%s" , repo , latest .TagName ))
5273 if err == nil {
5374 defer tagResp .Body .Close ()
@@ -65,26 +86,35 @@ func getLatestRelease() (*releaseInfo, error) {
6586}
6687
6788func isUpdateAvailable (latest * releaseInfo ) bool {
89+ // If we are in a dev build, we don't automatically suggest updates unless it's a forced check
90+ // This avoids the "dumb" behavior of dev always suggesting updates.
6891 if Version == "dev" {
69- return true // Always allow update from dev
92+ return false
7093 }
7194
72- remoteVer := latest .ActualSHA
73- if remoteVer == "" {
74- remoteVer = latest .TargetCommitish
95+ remoteSHA := latest .ActualSHA
96+ if remoteSHA == "" {
97+ // If we still don't have a SHA, we can't reliably say there's an update
98+ // unless the tag name is different.
99+ return latest .TagName != Version
75100 }
76101
77- // If tags differ, update is available
78- if latest .TagName ! = Version {
79- return true
102+ // If tags match (e.g. both are 'latest'), compare SHAs
103+ if latest .TagName = = Version {
104+ return remoteSHA != Commit
80105 }
81106
82- // If tags match (e.g. both are 'latest'), compare SHAs
83- return remoteVer != Commit
107+ // Otherwise, tags differ, so update is available
108+ return true
84109}
85110
86111// checkUpdateSilent checks for updates and prints a message if one is available
87112func checkUpdateSilent () {
113+ // Don't show update notification for dev builds
114+ if Version == "dev" {
115+ return
116+ }
117+
88118 latest , err := getLatestRelease ()
89119 if err != nil {
90120 return // Fail silently for background checks
@@ -254,7 +284,7 @@ var updateCmd = &cobra.Command{
254284 return fmt .Errorf ("checking for updates: %w" , err )
255285 }
256286
257- if ! isUpdateAvailable (latest ) {
287+ if ! isUpdateAvailable (latest ) && Version != "dev" {
258288 fmt .Println ("vibeaura is already up to date!" )
259289 return nil
260290 }
@@ -263,11 +293,13 @@ var updateCmd = &cobra.Command{
263293 if remoteVer == "" {
264294 remoteVer = latest .TargetCommitish
265295 }
266- if len (remoteVer ) > 7 {
267- remoteVer = remoteVer [:7 ]
296+
297+ displaySHA := remoteVer
298+ if len (displaySHA ) > 7 {
299+ displaySHA = displaySHA [:7 ]
268300 }
269301
270- fmt .Printf ("New version available: %s (commit: %s)\n " , latest .TagName , remoteVer )
302+ fmt .Printf ("New version available: %s (commit: %s)\n " , latest .TagName , displaySHA )
271303
272304 // ... (rest of the download/install logic)
273305
0 commit comments