Download packages/cli/src/commands/extensions/update.ts from SaylorTwift/gemini-cli: direct link, hf CLI and curl.
- Browser
- Download file 5.26 kB
-
https://huggingface.co/SaylorTwift/gemini-cli/resolve/main/packages/cli/src/commands/extensions/update.ts
- Command line
-
hf download hf://SaylorTwift/gemini-cli/packages/cli/src/commands/extensions/update.ts
-
curl -L -o update.ts https://huggingface.co/SaylorTwift/gemini-cli/resolve/main/packages/cli/src/commands/extensions/update.ts
5.26 kB
| /** | |
| * @license | |
| * Copyright 2025 Google LLC | |
| * SPDX-License-Identifier: Apache-2.0 | |
| */ | |
| import type { CommandModule } from 'yargs'; | |
| import { | |
| updateAllUpdatableExtensions, | |
| type ExtensionUpdateInfo, | |
| checkForAllExtensionUpdates, | |
| updateExtension, | |
| } from '../../config/extensions/update.js'; | |
| import { checkForExtensionUpdate } from '../../config/extensions/github.js'; | |
| import { ExtensionUpdateState } from '../../ui/state/extensions.js'; | |
| import { | |
| coreEvents, | |
| debugLogger, | |
| getErrorMessage, | |
| } from '@google/gemini-cli-core'; | |
| import { ExtensionManager } from '../../config/extension-manager.js'; | |
| import { requestConsentNonInteractive } from '../../config/extensions/consent.js'; | |
| import { loadSettings } from '../../config/settings.js'; | |
| import { promptForSetting } from '../../config/extensions/extensionSettings.js'; | |
| import { exitCli } from '../utils.js'; | |
| interface UpdateArgs { | |
| name?: string; | |
| all?: boolean; | |
| } | |
| const updateOutput = (info: ExtensionUpdateInfo) => | |
| `Extension "${info.name}" successfully updated: ${info.originalVersion} → ${info.updatedVersion}.`; | |
| export async function handleUpdate(args: UpdateArgs) { | |
| const workspaceDir = process.cwd(); | |
| const settings = loadSettings(workspaceDir).merged; | |
| const extensionManager = new ExtensionManager({ | |
| workspaceDir, | |
| requestConsent: requestConsentNonInteractive, | |
| requestSetting: promptForSetting, | |
| settings, | |
| }); | |
| const extensions = await extensionManager.loadExtensions(); | |
| if (args.name) { | |
| try { | |
| const extension = extensions.find( | |
| (extension) => extension.name === args.name, | |
| ); | |
| if (!extension) { | |
| if (extensions.length === 0) { | |
| coreEvents.emitFeedback( | |
| 'error', | |
| `Extension "${args.name}" not found.\n\nNo extensions installed.`, | |
| ); | |
| return; | |
| } | |
| const installedExtensions = extensions | |
| .map((extension) => `${extension.name} (${extension.version})`) | |
| .join('\n'); | |
| coreEvents.emitFeedback( | |
| 'error', | |
| `Extension "${args.name}" not found.\n\nInstalled extensions:\n${installedExtensions}\n\nRun "gemini extensions list" for details.`, | |
| ); | |
| return; | |
| } | |
| if (!extension.installMetadata) { | |
| debugLogger.log( | |
| `Unable to install extension "${args.name}" due to missing install metadata`, | |
| ); | |
| return; | |
| } | |
| const updateState = await checkForExtensionUpdate( | |
| extension, | |
| extensionManager, | |
| ); | |
| if (updateState !== ExtensionUpdateState.UPDATE_AVAILABLE) { | |
| debugLogger.log(`Extension "${args.name}" is already up to date.`); | |
| return; | |
| } | |
| const updatedExtensionInfo = (await updateExtension( | |
| extension, | |
| extensionManager, | |
| updateState, | |
| () => {}, | |
| settings.experimental?.extensionReloading, | |
| ))!; | |
| if ( | |
| updatedExtensionInfo.originalVersion !== | |
| updatedExtensionInfo.updatedVersion | |
| ) { | |
| debugLogger.log( | |
| `Extension "${args.name}" successfully updated: ${updatedExtensionInfo.originalVersion} → ${updatedExtensionInfo.updatedVersion}.`, | |
| ); | |
| } else { | |
| debugLogger.log(`Extension "${args.name}" is already up to date.`); | |
| } | |
| } catch (error) { | |
| debugLogger.error(getErrorMessage(error)); | |
| } | |
| } | |
| if (args.all) { | |
| try { | |
| const extensionState = new Map(); | |
| await checkForAllExtensionUpdates( | |
| extensions, | |
| extensionManager, | |
| (action) => { | |
| if (action.type === 'SET_STATE') { | |
| extensionState.set(action.payload.name, { | |
| status: action.payload.state, | |
| }); | |
| } | |
| }, | |
| ); | |
| let updateInfos = await updateAllUpdatableExtensions( | |
| extensions, | |
| extensionState, | |
| extensionManager, | |
| () => {}, | |
| ); | |
| updateInfos = updateInfos.filter( | |
| (info) => info.originalVersion !== info.updatedVersion, | |
| ); | |
| if (updateInfos.length === 0) { | |
| debugLogger.log('No extensions to update.'); | |
| return; | |
| } | |
| debugLogger.log(updateInfos.map((info) => updateOutput(info)).join('\n')); | |
| } catch (error) { | |
| debugLogger.error(getErrorMessage(error)); | |
| } | |
| } | |
| } | |
| export const updateCommand: CommandModule = { | |
| command: 'update [<name>] [--all]', | |
| describe: | |
| 'Updates all extensions or a named extension to the latest version.', | |
| builder: (yargs) => | |
| yargs | |
| .positional('name', { | |
| describe: 'The name of the extension to update.', | |
| type: 'string', | |
| }) | |
| .option('all', { | |
| describe: 'Update all extensions.', | |
| type: 'boolean', | |
| }) | |
| .conflicts('name', 'all') | |
| .check((argv) => { | |
| if (!argv.all && !argv.name) { | |
| throw new Error('Either an extension name or --all must be provided'); | |
| } | |
| return true; | |
| }), | |
| handler: async (argv) => { | |
| await handleUpdate({ | |
| // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion | |
| name: argv['name'] as string | undefined, | |
| // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion | |
| all: argv['all'] as boolean | undefined, | |
| }); | |
| await exitCli(); | |
| }, | |
| }; | |