feat(cli) Custom Commands work in Non-Interactive/Headless Mode (#8305)

This commit is contained in:
James
2025-09-19 13:49:35 +00:00
committed by GitHub
parent 23467cdbdb
commit 2c4f61eca5
5 changed files with 417 additions and 26 deletions
+39 -16
View File
@@ -5,6 +5,8 @@
*/
import type { Config, ToolCallRequestInfo } from '@google/gemini-cli-core';
import { isSlashCommand } from './ui/utils/commandUtils.js';
import type { LoadedSettings } from './config/settings.js';
import {
executeToolCall,
shutdownTelemetry,
@@ -16,8 +18,10 @@ import {
JsonFormatter,
uiTelemetryService,
} from '@google/gemini-cli-core';
import type { Content, Part } from '@google/genai';
import { handleSlashCommand } from './nonInteractiveCliCommands.js';
import { ConsolePatcher } from './ui/utils/ConsolePatcher.js';
import { handleAtCommand } from './ui/hooks/atCommandProcessor.js';
import {
@@ -29,6 +33,7 @@ import {
export async function runNonInteractive(
config: Config,
settings: LoadedSettings,
input: string,
prompt_id: string,
): Promise<void> {
@@ -52,26 +57,44 @@ export async function runNonInteractive(
const abortController = new AbortController();
const { processedQuery, shouldProceed } = await handleAtCommand({
query: input,
config,
addItem: (_item, _timestamp) => 0,
onDebugMessage: () => {},
messageId: Date.now(),
signal: abortController.signal,
});
let query: Part[] | undefined;
if (!shouldProceed || !processedQuery) {
// An error occurred during @include processing (e.g., file not found).
// The error message is already logged by handleAtCommand.
throw new FatalInputError(
'Exiting due to an error processing the @ command.',
if (isSlashCommand(input)) {
const slashCommandResult = await handleSlashCommand(
input,
abortController,
config,
settings,
);
// If a slash command is found and returns a prompt, use it.
// Otherwise, slashCommandResult fall through to the default prompt
// handling.
if (slashCommandResult) {
query = slashCommandResult as Part[];
}
}
let currentMessages: Content[] = [
{ role: 'user', parts: processedQuery as Part[] },
];
if (!query) {
const { processedQuery, shouldProceed } = await handleAtCommand({
query: input,
config,
addItem: (_item, _timestamp) => 0,
onDebugMessage: () => {},
messageId: Date.now(),
signal: abortController.signal,
});
if (!shouldProceed || !processedQuery) {
// An error occurred during @include processing (e.g., file not found).
// The error message is already logged by handleAtCommand.
throw new FatalInputError(
'Exiting due to an error processing the @ command.',
);
}
query = processedQuery as Part[];
}
let currentMessages: Content[] = [{ role: 'user', parts: query }];
let turnCount = 0;
while (true) {