main
 1#!/usr/bin/env bun
 2/**
 3 * PostToolUse hook β€” update terminal tab title with context.
 4 *
 5 * Shows project name, active skill, task progress.
 6 */
 7
 8import { readStdinJSON, setTerminalTitle } from "./lib.ts";
 9import { basename } from "node:path";
10
11interface ToolResult {
12  tool_name: string;
13  tool_input: Record<string, unknown>;
14}
15
16interface TodoItem {
17  content: string;
18  status: string;
19  activeForm?: string;
20}
21
22const SKILL_ICONS: Record<string, string> = {
23  Journal: "πŸ““",
24  Notes: "πŸ“",
25  TODOs: "βœ…",
26  Org: "πŸ“‹",
27  Git: "πŸ”€",
28  GitHub: "πŸ™",
29  Email: "πŸ“§",
30  Python: "🐍",
31  golang: "🐹",
32  Rust: "πŸ¦€",
33  Nix: "❄️",
34  Kubernetes: "☸️",
35  Tekton: "πŸ”§",
36};
37
38function getTodoProgress(todos: TodoItem[]): string | null {
39  if (!todos?.length) return null;
40  let completed = 0;
41  let active = "";
42  for (const t of todos) {
43    if (t.status === "completed") completed++;
44    if (t.status === "in_progress" && t.activeForm) active = t.activeForm;
45  }
46  return active ? `[${completed + 1}/${todos.length}] ${active}` : null;
47}
48
49function buildTitle(result: ToolResult | null): string {
50  const prefix = "Claude";
51  const parts: string[] = [];
52
53  if (result?.tool_name === "TodoWrite") {
54    const todos = (result.tool_input as any).todos as TodoItem[] | undefined;
55    if (todos) {
56      const progress = getTodoProgress(todos);
57      if (progress) parts.push(progress);
58    }
59  }
60
61  if (result?.tool_name === "Skill") {
62    const skill = (result.tool_input as any).skill as string | undefined;
63    if (skill) {
64      const icon = SKILL_ICONS[skill] || "🎯";
65      parts.push(`${icon} ${skill}`);
66    }
67  }
68
69  const projectDir = process.env.CLAUDE_PROJECT_DIR;
70  if (projectDir) parts.push(basename(projectDir));
71
72  try {
73    parts.push(basename(process.cwd()));
74  } catch {}
75
76  return parts.length ? `${prefix} ${parts.join(" β€’ ")}` : `${prefix} Ready`;
77}
78
79async function main() {
80  const result = await readStdinJSON<ToolResult>();
81  setTerminalTitle(buildTitle(result));
82}
83
84main();