Productivity
Hook
Hooks
What claude-adhd-skills runs automatically, and when. A hook is a command Claude Code fires at a fixed moment, without you asking for it.
Install
$ npx -y skills add ravila4/claude-adhd-skills --agent claude-codeShips with claude-adhd-skills. Installing the plugin gets these hooks.
Where it lives
- hooks/ack_alert.pyGitHub
Read the script
#!/usr/bin/env python3 """Acknowledge (dismiss) an alert.""" import sqlite3 import sys from pathlib import Path DB_PATH = Path(__file__).parent / "alerts.db" def ack_alert(alert_id: int) -> bool: """Mark alert as acknowledged. Returns True if found.""" with sqlite3.connect(DB_PATH) as conn: cursor = conn.execute( "UPDATE alerts SET acknowledged = 1 WHERE id = ?", (alert_id,), ) return cursor.rowcount > 0 def main() -> None: if len(sys.argv) < 2: print("Usage: ack_alert.py <alert_id>") sys.exit(1) alert_id = int(sys.argv[1]) if ack_alert(alert_id): print(f"Alert {alert_id} acknowledged") else: print(f"Alert {alert_id} not found") sys.exit(1) if __name__ == "__main__": main() - hooks/add_alert.pyGitHub
Read the script
#!/usr/bin/env python3 """Add a new alert to the database.""" import sqlite3 import sys from datetime import datetime, timedelta from pathlib import Path DB_PATH = Path(__file__).parent / "alerts.db" def init_db() -> None: """Create alerts table if it doesn't exist.""" with sqlite3.connect(DB_PATH) as conn: conn.execute(""" CREATE TABLE IF NOT EXISTS alerts ( id INTEGER PRIMARY KEY AUTOINCREMENT, due_at TEXT NOT NULL, message TEXT NOT NULL, created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, acknowledged INTEGER NOT NULL DEFAULT 0 ) """) def parse_time(time_str: str) -> str: """Parse time string into ISO format. Accepts: - HH:MM (today) - YYYY-MM-DD HH:MM - +Nm (N minutes from now) - +Nh (N hours from now) """ now = datetime.now() if time_str.startswith("+"): # Relative time try: amount = int(time_str[1:-1]) except ValueError: raise ValueError(f"Invalid time format: {time_str!r}. Expected +30m or +2h") unit = time_str[-1] if unit == "m": target = now + timedelta(minutes=amount) elif unit == "h": target = now + timedelta(hours=amount) else: raise ValueError(f"Unknown unit: {unit!r}. Use 'm' (minutes) or 'h' (hours)") return target.strftime("%Y-%m-%d %H:%M") if len(time_str) == 5 and ":" in time_str: # HH:MM format - assume today return f"{now.strftime('%Y-%m-%d')} {time_str}" # Assume full datetime return time_str def add_alert(due_at: str, message: str) -> int: """Add alert and return its ID.""" with sqlite3.connect(DB_PATH) as conn: cursor = conn.execute( "INSERT INTO alerts (due_at, message) VALUES (?, ?)", (due_at, message), ) return cursor.lastrowid def main() -> None: init_db() if len(sys.argv) < 3: print("Usage: add_alert.py <time> <message>") print(" Time formats: HH:MM, YYYY-MM-DD HH:MM, +30m, +2h") sys.exit(1) time_str = sys.argv[1] message = " ".join(sys.argv[2:]) due_at = parse_time(time_str) alert_id = add_alert(due_at, message) print(f"Alert {alert_id} set for {due_at}: {message}") if __name__ == "__main__": main() - hooks/check_alerts.pyGitHub
Read the script
#!/usr/bin/env python3 """Hook script: check for due alerts and print them.""" import sqlite3 from datetime import datetime from pathlib import Path DB_PATH = Path(__file__).parent / "alerts.db" def init_db() -> None: """Create alerts table if it doesn't exist.""" with sqlite3.connect(DB_PATH) as conn: conn.execute(""" CREATE TABLE IF NOT EXISTS alerts ( id INTEGER PRIMARY KEY AUTOINCREMENT, due_at TEXT NOT NULL, message TEXT NOT NULL, created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, acknowledged INTEGER NOT NULL DEFAULT 0 ) """) def check_alerts() -> list[tuple[int, str, str]]: """Return list of (id, due_at, message) for unacknowledged due alerts.""" now = datetime.now().strftime("%Y-%m-%d %H:%M") with sqlite3.connect(DB_PATH) as conn: cursor = conn.execute( """ SELECT id, due_at, message FROM alerts WHERE due_at <= ? AND acknowledged = 0 ORDER BY due_at """, (now,), ) return cursor.fetchall() def main() -> None: init_db() alerts = check_alerts() if alerts: print("⏰ ALERTS DUE:") for alert_id, due_at, message in alerts: print(f" [{alert_id}] {due_at}: {message}") print("(Use 'python3 ~/.claude/hooks/ack_alert.py <id>' to dismiss)") if __name__ == "__main__": main()
Read the script before you install anything that runs on your machine. This is the one part of a plugin that acts without being asked.
Ships withclaude-adhd-skills
(No ADHD required!) A set of Claude Code skills and hooks I use daily as scaffolding for staying organized while developing with AI agents.
Get the whole plugin

