2025-05-17 21:25:28 -07:00
|
|
|
/**
|
|
|
|
|
* @license
|
|
|
|
|
* Copyright 2025 Google LLC
|
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import { useState, useEffect } from 'react';
|
2025-06-25 05:41:11 -07:00
|
|
|
import { ApprovalMode, type Config } from '@google/gemini-cli-core';
|
2025-08-12 14:05:49 -07:00
|
|
|
import { useKeypress } from './useKeypress.js';
|
2026-01-12 14:50:32 -08:00
|
|
|
import { keyMatchers, Command } from '../keyMatchers.js';
|
2025-08-25 17:30:04 -07:00
|
|
|
import type { HistoryItemWithoutId } from '../types.js';
|
|
|
|
|
import { MessageType } from '../types.js';
|
2025-05-17 21:25:28 -07:00
|
|
|
|
2026-01-21 10:19:47 -05:00
|
|
|
export interface UseApprovalModeIndicatorArgs {
|
2025-05-17 21:25:28 -07:00
|
|
|
config: Config;
|
2025-09-14 20:20:21 -07:00
|
|
|
addItem?: (item: HistoryItemWithoutId, timestamp: number) => void;
|
|
|
|
|
onApprovalModeChange?: (mode: ApprovalMode) => void;
|
2026-01-12 15:30:12 -08:00
|
|
|
isActive?: boolean;
|
2025-05-17 21:25:28 -07:00
|
|
|
}
|
|
|
|
|
|
2026-01-21 10:19:47 -05:00
|
|
|
export function useApprovalModeIndicator({
|
2025-05-17 21:25:28 -07:00
|
|
|
config,
|
2025-08-25 17:30:04 -07:00
|
|
|
addItem,
|
2025-09-14 20:20:21 -07:00
|
|
|
onApprovalModeChange,
|
2026-01-12 15:30:12 -08:00
|
|
|
isActive = true,
|
2026-01-21 10:19:47 -05:00
|
|
|
}: UseApprovalModeIndicatorArgs): ApprovalMode {
|
2025-06-02 22:05:45 +02:00
|
|
|
const currentConfigValue = config.getApprovalMode();
|
2026-01-21 10:19:47 -05:00
|
|
|
const [showApprovalMode, setApprovalMode] = useState(currentConfigValue);
|
2025-05-17 21:25:28 -07:00
|
|
|
|
|
|
|
|
useEffect(() => {
|
2026-01-21 10:19:47 -05:00
|
|
|
setApprovalMode(currentConfigValue);
|
2025-05-17 21:25:28 -07:00
|
|
|
}, [currentConfigValue]);
|
|
|
|
|
|
2025-08-12 14:05:49 -07:00
|
|
|
useKeypress(
|
|
|
|
|
(key) => {
|
|
|
|
|
let nextApprovalMode: ApprovalMode | undefined;
|
|
|
|
|
|
2026-01-12 14:50:32 -08:00
|
|
|
if (keyMatchers[Command.TOGGLE_YOLO](key)) {
|
2025-10-22 11:57:10 -07:00
|
|
|
if (
|
|
|
|
|
config.isYoloModeDisabled() &&
|
|
|
|
|
config.getApprovalMode() !== ApprovalMode.YOLO
|
|
|
|
|
) {
|
|
|
|
|
if (addItem) {
|
|
|
|
|
addItem(
|
|
|
|
|
{
|
|
|
|
|
type: MessageType.WARNING,
|
|
|
|
|
text: 'You cannot enter YOLO mode since it is disabled in your settings.',
|
|
|
|
|
},
|
|
|
|
|
Date.now(),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-08-12 14:05:49 -07:00
|
|
|
nextApprovalMode =
|
|
|
|
|
config.getApprovalMode() === ApprovalMode.YOLO
|
|
|
|
|
? ApprovalMode.DEFAULT
|
|
|
|
|
: ApprovalMode.YOLO;
|
2026-01-21 10:19:47 -05:00
|
|
|
} else if (keyMatchers[Command.CYCLE_APPROVAL_MODE](key)) {
|
|
|
|
|
const currentMode = config.getApprovalMode();
|
|
|
|
|
switch (currentMode) {
|
|
|
|
|
case ApprovalMode.DEFAULT:
|
|
|
|
|
nextApprovalMode = config.isPlanEnabled()
|
|
|
|
|
? ApprovalMode.PLAN
|
|
|
|
|
: ApprovalMode.AUTO_EDIT;
|
|
|
|
|
break;
|
|
|
|
|
case ApprovalMode.PLAN:
|
|
|
|
|
nextApprovalMode = ApprovalMode.AUTO_EDIT;
|
|
|
|
|
break;
|
|
|
|
|
case ApprovalMode.AUTO_EDIT:
|
|
|
|
|
nextApprovalMode = ApprovalMode.DEFAULT;
|
|
|
|
|
break;
|
|
|
|
|
case ApprovalMode.YOLO:
|
|
|
|
|
nextApprovalMode = ApprovalMode.AUTO_EDIT;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
}
|
2025-08-12 14:05:49 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (nextApprovalMode) {
|
2025-08-25 17:30:04 -07:00
|
|
|
try {
|
|
|
|
|
config.setApprovalMode(nextApprovalMode);
|
|
|
|
|
// Update local state immediately for responsiveness
|
2026-01-21 10:19:47 -05:00
|
|
|
setApprovalMode(nextApprovalMode);
|
2025-09-14 20:20:21 -07:00
|
|
|
|
|
|
|
|
// Notify the central handler about the approval mode change
|
|
|
|
|
onApprovalModeChange?.(nextApprovalMode);
|
2025-08-25 17:30:04 -07:00
|
|
|
} catch (e) {
|
2025-09-14 20:20:21 -07:00
|
|
|
if (addItem) {
|
|
|
|
|
addItem(
|
|
|
|
|
{
|
|
|
|
|
type: MessageType.INFO,
|
|
|
|
|
text: (e as Error).message,
|
|
|
|
|
},
|
|
|
|
|
Date.now(),
|
|
|
|
|
);
|
|
|
|
|
}
|
2025-08-25 17:30:04 -07:00
|
|
|
}
|
2025-08-12 14:05:49 -07:00
|
|
|
}
|
|
|
|
|
},
|
2026-01-12 15:30:12 -08:00
|
|
|
{ isActive },
|
2025-08-12 14:05:49 -07:00
|
|
|
);
|
2025-05-17 21:25:28 -07:00
|
|
|
|
2026-01-21 10:19:47 -05:00
|
|
|
return showApprovalMode;
|
2025-05-17 21:25:28 -07:00
|
|
|
}
|