@premierstudio/ai-hooks 1.1.3 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/adapters/registry.ts","../../src/adapters/base.ts","../../src/adapters/amp.ts","../../src/adapters/claude-code.ts","../../src/adapters/cline.ts","../../src/adapters/codex.ts","../../src/adapters/cursor.ts","../../src/adapters/droid.ts","../../src/adapters/gemini-cli.ts","../../src/adapters/kiro.ts","../../src/adapters/opencode.ts"],"names":["adapter","resolve","existsSync","EVENT_MAP","REVERSE_MAP","readFile"],"mappings":"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","file":"all.js","sourcesContent":["import type { Adapter, AdapterFactory } from \"../types/index.js\";\n\n/**\n * Global adapter registry.\n * Adapters register themselves when imported, or can be manually added.\n */\nclass AdapterRegistry {\n private adapters: Map<string, Adapter> = new Map();\n private factories: Map<string, AdapterFactory> = new Map();\n\n /**\n * Register an adapter instance.\n */\n register(adapter: Adapter): void {\n this.adapters.set(adapter.id, adapter);\n }\n\n /**\n * Register an adapter factory for lazy instantiation.\n */\n registerFactory(id: string, factory: AdapterFactory): void {\n this.factories.set(id, factory);\n }\n\n /**\n * Get a registered adapter by ID.\n */\n get(id: string): Adapter | undefined {\n const existing = this.adapters.get(id);\n if (existing) return existing;\n\n // Try factory\n const factory = this.factories.get(id);\n if (factory) {\n const adapter = factory();\n this.adapters.set(id, adapter);\n return adapter;\n }\n\n return undefined;\n }\n\n /**\n * Get all registered adapter IDs.\n */\n list(): string[] {\n return [...new Set([...this.adapters.keys(), ...this.factories.keys()])];\n }\n\n /**\n * Detect which tools are available in the current environment.\n * Returns adapters that successfully detect their tool.\n */\n async detectAll(): Promise<Adapter[]> {\n const detected: Adapter[] = [];\n\n for (const id of this.list()) {\n const adapter = this.get(id);\n if (adapter) {\n try {\n const found = await adapter.detect();\n if (found) {\n detected.push(adapter);\n }\n } catch {\n // Detection failed, skip this adapter\n }\n }\n }\n\n return detected;\n }\n\n /**\n * Clear the registry. Useful for testing.\n */\n clear(): void {\n this.adapters.clear();\n this.factories.clear();\n }\n}\n\nexport const registry = new AdapterRegistry();\n","import { existsSync } from \"node:fs\";\nimport { readFile, writeFile, mkdir, rm } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\nimport type {\n Adapter,\n AdapterCapabilities,\n GeneratedConfig,\n HookDefinition,\n HookEventType,\n} from \"../types/index.js\";\n\n/**\n * Base adapter class with shared utilities.\n * Tool-specific adapters extend this and implement the abstract methods.\n */\nexport abstract class BaseAdapter implements Adapter {\n abstract readonly id: string;\n abstract readonly name: string;\n abstract readonly version: string;\n abstract readonly capabilities: AdapterCapabilities;\n\n abstract detect(): Promise<boolean>;\n abstract generate(hooks: HookDefinition[]): Promise<GeneratedConfig[]>;\n abstract mapEvent(event: HookEventType): string[];\n abstract mapNativeEvent(nativeEvent: string): HookEventType[];\n\n /**\n * Default install: write generated configs to disk.\n */\n async install(configs: GeneratedConfig[]): Promise<void> {\n for (const config of configs) {\n const fullPath = resolve(process.cwd(), config.path);\n await mkdir(dirname(fullPath), { recursive: true });\n await writeFile(fullPath, config.content, \"utf-8\");\n }\n }\n\n /**\n * Default uninstall: remove generated config files.\n */\n async uninstall(): Promise<void> {\n // Subclasses should override with specific file paths\n }\n\n // ── Utility Methods ───────────────────────────────────────\n\n protected async fileExists(path: string): Promise<boolean> {\n return existsSync(resolve(process.cwd(), path));\n }\n\n protected async readJsonFile<T>(path: string): Promise<T | null> {\n const fullPath = resolve(process.cwd(), path);\n if (!existsSync(fullPath)) return null;\n const content = await readFile(fullPath, \"utf-8\");\n return JSON.parse(content) as T;\n }\n\n protected async writeJsonFile(path: string, data: unknown): Promise<void> {\n const fullPath = resolve(process.cwd(), path);\n await mkdir(dirname(fullPath), { recursive: true });\n await writeFile(fullPath, JSON.stringify(data, null, 2) + \"\\n\", \"utf-8\");\n }\n\n protected async removeFile(path: string): Promise<void> {\n const fullPath = resolve(process.cwd(), path);\n if (existsSync(fullPath)) {\n await rm(fullPath);\n }\n }\n\n /**\n * Check if a CLI command exists on PATH.\n */\n protected async commandExists(command: string): Promise<boolean> {\n const { exec } = await import(\"node:child_process\");\n return new Promise((resolve) => {\n exec(`which ${command}`, (error) => {\n resolve(!error);\n });\n });\n }\n}\n","import { BaseAdapter, registry } from \"./index.js\";\nimport type {\n AdapterCapabilities,\n GeneratedConfig,\n HookDefinition,\n HookEventType,\n} from \"../types/index.js\";\nimport { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\n\n/**\n * Event mapping: ai-hooks universal events -> Amp native hooks.\n *\n * Amp (Sourcegraph) supports a limited hooks system via amp.hooks\n * settings, with events like \"tool:post-execute\". However, the hooks\n * API is not yet comprehensive, so this adapter primarily relies on\n * MCP for event delivery and uses the hooks system where available.\n *\n * Reference: https://ampcode.com/manual\n */\nconst EVENT_MAP: Record<string, string[]> = {\n \"session:start\": [],\n \"session:end\": [],\n \"prompt:submit\": [],\n \"prompt:response\": [],\n \"tool:before\": [\"tool:pre-execute\"],\n \"tool:after\": [\"tool:post-execute\"],\n \"file:write\": [\"tool:pre-execute\"],\n \"file:edit\": [\"tool:pre-execute\"],\n \"file:delete\": [\"tool:pre-execute\"],\n \"shell:before\": [\"tool:pre-execute\"],\n \"shell:after\": [\"tool:post-execute\"],\n \"mcp:before\": [\"tool:pre-execute\"],\n \"mcp:after\": [\"tool:post-execute\"],\n};\n\nconst REVERSE_MAP: Record<string, HookEventType[]> = {\n \"tool:pre-execute\": [\n \"tool:before\",\n \"file:write\",\n \"file:edit\",\n \"file:delete\",\n \"shell:before\",\n \"mcp:before\",\n ],\n \"tool:post-execute\": [\"tool:after\", \"shell:after\", \"mcp:after\"],\n};\n\n/**\n * Amp adapter for ai-hooks.\n *\n * Amp (Sourcegraph) has a growing hooks system and strong MCP support.\n * This adapter generates an MCP server configuration that the ai-hooks\n * MCP server provides, enabling tools management, event emission, and\n * hook control through MCP tool calls.\n *\n * The adapter also generates amp.hooks entries where the native system\n * supports tool pre/post-execute events.\n *\n * Reference: https://ampcode.com/manual\n */\nclass AmpAdapter extends BaseAdapter {\n readonly id = \"amp\";\n readonly name = \"Amp\";\n readonly version = \"1.0\";\n\n readonly capabilities: AdapterCapabilities = {\n beforeHooks: false,\n afterHooks: true,\n mcp: true,\n configFile: true,\n supportedEvents: [\n \"tool:before\",\n \"tool:after\",\n \"file:write\",\n \"file:edit\",\n \"file:delete\",\n \"shell:before\",\n \"shell:after\",\n \"mcp:before\",\n \"mcp:after\",\n ],\n blockableEvents: [],\n };\n\n async detect(): Promise<boolean> {\n const hasCommand = await this.commandExists(\"amp\");\n const hasDir = existsSync(resolve(process.cwd(), \".amp\"));\n return hasCommand || hasDir;\n }\n\n async generate(hooks: HookDefinition[]): Promise<GeneratedConfig[]> {\n const configs: GeneratedConfig[] = [];\n\n // Generate MCP server configuration for ai-hooks\n const mcpConfig = {\n mcpServers: {\n \"ai-hooks\": {\n command: \"npx\",\n args: [\"@premierstudio/mcp-server\"],\n env: {\n AI_HOOKS_CONFIG: resolve(process.cwd(), \"ai-hooks.config.ts\"),\n },\n },\n },\n };\n\n configs.push({\n path: \".amp/mcp.json\",\n content: JSON.stringify(mcpConfig, null, 2) + \"\\n\",\n format: \"json\",\n });\n\n // If any hooks need tool:pre/post-execute, note which events\n const neededEvents = new Set<string>();\n for (const hook of hooks) {\n for (const event of hook.events) {\n const nativeEvents = this.mapEvent(event);\n for (const ne of nativeEvents) {\n neededEvents.add(ne);\n }\n }\n }\n\n // Generate a summary of configured hooks for reference\n const hooksList = hooks.map((h) => ({\n id: h.id,\n name: h.name,\n events: h.events,\n phase: h.phase,\n nativeEvents: h.events.flatMap((e) => this.mapEvent(e)),\n }));\n\n configs.push({\n path: \".amp/ai-hooks-manifest.json\",\n content:\n JSON.stringify(\n {\n adapter: \"amp\",\n version: \"1.0\",\n hooks: hooksList,\n nativeEvents: [...neededEvents],\n mcpServer: \"@premierstudio/mcp-server\",\n },\n null,\n 2,\n ) + \"\\n\",\n format: \"json\",\n });\n\n return configs;\n }\n\n mapEvent(event: HookEventType): string[] {\n return EVENT_MAP[event] ?? [];\n }\n\n mapNativeEvent(nativeEvent: string): HookEventType[] {\n return REVERSE_MAP[nativeEvent] ?? [];\n }\n\n async uninstall(): Promise<void> {\n await this.removeFile(\".amp/mcp.json\");\n await this.removeFile(\".amp/ai-hooks-manifest.json\");\n }\n}\n\n// Auto-register\nconst adapter = new AmpAdapter();\nregistry.register(adapter);\n\nexport { AmpAdapter };\nexport default adapter;\n","import { BaseAdapter, registry } from \"./index.js\";\nimport type {\n AdapterCapabilities,\n GeneratedConfig,\n HookDefinition,\n HookEventType,\n} from \"../types/index.js\";\nimport { resolve } from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\n\n/**\n * Event mapping: ai-hooks universal events -> Claude Code native hooks.\n */\nconst EVENT_MAP: Record<string, string[]> = {\n \"session:start\": [\"SessionStart\"],\n \"session:end\": [],\n \"prompt:submit\": [\"UserPromptSubmit\"],\n \"prompt:response\": [\"PostToolUse\"], // approximate - Claude doesn't expose response directly\n \"tool:before\": [\"PreToolUse\"],\n \"tool:after\": [\"PostToolUse\"],\n \"file:read\": [\"PreToolUse\"], // Read tool\n \"file:write\": [\"PreToolUse\"], // Write tool\n \"file:edit\": [\"PreToolUse\"], // Edit tool\n \"file:delete\": [\"PreToolUse\"],\n \"shell:before\": [\"PreToolUse\"], // Bash tool\n \"shell:after\": [\"PostToolUse\"], // Bash tool\n \"mcp:before\": [\"PreToolUse\"],\n \"mcp:after\": [\"PostToolUse\"],\n notification: [\"Notification\"],\n};\n\nconst REVERSE_MAP: Record<string, HookEventType[]> = {\n SessionStart: [\"session:start\"],\n UserPromptSubmit: [\"prompt:submit\"],\n PreToolUse: [\n \"tool:before\",\n \"file:write\",\n \"file:edit\",\n \"file:delete\",\n \"shell:before\",\n \"mcp:before\",\n ],\n PostToolUse: [\"tool:after\", \"shell:after\", \"mcp:after\"],\n Notification: [\"notification\"],\n};\n\n/**\n * Claude Code adapter for ai-hooks.\n *\n * Generates `.claude/settings.json` hook entries and shell scripts\n * that delegate to the ai-hooks runtime.\n */\nclass ClaudeCodeAdapter extends BaseAdapter {\n readonly id = \"claude-code\";\n readonly name = \"Claude Code\";\n readonly version = \"1.0\";\n\n readonly capabilities: AdapterCapabilities = {\n beforeHooks: true,\n afterHooks: true,\n mcp: true,\n configFile: true,\n supportedEvents: [\n \"session:start\",\n \"prompt:submit\",\n \"tool:before\",\n \"tool:after\",\n \"file:read\",\n \"file:write\",\n \"file:edit\",\n \"file:delete\",\n \"shell:before\",\n \"shell:after\",\n \"mcp:before\",\n \"mcp:after\",\n \"notification\",\n ],\n blockableEvents: [\n \"prompt:submit\",\n \"tool:before\",\n \"file:write\",\n \"file:edit\",\n \"file:delete\",\n \"shell:before\",\n \"mcp:before\",\n ],\n };\n\n async detect(): Promise<boolean> {\n // Check for claude CLI command\n const hasCommand = await this.commandExists(\"claude\");\n\n // Also check for .claude directory (may not have CLI but has project config)\n const hasDir = existsSync(resolve(process.cwd(), \".claude\"));\n\n return hasCommand || hasDir;\n }\n\n async generate(hooks: HookDefinition[]): Promise<GeneratedConfig[]> {\n const configs: GeneratedConfig[] = [];\n\n // 1. Generate the hook runner script\n configs.push(this.generateRunner());\n\n // 2. Generate the settings.json entries\n configs.push(await this.generateSettings(hooks));\n\n return configs;\n }\n\n mapEvent(event: HookEventType): string[] {\n return EVENT_MAP[event] ?? [];\n }\n\n mapNativeEvent(nativeEvent: string): HookEventType[] {\n return REVERSE_MAP[nativeEvent] ?? [];\n }\n\n async uninstall(): Promise<void> {\n await this.removeFile(\".claude/hooks/ai-hooks-runner.js\");\n // Note: we don't remove settings.json as it may have other user config\n }\n\n // -- Private Methods ---------------------------------------------\n\n /**\n * Generate the hook runner script that Claude Code hooks call.\n * This script loads the ai-hooks config and runs the appropriate chain.\n */\n private generateRunner(): GeneratedConfig {\n const script = `#!/usr/bin/env node\n/**\n * ai-hooks runner for Claude Code.\n * Generated by: ai-hooks generate\n *\n * This script is called by Claude Code hooks. It loads your\n * ai-hooks.config.ts and runs the matching hook chain.\n *\n * DO NOT EDIT - regenerate with: ai-hooks generate\n */\n\nimport { loadConfig } from \"@premierstudio/ai-hooks\";\nimport { HookEngine } from \"@premierstudio/ai-hooks\";\n\nconst hookEvent = process.env.CLAUDE_HOOK_EVENT;\nconst toolName = process.env.CLAUDE_TOOL_NAME;\nconst inputJson = process.env.CLAUDE_TOOL_INPUT;\n\nasync function run() {\n const config = await loadConfig();\n const engine = new HookEngine(config);\n\n // Build the event from Claude Code's environment variables\n const event = buildEvent(hookEvent, toolName, inputJson);\n if (!event) {\n process.exit(0);\n }\n\n const toolInfo = { name: \"claude-code\", version: \"1.0\" };\n const results = await engine.emit(event, toolInfo);\n\n // Check for blocks\n const blocked = results.find((r) => r.blocked);\n if (blocked) {\n // Claude Code reads stdout JSON for hook results\n const output = JSON.stringify({\n decision: \"block\",\n reason: blocked.reason ?? \"Blocked by ai-hooks\",\n });\n process.stdout.write(output);\n process.exit(0);\n }\n\n process.exit(0);\n}\n\nfunction buildEvent(hookEvent, toolName, inputJson) {\n const timestamp = Date.now();\n const metadata = {};\n\n try {\n const input = inputJson ? JSON.parse(inputJson) : {};\n\n switch (hookEvent) {\n case \"PreToolUse\":\n return resolvePreToolUse(toolName, input, timestamp, metadata);\n case \"PostToolUse\":\n return resolvePostToolUse(toolName, input, timestamp, metadata);\n case \"SessionStart\":\n return {\n type: \"session:start\",\n tool: \"claude-code\",\n version: \"1.0\",\n workingDirectory: process.cwd(),\n timestamp,\n metadata,\n };\n case \"UserPromptSubmit\":\n return {\n type: \"prompt:submit\",\n prompt: input.prompt ?? \"\",\n timestamp,\n metadata,\n };\n default:\n return null;\n }\n } catch {\n return null;\n }\n}\n\nfunction resolvePreToolUse(toolName, input, timestamp, metadata) {\n switch (toolName) {\n case \"Write\":\n return {\n type: \"file:write\",\n path: input.file_path ?? \"\",\n content: input.content ?? \"\",\n timestamp,\n metadata,\n };\n case \"Edit\":\n return {\n type: \"file:edit\",\n path: input.file_path ?? \"\",\n oldContent: input.old_string ?? \"\",\n newContent: input.new_string ?? \"\",\n timestamp,\n metadata,\n };\n case \"Bash\":\n return {\n type: \"shell:before\",\n command: input.command ?? \"\",\n cwd: process.cwd(),\n timestamp,\n metadata,\n };\n default:\n return {\n type: \"tool:before\",\n toolName: toolName ?? \"unknown\",\n input: input ?? {},\n timestamp,\n metadata,\n };\n }\n}\n\nfunction resolvePostToolUse(toolName, input, timestamp, metadata) {\n switch (toolName) {\n case \"Bash\":\n return {\n type: \"shell:after\",\n command: input.command ?? \"\",\n cwd: process.cwd(),\n exitCode: input.exitCode ?? 0,\n stdout: input.stdout ?? \"\",\n stderr: input.stderr ?? \"\",\n duration: 0,\n timestamp,\n metadata,\n };\n default:\n return {\n type: \"tool:after\",\n toolName: toolName ?? \"unknown\",\n input: input ?? {},\n output: {},\n duration: 0,\n timestamp,\n metadata,\n };\n }\n}\n\nrun().catch((err) => {\n console.error(\"[ai-hooks] Error:\", err.message);\n process.exit(1);\n});\n`;\n\n return {\n path: \".claude/hooks/ai-hooks-runner.js\",\n content: script,\n format: \"js\",\n gitignore: false,\n };\n }\n\n /**\n * Generate the Claude Code settings.json hook entries.\n */\n private async generateSettings(hooks: HookDefinition[]): Promise<GeneratedConfig> {\n // Read existing settings\n const settingsPath = \".claude/settings.json\";\n let existing: Record<string, unknown> = {};\n\n const fullPath = resolve(process.cwd(), settingsPath);\n if (existsSync(fullPath)) {\n const raw = await readFile(fullPath, \"utf-8\");\n existing = JSON.parse(raw);\n }\n\n // Determine which Claude Code hook events we need\n const neededEvents = new Set<string>();\n for (const hook of hooks) {\n for (const event of hook.events) {\n const nativeEvents = this.mapEvent(event);\n for (const ne of nativeEvents) {\n neededEvents.add(ne);\n }\n }\n }\n\n // Build the hooks config\n // neededEvents is a Set, so each native event is processed exactly once.\n const hooksConfig: Record<string, unknown[]> = {};\n\n for (const event of neededEvents) {\n const hookEntry = {\n type: \"command\",\n command: `node .claude/hooks/ai-hooks-runner.js`,\n timeout: 10,\n description: `ai-hooks: ${event}`,\n };\n\n if (!hooksConfig[event]) {\n hooksConfig[event] = [];\n }\n (hooksConfig[event] as unknown[]).push({\n hooks: [hookEntry],\n });\n }\n\n // Merge with existing settings (preserve non-ai-hooks entries)\n const existingHooks = (existing.hooks ?? {}) as Record<string, unknown[]>;\n const mergedHooks: Record<string, unknown[]> = { ...existingHooks };\n\n for (const [event, entries] of Object.entries(hooksConfig)) {\n if (!mergedHooks[event]) {\n mergedHooks[event] = [];\n }\n // Remove old ai-hooks entries\n mergedHooks[event] = (\n mergedHooks[event] as Array<{ hooks?: Array<{ description?: string }> }>\n ).filter((entry) => !entry.hooks?.some((h) => h.description?.startsWith(\"ai-hooks:\")));\n // Add new ai-hooks entries\n mergedHooks[event].push(...entries);\n }\n\n const mergedSettings = {\n ...existing,\n hooks: mergedHooks,\n };\n\n return {\n path: settingsPath,\n content: JSON.stringify(mergedSettings, null, 2) + \"\\n\",\n format: \"json\",\n gitignore: false,\n };\n }\n}\n\n// Auto-register\nconst adapter = new ClaudeCodeAdapter();\nregistry.register(adapter);\n\nexport { ClaudeCodeAdapter };\nexport default adapter;\n","import { BaseAdapter, registry } from \"./index.js\";\nimport type {\n AdapterCapabilities,\n GeneratedConfig,\n HookDefinition,\n HookEventType,\n} from \"../types/index.js\";\nimport { resolve } from \"node:path\";\nimport { existsSync } from \"node:fs\";\n\n/**\n * Event mapping: ai-hooks universal events -> Cline native hooks.\n *\n * Cline supports seven hook events (since v3.36):\n * PreToolUse, PostToolUse, UserPromptSubmit,\n * TaskStart, TaskResume, TaskCancel, PreCompact\n *\n * Hook scripts are executables in .clinerules/hooks/ (project) or\n * ~/Documents/Cline/Rules/Hooks/ (global). They receive JSON via STDIN\n * and return JSON via STDOUT. The `cancel` field in output blocks\n * PreToolUse actions.\n *\n * Reference: https://docs.cline.bot/features/hooks\n */\nconst EVENT_MAP: Record<string, string[]> = {\n \"session:start\": [\"TaskStart\"],\n \"session:end\": [\"TaskCancel\"],\n \"prompt:submit\": [\"UserPromptSubmit\"],\n \"prompt:response\": [],\n \"tool:before\": [\"PreToolUse\"],\n \"tool:after\": [\"PostToolUse\"],\n \"file:read\": [\"PreToolUse\"],\n \"file:write\": [\"PreToolUse\"],\n \"file:edit\": [\"PreToolUse\"],\n \"file:delete\": [\"PreToolUse\"],\n \"shell:before\": [\"PreToolUse\"],\n \"shell:after\": [\"PostToolUse\"],\n \"mcp:before\": [\"PreToolUse\"],\n \"mcp:after\": [\"PostToolUse\"],\n notification: [],\n};\n\nconst REVERSE_MAP: Record<string, HookEventType[]> = {\n TaskStart: [\"session:start\"],\n TaskCancel: [\"session:end\"],\n TaskResume: [\"session:start\"],\n UserPromptSubmit: [\"prompt:submit\"],\n PreToolUse: [\n \"tool:before\",\n \"file:read\",\n \"file:write\",\n \"file:edit\",\n \"file:delete\",\n \"shell:before\",\n \"mcp:before\",\n ],\n PostToolUse: [\"tool:after\", \"shell:after\", \"mcp:after\"],\n PreCompact: [],\n};\n\n/**\n * Cline adapter for ai-hooks.\n *\n * Generates executable hook scripts in `.clinerules/hooks/` that delegate\n * to the ai-hooks runtime. Cline hooks receive JSON via STDIN containing\n * operation context (pendingToolInfo, etc.) and return JSON via STDOUT\n * with `cancel` boolean to block actions.\n *\n * Reference: https://docs.cline.bot/features/hooks\n */\nclass ClineAdapter extends BaseAdapter {\n readonly id = \"cline\";\n readonly name = \"Cline\";\n readonly version = \"1.0\";\n\n readonly capabilities: AdapterCapabilities = {\n beforeHooks: true,\n afterHooks: true,\n mcp: true,\n configFile: true,\n supportedEvents: [\n \"session:start\",\n \"session:end\",\n \"prompt:submit\",\n \"tool:before\",\n \"tool:after\",\n \"file:read\",\n \"file:write\",\n \"file:edit\",\n \"file:delete\",\n \"shell:before\",\n \"shell:after\",\n \"mcp:before\",\n \"mcp:after\",\n ],\n blockableEvents: [\n \"tool:before\",\n \"file:read\",\n \"file:write\",\n \"file:edit\",\n \"file:delete\",\n \"shell:before\",\n \"mcp:before\",\n ],\n };\n\n async detect(): Promise<boolean> {\n const hasCommand = await this.commandExists(\"cline\");\n const hasDir = existsSync(resolve(process.cwd(), \".clinerules\"));\n return hasCommand || hasDir;\n }\n\n async generate(hooks: HookDefinition[]): Promise<GeneratedConfig[]> {\n const configs: GeneratedConfig[] = [];\n\n // Collect needed native events\n const neededEvents = new Set<string>();\n for (const hook of hooks) {\n for (const event of hook.events) {\n const nativeEvents = this.mapEvent(event);\n for (const ne of nativeEvents) {\n neededEvents.add(ne);\n }\n }\n }\n\n // Generate one executable script per needed hook event\n for (const event of neededEvents) {\n configs.push({\n path: `.clinerules/hooks/${event}`,\n content: this.generateHookScript(event),\n format: \"js\",\n });\n }\n\n return configs;\n }\n\n mapEvent(event: HookEventType): string[] {\n return EVENT_MAP[event] ?? [];\n }\n\n mapNativeEvent(nativeEvent: string): HookEventType[] {\n return REVERSE_MAP[nativeEvent] ?? [];\n }\n\n async uninstall(): Promise<void> {\n const hookNames = [\n \"PreToolUse\",\n \"PostToolUse\",\n \"UserPromptSubmit\",\n \"TaskStart\",\n \"TaskResume\",\n \"TaskCancel\",\n \"PreCompact\",\n ];\n for (const name of hookNames) {\n await this.removeFile(`.clinerules/hooks/${name}`);\n }\n }\n\n private generateHookScript(eventName: string): string {\n return `#!/usr/bin/env node\n/**\n * ai-hooks runner for Cline (${eventName}).\n * Generated by: ai-hooks generate\n *\n * Cline passes hook event data as JSON via STDIN with:\n * hookName, taskId, workspaceRoots, pendingToolInfo, etc.\n *\n * Output JSON with { cancel: true, errorMessage: \"...\" } to block.\n * Output JSON with { cancel: false } to allow.\n *\n * DO NOT EDIT - regenerate with: ai-hooks generate\n */\nimport { loadConfig, HookEngine } from \"@premierstudio/ai-hooks\";\n\nasync function readStdin() {\n const chunks = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n }\n return Buffer.concat(chunks).toString(\"utf-8\");\n}\n\nasync function run() {\n const raw = await readStdin();\n const input = JSON.parse(raw || \"{}\");\n const hookName = input.hookName ?? \"${eventName}\";\n const pendingToolInfo = input.pendingToolInfo ?? {};\n const toolName = pendingToolInfo.toolName ?? \"\";\n\n const config = await loadConfig();\n const engine = new HookEngine(config);\n const toolInfo = { name: \"cline\", version: \"1.0\" };\n const timestamp = Date.now();\n const metadata = { taskId: input.taskId ?? \"\" };\n\n let event;\n switch (hookName) {\n case \"TaskStart\":\n case \"TaskResume\":\n event = {\n type: \"session:start\",\n tool: \"cline\",\n version: \"1.0\",\n workingDirectory: (input.workspaceRoots ?? [])[0] ?? process.cwd(),\n timestamp,\n metadata,\n };\n break;\n case \"TaskCancel\":\n event = { type: \"session:end\", tool: \"cline\", duration: 0, timestamp, metadata };\n break;\n case \"UserPromptSubmit\":\n event = { type: \"prompt:submit\", prompt: input.userMessage ?? \"\", timestamp, metadata };\n break;\n case \"PreToolUse\":\n event = resolvePreToolEvent(toolName, pendingToolInfo, timestamp, metadata);\n break;\n case \"PostToolUse\":\n event = resolvePostToolEvent(toolName, pendingToolInfo, timestamp, metadata);\n break;\n default:\n process.stdout.write(JSON.stringify({ cancel: false }));\n process.exit(0);\n }\n\n const results = await engine.emit(event, toolInfo);\n const blocked = results.find((r) => r.blocked);\n\n if (blocked) {\n process.stdout.write(JSON.stringify({\n cancel: true,\n errorMessage: blocked.reason ?? \"Blocked by ai-hooks\",\n }));\n process.exit(0);\n }\n\n process.stdout.write(JSON.stringify({ cancel: false }));\n}\n\nfunction resolvePreToolEvent(toolName, info, timestamp, metadata) {\n switch (toolName) {\n case \"write_to_file\":\n return { type: \"file:write\", path: info.path ?? \"\", content: info.content ?? \"\", timestamp, metadata };\n case \"replace_in_file\":\n return { type: \"file:edit\", path: info.path ?? \"\", oldContent: info.diff ?? \"\", newContent: \"\", timestamp, metadata };\n case \"read_file\":\n return { type: \"file:read\", path: info.path ?? \"\", timestamp, metadata };\n case \"execute_command\":\n return { type: \"shell:before\", command: info.command ?? \"\", cwd: process.cwd(), timestamp, metadata };\n case \"use_mcp_tool\":\n return { type: \"mcp:before\", server: info.mcpServer ?? \"\", tool: info.mcpTool ?? \"\", input: {}, timestamp, metadata };\n default:\n return { type: \"tool:before\", toolName: toolName || \"unknown\", input: info, timestamp, metadata };\n }\n}\n\nfunction resolvePostToolEvent(toolName, info, timestamp, metadata) {\n switch (toolName) {\n case \"execute_command\":\n return {\n type: \"shell:after\",\n command: info.command ?? \"\",\n cwd: process.cwd(),\n exitCode: 0,\n stdout: \"\",\n stderr: \"\",\n duration: 0,\n timestamp,\n metadata,\n };\n default:\n return { type: \"tool:after\", toolName: toolName || \"unknown\", input: info, output: {}, duration: 0, timestamp, metadata };\n }\n}\n\nrun().catch((err) => {\n console.error(\"[ai-hooks] Error:\", err.message);\n process.stdout.write(JSON.stringify({ cancel: false }));\n process.exit(0);\n});\n`;\n }\n}\n\n// Auto-register\nconst adapter = new ClineAdapter();\nregistry.register(adapter);\n\nexport { ClineAdapter };\nexport default adapter;\n","import { BaseAdapter, registry } from \"./index.js\";\nimport type {\n AdapterCapabilities,\n GeneratedConfig,\n HookDefinition,\n HookEventType,\n} from \"../types/index.js\";\nimport { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\n\n/**\n * Event mapping: ai-hooks -> Codex CLI native hooks.\n *\n * Codex uses an `agents.yaml` config with lifecycle events.\n * Reference: https://github.com/openai/codex\n */\nconst EVENT_MAP: Record<string, string[]> = {\n \"session:start\": [\"session_start\"],\n \"session:end\": [\"session_end\"],\n \"prompt:submit\": [\"user_message\"],\n \"prompt:response\": [\"assistant_message\"],\n \"tool:before\": [\"before_tool_call\"],\n \"tool:after\": [\"after_tool_call\"],\n \"file:write\": [\"before_file_write\"],\n \"file:edit\": [\"before_file_edit\"],\n \"file:delete\": [\"before_file_delete\"],\n \"shell:before\": [\"before_shell\"],\n \"shell:after\": [\"after_shell\"],\n \"mcp:before\": [\"before_mcp_call\"],\n \"mcp:after\": [\"after_mcp_call\"],\n};\n\nconst REVERSE_MAP: Record<string, HookEventType[]> = {\n session_start: [\"session:start\"],\n session_end: [\"session:end\"],\n user_message: [\"prompt:submit\"],\n assistant_message: [\"prompt:response\"],\n before_tool_call: [\"tool:before\"],\n after_tool_call: [\"tool:after\"],\n before_file_write: [\"file:write\"],\n before_file_edit: [\"file:edit\"],\n before_file_delete: [\"file:delete\"],\n before_shell: [\"shell:before\"],\n after_shell: [\"shell:after\"],\n before_mcp_call: [\"mcp:before\"],\n after_mcp_call: [\"mcp:after\"],\n};\n\nclass CodexAdapter extends BaseAdapter {\n readonly id = \"codex\";\n readonly name = \"Codex CLI\";\n readonly version = \"1.0\";\n\n readonly capabilities: AdapterCapabilities = {\n beforeHooks: true,\n afterHooks: true,\n mcp: true,\n configFile: true,\n supportedEvents: [\n \"session:start\",\n \"session:end\",\n \"prompt:submit\",\n \"prompt:response\",\n \"tool:before\",\n \"tool:after\",\n \"file:write\",\n \"file:edit\",\n \"file:delete\",\n \"shell:before\",\n \"shell:after\",\n \"mcp:before\",\n \"mcp:after\",\n ],\n blockableEvents: [\n \"tool:before\",\n \"file:write\",\n \"file:edit\",\n \"file:delete\",\n \"shell:before\",\n \"mcp:before\",\n ],\n };\n\n async detect(): Promise<boolean> {\n const hasCommand = await this.commandExists(\"codex\");\n const hasConfig =\n existsSync(resolve(process.cwd(), \"codex.json\")) ||\n existsSync(resolve(process.cwd(), \".codex\"));\n return hasCommand || hasConfig;\n }\n\n async generate(hooks: HookDefinition[]): Promise<GeneratedConfig[]> {\n // Codex uses a codex.json config file with hooks array\n const hookEntries: Record<string, unknown> = {};\n\n for (const hook of hooks) {\n for (const event of hook.events) {\n const nativeEvents = this.mapEvent(event);\n for (const ne of nativeEvents) {\n hookEntries[ne] = {\n command: \"node .codex/hooks/ai-hooks-runner.js\",\n timeout: 10,\n };\n }\n }\n }\n\n return [\n {\n path: \".codex/hooks/ai-hooks-runner.js\",\n content: this.generateRunner(),\n format: \"js\",\n },\n {\n path: \"codex.json\",\n content: JSON.stringify({ hooks: hookEntries }, null, 2) + \"\\n\",\n format: \"json\",\n },\n ];\n }\n\n mapEvent(event: HookEventType): string[] {\n return EVENT_MAP[event] ?? [];\n }\n\n mapNativeEvent(nativeEvent: string): HookEventType[] {\n return REVERSE_MAP[nativeEvent] ?? [];\n }\n\n async uninstall(): Promise<void> {\n await this.removeFile(\".codex/hooks/ai-hooks-runner.js\");\n }\n\n private generateRunner(): string {\n return `#!/usr/bin/env node\n/**\n * ai-hooks runner for Codex CLI.\n * Generated by: ai-hooks generate\n */\nimport { loadConfig, HookEngine } from \"@premierstudio/ai-hooks\";\n\nconst hookEvent = process.env.CODEX_HOOK_EVENT;\nconst toolInput = process.env.CODEX_TOOL_INPUT;\n\nasync function run() {\n const config = await loadConfig();\n const engine = new HookEngine(config);\n const toolInfo = { name: \"codex\", version: \"1.0\" };\n\n const input = toolInput ? JSON.parse(toolInput) : {};\n const timestamp = Date.now();\n const metadata = {};\n\n let event;\n switch (hookEvent) {\n case \"before_shell\":\n event = { type: \"shell:before\", command: input.command ?? \"\", cwd: process.cwd(), timestamp, metadata };\n break;\n case \"before_file_write\":\n event = { type: \"file:write\", path: input.path ?? \"\", content: input.content ?? \"\", timestamp, metadata };\n break;\n case \"before_file_edit\":\n event = { type: \"file:edit\", path: input.path ?? \"\", oldContent: input.old ?? \"\", newContent: input.new ?? \"\", timestamp, metadata };\n break;\n default:\n event = { type: \"tool:before\", toolName: hookEvent ?? \"unknown\", input, timestamp, metadata };\n }\n\n const results = await engine.emit(event, toolInfo);\n const blocked = results.find((r) => r.blocked);\n\n if (blocked) {\n console.log(JSON.stringify({ blocked: true, reason: blocked.reason }));\n process.exit(1);\n }\n}\n\nrun().catch(() => process.exit(1));\n`;\n }\n}\n\nconst adapter = new CodexAdapter();\nregistry.register(adapter);\n\nexport { CodexAdapter };\nexport default adapter;\n","import { BaseAdapter, registry } from \"./index.js\";\nimport type {\n AdapterCapabilities,\n GeneratedConfig,\n HookDefinition,\n HookEventType,\n} from \"../types/index.js\";\nimport { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\n\n/**\n * Event mapping: ai-hooks universal events -> Cursor native hooks.\n *\n * Cursor supports six lifecycle hooks (via .cursor/hooks.json):\n * beforeSubmitPrompt, beforeShellExecution, beforeMCPExecution,\n * beforeReadFile, afterFileEdit, stop\n *\n * Reference: https://docs.cursor.com/configuration/hooks\n */\nconst EVENT_MAP: Record<string, string[]> = {\n \"session:start\": [],\n \"session:end\": [\"stop\"],\n \"prompt:submit\": [\"beforeSubmitPrompt\"],\n \"prompt:response\": [\"stop\"],\n \"tool:before\": [\"beforeMCPExecution\"],\n \"tool:after\": [],\n \"file:read\": [\"beforeReadFile\"],\n \"file:write\": [\"afterFileEdit\"],\n \"file:edit\": [\"afterFileEdit\"],\n \"file:delete\": [],\n \"shell:before\": [\"beforeShellExecution\"],\n \"shell:after\": [],\n \"mcp:before\": [\"beforeMCPExecution\"],\n \"mcp:after\": [],\n};\n\nconst REVERSE_MAP: Record<string, HookEventType[]> = {\n beforeSubmitPrompt: [\"prompt:submit\"],\n beforeShellExecution: [\"shell:before\"],\n beforeMCPExecution: [\"tool:before\", \"mcp:before\"],\n beforeReadFile: [\"file:read\"],\n afterFileEdit: [\"file:write\", \"file:edit\"],\n stop: [\"session:end\", \"prompt:response\"],\n};\n\n/**\n * Cursor adapter for ai-hooks.\n *\n * Generates `.cursor/hooks.json` with hook entries and a runner script.\n * Cursor hooks use a `{ \"version\": 1, \"hooks\": { ... } }` format.\n *\n * For blocking hooks (beforeShellExecution, beforeMCPExecution), the\n * runner outputs JSON with `{ \"permission\": \"deny\" }` to block execution.\n *\n * Reference: https://docs.cursor.com/configuration/hooks\n */\nclass CursorAdapter extends BaseAdapter {\n readonly id = \"cursor\";\n readonly name = \"Cursor\";\n readonly version = \"1.0\";\n\n readonly capabilities: AdapterCapabilities = {\n beforeHooks: true,\n afterHooks: true,\n mcp: true,\n configFile: true,\n supportedEvents: [\n \"session:end\",\n \"prompt:submit\",\n \"prompt:response\",\n \"tool:before\",\n \"file:read\",\n \"file:write\",\n \"file:edit\",\n \"shell:before\",\n \"mcp:before\",\n ],\n blockableEvents: [\"shell:before\", \"mcp:before\", \"tool:before\"],\n };\n\n async detect(): Promise<boolean> {\n const hasCommand = await this.commandExists(\"cursor\");\n const hasDir = existsSync(resolve(process.cwd(), \".cursor\"));\n return hasCommand || hasDir;\n }\n\n async generate(hooks: HookDefinition[]): Promise<GeneratedConfig[]> {\n const configs: GeneratedConfig[] = [];\n\n // Collect needed native events\n const neededEvents = new Set<string>();\n for (const hook of hooks) {\n for (const event of hook.events) {\n const nativeEvents = this.mapEvent(event);\n for (const ne of nativeEvents) {\n neededEvents.add(ne);\n }\n }\n }\n\n // Generate the runner script\n configs.push({\n path: \".cursor/hooks/ai-hooks-runner.js\",\n content: this.generateRunner(),\n format: \"js\",\n });\n\n // Build Cursor hooks.json\n const hooksConfig: Record<string, unknown[]> = {};\n\n for (const event of neededEvents) {\n if (!hooksConfig[event]) {\n hooksConfig[event] = [];\n }\n hooksConfig[event].push({\n command: `node hooks/ai-hooks-runner.js ${event}`,\n });\n }\n\n configs.push({\n path: \".cursor/hooks.json\",\n content: JSON.stringify({ version: 1, hooks: hooksConfig }, null, 2) + \"\\n\",\n format: \"json\",\n });\n\n return configs;\n }\n\n mapEvent(event: HookEventType): string[] {\n return EVENT_MAP[event] ?? [];\n }\n\n mapNativeEvent(nativeEvent: string): HookEventType[] {\n return REVERSE_MAP[nativeEvent] ?? [];\n }\n\n async uninstall(): Promise<void> {\n await this.removeFile(\".cursor/hooks/ai-hooks-runner.js\");\n await this.removeFile(\".cursor/hooks.json\");\n }\n\n private generateRunner(): string {\n return `#!/usr/bin/env node\n/**\n * ai-hooks runner for Cursor.\n * Generated by: ai-hooks generate\n *\n * Cursor passes the hook event name as a CLI argument.\n * Blocking hooks (beforeShellExecution, beforeMCPExecution)\n * return JSON: { \"permission\": \"deny\", \"agentMessage\": \"reason\" }\n *\n * DO NOT EDIT - regenerate with: ai-hooks generate\n */\nimport { loadConfig, HookEngine } from \"@premierstudio/ai-hooks\";\n\nasync function readStdin() {\n const chunks = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n }\n return Buffer.concat(chunks).toString(\"utf-8\");\n}\n\nasync function run() {\n const hookEventName = process.argv[2] ?? \"\";\n let input = {};\n try {\n const raw = await readStdin();\n input = JSON.parse(raw || \"{}\");\n } catch {\n input = {};\n }\n\n const config = await loadConfig();\n const engine = new HookEngine(config);\n const toolInfo = { name: \"cursor\", version: \"1.0\" };\n const timestamp = Date.now();\n const metadata = {};\n\n let event;\n switch (hookEventName) {\n case \"beforeSubmitPrompt\":\n event = { type: \"prompt:submit\", prompt: input.prompt ?? \"\", timestamp, metadata };\n break;\n case \"beforeShellExecution\":\n event = { type: \"shell:before\", command: input.command ?? \"\", cwd: process.cwd(), timestamp, metadata };\n break;\n case \"beforeMCPExecution\":\n event = { type: \"mcp:before\", server: input.server ?? \"\", method: input.method ?? \"\", params: input.params ?? {}, timestamp, metadata };\n break;\n case \"beforeReadFile\":\n event = { type: \"file:read\", path: input.path ?? \"\", timestamp, metadata };\n break;\n case \"afterFileEdit\":\n event = { type: \"file:edit\", path: input.path ?? \"\", oldContent: \"\", newContent: \"\", timestamp, metadata };\n break;\n case \"stop\":\n event = { type: \"session:end\", tool: \"cursor\", duration: 0, timestamp, metadata };\n break;\n default:\n process.exit(0);\n }\n\n const results = await engine.emit(event, toolInfo);\n const blocked = results.find((r) => r.blocked);\n\n if (blocked) {\n const response = JSON.stringify({\n permission: \"deny\",\n agentMessage: blocked.reason ?? \"Blocked by ai-hooks\",\n userMessage: blocked.reason ?? \"Blocked by ai-hooks\",\n });\n process.stdout.write(response);\n process.exit(0);\n }\n\n if (hookEventName === \"beforeShellExecution\" || hookEventName === \"beforeMCPExecution\") {\n process.stdout.write(JSON.stringify({ permission: \"allow\" }));\n }\n}\n\nrun().catch((err) => {\n console.error(\"[ai-hooks] Error:\", err.message);\n process.exit(1);\n});\n`;\n }\n}\n\n// Auto-register\nconst adapter = new CursorAdapter();\nregistry.register(adapter);\n\nexport { CursorAdapter };\nexport default adapter;\n","import { BaseAdapter, registry } from \"./index.js\";\nimport type {\n AdapterCapabilities,\n GeneratedConfig,\n HookDefinition,\n HookEventType,\n} from \"../types/index.js\";\nimport { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { readFile } from \"node:fs/promises\";\n\n/**\n * Event mapping: ai-hooks universal events -> Factory Droid native hooks.\n *\n * Droid supports nine hook events:\n * PreToolUse, PostToolUse, UserPromptSubmit, Notification,\n * Stop, SubagentStop, PreCompact, SessionStart, SessionEnd\n *\n * Hook input is JSON via STDIN with tool_name, tool_input, etc.\n * Exit code 2 blocks on PreToolUse; STDERR is sent to Droid.\n *\n * Reference: https://docs.factory.ai/reference/hooks-reference\n */\nconst EVENT_MAP: Record<string, string[]> = {\n \"session:start\": [\"SessionStart\"],\n \"session:end\": [\"SessionEnd\"],\n \"prompt:submit\": [\"UserPromptSubmit\"],\n \"prompt:response\": [\"Stop\"],\n \"tool:before\": [\"PreToolUse\"],\n \"tool:after\": [\"PostToolUse\"],\n \"file:read\": [\"PreToolUse\"],\n \"file:write\": [\"PreToolUse\"],\n \"file:edit\": [\"PreToolUse\"],\n \"file:delete\": [\"PreToolUse\"],\n \"shell:before\": [\"PreToolUse\"],\n \"shell:after\": [\"PostToolUse\"],\n \"mcp:before\": [\"PreToolUse\"],\n \"mcp:after\": [\"PostToolUse\"],\n notification: [\"Notification\"],\n};\n\nconst REVERSE_MAP: Record<string, HookEventType[]> = {\n SessionStart: [\"session:start\"],\n SessionEnd: [\"session:end\"],\n UserPromptSubmit: [\"prompt:submit\"],\n Stop: [\"prompt:response\"],\n PreToolUse: [\n \"tool:before\",\n \"file:read\",\n \"file:write\",\n \"file:edit\",\n \"file:delete\",\n \"shell:before\",\n \"mcp:before\",\n ],\n PostToolUse: [\"tool:after\", \"shell:after\", \"mcp:after\"],\n Notification: [\"notification\"],\n};\n\n/**\n * Factory Droid adapter for ai-hooks.\n *\n * Generates `.factory/settings.json` hook entries and a runner script.\n * Droid uses a settings.json format very similar to Claude Code, with\n * hooks keyed by event name containing matcher patterns and commands.\n *\n * Hook scripts receive JSON via STDIN with session_id, cwd, tool_name,\n * tool_input, and hook_event_name. Exit code 2 blocks PreToolUse hooks\n * and STDERR is processed by Droid as feedback.\n *\n * Reference: https://docs.factory.ai/cli/configuration/hooks-guide\n */\nclass DroidAdapter extends BaseAdapter {\n readonly id = \"droid\";\n readonly name = \"Factory Droid\";\n readonly version = \"1.0\";\n\n readonly capabilities: AdapterCapabilities = {\n beforeHooks: true,\n afterHooks: true,\n mcp: true,\n configFile: true,\n supportedEvents: [\n \"session:start\",\n \"session:end\",\n \"prompt:submit\",\n \"prompt:response\",\n \"tool:before\",\n \"tool:after\",\n \"file:read\",\n \"file:write\",\n \"file:edit\",\n \"file:delete\",\n \"shell:before\",\n \"shell:after\",\n \"mcp:before\",\n \"mcp:after\",\n \"notification\",\n ],\n blockableEvents: [\n \"tool:before\",\n \"file:read\",\n \"file:write\",\n \"file:edit\",\n \"file:delete\",\n \"shell:before\",\n \"mcp:before\",\n ],\n };\n\n async detect(): Promise<boolean> {\n const hasCommand = await this.commandExists(\"droid\");\n const hasDir = existsSync(resolve(process.cwd(), \".factory\"));\n return hasCommand || hasDir;\n }\n\n async generate(hooks: HookDefinition[]): Promise<GeneratedConfig[]> {\n const configs: GeneratedConfig[] = [];\n\n // Collect needed native events\n const neededEvents = new Set<string>();\n for (const hook of hooks) {\n for (const event of hook.events) {\n const nativeEvents = this.mapEvent(event);\n for (const ne of nativeEvents) {\n neededEvents.add(ne);\n }\n }\n }\n\n // Generate the runner script\n configs.push({\n path: \".factory/hooks/ai-hooks-runner.js\",\n content: this.generateRunner(),\n format: \"js\",\n });\n\n // Build Droid settings hooks config\n const hooksConfig: Record<string, unknown[]> = {};\n const runnerAbsPath = resolve(process.cwd(), \".factory/hooks/ai-hooks-runner.js\");\n\n for (const event of neededEvents) {\n const hookEntry: Record<string, unknown> = {\n hooks: [\n {\n type: \"command\",\n command: `node ${runnerAbsPath}`,\n timeout: 30,\n },\n ],\n };\n\n // Tool-related events support matchers\n if (event === \"PreToolUse\" || event === \"PostToolUse\") {\n hookEntry.matcher = \"*\";\n }\n\n if (!hooksConfig[event]) {\n hooksConfig[event] = [];\n }\n hooksConfig[event].push(hookEntry);\n }\n\n // Merge with existing settings if present\n const settingsConfig = await this.mergeSettings(hooksConfig);\n\n configs.push({\n path: \".factory/settings.json\",\n content: JSON.stringify(settingsConfig, null, 2) + \"\\n\",\n format: \"json\",\n });\n\n return configs;\n }\n\n mapEvent(event: HookEventType): string[] {\n return EVENT_MAP[event] ?? [];\n }\n\n mapNativeEvent(nativeEvent: string): HookEventType[] {\n return REVERSE_MAP[nativeEvent] ?? [];\n }\n\n async uninstall(): Promise<void> {\n await this.removeFile(\".factory/hooks/ai-hooks-runner.js\");\n }\n\n private async mergeSettings(\n hooksConfig: Record<string, unknown[]>,\n ): Promise<Record<string, unknown>> {\n const settingsPath = resolve(process.cwd(), \".factory/settings.json\");\n let existing: Record<string, unknown> = {};\n\n if (existsSync(settingsPath)) {\n const raw = await readFile(settingsPath, \"utf-8\");\n existing = JSON.parse(raw);\n }\n\n // Merge hooks: preserve non-ai-hooks entries\n const existingHooks = (existing.hooks ?? {}) as Record<string, unknown[]>;\n const mergedHooks: Record<string, unknown[]> = { ...existingHooks };\n\n for (const [event, entries] of Object.entries(hooksConfig)) {\n if (!mergedHooks[event]) {\n mergedHooks[event] = [];\n }\n // Remove old ai-hooks entries (identified by runner path)\n mergedHooks[event] = (\n mergedHooks[event] as Array<{\n hooks?: Array<{ command?: string }>;\n }>\n ).filter((entry) => !entry.hooks?.some((h) => h.command?.includes(\"ai-hooks-runner\")));\n mergedHooks[event].push(...entries);\n }\n\n return {\n ...existing,\n hooks: mergedHooks,\n };\n }\n\n private generateRunner(): string {\n return `#!/usr/bin/env node\n/**\n * ai-hooks runner for Factory Droid.\n * Generated by: ai-hooks generate\n *\n * Droid passes hook event data as JSON via STDIN with:\n * hook_event_name, session_id, cwd, tool_name, tool_input, tool_response\n *\n * Exit code 0 = success, exit code 2 = block (PreToolUse).\n * STDERR on exit code 2 is fed back to Droid as context.\n *\n * DO NOT EDIT - regenerate with: ai-hooks generate\n */\nimport { loadConfig, HookEngine } from \"@premierstudio/ai-hooks\";\n\nasync function readStdin() {\n const chunks = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n }\n return Buffer.concat(chunks).toString(\"utf-8\");\n}\n\nasync function run() {\n const raw = await readStdin();\n const input = JSON.parse(raw || \"{}\");\n const hookEventName = input.hook_event_name ?? \"\";\n const toolName = input.tool_name ?? \"\";\n const toolInput = input.tool_input ?? {};\n const toolResponse = input.tool_response ?? {};\n\n const config = await loadConfig();\n const engine = new HookEngine(config);\n const toolInfo = { name: \"droid\", version: \"1.0\" };\n const timestamp = Date.now();\n const metadata = { sessionId: input.session_id ?? \"\" };\n\n let event;\n switch (hookEventName) {\n case \"SessionStart\":\n event = {\n type: \"session:start\",\n tool: \"droid\",\n version: \"1.0\",\n workingDirectory: input.cwd ?? process.cwd(),\n timestamp,\n metadata,\n };\n break;\n case \"SessionEnd\":\n event = { type: \"session:end\", tool: \"droid\", duration: 0, timestamp, metadata };\n break;\n case \"UserPromptSubmit\":\n event = { type: \"prompt:submit\", prompt: toolInput.prompt ?? \"\", timestamp, metadata };\n break;\n case \"Notification\":\n event = { type: \"notification\", level: \"info\", message: toolInput.message ?? \"\", timestamp, metadata };\n break;\n case \"Stop\":\n event = { type: \"session:end\", tool: \"droid\", duration: 0, timestamp, metadata };\n break;\n case \"PreToolUse\":\n event = resolvePreToolEvent(toolName, toolInput, timestamp, metadata);\n break;\n case \"PostToolUse\":\n event = resolvePostToolEvent(toolName, toolInput, toolResponse, timestamp, metadata);\n break;\n default:\n process.exit(0);\n }\n\n const results = await engine.emit(event, toolInfo);\n const blocked = results.find((r) => r.blocked);\n\n if (blocked) {\n process.stderr.write(blocked.reason ?? \"Blocked by ai-hooks\");\n process.exit(2);\n }\n}\n\nfunction resolvePreToolEvent(toolName, toolInput, timestamp, metadata) {\n switch (toolName) {\n case \"Write\":\n return { type: \"file:write\", path: toolInput.file_path ?? \"\", content: toolInput.content ?? \"\", timestamp, metadata };\n case \"Edit\":\n return { type: \"file:edit\", path: toolInput.file_path ?? \"\", oldContent: toolInput.old_string ?? \"\", newContent: toolInput.new_string ?? \"\", timestamp, metadata };\n case \"Read\":\n return { type: \"file:read\", path: toolInput.file_path ?? \"\", timestamp, metadata };\n case \"Bash\":\n return { type: \"shell:before\", command: toolInput.command ?? \"\", cwd: process.cwd(), timestamp, metadata };\n default:\n return { type: \"tool:before\", toolName: toolName || \"unknown\", input: toolInput, timestamp, metadata };\n }\n}\n\nfunction resolvePostToolEvent(toolName, toolInput, toolResponse, timestamp, metadata) {\n switch (toolName) {\n case \"Bash\":\n return {\n type: \"shell:after\",\n command: toolInput.command ?? \"\",\n cwd: process.cwd(),\n exitCode: toolResponse.exitCode ?? 0,\n stdout: toolResponse.stdout ?? \"\",\n stderr: toolResponse.stderr ?? \"\",\n duration: 0,\n timestamp,\n metadata,\n };\n default:\n return { type: \"tool:after\", toolName: toolName || \"unknown\", input: toolInput, output: toolResponse, duration: 0, timestamp, metadata };\n }\n}\n\nrun().catch((err) => {\n console.error(\"[ai-hooks] Error:\", err.message);\n process.exit(1);\n});\n`;\n }\n}\n\n// Auto-register\nconst adapter = new DroidAdapter();\nregistry.register(adapter);\n\nexport { DroidAdapter };\nexport default adapter;\n","import { BaseAdapter, registry } from \"./index.js\";\nimport type {\n AdapterCapabilities,\n GeneratedConfig,\n HookDefinition,\n HookEventType,\n} from \"../types/index.js\";\nimport { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\n\n/**\n * Event mapping: ai-hooks -> Gemini CLI native hooks.\n *\n * Gemini CLI uses GEMINI_HOOKS_DIR with event-named scripts.\n * Reference: https://github.com/google/gemini-cli\n */\nconst EVENT_MAP: Record<string, string[]> = {\n \"session:start\": [\"SessionStart\"],\n \"session:end\": [\"SessionEnd\"],\n \"prompt:submit\": [\"BeforePrompt\"],\n \"prompt:response\": [\"AfterResponse\"],\n \"tool:before\": [\"BeforeTool\"],\n \"tool:after\": [\"AfterTool\"],\n \"file:write\": [\"BeforeTool\"], // FileWrite tool\n \"file:edit\": [\"BeforeTool\"], // FileEdit tool\n \"file:delete\": [\"BeforeTool\"], // FileDelete tool\n \"shell:before\": [\"BeforeShell\"],\n \"shell:after\": [\"AfterShell\"],\n \"mcp:before\": [\"BeforeTool\"],\n \"mcp:after\": [\"AfterTool\"],\n};\n\nconst REVERSE_MAP: Record<string, HookEventType[]> = {\n SessionStart: [\"session:start\"],\n SessionEnd: [\"session:end\"],\n BeforePrompt: [\"prompt:submit\"],\n AfterResponse: [\"prompt:response\"],\n BeforeTool: [\"tool:before\", \"file:write\", \"file:edit\", \"file:delete\", \"mcp:before\"],\n AfterTool: [\"tool:after\", \"mcp:after\"],\n BeforeShell: [\"shell:before\"],\n AfterShell: [\"shell:after\"],\n};\n\nclass GeminiCliAdapter extends BaseAdapter {\n readonly id = \"gemini-cli\";\n readonly name = \"Gemini CLI\";\n readonly version = \"1.0\";\n\n readonly capabilities: AdapterCapabilities = {\n beforeHooks: true,\n afterHooks: true,\n mcp: true,\n configFile: true,\n supportedEvents: [\n \"session:start\",\n \"session:end\",\n \"prompt:submit\",\n \"prompt:response\",\n \"tool:before\",\n \"tool:after\",\n \"file:write\",\n \"file:edit\",\n \"file:delete\",\n \"shell:before\",\n \"shell:after\",\n \"mcp:before\",\n \"mcp:after\",\n ],\n blockableEvents: [\n \"prompt:submit\",\n \"tool:before\",\n \"file:write\",\n \"file:edit\",\n \"file:delete\",\n \"shell:before\",\n \"mcp:before\",\n ],\n };\n\n async detect(): Promise<boolean> {\n const hasCommand = await this.commandExists(\"gemini\");\n const hasConfig = existsSync(resolve(process.cwd(), \".gemini\"));\n return hasCommand || hasConfig;\n }\n\n async generate(hooks: HookDefinition[]): Promise<GeneratedConfig[]> {\n const configs: GeneratedConfig[] = [];\n\n // Gemini CLI uses a hooks directory with scripts named by event\n const neededEvents = new Set<string>();\n for (const hook of hooks) {\n for (const event of hook.events) {\n const nativeEvents = this.mapEvent(event);\n for (const ne of nativeEvents) {\n neededEvents.add(ne);\n }\n }\n }\n\n // Generate a hook script for each needed event\n for (const event of neededEvents) {\n configs.push({\n path: `.gemini/hooks/${event}.js`,\n content: this.generateEventScript(event),\n format: \"js\",\n });\n }\n\n // Generate settings to enable hooks\n configs.push({\n path: \".gemini/settings.json\",\n content:\n JSON.stringify(\n {\n hooks: {\n enabled: true,\n directory: \".gemini/hooks\",\n },\n },\n null,\n 2,\n ) + \"\\n\",\n format: \"json\",\n });\n\n return configs;\n }\n\n mapEvent(event: HookEventType): string[] {\n return EVENT_MAP[event] ?? [];\n }\n\n mapNativeEvent(nativeEvent: string): HookEventType[] {\n return REVERSE_MAP[nativeEvent] ?? [];\n }\n\n async uninstall(): Promise<void> {\n // Remove hook scripts\n for (const event of Object.keys(REVERSE_MAP)) {\n await this.removeFile(`.gemini/hooks/${event}.js`);\n }\n }\n\n private generateEventScript(nativeEvent: string): string {\n return `#!/usr/bin/env node\n/**\n * ai-hooks runner for Gemini CLI (${nativeEvent}).\n * Generated by: ai-hooks generate\n */\nimport { loadConfig, HookEngine } from \"@premierstudio/ai-hooks\";\n\nconst input = JSON.parse(process.env.GEMINI_HOOK_INPUT ?? \"{}\");\n\nasync function run() {\n const config = await loadConfig();\n const engine = new HookEngine(config);\n const toolInfo = { name: \"gemini-cli\", version: \"1.0\" };\n const timestamp = Date.now();\n const metadata = {};\n\n let event;\n switch (\"${nativeEvent}\") {\n case \"SessionStart\":\n event = { type: \"session:start\", tool: \"gemini-cli\", version: \"1.0\", workingDirectory: process.cwd(), timestamp, metadata };\n break;\n case \"BeforeShell\":\n event = { type: \"shell:before\", command: input.command ?? \"\", cwd: process.cwd(), timestamp, metadata };\n break;\n case \"BeforeTool\":\n event = { type: \"tool:before\", toolName: input.toolName ?? \"unknown\", input, timestamp, metadata };\n break;\n case \"BeforePrompt\":\n event = { type: \"prompt:submit\", prompt: input.prompt ?? \"\", timestamp, metadata };\n break;\n default:\n event = { type: \"tool:after\", toolName: \"${nativeEvent}\", input, output: {}, duration: 0, timestamp, metadata };\n }\n\n const results = await engine.emit(event, toolInfo);\n const blocked = results.find((r) => r.blocked);\n\n if (blocked) {\n console.log(JSON.stringify({ blocked: true, reason: blocked.reason }));\n process.exit(1);\n }\n}\n\nrun().catch(() => process.exit(1));\n`;\n }\n}\n\nconst adapter = new GeminiCliAdapter();\nregistry.register(adapter);\n\nexport { GeminiCliAdapter };\nexport default adapter;\n","import { BaseAdapter, registry } from \"./index.js\";\nimport type {\n AdapterCapabilities,\n GeneratedConfig,\n HookDefinition,\n HookEventType,\n} from \"../types/index.js\";\nimport { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\n\n/**\n * Event mapping: ai-hooks universal events -> Kiro CLI native hooks.\n *\n * Kiro supports five hook types:\n * agentSpawn, userPromptSubmit, preToolUse, postToolUse, stop\n *\n * Reference: https://kiro.dev/docs/cli/hooks/\n */\nconst EVENT_MAP: Record<string, string[]> = {\n \"session:start\": [\"agentSpawn\"],\n \"session:end\": [\"stop\"],\n \"prompt:submit\": [\"userPromptSubmit\"],\n \"prompt:response\": [\"stop\"],\n \"tool:before\": [\"preToolUse\"],\n \"tool:after\": [\"postToolUse\"],\n \"file:read\": [\"preToolUse\"],\n \"file:write\": [\"preToolUse\"],\n \"file:edit\": [\"preToolUse\"],\n \"file:delete\": [\"preToolUse\"],\n \"shell:before\": [\"preToolUse\"],\n \"shell:after\": [\"postToolUse\"],\n \"mcp:before\": [\"preToolUse\"],\n \"mcp:after\": [\"postToolUse\"],\n};\n\nconst REVERSE_MAP: Record<string, HookEventType[]> = {\n agentSpawn: [\"session:start\"],\n userPromptSubmit: [\"prompt:submit\"],\n preToolUse: [\n \"tool:before\",\n \"file:read\",\n \"file:write\",\n \"file:edit\",\n \"file:delete\",\n \"shell:before\",\n \"mcp:before\",\n ],\n postToolUse: [\"tool:after\", \"shell:after\", \"mcp:after\"],\n stop: [\"session:end\", \"prompt:response\"],\n};\n\n/**\n * Kiro CLI adapter for ai-hooks.\n *\n * Generates hook entries for Kiro's agent configuration format. Kiro uses\n * JSON agent config files in `.kiro/` with a `hooks` section containing\n * agentSpawn, userPromptSubmit, preToolUse, postToolUse, and stop events.\n *\n * Hook scripts receive event data as JSON via STDIN. Exit code 2 blocks\n * execution on preToolUse hooks.\n *\n * Reference: https://kiro.dev/docs/cli/hooks/\n */\nclass KiroAdapter extends BaseAdapter {\n readonly id = \"kiro\";\n readonly name = \"Kiro CLI\";\n readonly version = \"1.0\";\n\n readonly capabilities: AdapterCapabilities = {\n beforeHooks: true,\n afterHooks: true,\n mcp: true,\n configFile: true,\n supportedEvents: [\n \"session:start\",\n \"session:end\",\n \"prompt:submit\",\n \"prompt:response\",\n \"tool:before\",\n \"tool:after\",\n \"file:read\",\n \"file:write\",\n \"file:edit\",\n \"file:delete\",\n \"shell:before\",\n \"shell:after\",\n \"mcp:before\",\n \"mcp:after\",\n ],\n blockableEvents: [\n \"tool:before\",\n \"file:read\",\n \"file:write\",\n \"file:edit\",\n \"file:delete\",\n \"shell:before\",\n \"mcp:before\",\n ],\n };\n\n async detect(): Promise<boolean> {\n const hasCommand = await this.commandExists(\"kiro\");\n const hasDir = existsSync(resolve(process.cwd(), \".kiro\"));\n return hasCommand || hasDir;\n }\n\n async generate(hooks: HookDefinition[]): Promise<GeneratedConfig[]> {\n const configs: GeneratedConfig[] = [];\n\n // Collect needed native events\n const neededEvents = new Set<string>();\n for (const hook of hooks) {\n for (const event of hook.events) {\n const nativeEvents = this.mapEvent(event);\n for (const ne of nativeEvents) {\n neededEvents.add(ne);\n }\n }\n }\n\n // Generate the runner script\n configs.push({\n path: \".kiro/hooks/ai-hooks-runner.js\",\n content: this.generateRunner(),\n format: \"js\",\n });\n\n // Build Kiro hooks config\n const hooksConfig: Record<string, unknown[]> = {};\n\n for (const event of neededEvents) {\n const entry: Record<string, unknown> = {\n command: \"node .kiro/hooks/ai-hooks-runner.js\",\n };\n\n // preToolUse and postToolUse support matchers; use wildcard\n if (event === \"preToolUse\" || event === \"postToolUse\") {\n entry.matcher = \"*\";\n }\n\n if (!hooksConfig[event]) {\n hooksConfig[event] = [];\n }\n hooksConfig[event].push(entry);\n }\n\n configs.push({\n path: \".kiro/hooks/ai-hooks.json\",\n content: JSON.stringify({ hooks: hooksConfig }, null, 2) + \"\\n\",\n format: \"json\",\n });\n\n return configs;\n }\n\n mapEvent(event: HookEventType): string[] {\n return EVENT_MAP[event] ?? [];\n }\n\n mapNativeEvent(nativeEvent: string): HookEventType[] {\n return REVERSE_MAP[nativeEvent] ?? [];\n }\n\n async uninstall(): Promise<void> {\n await this.removeFile(\".kiro/hooks/ai-hooks-runner.js\");\n await this.removeFile(\".kiro/hooks/ai-hooks.json\");\n }\n\n private generateRunner(): string {\n return `#!/usr/bin/env node\n/**\n * ai-hooks runner for Kiro CLI.\n * Generated by: ai-hooks generate\n *\n * Kiro passes hook event data as JSON via STDIN.\n * Exit code 0 = success, exit code 2 = block (preToolUse only).\n *\n * DO NOT EDIT - regenerate with: ai-hooks generate\n */\nimport { loadConfig, HookEngine } from \"@premierstudio/ai-hooks\";\n\nasync function readStdin() {\n const chunks = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n }\n return Buffer.concat(chunks).toString(\"utf-8\");\n}\n\nasync function run() {\n const raw = await readStdin();\n const input = JSON.parse(raw || \"{}\");\n const hookEventName = input.hook_event_name ?? \"\";\n const toolName = input.tool_name ?? \"\";\n const toolInput = input.tool_input ?? {};\n\n const config = await loadConfig();\n const engine = new HookEngine(config);\n const toolInfo = { name: \"kiro\", version: \"1.0\" };\n const timestamp = Date.now();\n const metadata = {};\n\n let event;\n switch (hookEventName) {\n case \"agentSpawn\":\n event = {\n type: \"session:start\",\n tool: \"kiro\",\n version: \"1.0\",\n workingDirectory: input.cwd ?? process.cwd(),\n timestamp,\n metadata,\n };\n break;\n case \"userPromptSubmit\":\n event = {\n type: \"prompt:submit\",\n prompt: toolInput.prompt ?? \"\",\n timestamp,\n metadata,\n };\n break;\n case \"preToolUse\":\n event = resolvePreToolEvent(toolName, toolInput, timestamp, metadata);\n break;\n case \"postToolUse\":\n event = resolvePostToolEvent(toolName, toolInput, input.tool_response ?? {}, timestamp, metadata);\n break;\n case \"stop\":\n event = {\n type: \"session:end\",\n tool: \"kiro\",\n duration: 0,\n timestamp,\n metadata,\n };\n break;\n default:\n process.exit(0);\n }\n\n const results = await engine.emit(event, toolInfo);\n const blocked = results.find((r) => r.blocked);\n\n if (blocked) {\n process.stderr.write(blocked.reason ?? \"Blocked by ai-hooks\");\n process.exit(2);\n }\n}\n\nfunction resolvePreToolEvent(toolName, toolInput, timestamp, metadata) {\n switch (toolName) {\n case \"fs_write\":\n case \"write\":\n return { type: \"file:write\", path: toolInput.path ?? \"\", content: toolInput.content ?? \"\", timestamp, metadata };\n case \"fs_edit\":\n case \"edit\":\n return { type: \"file:edit\", path: toolInput.path ?? \"\", oldContent: toolInput.old_string ?? \"\", newContent: toolInput.new_string ?? \"\", timestamp, metadata };\n case \"fs_read\":\n case \"read\":\n return { type: \"file:read\", path: toolInput.path ?? \"\", timestamp, metadata };\n case \"execute_bash\":\n case \"shell\":\n return { type: \"shell:before\", command: toolInput.command ?? \"\", cwd: process.cwd(), timestamp, metadata };\n default:\n return { type: \"tool:before\", toolName: toolName || \"unknown\", input: toolInput, timestamp, metadata };\n }\n}\n\nfunction resolvePostToolEvent(toolName, toolInput, toolResponse, timestamp, metadata) {\n switch (toolName) {\n case \"execute_bash\":\n case \"shell\":\n return {\n type: \"shell:after\",\n command: toolInput.command ?? \"\",\n cwd: process.cwd(),\n exitCode: toolResponse.exitCode ?? 0,\n stdout: toolResponse.stdout ?? \"\",\n stderr: toolResponse.stderr ?? \"\",\n duration: 0,\n timestamp,\n metadata,\n };\n default:\n return { type: \"tool:after\", toolName: toolName || \"unknown\", input: toolInput, output: toolResponse, duration: 0, timestamp, metadata };\n }\n}\n\nrun().catch((err) => {\n console.error(\"[ai-hooks] Error:\", err.message);\n process.exit(1);\n});\n`;\n }\n}\n\n// Auto-register\nconst adapter = new KiroAdapter();\nregistry.register(adapter);\n\nexport { KiroAdapter };\nexport default adapter;\n","import { BaseAdapter, registry } from \"./index.js\";\nimport type {\n AdapterCapabilities,\n GeneratedConfig,\n HookDefinition,\n HookEventType,\n} from \"../types/index.js\";\nimport { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\n\n/**\n * Event mapping: ai-hooks universal events -> OpenCode plugin hooks.\n *\n * OpenCode (by SST) uses a plugin system with lifecycle hooks.\n * Plugins are JS/TS modules in `.opencode/plugins/` that export\n * hook handlers keyed by event name.\n *\n * Reference: https://opencode.ai/docs/plugins/\n */\nconst EVENT_MAP: Record<string, string[]> = {\n \"session:start\": [\"session.created\"],\n \"session:end\": [\"session.idle\"],\n \"prompt:submit\": [\"message.updated\"],\n \"prompt:response\": [\"message.part.updated\"],\n \"tool:before\": [\"tool.execute.before\"],\n \"tool:after\": [\"tool.execute.after\"],\n \"file:read\": [\"tool.execute.before\"],\n \"file:write\": [\"tool.execute.before\", \"file.edited\"],\n \"file:edit\": [\"tool.execute.before\", \"file.edited\"],\n \"file:delete\": [\"tool.execute.before\"],\n \"shell:before\": [\"tool.execute.before\"],\n \"shell:after\": [\"tool.execute.after\"],\n \"mcp:before\": [\"tool.execute.before\"],\n \"mcp:after\": [\"tool.execute.after\"],\n notification: [\"tui.toast.show\"],\n};\n\nconst REVERSE_MAP: Record<string, HookEventType[]> = {\n \"session.created\": [\"session:start\"],\n \"session.idle\": [\"session:end\"],\n \"message.updated\": [\"prompt:submit\"],\n \"message.part.updated\": [\"prompt:response\"],\n \"tool.execute.before\": [\n \"tool:before\",\n \"file:read\",\n \"file:write\",\n \"file:edit\",\n \"file:delete\",\n \"shell:before\",\n \"mcp:before\",\n ],\n \"tool.execute.after\": [\"tool:after\", \"shell:after\", \"mcp:after\"],\n \"file.edited\": [\"file:write\", \"file:edit\"],\n \"tui.toast.show\": [\"notification\"],\n};\n\n/**\n * OpenCode adapter for ai-hooks.\n *\n * Generates an OpenCode plugin in `.opencode/plugins/` that hooks into\n * the tool.execute.before/after and other lifecycle events. OpenCode\n * plugins receive context objects and can block tool execution by\n * returning a modified output from tool.execute.before.\n *\n * Reference: https://opencode.ai/docs/plugins/\n */\nclass OpenCodeAdapter extends BaseAdapter {\n readonly id = \"opencode\";\n readonly name = \"OpenCode\";\n readonly version = \"1.0\";\n\n readonly capabilities: AdapterCapabilities = {\n beforeHooks: true,\n afterHooks: true,\n mcp: true,\n configFile: true,\n supportedEvents: [\n \"session:start\",\n \"session:end\",\n \"prompt:submit\",\n \"prompt:response\",\n \"tool:before\",\n \"tool:after\",\n \"file:read\",\n \"file:write\",\n \"file:edit\",\n \"file:delete\",\n \"shell:before\",\n \"shell:after\",\n \"mcp:before\",\n \"mcp:after\",\n \"notification\",\n ],\n blockableEvents: [\n \"tool:before\",\n \"file:read\",\n \"file:write\",\n \"file:edit\",\n \"file:delete\",\n \"shell:before\",\n \"mcp:before\",\n ],\n };\n\n async detect(): Promise<boolean> {\n const hasCommand = await this.commandExists(\"opencode\");\n const hasDir = existsSync(resolve(process.cwd(), \".opencode\"));\n return hasCommand || hasDir;\n }\n\n async generate(hooks: HookDefinition[]): Promise<GeneratedConfig[]> {\n const configs: GeneratedConfig[] = [];\n\n // Collect needed native events\n const neededEvents = new Set<string>();\n for (const hook of hooks) {\n for (const event of hook.events) {\n const nativeEvents = this.mapEvent(event);\n for (const ne of nativeEvents) {\n neededEvents.add(ne);\n }\n }\n }\n\n // Generate the OpenCode plugin\n configs.push({\n path: \".opencode/plugins/ai-hooks-plugin.js\",\n content: this.generatePlugin(neededEvents),\n format: \"js\",\n });\n\n // Generate opencode.json config that registers the plugin\n configs.push({\n path: \".opencode/plugins/package.json\",\n content:\n JSON.stringify(\n {\n name: \"ai-hooks-opencode-plugin\",\n version: \"1.0.0\",\n type: \"module\",\n main: \"ai-hooks-plugin.js\",\n dependencies: {\n \"@premierstudio/ai-hooks\": \"*\",\n },\n },\n null,\n 2,\n ) + \"\\n\",\n format: \"json\",\n });\n\n return configs;\n }\n\n mapEvent(event: HookEventType): string[] {\n return EVENT_MAP[event] ?? [];\n }\n\n mapNativeEvent(nativeEvent: string): HookEventType[] {\n return REVERSE_MAP[nativeEvent] ?? [];\n }\n\n async uninstall(): Promise<void> {\n await this.removeFile(\".opencode/plugins/ai-hooks-plugin.js\");\n await this.removeFile(\".opencode/plugins/package.json\");\n }\n\n private generatePlugin(neededEvents: Set<string>): string {\n const hookEntries = [...neededEvents]\n .map((event) => {\n return ` \"${event}\": async (input, output) => {\n await handleHook(\"${event}\", input, output);\n }`;\n })\n .join(\",\\n\");\n\n return `/**\n * ai-hooks plugin for OpenCode.\n * Generated by: ai-hooks generate\n *\n * This plugin hooks into OpenCode's lifecycle events and delegates\n * to the ai-hooks engine for unified hook management.\n *\n * DO NOT EDIT - regenerate with: ai-hooks generate\n */\nimport { loadConfig, HookEngine } from \"@premierstudio/ai-hooks\";\n\nlet engine;\n\nasync function getEngine() {\n if (!engine) {\n const config = await loadConfig();\n engine = new HookEngine(config);\n }\n return engine;\n}\n\nasync function handleHook(hookName, input, output) {\n const eng = await getEngine();\n const toolInfo = { name: \"opencode\", version: \"1.0\" };\n const timestamp = Date.now();\n const metadata = {};\n\n let event;\n switch (hookName) {\n case \"session.created\":\n event = { type: \"session:start\", tool: \"opencode\", version: \"1.0\", workingDirectory: process.cwd(), timestamp, metadata };\n break;\n case \"session.idle\":\n event = { type: \"session:end\", tool: \"opencode\", duration: 0, timestamp, metadata };\n break;\n case \"tool.execute.before\":\n event = resolveToolBefore(input, timestamp, metadata);\n break;\n case \"tool.execute.after\":\n event = resolveToolAfter(input, timestamp, metadata);\n break;\n case \"file.edited\":\n event = { type: \"file:edit\", path: input.path ?? \"\", oldContent: \"\", newContent: \"\", timestamp, metadata };\n break;\n case \"message.updated\":\n event = { type: \"prompt:submit\", prompt: input.content ?? \"\", timestamp, metadata };\n break;\n case \"message.part.updated\":\n event = { type: \"prompt:response\", response: input.content ?? \"\", model: \"unknown\", tokens: { input: 0, output: 0 }, timestamp, metadata };\n break;\n case \"tui.toast.show\":\n event = { type: \"notification\", level: \"info\", message: input.message ?? \"\", timestamp, metadata };\n break;\n default:\n return output;\n }\n\n const results = await eng.emit(event, toolInfo);\n const blocked = results.find((r) => r.blocked);\n\n if (blocked && hookName === \"tool.execute.before\") {\n return { ...output, blocked: true, reason: blocked.reason ?? \"Blocked by ai-hooks\" };\n }\n\n return output;\n}\n\nfunction resolveToolBefore(input, timestamp, metadata) {\n const toolName = input.tool ?? input.name ?? \"unknown\";\n const toolInput = input.input ?? input.args ?? {};\n\n switch (toolName) {\n case \"file_write\":\n case \"write\":\n return { type: \"file:write\", path: toolInput.path ?? \"\", content: toolInput.content ?? \"\", timestamp, metadata };\n case \"file_edit\":\n case \"edit\":\n return { type: \"file:edit\", path: toolInput.path ?? \"\", oldContent: toolInput.old ?? \"\", newContent: toolInput.new ?? \"\", timestamp, metadata };\n case \"file_read\":\n case \"read\":\n return { type: \"file:read\", path: toolInput.path ?? \"\", timestamp, metadata };\n case \"bash\":\n case \"shell\":\n return { type: \"shell:before\", command: toolInput.command ?? \"\", cwd: process.cwd(), timestamp, metadata };\n default:\n return { type: \"tool:before\", toolName, input: toolInput, timestamp, metadata };\n }\n}\n\nfunction resolveToolAfter(input, timestamp, metadata) {\n const toolName = input.tool ?? input.name ?? \"unknown\";\n const toolInput = input.input ?? input.args ?? {};\n const toolOutput = input.output ?? input.result ?? {};\n\n switch (toolName) {\n case \"bash\":\n case \"shell\":\n return {\n type: \"shell:after\",\n command: toolInput.command ?? \"\",\n cwd: process.cwd(),\n exitCode: toolOutput.exitCode ?? 0,\n stdout: toolOutput.stdout ?? \"\",\n stderr: toolOutput.stderr ?? \"\",\n duration: 0,\n timestamp,\n metadata,\n };\n default:\n return { type: \"tool:after\", toolName, input: toolInput, output: toolOutput, duration: 0, timestamp, metadata };\n }\n}\n\nexport const AiHooksPlugin = async ({ project, directory }) => {\n return {\n${hookEntries}\n };\n};\n`;\n }\n}\n\n// Auto-register\nconst adapter = new OpenCodeAdapter();\nregistry.register(adapter);\n\nexport { OpenCodeAdapter };\nexport default adapter;\n"]}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"all.js"}
@@ -1,122 +1,3 @@
1
- import { existsSync } from 'fs';
2
- import { mkdir, writeFile, readFile, rm } from 'fs/promises';
3
- import { resolve, dirname } from 'path';
4
-
5
- // src/adapters/registry.ts
6
- var AdapterRegistry = class {
7
- adapters = /* @__PURE__ */ new Map();
8
- factories = /* @__PURE__ */ new Map();
9
- /**
10
- * Register an adapter instance.
11
- */
12
- register(adapter) {
13
- this.adapters.set(adapter.id, adapter);
14
- }
15
- /**
16
- * Register an adapter factory for lazy instantiation.
17
- */
18
- registerFactory(id, factory) {
19
- this.factories.set(id, factory);
20
- }
21
- /**
22
- * Get a registered adapter by ID.
23
- */
24
- get(id) {
25
- const existing = this.adapters.get(id);
26
- if (existing) return existing;
27
- const factory = this.factories.get(id);
28
- if (factory) {
29
- const adapter = factory();
30
- this.adapters.set(id, adapter);
31
- return adapter;
32
- }
33
- return void 0;
34
- }
35
- /**
36
- * Get all registered adapter IDs.
37
- */
38
- list() {
39
- return [.../* @__PURE__ */ new Set([...this.adapters.keys(), ...this.factories.keys()])];
40
- }
41
- /**
42
- * Detect which tools are available in the current environment.
43
- * Returns adapters that successfully detect their tool.
44
- */
45
- async detectAll() {
46
- const detected = [];
47
- for (const id of this.list()) {
48
- const adapter = this.get(id);
49
- if (adapter) {
50
- try {
51
- const found = await adapter.detect();
52
- if (found) {
53
- detected.push(adapter);
54
- }
55
- } catch {
56
- }
57
- }
58
- }
59
- return detected;
60
- }
61
- /**
62
- * Clear the registry. Useful for testing.
63
- */
64
- clear() {
65
- this.adapters.clear();
66
- this.factories.clear();
67
- }
68
- };
69
- var registry = new AdapterRegistry();
70
- var BaseAdapter = class {
71
- /**
72
- * Default install: write generated configs to disk.
73
- */
74
- async install(configs) {
75
- for (const config of configs) {
76
- const fullPath = resolve(process.cwd(), config.path);
77
- await mkdir(dirname(fullPath), { recursive: true });
78
- await writeFile(fullPath, config.content, "utf-8");
79
- }
80
- }
81
- /**
82
- * Default uninstall: remove generated config files.
83
- */
84
- async uninstall() {
85
- }
86
- // ── Utility Methods ───────────────────────────────────────
87
- async fileExists(path) {
88
- return existsSync(resolve(process.cwd(), path));
89
- }
90
- async readJsonFile(path) {
91
- const fullPath = resolve(process.cwd(), path);
92
- if (!existsSync(fullPath)) return null;
93
- const content = await readFile(fullPath, "utf-8");
94
- return JSON.parse(content);
95
- }
96
- async writeJsonFile(path, data) {
97
- const fullPath = resolve(process.cwd(), path);
98
- await mkdir(dirname(fullPath), { recursive: true });
99
- await writeFile(fullPath, JSON.stringify(data, null, 2) + "\n", "utf-8");
100
- }
101
- async removeFile(path) {
102
- const fullPath = resolve(process.cwd(), path);
103
- if (existsSync(fullPath)) {
104
- await rm(fullPath);
105
- }
106
- }
107
- /**
108
- * Check if a CLI command exists on PATH.
109
- */
110
- async commandExists(command) {
111
- const { exec } = await import('child_process');
112
- return new Promise((resolve2) => {
113
- exec(`which ${command}`, (error) => {
114
- resolve2(!error);
115
- });
116
- });
117
- }
118
- };
119
-
120
- export { BaseAdapter, registry };
1
+ export { BaseAdapter, registry } from '../chunk-FHFRGMW6.js';
121
2
  //# sourceMappingURL=index.js.map
122
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/adapters/registry.ts","../../src/adapters/base.ts"],"names":["resolve"],"mappings":";;;;;AAMA,IAAM,kBAAN,MAAsB;AAAA,EACZ,QAAA,uBAAqC,GAAA,EAAI;AAAA,EACzC,SAAA,uBAA6C,GAAA,EAAI;AAAA;AAAA;AAAA;AAAA,EAKzD,SAAS,OAAA,EAAwB;AAC/B,IAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,OAAA,CAAQ,EAAA,EAAI,OAAO,CAAA;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,eAAA,CAAgB,IAAY,OAAA,EAA+B;AACzD,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,EAAA,EAAI,OAAO,CAAA;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,EAAA,EAAiC;AACnC,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,EAAE,CAAA;AACrC,IAAA,IAAI,UAAU,OAAO,QAAA;AAGrB,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,EAAE,CAAA;AACrC,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,MAAM,UAAU,OAAA,EAAQ;AACxB,MAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,EAAA,EAAI,OAAO,CAAA;AAC7B,MAAA,OAAO,OAAA;AAAA,IACT;AAEA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,IAAA,GAAiB;AACf,IAAA,OAAO,CAAC,mBAAG,IAAI,GAAA,CAAI,CAAC,GAAG,IAAA,CAAK,QAAA,CAAS,IAAA,EAAK,EAAG,GAAG,IAAA,CAAK,SAAA,CAAU,IAAA,EAAM,CAAC,CAAC,CAAA;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,SAAA,GAAgC;AACpC,IAAA,MAAM,WAAsB,EAAC;AAE7B,IAAA,KAAA,MAAW,EAAA,IAAM,IAAA,CAAK,IAAA,EAAK,EAAG;AAC5B,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA;AAC3B,MAAA,IAAI,OAAA,EAAS;AACX,QAAA,IAAI;AACF,UAAA,MAAM,KAAA,GAAQ,MAAM,OAAA,CAAQ,MAAA,EAAO;AACnC,UAAA,IAAI,KAAA,EAAO;AACT,YAAA,QAAA,CAAS,KAAK,OAAO,CAAA;AAAA,UACvB;AAAA,QACF,CAAA,CAAA,MAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AAEA,IAAA,OAAO,QAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,SAAS,KAAA,EAAM;AACpB,IAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AAAA,EACvB;AACF,CAAA;AAEO,IAAM,QAAA,GAAW,IAAI,eAAA;ACnErB,IAAe,cAAf,MAA8C;AAAA;AAAA;AAAA;AAAA,EAcnD,MAAM,QAAQ,OAAA,EAA2C;AACvD,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,MAAA,MAAM,WAAW,OAAA,CAAQ,OAAA,CAAQ,GAAA,EAAI,EAAG,OAAO,IAAI,CAAA;AACnD,MAAA,MAAM,MAAM,OAAA,CAAQ,QAAQ,GAAG,EAAE,SAAA,EAAW,MAAM,CAAA;AAClD,MAAA,MAAM,SAAA,CAAU,QAAA,EAAU,MAAA,CAAO,OAAA,EAAS,OAAO,CAAA;AAAA,IACnD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAA,GAA2B;AAAA,EAEjC;AAAA;AAAA,EAIA,MAAgB,WAAW,IAAA,EAAgC;AACzD,IAAA,OAAO,WAAW,OAAA,CAAQ,OAAA,CAAQ,GAAA,EAAI,EAAG,IAAI,CAAC,CAAA;AAAA,EAChD;AAAA,EAEA,MAAgB,aAAgB,IAAA,EAAiC;AAC/D,IAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,OAAA,CAAQ,GAAA,IAAO,IAAI,CAAA;AAC5C,IAAA,IAAI,CAAC,UAAA,CAAW,QAAQ,CAAA,EAAG,OAAO,IAAA;AAClC,IAAA,MAAM,OAAA,GAAU,MAAM,QAAA,CAAS,QAAA,EAAU,OAAO,CAAA;AAChD,IAAA,OAAO,IAAA,CAAK,MAAM,OAAO,CAAA;AAAA,EAC3B;AAAA,EAEA,MAAgB,aAAA,CAAc,IAAA,EAAc,IAAA,EAA8B;AACxE,IAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,OAAA,CAAQ,GAAA,IAAO,IAAI,CAAA;AAC5C,IAAA,MAAM,MAAM,OAAA,CAAQ,QAAQ,GAAG,EAAE,SAAA,EAAW,MAAM,CAAA;AAClD,IAAA,MAAM,SAAA,CAAU,UAAU,IAAA,CAAK,SAAA,CAAU,MAAM,IAAA,EAAM,CAAC,CAAA,GAAI,IAAA,EAAM,OAAO,CAAA;AAAA,EACzE;AAAA,EAEA,MAAgB,WAAW,IAAA,EAA6B;AACtD,IAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,OAAA,CAAQ,GAAA,IAAO,IAAI,CAAA;AAC5C,IAAA,IAAI,UAAA,CAAW,QAAQ,CAAA,EAAG;AACxB,MAAA,MAAM,GAAG,QAAQ,CAAA;AAAA,IACnB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,cAAc,OAAA,EAAmC;AAC/D,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,OAAO,eAAoB,CAAA;AAClD,IAAA,OAAO,IAAI,OAAA,CAAQ,CAACA,QAAAA,KAAY;AAC9B,MAAA,IAAA,CAAK,CAAA,MAAA,EAAS,OAAO,CAAA,CAAA,EAAI,CAAC,KAAA,KAAU;AAClC,QAAAA,QAAAA,CAAQ,CAAC,KAAK,CAAA;AAAA,MAChB,CAAC,CAAA;AAAA,IACH,CAAC,CAAA;AAAA,EACH;AACF","file":"index.js","sourcesContent":["import type { Adapter, AdapterFactory } from \"../types/index.js\";\n\n/**\n * Global adapter registry.\n * Adapters register themselves when imported, or can be manually added.\n */\nclass AdapterRegistry {\n private adapters: Map<string, Adapter> = new Map();\n private factories: Map<string, AdapterFactory> = new Map();\n\n /**\n * Register an adapter instance.\n */\n register(adapter: Adapter): void {\n this.adapters.set(adapter.id, adapter);\n }\n\n /**\n * Register an adapter factory for lazy instantiation.\n */\n registerFactory(id: string, factory: AdapterFactory): void {\n this.factories.set(id, factory);\n }\n\n /**\n * Get a registered adapter by ID.\n */\n get(id: string): Adapter | undefined {\n const existing = this.adapters.get(id);\n if (existing) return existing;\n\n // Try factory\n const factory = this.factories.get(id);\n if (factory) {\n const adapter = factory();\n this.adapters.set(id, adapter);\n return adapter;\n }\n\n return undefined;\n }\n\n /**\n * Get all registered adapter IDs.\n */\n list(): string[] {\n return [...new Set([...this.adapters.keys(), ...this.factories.keys()])];\n }\n\n /**\n * Detect which tools are available in the current environment.\n * Returns adapters that successfully detect their tool.\n */\n async detectAll(): Promise<Adapter[]> {\n const detected: Adapter[] = [];\n\n for (const id of this.list()) {\n const adapter = this.get(id);\n if (adapter) {\n try {\n const found = await adapter.detect();\n if (found) {\n detected.push(adapter);\n }\n } catch {\n // Detection failed, skip this adapter\n }\n }\n }\n\n return detected;\n }\n\n /**\n * Clear the registry. Useful for testing.\n */\n clear(): void {\n this.adapters.clear();\n this.factories.clear();\n }\n}\n\nexport const registry = new AdapterRegistry();\n","import { existsSync } from \"node:fs\";\nimport { readFile, writeFile, mkdir, rm } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\nimport type {\n Adapter,\n AdapterCapabilities,\n GeneratedConfig,\n HookDefinition,\n HookEventType,\n} from \"../types/index.js\";\n\n/**\n * Base adapter class with shared utilities.\n * Tool-specific adapters extend this and implement the abstract methods.\n */\nexport abstract class BaseAdapter implements Adapter {\n abstract readonly id: string;\n abstract readonly name: string;\n abstract readonly version: string;\n abstract readonly capabilities: AdapterCapabilities;\n\n abstract detect(): Promise<boolean>;\n abstract generate(hooks: HookDefinition[]): Promise<GeneratedConfig[]>;\n abstract mapEvent(event: HookEventType): string[];\n abstract mapNativeEvent(nativeEvent: string): HookEventType[];\n\n /**\n * Default install: write generated configs to disk.\n */\n async install(configs: GeneratedConfig[]): Promise<void> {\n for (const config of configs) {\n const fullPath = resolve(process.cwd(), config.path);\n await mkdir(dirname(fullPath), { recursive: true });\n await writeFile(fullPath, config.content, \"utf-8\");\n }\n }\n\n /**\n * Default uninstall: remove generated config files.\n */\n async uninstall(): Promise<void> {\n // Subclasses should override with specific file paths\n }\n\n // ── Utility Methods ───────────────────────────────────────\n\n protected async fileExists(path: string): Promise<boolean> {\n return existsSync(resolve(process.cwd(), path));\n }\n\n protected async readJsonFile<T>(path: string): Promise<T | null> {\n const fullPath = resolve(process.cwd(), path);\n if (!existsSync(fullPath)) return null;\n const content = await readFile(fullPath, \"utf-8\");\n return JSON.parse(content) as T;\n }\n\n protected async writeJsonFile(path: string, data: unknown): Promise<void> {\n const fullPath = resolve(process.cwd(), path);\n await mkdir(dirname(fullPath), { recursive: true });\n await writeFile(fullPath, JSON.stringify(data, null, 2) + \"\\n\", \"utf-8\");\n }\n\n protected async removeFile(path: string): Promise<void> {\n const fullPath = resolve(process.cwd(), path);\n if (existsSync(fullPath)) {\n await rm(fullPath);\n }\n }\n\n /**\n * Check if a CLI command exists on PATH.\n */\n protected async commandExists(command: string): Promise<boolean> {\n const { exec } = await import(\"node:child_process\");\n return new Promise((resolve) => {\n exec(`which ${command}`, (error) => {\n resolve(!error);\n });\n });\n }\n}\n"]}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,100 @@
1
+ import { hook } from './chunk-N7ASBTX5.js';
2
+
3
+ // src/hooks/builtin.ts
4
+ var blockDangerousCommands = hook("before", ["shell:before"], async (ctx, next) => {
5
+ const command = ctx.event.command;
6
+ const dangerous = DANGEROUS_PATTERNS.find((p) => p.pattern.test(command));
7
+ if (dangerous) {
8
+ ctx.results.push({
9
+ blocked: true,
10
+ reason: `Blocked dangerous command: ${dangerous.description}`
11
+ });
12
+ return;
13
+ }
14
+ await next();
15
+ }).id("ai-hooks:block-dangerous-commands").name("Block Dangerous Commands").description("Prevents destructive shell commands like rm -rf /, drop database, etc.").priority(1).build();
16
+ var DANGEROUS_PATTERNS = [
17
+ { pattern: /rm\s+(-[a-zA-Z]*f[a-zA-Z]*\s+)?\/\s*$/, description: "rm -rf /" },
18
+ { pattern: /rm\s+-[a-zA-Z]*f[a-zA-Z]*\s+~\/?\s*$/, description: "rm -rf ~" },
19
+ { pattern: /mkfs\./, description: "filesystem format" },
20
+ { pattern: /dd\s+.*of=\/dev\/[sh]d/, description: "disk overwrite" },
21
+ { pattern: /:\(\)\s*\{\s*:\|:&\s*\}\s*;:/, description: "fork bomb" },
22
+ { pattern: />\s*\/dev\/[sh]d/, description: "device overwrite" },
23
+ { pattern: /chmod\s+(-R\s+)?777\s+\//, description: "chmod 777 /" },
24
+ { pattern: /DROP\s+DATABASE/i, description: "DROP DATABASE" },
25
+ { pattern: /DROP\s+TABLE/i, description: "DROP TABLE" },
26
+ { pattern: /TRUNCATE\s+TABLE/i, description: "TRUNCATE TABLE" }
27
+ ];
28
+ var scanSecrets = hook("before", ["file:write", "file:edit"], async (ctx, next) => {
29
+ const content = ctx.event.type === "file:write" ? ctx.event.content : ctx.event.newContent;
30
+ const found = SECRET_PATTERNS.find((p) => p.pattern.test(content));
31
+ if (found) {
32
+ ctx.results.push({
33
+ blocked: true,
34
+ reason: `Potential secret detected: ${found.description}. Use environment variables instead.`
35
+ });
36
+ return;
37
+ }
38
+ await next();
39
+ }).id("ai-hooks:scan-secrets").name("Scan for Secrets").description("Prevents hardcoded API keys, tokens, and credentials in file writes.").priority(2).build();
40
+ var SECRET_PATTERNS = [
41
+ { pattern: /(?:api[_-]?key|apikey)\s*[:=]\s*['"][a-zA-Z0-9]{20,}['"]/i, description: "API key" },
42
+ {
43
+ pattern: /(?:secret|token|password|passwd|pwd)\s*[:=]\s*['"][^'"]{8,}['"]/i,
44
+ description: "Secret/token/password"
45
+ },
46
+ { pattern: /-----BEGIN (?:RSA |EC |DSA )?PRIVATE KEY-----/, description: "Private key" },
47
+ { pattern: /ghp_[a-zA-Z0-9]{36}/, description: "GitHub personal access token" },
48
+ { pattern: /sk-[a-zA-Z0-9]{20,}/, description: "OpenAI/Stripe secret key" },
49
+ { pattern: /AKIA[0-9A-Z]{16}/, description: "AWS access key ID" },
50
+ { pattern: /xox[bpors]-[a-zA-Z0-9-]{10,}/, description: "Slack token" }
51
+ ];
52
+ var protectGitignored = hook("before", ["file:write"], async (ctx, next) => {
53
+ const path = ctx.event.path;
54
+ const sensitive = SENSITIVE_FILES.some((f) => path.endsWith(f));
55
+ if (sensitive) {
56
+ ctx.results.push({
57
+ blocked: true,
58
+ reason: `Cannot write to sensitive file: ${path}. This file should be managed manually.`
59
+ });
60
+ return;
61
+ }
62
+ await next();
63
+ }).id("ai-hooks:protect-sensitive-files").name("Protect Sensitive Files").description("Prevents AI tools from overwriting .env, credentials, and other sensitive files.").priority(3).build();
64
+ var SENSITIVE_FILES = [
65
+ ".env",
66
+ ".env.local",
67
+ ".env.production",
68
+ "credentials.json",
69
+ "service-account.json",
70
+ "id_rsa",
71
+ "id_ed25519",
72
+ ".npmrc",
73
+ ".pypirc"
74
+ ];
75
+ var auditShellCommands = hook("after", ["shell:after"], async (ctx, next) => {
76
+ const { command, exitCode, duration } = ctx.event;
77
+ ctx.results.push({
78
+ data: {
79
+ audit: {
80
+ type: "shell",
81
+ command,
82
+ exitCode,
83
+ duration,
84
+ timestamp: ctx.event.timestamp,
85
+ tool: ctx.tool.name
86
+ }
87
+ }
88
+ });
89
+ await next();
90
+ }).id("ai-hooks:audit-shell").name("Audit Shell Commands").description("Records all shell command executions for audit trail.").priority(999).build();
91
+ var builtinHooks = [
92
+ blockDangerousCommands,
93
+ scanSecrets,
94
+ protectGitignored,
95
+ auditShellCommands
96
+ ];
97
+
98
+ export { auditShellCommands, blockDangerousCommands, builtinHooks, protectGitignored, scanSecrets };
99
+ //# sourceMappingURL=chunk-DSRP646D.js.map
100
+ //# sourceMappingURL=chunk-DSRP646D.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hooks/builtin.ts"],"names":[],"mappings":"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","file":"chunk-DSRP646D.js","sourcesContent":["import { hook } from \"../config/define.js\";\nimport type { HookDefinition } from \"../types/index.js\";\n\n/**\n * Built-in hook: Block dangerous shell commands.\n * Prevents rm -rf /, drop database, and other destructive patterns.\n */\nexport const blockDangerousCommands = hook(\"before\", [\"shell:before\"], async (ctx, next) => {\n const command = ctx.event.command;\n const dangerous = DANGEROUS_PATTERNS.find((p) => p.pattern.test(command));\n\n if (dangerous) {\n ctx.results.push({\n blocked: true,\n reason: `Blocked dangerous command: ${dangerous.description}`,\n });\n return;\n }\n\n await next();\n})\n .id(\"ai-hooks:block-dangerous-commands\")\n .name(\"Block Dangerous Commands\")\n .description(\"Prevents destructive shell commands like rm -rf /, drop database, etc.\")\n .priority(1)\n .build();\n\nconst DANGEROUS_PATTERNS = [\n { pattern: /rm\\s+(-[a-zA-Z]*f[a-zA-Z]*\\s+)?\\/\\s*$/, description: \"rm -rf /\" },\n { pattern: /rm\\s+-[a-zA-Z]*f[a-zA-Z]*\\s+~\\/?\\s*$/, description: \"rm -rf ~\" },\n { pattern: /mkfs\\./, description: \"filesystem format\" },\n { pattern: /dd\\s+.*of=\\/dev\\/[sh]d/, description: \"disk overwrite\" },\n { pattern: /:\\(\\)\\s*\\{\\s*:\\|:&\\s*\\}\\s*;:/, description: \"fork bomb\" },\n { pattern: />\\s*\\/dev\\/[sh]d/, description: \"device overwrite\" },\n { pattern: /chmod\\s+(-R\\s+)?777\\s+\\//, description: \"chmod 777 /\" },\n { pattern: /DROP\\s+DATABASE/i, description: \"DROP DATABASE\" },\n { pattern: /DROP\\s+TABLE/i, description: \"DROP TABLE\" },\n { pattern: /TRUNCATE\\s+TABLE/i, description: \"TRUNCATE TABLE\" },\n];\n\n/**\n * Built-in hook: Scan for secrets in file writes.\n * Detects API keys, tokens, and credentials being written to files.\n */\nexport const scanSecrets = hook(\"before\", [\"file:write\", \"file:edit\"], async (ctx, next) => {\n const content = ctx.event.type === \"file:write\" ? ctx.event.content : ctx.event.newContent;\n\n const found = SECRET_PATTERNS.find((p) => p.pattern.test(content));\n\n if (found) {\n ctx.results.push({\n blocked: true,\n reason: `Potential secret detected: ${found.description}. Use environment variables instead.`,\n });\n return;\n }\n\n await next();\n})\n .id(\"ai-hooks:scan-secrets\")\n .name(\"Scan for Secrets\")\n .description(\"Prevents hardcoded API keys, tokens, and credentials in file writes.\")\n .priority(2)\n .build();\n\nconst SECRET_PATTERNS = [\n { pattern: /(?:api[_-]?key|apikey)\\s*[:=]\\s*['\"][a-zA-Z0-9]{20,}['\"]/i, description: \"API key\" },\n {\n pattern: /(?:secret|token|password|passwd|pwd)\\s*[:=]\\s*['\"][^'\"]{8,}['\"]/i,\n description: \"Secret/token/password\",\n },\n { pattern: /-----BEGIN (?:RSA |EC |DSA )?PRIVATE KEY-----/, description: \"Private key\" },\n { pattern: /ghp_[a-zA-Z0-9]{36}/, description: \"GitHub personal access token\" },\n { pattern: /sk-[a-zA-Z0-9]{20,}/, description: \"OpenAI/Stripe secret key\" },\n { pattern: /AKIA[0-9A-Z]{16}/, description: \"AWS access key ID\" },\n { pattern: /xox[bpors]-[a-zA-Z0-9-]{10,}/, description: \"Slack token\" },\n];\n\n/**\n * Built-in hook: Protect gitignored files from being read.\n */\nexport const protectGitignored = hook(\"before\", [\"file:write\"], async (ctx, next) => {\n const path = ctx.event.path;\n\n // Block writes to common sensitive files\n const sensitive = SENSITIVE_FILES.some((f) => path.endsWith(f));\n if (sensitive) {\n ctx.results.push({\n blocked: true,\n reason: `Cannot write to sensitive file: ${path}. This file should be managed manually.`,\n });\n return;\n }\n\n await next();\n})\n .id(\"ai-hooks:protect-sensitive-files\")\n .name(\"Protect Sensitive Files\")\n .description(\"Prevents AI tools from overwriting .env, credentials, and other sensitive files.\")\n .priority(3)\n .build();\n\nconst SENSITIVE_FILES = [\n \".env\",\n \".env.local\",\n \".env.production\",\n \"credentials.json\",\n \"service-account.json\",\n \"id_rsa\",\n \"id_ed25519\",\n \".npmrc\",\n \".pypirc\",\n];\n\n/**\n * Built-in hook: Log all shell commands (after phase).\n */\nexport const auditShellCommands = hook(\"after\", [\"shell:after\"], async (ctx, next) => {\n const { command, exitCode, duration } = ctx.event;\n ctx.results.push({\n data: {\n audit: {\n type: \"shell\",\n command,\n exitCode,\n duration,\n timestamp: ctx.event.timestamp,\n tool: ctx.tool.name,\n },\n },\n });\n await next();\n})\n .id(\"ai-hooks:audit-shell\")\n .name(\"Audit Shell Commands\")\n .description(\"Records all shell command executions for audit trail.\")\n .priority(999)\n .build();\n\n/**\n * All built-in hooks as an array.\n * Use with `extends` in defineConfig to include defaults.\n */\nexport const builtinHooks: HookDefinition[] = [\n blockDangerousCommands,\n scanSecrets,\n protectGitignored,\n auditShellCommands,\n];\n"]}