Skip to main content

Cyberstrike is now open source! AI-powered penetration testing for security professionals. Star on GitHub

Plugin Hooks

A plugin is a function (input) => Promise<Hooks> that returns an object of hook functions. Each hook receives an input (read-only context) and, for most hooks, an output object you mutate to change behavior. Throwing from a hook aborts the operation.

Plugin hook execution flow: chat.params/chat.headers before the LLM call, permission.ask before a tool, tool.execute.before to modify args or block, then tool.execute.after to transform output

See Creating Plugins for how to scaffold and register a plugin. This page is the reference for every hook.

Hook Reference

HookWhen it runsYou can…
eventOn any bus eventObserve events (logging, analytics)
configAfter config loadsInspect/adjust the loaded config
toolRegistrationAdd custom tools (map of name → definition)
authRegistrationAdd a custom auth provider
chat.messageA user message is receivedRead/append message parts
chat.paramsBefore an LLM callChange temperature, topP, topK, options
chat.headersBefore an LLM requestAdd/modify request headers
permission.askA permission is requestedSet status to allow/deny/ask
command.execute.beforeA slash command runsInject parts
tool.execute.beforeBefore a tool runsModify args, or throw to block
tool.execute.afterAfter a tool runsTransform title/output/metadata
tool.definitionTool sent to the LLMRewrite a tool’s description/parameters
shell.envA shell command runsAdd environment variables
experimental.chat.messages.transformBefore an LLM callRewrite the full message list
experimental.chat.system.transformBefore an LLM callRewrite the system prompt array
experimental.session.compactingBefore compactionAdd context or replace the compaction prompt
experimental.text.completeA text part completesRewrite the completed text

Signatures

Every hook is async and returns Promise<void>.

Tools

"tool.execute.before"?: (
input: { tool: string; sessionID: string; callID: string },
output: { args: any },
) => Promise<void>
"tool.execute.after"?: (
input: { tool: string; sessionID: string; callID: string; args: any },
output: { title: string; output: string; metadata: any },
) => Promise<void>
"tool.definition"?: (
input: { toolID: string },
output: { description: string; parameters: any },
) => Promise<void>

To block a tool, throw from tool.execute.before:

"tool.execute.before": async (input, output) => {
if (input.tool === "bash" && /rm\s+-rf/.test(output.args.command)) {
throw new Error("blocked: rm -rf")
}
}

Permissions

"permission.ask"?: (
input: Permission,
output: { status: "ask" | "deny" | "allow" },
) => Promise<void>
"permission.ask": async (input, output) => {
if (input.type === "read") output.status = "allow"
}

Chat

"chat.message"?: (
input: { sessionID: string; agent?: string; model?: { providerID: string; modelID: string }; messageID?: string; variant?: string },
output: { message: UserMessage; parts: Part[] },
) => Promise<void>
"chat.params"?: (
input: { sessionID: string; agent: string; model: Model; provider: ProviderContext; message: UserMessage },
output: { temperature: number; topP: number; topK: number; options: Record<string, any> },
) => Promise<void>
"chat.headers"?: (
input: { sessionID: string; agent: string; model: Model; provider: ProviderContext; message: UserMessage },
output: { headers: Record<string, string> },
) => Promise<void>

Commands & Shell

"command.execute.before"?: (
input: { command: string; sessionID: string; arguments: string },
output: { parts: Part[] },
) => Promise<void>
"shell.env"?: (
input: { cwd: string },
output: { env: Record<string, string> },
) => Promise<void>

Lifecycle

event?: (input: { event: Event }) => Promise<void>
config?: (input: Config) => Promise<void>

Experimental

"experimental.chat.messages.transform"?: (input: {}, output: { messages: { info: Message; parts: Part[] }[] }) => Promise<void>
"experimental.chat.system.transform"?: (input: { sessionID?: string; model: Model }, output: { system: string[] }) => Promise<void>
"experimental.session.compacting"?: (input: { sessionID: string }, output: { context: string[]; prompt?: string }) => Promise<void>
"experimental.text.complete"?: (input: { sessionID: string; messageID: string; partID: string }, output: { text: string }) => Promise<void>

Custom Tools & Auth

The tool and auth hooks register capabilities rather than react to events:

return {
tool: {
my_scanner: {
description: "Custom vulnerability scanner",
parameters: { type: "object", properties: { target: { type: "string" } }, required: ["target"] },
execute: async (args) => ({ title: `Scanned ${args.target}`, output: await scan(args.target) }),
},
},
}