@@ -25,6 +25,7 @@ import { detectCLIRuntime } from '../utils/runtime-detector';
25
25
import { version as currentVersion , name } from '../utils/version' ;
26
26
27
27
const GCS_BUCKET_URL = 'https://storage.googleapis.com/genkit-assets-cli' ;
28
+ const CLI_DOCS_URL = 'https://genkit.dev/docs/devtools/' ;
28
29
const AXIOS_INSTANCE : AxiosInstance = axios . create ( {
29
30
timeout : 3000 ,
30
31
} ) ;
@@ -79,7 +80,7 @@ interface NpmRegistryResponse {
79
80
latest : string ;
80
81
[ key : string ] : string ;
81
82
} ;
82
- versions : Record < string , any > ;
83
+ versions : Record < string , unknown > ;
83
84
}
84
85
85
86
/**
@@ -138,21 +139,21 @@ export async function getLatestVersionFromNpm(
138
139
// Sort by semver descending (newest first)
139
140
versions . sort ( semver . rcompare ) ;
140
141
return versions [ 0 ] ;
141
- } catch ( error : any ) {
142
+ } catch ( error : unknown ) {
142
143
if ( error instanceof GenkitToolsError ) {
143
144
throw error ;
144
145
}
145
146
146
147
throw new GenkitToolsError (
147
- `Failed to fetch npm versions: ${ error ?. message ?? error } `
148
+ `Failed to fetch npm versions: ${ ( error as Error ) ?. message ?? String ( error ) } `
148
149
) ;
149
150
}
150
151
}
151
152
152
153
/**
153
154
* Checks if update notifications are disabled via environment variable or user config.
154
155
*/
155
- function areUpdateNotificationsDisabled ( ) : boolean {
156
+ function isUpdateNotificationsDisabled ( ) : boolean {
156
157
if ( process . env . GENKIT_CLI_DISABLE_UPDATE_NOTIFICATIONS === 'true' ) {
157
158
return true ;
158
159
}
@@ -163,10 +164,7 @@ function areUpdateNotificationsDisabled(): boolean {
163
164
/**
164
165
* Gets the latest version and update message for compiled binary installations.
165
166
*/
166
- async function getBinaryUpdateInfo ( ) : Promise < {
167
- latestVersion : string ;
168
- updateMessage : string ;
169
- } | null > {
167
+ async function getBinaryUpdateInfo ( ) : Promise < string | null > {
170
168
const gcsLatestData = await getGCSLatestData ( ) ;
171
169
const machine = `${ platform } -${ arch } ` ;
172
170
const platformData = gcsLatestData . platforms [ machine ] ;
@@ -177,26 +175,19 @@ async function getBinaryUpdateInfo(): Promise<{
177
175
}
178
176
179
177
const latestVersion = normalizeVersion ( gcsLatestData . latestVersion ) ;
180
- const fileName = platformData . versionedUrl . split ( '/' ) . pop ( ) || '' ;
181
- const downloadUrl = `${ GCS_BUCKET_URL } /prod/${ machine } /v${ latestVersion } /${ fileName } ` ;
182
- const updateMessage = `${ clc . dim ( 'Run' ) } ${ clc . bold ( `curl -Lo ./genkit_bin ${ downloadUrl } ` ) } ${ clc . dim ( 'to upgrade' ) } ` ;
183
- return { latestVersion, updateMessage } ;
178
+ return latestVersion ;
184
179
}
185
180
186
181
/**
187
182
* Gets the latest version and update message for npm installations.
188
183
*/
189
- async function getNpmUpdateInfo ( ) : Promise < {
190
- latestVersion : string ;
191
- updateMessage : string ;
192
- } | null > {
184
+ async function getNpmUpdateInfo ( ) : Promise < string | null > {
193
185
const latestVersion = await getLatestVersionFromNpm ( ) ;
194
186
if ( ! latestVersion ) {
195
187
logger . debug ( 'No available versions found from npm.' ) ;
196
188
return null ;
197
189
}
198
- const updateMessage = `${ clc . dim ( 'Update' ) } ${ clc . bold ( 'genkit-cli' ) } ${ clc . dim ( 'using your preferred package manager (npm, pnpm, yarn, etc.)' ) } ` ;
199
- return { latestVersion, updateMessage } ;
190
+ return latestVersion ;
200
191
}
201
192
202
193
/**
@@ -206,7 +197,7 @@ async function getNpmUpdateInfo(): Promise<{
206
197
*/
207
198
export async function showUpdateNotification ( ) : Promise < void > {
208
199
try {
209
- if ( areUpdateNotificationsDisabled ( ) ) {
200
+ if ( isUpdateNotificationsDisabled ( ) ) {
210
201
return ;
211
202
}
212
203
@@ -219,7 +210,7 @@ export async function showUpdateNotification(): Promise<void> {
219
210
return ;
220
211
}
221
212
222
- const { latestVersion, updateMessage } = updateInfo ;
213
+ const latestVersion = updateInfo ;
223
214
const current = normalizeVersion ( currentVersion ) ;
224
215
225
216
if ( ! semver . valid ( latestVersion ) || ! semver . valid ( current ) ) {
@@ -233,12 +224,20 @@ export async function showUpdateNotification(): Promise<void> {
233
224
return ;
234
225
}
235
226
236
- logger . info (
237
- `\n${ clc . yellow ( '📦 Update available:' ) } ${ clc . bold ( `v${ current } ` ) } → ${ clc . bold ( clc . green ( `v${ latestVersion } ` ) ) } \n` +
238
- updateMessage +
239
- '\n' +
240
- `${ clc . dim ( 'Run' ) } ${ clc . bold ( 'genkit config set updateNotificationsOptOut true' ) } ${ clc . dim ( 'to disable these notifications' ) } \n`
241
- ) ;
227
+ // Determine install method and update command for message
228
+ const installMethod = isCompiledBinary ? "installer script" : "your package manager" ;
229
+ const updateCommand = isCompiledBinary
230
+ ? "curl -sL cli.genkit.dev | uninstall=true bash"
231
+ : "npm install -g genkit-cli" ;
232
+
233
+ const updateNotificationMessage =
234
+ `Update available ${ clc . gray ( `v${ current } ` ) } → ${ clc . green ( `v${ latestVersion } ` ) } \n` +
235
+ `To update to the latest version using ${ installMethod } , run\n${ clc . cyan ( updateCommand ) } \n` +
236
+ `For other CLI management options, visit ${ CLI_DOCS_URL } \n` +
237
+ `${ clc . dim ( 'Run' ) } ${ clc . bold ( 'genkit config set updateNotificationsOptOut true' ) } ${ clc . dim ( 'to disable these notifications' ) } \n` ;
238
+
239
+ logger . info ( `\n${ updateNotificationMessage } ` ) ;
240
+
242
241
} catch ( e ) {
243
242
// Silently fail - update notifications shouldn't break the CLI
244
243
logger . debug ( 'Failed to show update notification' , e ) ;
0 commit comments