@nimblebrain/synapse 0.21.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +4 -4
  2. package/dist/{check-VK4SOAUU.cjs → check-53RMGOVV.cjs} +8 -7
  3. package/dist/check-53RMGOVV.cjs.map +1 -0
  4. package/dist/{check-QMTOCTRS.js → check-CSE4XQRL.js} +8 -7
  5. package/dist/check-CSE4XQRL.js.map +1 -0
  6. package/dist/{chunk-ISV6HFQE.cjs → chunk-5FU64TOX.cjs} +3 -3
  7. package/dist/{chunk-ISV6HFQE.cjs.map → chunk-5FU64TOX.cjs.map} +1 -1
  8. package/dist/{chunk-H3INUKA3.js → chunk-H445DB4L.js} +3 -3
  9. package/dist/{chunk-H3INUKA3.js.map → chunk-H445DB4L.js.map} +1 -1
  10. package/dist/{chunk-TR2YNWZ5.js → chunk-QKSKSSD5.js} +5 -12
  11. package/dist/chunk-QKSKSSD5.js.map +1 -0
  12. package/dist/{chunk-HQLSVUOR.cjs → chunk-UN6PDZSL.cjs} +14 -21
  13. package/dist/chunk-UN6PDZSL.cjs.map +1 -0
  14. package/dist/codegen/cli.cjs +1 -1
  15. package/dist/codegen/cli.js +1 -1
  16. package/dist/codegen/index.d.cts +1 -1
  17. package/dist/codegen/index.d.ts +1 -1
  18. package/dist/connect.iife.global.js +15 -15
  19. package/dist/index.cjs +12 -12
  20. package/dist/index.d.cts +7 -5
  21. package/dist/index.d.ts +7 -5
  22. package/dist/index.js +3 -3
  23. package/dist/react/index.cjs +9 -12
  24. package/dist/react/index.cjs.map +1 -1
  25. package/dist/react/index.d.cts +2 -5
  26. package/dist/react/index.d.ts +2 -5
  27. package/dist/react/index.js +3 -6
  28. package/dist/react/index.js.map +1 -1
  29. package/dist/synapse-runtime.iife.global.js +15 -15
  30. package/dist/{types-BxPfGHKO.d.cts → types-BBoCSg35.d.cts} +4 -7
  31. package/dist/{types-BxPfGHKO.d.ts → types-BBoCSg35.d.ts} +4 -7
  32. package/dist/vite/index.cjs +5 -5
  33. package/dist/vite/index.js +1 -1
  34. package/package.json +1 -1
  35. package/dist/check-QMTOCTRS.js.map +0 -1
  36. package/dist/check-VK4SOAUU.cjs.map +0 -1
  37. package/dist/chunk-HQLSVUOR.cjs.map +0 -1
  38. package/dist/chunk-TR2YNWZ5.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts","../src/internals.ts","../src/result-parser.ts","../src/task-handle.ts","../src/content-parser.ts","../src/keyboard.ts","../src/resize.ts","../src/connect.ts","../src/extensions.ts"],"names":["raw","ExtAppsApp"],"mappings":"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","file":"chunk-QKSKSSD5.js","sourcesContent":["/**\n * Thrown when an app asks for something the host did not declare in\n * `ui/initialize`.\n *\n * The request is never sent. A host that does not implement a request may never\n * answer it, and this SDK's requests carry no deadline, so sending anyway would\n * leave the caller waiting forever rather than failing.\n *\n * `capability` names what was missing, as the host would have declared it: a\n * `hostCapabilities` field (`serverTools`, `downloadFile`) or an extension\n * identifier (`ai.nimblebrain/request-file`, `io.modelcontextprotocol/tasks`).\n */\nexport class HostCapabilityError extends Error {\n readonly capability: string;\n\n constructor(feature: string, capability: string) {\n super(`${feature} is not supported in this host: it did not declare ${capability}`);\n this.name = \"HostCapabilityError\";\n this.capability = capability;\n }\n}\n","/**\n * The plumbing the SDK's own composable helpers reach through — the file\n * picker, `action`, `downloadFile`, `callToolAsTask`.\n *\n * It lives in a module-private `WeakMap` rather than on the `App` object,\n * because those two options are not equivalent. A `_internals` member is still\n * a member: it type-checks, autocompletes, survives `Object.keys`, and hands\n * every consumer a transport the SDK does not model a use for. Underscore and\n * an `@internal` tag are a request, not a boundary, and a request is what the\n * removed `Synapse._request` was — which is exactly how a bridge script ended\n * up hand-rolling its own `tools/call`.\n *\n * So the public type is the protocol surface and nothing else, and the seam is\n * genuinely closed: a caller who needs something the SDK does not expose gets a\n * named method for it, or the SDK is missing a feature.\n */\nimport type { App, AppInternals } from \"./types.js\";\n\nconst INTERNALS = new WeakMap<App, AppInternals>();\n\n/** Called once by `connect()` for each app it builds. */\nexport function registerInternals(app: App, internals: AppInternals): void {\n INTERNALS.set(app, internals);\n}\n\n/**\n * The plumbing behind an app. Throws if `app` did not come from this copy of\n * the SDK — which is what a duplicated install looks like, and is worth failing\n * loudly for rather than as an undefined-property read three frames later.\n */\nexport function internalsFor(app: App): AppInternals {\n const internals = INTERNALS.get(app);\n if (!internals) {\n throw new Error(\n \"This App did not come from this copy of @nimblebrain/synapse. \" +\n \"Two copies of the package are installed (check for a duplicate in your \" +\n \"lockfile, or a bundler resolving the ESM and CJS builds separately).\",\n );\n }\n return internals;\n}\n","import type { ToolCallResult } from \"./types.js\";\n\n/**\n * Normalize a raw tool call response into a consistent `ToolCallResult`.\n *\n * Handles three shapes:\n * 1. MCP `CallToolResult` — has a `content` array with typed blocks.\n * 2. Raw JSON object (NimbleBrain bridge) — used as-is.\n * 3. Null / undefined — returns `{ data: null, isError: false }`.\n *\n * `_meta` on a `CallToolResult` is preserved on the parsed output as a\n * whole-object passthrough — notably `io.modelcontextprotocol/related-task`\n * (`{ taskId }`) for MCP 2025-11-25 task-augmented results, but any other\n * namespaced `_meta` keys propagate for free.\n */\nexport function parseToolResult(raw: unknown): ToolCallResult {\n if (raw == null) {\n return { data: null, isError: false };\n }\n\n if (isCallToolResult(raw)) {\n return parseCallToolResult(raw);\n }\n\n // Raw JSON object — pass through.\n return { data: raw, isError: false };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\ninterface McpTextBlock {\n type: \"text\";\n text: string;\n}\n\ninterface McpCallToolResult {\n content: unknown[];\n isError?: boolean;\n _meta?: { [key: string]: unknown };\n}\n\nfunction isCallToolResult(value: unknown): value is McpCallToolResult {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n return false;\n }\n return Array.isArray((value as Record<string, unknown>).content);\n}\n\nfunction isTextBlock(block: unknown): block is McpTextBlock {\n if (block === null || typeof block !== \"object\" || Array.isArray(block)) {\n return false;\n }\n const obj = block as Record<string, unknown>;\n return obj.type === \"text\" && typeof obj.text === \"string\";\n}\n\n/**\n * Extract `_meta` as a shallow-copied object if present and object-shaped.\n *\n * Key-preserving by design: every `_meta` entry propagates without\n * selective copying, so future spec additions flow through without code\n * changes. Returns `undefined` when the input has no meaningful `_meta`.\n */\nfunction extractMeta(result: McpCallToolResult): { [key: string]: unknown } | undefined {\n const meta = result._meta;\n if (!meta || typeof meta !== \"object\" || Array.isArray(meta)) return undefined;\n // Shallow spread so mutations on either side don't leak. Preserves the\n // full key set including `io.modelcontextprotocol/related-task`.\n return { ...meta };\n}\n\nfunction parseCallToolResult(result: McpCallToolResult): ToolCallResult {\n const isError = result.isError === true;\n const content = result.content;\n const meta = extractMeta(result);\n\n if (content.length === 0) {\n return { data: null, isError, content, ...(meta && { _meta: meta }) };\n }\n\n const firstText = content.find(isTextBlock);\n\n if (!firstText) {\n // No text blocks — return the full content array so callers can inspect it.\n return { data: content, isError, content, ...(meta && { _meta: meta }) };\n }\n\n // Try to parse JSON from the text block.\n try {\n return { data: JSON.parse(firstText.text), isError, content, ...(meta && { _meta: meta }) };\n } catch {\n // Invalid JSON — return the raw string.\n return { data: firstText.text, isError, content, ...(meta && { _meta: meta }) };\n }\n}\n","import type { McpUiHostCapabilities } from \"@modelcontextprotocol/ext-apps\";\nimport type {\n CallToolRequest,\n CancelTaskRequest,\n CancelTaskResult,\n CreateTaskResult,\n GetTaskPayloadRequest,\n GetTaskPayloadResult,\n GetTaskRequest,\n GetTaskResult,\n Task,\n TaskStatus,\n TaskStatusNotification,\n TaskStatusNotificationParams,\n} from \"@modelcontextprotocol/sdk/types.js\";\n\nimport { HostCapabilityError } from \"./errors.js\";\nimport { TOOLS_CALL_METHOD } from \"./event-map.js\";\nimport { internalsFor } from \"./internals.js\";\nimport { parseToolResult } from \"./result-parser.js\";\nimport type {\n App,\n CallToolAsTaskOptions,\n TaskHandle,\n TaskStatusRouter,\n TaskStatusUpdate,\n TasksCapability,\n ToolCallResult,\n} from \"./types.js\";\n\nexport type { TaskStatusRouter, TaskStatusUpdate };\n\n// -----------------------------------------------------------------------------\n// Host capability\n// -----------------------------------------------------------------------------\n\n/** The MCP Tasks extension identifier. */\nexport const TASKS_EXTENSION_ID = \"io.modelcontextprotocol/tasks\";\n\n/**\n * The host's tasks capability, from the `ui/initialize` result.\n *\n * It lives in `hostCapabilities.experimental`, under the MCP Tasks extension\n * identifier. The ext-apps host capability type has no `tasks` field, so a client that\n * validates the handshake against the spec's schema strips a top-level `tasks`;\n * `experimental` is the one slot whose contents survive that parse (ext-apps\n * 1.7.5 and later). A top-level `tasks` is therefore not read at all — reading\n * it would make a capability visible here that no spec client can see.\n *\n * One key, and only that one: the identifier is the extension registry's, and a\n * host publishing the capability under any other name is not advertising this\n * extension.\n */\nexport function readHostTasksCapability(\n capabilities: McpUiHostCapabilities | undefined,\n): TasksCapability | undefined {\n const entry = capabilities?.experimental?.[TASKS_EXTENSION_ID];\n return entry && typeof entry === \"object\" && !Array.isArray(entry)\n ? (entry as TasksCapability)\n : undefined;\n}\n\n// -----------------------------------------------------------------------------\n// Spec method constants\n// -----------------------------------------------------------------------------\n//\n// The MCP SDK publishes task-method strings only inside Zod `z.literal(...)`s,\n// not as top-level `*_METHOD` constants. Derive each from its request's\n// `method` type so an upstream rename surfaces here as a compile error\n// (same pattern as `READ_RESOURCE_METHOD` in event-map.ts, where the core-MCP\n// method constants live).\n//\n// When adding a new method here, also mirror it in `src/_shims/ext-apps.ts`\n// per the IIFE build instructions in CLAUDE.md — the shim must export the\n// same string constants any source file consumes.\n\nexport const TASKS_GET_METHOD: GetTaskRequest[\"method\"] = \"tasks/get\";\nexport const TASKS_RESULT_METHOD: GetTaskPayloadRequest[\"method\"] = \"tasks/result\";\nexport const TASKS_CANCEL_METHOD: CancelTaskRequest[\"method\"] = \"tasks/cancel\";\nexport const TASKS_STATUS_NOTIFICATION_METHOD: TaskStatusNotification[\"method\"] =\n \"notifications/tasks/status\";\n\n// -----------------------------------------------------------------------------\n// Status router\n// -----------------------------------------------------------------------------\n\n/** Subscribe to a wire method, and return the unsubscribe. */\ntype SubscribeFn = (\n method: string,\n handler: (params: Record<string, unknown> | undefined) => void,\n) => () => void;\n\nexport function createTaskStatusRouter(subscribe: SubscribeFn): TaskStatusRouter {\n const listeners = new Map<string, Set<(update: TaskStatusUpdate) => void>>();\n\n // A single subscription to the wire method. All per-handle listeners filter\n // in-memory by taskId off this one handler.\n const unsub = subscribe(TASKS_STATUS_NOTIFICATION_METHOD, (rawParams) => {\n if (!rawParams) return;\n const params = rawParams as unknown as TaskStatusNotificationParams;\n const taskId = params.taskId;\n if (typeof taskId !== \"string\") return;\n\n const set = listeners.get(taskId);\n if (!set || set.size === 0) return;\n\n // Forward the spec-guaranteed fields verbatim. We deliberately don't\n // fabricate `createdAt`/`lastUpdatedAt`/`ttl` here — the handle merges\n // these from its initial `CreateTaskResult.task` so consumers always\n // see a real Task with no placeholder strings.\n const update: TaskStatusUpdate = {\n taskId: params.taskId,\n status: params.status,\n ...(params.statusMessage !== undefined && { statusMessage: params.statusMessage }),\n };\n\n for (const cb of set) cb(update);\n });\n\n return {\n subscribe(taskId, cb) {\n let set = listeners.get(taskId);\n if (!set) {\n set = new Set();\n listeners.set(taskId, set);\n }\n set.add(cb);\n return () => {\n const s = listeners.get(taskId);\n if (!s) return;\n s.delete(cb);\n if (s.size === 0) listeners.delete(taskId);\n };\n },\n dispose() {\n listeners.clear();\n unsub();\n },\n };\n}\n\n// -----------------------------------------------------------------------------\n// Caller-facing factory\n// -----------------------------------------------------------------------------\n\n/**\n * Task-augment a `tools/call` per the MCP 2025-11-25 tasks utility.\n *\n * A composable helper over {@link App} rather than a method on it: the object\n * `connect()` returns carries the ext-apps surface, and tasks ride alongside.\n * The receiver answers a task-augmented call with a `CreateTaskResult`\n * promptly; the actual `CallToolResult` arrives later via `tasks/result`.\n *\n * ```ts\n * const handle = await callToolAsTask(app, \"deep_research\", { topic });\n * handle.onStatus((t) => setStatus(t.status));\n * const result = await handle.result();\n * ```\n *\n * Rejects with `HostCapabilityError` if the host did not advertise\n * `tasks.requests.tools.call` — per spec a requestor MUST NOT task-augment\n * without matching receiver capability. Check `app.supportsTasks` first, and\n * fall back to `app.callTool`.\n */\nexport async function callToolAsTask<TOutput = unknown>(\n app: App,\n toolName: string,\n args?: unknown,\n options?: CallToolAsTaskOptions,\n): Promise<TaskHandle<TOutput>> {\n const deps = internalsFor(app);\n const hostTasks = deps.hostTasksCapability;\n if (!hostTasks?.requests?.tools?.call) {\n throw new HostCapabilityError(\n \"callToolAsTask\",\n `${TASKS_EXTENSION_ID} with requests.tools.call`,\n );\n }\n\n // Per spec, `task` is an object even when the caller provides no hints —\n // its presence is the signal to the receiver that augmentation is\n // requested. An empty `{}` is valid.\n const taskParam: { ttl?: number } = {};\n if (options?.ttl !== undefined) taskParam.ttl = options.ttl;\n\n // Build `tools/call` params. We layer our own shape on the SDK's\n // `CallToolRequest[\"params\"]` via `satisfies` so any rename upstream\n // (`name` → `toolName`, `arguments` → `args`, etc.) trips tsc.\n const callParams = {\n name: toolName,\n arguments: (args as Record<string, unknown> | undefined) ?? {},\n task: taskParam,\n } satisfies CallToolRequest[\"params\"];\n\n const raw = await deps.request(\n TOOLS_CALL_METHOD,\n callParams as unknown as Record<string, unknown>,\n );\n\n // Spec: task-augmented `tools/call` returns a `CreateTaskResult`. If a\n // receiver that advertised the capability returns a bare\n // `CallToolResult` instead, that's a protocol violation — surface it.\n const createResult = raw as CreateTaskResult | null | undefined;\n const initialTask = createResult?.task;\n if (!initialTask || typeof initialTask !== \"object\" || typeof initialTask.taskId !== \"string\") {\n throw new Error(\n \"callToolAsTask: receiver returned a response without `task` per CreateTaskResult \" +\n \"(expected shape: `{ task: { taskId, status, ... } }`). Receiver may not honor \" +\n \"the advertised tasks capability.\",\n );\n }\n\n const taskId = initialTask.taskId;\n\n // Preserve the Set-semantic dedup contract on `onStatus`: registering the\n // same callback twice collapses to one wire subscription, and either\n // returned unsub releases it. Without this, every `onStatus(cb)` would\n // create a fresh wrapper that the router treats as distinct.\n const localCallbacks = new Map<(task: Task) => void, () => void>();\n\n const handle: TaskHandle<TOutput> = {\n task: initialTask,\n\n async result(): Promise<ToolCallResult<TOutput>> {\n const params = { taskId } satisfies GetTaskPayloadRequest[\"params\"];\n const rawResult = await deps.request(\n TASKS_RESULT_METHOD,\n params as unknown as Record<string, unknown>,\n );\n // Per spec §: `tasks/result` returns exactly what the non-task\n // response would return. Parse through the shared tool-result\n // parser so `_meta[\"io.modelcontextprotocol/related-task\"]`\n // propagates unchanged (key-preserving spread).\n //\n // Type note: `GetTaskPayloadResult` is a union of result shapes\n // (one per augmentable request type). For `tools/call` tasks,\n // the runtime shape is `CallToolResult`, which `parseToolResult`\n // already handles.\n const typed = rawResult as GetTaskPayloadResult;\n return parseToolResult(typed) as ToolCallResult<TOutput>;\n },\n\n async refresh(): Promise<Task> {\n const params = { taskId } satisfies GetTaskRequest[\"params\"];\n const raw = await deps.request(\n TASKS_GET_METHOD,\n params as unknown as Record<string, unknown>,\n );\n // Per spec, `tasks/get` returns the task shape FLAT (taskId, status,\n // ttl, createdAt, lastUpdatedAt, ... at the top level) — NOT\n // wrapped in a `{ task }` field (unlike `CreateTaskResult`).\n return projectTask(raw as GetTaskResult);\n },\n\n async cancel(): Promise<Task> {\n const params = { taskId } satisfies CancelTaskRequest[\"params\"];\n const raw = await deps.request(\n TASKS_CANCEL_METHOD,\n params as unknown as Record<string, unknown>,\n );\n // `CancelTaskResult` is flat like `GetTaskResult`.\n return projectTask(raw as CancelTaskResult);\n },\n\n onStatus(cb) {\n // Idempotent-in-callback: if the same `cb` is already subscribed,\n // return the existing unsub.\n const existing = localCallbacks.get(cb);\n if (existing) return existing;\n\n // Merge the notification's spec-guaranteed fields (taskId, status,\n // statusMessage) with the handle's initial `CreateTaskResult.task`\n // so the consumer always sees a full valid `Task`. `lastUpdatedAt`\n // is stamped at SDK-receive time (an approximation of the host's\n // update time — the spec doesn't wire the host's timestamp through\n // the notification, so this is the closest signal we have).\n // `createdAt`, `ttl`, `pollInterval` come from the initial task\n // because they don't change over a task's lifetime.\n const wireUnsub = deps.taskRouter.subscribe(taskId, (update) => {\n const merged: Task = {\n taskId: update.taskId,\n status: update.status,\n ttl: initialTask.ttl,\n createdAt: initialTask.createdAt,\n lastUpdatedAt: new Date().toISOString(),\n ...(initialTask.pollInterval !== undefined && {\n pollInterval: initialTask.pollInterval,\n }),\n ...(update.statusMessage !== undefined && { statusMessage: update.statusMessage }),\n };\n cb(merged);\n });\n\n const unsub = () => {\n localCallbacks.delete(cb);\n wireUnsub();\n };\n localCallbacks.set(cb, unsub);\n return unsub;\n },\n };\n\n return handle;\n}\n\n// -----------------------------------------------------------------------------\n// Internal helpers\n// -----------------------------------------------------------------------------\n\n/**\n * Project a `GetTaskResult` / `CancelTaskResult` down to the canonical\n * `Task` shape. Both result types are structurally `Task` with an\n * optional `_meta` field on top; we project explicitly so consumers\n * don't see protocol-level `_meta` leaking onto the task state they\n * get back from `refresh()` / `cancel()`.\n *\n * Asymmetry note: `parseToolResult` (for `tools/call` / `tasks/result`\n * payloads) is key-preserving — `_meta` flows through end-to-end, which\n * matters for `io.modelcontextprotocol/related-task` correlation. Here\n * we drop `_meta` because no downstream consumer reads it on `Task` state\n * today. If a host starts stamping useful keys on `tasks/get`/`tasks/cancel`\n * responses, switch to a key-preserving projection.\n */\nfunction projectTask(raw: GetTaskResult | CancelTaskResult): Task {\n return {\n taskId: raw.taskId,\n status: raw.status,\n ttl: raw.ttl,\n createdAt: raw.createdAt,\n lastUpdatedAt: raw.lastUpdatedAt,\n ...(raw.pollInterval !== undefined && { pollInterval: raw.pollInterval }),\n ...(raw.statusMessage !== undefined && { statusMessage: raw.statusMessage }),\n };\n}\n","import type { ToolResultData } from \"./types.js\";\n\nexport type { ToolResultData };\n\n/**\n * Parse inbound `ui/notifications/tool-result` notification params into\n * a consistent `ToolResultData` shape.\n *\n * Implements the 5-step parsing algorithm from the RFC:\n * 1. If `params.structuredContent` exists → use it as content.\n * 2. Else if `params.content` is an array of `{type:\"text\", text}` blocks →\n * join the text values and try JSON.parse.\n * 3. Else if `params.content` is a string → try JSON.parse.\n * 4. If JSON.parse fails in steps 2 or 3 → deliver the raw string.\n * 5. Return `{ content, structuredContent, raw }`.\n */\nexport function parseToolResultParams(params: Record<string, unknown> | undefined): ToolResultData {\n const raw = params ?? {};\n const structuredContent = raw.structuredContent ?? null;\n\n // Step 1: If structuredContent exists, use it as content\n if (structuredContent != null) {\n return { content: structuredContent, structuredContent, raw };\n }\n\n const rawContent = raw.content;\n\n // Step 2: If content is array of {type:\"text\", text} blocks, join texts and try JSON.parse\n if (Array.isArray(rawContent)) {\n const texts = rawContent\n .filter(\n (block: unknown) =>\n block != null &&\n typeof block === \"object\" &&\n (block as Record<string, unknown>).type === \"text\" &&\n typeof (block as Record<string, unknown>).text === \"string\",\n )\n .map((block: unknown) => (block as Record<string, unknown>).text as string);\n\n if (texts.length > 0) {\n const joined = texts.join(\"\");\n try {\n return { content: JSON.parse(joined), structuredContent: null, raw };\n } catch {\n return { content: joined, structuredContent: null, raw };\n }\n }\n\n // No text blocks — return raw content array\n return { content: rawContent, structuredContent: null, raw };\n }\n\n // Step 3: If content is string, try JSON.parse\n if (typeof rawContent === \"string\") {\n try {\n return { content: JSON.parse(rawContent), structuredContent: null, raw };\n } catch {\n return { content: rawContent, structuredContent: null, raw };\n }\n }\n\n // Fallback: return content as-is (could be null, object, etc.)\n return { content: rawContent ?? null, structuredContent: null, raw };\n}\n","import { KEYDOWN_METHOD } from \"./event-map.js\";\nimport type { KeyForwardConfig } from \"./types.js\";\n\n/** Send a notification to the host. */\ntype SendFn = (method: string, params: Record<string, unknown>) => void;\n\n/**\n * Forward keyboard shortcuts from the iframe document to the host.\n *\n * By default, forwards all Ctrl/Cmd+key combos and Escape.\n * Apps can customize via `forwardKeys` config.\n */\nexport class KeyboardForwarder {\n private listener: (event: KeyboardEvent) => void;\n private destroyed = false;\n\n constructor(send: SendFn, customKeys?: KeyForwardConfig[]) {\n const config = customKeys ?? null; // null = default behavior\n\n this.listener = (event: KeyboardEvent) => {\n if (this.destroyed) return;\n if (this.shouldForward(event, config)) {\n event.preventDefault();\n send(KEYDOWN_METHOD, {\n key: event.key,\n ctrlKey: event.ctrlKey,\n metaKey: event.metaKey,\n shiftKey: event.shiftKey,\n altKey: event.altKey,\n });\n }\n };\n\n document.addEventListener(\"keydown\", this.listener);\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n document.removeEventListener(\"keydown\", this.listener);\n }\n\n private shouldForward(event: KeyboardEvent, config: KeyForwardConfig[] | null): boolean {\n // Empty array = forwarding disabled\n if (config && config.length === 0) return false;\n\n // Custom config: match exactly\n if (config) {\n return config.some(\n (k) =>\n event.key.toLowerCase() === k.key.toLowerCase() &&\n (k.ctrl === undefined || event.ctrlKey === k.ctrl) &&\n (k.meta === undefined || event.metaKey === k.meta) &&\n (k.shift === undefined || event.shiftKey === k.shift) &&\n (k.alt === undefined || event.altKey === k.alt),\n );\n }\n\n // Default: forward all Ctrl/Cmd combos + Escape,\n // EXCEPT clipboard shortcuts (c, v, x, a) which the browser must handle natively.\n if (event.key === \"Escape\") return true;\n if (event.ctrlKey || event.metaKey) {\n const key = event.key.toLowerCase();\n if (key === \"c\" || key === \"v\" || key === \"x\" || key === \"a\") return false;\n return true;\n }\n return false;\n }\n}\n","import { SIZE_CHANGED_METHOD } from \"@modelcontextprotocol/ext-apps\";\n\ntype SendFn = (method: string, params: Record<string, unknown>) => void;\n\ninterface Resizer {\n resize(width?: number, height?: number): void;\n measureAndSend(): void;\n destroy(): void;\n}\n\nexport function createResizer(send: SendFn, autoResize: boolean): Resizer {\n let destroyed = false;\n let observer: ResizeObserver | null = null;\n let rafId: number | null = null;\n\n function measureAndSend(): void {\n if (destroyed) return;\n const width = document.body.scrollWidth;\n const height = document.body.scrollHeight;\n send(SIZE_CHANGED_METHOD, { width, height });\n }\n\n function resize(width?: number, height?: number): void {\n if (destroyed) return;\n if (width !== undefined && height !== undefined) {\n send(SIZE_CHANGED_METHOD, { width, height });\n } else {\n measureAndSend();\n }\n }\n\n // Auto mode: attach ResizeObserver, debounced at 16ms via requestAnimationFrame\n if (autoResize && typeof ResizeObserver !== \"undefined\") {\n observer = new ResizeObserver(() => {\n if (destroyed) return;\n if (rafId !== null) cancelAnimationFrame(rafId);\n rafId = requestAnimationFrame(() => {\n rafId = null;\n measureAndSend();\n });\n });\n observer.observe(document.body);\n }\n\n function destroy(): void {\n if (destroyed) return;\n destroyed = true;\n if (rafId !== null) cancelAnimationFrame(rafId);\n observer?.disconnect();\n observer = null;\n }\n\n return { resize, measureAndSend, destroy };\n}\n","import type {\n AppEventMap,\n AppNotification,\n AppRequest,\n McpUiHostCapabilities,\n McpUiHostContext,\n McpUiInitializeRequest,\n McpUiMessageRequest,\n McpUiOpenLinkRequest,\n McpUiUpdateModelContextRequest,\n} from \"@modelcontextprotocol/ext-apps\";\nimport {\n applyHostFonts,\n App as ExtAppsApp,\n HOST_CONTEXT_CHANGED_METHOD,\n RESOURCE_TEARDOWN_METHOD,\n TOOL_CANCELLED_METHOD,\n TOOL_INPUT_METHOD,\n TOOL_INPUT_PARTIAL_METHOD,\n TOOL_RESULT_METHOD,\n} from \"@modelcontextprotocol/ext-apps\";\nimport type { RequestOptions } from \"@modelcontextprotocol/sdk/shared/protocol.js\";\nimport type {\n CallToolRequest,\n ReadResourceRequest,\n ReadResourceResult,\n TextContent,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { CallToolResultSchema, ResultSchema } from \"@modelcontextprotocol/sdk/types.js\";\n\nimport { parseToolResultParams } from \"./content-parser.js\";\nimport { extractHostFontCss, extractTheme } from \"./detection.js\";\nimport { HostCapabilityError } from \"./errors.js\";\nimport { NIMBLEBRAIN_EXTENSIONS, resolveEventMethod, TOOLS_CALL_METHOD } from \"./event-map.js\";\nimport { registerInternals } from \"./internals.js\";\nimport { KeyboardForwarder } from \"./keyboard.js\";\nimport { createResizer } from \"./resize.js\";\nimport { parseToolResult } from \"./result-parser.js\";\nimport { createTaskStatusRouter, readHostTasksCapability } from \"./task-handle.js\";\nimport { applyTheme } from \"./theme-defaults.js\";\nimport type {\n App,\n ConnectOptions,\n Dimensions,\n TasksCapability,\n Theme,\n ToolCallResult,\n} from \"./types.js\";\n\n/**\n * The host name that identifies a NimbleBrain host in the handshake. Identity\n * only: the NimbleBrain host extensions are gated on the host declaring each one.\n */\nconst NIMBLEBRAIN_HOST = \"nimblebrain\";\n\n/**\n * Requests this SDK sends carry no deadline.\n *\n * The MCP SDK gives every request a 60-second one, which is wrong for all three\n * kinds of request an app makes: a file picker waits on a person, `tasks/result`\n * blocks until the task finishes, and a tool call takes as long as the tool\n * takes. A deadline here would reject a call the host is still working on, and\n * the app would report a failure that did not happen.\n *\n * `Infinity` is not usable — `setTimeout` coerces it to `0` and the timer fires\n * immediately — so this is the largest delay a browser timer accepts, about 24\n * days.\n */\nconst NO_DEADLINE: RequestOptions = { timeout: 2_147_483_647 };\n\n/**\n * The events `App` models, paired with the wire method each one carries.\n *\n * Every one is registered exactly once, before the handshake, and fans out to\n * this SDK's own subscribers underneath. Two reasons it has to be this way: a\n * second registration for the same method through the `on*` setters throws, and\n * `App` warns when a handler for a one-shot event (the tool ones) is registered\n * after `connect()` resolves, which is when every hook subscribes.\n */\nconst MAPPED_EVENTS = [\n [\"toolinput\", TOOL_INPUT_METHOD],\n [\"toolinputpartial\", TOOL_INPUT_PARTIAL_METHOD],\n [\"toolresult\", TOOL_RESULT_METHOD],\n [\"toolcancelled\", TOOL_CANCELLED_METHOD],\n] as const satisfies ReadonlyArray<readonly [keyof AppEventMap, string]>;\n\n/**\n * Connect to an MCP Apps host.\n *\n * The one entry point. The protocol underneath is the spec's own client,\n * `@modelcontextprotocol/ext-apps`'s `App`: it owns the transport, the\n * handshake and the wire schemas. What this adds is the framework on top —\n * theme injection, the parsed payloads, multi-subscriber events, resize, and\n * the NimbleBrain extensions — and it resolves to a ready {@link App}.\n *\n * The `App` it returns stays deliberately small. NimbleBrain's own extensions\n * (`action`, the file picker), `downloadFile` and the MCP tasks utility are\n * composable functions over it — import them from the package root.\n */\nexport async function connect(options: ConnectOptions): Promise<App> {\n const { name, version, autoResize = false, forwardKeys } = options;\n\n let destroyed = false;\n\n // --- Mutable state ---\n //\n // The host context lives in `App`, which merges each delta into it, so it is\n // read back rather than copied. `theme` is a derived view of it.\n let hostInfo: { name: string; version: string } = { name: \"unknown\", version: \"unknown\" };\n let isNimbleBrainHost = false;\n let toolInfo: { tool: Record<string, unknown> } | null = null;\n let containerDimensions: Dimensions | null = null;\n let hostCapabilities: McpUiHostCapabilities = {};\n let hostTasksCapability: TasksCapability | undefined;\n let keyboard: KeyboardForwarder | null = null;\n\n // The theme currently applied to the document. Tracked rather than derived at\n // dispatch time, because `App` merges a host-context delta into the context it\n // holds *before* it calls listeners — so by the time this SDK hears about a\n // change, \"the theme before it\" is no longer recoverable from the context.\n // Comparing against what is actually loaded is also the honest question: the\n // filter exists to skip a re-render when nothing visible moved.\n let appliedTheme: Theme = { mode: \"light\", tokens: {} };\n\n // `appCapabilities` is typed as `McpUiAppCapabilities` by the ext-apps spec\n // package, which does not yet model the MCP 2025-11-25 tasks utility. We\n // extend structurally via `TasksCapability` and `satisfies` the extension so\n // the nested objects match the spec literally — empty objects `{}` as\n // presence flags, NOT booleans.\n const appCapabilities = {\n tasks: {\n cancel: {},\n requests: { tools: { call: {} } },\n } satisfies TasksCapability,\n };\n\n // `autoResize` is handed to `App`, which observes the document and reports\n // size after the handshake. Ours must not observe as well: two observers mean\n // two `size-changed` streams for one document.\n const client = new ExtAppsApp(\n { name, version },\n appCapabilities as unknown as McpUiInitializeRequest[\"params\"][\"appCapabilities\"],\n { autoResize },\n );\n\n function currentContext(): McpUiHostContext {\n return client.getHostContext() ?? {};\n }\n\n /**\n * The theme as reported to consumers, derived from the context. Every public\n * view goes through here — the `theme` getter, the `theme-changed` payload,\n * and its equality filter — so they cannot disagree with each other or with\n * what is actually applied.\n */\n function resolveTheme(): Theme {\n return extractTheme(currentContext());\n }\n\n /**\n * Load the host's `@font-face` CSS (`styles.css.fonts`) into the document.\n *\n * The spec's helper injects it once and leaves it in place, so a later\n * host-context change that carries no `css` — a theme toggle, say — keeps the\n * host's typeface loaded rather than unloading it.\n */\n function applyFontsFrom(ctx: Partial<McpUiHostContext> | undefined): void {\n const css = extractHostFontCss(ctx);\n if (css !== undefined && typeof document !== \"undefined\") applyHostFonts(css);\n }\n\n /** Apply the current theme to the document, and record what was applied. */\n function applyResolvedTheme(): Theme {\n const theme = resolveTheme();\n applyTheme(theme.mode, theme.tokens);\n appliedTheme = theme;\n return theme;\n }\n\n // --- Event handlers ---\n //\n // Generic wire methods share one registry keyed by method. The two events\n // that are a *view* over a wire message rather than the message itself\n // (theme, host context) get their own sets, because they ride the same\n // notification and hand their subscribers different payloads.\n const handlers = new Map<string, Set<(params: unknown) => void>>();\n const themeCallbacks = new Set<(theme: Theme) => void>();\n const hostContextCallbacks = new Set<(ctx: McpUiHostContext) => void>();\n\n /** Deliver a payload to everyone subscribed to a wire method. */\n function fanOut(method: string, payload: unknown): void {\n const set = handlers.get(method);\n if (!set) return;\n for (const handler of set) handler(payload);\n }\n\n /**\n * Send a notification `App` does not model. The NimbleBrain host extensions have\n * no spec equivalent and so no place in its notification union; the cast is\n * the one place that is admitted, and the method still comes from a constant\n * rather than a literal spelled at the call site.\n */\n function sendRaw(method: string, params?: Record<string, unknown>): void {\n if (destroyed) return;\n void client\n .notification({ method, params } as unknown as AppNotification)\n // A closed transport is the ordinary way this rejects, during teardown.\n .catch(() => {});\n }\n\n /** Send a request `App` does not model, and resolve with the host's result. */\n function requestRaw(method: string, params?: Record<string, unknown>): Promise<unknown> {\n return client.request({ method, params } as unknown as AppRequest, ResultSchema, NO_DEADLINE);\n }\n\n // --- Route what the host sends ---\n //\n // Registered before `connect()`, so a notification the host sends the instant\n // the handshake completes is already routed.\n\n for (const [event, method] of MAPPED_EVENTS) {\n client.addEventListener(event, (params) => {\n if (destroyed) return;\n // `tool-result` is delivered parsed — the payload every subscriber gets,\n // however they subscribed — because the wire shape is three shapes and\n // picking between them is work each app would otherwise repeat.\n fanOut(\n method,\n method === TOOL_RESULT_METHOD\n ? parseToolResultParams(params as Record<string, unknown>)\n : params,\n );\n });\n }\n\n client.addEventListener(\"hostcontextchanged\", (params) => {\n if (destroyed) return;\n const prevTheme = appliedTheme;\n\n // `App` has already merged this delta into the context it holds — shallowly,\n // which is what the spec asks for: `styles.variables` is a complete map when\n // the host sends one, so a deep merge would leave a host no way to remove a\n // variable. Fonts are read from the delta as sent, because a merged\n // context loses `styles.css` whenever the host sends `styles.variables`\n // alone.\n applyFontsFrom(params as Partial<McpUiHostContext>);\n const nextTheme = applyResolvedTheme();\n\n // Subscribers to the short event get the merged snapshot, because that is\n // what `app.hostContext` means and a delta cannot distinguish an omitted\n // field from a cleared one. A caller who genuinely wants the notification as\n // sent subscribes to the wire method instead, which is passed through\n // untouched.\n const merged = currentContext();\n for (const cb of hostContextCallbacks) cb(merged);\n fanOut(HOST_CONTEXT_CHANGED_METHOD, params);\n // Theme subscribers see only real theme movement: a host-context change\n // that leaves the derived theme identical (a workspace switch, say) must\n // not re-render every themed component in the app.\n if (!themesEqual(prevTheme, nextTheme)) {\n for (const cb of themeCallbacks) cb(nextTheme);\n }\n });\n\n // Teardown is a *request* in the spec, not a notification: the host asks, and\n // the view is expected to answer. Subscribers see it as the `teardown` event;\n // answering it is this SDK's job, not theirs.\n client.onteardown = (params) => {\n if (!destroyed) fanOut(RESOURCE_TEARDOWN_METHOD, params);\n return {};\n };\n\n // Everything else the host sends: vendor extension notifications, the server's\n // `notifications/resources/list_changed`, and `notifications/tasks/status`.\n // `App` routes a notification here when no typed handler claims its method,\n // and one handler with a fan-out under it is the only safe shape —\n // registering a second handler for a method would silently replace the first.\n client.fallbackNotificationHandler = async (notification) => {\n if (destroyed) return;\n fanOut(notification.method, notification.params);\n };\n\n /** Register one handler and return its unsubscribe. */\n function subscribe(event: string, handler: (params: any) => void): () => void {\n switch (event) {\n case \"theme-changed\":\n themeCallbacks.add(handler);\n return () => {\n themeCallbacks.delete(handler);\n };\n case \"host-context-changed\":\n hostContextCallbacks.add(handler);\n return () => {\n hostContextCallbacks.delete(handler);\n };\n default: {\n const method = resolveEventMethod(event);\n if (!handlers.has(method)) handlers.set(method, new Set());\n handlers.get(method)?.add(handler);\n return () => {\n const set = handlers.get(method);\n if (set) {\n set.delete(handler);\n if (set.size === 0) handlers.delete(method);\n }\n };\n }\n }\n }\n\n // Handlers from `options.on` are registered before the handshake goes out, so\n // a tool result the host sends in the same turn as `initialized` is not lost.\n if (options.on) {\n for (const [event, handler] of Object.entries(options.on)) {\n if (typeof handler === \"function\") subscribe(event, handler);\n }\n }\n\n // --- The handshake: `ui/initialize`, then `initialized` ---\n await client.connect();\n\n const hostVersion = client.getHostVersion();\n hostInfo = {\n name: hostVersion?.name ?? \"unknown\",\n version: hostVersion?.version ?? \"unknown\",\n };\n isNimbleBrainHost = hostInfo.name === NIMBLEBRAIN_HOST;\n\n // Everything an app may ask of the host is decided here, once: each method\n // below and each helper beside `App` checks the declaration before sending.\n hostCapabilities = client.getHostCapabilities() ?? {};\n hostTasksCapability = readHostTasksCapability(hostCapabilities);\n\n const initialContext = client.getHostContext();\n if (initialContext) {\n if (initialContext.toolInfo && typeof initialContext.toolInfo === \"object\") {\n toolInfo = {\n tool: (initialContext.toolInfo.tool as unknown as Record<string, unknown>) ?? {},\n };\n }\n if (\n initialContext.containerDimensions &&\n typeof initialContext.containerDimensions === \"object\"\n ) {\n containerDimensions = initialContext.containerDimensions as Dimensions;\n }\n\n // Inject the theme into the DOM: the host's values go inline, and the\n // neutral defaults for the mode go in a cascade layer, where they back any\n // var nobody declares and lose to every var that is declared. The host's\n // `@font-face` CSS loads alongside — a token names a family, it cannot load\n // one.\n applyFontsFrom(initialContext);\n applyResolvedTheme();\n }\n\n // Keyboard forwarding is a NimbleBrain extension. Forwarding to a host that\n // did not declare it would `preventDefault` a key for a host that does\n // nothing with it, so the gate is on the declaration, not just the option.\n if (\n forwardKeys &&\n hostCapabilities.experimental?.[NIMBLEBRAIN_EXTENSIONS.keydown.capability] !== undefined\n ) {\n keyboard = new KeyboardForwarder(sendRaw, forwardKeys === true ? undefined : forwardKeys);\n }\n\n // The resizer serves `app.resize()`. It never observes: under `autoResize`\n // that is `App`'s job, and it has already reported the first size.\n const resizer = createResizer(sendRaw, false);\n if (!autoResize) resizer.measureAndSend();\n\n // Shared router for `notifications/tasks/status`. Created eagerly so the\n // subscription registers exactly once — every `TaskHandle` filters off this\n // single wire subscription by taskId.\n const taskRouter = createTaskStatusRouter((method, handler) =>\n subscribe(method, handler as (params: any) => void),\n );\n\n // --- The App this SDK hands out ---\n const app: App = {\n get theme() {\n return resolveTheme();\n },\n get hostInfo() {\n return { ...hostInfo };\n },\n get hostContext() {\n return currentContext();\n },\n get hostCapabilities() {\n return hostCapabilities;\n },\n get isNimbleBrainHost() {\n return isNimbleBrainHost;\n },\n get toolInfo() {\n return toolInfo;\n },\n get containerDimensions() {\n return containerDimensions;\n },\n get destroyed() {\n return destroyed;\n },\n get supportsTasks() {\n return hostTasksCapability?.requests?.tools?.call !== undefined;\n },\n\n on(event: string, handler: (params: any) => void): () => void {\n return subscribe(event, handler);\n },\n\n resize(width?: number, height?: number): void {\n resizer.resize(width, height);\n },\n\n openLink(url: string): void {\n if (destroyed) return;\n if (!hostCapabilities.openLinks) {\n window.open(url, \"_blank\", \"noopener\");\n return;\n }\n const params: McpUiOpenLinkRequest[\"params\"] = { url };\n client.openLink(params, NO_DEADLINE).catch(() => {\n // The host refused or does not serve it: open directly instead.\n window.open(url, \"_blank\", \"noopener\");\n });\n },\n\n updateModelContext(state: Record<string, unknown>, summary?: string): void {\n if (destroyed || !hostCapabilities.updateModelContext) return;\n const params: McpUiUpdateModelContextRequest[\"params\"] = {\n structuredContent: state,\n ...(summary !== undefined && {\n content: [{ type: \"text\", text: summary } satisfies TextContent],\n }),\n };\n client.updateModelContext(params, NO_DEADLINE).catch(() => {});\n },\n\n async callTool<TOutput = unknown>(\n toolName: string,\n args?: Record<string, unknown>,\n ): Promise<ToolCallResult<TOutput>> {\n if (!hostCapabilities.serverTools) {\n throw new HostCapabilityError(\"callTool\", \"serverTools\");\n }\n // No target. A host scopes an app's call to the server that mounted it,\n // so `params` carries what the spec names and nothing else.\n const params: CallToolRequest[\"params\"] = {\n name: toolName,\n arguments: args ?? {},\n };\n // Sent through the generic request path rather than `callServerTool`,\n // which asks for a progress token: that puts `_meta.progressToken` on\n // every call, and nothing here subscribes to progress. The result is\n // validated against the spec's schema either way.\n const raw = await client.request(\n { method: TOOLS_CALL_METHOD, params },\n CallToolResultSchema,\n NO_DEADLINE,\n );\n return parseToolResult(raw) as ToolCallResult<TOutput>;\n },\n\n async readServerResource(params: ReadResourceRequest[\"params\"]): Promise<ReadResourceResult> {\n if (!hostCapabilities.serverResources) {\n throw new HostCapabilityError(\"readServerResource\", \"serverResources\");\n }\n return await client.readServerResource(params, NO_DEADLINE);\n },\n\n sendMessage(text: string): void {\n if (destroyed || !hostCapabilities.message) return;\n const textBlock: TextContent = { type: \"text\", text };\n const params: McpUiMessageRequest[\"params\"] = {\n role: \"user\",\n content: [textBlock],\n };\n client.sendMessage(params, NO_DEADLINE).catch(() => {});\n },\n\n destroy(): void {\n if (destroyed) return;\n destroyed = true;\n keyboard?.destroy();\n resizer.destroy();\n taskRouter.dispose();\n handlers.clear();\n themeCallbacks.clear();\n hostContextCallbacks.clear();\n void client.close();\n },\n };\n\n registerInternals(app, {\n send(method, params) {\n sendRaw(method, params);\n },\n request(method, params) {\n return requestRaw(method, params);\n },\n onMessage(method, handler) {\n return subscribe(method, handler as (params: any) => void);\n },\n taskRouter,\n get hostTasksCapability() {\n return hostTasksCapability;\n },\n });\n\n return app;\n}\n\n/**\n * Shallow equality for `Theme` — used to filter host-context changes that\n * don't actually move the theme (e.g. a workspace switch that leaves\n * theme/styles untouched). Cheap; tokens are ~40 entries.\n */\nfunction themesEqual(a: Theme, b: Theme): boolean {\n if (a.mode !== b.mode) return false;\n const aKeys = Object.keys(a.tokens);\n const bKeys = Object.keys(b.tokens);\n if (aKeys.length !== bKeys.length) return false;\n // Iterating only over `a`'s keys is sufficient: under equal length, any key\n // in `a` missing from `b` reads `b[k] === undefined`, which fails the strict\n // inequality check. Symmetric difference is covered.\n for (const k of aKeys) {\n if (a.tokens[k] !== b.tokens[k]) return false;\n }\n return true;\n}\n","/**\n * NimbleBrain host extensions — composable functions over {@link App}.\n *\n * These are not ext-apps spec surface. They are the NimbleBrain host's own\n * `ai.nimblebrain/*` methods, which this package implements a client for, and\n * `NIMBLEBRAIN_EXTENSIONS` in `event-map.ts` is the complete list. They\n * live here rather than on the `App` object so the object stays the spec\n * surface plus the handshake state, and so an app that never picks a file\n * never pulls this code in.\n *\n * Every one of them is gated on the host declaring it in `ui/initialize`: where\n * it is not declared, the fire-and-forget ones are no-ops and the ones with a\n * return value throw `HostCapabilityError`, because a picker that silently\n * resolves `null` forever is worse than one that says it isn't there.\n * `keydown` has no function here; `connect({ forwardKeys })` applies the same\n * gate.\n */\nimport { HostCapabilityError } from \"./errors.js\";\nimport { NIMBLEBRAIN_EXTENSIONS, type NimbleBrainExtension } from \"./event-map.js\";\nimport { internalsFor } from \"./internals.js\";\nimport type { App, FileResult, RequestFileOptions } from \"./types.js\";\n\n/**\n * Whether the host declared a NimbleBrain extension. Use it to decide what to\n * offer, e.g. to hide an upload button on a host with no file picker.\n */\nexport function hostSupports(app: App, extension: NimbleBrainExtension): boolean {\n const { capability } = NIMBLEBRAIN_EXTENSIONS[extension];\n return app.hostCapabilities.experimental?.[capability] !== undefined;\n}\n\n/** 25 MB — the host's default cap on a single picked file. */\nconst DEFAULT_MAX_FILE_SIZE = 26_214_400;\n\n/**\n * Trigger a host-side action.\n *\n * Sends a command *to* the host. The NimbleBrain host serves `openApp`\n * (`{ name }`) and `openConversation` (`{ id }`) and ignores any other name. A\n * message into the conversation is `sendMessage`, and an external page is\n * `openLink`. A no-op when the host did not declare `ai.nimblebrain/action`.\n */\nexport function action(app: App, name: string, params?: Record<string, unknown>): void {\n if (!hostSupports(app, \"action\")) return;\n internalsFor(app).send(NIMBLEBRAIN_EXTENSIONS.action.method, { action: name, ...params });\n}\n\n/**\n * Request one file from the user via the host's native file picker.\n *\n * Resolves `null` if the user cancels. Rejects with `HostCapabilityError` when\n * the host did not declare `ai.nimblebrain/request-file`.\n */\nexport async function pickFile(app: App, options?: RequestFileOptions): Promise<FileResult | null> {\n requireRequestFile(\"pickFile\", app);\n const files = await requestFile(app, options, false);\n // One pick, so the first entry is the answer; an empty list is a cancel.\n return files[0] ?? null;\n}\n\n/**\n * Request several files from the user.\n *\n * Resolves `[]` if the user cancels. Rejects with `HostCapabilityError` when\n * the host did not declare `ai.nimblebrain/request-file`.\n */\nexport async function pickFiles(app: App, options?: RequestFileOptions): Promise<FileResult[]> {\n requireRequestFile(\"pickFiles\", app);\n return await requestFile(app, options, true);\n}\n\nfunction requireRequestFile(feature: string, app: App): void {\n if (!hostSupports(app, \"requestFile\")) {\n throw new HostCapabilityError(feature, NIMBLEBRAIN_EXTENSIONS.requestFile.capability);\n }\n}\n\n/**\n * Shared request path for `pickFile` / `pickFiles`.\n *\n * The host answers with `{ files }` — an empty array when the user cancelled.\n * A JSON-RPC result is an object by definition, and MCP types it as one, so the\n * files travel under a field rather than as a bare array or a bare `null`: a\n * spec client refuses to parse anything else, and the call would hang rather\n * than resolve.\n *\n * Entries are shape-checked here. The type promises a string `id`, and without\n * the guard a consumer reads `undefined.id` three frames later, where nothing\n * says which side is mismatched.\n */\nasync function requestFile(\n app: App,\n options: RequestFileOptions | undefined,\n multiple: boolean,\n): Promise<FileResult[]> {\n const result = await internalsFor(app).request(NIMBLEBRAIN_EXTENSIONS.requestFile.method, {\n accept: options?.accept,\n maxSize: options?.maxSize ?? DEFAULT_MAX_FILE_SIZE,\n multiple,\n });\n const files = (result as { files?: unknown } | null | undefined)?.files;\n if (files === undefined) {\n throw new Error(\n \"ai.nimblebrain/request-file returned no `files`. The host is older than this \" +\n \"SDK targets: it answers the picker with a bare array or `null`, which \" +\n \"a spec-compliant client cannot parse.\",\n );\n }\n if (!Array.isArray(files)) {\n throw new Error(\"ai.nimblebrain/request-file returned a `files` field that is not an array.\");\n }\n return files.map(validateFileResult);\n}\n\nfunction validateFileResult(value: unknown): FileResult {\n if (\n typeof value !== \"object\" ||\n value === null ||\n typeof (value as { id?: unknown }).id !== \"string\"\n ) {\n throw new Error(\n \"ai.nimblebrain/request-file returned a result without a string `id`. \" +\n \"The host appears to be on a version older than this SDK targets — \" +\n \"@nimblebrain/synapse 0.8.0+ requires a host with POST /v1/resources \" +\n \"(NimbleBrain ≥ the version that ships PR #93).\",\n );\n }\n return value as FileResult;\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var chunkYSL7KJNU_cjs = require('./chunk-YSL7KJNU.cjs');
4
- var chunkISV6HFQE_cjs = require('./chunk-ISV6HFQE.cjs');
4
+ var chunk5FU64TOX_cjs = require('./chunk-5FU64TOX.cjs');
5
5
  var extApps = require('@modelcontextprotocol/ext-apps');
6
6
  var types_js = require('@modelcontextprotocol/sdk/types.js');
7
7
 
@@ -140,7 +140,7 @@ async function callToolAsTask(app, toolName, args, options) {
140
140
  task: taskParam
141
141
  };
142
142
  const raw = await deps.request(
143
- chunkISV6HFQE_cjs.TOOLS_CALL_METHOD,
143
+ chunk5FU64TOX_cjs.TOOLS_CALL_METHOD,
144
144
  callParams
145
145
  );
146
146
  const createResult = raw;
@@ -260,7 +260,7 @@ var KeyboardForwarder = class {
260
260
  if (this.destroyed) return;
261
261
  if (this.shouldForward(event, config)) {
262
262
  event.preventDefault();
263
- send(chunkISV6HFQE_cjs.KEYDOWN_METHOD, {
263
+ send(chunk5FU64TOX_cjs.KEYDOWN_METHOD, {
264
264
  key: event.key,
265
265
  ctrlKey: event.ctrlKey,
266
266
  metaKey: event.metaKey,
@@ -320,7 +320,6 @@ function createResizer(send, autoResize) {
320
320
 
321
321
  // src/connect.ts
322
322
  var NIMBLEBRAIN_HOST = "nimblebrain";
323
- var CHAT_CONTEXT_META_KEY = "ai.nimblebrain/context";
324
323
  var NO_DEADLINE = { timeout: 2147483647 };
325
324
  var MAPPED_EVENTS = [
326
325
  ["toolinput", extApps.TOOL_INPUT_METHOD],
@@ -424,7 +423,7 @@ async function connect(options) {
424
423
  hostContextCallbacks.delete(handler);
425
424
  };
426
425
  default: {
427
- const method = chunkISV6HFQE_cjs.resolveEventMethod(event);
426
+ const method = chunk5FU64TOX_cjs.resolveEventMethod(event);
428
427
  if (!handlers.has(method)) handlers.set(method, /* @__PURE__ */ new Set());
429
428
  handlers.get(method)?.add(handler);
430
429
  return () => {
@@ -464,7 +463,7 @@ async function connect(options) {
464
463
  applyFontsFrom(initialContext);
465
464
  applyResolvedTheme();
466
465
  }
467
- if (forwardKeys && hostCapabilities.experimental?.[chunkISV6HFQE_cjs.NIMBLEBRAIN_EXTENSIONS.keydown.capability] !== void 0) {
466
+ if (forwardKeys && hostCapabilities.experimental?.[chunk5FU64TOX_cjs.NIMBLEBRAIN_EXTENSIONS.keydown.capability] !== void 0) {
468
467
  keyboard = new KeyboardForwarder(sendRaw, forwardKeys === true ? void 0 : forwardKeys);
469
468
  }
470
469
  const resizer = createResizer(sendRaw);
@@ -537,7 +536,7 @@ async function connect(options) {
537
536
  arguments: args ?? {}
538
537
  };
539
538
  const raw = await client.request(
540
- { method: chunkISV6HFQE_cjs.TOOLS_CALL_METHOD, params },
539
+ { method: chunk5FU64TOX_cjs.TOOLS_CALL_METHOD, params },
541
540
  types_js.CallToolResultSchema,
542
541
  NO_DEADLINE
543
542
  );
@@ -549,15 +548,9 @@ async function connect(options) {
549
548
  }
550
549
  return await client.readServerResource(params, NO_DEADLINE);
551
550
  },
552
- sendMessage(text, context) {
551
+ sendMessage(text) {
553
552
  if (destroyed || !hostCapabilities.message) return;
554
- const textBlock = {
555
- type: "text",
556
- text,
557
- // The chat context is a NimbleBrain host field; other hosts ignore it,
558
- // but there is no reason to spend the bytes off one.
559
- ...isNimbleBrainHost && context && { _meta: { [CHAT_CONTEXT_META_KEY]: context } }
560
- };
553
+ const textBlock = { type: "text", text };
561
554
  const params = {
562
555
  role: "user",
563
556
  content: [textBlock]
@@ -607,13 +600,13 @@ function themesEqual(a, b) {
607
600
 
608
601
  // src/extensions.ts
609
602
  function hostSupports(app, extension) {
610
- const { capability } = chunkISV6HFQE_cjs.NIMBLEBRAIN_EXTENSIONS[extension];
603
+ const { capability } = chunk5FU64TOX_cjs.NIMBLEBRAIN_EXTENSIONS[extension];
611
604
  return app.hostCapabilities.experimental?.[capability] !== void 0;
612
605
  }
613
606
  var DEFAULT_MAX_FILE_SIZE = 26214400;
614
607
  function action(app, name, params) {
615
608
  if (!hostSupports(app, "action")) return;
616
- internalsFor(app).send(chunkISV6HFQE_cjs.NIMBLEBRAIN_EXTENSIONS.action.method, { action: name, ...params });
609
+ internalsFor(app).send(chunk5FU64TOX_cjs.NIMBLEBRAIN_EXTENSIONS.action.method, { action: name, ...params });
617
610
  }
618
611
  async function pickFile(app, options) {
619
612
  requireRequestFile("pickFile", app);
@@ -626,11 +619,11 @@ async function pickFiles(app, options) {
626
619
  }
627
620
  function requireRequestFile(feature, app) {
628
621
  if (!hostSupports(app, "requestFile")) {
629
- throw new HostCapabilityError(feature, chunkISV6HFQE_cjs.NIMBLEBRAIN_EXTENSIONS.requestFile.capability);
622
+ throw new HostCapabilityError(feature, chunk5FU64TOX_cjs.NIMBLEBRAIN_EXTENSIONS.requestFile.capability);
630
623
  }
631
624
  }
632
625
  async function requestFile(app, options, multiple) {
633
- const result = await internalsFor(app).request(chunkISV6HFQE_cjs.NIMBLEBRAIN_EXTENSIONS.requestFile.method, {
626
+ const result = await internalsFor(app).request(chunk5FU64TOX_cjs.NIMBLEBRAIN_EXTENSIONS.requestFile.method, {
634
627
  accept: options?.accept,
635
628
  maxSize: options?.maxSize ?? DEFAULT_MAX_FILE_SIZE,
636
629
  multiple
@@ -663,5 +656,5 @@ exports.hostSupports = hostSupports;
663
656
  exports.internalsFor = internalsFor;
664
657
  exports.pickFile = pickFile;
665
658
  exports.pickFiles = pickFiles;
666
- //# sourceMappingURL=chunk-HQLSVUOR.cjs.map
667
- //# sourceMappingURL=chunk-HQLSVUOR.cjs.map
659
+ //# sourceMappingURL=chunk-UN6PDZSL.cjs.map
660
+ //# sourceMappingURL=chunk-UN6PDZSL.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts","../src/internals.ts","../src/result-parser.ts","../src/task-handle.ts","../src/content-parser.ts","../src/keyboard.ts","../src/resize.ts","../src/connect.ts","../src/extensions.ts"],"names":["TOOLS_CALL_METHOD","raw","KEYDOWN_METHOD","SIZE_CHANGED_METHOD","TOOL_INPUT_METHOD","TOOL_INPUT_PARTIAL_METHOD","TOOL_RESULT_METHOD","TOOL_CANCELLED_METHOD","ExtAppsApp","extractTheme","extractHostFontCss","applyTheme","ResultSchema","HOST_CONTEXT_CHANGED_METHOD","RESOURCE_TEARDOWN_METHOD","resolveEventMethod","NIMBLEBRAIN_EXTENSIONS","CallToolResultSchema"],"mappings":"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","file":"chunk-UN6PDZSL.cjs","sourcesContent":["/**\n * Thrown when an app asks for something the host did not declare in\n * `ui/initialize`.\n *\n * The request is never sent. A host that does not implement a request may never\n * answer it, and this SDK's requests carry no deadline, so sending anyway would\n * leave the caller waiting forever rather than failing.\n *\n * `capability` names what was missing, as the host would have declared it: a\n * `hostCapabilities` field (`serverTools`, `downloadFile`) or an extension\n * identifier (`ai.nimblebrain/request-file`, `io.modelcontextprotocol/tasks`).\n */\nexport class HostCapabilityError extends Error {\n readonly capability: string;\n\n constructor(feature: string, capability: string) {\n super(`${feature} is not supported in this host: it did not declare ${capability}`);\n this.name = \"HostCapabilityError\";\n this.capability = capability;\n }\n}\n","/**\n * The plumbing the SDK's own composable helpers reach through — the file\n * picker, `action`, `downloadFile`, `callToolAsTask`.\n *\n * It lives in a module-private `WeakMap` rather than on the `App` object,\n * because those two options are not equivalent. A `_internals` member is still\n * a member: it type-checks, autocompletes, survives `Object.keys`, and hands\n * every consumer a transport the SDK does not model a use for. Underscore and\n * an `@internal` tag are a request, not a boundary, and a request is what the\n * removed `Synapse._request` was — which is exactly how a bridge script ended\n * up hand-rolling its own `tools/call`.\n *\n * So the public type is the protocol surface and nothing else, and the seam is\n * genuinely closed: a caller who needs something the SDK does not expose gets a\n * named method for it, or the SDK is missing a feature.\n */\nimport type { App, AppInternals } from \"./types.js\";\n\nconst INTERNALS = new WeakMap<App, AppInternals>();\n\n/** Called once by `connect()` for each app it builds. */\nexport function registerInternals(app: App, internals: AppInternals): void {\n INTERNALS.set(app, internals);\n}\n\n/**\n * The plumbing behind an app. Throws if `app` did not come from this copy of\n * the SDK — which is what a duplicated install looks like, and is worth failing\n * loudly for rather than as an undefined-property read three frames later.\n */\nexport function internalsFor(app: App): AppInternals {\n const internals = INTERNALS.get(app);\n if (!internals) {\n throw new Error(\n \"This App did not come from this copy of @nimblebrain/synapse. \" +\n \"Two copies of the package are installed (check for a duplicate in your \" +\n \"lockfile, or a bundler resolving the ESM and CJS builds separately).\",\n );\n }\n return internals;\n}\n","import type { ToolCallResult } from \"./types.js\";\n\n/**\n * Normalize a raw tool call response into a consistent `ToolCallResult`.\n *\n * Handles three shapes:\n * 1. MCP `CallToolResult` — has a `content` array with typed blocks.\n * 2. Raw JSON object (NimbleBrain bridge) — used as-is.\n * 3. Null / undefined — returns `{ data: null, isError: false }`.\n *\n * `_meta` on a `CallToolResult` is preserved on the parsed output as a\n * whole-object passthrough — notably `io.modelcontextprotocol/related-task`\n * (`{ taskId }`) for MCP 2025-11-25 task-augmented results, but any other\n * namespaced `_meta` keys propagate for free.\n */\nexport function parseToolResult(raw: unknown): ToolCallResult {\n if (raw == null) {\n return { data: null, isError: false };\n }\n\n if (isCallToolResult(raw)) {\n return parseCallToolResult(raw);\n }\n\n // Raw JSON object — pass through.\n return { data: raw, isError: false };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\ninterface McpTextBlock {\n type: \"text\";\n text: string;\n}\n\ninterface McpCallToolResult {\n content: unknown[];\n isError?: boolean;\n _meta?: { [key: string]: unknown };\n}\n\nfunction isCallToolResult(value: unknown): value is McpCallToolResult {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n return false;\n }\n return Array.isArray((value as Record<string, unknown>).content);\n}\n\nfunction isTextBlock(block: unknown): block is McpTextBlock {\n if (block === null || typeof block !== \"object\" || Array.isArray(block)) {\n return false;\n }\n const obj = block as Record<string, unknown>;\n return obj.type === \"text\" && typeof obj.text === \"string\";\n}\n\n/**\n * Extract `_meta` as a shallow-copied object if present and object-shaped.\n *\n * Key-preserving by design: every `_meta` entry propagates without\n * selective copying, so future spec additions flow through without code\n * changes. Returns `undefined` when the input has no meaningful `_meta`.\n */\nfunction extractMeta(result: McpCallToolResult): { [key: string]: unknown } | undefined {\n const meta = result._meta;\n if (!meta || typeof meta !== \"object\" || Array.isArray(meta)) return undefined;\n // Shallow spread so mutations on either side don't leak. Preserves the\n // full key set including `io.modelcontextprotocol/related-task`.\n return { ...meta };\n}\n\nfunction parseCallToolResult(result: McpCallToolResult): ToolCallResult {\n const isError = result.isError === true;\n const content = result.content;\n const meta = extractMeta(result);\n\n if (content.length === 0) {\n return { data: null, isError, content, ...(meta && { _meta: meta }) };\n }\n\n const firstText = content.find(isTextBlock);\n\n if (!firstText) {\n // No text blocks — return the full content array so callers can inspect it.\n return { data: content, isError, content, ...(meta && { _meta: meta }) };\n }\n\n // Try to parse JSON from the text block.\n try {\n return { data: JSON.parse(firstText.text), isError, content, ...(meta && { _meta: meta }) };\n } catch {\n // Invalid JSON — return the raw string.\n return { data: firstText.text, isError, content, ...(meta && { _meta: meta }) };\n }\n}\n","import type { McpUiHostCapabilities } from \"@modelcontextprotocol/ext-apps\";\nimport type {\n CallToolRequest,\n CancelTaskRequest,\n CancelTaskResult,\n CreateTaskResult,\n GetTaskPayloadRequest,\n GetTaskPayloadResult,\n GetTaskRequest,\n GetTaskResult,\n Task,\n TaskStatus,\n TaskStatusNotification,\n TaskStatusNotificationParams,\n} from \"@modelcontextprotocol/sdk/types.js\";\n\nimport { HostCapabilityError } from \"./errors.js\";\nimport { TOOLS_CALL_METHOD } from \"./event-map.js\";\nimport { internalsFor } from \"./internals.js\";\nimport { parseToolResult } from \"./result-parser.js\";\nimport type {\n App,\n CallToolAsTaskOptions,\n TaskHandle,\n TaskStatusRouter,\n TaskStatusUpdate,\n TasksCapability,\n ToolCallResult,\n} from \"./types.js\";\n\nexport type { TaskStatusRouter, TaskStatusUpdate };\n\n// -----------------------------------------------------------------------------\n// Host capability\n// -----------------------------------------------------------------------------\n\n/** The MCP Tasks extension identifier. */\nexport const TASKS_EXTENSION_ID = \"io.modelcontextprotocol/tasks\";\n\n/**\n * The host's tasks capability, from the `ui/initialize` result.\n *\n * It lives in `hostCapabilities.experimental`, under the MCP Tasks extension\n * identifier. The ext-apps host capability type has no `tasks` field, so a client that\n * validates the handshake against the spec's schema strips a top-level `tasks`;\n * `experimental` is the one slot whose contents survive that parse (ext-apps\n * 1.7.5 and later). A top-level `tasks` is therefore not read at all — reading\n * it would make a capability visible here that no spec client can see.\n *\n * One key, and only that one: the identifier is the extension registry's, and a\n * host publishing the capability under any other name is not advertising this\n * extension.\n */\nexport function readHostTasksCapability(\n capabilities: McpUiHostCapabilities | undefined,\n): TasksCapability | undefined {\n const entry = capabilities?.experimental?.[TASKS_EXTENSION_ID];\n return entry && typeof entry === \"object\" && !Array.isArray(entry)\n ? (entry as TasksCapability)\n : undefined;\n}\n\n// -----------------------------------------------------------------------------\n// Spec method constants\n// -----------------------------------------------------------------------------\n//\n// The MCP SDK publishes task-method strings only inside Zod `z.literal(...)`s,\n// not as top-level `*_METHOD` constants. Derive each from its request's\n// `method` type so an upstream rename surfaces here as a compile error\n// (same pattern as `READ_RESOURCE_METHOD` in event-map.ts, where the core-MCP\n// method constants live).\n//\n// When adding a new method here, also mirror it in `src/_shims/ext-apps.ts`\n// per the IIFE build instructions in CLAUDE.md — the shim must export the\n// same string constants any source file consumes.\n\nexport const TASKS_GET_METHOD: GetTaskRequest[\"method\"] = \"tasks/get\";\nexport const TASKS_RESULT_METHOD: GetTaskPayloadRequest[\"method\"] = \"tasks/result\";\nexport const TASKS_CANCEL_METHOD: CancelTaskRequest[\"method\"] = \"tasks/cancel\";\nexport const TASKS_STATUS_NOTIFICATION_METHOD: TaskStatusNotification[\"method\"] =\n \"notifications/tasks/status\";\n\n// -----------------------------------------------------------------------------\n// Status router\n// -----------------------------------------------------------------------------\n\n/** Subscribe to a wire method, and return the unsubscribe. */\ntype SubscribeFn = (\n method: string,\n handler: (params: Record<string, unknown> | undefined) => void,\n) => () => void;\n\nexport function createTaskStatusRouter(subscribe: SubscribeFn): TaskStatusRouter {\n const listeners = new Map<string, Set<(update: TaskStatusUpdate) => void>>();\n\n // A single subscription to the wire method. All per-handle listeners filter\n // in-memory by taskId off this one handler.\n const unsub = subscribe(TASKS_STATUS_NOTIFICATION_METHOD, (rawParams) => {\n if (!rawParams) return;\n const params = rawParams as unknown as TaskStatusNotificationParams;\n const taskId = params.taskId;\n if (typeof taskId !== \"string\") return;\n\n const set = listeners.get(taskId);\n if (!set || set.size === 0) return;\n\n // Forward the spec-guaranteed fields verbatim. We deliberately don't\n // fabricate `createdAt`/`lastUpdatedAt`/`ttl` here — the handle merges\n // these from its initial `CreateTaskResult.task` so consumers always\n // see a real Task with no placeholder strings.\n const update: TaskStatusUpdate = {\n taskId: params.taskId,\n status: params.status,\n ...(params.statusMessage !== undefined && { statusMessage: params.statusMessage }),\n };\n\n for (const cb of set) cb(update);\n });\n\n return {\n subscribe(taskId, cb) {\n let set = listeners.get(taskId);\n if (!set) {\n set = new Set();\n listeners.set(taskId, set);\n }\n set.add(cb);\n return () => {\n const s = listeners.get(taskId);\n if (!s) return;\n s.delete(cb);\n if (s.size === 0) listeners.delete(taskId);\n };\n },\n dispose() {\n listeners.clear();\n unsub();\n },\n };\n}\n\n// -----------------------------------------------------------------------------\n// Caller-facing factory\n// -----------------------------------------------------------------------------\n\n/**\n * Task-augment a `tools/call` per the MCP 2025-11-25 tasks utility.\n *\n * A composable helper over {@link App} rather than a method on it: the object\n * `connect()` returns carries the ext-apps surface, and tasks ride alongside.\n * The receiver answers a task-augmented call with a `CreateTaskResult`\n * promptly; the actual `CallToolResult` arrives later via `tasks/result`.\n *\n * ```ts\n * const handle = await callToolAsTask(app, \"deep_research\", { topic });\n * handle.onStatus((t) => setStatus(t.status));\n * const result = await handle.result();\n * ```\n *\n * Rejects with `HostCapabilityError` if the host did not advertise\n * `tasks.requests.tools.call` — per spec a requestor MUST NOT task-augment\n * without matching receiver capability. Check `app.supportsTasks` first, and\n * fall back to `app.callTool`.\n */\nexport async function callToolAsTask<TOutput = unknown>(\n app: App,\n toolName: string,\n args?: unknown,\n options?: CallToolAsTaskOptions,\n): Promise<TaskHandle<TOutput>> {\n const deps = internalsFor(app);\n const hostTasks = deps.hostTasksCapability;\n if (!hostTasks?.requests?.tools?.call) {\n throw new HostCapabilityError(\n \"callToolAsTask\",\n `${TASKS_EXTENSION_ID} with requests.tools.call`,\n );\n }\n\n // Per spec, `task` is an object even when the caller provides no hints —\n // its presence is the signal to the receiver that augmentation is\n // requested. An empty `{}` is valid.\n const taskParam: { ttl?: number } = {};\n if (options?.ttl !== undefined) taskParam.ttl = options.ttl;\n\n // Build `tools/call` params. We layer our own shape on the SDK's\n // `CallToolRequest[\"params\"]` via `satisfies` so any rename upstream\n // (`name` → `toolName`, `arguments` → `args`, etc.) trips tsc.\n const callParams = {\n name: toolName,\n arguments: (args as Record<string, unknown> | undefined) ?? {},\n task: taskParam,\n } satisfies CallToolRequest[\"params\"];\n\n const raw = await deps.request(\n TOOLS_CALL_METHOD,\n callParams as unknown as Record<string, unknown>,\n );\n\n // Spec: task-augmented `tools/call` returns a `CreateTaskResult`. If a\n // receiver that advertised the capability returns a bare\n // `CallToolResult` instead, that's a protocol violation — surface it.\n const createResult = raw as CreateTaskResult | null | undefined;\n const initialTask = createResult?.task;\n if (!initialTask || typeof initialTask !== \"object\" || typeof initialTask.taskId !== \"string\") {\n throw new Error(\n \"callToolAsTask: receiver returned a response without `task` per CreateTaskResult \" +\n \"(expected shape: `{ task: { taskId, status, ... } }`). Receiver may not honor \" +\n \"the advertised tasks capability.\",\n );\n }\n\n const taskId = initialTask.taskId;\n\n // Preserve the Set-semantic dedup contract on `onStatus`: registering the\n // same callback twice collapses to one wire subscription, and either\n // returned unsub releases it. Without this, every `onStatus(cb)` would\n // create a fresh wrapper that the router treats as distinct.\n const localCallbacks = new Map<(task: Task) => void, () => void>();\n\n const handle: TaskHandle<TOutput> = {\n task: initialTask,\n\n async result(): Promise<ToolCallResult<TOutput>> {\n const params = { taskId } satisfies GetTaskPayloadRequest[\"params\"];\n const rawResult = await deps.request(\n TASKS_RESULT_METHOD,\n params as unknown as Record<string, unknown>,\n );\n // Per spec §: `tasks/result` returns exactly what the non-task\n // response would return. Parse through the shared tool-result\n // parser so `_meta[\"io.modelcontextprotocol/related-task\"]`\n // propagates unchanged (key-preserving spread).\n //\n // Type note: `GetTaskPayloadResult` is a union of result shapes\n // (one per augmentable request type). For `tools/call` tasks,\n // the runtime shape is `CallToolResult`, which `parseToolResult`\n // already handles.\n const typed = rawResult as GetTaskPayloadResult;\n return parseToolResult(typed) as ToolCallResult<TOutput>;\n },\n\n async refresh(): Promise<Task> {\n const params = { taskId } satisfies GetTaskRequest[\"params\"];\n const raw = await deps.request(\n TASKS_GET_METHOD,\n params as unknown as Record<string, unknown>,\n );\n // Per spec, `tasks/get` returns the task shape FLAT (taskId, status,\n // ttl, createdAt, lastUpdatedAt, ... at the top level) — NOT\n // wrapped in a `{ task }` field (unlike `CreateTaskResult`).\n return projectTask(raw as GetTaskResult);\n },\n\n async cancel(): Promise<Task> {\n const params = { taskId } satisfies CancelTaskRequest[\"params\"];\n const raw = await deps.request(\n TASKS_CANCEL_METHOD,\n params as unknown as Record<string, unknown>,\n );\n // `CancelTaskResult` is flat like `GetTaskResult`.\n return projectTask(raw as CancelTaskResult);\n },\n\n onStatus(cb) {\n // Idempotent-in-callback: if the same `cb` is already subscribed,\n // return the existing unsub.\n const existing = localCallbacks.get(cb);\n if (existing) return existing;\n\n // Merge the notification's spec-guaranteed fields (taskId, status,\n // statusMessage) with the handle's initial `CreateTaskResult.task`\n // so the consumer always sees a full valid `Task`. `lastUpdatedAt`\n // is stamped at SDK-receive time (an approximation of the host's\n // update time — the spec doesn't wire the host's timestamp through\n // the notification, so this is the closest signal we have).\n // `createdAt`, `ttl`, `pollInterval` come from the initial task\n // because they don't change over a task's lifetime.\n const wireUnsub = deps.taskRouter.subscribe(taskId, (update) => {\n const merged: Task = {\n taskId: update.taskId,\n status: update.status,\n ttl: initialTask.ttl,\n createdAt: initialTask.createdAt,\n lastUpdatedAt: new Date().toISOString(),\n ...(initialTask.pollInterval !== undefined && {\n pollInterval: initialTask.pollInterval,\n }),\n ...(update.statusMessage !== undefined && { statusMessage: update.statusMessage }),\n };\n cb(merged);\n });\n\n const unsub = () => {\n localCallbacks.delete(cb);\n wireUnsub();\n };\n localCallbacks.set(cb, unsub);\n return unsub;\n },\n };\n\n return handle;\n}\n\n// -----------------------------------------------------------------------------\n// Internal helpers\n// -----------------------------------------------------------------------------\n\n/**\n * Project a `GetTaskResult` / `CancelTaskResult` down to the canonical\n * `Task` shape. Both result types are structurally `Task` with an\n * optional `_meta` field on top; we project explicitly so consumers\n * don't see protocol-level `_meta` leaking onto the task state they\n * get back from `refresh()` / `cancel()`.\n *\n * Asymmetry note: `parseToolResult` (for `tools/call` / `tasks/result`\n * payloads) is key-preserving — `_meta` flows through end-to-end, which\n * matters for `io.modelcontextprotocol/related-task` correlation. Here\n * we drop `_meta` because no downstream consumer reads it on `Task` state\n * today. If a host starts stamping useful keys on `tasks/get`/`tasks/cancel`\n * responses, switch to a key-preserving projection.\n */\nfunction projectTask(raw: GetTaskResult | CancelTaskResult): Task {\n return {\n taskId: raw.taskId,\n status: raw.status,\n ttl: raw.ttl,\n createdAt: raw.createdAt,\n lastUpdatedAt: raw.lastUpdatedAt,\n ...(raw.pollInterval !== undefined && { pollInterval: raw.pollInterval }),\n ...(raw.statusMessage !== undefined && { statusMessage: raw.statusMessage }),\n };\n}\n","import type { ToolResultData } from \"./types.js\";\n\nexport type { ToolResultData };\n\n/**\n * Parse inbound `ui/notifications/tool-result` notification params into\n * a consistent `ToolResultData` shape.\n *\n * Implements the 5-step parsing algorithm from the RFC:\n * 1. If `params.structuredContent` exists → use it as content.\n * 2. Else if `params.content` is an array of `{type:\"text\", text}` blocks →\n * join the text values and try JSON.parse.\n * 3. Else if `params.content` is a string → try JSON.parse.\n * 4. If JSON.parse fails in steps 2 or 3 → deliver the raw string.\n * 5. Return `{ content, structuredContent, raw }`.\n */\nexport function parseToolResultParams(params: Record<string, unknown> | undefined): ToolResultData {\n const raw = params ?? {};\n const structuredContent = raw.structuredContent ?? null;\n\n // Step 1: If structuredContent exists, use it as content\n if (structuredContent != null) {\n return { content: structuredContent, structuredContent, raw };\n }\n\n const rawContent = raw.content;\n\n // Step 2: If content is array of {type:\"text\", text} blocks, join texts and try JSON.parse\n if (Array.isArray(rawContent)) {\n const texts = rawContent\n .filter(\n (block: unknown) =>\n block != null &&\n typeof block === \"object\" &&\n (block as Record<string, unknown>).type === \"text\" &&\n typeof (block as Record<string, unknown>).text === \"string\",\n )\n .map((block: unknown) => (block as Record<string, unknown>).text as string);\n\n if (texts.length > 0) {\n const joined = texts.join(\"\");\n try {\n return { content: JSON.parse(joined), structuredContent: null, raw };\n } catch {\n return { content: joined, structuredContent: null, raw };\n }\n }\n\n // No text blocks — return raw content array\n return { content: rawContent, structuredContent: null, raw };\n }\n\n // Step 3: If content is string, try JSON.parse\n if (typeof rawContent === \"string\") {\n try {\n return { content: JSON.parse(rawContent), structuredContent: null, raw };\n } catch {\n return { content: rawContent, structuredContent: null, raw };\n }\n }\n\n // Fallback: return content as-is (could be null, object, etc.)\n return { content: rawContent ?? null, structuredContent: null, raw };\n}\n","import { KEYDOWN_METHOD } from \"./event-map.js\";\nimport type { KeyForwardConfig } from \"./types.js\";\n\n/** Send a notification to the host. */\ntype SendFn = (method: string, params: Record<string, unknown>) => void;\n\n/**\n * Forward keyboard shortcuts from the iframe document to the host.\n *\n * By default, forwards all Ctrl/Cmd+key combos and Escape.\n * Apps can customize via `forwardKeys` config.\n */\nexport class KeyboardForwarder {\n private listener: (event: KeyboardEvent) => void;\n private destroyed = false;\n\n constructor(send: SendFn, customKeys?: KeyForwardConfig[]) {\n const config = customKeys ?? null; // null = default behavior\n\n this.listener = (event: KeyboardEvent) => {\n if (this.destroyed) return;\n if (this.shouldForward(event, config)) {\n event.preventDefault();\n send(KEYDOWN_METHOD, {\n key: event.key,\n ctrlKey: event.ctrlKey,\n metaKey: event.metaKey,\n shiftKey: event.shiftKey,\n altKey: event.altKey,\n });\n }\n };\n\n document.addEventListener(\"keydown\", this.listener);\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n document.removeEventListener(\"keydown\", this.listener);\n }\n\n private shouldForward(event: KeyboardEvent, config: KeyForwardConfig[] | null): boolean {\n // Empty array = forwarding disabled\n if (config && config.length === 0) return false;\n\n // Custom config: match exactly\n if (config) {\n return config.some(\n (k) =>\n event.key.toLowerCase() === k.key.toLowerCase() &&\n (k.ctrl === undefined || event.ctrlKey === k.ctrl) &&\n (k.meta === undefined || event.metaKey === k.meta) &&\n (k.shift === undefined || event.shiftKey === k.shift) &&\n (k.alt === undefined || event.altKey === k.alt),\n );\n }\n\n // Default: forward all Ctrl/Cmd combos + Escape,\n // EXCEPT clipboard shortcuts (c, v, x, a) which the browser must handle natively.\n if (event.key === \"Escape\") return true;\n if (event.ctrlKey || event.metaKey) {\n const key = event.key.toLowerCase();\n if (key === \"c\" || key === \"v\" || key === \"x\" || key === \"a\") return false;\n return true;\n }\n return false;\n }\n}\n","import { SIZE_CHANGED_METHOD } from \"@modelcontextprotocol/ext-apps\";\n\ntype SendFn = (method: string, params: Record<string, unknown>) => void;\n\ninterface Resizer {\n resize(width?: number, height?: number): void;\n measureAndSend(): void;\n destroy(): void;\n}\n\nexport function createResizer(send: SendFn, autoResize: boolean): Resizer {\n let destroyed = false;\n let observer: ResizeObserver | null = null;\n let rafId: number | null = null;\n\n function measureAndSend(): void {\n if (destroyed) return;\n const width = document.body.scrollWidth;\n const height = document.body.scrollHeight;\n send(SIZE_CHANGED_METHOD, { width, height });\n }\n\n function resize(width?: number, height?: number): void {\n if (destroyed) return;\n if (width !== undefined && height !== undefined) {\n send(SIZE_CHANGED_METHOD, { width, height });\n } else {\n measureAndSend();\n }\n }\n\n // Auto mode: attach ResizeObserver, debounced at 16ms via requestAnimationFrame\n if (autoResize && typeof ResizeObserver !== \"undefined\") {\n observer = new ResizeObserver(() => {\n if (destroyed) return;\n if (rafId !== null) cancelAnimationFrame(rafId);\n rafId = requestAnimationFrame(() => {\n rafId = null;\n measureAndSend();\n });\n });\n observer.observe(document.body);\n }\n\n function destroy(): void {\n if (destroyed) return;\n destroyed = true;\n if (rafId !== null) cancelAnimationFrame(rafId);\n observer?.disconnect();\n observer = null;\n }\n\n return { resize, measureAndSend, destroy };\n}\n","import type {\n AppEventMap,\n AppNotification,\n AppRequest,\n McpUiHostCapabilities,\n McpUiHostContext,\n McpUiInitializeRequest,\n McpUiMessageRequest,\n McpUiOpenLinkRequest,\n McpUiUpdateModelContextRequest,\n} from \"@modelcontextprotocol/ext-apps\";\nimport {\n applyHostFonts,\n App as ExtAppsApp,\n HOST_CONTEXT_CHANGED_METHOD,\n RESOURCE_TEARDOWN_METHOD,\n TOOL_CANCELLED_METHOD,\n TOOL_INPUT_METHOD,\n TOOL_INPUT_PARTIAL_METHOD,\n TOOL_RESULT_METHOD,\n} from \"@modelcontextprotocol/ext-apps\";\nimport type { RequestOptions } from \"@modelcontextprotocol/sdk/shared/protocol.js\";\nimport type {\n CallToolRequest,\n ReadResourceRequest,\n ReadResourceResult,\n TextContent,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { CallToolResultSchema, ResultSchema } from \"@modelcontextprotocol/sdk/types.js\";\n\nimport { parseToolResultParams } from \"./content-parser.js\";\nimport { extractHostFontCss, extractTheme } from \"./detection.js\";\nimport { HostCapabilityError } from \"./errors.js\";\nimport { NIMBLEBRAIN_EXTENSIONS, resolveEventMethod, TOOLS_CALL_METHOD } from \"./event-map.js\";\nimport { registerInternals } from \"./internals.js\";\nimport { KeyboardForwarder } from \"./keyboard.js\";\nimport { createResizer } from \"./resize.js\";\nimport { parseToolResult } from \"./result-parser.js\";\nimport { createTaskStatusRouter, readHostTasksCapability } from \"./task-handle.js\";\nimport { applyTheme } from \"./theme-defaults.js\";\nimport type {\n App,\n ConnectOptions,\n Dimensions,\n TasksCapability,\n Theme,\n ToolCallResult,\n} from \"./types.js\";\n\n/**\n * The host name that identifies a NimbleBrain host in the handshake. Identity\n * only: the NimbleBrain host extensions are gated on the host declaring each one.\n */\nconst NIMBLEBRAIN_HOST = \"nimblebrain\";\n\n/**\n * Requests this SDK sends carry no deadline.\n *\n * The MCP SDK gives every request a 60-second one, which is wrong for all three\n * kinds of request an app makes: a file picker waits on a person, `tasks/result`\n * blocks until the task finishes, and a tool call takes as long as the tool\n * takes. A deadline here would reject a call the host is still working on, and\n * the app would report a failure that did not happen.\n *\n * `Infinity` is not usable — `setTimeout` coerces it to `0` and the timer fires\n * immediately — so this is the largest delay a browser timer accepts, about 24\n * days.\n */\nconst NO_DEADLINE: RequestOptions = { timeout: 2_147_483_647 };\n\n/**\n * The events `App` models, paired with the wire method each one carries.\n *\n * Every one is registered exactly once, before the handshake, and fans out to\n * this SDK's own subscribers underneath. Two reasons it has to be this way: a\n * second registration for the same method through the `on*` setters throws, and\n * `App` warns when a handler for a one-shot event (the tool ones) is registered\n * after `connect()` resolves, which is when every hook subscribes.\n */\nconst MAPPED_EVENTS = [\n [\"toolinput\", TOOL_INPUT_METHOD],\n [\"toolinputpartial\", TOOL_INPUT_PARTIAL_METHOD],\n [\"toolresult\", TOOL_RESULT_METHOD],\n [\"toolcancelled\", TOOL_CANCELLED_METHOD],\n] as const satisfies ReadonlyArray<readonly [keyof AppEventMap, string]>;\n\n/**\n * Connect to an MCP Apps host.\n *\n * The one entry point. The protocol underneath is the spec's own client,\n * `@modelcontextprotocol/ext-apps`'s `App`: it owns the transport, the\n * handshake and the wire schemas. What this adds is the framework on top —\n * theme injection, the parsed payloads, multi-subscriber events, resize, and\n * the NimbleBrain extensions — and it resolves to a ready {@link App}.\n *\n * The `App` it returns stays deliberately small. NimbleBrain's own extensions\n * (`action`, the file picker), `downloadFile` and the MCP tasks utility are\n * composable functions over it — import them from the package root.\n */\nexport async function connect(options: ConnectOptions): Promise<App> {\n const { name, version, autoResize = false, forwardKeys } = options;\n\n let destroyed = false;\n\n // --- Mutable state ---\n //\n // The host context lives in `App`, which merges each delta into it, so it is\n // read back rather than copied. `theme` is a derived view of it.\n let hostInfo: { name: string; version: string } = { name: \"unknown\", version: \"unknown\" };\n let isNimbleBrainHost = false;\n let toolInfo: { tool: Record<string, unknown> } | null = null;\n let containerDimensions: Dimensions | null = null;\n let hostCapabilities: McpUiHostCapabilities = {};\n let hostTasksCapability: TasksCapability | undefined;\n let keyboard: KeyboardForwarder | null = null;\n\n // The theme currently applied to the document. Tracked rather than derived at\n // dispatch time, because `App` merges a host-context delta into the context it\n // holds *before* it calls listeners — so by the time this SDK hears about a\n // change, \"the theme before it\" is no longer recoverable from the context.\n // Comparing against what is actually loaded is also the honest question: the\n // filter exists to skip a re-render when nothing visible moved.\n let appliedTheme: Theme = { mode: \"light\", tokens: {} };\n\n // `appCapabilities` is typed as `McpUiAppCapabilities` by the ext-apps spec\n // package, which does not yet model the MCP 2025-11-25 tasks utility. We\n // extend structurally via `TasksCapability` and `satisfies` the extension so\n // the nested objects match the spec literally — empty objects `{}` as\n // presence flags, NOT booleans.\n const appCapabilities = {\n tasks: {\n cancel: {},\n requests: { tools: { call: {} } },\n } satisfies TasksCapability,\n };\n\n // `autoResize` is handed to `App`, which observes the document and reports\n // size after the handshake. Ours must not observe as well: two observers mean\n // two `size-changed` streams for one document.\n const client = new ExtAppsApp(\n { name, version },\n appCapabilities as unknown as McpUiInitializeRequest[\"params\"][\"appCapabilities\"],\n { autoResize },\n );\n\n function currentContext(): McpUiHostContext {\n return client.getHostContext() ?? {};\n }\n\n /**\n * The theme as reported to consumers, derived from the context. Every public\n * view goes through here — the `theme` getter, the `theme-changed` payload,\n * and its equality filter — so they cannot disagree with each other or with\n * what is actually applied.\n */\n function resolveTheme(): Theme {\n return extractTheme(currentContext());\n }\n\n /**\n * Load the host's `@font-face` CSS (`styles.css.fonts`) into the document.\n *\n * The spec's helper injects it once and leaves it in place, so a later\n * host-context change that carries no `css` — a theme toggle, say — keeps the\n * host's typeface loaded rather than unloading it.\n */\n function applyFontsFrom(ctx: Partial<McpUiHostContext> | undefined): void {\n const css = extractHostFontCss(ctx);\n if (css !== undefined && typeof document !== \"undefined\") applyHostFonts(css);\n }\n\n /** Apply the current theme to the document, and record what was applied. */\n function applyResolvedTheme(): Theme {\n const theme = resolveTheme();\n applyTheme(theme.mode, theme.tokens);\n appliedTheme = theme;\n return theme;\n }\n\n // --- Event handlers ---\n //\n // Generic wire methods share one registry keyed by method. The two events\n // that are a *view* over a wire message rather than the message itself\n // (theme, host context) get their own sets, because they ride the same\n // notification and hand their subscribers different payloads.\n const handlers = new Map<string, Set<(params: unknown) => void>>();\n const themeCallbacks = new Set<(theme: Theme) => void>();\n const hostContextCallbacks = new Set<(ctx: McpUiHostContext) => void>();\n\n /** Deliver a payload to everyone subscribed to a wire method. */\n function fanOut(method: string, payload: unknown): void {\n const set = handlers.get(method);\n if (!set) return;\n for (const handler of set) handler(payload);\n }\n\n /**\n * Send a notification `App` does not model. The NimbleBrain host extensions have\n * no spec equivalent and so no place in its notification union; the cast is\n * the one place that is admitted, and the method still comes from a constant\n * rather than a literal spelled at the call site.\n */\n function sendRaw(method: string, params?: Record<string, unknown>): void {\n if (destroyed) return;\n void client\n .notification({ method, params } as unknown as AppNotification)\n // A closed transport is the ordinary way this rejects, during teardown.\n .catch(() => {});\n }\n\n /** Send a request `App` does not model, and resolve with the host's result. */\n function requestRaw(method: string, params?: Record<string, unknown>): Promise<unknown> {\n return client.request({ method, params } as unknown as AppRequest, ResultSchema, NO_DEADLINE);\n }\n\n // --- Route what the host sends ---\n //\n // Registered before `connect()`, so a notification the host sends the instant\n // the handshake completes is already routed.\n\n for (const [event, method] of MAPPED_EVENTS) {\n client.addEventListener(event, (params) => {\n if (destroyed) return;\n // `tool-result` is delivered parsed — the payload every subscriber gets,\n // however they subscribed — because the wire shape is three shapes and\n // picking between them is work each app would otherwise repeat.\n fanOut(\n method,\n method === TOOL_RESULT_METHOD\n ? parseToolResultParams(params as Record<string, unknown>)\n : params,\n );\n });\n }\n\n client.addEventListener(\"hostcontextchanged\", (params) => {\n if (destroyed) return;\n const prevTheme = appliedTheme;\n\n // `App` has already merged this delta into the context it holds — shallowly,\n // which is what the spec asks for: `styles.variables` is a complete map when\n // the host sends one, so a deep merge would leave a host no way to remove a\n // variable. Fonts are read from the delta as sent, because a merged\n // context loses `styles.css` whenever the host sends `styles.variables`\n // alone.\n applyFontsFrom(params as Partial<McpUiHostContext>);\n const nextTheme = applyResolvedTheme();\n\n // Subscribers to the short event get the merged snapshot, because that is\n // what `app.hostContext` means and a delta cannot distinguish an omitted\n // field from a cleared one. A caller who genuinely wants the notification as\n // sent subscribes to the wire method instead, which is passed through\n // untouched.\n const merged = currentContext();\n for (const cb of hostContextCallbacks) cb(merged);\n fanOut(HOST_CONTEXT_CHANGED_METHOD, params);\n // Theme subscribers see only real theme movement: a host-context change\n // that leaves the derived theme identical (a workspace switch, say) must\n // not re-render every themed component in the app.\n if (!themesEqual(prevTheme, nextTheme)) {\n for (const cb of themeCallbacks) cb(nextTheme);\n }\n });\n\n // Teardown is a *request* in the spec, not a notification: the host asks, and\n // the view is expected to answer. Subscribers see it as the `teardown` event;\n // answering it is this SDK's job, not theirs.\n client.onteardown = (params) => {\n if (!destroyed) fanOut(RESOURCE_TEARDOWN_METHOD, params);\n return {};\n };\n\n // Everything else the host sends: vendor extension notifications, the server's\n // `notifications/resources/list_changed`, and `notifications/tasks/status`.\n // `App` routes a notification here when no typed handler claims its method,\n // and one handler with a fan-out under it is the only safe shape —\n // registering a second handler for a method would silently replace the first.\n client.fallbackNotificationHandler = async (notification) => {\n if (destroyed) return;\n fanOut(notification.method, notification.params);\n };\n\n /** Register one handler and return its unsubscribe. */\n function subscribe(event: string, handler: (params: any) => void): () => void {\n switch (event) {\n case \"theme-changed\":\n themeCallbacks.add(handler);\n return () => {\n themeCallbacks.delete(handler);\n };\n case \"host-context-changed\":\n hostContextCallbacks.add(handler);\n return () => {\n hostContextCallbacks.delete(handler);\n };\n default: {\n const method = resolveEventMethod(event);\n if (!handlers.has(method)) handlers.set(method, new Set());\n handlers.get(method)?.add(handler);\n return () => {\n const set = handlers.get(method);\n if (set) {\n set.delete(handler);\n if (set.size === 0) handlers.delete(method);\n }\n };\n }\n }\n }\n\n // Handlers from `options.on` are registered before the handshake goes out, so\n // a tool result the host sends in the same turn as `initialized` is not lost.\n if (options.on) {\n for (const [event, handler] of Object.entries(options.on)) {\n if (typeof handler === \"function\") subscribe(event, handler);\n }\n }\n\n // --- The handshake: `ui/initialize`, then `initialized` ---\n await client.connect();\n\n const hostVersion = client.getHostVersion();\n hostInfo = {\n name: hostVersion?.name ?? \"unknown\",\n version: hostVersion?.version ?? \"unknown\",\n };\n isNimbleBrainHost = hostInfo.name === NIMBLEBRAIN_HOST;\n\n // Everything an app may ask of the host is decided here, once: each method\n // below and each helper beside `App` checks the declaration before sending.\n hostCapabilities = client.getHostCapabilities() ?? {};\n hostTasksCapability = readHostTasksCapability(hostCapabilities);\n\n const initialContext = client.getHostContext();\n if (initialContext) {\n if (initialContext.toolInfo && typeof initialContext.toolInfo === \"object\") {\n toolInfo = {\n tool: (initialContext.toolInfo.tool as unknown as Record<string, unknown>) ?? {},\n };\n }\n if (\n initialContext.containerDimensions &&\n typeof initialContext.containerDimensions === \"object\"\n ) {\n containerDimensions = initialContext.containerDimensions as Dimensions;\n }\n\n // Inject the theme into the DOM: the host's values go inline, and the\n // neutral defaults for the mode go in a cascade layer, where they back any\n // var nobody declares and lose to every var that is declared. The host's\n // `@font-face` CSS loads alongside — a token names a family, it cannot load\n // one.\n applyFontsFrom(initialContext);\n applyResolvedTheme();\n }\n\n // Keyboard forwarding is a NimbleBrain extension. Forwarding to a host that\n // did not declare it would `preventDefault` a key for a host that does\n // nothing with it, so the gate is on the declaration, not just the option.\n if (\n forwardKeys &&\n hostCapabilities.experimental?.[NIMBLEBRAIN_EXTENSIONS.keydown.capability] !== undefined\n ) {\n keyboard = new KeyboardForwarder(sendRaw, forwardKeys === true ? undefined : forwardKeys);\n }\n\n // The resizer serves `app.resize()`. It never observes: under `autoResize`\n // that is `App`'s job, and it has already reported the first size.\n const resizer = createResizer(sendRaw, false);\n if (!autoResize) resizer.measureAndSend();\n\n // Shared router for `notifications/tasks/status`. Created eagerly so the\n // subscription registers exactly once — every `TaskHandle` filters off this\n // single wire subscription by taskId.\n const taskRouter = createTaskStatusRouter((method, handler) =>\n subscribe(method, handler as (params: any) => void),\n );\n\n // --- The App this SDK hands out ---\n const app: App = {\n get theme() {\n return resolveTheme();\n },\n get hostInfo() {\n return { ...hostInfo };\n },\n get hostContext() {\n return currentContext();\n },\n get hostCapabilities() {\n return hostCapabilities;\n },\n get isNimbleBrainHost() {\n return isNimbleBrainHost;\n },\n get toolInfo() {\n return toolInfo;\n },\n get containerDimensions() {\n return containerDimensions;\n },\n get destroyed() {\n return destroyed;\n },\n get supportsTasks() {\n return hostTasksCapability?.requests?.tools?.call !== undefined;\n },\n\n on(event: string, handler: (params: any) => void): () => void {\n return subscribe(event, handler);\n },\n\n resize(width?: number, height?: number): void {\n resizer.resize(width, height);\n },\n\n openLink(url: string): void {\n if (destroyed) return;\n if (!hostCapabilities.openLinks) {\n window.open(url, \"_blank\", \"noopener\");\n return;\n }\n const params: McpUiOpenLinkRequest[\"params\"] = { url };\n client.openLink(params, NO_DEADLINE).catch(() => {\n // The host refused or does not serve it: open directly instead.\n window.open(url, \"_blank\", \"noopener\");\n });\n },\n\n updateModelContext(state: Record<string, unknown>, summary?: string): void {\n if (destroyed || !hostCapabilities.updateModelContext) return;\n const params: McpUiUpdateModelContextRequest[\"params\"] = {\n structuredContent: state,\n ...(summary !== undefined && {\n content: [{ type: \"text\", text: summary } satisfies TextContent],\n }),\n };\n client.updateModelContext(params, NO_DEADLINE).catch(() => {});\n },\n\n async callTool<TOutput = unknown>(\n toolName: string,\n args?: Record<string, unknown>,\n ): Promise<ToolCallResult<TOutput>> {\n if (!hostCapabilities.serverTools) {\n throw new HostCapabilityError(\"callTool\", \"serverTools\");\n }\n // No target. A host scopes an app's call to the server that mounted it,\n // so `params` carries what the spec names and nothing else.\n const params: CallToolRequest[\"params\"] = {\n name: toolName,\n arguments: args ?? {},\n };\n // Sent through the generic request path rather than `callServerTool`,\n // which asks for a progress token: that puts `_meta.progressToken` on\n // every call, and nothing here subscribes to progress. The result is\n // validated against the spec's schema either way.\n const raw = await client.request(\n { method: TOOLS_CALL_METHOD, params },\n CallToolResultSchema,\n NO_DEADLINE,\n );\n return parseToolResult(raw) as ToolCallResult<TOutput>;\n },\n\n async readServerResource(params: ReadResourceRequest[\"params\"]): Promise<ReadResourceResult> {\n if (!hostCapabilities.serverResources) {\n throw new HostCapabilityError(\"readServerResource\", \"serverResources\");\n }\n return await client.readServerResource(params, NO_DEADLINE);\n },\n\n sendMessage(text: string): void {\n if (destroyed || !hostCapabilities.message) return;\n const textBlock: TextContent = { type: \"text\", text };\n const params: McpUiMessageRequest[\"params\"] = {\n role: \"user\",\n content: [textBlock],\n };\n client.sendMessage(params, NO_DEADLINE).catch(() => {});\n },\n\n destroy(): void {\n if (destroyed) return;\n destroyed = true;\n keyboard?.destroy();\n resizer.destroy();\n taskRouter.dispose();\n handlers.clear();\n themeCallbacks.clear();\n hostContextCallbacks.clear();\n void client.close();\n },\n };\n\n registerInternals(app, {\n send(method, params) {\n sendRaw(method, params);\n },\n request(method, params) {\n return requestRaw(method, params);\n },\n onMessage(method, handler) {\n return subscribe(method, handler as (params: any) => void);\n },\n taskRouter,\n get hostTasksCapability() {\n return hostTasksCapability;\n },\n });\n\n return app;\n}\n\n/**\n * Shallow equality for `Theme` — used to filter host-context changes that\n * don't actually move the theme (e.g. a workspace switch that leaves\n * theme/styles untouched). Cheap; tokens are ~40 entries.\n */\nfunction themesEqual(a: Theme, b: Theme): boolean {\n if (a.mode !== b.mode) return false;\n const aKeys = Object.keys(a.tokens);\n const bKeys = Object.keys(b.tokens);\n if (aKeys.length !== bKeys.length) return false;\n // Iterating only over `a`'s keys is sufficient: under equal length, any key\n // in `a` missing from `b` reads `b[k] === undefined`, which fails the strict\n // inequality check. Symmetric difference is covered.\n for (const k of aKeys) {\n if (a.tokens[k] !== b.tokens[k]) return false;\n }\n return true;\n}\n","/**\n * NimbleBrain host extensions — composable functions over {@link App}.\n *\n * These are not ext-apps spec surface. They are the NimbleBrain host's own\n * `ai.nimblebrain/*` methods, which this package implements a client for, and\n * `NIMBLEBRAIN_EXTENSIONS` in `event-map.ts` is the complete list. They\n * live here rather than on the `App` object so the object stays the spec\n * surface plus the handshake state, and so an app that never picks a file\n * never pulls this code in.\n *\n * Every one of them is gated on the host declaring it in `ui/initialize`: where\n * it is not declared, the fire-and-forget ones are no-ops and the ones with a\n * return value throw `HostCapabilityError`, because a picker that silently\n * resolves `null` forever is worse than one that says it isn't there.\n * `keydown` has no function here; `connect({ forwardKeys })` applies the same\n * gate.\n */\nimport { HostCapabilityError } from \"./errors.js\";\nimport { NIMBLEBRAIN_EXTENSIONS, type NimbleBrainExtension } from \"./event-map.js\";\nimport { internalsFor } from \"./internals.js\";\nimport type { App, FileResult, RequestFileOptions } from \"./types.js\";\n\n/**\n * Whether the host declared a NimbleBrain extension. Use it to decide what to\n * offer, e.g. to hide an upload button on a host with no file picker.\n */\nexport function hostSupports(app: App, extension: NimbleBrainExtension): boolean {\n const { capability } = NIMBLEBRAIN_EXTENSIONS[extension];\n return app.hostCapabilities.experimental?.[capability] !== undefined;\n}\n\n/** 25 MB — the host's default cap on a single picked file. */\nconst DEFAULT_MAX_FILE_SIZE = 26_214_400;\n\n/**\n * Trigger a host-side action.\n *\n * Sends a command *to* the host. The NimbleBrain host serves `openApp`\n * (`{ name }`) and `openConversation` (`{ id }`) and ignores any other name. A\n * message into the conversation is `sendMessage`, and an external page is\n * `openLink`. A no-op when the host did not declare `ai.nimblebrain/action`.\n */\nexport function action(app: App, name: string, params?: Record<string, unknown>): void {\n if (!hostSupports(app, \"action\")) return;\n internalsFor(app).send(NIMBLEBRAIN_EXTENSIONS.action.method, { action: name, ...params });\n}\n\n/**\n * Request one file from the user via the host's native file picker.\n *\n * Resolves `null` if the user cancels. Rejects with `HostCapabilityError` when\n * the host did not declare `ai.nimblebrain/request-file`.\n */\nexport async function pickFile(app: App, options?: RequestFileOptions): Promise<FileResult | null> {\n requireRequestFile(\"pickFile\", app);\n const files = await requestFile(app, options, false);\n // One pick, so the first entry is the answer; an empty list is a cancel.\n return files[0] ?? null;\n}\n\n/**\n * Request several files from the user.\n *\n * Resolves `[]` if the user cancels. Rejects with `HostCapabilityError` when\n * the host did not declare `ai.nimblebrain/request-file`.\n */\nexport async function pickFiles(app: App, options?: RequestFileOptions): Promise<FileResult[]> {\n requireRequestFile(\"pickFiles\", app);\n return await requestFile(app, options, true);\n}\n\nfunction requireRequestFile(feature: string, app: App): void {\n if (!hostSupports(app, \"requestFile\")) {\n throw new HostCapabilityError(feature, NIMBLEBRAIN_EXTENSIONS.requestFile.capability);\n }\n}\n\n/**\n * Shared request path for `pickFile` / `pickFiles`.\n *\n * The host answers with `{ files }` — an empty array when the user cancelled.\n * A JSON-RPC result is an object by definition, and MCP types it as one, so the\n * files travel under a field rather than as a bare array or a bare `null`: a\n * spec client refuses to parse anything else, and the call would hang rather\n * than resolve.\n *\n * Entries are shape-checked here. The type promises a string `id`, and without\n * the guard a consumer reads `undefined.id` three frames later, where nothing\n * says which side is mismatched.\n */\nasync function requestFile(\n app: App,\n options: RequestFileOptions | undefined,\n multiple: boolean,\n): Promise<FileResult[]> {\n const result = await internalsFor(app).request(NIMBLEBRAIN_EXTENSIONS.requestFile.method, {\n accept: options?.accept,\n maxSize: options?.maxSize ?? DEFAULT_MAX_FILE_SIZE,\n multiple,\n });\n const files = (result as { files?: unknown } | null | undefined)?.files;\n if (files === undefined) {\n throw new Error(\n \"ai.nimblebrain/request-file returned no `files`. The host is older than this \" +\n \"SDK targets: it answers the picker with a bare array or `null`, which \" +\n \"a spec-compliant client cannot parse.\",\n );\n }\n if (!Array.isArray(files)) {\n throw new Error(\"ai.nimblebrain/request-file returned a `files` field that is not an array.\");\n }\n return files.map(validateFileResult);\n}\n\nfunction validateFileResult(value: unknown): FileResult {\n if (\n typeof value !== \"object\" ||\n value === null ||\n typeof (value as { id?: unknown }).id !== \"string\"\n ) {\n throw new Error(\n \"ai.nimblebrain/request-file returned a result without a string `id`. \" +\n \"The host appears to be on a version older than this SDK targets — \" +\n \"@nimblebrain/synapse 0.8.0+ requires a host with POST /v1/resources \" +\n \"(NimbleBrain ≥ the version that ships PR #93).\",\n );\n }\n return value as FileResult;\n}\n"]}
@@ -86,7 +86,7 @@ async function runPreview(args2) {
86
86
  });
87
87
  }
88
88
  async function runCheck(args2) {
89
- const { applyProfiles, formatReport, isTargetName, PROFILES, runChecks } = await import('../check-VK4SOAUU.cjs');
89
+ const { applyProfiles, formatReport, isTargetName, PROFILES, runChecks } = await import('../check-53RMGOVV.cjs');
90
90
  const flags = parseFlags(args2, ["target", "token"]);
91
91
  const json = args2.includes("--json");
92
92
  const positional = args2.filter(
@@ -84,7 +84,7 @@ async function runPreview(args2) {
84
84
  });
85
85
  }
86
86
  async function runCheck(args2) {
87
- const { applyProfiles, formatReport, isTargetName, PROFILES, runChecks } = await import('../check-QMTOCTRS.js');
87
+ const { applyProfiles, formatReport, isTargetName, PROFILES, runChecks } = await import('../check-CSE4XQRL.js');
88
88
  const flags = parseFlags(args2, ["target", "token"]);
89
89
  const json = args2.includes("--json");
90
90
  const positional = args2.filter(
@@ -1,4 +1,4 @@
1
- import { e as ToolDefinition } from '../types-BxPfGHKO.cjs';
1
+ import { e as ToolDefinition } from '../types-BBoCSg35.cjs';
2
2
  import '@modelcontextprotocol/ext-apps';
3
3
  import '@modelcontextprotocol/sdk/types.js';
4
4
 
@@ -1,4 +1,4 @@
1
- import { e as ToolDefinition } from '../types-BxPfGHKO.js';
1
+ import { e as ToolDefinition } from '../types-BBoCSg35.js';
2
2
  import '@modelcontextprotocol/ext-apps';
3
3
  import '@modelcontextprotocol/sdk/types.js';
4
4