# SDK package agent guide This package is the public Coline App SDK. Treat its exported TypeScript types, tests, and README as the source of truth for app authors. Do not use private `apps/web` code or first-party apps to invent public API behavior. ## Public entry points - `@colineapp/sdk/v2` is the current app-authoring API: `defineApp`, `defineTool`, `defineFileType`, `defineCommand`, `ui`, `actions`, manifest schemas, capability types, and hosted protocol helpers. - `@colineapp/sdk/testing` provides `createTestWorkspace`, the in-memory capability fake used by app tests. - `@colineapp/sdk` is the legacy v1 surface. Do not use it for new apps. ## Contract map - `src/define/` extracts and validates an app definition. - `src/manifest/` defines the consented manifest: permissions, surfaces, file types, tools, hosting, triggers, and commands. - `src/capabilities/types.ts` is the transport-neutral `coline.*` contract. - `src/tree/tree.ts` is the tree UI builder API used by hosted handlers and Kairo cards. `src/tree/chat-card.ts` defines the stricter chat subset. - `src/testing/` must stay behaviorally aligned with the capability types. ## App-authoring rules ```ts import { z } from "zod/v4"; import { defineApp, defineTool, ui } from "@colineapp/sdk/v2"; const createThing = defineTool({ name: "things.create_thing", description: "Create a thing.", input: z.object({ title: z.string().min(1) }), effect: "write", execute: async (input) => ({ output: { title: input.title }, card: ui.text(`Created ${input.title}.`), }), }); ``` - Tool names are app-key-prefixed (`app-key.operation`). - Validate every tool input with Zod. - `effect` is an enforced capability ceiling: reads are `read`, mutations are `write`, destructive actions are `destructive`, and external side effects are `external`. - Request the minimum manifest permissions. A tool declaration does not grant a capability by itself. - Tree handlers return `ui.*` nodes. React surfaces use `@colineapp/ui`; the SDK does not provide React components. - App records are envelopes: `{ id, appId, installId, collection, createdBy, createdAt, updatedAt, data }`. - Collection queries support top-level equality/comparison/contains `where`, `orderBy`, `order`, `limit`, and `cursor`. Keep the fake and backend aligned. ## Testing and changes - Test tools with `createTestWorkspace(app).invokeTool(...)`. - Assert cards with the chat-card validator and state with `workspace.files`, `workspace.state`, or collection results. - Run focused checks from the repository root: `pnpm --filter @colineapp/sdk typecheck` and `pnpm --filter @colineapp/sdk test`. - When changing a public type, update the closest unit test and README example in the same change. Keep v2 behavior transport-neutral. - Never add a second capability client or a second tree schema. Extend the canonical types and fake together. ## Release hygiene The package ships `dist/` plus this guide. Update the package version and generated artifacts through the repository release process; never hand-edit a declaration file to hide a type failure. ## Shared workspace capabilities Tasks, calendar events, messages/comments, and references use canonical workspace objects with explicit domain grants and invoking-user ACLs. App records remain install-private; share files/references instead of copying work between apps. `workspace.client()` tests interactive writes; preview/server rendering stays read-only. ## Live records Records now carry `version` and `access`. Use `createLiveCollection` for optimistic views; direct writes should pass `expectedVersion`. Collection `sync` returns a bounded authorized snapshot or null rows when its durable revision is unchanged. Do not infer permission from cached data: the host checks every operation. Record access is enforced in the fake as well as the host. Use `clientAs(userId)` with `createTestWorkspace(app, { members: [...] })` for multiple-actor tests. See `docs/sdk/live-data.md` in the product repo and the package README for usage.