{"owner":"GitbookIO","repo":"gitbook","hasSkills":true,"totalSkillsCount":13,"totalTokensCount":6453,"categories":["anthropic-skill","root-instruction","claude-rule","plugin-manifest"],"hasMcp":false,"mcpConfig":null,"found":[".agents/skills/write-pr-description/SKILL.md","AGENTS.md","CLAUDE.md","packages/browser-types/README.md","packages/cache-tags/README.md","packages/colors/README.md","packages/embed/README.md","packages/expr/README.md","packages/fonts/README.md","packages/icons/README.md","packages/openapi-parser/README.md","packages/react-math/README.md","packages/react-openapi/README.md"],"skills":{".agents/skills/write-pr-description/SKILL.md":"---\nname: write-pr-description\ndescription: Write a concise, product-focused PR description from the changes and available discussion. Use when asked for a PR summary or description.\n---\n\n# Write a PR description\n\nRead the full branch diff and commit history against the PR's base branch, not just the latest commit. Use the PR discussion and linked issues for context when available. The PR's changes are the source of truth for what ships if an issue describes something different.\n\nWrite for contributors and reviewers who may not know the area. Lead with what changes, prefer user or product impact when supported, and include implementation details only when they help review. Keep the proposed changes short, using bullets only when useful.\n\nInclude relevant validation and screenshots when available. Do not claim checks passed unless they ran. Use only information appropriate for a public repository; do not copy private issue details or customer information into the description.\n\n## Template and changelog\n\nRead `.github/pull_request_template.md` immediately before writing. Preserve its required section names and order. Include `Proposed changes` and `Changelog`; omit `Demo` when there is nothing to show. Add optional `Context` before `Changelog` only when it meets the rule below.\n\nWrite a short changelog entry describing what shipped. Use `[Feature]` for user-facing additions or improvements, `[Fix]` for user-facing bug fixes, and `[Chore]` for internal maintenance. For features and fixes, say what users can do or what no longer goes wrong in plain words. Keep chores useful to teammates without inventing user impact. Remove unused examples and placeholders. Usually one entry is enough; use more only for distinct changes. The PR changelog does not replace any changeset required by `AGENTS.md`.\n\n## Optional context\n\nWrite `Proposed changes` and `Changelog` first. Add `Context` only when it tells someone unfamiliar with the area something material that the changelog does not. `Problem` names a concrete failure or limitation supported by the PR or discussion. `Outcome` names what this PR delivers at its actual scope. Omit the section if either field would repeat the changelog, describe only implementation, or guess at an impact.\n\n```markdown\n## Context\n\n**Problem:** <concrete failure or limitation>\n\n**Outcome:** <result delivered by this PR>\n```\n\nKeep each field to 1–2 short, non-technical sentences. Prefer user or product impact when supported. For infrastructure changes, explain the failure or limitation they caused. Do not invent an actor, customer segment, ownership, or impact, or force the change into a user story. Do not turn a preparatory change into a claim that the whole workflow is fixed. Keep the roles distinct: `Context` explains why this matters, `Changelog` says what shipped, and `Proposed changes` can explain implementation.\n\nExamples:\n\n- A dependency bump with no demonstrated user effect needs no `Context`.\n- If creating the first change request leaves the user on an empty screen, say that it now opens after creation. Leave the animation-listener details in `Proposed changes`.\n- If a PR indexes links for later checks, describe the indexing result. Do not claim every link has already been checked.\n\n## Writing pass\n\n- Use plain words and direct verbs: \"use\" instead of \"leverage\", \"help\" instead of \"facilitate\". Prefer active voice when the actor is known.\n- Name the concrete behavior instead of saying \"improves the experience\" or \"makes it more robust\". Support performance claims with measurements.\n- Cut filler, promotional language, and generic conclusions. If a sentence could fit almost any PR, make it specific or delete it.\n- Keep one idea per sentence and use consistent names. Remove redundant hedging without hiding real uncertainty.\n- Avoid \"not just X, but Y\", forced groups of three, em dashes, decorative emojis, and unnecessary bold text.\n\nReturn the description in a Markdown code block unless asked to update the PR. When asked to update it, apply the description with `gh pr edit` using a body file.\n","AGENTS.md":"# AGENTS Instructions\n\n## Commands\n\n```bash\nbun install          # Install dependencies\nbun dev              # Start dev server (all packages)\nbun run build        # Build all packages\nbun run lint         # Lint with Oxlint\nbun run format       # Format with Oxfmt (run after every change)\nbun run typecheck    # Type-check all packages\nbun run unit         # Run unit tests\n```\n\n## Development\n\nThe dev server proxies published GitBook sites locally. After `bun dev`, access any published site at:\n\n```\nhttp://localhost:3000/url/<published-gitbook-url>\n```\n\nExamples:\n- `http://localhost:3000/url/gitbook.com/docs`\n- `http://localhost:3000/url/open-source.gitbook.io/midjourney`\n\n## Architecture\n\n```\npackages/\n  gitbook/          # Main Next.js app\n    src/\n      app/          # Next.js App Router (sites/)\n      components/   # React components\n      lib/          # Server utilities, data fetching\n      intl/         # Internationalization (translations/)\n  openapi-parser/   # OpenAPI 3.0/3.1/Swagger parser\n  react-openapi/    # OpenAPI rendering components\n  react-contentkit/ # ContentKit component rendering\n  embed/            # Embeddable GitBook components\n  shared/           # Shared utilities\n  icons/            # Icon assets\n  fonts/            # Font assets\n  colors/           # Color tokens\n  expr/             # GitBook expression evaluator\n  cache-do/         # Cloudflare DO cache\n  cache-tags/       # Cache tag utilities\n```\n\n## Testing\n\n```bash\nbun run unit         # Unit tests via bun test (not vitest)\nbun run e2e          # Playwright e2e tests (requires built app)\n```\n\nRun a specific test file:\n```bash\ncd packages/gitbook && bun test src/lib/cache.test.ts\n```\n\n## Changesets\n\nAfter committing code changes, create a changeset for the affected package:\n\n```md\n---\n\"gitbook\": patch\n---\n\nProvide a short description of the change.\n```\n\nSave as `.changeset/<name>.md`, then commit it separately with message: `changeset`\n\n## Formatting\n\nLinting uses Oxlint and formatting uses Oxfmt. Always run `bun run format` before committing.\n\n## Comments\n\nComment to explain *why*, not *what* — the code already shows what it does. Keep comments short, ideally a single line. Avoid multi-line block comments that narrate mechanics a reader can follow from the code; they add noise and go stale. Reserve longer comments for genuinely non-obvious rationale: a subtle invariant, or a workaround and the reason it exists.\n","CLAUDE.md":"@AGENTS.md\n","packages/browser-types/README.md":"# `@gitbook/browser-types`\n\nTypescript types for the global variables available in a GitBook website. These types can be used by integrations embedding scripts.\n","packages/cache-tags/README.md":"# `@gitbook/cache-tags`\n\nUtility to generate cache tags for GitBook Open.","packages/colors/README.md":"# `@gitbook/colors`\n\nA set of default colors and transformation functions used throughout the GitBook Open and app.\n","packages/embed/README.md":"# GitBook Docs Embed (`@gitbook/embed`)\n\nEmbed your GitBook docs in your product or website.\n\nThe Docs Embed can contain three tabs:\n- **Assistant**: The [GitBook Assistant](https://gitbook.com/docs/publishing-documentation/gitbook-ai-assistant) - an AI-powered chat interface to help users find answers\n- **Search**: A search-focused surface for quickly finding pages and asking scoped questions\n- **Docs**: A browser for navigating your documentation site\n\nThe embed is set up automatically based on your site's configuration. You can optionally customize and override the configuration with custom actions, tools, suggested questions, [Authenticated Access](https://gitbook.com/docs/publishing-documentation/authenticated-access), and more. See the [Configuration](#configuration) section for all available options.\n\n# Usage\n\n## As a standalone script from your docs site\n\nAll GitBook docs sites include a script to easily add the Docs Embed as a widget on your website.\n\nThe script is served at `https://docs.company.com/~gitbook/embed/script.js`.\n\nYou can find the embed script from your docs site settings, or you can copy the following and replace `docs.company.com` with your docs site hostname.\n\n```html\n<script src=\"https://docs.company.com/~gitbook/embed/script.js\"></script>\n```\n\nThe script initializes the widget itself, so there is nothing to call. To pin the embed to one color\nscheme, put it on the script URL — it has to be known before the widget renders:\n\n```html\n<script src=\"https://docs.company.com/~gitbook/embed/script.js?theme=light\"></script>\n```\n\nTo authenticate the visitor, call `init` with their token. Keep tokens out of the script URL: it is\npublicly cacheable and ends up in server logs.\n\n```html\n<script src=\"https://docs.company.com/~gitbook/embed/script.js\"></script>\n<script>\nwindow.GitBook('init',\n    { siteURL: 'https://docs.company.com' },\n    { visitor: { token: 'your-jwt-token' } }\n);\n</script>\n```\n\nThe standalone script provides a global `GitBook` function. See the [API Reference](#api-reference) section for all available methods.\n\n### Example: Configuring the widget\n\n```javascript\nGitBook('configure', {\n    button: {\n        label: 'Ask',\n        icon: 'assistant' // 'assistant' | 'sparkle' | 'help' | 'book'\n    },\n    tabs: ['assistant', 'search', 'docs'],\n    defaultPage: '/getting-started',\n    actions: [\n        {\n            icon: 'circle-question',\n            label: 'Contact Support',\n            onClick: () => window.open('https://support.example.com', '_blank')\n        }\n    ],\n    greeting: { title: 'Welcome!', subtitle: 'How can I help?' },\n    assistantName: 'Support Assistant',\n    suggestions: ['What is GitBook?', 'How do I get started?'],\n    tools: [/* ... */],\n    closeButton: true,\n});\n```\n\nSee the [Configuration](#configuration) section for all available options.\n\n## As a package from NPM\n\nInstall the package: `npm install @gitbook/embed` and import it in your web application:\n\n```tsx\nimport { createGitBook } from '@gitbook/embed';\n\nconst gitbook = createGitBook({\n    siteURL: 'https://docs.company.com'\n});\n\n// Create an iframe and get its URL\nconst iframe = document.createElement('iframe');\niframe.src = gitbook.getFrameURL({\n    colorScheme: 'dark', // Optional: force the embed to render in dark mode\n    visitor: {\n        token: 'your-jwt-token', // Optional: for Adaptive Content or Authenticated Access\n        unsignedClaims: { // Optional: custom claims for dynamic expressions\n            userId: '123',\n            plan: 'premium'\n        }\n    }\n});\n\n// Create a frame client to communicate with the iframe\nconst frame = gitbook.createFrame(iframe);\n\n// Use the frame client methods\nframe.navigateToPage('/getting-started'); // Navigate to a page in the docs tab\nframe.navigateToAssistant(); // Switch to the assistant tab\nframe.postUserMessage('How do I get started?');\nframe.clearChat();\n\n// Configure the embed (see Configuration section for all options)\nframe.configure({\n    tabs: ['assistant', 'search', 'docs'],\n    defaultPage: '/getting-started',\n    actions: [\n        {\n            icon: 'circle-question',\n            label: 'Contact Support',\n            onClick: () => window.open('https://support.example.com', '_blank')\n        }\n    ],\n    greeting: { title: 'Welcome!', subtitle: 'How can I help?' },\n    assistantName: 'Support Assistant',\n    suggestions: ['What is GitBook?', 'How do I get started?'],\n    tools: [/* ... */],\n    closeButton: true\n});\n\n// Listen to events\nframe.on('close', () => {\n    console.log('Frame closed');\n});\n```\n\n## As React components\n\nAfter installing the NPM package, you can import prebuilt React components:\n\n```tsx\nimport { GitBookProvider, GitBookFrame } from '@gitbook/embed/react';\n\n<GitBookProvider siteURL=\"https://docs.company.com\">\n    <GitBookFrame\n        colorScheme=\"dark\"\n        visitor={{\n            token: 'your-jwt-token', // Optional: for Adaptive Content or Authenticated Access\n            unsignedClaims: { userId: '123' } // Optional: custom claims for dynamic expressions\n        }}\n        tabs={['assistant', 'search', 'docs']}\n        defaultPage=\"/getting-started\"\n        greeting={{ title: 'Welcome!', subtitle: 'How can I help?' }}\n        assistantName=\"Support Assistant\"\n        suggestions={['What is GitBook?', 'How do I get started?']}\n        actions={[\n            {\n                icon: 'circle-question',\n                label: 'Contact Support',\n                onClick: () => window.open('https://support.example.com', '_blank')\n            }\n        ]}\n        tools={[/* ... */]}\n        closeButton\n    />\n</GitBookProvider>\n```\n\nYou can also use the `useGitBook` hook to access the client:\n\n```tsx\nimport { useGitBook } from '@gitbook/embed/react';\n\nfunction MyComponent() {\n    const gitbook = useGitBook();\n    const frameURL = gitbook.getFrameURL({ colorScheme: 'dark', visitor: { token: '...' } });\n    // ...\n}\n```\n\n# API Reference\n\n## Method Comparison\n\n| Method | Standalone Script | NPM Package | React Components |\n|--------|------------------|-------------|------------------|\n| **Initialize** | `GitBook('init', options, frameOptions)` | `createGitBook(options)` | `<GitBookProvider siteURL=\"...\">` |\n| **Get frame URL** | ❌ (handled internally) | `client.getFrameURL(options)` | `useGitBook().getFrameURL(options)` |\n| **Create frame client** | ❌ (handled internally) | `client.createFrame(iframe)` | `useGitBook().createFrame(iframe)` |\n| **Show/Hide widget** | `GitBook('show')` / `GitBook('hide')` | ❌ | ❌ |\n| **Open/Close window** | `GitBook('open')` / `GitBook('close')` / `GitBook('toggle')` | ❌ | ❌ |\n| **Navigate to page** | `GitBook('navigateToPage', path)` | `frame.navigateToPage(path)` | Via frame client |\n| **Navigate to assistant** | `GitBook('navigateToAssistant')` | `frame.navigateToAssistant()` | Via frame client |\n| **Post message** | `GitBook('postUserMessage', message)` | `frame.postUserMessage(message)` | Via frame client |\n| **Clear chat** | `GitBook('clearChat')` | `frame.clearChat()` | Via frame client |\n| **Configure** | `GitBook('configure', settings)` | `frame.configure(settings)` | Props on `<GitBookFrame>` |\n| **Event listeners** | ❌ | `frame.on(event, listener)` | Via frame client |\n| **Unload** | `GitBook('unload')` | ❌ | ❌ |\n\n## Method Signatures\n\n### Standalone Script\n\n- `GitBook('init', options: { siteURL: string }, frameOptions?: { colorScheme?: 'light' | 'dark', visitor?: {...} })` - Initialize widget\n- `GitBook('show')` - Show widget button\n- `GitBook('hide')` - Hide widget button\n- `GitBook('open')` - Open widget window\n- `GitBook('close')` - Close widget window\n- `GitBook('toggle')` - Toggle widget window\n- `GitBook('navigateToPage', path: string)` - Navigate to page (accepts the page path within the site, an absolute path, or the full published URL; resolves pages in any space/section)\n- `GitBook('navigateToAssistant')` - Navigate to assistant tab\n- `GitBook('postUserMessage', message: string)` - Post message to chat\n- `GitBook('clearChat')` - Clear chat history\n- `GitBook('configure', settings: {...})` - Configure widget\n- `GitBook('unload')` - Unload widget\n\n### NPM Package\n\n**Client Factory:**\n- `createGitBook(options: { siteURL: string })` → `GitBookClient`\n- `client.getFrameURL(options?: { colorScheme?: 'light' | 'dark', visitor?: {...} })` → `string`\n- `client.createFrame(iframe: HTMLIFrameElement)` → `GitBookFrameClient`\n\n**Frame Client:**\n- `frame.navigateToPage(path: string)` → `void` (accepts the page path within the site, an absolute path, or the full published URL; resolves pages in any space/section)\n- `frame.navigateToAssistant()` → `void`\n- `frame.postUserMessage(message: string)` → `void`\n- `frame.clearChat()` → `void`\n- `frame.configure(settings: Partial<GitBookEmbeddableConfiguration>)` → `void`\n- `frame.on(event: string, listener: Function)` → `() => void` (unsubscribe)\n\n### React Components\n\n**Components:**\n- `<GitBookProvider siteURL: string>` - Provider component\n- `<GitBookFrame {...props}>` - Frame component (accepts all config options as props)\n\n**Hooks:**\n- `useGitBook()` → `GitBookClient` (must be used within `<GitBookProvider>`)\n\n# Configuration\n\nConfiguration options are available across usage methods as follows:\n- **Standalone script**: via `GitBook('configure', {...})`\n- **NPM package**: via `frame.configure({...})`\n- **React components**: via props on `<GitBookFrame>`\n\n### `tabs`\n\nAvailable in: Standalone script, NPM package, React components\n\nOverride which tabs are displayed. Defaults to your site's configuration.\n\n- **Type**: `('assistant' | 'search' | 'docs')[]`\n\n```javascript\ntabs: ['assistant', 'search', 'docs']\n```\n\n### `defaultTab`\n\nAvailable in: Standalone script, NPM package, React components\n\nThe tab the embed opens on. Without it, the embed opens on `defaultPage` if set, otherwise on the assistant (or the docs when the assistant isn't available). The tab must be one of the enabled `tabs`.\n\n- **Type**: `'assistant' | 'search' | 'docs'`\n\n```javascript\ntabs: ['assistant', 'search', 'docs'],\ndefaultTab: 'search'\n```\n\n`defaultTab` and `defaultPage` apply when the embed first loads: the standalone widget keeps its place when it is closed and reopened. To move it later, use `navigateToPage` or `navigateToAssistant`.\n\n### `defaultPage`\n\nAvailable in: Standalone script, NPM package, React components\n\nThe page the docs tab opens on, in place of your site's home page. Accepts the same references as `navigateToPage`: the page's path within the site, an absolute path, or its full published URL. Unless `defaultTab` says otherwise, the embed opens on this page.\n\n- **Type**: `string`\n\n```javascript\ndefaultPage: '/getting-started/quickstart'\n```\n\n### `closeButton`\n\nAvailable in: Standalone script, NPM package, React components\n\nDisplay a close (`x`) button in the embed sidebar.\n\n- **Type**: `boolean`\n- **Default**: `false`\n\n```javascript\ncloseButton: true\n```\n\nBehavior:\n- When clicked, the embed sends a `close` event to the parent page.\n- In the standalone script, this event is handled automatically and the widget closes.\n- In custom iframe integrations (NPM package), you must listen for the `close` event and decide how to hide/collapse your UI.\n- In React, this works automatically when using the standard widget flow. If you build custom frame wiring, handle `close` the same way as the NPM package.\n\nNPM package example:\n\n```typescript\nconst frame = gitbook.createFrame(iframe);\n\nframe.configure({\n    closeButton: true\n});\n\nconst unsubscribe = frame.on('close', () => {\n    // Hide your modal/drawer/container\n    container.classList.add('hidden');\n});\n```\n\nNotes:\n- The close button is rendered in the same sidebar area as tabs/actions.\n- If your UI hides that sidebar or doesn't render it, the button will not be visible.\n\n### `trademark`\n\nAvailable in: Standalone script, NPM package, React components\n\nDisplay GitBook branding in the embed. Defaults to true.\n\n- **Type**: `boolean`\n- **Default**: `true`\n\n```javascript\ntrademark: true\n```\n\n### `actions`\n\nAvailable in: Standalone script, NPM package, React components\n\nCustom action buttons rendered in the sidebar alongside tabs. Each action button triggers a callback when clicked.\n\n**Note**: This prop was previously named `buttons`. Use `actions` instead, it has the same functionality.\n\n- **Type**: `GitBookEmbeddableActionDefinition[]`\n- **Properties**:\n  - `icon`: `string` - Icon name. Any [FontAwesome icon](https://fontawesome.com/search) is supported. (e.g., `'rocket'`, `'comments'`, `'user-circle'`, ...)\n  - `label`: `string` - Button label text\n  - `onClick`: `() => void | Promise<void>` - Callback function when clicked\n\n```javascript\nactions: [\n    {\n        icon: 'comments',\n        label: 'Contact Support',\n        onClick: () => window.open('https://support.example.com', '_blank')\n    },\n    {\n        icon: 'rocket',\n        label: 'Get started',\n        onClick: () => {\n            GitBook('navigateToPage', '/getting-started');\n        }\n    }\n]\n```\n\n### `greeting`\n\nAvailable in: Standalone script, NPM package, React components\n\nWelcome message displayed in the [Assistant](https://gitbook.com/docs/publishing-documentation/gitbook-ai-assistant) tab.\n\n- **Type**: `{ title: string, subtitle: string }`\n\n```javascript\ngreeting: {\n    title: 'Welcome!',\n    subtitle: 'How can I help you today?'\n}\n```\n\n### `assistantName`\n\nAvailable in: Standalone script, NPM package, React components\n\nOverride the assistant name displayed in the chat header and assistant entry points (for example, sidebar tabs and action labels). This name will be limited to 32 characters to prevent text overflow.\n\n- **Type**: `string`\n\n```javascript\nassistantName: 'Support Assistant'\n```\n\n### `suggestions`\n\nAvailable in: Standalone script, NPM package, React components\n\nSuggested questions displayed in the [Assistant](https://gitbook.com/docs/publishing-documentation/gitbook-ai-assistant) welcome screen.\n\n- **Type**: `string[]`\n\n```javascript\nsuggestions: [\n    'What is GitBook?',\n    'How do I get started?',\n    'What can you do?'\n]\n```\n\n### `tools`\n\nAvailable in: Standalone script, NPM package, React components\n\nCustom AI tools to extend the [Assistant](https://gitbook.com/docs/publishing-documentation/gitbook-ai-assistant). Tools allow the assistant to execute functions and integrate with your own systems.\n\n**Note**: In addition to custom tools, the Assistant will always have access to any [MCP servers you define](https://gitbook.com/docs/publishing-documentation/gitbook-ai-assistant#extend-gitbook-assistant-with-mcp-servers) in your site's AI settings.\n\n- **Type**: `GitBookToolDefinition[]`\n- **Properties**:\n  - `name`: `string` - Unique tool identifier\n  - `description`: `string` - Description of what the tool does (used by the AI to decide when and how to use it).\n  - `inputSchema`: `object` - JSON schema defining the tool's input parameters\n  - `execute`: `(input: object) => Promise<{ output: any, summary: string }>` - Async function that executes the tool.\n    - `output`: The result of the tool execution, provided to the AI to continue working with. Not shown to the user.\n    - `summary`: The visual summary of the tool execution, shown in the user's chat window.\n  - `confirmation`: `{ icon?: string, label: string }` (optional) - Confirmation button shown before execution, useful for actions that require the user's express approval.\n\n```javascript\ntools: [\n    {\n        name: 'get_user_info',\n        description: 'Get information about the current user',\n        inputSchema: {\n            type: 'object',\n            properties: {\n                userId: { \n                    type: 'string', \n                    description: 'The user ID to look up' \n                }\n            },\n            required: ['userId']\n        },\n        execute: async (input) => {\n            const user = await fetch(`/api/users/${input.userId}`).then(r => r.json());\n            return {\n                output: { name: user.name, plan: user.plan },\n                summary: `Retrieved info for user ${user.name}`\n            };\n        }\n    },\n    {\n        name: 'create_ticket',\n        description: 'Create a support ticket',\n        confirmation: {\n            icon: 'circle-question',\n            label: 'Create support ticket?'\n        },\n        inputSchema: {\n            type: 'object',\n            properties: {\n                subject: { type: 'string' },\n                description: { type: 'string' }\n            },\n            required: ['subject', 'description']\n        },\n        execute: async (input) => {\n            const ticket = await fetch('/api/tickets', {\n                method: 'POST',\n                body: JSON.stringify(input)\n            }).then(r => r.json());\n            return {\n                output: { ticketId: ticket.id },\n                summary: `Created ticket #${ticket.id}`\n            };\n        }\n    }\n]\n```\n\n### `visitor` (Authenticated Access)\n\nAvailable in: Standalone script (via `init`), NPM package (via `getFrameURL()`), React components (as prop)\n\n[Authenticated Access](https://gitbook.com/docs/publishing-documentation/authenticated-access) options passed when creating the frame URL. Used for [Adaptive Content](https://gitbook.com/docs/publishing-documentation/adaptive-content) and [Authenticated Access](https://gitbook.com/docs/publishing-documentation/authenticated-access).\n\n**Note**: This is not a configuration option but rather a parameter when initializing the frame or creating the frame URL.\n\n**Standalone script**: Pass as the second argument to `GitBook('init', options, frameOptions)`\n**NPM package**: Pass to `getFrameURL({ visitor: {...} })`\n**React components**: Pass as the `visitor` prop on `<GitBookFrame>`\n\n- **Type**: `{ token?: string, unsignedClaims?: Record<string, unknown> }`\n- **Properties**:\n  - `token`: `string` (optional) - Signed JWT token for [Adaptive Content](https://gitbook.com/docs/publishing-documentation/adaptive-content) or [Authenticated Access](https://gitbook.com/docs/publishing-documentation/authenticated-access)\n  - `unsignedClaims`: `Record<string, unknown>` (optional) - Unsigned claims that can be used in dynamic expressions via `visitor.claims.unsigned.<claim-name>`\n\n```javascript\nvisitor: {\n    token: 'your-jwt-token',\n    unsignedClaims: {\n        userId: '123',\n        plan: 'premium',\n        role: 'admin'\n    }\n}\n```\n\n### `colorScheme`\n\nAvailable in: Standalone script (via `init`), NPM package (via `getFrameURL()`), React components (as prop)\n\nOverride the embed's color scheme.\n\nWhen omitted, the standalone widget follows the page it is embedded in — its `color-scheme`, falling back to the visitor's OS preference only when that page declares support for both. With the NPM package or the React components you own the iframe, so the embed follows the visitor's OS preference unless you pass this.\n\n**Note**: This is not a configuration option but rather a parameter when initializing the frame or creating the frame URL.\n\n**Standalone script**: `?theme=light` on the script URL\n**NPM package**: Pass to `getFrameURL({ colorScheme: 'dark' })`\n**React components**: Pass as the `colorScheme` prop on `<GitBookFrame>`\n\n- **Type**: `'light' | 'dark'`\n\n```html\n<script src=\"https://docs.company.com/~gitbook/embed/script.js?theme=light\"></script>\n```\n\nSites published with a single theme always render in that theme, so `colorScheme` has no effect on\nthem — the widget follows the site instead, to keep its chrome and the docs inside it consistent.\n\n### `button`\n\nAvailable in: Standalone script only\n\nConfigure the widget button for the standalone script. This option is not available when using the NPM package or React components, since they can be customized completely.\n\n- **Type**: `{ label: string, icon: 'assistant' | 'sparkle' | 'help' | 'book' }`\n- **Properties**:\n  - `label`: `string` - Button label text\n  - `icon`: `'assistant' | 'sparkle' | 'help' | 'book'` - Icon displayed on the button. Choose from one of 4 presets.\n\n```javascript\nbutton: {\n    label: 'Ask',\n    icon: 'assistant'\n}\n```\n","packages/expr/README.md":"# `@gitbook/expr`\n\nSafely evaluate & parse user-defined GitBook expressions.\n","packages/fonts/README.md":"# `@gitbook/fonts`\n\nUtilities to lookup default fonts supported by GitBook.\n","packages/icons/README.md":"# `@gitbook/icons`\n\nIcon sets useed in GitBook content.\n\n## Usage\n\n```tsx\nimport { Icon } from '@gitbook/icons';\n\n<Icon name=\"x\" className={'size-5'} />;\n```\n","packages/openapi-parser/README.md":"# `@gitbook/openapi-parser`\n\nModern OpenAPI parser written in TypeScript with support for OpenAPI 3.1, OpenAPI 3.0 and Swagger 2.0.","packages/react-math/README.md":"# `@gitbook/react-math`\n\nReact component to render a Math formula. It uses KaTeX when possible and fallbacks to MathJaX if needed.\n","packages/react-openapi/README.md":"# `@gitbook/react-openapi`\n\nStyle-less React components to render OpenAPI operation blocks.\n"},"files":{".agents/skills/write-pr-description/SKILL.md":"---\nname: write-pr-description\ndescription: Write a concise, product-focused PR description from the changes and available discussion. Use when asked for a PR summary or description.\n---\n\n# Write a PR description\n\nRead the full branch diff and commit history against the PR's base branch, not just the latest commit. Use the PR discussion and linked issues for context when available. The PR's changes are the source of truth for what ships if an issue describes something different.\n\nWrite for contributors and reviewers who may not know the area. Lead with what changes, prefer user or product impact when supported, and include implementation details only when they help review. Keep the proposed changes short, using bullets only when useful.\n\nInclude relevant validation and screenshots when available. Do not claim checks passed unless they ran. Use only information appropriate for a public repository; do not copy private issue details or customer information into the description.\n\n## Template and changelog\n\nRead `.github/pull_request_template.md` immediately before writing. Preserve its required section names and order. Include `Proposed changes` and `Changelog`; omit `Demo` when there is nothing to show. Add optional `Context` before `Changelog` only when it meets the rule below.\n\nWrite a short changelog entry describing what shipped. Use `[Feature]` for user-facing additions or improvements, `[Fix]` for user-facing bug fixes, and `[Chore]` for internal maintenance. For features and fixes, say what users can do or what no longer goes wrong in plain words. Keep chores useful to teammates without inventing user impact. Remove unused examples and placeholders. Usually one entry is enough; use more only for distinct changes. The PR changelog does not replace any changeset required by `AGENTS.md`.\n\n## Optional context\n\nWrite `Proposed changes` and `Changelog` first. Add `Context` only when it tells someone unfamiliar with the area something material that the changelog does not. `Problem` names a concrete failure or limitation supported by the PR or discussion. `Outcome` names what this PR delivers at its actual scope. Omit the section if either field would repeat the changelog, describe only implementation, or guess at an impact.\n\n```markdown\n## Context\n\n**Problem:** <concrete failure or limitation>\n\n**Outcome:** <result delivered by this PR>\n```\n\nKeep each field to 1–2 short, non-technical sentences. Prefer user or product impact when supported. For infrastructure changes, explain the failure or limitation they caused. Do not invent an actor, customer segment, ownership, or impact, or force the change into a user story. Do not turn a preparatory change into a claim that the whole workflow is fixed. Keep the roles distinct: `Context` explains why this matters, `Changelog` says what shipped, and `Proposed changes` can explain implementation.\n\nExamples:\n\n- A dependency bump with no demonstrated user effect needs no `Context`.\n- If creating the first change request leaves the user on an empty screen, say that it now opens after creation. Leave the animation-listener details in `Proposed changes`.\n- If a PR indexes links for later checks, describe the indexing result. Do not claim every link has already been checked.\n\n## Writing pass\n\n- Use plain words and direct verbs: \"use\" instead of \"leverage\", \"help\" instead of \"facilitate\". Prefer active voice when the actor is known.\n- Name the concrete behavior instead of saying \"improves the experience\" or \"makes it more robust\". Support performance claims with measurements.\n- Cut filler, promotional language, and generic conclusions. If a sentence could fit almost any PR, make it specific or delete it.\n- Keep one idea per sentence and use consistent names. Remove redundant hedging without hiding real uncertainty.\n- Avoid \"not just X, but Y\", forced groups of three, em dashes, decorative emojis, and unnecessary bold text.\n\nReturn the description in a Markdown code block unless asked to update the PR. When asked to update it, apply the description with `gh pr edit` using a body file.\n","AGENTS.md":"# AGENTS Instructions\n\n## Commands\n\n```bash\nbun install          # Install dependencies\nbun dev              # Start dev server (all packages)\nbun run build        # Build all packages\nbun run lint         # Lint with Oxlint\nbun run format       # Format with Oxfmt (run after every change)\nbun run typecheck    # Type-check all packages\nbun run unit         # Run unit tests\n```\n\n## Development\n\nThe dev server proxies published GitBook sites locally. After `bun dev`, access any published site at:\n\n```\nhttp://localhost:3000/url/<published-gitbook-url>\n```\n\nExamples:\n- `http://localhost:3000/url/gitbook.com/docs`\n- `http://localhost:3000/url/open-source.gitbook.io/midjourney`\n\n## Architecture\n\n```\npackages/\n  gitbook/          # Main Next.js app\n    src/\n      app/          # Next.js App Router (sites/)\n      components/   # React components\n      lib/          # Server utilities, data fetching\n      intl/         # Internationalization (translations/)\n  openapi-parser/   # OpenAPI 3.0/3.1/Swagger parser\n  react-openapi/    # OpenAPI rendering components\n  react-contentkit/ # ContentKit component rendering\n  embed/            # Embeddable GitBook components\n  shared/           # Shared utilities\n  icons/            # Icon assets\n  fonts/            # Font assets\n  colors/           # Color tokens\n  expr/             # GitBook expression evaluator\n  cache-do/         # Cloudflare DO cache\n  cache-tags/       # Cache tag utilities\n```\n\n## Testing\n\n```bash\nbun run unit         # Unit tests via bun test (not vitest)\nbun run e2e          # Playwright e2e tests (requires built app)\n```\n\nRun a specific test file:\n```bash\ncd packages/gitbook && bun test src/lib/cache.test.ts\n```\n\n## Changesets\n\nAfter committing code changes, create a changeset for the affected package:\n\n```md\n---\n\"gitbook\": patch\n---\n\nProvide a short description of the change.\n```\n\nSave as `.changeset/<name>.md`, then commit it separately with message: `changeset`\n\n## Formatting\n\nLinting uses Oxlint and formatting uses Oxfmt. Always run `bun run format` before committing.\n\n## Comments\n\nComment to explain *why*, not *what* — the code already shows what it does. Keep comments short, ideally a single line. Avoid multi-line block comments that narrate mechanics a reader can follow from the code; they add noise and go stale. Reserve longer comments for genuinely non-obvious rationale: a subtle invariant, or a workaround and the reason it exists.\n","CLAUDE.md":"@AGENTS.md\n","packages/browser-types/README.md":"# `@gitbook/browser-types`\n\nTypescript types for the global variables available in a GitBook website. These types can be used by integrations embedding scripts.\n","packages/cache-tags/README.md":"# `@gitbook/cache-tags`\n\nUtility to generate cache tags for GitBook Open.","packages/colors/README.md":"# `@gitbook/colors`\n\nA set of default colors and transformation functions used throughout the GitBook Open and app.\n","packages/embed/README.md":"# GitBook Docs Embed (`@gitbook/embed`)\n\nEmbed your GitBook docs in your product or website.\n\nThe Docs Embed can contain three tabs:\n- **Assistant**: The [GitBook Assistant](https://gitbook.com/docs/publishing-documentation/gitbook-ai-assistant) - an AI-powered chat interface to help users find answers\n- **Search**: A search-focused surface for quickly finding pages and asking scoped questions\n- **Docs**: A browser for navigating your documentation site\n\nThe embed is set up automatically based on your site's configuration. You can optionally customize and override the configuration with custom actions, tools, suggested questions, [Authenticated Access](https://gitbook.com/docs/publishing-documentation/authenticated-access), and more. See the [Configuration](#configuration) section for all available options.\n\n# Usage\n\n## As a standalone script from your docs site\n\nAll GitBook docs sites include a script to easily add the Docs Embed as a widget on your website.\n\nThe script is served at `https://docs.company.com/~gitbook/embed/script.js`.\n\nYou can find the embed script from your docs site settings, or you can copy the following and replace `docs.company.com` with your docs site hostname.\n\n```html\n<script src=\"https://docs.company.com/~gitbook/embed/script.js\"></script>\n```\n\nThe script initializes the widget itself, so there is nothing to call. To pin the embed to one color\nscheme, put it on the script URL — it has to be known before the widget renders:\n\n```html\n<script src=\"https://docs.company.com/~gitbook/embed/script.js?theme=light\"></script>\n```\n\nTo authenticate the visitor, call `init` with their token. Keep tokens out of the script URL: it is\npublicly cacheable and ends up in server logs.\n\n```html\n<script src=\"https://docs.company.com/~gitbook/embed/script.js\"></script>\n<script>\nwindow.GitBook('init',\n    { siteURL: 'https://docs.company.com' },\n    { visitor: { token: 'your-jwt-token' } }\n);\n</script>\n```\n\nThe standalone script provides a global `GitBook` function. See the [API Reference](#api-reference) section for all available methods.\n\n### Example: Configuring the widget\n\n```javascript\nGitBook('configure', {\n    button: {\n        label: 'Ask',\n        icon: 'assistant' // 'assistant' | 'sparkle' | 'help' | 'book'\n    },\n    tabs: ['assistant', 'search', 'docs'],\n    defaultPage: '/getting-started',\n    actions: [\n        {\n            icon: 'circle-question',\n            label: 'Contact Support',\n            onClick: () => window.open('https://support.example.com', '_blank')\n        }\n    ],\n    greeting: { title: 'Welcome!', subtitle: 'How can I help?' },\n    assistantName: 'Support Assistant',\n    suggestions: ['What is GitBook?', 'How do I get started?'],\n    tools: [/* ... */],\n    closeButton: true,\n});\n```\n\nSee the [Configuration](#configuration) section for all available options.\n\n## As a package from NPM\n\nInstall the package: `npm install @gitbook/embed` and import it in your web application:\n\n```tsx\nimport { createGitBook } from '@gitbook/embed';\n\nconst gitbook = createGitBook({\n    siteURL: 'https://docs.company.com'\n});\n\n// Create an iframe and get its URL\nconst iframe = document.createElement('iframe');\niframe.src = gitbook.getFrameURL({\n    colorScheme: 'dark', // Optional: force the embed to render in dark mode\n    visitor: {\n        token: 'your-jwt-token', // Optional: for Adaptive Content or Authenticated Access\n        unsignedClaims: { // Optional: custom claims for dynamic expressions\n            userId: '123',\n            plan: 'premium'\n        }\n    }\n});\n\n// Create a frame client to communicate with the iframe\nconst frame = gitbook.createFrame(iframe);\n\n// Use the frame client methods\nframe.navigateToPage('/getting-started'); // Navigate to a page in the docs tab\nframe.navigateToAssistant(); // Switch to the assistant tab\nframe.postUserMessage('How do I get started?');\nframe.clearChat();\n\n// Configure the embed (see Configuration section for all options)\nframe.configure({\n    tabs: ['assistant', 'search', 'docs'],\n    defaultPage: '/getting-started',\n    actions: [\n        {\n            icon: 'circle-question',\n            label: 'Contact Support',\n            onClick: () => window.open('https://support.example.com', '_blank')\n        }\n    ],\n    greeting: { title: 'Welcome!', subtitle: 'How can I help?' },\n    assistantName: 'Support Assistant',\n    suggestions: ['What is GitBook?', 'How do I get started?'],\n    tools: [/* ... */],\n    closeButton: true\n});\n\n// Listen to events\nframe.on('close', () => {\n    console.log('Frame closed');\n});\n```\n\n## As React components\n\nAfter installing the NPM package, you can import prebuilt React components:\n\n```tsx\nimport { GitBookProvider, GitBookFrame } from '@gitbook/embed/react';\n\n<GitBookProvider siteURL=\"https://docs.company.com\">\n    <GitBookFrame\n        colorScheme=\"dark\"\n        visitor={{\n            token: 'your-jwt-token', // Optional: for Adaptive Content or Authenticated Access\n            unsignedClaims: { userId: '123' } // Optional: custom claims for dynamic expressions\n        }}\n        tabs={['assistant', 'search', 'docs']}\n        defaultPage=\"/getting-started\"\n        greeting={{ title: 'Welcome!', subtitle: 'How can I help?' }}\n        assistantName=\"Support Assistant\"\n        suggestions={['What is GitBook?', 'How do I get started?']}\n        actions={[\n            {\n                icon: 'circle-question',\n                label: 'Contact Support',\n                onClick: () => window.open('https://support.example.com', '_blank')\n            }\n        ]}\n        tools={[/* ... */]}\n        closeButton\n    />\n</GitBookProvider>\n```\n\nYou can also use the `useGitBook` hook to access the client:\n\n```tsx\nimport { useGitBook } from '@gitbook/embed/react';\n\nfunction MyComponent() {\n    const gitbook = useGitBook();\n    const frameURL = gitbook.getFrameURL({ colorScheme: 'dark', visitor: { token: '...' } });\n    // ...\n}\n```\n\n# API Reference\n\n## Method Comparison\n\n| Method | Standalone Script | NPM Package | React Components |\n|--------|------------------|-------------|------------------|\n| **Initialize** | `GitBook('init', options, frameOptions)` | `createGitBook(options)` | `<GitBookProvider siteURL=\"...\">` |\n| **Get frame URL** | ❌ (handled internally) | `client.getFrameURL(options)` | `useGitBook().getFrameURL(options)` |\n| **Create frame client** | ❌ (handled internally) | `client.createFrame(iframe)` | `useGitBook().createFrame(iframe)` |\n| **Show/Hide widget** | `GitBook('show')` / `GitBook('hide')` | ❌ | ❌ |\n| **Open/Close window** | `GitBook('open')` / `GitBook('close')` / `GitBook('toggle')` | ❌ | ❌ |\n| **Navigate to page** | `GitBook('navigateToPage', path)` | `frame.navigateToPage(path)` | Via frame client |\n| **Navigate to assistant** | `GitBook('navigateToAssistant')` | `frame.navigateToAssistant()` | Via frame client |\n| **Post message** | `GitBook('postUserMessage', message)` | `frame.postUserMessage(message)` | Via frame client |\n| **Clear chat** | `GitBook('clearChat')` | `frame.clearChat()` | Via frame client |\n| **Configure** | `GitBook('configure', settings)` | `frame.configure(settings)` | Props on `<GitBookFrame>` |\n| **Event listeners** | ❌ | `frame.on(event, listener)` | Via frame client |\n| **Unload** | `GitBook('unload')` | ❌ | ❌ |\n\n## Method Signatures\n\n### Standalone Script\n\n- `GitBook('init', options: { siteURL: string }, frameOptions?: { colorScheme?: 'light' | 'dark', visitor?: {...} })` - Initialize widget\n- `GitBook('show')` - Show widget button\n- `GitBook('hide')` - Hide widget button\n- `GitBook('open')` - Open widget window\n- `GitBook('close')` - Close widget window\n- `GitBook('toggle')` - Toggle widget window\n- `GitBook('navigateToPage', path: string)` - Navigate to page (accepts the page path within the site, an absolute path, or the full published URL; resolves pages in any space/section)\n- `GitBook('navigateToAssistant')` - Navigate to assistant tab\n- `GitBook('postUserMessage', message: string)` - Post message to chat\n- `GitBook('clearChat')` - Clear chat history\n- `GitBook('configure', settings: {...})` - Configure widget\n- `GitBook('unload')` - Unload widget\n\n### NPM Package\n\n**Client Factory:**\n- `createGitBook(options: { siteURL: string })` → `GitBookClient`\n- `client.getFrameURL(options?: { colorScheme?: 'light' | 'dark', visitor?: {...} })` → `string`\n- `client.createFrame(iframe: HTMLIFrameElement)` → `GitBookFrameClient`\n\n**Frame Client:**\n- `frame.navigateToPage(path: string)` → `void` (accepts the page path within the site, an absolute path, or the full published URL; resolves pages in any space/section)\n- `frame.navigateToAssistant()` → `void`\n- `frame.postUserMessage(message: string)` → `void`\n- `frame.clearChat()` → `void`\n- `frame.configure(settings: Partial<GitBookEmbeddableConfiguration>)` → `void`\n- `frame.on(event: string, listener: Function)` → `() => void` (unsubscribe)\n\n### React Components\n\n**Components:**\n- `<GitBookProvider siteURL: string>` - Provider component\n- `<GitBookFrame {...props}>` - Frame component (accepts all config options as props)\n\n**Hooks:**\n- `useGitBook()` → `GitBookClient` (must be used within `<GitBookProvider>`)\n\n# Configuration\n\nConfiguration options are available across usage methods as follows:\n- **Standalone script**: via `GitBook('configure', {...})`\n- **NPM package**: via `frame.configure({...})`\n- **React components**: via props on `<GitBookFrame>`\n\n### `tabs`\n\nAvailable in: Standalone script, NPM package, React components\n\nOverride which tabs are displayed. Defaults to your site's configuration.\n\n- **Type**: `('assistant' | 'search' | 'docs')[]`\n\n```javascript\ntabs: ['assistant', 'search', 'docs']\n```\n\n### `defaultTab`\n\nAvailable in: Standalone script, NPM package, React components\n\nThe tab the embed opens on. Without it, the embed opens on `defaultPage` if set, otherwise on the assistant (or the docs when the assistant isn't available). The tab must be one of the enabled `tabs`.\n\n- **Type**: `'assistant' | 'search' | 'docs'`\n\n```javascript\ntabs: ['assistant', 'search', 'docs'],\ndefaultTab: 'search'\n```\n\n`defaultTab` and `defaultPage` apply when the embed first loads: the standalone widget keeps its place when it is closed and reopened. To move it later, use `navigateToPage` or `navigateToAssistant`.\n\n### `defaultPage`\n\nAvailable in: Standalone script, NPM package, React components\n\nThe page the docs tab opens on, in place of your site's home page. Accepts the same references as `navigateToPage`: the page's path within the site, an absolute path, or its full published URL. Unless `defaultTab` says otherwise, the embed opens on this page.\n\n- **Type**: `string`\n\n```javascript\ndefaultPage: '/getting-started/quickstart'\n```\n\n### `closeButton`\n\nAvailable in: Standalone script, NPM package, React components\n\nDisplay a close (`x`) button in the embed sidebar.\n\n- **Type**: `boolean`\n- **Default**: `false`\n\n```javascript\ncloseButton: true\n```\n\nBehavior:\n- When clicked, the embed sends a `close` event to the parent page.\n- In the standalone script, this event is handled automatically and the widget closes.\n- In custom iframe integrations (NPM package), you must listen for the `close` event and decide how to hide/collapse your UI.\n- In React, this works automatically when using the standard widget flow. If you build custom frame wiring, handle `close` the same way as the NPM package.\n\nNPM package example:\n\n```typescript\nconst frame = gitbook.createFrame(iframe);\n\nframe.configure({\n    closeButton: true\n});\n\nconst unsubscribe = frame.on('close', () => {\n    // Hide your modal/drawer/container\n    container.classList.add('hidden');\n});\n```\n\nNotes:\n- The close button is rendered in the same sidebar area as tabs/actions.\n- If your UI hides that sidebar or doesn't render it, the button will not be visible.\n\n### `trademark`\n\nAvailable in: Standalone script, NPM package, React components\n\nDisplay GitBook branding in the embed. Defaults to true.\n\n- **Type**: `boolean`\n- **Default**: `true`\n\n```javascript\ntrademark: true\n```\n\n### `actions`\n\nAvailable in: Standalone script, NPM package, React components\n\nCustom action buttons rendered in the sidebar alongside tabs. Each action button triggers a callback when clicked.\n\n**Note**: This prop was previously named `buttons`. Use `actions` instead, it has the same functionality.\n\n- **Type**: `GitBookEmbeddableActionDefinition[]`\n- **Properties**:\n  - `icon`: `string` - Icon name. Any [FontAwesome icon](https://fontawesome.com/search) is supported. (e.g., `'rocket'`, `'comments'`, `'user-circle'`, ...)\n  - `label`: `string` - Button label text\n  - `onClick`: `() => void | Promise<void>` - Callback function when clicked\n\n```javascript\nactions: [\n    {\n        icon: 'comments',\n        label: 'Contact Support',\n        onClick: () => window.open('https://support.example.com', '_blank')\n    },\n    {\n        icon: 'rocket',\n        label: 'Get started',\n        onClick: () => {\n            GitBook('navigateToPage', '/getting-started');\n        }\n    }\n]\n```\n\n### `greeting`\n\nAvailable in: Standalone script, NPM package, React components\n\nWelcome message displayed in the [Assistant](https://gitbook.com/docs/publishing-documentation/gitbook-ai-assistant) tab.\n\n- **Type**: `{ title: string, subtitle: string }`\n\n```javascript\ngreeting: {\n    title: 'Welcome!',\n    subtitle: 'How can I help you today?'\n}\n```\n\n### `assistantName`\n\nAvailable in: Standalone script, NPM package, React components\n\nOverride the assistant name displayed in the chat header and assistant entry points (for example, sidebar tabs and action labels). This name will be limited to 32 characters to prevent text overflow.\n\n- **Type**: `string`\n\n```javascript\nassistantName: 'Support Assistant'\n```\n\n### `suggestions`\n\nAvailable in: Standalone script, NPM package, React components\n\nSuggested questions displayed in the [Assistant](https://gitbook.com/docs/publishing-documentation/gitbook-ai-assistant) welcome screen.\n\n- **Type**: `string[]`\n\n```javascript\nsuggestions: [\n    'What is GitBook?',\n    'How do I get started?',\n    'What can you do?'\n]\n```\n\n### `tools`\n\nAvailable in: Standalone script, NPM package, React components\n\nCustom AI tools to extend the [Assistant](https://gitbook.com/docs/publishing-documentation/gitbook-ai-assistant). Tools allow the assistant to execute functions and integrate with your own systems.\n\n**Note**: In addition to custom tools, the Assistant will always have access to any [MCP servers you define](https://gitbook.com/docs/publishing-documentation/gitbook-ai-assistant#extend-gitbook-assistant-with-mcp-servers) in your site's AI settings.\n\n- **Type**: `GitBookToolDefinition[]`\n- **Properties**:\n  - `name`: `string` - Unique tool identifier\n  - `description`: `string` - Description of what the tool does (used by the AI to decide when and how to use it).\n  - `inputSchema`: `object` - JSON schema defining the tool's input parameters\n  - `execute`: `(input: object) => Promise<{ output: any, summary: string }>` - Async function that executes the tool.\n    - `output`: The result of the tool execution, provided to the AI to continue working with. Not shown to the user.\n    - `summary`: The visual summary of the tool execution, shown in the user's chat window.\n  - `confirmation`: `{ icon?: string, label: string }` (optional) - Confirmation button shown before execution, useful for actions that require the user's express approval.\n\n```javascript\ntools: [\n    {\n        name: 'get_user_info',\n        description: 'Get information about the current user',\n        inputSchema: {\n            type: 'object',\n            properties: {\n                userId: { \n                    type: 'string', \n                    description: 'The user ID to look up' \n                }\n            },\n            required: ['userId']\n        },\n        execute: async (input) => {\n            const user = await fetch(`/api/users/${input.userId}`).then(r => r.json());\n            return {\n                output: { name: user.name, plan: user.plan },\n                summary: `Retrieved info for user ${user.name}`\n            };\n        }\n    },\n    {\n        name: 'create_ticket',\n        description: 'Create a support ticket',\n        confirmation: {\n            icon: 'circle-question',\n            label: 'Create support ticket?'\n        },\n        inputSchema: {\n            type: 'object',\n            properties: {\n                subject: { type: 'string' },\n                description: { type: 'string' }\n            },\n            required: ['subject', 'description']\n        },\n        execute: async (input) => {\n            const ticket = await fetch('/api/tickets', {\n                method: 'POST',\n                body: JSON.stringify(input)\n            }).then(r => r.json());\n            return {\n                output: { ticketId: ticket.id },\n                summary: `Created ticket #${ticket.id}`\n            };\n        }\n    }\n]\n```\n\n### `visitor` (Authenticated Access)\n\nAvailable in: Standalone script (via `init`), NPM package (via `getFrameURL()`), React components (as prop)\n\n[Authenticated Access](https://gitbook.com/docs/publishing-documentation/authenticated-access) options passed when creating the frame URL. Used for [Adaptive Content](https://gitbook.com/docs/publishing-documentation/adaptive-content) and [Authenticated Access](https://gitbook.com/docs/publishing-documentation/authenticated-access).\n\n**Note**: This is not a configuration option but rather a parameter when initializing the frame or creating the frame URL.\n\n**Standalone script**: Pass as the second argument to `GitBook('init', options, frameOptions)`\n**NPM package**: Pass to `getFrameURL({ visitor: {...} })`\n**React components**: Pass as the `visitor` prop on `<GitBookFrame>`\n\n- **Type**: `{ token?: string, unsignedClaims?: Record<string, unknown> }`\n- **Properties**:\n  - `token`: `string` (optional) - Signed JWT token for [Adaptive Content](https://gitbook.com/docs/publishing-documentation/adaptive-content) or [Authenticated Access](https://gitbook.com/docs/publishing-documentation/authenticated-access)\n  - `unsignedClaims`: `Record<string, unknown>` (optional) - Unsigned claims that can be used in dynamic expressions via `visitor.claims.unsigned.<claim-name>`\n\n```javascript\nvisitor: {\n    token: 'your-jwt-token',\n    unsignedClaims: {\n        userId: '123',\n        plan: 'premium',\n        role: 'admin'\n    }\n}\n```\n\n### `colorScheme`\n\nAvailable in: Standalone script (via `init`), NPM package (via `getFrameURL()`), React components (as prop)\n\nOverride the embed's color scheme.\n\nWhen omitted, the standalone widget follows the page it is embedded in — its `color-scheme`, falling back to the visitor's OS preference only when that page declares support for both. With the NPM package or the React components you own the iframe, so the embed follows the visitor's OS preference unless you pass this.\n\n**Note**: This is not a configuration option but rather a parameter when initializing the frame or creating the frame URL.\n\n**Standalone script**: `?theme=light` on the script URL\n**NPM package**: Pass to `getFrameURL({ colorScheme: 'dark' })`\n**React components**: Pass as the `colorScheme` prop on `<GitBookFrame>`\n\n- **Type**: `'light' | 'dark'`\n\n```html\n<script src=\"https://docs.company.com/~gitbook/embed/script.js?theme=light\"></script>\n```\n\nSites published with a single theme always render in that theme, so `colorScheme` has no effect on\nthem — the widget follows the site instead, to keep its chrome and the docs inside it consistent.\n\n### `button`\n\nAvailable in: Standalone script only\n\nConfigure the widget button for the standalone script. This option is not available when using the NPM package or React components, since they can be customized completely.\n\n- **Type**: `{ label: string, icon: 'assistant' | 'sparkle' | 'help' | 'book' }`\n- **Properties**:\n  - `label`: `string` - Button label text\n  - `icon`: `'assistant' | 'sparkle' | 'help' | 'book'` - Icon displayed on the button. Choose from one of 4 presets.\n\n```javascript\nbutton: {\n    label: 'Ask',\n    icon: 'assistant'\n}\n```\n","packages/expr/README.md":"# `@gitbook/expr`\n\nSafely evaluate & parse user-defined GitBook expressions.\n","packages/fonts/README.md":"# `@gitbook/fonts`\n\nUtilities to lookup default fonts supported by GitBook.\n","packages/icons/README.md":"# `@gitbook/icons`\n\nIcon sets useed in GitBook content.\n\n## Usage\n\n```tsx\nimport { Icon } from '@gitbook/icons';\n\n<Icon name=\"x\" className={'size-5'} />;\n```\n","packages/openapi-parser/README.md":"# `@gitbook/openapi-parser`\n\nModern OpenAPI parser written in TypeScript with support for OpenAPI 3.1, OpenAPI 3.0 and Swagger 2.0.","packages/react-math/README.md":"# `@gitbook/react-math`\n\nReact component to render a Math formula. It uses KaTeX when possible and fallbacks to MathJaX if needed.\n","packages/react-openapi/README.md":"# `@gitbook/react-openapi`\n\nStyle-less React components to render OpenAPI operation blocks.\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","rawUrl":"https://raw.githubusercontent.com/GitbookIO/gitbook/HEAD/AGENTS.md","title":"AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"# AGENTS Instructions\n\n## Commands\n\n```bash\nbun install          # Install dependencies\nbun dev              # Start dev server (all packages)\nbun run build        # Build all packages\nbun run lint         # Lint with Oxlint\nbun run format       # Format with Oxfmt (run after every change)\nbun run typecheck    # Type-check all packages\nbun run unit         # Run unit tests\n```\n\n## Development\n\nThe dev server proxies published GitBook sites locally. After `bun dev`, access any published site at:\n\n```\nhttp://localhost:3000/url/<published-gitbook-url>\n```\n\nExamples:\n- `http://localhost:3000/url/gitbook.com/docs`\n- `http://localhost:3000/url/open-source.gitbook.io/midjourney`\n\n## Architecture\n\n```\npackages/\n  gitbook/          # Main Next.js app\n    src/\n      app/          # Next.js App Router (sites/)\n      components/   # React components\n      lib/          # Server utilities, data fetching\n      intl/         # Internationalization (translations/)\n  openapi-parser/   # OpenAPI 3.0/3.1/Swagger parser\n  react-openapi/    # OpenAPI rendering components\n  react-contentkit/ # ContentKit component rendering\n  embed/            # Embeddable GitBook components\n  shared/           # Shared utilities\n  icons/            # Icon assets\n  fonts/            # Font assets\n  colors/           # Color tokens\n  expr/             # GitBook expression evaluator\n  cache-do/         # Cloudflare DO cache\n  cache-tags/       # Cache tag utilities\n```\n\n## Testing\n\n```bash\nbun run unit         # Unit tests via bun test (not vitest)\nbun run e2e          # Playwright e2e tests (requires built app)\n```\n\nRun a specific test file:\n```bash\ncd packages/gitbook && bun test src/lib/cache.test.ts\n```\n\n## Changesets\n\nAfter committing code changes, create a changeset for the affected package:\n\n```md\n---\n\"gitbook\": patch\n---\n\nProvide a short description of the change.\n```\n\nSave as `.changeset/<name>.md`, then commit it separately with message: `changeset`\n\n## Formatting\n\nLinting uses Oxlint and formatting uses Oxfmt. Always run `bun run format` before committing.\n\n## Comments\n\nComment to explain *why*, not *what* — the code already shows what it does. Keep comments short, ideally a single line. Avoid multi-line block comments that narrate mechanics a reader can follow from the code; they add noise and go stale. Reserve longer comments for genuinely non-obvious rationale: a subtle invariant, or a workaround and the reason it exists.\n","isInternal":false,"tokens":586,"sizeBytes":2441},{"name":"CLAUDE.md","path":"CLAUDE.md","rawUrl":"https://raw.githubusercontent.com/GitbookIO/gitbook/HEAD/CLAUDE.md","title":"Claude Agent Guidelines & System Prompt","category":"claude-rule","format":"markdown","content":"@AGENTS.md\n","isInternal":false,"tokens":5,"sizeBytes":11},{"name":"SKILL.md","path":".agents/skills/write-pr-description/SKILL.md","rawUrl":"https://raw.githubusercontent.com/GitbookIO/gitbook/HEAD/.agents/skills/write-pr-description/SKILL.md","title":"write-pr-description","category":"anthropic-skill","format":"markdown","content":"---\nname: write-pr-description\ndescription: Write a concise, product-focused PR description from the changes and available discussion. Use when asked for a PR summary or description.\n---\n\n# Write a PR description\n\nRead the full branch diff and commit history against the PR's base branch, not just the latest commit. Use the PR discussion and linked issues for context when available. The PR's changes are the source of truth for what ships if an issue describes something different.\n\nWrite for contributors and reviewers who may not know the area. Lead with what changes, prefer user or product impact when supported, and include implementation details only when they help review. Keep the proposed changes short, using bullets only when useful.\n\nInclude relevant validation and screenshots when available. Do not claim checks passed unless they ran. Use only information appropriate for a public repository; do not copy private issue details or customer information into the description.\n\n## Template and changelog\n\nRead `.github/pull_request_template.md` immediately before writing. Preserve its required section names and order. Include `Proposed changes` and `Changelog`; omit `Demo` when there is nothing to show. Add optional `Context` before `Changelog` only when it meets the rule below.\n\nWrite a short changelog entry describing what shipped. Use `[Feature]` for user-facing additions or improvements, `[Fix]` for user-facing bug fixes, and `[Chore]` for internal maintenance. For features and fixes, say what users can do or what no longer goes wrong in plain words. Keep chores useful to teammates without inventing user impact. Remove unused examples and placeholders. Usually one entry is enough; use more only for distinct changes. The PR changelog does not replace any changeset required by `AGENTS.md`.\n\n## Optional context\n\nWrite `Proposed changes` and `Changelog` first. Add `Context` only when it tells someone unfamiliar with the area something material that the changelog does not. `Problem` names a concrete failure or limitation supported by the PR or discussion. `Outcome` names what this PR delivers at its actual scope. Omit the section if either field would repeat the changelog, describe only implementation, or guess at an impact.\n\n```markdown\n## Context\n\n**Problem:** <concrete failure or limitation>\n\n**Outcome:** <result delivered by this PR>\n```\n\nKeep each field to 1–2 short, non-technical sentences. Prefer user or product impact when supported. For infrastructure changes, explain the failure or limitation they caused. Do not invent an actor, customer segment, ownership, or impact, or force the change into a user story. Do not turn a preparatory change into a claim that the whole workflow is fixed. Keep the roles distinct: `Context` explains why this matters, `Changelog` says what shipped, and `Proposed changes` can explain implementation.\n\nExamples:\n\n- A dependency bump with no demonstrated user effect needs no `Context`.\n- If creating the first change request leaves the user on an empty screen, say that it now opens after creation. Leave the animation-listener details in `Proposed changes`.\n- If a PR indexes links for later checks, describe the indexing result. Do not claim every link has already been checked.\n\n## Writing pass\n\n- Use plain words and direct verbs: \"use\" instead of \"leverage\", \"help\" instead of \"facilitate\". Prefer active voice when the actor is known.\n- Name the concrete behavior instead of saying \"improves the experience\" or \"makes it more robust\". Support performance claims with measurements.\n- Cut filler, promotional language, and generic conclusions. If a sentence could fit almost any PR, make it specific or delete it.\n- Keep one idea per sentence and use consistent names. Remove redundant hedging without hiding real uncertainty.\n- Avoid \"not just X, but Y\", forced groups of three, em dashes, decorative emojis, and unnecessary bold text.\n\nReturn the description in a Markdown code block unless asked to update the PR. When asked to update it, apply the description with `gh pr edit` using a body file.\n","frontmatter":{"name":"write-pr-description","description":"Write a concise, product-focused PR description from the changes and available discussion. Use when asked for a PR summary or description."},"isInternal":false,"tokens":832,"sizeBytes":4090},{"name":"README.md","path":"packages/browser-types/README.md","rawUrl":"https://raw.githubusercontent.com/GitbookIO/gitbook/HEAD/packages/browser-types/README.md","title":"browser-types Documentation","category":"plugin-manifest","format":"markdown","content":"# `@gitbook/browser-types`\n\nTypescript types for the global variables available in a GitBook website. These types can be used by integrations embedding scripts.\n","isInternal":false,"tokens":33,"sizeBytes":161},{"name":"README.md","path":"packages/cache-tags/README.md","rawUrl":"https://raw.githubusercontent.com/GitbookIO/gitbook/HEAD/packages/cache-tags/README.md","title":"cache-tags Documentation","category":"plugin-manifest","format":"markdown","content":"# `@gitbook/cache-tags`\n\nUtility to generate cache tags for GitBook Open.","isInternal":false,"tokens":18,"sizeBytes":73},{"name":"README.md","path":"packages/colors/README.md","rawUrl":"https://raw.githubusercontent.com/GitbookIO/gitbook/HEAD/packages/colors/README.md","title":"colors Documentation","category":"plugin-manifest","format":"markdown","content":"# `@gitbook/colors`\n\nA set of default colors and transformation functions used throughout the GitBook Open and app.\n","isInternal":false,"tokens":24,"sizeBytes":116},{"name":"README.md","path":"packages/embed/README.md","rawUrl":"https://raw.githubusercontent.com/GitbookIO/gitbook/HEAD/packages/embed/README.md","title":"embed Documentation","category":"plugin-manifest","format":"markdown","content":"# GitBook Docs Embed (`@gitbook/embed`)\n\nEmbed your GitBook docs in your product or website.\n\nThe Docs Embed can contain three tabs:\n- **Assistant**: The [GitBook Assistant](https://gitbook.com/docs/publishing-documentation/gitbook-ai-assistant) - an AI-powered chat interface to help users find answers\n- **Search**: A search-focused surface for quickly finding pages and asking scoped questions\n- **Docs**: A browser for navigating your documentation site\n\nThe embed is set up automatically based on your site's configuration. You can optionally customize and override the configuration with custom actions, tools, suggested questions, [Authenticated Access](https://gitbook.com/docs/publishing-documentation/authenticated-access), and more. See the [Configuration](#configuration) section for all available options.\n\n# Usage\n\n## As a standalone script from your docs site\n\nAll GitBook docs sites include a script to easily add the Docs Embed as a widget on your website.\n\nThe script is served at `https://docs.company.com/~gitbook/embed/script.js`.\n\nYou can find the embed script from your docs site settings, or you can copy the following and replace `docs.company.com` with your docs site hostname.\n\n```html\n<script src=\"https://docs.company.com/~gitbook/embed/script.js\"></script>\n```\n\nThe script initializes the widget itself, so there is nothing to call. To pin the embed to one color\nscheme, put it on the script URL — it has to be known before the widget renders:\n\n```html\n<script src=\"https://docs.company.com/~gitbook/embed/script.js?theme=light\"></script>\n```\n\nTo authenticate the visitor, call `init` with their token. Keep tokens out of the script URL: it is\npublicly cacheable and ends up in server logs.\n\n```html\n<script src=\"https://docs.company.com/~gitbook/embed/script.js\"></script>\n<script>\nwindow.GitBook('init',\n    { siteURL: 'https://docs.company.com' },\n    { visitor: { token: 'your-jwt-token' } }\n);\n</script>\n```\n\nThe standalone script provides a global `GitBook` function. See the [API Reference](#api-reference) section for all available methods.\n\n### Example: Configuring the widget\n\n```javascript\nGitBook('configure', {\n    button: {\n        label: 'Ask',\n        icon: 'assistant' // 'assistant' | 'sparkle' | 'help' | 'book'\n    },\n    tabs: ['assistant', 'search', 'docs'],\n    defaultPage: '/getting-started',\n    actions: [\n        {\n            icon: 'circle-question',\n            label: 'Contact Support',\n            onClick: () => window.open('https://support.example.com', '_blank')\n        }\n    ],\n    greeting: { title: 'Welcome!', subtitle: 'How can I help?' },\n    assistantName: 'Support Assistant',\n    suggestions: ['What is GitBook?', 'How do I get started?'],\n    tools: [/* ... */],\n    closeButton: true,\n});\n```\n\nSee the [Configuration](#configuration) section for all available options.\n\n## As a package from NPM\n\nInstall the package: `npm install @gitbook/embed` and import it in your web application:\n\n```tsx\nimport { createGitBook } from '@gitbook/embed';\n\nconst gitbook = createGitBook({\n    siteURL: 'https://docs.company.com'\n});\n\n// Create an iframe and get its URL\nconst iframe = document.createElement('iframe');\niframe.src = gitbook.getFrameURL({\n    colorScheme: 'dark', // Optional: force the embed to render in dark mode\n    visitor: {\n        token: 'your-jwt-token', // Optional: for Adaptive Content or Authenticated Access\n        unsignedClaims: { // Optional: custom claims for dynamic expressions\n            userId: '123',\n            plan: 'premium'\n        }\n    }\n});\n\n// Create a frame client to communicate with the iframe\nconst frame = gitbook.createFrame(iframe);\n\n// Use the frame client methods\nframe.navigateToPage('/getting-started'); // Navigate to a page in the docs tab\nframe.navigateToAssistant(); // Switch to the assistant tab\nframe.postUserMessage('How do I get started?');\nframe.clearChat();\n\n// Configure the embed (see Configuration section for all options)\nframe.configure({\n    tabs: ['assistant', 'search', 'docs'],\n    defaultPage: '/getting-started',\n    actions: [\n        {\n            icon: 'circle-question',\n            label: 'Contact Support',\n            onClick: () => window.open('https://support.example.com', '_blank')\n        }\n    ],\n    greeting: { title: 'Welcome!', subtitle: 'How can I help?' },\n    assistantName: 'Support Assistant',\n    suggestions: ['What is GitBook?', 'How do I get started?'],\n    tools: [/* ... */],\n    closeButton: true\n});\n\n// Listen to events\nframe.on('close', () => {\n    console.log('Frame closed');\n});\n```\n\n## As React components\n\nAfter installing the NPM package, you can import prebuilt React components:\n\n```tsx\nimport { GitBookProvider, GitBookFrame } from '@gitbook/embed/react';\n\n<GitBookProvider siteURL=\"https://docs.company.com\">\n    <GitBookFrame\n        colorScheme=\"dark\"\n        visitor={{\n            token: 'your-jwt-token', // Optional: for Adaptive Content or Authenticated Access\n            unsignedClaims: { userId: '123' } // Optional: custom claims for dynamic expressions\n        }}\n        tabs={['assistant', 'search', 'docs']}\n        defaultPage=\"/getting-started\"\n        greeting={{ title: 'Welcome!', subtitle: 'How can I help?' }}\n        assistantName=\"Support Assistant\"\n        suggestions={['What is GitBook?', 'How do I get started?']}\n        actions={[\n            {\n                icon: 'circle-question',\n                label: 'Contact Support',\n                onClick: () => window.open('https://support.example.com', '_blank')\n            }\n        ]}\n        tools={[/* ... */]}\n        closeButton\n    />\n</GitBookProvider>\n```\n\nYou can also use the `useGitBook` hook to access the client:\n\n```tsx\nimport { useGitBook } from '@gitbook/embed/react';\n\nfunction MyComponent() {\n    const gitbook = useGitBook();\n    const frameURL = gitbook.getFrameURL({ colorScheme: 'dark', visitor: { token: '...' } });\n    // ...\n}\n```\n\n# API Reference\n\n## Method Comparison\n\n| Method | Standalone Script | NPM Package | React Components |\n|--------|------------------|-------------|------------------|\n| **Initialize** | `GitBook('init', options, frameOptions)` | `createGitBook(options)` | `<GitBookProvider siteURL=\"...\">` |\n| **Get frame URL** | ❌ (handled internally) | `client.getFrameURL(options)` | `useGitBook().getFrameURL(options)` |\n| **Create frame client** | ❌ (handled internally) | `client.createFrame(iframe)` | `useGitBook().createFrame(iframe)` |\n| **Show/Hide widget** | `GitBook('show')` / `GitBook('hide')` | ❌ | ❌ |\n| **Open/Close window** | `GitBook('open')` / `GitBook('close')` / `GitBook('toggle')` | ❌ | ❌ |\n| **Navigate to page** | `GitBook('navigateToPage', path)` | `frame.navigateToPage(path)` | Via frame client |\n| **Navigate to assistant** | `GitBook('navigateToAssistant')` | `frame.navigateToAssistant()` | Via frame client |\n| **Post message** | `GitBook('postUserMessage', message)` | `frame.postUserMessage(message)` | Via frame client |\n| **Clear chat** | `GitBook('clearChat')` | `frame.clearChat()` | Via frame client |\n| **Configure** | `GitBook('configure', settings)` | `frame.configure(settings)` | Props on `<GitBookFrame>` |\n| **Event listeners** | ❌ | `frame.on(event, listener)` | Via frame client |\n| **Unload** | `GitBook('unload')` | ❌ | ❌ |\n\n## Method Signatures\n\n### Standalone Script\n\n- `GitBook('init', options: { siteURL: string }, frameOptions?: { colorScheme?: 'light' | 'dark', visitor?: {...} })` - Initialize widget\n- `GitBook('show')` - Show widget button\n- `GitBook('hide')` - Hide widget button\n- `GitBook('open')` - Open widget window\n- `GitBook('close')` - Close widget window\n- `GitBook('toggle')` - Toggle widget window\n- `GitBook('navigateToPage', path: string)` - Navigate to page (accepts the page path within the site, an absolute path, or the full published URL; resolves pages in any space/section)\n- `GitBook('navigateToAssistant')` - Navigate to assistant tab\n- `GitBook('postUserMessage', message: string)` - Post message to chat\n- `GitBook('clearChat')` - Clear chat history\n- `GitBook('configure', settings: {...})` - Configure widget\n- `GitBook('unload')` - Unload widget\n\n### NPM Package\n\n**Client Factory:**\n- `createGitBook(options: { siteURL: string })` → `GitBookClient`\n- `client.getFrameURL(options?: { colorScheme?: 'light' | 'dark', visitor?: {...} })` → `string`\n- `client.createFrame(iframe: HTMLIFrameElement)` → `GitBookFrameClient`\n\n**Frame Client:**\n- `frame.navigateToPage(path: string)` → `void` (accepts the page path within the site, an absolute path, or the full published URL; resolves pages in any space/section)\n- `frame.navigateToAssistant()` → `void`\n- `frame.postUserMessage(message: string)` → `void`\n- `frame.clearChat()` → `void`\n- `frame.configure(settings: Partial<GitBookEmbeddableConfiguration>)` → `void`\n- `frame.on(event: string, listener: Function)` → `() => void` (unsubscribe)\n\n### React Components\n\n**Components:**\n- `<GitBookProvider siteURL: string>` - Provider component\n- `<GitBookFrame {...props}>` - Frame component (accepts all config options as props)\n\n**Hooks:**\n- `useGitBook()` → `GitBookClient` (must be used within `<GitBookProvider>`)\n\n# Configuration\n\nConfiguration options are available across usage methods as follows:\n- **Standalone script**: via `GitBook('configure', {...})`\n- **NPM package**: via `frame.configure({...})`\n- **React components**: via props on `<GitBookFrame>`\n\n### `tabs`\n\nAvailable in: Standalone script, NPM package, React components\n\nOverride which tabs are displayed. Defaults to your site's configuration.\n\n- **Type**: `('assistant' | 'search' | 'docs')[]`\n\n```javascript\ntabs: ['assistant', 'search', 'docs']\n```\n\n### `defaultTab`\n\nAvailable in: Standalone script, NPM package, React components\n\nThe tab the embed opens on. Without it, the embed opens on `defaultPage` if set, otherwise on the assistant (or the docs when the assistant isn't available). The tab must be one of the enabled `tabs`.\n\n- **Type**: `'assistant' | 'search' | 'docs'`\n\n```javascript\ntabs: ['assistant', 'search', 'docs'],\ndefaultTab: 'search'\n```\n\n`defaultTab` and `defaultPage` apply when the embed first loads: the standalone widget keeps its place when it is closed and reopened. To move it later, use `navigateToPage` or `navigateToAssistant`.\n\n### `defaultPage`\n\nAvailable in: Standalone script, NPM package, React components\n\nThe page the docs tab opens on, in place of your site's home page. Accepts the same references as `navigateToPage`: the page's path within the site, an absolute path, or its full published URL. Unless `defaultTab` says otherwise, the embed opens on this page.\n\n- **Type**: `string`\n\n```javascript\ndefaultPage: '/getting-started/quickstart'\n```\n\n### `closeButton`\n\nAvailable in: Standalone script, NPM package, React components\n\nDisplay a close (`x`) button in the embed sidebar.\n\n- **Type**: `boolean`\n- **Default**: `false`\n\n```javascript\ncloseButton: true\n```\n\nBehavior:\n- When clicked, the embed sends a `close` event to the parent page.\n- In the standalone script, this event is handled automatically and the widget closes.\n- In custom iframe integrations (NPM package), you must listen for the `close` event and decide how to hide/collapse your UI.\n- In React, this works automatically when using the standard widget flow. If you build custom frame wiring, handle `close` the same way as the NPM package.\n\nNPM package example:\n\n```typescript\nconst frame = gitbook.createFrame(iframe);\n\nframe.configure({\n    closeButton: true\n});\n\nconst unsubscribe = frame.on('close', () => {\n    // Hide your modal/drawer/container\n    container.classList.add('hidden');\n});\n```\n\nNotes:\n- The close button is rendered in the same sidebar area as tabs/actions.\n- If your UI hides that sidebar or doesn't render it, the button will not be visible.\n\n### `trademark`\n\nAvailable in: Standalone script, NPM package, React components\n\nDisplay GitBook branding in the embed. Defaults to true.\n\n- **Type**: `boolean`\n- **Default**: `true`\n\n```javascript\ntrademark: true\n```\n\n### `actions`\n\nAvailable in: Standalone script, NPM package, React components\n\nCustom action buttons rendered in the sidebar alongside tabs. Each action button triggers a callback when clicked.\n\n**Note**: This prop was previously named `buttons`. Use `actions` instead, it has the same functionality.\n\n- **Type**: `GitBookEmbeddableActionDefinition[]`\n- **Properties**:\n  - `icon`: `string` - Icon name. Any [FontAwesome icon](https://fontawesome.com/search) is supported. (e.g., `'rocket'`, `'comments'`, `'user-circle'`, ...)\n  - `label`: `string` - Button label text\n  - `onClick`: `() => void | Promise<void>` - Callback function when clicked\n\n```javascript\nactions: [\n    {\n        icon: 'comments',\n        label: 'Contact Support',\n        onClick: () => window.open('https://support.example.com', '_blank')\n    },\n    {\n        icon: 'rocket',\n        label: 'Get started',\n        onClick: () => {\n            GitBook('navigateToPage', '/getting-started');\n        }\n    }\n]\n```\n\n### `greeting`\n\nAvailable in: Standalone script, NPM package, React components\n\nWelcome message displayed in the [Assistant](https://gitbook.com/docs/publishing-documentation/gitbook-ai-assistant) tab.\n\n- **Type**: `{ title: string, subtitle: string }`\n\n```javascript\ngreeting: {\n    title: 'Welcome!',\n    subtitle: 'How can I help you today?'\n}\n```\n\n### `assistantName`\n\nAvailable in: Standalone script, NPM package, React components\n\nOverride the assistant name displayed in the chat header and assistant entry points (for example, sidebar tabs and action labels). This name will be limited to 32 characters to prevent text overflow.\n\n- **Type**: `string`\n\n```javascript\nassistantName: 'Support Assistant'\n```\n\n### `suggestions`\n\nAvailable in: Standalone script, NPM package, React components\n\nSuggested questions displayed in the [Assistant](https://gitbook.com/docs/publishing-documentation/gitbook-ai-assistant) welcome screen.\n\n- **Type**: `string[]`\n\n```javascript\nsuggestions: [\n    'What is GitBook?',\n    'How do I get started?',\n    'What can you do?'\n]\n```\n\n### `tools`\n\nAvailable in: Standalone script, NPM package, React components\n\nCustom AI tools to extend the [Assistant](https://gitbook.com/docs/publishing-documentation/gitbook-ai-assistant). Tools allow the assistant to execute functions and integrate with your own systems.\n\n**Note**: In addition to custom tools, the Assistant will always have access to any [MCP servers you define](https://gitbook.com/docs/publishing-documentation/gitbook-ai-assistant#extend-gitbook-assistant-with-mcp-servers) in your site's AI settings.\n\n- **Type**: `GitBookToolDefinition[]`\n- **Properties**:\n  - `name`: `string` - Unique tool identifier\n  - `description`: `string` - Description of what the tool does (used by the AI to decide when and how to use it).\n  - `inputSchema`: `object` - JSON schema defining the tool's input parameters\n  - `execute`: `(input: object) => Promise<{ output: any, summary: string }>` - Async function that executes the tool.\n    - `output`: The result of the tool execution, provided to the AI to continue working with. Not shown to the user.\n    - `summary`: The visual summary of the tool execution, shown in the user's chat window.\n  - `confirmation`: `{ icon?: string, label: string }` (optional) - Confirmation button shown before execution, useful for actions that require the user's express approval.\n\n```javascript\ntools: [\n    {\n        name: 'get_user_info',\n        description: 'Get information about the current user',\n        inputSchema: {\n            type: 'object',\n            properties: {\n                userId: { \n                    type: 'string', \n                    description: 'The user ID to look up' \n                }\n            },\n            required: ['userId']\n        },\n        execute: async (input) => {\n            const user = await fetch(`/api/users/${input.userId}`).then(r => r.json());\n            return {\n                output: { name: user.name, plan: user.plan },\n                summary: `Retrieved info for user ${user.name}`\n            };\n        }\n    },\n    {\n        name: 'create_ticket',\n        description: 'Create a support ticket',\n        confirmation: {\n            icon: 'circle-question',\n            label: 'Create support ticket?'\n        },\n        inputSchema: {\n            type: 'object',\n            properties: {\n                subject: { type: 'string' },\n                description: { type: 'string' }\n            },\n            required: ['subject', 'description']\n        },\n        execute: async (input) => {\n            const ticket = await fetch('/api/tickets', {\n                method: 'POST',\n                body: JSON.stringify(input)\n            }).then(r => r.json());\n            return {\n                output: { ticketId: ticket.id },\n                summary: `Created ticket #${ticket.id}`\n            };\n        }\n    }\n]\n```\n\n### `visitor` (Authenticated Access)\n\nAvailable in: Standalone script (via `init`), NPM package (via `getFrameURL()`), React components (as prop)\n\n[Authenticated Access](https://gitbook.com/docs/publishing-documentation/authenticated-access) options passed when creating the frame URL. Used for [Adaptive Content](https://gitbook.com/docs/publishing-documentation/adaptive-content) and [Authenticated Access](https://gitbook.com/docs/publishing-documentation/authenticated-access).\n\n**Note**: This is not a configuration option but rather a parameter when initializing the frame or creating the frame URL.\n\n**Standalone script**: Pass as the second argument to `GitBook('init', options, frameOptions)`\n**NPM package**: Pass to `getFrameURL({ visitor: {...} })`\n**React components**: Pass as the `visitor` prop on `<GitBookFrame>`\n\n- **Type**: `{ token?: string, unsignedClaims?: Record<string, unknown> }`\n- **Properties**:\n  - `token`: `string` (optional) - Signed JWT token for [Adaptive Content](https://gitbook.com/docs/publishing-documentation/adaptive-content) or [Authenticated Access](https://gitbook.com/docs/publishing-documentation/authenticated-access)\n  - `unsignedClaims`: `Record<string, unknown>` (optional) - Unsigned claims that can be used in dynamic expressions via `visitor.claims.unsigned.<claim-name>`\n\n```javascript\nvisitor: {\n    token: 'your-jwt-token',\n    unsignedClaims: {\n        userId: '123',\n        plan: 'premium',\n        role: 'admin'\n    }\n}\n```\n\n### `colorScheme`\n\nAvailable in: Standalone script (via `init`), NPM package (via `getFrameURL()`), React components (as prop)\n\nOverride the embed's color scheme.\n\nWhen omitted, the standalone widget follows the page it is embedded in — its `color-scheme`, falling back to the visitor's OS preference only when that page declares support for both. With the NPM package or the React components you own the iframe, so the embed follows the visitor's OS preference unless you pass this.\n\n**Note**: This is not a configuration option but rather a parameter when initializing the frame or creating the frame URL.\n\n**Standalone script**: `?theme=light` on the script URL\n**NPM package**: Pass to `getFrameURL({ colorScheme: 'dark' })`\n**React components**: Pass as the `colorScheme` prop on `<GitBookFrame>`\n\n- **Type**: `'light' | 'dark'`\n\n```html\n<script src=\"https://docs.company.com/~gitbook/embed/script.js?theme=light\"></script>\n```\n\nSites published with a single theme always render in that theme, so `colorScheme` has no effect on\nthem — the widget follows the site instead, to keep its chrome and the docs inside it consistent.\n\n### `button`\n\nAvailable in: Standalone script only\n\nConfigure the widget button for the standalone script. This option is not available when using the NPM package or React components, since they can be customized completely.\n\n- **Type**: `{ label: string, icon: 'assistant' | 'sparkle' | 'help' | 'book' }`\n- **Properties**:\n  - `label`: `string` - Button label text\n  - `icon`: `'assistant' | 'sparkle' | 'help' | 'book'` - Icon displayed on the button. Choose from one of 4 presets.\n\n```javascript\nbutton: {\n    label: 'Ask',\n    icon: 'assistant'\n}\n```\n","isInternal":false,"tokens":4779,"sizeBytes":20140},{"name":"README.md","path":"packages/expr/README.md","rawUrl":"https://raw.githubusercontent.com/GitbookIO/gitbook/HEAD/packages/expr/README.md","title":"expr Documentation","category":"plugin-manifest","format":"markdown","content":"# `@gitbook/expr`\n\nSafely evaluate & parse user-defined GitBook expressions.\n","isInternal":false,"tokens":20,"sizeBytes":77},{"name":"README.md","path":"packages/fonts/README.md","rawUrl":"https://raw.githubusercontent.com/GitbookIO/gitbook/HEAD/packages/fonts/README.md","title":"fonts Documentation","category":"plugin-manifest","format":"markdown","content":"# `@gitbook/fonts`\n\nUtilities to lookup default fonts supported by GitBook.\n","isInternal":false,"tokens":17,"sizeBytes":76},{"name":"README.md","path":"packages/icons/README.md","rawUrl":"https://raw.githubusercontent.com/GitbookIO/gitbook/HEAD/packages/icons/README.md","title":"icons Documentation","category":"plugin-manifest","format":"markdown","content":"# `@gitbook/icons`\n\nIcon sets useed in GitBook content.\n\n## Usage\n\n```tsx\nimport { Icon } from '@gitbook/icons';\n\n<Icon name=\"x\" className={'size-5'} />;\n```\n","isInternal":false,"tokens":47,"sizeBytes":158},{"name":"README.md","path":"packages/openapi-parser/README.md","rawUrl":"https://raw.githubusercontent.com/GitbookIO/gitbook/HEAD/packages/openapi-parser/README.md","title":"openapi-parser Documentation","category":"plugin-manifest","format":"markdown","content":"# `@gitbook/openapi-parser`\n\nModern OpenAPI parser written in TypeScript with support for OpenAPI 3.1, OpenAPI 3.0 and Swagger 2.0.","isInternal":false,"tokens":39,"sizeBytes":131},{"name":"README.md","path":"packages/react-math/README.md","rawUrl":"https://raw.githubusercontent.com/GitbookIO/gitbook/HEAD/packages/react-math/README.md","title":"react-math Documentation","category":"plugin-manifest","format":"markdown","content":"# `@gitbook/react-math`\n\nReact component to render a Math formula. It uses KaTeX when possible and fallbacks to MathJaX if needed.\n","isInternal":false,"tokens":33,"sizeBytes":131},{"name":"README.md","path":"packages/react-openapi/README.md","rawUrl":"https://raw.githubusercontent.com/GitbookIO/gitbook/HEAD/packages/react-openapi/README.md","title":"react-openapi Documentation","category":"plugin-manifest","format":"markdown","content":"# `@gitbook/react-openapi`\n\nStyle-less React components to render OpenAPI operation blocks.\n","isInternal":false,"tokens":20,"sizeBytes":92}],"systemPromptSnippet":"<yakaai_skills repo=\"GitbookIO/gitbook\">\n<!-- File: AGENTS.md (Tokens: ~586 | Category: root-instruction) -->\n# AGENTS Instructions\n\n## Commands\n\n```bash\nbun install          # Install dependencies\nbun dev              # Start dev server (all packages)\nbun run build        # Build all packages\nbun run lint         # Lint with Oxlint\nbun run format       # Format with Oxfmt (run after every change)\nbun run typecheck    # Type-check all packages\nbun run unit         # Run unit tests\n```\n\n## Development\n\nThe dev server proxies published GitBook sites locally. After `bun dev`, access any published site at:\n\n```\nhttp://localhost:3000/url/<published-gitbook-url>\n```\n\nExamples:\n- `http://localhost:3000/url/gitbook.com/docs`\n- `http://localhost:3000/url/open-source.gitbook.io/midjourney`\n\n## Architecture\n\n```\npackages/\n  gitbook/          # Main Next.js app\n    src/\n      app/          # Next.js App Router (sites/)\n      components/   # React components\n      lib/          # Server utilities, data fetching\n      intl/         # Internationalization (translations/)\n  openapi-parser/   # OpenAPI 3.0/3.1/Swagger parser\n  react-openapi/    # OpenAPI rendering components\n  react-contentkit/ # ContentKit component rendering\n  embed/            # Embeddable GitBook components\n  shared/           # Shared utilities\n  icons/            # Icon assets\n  fonts/            # Font assets\n  colors/           # Color tokens\n  expr/             # GitBook expression evaluator\n  cache-do/         # Cloudflare DO cache\n  cache-tags/       # Cache tag utilities\n```\n\n## Testing\n\n```bash\nbun run unit         # Unit tests via bun test (not vitest)\nbun run e2e          # Playwright e2e tests (requires built app)\n```\n\nRun a specific test file:\n```bash\ncd packages/gitbook && bun test src/lib/cache.test.ts\n```\n\n## Changesets\n\nAfter committing code changes, create a changeset for the affected package:\n\n```md\n---\n\"gitbook\": patch\n---\n\nProvide a short description of the change.\n```\n\nSave as `.changeset/<name>.md`, then commit it separately with message: `changeset`\n\n## Formatting\n\nLinting uses Oxlint and formatting uses Oxfmt. Always run `bun run format` before committing.\n\n## Comments\n\nComment to explain *why*, not *what* — the code already shows what it does. Keep comments short, ideally a single line. Avoid multi-line block comments that narrate mechanics a reader can follow from the code; they add noise and go stale. Reserve longer comments for genuinely non-obvious rationale: a subtle invariant, or a workaround and the reason it exists.\n\n<!-- File: CLAUDE.md (Tokens: ~5 | Category: claude-rule) -->\n@AGENTS.md\n\n<!-- File: .agents/skills/write-pr-description/SKILL.md (Tokens: ~832 | Category: anthropic-skill) -->\n---\nname: write-pr-description\ndescription: Write a concise, product-focused PR description from the changes and available discussion. Use when asked for a PR summary or description.\n---\n\n# Write a PR description\n\nRead the full branch diff and commit history against the PR's base branch, not just the latest commit. Use the PR discussion and linked issues for context when available. The PR's changes are the source of truth for what ships if an issue describes something different.\n\nWrite for contributors and reviewers who may not know the area. Lead with what changes, prefer user or product impact when supported, and include implementation details only when they help review. Keep the proposed changes short, using bullets only when useful.\n\nInclude relevant validation and screenshots when available. Do not claim checks passed unless they ran. Use only information appropriate for a public repository; do not copy private issue details or customer information into the description.\n\n## Template and changelog\n\nRead `.github/pull_request_template.md` immediately before writing. Preserve its required section names and order. Include `Proposed changes` and `Changelog`; omit `Demo` when there is nothing to show. Add optional `Context` before `Changelog` only when it meets the rule below.\n\nWrite a short changelog entry describing what shipped. Use `[Feature]` for user-facing additions or improvements, `[Fix]` for user-facing bug fixes, and `[Chore]` for internal maintenance. For features and fixes, say what users can do or what no longer goes wrong in plain words. Keep chores useful to teammates without inventing user impact. Remove unused examples and placeholders. Usually one entry is enough; use more only for distinct changes. The PR changelog does not replace any changeset required by `AGENTS.md`.\n\n## Optional context\n\nWrite `Proposed changes` and `Changelog` first. Add `Context` only when it tells someone unfamiliar with the area something material that the changelog does not. `Problem` names a concrete failure or limitation supported by the PR or discussion. `Outcome` names what this PR delivers at its actual scope. Omit the section if either field would repeat the changelog, describe only implementation, or guess at an impact.\n\n```markdown\n## Context\n\n**Problem:** <concrete failure or limitation>\n\n**Outcome:** <result delivered by this PR>\n```\n\nKeep each field to 1–2 short, non-technical sentences. Prefer user or product impact when supported. For infrastructure changes, explain the failure or limitation they caused. Do not invent an actor, customer segment, ownership, or impact, or force the change into a user story. Do not turn a preparatory change into a claim that the whole workflow is fixed. Keep the roles distinct: `Context` explains why this matters, `Changelog` says what shipped, and `Proposed changes` can explain implementation.\n\nExamples:\n\n- A dependency bump with no demonstrated user effect needs no `Context`.\n- If creating the first change request leaves the user on an empty screen, say that it now opens after creation. Leave the animation-listener details in `Proposed changes`.\n- If a PR indexes links for later checks, describe the indexing result. Do not claim every link has already been checked.\n\n## Writing pass\n\n- Use plain words and direct verbs: \"use\" instead of \"leverage\", \"help\" instead of \"facilitate\". Prefer active voice when the actor is known.\n- Name the concrete behavior instead of saying \"improves the experience\" or \"makes it more robust\". Support performance claims with measurements.\n- Cut filler, promotional language, and generic conclusions. If a sentence could fit almost any PR, make it specific or delete it.\n- Keep one idea per sentence and use consistent names. Remove redundant hedging without hiding real uncertainty.\n- Avoid \"not just X, but Y\", forced groups of three, em dashes, decorative emojis, and unnecessary bold text.\n\nReturn the description in a Markdown code block unless asked to update the PR. When asked to update it, apply the description with `gh pr edit` using a body file.\n\n<!-- File: packages/browser-types/README.md (Tokens: ~33 | Category: plugin-manifest) -->\n# `@gitbook/browser-types`\n\nTypescript types for the global variables available in a GitBook website. These types can be used by integrations embedding scripts.\n\n<!-- File: packages/cache-tags/README.md (Tokens: ~18 | Category: plugin-manifest) -->\n# `@gitbook/cache-tags`\n\nUtility to generate cache tags for GitBook Open.\n\n<!-- File: packages/colors/README.md (Tokens: ~24 | Category: plugin-manifest) -->\n# `@gitbook/colors`\n\nA set of default colors and transformation functions used throughout the GitBook Open and app.\n\n<!-- File: packages/embed/README.md (Tokens: ~4779 | Category: plugin-manifest) -->\n# GitBook Docs Embed (`@gitbook/embed`)\n\nEmbed your GitBook docs in your product or website.\n\nThe Docs Embed can contain three tabs:\n- **Assistant**: The [GitBook Assistant](https://gitbook.com/docs/publishing-documentation/gitbook-ai-assistant) - an AI-powered chat interface to help users find answers\n- **Search**: A search-focused surface for quickly finding pages and asking scoped questions\n- **Docs**: A browser for navigating your documentation site\n\nThe embed is set up automatically based on your site's configuration. You can optionally customize and override the configuration with custom actions, tools, suggested questions, [Authenticated Access](https://gitbook.com/docs/publishing-documentation/authenticated-access), and more. See the [Configuration](#configuration) section for all available options.\n\n# Usage\n\n## As a standalone script from your docs site\n\nAll GitBook docs sites include a script to easily add the Docs Embed as a widget on your website.\n\nThe script is served at `https://docs.company.com/~gitbook/embed/script.js`.\n\nYou can find the embed script from your docs site settings, or you can copy the following and replace `docs.company.com` with your docs site hostname.\n\n```html\n<script src=\"https://docs.company.com/~gitbook/embed/script.js\"></script>\n```\n\nThe script initializes the widget itself, so there is nothing to call. To pin the embed to one color\nscheme, put it on the script URL — it has to be known before the widget renders:\n\n```html\n<script src=\"https://docs.company.com/~gitbook/embed/script.js?theme=light\"></script>\n```\n\nTo authenticate the visitor, call `init` with their token. Keep tokens out of the script URL: it is\npublicly cacheable and ends up in server logs.\n\n```html\n<script src=\"https://docs.company.com/~gitbook/embed/script.js\"></script>\n<script>\nwindow.GitBook('init',\n    { siteURL: 'https://docs.company.com' },\n    { visitor: { token: 'your-jwt-token' } }\n);\n</script>\n```\n\nThe standalone script provides a global `GitBook` function. See the [API Reference](#api-reference) section for all available methods.\n\n### Example: Configuring the widget\n\n```javascript\nGitBook('configure', {\n    button: {\n        label: 'Ask',\n        icon: 'assistant' // 'assistant' | 'sparkle' | 'help' | 'book'\n    },\n    tabs: ['assistant', 'search', 'docs'],\n    defaultPage: '/getting-started',\n    actions: [\n        {\n            icon: 'circle-question',\n            label: 'Contact Support',\n            onClick: () => window.open('https://support.example.com', '_blank')\n        }\n    ],\n    greeting: { title: 'Welcome!', subtitle: 'How can I help?' },\n    assistantName: 'Support Assistant',\n    suggestions: ['What is GitBook?', 'How do I get started?'],\n    tools: [/* ... */],\n    closeButton: true,\n});\n```\n\nSee the [Configuration](#configuration) section for all available options.\n\n## As a package from NPM\n\nInstall the package: `npm install @gitbook/embed` and import it in your web application:\n\n```tsx\nimport { createGitBook } from '@gitbook/embed';\n\nconst gitbook = createGitBook({\n    siteURL: 'https://docs.company.com'\n});\n\n// Create an iframe and get its URL\nconst iframe = document.createElement('iframe');\niframe.src = gitbook.getFrameURL({\n    colorScheme: 'dark', // Optional: force the embed to render in dark mode\n    visitor: {\n        token: 'your-jwt-token', // Optional: for Adaptive Content or Authenticated Access\n        unsignedClaims: { // Optional: custom claims for dynamic expressions\n            userId: '123',\n            plan: 'premium'\n        }\n    }\n});\n\n// Create a frame client to communicate with the iframe\nconst frame = gitbook.createFrame(iframe);\n\n// Use the frame client methods\nframe.navigateToPage('/getting-started'); // Navigate to a page in the docs tab\nframe.navigateToAssistant(); // Switch to the assistant tab\nframe.postUserMessage('How do I get started?');\nframe.clearChat();\n\n// Configure the embed (see Configuration section for all options)\nframe.configure({\n    tabs: ['assistant', 'search', 'docs'],\n    defaultPage: '/getting-started',\n    actions: [\n        {\n            icon: 'circle-question',\n            label: 'Contact Support',\n            onClick: () => window.open('https://support.example.com', '_blank')\n        }\n    ],\n    greeting: { title: 'Welcome!', subtitle: 'How can I help?' },\n    assistantName: 'Support Assistant',\n    suggestions: ['What is GitBook?', 'How do I get started?'],\n    tools: [/* ... */],\n    closeButton: true\n});\n\n// Listen to events\nframe.on('close', () => {\n    console.log('Frame closed');\n});\n```\n\n## As React components\n\nAfter installing the NPM package, you can import prebuilt React components:\n\n```tsx\nimport { GitBookProvider, GitBookFrame } from '@gitbook/embed/react';\n\n<GitBookProvider siteURL=\"https://docs.company.com\">\n    <GitBookFrame\n        colorScheme=\"dark\"\n        visitor={{\n            token: 'your-jwt-token', // Optional: for Adaptive Content or Authenticated Access\n            unsignedClaims: { userId: '123' } // Optional: custom claims for dynamic expressions\n        }}\n        tabs={['assistant', 'search', 'docs']}\n        defaultPage=\"/getting-started\"\n        greeting={{ title: 'Welcome!', subtitle: 'How can I help?' }}\n        assistantName=\"Support Assistant\"\n        suggestions={['What is GitBook?', 'How do I get started?']}\n        actions={[\n            {\n                icon: 'circle-question',\n                label: 'Contact Support',\n                onClick: () => window.open('https://support.example.com', '_blank')\n            }\n        ]}\n        tools={[/* ... */]}\n        closeButton\n    />\n</GitBookProvider>\n```\n\nYou can also use the `useGitBook` hook to access the client:\n\n```tsx\nimport { useGitBook } from '@gitbook/embed/react';\n\nfunction MyComponent() {\n    const gitbook = useGitBook();\n    const frameURL = gitbook.getFrameURL({ colorScheme: 'dark', visitor: { token: '...' } });\n    // ...\n}\n```\n\n# API Reference\n\n## Method Comparison\n\n| Method | Standalone Script | NPM Package | React Components |\n|--------|------------------|-------------|------------------|\n| **Initialize** | `GitBook('init', options, frameOptions)` | `createGitBook(options)` | `<GitBookProvider siteURL=\"...\">` |\n| **Get frame URL** | ❌ (handled internally) | `client.getFrameURL(options)` | `useGitBook().getFrameURL(options)` |\n| **Create frame client** | ❌ (handled internally) | `client.createFrame(iframe)` | `useGitBook().createFrame(iframe)` |\n| **Show/Hide widget** | `GitBook('show')` / `GitBook('hide')` | ❌ | ❌ |\n| **Open/Close window** | `GitBook('open')` / `GitBook('close')` / `GitBook('toggle')` | ❌ | ❌ |\n| **Navigate to page** | `GitBook('navigateToPage', path)` | `frame.navigateToPage(path)` | Via frame client |\n| **Navigate to assistant** | `GitBook('navigateToAssistant')` | `frame.navigateToAssistant()` | Via frame client |\n| **Post message** | `GitBook('postUserMessage', message)` | `frame.postUserMessage(message)` | Via frame client |\n| **Clear chat** | `GitBook('clearChat')` | `frame.clearChat()` | Via frame client |\n| **Configure** | `GitBook('configure', settings)` | `frame.configure(settings)` | Props on `<GitBookFrame>` |\n| **Event listeners** | ❌ | `frame.on(event, listener)` | Via frame client |\n| **Unload** | `GitBook('unload')` | ❌ | ❌ |\n\n## Method Signatures\n\n### Standalone Script\n\n- `GitBook('init', options: { siteURL: string }, frameOptions?: { colorScheme?: 'light' | 'dark', visitor?: {...} })` - Initialize widget\n- `GitBook('show')` - Show widget button\n- `GitBook('hide')` - Hide widget button\n- `GitBook('open')` - Open widget window\n- `GitBook('close')` - Close widget window\n- `GitBook('toggle')` - Toggle widget window\n- `GitBook('navigateToPage', path: string)` - Navigate to page (accepts the page path within the site, an absolute path, or the full published URL; resolves pages in any space/section)\n- `GitBook('navigateToAssistant')` - Navigate to assistant tab\n- `GitBook('postUserMessage', message: string)` - Post message to chat\n- `GitBook('clearChat')` - Clear chat history\n- `GitBook('configure', settings: {...})` - Configure widget\n- `GitBook('unload')` - Unload widget\n\n### NPM Package\n\n**Client Factory:**\n- `createGitBook(options: { siteURL: string })` → `GitBookClient`\n- `client.getFrameURL(options?: { colorScheme?: 'light' | 'dark', visitor?: {...} })` → `string`\n- `client.createFrame(iframe: HTMLIFrameElement)` → `GitBookFrameClient`\n\n**Frame Client:**\n- `frame.navigateToPage(path: string)` → `void` (accepts the page path within the site, an absolute path, or the full published URL; resolves pages in any space/section)\n- `frame.navigateToAssistant()` → `void`\n- `frame.postUserMessage(message: string)` → `void`\n- `frame.clearChat()` → `void`\n- `frame.configure(settings: Partial<GitBookEmbeddableConfiguration>)` → `void`\n- `frame.on(event: string, listener: Function)` → `() => void` (unsubscribe)\n\n### React Components\n\n**Components:**\n- `<GitBookProvider siteURL: string>` - Provider component\n- `<GitBookFrame {...props}>` - Frame component (accepts all config options as props)\n\n**Hooks:**\n- `useGitBook()` → `GitBookClient` (must be used within `<GitBookProvider>`)\n\n# Configuration\n\nConfiguration options are available across usage methods as follows:\n- **Standalone script**: via `GitBook('configure', {...})`\n- **NPM package**: via `frame.configure({...})`\n- **React components**: via props on `<GitBookFrame>`\n\n### `tabs`\n\nAvailable in: Standalone script, NPM package, React components\n\nOverride which tabs are displayed. Defaults to your site's configuration.\n\n- **Type**: `('assistant' | 'search' | 'docs')[]`\n\n```javascript\ntabs: ['assistant', 'search', 'docs']\n```\n\n### `defaultTab`\n\nAvailable in: Standalone script, NPM package, React components\n\nThe tab the embed opens on. Without it, the embed opens on `defaultPage` if set, otherwise on the assistant (or the docs when the assistant isn't available). The tab must be one of the enabled `tabs`.\n\n- **Type**: `'assistant' | 'search' | 'docs'`\n\n```javascript\ntabs: ['assistant', 'search', 'docs'],\ndefaultTab: 'search'\n```\n\n`defaultTab` and `defaultPage` apply when the embed first loads: the standalone widget keeps its place when it is closed and reopened. To move it later, use `navigateToPage` or `navigateToAssistant`.\n\n### `defaultPage`\n\nAvailable in: Standalone script, NPM package, React components\n\nThe page the docs tab opens on, in place of your site's home page. Accepts the same references as `navigateToPage`: the page's path within the site, an absolute path, or its full published URL. Unless `defaultTab` says otherwise, the embed opens on this page.\n\n- **Type**: `string`\n\n```javascript\ndefaultPage: '/getting-started/quickstart'\n```\n\n### `closeButton`\n\nAvailable in: Standalone script, NPM package, React components\n\nDisplay a close (`x`) button in the embed sidebar.\n\n- **Type**: `boolean`\n- **Default**: `false`\n\n```javascript\ncloseButton: true\n```\n\nBehavior:\n- When clicked, the embed sends a `close` event to the parent page.\n- In the standalone script, this event is handled automatically and the widget closes.\n- In custom iframe integrations (NPM package), you must listen for the `close` event and decide how to hide/collapse your UI.\n- In React, this works automatically when using the standard widget flow. If you build custom frame wiring, handle `close` the same way as the NPM package.\n\nNPM package example:\n\n```typescript\nconst frame = gitbook.createFrame(iframe);\n\nframe.configure({\n    closeButton: true\n});\n\nconst unsubscribe = frame.on('close', () => {\n    // Hide your modal/drawer/container\n    container.classList.add('hidden');\n});\n```\n\nNotes:\n- The close button is rendered in the same sidebar area as tabs/actions.\n- If your UI hides that sidebar or doesn't render it, the button will not be visible.\n\n### `trademark`\n\nAvailable in: Standalone script, NPM package, React components\n\nDisplay GitBook branding in the embed. Defaults to true.\n\n- **Type**: `boolean`\n- **Default**: `true`\n\n```javascript\ntrademark: true\n```\n\n### `actions`\n\nAvailable in: Standalone script, NPM package, React components\n\nCustom action buttons rendered in the sidebar alongside tabs. Each action button triggers a callback when clicked.\n\n**Note**: This prop was previously named `buttons`. Use `actions` instead, it has the same functionality.\n\n- **Type**: `GitBookEmbeddableActionDefinition[]`\n- **Properties**:\n  - `icon`: `string` - Icon name. Any [FontAwesome icon](https://fontawesome.com/search) is supported. (e.g., `'rocket'`, `'comments'`, `'user-circle'`, ...)\n  - `label`: `string` - Button label text\n  - `onClick`: `() => void | Promise<void>` - Callback function when clicked\n\n```javascript\nactions: [\n    {\n        icon: 'comments',\n        label: 'Contact Support',\n        onClick: () => window.open('https://support.example.com', '_blank')\n    },\n    {\n        icon: 'rocket',\n        label: 'Get started',\n        onClick: () => {\n            GitBook('navigateToPage', '/getting-started');\n        }\n    }\n]\n```\n\n### `greeting`\n\nAvailable in: Standalone script, NPM package, React components\n\nWelcome message displayed in the [Assistant](https://gitbook.com/docs/publishing-documentation/gitbook-ai-assistant) tab.\n\n- **Type**: `{ title: string, subtitle: string }`\n\n```javascript\ngreeting: {\n    title: 'Welcome!',\n    subtitle: 'How can I help you today?'\n}\n```\n\n### `assistantName`\n\nAvailable in: Standalone script, NPM package, React components\n\nOverride the assistant name displayed in the chat header and assistant entry points (for example, sidebar tabs and action labels). This name will be limited to 32 characters to prevent text overflow.\n\n- **Type**: `string`\n\n```javascript\nassistantName: 'Support Assistant'\n```\n\n### `suggestions`\n\nAvailable in: Standalone script, NPM package, React components\n\nSuggested questions displayed in the [Assistant](https://gitbook.com/docs/publishing-documentation/gitbook-ai-assistant) welcome screen.\n\n- **Type**: `string[]`\n\n```javascript\nsuggestions: [\n    'What is GitBook?',\n    'How do I get started?',\n    'What can you do?'\n]\n```\n\n### `tools`\n\nAvailable in: Standalone script, NPM package, React components\n\nCustom AI tools to extend the [Assistant](https://gitbook.com/docs/publishing-documentation/gitbook-ai-assistant). Tools allow the assistant to execute functions and integrate with your own systems.\n\n**Note**: In addition to custom tools, the Assistant will always have access to any [MCP servers you define](https://gitbook.com/docs/publishing-documentation/gitbook-ai-assistant#extend-gitbook-assistant-with-mcp-servers) in your site's AI settings.\n\n- **Type**: `GitBookToolDefinition[]`\n- **Properties**:\n  - `name`: `string` - Unique tool identifier\n  - `description`: `string` - Description of what the tool does (used by the AI to decide when and how to use it).\n  - `inputSchema`: `object` - JSON schema defining the tool's input parameters\n  - `execute`: `(input: object) => Promise<{ output: any, summary: string }>` - Async function that executes the tool.\n    - `output`: The result of the tool execution, provided to the AI to continue working with. Not shown to the user.\n    - `summary`: The visual summary of the tool execution, shown in the user's chat window.\n  - `confirmation`: `{ icon?: string, label: string }` (optional) - Confirmation button shown before execution, useful for actions that require the user's express approval.\n\n```javascript\ntools: [\n    {\n        name: 'get_user_info',\n        description: 'Get information about the current user',\n        inputSchema: {\n            type: 'object',\n            properties: {\n                userId: { \n                    type: 'string', \n                    description: 'The user ID to look up' \n                }\n            },\n            required: ['userId']\n        },\n        execute: async (input) => {\n            const user = await fetch(`/api/users/${input.userId}`).then(r => r.json());\n            return {\n                output: { name: user.name, plan: user.plan },\n                summary: `Retrieved info for user ${user.name}`\n            };\n        }\n    },\n    {\n        name: 'create_ticket',\n        description: 'Create a support ticket',\n        confirmation: {\n            icon: 'circle-question',\n            label: 'Create support ticket?'\n        },\n        inputSchema: {\n            type: 'object',\n            properties: {\n                subject: { type: 'string' },\n                description: { type: 'string' }\n            },\n            required: ['subject', 'description']\n        },\n        execute: async (input) => {\n            const ticket = await fetch('/api/tickets', {\n                method: 'POST',\n                body: JSON.stringify(input)\n            }).then(r => r.json());\n            return {\n                output: { ticketId: ticket.id },\n                summary: `Created ticket #${ticket.id}`\n            };\n        }\n    }\n]\n```\n\n### `visitor` (Authenticated Access)\n\nAvailable in: Standalone script (via `init`), NPM package (via `getFrameURL()`), React components (as prop)\n\n[Authenticated Access](https://gitbook.com/docs/publishing-documentation/authenticated-access) options passed when creating the frame URL. Used for [Adaptive Content](https://gitbook.com/docs/publishing-documentation/adaptive-content) and [Authenticated Access](https://gitbook.com/docs/publishing-documentation/authenticated-access).\n\n**Note**: This is not a configuration option but rather a parameter when initializing the frame or creating the frame URL.\n\n**Standalone script**: Pass as the second argument to `GitBook('init', options, frameOptions)`\n**NPM package**: Pass to `getFrameURL({ visitor: {...} })`\n**React components**: Pass as the `visitor` prop on `<GitBookFrame>`\n\n- **Type**: `{ token?: string, unsignedClaims?: Record<string, unknown> }`\n- **Properties**:\n  - `token`: `string` (optional) - Signed JWT token for [Adaptive Content](https://gitbook.com/docs/publishing-documentation/adaptive-content) or [Authenticated Access](https://gitbook.com/docs/publishing-documentation/authenticated-access)\n  - `unsignedClaims`: `Record<string, unknown>` (optional) - Unsigned claims that can be used in dynamic expressions via `visitor.claims.unsigned.<claim-name>`\n\n```javascript\nvisitor: {\n    token: 'your-jwt-token',\n    unsignedClaims: {\n        userId: '123',\n        plan: 'premium',\n        role: 'admin'\n    }\n}\n```\n\n### `colorScheme`\n\nAvailable in: Standalone script (via `init`), NPM package (via `getFrameURL()`), React components (as prop)\n\nOverride the embed's color scheme.\n\nWhen omitted, the standalone widget follows the page it is embedded in — its `color-scheme`, falling back to the visitor's OS preference only when that page declares support for both. With the NPM package or the React components you own the iframe, so the embed follows the visitor's OS preference unless you pass this.\n\n**Note**: This is not a configuration option but rather a parameter when initializing the frame or creating the frame URL.\n\n**Standalone script**: `?theme=light` on the script URL\n**NPM package**: Pass to `getFrameURL({ colorScheme: 'dark' })`\n**React components**: Pass as the `colorScheme` prop on `<GitBookFrame>`\n\n- **Type**: `'light' | 'dark'`\n\n```html\n<script src=\"https://docs.company.com/~gitbook/embed/script.js?theme=light\"></script>\n```\n\nSites published with a single theme always render in that theme, so `colorScheme` has no effect on\nthem — the widget follows the site instead, to keep its chrome and the docs inside it consistent.\n\n### `button`\n\nAvailable in: Standalone script only\n\nConfigure the widget button for the standalone script. This option is not available when using the NPM package or React components, since they can be customized completely.\n\n- **Type**: `{ label: string, icon: 'assistant' | 'sparkle' | 'help' | 'book' }`\n- **Properties**:\n  - `label`: `string` - Button label text\n  - `icon`: `'assistant' | 'sparkle' | 'help' | 'book'` - Icon displayed on the button. Choose from one of 4 presets.\n\n```javascript\nbutton: {\n    label: 'Ask',\n    icon: 'assistant'\n}\n```\n\n<!-- File: packages/expr/README.md (Tokens: ~20 | Category: plugin-manifest) -->\n# `@gitbook/expr`\n\nSafely evaluate & parse user-defined GitBook expressions.\n\n<!-- File: packages/fonts/README.md (Tokens: ~17 | Category: plugin-manifest) -->\n# `@gitbook/fonts`\n\nUtilities to lookup default fonts supported by GitBook.\n\n<!-- File: packages/icons/README.md (Tokens: ~47 | Category: plugin-manifest) -->\n# `@gitbook/icons`\n\nIcon sets useed in GitBook content.\n\n## Usage\n\n```tsx\nimport { Icon } from '@gitbook/icons';\n\n<Icon name=\"x\" className={'size-5'} />;\n```\n\n<!-- File: packages/openapi-parser/README.md (Tokens: ~39 | Category: plugin-manifest) -->\n# `@gitbook/openapi-parser`\n\nModern OpenAPI parser written in TypeScript with support for OpenAPI 3.1, OpenAPI 3.0 and Swagger 2.0.\n\n<!-- File: packages/react-math/README.md (Tokens: ~33 | Category: plugin-manifest) -->\n# `@gitbook/react-math`\n\nReact component to render a Math formula. It uses KaTeX when possible and fallbacks to MathJaX if needed.\n\n<!-- File: packages/react-openapi/README.md (Tokens: ~20 | Category: plugin-manifest) -->\n# `@gitbook/react-openapi`\n\nStyle-less React components to render OpenAPI operation blocks.\n</yakaai_skills>"}