Extension update confirm dialog (#10183)

This commit is contained in:
Jacob MacDonald
2025-09-29 14:19:19 -07:00
committed by GitHub
parent d6933c77ba
commit cea1a867b6
14 changed files with 310 additions and 50 deletions

View File

@@ -32,6 +32,7 @@ import type {
HistoryItemWithoutId,
SlashCommandProcessorResult,
HistoryItem,
ConfirmationRequest,
} from '../types.js';
import { MessageType } from '../types.js';
import type { LoadedSettings } from '../../config/settings.js';
@@ -57,6 +58,7 @@ interface SlashCommandProcessorActions {
setExtensionsUpdateState: Dispatch<
SetStateAction<Map<string, ExtensionUpdateState>>
>;
addConfirmUpdateExtensionRequest: (request: ConfirmationRequest) => void;
}
/**
@@ -206,6 +208,8 @@ export const useSlashCommandProcessor = (
reloadCommands,
extensionsUpdateState,
setExtensionsUpdateState: actions.setExtensionsUpdateState,
addConfirmUpdateExtensionRequest:
actions.addConfirmUpdateExtensionRequest,
},
session: {
stats: session.stats,

View File

@@ -7,9 +7,9 @@
import type { GeminiCLIExtension } from '@google/gemini-cli-core';
import { getErrorMessage } from '../../utils/errors.js';
import { ExtensionUpdateState } from '../state/extensions.js';
import { useState } from 'react';
import { useCallback, useState } from 'react';
import type { UseHistoryManagerReturn } from './useHistoryManager.js';
import { MessageType } from '../types.js';
import { MessageType, type ConfirmationRequest } from '../types.js';
import {
checkForAllExtensionUpdates,
updateExtension,
@@ -25,6 +25,29 @@ export const useExtensionUpdates = (
new Map<string, ExtensionUpdateState>(),
);
const [isChecking, setIsChecking] = useState(false);
const [confirmUpdateExtensionRequests, setConfirmUpdateExtensionRequests] =
useState<
Array<{
prompt: React.ReactNode;
onConfirm: (confirmed: boolean) => void;
}>
>([]);
const addConfirmUpdateExtensionRequest = useCallback(
(original: ConfirmationRequest) => {
const wrappedRequest = {
prompt: original.prompt,
onConfirm: (confirmed: boolean) => {
// Remove it from the outstanding list of requests by identity.
setConfirmUpdateExtensionRequests((prev) =>
prev.filter((r) => r !== wrappedRequest),
);
original.onConfirm(confirmed);
},
};
setConfirmUpdateExtensionRequests((prev) => [...prev, wrappedRequest]);
},
[setConfirmUpdateExtensionRequests],
);
(async () => {
if (isChecking) return;
@@ -49,7 +72,11 @@ export const useExtensionUpdates = (
updateExtension(
extension,
cwd,
(description) => requestConsentInteractive(description, addItem),
(description) =>
requestConsentInteractive(
description,
addConfirmUpdateExtensionRequest,
),
currentState,
(newState) => {
setExtensionsUpdateState((prev) => {
@@ -70,8 +97,12 @@ export const useExtensionUpdates = (
);
})
.catch((error) => {
console.error(
`Error updating extension "${extension.name}": ${getErrorMessage(error)}.`,
addItem(
{
type: MessageType.ERROR,
text: getErrorMessage(error),
},
Date.now(),
);
});
} else {
@@ -96,5 +127,7 @@ export const useExtensionUpdates = (
return {
extensionsUpdateState,
setExtensionsUpdateState,
confirmUpdateExtensionRequests,
addConfirmUpdateExtensionRequest,
};
};