flake-update-20260505
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();