({
projectPath,
scope,
readOnly = false,
className,
onChange,
hideActions = false
})
| 109 | }; |
| 110 | |
| 111 | export const HooksEditor: React.FC<HooksEditorProps> = ({ |
| 112 | projectPath, |
| 113 | scope, |
| 114 | readOnly = false, |
| 115 | className, |
| 116 | onChange, |
| 117 | hideActions = false |
| 118 | }) => { |
| 119 | const [selectedEvent, setSelectedEvent] = useState<HookEvent>('PreToolUse'); |
| 120 | const [showTemplateDialog, setShowTemplateDialog] = useState(false); |
| 121 | const [validationErrors, setValidationErrors] = useState<string[]>([]); |
| 122 | const [validationWarnings, setValidationWarnings] = useState<string[]>([]); |
| 123 | const isInitialMount = React.useRef(true); |
| 124 | const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false); |
| 125 | const [isSaving, setIsSaving] = useState(false); |
| 126 | const [isLoading, setIsLoading] = useState(false); |
| 127 | const [loadError, setLoadError] = useState<string | null>(null); |
| 128 | const [hooks, setHooks] = useState<HooksConfiguration>({}); |
| 129 | |
| 130 | // Events with matchers (tool-related) |
| 131 | const matcherEvents = ['PreToolUse', 'PostToolUse'] as const; |
| 132 | // Events without matchers (non-tool-related) |
| 133 | const directEvents = ['Notification', 'Stop', 'SubagentStop'] as const; |
| 134 | |
| 135 | // Convert hooks to editable format with IDs |
| 136 | const [editableHooks, setEditableHooks] = useState<{ |
| 137 | PreToolUse: EditableHookMatcher[]; |
| 138 | PostToolUse: EditableHookMatcher[]; |
| 139 | Notification: EditableHookCommand[]; |
| 140 | Stop: EditableHookCommand[]; |
| 141 | SubagentStop: EditableHookCommand[]; |
| 142 | }>(() => { |
| 143 | const result = { |
| 144 | PreToolUse: [], |
| 145 | PostToolUse: [], |
| 146 | Notification: [], |
| 147 | Stop: [], |
| 148 | SubagentStop: [] |
| 149 | } as any; |
| 150 | |
| 151 | // Initialize matcher events |
| 152 | matcherEvents.forEach(event => { |
| 153 | const matchers = hooks?.[event] as HookMatcher[] | undefined; |
| 154 | if (matchers && Array.isArray(matchers)) { |
| 155 | result[event] = matchers.map(matcher => ({ |
| 156 | ...matcher, |
| 157 | id: HooksManager.generateId(), |
| 158 | expanded: false, |
| 159 | hooks: (matcher.hooks || []).map(hook => ({ |
| 160 | ...hook, |
| 161 | id: HooksManager.generateId() |
| 162 | })) |
| 163 | })); |
| 164 | } |
| 165 | }); |
| 166 | |
| 167 | // Initialize direct events |
| 168 | directEvents.forEach(event => { |
nothing calls this directly
no test coverage detected