mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-29 22:44:45 -07:00
feat(hooks): Hook Session Lifecycle & Compression Integration (#14151)
This commit is contained in:
@@ -220,6 +220,57 @@ function validateNotificationInput(input: Record<string, unknown>): {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates SessionStart input fields
|
||||
*/
|
||||
function validateSessionStartInput(input: Record<string, unknown>): {
|
||||
source: SessionStartSource;
|
||||
} {
|
||||
const source = input['source'];
|
||||
if (typeof source !== 'string') {
|
||||
throw new Error(
|
||||
'Invalid input for SessionStart hook event: source must be a string',
|
||||
);
|
||||
}
|
||||
return {
|
||||
source: source as SessionStartSource,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates SessionEnd input fields
|
||||
*/
|
||||
function validateSessionEndInput(input: Record<string, unknown>): {
|
||||
reason: SessionEndReason;
|
||||
} {
|
||||
const reason = input['reason'];
|
||||
if (typeof reason !== 'string') {
|
||||
throw new Error(
|
||||
'Invalid input for SessionEnd hook event: reason must be a string',
|
||||
);
|
||||
}
|
||||
return {
|
||||
reason: reason as SessionEndReason,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates PreCompress input fields
|
||||
*/
|
||||
function validatePreCompressInput(input: Record<string, unknown>): {
|
||||
trigger: PreCompressTrigger;
|
||||
} {
|
||||
const trigger = input['trigger'];
|
||||
if (typeof trigger !== 'string') {
|
||||
throw new Error(
|
||||
'Invalid input for PreCompress hook event: trigger must be a string',
|
||||
);
|
||||
}
|
||||
return {
|
||||
trigger: trigger as PreCompressTrigger,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook event bus that coordinates hook execution across the system
|
||||
*/
|
||||
@@ -704,6 +755,21 @@ export class HookEventHandler {
|
||||
);
|
||||
break;
|
||||
}
|
||||
case HookEventName.SessionStart: {
|
||||
const { source } = validateSessionStartInput(enrichedInput);
|
||||
result = await this.fireSessionStartEvent(source);
|
||||
break;
|
||||
}
|
||||
case HookEventName.SessionEnd: {
|
||||
const { reason } = validateSessionEndInput(enrichedInput);
|
||||
result = await this.fireSessionEndEvent(reason);
|
||||
break;
|
||||
}
|
||||
case HookEventName.PreCompress: {
|
||||
const { trigger } = validatePreCompressInput(enrichedInput);
|
||||
result = await this.firePreCompressEvent(trigger);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new Error(`Unsupported hook event: ${request.eventName}`);
|
||||
}
|
||||
|
||||
@@ -238,8 +238,18 @@ export class HookRunner {
|
||||
debugLogger.warn(`Hook stdin error: ${err}`);
|
||||
}
|
||||
});
|
||||
child.stdin.write(JSON.stringify(input));
|
||||
child.stdin.end();
|
||||
|
||||
// Wrap write operations in try-catch to handle synchronous EPIPE errors
|
||||
// that occur when the child process exits before we finish writing
|
||||
try {
|
||||
child.stdin.write(JSON.stringify(input));
|
||||
child.stdin.end();
|
||||
} catch (err) {
|
||||
// Ignore EPIPE errors which happen when the child process closes stdin early
|
||||
if (err instanceof Error && 'code' in err && err.code !== 'EPIPE') {
|
||||
debugLogger.warn(`Hook stdin write error: ${err}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Collect stdout
|
||||
|
||||
@@ -19,3 +19,10 @@ export { HookEventHandler } from './hookEventHandler.js';
|
||||
export type { HookRegistryEntry, ConfigSource } from './hookRegistry.js';
|
||||
export type { AggregatedHookResult } from './hookAggregator.js';
|
||||
export type { HookEventContext } from './hookPlanner.js';
|
||||
|
||||
// Export hook trigger functions
|
||||
export {
|
||||
fireSessionStartHook,
|
||||
fireSessionEndHook,
|
||||
firePreCompressHook,
|
||||
} from '../core/sessionHookTriggers.js';
|
||||
|
||||
@@ -463,7 +463,6 @@ export enum SessionStartSource {
|
||||
Startup = 'startup',
|
||||
Resume = 'resume',
|
||||
Clear = 'clear',
|
||||
Compress = 'compress',
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user