main
 1#!/usr/bin/env bun
 2/**
 3 * PostToolUse hook — capture interesting tool outputs to JSONL.
 4 *
 5 * Tool-output logs are Claude-specific (not shared across tools)
 6 * and stay under ~/.config/claude/history/tool-outputs/.
 7 */
 8
 9import { readStdinJSON, TOOL_OUTPUTS_DIR, dateStr, yearMonth, ensureDir, now } from "./lib.ts";
10import { appendFileSync } from "node:fs";
11import { join } from "node:path";
12
13interface ToolUseData {
14  tool_name: string;
15  tool_input: Record<string, unknown>;
16  tool_response: Record<string, unknown>;
17  conversation_id?: string;
18  timestamp?: string;
19}
20
21const INTERESTING_TOOLS = new Set([
22  "Bash",
23  "Edit",
24  "Write",
25  "Read",
26  "Task",
27  "NotebookEdit",
28  "Skill",
29  "SlashCommand",
30]);
31
32async function main() {
33  const data = await readStdinJSON<ToolUseData>();
34  if (!data || !INTERESTING_TOOLS.has(data.tool_name)) {
35    process.exit(0);
36  }
37
38  const d = now();
39  const dir = join(TOOL_OUTPUTS_DIR, yearMonth(d));
40  ensureDir(dir);
41
42  const entry = {
43    timestamp: data.timestamp || d.toISOString(),
44    tool: data.tool_name,
45    input: data.tool_input,
46    output: data.tool_response,
47    session: data.conversation_id || "",
48  };
49
50  const file = join(dir, `${dateStr(d)}_tool-outputs.jsonl`);
51
52  try {
53    appendFileSync(file, JSON.stringify(entry) + "\n");
54  } catch (err) {
55    process.stderr.write(`[capture-tool-output] Error: ${err}\n`);
56  }
57
58  process.exit(0);
59}
60
61main();