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.
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. Let your AI agent find, compare, install, and report outcomes for the right reusable skill automatically. OpenAgentSkill is npm for AI Agent Skills.
Get the whole plugin
Stats
228
Stars
25
Forks
Active
Maintenance
TypeScript
Language
MIT
License
4h ago
Last commit
5mo ago
Created
Repo: Leon-Drq/openagentskill

