mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-01 00:40:42 -07:00
fix(hooks): enable /hooks disable to reliably stop single hooks (#16804)
This commit is contained in:
@@ -1532,40 +1532,16 @@ describe('Config getHooks', () => {
|
||||
});
|
||||
|
||||
it('should return the hooks configuration when provided', () => {
|
||||
const mockHooks: { [K in HookEventName]?: HookDefinition[] } = {
|
||||
[HookEventName.BeforeTool]: [
|
||||
const mockHooks = {
|
||||
BeforeTool: [
|
||||
{
|
||||
matcher: 'write_file',
|
||||
hooks: [
|
||||
{
|
||||
type: HookType.Command,
|
||||
command: 'echo "test hook"',
|
||||
timeout: 5000,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
[HookEventName.AfterTool]: [
|
||||
{
|
||||
hooks: [
|
||||
{
|
||||
type: HookType.Command,
|
||||
command: './hooks/after-tool.sh',
|
||||
timeout: 10000,
|
||||
},
|
||||
],
|
||||
hooks: [{ type: HookType.Command, command: 'echo 1' }],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const config = new Config({
|
||||
...baseParams,
|
||||
hooks: mockHooks,
|
||||
});
|
||||
|
||||
const config = new Config({ ...baseParams, hooks: mockHooks });
|
||||
const retrievedHooks = config.getHooks();
|
||||
expect(retrievedHooks).toEqual(mockHooks);
|
||||
expect(retrievedHooks).toBe(mockHooks); // Should return the same reference
|
||||
});
|
||||
|
||||
it('should return hooks with all supported event types', () => {
|
||||
@@ -1842,6 +1818,43 @@ describe('Availability Service Integration', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Hooks configuration', () => {
|
||||
const baseParams: ConfigParameters = {
|
||||
sessionId: 'test',
|
||||
targetDir: '.',
|
||||
debugMode: false,
|
||||
model: 'test-model',
|
||||
cwd: '.',
|
||||
hooks: { disabled: ['initial-hook'] },
|
||||
};
|
||||
|
||||
it('updateDisabledHooks should update the disabled list', () => {
|
||||
const config = new Config(baseParams);
|
||||
expect(config.getDisabledHooks()).toEqual(['initial-hook']);
|
||||
|
||||
const newDisabled = ['new-hook-1', 'new-hook-2'];
|
||||
config.updateDisabledHooks(newDisabled);
|
||||
|
||||
expect(config.getDisabledHooks()).toEqual(['new-hook-1', 'new-hook-2']);
|
||||
});
|
||||
|
||||
it('updateDisabledHooks should only update disabled list and not definitions', () => {
|
||||
const initialHooks = {
|
||||
BeforeAgent: [
|
||||
{
|
||||
hooks: [{ type: HookType.Command, command: 'initial' }],
|
||||
},
|
||||
],
|
||||
};
|
||||
const config = new Config({ ...baseParams, hooks: initialHooks });
|
||||
|
||||
config.updateDisabledHooks(['some-hook']);
|
||||
|
||||
expect(config.getDisabledHooks()).toEqual(['some-hook']);
|
||||
expect(config.getHooks()).toEqual(initialHooks);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Config Quota & Preview Model Access', () => {
|
||||
let config: Config;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
@@ -511,13 +511,11 @@ export class Config {
|
||||
private pendingIncludeDirectories: string[];
|
||||
private readonly enableHooks: boolean;
|
||||
private readonly enableHooksUI: boolean;
|
||||
private readonly hooks:
|
||||
| { [K in HookEventName]?: HookDefinition[] }
|
||||
| undefined;
|
||||
private readonly projectHooks:
|
||||
private hooks: { [K in HookEventName]?: HookDefinition[] } | undefined;
|
||||
private projectHooks:
|
||||
| ({ [K in HookEventName]?: HookDefinition[] } & { disabled?: string[] })
|
||||
| undefined;
|
||||
private readonly disabledHooks: string[];
|
||||
private disabledHooks: string[];
|
||||
private experiments: Experiments | undefined;
|
||||
private experimentsPromise: Promise<void> | undefined;
|
||||
private hookSystem?: HookSystem;
|
||||
@@ -710,8 +708,15 @@ export class Config {
|
||||
};
|
||||
this.retryFetchErrors = params.retryFetchErrors ?? false;
|
||||
this.disableYoloMode = params.disableYoloMode ?? false;
|
||||
this.hooks = params.hooks;
|
||||
this.projectHooks = params.projectHooks;
|
||||
|
||||
if (params.hooks) {
|
||||
const { disabled: _, ...restOfHooks } = params.hooks;
|
||||
this.hooks = restOfHooks;
|
||||
}
|
||||
if (params.projectHooks) {
|
||||
this.projectHooks = params.projectHooks;
|
||||
}
|
||||
|
||||
this.experiments = params.experiments;
|
||||
this.onModelChange = params.onModelChange;
|
||||
this.onReload = params.onReload;
|
||||
@@ -1930,6 +1935,15 @@ export class Config {
|
||||
return this.projectHooks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the list of disabled hooks dynamically.
|
||||
* This is used to keep the running system in sync with settings changes
|
||||
* without risk of loading new hook definitions into memory.
|
||||
*/
|
||||
updateDisabledHooks(disabledHooks: string[]): void {
|
||||
this.disabledHooks = disabledHooks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get disabled hooks list
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user