feat: Add a --session-summary flag (#7347)

This commit is contained in:
Lee James
2025-08-29 12:53:39 -04:00
committed by GitHub
parent eb13b2a7a1
commit 6a9fb6d2ea
3 changed files with 61 additions and 1 deletions

View File

@@ -0,0 +1,37 @@
/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { TestRig } from './test-helper.js';
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { join } from 'node:path';
import { readFileSync } from 'node:fs';
describe('session-summary flag', () => {
let rig: TestRig;
beforeEach(function (context) {
rig = new TestRig();
if (context.task.name) {
rig.setup(context.task.name);
}
});
afterEach(async () => {
await rig.cleanup();
});
it('should write a session summary in non-interactive mode', async () => {
const summaryPath = join(rig.testDir!, 'summary.json');
await rig.run('Say hello', '--session-summary', summaryPath);
const summaryContent = readFileSync(summaryPath, 'utf-8');
const summary = JSON.parse(summaryContent);
expect(summary).toBeDefined();
expect(summary.models).toBeDefined();
expect(summary.tools).toBeDefined();
});
});

View File

@@ -78,6 +78,7 @@ export interface CliArgs {
proxy: string | undefined; proxy: string | undefined;
includeDirectories: string[] | undefined; includeDirectories: string[] | undefined;
screenReader: boolean | undefined; screenReader: boolean | undefined;
sessionSummary: string | undefined;
} }
export async function parseArguments(settings: Settings): Promise<CliArgs> { export async function parseArguments(settings: Settings): Promise<CliArgs> {
@@ -227,6 +228,10 @@ export async function parseArguments(settings: Settings): Promise<CliArgs> {
description: 'Enable screen reader mode for accessibility.', description: 'Enable screen reader mode for accessibility.',
default: false, default: false,
}) })
.option('session-summary', {
type: 'string',
description: 'File to write session summary to.',
})
.deprecateOption( .deprecateOption(
'telemetry', 'telemetry',
'Use settings.json instead. This flag will be removed in a future version.', 'Use settings.json instead. This flag will be removed in a future version.',

View File

@@ -24,7 +24,11 @@ import { getUserStartupWarnings } from './utils/userStartupWarnings.js';
import { ConsolePatcher } from './ui/utils/ConsolePatcher.js'; import { ConsolePatcher } from './ui/utils/ConsolePatcher.js';
import { runNonInteractive } from './nonInteractiveCli.js'; import { runNonInteractive } from './nonInteractiveCli.js';
import { loadExtensions } from './config/extension.js'; import { loadExtensions } from './config/extension.js';
import { cleanupCheckpoints, registerCleanup } from './utils/cleanup.js'; import {
cleanupCheckpoints,
registerCleanup,
runExitCleanup,
} from './utils/cleanup.js';
import { getCliVersion } from './utils/version.js'; import { getCliVersion } from './utils/version.js';
import type { Config } from '@google/gemini-cli-core'; import type { Config } from '@google/gemini-cli-core';
import { import {
@@ -36,6 +40,7 @@ import {
IdeConnectionEvent, IdeConnectionEvent,
IdeConnectionType, IdeConnectionType,
FatalConfigError, FatalConfigError,
uiTelemetryService,
} from '@google/gemini-cli-core'; } from '@google/gemini-cli-core';
import { validateAuthMethod } from './config/auth.js'; import { validateAuthMethod } from './config/auth.js';
import { setMaxSizedBoxDebugging } from './ui/components/shared/MaxSizedBox.js'; import { setMaxSizedBoxDebugging } from './ui/components/shared/MaxSizedBox.js';
@@ -45,6 +50,7 @@ import { checkForUpdates } from './ui/utils/updateCheck.js';
import { handleAutoUpdate } from './utils/handleAutoUpdate.js'; import { handleAutoUpdate } from './utils/handleAutoUpdate.js';
import { appEvents, AppEvent } from './utils/events.js'; import { appEvents, AppEvent } from './utils/events.js';
import { SettingsContext } from './ui/contexts/SettingsContext.js'; import { SettingsContext } from './ui/contexts/SettingsContext.js';
import { writeFileSync } from 'node:fs';
export function validateDnsResolutionOrder( export function validateDnsResolutionOrder(
order: string | undefined, order: string | undefined,
@@ -225,6 +231,16 @@ export async function main() {
argv, argv,
); );
if (argv.sessionSummary) {
registerCleanup(() => {
const metrics = uiTelemetryService.getMetrics();
writeFileSync(
argv.sessionSummary!,
JSON.stringify({ sessionMetrics: metrics }, null, 2),
);
});
}
const consolePatcher = new ConsolePatcher({ const consolePatcher = new ConsolePatcher({
stderr: true, stderr: true,
debugMode: config.getDebugMode(), debugMode: config.getDebugMode(),
@@ -434,6 +450,8 @@ export async function main() {
} }
await runNonInteractive(nonInteractiveConfig, input, prompt_id); await runNonInteractive(nonInteractiveConfig, input, prompt_id);
// Call cleanup before process.exit, which causes cleanup to not run
await runExitCleanup();
process.exit(0); process.exit(0);
} }