/** * Prints the generated tables of docs.coline.app/sdk/reference from the * SDK's own contract: permissions, capability operations, the operations * site visitors may call, and the chat card node allowlist. Run it when the * contract changes and paste the output over the tables in * apps/docs/content/docs/sdk/reference.mdx: * * pnpm --filter @colineapp/sdk exec tsx scripts/docs-reference.ts */ import { readFileSync } from "node:fs"; import { APP_CAPABILITY_OPERATIONS, VISITOR_CAPABILITY_OPERATIONS } from "../src/capabilities/operations"; import { APP_PERMISSION_V2_DESCRIPTIONS, APP_PERMISSIONS_V2 } from "../src/manifest/permissions"; import { CHAT_CARD_ALLOWED_NODE_TYPES } from "../src/tree/chat-card"; const pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")) as { version: string }; const lines: string[] = []; lines.push(`{/* Generated from @colineapp/sdk ${pkg.version} by packages/sdk/scripts/docs-reference.ts */}`, ""); lines.push("## Permissions", ""); lines.push( "Declared in the manifest, approved by a workspace admin at install, and shown to people with exactly this wording. Every capability call needs its permission declared and granted.", "", ); lines.push("| Permission | Shown to people as |", "| --- | --- |"); for (const permission of APP_PERMISSIONS_V2) { lines.push(`| \`${permission}\` | ${APP_PERMISSION_V2_DESCRIPTIONS[permission]} |`); } lines.push("", "## Capability operations", ""); lines.push( "Every `coline.*` call maps to one operation with one required permission and one mutation class. A tool's effect must allow the operation's class, or the call fails with `effect_ceiling_exceeded`.", "", ); lines.push("| Operation | Mutation | Permission | Site visitors |", "| --- | --- | --- | --- |"); const visitor = new Set(VISITOR_CAPABILITY_OPERATIONS); for (const [operation, spec] of Object.entries(APP_CAPABILITY_OPERATIONS).sort(([a], [b]) => a.localeCompare(b))) { const { permission, mutation } = spec as { permission: string | null; mutation: string }; lines.push(`| \`${operation}\` | ${mutation} | ${permission ? `\`${permission}\`` : "None"} | ${visitor.has(operation) ? "Yes" : ""} |`); } lines.push("", "## Chat cards", ""); lines.push( "Tool result cards and inline file surfaces render inside conversations, so they accept this subset of tree nodes. Home, preview and editor surfaces can use every node.", "", ); lines.push([...CHAT_CARD_ALLOWED_NODE_TYPES].sort().map((type) => `\`${type}\``).join(", ")); console.log(lines.join("\n"));