diff --git a/examples/notion/README.md b/examples/notion/README.md index 8038c79..74bff1c 100644 --- a/examples/notion/README.md +++ b/examples/notion/README.md @@ -8,8 +8,9 @@ server and adds native React widgets for the tool results. - 1:1 Sidecar tool folders for the public Notion MCP tool names. - An explicit `authorize` tool that returns the user's Notion OAuth link before they run other Notion tools. -- WorkOS AuthKit as the MCP authorization server. -- WorkOS Vault storage for each user's upstream Notion MCP token. +- WorkOS-managed API keys as the MCP bearer credential. +- WorkOS Vault storage for the upstream Notion MCP token, keyed by the API + key owner. - Streamable HTTP calls to `https://mcp.notion.com/mcp` with the official MCP TypeScript SDK. - Native widgets for search, fetch, read/query, metadata, and write results. @@ -73,39 +74,40 @@ This example is intentionally not a root npm workspace, so Vercel installs ## Auth -Hosted Notion MCP requires a Notion-audience OAuth token. This example keeps -Sidecar spec-compliant by making this MCP server the resource server and using -WorkOS AuthKit as its authorization server. It stores the separate upstream -Notion MCP token in WorkOS Vault, keyed by the authenticated WorkOS user id. +Hosted Notion MCP requires a Notion-audience OAuth token. This example uses a +WorkOS-managed API key as the MCP bearer credential. The server validates the +incoming bearer token with WorkOS API Keys and stores the separate upstream +Notion MCP token in WorkOS Vault under the validated key owner. + +This keeps the Sidecar dev harness simple: paste the WorkOS organization API key +into the bearer-token field and the harness sends it as the standard MCP +`Authorization: Bearer ...` header. Configure: ```sh WORKOS_CLIENT_ID=client_... WORKOS_API_KEY_NOTION=sk_... -WORKOS_AUTHKIT_DOMAIN=your-subdomain.authkit.app SIDECAR_MCP_URL=https://sidecar-notion.vercel.app/mcp SIDECAR_PUBLIC_URL=https://sidecar-notion.vercel.app ``` -WorkOS MCP auth requires Connect configuration in the WorkOS dashboard: - -1. Enable Client ID Metadata Document (CIMD). Dynamic Client Registration - (DCR) is optional for clients that have not adopted CIMD yet. -2. Add `https://sidecar-notion.vercel.app/mcp` as a Resource Indicator. -3. Use the AuthKit domain shown in WorkOS, for example - `your-subdomain.authkit.app`, as `WORKOS_AUTHKIT_DOMAIN`. - -`auth.ts` verifies AuthKit access tokens against the AuthKit issuer and JWKS -endpoint. Tool execution reads the user's Notion MCP token from WorkOS Vault -with an object name derived from the WorkOS user id and a Vault key context -containing `user_id` and `data_type=notion_mcp_token`. - -When a user has no stored Notion token, ask the model to run `authorize` first. -That tool returns a Notion OAuth link for the current authenticated WorkOS user. -If the user calls another Notion tool before linking, the tool result also -includes the same authorization link. The flow uses Notion's MCP OAuth -discovery, dynamic client registration, PKCE, and the local callback route at -`/notion/oauth/callback`. The callback stores the Notion access token and -refresh token in WorkOS Vault. Access tokens are refreshed from Vault before -upstream tool calls when they are close to expiry. +Create an organization-owned or user-owned API key in WorkOS AuthKit, then +either paste it into the local harness bearer-token dialog or set it as +`MCP_BEARER` before starting dev. User-owned keys still require an organization +membership; WorkOS uses that membership to decide which organization the key can +access. + +`auth.ts` validates `Authorization: Bearer ` with WorkOS. Tool +execution reads the Notion MCP token from WorkOS Vault with an object name +derived from the validated key owner and a Vault key context containing +`user_id`, `organization_id` when present, and `data_type=notion_mcp_token`. + +When Vault has no stored Notion token for the configured owner id, ask the model +to run `authorize` first. That tool returns a Notion OAuth link. If the user +calls another Notion tool before linking, the tool result also includes the same +authorization link. The flow uses Notion's MCP OAuth discovery, dynamic client +registration, PKCE, and the local callback route at `/notion/oauth/callback`. +The callback stores the Notion access token and refresh token in WorkOS Vault. +Access tokens are refreshed from Vault before upstream tool calls when they are +close to expiry. diff --git a/examples/notion/auth.ts b/examples/notion/auth.ts index aa2394d..931bac0 100644 --- a/examples/notion/auth.ts +++ b/examples/notion/auth.ts @@ -1,36 +1,57 @@ /** - * WorkOS AuthKit authentication for the hosted Notion MCP example. + * WorkOS API-key authentication for the private Notion MCP example. * - * Sidecar is the MCP resource server, AuthKit is the OAuth authorization - * server, and WorkOS Vault stores the per-user upstream Notion MCP token. + * The Sidecar dev harness and MCP clients send a standard bearer token. This + * file validates that bearer value with WorkOS API Keys, then uses the API key + * owner as the stable Vault owner for the upstream Notion token. */ import "dotenv/config"; -import { createRemoteJWKSet, jwtVerify, type JWTPayload } from "jose"; +import { WorkOS } from "@workos-inc/node"; import { auth, type AuthSession } from "sidecar-ai"; -const DEFAULT_AUTHKIT_ISSUER = "https://signin.workos.com"; - -/** Verified AuthKit claims accepted by this example. */ -export type WorkOSMcpClaims = JWTPayload & { - scope?: string; - scp?: string[]; - client_id?: string; - org_id?: string; - organization_id?: string; +/** Claims attached to validated WorkOS API-key sessions in this example. */ +export type NotionApiKeyClaims = { + sub: string; + scope: string; + kind: "workos-api-key"; + apiKeyId: string; + ownerType: "organization" | "user"; + ownerId: string; + organizationId?: string; + permissions: string[]; }; /** Session shape available to every Notion tool through `ctx.auth`. */ export type NotionSession = AuthSession< - WorkOSMcpClaims, + NotionApiKeyClaims, { workosUserId: string; workosOrganizationId?: string; + workosApiKeyId: string; + workosApiKeyName: string; + workosApiKeyPermissions: string[]; } >; +let workosClient: WorkOS | undefined; +let warnedMissingWorkosKey = false; + +/** Minimal API key shape returned by WorkOS validation. */ +type ValidatedWorkosApiKey = { + id: string; + owner: { + type: "organization" | "user"; + id: string; + organizationId?: string; + organization_id?: string; + }; + name: string; + permissions: string[]; +}; + const appAuth = auth({ resource: mcpResource(), - authorizationServers: [authKitIssuer()], + authorizationServers: [metadataOnlyAuthorizationServer()], scopes: {}, async session(request): Promise { const token = request.bearerToken(); @@ -38,105 +59,177 @@ const appAuth = auth({ return null; } - const claims = await verifyAuthKitToken(token).catch((error) => { - console.warn(JSON.stringify({ - event: "sidecar.notion.auth.invalid_token", - message: error instanceof Error ? error.message : "Invalid AuthKit token.", - })); - return null; - }); - if (!claims) { + const apiKey = await validateWorkosApiKey(token); + if (!apiKey) { return null; } - const workosUserId = subject(claims); - const workosOrganizationId = organizationId(claims); - - return { - userId: workosUserId, - subject: workosUserId, - clientId: optionalString(claims.client_id), - scopes: scopesFromClaims(claims), - expiresAt: expiresAt(claims), - token, - claims, - workosUserId, - workosOrganizationId, - }; + return sessionFromApiKey(token, apiKey); }, }); export default appAuth; -/** Verifies an AuthKit-issued JWT against the issuer's JWKS endpoint. */ -async function verifyAuthKitToken(token: string): Promise { - const issuer = authKitIssuer(); - const jwks = createRemoteJWKSet(new URL("/oauth2/jwks", issuer)); - const { payload } = await jwtVerify(token, jwks, { issuer }); - return payload as WorkOSMcpClaims; -} - /** Returns the MCP resource URL advertised to clients. */ function mcpResource(): string { return process.env.SIDECAR_MCP_URL ?? "http://127.0.0.1:3101/mcp"; } -/** Returns the AuthKit issuer URL configured in WorkOS. */ -function authKitIssuer(): string { - const explicit = process.env.WORKOS_AUTHKIT_ISSUER ?? process.env.AUTHKIT_ISSUER; - if (explicit) { - return normalizeIssuer(explicit); +/** + * Returns the metadata-only authorization server URL required by Sidecar auth. + * + * This example authenticates with WorkOS-managed API keys instead of an OAuth + * login flow into Sidecar. Clients should send `Authorization: Bearer ` + * directly and should not attempt OAuth discovery against this URL. + */ +function metadataOnlyAuthorizationServer(): string { + return process.env.SIDECAR_NOTION_AUTH_SERVER ?? "https://sidecar.ai/notion-workos-api-key"; +} + +/** Validates a bearer token with WorkOS API Keys. */ +async function validateWorkosApiKey(value: string): Promise { + try { + const result = await createApiKeyValidation(value); + return normalizeValidatedApiKey(result.apiKey); + } catch (error) { + console.warn(JSON.stringify({ + event: "sidecar.notion.auth.api_key_validation_failed", + message: error instanceof Error ? error.message : "WorkOS API key validation failed.", + })); + return null; } +} - const domain = process.env.WORKOS_AUTHKIT_DOMAIN ?? process.env.AUTHKIT_DOMAIN; - if (domain) { - return normalizeIssuer(domain.startsWith("http") ? domain : `https://${domain}`); +/** Supports both current and older WorkOS SDK validation method names. */ +async function createApiKeyValidation(value: string): Promise<{ apiKey: unknown }> { + const apiKeys = workos().apiKeys as { + validateApiKey?: (payload: { value: string }) => Promise<{ apiKey: unknown }>; + createValidation?: (payload: { value: string }) => Promise<{ apiKey: unknown }>; + }; + const validate = apiKeys.validateApiKey ?? apiKeys.createValidation; + if (!validate) { + throw new Error("Installed @workos-inc/node does not expose API key validation."); } - return DEFAULT_AUTHKIT_ISSUER; + return await validate.call(apiKeys, { value }); } -/** Ensures issuer strings are URL-like and do not carry a trailing slash. */ -function normalizeIssuer(value: string): string { - const url = new URL(value); - if (url.protocol !== "https:" && url.hostname !== "localhost" && url.hostname !== "127.0.0.1") { - throw new Error("WORKOS_AUTHKIT_ISSUER must be https:// except for localhost development."); +/** Normalizes WorkOS API key validation output across SDK response shapes. */ +function normalizeValidatedApiKey(value: unknown): ValidatedWorkosApiKey | null { + if (!isRecord(value)) { + return null; + } + if (typeof value.id !== "string" || typeof value.name !== "string" || !isRecord(value.owner)) { + return null; + } + const ownerType = value.owner.type; + const ownerId = value.owner.id; + if ((ownerType !== "organization" && ownerType !== "user") || typeof ownerId !== "string") { + return null; } - url.pathname = url.pathname.replace(/\/+$/, ""); - return url.toString().replace(/\/$/, ""); + return { + id: value.id, + name: value.name, + owner: { + type: ownerType, + id: ownerId, + organizationId: optionalString(value.owner.organizationId) ?? optionalString(value.owner.organization_id), + }, + permissions: Array.isArray(value.permissions) + ? value.permissions.filter((permission): permission is string => typeof permission === "string") + : [], + }; } -/** Extracts the authenticated user id from required JWT subject. */ -function subject(claims: WorkOSMcpClaims): string { - if (!claims.sub) { - throw new Error("AuthKit token is missing required subject claim."); - } - return claims.sub; +/** Builds a Sidecar session from a validated WorkOS API key. */ +function sessionFromApiKey(token: string, apiKey: ValidatedWorkosApiKey): NotionSession { + const owner = apiKeyOwner(apiKey); + const claims: NotionApiKeyClaims = { + sub: owner.userId, + scope: permissionsScope(apiKey.permissions), + kind: "workos-api-key", + apiKeyId: apiKey.id, + ownerType: apiKey.owner.type, + ownerId: apiKey.owner.id, + organizationId: owner.organizationId, + permissions: apiKey.permissions, + }; + + return { + userId: owner.userId, + subject: owner.userId, + clientId: apiKey.id, + scopes: apiKey.permissions, + token, + claims, + workosUserId: owner.userId, + workosOrganizationId: owner.organizationId, + workosApiKeyId: apiKey.id, + workosApiKeyName: apiKey.name, + workosApiKeyPermissions: apiKey.permissions, + }; } -/** Extracts a WorkOS organization id when the token contains one. */ -function organizationId(claims: WorkOSMcpClaims): string | undefined { - return optionalString(claims.org_id) ?? optionalString(claims.organization_id); +/** Returns the Vault owner identity represented by a WorkOS API key. */ +function apiKeyOwner(apiKey: ValidatedWorkosApiKey): { userId: string; organizationId?: string } { + if (apiKey.owner.type === "organization") { + return { + userId: apiKey.owner.id, + organizationId: apiKey.owner.id, + }; + } + + return { + userId: apiKey.owner.id, + organizationId: apiKey.owner.organizationId, + }; } -/** Converts JWT expiry seconds into a Date for Sidecar's auth context. */ -function expiresAt(claims: WorkOSMcpClaims): Date | undefined { - return typeof claims.exp === "number" ? new Date(claims.exp * 1000) : undefined; +/** Creates the WorkOS SDK client lazily so imports stay cheap. */ +function workos(): WorkOS { + workosClient ??= new WorkOS(requiredEnv("WORKOS_API_KEY_NOTION", "WORKOS_API_KEY"), { + clientId: process.env.WORKOS_CLIENT_ID, + }); + return workosClient; } -/** Reads OAuth scopes from either `scope` or `scp` claim conventions. */ -function scopesFromClaims(claims: WorkOSMcpClaims): string[] { - if (Array.isArray(claims.scp)) { - return claims.scp.filter((scope): scope is string => typeof scope === "string" && scope.length > 0); +/** Reads the first present environment variable from a prioritized list. */ +function requiredEnv(...names: string[]): string { + for (const name of names) { + const value = process.env[name]; + if (value) { + return value; + } } - if (typeof claims.scope === "string") { - return claims.scope.split(/\s+/).filter(Boolean); + + warnMissingWorkosKeyOnce(names); + throw new Error(`Set one of ${names.join(", ")} before validating WorkOS API keys.`); +} + +/** Warns once when the server-side WorkOS key is missing. */ +function warnMissingWorkosKeyOnce(names: string[]): void { + if (warnedMissingWorkosKey) { + return; } - return []; + warnedMissingWorkosKey = true; + console.warn(JSON.stringify({ + event: "sidecar.notion.auth.missing_workos_api_key", + message: `Set one of ${names.join(", ")} before calling the Notion MCP example.`, + })); +} + +/** Formats API key permissions as an OAuth-style scope string for diagnostics. */ +function permissionsScope(permissions: string[]): string { + return permissions.length ? permissions.join(" ") : "notion"; +} + +/** Returns true for non-array objects. */ +function isRecord(value: unknown): value is Record { + return Boolean(value && typeof value === "object" && !Array.isArray(value)); } -/** Returns a string only when the claim is present. */ +/** Returns a non-empty string value. */ function optionalString(value: unknown): string | undefined { return typeof value === "string" && value ? value : undefined; } diff --git a/examples/notion/lib/workos-vault.ts b/examples/notion/lib/workos-vault.ts index 8477424..f5a0e9f 100644 --- a/examples/notion/lib/workos-vault.ts +++ b/examples/notion/lib/workos-vault.ts @@ -48,7 +48,7 @@ export type StoredNotionOAuthState = NotionTokenOwner & { /** Identity used to scope one stored Notion token. */ export type NotionTokenOwner = { - /** WorkOS user id from the validated AuthKit access token. */ + /** Stable owner id used to partition the stored Notion token in Vault. */ workosUserId: string; /** WorkOS organization id, if this app is running in an org context. */ workosOrganizationId?: string; diff --git a/examples/notion/package-lock.json b/examples/notion/package-lock.json index 8e42d13..1ab9ff5 100644 --- a/examples/notion/package-lock.json +++ b/examples/notion/package-lock.json @@ -1,25 +1,24 @@ { "name": "sidecar-notion-example", - "version": "0.1.0-alpha.14", + "version": "0.1.0-alpha.15", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "sidecar-notion-example", - "version": "0.1.0-alpha.14", + "version": "0.1.0-alpha.15", "dependencies": { "@modelcontextprotocol/sdk": "^1.29.0", - "@sidecar-ai/anthropic": "0.1.0-alpha.14", - "@sidecar-ai/openai": "0.1.0-alpha.14", + "@sidecar-ai/anthropic": "0.1.0-alpha.15", + "@sidecar-ai/openai": "0.1.0-alpha.15", "@workos-inc/node": "^9.3.0", "dotenv": "^17.4.2", - "jose": "^6.2.3", "react": "^19.0.0", "react-dom": "^19.0.0", "react-markdown": "^9.1.0", "remark-breaks": "^4.0.0", "remark-gfm": "^4.0.1", - "sidecar-ai": "0.1.0-alpha.14" + "sidecar-ai": "0.1.0-alpha.15" } }, "node_modules/@alloc/quick-lru": { @@ -69,9 +68,9 @@ "license": "Apache-2.0" }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz", - "integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", + "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", "cpu": [ "ppc64" ], @@ -85,9 +84,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz", - "integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", + "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", "cpu": [ "arm" ], @@ -101,9 +100,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz", - "integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", + "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", "cpu": [ "arm64" ], @@ -117,9 +116,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz", - "integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", + "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", "cpu": [ "x64" ], @@ -133,9 +132,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz", - "integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", + "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", "cpu": [ "arm64" ], @@ -149,9 +148,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz", - "integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", + "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", "cpu": [ "x64" ], @@ -165,9 +164,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz", - "integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", + "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", "cpu": [ "arm64" ], @@ -181,9 +180,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz", - "integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", + "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", "cpu": [ "x64" ], @@ -197,9 +196,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz", - "integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", + "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", "cpu": [ "arm" ], @@ -213,9 +212,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz", - "integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", + "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", "cpu": [ "arm64" ], @@ -229,9 +228,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz", - "integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", + "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", "cpu": [ "ia32" ], @@ -245,9 +244,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz", - "integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", + "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", "cpu": [ "loong64" ], @@ -261,9 +260,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz", - "integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", + "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", "cpu": [ "mips64el" ], @@ -277,9 +276,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz", - "integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", + "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", "cpu": [ "ppc64" ], @@ -293,9 +292,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz", - "integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", + "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", "cpu": [ "riscv64" ], @@ -309,9 +308,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz", - "integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", + "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", "cpu": [ "s390x" ], @@ -325,9 +324,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz", - "integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", + "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", "cpu": [ "x64" ], @@ -341,9 +340,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz", - "integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", + "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", "cpu": [ "arm64" ], @@ -357,9 +356,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz", - "integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", + "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", "cpu": [ "x64" ], @@ -373,9 +372,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz", - "integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", + "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", "cpu": [ "arm64" ], @@ -389,9 +388,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz", - "integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", + "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", "cpu": [ "x64" ], @@ -405,9 +404,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz", - "integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", + "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", "cpu": [ "arm64" ], @@ -421,9 +420,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz", - "integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", + "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", "cpu": [ "x64" ], @@ -437,9 +436,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz", - "integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", + "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", "cpu": [ "arm64" ], @@ -453,9 +452,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz", - "integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", + "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", "cpu": [ "ia32" ], @@ -469,9 +468,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz", - "integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", + "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", "cpu": [ "x64" ], @@ -541,9 +540,9 @@ "license": "MIT" }, "node_modules/@iconify/utils": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-3.1.3.tgz", - "integrity": "sha512-LPKOXPn/zV+zis1oOfGWogaXVpqUybF3ZS6SCZIsz8vg0ivVp9+fVqyYB7xq0aiST/VhUQYGO1qo6uoYSiEJqw==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-3.1.4.tgz", + "integrity": "sha512-b1S7B1k9ohZ+iNTi2ATxbRYG9fTrJmUT0rc46bvVnNxqNRGW7dyo/vRREwyniI5IRN2RSJHDcm+s3BjWrSAjHw==", "license": "MIT", "dependencies": { "@antfu/install-pkg": "^1.1.0", @@ -597,24 +596,24 @@ } }, "node_modules/@lobehub/icons-static-svg": { - "version": "1.90.0", - "resolved": "https://registry.npmjs.org/@lobehub/icons-static-svg/-/icons-static-svg-1.90.0.tgz", - "integrity": "sha512-iy/OBllvvj1YOCN7NqCYJJKdLS0l02+PSSYAwXKUWpGb6i+7J5rIpLh8RaetrYcqoqSmxE2jE6w5zhhaTmPw7Q==", + "version": "1.91.0", + "resolved": "https://registry.npmjs.org/@lobehub/icons-static-svg/-/icons-static-svg-1.91.0.tgz", + "integrity": "sha512-ZDflEq0uUvAkH4WK4h3qNvvY09ts4OqUb5azD7A0xKfcuYhffGwB1Q/As2RguZYq4Gh4v925CJ8iodiClzc4zw==", "license": "MIT" }, "node_modules/@mermaid-js/parser": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-1.1.1.tgz", - "integrity": "sha512-VuHdsYMK1bT6X2JbcAaWAhugTRvRBRyuZgd+c22swUeI9g/ntaxF7CY7dYarhZovofCbUNO0G7JesfmNtjYOCw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-1.2.0.tgz", + "integrity": "sha512-oYPyv8A4As1yH5Bx+04iQEQxXuIQDe0GKCNSRgao6z8AM9jixXIfP0vsppRLvGf+nKIOb9/LdpWA4YuJiVvESA==", "license": "MIT", "dependencies": { - "@chevrotain/types": "~11.1.1" + "@chevrotain/types": "~11.1.2" } }, "node_modules/@modelcontextprotocol/ext-apps": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/ext-apps/-/ext-apps-1.7.2.tgz", - "integrity": "sha512-OOWKDxdAjYDcgHkmzVzccyyag3FK+jBWPaWu4WvTxFsU4R/cgOX4eep66zPRA5n4v6WfxUNibPyvX4iJ7egYTg==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/ext-apps/-/ext-apps-1.7.4.tgz", + "integrity": "sha512-QQqysE549cf/Y0VabBmAACXhj92EhB3t8yVct2BHbkWiPTFA1S91EqTVjYXXcZEefXU0pmHcdObhsNMcomJIOQ==", "license": "MIT", "workspaces": [ "examples/*" @@ -2240,34 +2239,34 @@ "license": "MIT" }, "node_modules/@sidecar-ai/anthropic": { - "version": "0.1.0-alpha.14", - "resolved": "https://registry.npmjs.org/@sidecar-ai/anthropic/-/anthropic-0.1.0-alpha.14.tgz", - "integrity": "sha512-K8i5nN1/yqdIiPb5lRt9ZDEgRtrBaeYGS1zaqg60acf0nnhNabWrvBY7NA6Q9CT0Xy6wyzleGCXhyXG4Iv4YTA==", + "version": "0.1.0-alpha.15", + "resolved": "https://registry.npmjs.org/@sidecar-ai/anthropic/-/anthropic-0.1.0-alpha.15.tgz", + "integrity": "sha512-NWcXcVzYWq0lSLwlrWLCpCQmQzr383XKyMoz4yd7nirAuoGZ2AnYdxNsbGjkK2J0Udzq1pH7qYIlTZAC2SmoUg==", "dependencies": { - "@sidecar-ai/native": "0.1.0-alpha.14" + "@sidecar-ai/native": "0.1.0-alpha.15" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0" } }, "node_modules/@sidecar-ai/auth": { - "version": "0.1.0-alpha.14", - "resolved": "https://registry.npmjs.org/@sidecar-ai/auth/-/auth-0.1.0-alpha.14.tgz", - "integrity": "sha512-vkdmq4nAf1Do7PY4SEK1upH1X+l+MKBG6FyWlLUI9B6IlH4U6SEoR/xrnY6DbeYqab21LL9BPdBaQnR2yk9NWg==", + "version": "0.1.0-alpha.15", + "resolved": "https://registry.npmjs.org/@sidecar-ai/auth/-/auth-0.1.0-alpha.15.tgz", + "integrity": "sha512-ZFwEboajcRRVJ4/of7Ydw/AlFd7f/mUCW14U/pFqcbWWhwMQxu24JFdDyFSWFgJn4mzegRkh+vijRI09Z5/N8g==", "dependencies": { - "@sidecar-ai/core": "0.1.0-alpha.14" + "@sidecar-ai/core": "0.1.0-alpha.15" } }, "node_modules/@sidecar-ai/cli": { - "version": "0.1.0-alpha.14", - "resolved": "https://registry.npmjs.org/@sidecar-ai/cli/-/cli-0.1.0-alpha.14.tgz", - "integrity": "sha512-yi2UG3If/q2aVpMc4von1xOZlMvX4/84glyz4IjHr3XPidp4DQn1mh8bt4nKV7D+ouT6vZ75c51Ru3WE/63YMQ==", + "version": "0.1.0-alpha.15", + "resolved": "https://registry.npmjs.org/@sidecar-ai/cli/-/cli-0.1.0-alpha.15.tgz", + "integrity": "sha512-wXgfuVv0n5Fd5f5ihXyaRQDa0O0Sfd0YIIyiRdgzE5UYfQiD5punI9iH8x3SbLC5oGx6kpFQCXxl55M2hzqmng==", "dependencies": { "@lobehub/icons-static-svg": "^1.90.0", - "@sidecar-ai/auth": "0.1.0-alpha.14", - "@sidecar-ai/compiler": "0.1.0-alpha.14", - "@sidecar-ai/core": "0.1.0-alpha.14", - "@sidecar-ai/server": "0.1.0-alpha.14", + "@sidecar-ai/auth": "0.1.0-alpha.15", + "@sidecar-ai/compiler": "0.1.0-alpha.15", + "@sidecar-ai/core": "0.1.0-alpha.15", + "@sidecar-ai/server": "0.1.0-alpha.15", "esbuild": "^0.28.0", "react": "^19.2.6", "react-dom": "^19.2.6", @@ -2279,19 +2278,19 @@ } }, "node_modules/@sidecar-ai/client": { - "version": "0.1.0-alpha.14", - "resolved": "https://registry.npmjs.org/@sidecar-ai/client/-/client-0.1.0-alpha.14.tgz", - "integrity": "sha512-ca1rEu8PQwlYBqexy/hVMnPjygrYUVBqZ7kZcnIr9Ghx5p1SSAZqwOuBwZaB5jrnPsnIUBZpk/JDlydVofVgvg==", + "version": "0.1.0-alpha.15", + "resolved": "https://registry.npmjs.org/@sidecar-ai/client/-/client-0.1.0-alpha.15.tgz", + "integrity": "sha512-cKW/1XAkKOG3UVP49Aw1Jh+HGUS5x7qxxqlMGTQl7iMCzDxJC/vF0Zqr3izTKNo6Xl+gUITYCl6jnNXSxtZ0Fw==", "dependencies": { "@modelcontextprotocol/ext-apps": "^1.7.2" } }, "node_modules/@sidecar-ai/compiler": { - "version": "0.1.0-alpha.14", - "resolved": "https://registry.npmjs.org/@sidecar-ai/compiler/-/compiler-0.1.0-alpha.14.tgz", - "integrity": "sha512-Ad6upfLTY3K9CixiHrRkYwxwiu7cF95qGcdV6ZHg6h47FpITtHpcY0Rwma5oxKjWUEuF8RyOsSRFOcWhon7UzA==", + "version": "0.1.0-alpha.15", + "resolved": "https://registry.npmjs.org/@sidecar-ai/compiler/-/compiler-0.1.0-alpha.15.tgz", + "integrity": "sha512-40lNu37qBKKh0QgU6/r07F4isZzb2X7/u/kHOjTu3RFb+LwMd2TOjB9jFmFhEYJAIkI5ThRw3jg/iF7LW8cqRw==", "dependencies": { - "@sidecar-ai/core": "0.1.0-alpha.14", + "@sidecar-ai/core": "0.1.0-alpha.15", "@tailwindcss/postcss": "^4.3.0", "autoprefixer": "^10.5.0", "esbuild": "^0.28.0", @@ -2301,9 +2300,9 @@ } }, "node_modules/@sidecar-ai/core": { - "version": "0.1.0-alpha.14", - "resolved": "https://registry.npmjs.org/@sidecar-ai/core/-/core-0.1.0-alpha.14.tgz", - "integrity": "sha512-KImgSTCpeUab0BjyjqiuOdc/AenZw+rENk9Y7AyQMlAcpmHhtjPuBNNp0RxxJPssGWHBvjRQAJkHC74VkoCb4Q==", + "version": "0.1.0-alpha.15", + "resolved": "https://registry.npmjs.org/@sidecar-ai/core/-/core-0.1.0-alpha.15.tgz", + "integrity": "sha512-YESO6P2AUl2/uv2eawtjh/LvnBYX8/h0CzT7Iz8p46ncJrSoH9bHetkUWb/qLljRzpEzHPsrCu960IMtZml5Qg==", "peerDependencies": { "zod": "^4.0.0" }, @@ -2314,24 +2313,24 @@ } }, "node_modules/@sidecar-ai/native": { - "version": "0.1.0-alpha.14", - "resolved": "https://registry.npmjs.org/@sidecar-ai/native/-/native-0.1.0-alpha.14.tgz", - "integrity": "sha512-Vydj/XVCx8so+hY15eJIfoib62ti36Td1YzFE9sCs0VcwaaNMUVP0iKb/zHB1vxjeWs0P14AYTYoaYapKmfW2g==", + "version": "0.1.0-alpha.15", + "resolved": "https://registry.npmjs.org/@sidecar-ai/native/-/native-0.1.0-alpha.15.tgz", + "integrity": "sha512-9VpGst+gYnc3kI+D1W7ExrzyyTiR1w7Mk0Gl1WeJ1nFEA7LAFH8V68PS7EuhdKuSSwrSUwdqQ2GMh1liAm/iMQ==", "dependencies": { - "@sidecar-ai/client": "0.1.0-alpha.14" + "@sidecar-ai/client": "0.1.0-alpha.15" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0" } }, "node_modules/@sidecar-ai/openai": { - "version": "0.1.0-alpha.14", - "resolved": "https://registry.npmjs.org/@sidecar-ai/openai/-/openai-0.1.0-alpha.14.tgz", - "integrity": "sha512-Tqh2GO2PmqAZujhgjeBTGu3Hv9y4Yt5pyEl+brWqfwxdIn7zUius1eTWll4lNvLwUqFnmv713Jrmbv/zjsqChA==", + "version": "0.1.0-alpha.15", + "resolved": "https://registry.npmjs.org/@sidecar-ai/openai/-/openai-0.1.0-alpha.15.tgz", + "integrity": "sha512-c3nlIrjlQXSpq+kc2gGl1crpD2eB+HgTX9xyxGb3znAXgJLzGfY6zY0mbH/kb6Kjg6mGTaBvLKYcU45XNEYTIg==", "dependencies": { "@openai/apps-sdk-ui": "^0.2.2", - "@sidecar-ai/core": "0.1.0-alpha.14", - "@sidecar-ai/native": "0.1.0-alpha.14" + "@sidecar-ai/core": "0.1.0-alpha.15", + "@sidecar-ai/native": "0.1.0-alpha.15" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0", @@ -2339,25 +2338,25 @@ } }, "node_modules/@sidecar-ai/react": { - "version": "0.1.0-alpha.14", - "resolved": "https://registry.npmjs.org/@sidecar-ai/react/-/react-0.1.0-alpha.14.tgz", - "integrity": "sha512-O3XfOMvSM8EmpNhObDGwBrAJ90V8MMCWY7qK+MLvuQPxuFLOczAtFY1LNCMkRTbiSDxKRQD/2LzT0o1PYnFunQ==", + "version": "0.1.0-alpha.15", + "resolved": "https://registry.npmjs.org/@sidecar-ai/react/-/react-0.1.0-alpha.15.tgz", + "integrity": "sha512-+4XXypYMRT9/eP0bYzEvhRvD9HpN0AIBZU+Nbo8pCfqXzTrrKlqYvXF441iRDMJQMNAEfglMIZW2XKDXbruO7g==", "dependencies": { - "@sidecar-ai/client": "0.1.0-alpha.14", - "@sidecar-ai/core": "0.1.0-alpha.14" + "@sidecar-ai/client": "0.1.0-alpha.15", + "@sidecar-ai/core": "0.1.0-alpha.15" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0" } }, "node_modules/@sidecar-ai/server": { - "version": "0.1.0-alpha.14", - "resolved": "https://registry.npmjs.org/@sidecar-ai/server/-/server-0.1.0-alpha.14.tgz", - "integrity": "sha512-G2Q+E83hlWQT8gVrShFJCMDu7ulNUcVnq4fGcXm34FSEMUEh+vzh7qhpjruICFc9i9bi8ASvsPxJt27wnfqZdA==", + "version": "0.1.0-alpha.15", + "resolved": "https://registry.npmjs.org/@sidecar-ai/server/-/server-0.1.0-alpha.15.tgz", + "integrity": "sha512-wAz8rqoTruzQyZMGctK13PI4T/tkaFsqJpJsu7pKGDkd675J2mGjduLBkVN4cHaDlF2GqDZj4vn+TYv0hMOSKw==", "dependencies": { "@modelcontextprotocol/sdk": "^1.29.0", - "@sidecar-ai/auth": "0.1.0-alpha.14", - "@sidecar-ai/core": "0.1.0-alpha.14" + "@sidecar-ai/auth": "0.1.0-alpha.15", + "@sidecar-ai/core": "0.1.0-alpha.15" } }, "node_modules/@standard-schema/spec": { @@ -2367,47 +2366,47 @@ "license": "MIT" }, "node_modules/@tailwindcss/node": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.0.tgz", - "integrity": "sha512-aFb4gUhFOgdh9AXo4IzBEOzBkkAxm9VigwDJnMIYv3lcfXCJVesNfbEaBl4BNgVRyid92AmdviqwBUBRKSeY3g==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.2.tgz", + "integrity": "sha512-yWP/sqEcBLaD8JuA6zNwxoYKr75qxTioYwlRwekj5Jr/I5GXnoJfjetH/psLUIv74cYTH2lBUEzBkinthoYcBg==", "license": "MIT", "dependencies": { "@jridgewell/remapping": "^2.3.5", - "enhanced-resolve": "^5.21.0", - "jiti": "^2.6.1", + "enhanced-resolve": "5.21.6", + "jiti": "^2.7.0", "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", - "tailwindcss": "4.3.0" + "tailwindcss": "4.3.2" } }, "node_modules/@tailwindcss/oxide": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.0.tgz", - "integrity": "sha512-F7HZGBeN9I0/AuuJS5PwcD8xayx5ri5GhjYUDBEVYUkexyA/giwbDNjRVrxSezE3T250OU2K/wp/ltWx3UOefg==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.2.tgz", + "integrity": "sha512-z8ZgnzX8gdNoWLBLqBPoh/sjnxkwvf9ZuWjnO0l0yIzbLa5/9S+eC5QxGZKRobVHIC3/1BoMWjHblqWjcgFgag==", "license": "MIT", "engines": { "node": ">= 20" }, "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.3.0", - "@tailwindcss/oxide-darwin-arm64": "4.3.0", - "@tailwindcss/oxide-darwin-x64": "4.3.0", - "@tailwindcss/oxide-freebsd-x64": "4.3.0", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.0", - "@tailwindcss/oxide-linux-arm64-gnu": "4.3.0", - "@tailwindcss/oxide-linux-arm64-musl": "4.3.0", - "@tailwindcss/oxide-linux-x64-gnu": "4.3.0", - "@tailwindcss/oxide-linux-x64-musl": "4.3.0", - "@tailwindcss/oxide-wasm32-wasi": "4.3.0", - "@tailwindcss/oxide-win32-arm64-msvc": "4.3.0", - "@tailwindcss/oxide-win32-x64-msvc": "4.3.0" + "@tailwindcss/oxide-android-arm64": "4.3.2", + "@tailwindcss/oxide-darwin-arm64": "4.3.2", + "@tailwindcss/oxide-darwin-x64": "4.3.2", + "@tailwindcss/oxide-freebsd-x64": "4.3.2", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.2", + "@tailwindcss/oxide-linux-arm64-gnu": "4.3.2", + "@tailwindcss/oxide-linux-arm64-musl": "4.3.2", + "@tailwindcss/oxide-linux-x64-gnu": "4.3.2", + "@tailwindcss/oxide-linux-x64-musl": "4.3.2", + "@tailwindcss/oxide-wasm32-wasi": "4.3.2", + "@tailwindcss/oxide-win32-arm64-msvc": "4.3.2", + "@tailwindcss/oxide-win32-x64-msvc": "4.3.2" } }, "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.0.tgz", - "integrity": "sha512-TJPiq67tKlLuObP6RkwvVGDoxCMBVtDgKkLfa/uyj7/FyxvQwHS+UOnVrXXgbEsfUaMgiVvC4KbJnRr26ho4Ng==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.2.tgz", + "integrity": "sha512-WHxqIuHpvZ5VtdX6GTl1Ik/Vp2YuN42Et+0CdeaVd/frQ9jAvGmvR8vLT+jk3e8/Q3x8kECB9+R17pgpp2BulA==", "cpu": [ "arm64" ], @@ -2421,9 +2420,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.0.tgz", - "integrity": "sha512-oMN/WZRb+SO37BmUElEgeEWuU8E/HXRkiODxJxLe1UTHVXLrdVSgfaJV7pSlhRGMSOiXLuxTIjfsF3wYvz8cgQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.2.tgz", + "integrity": "sha512-GZypeUY/IDJW3877KeM+O67vbXr3MBnbtEL4aYhNErv/JWZhye2vGSWWG9tB6iiqR2MqRNkY8IOUy4NdSZV26w==", "cpu": [ "arm64" ], @@ -2437,9 +2436,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.0.tgz", - "integrity": "sha512-N6CUmu4a6bKVADfw77p+iw6Yd9Q3OBhe0veaDX+QazfuVYlQsHfDgxBrsjQ/IW+zywL8mTrNd0SdJT/zgtvMdA==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.2.tgz", + "integrity": "sha512-UIIzmefR6KO1sDU7MzRqAxC8iBpft/VhkGjTjnhoS6k7Z3rQ9wEgA1ODSiyH/tcSYssulNm4Ci3hOeK1jH7ccQ==", "cpu": [ "x64" ], @@ -2453,9 +2452,9 @@ } }, "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.0.tgz", - "integrity": "sha512-zDL5hBkQdH5C6MpqbK3gQAgP80tsMwSI26vjOzjJtNCMUo0lFgOItzHKBIupOZNQxt3ouPH7RPhvNhiTfCe5CQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.2.tgz", + "integrity": "sha512-GN+uAmcI6DNspnCDwtOAZrTz6oukJnp337qZvxqCGLd3BHBzJpO0ZbTLRvJNdztOeAmTzewewGIMPb0tk2R4WA==", "cpu": [ "x64" ], @@ -2469,9 +2468,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.0.tgz", - "integrity": "sha512-R06HdNi7A7OEoMsf6d4tjZ71RCWnZQPHj2mnotSFURjNLdBC+cIgXQ7l81CqeoiQftjf6OOblxXMInMgN2VzMA==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.2.tgz", + "integrity": "sha512-4ABn7qSbdHRwTiDiuWNegCyb5+2FJ4vKIKc3DmKrvAFw7MU1Lm11dIkTPwUaFdTzc7IsOpDbqBrlh0x6y36U/w==", "cpu": [ "arm" ], @@ -2485,9 +2484,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.0.tgz", - "integrity": "sha512-qTJHELX8jetjhRQHCLilkVLmybpzNQAtaI/gaoVoidn/ufbNDbAo8KlK2J+yPoc8wQxvDxCmh/5lr8nC1+lTbg==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.2.tgz", + "integrity": "sha512-wDgEIGwoM8w8pufh9LVt1PahDgNdKXrLC2qfAnV3vAmococ9RWbxeAw4pxPttd/TsJfwjyLf90Dg1y9y8I6Emw==", "cpu": [ "arm64" ], @@ -2504,9 +2503,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.0.tgz", - "integrity": "sha512-Z6sukiQsngnWO+l39X4pPbiWT81IC+PLKF+PHxIlyZbGNb9MODfYlXEVlFvej5BOZInWX01kVyzeLvHsXhfczQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.2.tgz", + "integrity": "sha512-J5Nuk0uZQIiMTJj3LEx4sAA9tMFUoXQZFv1J6An+QGYe53HKRJuFDi0rpq/tuouCZeAbOBY3kQ6g8qeD4TUjtA==", "cpu": [ "arm64" ], @@ -2523,9 +2522,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.0.tgz", - "integrity": "sha512-DRNdQRpSGzRGfARVuVkxvM8Q12nh19l4BF/G7zGA1oe+9wcC6saFBHTISrpIcKzhiXtSrlSrluCfvMuledoCTQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.2.tgz", + "integrity": "sha512-kqCZpSKOBEJO4mz7OqWoofBZeXTAwaVGPj0ErAj7CojmhKpWVWVOnrt9dE8odoIraZq4oj3ausM37kXi+Tow8w==", "cpu": [ "x64" ], @@ -2542,9 +2541,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.0.tgz", - "integrity": "sha512-Z0IADbDo8bh6I7h2IQMx601AdXBLfFpEdUotft86evd/8ZPflZe9COPO8Q1vw+pfLWIUo9zN/JGZvwuAJqduqg==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.2.tgz", + "integrity": "sha512-cixpqbh2toJDmkuCRI68nXA8ZxNmdK9Y+9v5h3MC3ZQKy/0BO8AWzlkWyRM7JAFSGBlfig4YVTPsK6MVgqz1uw==", "cpu": [ "x64" ], @@ -2561,9 +2560,9 @@ } }, "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.0.tgz", - "integrity": "sha512-HNZGOUxEmElksYR7S6sC5jTeNGpobAsy9u7Gu0AskJ8/20FR9GqebUyB+HBcU/ax6BHuiuJi+Oda4B+YX6H1yA==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.2.tgz", + "integrity": "sha512-4ec2Z/LOmRsAgU23CS4xeJfcJlmRg94A/XrbGRCF1gyU/zdDfRLYDVsS+ynSZCmGNxQ1jQriQOKMQeQxBA3Isw==", "bundleDependencies": [ "@napi-rs/wasm-runtime", "@emnapi/core", @@ -2578,11 +2577,11 @@ "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "^1.10.0", - "@emnapi/runtime": "^1.10.0", - "@emnapi/wasi-threads": "^1.2.1", + "@emnapi/core": "^1.11.1", + "@emnapi/runtime": "^1.11.1", + "@emnapi/wasi-threads": "^1.2.2", "@napi-rs/wasm-runtime": "^1.1.4", - "@tybys/wasm-util": "^0.10.1", + "@tybys/wasm-util": "^0.10.2", "tslib": "^2.8.1" }, "engines": { @@ -2590,17 +2589,17 @@ } }, "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": { - "version": "1.10.0", + "version": "1.11.1", "inBundle": true, "license": "MIT", "optional": true, "dependencies": { - "@emnapi/wasi-threads": "1.2.1", + "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" } }, "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": { - "version": "1.10.0", + "version": "1.11.1", "inBundle": true, "license": "MIT", "optional": true, @@ -2609,7 +2608,7 @@ } }, "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": { - "version": "1.2.1", + "version": "1.2.2", "inBundle": true, "license": "MIT", "optional": true, @@ -2635,7 +2634,7 @@ } }, "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { - "version": "0.10.1", + "version": "0.10.2", "inBundle": true, "license": "MIT", "optional": true, @@ -2650,9 +2649,9 @@ "optional": true }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.0.tgz", - "integrity": "sha512-Pe+RPVTi1T+qymuuRpcdvwSVZjnll/f7n8gBxMMh3xLTctMDKqpdfGimbMyioqtLhUYZxdJ9wGNhV7MKHvgZsQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.2.tgz", + "integrity": "sha512-Zyr/M0+XcYZu3bZrUytc7TXvrk0ftWfl8gN2MwekNDzhqhKRUucMPSeOzM0o0wH5AWOU49BsKRrfKxI2atCPMQ==", "cpu": [ "arm64" ], @@ -2666,9 +2665,9 @@ } }, "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.0.tgz", - "integrity": "sha512-Mvrf2kXW/yeW/OTezZlCGOirXRcUuLIBx/5Y12BaPM7wJoryG6dfS/NJL8aBPqtTEx/Vm4T4vKzFUcKDT+TKUA==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.2.tgz", + "integrity": "sha512-QI9BO7KlNZsp2GuO0jwAAj5jCDABOKXRkCk2XuKTSaNEFSdfzqswYVTtCHBNKHLsqyjFyFkqlDiwkNbTYSssMQ==", "cpu": [ "x64" ], @@ -2682,16 +2681,16 @@ } }, "node_modules/@tailwindcss/postcss": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.3.0.tgz", - "integrity": "sha512-Jm05Tjx+9yCLGv5qw1c+84Psds8MnyrEQYCB+FFk2lgGiUjlRqdxke4mVTuYrj2xnVZqKim2Apr5ySuQRYAw/w==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.3.2.tgz", + "integrity": "sha512-rjVWYCa7Ngbi5AarT6k8TkxUG3Wl1QKzHdIZVsjZSzf36Jmo2IKZt/NHRAwly8oDkbBOH0YTu+CHuf9jPxMc+g==", "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", - "@tailwindcss/node": "4.3.0", - "@tailwindcss/oxide": "4.3.0", - "postcss": "^8.5.10", - "tailwindcss": "4.3.0" + "@tailwindcss/node": "4.3.2", + "@tailwindcss/oxide": "4.3.2", + "postcss": "^8.5.15", + "tailwindcss": "4.3.2" } }, "node_modules/@ts-morph/common": { @@ -2886,9 +2885,9 @@ "license": "MIT" }, "node_modules/@types/d3-random": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", - "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.4.tgz", + "integrity": "sha512-UHYId5WTCx4L4YNel7NU00XUXXgvgpgZOvp10PuvsQENjMDXhh2RyFc0KBjO7B45ne4Ha1yVH7ii0vnzKkuzWA==", "license": "MIT" }, "node_modules/@types/d3-scale": { @@ -3134,9 +3133,9 @@ } }, "node_modules/autoprefixer": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.0.tgz", - "integrity": "sha512-FMhOoZV4+qR6aTUALKX2rEqGG+oyATvwBt9IIzVR5rMa2HRWPkxf+P+PAJLD1I/H5/II+HuZcBJYEFBpq39ong==", + "version": "10.5.2", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.2.tgz", + "integrity": "sha512-rD5t5DwOjJdmSORcTq64j8MawTC+tbQ+HHqjR4NDumamy/ambn1UJrlKL+KdwujWxMkFjPM3pPHOEA9tl4767Q==", "funding": [ { "type": "opencollective", @@ -3153,8 +3152,8 @@ ], "license": "MIT", "dependencies": { - "browserslist": "^4.28.2", - "caniuse-lite": "^1.0.30001787", + "browserslist": "^4.28.4", + "caniuse-lite": "^1.0.30001799", "fraction.js": "^5.3.4", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" @@ -3189,9 +3188,9 @@ } }, "node_modules/baseline-browser-mapping": { - "version": "2.10.32", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.32.tgz", - "integrity": "sha512-wbPvpyjJPC0zdfdKXxqEL3Ea+bOMD/87X4lftiJkkaBiuG6ALQy1SLmEd7BSmVCuwCQsBrCamgBoLyfFDD1EPg==", + "version": "2.10.43", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.43.tgz", + "integrity": "sha512-AjYpR78kDWAY3Efj+cDTFH9t9SCoL7OoTp1BOb0mQV7S+6CiLwnWM3FyxhJtdPufDFKzmCSFoUncKjWgJEZTCQ==", "license": "Apache-2.0", "bin": { "baseline-browser-mapping": "dist/cli.cjs" @@ -3225,9 +3224,9 @@ } }, "node_modules/brace-expansion": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", - "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", + "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" @@ -3249,9 +3248,9 @@ } }, "node_modules/browserslist": { - "version": "4.28.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", - "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "version": "4.28.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.6.tgz", + "integrity": "sha512-FQBYNK15VMslhLHpA7+n+n1GOlF1kId2xcCg7/j95f24AOF6VDYMNH4mFxF7KuaTdv627faazpOAjFzMrfJOUw==", "funding": [ { "type": "opencollective", @@ -3268,10 +3267,10 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.10.12", - "caniuse-lite": "^1.0.30001782", - "electron-to-chromium": "^1.5.328", - "node-releases": "^2.0.36", + "baseline-browser-mapping": "^2.10.42", + "caniuse-lite": "^1.0.30001803", + "electron-to-chromium": "^1.5.389", + "node-releases": "^2.0.51", "update-browserslist-db": "^1.2.3" }, "bin": { @@ -3320,9 +3319,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001793", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001793.tgz", - "integrity": "sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==", + "version": "1.0.30001805", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001805.tgz", + "integrity": "sha512-52noaS3DubycKSXaU30TwPGIp+POyQSUVa5jBEq3vkRkY0kjyb3LQgvhU6WGyCcyXqVLWO0Cw0Q6BSdD0kUfVA==", "funding": [ { "type": "opencollective", @@ -3511,9 +3510,9 @@ "peer": true }, "node_modules/cytoscape": { - "version": "3.33.4", - "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.33.4.tgz", - "integrity": "sha512-HIN5Pmd9MrX9BkV7tDwnOcEJCSFvCpc8X97h3f508J6I5FsqAY65wKOCvgH2CuP42CaahWaz4tuh32SOOIH7ww==", + "version": "3.34.0", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.34.0.tgz", + "integrity": "sha512-62rNSrioXw93uliKFBwjukeQyeWwH2PqDrTac31r2P6464u3AUvTk0xS4LVvT251g7IgkFunrI48ZEZGjywSOg==", "license": "MIT", "engines": { "node": ">=0.10" @@ -4031,9 +4030,9 @@ } }, "node_modules/dayjs": { - "version": "1.11.20", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.20.tgz", - "integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==", + "version": "1.11.21", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.21.tgz", + "integrity": "sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA==", "license": "MIT" }, "node_modules/debug": { @@ -4122,9 +4121,9 @@ } }, "node_modules/dompurify": { - "version": "3.4.5", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.5.tgz", - "integrity": "sha512-OrwIBKsdNSVEeubdJ1HBv/wNENRM9ytAVCv7YXt//A3vPdVMNuACRqK9mXCGCBW2ln7BT/A4X0jXHo2Gu89miA==", + "version": "3.4.12", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.12.tgz", + "integrity": "sha512-zQvGet8Z2sWbQhCmfFz/T5QWH2oBmjnqK3qvOjaqaNLrLEF912WamU+ohnTp0TCep/MFVHpdJuCZEdFOdTnEFg==", "license": "(MPL-2.0 OR Apache-2.0)", "optionalDependencies": { "@types/trusted-types": "^2.0.7" @@ -4163,9 +4162,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.361", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.361.tgz", - "integrity": "sha512-Q6Hts7N9FnJc5LeGRINFvLhCI9xZmNtTDe5ZbcVezQz7cU4a8Aua3GH1b8J2XY8Al9PF+OCwYqhgsOOheMdvkA==", + "version": "1.5.389", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.389.tgz", + "integrity": "sha512-cEto7aeOqBfU1D+c5py5pE+ooscKE75JifxLBdFUZsqAxRS6y7kebtxAZvICszSl05gPjYHDTjY+lXpyGvpJbg==", "license": "ISC" }, "node_modules/encodeurl": { @@ -4178,9 +4177,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.22.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.22.0.tgz", - "integrity": "sha512-xYcDWrpELkFzz9SpZ3PlI6Eu6eD93Yf0WLDRxikGhWJ3MAir2SNZTIVCVZqZ/NUyx8AdMc2gT9C0gPiw18kG+A==", + "version": "5.21.6", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.6.tgz", + "integrity": "sha512-aNnGCvbJ/RIyWo1IuhNdVjnNF+EjH9wpzpNHt+ci/m9He9LJvUN8wrCcXjp9cWsGNAuvSpVFTx/vraAFQ8qGjQ==", "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", @@ -4233,9 +4232,9 @@ } }, "node_modules/es-toolkit": { - "version": "1.46.1", - "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.46.1.tgz", - "integrity": "sha512-5eNtXOs3tbfxXOj04tjjseeWkRWaoCjdEI+96DgwzZoe6c9juL49pXlzAFTI72aWC9Y8p7168g6XIKjh7k6pyQ==", + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.49.0.tgz", + "integrity": "sha512-G5iZ6Pc/FNRY/soKZHC+TxGDD83rHUDXxzaWhGCX44vAv/tMs56WMusnm/KMNK+luUPsgA9U28cGr4RDlSzL2g==", "license": "MIT", "workspaces": [ "docs", @@ -4243,9 +4242,9 @@ ] }, "node_modules/esbuild": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz", - "integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", + "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", "hasInstallScript": true, "license": "MIT", "bin": { @@ -4255,32 +4254,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.28.0", - "@esbuild/android-arm": "0.28.0", - "@esbuild/android-arm64": "0.28.0", - "@esbuild/android-x64": "0.28.0", - "@esbuild/darwin-arm64": "0.28.0", - "@esbuild/darwin-x64": "0.28.0", - "@esbuild/freebsd-arm64": "0.28.0", - "@esbuild/freebsd-x64": "0.28.0", - "@esbuild/linux-arm": "0.28.0", - "@esbuild/linux-arm64": "0.28.0", - "@esbuild/linux-ia32": "0.28.0", - "@esbuild/linux-loong64": "0.28.0", - "@esbuild/linux-mips64el": "0.28.0", - "@esbuild/linux-ppc64": "0.28.0", - "@esbuild/linux-riscv64": "0.28.0", - "@esbuild/linux-s390x": "0.28.0", - "@esbuild/linux-x64": "0.28.0", - "@esbuild/netbsd-arm64": "0.28.0", - "@esbuild/netbsd-x64": "0.28.0", - "@esbuild/openbsd-arm64": "0.28.0", - "@esbuild/openbsd-x64": "0.28.0", - "@esbuild/openharmony-arm64": "0.28.0", - "@esbuild/sunos-x64": "0.28.0", - "@esbuild/win32-arm64": "0.28.0", - "@esbuild/win32-ia32": "0.28.0", - "@esbuild/win32-x64": "0.28.0" + "@esbuild/aix-ppc64": "0.28.1", + "@esbuild/android-arm": "0.28.1", + "@esbuild/android-arm64": "0.28.1", + "@esbuild/android-x64": "0.28.1", + "@esbuild/darwin-arm64": "0.28.1", + "@esbuild/darwin-x64": "0.28.1", + "@esbuild/freebsd-arm64": "0.28.1", + "@esbuild/freebsd-x64": "0.28.1", + "@esbuild/linux-arm": "0.28.1", + "@esbuild/linux-arm64": "0.28.1", + "@esbuild/linux-ia32": "0.28.1", + "@esbuild/linux-loong64": "0.28.1", + "@esbuild/linux-mips64el": "0.28.1", + "@esbuild/linux-ppc64": "0.28.1", + "@esbuild/linux-riscv64": "0.28.1", + "@esbuild/linux-s390x": "0.28.1", + "@esbuild/linux-x64": "0.28.1", + "@esbuild/netbsd-arm64": "0.28.1", + "@esbuild/netbsd-x64": "0.28.1", + "@esbuild/openbsd-arm64": "0.28.1", + "@esbuild/openbsd-x64": "0.28.1", + "@esbuild/openharmony-arm64": "0.28.1", + "@esbuild/sunos-x64": "0.28.1", + "@esbuild/win32-arm64": "0.28.1", + "@esbuild/win32-ia32": "0.28.1", + "@esbuild/win32-x64": "0.28.1" } }, "node_modules/escalade": { @@ -5902,26 +5901,26 @@ } }, "node_modules/mermaid": { - "version": "11.15.0", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.15.0.tgz", - "integrity": "sha512-pTMbcf3rWdtLiYGpmoTjHEpeY8seiy6sR+9nD7LOs8KfUbHE4lOUAprTRqRAcWSQ6MQpdX+YEsxShtGsINtPtw==", + "version": "11.16.0", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.16.0.tgz", + "integrity": "sha512-Zvm3kbstgdpvIJPPItlL7fppIZ3kibvc1oZIGxdvk9t6UFz6flv+Jw7FtRGKwfcI8OckmH04LqG6LlS6X4B1pA==", "license": "MIT", "dependencies": { - "@braintree/sanitize-url": "^7.1.1", + "@braintree/sanitize-url": "^7.1.2", "@iconify/utils": "^3.0.2", - "@mermaid-js/parser": "^1.1.1", + "@mermaid-js/parser": "^1.2.0", "@types/d3": "^7.4.3", "@upsetjs/venn.js": "^2.0.0", - "cytoscape": "^3.33.1", + "cytoscape": "^3.33.3", "cytoscape-cose-bilkent": "^4.1.0", "cytoscape-fcose": "^2.2.0", "d3": "^7.9.0", "d3-sankey": "^0.12.3", "dagre-d3-es": "7.0.14", - "dayjs": "^1.11.19", - "dompurify": "^3.3.1", + "dayjs": "^1.11.20", + "dompurify": "^3.3.3", "es-toolkit": "^1.45.1", - "katex": "^0.16.25", + "katex": "^0.16.45", "khroma": "^2.1.0", "marked": "^16.3.0", "roughjs": "^4.6.6", @@ -6603,9 +6602,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", - "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", "funding": [ { "type": "github", @@ -6630,9 +6629,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.46", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.46.tgz", - "integrity": "sha512-GYVXHE2KnrzAfsAjl4uP++evGFCrAU1jta4ubEjIG7YWt/64Gqv66a30yKwWczVjA6j3bM4nBwH7Pk1JmDHaxQ==", + "version": "2.0.51", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz", + "integrity": "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==", "license": "MIT", "engines": { "node": ">=18" @@ -6681,9 +6680,9 @@ } }, "node_modules/package-manager-detector": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz", - "integrity": "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.7.0.tgz", + "integrity": "sha512-xg1eHpwYL/D/HEdWw2goFZP6vV0FH7W+PZ5rFkGjdIDLtxq7EkzBUeT3m+lndYCt8wKbmofUu1MUdMCXkCk9ZQ==", "license": "MIT" }, "node_modules/parse-entities": { @@ -6807,9 +6806,9 @@ } }, "node_modules/postcss": { - "version": "8.5.15", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", - "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "version": "8.5.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.18.tgz", + "integrity": "sha512-xdB1oSLHbz1vRWgCDalrCqEFTWzFlhqFC5tIHLMOSUIjhm3XXQ1qrFy8S/ESr1JYRRXqM3c1QFiMZUJdUTqyMQ==", "funding": [ { "type": "opencollective", @@ -7586,16 +7585,16 @@ } }, "node_modules/sidecar-ai": { - "version": "0.1.0-alpha.14", - "resolved": "https://registry.npmjs.org/sidecar-ai/-/sidecar-ai-0.1.0-alpha.14.tgz", - "integrity": "sha512-/ZOkUGb+yUxsopUwnp+18fQ4UPtQL6MCs8ACbKv5m9Jk1nv6SgV/BfFxbrL0KkXObD2G1TGDKx79GsRa8Arm0Q==", + "version": "0.1.0-alpha.15", + "resolved": "https://registry.npmjs.org/sidecar-ai/-/sidecar-ai-0.1.0-alpha.15.tgz", + "integrity": "sha512-lhoaZUTEyVCdxFSSiUuH5Pe0KYsrIuw0LxOFOLNJf7tb7naauGQNdJ3h4AIp86qi24tksw5ovhhyMUExDhwrqw==", "dependencies": { - "@sidecar-ai/auth": "0.1.0-alpha.14", - "@sidecar-ai/cli": "0.1.0-alpha.14", - "@sidecar-ai/client": "0.1.0-alpha.14", - "@sidecar-ai/core": "0.1.0-alpha.14", - "@sidecar-ai/native": "0.1.0-alpha.14", - "@sidecar-ai/react": "0.1.0-alpha.14" + "@sidecar-ai/auth": "0.1.0-alpha.15", + "@sidecar-ai/cli": "0.1.0-alpha.15", + "@sidecar-ai/client": "0.1.0-alpha.15", + "@sidecar-ai/core": "0.1.0-alpha.15", + "@sidecar-ai/native": "0.1.0-alpha.15", + "@sidecar-ai/react": "0.1.0-alpha.15" }, "bin": { "sidecar": "dist/sidecar.js" @@ -7710,9 +7709,9 @@ } }, "node_modules/tailwindcss": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.0.tgz", - "integrity": "sha512-y6nxMGB1nMW9R6k96e5gdIFzcfL/gTJRNaqGes1YvkLnPVXzWgbqFF2yLC0T8G774n24cx3Pe8XrKoniCOAH+Q==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.2.tgz", + "integrity": "sha512-WtctNNSH8A9jlMIqxzuYumOHU5uGZyRv0Q5svQl+oEPy5w84YpBxdb7MdqyiSPQge5jTJ6zFQLq0PFygdccSBA==", "license": "MIT" }, "node_modules/tapable": { @@ -7729,9 +7728,9 @@ } }, "node_modules/tinyexec": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.1.2.tgz", - "integrity": "sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz", + "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==", "license": "MIT", "engines": { "node": ">=18" @@ -7779,9 +7778,9 @@ } }, "node_modules/ts-dedent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", - "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.3.0.tgz", + "integrity": "sha512-JfJeIHke7y2egdGGgRAvpCwYFUsHlM2gPcrVOxFkznt/4uzQ7HFmvE63iFHVLBJNDuyDOQgijDK/tXH/f6Msjg==", "license": "MIT", "engines": { "node": ">=6.10" @@ -7804,9 +7803,9 @@ "license": "0BSD" }, "node_modules/tsx": { - "version": "4.22.3", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.22.3.tgz", - "integrity": "sha512-mdoNxBC/cSQObGGVQ5Bpn5i+yv7j68gk3Nfm3wFjcJg3Z0Mix9jzAFfP12prmm5eVGmDKtp0yyArrs0Q+8gZHg==", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.23.0.tgz", + "integrity": "sha512-eUdUIaCr963q2h5u3+QwvYp0+eqPvn+egeqZUm0hwERCqqx1E3kK5ehbGCvqSE5MQAULr67ww0cA3jKc3YkM1w==", "license": "MIT", "dependencies": { "esbuild": "~0.28.0" @@ -8074,9 +8073,9 @@ } }, "node_modules/uuid": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz", - "integrity": "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.1.tgz", + "integrity": "sha512-6ZxzVpzDXDa3bJWaHilVayA+BH/1zmxCJoVgvmqJnid/gPoKHxUrS/aC/T6LGQtNHT+XHG9fXPJB4d+IrU30Ew==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" diff --git a/examples/notion/package.json b/examples/notion/package.json index d6d4bf2..6035b5d 100644 --- a/examples/notion/package.json +++ b/examples/notion/package.json @@ -1,6 +1,6 @@ { "name": "sidecar-notion-example", - "version": "0.1.0-alpha.14", + "version": "0.1.0-alpha.15", "private": true, "type": "module", "scripts": { @@ -14,17 +14,16 @@ }, "dependencies": { "@modelcontextprotocol/sdk": "^1.29.0", - "@sidecar-ai/anthropic": "0.1.0-alpha.14", - "@sidecar-ai/openai": "0.1.0-alpha.14", + "@sidecar-ai/anthropic": "0.1.0-alpha.15", + "@sidecar-ai/openai": "0.1.0-alpha.15", "@workos-inc/node": "^9.3.0", "dotenv": "^17.4.2", - "jose": "^6.2.3", "react": "^19.0.0", "react-dom": "^19.0.0", "react-markdown": "^9.1.0", "remark-breaks": "^4.0.0", "remark-gfm": "^4.0.1", - "sidecar-ai": "0.1.0-alpha.14" + "sidecar-ai": "0.1.0-alpha.15" }, "overrides": { "lodash": "4.18.1" diff --git a/packages/cli/src/dev-harness.ts b/packages/cli/src/dev-harness.ts index 19d4bdf..7848e99 100644 --- a/packages/cli/src/dev-harness.ts +++ b/packages/cli/src/dev-harness.ts @@ -1726,17 +1726,17 @@ form.addEventListener("submit", async (event) => { clearEmpty(); messages.push({ role: "user", content: text }); appendMessage("user", text); - const assistant = appendMessage("assistant", ""); statusEl.classList.remove("error"); statusEl.textContent = "Thinking..."; try { - await streamChat(assistant.querySelector(".content")); + await streamChat(); statusEl.classList.remove("error"); statusEl.textContent = ""; } catch (error) { const message = error instanceof Error ? error.message : String(error); statusEl.classList.remove("error"); statusEl.textContent = ""; + const assistant = appendMessage("assistant", ""); const assistantError = renderAssistantError(assistant.querySelector(".content"), message); messages.push({ role: "assistant", content: assistantError }); } @@ -1814,7 +1814,7 @@ window.addEventListener("message", async (event) => { } }); -async function streamChat(contentEl) { +async function streamChat() { const response = await fetch("/__sidecar/dev/chat", { method: "POST", headers: { "content-type": "application/json" }, @@ -1829,7 +1829,9 @@ async function streamChat(contentEl) { const reader = response.body.getReader(); const decoder = new TextDecoder(); let buffer = ""; - let assistantText = ""; + let currentAssistantContentEl = null; + let currentAssistantText = ""; + const assistantSegments = []; while (true) { const { done, value } = await reader.read(); if (done) break; @@ -1841,15 +1843,18 @@ async function streamChat(contentEl) { const parsed = parseEvent(raw); if (parsed) { if (parsed.event === "delta") { - assistantText += parsed.data.text || ""; - renderMarkdown(contentEl, assistantText); + const text = parsed.data.text || ""; + if (text) { + currentAssistantText += text; + currentAssistantContentEl ??= appendMessage("assistant", "").querySelector(".content"); + renderMarkdown(currentAssistantContentEl, currentAssistantText); + } } else if (parsed.event === "tool_start") { + finalizeAssistantSegment(); appendToolStart(parsed.data); } else if (parsed.event === "tool_result") { - const toolArticle = appendToolResult(parsed.data); - if (parsed.data.tool?.resourceUri) { - moveAssistantAfterToolUi(contentEl, toolArticle); - } + finalizeAssistantSegment(); + appendToolResult(parsed.data); } else if (parsed.event === "error") { throw new Error(parsed.data.message || "Sidecar dev chat failed."); } @@ -1857,8 +1862,17 @@ async function streamChat(contentEl) { boundary = buffer.indexOf("\n\n"); } } - if (assistantText.trim()) { - messages.push({ role: "assistant", content: assistantText }); + finalizeAssistantSegment(); + if (assistantSegments.length) { + messages.push({ role: "assistant", content: assistantSegments.join("\n\n") }); + } + + function finalizeAssistantSegment() { + if (currentAssistantText.trim()) { + assistantSegments.push(currentAssistantText); + } + currentAssistantText = ""; + currentAssistantContentEl = null; } } @@ -1919,17 +1933,6 @@ function renderAssistantError(element, message) { return text; } -function moveAssistantAfterToolUi(contentEl, toolArticle) { - const assistantArticle = contentEl.closest(".message"); - if (!assistantArticle || !toolArticle?.parentElement || assistantArticle === toolArticle) { - return; - } - if (toolArticle.nextSibling === assistantArticle) { - return; - } - messagesEl.insertBefore(assistantArticle, toolArticle.nextSibling); -} - function appendToolStart(tool) { const article = document.createElement("article"); article.className = "tool-card"; diff --git a/packages/cli/test/dev-harness.test.ts b/packages/cli/test/dev-harness.test.ts index 36e3fcc..5cd26e8 100644 --- a/packages/cli/test/dev-harness.test.ts +++ b/packages/cli/test/dev-harness.test.ts @@ -157,6 +157,7 @@ describe("dev harness", () => { model: "gpt-4.1-mini", }); + expect(html).toContain("const assistant = appendMessage(\"assistant\", \"\");"); expect(html).toContain("renderAssistantError(assistant.querySelector(\".content\"), message)"); expect(html).toContain("Sidecar dev hit an error:"); expect(html).not.toContain("statusEl.textContent = error instanceof Error ? error.message : String(error)"); @@ -181,7 +182,7 @@ describe("dev harness", () => { expect(html).toContain('iframe.style.height = Math.min(2000, Math.max(120, Math.ceil(requestedHeight))) + "px";'); }); - it("renders assistant text below widget UI when a response includes a widget", () => { + it("appends assistant text when stream deltas arrive instead of pre-allocating a message", () => { const html = renderDevHarnessHtml({ host: "claude", theme: "dark", @@ -190,10 +191,12 @@ describe("dev harness", () => { model: "gpt-4.1-mini", }); - expect(html).toContain("const toolArticle = appendToolResult(parsed.data);"); - expect(html).toContain("if (parsed.data.tool?.resourceUri) {"); - expect(html).toContain("moveAssistantAfterToolUi(contentEl, toolArticle);"); - expect(html).toContain("messagesEl.insertBefore(assistantArticle, toolArticle.nextSibling);"); + expect(html).toContain("await streamChat();"); + expect(html).toContain("let currentAssistantContentEl = null;"); + expect(html).toContain("currentAssistantContentEl ??= appendMessage(\"assistant\", \"\").querySelector(\".content\");"); + expect(html).toContain("finalizeAssistantSegment();"); + expect(html).not.toContain("await streamChat(assistant.querySelector(\".content\"));"); + expect(html).not.toContain("moveAssistantAfterToolUi"); }); it("can seed the bearer token from the dev environment", () => {