Skip to content
Development
Hook

Hooks

What openagentskill runs automatically, and when. A hook is a command Claude Code fires at a fixed moment, without you asking for it.

From plugin
openagentskill
3521 skill2 hooks
Install
$ npx -y skills add Leon-Drq/openagentskill --agent claude-code

Ships with openagentskill. Installing the plugin gets these hooks.

Where it lives

  • hooks/use-mobile.tsGitHub
    Read the script
    import * as React from 'react'
    
    const MOBILE_BREAKPOINT = 768
    
    export function useIsMobile() {
      const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)
    
      React.useEffect(() => {
        const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
        const onChange = () => {
          setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
        }
        mql.addEventListener('change', onChange)
        setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
        return () => mql.removeEventListener('change', onChange)
      }, [])
    
      return !!isMobile
    }
    
  • hooks/use-toast.tsGitHub
    Read the script
    'use client'
    
    // Inspired by react-hot-toast library
    import * as React from 'react'
    
    import type { ToastActionElement, ToastProps } from '@/components/ui/toast'
    
    const TOAST_LIMIT = 1
    const TOAST_REMOVE_DELAY = 1000000
    
    type ToasterToast = ToastProps & {
      id: string
      title?: React.ReactNode
      description?: React.ReactNode
      action?: ToastActionElement
    }
    
    const actionTypes = {
      ADD_TOAST: 'ADD_TOAST',
      UPDATE_TOAST: 'UPDATE_TOAST',
      DISMISS_TOAST: 'DISMISS_TOAST',
      REMOVE_TOAST: 'REMOVE_TOAST',
    } as const
    
    let count = 0
    
    function genId() {
      count = (count + 1) % Number.MAX_SAFE_INTEGER
      return count.toString()
    }
    
    type ActionType = typeof actionTypes
    
    type Action =
      | {
          type: ActionType['ADD_TOAST']
          toast: ToasterToast
        }
      | {
          type: ActionType['UPDATE_TOAST']
          toast: Partial<ToasterToast>
        }
      | {
          type: ActionType['DISMISS_TOAST']
          toastId?: ToasterToast['id']
        }
      | {
          type: ActionType['REMOVE_TOAST']
          toastId?: ToasterToast['id']
        }
    
    interface State {
      toasts: ToasterToast[]
    }
    
    const toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>()
    
    const addToRemoveQueue = (toastId: string) => {
      if (toastTimeouts.has(toastId)) {
        return
      }
    
      const timeout = setTimeout(() => {
        toastTimeouts.delete(toastId)
        dispatch({
          type: 'REMOVE_TOAST',
          toastId: toastId,
        })
      }, TOAST_REMOVE_DELAY)
    
      toastTimeouts.set(toastId, timeout)
    }
    
    export const reducer = (state: State, action: Action): State => {
      switch (action.type) {
        case 'ADD_TOAST':
          return {
            ...state,
            toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),
          }
    
        case 'UPDATE_TOAST':
          return {
            ...state,
            toasts: state.toasts.map((t) =>
              t.id === action.toast.id ? { ...t, ...action.toast } : t,
            ),
          }
    
        case 'DISMISS_TOAST': {
          const { toastId } = action
    
          // ! Side effects ! - This could be extracted into a dismissToast() action,
          // but I'll keep it here for simplicity
          if (toastId) {
            addToRemoveQueue(toastId)
          } else {
            state.toasts.forEach((toast) => {
              addToRemoveQueue(toast.id)
            })
          }
    
          return {
            ...state,
            toasts: state.toasts.map((t) =>
              t.id === toastId || toastId === undefined
                ? {
                    ...t,
                    open: false,
                  }
                : t,
            ),
          }
        }
        case 'REMOVE_TOAST':
          if (action.toastId === undefined) {
            return {
              ...state,
              toasts: [],
            }
          }
          return {
            ...state,
            toasts: state.toasts.filter((t) => t.id !== action.toastId),
          }
      }
    }
    
    const listeners: Array<(state: State) => void> = []
    
    let memoryState: State = { toasts: [] }
    
    function dispatch(action: Action) {
      memoryState = reducer(memoryState, action)
      listeners.forEach((listener) => {
        listener(memoryState)
      })
    }
    
    type Toast = Omit<ToasterToast, 'id'>
    
    function toast({ ...props }: Toast) {
      const id = genId()
    
      const update = (props: ToasterToast) =>
        dispatch({
          type: 'UPDATE_TOAST',
          toast: { ...props, id },
        })
      const dismiss = () => dispatch({ type: 'DISMISS_TOAST', toastId: id })
    
      dispatch({
        type: 'ADD_TOAST',
        toast: {
          ...props,
          id,
          open: true,
          onOpenChange: (open) => {
            if (!open) dismiss()
          },
        },
      })
    
      return {
        id: id,
        dismiss,
        update,
      }
    }
    
    function useToast() {
      const [state, setState] = React.useState<State>(memoryState)
    
      React.useEffect(() => {
        listeners.push(setState)
        return () => {
          const index = listeners.indexOf(setState)
          if (index > -1) {
            listeners.splice(index, 1)
          }
        }
      }, [state])
    
      return {
        ...state,
        toast,
        dismiss: (toastId?: string) => dispatch({ type: 'DISMISS_TOAST', toastId }),
      }
    }
    
    export { useToast, toast }
    

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 withopenagentskill

The skill layer for AI agents. Find, compare, audit, and install the right reusable Agent Skill before an agent acts.

Get the whole plugin
Stats
354
Stars
29
Forks
Active
Maintenance
TypeScript
Language
MIT
License
4m ago
Last commit
7mo ago
Created

Repo: Leon-Drq/openagentskill