main*
📝ai-hooks-universal-hook-engine.md
📅September 9, 20255 min read📁ai-hooks

Building ai-hooks: A Universal Hook Engine for AI Coding Tools

#ai-hooks#open-source#typescript#mcp#guardrails#premierstudio

Building ai-hooks: A Universal Hook Engine for AI Coding Tools

The Problem

Every team working with AI coding assistants hits the same wall:

  • No unified policy layer. Each tool — Claude Code, Cursor, Codex — has its own hook format. Your guardrails get duplicated, drift, and break silently.
  • No external control plane. If you need to programmatically steer the AI client a developer is using — set boundaries, collect signals, enforce workflow rules — there's no standard way to do it. You're locked into one vendor's API.
  • Fragmented audit trails. Shell commands, file writes, and tool calls are logged in different formats per tool, making compliance and debugging painful.
  • Inconsistent enforcement. Some tools can block dangerous actions before they happen; others can only observe after the fact.

I built ai-hooks to solve this. It's a universal hook engine that works across every major AI coding tool.

What ai-hooks Does

ai-hooks gives you a single policy engine that can steer any AI coding client with native hook support. Write rules once, and adapters translate them into the exact config format each tool understands.

Loading diagram...

Two ways to use it:

  1. Config-driven — Write an ai-hooks.config.ts, run ai-hooks generate, and adapters produce native hook configs for every detected tool.

  2. Library / control plane — Import the engine into your platform. Programmatically steer the AI client — set boundaries, collect signals, enforce workflow rules — all through a standard API.

Supported Tools

ToolBlockingObservationEvents
Claude CodeYesYes13
Codex CLIYesYes13
Gemini CLIYesYes13
CursorYesYes9
KiroYesYes14
OpenCodeYesYes13
Factory DroidYesYes9
ClineYesYes7
AmpYesYes2

Plus VS Code 1.109+ agent hooks (same format as Claude Code).

Built-in Safety Hooks

ai-ships with 4 hooks you can use immediately:

HookPhaseWhat it does
block-dangerous-commandsbeforeBlocks rm -rf /, DROP DATABASE, fork bombs
scan-secretsbeforeDetects API keys, tokens, private keys in file writes
protect-sensitive-filesbeforePrevents writes to .env, credentials.json, SSH keys
audit-shellafterRecords command, exit code, duration, tool name

Universal Event Model

15 event types across the full AI tool lifecycle:

CategoryBefore (blockable)After (observe-only)
Sessionsession:startsession:end
Promptprompt:submitprompt:response
Tooltool:beforetool:after
Filefile:write, file:edit, file:deletefile:read
Shellshell:beforeshell:after
MCPmcp:beforemcp:after
Systemnotification

Config Example

// ai-hooks.config.ts
import { defineConfig, hook, builtinHooks } from "@premierstudio/ai-hooks";
 
export default defineConfig({
  extends: [{ hooks: builtinHooks }],
  hooks: [
    hook("before", ["shell:before"], async (ctx, next) => {
      if (ctx.event.command.includes("npm publish")) {
        ctx.results.push({ blocked: true, reason: "Publishing is restricted" });
        return;
      }
      await next();
    })
      .id("org:block-publish")
      .name("Block npm publish")
      .priority(10)
      .build(),
  ],
  settings: {
    hookTimeout: 5000,
    failMode: "open",
    logLevel: "warn",
  },
});

Using as a Library

If you're building a platform that orchestrates AI agents — a PM tool, CI system, or custom control plane — import the engine directly:

import { HookEngine, builtinHooks } from "@premierstudio/ai-hooks";
 
const engine = new HookEngine({
  hooks: builtinHooks,
  settings: { failMode: "closed" },
});
 
// Check if an action should be blocked
const result = await engine.isBlocked(event, { name: "my-platform", version: "1.0" });
if (result.blocked) {
  console.log(`Blocked: ${result.reason}`);
}

Plannable Integration

ai-hooks powers the PM-AI hooks in Plannable. When you connect your AI coding tools to Plannable via @premierstudio/plannable, it automatically:

  1. Authenticates via OAuth
  2. Detects your AI tools (Claude Code, Cursor, Gemini CLI, etc.)
  3. Configures MCP server connections
  4. Installs intelligent guardrails via ai-hooks

This lets Plannable:

  • Guide your AI toward the right tasks and priorities
  • Enforce project conventions automatically
  • Signal file and shell activity back to Plannable for risk detection
  • Block unsafe operations before they happen

The Journey

Building ai-hooks went through several iterations:

  1. Monorepo consolidation — Started as 13 separate packages, consolidated to 2 (@premierstudio/ai-hooks and @premierstudio/plannable)
  2. Adapter registry issues — Solved module duplication problems with a globalThis singleton pattern
  3. Dynamic versioning — Switched from build-time to runtime version resolution for better publish workflows
  4. OIDC publisher — Set up trusted publisher for secure npm publishing

The project now has 100% test coverage and uses oxlint for strict TypeScript enforcement.

What's Next

  • Amp hooks support (planned)
  • More built-in safety hooks
  • Event replay and auditing
  • Integration with more platforms beyond Plannable

Links: