Skip to content
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.

From plugin
claude-adhd-skills
1664 skills3 hooks
Install
$ npx -y skills add ravila4/claude-adhd-skills --agent claude-code

Ships 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
Stats
166
Stars
9
Forks
Quiet
Maintenance
Python
Language
MIT
License
7mo ago
Last commit
7mo ago
Created
1d ago
Added

Repo: ravila4/claude-adhd-skills