How to configure, compose, or eject Agent Native features into app-owned code. Use when overriding shared components or integrations, customizing a template, adding UI to chat or headless apps, or inspecting package source.
78
100%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Start with the app's registered design system and local UI adapters, then use
the public feature's props, semantic components, controller, product slots,
and callbacks. If those seams are not enough, use the eject CLI to transfer
the smallest supported feature into the app and make that copy app-owned.
Never edit node_modules, deep-import a private source file at runtime, or
patch an @agent-native/* package.
Use this order:
app/design-system.ts with
defineDesignSystem, then pass that definition to ToolkitProvider.Ejection is for intentional product customization, not for hiding an upgrade failure or replacing Core runtime behavior.
Keep the explicit, typed registration seam in app/design-system.ts:
import { defineDesignSystem } from "@agent-native/toolkit/design-system";
import {
AcmeActionButtonAdapter,
AcmeDialogAdapter,
} from "./design-system/acme-adapter";
export const designSystem = defineDesignSystem({
name: "Acme",
components: {
ActionButton: AcmeActionButtonAdapter,
Dialog: AcmeDialogAdapter,
},
});Adapters translate the semantic Toolkit contract into company component props.
They are ordinary React components and may use MUI-style providers, React Aria,
CSS modules, CSS-in-JS, or another styling runtime. className and style are
optional interoperability hooks, not Tailwind or CVA requirements.
The contract has nine leaf components (ActionButton, IconButton,
TextField, TextArea, Spinner, Skeleton, Status, Surface, Avatar)
and eight behavior components (Tooltip, Menu, Popover, Dialog,
Picker, Checkbox, Switch, Tabs). Picker covers select and combobox
behavior, not date picking. Behavior adapters own their portal, focus,
keyboard, dismissal, and stacking implementation while honoring the semantic
props and portalContainer interop contract.
App product code imports standard controls from its local adapter path, usually
@/components/ui/*. Do not import @agent-native/toolkit/ui/* directly from
pages, routes, or domain components. That bypasses the app seam and makes a
future design-system replacement incomplete. Toolkit feature packages remain
valid imports; configure their presentation through the registered semantic
components, controller, and product slots.
Run the published conformance kit against a complete adapter in its own CI:
import { assertDesignSystemConformance } from "@agent-native/toolkit/conformance";
import { DESIGN_SYSTEM_CONTRACT_VERSION } from "@agent-native/toolkit/design-system";
await assertDesignSystemConformance({
adapterName: "Acme",
components,
contractVersion: DESIGN_SYSTEM_CONTRACT_VERSION,
});New components and optional props are minor contract changes. Required props, removed APIs, or behavioral changes require a new contract major.
Prefer feature-level headless controllers over rebuilding individual widgets. One controller must power both the Toolkit default view and every custom render path so behavior, actions, analytics, accessibility state, and error handling cannot drift. Use a product-level render slot to replace the view while keeping that controller. Eject only when the controller and slots cannot express the required product behavior.
Discover and inspect the ejection units published by installed first-party packages before changing source:
agent-native eject --list
agent-native eject inspect <unit>
agent-native eject <unit> --app <app>
agent-native eject <unit> --app <app> --applyThe command is dry-run by default. It prints the file closure, consumer import
rewrites, protected package contracts, and verification commands before
writing. --apply copies the package-version-matched source into the app and
rewrites only imports covered by the unit manifest.
Every first-party public ejection unit must have a complete manifest. If one is missing, treat that as a framework coverage bug instead of inventing a copy recipe. For an unknown third-party package, use the emitted add-style blueprint as a starting point. Protected runtime behavior is never copied; follow the reported configuration, adapter, or extension seam instead.
Applied ejections are recorded in the committed
agent-native.ejections.json, including package version, manifest digest,
target hashes, and import rewrites. Use the recorded state to review drift or
undo an unchanged ejection:
agent-native eject diff <unit> --app <app>
agent-native eject restore <unit> --app <app>
agent-native eject restore <unit> --app <app> --applyRestore is hash-gated. It refuses to remove locally edited files or reverse changed imports and prints their diff instead. Keep an edited ejection as app-owned code, or reconcile those edits before restoring it.
Use the source that matches the installed package version:
pnpm action docs-search --query "<component or feature>"
pnpm action source-search --query "<component or symbol>"
rg -n "<component or symbol>" node_modules/@agent-native/toolkit/src
rg -n "<component or symbol>" node_modules/@agent-native/core/corpusnode_modules/@agent-native/toolkit/src/ for selective UI adoption.node_modules/@agent-native/core/corpus/core/ and
node_modules/@agent-native/core/corpus/templates/.agent-native eject so the
package manifest selects the complete source closure and rewrites imports.
Manual inspection is still useful for deciding whether to configure,
compose, eject, or propose a shared seam.Do not manually guess at sibling dependencies. The ejection manifest owns the required file closure and keeps protected contracts on public package imports.
UI ownership may change; product contracts should not:
defineAction actions and call them through
useActionQuery, useActionMutation, or another named client helper.app/design-system.ts, its local UI adapters,
and domain UI. Use Toolkit features for repeated workspace behavior; eject
only the unit being customized.AgentChatSurface, thread state, and chat transport in
Core. Compose or eject Toolkit presentation such as chat-history UI around it.packages/shared only when multiple workspace apps use it.agent-native.ejections.json with the app-owned files and rewrites.eject diff to
distinguish recorded output from subsequent local edits.node_modules/@agent-native/*/src at runtime.pnpm.overrides, patches, or resolutions for Agent Native packages.agent-native-docs — version-matched docs and source lookupagent-native-toolkit — shared-vs-app-owned architecture boundaryself-modifying-code — safe app source editsupgrade-agent-native — supported package upgrade pathadding-a-feature — UI/action/instructions/application-state parityc1ee18b
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.