Extension guides
Composer contributions
Composer slots are for state and actions tied to the next message. They stay deliberately small so the conversation and input remain usable at narrow widths.
Composer controls
A control sits in the compact row beside NativePi's model and thinking controls. Use it for one frequent action or a concise mode selector.
export default defineRenderer({
apiVersion: 1,
composerControls: [
{
id: "query-mode",
render: (context) => (
<Button
size="sm"
variant="ghost"
onClick={() => context.actions.insertIntoComposer("Run as read-only: ")}
>
Read-only query
</Button>
),
},
],
});Return one small interactive element. Put configuration in settings and detailed output in a dialog or panel rather than expanding the control row.
Composer widgets
A widget spans the composer immediately above or below it. Use the placement that matches its relationship to the input; most next-message context belongs above.
export default defineRenderer({
apiVersion: 1,
protocol: deployProtocol,
composerWidgets: [
{
id: "deploy-target",
placement: "aboveComposer",
render: (context) => <DeployTarget context={context} />,
},
],
});Placement rules
aboveComposerworks for selected targets, modes, validation, and context that affects the draft.belowComposerworks for compact status or helper actions that should follow NativePi's own controls.
Interaction behavior
- Inserting text must not send the message on the reader's behalf.
- Disable or explain actions that require an active session when
session.fileis null. - Show host-call failures near the control rather than leaving a rejected promise.
- Use shared controls so focus, disabled, hover, and reduced-motion behavior match NativePi.
See Shared UI for the available button, select, menu, and dialog components.