Commit 4f1a2e87190b

Vincent Demeester <vincent@sbr.pm>
2026-02-06 09:56:05
refactor(pi): remove claude-hooks.ts wrapper
All functionality has been migrated to native TypeScript extensions: - validate-git-push.ts: git safety validation - terminal-status.ts: terminal title, bell, notifications - ai-storage: session logging and saving The Go binaries are no longer called from Pi.
1 parent 3300a16
Changed files (1)
dots
pi
agent
dots/pi/agent/extensions/claude-hooks.ts
@@ -1,141 +0,0 @@
-/**
- * Pi Extension: Claude Code Hooks Wrapper
- *
- * Wraps the Go-based Claude Code hook binaries (claude-hooks-*) to provide
- * consistent hook behavior across AI coding agents.
- *
- * Events mapped:
- * - session_start -> claude-hooks-initialize-session
- * - session_shutdown -> claude-hooks-save-session
- * - tool_result -> claude-hooks-capture-tool-output
- *
- * Migrated to native TypeScript extensions:
- * - validate-git-push.ts (was: claude-hooks-validate-git-push)
- * - terminal-status.ts (was: claude-hooks-update-terminal-title)
- *
- * Requirements:
- * - claude-hooks-* binaries must be in PATH (installed via home-manager)
- */
-
-import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
-import { execSync, spawn } from "node:child_process";
-
-// Track if session has been initialized
-let sessionInitialized = false;
-
-// Cache binary existence checks
-const binaryCache = new Map<string, boolean>();
-
-// Convert Pi event format to Claude Code JSON format
-function toClaudePreToolUse(event: { toolName: string; input: any }): string {
-  return JSON.stringify({
-    tool_name: capitalize(event.toolName),
-    tool_input: event.input || {},
-    conversation_id: "pi-session",
-  });
-}
-
-function toClaudePostToolUse(event: {
-  toolName: string;
-  input: any;
-  content?: any[];
-  isError?: boolean;
-}): string {
-  return JSON.stringify({
-    tool_name: capitalize(event.toolName),
-    tool_input: event.input || {},
-    tool_response: {
-      content: event.content || [],
-      is_error: event.isError || false,
-    },
-    conversation_id: "pi-session",
-  });
-}
-
-function capitalize(s: string): string {
-  return s.charAt(0).toUpperCase() + s.slice(1);
-}
-
-// Run a Claude hook binary with JSON input
-async function runHook(
-  binary: string,
-  jsonInput?: string
-): Promise<{ exitCode: number; stdout: string; stderr: string }> {
-  return new Promise((resolve) => {
-    const proc = spawn(binary, [], {
-      shell: true,
-      stdio: ["pipe", "pipe", "pipe"],
-    });
-
-    let stdout = "";
-    let stderr = "";
-
-    proc.stdout.on("data", (data) => (stdout += data.toString()));
-    proc.stderr.on("data", (data) => (stderr += data.toString()));
-
-    if (jsonInput) {
-      proc.stdin.write(jsonInput);
-      proc.stdin.end();
-    } else {
-      proc.stdin.end();
-    }
-
-    proc.on("close", (code) => {
-      resolve({ exitCode: code ?? 0, stdout, stderr });
-    });
-
-    proc.on("error", () => {
-      resolve({ exitCode: 1, stdout: "", stderr: `Failed to spawn ${binary}` });
-    });
-  });
-}
-
-// Check if a binary exists in PATH (cached)
-function binaryExists(name: string): boolean {
-  if (binaryCache.has(name)) {
-    return binaryCache.get(name)!;
-  }
-  try {
-    execSync(`which ${name}`, { stdio: "ignore" });
-    binaryCache.set(name, true);
-    return true;
-  } catch {
-    binaryCache.set(name, false);
-    return false;
-  }
-}
-
-export default function (pi: ExtensionAPI) {
-  // Session initialization
-  pi.on("session_start", async (_event, ctx) => {
-    if (sessionInitialized) return;
-    sessionInitialized = true;
-
-    if (binaryExists("claude-hooks-initialize-session")) {
-      const result = await runHook("claude-hooks-initialize-session");
-      if (result.stderr && result.exitCode === 0) {
-        ctx.ui.notify(result.stderr.trim(), "info");
-      }
-    }
-  });
-
-  // Session shutdown
-  pi.on("session_shutdown", async (_event, _ctx) => {
-    if (binaryExists("claude-hooks-save-session")) {
-      await runHook("claude-hooks-save-session");
-    }
-    sessionInitialized = false;
-  });
-
-  // Pre-tool-use validation is now handled by validate-git-push.ts extension
-  // No need to call Go binary here anymore
-
-  // Post-tool-use capture
-  // NOTE: terminal title is now handled by terminal-status.ts extension
-  pi.on("tool_result", async (event, _ctx) => {
-    if (binaryExists("claude-hooks-capture-tool-output")) {
-      const jsonInput = toClaudePostToolUse(event);
-      await runHook("claude-hooks-capture-tool-output", jsonInput);
-    }
-  });
-}