feat(coder): add plugin hook host
- Typed hook registry with registerHook/emitHook/clearHooks - Hooks: tool.execute.before/after, turn.start/end, task.terminal - SUL patterns only (oh-my-openagent: architecture study, no code copy)
This commit is contained in:
42
apps/coder/src/plugins/host.ts
Normal file
42
apps/coder/src/plugins/host.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
export type HookName =
|
||||
| 'tool.execute.before'
|
||||
| 'tool.execute.after'
|
||||
| 'turn.start'
|
||||
| 'turn.end'
|
||||
| 'task.terminal';
|
||||
|
||||
export interface ToolHookContext {
|
||||
tool: string;
|
||||
args: Record<string, unknown>;
|
||||
projectRoot: string;
|
||||
sessionId: string;
|
||||
}
|
||||
|
||||
export interface ToolResultContext extends ToolHookContext {
|
||||
result: unknown;
|
||||
}
|
||||
|
||||
export type PluginHook = (ctx: any) => Promise<any>;
|
||||
|
||||
const hooks = new Map<HookName, PluginHook[]>();
|
||||
|
||||
export function registerHook(name: HookName, fn: PluginHook): void {
|
||||
const list = hooks.get(name) || [];
|
||||
list.push(fn);
|
||||
hooks.set(name, list);
|
||||
}
|
||||
|
||||
export async function emitHook(name: HookName, ctx: any): Promise<any> {
|
||||
const list = hooks.get(name);
|
||||
if (!list) return ctx;
|
||||
let current = ctx;
|
||||
for (const fn of list) {
|
||||
const result = await fn(current);
|
||||
if (result !== undefined) current = result;
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
export function clearHooks(): void {
|
||||
hooks.clear();
|
||||
}
|
||||
Reference in New Issue
Block a user