65 lines
2.0 KiB
TypeScript
65 lines
2.0 KiB
TypeScript
import { HOOK_EVENTS } from 'src/entrypoints/agentSdkTypes.ts'
|
|
import type { AppState } from 'src/state/AppState.js'
|
|
import { logForDebugging } from '../debug.js'
|
|
import type { HooksSettings } from '../settings/types.js'
|
|
import { addSessionHook, removeSessionHook } from './sessionHooks.js'
|
|
|
|
/**
|
|
* Registers hooks from a skill's frontmatter as session hooks.
|
|
*
|
|
* Hooks are registered as session-scoped hooks that persist for the duration
|
|
* of the session. If a hook has `once: true`, it will be automatically removed
|
|
* after its first successful execution.
|
|
*
|
|
* @param setAppState - Function to update the app state
|
|
* @param sessionId - The current session ID
|
|
* @param hooks - The hooks settings from the skill's frontmatter
|
|
* @param skillName - The name of the skill (for logging)
|
|
* @param skillRoot - The base directory of the skill (for CLAUDE_PLUGIN_ROOT env var)
|
|
*/
|
|
export function registerSkillHooks(
|
|
setAppState: (updater: (prev: AppState) => AppState) => void,
|
|
sessionId: string,
|
|
hooks: HooksSettings,
|
|
skillName: string,
|
|
skillRoot?: string,
|
|
): void {
|
|
let registeredCount = 0
|
|
|
|
for (const eventName of HOOK_EVENTS) {
|
|
const matchers = hooks[eventName]
|
|
if (!matchers) continue
|
|
|
|
for (const matcher of matchers) {
|
|
for (const hook of matcher.hooks) {
|
|
// For once: true hooks, use onHookSuccess callback to remove after execution
|
|
const onHookSuccess = hook.once
|
|
? () => {
|
|
logForDebugging(
|
|
`Removing one-shot hook for event ${eventName} in skill '${skillName}'`,
|
|
)
|
|
removeSessionHook(setAppState, sessionId, eventName, hook)
|
|
}
|
|
: undefined
|
|
|
|
addSessionHook(
|
|
setAppState,
|
|
sessionId,
|
|
eventName,
|
|
matcher.matcher || '',
|
|
hook,
|
|
onHookSuccess,
|
|
skillRoot,
|
|
)
|
|
registeredCount++
|
|
}
|
|
}
|
|
}
|
|
|
|
if (registeredCount > 0) {
|
|
logForDebugging(
|
|
`Registered ${registeredCount} hooks from skill '${skillName}'`,
|
|
)
|
|
}
|
|
}
|