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.
Install
$ npx -y skills add Leon-Drq/openagentskill --agent claude-codeShips 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

