Hooks

Translate lifecycle hooks and scripts across harness event models.

Hooks run commands around tool calls, prompts, sessions, and agent stops. ap-sdk uses a portable event vocabulary and translates native event spellings where a harness supports hooks.

plugin.ts

import { defineHook, definePlugin } from "@jalco/ap-sdk";

export default definePlugin({
  id: "plan-review",
  description: "Review plans before execution.",
  hooks: [
    defineHook({
      event: "pre-tool-use",
      matcher: "ExitPlanMode",
      command: { unix: "node hooks/plan-review.mjs", powershell: "node hooks/plan-review.mjs" },
      timeout: 120,
      async: true,
      harness: { codex: { event: "stop", matcher: undefined } },
    }),
  ],
});

Portable events

ap-sdk eventClaudeCopilotGemini
pre-tool-usePreToolUsepreToolUseBeforeTool
post-tool-usePostToolUsepostToolUseAfterTool
stopStopstopStop
user-prompt-submitUserPromptSubmituserPromptSubmitUserPromptSubmit
session-startSessionStartsessionStartSessionStart
notificationNotificationnotificationNotification
permission-requestPermissionRequestpermissionRequestPermissionRequest
subagent-stopSubagentStopsubagentStopSubagentStop
pre-compactPreCompactpreCompactPreCompact
session-endSessionEndsessionEndSessionEnd

Fields

  • event, matcher, command, and timeout define the hook.
  • async is native in Claude and dropped with a warning elsewhere.
  • Object commands can provide unix and powershell; PowerShell is used by Copilot.
  • harness.<target>.event and matcher override native mapping. Use matcher: undefined to explicitly clear a matcher.

Next: MCP servers and the support matrix.