# UI package agent guide `@colineapp/ui` is the public React component and bridge-provider package for tier-2 Coline Apps. It is the app author's UI layer; it is not the platform's internal component library. ## Required app setup ```tsx import { createRoot } from "react-dom/client"; import { Button, ColineAppProvider, useColine, useColineQuery, } from "@colineapp/ui"; import "@colineapp/ui/styles.css"; function Home() { const coline = useColine(); const items = useColineQuery( (capabilities) => capabilities.files.list({ limit: 100 }), [], ); return ; } const root = document.getElementById("root"); if (root) { createRoot(root).render( , ); } ``` The package requires React 19 and ReactDOM 19 as peer dependencies. The scaffold installs them for app authors. `ColineAppProvider` is mandatory before using `useColine`, `useColineContext`, `useColineQuery`, or `useColorScheme`; it intentionally renders nothing until the bridge connects. ## On a Coline Site A site's page (`surfaces.site.entry`) has no Coline host. Wrap it in `ColineSiteProvider` (follows the visitor's light/dark preference; pass `theme="light"` or `"dark"` to fix one), import `@colineapp/ui/styles.css`, and import `@colineapp/ui/theme.css` after `tailwindcss` in the site's CSS so `bg-card`, `text-muted-foreground`, `border-border` and `dark:` match the components. Build every control from these components; don't hand-roll buttons, inputs or cards. A site looks like Coline. Its one design choice is `accent` on `ColineSiteProvider` (sets `--action` on the root, lifted for dark mode unless `{ light, dark }` is passed). Everything else stays Coline's: no className or CSS that changes a component's colors, borders, radius, padding or fonts, no custom fonts or palettes, `Tabs` / `SegmentedControl` for navigation. `coline-app check` warns about each of these (`packages/create-coline-app/src/site-design.ts`). Keep the rules in this file, the site template's AGENTS.md, the docs' `sites/design` page and `apps/docs/src/lib/agents.ts` saying the same thing. Workspace-only, unavailable on sites: `ColineAppProvider`, `useColine`, `useColineContext`, `useColineQuery`, `useColorScheme`, `useToast`, `FilePreview`, `FileDropzone`, `SaveAsButton`, `useFilePicker`, `ConnectButton`. Sites read data with `@colineapp/sdk/site/react` (`createSiteHooks()`) and upload with `useUpload`. ## Data and sandbox rules - All app data goes through the injected `coline.*` capability client. - Do not use `fetch`, localStorage, cookies, direct API routes, or credentials in a sandboxed app. Network access belongs behind `coline.net.fetch` and the manifest allowlist. - `useColineQuery(loader, deps)` is a small loading/error/refetch helper, not a cache. Keep loaders bounded and put stable values in `deps`. - Use host theme tokens and the exported components. Do not hardcode light-only colors or invent a second provider. ## Component contract The public barrel exports the provider/hooks plus accessible components such as `Button`, `Card`, `Input`, `Textarea`, `Badge`, `Dialog`, `Select`, `Checkbox`, `Switch`, `Tabs`, `Table`, `Skeleton`, and `Tooltip`. Check the component source and declaration output before documenting a new prop. The CLI bundles `main.tsx`, installed client dependencies, and imported CSS. Coline rebuilds the uploaded artifact; the sandbox does not install packages. Browser-compatible npm dependencies can be added to the app package. ## Verification and release - Run `pnpm --filter @colineapp/ui typecheck` after component/provider changes. - Keep CSS export and component export changes together. - Preserve React peer dependency ranges and the `./styles.css` export. - Update README examples and the scaffold skill when an app-facing contract changes. The generated app must be able to use the documented API after a clean `npm install`. ## SDK 0.4 / CLI 2.4 workflow Run `coline-app check` before pushing: it checks types, the manifest, hosted logic, and the React bundle without uploading. `dev --internal` updates one development version; install it in the workspace and reload after changes. The CLI bundles from the app's installed dependencies and preserves imported CSS and inline assets. CLI 2.5 compiles app-specific Tailwind v4 and ordinary CSS automatically. Import UI styles, then app.css; use complete class names. Local `preview` uses the public test workspace and sandbox bridge, requires no credentials, and can capture light/dark/mobile/error states with `--screenshots `. The starter includes a React home and editor, tree mobile fallback, and a tool. Use `coline.tools.invoke` or `actions.invokeTool` to run the same declared tool from UI that Kairo runs. Save with `expectedVersion` to detect concurrent edits. Homes/editors can write within grants; previews and server render handlers cannot. `createTestWorkspace(app).client()` tests the interactive contract and `grantedPermissions` simulates revoked consent. New `tasks`, `calendar`, `messages`, and `references` capabilities require their explicit manifest permissions and retain the invoking user's workspace access. Use `files.list({ scope: "workspace" })` for shared files; document writes stay with the owning app. Collections are install-private. A native mobile React runtime is separate work; Coline Code builds and publishes apps (see `docs/sdk/full-stack.md`). `src/live-collection.ts` wraps the SDK's canonical live-record implementation. Keep state/conflict/sync logic in the SDK; React owns only subscriptions and lifecycle. Inline serializable query objects must not restart the view on each render. React Strict Mode cleanup/start must remain supported. Never infer record permission from optimistic state or broadcast private fields to an install room. ## UI 0.4.1 defaults Use `Tabs` / `TabsList` / `TabsTrigger` / `TabsContent` for app views. The raised sliding selection and content transition are automatic. Do not recreate tab buttons or choose the opt-in line variant for standard Coline navigation. Use `FilterMenu` for value filters, and `DropdownMenu` for actions. Both use the canonical Coline menu surface and highlight. `pnpm check:parity` enforces the vendored dropdown implementation; `pnpm sync:platform` refreshes it. Keep animation CSS in the package, respect reduced motion, and verify controls in a portalled dialog as well as on the page. A form submit button needs explicit `type="submit"`. Do not restyle shared controls with app-specific CSS. The menu parity sync includes `menu-item-styles.ts`, the shared class definition used by dropdown items. Keep this dependency in the sync list when canonical controls extract helpers; a public package build must work in a fresh checkout. The stylesheet includes the Latin Geist variable font and its SIL Open Font License in `dist/fonts`. The CLI embeds the font in the app bundle, so sandbox text uses Coline typography without remote font requests. Other scripts use the system fallback. Keep font assets and their license in release tarballs. ## UI 0.6 contract - Components consume host tokens only. Status and chart colors come from the sandbox bridge (`--status-*`, `--action`, `--chart-*`); never hard-code hex or raw Tailwind palette colors. - Motion goes through `lib/motion.ts` (`transitions.enter|quick|indicator|spring`, `staggerDelay`) and every animation respects `useReducedMotion`. - After changing components or styles: `pnpm --filter @colineapp/ui typecheck`, `pnpm --filter @colineapp/ui build:css`, `node scripts/sync-sandbox-styles.mjs` (regenerates `apps/web/src/lib/apps/sandbox-styles.generated.ts`), and `pnpm --filter @colineapp/ui check:parity`. - Re-scaffold every create-coline-app template and run `coline-app check`; the templates are the kit's real consumers.