68 lines
2.2 KiB
TypeScript
68 lines
2.2 KiB
TypeScript
import { HOOK_EVENTS, type HookEvent } from 'src/entrypoints/agentSdkTypes.js'
|
|
import type { AppState } from 'src/state/AppState.js'
|
|
import { logForDebugging } from '../debug.js'
|
|
import type { HooksSettings } from '../settings/types.js'
|
|
import { addSessionHook } from './sessionHooks.js'
|
|
|
|
/**
|
|
* Register hooks from frontmatter (agent or skill) into session-scoped hooks.
|
|
* These hooks will be active for the duration of the session/agent and cleaned up
|
|
* when the session/agent ends.
|
|
*
|
|
* @param setAppState Function to update app state
|
|
* @param sessionId Session ID to scope the hooks (agent ID for agents, session ID for skills)
|
|
* @param hooks The hooks settings from frontmatter
|
|
* @param sourceName Human-readable source name for logging (e.g., "agent 'my-agent'")
|
|
* @param isAgent If true, converts Stop hooks to SubagentStop (since subagents trigger SubagentStop, not Stop)
|
|
*/
|
|
export function registerFrontmatterHooks(
|
|
setAppState: (updater: (prev: AppState) => AppState) => void,
|
|
sessionId: string,
|
|
hooks: HooksSettings,
|
|
sourceName: string,
|
|
isAgent: boolean = false,
|
|
): void {
|
|
if (!hooks || Object.keys(hooks).length === 0) {
|
|
return
|
|
}
|
|
|
|
let hookCount = 0
|
|
|
|
for (const event of HOOK_EVENTS) {
|
|
const matchers = hooks[event]
|
|
if (!matchers || matchers.length === 0) {
|
|
continue
|
|
}
|
|
|
|
// For agents, convert Stop hooks to SubagentStop since that's what fires when an agent completes
|
|
// (executeStopHooks uses SubagentStop when called with an agentId)
|
|
let targetEvent: HookEvent = event
|
|
if (isAgent && event === 'Stop') {
|
|
targetEvent = 'SubagentStop'
|
|
logForDebugging(
|
|
`Converting Stop hook to SubagentStop for ${sourceName} (subagents trigger SubagentStop)`,
|
|
)
|
|
}
|
|
|
|
for (const matcherConfig of matchers) {
|
|
const matcher = matcherConfig.matcher ?? ''
|
|
const hooksArray = matcherConfig.hooks
|
|
|
|
if (!hooksArray || hooksArray.length === 0) {
|
|
continue
|
|
}
|
|
|
|
for (const hook of hooksArray) {
|
|
addSessionHook(setAppState, sessionId, targetEvent, matcher, hook)
|
|
hookCount++
|
|
}
|
|
}
|
|
}
|
|
|
|
if (hookCount > 0) {
|
|
logForDebugging(
|
|
`Registered ${hookCount} frontmatter hook(s) from ${sourceName} for session ${sessionId}`,
|
|
)
|
|
}
|
|
}
|