mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-21 03:21:11 -07:00
Fix extensions logging race condition and slash command logging (#12732)
This commit is contained in:
@@ -303,7 +303,7 @@ export class ExtensionManager extends ExtensionLoader {
|
||||
throw new Error(`Extension not found`);
|
||||
}
|
||||
if (isUpdate) {
|
||||
logExtensionUpdateEvent(
|
||||
await logExtensionUpdateEvent(
|
||||
this.telemetryConfig,
|
||||
new ExtensionUpdateEvent(
|
||||
hashValue(newExtensionConfig.name),
|
||||
@@ -315,7 +315,7 @@ export class ExtensionManager extends ExtensionLoader {
|
||||
),
|
||||
);
|
||||
} else {
|
||||
logExtensionInstallEvent(
|
||||
await logExtensionInstallEvent(
|
||||
this.telemetryConfig,
|
||||
new ExtensionInstallEvent(
|
||||
hashValue(newExtensionConfig.name),
|
||||
@@ -348,7 +348,7 @@ export class ExtensionManager extends ExtensionLoader {
|
||||
? getExtensionId(config, installMetadata)
|
||||
: undefined;
|
||||
if (isUpdate) {
|
||||
logExtensionUpdateEvent(
|
||||
await logExtensionUpdateEvent(
|
||||
this.telemetryConfig,
|
||||
new ExtensionUpdateEvent(
|
||||
hashValue(config?.name ?? ''),
|
||||
@@ -360,7 +360,7 @@ export class ExtensionManager extends ExtensionLoader {
|
||||
),
|
||||
);
|
||||
} else {
|
||||
logExtensionInstallEvent(
|
||||
await logExtensionInstallEvent(
|
||||
this.telemetryConfig,
|
||||
new ExtensionInstallEvent(
|
||||
hashValue(newExtensionConfig?.name ?? ''),
|
||||
@@ -403,7 +403,7 @@ export class ExtensionManager extends ExtensionLoader {
|
||||
|
||||
this.extensionEnablementManager.remove(extension.name);
|
||||
|
||||
logExtensionUninstall(
|
||||
await logExtensionUninstall(
|
||||
this.telemetryConfig,
|
||||
new ExtensionUninstallEvent(
|
||||
hashValue(extension.name),
|
||||
@@ -569,6 +569,8 @@ export class ExtensionManager extends ExtensionLoader {
|
||||
const status = workspaceEnabled ? chalk.green('✓') : chalk.red('✗');
|
||||
let output = `${status} ${extension.name} (${extension.version})`;
|
||||
output += `\n ID: ${extension.id}`;
|
||||
output += `\n name: ${hashValue(extension.name)}`;
|
||||
|
||||
output += `\n Path: ${extension.path}`;
|
||||
if (extension.installMetadata) {
|
||||
output += `\n Source: ${extension.installMetadata.source} (Type: ${extension.installMetadata.type})`;
|
||||
@@ -621,7 +623,7 @@ export class ExtensionManager extends ExtensionLoader {
|
||||
scope === SettingScope.Workspace ? this.workspaceDir : os.homedir();
|
||||
this.extensionEnablementManager.disable(name, true, scopePath);
|
||||
}
|
||||
logExtensionDisable(
|
||||
await logExtensionDisable(
|
||||
this.telemetryConfig,
|
||||
new ExtensionDisableEvent(hashValue(name), extension.id, scope),
|
||||
);
|
||||
@@ -656,7 +658,7 @@ export class ExtensionManager extends ExtensionLoader {
|
||||
scope === SettingScope.Workspace ? this.workspaceDir : os.homedir();
|
||||
this.extensionEnablementManager.enable(name, true, scopePath);
|
||||
}
|
||||
logExtensionEnable(
|
||||
await logExtensionEnable(
|
||||
this.telemetryConfig,
|
||||
new ExtensionEnableEvent(hashValue(name), extension.id, scope),
|
||||
);
|
||||
|
||||
@@ -842,6 +842,52 @@ describe('FileCommandLoader', () => {
|
||||
assert.fail('Incorrect action type');
|
||||
}
|
||||
});
|
||||
|
||||
it('correctly loads extensionId for extension commands', async () => {
|
||||
const extensionId = 'my-test-ext-id-123';
|
||||
const extensionDir = path.join(
|
||||
process.cwd(),
|
||||
GEMINI_DIR,
|
||||
'extensions',
|
||||
'my-test-ext',
|
||||
);
|
||||
|
||||
mock({
|
||||
[extensionDir]: {
|
||||
'gemini-extension.json': JSON.stringify({
|
||||
name: 'my-test-ext',
|
||||
id: extensionId,
|
||||
version: '1.0.0',
|
||||
}),
|
||||
commands: {
|
||||
'my-cmd.toml': 'prompt = "My test command"',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const mockConfig = {
|
||||
getProjectRoot: vi.fn(() => process.cwd()),
|
||||
getExtensions: vi.fn(() => [
|
||||
{
|
||||
name: 'my-test-ext',
|
||||
id: extensionId,
|
||||
version: '1.0.0',
|
||||
isActive: true,
|
||||
path: extensionDir,
|
||||
},
|
||||
]),
|
||||
getFolderTrust: vi.fn(() => false),
|
||||
isTrustedFolder: vi.fn(() => false),
|
||||
} as unknown as Config;
|
||||
const loader = new FileCommandLoader(mockConfig);
|
||||
const commands = await loader.loadCommands(signal);
|
||||
|
||||
expect(commands).toHaveLength(1);
|
||||
const command = commands[0];
|
||||
expect(command.name).toBe('my-cmd');
|
||||
expect(command.extensionName).toBe('my-test-ext');
|
||||
expect(command.extensionId).toBe(extensionId);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Argument Handling Integration (via ShellProcessor)', () => {
|
||||
|
||||
@@ -37,6 +37,7 @@ import { AtFileProcessor } from './prompt-processors/atFileProcessor.js';
|
||||
interface CommandDirectory {
|
||||
path: string;
|
||||
extensionName?: string;
|
||||
extensionId?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,6 +111,7 @@ export class FileCommandLoader implements ICommandLoader {
|
||||
path.join(dirInfo.path, file),
|
||||
dirInfo.path,
|
||||
dirInfo.extensionName,
|
||||
dirInfo.extensionId,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -158,6 +160,7 @@ export class FileCommandLoader implements ICommandLoader {
|
||||
const extensionCommandDirs = activeExtensions.map((ext) => ({
|
||||
path: path.join(ext.path, 'commands'),
|
||||
extensionName: ext.name,
|
||||
extensionId: ext.id,
|
||||
}));
|
||||
|
||||
dirs.push(...extensionCommandDirs);
|
||||
@@ -177,6 +180,7 @@ export class FileCommandLoader implements ICommandLoader {
|
||||
filePath: string,
|
||||
baseDir: string,
|
||||
extensionName?: string,
|
||||
extensionId?: string,
|
||||
): Promise<SlashCommand | null> {
|
||||
let fileContent: string;
|
||||
try {
|
||||
@@ -265,6 +269,7 @@ export class FileCommandLoader implements ICommandLoader {
|
||||
description,
|
||||
kind: CommandKind.FILE,
|
||||
extensionName,
|
||||
extensionId,
|
||||
action: async (
|
||||
context: CommandContext,
|
||||
_args: string,
|
||||
|
||||
Reference in New Issue
Block a user