Register form
AI copilot for React apps. Reads your state, fills forms, confirms actions, calls your tools. Multi-agent, AI SDK 6 + AG-UI, markdown skills. MIT.
npx -y skills add hec-ovi/agentickit --skill register-formAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Attach a react-hook-form instance to the copilot via usePilotForm. The hook registers three scoped tools (set_<name>_field, submit_<name>, reset_<name>) so the assistant can progressively fill and submit the form. Use when a consumer wants AI-assisted form completion.
SKILL.md
5.8 KB, as published. Nobody here has run it
Register Form
Contract
By the end of this skill the consumer has:
react-hook-forminstalled (it's an optional peer dep).- A
useForm<TFieldValues>()instance inside their component. - A call to
usePilotForm(form, { name }). The hook returns the form unchanged; existingform.register(...)calls keep working. - Three tools registered under the scoped names, no more, no less.
- Understanding that
submit_<name>walks the form's registered field refs to locate the<form>DOM node. It will NOT fall back todocument.forms.
Iron Law: usePilotForm never wraps, only registers
The hook takes a UseFormReturn<TFieldValues> and returns the same object
unchanged (see packages/agentickit/src/hooks/use-pilot-form.ts line 141).
Consumers keep calling form.register(...), form.handleSubmit(...),
form.watch(...) exactly as they would without the copilot. Do not
suggest an alternate "copilot-aware" form API. There isn't one, and
introducing one would break the RHF ecosystem integration.
Phases
Phase 1: install the peer
npm install react-hook-form
It's declared as an optional peer in packages/agentickit/package.json;
consumers who don't use forms skip it entirely.
Phase 2: wire useForm
Standard RHF. Pick the type for the field values first:
import { useForm } from "react-hook-form";
type InvoiceFields = { email: string; amount: number };
const form = useForm<InvoiceFields>({
defaultValues: { email: "", amount: 0 },
});
Phase 3: attach usePilotForm
import { usePilotForm } from "@hec-ovi/agentickit";
usePilotForm(form, { name: "invoice" });
The signature (verified against use-pilot-form.ts):
function usePilotForm<TFieldValues extends FieldValues>(
form: UseFormReturn<TFieldValues>,
options?: {
name?: string;
confirm?: { submit?: boolean; reset?: boolean };
},
): UseFormReturn<TFieldValues>
name defaults to "form", which is fine for single-form pages. Set it
explicitly on multi-form pages so the tool names don't collide.
confirm controls the per-form gate on the auto-registered submit_<name>
and reset_<name> tools. Both default to true; flip a key to false for
low-stakes flows where the approval popup is friction more than safety
(e.g. a draft-only "create" wizard whose output the user immediately edits).
Phase 4: render the form normally
<form onSubmit={form.handleSubmit(handleSubmit)}>
<input type="email" {...form.register("email", { required: true })} />
<input type="number" {...form.register("amount", { valueAsNumber: true })} />
<button type="submit">Send</button>
</form>
No wrapper component, no special props. The three scoped tools drive this
form via normal RHF APIs (setValue, reset, requestSubmit).
Phase 5: understand the registered tools
With name: "invoice", the hook registers:
set_invoice_field({ field, value })writes a single field viaform.setValue(field, value, { shouldValidate: true, shouldDirty: true, shouldTouch: true }). Field path strings like"email"or"address.street"are accepted. Triggers RHF validation so the UI reflects errors immediately. (Seeuse-pilot-form.tslines 71-91.)submit_invoice()callsrequestSubmit()on the located form node so the declaredonSubmithandler runs exactly as if the user clicked. Returns{ success: false, message }if the form is already submitting or not mounted.mutating: true. (Lines 93-120.)reset_invoice()callsform.reset()back todefaultValues.mutating: true. (Lines 122-132.)
Phase 6: security note
submit_invoice locates the <form> DOM node by walking from a
registered field's ref up to the nearest <form> ancestor. It will NOT
fall back to document.forms; doing so would let the assistant submit
any form on the page, including a search bar baked into a host shell.
(See findFormElement at use-pilot-form.ts lines 156-172 and the
comment on lines 149-155 explaining why.)
If submit_<name> returns { success: false, message: "Could not locate the <form> element." }, the form hasn't rendered yet or no fields are
registered. Register at least one field via form.register(...) before
the AI can submit.
Anti-Patterns
- Calling
usePilotForm(form)outside a<Pilot>provider. Logs a dev-only warning and is a no-op (lines 60-68). The user sees no error in prod. - Forgetting the
nameon multi-form pages.set_form_fieldcollides with itself across forms; the last registration wins, chaos ensues. - Letting the AI submit without the user's eyes on the form.
submit_<name>is alreadymutating: true; don't also manually register a bypass-confirm version. - Attempting to expose individual fields via
usePilotState. The per-field state is RHF's internal. Useform.watch()if you want read access, and surface that derived value throughusePilotStateif truly needed.
Output Format
After wiring, report:
- The form
name. - The three registered tool names (
set_<name>_field,submit_<name>,reset_<name>). - A one-line field-shape summary.
Tools Used
npm install react-hook-formif not already installed.- Edit the consumer component to add
useFormandusePilotForm. - Read
packages/agentickit/src/hooks/use-pilot-form.tsto verify the option shape and tool registration.