{"_id":"@codrstudio/openclaude-sdk","_rev":"5-7e18e25e9fcf55cacb8de9f0f63463cf","name":"@codrstudio/openclaude-sdk","dist-tags":{"latest":"0.4.0"},"versions":{"0.1.0":{"name":"@codrstudio/openclaude-sdk","version":"0.1.0","license":"MIT","_id":"@codrstudio/openclaude-sdk@0.1.0","maintainers":[{"name":"gugacoder","email":"guga.coder@gmail.com"}],"homepage":"https://github.com/codrstudio/openclaude-sdk","bugs":{"url":"https://github.com/codrstudio/openclaude-sdk/issues"},"dist":{"shasum":"11709b8cb7cc4470220459b3a2f878d7484436f3","tarball":"https://registry.npmjs.org/@codrstudio/openclaude-sdk/-/openclaude-sdk-0.1.0.tgz","fileCount":9,"integrity":"sha512-BKnsSQl7eUt+3fsnUYEuzEeYdhT+gOFACeO617PgaJAeqAMBYw8BKOzYRz4Y8wRIZnWsnKNnLeFPTSx3t/GP2w==","signatures":[{"sig":"MEUCIQCl+UvVsyRBbtN7VVgU5tIOWe4wmnCL5CY8g1TIp7opXwIgNWwR6bcHp31Z/929kw/+N8YEzEkJasZI1hZdr/ht1KM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":236302},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"0ae6ebea097e45ca3198334b2672c58fe1e59611","scripts":{"dev":"tsup --watch","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"gugacoder","email":"guga.coder@gmail.com"},"repository":{"url":"git+https://github.com/codrstudio/openclaude-sdk.git","type":"git"},"_npmVersion":"10.9.3","description":"TypeScript SDK wrapper for the OpenClaude CLI","directories":{},"_nodeVersion":"22.20.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","typescript":"^5.4.0"},"_npmOperationalInternal":{"tmp":"tmp/openclaude-sdk_0.1.0_1775704749089_0.4481824749581649","host":"s3://npm-registry-packages-npm-production"}},"0.1.6":{"name":"@codrstudio/openclaude-sdk","version":"0.1.6","license":"MIT","_id":"@codrstudio/openclaude-sdk@0.1.6","maintainers":[{"name":"gugacoder","email":"guga.coder@gmail.com"}],"homepage":"https://github.com/codrstudio/openclaude-sdk","bugs":{"url":"https://github.com/codrstudio/openclaude-sdk/issues"},"dist":{"shasum":"fd4e0744c73c2b6e2406a96daef77e5e384f8f2c","tarball":"https://registry.npmjs.org/@codrstudio/openclaude-sdk/-/openclaude-sdk-0.1.6.tgz","fileCount":9,"integrity":"sha512-L7ojR6tZE/CuuJt87gFg0J6KxgFdEns47mHauhRO7Kxh7dQTzn/rKsoteaHgJ7TG7e/80Q+NMTDVKanaZl8rxg==","signatures":[{"sig":"MEYCIQDQ8EidyZGh16F4psWATdCNOoBPk0LixI6ca4rUgZIqGAIhAM+vxVG/JEoxugcohvBEtKisKOeGbvIC9Zlfp5yYSEjS","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@codrstudio%2fopenclaude-sdk@0.1.6","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":759917},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"5ddd14a20b8f09c90de97b2feb44d1cdfca66bfa","scripts":{"dev":"tsup --watch","build":"tsup","translate":"tsx scripts/translate-locale.ts","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:b6e908e0-e790-41e6-a7ce-bed8a799d744"}},"repository":{"url":"git+https://github.com/codrstudio/openclaude-sdk.git","type":"git"},"_npmVersion":"11.11.0","description":"TypeScript SDK wrapper for the OpenClaude CLI","directories":{},"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.0.0","zod":"^4.3.6","tsup":"^8.0.0","typescript":"^5.4.0","@types/node":"^25.6.0","@modelcontextprotocol/sdk":"^1.29.0"},"peerDependencies":{"zod":">=4.0.0","@modelcontextprotocol/sdk":">=1.0.0"},"peerDependenciesMeta":{"zod":{"optional":true},"@modelcontextprotocol/sdk":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/openclaude-sdk_0.1.6_1775965620978_0.9219625495338941","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@codrstudio/openclaude-sdk","version":"0.2.0","license":"MIT","_id":"@codrstudio/openclaude-sdk@0.2.0","maintainers":[{"name":"gugacoder","email":"guga.coder@gmail.com"}],"homepage":"https://github.com/codrstudio/openclaude-sdk","bugs":{"url":"https://github.com/codrstudio/openclaude-sdk/issues"},"dist":{"shasum":"0ecf628c4a70acfce97dd75e56b2e1bdae0bcd8e","tarball":"https://registry.npmjs.org/@codrstudio/openclaude-sdk/-/openclaude-sdk-0.2.0.tgz","fileCount":9,"integrity":"sha512-yjdmSCMl9qIHHK3YxnUocjnEcjg/Rb+zJJtzNV7qc3xaRM59zodAh3g/Tb2rDdgoPqH995Bk4TWtXdWifP7wLw==","signatures":[{"sig":"MEUCIQCAcfeYU8F9r+NSzpYQa2fz/iZo9CBcEXj14Hr1NGbv0wIgWXgQYHlLY8rDzHjGH7QP75d8158GZ4/Fak+76EYZTYI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@codrstudio%2fopenclaude-sdk@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":759917},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"6b198dede51a4b9a8699491410f151b99ea9ff52","scripts":{"dev":"tsup --watch","build":"tsup","translate":"tsx scripts/translate-locale.ts","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:b6e908e0-e790-41e6-a7ce-bed8a799d744"}},"repository":{"url":"git+https://github.com/codrstudio/openclaude-sdk.git","type":"git"},"_npmVersion":"11.11.0","description":"TypeScript SDK wrapper for the OpenClaude CLI","directories":{},"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.0.0","zod":"^4.3.6","tsup":"^8.0.0","typescript":"^5.4.0","@types/node":"^25.6.0","@modelcontextprotocol/sdk":"^1.29.0"},"peerDependencies":{"zod":">=4.0.0","@modelcontextprotocol/sdk":">=1.0.0"},"peerDependenciesMeta":{"zod":{"optional":true},"@modelcontextprotocol/sdk":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/openclaude-sdk_0.2.0_1775965801745_0.4425399446024627","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@codrstudio/openclaude-sdk","version":"0.3.0","license":"MIT","_id":"@codrstudio/openclaude-sdk@0.3.0","maintainers":[{"name":"gugacoder","email":"guga.coder@gmail.com"}],"homepage":"https://github.com/codrstudio/openclaude-sdk","bugs":{"url":"https://github.com/codrstudio/openclaude-sdk/issues"},"dist":{"shasum":"27da2b12cf58a0456193fe5701a12ad4b6c5a820","tarball":"https://registry.npmjs.org/@codrstudio/openclaude-sdk/-/openclaude-sdk-0.3.0.tgz","fileCount":9,"integrity":"sha512-K+QIPNI0lxTrQzTcICh2cR9wTKRqDgjykNk3yalDwbIfClc3N3XB2yBg8gfmG2WIkJdrn3u+dgVj1uQM8ZR0/g==","signatures":[{"sig":"MEUCIQDTDXfj5ofVH9H13aMKyjMknGZdVQRWE7qOlIUu1ZiYPwIgX7UNnP/KdCujEaP8f9oxTV4+mc/TQRAytYkG9u2Ovk4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@codrstudio%2fopenclaude-sdk@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":794103},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"837e530d7702b271aae8be833e1aa0f779828978","scripts":{"dev":"tsup --watch","build":"tsup","translate":"tsx scripts/translate-locale.ts","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:b6e908e0-e790-41e6-a7ce-bed8a799d744"}},"repository":{"url":"git+https://github.com/codrstudio/openclaude-sdk.git","type":"git"},"_npmVersion":"11.11.0","description":"TypeScript SDK wrapper for the OpenClaude CLI","directories":{},"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.0.0","zod":"^4.3.6","tsup":"^8.0.0","typescript":"^5.4.0","@types/node":"^25.6.0","@modelcontextprotocol/sdk":"^1.29.0"},"peerDependencies":{"zod":">=4.0.0","@modelcontextprotocol/sdk":">=1.0.0"},"peerDependenciesMeta":{"zod":{"optional":true},"@modelcontextprotocol/sdk":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/openclaude-sdk_0.3.0_1776062711450_0.0821599631088652","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@codrstudio/openclaude-sdk","version":"0.4.0","description":"TypeScript SDK wrapper for the OpenClaude CLI","license":"MIT","repository":{"type":"git","url":"git+https://github.com/codrstudio/openclaude-sdk.git"},"homepage":"https://github.com/codrstudio/openclaude-sdk","bugs":{"url":"https://github.com/codrstudio/openclaude-sdk/issues"},"publishConfig":{"access":"public"},"type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"engines":{"node":">=20"},"scripts":{"build":"tsup","dev":"tsup --watch","typecheck":"tsc --noEmit","translate":"tsx scripts/translate-locale.ts"},"devDependencies":{"@modelcontextprotocol/sdk":"^1.29.0","@types/node":"^25.6.0","tsup":"^8.0.0","tsx":"^4.0.0","typescript":"^5.4.0","zod":"^4.3.6"},"peerDependencies":{"@modelcontextprotocol/sdk":">=1.0.0","zod":">=4.0.0"},"peerDependenciesMeta":{"zod":{"optional":true},"@modelcontextprotocol/sdk":{"optional":true}},"gitHead":"563fe140a427d36970507d24ec28dbf896f44660","_id":"@codrstudio/openclaude-sdk@0.4.0","_nodeVersion":"24.14.1","_npmVersion":"11.11.0","dist":{"integrity":"sha512-F7z5ZhDfxtNVKxPnPA8A9YUGc1PWO+6gCBt9yh7wHxIw94ufM5dodN4Ri7HBi1ueC3X+CMcTzPcXhDiyySjU7w==","shasum":"654ea306cf6e4cc14970f6ba648d61f47749cbf9","tarball":"https://registry.npmjs.org/@codrstudio/openclaude-sdk/-/openclaude-sdk-0.4.0.tgz","fileCount":9,"unpackedSize":794103,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@codrstudio%2fopenclaude-sdk@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIAYgyPKjykZjt9XCnuufyYRFAQk5hxLnrzMA32N9q8ihAiAuqewbr3zmLl0RqI40NWT9dJX8h+b+Qe4hRgpCsEcyig=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:b6e908e0-e790-41e6-a7ce-bed8a799d744"}},"directories":{},"maintainers":[{"name":"gugacoder","email":"guga.coder@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/openclaude-sdk_0.4.0_1776084575221_0.016849314614579614"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-09T03:19:08.722Z","modified":"2026-04-13T12:49:35.720Z","0.1.0":"2026-04-09T03:19:09.295Z","0.1.6":"2026-04-12T03:47:01.199Z","0.2.0":"2026-04-12T03:50:01.950Z","0.3.0":"2026-04-13T06:45:11.604Z","0.4.0":"2026-04-13T12:49:35.364Z"},"bugs":{"url":"https://github.com/codrstudio/openclaude-sdk/issues"},"license":"MIT","homepage":"https://github.com/codrstudio/openclaude-sdk","repository":{"type":"git","url":"git+https://github.com/codrstudio/openclaude-sdk.git"},"description":"TypeScript SDK wrapper for the OpenClaude CLI","maintainers":[{"name":"gugacoder","email":"guga.coder@gmail.com"}],"readme":"# openclaude-sdk\n\nTypeScript SDK wrapper for the OpenClaude CLI.\n\n## Installation\n\n```bash\nnpm install openclaude-sdk\n```\n\nRequires Node.js >= 20 and the [OpenClaude CLI](https://github.com/Gitlawb/openclaude) installed and available in your `PATH`.\n\n## Quick Start\n\n```typescript\nimport { query } from \"openclaude-sdk\"\n\nconst q = query({ prompt: \"Hello, world!\" })\n\nfor await (const message of q) {\n  if (message.type === \"assistant\") {\n    console.log(message.message.content)\n  }\n}\n```\n\n## API Reference\n\n### `query(params)`\n\nThe primary entry point. Returns a `Query` object — an `AsyncGenerator<SDKMessage>` decorated with extra control methods.\n\n```typescript\nfunction query(params: {\n  prompt: string\n  model?: string\n  registry?: ProviderRegistry\n  options?: Options\n}): Query\n```\n\n**Example:**\n\n```typescript\nimport { query } from \"openclaude-sdk\"\n\nconst q = query({\n  prompt: \"List files in the current directory\",\n  options: { cwd: \"/my/project\", maxTurns: 5 },\n})\n\nfor await (const msg of q) {\n  if (msg.type === \"result\") {\n    console.log(\"Result:\", msg.result)\n    console.log(\"Cost:\", msg.total_cost_usd)\n  }\n}\n```\n\nThe `Query` object also exposes:\n\n#### Core Methods\n\n| Method | Description |\n|--------|-------------|\n| `interrupt(): Promise<void>` | Gracefully interrupt the running agent (SIGINT) |\n| `close(): Promise<void>` | Terminate the subprocess (3-stage shutdown) |\n| `respondToPermission(response: PermissionResponse): void` | Respond to a tool permission request (plan mode) |\n\n#### Control Methods (fire-and-forget)\n\nSent via stdin — no response is awaited.\n\n| Method | Description |\n|--------|-------------|\n| `setModel(model?: string): void` | Change the model mid-session. `undefined` resets to default |\n| `setPermissionMode(mode: PermissionMode): void` | Change permission mode mid-session (`\"default\"`, `\"plan\"`, `\"bypassPermissions\"`, `\"dontAsk\"`) |\n| `setMaxThinkingTokens(tokens: number \\| null): void` | Set max thinking tokens mid-session. `null` to disable |\n\n#### Introspection Methods (request/response, timeout 10s)\n\nOnly available while the agent is active (during stream iteration).\n\n| Method | Return | Description |\n|--------|--------|-------------|\n| `initializationResult()` | `Promise<InitializationResult>` | Initialization result (tools, agents, MCP) |\n| `supportedCommands()` | `Promise<SlashCommand[]>` | Available slash commands |\n| `supportedModels()` | `Promise<ModelInfo[]>` | Available models |\n| `supportedAgents()` | `Promise<AgentInfo[]>` | Configured agents |\n| `mcpServerStatus()` | `Promise<McpServerStatusInfo[]>` | Status of connected MCP servers |\n| `accountInfo()` | `Promise<AccountInfo>` | Account information |\n\n**Example — mid-session control and introspection:**\n\n```typescript\nimport { query } from \"openclaude-sdk\"\n\nconst q = query({\n  prompt: \"Analyze this codebase\",\n  options: { permissionMode: \"plan\" },\n})\n\n// Change model mid-session (fire-and-forget)\nq.setModel(\"claude-sonnet-4-6\")\n\n// Check available models\nconst models = await q.supportedModels()\nconsole.log(\"Available models:\", models.map(m => m.id))\n\n// Check MCP server status\nconst mcpStatus = await q.mcpServerStatus()\nfor (const server of mcpStatus) {\n  console.log(`${server.name}: ${server.status}`)\n}\n\nfor await (const msg of q) {\n  // process messages\n}\n```\n\n> **Protocol note:** Control methods (`set*`) are fire-and-forget — they write a command to stdin and return immediately. Introspection methods are request/response — they write a command and await a reply on stdout (timeout 10s).\n\n**Exported introspection types:**\n\n```typescript\nimport type {\n  InitializationResult,\n  SlashCommand,\n  ModelInfo,\n  AgentInfo,\n  McpServerStatusInfo,\n  AccountInfo,\n} from \"openclaude-sdk\"\n```\n\n#### Operation Methods\n\n##### Request/Response Operations (timeout 30s)\n\n| Method | Return | Description |\n|--------|--------|-------------|\n| `rewindFiles(userMessageId, opts?)` | `Promise<RewindFilesResult>` | Reverts files changed by the agent back to a previous point. Pass `opts.dryRun: true` for a preview without reverting |\n| `setMcpServers(servers)` | `Promise<McpSetServersResult>` | Reconfigures MCP servers mid-session |\n\n> **Timeout note:** Request/response operations use a 30s timeout (longer than introspection) because they may involve filesystem or network operations.\n\n##### Fire-and-Forget Operations\n\n| Method | Description |\n|--------|-------------|\n| `reconnectMcpServer(serverName: string): void` | Reconnects a disconnected MCP server |\n| `toggleMcpServer(serverName: string, enabled: boolean): void` | Enables or disables a MCP server |\n| `stopTask(taskId: string): void` | Stops a specific agent task |\n\n##### Stream Operations\n\n| Method | Return | Description |\n|--------|--------|-------------|\n| `streamInput(stream: AsyncIterable<string>)` | `Promise<void>` | Sends text chunk by chunk via stdin. Blocks until the entire iterable is consumed |\n\n**Example — `rewindFiles()` with dryRun:**\n\n```typescript\nimport { query } from \"openclaude-sdk\"\n\nconst q = query({\n  prompt: \"Refactor the auth module\",\n  options: { permissionMode: \"plan\" },\n})\n\nlet lastUserMessageId: string | null = null\n\nfor await (const msg of q) {\n  if (msg.type === \"user\") {\n    lastUserMessageId = msg.uuid\n  }\n\n  if (shouldRevert && lastUserMessageId) {\n    // Preview which files would be reverted\n    const preview = await q.rewindFiles(lastUserMessageId, { dryRun: true })\n    console.log(\"Files to revert:\", preview)\n\n    // Actually revert\n    await q.rewindFiles(lastUserMessageId)\n    break\n  }\n}\n```\n\n**Example — `streamInput()` with AsyncIterable:**\n\n```typescript\nimport { query } from \"openclaude-sdk\"\n\nconst q = query({ prompt: \"Process the following data:\" })\n\nasync function* generateChunks() {\n  yield \"First chunk of data\\n\"\n  yield \"Second chunk of data\\n\"\n  yield \"Final chunk\\n\"\n}\n\n// Stream all chunks into the agent before iterating responses\nawait q.streamInput(generateChunks())\n\nfor await (const msg of q) {\n  // process messages\n}\n```\n\n**Exported operation types:**\n\n```typescript\nimport type {\n  RewindFilesResult,\n  McpSetServersResult,\n} from \"openclaude-sdk\"\n```\n\n---\n\n### `collectMessages(q)`\n\nConsumes a `Query` to completion and returns a structured result. Throws typed errors on failure.\n\n```typescript\nfunction collectMessages(q: Query): Promise<{\n  messages: SDKMessage[]\n  sessionId: string | null\n  result: string | null\n  costUsd: number\n  durationMs: number\n}>\n```\n\n**Example:**\n\n```typescript\nimport { query, collectMessages } from \"openclaude-sdk\"\n\nconst q = query({ prompt: \"What is 2 + 2?\" })\nconst { result, costUsd } = await collectMessages(q)\nconsole.log(result, costUsd)\n```\n\n---\n\n### `continueSession(params)`\n\nConvenience wrapper for resuming an existing session. Equivalent to calling `query()` with `options.resume` set.\n\n```typescript\nfunction continueSession(params: {\n  sessionId: string\n  prompt: string\n  model?: string\n  registry?: ProviderRegistry\n  options?: Options\n}): Query\n```\n\n**Example:**\n\n```typescript\nimport { continueSession } from \"openclaude-sdk\"\n\nconst q = continueSession({\n  sessionId: \"abc-123\",\n  prompt: \"Now also rename the file\",\n})\n\nfor await (const msg of q) {\n  // ...\n}\n```\n\n---\n\n### `createOpenRouterRegistry(config)`\n\nFactory that creates a `ProviderRegistry` configured for [OpenRouter](https://openrouter.ai).\n\n```typescript\nfunction createOpenRouterRegistry(config: {\n  apiKey: string\n  models: {\n    id: string\n    label: string\n    contextWindow?: number\n    supportsVision?: boolean\n  }[]\n}): ProviderRegistry\n```\n\n**Example:**\n\n```typescript\nimport { createOpenRouterRegistry, query } from \"openclaude-sdk\"\n\nconst registry = createOpenRouterRegistry({\n  apiKey: process.env.OPENROUTER_API_KEY!,\n  models: [{ id: \"anthropic/claude-3.5-sonnet\", label: \"Claude 3.5 Sonnet\" }],\n})\n\nconst q = query({\n  prompt: \"Refactor this function\",\n  model: \"anthropic/claude-3.5-sonnet\",\n  registry,\n})\n```\n\n---\n\n### `resolveModelEnv(registry, modelId)`\n\nResolves a model ID within a registry to the environment variables required by the OpenClaude CLI (e.g., `OPENAI_API_KEY`, `CLAUDE_CODE_USE_OPENAI`).\n\n```typescript\nfunction resolveModelEnv(\n  registry: ProviderRegistry,\n  modelId: string,\n): Record<string, string>\n```\n\n**Example:**\n\n```typescript\nimport { createOpenRouterRegistry, resolveModelEnv } from \"openclaude-sdk\"\n\nconst registry = createOpenRouterRegistry({ apiKey: \"...\", models: [...] })\nconst envVars = resolveModelEnv(registry, \"anthropic/claude-3.5-sonnet\")\n// { CLAUDE_CODE_USE_OPENAI: '1', OPENAI_BASE_URL: '...', OPENAI_API_KEY: '...', OPENAI_MODEL: '...' }\n```\n\n---\n\n### `listSessions(options?)`\n\nLists Claude Code sessions stored in `~/.claude/projects/`. By default performs a deep search across all project subdirectories. Results are sorted by `lastModified` descending.\n\n```typescript\nfunction listSessions(options?: ListSessionsOptions): Promise<SDKSessionInfo[]>\n\ninterface ListSessionsOptions {\n  dir?: string    // restrict to a specific working directory\n  limit?: number  // max number of results\n  deep?: boolean  // default true; set false to search root only\n}\n```\n\n**Example:**\n\n```typescript\nimport { listSessions } from \"openclaude-sdk\"\n\n// Deep search across all projects (default)\nconst all = await listSessions({ limit: 20 })\n\n// Sessions for a specific project directory\nconst project = await listSessions({ dir: \"/my/project\" })\n\n// Root only (no subdirectory traversal)\nconst root = await listSessions({ deep: false })\n```\n\n---\n\n### `getSessionMessages(sessionId, options?)`\n\nReturns the messages for a given session.\n\n```typescript\nfunction getSessionMessages(\n  sessionId: string,\n  options?: GetSessionMessagesOptions,\n): Promise<SessionMessage[]>\n\ninterface GetSessionMessagesOptions {\n  dir?: string\n  limit?: number\n  offset?: number\n}\n```\n\n**Example:**\n\n```typescript\nimport { getSessionMessages } from \"openclaude-sdk\"\n\nconst messages = await getSessionMessages(\"abc-123\", { limit: 50 })\n```\n\n---\n\n### `getSessionInfo(sessionId, options?)`\n\nReturns metadata for a single session, or `undefined` if not found.\n\n```typescript\nfunction getSessionInfo(\n  sessionId: string,\n  options?: GetSessionInfoOptions,\n): Promise<SDKSessionInfo | undefined>\n```\n\n**Example:**\n\n```typescript\nimport { getSessionInfo } from \"openclaude-sdk\"\n\nconst info = await getSessionInfo(\"abc-123\")\nconsole.log(info?.summary, info?.lastModified)\n```\n\n---\n\n### `renameSession(sessionId, title, options?)`\n\nSets a custom title for a session by appending a `custom_title` record to its JSONL file.\n\n```typescript\nfunction renameSession(\n  sessionId: string,\n  title: string,\n  options?: SessionMutationOptions,\n): Promise<void>\n```\n\n**Example:**\n\n```typescript\nimport { renameSession } from \"openclaude-sdk\"\n\nawait renameSession(\"abc-123\", \"Refactor auth module\")\n```\n\n---\n\n### `tagSession(sessionId, tag, options?)`\n\nAdds or removes a tag on a session. Pass `null` to clear the tag.\n\n```typescript\nfunction tagSession(\n  sessionId: string,\n  tag: string | null,\n  options?: SessionMutationOptions,\n): Promise<void>\n```\n\n**Example:**\n\n```typescript\nimport { tagSession } from \"openclaude-sdk\"\n\nawait tagSession(\"abc-123\", \"reviewed\")\nawait tagSession(\"abc-123\", null) // remove tag\n```\n\n---\n\n## Options\n\nAll `Options` fields are optional. They are passed via `query({ options })` or `continueSession({ options })`.\n\n### Execution\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `cwd` | `string` | Working directory for the agent subprocess |\n| `model` | `string` | Model identifier (e.g. `\"claude-sonnet-4-6\"`) |\n| `maxTurns` | `number` | Maximum number of agent turns |\n| `maxBudgetUsd` | `number` | Spend cap in USD; throws `MaxBudgetError` when exceeded |\n| `timeoutMs` | `number` | Timeout in milliseconds for the agent subprocess |\n| `effort` | `\"low\" \\| \"medium\" \\| \"high\" \\| \"max\"` | Controls agent effort level |\n| `thinking` | `ThinkingConfig` | Controls extended thinking (`adaptive`, `enabled`, `disabled`) |\n\n### Permissions\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `permissionMode` | `PermissionMode` | `\"default\"` \\| `\"plan\"` \\| `\"bypassPermissions\"` \\| `\"dontAsk\"` — controls how tool use is approved |\n| `allowDangerouslySkipPermissions` | `boolean` | Skip all permission prompts (use with care) |\n| `allowedTools` | `string[]` | Whitelist of tool names the agent may use |\n| `disallowedTools` | `string[]` | Blacklist of tool names the agent may not use |\n\n### Session\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `resume` | `string` | Session ID to resume from |\n| `continue` | `boolean` | Continue the most recent session |\n| `sessionId` | `string` | Explicit session ID to use |\n\n### Prompt\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `systemPrompt` | `string \\| { type: \"preset\"; preset: \"claude_code\"; append?: string }` | Override or extend the system prompt |\n\n### Output\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `outputFormat` | `{ type: \"json_schema\"; schema: unknown }` | Request structured JSON output matching the provided schema (uses `--json-schema`) |\n\n### Advanced\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `additionalDirectories` | `string[]` | Extra directories to make available to the agent (`--add-dir`) |\n| `betas` | `SdkBeta[]` | Enable beta features (e.g. `\"context-1m-2025-08-07\"`) |\n| `extraArgs` | `Record<string, string \\| null>` | Pass arbitrary CLI flags; `null` value emits a bare flag (e.g. `{ verbose: null }` → `--verbose`) |\n| `mcpServers` | `Record<string, McpServerConfig>` | MCP server definitions (stdio, SSE, or HTTP) to pass to the agent |\n| `env` | `Record<string, string>` | Additional environment variables for the subprocess |\n| `pathToClaudeCodeExecutable` | `string` | Override the path to the OpenClaude executable (default: `\"openclaude\"`) |\n\n---\n\n## Error Handling\n\n`collectMessages()` throws typed errors when the agent terminates abnormally. Use `isRecoverable()` to decide whether to retry.\n\n### Error Hierarchy\n\n```\nOpenClaudeError\n├── AuthenticationError      (fatal)\n├── BillingError             (fatal)\n├── InvalidRequestError      (fatal)\n├── MaxTurnsError            (fatal)\n├── MaxBudgetError           (fatal)\n├── ExecutionError           (fatal)\n├── StructuredOutputError    (fatal)\n├── RateLimitError           (recoverable — has resetsAt, utilization)\n└── ServerError              (recoverable)\n```\n\n```typescript\nimport { query, collectMessages, isRecoverable, RateLimitError } from \"openclaude-sdk\"\n\nasync function run(prompt: string) {\n  const q = query({ prompt })\n  try {\n    const { result } = await collectMessages(q)\n    return result\n  } catch (err) {\n    if (err instanceof RateLimitError) {\n      console.log(\"Rate limited, resets at:\", err.resetsAt)\n    }\n    if (isRecoverable(err)) {\n      console.log(\"Recoverable error, can retry:\", err.message)\n    } else {\n      console.error(\"Fatal error:\", err.message)\n    }\n    throw err\n  }\n}\n```\n\n### Error Classes\n\nAll errors extend `OpenClaudeError` which provides:\n\n| Property | Type | Description |\n|----------|------|-------------|\n| `code` | `string` | Machine-readable error code |\n| `message` | `string` | Human-readable description |\n| `sessionId` | `string \\| null` | Session ID at time of failure |\n| `costUsd` | `number` | Spend up to the point of failure |\n| `durationMs` | `number` | Duration up to the point of failure |\n\n### Error Table\n\n| Class | Code | `isRecoverable` | When thrown |\n|-------|------|-----------------|-------------|\n| `AuthenticationError` | `authentication_failed` | false | Invalid API key or credentials |\n| `BillingError` | `billing_error` | false | Account billing issue |\n| `InvalidRequestError` | `invalid_request` | false | Malformed request |\n| `RateLimitError` | `rate_limit` | **true** | API rate limit hit (has `resetsAt?`, `utilization?`) |\n| `ServerError` | `server_error` | **true** | Transient server failure |\n| `MaxTurnsError` | `max_turns` | **true** | Agent exceeded `maxTurns` |\n| `MaxBudgetError` | `max_budget_usd` | **true** | Agent exceeded `maxBudgetUsd` |\n| `ExecutionError` | `execution_error` | **true** | Runtime execution error |\n| `StructuredOutputError` | `structured_output_retries` | **true** | Max retries for structured output exceeded |\n\n---\n\n## Provider Registry\n\nUse a `ProviderRegistry` to route requests through any OpenAI-compatible provider (e.g. OpenRouter) without managing environment variables manually.\n\n```typescript\nimport { createOpenRouterRegistry, DEFAULT_MODEL, query, collectMessages } from \"openclaude-sdk\"\n\nconst registry = createOpenRouterRegistry({\n  apiKey: process.env.OPENROUTER_API_KEY!,\n  models: [\n    DEFAULT_MODEL, // GLM 4.7 Flash — best cost/quality ratio\n    {\n      id: \"google/gemini-2.5-pro-preview-06-05\",\n      label: \"Gemini 2.5 Pro\",\n      contextWindow: 1000000,\n    },\n  ],\n})\n\nconst q = query({\n  prompt: \"Summarize this codebase\",\n  model: DEFAULT_MODEL.id,\n  registry,\n  options: { cwd: \"/my/project\" },\n})\n\nconst { result } = await collectMessages(q)\nconsole.log(result)\n```\n\nThe SDK automatically resolves the model to the correct CLI environment variables (`CLAUDE_CODE_USE_OPENAI`, `OPENAI_BASE_URL`, `OPENAI_API_KEY`, `OPENAI_MODEL`).\n\n---\n\n## Session Management\n\n### List sessions (deep search)\n\nBy default, `listSessions()` traverses all project subdirectories under `~/.claude/projects/` to aggregate sessions across every project:\n\n```typescript\nimport { listSessions, continueSession, collectMessages } from \"openclaude-sdk\"\n\n// Find the most recent session\nconst [latest] = await listSessions({ limit: 1 })\nconsole.log(latest.sessionId, latest.summary)\n\n// Continue it with a new prompt\nconst q = continueSession({\n  sessionId: latest.sessionId,\n  prompt: \"Now add unit tests for what you just wrote\",\n})\n\nconst { result } = await collectMessages(q)\nconsole.log(result)\n```\n\n### Resume a known session\n\n```typescript\nimport { query } from \"openclaude-sdk\"\n\nconst q = query({\n  prompt: \"Fix the bug we found earlier\",\n  options: { resume: \"abc-123\" },\n})\n\nfor await (const msg of q) {\n  // ...\n}\n```\n\n---\n\n## V2 Session API\n\nA V2 Session API é o padrão recomendado para conversas multi-turn, substituindo o gerenciamento manual de `sessionId`.\n\n### `createSession(opts?)`\n\n```typescript\nfunction createSession(opts?: CreateSessionOptions): SDKSession\n\ninterface CreateSessionOptions {\n  model?: string\n  registry?: ProviderRegistry\n  options?: Options\n  sessionId?: string  // auto-gerado se omitido\n}\n```\n\n### Interface `SDKSession`\n\n| Método | Retorno | Descrição |\n|--------|---------|-----------|\n| `send(prompt, options?)` | `Query` | Envia mensagem e retorna stream (AsyncGenerator) |\n| `collect(prompt, options?)` | `Promise<{ messages, result, costUsd, durationMs }>` | Envia e coleta resultado completo |\n| `close()` | `Promise<void>` | Fecha a sessão e mata query ativa |\n| `[Symbol.asyncDispose]()` | `Promise<void>` | Suporte a `await using` |\n\n### Exemplo: Multi-turn com streaming\n\n```typescript\nimport { createSession } from \"openclaude-sdk\"\n\nawait using session = createSession({ model: \"sonnet\" })\n\n// Turno 1 — streaming\nfor await (const msg of session.send(\"Create a hello.ts file\")) {\n  if (msg.type === \"assistant\") {\n    console.log(msg.message.content)\n  }\n}\n\n// Turno 2 — coleta completa\nconst result = await session.collect(\"Now add error handling\")\nconsole.log(result.result)\n```\n\n### `resumeSession(sessionId, opts?)`\n\n```typescript\nfunction resumeSession(sessionId: string, opts?: ResumeSessionOptions): SDKSession\n\ninterface ResumeSessionOptions {\n  model?: string\n  registry?: ProviderRegistry\n  options?: Options\n}\n```\n\n**Exemplo:**\n\n```typescript\nimport { resumeSession } from \"openclaude-sdk\"\n\nconst session = resumeSession(\"abc-123-def\")\nconst result = await session.collect(\"Continue where we left off\")\nawait session.close()\n```\n\n### `prompt(text, opts?)` — one-shot\n\n```typescript\nfunction prompt(text: string, opts?: PromptOptions): Promise<{\n  result: string | null\n  sessionId: string | null\n  costUsd: number\n  durationMs: number\n}>\n```\n\n**Exemplo:**\n\n```typescript\nimport { prompt } from \"openclaude-sdk\"\n\nconst { result, costUsd } = await prompt(\"What is 2 + 2?\")\nconsole.log(result) // \"4\"\n```\n\n### Nota sobre `await using`\n\n`SDKSession` implementa `AsyncDisposable` — `await using` garante cleanup automático mesmo em caso de exceção. Requer TypeScript >= 5.2 com `target: \"ES2022\"` ou superior.\n\n### Comparação V1 vs V2\n\n| Aspecto | V1 (`query` + `continueSession`) | V2 (`createSession`) |\n|---------|----------------------------------|----------------------|\n| Gerenciamento de sessionId | Manual | Automático |\n| Multi-turn | `continueSession()` a cada turno | `session.send()` encadeia |\n| Cleanup | Manual (`q.close()`) | `await using` |\n| One-shot | `query()` + `collectMessages()` | `prompt()` |\n\n### Tipos exportados\n\n```typescript\nimport type {\n  SDKSession,\n  CreateSessionOptions,\n  ResumeSessionOptions,\n  PromptOptions,\n} from \"openclaude-sdk\"\n```\n\n---\n\n## Plan Mode\n\nIn `\"plan\"` permission mode the agent pauses before executing tools and emits a permission request. Use `respondToPermission()` on the `Query` object to approve or deny each request.\n\n```typescript\nimport { query } from \"openclaude-sdk\"\n\nconst q = query({\n  prompt: \"Delete all .log files in /tmp\",\n  options: {\n    permissionMode: \"plan\",\n    cwd: \"/tmp\",\n  },\n})\n\nfor await (const msg of q) {\n  if (msg.type === \"assistant\" && msg.message?.content) {\n    // Agent is asking for permission to use a tool\n    const content = msg.message.content\n    if (Array.isArray(content)) {\n      for (const block of content) {\n        if (block.type === \"tool_use\") {\n          const approved = block.name !== \"Bash\" // approve everything except Bash\n          q.respondToPermission({\n            toolUseId: block.id,\n            behavior: approved ? \"allow\" : \"deny\",\n            message: approved ? undefined : \"Bash execution not allowed\",\n          })\n        }\n      }\n    }\n  }\n}\n```\n\n`respondToPermission` serializes a JSON response to the agent's stdin with the shape:\n\n```json\n{\n  \"tool_use_id\": \"...\",\n  \"behavior\": \"allow\" | \"deny\",\n  \"message\": \"optional denial reason\"\n}\n```\n\n> **Note:** `stdin` is kept open automatically in `plan` mode. It is closed after the initial prompt only in `bypassPermissions` and `dontAsk` modes.\n\n---\n\n## Permission Mid-Stream\n\nWhen `permissionMode` is `\"plan\"`, the agent pauses before executing tools and waits for your decision. Call `respondToPermission()` on the `Query` object to approve or deny each request mid-stream.\n\n```typescript\nimport { query } from \"openclaude-sdk\"\n\nconst q = query({\n  prompt: \"Create a new file called hello.txt\",\n  options: { permissionMode: \"plan\" },\n})\n\nfor await (const msg of q) {\n  if (msg.type === \"assistant\" && msg.message?.content) {\n    const content = msg.message.content\n    if (Array.isArray(content)) {\n      for (const block of content) {\n        if (block.type === \"tool_use\") {\n          q.respondToPermission({\n            toolUseId: block.id,\n            behavior: \"allow\",\n            message: \"Approved by automation\",\n          })\n        }\n      }\n    }\n  }\n}\n```\n\nKey points:\n\n- `permissionMode: \"plan\"` keeps `stdin` open so responses can be sent during iteration\n- `behavior: \"deny\"` rejects the action — the agent will attempt an alternative approach\n- `message` is optional and provides a reason (shown to the agent on denial)\n\n## MCP Tool Factories\n\nMCP tool factories permitem definir tools inline em TypeScript e registrá-las num servidor in-process, sem precisar de um servidor MCP externo separado.\n\n> **Peer dependencies:** `zod` e `@modelcontextprotocol/sdk` devem estar instalados no seu projeto.\n\n### `tool(name, description, inputSchema, handler, extras?)`\n\n```typescript\nfunction tool<Schema extends z.ZodRawShape>(\n  name: string,\n  description: string,\n  inputSchema: Schema,\n  handler: (args: z.infer<z.ZodObject<Schema>>, extra: unknown) => Promise<CallToolResult>,\n  extras?: { annotations?: ToolAnnotations },\n): SdkMcpToolDefinition<Schema>\n```\n\n| Parâmetro | Tipo | Descrição |\n|-----------|------|-----------|\n| `name` | `string` | Nome da tool (visível ao agente) |\n| `description` | `string` | Descrição da tool (usada pelo agente para decidir quando invocar) |\n| `inputSchema` | `z.ZodRawShape` | Schema Zod dos parâmetros de entrada |\n| `handler` | `(args, extra) => Promise<CallToolResult>` | Função async que executa a tool |\n| `extras.annotations` | `ToolAnnotations` | Anotações opcionais de comportamento |\n\n### `createSdkMcpServer(options)`\n\n```typescript\nasync function createSdkMcpServer(options: {\n  name: string\n  version?: string\n  tools?: Array<SdkMcpToolDefinition<any>>\n}): Promise<McpSdkServerConfig>\n```\n\nRetorna um `Promise<McpSdkServerConfig>` com `type: \"sdk\"` que pode ser passado diretamente em `options.mcpServers`. O servidor roda in-process — sem porta de rede, sem processo filho.\n\n### Exemplo end-to-end\n\n```typescript\nimport { z } from \"zod\"\nimport { tool, createSdkMcpServer, query, collectMessages } from \"openclaude-sdk\"\n\n// 1. Definir tools\nconst weatherTool = tool(\n  \"get_weather\",\n  \"Get current weather for a city\",\n  { city: z.string().describe(\"City name\") },\n  async ({ city }) => ({\n    content: [{ type: \"text\", text: `Weather in ${city}: 22°C, sunny` }],\n  }),\n)\n\nconst timeTool = tool(\n  \"get_time\",\n  \"Get current time in a timezone\",\n  { timezone: z.string().describe(\"IANA timezone\") },\n  async ({ timezone }) => ({\n    content: [{ type: \"text\", text: `Current time in ${timezone}: ${new Date().toISOString()}` }],\n  }),\n  { annotations: { readOnly: true } },\n)\n\n// 2. Criar servidor in-process\nconst mcpServer = await createSdkMcpServer({\n  name: \"my-tools\",\n  tools: [weatherTool, timeTool],\n})\n\n// 3. Usar com query\nconst q = query({\n  prompt: \"What's the weather in Tokyo?\",\n  options: {\n    mcpServers: { \"my-tools\": mcpServer },\n  },\n})\n\nconst { result } = await collectMessages(q)\nconsole.log(result)\n```\n\n### `ToolAnnotations`\n\n| Campo | Tipo | Descrição |\n|-------|------|-----------|\n| `readOnly` | `boolean` | Tool apenas lê dados, não modifica estado |\n| `destructive` | `boolean` | Tool pode causar efeitos destrutivos |\n| `idempotent` | `boolean` | Múltiplas execuções produzem o mesmo resultado |\n| `openWorld` | `boolean` | Tool acessa recursos externos (rede, filesystem) |\n\n### Tipos exportados\n\n```typescript\nimport type {\n  SdkMcpToolDefinition,\n  ToolAnnotations,\n  CallToolResult,\n} from \"openclaude-sdk\"\n```\n\n## External MCP Servers\n\nAlém de MCP tool factories (inline), o SDK suporta conexão a servidores MCP externos via stdio, SSE e HTTP através do campo `mcpServers` em `Options`.\n\n### Servidor stdio (processo local)\n\n```typescript\nimport { query } from \"openclaude-sdk\"\n\nconst q = query({\n  prompt: \"Search for TypeScript best practices\",\n  options: {\n    mcpServers: {\n      \"brave-search\": {\n        type: \"stdio\",\n        command: \"npx\",\n        args: [\"-y\", \"@anthropic-ai/brave-search-mcp\"],\n        env: { BRAVE_API_KEY: process.env.BRAVE_API_KEY! },\n      },\n    },\n  },\n})\n```\n\n### Servidor SSE com autenticação\n\n```typescript\nimport { query } from \"openclaude-sdk\"\n\nconst q = query({\n  prompt: \"List recent deployments\",\n  options: {\n    mcpServers: {\n      \"deploy-api\": {\n        type: \"sse\",\n        url: \"https://mcp.example.com/sse\",\n        headers: {\n          Authorization: `Bearer ${process.env.API_TOKEN}`,\n        },\n      },\n    },\n  },\n})\n```\n\n### Servidor HTTP com header de API\n\n```typescript\nimport { query } from \"openclaude-sdk\"\n\nconst q = query({\n  prompt: \"Query the database\",\n  options: {\n    mcpServers: {\n      \"db-server\": {\n        type: \"http\",\n        url: \"https://mcp.example.com/mcp\",\n        headers: {\n          \"X-API-Key\": process.env.DB_API_KEY!,\n        },\n      },\n    },\n  },\n})\n```\n\n### Combinando servidores inline e externos\n\n```typescript\nimport { query, tool, createSdkMcpServer } from \"openclaude-sdk\"\nimport { z } from \"zod\"\n\n// Servidor inline (in-process)\nconst myTools = await createSdkMcpServer({\n  name: \"my-tools\",\n  tools: [\n    tool(\"greet\", \"Greet a user\", { name: z.string() }, async ({ name }) => ({\n      content: [{ type: \"text\", text: `Hello, ${name}!` }],\n    })),\n  ],\n})\n\nconst q = query({\n  prompt: \"Search for news and greet the user\",\n  options: {\n    mcpServers: {\n      // Servidor externo via stdio\n      \"brave-search\": {\n        type: \"stdio\",\n        command: \"npx\",\n        args: [\"-y\", \"@anthropic-ai/brave-search-mcp\"],\n        env: { BRAVE_API_KEY: process.env.BRAVE_API_KEY! },\n      },\n      // Servidor inline SDK\n      \"my-tools\": myTools,\n    },\n  },\n})\n```\n\n### Tipos de servidor\n\n| Tipo | Interface | Campos | Uso |\n|------|-----------|--------|-----|\n| `stdio` | `McpStdioServerConfig` | `command`, `args?`, `env?` | Servidores locais via stdin/stdout |\n| `sse` | `McpSSEServerConfig` | `url`, `headers?` | Servidores remotos via Server-Sent Events |\n| `http` | `McpHttpServerConfig` | `url`, `headers?` | Servidores remotos via HTTP |\n| `sdk` | `McpSdkServerConfig` | `name`, `instance` | Servidores inline (via `createSdkMcpServer()`) |\n\n### Variáveis de ambiente em servidores stdio\n\nO campo `env` de um servidor stdio é mesclado ao ambiente do processo filho — as variáveis do processo pai (`process.env`) já estão disponíveis automaticamente. Use `env` para adicionar ou sobrescrever variáveis específicas do servidor, como chaves de API.\n\n## Rich Output\n\nA flag `richOutput` ativa um conjunto de 4 MCP tools built-in que permitem ao modelo emitir **conteúdo visual estruturado** (gráficos, tabelas, produtos, métricas, etc.) como `tool_use` blocks no stream. O cliente detecta esses blocks e os renderiza como widgets ricos.\n\nQuando `richOutput: false` (padrão), nenhum servidor MCP é registrado e o system prompt não é modificado — **zero overhead**.\n\nQuando `richOutput: true`, o SDK automaticamente:\n1. Registra um servidor MCP in-process com as 4 display tools\n2. Injeta uma instrução curta no system prompt explicando quando usar cada tool\n\n### As 4 meta-tools de display\n\n| Tool | Actions | Propósito |\n|------|---------|-----------|\n| `display_highlight` | `metric`, `price`, `alert`, `choices` | Destaque de informação pontual |\n| `display_collection` | `table`, `spreadsheet`, `comparison`, `carousel`, `gallery`, `sources` | Coleção de itens |\n| `display_card` | `product`, `link`, `file`, `image` | Item individual com detalhes |\n| `display_visual` | `chart`, `map`, `code`, `progress`, `steps` | Visualização especializada |\n\nCada tool recebe um campo `action` que seleciona o tipo de conteúdo, mais os campos específicos daquela action.\n\n### Exemplo end-to-end\n\n```typescript\nimport { query } from \"openclaude-sdk\"\n\nconst q = query({\n  prompt: \"Compare the top 3 laptops under $1500 with specs and prices\",\n  options: {\n    richOutput: true,\n  },\n})\n\nfor await (const msg of q) {\n  if (msg.type === \"assistant\") {\n    for (const block of msg.message.content) {\n      if (block.type === \"tool_use\" && block.name?.startsWith(\"display_\")) {\n        // Bloco de display tool — renderizar como widget rico\n        console.log(`[rich] ${block.name}:`, block.input)\n      } else if (block.type === \"text\") {\n        console.log(block.text)\n      }\n    }\n  }\n}\n```\n\n### Validação client-side com `DisplayToolRegistry`\n\n`DisplayToolRegistry` é um `Record<nome, schema>` com os 19 schemas base. Use-o para validar o `input` de um `tool_use` block antes de renderizar:\n\n```typescript\nimport { DisplayToolRegistry } from \"openclaude-sdk\"\n\nfunction handleDisplayBlock(name: string, input: unknown) {\n  const schema = DisplayToolRegistry[name as keyof typeof DisplayToolRegistry]\n  if (!schema) return // tool desconhecida\n\n  const result = schema.safeParse(input)\n  if (!result.success) {\n    console.warn(`Invalid display input for ${name}:`, result.error)\n    return\n  }\n\n  // input validado — despachar para renderer\n  render(name, result.data)\n}\n```\n\n### Schemas exportados\n\nTodos os 19 schemas e tipos estão disponíveis como exports públicos:\n\n```typescript\nimport {\n  DisplayMetricSchema,\n  DisplayChartSchema,\n  DisplayTableSchema,\n  DisplayProgressSchema,\n  DisplayProductSchema,\n  DisplayComparisonSchema,\n  DisplayPriceSchema,\n  DisplayImageSchema,\n  DisplayGallerySchema,\n  DisplayCarouselSchema,\n  DisplaySourcesSchema,\n  DisplayLinkSchema,\n  DisplayMapSchema,\n  DisplayFileSchema,\n  DisplayCodeSchema,\n  DisplaySpreadsheetSchema,\n  DisplayStepsSchema,\n  DisplayAlertSchema,\n  DisplayChoicesSchema,\n  DisplayToolRegistry,\n} from \"openclaude-sdk\"\n\nimport type {\n  DisplayMetric,\n  DisplayChart,\n  DisplayTable,\n  DisplayToolName,\n} from \"openclaude-sdk\"\n```\n\n### React Rich Output\n\nA flag `reactOutput` estende o Rich Output adicionando a action `react` ao `display_visual`, permitindo que o modelo emita **componentes React funcionais com Framer Motion** que o cliente transpila e renderiza como widgets animados.\n\n`reactOutput` só tem efeito quando `richOutput` também está ativo — caso contrário é ignorado silenciosamente (sem warn, sem erro).\n\n#### Gate das duas flags\n\n| `richOutput` | `reactOutput` | Resultado |\n|---|---|---|\n| `false` / ausente | qualquer | Nada injetado — zero overhead |\n| `true` | `false` / ausente | Display tools ativas **sem** action `react` |\n| `true` | `true` | Display tools ativas **com** action `react` + system prompt React |\n\n#### Exemplo end-to-end\n\n```typescript\nimport { query } from \"openclaude-sdk\"\n\nconst q = query({\n  prompt: \"Monta um dashboard animado com 4 KPIs de vendas e um chart de linha\",\n  options: {\n    richOutput: true,\n    reactOutput: true,\n  },\n})\n\nfor await (const msg of q) {\n  if (msg.type === \"assistant\") {\n    for (const block of msg.message.content) {\n      if (block.type === \"tool_use\" && block.name === \"display_visual\") {\n        const input = block.input as { action: string }\n        if (input.action === \"react\") {\n          console.log(\"[react payload]\", input)\n          // host: validate -> transpile -> sandbox -> render\n        }\n      }\n    }\n  }\n}\n```\n\n#### Pipeline obrigatório do cliente\n\nO SDK **não renderiza** — apenas transmite o payload. O host é responsável por seguir este pipeline antes de montar o componente:\n\n1. **VALIDATE** — `version === \"1\"`, todos os `imports[].module` na whitelist (`react` | `framer-motion`), nenhum import no `code` fora dos declarados em `imports`, `code.length <= 8 KB`, `JSON.stringify(initialProps).length <= 32 KB`.\n\n2. **TRANSPILE** — Use Babel standalone com preset `[\"react\"]` (+ `\"typescript\"` se `language === \"tsx\"`), ou sucrase com transforms `[\"jsx\", \"typescript\"]`. Extrai o `export default`.\n\n3. **SANDBOX** — Renderize dentro de um `<iframe sandbox=\"allow-scripts\">` em origin distinto, ou shadow DOM com escopo restrito.\n\n4. **INJECT SCOPE** — Forneça apenas `react` e `framer-motion` como resolver de módulos. Qualquer outro import deve lançar erro em tempo de resolução.\n\n5. **RENDER** — Monte como `<Component {...payload.initialProps} />` dentro de um error boundary. Envolva em `<MotionConfig reducedMotion=\"user\">`. Respeite `layout.height` / `layout.aspectRatio` no container.\n\n6. **THEME** — Se `payload.theme` estiver definido, exponha as variáveis CSS (`--fg`, `--bg`, `--accent`, `--muted`) no container host antes de montar.\n\n> **Nota de segurança:** O passo 3 (sandbox) é **obrigatório**. Avaliar código gerado por LLM no origin principal com acesso a dados do usuário é uma vulnerabilidade crítica. Hosts que pulam o sandbox expõem usuários a execução arbitrária de código.\n\n### Ask User\n\nEnable `askUser` to let the agent pause and ask the user structured questions mid-task:\n\n```typescript\nimport { query } from \"openclaude-sdk\"\nimport type { AskUserRequest } from \"openclaude-sdk\"\n\nconst q = query({\n  prompt: \"Book a meeting for next week with the marketing team\",\n  options: { askUser: true },\n})\n\nq.onAskUser((req: AskUserRequest) => {\n  console.log(`[agent asks] ${req.question}`)\n\n  if (req.inputType === \"choice\" && req.choices) {\n    q.respondToAskUser(req.callId, { type: \"choice\", id: req.choices[0].id })\n  } else {\n    q.respondToAskUser(req.callId, { type: \"text\", value: \"Tuesday 2pm\" })\n  }\n})\n\nfor await (const msg of q) {\n  // process messages...\n}\n```\n\n**Options:**\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `askUser` | `boolean` | `false` | Enable the ask_user built-in tool |\n| `askUserTimeoutMs` | `number` | `undefined` | Auto-cancel unanswered questions after N ms |\n\n**Input types:**\n\n| inputType | Answer type | When to use |\n|-----------|-------------|-------------|\n| `text` | `{ type: \"text\", value: string }` | Free-form text input |\n| `number` | `{ type: \"number\", value: number }` | Numeric values |\n| `boolean` | `{ type: \"boolean\", value: boolean }` | Yes/no confirmations |\n| `choice` | `{ type: \"choice\", id: string }` | Discrete options (requires `choices` array) |\n\nTo cancel a pending question:\n\n```typescript\nq.respondToAskUser(req.callId, { type: \"cancelled\" })\n```\n\n`askUser` and `richOutput` are orthogonal — both can be enabled simultaneously.\n","readmeFilename":"README.md"}