93 lines
2.2 KiB
TypeScript
93 lines
2.2 KiB
TypeScript
import type { Event, HookType } from "./event-queue.js";
|
|
|
|
export interface HookConfig {
|
|
startup?: string;
|
|
agent_begin?: string;
|
|
agent_stop?: string;
|
|
shutdown?: string;
|
|
}
|
|
|
|
export interface AgentRuntimeLike {
|
|
processEvent(event: Event): Promise<any>;
|
|
}
|
|
|
|
type EnqueueFn = (event: Omit<Event, "id" | "timestamp">) => Event | null;
|
|
|
|
export class HookManager {
|
|
private config: HookConfig = {};
|
|
|
|
parseConfig(content: string): HookConfig {
|
|
const config: HookConfig = {};
|
|
const lines = content.split("\n");
|
|
|
|
let inHooksSection = false;
|
|
let currentHookType: HookType | null = null;
|
|
|
|
for (const line of lines) {
|
|
const h2Match = line.match(/^##\s+(.+)$/);
|
|
if (h2Match) {
|
|
if (inHooksSection) {
|
|
// Another ## heading ends the Hooks section
|
|
break;
|
|
}
|
|
if (h2Match[1].trim() === "Hooks") {
|
|
inHooksSection = true;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if (!inHooksSection) continue;
|
|
|
|
const h3Match = line.match(/^###\s+(.+)$/);
|
|
if (h3Match) {
|
|
const name = h3Match[1].trim();
|
|
if (name === "startup" || name === "agent_begin" || name === "agent_stop" || name === "shutdown") {
|
|
currentHookType = name;
|
|
} else {
|
|
currentHookType = null;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
const instructionMatch = line.match(/^Instruction:\s*(.+)$/);
|
|
if (instructionMatch && currentHookType !== null) {
|
|
config[currentHookType] = instructionMatch[1].trim();
|
|
continue;
|
|
}
|
|
}
|
|
|
|
this.config = config;
|
|
return config;
|
|
}
|
|
|
|
fire(hookType: HookType, enqueue: EnqueueFn): void {
|
|
const instruction = this.config[hookType];
|
|
|
|
enqueue({
|
|
type: "hook",
|
|
payload: {
|
|
hookType,
|
|
...(instruction !== undefined ? { instruction } : {}),
|
|
},
|
|
source: "hook-manager",
|
|
});
|
|
}
|
|
|
|
async fireInline(hookType: HookType, runtime: AgentRuntimeLike): Promise<void> {
|
|
const instruction = this.config[hookType];
|
|
|
|
const event: Event = {
|
|
id: 0,
|
|
type: "hook",
|
|
payload: {
|
|
hookType,
|
|
...(instruction !== undefined ? { instruction } : {}),
|
|
},
|
|
timestamp: new Date(),
|
|
source: "hook-manager-inline",
|
|
};
|
|
|
|
await runtime.processEvent(event);
|
|
}
|
|
}
|