/**
* React hooks for the AgentKit.
*
* These hooks allow advanced usage such as manual element registration,
* custom commands, and bridge status monitoring.
*/
import { useContext, useEffect, useRef } from 'react';
import type { ElementInfo, ElementHandlers } from './types';
import { AgentKitContext } from './AgentKitProvider';
import type { AgentKitContextValue } from './AgentKitProvider';
import { ElementRegistry } from './ElementRegistry';
/**
* Access the AgentKit context.
*
* @example
* ```tsx
* function MyScreen() {
* const { isRunning, elementCount, rescan } = useAgentKit();
*
* return (
*
* Bridge running: {isRunning ? 'Yes' : 'No'}
* Elements: {elementCount}
*
*
* );
* }
* ```
*/
export function useAgentKit(): AgentKitContextValue {
return useContext(AgentKitContext);
}
/**
* Register a UI element with the AgentKit for AI agent interaction.
*
* Use this when automatic introspection doesn't pick up an element,
* or when you want to provide better metadata/labels.
*
* @example
* ```tsx
* function CustomButton({ onPress, label }: Props) {
* const ref = useRef(null);
*
* useAgentKitElement('my-custom-btn', {
* type: 'button',
* label,
* state: { disabled: false, selected: false },
* position: { x: 0, y: 0, width: 0, height: 0 },
* children: [],
* actions: ['tap'],
* }, ref, { onPress });
*
* return (
*
* {label}
*
* );
* }
* ```
*/
export function useAgentKitElement(
id: string,
info: Omit,
ref: React.RefObject,
handlers?: ElementHandlers
): void {
const { registerElement, unregisterElement } = useAgentKit();
// Keep latest handlers/info in refs so the registry always has current values
const handlersRef = useRef(handlers);
const infoRef = useRef(info);
handlersRef.current = handlers;
infoRef.current = info;
// Register on mount, unregister on unmount
useEffect(() => {
const registeredId = registerElement(
id,
infoRef.current,
ref,
handlersRef.current
);
return () => unregisterElement(registeredId);
}, [id]); // eslint-disable-line react-hooks/exhaustive-deps
// Update handlers and info on every change
useEffect(() => {
ElementRegistry.update(id, info);
if (handlers) {
ElementRegistry.updateHandlers(id, handlers);
}
}); // no deps — runs every render to keep handlers fresh
}
/**
* Get a rescan trigger for the AgentKit.
*
* Useful when you know the screen content has changed (e.g. after
* navigation or data loading) and want to update the element registry
* immediately rather than waiting for the next periodic scan.
*
* @example
* ```tsx
* function MyComponent() {
* const triggerRescan = useAgentKitRescan();
*
* useEffect(() => {
* // After data loads, trigger a rescan
* fetchData().then(() => triggerRescan());
* }, []);
* }
* ```
*/
export function useAgentKitRescan(): () => void {
const { rescan } = useAgentKit();
return rescan;
}
/**
* Monitor the AgentKit status.
*
* @example
* ```tsx
* function StatusBar() {
* const { isRunning, elementCount } = useAgentKitStatus();
* return {isRunning ? `🟢 ${elementCount} elements` : '🔴 Offline'};
* }
* ```
*/
export function useAgentKitStatus(): {
isRunning: boolean;
elementCount: number;
} {
const { isRunning, elementCount } = useAgentKit();
return { isRunning, elementCount };
}