Disallow floating promises. (#14605)

This commit is contained in:
Christian Gunderman 2025-12-05 16:12:49 -08:00 committed by GitHub
parent 3cf44acc08
commit 025e450ac2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
57 changed files with 128 additions and 4 deletions

View file

@ -165,6 +165,7 @@ export default tseslint.config(
'prefer-const': ['error', { destructuring: 'all' }],
radix: 'error',
'default-case': 'error',
'@typescript-eslint/no-floating-promises': ['error'],
},
},
{

View file

@ -397,6 +397,7 @@ export class CoderAgentExecutor implements AgentExecutor {
`[CoderAgentExecutor] Error creating task ${taskId}:`,
error,
);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
pushTaskStateFailed(error, eventBus, taskId, contextId);
return;
}

View file

@ -395,6 +395,7 @@ export class Task {
logger.info('[Task] YOLO mode enabled. Auto-approving all tool calls.');
toolCalls.forEach((tc: ToolCall) => {
if (tc.status === 'awaiting_approval' && tc.confirmationDetails) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
tc.confirmationDetails.onConfirm(ToolConfirmationOutcome.ProceedOnce);
this.pendingToolConfirmationDetails.delete(tc.request.callId);
}
@ -819,6 +820,7 @@ export class Task {
} else {
parts = [response];
}
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.geminiClient.addHistory({
role: 'user',
parts,

View file

@ -346,6 +346,7 @@ export class ExtensionManager extends ExtensionLoader {
'success',
),
);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.enableExtension(newExtensionConfig.name, SettingScope.User);
}
} finally {

View file

@ -799,6 +799,7 @@ export function migrateDeprecatedSettings(
`Migrating deprecated extensions.disabled settings from ${scope} settings...`,
);
for (const extension of settings.extensions.disabled ?? []) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
extensionManager.disableExtension(extension, scope);
}

View file

@ -294,6 +294,7 @@ export const AppContainer = (props: AppContainerProps) => {
const staticExtraHeight = 3;
useEffect(() => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
(async () => {
// Note: the program will not work if this fails so let errors be
// handled by the global catch.
@ -384,6 +385,7 @@ export const AppContainer = (props: AppContainerProps) => {
// Initialize input history from logger (past sessions)
useEffect(() => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
initializeFromLogger(logger);
}, [logger, initializeFromLogger]);
@ -984,6 +986,7 @@ Logging in with Google... Restarting Gemini CLI to continue.
const currentIde = ideClient.getCurrentIde();
setCurrentIDE(currentIde || null);
};
// eslint-disable-next-line @typescript-eslint/no-floating-promises
getIde();
}, []);
const shouldShowIdePrompt = Boolean(
@ -1109,6 +1112,7 @@ Logging in with Google... Restarting Gemini CLI to continue.
recordExitFail(config);
}
if (ctrlCPressCount > 1) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
handleSlashCommand('/quit', undefined, undefined, false);
} else {
ctrlCTimerRef.current = setTimeout(() => {
@ -1127,6 +1131,7 @@ Logging in with Google... Restarting Gemini CLI to continue.
recordExitFail(config);
}
if (ctrlDPressCount > 1) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
handleSlashCommand('/quit', undefined, undefined, false);
} else {
ctrlDTimerRef.current = setTimeout(() => {
@ -1143,6 +1148,7 @@ Logging in with Google... Restarting Gemini CLI to continue.
const handleIdePromptComplete = useCallback(
(result: IdeIntegrationNudgeResult) => {
if (result.userSelection === 'yes') {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
handleSlashCommand('/ide install');
settings.setValue(
SettingScope.User,
@ -1225,6 +1231,7 @@ Logging in with Google... Restarting Gemini CLI to continue.
config.getIdeMode() &&
ideContextState
) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
handleSlashCommand('/ide status');
} else if (
keyMatchers[Command.SHOW_MORE_LINES](key) &&
@ -1425,6 +1432,7 @@ Logging in with Google... Restarting Gemini CLI to continue.
}
}
};
// eslint-disable-next-line @typescript-eslint/no-floating-promises
fetchBannerTexts();
return () => {

View file

@ -154,6 +154,7 @@ export function AuthDialog({
if (error) {
onAuthError(error);
} else {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
onSelect(authMethod, SettingScope.User);
}
};
@ -173,6 +174,7 @@ export function AuthDialog({
);
return;
}
// eslint-disable-next-line @typescript-eslint/no-floating-promises
onSelect(undefined, SettingScope.User);
}
},

View file

@ -64,11 +64,13 @@ export const useAuthCommand = (settings: LoadedSettings, config: Config) => {
useEffect(() => {
if (authState === AuthState.AwaitingApiKeyInput) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
reloadApiKey();
}
}, [authState, reloadApiKey]);
useEffect(() => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
(async () => {
if (authState !== AuthState.Unauthenticated) {
return;

View file

@ -72,6 +72,7 @@ describe('directoryCommand', () => {
describe('show', () => {
it('should display the list of directories', () => {
if (!showCommand?.action) throw new Error('No action');
// eslint-disable-next-line @typescript-eslint/no-floating-promises
showCommand.action(mockContext, '');
expect(mockWorkspaceContext.getDirectories).toHaveBeenCalled();
expect(mockContext.ui.addItem).toHaveBeenCalledWith(
@ -101,6 +102,7 @@ describe('directoryCommand', () => {
it('should show an error if no path is provided', () => {
if (!addCommand?.action) throw new Error('No action');
// eslint-disable-next-line @typescript-eslint/no-floating-promises
addCommand.action(mockContext, '');
expect(mockContext.ui.addItem).toHaveBeenCalledWith(
expect.objectContaining({

View file

@ -92,6 +92,7 @@ function updateAction(context: CommandContext, args: string): Promise<void> {
extensions,
};
// eslint-disable-next-line @typescript-eslint/no-floating-promises
updateComplete.then((updateInfos) => {
if (updateInfos.length === 0) {
context.ui.addItem(

View file

@ -30,6 +30,7 @@ describe('statsCommand', () => {
it('should display general session stats when run with no subcommand', () => {
if (!statsCommand.action) throw new Error('Command has no action');
// eslint-disable-next-line @typescript-eslint/no-floating-promises
statsCommand.action(mockContext, '');
const expectedDuration = formatDuration(
@ -50,6 +51,7 @@ describe('statsCommand', () => {
);
if (!modelSubCommand?.action) throw new Error('Subcommand has no action');
// eslint-disable-next-line @typescript-eslint/no-floating-promises
modelSubCommand.action(mockContext, '');
expect(mockContext.ui.addItem).toHaveBeenCalledWith(
@ -66,6 +68,7 @@ describe('statsCommand', () => {
);
if (!toolsSubCommand?.action) throw new Error('Subcommand has no action');
// eslint-disable-next-line @typescript-eslint/no-floating-promises
toolsSubCommand.action(mockContext, '');
expect(mockContext.ui.addItem).toHaveBeenCalledWith(

View file

@ -41,6 +41,7 @@ export const FolderTrustDialog: React.FC<FolderTrustDialogProps> = ({
}, 250);
}
};
// eslint-disable-next-line @typescript-eslint/no-floating-promises
doRelaunch();
}, [isRestarting]);

View file

@ -18,6 +18,7 @@ export const IdeTrustChangeDialog = ({ reason }: IdeTrustChangeDialogProps) => {
useKeypress(
(key) => {
if (key.name === 'r' || key.name === 'R') {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
relaunchApp();
}
},

View file

@ -373,6 +373,7 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
useMouse(
(event: MouseEvent) => {
if (event.name === 'right-release') {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
handleClipboardPaste();
}
},
@ -779,12 +780,14 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
// External editor
if (keyMatchers[Command.OPEN_EXTERNAL_EDITOR](key)) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
buffer.openInExternalEditor();
return;
}
// Ctrl+V for clipboard paste
if (keyMatchers[Command.PASTE_CLIPBOARD](key)) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
handleClipboardPaste();
return;
}

View file

@ -66,6 +66,7 @@ export const MultiFolderTrustDialog: React.FC<MultiFolderTrustDialogProps> = ({
useKeypress(
(key) => {
if (key.name === 'escape') {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
handleCancel();
}
},

View file

@ -49,6 +49,7 @@ export const Notifications = () => {
};
if (isScreenReaderEnabled) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
checkScreenReader();
}
}, [isScreenReaderEnabled]);
@ -69,6 +70,7 @@ export const Notifications = () => {
}
}
};
// eslint-disable-next-line @typescript-eslint/no-floating-promises
writeScreenReaderNudgeFile();
}, [showScreenReaderNudge]);

View file

@ -70,6 +70,7 @@ export function PermissionsModifyTrustDialog({
if (needsRestart && key.name === 'r') {
const success = commitTrustLevelChange();
if (success) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
relaunchApp();
} else {
onExit();

View file

@ -665,6 +665,7 @@ const useLoadSessions = (config: Config, state: SessionBrowserState) => {
}
};
// eslint-disable-next-line @typescript-eslint/no-floating-promises
loadSessions();
}, [config, setSessions, setLoading, setError]);
@ -693,6 +694,7 @@ const useLoadSessions = (config: Config, state: SessionBrowserState) => {
}
};
// eslint-disable-next-line @typescript-eslint/no-floating-promises
loadFullContent();
}, [
isSearchMode,

View file

@ -139,6 +139,7 @@ export function SettingsDialog({
setScrollOffset(0);
};
// eslint-disable-next-line @typescript-eslint/no-floating-promises
doSearch();
return () => {

View file

@ -57,6 +57,7 @@ export const ToolConfirmationMessage: React.FC<
setIsDiffingEnabled(client?.isDiffingEnabled() ?? false);
}
};
// eslint-disable-next-line @typescript-eslint/no-floating-promises
getIdeClient();
}
return () => {
@ -75,6 +76,7 @@ export const ToolConfirmationMessage: React.FC<
);
}
}
// eslint-disable-next-line @typescript-eslint/no-floating-promises
onConfirm(outcome);
};
@ -84,6 +86,7 @@ export const ToolConfirmationMessage: React.FC<
(key) => {
if (!isFocused) return;
if (key.name === 'escape' || (key.ctrl && key.name === 'c')) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
handleConfirm(ToolConfirmationOutcome.Cancel);
}
},

View file

@ -645,12 +645,14 @@ describe('KeypressContext', () => {
expect(keyHandler).not.toHaveBeenCalled();
// Advance time just before timeout
// eslint-disable-next-line @typescript-eslint/no-floating-promises
act(() => vi.advanceTimersByTime(ESC_TIMEOUT - 5));
// Still shouldn't broadcast
expect(keyHandler).not.toHaveBeenCalled();
// Advance past timeout
// eslint-disable-next-line @typescript-eslint/no-floating-promises
act(() => vi.advanceTimersByTime(10));
// Should now broadcast the incomplete sequence as regular input
@ -789,12 +791,14 @@ describe('KeypressContext', () => {
act(() => stdin.write('\x1b[97;13'));
// Advance time partway
// eslint-disable-next-line @typescript-eslint/no-floating-promises
act(() => vi.advanceTimersByTime(30));
// Add more to sequence
act(() => stdin.write('5'));
// Advance time from the first timeout point
// eslint-disable-next-line @typescript-eslint/no-floating-promises
act(() => vi.advanceTimersByTime(25));
// Should not have timed out yet (timeout restarted)
@ -878,6 +882,7 @@ describe('KeypressContext', () => {
act(() => stdin.write('\x1b[<'));
// Advance time past the normal kitty timeout (50ms)
// eslint-disable-next-line @typescript-eslint/no-floating-promises
act(() => vi.advanceTimersByTime(ESC_TIMEOUT + 10));
// Send the rest
@ -930,6 +935,8 @@ describe('KeypressContext', () => {
for (const char of sequence) {
act(() => stdin.write(char));
// eslint-disable-next-line @typescript-eslint/no-floating-promises
act(() => vi.advanceTimersByTime(0));
}

View file

@ -40,6 +40,7 @@ function addShellCommandToGeminiHistory(
? resultText.substring(0, MAX_OUTPUT_LENGTH) + '\n... (truncated)'
: resultText;
// eslint-disable-next-line @typescript-eslint/no-floating-promises
geminiClient.addHistory({
role: 'user',
parts: [
@ -350,6 +351,7 @@ export const useShellCommandProcessor = (
};
const execPromise = new Promise<void>((resolve) => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
executeCommand(resolve);
});

View file

@ -258,6 +258,7 @@ export const useSlashCommandProcessor = (
reloadCommands();
};
// eslint-disable-next-line @typescript-eslint/no-floating-promises
(async () => {
const ideClient = await IdeClient.getInstance();
ideClient.addStatusChangeListener(listener);
@ -278,6 +279,7 @@ export const useSlashCommandProcessor = (
appEvents.on('extensionsStopping', extensionEventListener);
return () => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
(async () => {
const ideClient = await IdeClient.getInstance();
ideClient.removeStatusChangeListener(listener);
@ -290,6 +292,7 @@ export const useSlashCommandProcessor = (
useEffect(() => {
const controller = new AbortController();
// eslint-disable-next-line @typescript-eslint/no-floating-promises
(async () => {
const commandService = await CommandService.create(
[

View file

@ -223,8 +223,10 @@ export function useAtCompletion(props: UseAtCompletionProps): void {
};
if (state.status === AtCompletionStatus.INITIALIZING) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
initialize();
} else if (state.status === AtCompletionStatus.SEARCHING) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
search();
}

View file

@ -98,6 +98,7 @@ export const useExtensionUpdates = (
return !currentState || currentState === ExtensionUpdateState.UNKNOWN;
});
if (extensionsToCheck.length === 0) return;
// eslint-disable-next-line @typescript-eslint/no-floating-promises
checkForAllExtensionUpdates(
extensionsToCheck,
extensionManager,
@ -200,6 +201,7 @@ export const useExtensionUpdates = (
);
}
if (scheduledUpdate) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
Promise.all(updatePromises).then((results) => {
const nonNullResults = results.filter((result) => result != null);
scheduledUpdate.onCompleteCallbacks.forEach((callback) => {

View file

@ -977,6 +977,7 @@ describe('useGeminiStream', () => {
// Start a query
await act(async () => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
result.current.submitQuery('test query');
});
@ -1036,6 +1037,7 @@ describe('useGeminiStream', () => {
// Start a query
await act(async () => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
result.current.submitQuery('test query');
});
@ -1076,6 +1078,7 @@ describe('useGeminiStream', () => {
// Start a query
await act(async () => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
result.current.submitQuery('test query');
});
@ -1117,6 +1120,7 @@ describe('useGeminiStream', () => {
const { result } = renderTestHook();
await act(async () => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
result.current.submitQuery('long running query');
});

View file

@ -993,6 +993,7 @@ export const useGeminiStream = (
);
if (lastQueryRef.current && lastPromptIdRef.current) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
submitQuery(
lastQueryRef.current,
{ isContinuation: true },
@ -1176,6 +1177,7 @@ export const useGeminiStream = (
const combinedParts = geminiTools.flatMap(
(toolCall) => toolCall.response.responseParts,
);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
geminiClient.addHistory({
role: 'user',
parts: combinedParts,
@ -1207,6 +1209,7 @@ export const useGeminiStream = (
return;
}
// eslint-disable-next-line @typescript-eslint/no-floating-promises
submitQuery(
responsesToSend,
{
@ -1342,6 +1345,7 @@ export const useGeminiStream = (
}
}
};
// eslint-disable-next-line @typescript-eslint/no-floating-promises
saveRestorableToolCalls();
}, [
toolCalls,

View file

@ -37,6 +37,7 @@ export function useGitBranchName(cwd: string): string | undefined {
}, [cwd, setBranchName]);
useEffect(() => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
fetchBranchName(); // Initial fetch
const gitLogsHeadPath = path.join(cwd, '.git', 'logs', 'HEAD');
@ -52,6 +53,7 @@ export function useGitBranchName(cwd: string): string | undefined {
// Changes to .git/logs/HEAD (appends) indicate HEAD has likely changed
if (eventType === 'change' || eventType === 'rename') {
// Handle rename just in case
// eslint-disable-next-line @typescript-eslint/no-floating-promises
fetchBranchName();
}
});
@ -62,6 +64,7 @@ export function useGitBranchName(cwd: string): string | undefined {
}
};
// eslint-disable-next-line @typescript-eslint/no-floating-promises
setupWatcher();
return () => {

View file

@ -49,6 +49,7 @@ export function useIdeTrustListener() {
onStoreChange();
};
// eslint-disable-next-line @typescript-eslint/no-floating-promises
(async () => {
const ideClient = await IdeClient.getInstance();
ideClient.addTrustChangeListener(handleTrustChange);
@ -56,6 +57,7 @@ export function useIdeTrustListener() {
setConnectionStatus(ideClient.getConnectionStatus().status);
})();
return () => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
(async () => {
const ideClient = await IdeClient.getInstance();
ideClient.removeTrustChangeListener(handleTrustChange);

View file

@ -87,6 +87,7 @@ export function useIncludeDirsTrust(
}
if (added.length > 0 || errors.length > 0) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
finishAddingDirectories(config, addItem, added, errors);
}
config.clearPendingIncludeDirectories();
@ -151,6 +152,7 @@ export function useIncludeDirsTrust(
/>,
);
} else if (added.length > 0 || errors.length > 0) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
finishAddingDirectories(config, addItem, added, errors);
config.clearPendingIncludeDirectories();
}

View file

@ -23,6 +23,7 @@ describe('useLoadingIndicator', () => {
afterEach(() => {
vi.useRealTimers(); // Restore real timers after each test
// eslint-disable-next-line @typescript-eslint/no-floating-promises
act(() => vi.runOnlyPendingTimers);
vi.restoreAllMocks();
});

View file

@ -58,6 +58,7 @@ export const usePrivacySettings = (config: Config) => {
});
}
};
// eslint-disable-next-line @typescript-eslint/no-floating-promises
fetchInitialState();
}, [config]);

View file

@ -181,6 +181,7 @@ export function usePromptCompletion({
lastSelectedTextRef.current = '';
}
// eslint-disable-next-line @typescript-eslint/no-floating-promises
generatePromptSuggestions();
}, [
buffer.text,

View file

@ -584,11 +584,13 @@ describe('useSelectionList', () => {
});
pressNumber('0');
// eslint-disable-next-line @typescript-eslint/no-floating-promises
act(() => vi.advanceTimersByTime(1000)); // Timeout the '0' input
pressNumber('1');
expect(mockOnSelect).not.toHaveBeenCalled(); // Should be waiting for second digit
// eslint-disable-next-line @typescript-eslint/no-floating-promises
act(() => vi.advanceTimersByTime(1000)); // Timeout '1'
expect(mockOnSelect).toHaveBeenCalledWith('Item 1');
});

View file

@ -64,6 +64,7 @@ export function useSessionResume({
refreshStaticRef.current(); // Force Static component to re-render with the updated history.
// Give the history to the Gemini client.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
config.getGeminiClient()?.resumeChat(clientHistory, resumedData);
},
[config, isGeminiClientInitialized, setQuittingMessages],

View file

@ -84,6 +84,7 @@ export function useShellHistory(
const loadedHistory = await readHistoryFile(filePath);
setHistory(loadedHistory.reverse()); // Newest first
}
// eslint-disable-next-line @typescript-eslint/no-floating-promises
loadHistory();
}, [projectRoot, storage]);
@ -97,6 +98,7 @@ export function useShellHistory(
.filter(Boolean);
setHistory(newHistory);
// Write to file in reverse order (oldest first)
// eslint-disable-next-line @typescript-eslint/no-floating-promises
writeHistoryFile(historyFilePath, [...newHistory].reverse());
setHistoryIndex(-1);
},

View file

@ -232,6 +232,7 @@ function useCommandSuggestions(
}
}
};
// eslint-disable-next-line @typescript-eslint/no-floating-promises
fetchAndSetSuggestions();
return () => abortController.abort();
}

View file

@ -112,6 +112,7 @@ export const CloudFreePrivacyNotice = ({
items={items}
initialIndex={privacyState.dataCollectionOptIn ? 0 : 1}
onSelect={(value) => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
updateDataCollectionOptIn(value);
// Only exit if there was no error.
if (!privacyState.error) {

View file

@ -105,6 +105,7 @@ export class Connection {
this.#handler = handler;
this.#peerInput = peerInput;
this.#textEncoder = new TextEncoder();
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.#receive(peerOutput);
}
@ -121,6 +122,7 @@ export class Connection {
if (trimmedLine) {
const message = JSON.parse(trimmedLine);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.#processMessage(message);
}
}

View file

@ -289,6 +289,7 @@ export class Session {
text: part.text,
};
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.sendUpdate({
sessionUpdate: part.thought
? 'agent_thought_chunk'

View file

@ -599,6 +599,7 @@ export class Config {
}
if (this.telemetrySettings.enabled) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
initializeTelemetry(this);
}

View file

@ -183,6 +183,7 @@ export class MessageBus extends EventEmitter {
this.subscribe<TResponse>(responseType, responseHandler);
// Publish the request with correlation ID
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.publish({ ...request, correlationId } as TRequest);
});
}

View file

@ -1166,6 +1166,7 @@ describe('CoreToolScheduler request queueing', () => {
};
// Schedule the first call, which will pause execution.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
scheduler.schedule([request1], abortController.signal);
// Wait for the first call to be in the 'executing' state.

View file

@ -381,6 +381,7 @@ export class CoreToolScheduler {
const sharedHandler = (request: ToolConfirmationRequest) => {
// When ASK_USER policy decision is made, respond with requiresUserConfirmation=true
// to tell tools to use their legacy confirmation flow
// eslint-disable-next-line @typescript-eslint/no-floating-promises
messageBus.publish({
type: MessageBusType.TOOL_CONFIRMATION_RESPONSE,
correlationId: request.correlationId,
@ -883,8 +884,10 @@ export class CoreToolScheduler {
confirmationDetails.type === 'edit' &&
confirmationDetails.ideConfirmation
) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
confirmationDetails.ideConfirmation.then((resolution) => {
if (resolution.status === 'accepted') {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.handleConfirmationResponse(
reqInfo.callId,
confirmationDetails.onConfirm,
@ -892,6 +895,7 @@ export class CoreToolScheduler {
signal,
);
} else {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.handleConfirmationResponse(
reqInfo.callId,
confirmationDetails.onConfirm,

View file

@ -776,6 +776,7 @@ export class HookEventHandler {
// Publish response through MessageBus
if (this.messageBus) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.messageBus.publish({
type: MessageBusType.HOOK_EXECUTION_RESPONSE,
correlationId: request.correlationId,
@ -786,6 +787,7 @@ export class HookEventHandler {
} catch (error) {
// Publish error response
if (this.messageBus) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.messageBus.publish({
type: MessageBusType.HOOK_EXECUTION_RESPONSE,
correlationId: request.correlationId,

View file

@ -278,6 +278,7 @@ export class IdeClient {
});
// Ensure the mutex is released only after the diff interaction is complete.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
promise.finally(release);
return promise;
@ -406,6 +407,7 @@ export class IdeClient {
IDEConnectionStatus.Disconnected,
'IDE integration disabled. To enable it again, run /ide enable.',
);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.client?.close();
}

View file

@ -685,6 +685,7 @@ export class ShellExecutionService {
});
});
// eslint-disable-next-line @typescript-eslint/no-floating-promises
Promise.race([processingComplete, abortFired]).then(() => {
finalize();
});

View file

@ -284,6 +284,7 @@ export class ClearcutLogger {
event: LogEvent,
): Promise<void> {
try {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.config?.getExperimentsAsync().then((experiments) => {
if (experiments) {
const exp_id_data: EventValue[] = [
@ -557,6 +558,7 @@ export class ClearcutLogger {
this.sessionData = data;
// Flush after experiments finish loading from CCPA server
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.enqueueLogEventAfterExperimentsLoadAsync(
this.createLogEvent(EventNames.START_SESSION, data),
).then(() => {
@ -900,6 +902,7 @@ export class ClearcutLogger {
];
// Flush after experiments finish loading from CCPA server
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.enqueueLogEventAfterExperimentsLoadAsync(
this.createLogEvent(EventNames.START_SESSION, data),
).then(() => {

View file

@ -96,6 +96,7 @@ export class GcpLogExporter implements LogRecordExporter {
.finally(() => {
const index = this.pendingWrites.indexOf(writePromise);
if (index > -1) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.pendingWrites.splice(index, 1);
}
});

View file

@ -94,6 +94,7 @@ export function isTelemetrySdkInitialized(): boolean {
export function bufferTelemetryEvent(fn: () => void | Promise<void>): void {
if (telemetryInitialized) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
fn();
} else {
telemetryBuffer.push(fn);
@ -303,9 +304,11 @@ export async function initializeTelemetry(
// and won't wait for the async shutdownTelemetry() to complete.
// Instead, telemetry shutdown is handled in runExitCleanup() in cleanup.ts
process.on('SIGTERM', () => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
shutdownTelemetry(config);
});
process.on('SIGINT', () => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
shutdownTelemetry(config);
});
}

View file

@ -160,6 +160,7 @@ export class McpClientManager {
}
const currentDiscoveryPromise = new Promise<void>((resolve, _reject) => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
(async () => {
try {
if (existing) {
@ -228,6 +229,7 @@ export class McpClientManager {
}
this.eventEmitter?.emit('mcp-client-update', this.clients);
const currentPromise = this.discoveryPromise;
// eslint-disable-next-line @typescript-eslint/no-floating-promises
currentPromise.then((_) => {
// If we are the last recorded discoveryPromise, then we are done, reset
// the world.

View file

@ -739,6 +739,7 @@ export async function connectAndDiscover(
toolRegistry.sortTools();
} catch (error) {
if (mcpClient) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
mcpClient.close();
}
coreEvents.emitFeedback(

View file

@ -131,6 +131,7 @@ export abstract class BaseToolInvocation<
onConfirm: async (outcome: ToolConfirmationOutcome) => {
if (outcome === ToolConfirmationOutcome.ProceedAlways) {
if (this.messageBus && this._toolName) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.messageBus.publish({
type: MessageBusType.UPDATE_POLICY,
toolName: this._toolName,
@ -220,6 +221,7 @@ export abstract class BaseToolInvocation<
};
try {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.messageBus.publish(request);
} catch (_error) {
cleanup();

View file

@ -20,6 +20,10 @@ export default [
parser: tsParser,
ecmaVersion: 2022,
sourceType: 'module',
parserOptions: {
project: './tsconfig.json',
tsconfigRootDir: import.meta.dirname,
},
},
rules: {
@ -35,6 +39,7 @@ export default [
eqeqeq: 'warn',
'no-throw-literal': 'warn',
semi: 'warn',
'@typescript-eslint/no-floating-promises': ['error'],
},
},
];

View file

@ -62,9 +62,11 @@ export class DiffManager {
) {
this.subscriptions.push(
vscode.window.onDidChangeActiveTextEditor((editor) => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.onActiveEditorChange(editor);
}),
);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.onActiveEditorChange(vscode.window.activeTextEditor);
}

View file

@ -112,6 +112,7 @@ export async function activate(context: vscode.ExtensionContext) {
detectIdeFromEnv().name,
);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
checkForUpdates(context, log, isManagedExtensionSurface);
const diffContentProvider = new DiffContentProvider();
@ -120,6 +121,7 @@ export async function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(
vscode.workspace.onDidCloseTextDocument((doc) => {
if (doc.uri.scheme === DIFF_SCHEME) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
diffManager.cancelDiff(doc.uri);
}
}),
@ -127,11 +129,12 @@ export async function activate(context: vscode.ExtensionContext) {
DIFF_SCHEME,
diffContentProvider,
),
vscode.commands.registerCommand(
(vscode.commands.registerCommand(
'gemini.diff.accept',
(uri?: vscode.Uri) => {
const docUri = uri ?? vscode.window.activeTextEditor?.document.uri;
if (docUri && docUri.scheme === DIFF_SCHEME) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
diffManager.acceptDiff(docUri);
}
},
@ -141,10 +144,11 @@ export async function activate(context: vscode.ExtensionContext) {
(uri?: vscode.Uri) => {
const docUri = uri ?? vscode.window.activeTextEditor?.document.uri;
if (docUri && docUri.scheme === DIFF_SCHEME) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
diffManager.cancelDiff(docUri);
}
},
),
)),
);
ideServer = new IDEServer(log, diffManager);
@ -166,12 +170,14 @@ export async function activate(context: vscode.ExtensionContext) {
}
context.subscriptions.push(
vscode.workspace.onDidChangeWorkspaceFolders(() => {
(vscode.workspace.onDidChangeWorkspaceFolders(() => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
ideServer.syncEnvVars();
}),
vscode.workspace.onDidGrantWorkspaceTrust(() => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
ideServer.syncEnvVars();
}),
})),
vscode.commands.registerCommand('gemini-cli.runGeminiCLI', async () => {
const workspaceFolders = vscode.workspace.workspaceFolders;
if (!workspaceFolders || workspaceFolders.length === 0) {

View file

@ -107,6 +107,7 @@ function sendIdeContextUpdateNotification(
params: ideContext,
});
// eslint-disable-next-line @typescript-eslint/no-floating-promises
transport.send(notification);
}
@ -196,6 +197,7 @@ export class IDEServer {
const onDidChangeDiffSubscription = this.diffManager.onDidChange(
(notification) => {
for (const transport of Object.values(this.transports)) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
transport.send(notification);
}
},
@ -248,6 +250,8 @@ export class IDEServer {
delete this.transports[transport.sessionId];
}
};
// eslint-disable-next-line @typescript-eslint/no-floating-promises
mcpServer.connect(transport);
} else {
this.log(