From e7effa297ceea89a27db20ab0722d70b66e99495 Mon Sep 17 00:00:00 2001 From: mw Date: Mon, 29 Dec 2025 14:53:10 -0500 Subject: [PATCH 1/2] feat: Gemini integration with Local/Remote mode switching - Implemented Gemini Local and Remote launchers. - Added support for mode switching and session resumption. - Fixed stdin handling issues in Gemini mode. - Introduced dedicated Gemini message types and dual format support. - Refactored runGemini to use new launcher architecture. - Added explicit error handling for missing 'gemini' CLI. - Updated API types and documentation for long-term maintenance. --- src/agent/acp/AcpSdkBackend.ts | 3 + src/agent/acp/gemini.ts | 20 +- src/api/apiSession.ts | 139 ++- src/api/types.ts | 107 +- src/claude/claudeRemoteLauncher.ts | 26 +- src/claude/loop.ts | 5 + src/gemini/geminiLocal.ts | 101 ++ src/gemini/geminiLocalLauncher.ts | 174 +++ src/gemini/geminiRemoteLauncher.ts | 891 ++++++++++++++++ src/gemini/loop.ts | 111 ++ src/gemini/runGemini.ts | 999 +----------------- src/gemini/session.ts | 117 ++ .../utils/generateGeminiHookSettings.ts | 133 +++ src/gemini/utils/path.ts | 37 + src/gemini/utils/sessionScanner.ts | 171 +++ src/index.ts | 37 +- src/ui/ink/GeminiDisplay.tsx | 67 +- yarn.lock | 776 +++----------- 18 files changed, 2296 insertions(+), 1618 deletions(-) create mode 100644 src/gemini/geminiLocal.ts create mode 100644 src/gemini/geminiLocalLauncher.ts create mode 100644 src/gemini/geminiRemoteLauncher.ts create mode 100644 src/gemini/loop.ts create mode 100644 src/gemini/session.ts create mode 100644 src/gemini/utils/generateGeminiHookSettings.ts create mode 100644 src/gemini/utils/path.ts create mode 100644 src/gemini/utils/sessionScanner.ts diff --git a/src/agent/acp/AcpSdkBackend.ts b/src/agent/acp/AcpSdkBackend.ts index 8a88fd69..dae94f12 100644 --- a/src/agent/acp/AcpSdkBackend.ts +++ b/src/agent/acp/AcpSdkBackend.ts @@ -652,6 +652,9 @@ export class AcpSdkBackend implements AgentBackend { this.acpSessionId = sessionResponse.sessionId; logger.debug(`[AcpSdkBackend] Session created: ${this.acpSessionId}`); + // Emit session-created event so the launcher can track the session ID + this.emit({ type: 'event', name: 'session-created', payload: { sessionId: this.acpSessionId } }); + this.emit({ type: 'status', status: 'idle' }); // Send initial prompt if provided diff --git a/src/agent/acp/gemini.ts b/src/agent/acp/gemini.ts index 2b662ead..eb4578cd 100644 --- a/src/agent/acp/gemini.ts +++ b/src/agent/acp/gemini.ts @@ -30,20 +30,23 @@ import { export interface GeminiBackendOptions extends AgentFactoryOptions { /** API key for Gemini (defaults to GEMINI_API_KEY or GOOGLE_API_KEY env var) */ apiKey?: string; - + /** OAuth token from Happy cloud (via 'happy connect gemini') - highest priority */ cloudToken?: string; - + /** Model to use. If undefined, will use local config, env var, or default. * If explicitly set to null, will use default (skip local config). * (defaults to GEMINI_MODEL env var or 'gemini-2.5-pro') */ model?: string | null; - + /** MCP servers to make available to the agent */ mcpServers?: Record; - + /** Optional permission handler for tool approval */ permissionHandler?: AcpPermissionHandler; + + /** Session ID to resume (if available). Passed to Gemini CLI via --resume flag */ + sessionId?: string | null; } /** @@ -86,11 +89,18 @@ export function createGeminiBackend(options: GeminiBackendOptions): AgentBackend // If options.model is explicitly null, skip local config and use env/default const model = determineGeminiModel(options.model, localConfig); - // Build args - use only --experimental-acp flag + // Build args - start with --experimental-acp flag // Model is passed via GEMINI_MODEL env var (gemini CLI reads it automatically) // We don't use --model flag to avoid potential stdout conflicts with ACP protocol const geminiArgs = ['--experimental-acp']; + // Add --resume flag if session ID is provided + // This allows the Gemini CLI to resume an existing session, maintaining conversation history + if (options.sessionId) { + geminiArgs.push('--resume', options.sessionId); + logger.debug(`[Gemini] Resuming session: ${options.sessionId}`); + } + const backendOptions: AcpSdkBackendOptions = { agentName: 'gemini', cwd: options.cwd, diff --git a/src/api/apiSession.ts b/src/api/apiSession.ts index a2805c94..dd0bd290 100644 --- a/src/api/apiSession.ts +++ b/src/api/apiSession.ts @@ -226,26 +226,159 @@ export class ApiSessionClient extends EventEmitter { role: 'agent', content: { type: 'codex', - data: body // This wraps the entire Claude message + data: body // This wraps the entire Codex message }, meta: { sentFrom: 'cli' } }; const encrypted = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, content)); - + // Check if socket is connected before sending if (!this.socket.connected) { logger.debug('[API] Socket not connected, cannot send message. Message will be lost:', { type: body.type }); // TODO: Consider implementing message queue or HTTP fallback for reliability } - + this.socket.emit('message', { sid: this.sessionId, message: encrypted }); } + /** + * Send Gemini message to mobile client + * Uses dedicated 'gemini' type instead of 'codex' for proper ACP alignment + * + * Configuration: GEMINI_DUAL_FORMAT + * - 'new': Send only gemini format + * - 'old': Send only legacy codex format (for rollback) + * - 'both': Send both formats for backward compatibility (default) + */ + sendGeminiMessage(body: any) { + const dualFormatMode = process.env.GEMINI_DUAL_FORMAT || 'both'; + + // Check if socket is connected before sending + if (!this.socket.connected) { + logger.debug('[API] Socket not connected, cannot send Gemini message. Message will be lost:', { type: body.type }); + return; + } + + // Send new gemini format + if (dualFormatMode === 'new' || dualFormatMode === 'both') { + let geminiContent = { + role: 'agent', + content: { + type: 'gemini', // Dedicated Gemini type + data: body + }, + meta: { + sentFrom: 'cli', + format: 'gemini' // Marker for debugging + } + }; + const geminiEncrypted = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, geminiContent)); + + this.socket.emit('message', { + sid: this.sessionId, + message: geminiEncrypted + }); + + if (dualFormatMode === 'new') { + logger.debug('[API] Sent Gemini message (new format only):', { type: body.type }); + } + } + + // Send old codex format for backward compatibility + if (dualFormatMode === 'old' || dualFormatMode === 'both') { + // Convert new format to old codex format + let codexBody = this.convertGeminiToCodex(body); + if (codexBody) { + let codexContent = { + role: 'agent', + content: { + type: 'codex', + data: codexBody + }, + meta: { + sentFrom: 'cli', + format: 'codex-compat' // Marker for debugging + } + }; + const codexEncrypted = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, codexContent)); + + this.socket.emit('message', { + sid: this.sessionId, + message: codexEncrypted + }); + + if (dualFormatMode === 'both') { + logger.debug('[API] Sent Gemini message (dual format - new + old):', { type: body.type }); + } + } + } + } + + /** + * Convert new Gemini message format to old Codex format for backward compatibility + */ + private convertGeminiToCodex(geminiBody: any): any { + const type = geminiBody.type; + + switch (type) { + case 'model-output': + return { + type: 'message', + message: geminiBody.textDelta || '', + id: geminiBody.id + }; + + case 'thinking': + return { + type: 'reasoning', + message: geminiBody.text, + id: geminiBody.id + }; + + case 'message': + return { + type: 'message', + message: geminiBody.message, + id: geminiBody.id + }; + + case 'tool-call': + return { + type: 'tool-call', + callId: geminiBody.callId, + name: geminiBody.toolName, + input: geminiBody.args, + id: geminiBody.id + }; + + case 'tool-result': + return { + type: 'tool-call-result', + callId: geminiBody.callId, + output: geminiBody.result, + id: geminiBody.id + }; + + case 'status': + case 'token-count': + case 'file-edit': + case 'terminal-output': + case 'permission-request': + // These don't exist in old format, skip + logger.debug('[API] Skipping Gemini message type in codex conversion:', type); + return null; + + default: + logger.debug('[API] Unknown Gemini message type for codex conversion:', type); + return null; + } + } + /** * Send a generic agent message to the session. * Works for any agent type (Gemini, Codex, Claude, etc.) diff --git a/src/api/types.ts b/src/api/types.ts index ae0147e5..7880ced3 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -271,12 +271,111 @@ export const UserMessageSchema = z.object({ export type UserMessage = z.infer +/** + * Gemini message data schema - aligned with ACP protocol + * Used for dedicated Gemini message type (separate from Codex) + */ +export const GeminiMessageDataSchema = z.discriminatedUnion('type', [ + // Text output from model + z.object({ + type: z.literal('model-output'), + textDelta: z.string().optional(), + id: z.string() + }), + + // Tool call + z.object({ + type: z.literal('tool-call'), + toolName: z.string(), + args: z.any(), + callId: z.string(), + id: z.string() + }), + + // Tool result + z.object({ + type: z.literal('tool-result'), + toolName: z.string(), + result: z.any(), + callId: z.string(), + isError: z.boolean().optional(), + id: z.string() + }), + + // Status update + z.object({ + type: z.literal('status'), + status: z.enum(['starting', 'running', 'idle', 'stopped', 'error']), + id: z.string() + }), + + // Token usage + z.object({ + type: z.literal('token-count'), + inputTokens: z.number(), + outputTokens: z.number(), + totalTokens: z.number().optional(), + id: z.string() + }), + + // Thinking/reasoning + z.object({ + type: z.literal('thinking'), + text: z.string(), + id: z.string() + }), + + // File edit + z.object({ + type: z.literal('file-edit'), + description: z.string(), + diff: z.string(), + path: z.string().optional(), + id: z.string() + }), + + // Terminal output + z.object({ + type: z.literal('terminal-output'), + data: z.string(), + id: z.string() + }), + + // Permission request + z.object({ + type: z.literal('permission-request'), + permissionId: z.string(), + reason: z.string(), + payload: z.any().optional(), + id: z.string() + }), + + // Generic message + z.object({ + type: z.literal('message'), + message: z.string(), + id: z.string() + }) +]); + +export type GeminiMessageData = z.infer + export const AgentMessageSchema = z.object({ role: z.literal('agent'), - content: z.object({ - type: z.literal('output'), - data: z.any() - }), + content: z.discriminatedUnion('type', [ + z.object({ + type: z.literal('output'), + data: z.any() // Claude messages + }), + z.object({ + type: z.literal('codex'), + data: z.any() // Codex/OpenAI messages + }), + z.object({ + type: z.literal('gemini'), // Gemini messages + data: GeminiMessageDataSchema + }) + ]), meta: MessageMetaSchema.optional() }) diff --git a/src/claude/claudeRemoteLauncher.ts b/src/claude/claudeRemoteLauncher.ts index b1888804..a8691c27 100644 --- a/src/claude/claudeRemoteLauncher.ts +++ b/src/claude/claudeRemoteLauncher.ts @@ -440,14 +440,34 @@ export async function claudeRemoteLauncher(session: Session): Promise<'switch' | // Clean up permission handler permissionHandler.reset(); - // Reset Terminal + // Reset Terminal - IMPORTANT: Order matters to prevent stdin listener competition bug! + // Must unmount Ink BEFORE changing terminal modes to ensure useInput listeners are removed + if (inkInstance) { + inkInstance.unmount(); + } + + // Remove explicit abort listener process.stdin.off('data', abort); + + // Reset terminal mode after Ink cleanup if (process.stdin.isTTY) { process.stdin.setRawMode(false); } - if (inkInstance) { - inkInstance.unmount(); + + // Additional cleanup: Ensure ALL stdin listeners are removed before switching to local mode + // This prevents parent and child from competing for stdin input (double character bug) + if (exitReason === 'switch') { + // Remove any remaining data listeners that might compete with the child process + const dataListeners = process.stdin.listeners('data'); + const keypressListeners = process.stdin.listeners('keypress'); + + if (dataListeners.length > 0 || keypressListeners.length > 0) { + logger.debug(`[remote]: Cleaning up remaining stdin listeners before switch (data: ${dataListeners.length}, keypress: ${keypressListeners.length})`); + process.stdin.removeAllListeners('data'); + process.stdin.removeAllListeners('keypress'); + } } + messageBuffer.clear(); // Resolve abort future diff --git a/src/claude/loop.ts b/src/claude/loop.ts index b3d1f7e0..dcab191c 100644 --- a/src/claude/loop.ts +++ b/src/claude/loop.ts @@ -91,6 +91,11 @@ export async function loop(opts: LoopOptions) { if (opts.onModeChange) { opts.onModeChange(mode); } + + // Small delay to ensure remote mode stdin cleanup fully completes + // before local mode spawns child (prevents stdin listener competition) + await new Promise(resolve => setTimeout(resolve, 50)); + continue; } } diff --git a/src/gemini/geminiLocal.ts b/src/gemini/geminiLocal.ts new file mode 100644 index 00000000..ae853f64 --- /dev/null +++ b/src/gemini/geminiLocal.ts @@ -0,0 +1,101 @@ +/** + * Gemini Local Mode - Spawn Gemini CLI Process + * + * This module spawns the Gemini CLI as a child process with inherited stdio, + * allowing the user to interact directly with Gemini's native interface. + * + * Similar to claudeLocal.ts but adapted for Gemini CLI's API. + */ + +import { spawn } from 'node:child_process'; +import { logger } from '@/ui/logger'; + +export async function geminiLocal(opts: { + abort: AbortSignal, + sessionId: string | null, + path: string, + onSessionFound: (id: string) => void, + model?: string, + approvalMode?: string, + allowedTools?: string[], +}): Promise { + logger.debug(`[GeminiLocal] Starting Gemini CLI in local mode`); + logger.debug(`[GeminiLocal] Working directory: ${opts.path}`); + logger.debug(`[GeminiLocal] Session ID: ${opts.sessionId || 'new'}`); + + // Build Gemini CLI arguments + const args: string[] = []; + + // Session management + if (opts.sessionId) { + args.push('--resume', opts.sessionId); + logger.debug(`[GeminiLocal] Resuming session: ${opts.sessionId}`); + } else { + logger.debug(`[GeminiLocal] Starting fresh session`); + } + + // Model selection + if (opts.model) { + args.push('--model', opts.model); + logger.debug(`[GeminiLocal] Using model: ${opts.model}`); + } + + // Permission/approval mode + if (opts.approvalMode) { + args.push('--approval-mode', opts.approvalMode); + logger.debug(`[GeminiLocal] Approval mode: ${opts.approvalMode}`); + } + + // Allowed tools (pre-approved tools that don't need confirmation) + if (opts.allowedTools && opts.allowedTools.length > 0) { + args.push('--allowed-tools', ...opts.allowedTools); + logger.debug(`[GeminiLocal] Allowed tools: ${opts.allowedTools.join(', ')}`); + } + + logger.debug(`[GeminiLocal] Spawning: gemini ${args.join(' ')}`); + + // Spawn the Gemini CLI process + try { + await new Promise((resolve, reject) => { + const child = spawn('gemini', args, { + stdio: ['inherit', 'inherit', 'inherit'], + signal: opts.abort, + cwd: opts.path, + env: { + ...process.env, + // Gemini CLI environment variables + GEMINI_PROJECT_DIR: opts.path, + } + }); + + child.on('error', (error) => { + logger.debug('[GeminiLocal] Process error:', error); + reject(error); + }); + + child.on('exit', (code, signal) => { + if (signal === 'SIGTERM' && opts.abort.aborted) { + // Normal termination due to abort signal + logger.debug('[GeminiLocal] Process aborted by signal'); + resolve(); + } else if (signal) { + logger.debug(`[GeminiLocal] Process terminated with signal: ${signal}`); + reject(new Error(`Gemini terminated with signal: ${signal}`)); + } else { + logger.debug(`[GeminiLocal] Process exited with code: ${code}`); + resolve(); + } + }); + }); + } catch (error: any) { + logger.debug('[GeminiLocal] Spawn failed:', error); + if (error.code === 'ENOENT') { + throw new Error('Gemini CLI not found. Please install it with: npm install -g @google/gemini-cli'); + } + throw error; + } finally { + logger.debug('[GeminiLocal] Cleanup complete'); + } + + return opts.sessionId; +} diff --git a/src/gemini/geminiLocalLauncher.ts b/src/gemini/geminiLocalLauncher.ts new file mode 100644 index 00000000..9942415d --- /dev/null +++ b/src/gemini/geminiLocalLauncher.ts @@ -0,0 +1,174 @@ +/** + * Gemini Local Mode Launcher + * + * Orchestrates local mode: spawns Gemini CLI, monitors session via hooks, + * and handles mode switching. + * + * Adapted from claudeLocalLauncher.ts for Gemini CLI. + */ + +import { logger } from '@/ui/logger'; +import { geminiLocal } from './geminiLocal'; +import { GeminiSession } from './session'; +import { Future } from '@/utils/future'; +import { createGeminiSessionScanner } from './utils/sessionScanner'; + +export async function geminiLocalLauncher(session: GeminiSession, opts: { + model?: string; + approvalMode?: string; + allowedTools?: string[]; +}): Promise<'switch' | 'exit'> { + logger.debug('[geminiLocalLauncher] Starting local launcher'); + + // Create scanner if we have a transcript path + let scanner: Awaited> | null = null; + + if (session.transcriptPath) { + scanner = await createGeminiSessionScanner({ + transcriptPath: session.transcriptPath, + onMessage: (message) => { + // Forward messages to Happy server + // TODO: Convert Gemini message format to Happy format + logger.debug(`[geminiLocalLauncher] Received message:`, message); + // session.client.sendGeminiSessionMessage(message); + } + }); + } + + // Register callbacks for when session/transcript are found via hook + const scannerSessionCallback = (transcriptPath: string) => { + logger.debug(`[geminiLocalLauncher] Transcript path callback: ${transcriptPath}`); + if (scanner) { + scanner.onNewSession(transcriptPath); + } + }; + + if (!session.transcriptPath) { + session.addTranscriptPathCallback(scannerSessionCallback); + } + + // Handle abort + let exitReason: 'switch' | 'exit' | null = null; + const processAbortController = new AbortController(); + let exitFuture = new Future(); + + try { + async function abort() { + // Send abort signal + if (!processAbortController.signal.aborted) { + processAbortController.abort(); + } + + // Await full exit + await exitFuture.promise; + } + + async function doAbort() { + logger.debug('[geminiLocal]: doAbort'); + + // Switching to remote mode + if (!exitReason) { + exitReason = 'switch'; + } + + // Reset sent messages + session.queue.reset(); + + // Abort + await abort(); + } + + async function doSwitch() { + logger.debug('[geminiLocal]: doSwitch'); + + // Switching to remote mode + if (!exitReason) { + exitReason = 'switch'; + } + + // Abort + await abort(); + } + + // Register RPC handlers for mode switching + session.client.rpcHandlerManager.registerHandler('abort', doAbort); + session.client.rpcHandlerManager.registerHandler('switch', doSwitch); + + // When any message is received, switch to remote mode + session.queue.setOnMessage((message: string, mode) => { + doSwitch(); + }); + + // If there are already messages in the queue, switch immediately + if (session.queue.size() > 0) { + logger.debug('[geminiLocal]: Messages in queue, switching to remote'); + return 'switch'; + } + + // Handle session start from hook + const handleSessionStart = (sessionId: string) => { + session.onSessionFound(sessionId); + }; + + // Run local mode + while (true) { + // If we already have an exit reason, return it + if (exitReason) { + return exitReason; + } + + // Launch Gemini CLI + logger.debug('[geminiLocal]: Launching Gemini CLI'); + try { + await geminiLocal({ + path: session.path, + sessionId: session.sessionId, + onSessionFound: handleSessionStart, + abort: processAbortController.signal, + model: opts.model, + approvalMode: opts.approvalMode, + allowedTools: opts.allowedTools, + }); + + // Normal exit + if (!exitReason) { + exitReason = 'exit'; + break; + } + } catch (e) { + logger.debug('[geminiLocal]: Launch error', e); + if (!exitReason) { + session.client.sendSessionEvent({ + type: 'message', + message: 'Gemini process exited unexpectedly' + }); + continue; + } else { + break; + } + } + logger.debug('[geminiLocal]: Launch done'); + } + } finally { + // Resolve future + exitFuture.resolve(undefined); + + // Set handlers to no-op + session.client.rpcHandlerManager.registerHandler('abort', async () => {}); + session.client.rpcHandlerManager.registerHandler('switch', async () => {}); + session.queue.setOnMessage(null); + + // Remove callbacks + if (!session.transcriptPath) { + session.removeTranscriptPathCallback(scannerSessionCallback); + } + + // Cleanup scanner + if (scanner) { + await scanner.cleanup(); + } + } + + // Return + return exitReason || 'exit'; +} diff --git a/src/gemini/geminiRemoteLauncher.ts b/src/gemini/geminiRemoteLauncher.ts new file mode 100644 index 00000000..d6031858 --- /dev/null +++ b/src/gemini/geminiRemoteLauncher.ts @@ -0,0 +1,891 @@ +/** + * Gemini Remote Mode Launcher + * + * Handles Gemini's remote mode with ACP backend and Ink UI. + * Extracted from runGemini.ts for better separation between local and remote modes. + */ + +import { render } from 'ink'; +import React from 'react'; +import { randomUUID } from 'node:crypto'; +import { join, resolve } from 'node:path'; + +import { ApiSessionClient } from '@/api/apiSession'; +import { ApiClient } from '@/api/api'; +import { logger } from '@/ui/logger'; +import { MessageQueue2 } from '@/utils/MessageQueue2'; +import { projectPath } from '@/projectPath'; +import { startHappyServer } from '@/claude/utils/startHappyServer'; +import { MessageBuffer } from '@/ui/ink/messageBuffer'; +import { registerKillSessionHandler } from '@/claude/registerKillSessionHandler'; + +import { createGeminiBackend } from '@/agent/acp/gemini'; +import type { AgentBackend, AgentMessage } from '@/agent/AgentBackend'; +import { GeminiDisplay } from '@/ui/ink/GeminiDisplay'; +import { GeminiPermissionHandler } from '@/gemini/utils/permissionHandler'; +import { GeminiReasoningProcessor } from '@/gemini/utils/reasoningProcessor'; +import { GeminiDiffProcessor } from '@/gemini/utils/diffProcessor'; +import type { PermissionMode, GeminiMode } from '@/gemini/types'; +import { GEMINI_MODEL_ENV, DEFAULT_GEMINI_MODEL, CHANGE_TITLE_INSTRUCTION } from '@/gemini/constants'; +import { + readGeminiLocalConfig, + determineGeminiModel, + saveGeminiModelToConfig, + getInitialGeminiModel +} from '@/gemini/utils/config'; +import { + parseOptionsFromText, + hasIncompleteOptions, + formatOptionsXml, +} from '@/gemini/utils/optionsParser'; + +export async function geminiRemoteLauncher(opts: { + session: ApiSessionClient; + api: ApiClient; + messageQueue: MessageQueue2; + model?: string; + approvalMode?: string; + allowedTools?: string[]; + cloudToken?: string; + sessionId?: string | null; + onSessionFound?: (sessionId: string) => void; +}): Promise<'switch' | 'exit'> { + logger.debug('[geminiRemoteLauncher] Starting remote mode'); + + const { session, api, messageQueue, cloudToken } = opts; + + // Track current overrides to apply per message (remote mode only) + let currentPermissionMode: PermissionMode | undefined = undefined; + let currentModel: string | undefined = opts.model; + + // Track if this is the first message to include system prompt only once + let isFirstMessage = true; + + session.onUserMessage((message) => { + // Resolve permission mode (validate) - same as Codex + let messagePermissionMode = currentPermissionMode; + if (message.meta?.permissionMode) { + const validModes: PermissionMode[] = ['default', 'read-only', 'safe-yolo', 'yolo']; + if (validModes.includes(message.meta.permissionMode as PermissionMode)) { + messagePermissionMode = message.meta.permissionMode as PermissionMode; + currentPermissionMode = messagePermissionMode; + // Update permission handler with new mode + updatePermissionMode(messagePermissionMode); + logger.debug(`[Gemini] Permission mode updated from user message to: ${currentPermissionMode}`); + } else { + logger.debug(`[Gemini] Invalid permission mode received: ${message.meta.permissionMode}`); + } + } else { + logger.debug(`[Gemini] User message received with no permission mode override, using current: ${currentPermissionMode ?? 'default (effective)'}`); + } + + // Initialize permission mode if not set yet + if (currentPermissionMode === undefined) { + currentPermissionMode = 'default'; + updatePermissionMode('default'); + } + + // Resolve model; explicit null resets to default (undefined) + let messageModel = currentModel; + if (message.meta?.hasOwnProperty('model')) { + if (message.meta.model === null) { + messageModel = undefined; + currentModel = undefined; + } else if (message.meta.model) { + messageModel = message.meta.model; + currentModel = messageModel; + updateDisplayedModel(messageModel, true); + messageBuffer.addMessage(`Model changed to: ${messageModel}`, 'system'); + } + } + + // Build the full prompt with appendSystemPrompt if provided + const originalUserMessage = message.content.text; + let fullPrompt = originalUserMessage; + if (isFirstMessage && message.meta?.appendSystemPrompt) { + fullPrompt = message.meta.appendSystemPrompt + '\n\n' + originalUserMessage + '\n\n' + CHANGE_TITLE_INSTRUCTION; + isFirstMessage = false; + } + + const mode: GeminiMode = { + permissionMode: messagePermissionMode || 'default', + model: messageModel, + originalUserMessage, + }; + messageQueue.push(fullPrompt, mode); + }); + + let thinking = false; + session.keepAlive(thinking, 'remote'); + const keepAliveInterval = setInterval(() => { + session.keepAlive(thinking, 'remote'); + }, 2000); + + const sendReady = () => { + session.sendSessionEvent({ type: 'ready' }); + try { + api.push().sendToAllDevices( + "It's ready!", + 'Gemini is waiting for your command', + { sessionId: session.sessionId } + ); + } catch (pushError) { + logger.debug('[Gemini] Failed to send ready push', pushError); + } + }; + + const emitReadyIfIdle = (): boolean => { + if (shouldExit) return false; + if (thinking) return false; + if (isResponseInProgress) return false; + if (messageQueue.size() > 0) return false; + + sendReady(); + return true; + }; + + // + // Abort handling + // + + let abortController = new AbortController(); + let shouldExit = false; + let switchToLocal = false; + let geminiBackend: AgentBackend | null = null; + let acpSessionId: string | null = opts.sessionId || null; // Start with provided session ID, will be updated when backend creates session + let wasSessionCreated = false; + + async function handleAbort() { + logger.debug('[Gemini] Abort requested - stopping current task'); + + session.sendGeminiMessage({ + type: 'message', + message: 'Turn aborted', + id: randomUUID(), + }); + + reasoningProcessor.abort(); + diffProcessor.reset(); + + try { + abortController.abort(); + messageQueue.reset(); + if (geminiBackend && acpSessionId) { + await geminiBackend.cancel(acpSessionId); + } + logger.debug('[Gemini] Abort completed - session remains active'); + } catch (error) { + logger.debug('[Gemini] Error during abort:', error); + } finally { + abortController = new AbortController(); + } + } + + const handleKillSession = async () => { + logger.debug('[Gemini] Kill session requested - terminating process'); + await handleAbort(); + shouldExit = true; + }; + + async function doSwitch() { + console.error('[geminiRemoteLauncher] Switch to local mode requested'); + logger.debug('[geminiRemoteLauncher] Switch to local mode requested'); + logger.debug(`[geminiRemoteLauncher] Current state - switchToLocal: ${switchToLocal}, shouldExit: ${shouldExit}`); + console.error(`[geminiRemoteLauncher] Setting flags - switchToLocal=true, shouldExit=true`); + switchToLocal = true; + shouldExit = true; + logger.debug('[geminiRemoteLauncher] State updated - switchToLocal: true, shouldExit: true'); + console.error('[geminiRemoteLauncher] Calling handleAbort()...'); + logger.debug('[geminiRemoteLauncher] Calling handleAbort()...'); + await handleAbort(); + console.error('[geminiRemoteLauncher] handleAbort() completed'); + logger.debug('[geminiRemoteLauncher] handleAbort() completed'); + } + + // Register RPC handlers for abort and mode switching + session.rpcHandlerManager.registerHandler('abort', handleAbort); + registerKillSessionHandler(session.rpcHandlerManager, handleKillSession); + session.rpcHandlerManager.registerHandler('switch', doSwitch); // When user wants to switch to local mode + + // + // Initialize Ink UI + // + + const messageBuffer = new MessageBuffer(); + const hasTTY = process.stdout.isTTY && process.stdin.isTTY; + let inkInstance: ReturnType | null = null; + + let displayedModel: string | undefined = opts.model || getInitialGeminiModel(); + + const localConfig = readGeminiLocalConfig(); + logger.debug(`[gemini] Initial model setup: env[GEMINI_MODEL_ENV]=${process.env[GEMINI_MODEL_ENV] || 'not set'}, localConfig=${localConfig.model || 'not set'}, displayedModel=${displayedModel}`); + + const updateDisplayedModel = (model: string | undefined, saveToConfig: boolean = false) => { + if (model === undefined) { + logger.debug(`[gemini] updateDisplayedModel called with undefined, skipping update`); + return; + } + + const oldModel = displayedModel; + displayedModel = model; + logger.debug(`[gemini] updateDisplayedModel called: oldModel=${oldModel}, newModel=${model}, saveToConfig=${saveToConfig}`); + + if (saveToConfig) { + saveGeminiModelToConfig(model); + } + + if (hasTTY && oldModel !== model) { + logger.debug(`[gemini] Adding model update message to buffer: [MODEL:${model}]`); + messageBuffer.addMessage(`[MODEL:${model}]`, 'system'); + } else if (hasTTY) { + logger.debug(`[gemini] Model unchanged, skipping update message`); + } + }; + + if (hasTTY) { + console.clear(); + + const switchCallback = () => { + logger.debug('[gemini]: Switching to local mode via spacebar'); + doSwitch(); + }; + + const exitCallback = async () => { + logger.debug('[gemini]: Exiting agent via Ctrl-C'); + shouldExit = true; + await handleAbort(); + }; + + inkInstance = render(React.createElement(GeminiDisplay, { + messageBuffer, + logPath: process.env.DEBUG ? logger.getLogPath() : undefined, + currentModel: displayedModel || 'gemini-2.5-pro', + onExit: exitCallback, + onSwitchToLocal: switchCallback + }), { + exitOnCtrlC: false, + patchConsole: false + }); + + const initialModelName = displayedModel || 'gemini-2.5-pro'; + logger.debug(`[gemini] Sending initial model to UI: ${initialModelName}`); + messageBuffer.addMessage(`[MODEL:${initialModelName}]`, 'system'); + } + + if (hasTTY) { + process.stdin.resume(); + if (process.stdin.isTTY) { + process.stdin.setRawMode(true); + } + process.stdin.setEncoding('utf8'); + } + + // + // Start Happy MCP server and create Gemini backend + // + + const happyServer = await startHappyServer(session); + const bridgeCommand = join(projectPath(), 'bin', 'happy-mcp.mjs'); + const mcpServers = { + happy: { + command: bridgeCommand, + args: ['--url', happyServer.url] + } + }; + + const permissionHandler = new GeminiPermissionHandler(session); + const reasoningProcessor = new GeminiReasoningProcessor((message) => { + session.sendGeminiMessage(message); + }); + const diffProcessor = new GeminiDiffProcessor((message) => { + session.sendGeminiMessage(message); + }); + + const updatePermissionMode = (mode: PermissionMode) => { + permissionHandler.setPermissionMode(mode); + }; + + let accumulatedResponse = ''; + let isResponseInProgress = false; + let currentResponseMessageId: string | null = null; + + function setupGeminiMessageHandler(backend: AgentBackend): void { + backend.onMessage((msg: AgentMessage) => { + + switch (msg.type) { + case 'model-output': + if (msg.textDelta) { + if (!isResponseInProgress) { + messageBuffer.removeLastMessage('system'); + messageBuffer.addMessage(msg.textDelta, 'assistant'); + isResponseInProgress = true; + logger.debug(`[gemini] Started new response, first chunk length: ${msg.textDelta.length}`); + } else { + messageBuffer.updateLastMessage(msg.textDelta, 'assistant'); + logger.debug(`[gemini] Updated response, chunk length: ${msg.textDelta.length}, total accumulated: ${accumulatedResponse.length + msg.textDelta.length}`); + } + accumulatedResponse += msg.textDelta; + } + break; + + case 'status': + logger.debug(`[gemini] Status changed: ${msg.status}${msg.detail ? ` - ${msg.detail}` : ''}`); + + if (msg.status === 'error') { + logger.debug(`[gemini] ⚠️ Error status received: ${msg.detail || 'Unknown error'}`); + session.sendGeminiMessage({ + type: 'status', + status: 'error', + id: randomUUID(), + }); + } + + if (msg.status === 'running') { + thinking = true; + session.keepAlive(thinking, 'remote'); + session.sendGeminiMessage({ + type: 'status', + status: 'running', + id: randomUUID(), + }); + messageBuffer.addMessage('Thinking...', 'system'); + } else if (msg.status === 'idle' || msg.status === 'stopped') { + if (thinking) { + thinking = false; + } + thinking = false; + session.keepAlive(thinking, 'remote'); + + const reasoningCompleted = reasoningProcessor.complete(); + + if (reasoningCompleted || isResponseInProgress) { + session.sendGeminiMessage({ + type: 'status', + status: 'idle', + id: randomUUID(), + }); + } + + if (isResponseInProgress && accumulatedResponse.trim()) { + const { text: messageText, options } = parseOptionsFromText(accumulatedResponse); + + let finalMessageText = messageText; + if (options.length > 0) { + const optionsXml = formatOptionsXml(options); + finalMessageText = messageText + optionsXml; + logger.debug(`[gemini] Found ${options.length} options in response:`, options); + logger.debug(`[gemini] Keeping options in message text for mobile app parsing`); + } else if (hasIncompleteOptions(accumulatedResponse)) { + logger.debug(`[gemini] Warning: Incomplete options block detected but sending message anyway`); + } + + const messageId = randomUUID(); + + logger.debug(`[gemini] Sending complete message to mobile (length: ${finalMessageText.length}): ${finalMessageText.substring(0, 100)}...`); + session.sendGeminiMessage({ + type: 'model-output', + textDelta: finalMessageText, + id: messageId, + }); + accumulatedResponse = ''; + isResponseInProgress = false; + } + } else if (msg.status === 'error') { + thinking = false; + session.keepAlive(thinking, 'remote'); + accumulatedResponse = ''; + isResponseInProgress = false; + currentResponseMessageId = null; + + const errorMessage = msg.detail || 'Unknown error'; + messageBuffer.addMessage(`Error: ${errorMessage}`, 'status'); + + session.sendGeminiMessage({ + type: 'message', + message: `Error: ${errorMessage}`, + id: randomUUID(), + }); + } + break; + + case 'tool-call': + const toolArgs = msg.args ? JSON.stringify(msg.args).substring(0, 100) : ''; + const isInvestigationTool = msg.toolName === 'codebase_investigator' || + (typeof msg.toolName === 'string' && msg.toolName.includes('investigator')); + + logger.debug(`[gemini] 🔧 Tool call received: ${msg.toolName} (${msg.callId})${isInvestigationTool ? ' [INVESTIGATION]' : ''}`); + if (isInvestigationTool && msg.args && typeof msg.args === 'object' && 'objective' in msg.args) { + logger.debug(`[gemini] 🔍 Investigation objective: ${String(msg.args.objective).substring(0, 150)}...`); + } + + messageBuffer.addMessage(`Executing: ${msg.toolName}${toolArgs ? ` ${toolArgs}${toolArgs.length >= 100 ? '...' : ''}` : ''}`, 'tool'); + session.sendGeminiMessage({ + type: 'tool-call', + toolName: msg.toolName, + args: msg.args, + callId: msg.callId, + id: randomUUID(), + }); + break; + + case 'tool-result': + const isError = msg.result && typeof msg.result === 'object' && 'error' in msg.result; + const resultText = typeof msg.result === 'string' + ? msg.result.substring(0, 200) + : JSON.stringify(msg.result).substring(0, 200); + const truncatedResult = resultText + (typeof msg.result === 'string' && msg.result.length > 200 ? '...' : ''); + + const resultSize = typeof msg.result === 'string' + ? msg.result.length + : JSON.stringify(msg.result).length; + + logger.debug(`[gemini] ${isError ? '❌' : '✅'} Tool result received: ${msg.toolName} (${msg.callId}) - Size: ${resultSize} bytes${isError ? ' [ERROR]' : ''}`); + + if (!isError) { + diffProcessor.processToolResult(msg.toolName, msg.result, msg.callId); + } + + if (isError) { + const errorMsg = (msg.result as any).error || 'Tool call failed'; + logger.debug(`[gemini] ❌ Tool call error: ${errorMsg.substring(0, 300)}`); + messageBuffer.addMessage(`Error: ${errorMsg}`, 'status'); + } else { + if (resultSize > 1000) { + logger.debug(`[gemini] ✅ Large tool result (${resultSize} bytes) - first 200 chars: ${truncatedResult}`); + } + messageBuffer.addMessage(`Result: ${truncatedResult}`, 'result'); + } + + session.sendGeminiMessage({ + type: 'tool-result', + toolName: msg.toolName, + result: msg.result, + callId: msg.callId, + isError: isError, + id: randomUUID(), + }); + break; + + case 'fs-edit': + messageBuffer.addMessage(`File edit: ${msg.description}`, 'tool'); + diffProcessor.processFsEdit(msg.path || '', msg.description, msg.diff); + + session.sendGeminiMessage({ + type: 'file-edit', + description: msg.description, + diff: msg.diff, + path: msg.path, + id: randomUUID(), + }); + break; + + case 'terminal-output': + messageBuffer.addMessage(msg.data, 'result'); + session.sendGeminiMessage({ + type: 'terminal-output', + data: msg.data, + id: randomUUID(), + }); + break; + + case 'permission-request': + session.sendGeminiMessage({ + type: 'permission-request', + permissionId: msg.id, + reason: msg.reason, + payload: msg.payload, + id: randomUUID(), + }); + break; + + case 'exec-approval-request': + const execApprovalMsg = msg as any; + const callId = execApprovalMsg.call_id || execApprovalMsg.callId || randomUUID(); + const { call_id, type, ...inputs } = execApprovalMsg; + + logger.debug(`[gemini] Exec approval request received: ${callId}`); + messageBuffer.addMessage(`Exec approval requested: ${callId}`, 'tool'); + + session.sendGeminiMessage({ + type: 'tool-call', + toolName: 'GeminiBash', + args: inputs, + callId: callId, + id: randomUUID(), + }); + break; + + case 'patch-apply-begin': + const patchBeginMsg = msg as any; + const patchCallId = patchBeginMsg.call_id || patchBeginMsg.callId || randomUUID(); + const { call_id: patchCallIdVar, type: patchType, auto_approved, changes } = patchBeginMsg; + + const changeCount = changes ? Object.keys(changes).length : 0; + const filesMsg = changeCount === 1 ? '1 file' : `${changeCount} files`; + messageBuffer.addMessage(`Modifying ${filesMsg}...`, 'tool'); + logger.debug(`[gemini] Patch apply begin: ${patchCallId}, files: ${changeCount}`); + + session.sendGeminiMessage({ + type: 'tool-call', + toolName: 'GeminiPatch', + args: { + auto_approved, + changes + }, + callId: patchCallId, + id: randomUUID(), + }); + break; + + case 'patch-apply-end': + const patchEndMsg = msg as any; + const patchEndCallId = patchEndMsg.call_id || patchEndMsg.callId || randomUUID(); + const { call_id: patchEndCallIdVar, type: patchEndType, stdout, stderr, success } = patchEndMsg; + + if (success) { + const message = stdout || 'Files modified successfully'; + messageBuffer.addMessage(message.substring(0, 200), 'result'); + } else { + const errorMsg = stderr || 'Failed to modify files'; + messageBuffer.addMessage(`Error: ${errorMsg.substring(0, 200)}`, 'result'); + } + logger.debug(`[gemini] Patch apply end: ${patchEndCallId}, success: ${success}`); + + session.sendGeminiMessage({ + type: 'tool-result', + toolName: 'GeminiPatch', + result: { + stdout, + stderr, + success + }, + callId: patchEndCallId, + isError: !success, + id: randomUUID(), + }); + break; + + case 'event': + if (msg.name === 'session-created') { + // Capture the ACP session ID for future resumption + const sessionPayload = msg.payload as { sessionId?: string } | undefined; + if (sessionPayload && sessionPayload.sessionId) { + acpSessionId = sessionPayload.sessionId; + logger.debug(`[gemini] Session created/captured: ${acpSessionId}`); + + // Notify the loop so it can update the GeminiSession object + if (opts.onSessionFound) { + opts.onSessionFound(acpSessionId); + } + } + } else if (msg.name === 'thinking') { + const thinkingPayload = msg.payload as { text?: string } | undefined; + const thinkingText = (thinkingPayload && typeof thinkingPayload === 'object' && 'text' in thinkingPayload) + ? String(thinkingPayload.text || '') + : ''; + if (thinkingText) { + reasoningProcessor.processChunk(thinkingText); + logger.debug(`[gemini] 💭 Thinking chunk received: ${thinkingText.length} chars - Preview: ${thinkingText.substring(0, 100)}...`); + + if (!thinkingText.startsWith('**')) { + const thinkingPreview = thinkingText.substring(0, 100); + messageBuffer.updateLastMessage(`[Thinking] ${thinkingPreview}...`, 'system'); + } + } + session.sendGeminiMessage({ + type: 'thinking', + text: thinkingText, + id: randomUUID(), + }); + } + break; + + default: + if ((msg as any).type === 'token-count') { + const tokenMsg = msg as any; + session.sendGeminiMessage({ + type: 'token-count', + inputTokens: tokenMsg.inputTokens || 0, + outputTokens: tokenMsg.outputTokens || 0, + totalTokens: tokenMsg.totalTokens, + id: randomUUID(), + }); + } + break; + } + }); + } + + let first = true; + + try { + let currentModeHash: string | null = null; + let pending: { message: string; mode: GeminiMode; isolate: boolean; hash: string } | null = null; + + while (!shouldExit) { + logger.debug(`[gemini] Main loop iteration - shouldExit: ${shouldExit}, switchToLocal: ${switchToLocal}`); + let message: { message: string; mode: GeminiMode; isolate: boolean; hash: string } | null = pending; + pending = null; + + if (!message) { + logger.debug('[gemini] Main loop: waiting for messages from queue...'); + const waitSignal = abortController.signal; + const batch = await messageQueue.waitForMessagesAndGetAsString(waitSignal); + if (!batch) { + if (waitSignal.aborted && !shouldExit) { + logger.debug('[gemini] Main loop: wait aborted but shouldExit is false, continuing...'); + continue; + } + logger.debug(`[gemini] Main loop: no batch received (aborted: ${waitSignal.aborted}, shouldExit: ${shouldExit}), breaking...`); + break; + } + logger.debug(`[gemini] Main loop: received message from queue (length: ${batch.message.length})`); + message = batch; + } + + if (!message) { + break; + } + + // Handle mode change + if (wasSessionCreated && currentModeHash && message.hash !== currentModeHash) { + logger.debug('[Gemini] Mode changed – restarting Gemini session'); + messageBuffer.addMessage('═'.repeat(40), 'status'); + messageBuffer.addMessage('Starting new Gemini session (mode changed)...', 'status'); + + permissionHandler.reset(); + reasoningProcessor.abort(); + + if (geminiBackend) { + await geminiBackend.dispose(); + geminiBackend = null; + } + + const modelToUse = message.mode?.model === undefined ? undefined : (message.mode.model || null); + geminiBackend = createGeminiBackend({ + cwd: process.cwd(), + mcpServers, + permissionHandler, + cloudToken, + model: modelToUse, + sessionId: acpSessionId, // Use captured session ID + }); + + setupGeminiMessageHandler(geminiBackend); + + const localConfigForModel = readGeminiLocalConfig(); + const actualModel = determineGeminiModel(modelToUse, localConfigForModel); + logger.debug(`[gemini] Model change - modelToUse=${modelToUse}, actualModel=${actualModel}`); + + logger.debug('[gemini] Starting new ACP session with model:', actualModel); + const { sessionId } = await geminiBackend.startSession(); + acpSessionId = sessionId; + logger.debug(`[gemini] New ACP session started: ${acpSessionId}`); + + logger.debug(`[gemini] Calling updateDisplayedModel with: ${actualModel}`); + updateDisplayedModel(actualModel, false); + + updatePermissionMode(message.mode.permissionMode); + + wasSessionCreated = true; + currentModeHash = message.hash; + first = false; + } + + currentModeHash = message.hash; + const userMessageToShow = message.mode?.originalUserMessage || message.message; + messageBuffer.addMessage(userMessageToShow, 'user'); + + try { + if (first || !wasSessionCreated) { + if (!geminiBackend) { + const modelToUse = message.mode?.model === undefined ? undefined : (message.mode.model || null); + geminiBackend = createGeminiBackend({ + cwd: process.cwd(), + mcpServers, + permissionHandler, + cloudToken, + model: modelToUse, + sessionId: acpSessionId, // Use captured session ID + }); + + setupGeminiMessageHandler(geminiBackend); + + const localConfigForModel = readGeminiLocalConfig(); + const actualModel = determineGeminiModel(modelToUse, localConfigForModel); + + const modelSource = modelToUse !== undefined + ? 'message' + : process.env[GEMINI_MODEL_ENV] + ? 'env-var' + : localConfigForModel.model + ? 'local-config' + : 'default'; + + logger.debug(`[gemini] Backend created, model will be: ${actualModel} (from ${modelSource})`); + logger.debug(`[gemini] Calling updateDisplayedModel with: ${actualModel}`); + updateDisplayedModel(actualModel, false); + } + + if (!acpSessionId) { + logger.debug('[gemini] Starting ACP session...'); + updatePermissionMode(message.mode.permissionMode); + const { sessionId } = await geminiBackend.startSession(); + acpSessionId = sessionId; + logger.debug(`[gemini] ACP session started: ${acpSessionId}`); + wasSessionCreated = true; + currentModeHash = message.hash; + + logger.debug(`[gemini] Displaying model in UI: ${displayedModel || 'gemini-2.5-pro'}, displayedModel: ${displayedModel}`); + } + } + + if (!acpSessionId) { + throw new Error('ACP session not started'); + } + + accumulatedResponse = ''; + isResponseInProgress = false; + + if (!geminiBackend || !acpSessionId) { + throw new Error('Gemini backend or session not initialized'); + } + + const promptToSend = message.message; + + logger.debug(`[gemini] Sending prompt to Gemini (length: ${promptToSend.length}): ${promptToSend.substring(0, 100)}...`); + logger.debug(`[gemini] Full prompt: ${promptToSend}`); + await geminiBackend.sendPrompt(acpSessionId, promptToSend); + logger.debug('[gemini] Prompt sent successfully'); + + if (first) { + first = false; + } + } catch (error) { + logger.debug('[gemini] Error in gemini session:', error); + const isAbortError = error instanceof Error && error.name === 'AbortError'; + + if (isAbortError) { + messageBuffer.addMessage('Aborted by user', 'status'); + session.sendSessionEvent({ type: 'message', message: 'Aborted by user' }); + } else { + let errorMsg = 'Process error occurred'; + + if (typeof error === 'object' && error !== null) { + const errObj = error as any; + + const errorDetails = errObj.data?.details || errObj.details || ''; + const errorCode = errObj.code || errObj.status || (errObj.response?.status); + const errorMessage = errObj.message || errObj.error?.message || ''; + const errorString = String(error); + + if (errorCode === 404 || errorDetails.includes('notFound') || errorDetails.includes('404') || + errorMessage.includes('not found') || errorMessage.includes('404')) { + const currentModel = displayedModel || 'gemini-2.5-pro'; + errorMsg = `Model "${currentModel}" not found. Available models: gemini-2.5-pro, gemini-2.5-flash, gemini-2.5-flash-lite`; + } + else if (errorCode === 429 || + errorDetails.includes('429') || errorMessage.includes('429') || errorString.includes('429') || + errorDetails.includes('rateLimitExceeded') || errorDetails.includes('RESOURCE_EXHAUSTED') || + errorMessage.includes('Rate limit exceeded') || errorMessage.includes('Resource exhausted') || + errorString.includes('rateLimitExceeded') || errorString.includes('RESOURCE_EXHAUSTED')) { + errorMsg = 'Gemini API rate limit exceeded. Please wait a moment and try again. The API will retry automatically.'; + } + else if (errorDetails.includes('quota') || errorMessage.includes('quota') || errorString.includes('quota')) { + errorMsg = 'Gemini API daily quota exceeded. Please wait until quota resets or use a paid API key.'; + } + else if (Object.keys(error).length === 0) { + errorMsg = 'Failed to start Gemini. Is "gemini" CLI installed? Run: npm install -g @google/gemini-cli'; + } + else if (errObj.message || errorMessage) { + errorMsg = errorDetails || errorMessage || errObj.message; + } + } else if (error instanceof Error) { + errorMsg = error.message; + } + + messageBuffer.addMessage(errorMsg, 'status'); + session.sendGeminiMessage({ + type: 'message', + message: errorMsg, + id: randomUUID(), + }); + } + } finally { + permissionHandler.reset(); + reasoningProcessor.abort(); + diffProcessor.reset(); + + thinking = false; + session.keepAlive(thinking, 'remote'); + + emitReadyIfIdle(); + + logger.debug(`[gemini] Main loop: turn completed, continuing to next iteration (queue size: ${messageQueue.size()})`); + } + } + + } finally { + // Clean up resources + logger.debug('[geminiRemoteLauncher]: Cleanup start'); + + // Note: RPC handlers are not unregistered as RpcHandlerManager doesn't provide unregisterHandler + // They will be cleaned up when the session is closed in runGemini.ts + + if (geminiBackend) { + await geminiBackend.dispose(); + } + + happyServer.stop(); + + // Clean up stdin with proper order (from bug fix) + if (inkInstance) { + inkInstance.unmount(); + } + + // Remove stdin listeners and reset terminal mode BEFORE clearing screen + // This ensures stdin is fully released before local mode starts + logger.debug('[geminiRemoteLauncher]: Starting stdin cleanup'); + + // Remove all stdin listeners (the old code with off() didn't work) + process.stdin.removeAllListeners('data'); + process.stdin.removeAllListeners('keypress'); + + const listenersRemaining = process.stdin.listeners('data').length + process.stdin.listeners('keypress').length; + logger.debug(`[geminiRemoteLauncher]: Stdin listeners removed. Remaining: ${listenersRemaining}`); + + // Reset terminal mode + if (process.stdin.isTTY) { + try { + process.stdin.setRawMode(false); + logger.debug('[geminiRemoteLauncher]: Stdin raw mode disabled'); + } catch (e) { + logger.debug('[geminiRemoteLauncher]: Failed to disable raw mode:', e); + } + } + + if (hasTTY) { + try { + process.stdin.pause(); + logger.debug('[geminiRemoteLauncher]: Stdin paused'); + } catch (e) { + logger.debug('[geminiRemoteLauncher]: Failed to pause stdin:', e); + } + } + + // Clear screen when switching to local mode (AFTER stdin cleanup) + if (switchToLocal && hasTTY) { + console.clear(); + logger.debug('[geminiRemoteLauncher]: Screen cleared for local mode'); + } + + clearInterval(keepAliveInterval); + messageBuffer.clear(); + + logger.debug('[geminiRemoteLauncher]: Cleanup completed'); + } + + const returnValue = switchToLocal ? 'switch' : 'exit'; + logger.debug(`[geminiRemoteLauncher]: Returning '${returnValue}' to geminiLoop`); + return returnValue; +} diff --git a/src/gemini/loop.ts b/src/gemini/loop.ts new file mode 100644 index 00000000..7659598d --- /dev/null +++ b/src/gemini/loop.ts @@ -0,0 +1,111 @@ +/** + * Gemini Mode Switching Loop + * + * Manages switching between local and remote modes for Gemini, + * similar to Claude's loop.ts + */ + +import { ApiSessionClient } from "@/api/apiSession"; +import { MessageQueue2 } from "@/utils/MessageQueue2"; +import { logger } from "@/ui/logger"; +import { GeminiSession } from "./session"; +import { geminiLocalLauncher } from "./geminiLocalLauncher"; +import { ApiClient } from "@/lib"; +import type { GeminiMode } from "./types"; + +interface GeminiLoopOptions { + path: string; + model?: string; + approvalMode?: string; + startingMode?: 'local' | 'remote'; + onModeChange: (mode: 'local' | 'remote') => void; + session: ApiSessionClient; + api: ApiClient; + messageQueue: MessageQueue2; + allowedTools?: string[]; + cloudToken?: string; + onSessionReady?: (session: GeminiSession) => void; +} + +export async function geminiLoop(opts: GeminiLoopOptions) { + // Get log path for debug display + const logPath = logger.logFilePath; + + // Create Gemini session + let session = new GeminiSession({ + client: opts.session, + path: opts.path, + sessionId: null, + logPath: logPath, + queue: opts.messageQueue, + }); + + // Notify that session is ready + if (opts.onSessionReady) { + opts.onSessionReady(session); + } + + let mode: 'local' | 'remote' = opts.startingMode ?? 'remote'; + + while (true) { + logger.debug(`[geminiLoop] Iteration with mode: ${mode}`); + + // Run local mode + if (mode === 'local') { + let reason = await geminiLocalLauncher(session, { + model: opts.model, + approvalMode: opts.approvalMode, + allowedTools: opts.allowedTools, + }); + + if (reason === 'exit') { + // Normal exit - Exit loop + return; + } + + // Non "exit" reason means we need to switch to remote mode + mode = 'remote'; + if (opts.onModeChange) { + opts.onModeChange(mode); + } + continue; + } + + // Run remote mode + if (mode === 'remote') { + const { geminiRemoteLauncher } = await import('./geminiRemoteLauncher'); + + let reason = await geminiRemoteLauncher({ + session: opts.session, + api: opts.api, + messageQueue: opts.messageQueue, + model: opts.model, + approvalMode: opts.approvalMode, + allowedTools: opts.allowedTools, + cloudToken: opts.cloudToken, + sessionId: session.sessionId, + onSessionFound: (sessionId: string) => { + logger.debug(`[geminiLoop] Session found in remote mode: ${sessionId}`); + session.onSessionFound(sessionId); + }, + }); + + if (reason === 'exit') { + // Normal exit - Exit loop + return; + } + + // Non "exit" reason means we need to switch to local mode + mode = 'local'; + if (opts.onModeChange) { + opts.onModeChange(mode); + } + + // Small delay to ensure remote mode stdin cleanup fully completes + // before local mode spawns child (prevents stdin listener competition) + await new Promise(resolve => setTimeout(resolve, 50)); + + continue; + } + } +} diff --git a/src/gemini/runGemini.ts b/src/gemini/runGemini.ts index b89554bf..1b50dca2 100644 --- a/src/gemini/runGemini.ts +++ b/src/gemini/runGemini.ts @@ -35,6 +35,7 @@ import { GeminiPermissionHandler } from '@/gemini/utils/permissionHandler'; import { GeminiReasoningProcessor } from '@/gemini/utils/reasoningProcessor'; import { GeminiDiffProcessor } from '@/gemini/utils/diffProcessor'; import type { PermissionMode, GeminiMode, CodexMessagePayload } from '@/gemini/types'; +import type { GeminiSession } from '@/gemini/session'; import { GEMINI_MODEL_ENV, DEFAULT_GEMINI_MODEL, CHANGE_TITLE_INSTRUCTION } from '@/gemini/constants'; import { readGeminiLocalConfig, @@ -55,6 +56,7 @@ import { export async function runGemini(opts: { credentials: Credentials; startedBy?: 'daemon' | 'terminal'; + startingMode?: 'local' | 'remote'; }): Promise { // // Define session @@ -140,963 +142,66 @@ export async function runGemini(opts: { model: mode.model, })); - // Track current overrides to apply per message - let currentPermissionMode: PermissionMode | undefined = undefined; - let currentModel: string | undefined = undefined; + // Variable to track current session instance (updated via onSessionReady callback) + // Used by hook server to notify GeminiSession when Gemini changes session ID + let currentSession: GeminiSession | null = null; - session.onUserMessage((message) => { - // Resolve permission mode (validate) - same as Codex - let messagePermissionMode = currentPermissionMode; - if (message.meta?.permissionMode) { - const validModes: PermissionMode[] = ['default', 'read-only', 'safe-yolo', 'yolo']; - if (validModes.includes(message.meta.permissionMode as PermissionMode)) { - messagePermissionMode = message.meta.permissionMode as PermissionMode; - currentPermissionMode = messagePermissionMode; - // Update permission handler with new mode - updatePermissionMode(messagePermissionMode); - logger.debug(`[Gemini] Permission mode updated from user message to: ${currentPermissionMode}`); - } else { - logger.debug(`[Gemini] Invalid permission mode received: ${message.meta.permissionMode}`); - } - } else { - logger.debug(`[Gemini] User message received with no permission mode override, using current: ${currentPermissionMode ?? 'default (effective)'}`); - } - - // Initialize permission mode if not set yet - if (currentPermissionMode === undefined) { - currentPermissionMode = 'default'; - updatePermissionMode('default'); - } - - // Resolve model; explicit null resets to default (undefined) - let messageModel = currentModel; - if (message.meta?.hasOwnProperty('model')) { - // If model is explicitly null, reset internal state but don't update displayed model - // If model is provided, use it and update displayed model - // Otherwise keep current model - if (message.meta.model === null) { - messageModel = undefined; // Explicitly reset - will use default/env/config - currentModel = undefined; - // Don't call updateDisplayedModel here - keep current displayed model - // The backend will use the correct model from env/config/default - } else if (message.meta.model) { - messageModel = message.meta.model; - currentModel = messageModel; - // Save model to config file so it persists across sessions - updateDisplayedModel(messageModel, true); // Update UI and save to config - // Show model change message in UI (this will trigger UI re-render) - messageBuffer.addMessage(`Model changed to: ${messageModel}`, 'system'); - } - // If message.meta.model is undefined, keep currentModel - } - - // Build the full prompt with appendSystemPrompt if provided - // Only include system prompt for the first message to avoid forcing tool usage on every message - const originalUserMessage = message.content.text; - let fullPrompt = originalUserMessage; - if (isFirstMessage && message.meta?.appendSystemPrompt) { - // Prepend system prompt to user message only for first message - // Also add change_title instruction (like Codex does) - // Use EXACT same format as Codex: add instruction AFTER user message - // This matches Codex's approach exactly - instruction comes after user message - // Codex format: system prompt + user message + change_title instruction - fullPrompt = message.meta.appendSystemPrompt + '\n\n' + originalUserMessage + '\n\n' + CHANGE_TITLE_INSTRUCTION; - isFirstMessage = false; - } - - const mode: GeminiMode = { - permissionMode: messagePermissionMode || 'default', - model: messageModel, - originalUserMessage, // Store original message separately - }; - messageQueue.push(fullPrompt, mode); - }); - - let thinking = false; - session.keepAlive(thinking, 'remote'); - const keepAliveInterval = setInterval(() => { - session.keepAlive(thinking, 'remote'); - }, 2000); - - // Track if this is the first message to include system prompt only once - let isFirstMessage = true; - - const sendReady = () => { - session.sendSessionEvent({ type: 'ready' }); - try { - api.push().sendToAllDevices( - "It's ready!", - 'Gemini is waiting for your command', - { sessionId: session.sessionId } - ); - } catch (pushError) { - logger.debug('[Gemini] Failed to send ready push', pushError); - } - }; - - /** - * Check if we can emit ready event - * * Returns true when ready event was emitted - */ - const emitReadyIfIdle = (): boolean => { - if (shouldExit) { - return false; - } - if (thinking) { - return false; - } - if (isResponseInProgress) { - return false; - } - if (messageQueue.size() > 0) { - return false; - } - - sendReady(); - return true; - }; - - // - // Abort handling - // - - let abortController = new AbortController(); - let shouldExit = false; - let geminiBackend: AgentBackend | null = null; - let acpSessionId: string | null = null; - let wasSessionCreated = false; - - async function handleAbort() { - logger.debug('[Gemini] Abort requested - stopping current task'); - - // Send turn_aborted event (like Codex) when abort is requested - session.sendCodexMessage({ - type: 'turn_aborted', - id: randomUUID(), - }); - - // Abort reasoning processor and reset diff processor - reasoningProcessor.abort(); - diffProcessor.reset(); - - try { - abortController.abort(); - messageQueue.reset(); - if (geminiBackend && acpSessionId) { - await geminiBackend.cancel(acpSessionId); - } - logger.debug('[Gemini] Abort completed - session remains active'); - } catch (error) { - logger.debug('[Gemini] Error during abort:', error); - } finally { - abortController = new AbortController(); - } - } - - const handleKillSession = async () => { - logger.debug('[Gemini] Kill session requested - terminating process'); - await handleAbort(); - logger.debug('[Gemini] Abort completed, proceeding with termination'); + // Use geminiLoop for both local and remote modes + // Default to remote mode if no mode is specified + const startingMode = opts.startingMode || 'remote'; + logger.debug(`[Gemini] Starting in ${startingMode} mode with loop`); + const { geminiLoop } = await import('./loop'); + const { startHookServer } = await import('@/claude/utils/startHookServer'); + const { addGeminiHookToProject, removeGeminiHookFromProject } = await import('./utils/generateGeminiHookSettings'); - try { - if (session) { - session.updateMetadata((currentMetadata) => ({ - ...currentMetadata, - lifecycleState: 'archived', - lifecycleStateSince: Date.now(), - archivedBy: 'cli', - archiveReason: 'User terminated' - })); + // Start hook server for session tracking (needed for local mode) + const hookServer = await startHookServer({ + onSessionHook: (sessionId, data) => { + logger.debug(`[Gemini] SessionStart hook received: ${sessionId}`); + logger.debug(`[Gemini] Transcript path: ${data.transcript_path}`); - session.sendSessionDeath(); - await session.flush(); - await session.close(); - } - - stopCaffeinate(); - happyServer.stop(); - - if (geminiBackend) { - await geminiBackend.dispose(); - } - - logger.debug('[Gemini] Session termination complete, exiting'); - process.exit(0); - } catch (error) { - logger.debug('[Gemini] Error during session termination:', error); - process.exit(1); - } - }; - - session.rpcHandlerManager.registerHandler('abort', handleAbort); - registerKillSessionHandler(session.rpcHandlerManager, handleKillSession); - - // - // Initialize Ink UI - // - - const messageBuffer = new MessageBuffer(); - const hasTTY = process.stdout.isTTY && process.stdin.isTTY; - let inkInstance: ReturnType | null = null; - - // Track current model for UI display - // Initialize with env var or default to show correct model from start - let displayedModel: string | undefined = getInitialGeminiModel(); - - // Log initial values - const localConfig = readGeminiLocalConfig(); - logger.debug(`[gemini] Initial model setup: env[GEMINI_MODEL_ENV]=${process.env[GEMINI_MODEL_ENV] || 'not set'}, localConfig=${localConfig.model || 'not set'}, displayedModel=${displayedModel}`); - - // Function to update displayed model and notify UI - const updateDisplayedModel = (model: string | undefined, saveToConfig: boolean = false) => { - // Only update if model is actually provided (not undefined) - if (model === undefined) { - logger.debug(`[gemini] updateDisplayedModel called with undefined, skipping update`); - return; - } - - const oldModel = displayedModel; - displayedModel = model; - logger.debug(`[gemini] updateDisplayedModel called: oldModel=${oldModel}, newModel=${model}, saveToConfig=${saveToConfig}`); - - // Save to config file if requested (when user changes model via mobile app) - if (saveToConfig) { - saveGeminiModelToConfig(model); - } - - // Trigger UI update by adding a system message with model info - // The message will be parsed by UI to extract model name - if (hasTTY && oldModel !== model) { - // Add a system message that includes model info - UI will parse it - // Format: [MODEL:gemini-2.5-pro] to make it easy to extract - logger.debug(`[gemini] Adding model update message to buffer: [MODEL:${model}]`); - messageBuffer.addMessage(`[MODEL:${model}]`, 'system'); - } else if (hasTTY) { - logger.debug(`[gemini] Model unchanged, skipping update message`); - } - }; - - if (hasTTY) { - console.clear(); - // Create a React component that reads displayedModel from closure - // Model will update when UI re-renders (on messageBuffer updates) - // We use a function component that reads displayedModel on each render - const DisplayComponent = () => { - // Read displayedModel from closure - it will have latest value on each render - const currentModelValue = displayedModel || 'gemini-2.5-pro'; - // Don't log on every render to avoid spam - only log when model changes - return React.createElement(GeminiDisplay, { - messageBuffer, - logPath: process.env.DEBUG ? logger.getLogPath() : undefined, - currentModel: currentModelValue, - onExit: async () => { - logger.debug('[gemini]: Exiting agent via Ctrl-C'); - shouldExit = true; - await handleAbort(); + // Update session ID and transcript path in the GeminiSession instance + if (currentSession) { + const previousSessionId = currentSession.sessionId; + if (previousSessionId !== sessionId) { + logger.debug(`[Gemini] Session ID changed: ${previousSessionId} -> ${sessionId}`); + currentSession.onSessionFound(sessionId); } - }); - }; - - inkInstance = render(React.createElement(DisplayComponent), { - exitOnCtrlC: false, - patchConsole: false - }); - - // Send initial model to UI so it displays correctly from start - const initialModelName = displayedModel || 'gemini-2.5-pro'; - logger.debug(`[gemini] Sending initial model to UI: ${initialModelName}`); - messageBuffer.addMessage(`[MODEL:${initialModelName}]`, 'system'); - } - - if (hasTTY) { - process.stdin.resume(); - if (process.stdin.isTTY) { - process.stdin.setRawMode(true); - } - process.stdin.setEncoding('utf8'); - } - - // - // Start Happy MCP server and create Gemini backend - // - const happyServer = await startHappyServer(session); - const bridgeCommand = join(projectPath(), 'bin', 'happy-mcp.mjs'); - const mcpServers = { - happy: { - command: bridgeCommand, - args: ['--url', happyServer.url] - } - }; - - // Create permission handler for tool approval - const permissionHandler = new GeminiPermissionHandler(session); - - // Create reasoning processor for handling thinking/reasoning chunks - const reasoningProcessor = new GeminiReasoningProcessor((message) => { - // Callback to send messages directly from the processor - session.sendCodexMessage(message); - }); - - // Create diff processor for handling file edit events and diff tracking - const diffProcessor = new GeminiDiffProcessor((message) => { - // Callback to send messages directly from the processor - session.sendCodexMessage(message); - }); - - // Update permission handler when permission mode changes - const updatePermissionMode = (mode: PermissionMode) => { - permissionHandler.setPermissionMode(mode); - }; - - // Accumulate Gemini response text for sending complete message to mobile - let accumulatedResponse = ''; - let isResponseInProgress = false; - let currentResponseMessageId: string | null = null; // Track the message ID for current response - - /** - * Set up message handler for Gemini backend - * This function is called when backend is created or recreated - */ - function setupGeminiMessageHandler(backend: AgentBackend): void { - backend.onMessage((msg: AgentMessage) => { - - switch (msg.type) { - case 'model-output': - if (msg.textDelta) { - // If this is the first delta of a new response, create a new message - // Otherwise, update the existing message for this response - if (!isResponseInProgress) { - // Start of new response - create new assistant message - // Remove "Thinking..." message if it exists (it will be replaced by actual response) - messageBuffer.removeLastMessage('system'); // Remove "Thinking..." if present - messageBuffer.addMessage(msg.textDelta, 'assistant'); - isResponseInProgress = true; - logger.debug(`[gemini] Started new response, first chunk length: ${msg.textDelta.length}`); - } else { - // Continue existing response - update last assistant message - messageBuffer.updateLastMessage(msg.textDelta, 'assistant'); - logger.debug(`[gemini] Updated response, chunk length: ${msg.textDelta.length}, total accumulated: ${accumulatedResponse.length + msg.textDelta.length}`); - } - accumulatedResponse += msg.textDelta; - } - break; - - case 'status': - // Log status changes for debugging - logger.debug(`[gemini] Status changed: ${msg.status}${msg.detail ? ` - ${msg.detail}` : ''}`); - - // Log error status with details - if (msg.status === 'error') { - logger.debug(`[gemini] ⚠️ Error status received: ${msg.detail || 'Unknown error'}`); - - // Send turn_aborted event (like Codex) when error occurs - session.sendCodexMessage({ - type: 'turn_aborted', - id: randomUUID(), - }); - } - - if (msg.status === 'running') { - thinking = true; - session.keepAlive(thinking, 'remote'); - - // Send task_started event (like Codex) when agent starts working - session.sendCodexMessage({ - type: 'task_started', - id: randomUUID(), - }); - - // Show thinking indicator in UI when agent starts working (like Codex) - // This will be updated with actual thinking text when agent_thought_chunk events arrive - // Always show thinking indicator when status becomes 'running' to give user feedback - // Even if response is in progress, we want to show thinking for new operations - messageBuffer.addMessage('Thinking...', 'system'); - - // Don't reset accumulator here - tool calls can happen during a response - // Accumulator will be reset when a new prompt is sent (in the main loop) - } else if (msg.status === 'idle' || msg.status === 'stopped') { - if (thinking) { - // Clear thinking indicator when agent finishes - thinking = false; - // Remove thinking message from UI when agent finishes (like Codex) - // The thinking messages will be replaced by actual response - } - thinking = false; - session.keepAlive(thinking, 'remote'); - - // Complete reasoning processor when status becomes idle (like Codex) - // Only complete if there's actually reasoning content to complete - // Skip if this is just the initial idle status after session creation - const reasoningCompleted = reasoningProcessor.complete(); - - // Send task_complete event (like Codex) when agent finishes - // Only send if this is a real task completion (not initial idle) - if (reasoningCompleted || isResponseInProgress) { - session.sendCodexMessage({ - type: 'task_complete', - id: randomUUID(), - }); - } - - // Send accumulated response to mobile app when response is complete - // Status 'idle' indicates task completion (similar to Codex's task_complete) - if (isResponseInProgress && accumulatedResponse.trim()) { - // Parse options from response text (for logging/debugging) - // But keep options IN the text - mobile app's parseMarkdown will extract them - const { text: messageText, options } = parseOptionsFromText(accumulatedResponse); - - // Mobile app parses options from text via parseMarkdown, so we need to keep them in the message - // Re-add options XML block to the message text if options were found - let finalMessageText = messageText; - if (options.length > 0) { - const optionsXml = formatOptionsXml(options); - finalMessageText = messageText + optionsXml; - logger.debug(`[gemini] Found ${options.length} options in response:`, options); - logger.debug(`[gemini] Keeping options in message text for mobile app parsing`); - } else if (hasIncompleteOptions(accumulatedResponse)) { - // If we have incomplete options block, still send the message - // The mobile app will handle incomplete blocks gracefully - logger.debug(`[gemini] Warning: Incomplete options block detected but sending message anyway`); - } - - const messageId = randomUUID(); - - const messagePayload: CodexMessagePayload = { - type: 'message', - message: finalMessageText, // Include options XML in text for mobile app - id: messageId, - ...(options.length > 0 && { options }), - }; - - logger.debug(`[gemini] Sending complete message to mobile (length: ${finalMessageText.length}): ${finalMessageText.substring(0, 100)}...`); - logger.debug(`[gemini] Full message payload:`, JSON.stringify(messagePayload, null, 2)); - // Use sendCodexMessage - mobile app parses options from message text via parseMarkdown - session.sendCodexMessage(messagePayload); - accumulatedResponse = ''; - isResponseInProgress = false; - } - // Note: sendReady() is called via emitReadyIfIdle() in the finally block after prompt completes - // Don't call it here to avoid duplicates - } else if (msg.status === 'error') { - thinking = false; - session.keepAlive(thinking, 'remote'); - accumulatedResponse = ''; - isResponseInProgress = false; - currentResponseMessageId = null; - - // Show error in CLI UI - const errorMessage = msg.detail || 'Unknown error'; - messageBuffer.addMessage(`Error: ${errorMessage}`, 'status'); - - // Use sendCodexMessage for consistency with codex format - session.sendCodexMessage({ - type: 'message', - message: `Error: ${errorMessage}`, - id: randomUUID(), - }); - } - break; - - case 'tool-call': - // Show tool call in UI like Codex does - const toolArgs = msg.args ? JSON.stringify(msg.args).substring(0, 100) : ''; - const isInvestigationTool = msg.toolName === 'codebase_investigator' || - (typeof msg.toolName === 'string' && msg.toolName.includes('investigator')); - - logger.debug(`[gemini] 🔧 Tool call received: ${msg.toolName} (${msg.callId})${isInvestigationTool ? ' [INVESTIGATION]' : ''}`); - if (isInvestigationTool && msg.args && typeof msg.args === 'object' && 'objective' in msg.args) { - logger.debug(`[gemini] 🔍 Investigation objective: ${String(msg.args.objective).substring(0, 150)}...`); - } - - messageBuffer.addMessage(`Executing: ${msg.toolName}${toolArgs ? ` ${toolArgs}${toolArgs.length >= 100 ? '...' : ''}` : ''}`, 'tool'); - session.sendCodexMessage({ - type: 'tool-call', - name: msg.toolName, - callId: msg.callId, - input: msg.args, - id: randomUUID(), - }); - break; - - case 'tool-result': - // Show tool result in UI like Codex does - // Check if result contains error information - const isError = msg.result && typeof msg.result === 'object' && 'error' in msg.result; - const resultText = typeof msg.result === 'string' - ? msg.result.substring(0, 200) - : JSON.stringify(msg.result).substring(0, 200); - const truncatedResult = resultText + (typeof msg.result === 'string' && msg.result.length > 200 ? '...' : ''); - - const resultSize = typeof msg.result === 'string' - ? msg.result.length - : JSON.stringify(msg.result).length; - - logger.debug(`[gemini] ${isError ? '❌' : '✅'} Tool result received: ${msg.toolName} (${msg.callId}) - Size: ${resultSize} bytes${isError ? ' [ERROR]' : ''}`); - - // Process tool result through diff processor to check for diff information (like Codex) - if (!isError) { - diffProcessor.processToolResult(msg.toolName, msg.result, msg.callId); - } - - if (isError) { - const errorMsg = (msg.result as any).error || 'Tool call failed'; - logger.debug(`[gemini] ❌ Tool call error: ${errorMsg.substring(0, 300)}`); - messageBuffer.addMessage(`Error: ${errorMsg}`, 'status'); - } else { - // Log summary for large results (like investigation tools) - if (resultSize > 1000) { - logger.debug(`[gemini] ✅ Large tool result (${resultSize} bytes) - first 200 chars: ${truncatedResult}`); - } - messageBuffer.addMessage(`Result: ${truncatedResult}`, 'result'); + if (data.transcript_path) { + logger.debug(`[Gemini] Transcript path: ${data.transcript_path}`); + currentSession.onTranscriptPathFound(data.transcript_path); } - - session.sendCodexMessage({ - type: 'tool-call-result', - callId: msg.callId, - output: msg.result, - id: randomUUID(), - }); - break; - - case 'fs-edit': - messageBuffer.addMessage(`File edit: ${msg.description}`, 'tool'); - - // Process fs-edit through diff processor (like Codex) - // msg.diff is optional (diff?: string), so it can be undefined - diffProcessor.processFsEdit(msg.path || '', msg.description, msg.diff); - - session.sendCodexMessage({ - type: 'file-edit', - description: msg.description, - diff: msg.diff, - path: msg.path, - id: randomUUID(), - }); - break; - - default: - // Handle token-count and other potential message types - if ((msg as any).type === 'token-count') { - // Forward token count to mobile app (like Codex) - // Note: Gemini ACP may not provide token_count events directly, - // but we handle them if they come from the backend - session.sendCodexMessage({ - type: 'token_count', - ...(msg as any), - id: randomUUID(), - }); - } - break; - - case 'terminal-output': - messageBuffer.addMessage(msg.data, 'result'); - session.sendCodexMessage({ - type: 'terminal-output', - data: msg.data, - id: randomUUID(), - }); - break; - - case 'permission-request': - // Forward permission request to mobile app - session.sendCodexMessage({ - type: 'permission-request', - permissionId: msg.id, - reason: msg.reason, - payload: msg.payload, - id: randomUUID(), - }); - break; - - case 'exec-approval-request': - // Handle exec approval request (like Codex exec_approval_request) - // Convert to tool call for mobile app compatibility - const execApprovalMsg = msg as any; - const callId = execApprovalMsg.call_id || execApprovalMsg.callId || randomUUID(); - const { call_id, type, ...inputs } = execApprovalMsg; - - logger.debug(`[gemini] Exec approval request received: ${callId}`); - messageBuffer.addMessage(`Exec approval requested: ${callId}`, 'tool'); - - session.sendCodexMessage({ - type: 'tool-call', - name: 'GeminiBash', // Similar to Codex's CodexBash - callId: callId, - input: inputs, - id: randomUUID(), - }); - break; - - case 'patch-apply-begin': - // Handle patch operation begin (like Codex patch_apply_begin) - const patchBeginMsg = msg as any; - const patchCallId = patchBeginMsg.call_id || patchBeginMsg.callId || randomUUID(); - const { call_id: patchCallIdVar, type: patchType, auto_approved, changes } = patchBeginMsg; - - // Add UI feedback for patch operation - const changeCount = changes ? Object.keys(changes).length : 0; - const filesMsg = changeCount === 1 ? '1 file' : `${changeCount} files`; - messageBuffer.addMessage(`Modifying ${filesMsg}...`, 'tool'); - logger.debug(`[gemini] Patch apply begin: ${patchCallId}, files: ${changeCount}`); - - session.sendCodexMessage({ - type: 'tool-call', - name: 'GeminiPatch', // Similar to Codex's CodexPatch - callId: patchCallId, - input: { - auto_approved, - changes - }, - id: randomUUID(), - }); - break; - - case 'patch-apply-end': - // Handle patch operation end (like Codex patch_apply_end) - const patchEndMsg = msg as any; - const patchEndCallId = patchEndMsg.call_id || patchEndMsg.callId || randomUUID(); - const { call_id: patchEndCallIdVar, type: patchEndType, stdout, stderr, success } = patchEndMsg; - - // Add UI feedback for completion - if (success) { - const message = stdout || 'Files modified successfully'; - messageBuffer.addMessage(message.substring(0, 200), 'result'); - } else { - const errorMsg = stderr || 'Failed to modify files'; - messageBuffer.addMessage(`Error: ${errorMsg.substring(0, 200)}`, 'result'); - } - logger.debug(`[gemini] Patch apply end: ${patchEndCallId}, success: ${success}`); - - session.sendCodexMessage({ - type: 'tool-call-result', - callId: patchEndCallId, - output: { - stdout, - stderr, - success - }, - id: randomUUID(), - }); - break; - - case 'event': - // Handle thinking events - process through ReasoningProcessor like Codex - if (msg.name === 'thinking') { - const thinkingPayload = msg.payload as { text?: string } | undefined; - const thinkingText = (thinkingPayload && typeof thinkingPayload === 'object' && 'text' in thinkingPayload) - ? String(thinkingPayload.text || '') - : ''; - if (thinkingText) { - // Process thinking chunk through reasoning processor - // This will identify titled reasoning sections (**Title**) and convert them to tool calls - reasoningProcessor.processChunk(thinkingText); - - // Log thinking chunks (especially useful for investigation tools) - logger.debug(`[gemini] 💭 Thinking chunk received: ${thinkingText.length} chars - Preview: ${thinkingText.substring(0, 100)}...`); - - // Show thinking message in UI (truncated like Codex) - // For titled reasoning (starts with **), ReasoningProcessor will show it as tool call - // But we still show progress for long operations - if (!thinkingText.startsWith('**')) { - // Update existing "Thinking..." message or add new one for untitled reasoning - const thinkingPreview = thinkingText.substring(0, 100); - messageBuffer.updateLastMessage(`[Thinking] ${thinkingPreview}...`, 'system'); - } - // For titled reasoning, ReasoningProcessor will send tool call, but we keep "Thinking..." visible - // This ensures user sees progress during long reasoning operations - } - // Also forward to mobile for UI feedback - session.sendCodexMessage({ - type: 'thinking', - text: thinkingText, - id: randomUUID(), - }); - } - break; + } } - }); - } - - // Note: Backend will be created dynamically in the main loop based on model from first message - // This allows us to support model changes by recreating the backend - - let first = true; + }); try { - let currentModeHash: string | null = null; - let pending: { message: string; mode: GeminiMode; isolate: boolean; hash: string } | null = null; - - while (!shouldExit) { - let message: { message: string; mode: GeminiMode; isolate: boolean; hash: string } | null = pending; - pending = null; - - if (!message) { - logger.debug('[gemini] Main loop: waiting for messages from queue...'); - const waitSignal = abortController.signal; - const batch = await messageQueue.waitForMessagesAndGetAsString(waitSignal); - if (!batch) { - if (waitSignal.aborted && !shouldExit) { - logger.debug('[gemini] Main loop: wait aborted, continuing...'); - continue; - } - logger.debug('[gemini] Main loop: no batch received, breaking...'); - break; - } - logger.debug(`[gemini] Main loop: received message from queue (length: ${batch.message.length})`); - message = batch; - } - - if (!message) { - break; - } - - // Handle mode change (like Codex) - restart session if permission mode or model changed - if (wasSessionCreated && currentModeHash && message.hash !== currentModeHash) { - logger.debug('[Gemini] Mode changed – restarting Gemini session'); - messageBuffer.addMessage('═'.repeat(40), 'status'); - messageBuffer.addMessage('Starting new Gemini session (mode changed)...', 'status'); - - // Reset permission handler and reasoning processor on mode change (like Codex) - permissionHandler.reset(); - reasoningProcessor.abort(); - - // Dispose old backend and create new one with new model - if (geminiBackend) { - await geminiBackend.dispose(); - geminiBackend = null; - } - - // Create new backend with new model - const modelToUse = message.mode?.model === undefined ? undefined : (message.mode.model || null); - geminiBackend = createGeminiBackend({ - cwd: process.cwd(), - mcpServers, - permissionHandler, - cloudToken, - // Pass model from message - if undefined, will use local config/env/default - // If explicitly null, will skip local config and use env/default - model: modelToUse, - }); - - // Set up message handler again - setupGeminiMessageHandler(geminiBackend); - - // Start new session - // Determine actual model that will be used (from backend creation logic) - // Replicate backend logic: message model > env var > local config > default - const localConfigForModel = readGeminiLocalConfig(); - const actualModel = determineGeminiModel(modelToUse, localConfigForModel); - logger.debug(`[gemini] Model change - modelToUse=${modelToUse}, actualModel=${actualModel}`); - - logger.debug('[gemini] Starting new ACP session with model:', actualModel); - const { sessionId } = await geminiBackend.startSession(); - acpSessionId = sessionId; - logger.debug(`[gemini] New ACP session started: ${acpSessionId}`); - - // Update displayed model in UI (don't save to config - this is backend initialization) - logger.debug(`[gemini] Calling updateDisplayedModel with: ${actualModel}`); - updateDisplayedModel(actualModel, false); - // Don't add "Using model" message - model is shown in status bar - - // Update permission handler with current permission mode - updatePermissionMode(message.mode.permissionMode); - - wasSessionCreated = true; - currentModeHash = message.hash; - first = false; // Not first message anymore - } - - currentModeHash = message.hash; - // Show only original user message in UI, not the full prompt with system prompt - const userMessageToShow = message.mode?.originalUserMessage || message.message; - messageBuffer.addMessage(userMessageToShow, 'user'); - - try { - if (first || !wasSessionCreated) { - // First message or session not created yet - create backend and start session - if (!geminiBackend) { - const modelToUse = message.mode?.model === undefined ? undefined : (message.mode.model || null); - geminiBackend = createGeminiBackend({ - cwd: process.cwd(), - mcpServers, - permissionHandler, - cloudToken, - // Pass model from message - if undefined, will use local config/env/default - // If explicitly null, will skip local config and use env/default - model: modelToUse, - }); - - // Set up message handler - setupGeminiMessageHandler(geminiBackend); - - // Determine actual model that will be used - // Backend will determine model from: message model > env var > local config > default - // We need to replicate this logic here to show correct model in UI - const localConfigForModel = readGeminiLocalConfig(); - const actualModel = determineGeminiModel(modelToUse, localConfigForModel); - - const modelSource = modelToUse !== undefined - ? 'message' - : process.env[GEMINI_MODEL_ENV] - ? 'env-var' - : localConfigForModel.model - ? 'local-config' - : 'default'; - - logger.debug(`[gemini] Backend created, model will be: ${actualModel} (from ${modelSource})`); - logger.debug(`[gemini] Calling updateDisplayedModel with: ${actualModel}`); - updateDisplayedModel(actualModel, false); // Don't save - this is backend initialization - } - - // Start session if not started - if (!acpSessionId) { - logger.debug('[gemini] Starting ACP session...'); - // Update permission handler with current permission mode before starting session - updatePermissionMode(message.mode.permissionMode); - const { sessionId } = await geminiBackend.startSession(); - acpSessionId = sessionId; - logger.debug(`[gemini] ACP session started: ${acpSessionId}`); - wasSessionCreated = true; - currentModeHash = message.hash; - - // Model info is already shown in status bar via updateDisplayedModel - logger.debug(`[gemini] Displaying model in UI: ${displayedModel || 'gemini-2.5-pro'}, displayedModel: ${displayedModel}`); - } - } - - if (!acpSessionId) { - throw new Error('ACP session not started'); - } - - // Reset accumulator when sending a new prompt (not when tool calls start) - // Reset accumulated response for new prompt - // This ensures a new assistant message will be created (not updating previous one) - accumulatedResponse = ''; - isResponseInProgress = false; - - if (!geminiBackend || !acpSessionId) { - throw new Error('Gemini backend or session not initialized'); - } - - // The prompt already includes system prompt and change_title instruction (added in onUserMessage handler) - // This is done in the message queue, so message.message already contains everything - const promptToSend = message.message; - - logger.debug(`[gemini] Sending prompt to Gemini (length: ${promptToSend.length}): ${promptToSend.substring(0, 100)}...`); - logger.debug(`[gemini] Full prompt: ${promptToSend}`); - await geminiBackend.sendPrompt(acpSessionId, promptToSend); - logger.debug('[gemini] Prompt sent successfully'); - - // Mark as not first message after sending prompt - if (first) { - first = false; - } - } catch (error) { - logger.debug('[gemini] Error in gemini session:', error); - const isAbortError = error instanceof Error && error.name === 'AbortError'; - - if (isAbortError) { - messageBuffer.addMessage('Aborted by user', 'status'); - session.sendSessionEvent({ type: 'message', message: 'Aborted by user' }); - } else { - // Parse error message - let errorMsg = 'Process error occurred'; - - if (typeof error === 'object' && error !== null) { - const errObj = error as any; - - // Extract error information from various possible formats - const errorDetails = errObj.data?.details || errObj.details || ''; - const errorCode = errObj.code || errObj.status || (errObj.response?.status); - const errorMessage = errObj.message || errObj.error?.message || ''; - const errorString = String(error); - - // Check for 404 error (model not found) - if (errorCode === 404 || errorDetails.includes('notFound') || errorDetails.includes('404') || - errorMessage.includes('not found') || errorMessage.includes('404')) { - const currentModel = displayedModel || 'gemini-2.5-pro'; - errorMsg = `Model "${currentModel}" not found. Available models: gemini-2.5-pro, gemini-2.5-flash, gemini-2.5-flash-lite`; - } - // Check for rate limit error (429) - multiple possible formats - else if (errorCode === 429 || - errorDetails.includes('429') || errorMessage.includes('429') || errorString.includes('429') || - errorDetails.includes('rateLimitExceeded') || errorDetails.includes('RESOURCE_EXHAUSTED') || - errorMessage.includes('Rate limit exceeded') || errorMessage.includes('Resource exhausted') || - errorString.includes('rateLimitExceeded') || errorString.includes('RESOURCE_EXHAUSTED')) { - errorMsg = 'Gemini API rate limit exceeded. Please wait a moment and try again. The API will retry automatically.'; - } - // Check for quota exceeded error - else if (errorDetails.includes('quota') || errorMessage.includes('quota') || errorString.includes('quota')) { - errorMsg = 'Gemini API daily quota exceeded. Please wait until quota resets or use a paid API key.'; - } - // Check for empty error (command not found) - else if (Object.keys(error).length === 0) { - errorMsg = 'Failed to start Gemini. Is "gemini" CLI installed? Run: npm install -g @google/gemini-cli'; - } - // Use message from error object - else if (errObj.message || errorMessage) { - errorMsg = errorDetails || errorMessage || errObj.message; - } - } else if (error instanceof Error) { - errorMsg = error.message; - } - - messageBuffer.addMessage(errorMsg, 'status'); - // Use sendCodexMessage for consistency with codex format - session.sendCodexMessage({ - type: 'message', - message: errorMsg, - id: randomUUID(), - }); - } - } finally { - // Reset permission handler, reasoning processor, and diff processor after turn (like Codex) - permissionHandler.reset(); - reasoningProcessor.abort(); // Use abort to properly finish any in-progress tool calls - diffProcessor.reset(); // Reset diff processor on turn completion - - thinking = false; - session.keepAlive(thinking, 'remote'); - - // Use same logic as Codex - emit ready if idle (no pending operations, no queue) - emitReadyIfIdle(); - - logger.debug(`[gemini] Main loop: turn completed, continuing to next iteration (queue size: ${messageQueue.size()})`); + // Add hook to project settings (for local mode) + addGeminiHookToProject(hookServer.port, metadata.path); + + // Run the loop + await geminiLoop({ + path: metadata.path, + model: undefined, // TODO: get from initial config + approvalMode: 'default', // TODO: map permission mode + startingMode: startingMode, + onModeChange: (mode) => { + logger.debug(`[Gemini] Mode changed to: ${mode}`); + }, + session, + api, + messageQueue, + cloudToken, + allowedTools: undefined, // TODO: get from config + onSessionReady: (sessionInstance) => { + // Store reference for hook server callback + currentSession = sessionInstance; } - } - + }); } finally { - // Clean up resources - logger.debug('[gemini]: Final cleanup start'); - try { - session.sendSessionDeath(); - await session.flush(); - await session.close(); - } catch (e) { - logger.debug('[gemini]: Error while closing session', e); - } - - if (geminiBackend) { - await geminiBackend.dispose(); - } - - happyServer.stop(); - - if (process.stdin.isTTY) { - try { process.stdin.setRawMode(false); } catch { /* ignore */ } - } - if (hasTTY) { - try { process.stdin.pause(); } catch { /* ignore */ } - } - - clearInterval(keepAliveInterval); - if (inkInstance) { - inkInstance.unmount(); - } - messageBuffer.clear(); - - logger.debug('[gemini]: Final cleanup completed'); + // Cleanup hook + removeGeminiHookFromProject(metadata.path); + hookServer.stop(); } } - diff --git a/src/gemini/session.ts b/src/gemini/session.ts new file mode 100644 index 00000000..c5b929b3 --- /dev/null +++ b/src/gemini/session.ts @@ -0,0 +1,117 @@ +/** + * Gemini Session Management + * + * Manages session state for Gemini local/remote modes, + * similar to Claude's Session class. + */ + +import { ApiSessionClient } from '@/api/apiSession'; +import { MessageQueue2 } from '@/utils/MessageQueue2'; +import { logger } from '@/ui/logger'; +import type { GeminiMode } from './types'; + +export class GeminiSession { + public sessionId: string | null; + public transcriptPath: string | null = null; + public readonly client: ApiSessionClient; + public readonly path: string; + public readonly logPath: string; + public readonly queue: MessageQueue2; + public readonly onThinkingChange?: (thinking: boolean) => void; + + // Session found callbacks + private sessionFoundCallbacks: Array<(sessionId: string) => void> = []; + + // Transcript path callbacks + private transcriptPathCallbacks: Array<(path: string) => void> = []; + + constructor(opts: { + client: ApiSessionClient; + path: string; + sessionId: string | null; + logPath: string; + queue: MessageQueue2; + onThinkingChange?: (thinking: boolean) => void; + }) { + this.client = opts.client; + this.path = opts.path; + this.sessionId = opts.sessionId; + this.logPath = opts.logPath; + this.queue = opts.queue; + this.onThinkingChange = opts.onThinkingChange; + } + + /** + * Called when a session ID is discovered (from SessionStart hook) + */ + onSessionFound(sessionId: string): void { + logger.debug(`[GeminiSession] Session found: ${sessionId}`); + + if (this.sessionId !== sessionId) { + this.sessionId = sessionId; + + // Notify all callbacks + for (const callback of this.sessionFoundCallbacks) { + try { + callback(sessionId); + } catch (error) { + logger.debug('[GeminiSession] Session found callback error:', error); + } + } + } + } + + /** + * Called when transcript path is discovered (from SessionStart hook) + */ + onTranscriptPathFound(transcriptPath: string): void { + logger.debug(`[GeminiSession] Transcript path found: ${transcriptPath}`); + + if (this.transcriptPath !== transcriptPath) { + this.transcriptPath = transcriptPath; + + // Notify all callbacks + for (const callback of this.transcriptPathCallbacks) { + try { + callback(transcriptPath); + } catch (error) { + logger.debug('[GeminiSession] Transcript path callback error:', error); + } + } + } + } + + /** + * Register a callback for when session ID is found + */ + addSessionFoundCallback(callback: (sessionId: string) => void): void { + this.sessionFoundCallbacks.push(callback); + } + + /** + * Remove a session found callback + */ + removeSessionFoundCallback(callback: (sessionId: string) => void): void { + const index = this.sessionFoundCallbacks.indexOf(callback); + if (index !== -1) { + this.sessionFoundCallbacks.splice(index, 1); + } + } + + /** + * Register a callback for when transcript path is found + */ + addTranscriptPathCallback(callback: (path: string) => void): void { + this.transcriptPathCallbacks.push(callback); + } + + /** + * Remove a transcript path callback + */ + removeTranscriptPathCallback(callback: (path: string) => void): void { + const index = this.transcriptPathCallbacks.indexOf(callback); + if (index !== -1) { + this.transcriptPathCallbacks.splice(index, 1); + } + } +} diff --git a/src/gemini/utils/generateGeminiHookSettings.ts b/src/gemini/utils/generateGeminiHookSettings.ts new file mode 100644 index 00000000..1778fc79 --- /dev/null +++ b/src/gemini/utils/generateGeminiHookSettings.ts @@ -0,0 +1,133 @@ +/** + * Generate Gemini hook settings for session tracking + * + * Unlike Claude which uses a temporary settings file passed via --settings flag, + * Gemini reads settings from .gemini/settings.json in the project directory. + * + * This module manages adding/removing the SessionStart hook to that file. + */ + +import { join } from 'node:path'; +import { writeFileSync, mkdirSync, existsSync, readFileSync } from 'node:fs'; +import { logger } from '@/ui/logger'; +import { projectPath } from '@/projectPath'; +import { resolve } from 'node:path'; + +/** + * Add SessionStart hook to project's .gemini/settings.json + * + * @param port - The port where Happy's hook server is listening + * @param projectDir - The project directory (cwd) + * @returns Path to the settings file + */ +export function addGeminiHookToProject(port: number, projectDir: string): string { + const geminiDir = join(projectDir, '.gemini'); + const settingsPath = join(geminiDir, 'settings.json'); + + // Ensure .gemini directory exists + mkdirSync(geminiDir, { recursive: true }); + + // Path to the hook forwarder script (reuse Claude's!) + const forwarderScript = resolve(projectPath(), 'scripts', 'session_hook_forwarder.cjs'); + const hookCommand = `node "${forwarderScript}" ${port}`; + + // Read existing settings or create new + let settings: any = {}; + if (existsSync(settingsPath)) { + try { + const content = readFileSync(settingsPath, 'utf-8'); + settings = JSON.parse(content); + logger.debug(`[generateGeminiHookSettings] Read existing settings from ${settingsPath}`); + } catch (error) { + logger.debug(`[generateGeminiHookSettings] Failed to parse existing settings, starting fresh:`, error); + settings = {}; + } + } + + // Preserve existing hooks, add our SessionStart hook + if (!settings.hooks) { + settings.hooks = {}; + } + + // Add SessionStart hook (will replace if exists) + // Match on "startup" and "resume" events + settings.hooks.SessionStart = [ + { + matcher: "startup|resume", + hooks: [ + { + name: "happy-session-tracker", + type: "command", + command: hookCommand, + description: "Happy CLI session tracking hook", + timeout: 5000 + } + ] + } + ]; + + // Write back to file + writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf-8'); + logger.debug(`[generateGeminiHookSettings] Wrote hook settings to ${settingsPath}`); + + return settingsPath; +} + +/** + * Remove Happy's SessionStart hook from project's .gemini/settings.json + * + * @param projectDir - The project directory (cwd) + */ +export function removeGeminiHookFromProject(projectDir: string): void { + const geminiDir = join(projectDir, '.gemini'); + const settingsPath = join(geminiDir, 'settings.json'); + + if (!existsSync(settingsPath)) { + logger.debug(`[generateGeminiHookSettings] No settings file to clean up`); + return; + } + + try { + const content = readFileSync(settingsPath, 'utf-8'); + const settings = JSON.parse(content); + + if (settings.hooks && settings.hooks.SessionStart) { + // Filter out our hook (by name) + const filtered = settings.hooks.SessionStart.map((matcher: any) => { + if (matcher.hooks) { + matcher.hooks = matcher.hooks.filter((hook: any) => + hook.name !== 'happy-session-tracker' + ); + } + return matcher; + }).filter((matcher: any) => matcher.hooks && matcher.hooks.length > 0); + + if (filtered.length > 0) { + settings.hooks.SessionStart = filtered; + } else { + delete settings.hooks.SessionStart; + } + + // If no hooks left, remove hooks object + if (Object.keys(settings.hooks).length === 0) { + delete settings.hooks; + } + + writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf-8'); + logger.debug(`[generateGeminiHookSettings] Removed hook from ${settingsPath}`); + } + } catch (error) { + logger.debug(`[generateGeminiHookSettings] Failed to cleanup hook:`, error); + } +} + +/** + * Get the path to Gemini's project directory + * + * Gemini uses a hash of the project path for organization, + * but we don't need to compute that - we just write hooks to + * the project's .gemini/ directory and Gemini will find it. + */ +export function getGeminiProjectDir(projectPath: string): string { + return projectPath; +} diff --git a/src/gemini/utils/path.ts b/src/gemini/utils/path.ts new file mode 100644 index 00000000..027ba8f0 --- /dev/null +++ b/src/gemini/utils/path.ts @@ -0,0 +1,37 @@ +/** + * Gemini path utilities + * + * Helper functions for Gemini-specific file paths + */ + +import { join } from 'node:path'; +import { homedir } from 'node:os'; + +/** + * Get the Gemini config directory for a project + * + * @param projectPath - The project working directory + * @returns Path to .gemini directory + */ +export function getGeminiProjectConfigDir(projectPath: string): string { + return join(projectPath, '.gemini'); +} + +/** + * Get the Gemini global config directory + * + * @returns Path to ~/.gemini + */ +export function getGeminiGlobalConfigDir(): string { + return join(homedir(), '.gemini'); +} + +/** + * Get the Gemini settings file path for a project + * + * @param projectPath - The project working directory + * @returns Path to .gemini/settings.json + */ +export function getGeminiSettingsPath(projectPath: string): string { + return join(getGeminiProjectConfigDir(projectPath), 'settings.json'); +} diff --git a/src/gemini/utils/sessionScanner.ts b/src/gemini/utils/sessionScanner.ts new file mode 100644 index 00000000..1f00b305 --- /dev/null +++ b/src/gemini/utils/sessionScanner.ts @@ -0,0 +1,171 @@ +/** + * Gemini Session Scanner + * + * Watches Gemini's transcript JSONL file for new messages and forwards them + * to Happy's session sync system. + * + * Similar to Claude's session scanner but adapted for Gemini's transcript format. + */ + +import { watch, FSWatcher } from 'node:fs'; +import { readFile } from 'node:fs/promises'; +import { existsSync } from 'node:fs'; +import { logger } from '@/ui/logger'; + +/** + * Message from Gemini's transcript + * This is a simplified interface - adjust based on actual Gemini format + */ +export interface GeminiTranscriptMessage { + sessionId?: string; + messageId?: number; + type?: string; + message?: string; + timestamp?: string; + [key: string]: any; +} + +export interface GeminiSessionScanner { + cleanup: () => void; + onNewSession: (transcriptPath: string) => void; +} + +/** + * Create a scanner that watches Gemini's transcript JSONL file + * + * @param opts.transcriptPath - Path to the JSONL transcript file from SessionStart hook + * @param opts.onMessage - Callback when a new message is detected + */ +export async function createGeminiSessionScanner(opts: { + transcriptPath: string | null; + onMessage: (message: GeminiTranscriptMessage) => void; +}): Promise { + let currentTranscriptPath: string | null = opts.transcriptPath; + let watcher: FSWatcher | null = null; + let processedLines = new Set(); + let lastFileSize = 0; + + /** + * Read and process new lines from the transcript file + */ + async function processTranscript() { + if (!currentTranscriptPath) { + return; + } + + if (!existsSync(currentTranscriptPath)) { + logger.debug(`[GeminiScanner] Transcript file doesn't exist yet: ${currentTranscriptPath}`); + return; + } + + try { + const content = await readFile(currentTranscriptPath, 'utf-8'); + const currentSize = content.length; + + // Only process if file has grown + if (currentSize <= lastFileSize) { + return; + } + + lastFileSize = currentSize; + + const lines = content.split('\n'); + let newMessages = 0; + + for (const line of lines) { + const trimmed = line.trim(); + if (!trimmed || processedLines.has(trimmed)) { + continue; + } + + try { + const message: GeminiTranscriptMessage = JSON.parse(trimmed); + processedLines.add(trimmed); + opts.onMessage(message); + newMessages++; + logger.debug(`[GeminiScanner] New message: type=${message.type}, messageId=${message.messageId}`); + } catch (parseError) { + logger.debug(`[GeminiScanner] Failed to parse line as JSON:`, parseError); + // Skip invalid JSON lines + } + } + + if (newMessages > 0) { + logger.debug(`[GeminiScanner] Processed ${newMessages} new messages`); + } + } catch (error) { + logger.debug(`[GeminiScanner] Error reading transcript:`, error); + } + } + + /** + * Start watching the transcript file + */ + function startWatching() { + if (!currentTranscriptPath) { + logger.debug(`[GeminiScanner] No transcript path, skipping watch`); + return; + } + + // Stop existing watcher if any + if (watcher) { + watcher.close(); + watcher = null; + } + + logger.debug(`[GeminiScanner] Starting watch on: ${currentTranscriptPath}`); + + // Initial scan + processTranscript().catch((error) => { + logger.debug(`[GeminiScanner] Initial scan error:`, error); + }); + + // Watch for changes + try { + watcher = watch(currentTranscriptPath, { persistent: false }, (eventType) => { + if (eventType === 'change') { + processTranscript().catch((error) => { + logger.debug(`[GeminiScanner] Watch callback error:`, error); + }); + } + }); + + watcher.on('error', (error) => { + logger.debug(`[GeminiScanner] Watcher error:`, error); + }); + } catch (error) { + logger.debug(`[GeminiScanner] Failed to start watch:`, error); + } + } + + // Start watching if we have a path + if (currentTranscriptPath) { + startWatching(); + } + + return { + /** + * Update to a new transcript path (when session changes) + */ + onNewSession: (newTranscriptPath: string) => { + logger.debug(`[GeminiScanner] Switching to new transcript: ${newTranscriptPath}`); + currentTranscriptPath = newTranscriptPath; + processedLines.clear(); + lastFileSize = 0; + startWatching(); + }, + + /** + * Stop watching and cleanup + */ + cleanup: () => { + logger.debug(`[GeminiScanner] Cleanup`); + if (watcher) { + watcher.close(); + watcher = null; + } + processedLines.clear(); + lastFileSize = 0; + } + }; +} diff --git a/src/index.ts b/src/index.ts index 94c01c0f..b3ea2493 100644 --- a/src/index.ts +++ b/src/index.ts @@ -202,16 +202,45 @@ import { execFileSync } from 'node:child_process' // Handle gemini command (ACP-based agent) try { + // Check for special flags that should bypass our infrastructure + const specialFlags = ['--help', '--version', '-h', '-v']; + const hasSpecialFlag = args.slice(1).some(arg => specialFlags.includes(arg)); + + if (hasSpecialFlag) { + // Just spawn gemini directly and exit + const { spawn } = await import('child_process'); + try { + const child = spawn('gemini', args.slice(1), { stdio: 'inherit' }); + await new Promise((resolve, reject) => { + child.on('close', () => resolve()); + child.on('error', (err) => reject(err)); + }); + } catch (error: any) { + if (error.code === 'ENOENT') { + console.error(chalk.red('Error: Gemini CLI not found. Please install it with: npm install -g @google/gemini-cli')); + process.exit(1); + } + throw error; + } + return; + } + const { runGemini } = await import('@/gemini/runGemini'); - - // Parse startedBy argument + + // Parse startedBy and startingMode arguments let startedBy: 'daemon' | 'terminal' | undefined = undefined; + let startingMode: 'local' | 'remote' | undefined = undefined; + for (let i = 1; i < args.length; i++) { if (args[i] === '--started-by') { startedBy = args[++i] as 'daemon' | 'terminal'; + } else if (args[i] === '--local') { + startingMode = 'local'; + } else if (args[i] === '--remote') { + startingMode = 'remote'; } } - + const { credentials } = await authAndSetupMachineIfNeeded(); @@ -229,7 +258,7 @@ import { execFileSync } from 'node:child_process' await new Promise(resolve => setTimeout(resolve, 200)); } - await runGemini({credentials, startedBy}); + await runGemini({credentials, startedBy, startingMode}); } catch (error) { console.error(chalk.red('Error:'), error instanceof Error ? error.message : 'Unknown error') if (process.env.DEBUG) { diff --git a/src/ui/ink/GeminiDisplay.tsx b/src/ui/ink/GeminiDisplay.tsx index cd8e65f5..2e9fda81 100644 --- a/src/ui/ink/GeminiDisplay.tsx +++ b/src/ui/ink/GeminiDisplay.tsx @@ -14,12 +14,13 @@ interface GeminiDisplayProps { logPath?: string; currentModel?: string; onExit?: () => void; + onSwitchToLocal?: () => void; } -export const GeminiDisplay: React.FC = ({ messageBuffer, logPath, currentModel, onExit }) => { +export const GeminiDisplay: React.FC = ({ messageBuffer, logPath, currentModel, onExit, onSwitchToLocal }) => { const [messages, setMessages] = useState([]); - const [confirmationMode, setConfirmationMode] = useState(false); - const [actionInProgress, setActionInProgress] = useState(false); + const [confirmationMode, setConfirmationMode] = useState<'exit' | 'switch' | null>(null); + const [actionInProgress, setActionInProgress] = useState<'exiting' | 'switching' | null>(null); const [model, setModel] = useState(currentModel); const confirmationTimeoutRef = useRef(null); const { stdout } = useStdout(); @@ -68,15 +69,15 @@ export const GeminiDisplay: React.FC = ({ messageBuffer, log }, [messageBuffer]); const resetConfirmation = useCallback(() => { - setConfirmationMode(false); + setConfirmationMode(null); if (confirmationTimeoutRef.current) { clearTimeout(confirmationTimeoutRef.current); confirmationTimeoutRef.current = null; } }, []); - const setConfirmationWithTimeout = useCallback(() => { - setConfirmationMode(true); + const setConfirmationWithTimeout = useCallback((mode: 'exit' | 'switch') => { + setConfirmationMode(mode); if (confirmationTimeoutRef.current) { clearTimeout(confirmationTimeoutRef.current); } @@ -86,19 +87,45 @@ export const GeminiDisplay: React.FC = ({ messageBuffer, log }, [resetConfirmation]); useInput(useCallback(async (input, key) => { - if (actionInProgress) return; + // Debug: Log every key press to verify useInput is working + console.error(`[GeminiDisplay] useInput fired: input="${input}", key=${JSON.stringify(key)}, confirmationMode=${confirmationMode}, actionInProgress=${actionInProgress}`); + + if (actionInProgress) { + console.error(`[GeminiDisplay] Ignoring input - action already in progress: ${actionInProgress}`); + return; + } // Handle Ctrl-C if (key.ctrl && input === 'c') { - if (confirmationMode) { + if (confirmationMode === 'exit') { // Second Ctrl-C, exit resetConfirmation(); - setActionInProgress(true); + setActionInProgress('exiting'); await new Promise(resolve => setTimeout(resolve, 100)); - onExit?.(); + try { + await onExit?.(); + console.error(`[GeminiDisplay] onExit callback completed successfully`); + } catch (error) { + console.error(`[GeminiDisplay] onExit callback threw error:`, error); + } } else { // First Ctrl-C, show confirmation - setConfirmationWithTimeout(); + setConfirmationWithTimeout('exit'); + } + return; + } + + // Handle double space for mode switching + if (input === ' ') { + if (confirmationMode === 'switch') { + // Second space, switch to local + resetConfirmation(); + setActionInProgress('switching'); + await new Promise(resolve => setTimeout(resolve, 100)); + onSwitchToLocal?.(); + } else { + // First space, show confirmation + setConfirmationWithTimeout('switch'); } return; } @@ -107,7 +134,7 @@ export const GeminiDisplay: React.FC = ({ messageBuffer, log if (confirmationMode) { resetConfirmation(); } - }, [confirmationMode, actionInProgress, onExit, setConfirmationWithTimeout, resetConfirmation])); + }, [confirmationMode, actionInProgress, onExit, onSwitchToLocal, setConfirmationWithTimeout, resetConfirmation])); const getMessageColor = (type: BufferedMessage['type']): string => { switch (type) { @@ -147,7 +174,7 @@ export const GeminiDisplay: React.FC = ({ messageBuffer, log overflow="hidden" > - ✨ Gemini Agent Messages + 📡 Remote Mode - Gemini Messages {'─'.repeat(Math.min(terminalWidth - 4, 60))} @@ -200,18 +227,26 @@ export const GeminiDisplay: React.FC = ({ messageBuffer, log flexDirection="column" > - {actionInProgress ? ( + {actionInProgress === 'exiting' ? ( Exiting agent... - ) : confirmationMode ? ( + ) : actionInProgress === 'switching' ? ( + + Switching to local mode... + + ) : confirmationMode === 'exit' ? ( ⚠️ Press Ctrl-C again to exit the agent + ) : confirmationMode === 'switch' ? ( + + ⏸️ Press space again to switch to local mode + ) : ( <> - ✨ Gemini Agent Running • Ctrl-C to exit + 📱 Press space to switch to local mode • Ctrl-C to exit {model && ( diff --git a/yarn.lock b/yarn.lock index 8491498f..dbfccaad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4,12 +4,12 @@ "@agentclientprotocol/sdk@^0.8.0": version "0.8.0" - resolved "https://registry.yarnpkg.com/@agentclientprotocol/sdk/-/sdk-0.8.0.tgz#79d39716461dc5ac544680ecaa695cb1b338849a" + resolved "https://registry.npmjs.org/@agentclientprotocol/sdk/-/sdk-0.8.0.tgz" integrity sha512-RnYsrYqrGFNpPc/cgHgMPHjgn52F1tw5PWyr7UucQ2V1O72JWy3fCCkUgbbRgn7wbNVFsrEZMuBS186Mxgkhfg== "@ai-sdk/gateway@2.0.18": version "2.0.18" - resolved "https://registry.yarnpkg.com/@ai-sdk/gateway/-/gateway-2.0.18.tgz#7e81bdedddb7363af2c38d2cf7f34ac2d5e5eaa7" + resolved "https://registry.npmjs.org/@ai-sdk/gateway/-/gateway-2.0.18.tgz" integrity sha512-sDQcW+6ck2m0pTIHW6BPHD7S125WD3qNkx/B8sEzJp/hurocmJ5Cni0ybExg6sQMGo+fr/GWOwpHF1cmCdg5rQ== dependencies: "@ai-sdk/provider" "2.0.0" @@ -18,7 +18,7 @@ "@ai-sdk/provider-utils@3.0.18": version "3.0.18" - resolved "https://registry.yarnpkg.com/@ai-sdk/provider-utils/-/provider-utils-3.0.18.tgz#fc7757ad7eb48a48ce1976da3025f0b9215b1aff" + resolved "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-3.0.18.tgz" integrity sha512-ypv1xXMsgGcNKUP+hglKqtdDuMg68nWHucPPAhIENrbFAI+xCHiqPVN8Zllxyv1TNZwGWUghPxJXU+Mqps0YRQ== dependencies: "@ai-sdk/provider" "2.0.0" @@ -27,7 +27,7 @@ "@ai-sdk/provider@2.0.0": version "2.0.0" - resolved "https://registry.yarnpkg.com/@ai-sdk/provider/-/provider-2.0.0.tgz#b853c739d523b33675bc74b6c506b2c690bc602b" + resolved "https://registry.npmjs.org/@ai-sdk/provider/-/provider-2.0.0.tgz" integrity sha512-6o7Y2SeO9vFKB8lArHXehNuusnpddKPk7xqL7T2/b+OvXMRIXUO1rR4wcv1hAFUAT9avGZshty3Wlua/XA7TvA== dependencies: json-schema "^0.4.0" @@ -52,266 +52,16 @@ resolved "https://registry.npmjs.org/@epic-web/invariant/-/invariant-1.0.0.tgz" integrity sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA== -"@esbuild/aix-ppc64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz#bef96351f16520055c947aba28802eede3c9e9a9" - integrity sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA== - -"@esbuild/aix-ppc64@0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.26.0.tgz#e1d4bed341913e20caf2c2cb3a77b9662a8e40f1" - integrity sha512-hj0sKNCQOOo2fgyII3clmJXP28VhgDfU5iy3GNHlWO76KG6N7x4D9ezH5lJtQTG+1J6MFDAJXC1qsI+W+LvZoA== - -"@esbuild/android-arm64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz#d2e70be7d51a529425422091e0dcb90374c1546c" - integrity sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg== - -"@esbuild/android-arm64@0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.26.0.tgz#0a871d1332467be244101f757213a4dfc32ee93c" - integrity sha512-DDnoJ5eoa13L8zPh87PUlRd/IyFaIKOlRbxiwcSbeumcJ7UZKdtuMCHa1Q27LWQggug6W4m28i4/O2qiQQ5NZQ== - -"@esbuild/android-arm@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.9.tgz#d2a753fe2a4c73b79437d0ba1480e2d760097419" - integrity sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ== - -"@esbuild/android-arm@0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.26.0.tgz#6615de6d8fe792f8abd752cf0118305a171e15cd" - integrity sha512-C0hkDsYNHZkBtPxxDx177JN90/1MiCpvBNjz1f5yWJo1+5+c5zr8apjastpEG+wtPjo9FFtGG7owSsAxyKiHxA== - -"@esbuild/android-x64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.9.tgz#5278836e3c7ae75761626962f902a0d55352e683" - integrity sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw== - -"@esbuild/android-x64@0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.26.0.tgz#c9e69f9389893392aed36824677c2594ae2445e2" - integrity sha512-bKDkGXGZnj0T70cRpgmv549x38Vr2O3UWLbjT2qmIkdIWcmlg8yebcFWoT9Dku7b5OV3UqPEuNKRzlNhjwUJ9A== - -"@esbuild/darwin-arm64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz#f1513eaf9ec8fa15dcaf4c341b0f005d3e8b47ae" - integrity sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg== - -"@esbuild/darwin-arm64@0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.26.0.tgz#62e27842256044d4a0d6ba810f407890c746ce6e" - integrity sha512-6Z3naJgOuAIB0RLlJkYc81An3rTlQ/IeRdrU3dOea8h/PvZSgitZV+thNuIccw0MuK1GmIAnAmd5TrMZad8FTQ== - -"@esbuild/darwin-x64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz#e27dbc3b507b3a1cea3b9280a04b8b6b725f82be" - integrity sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ== - -"@esbuild/darwin-x64@0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.26.0.tgz#ea6d99e8c706318ce0171e85eb61ebb6e1a3e8f3" - integrity sha512-OPnYj0zpYW0tHusMefyaMvNYQX5pNQuSsHFTHUBNp3vVXupwqpxofcjVsUx11CQhGVkGeXjC3WLjh91hgBG2xw== - -"@esbuild/freebsd-arm64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz#364e3e5b7a1fd45d92be08c6cc5d890ca75908ca" - integrity sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q== - -"@esbuild/freebsd-arm64@0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.26.0.tgz#9acd33e588d2e1edddf6ee0e5a5272336b6ffcc1" - integrity sha512-jix2fa6GQeZhO1sCKNaNMjfj5hbOvoL2F5t+w6gEPxALumkpOV/wq7oUBMHBn2hY2dOm+mEV/K+xfZy3mrsxNQ== - -"@esbuild/freebsd-x64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz#7c869b45faeb3df668e19ace07335a0711ec56ab" - integrity sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg== - -"@esbuild/freebsd-x64@0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.26.0.tgz#c187f1f56731ab17861b9d3b00a9ddd7fbf6e46d" - integrity sha512-tccJaH5xHJD/239LjbVvJwf6T4kSzbk6wPFerF0uwWlkw/u7HL+wnAzAH5GB2irGhYemDgiNTp8wJzhAHQ64oA== - -"@esbuild/linux-arm64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz#48d42861758c940b61abea43ba9a29b186d6cb8b" - integrity sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw== - -"@esbuild/linux-arm64@0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.26.0.tgz#e516c7062d0b7f19cd139a5b597cd827d1e843ee" - integrity sha512-IMJYN7FSkLttYyTbsbme0Ra14cBO5z47kpamo16IwggzzATFY2lcZAwkbcNkWiAduKrTgFJP7fW5cBI7FzcuNQ== - -"@esbuild/linux-arm@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz#6ce4b9cabf148274101701d112b89dc67cc52f37" - integrity sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw== - -"@esbuild/linux-arm@0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.26.0.tgz#f26b22a0c80ac1ea73afd33c4e5034c69ae9ab14" - integrity sha512-JY8NyU31SyRmRpuc5W8PQarAx4TvuYbyxbPIpHAZdr/0g4iBr8KwQBS4kiiamGl2f42BBecHusYCsyxi7Kn8UQ== - -"@esbuild/linux-ia32@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz#207e54899b79cac9c26c323fc1caa32e3143f1c4" - integrity sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A== - -"@esbuild/linux-ia32@0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.26.0.tgz#22b310b307f68b57a28d25c662758a865555b6dc" - integrity sha512-XITaGqGVLgk8WOHw8We9Z1L0lbLFip8LyQzKYFKO4zFo1PFaaSKsbNjvkb7O8kEXytmSGRkYpE8LLVpPJpsSlw== - -"@esbuild/linux-loong64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz#0ba48a127159a8f6abb5827f21198b999ffd1fc0" - integrity sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ== - -"@esbuild/linux-loong64@0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.26.0.tgz#39027e0050ec9b275432814f47d3325562c62565" - integrity sha512-MkggfbDIczStUJwq9wU7gQ7kO33d8j9lWuOCDifN9t47+PeI+9m2QVh51EI/zZQ1spZtFMC1nzBJ+qNGCjJnsg== - -"@esbuild/linux-mips64el@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz#a4d4cc693d185f66a6afde94f772b38ce5d64eb5" - integrity sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA== - -"@esbuild/linux-mips64el@0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.26.0.tgz#d30185dc4298bd2470b21e6358f4c0e42cd8ecfc" - integrity sha512-fUYup12HZWAeccNLhQ5HwNBPr4zXCPgUWzEq2Rfw7UwqwfQrFZ0SR/JljaURR8xIh9t+o1lNUFTECUTmaP7yKA== - -"@esbuild/linux-ppc64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz#0f5805c1c6d6435a1dafdc043cb07a19050357db" - integrity sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w== - -"@esbuild/linux-ppc64@0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.26.0.tgz#8df55e65fd98a4244aaea649ba9745998f82a2e8" - integrity sha512-MzRKhM0Ip+//VYwC8tialCiwUQ4G65WfALtJEFyU0GKJzfTYoPBw5XNWf0SLbCUYQbxTKamlVwPmcw4DgZzFxg== - -"@esbuild/linux-riscv64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz#6776edece0f8fca79f3386398b5183ff2a827547" - integrity sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg== - -"@esbuild/linux-riscv64@0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.26.0.tgz#406e26b21646d19bf2e58a187a53fec719465512" - integrity sha512-QhCc32CwI1I4Jrg1enCv292sm3YJprW8WHHlyxJhae/dVs+KRWkbvz2Nynl5HmZDW/m9ZxrXayHzjzVNvQMGQA== - -"@esbuild/linux-s390x@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz#3f6f29ef036938447c2218d309dc875225861830" - integrity sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA== - -"@esbuild/linux-s390x@0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.26.0.tgz#a3c55edb6f19b2ff737f3d5d238bbcaf58815652" - integrity sha512-1D6vi6lfI18aNT1aTf2HV+RIlm6fxtlAp8eOJ4mmnbYmZ4boz8zYDar86sIYNh0wmiLJEbW/EocaKAX6Yso2fw== - "@esbuild/linux-x64@0.25.9": version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz#831fe0b0e1a80a8b8391224ea2377d5520e1527f" + resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz" integrity sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg== "@esbuild/linux-x64@0.26.0": version "0.26.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.26.0.tgz#d60f139897b12e5af37113d6a433a7ef27c6d87f" + resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.26.0.tgz" integrity sha512-rnDcepj7LjrKFvZkx+WrBv6wECeYACcFjdNPvVPojCPJD8nHpb3pv3AuR9CXgdnjH1O23btICj0rsp0L9wAnHA== -"@esbuild/netbsd-arm64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz#06f99d7eebe035fbbe43de01c9d7e98d2a0aa548" - integrity sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q== - -"@esbuild/netbsd-arm64@0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.26.0.tgz#a89594f82f8172b127d7a59988dbde1a56a4d03e" - integrity sha512-FSWmgGp0mDNjEXXFcsf12BmVrb+sZBBBlyh3LwB/B9ac3Kkc8x5D2WimYW9N7SUkolui8JzVnVlWh7ZmjCpnxw== - -"@esbuild/netbsd-x64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz#db99858e6bed6e73911f92a88e4edd3a8c429a52" - integrity sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g== - -"@esbuild/netbsd-x64@0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.26.0.tgz#22c396c61067d4057d3c8b1e0b7481422bcf70f5" - integrity sha512-0QfciUDFryD39QoSPUDshj4uNEjQhp73+3pbSAaxjV2qGOEDsM67P7KbJq7LzHoVl46oqhIhJ1S+skKGR7lMXA== - -"@esbuild/openbsd-arm64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz#afb886c867e36f9d86bb21e878e1185f5d5a0935" - integrity sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ== - -"@esbuild/openbsd-arm64@0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.26.0.tgz#302f9602161cf1556dfc3574f6ff895f92566221" - integrity sha512-vmAK+nHhIZWImwJ3RNw9hX3fU4UGN/OqbSE0imqljNbUQC3GvVJ1jpwYoTfD6mmXmQaxdJY6Hn4jQbLGJKg5Yw== - -"@esbuild/openbsd-x64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz#30855c9f8381fac6a0ef5b5f31ac6e7108a66ecf" - integrity sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA== - -"@esbuild/openbsd-x64@0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.26.0.tgz#2d702092fe56dcc9f77932733898900b077e195a" - integrity sha512-GPXF7RMkJ7o9bTyUsnyNtrFMqgM3X+uM/LWw4CeHIjqc32fm0Ir6jKDnWHpj8xHFstgWDUYseSABK9KCkHGnpg== - -"@esbuild/openharmony-arm64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz#2f2144af31e67adc2a8e3705c20c2bd97bd88314" - integrity sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg== - -"@esbuild/openharmony-arm64@0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.26.0.tgz#b23c269bfe5583f2ffecf2778200194756652262" - integrity sha512-nUHZ5jEYqbBthbiBksbmHTlbb5eElyVfs/s1iHQ8rLBq1eWsd5maOnDpCocw1OM8kFK747d1Xms8dXJHtduxSw== - -"@esbuild/sunos-x64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz#69b99a9b5bd226c9eb9c6a73f990fddd497d732e" - integrity sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw== - -"@esbuild/sunos-x64@0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.26.0.tgz#8579737e0e147af566070fdcf691b79cf508666c" - integrity sha512-TMg3KCTCYYaVO+R6P5mSORhcNDDlemUVnUbb8QkboUtOhb5JWKAzd5uMIMECJQOxHZ/R+N8HHtDF5ylzLfMiLw== - -"@esbuild/win32-arm64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz#d789330a712af916c88325f4ffe465f885719c6b" - integrity sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ== - -"@esbuild/win32-arm64@0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.26.0.tgz#6761aab78c8b7d397a82d73c545de0410e61a5f7" - integrity sha512-apqYgoAUd6ZCb9Phcs8zN32q6l0ZQzQBdVXOofa6WvHDlSOhwCWgSfVQabGViThS40Y1NA4SCvQickgZMFZRlA== - -"@esbuild/win32-ia32@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz#52fc735406bd49688253e74e4e837ac2ba0789e3" - integrity sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww== - -"@esbuild/win32-ia32@0.26.0": - version "0.26.0" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.26.0.tgz#22bef8d60489e4edd3646154ef23d0bdab54b12a" - integrity sha512-FGJAcImbJNZzLWu7U6WB0iKHl4RuY4TsXEwxJPl9UZLS47agIZuILZEX3Pagfw7I4J3ddflomt9f0apfaJSbaw== - -"@esbuild/win32-x64@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz" - integrity sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ== - -"@esbuild/win32-x64@0.26.0": - version "0.26.0" - resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.26.0.tgz" - integrity sha512-WAckBKaVnmFqbEhbymrPK7M086DQMpL1XoRbpmN0iW8k5JSXjDRQBhcZNa0VweItknLq9eAeCL34jK7/CDcw7A== - "@eslint-community/eslint-utils@^4.2.0": version "4.7.0" resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz" @@ -592,16 +342,11 @@ "@inquirer/type" "^3.0.10" yoctocolors-cjs "^2.1.3" -"@inquirer/type@^3.0.10": +"@inquirer/type@^3.0.10", "@inquirer/type@^3.0.8": version "3.0.10" resolved "https://registry.npmjs.org/@inquirer/type/-/type-3.0.10.tgz" integrity sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA== -"@inquirer/type@^3.0.8": - version "3.0.8" - resolved "https://registry.npmjs.org/@inquirer/type/-/type-3.0.8.tgz" - integrity sha512-lg9Whz8onIHRthWaN1Q9EGLa/0LFJjyM8mEUbL1eTi6yMGvBf8gvyDLtxSXztQsxMvhxxNpJYrwa1YHdq+w4Jw== - "@isaacs/fs-minipass@^4.0.0": version "4.0.1" resolved "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz" @@ -614,7 +359,7 @@ resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz" integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== -"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.5.0", "@jridgewell/sourcemap-codec@^1.5.5": +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.5.5": version "1.5.5" resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz" integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== @@ -654,7 +399,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": +"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -679,7 +424,7 @@ resolved "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz" integrity sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w== -"@octokit/core@^7.0.2": +"@octokit/core@^7.0.2", "@octokit/core@>=6": version "7.0.6" resolved "https://registry.npmjs.org/@octokit/core/-/core-7.0.6.tgz" integrity sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q== @@ -782,7 +527,7 @@ "@opentelemetry/api@1.9.0": version "1.9.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.9.0.tgz#d03eba68273dc0f7509e2a3d5cba21eae10379fe" + resolved "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz" integrity sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg== "@phun-ky/typeof@2.0.3": @@ -851,16 +596,7 @@ is-module "^1.0.0" resolve "^1.22.1" -"@rollup/pluginutils@^5.0.1", "@rollup/pluginutils@^5.1.0": - version "5.2.0" - resolved "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.2.0.tgz" - integrity sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw== - dependencies: - "@types/estree" "^1.0.0" - estree-walker "^2.0.2" - picomatch "^4.0.2" - -"@rollup/pluginutils@^5.3.0": +"@rollup/pluginutils@^5.0.1", "@rollup/pluginutils@^5.1.0", "@rollup/pluginutils@^5.3.0": version "5.3.0" resolved "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz" integrity sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q== @@ -869,216 +605,11 @@ estree-walker "^2.0.2" picomatch "^4.0.2" -"@rollup/rollup-android-arm-eabi@4.46.3": - version "4.46.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.46.3.tgz#8d8afcc5a79a3f190c5f855facde6e0da6a5b7ea" - integrity sha512-UmTdvXnLlqQNOCJnyksjPs1G4GqXNGW1LrzCe8+8QoaLhhDeTXYBgJ3k6x61WIhlHX2U+VzEJ55TtIjR/HTySA== - -"@rollup/rollup-android-arm-eabi@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz#7e478b66180c5330429dd161bf84dad66b59c8eb" - integrity sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w== - -"@rollup/rollup-android-arm64@4.46.3": - version "4.46.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.46.3.tgz#bed8ee4c2b31fd255fb91c2f52949dffef16ecf1" - integrity sha512-8NoxqLpXm7VyeI0ocidh335D6OKT0UJ6fHdnIxf3+6oOerZZc+O7r+UhvROji6OspyPm+rrIdb1gTXtVIqn+Sg== - -"@rollup/rollup-android-arm64@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.3.tgz#2b025510c53a5e3962d3edade91fba9368c9d71c" - integrity sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w== - -"@rollup/rollup-darwin-arm64@4.46.3": - version "4.46.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.46.3.tgz#ee2a75deb8786b394c7f1777cc0c2ae2c3680469" - integrity sha512-csnNavqZVs1+7/hUKtgjMECsNG2cdB8F7XBHP6FfQjqhjF8rzMzb3SLyy/1BG7YSfQ+bG75Ph7DyedbUqwq1rA== - -"@rollup/rollup-darwin-arm64@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz#3577c38af68ccf34c03e84f476bfd526abca10a0" - integrity sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA== - -"@rollup/rollup-darwin-x64@4.46.3": - version "4.46.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.46.3.tgz#f5a01577c40830c423855492ecd8d3a7ae1b4836" - integrity sha512-r2MXNjbuYabSIX5yQqnT8SGSQ26XQc8fmp6UhlYJd95PZJkQD1u82fWP7HqvGUf33IsOC6qsiV+vcuD4SDP6iw== - -"@rollup/rollup-darwin-x64@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.3.tgz#2bf5f2520a1f3b551723d274b9669ba5b75ed69c" - integrity sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ== - -"@rollup/rollup-freebsd-arm64@4.46.3": - version "4.46.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.46.3.tgz#d272eed9c14efc149bab316de364c04f236c544f" - integrity sha512-uluObTmgPJDuJh9xqxyr7MV61Imq+0IvVsAlWyvxAaBSNzCcmZlhfYcRhCdMaCsy46ccZa7vtDDripgs9Jkqsw== - -"@rollup/rollup-freebsd-arm64@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.3.tgz#4bb9cc80252564c158efc0710153c71633f1927c" - integrity sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w== - -"@rollup/rollup-freebsd-x64@4.46.3": - version "4.46.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.46.3.tgz#4c793f86e2dc64e725370daa2bec103f5869b5a6" - integrity sha512-AVJXEq9RVHQnejdbFvh1eWEoobohUYN3nqJIPI4mNTMpsyYN01VvcAClxflyk2HIxvLpRcRggpX1m9hkXkpC/A== - -"@rollup/rollup-freebsd-x64@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.3.tgz#2301289094d49415a380cf942219ae9d8b127440" - integrity sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q== - -"@rollup/rollup-linux-arm-gnueabihf@4.46.3": - version "4.46.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.46.3.tgz#28da78d3709262f0b7ef0ba7e8e6f77c1b2f30a6" - integrity sha512-byyflM+huiwHlKi7VHLAYTKr67X199+V+mt1iRgJenAI594vcmGGddWlu6eHujmcdl6TqSNnvqaXJqZdnEWRGA== - -"@rollup/rollup-linux-arm-gnueabihf@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.3.tgz#1d03d776f2065e09fc141df7d143476e94acca88" - integrity sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw== - -"@rollup/rollup-linux-arm-musleabihf@4.46.3": - version "4.46.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.46.3.tgz#7e3309e6519eca1459038761aad44863e86fc497" - integrity sha512-aLm3NMIjr4Y9LklrH5cu7yybBqoVCdr4Nvnm8WB7PKCn34fMCGypVNpGK0JQWdPAzR/FnoEoFtlRqZbBBLhVoQ== - -"@rollup/rollup-linux-arm-musleabihf@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.3.tgz#8623de0e040b2fd52a541c602688228f51f96701" - integrity sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg== - -"@rollup/rollup-linux-arm64-gnu@4.46.3": - version "4.46.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.46.3.tgz#bc18efe81022baac97566cc0ace04b359eb7cd16" - integrity sha512-VtilE6eznJRDIoFOzaagQodUksTEfLIsvXymS+UdJiSXrPW7Ai+WG4uapAc3F7Hgs791TwdGh4xyOzbuzIZrnw== - -"@rollup/rollup-linux-arm64-gnu@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.3.tgz#ce2d1999bc166277935dde0301cde3dd0417fb6e" - integrity sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w== - -"@rollup/rollup-linux-arm64-musl@4.46.3": - version "4.46.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.46.3.tgz#3ac849b6c42591014b0cb8e25c9ba1ace8fe19ec" - integrity sha512-dG3JuS6+cRAL0GQ925Vppafi0qwZnkHdPeuZIxIPXqkCLP02l7ka+OCyBoDEv8S+nKHxfjvjW4OZ7hTdHkx8/w== - -"@rollup/rollup-linux-arm64-musl@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.3.tgz#88c2523778444da952651a2219026416564a4899" - integrity sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A== - -"@rollup/rollup-linux-loong64-gnu@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.3.tgz#578ca2220a200ac4226c536c10c8cc6e4f276714" - integrity sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g== - -"@rollup/rollup-linux-loongarch64-gnu@4.46.3": - version "4.46.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.46.3.tgz#10260ca0c3682c2904b04bb907163aca8bc5adef" - integrity sha512-iU8DxnxEKJptf8Vcx4XvAUdpkZfaz0KWfRrnIRrOndL0SvzEte+MTM7nDH4A2Now4FvTZ01yFAgj6TX/mZl8hQ== - -"@rollup/rollup-linux-ppc64-gnu@4.46.3": - version "4.46.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.46.3.tgz#36b002a84c04f2e18093f563896c95a6e687f28f" - integrity sha512-VrQZp9tkk0yozJoQvQcqlWiqaPnLM6uY1qPYXvukKePb0fqaiQtOdMJSxNFUZFsGw5oA5vvVokjHrx8a9Qsz2A== - -"@rollup/rollup-linux-ppc64-gnu@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.3.tgz#aa338d3effd4168a20a5023834a74ba2c3081293" - integrity sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw== - -"@rollup/rollup-linux-riscv64-gnu@4.46.3": - version "4.46.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.46.3.tgz#ff1b3708624fc8b912e5341431751977b78be273" - integrity sha512-uf2eucWSUb+M7b0poZ/08LsbcRgaDYL8NCGjUeFMwCWFwOuFcZ8D9ayPl25P3pl+D2FH45EbHdfyUesQ2Lt9wA== - -"@rollup/rollup-linux-riscv64-gnu@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.3.tgz#16ba582f9f6cff58119aa242782209b1557a1508" - integrity sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g== - -"@rollup/rollup-linux-riscv64-musl@4.46.3": - version "4.46.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.46.3.tgz#ab6f7ef69cdf812eccb318021a8f5c221bd0c048" - integrity sha512-7tnUcDvN8DHm/9ra+/nF7lLzYHDeODKKKrh6JmZejbh1FnCNZS8zMkZY5J4sEipy2OW1d1Ncc4gNHUd0DLqkSg== - -"@rollup/rollup-linux-riscv64-musl@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.3.tgz#e404a77ebd6378483888b8064c703adb011340ab" - integrity sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A== - -"@rollup/rollup-linux-s390x-gnu@4.46.3": - version "4.46.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.46.3.tgz#60527b48dd84814fa5092a2eef1ac90e2b4bf825" - integrity sha512-MUpAOallJim8CsJK+4Lc9tQzlfPbHxWDrGXZm2z6biaadNpvh3a5ewcdat478W+tXDoUiHwErX/dOql7ETcLqg== - -"@rollup/rollup-linux-s390x-gnu@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.3.tgz#92ad52d306227c56bec43d96ad2164495437ffe6" - integrity sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg== - -"@rollup/rollup-linux-x64-gnu@4.46.3": - version "4.46.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.46.3.tgz#c95698199820782b7420f5472e5d36b681728274" - integrity sha512-F42IgZI4JicE2vM2PWCe0N5mR5vR0gIdORPqhGQ32/u1S1v3kLtbZ0C/mi9FFk7C5T0PgdeyWEPajPjaUpyoKg== - "@rollup/rollup-linux-x64-gnu@4.53.3": version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz#fd0dea3bb9aa07e7083579f25e1c2285a46cb9fa" + resolved "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz" integrity sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w== -"@rollup/rollup-linux-x64-musl@4.46.3": - version "4.46.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.46.3.tgz#226eb081be8d6698a580022448197b01cb4193a2" - integrity sha512-oLc+JrwwvbimJUInzx56Q3ujL3Kkhxehg7O1gWAYzm8hImCd5ld1F2Gry5YDjR21MNb5WCKhC9hXgU7rRlyegQ== - -"@rollup/rollup-linux-x64-musl@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz#37a3efb09f18d555f8afc490e1f0444885de8951" - integrity sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q== - -"@rollup/rollup-openharmony-arm64@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.3.tgz#c489bec9f4f8320d42c9b324cca220c90091c1f7" - integrity sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw== - -"@rollup/rollup-win32-arm64-msvc@4.46.3": - version "4.46.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.46.3.tgz#e900bd51cfc20af2a1c828d999bb49da1bd497eb" - integrity sha512-lOrQ+BVRstruD1fkWg9yjmumhowR0oLAAzavB7yFSaGltY8klttmZtCLvOXCmGE9mLIn8IBV/IFrQOWz5xbFPg== - -"@rollup/rollup-win32-arm64-msvc@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.3.tgz#152832b5f79dc22d1606fac3db946283601b7080" - integrity sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw== - -"@rollup/rollup-win32-ia32-msvc@4.46.3": - version "4.46.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.46.3.tgz#94652ba771a90bf2558c0a6c553857148d7ff8f4" - integrity sha512-vvrVKPRS4GduGR7VMH8EylCBqsDcw6U+/0nPDuIjXQRbHJc6xOBj+frx8ksfZAh6+Fptw5wHrN7etlMmQnPQVg== - -"@rollup/rollup-win32-ia32-msvc@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.3.tgz#54d91b2bb3bf3e9f30d32b72065a4e52b3a172a5" - integrity sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA== - -"@rollup/rollup-win32-x64-gnu@4.53.3": - version "4.53.3" - resolved "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz" - integrity sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg== - -"@rollup/rollup-win32-x64-msvc@4.46.3": - version "4.46.3" - resolved "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.46.3.tgz" - integrity sha512-fi3cPxCnu3ZeM3EwKZPgXbWoGzm2XHgB/WShKI81uj8wG0+laobmqy5wbgEwzstlbLu4MyO8C19FyhhWseYKNQ== - -"@rollup/rollup-win32-x64-msvc@4.53.3": - version "4.53.3" - resolved "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz" - integrity sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ== - "@socket.io/component-emitter@~3.1.0": version "3.1.2" resolved "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz" @@ -1096,7 +627,7 @@ "@standard-schema/spec@^1.0.0": version "1.0.0" - resolved "https://registry.yarnpkg.com/@standard-schema/spec/-/spec-1.0.0.tgz#f193b73dc316c4170f2e82a881da0f550d551b9c" + resolved "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz" integrity sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA== "@tootallnate/quickjs-emscripten@^0.23.0": @@ -1143,19 +674,12 @@ resolved "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz" integrity sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw== -"@types/estree@*", "@types/estree@1.0.8", "@types/estree@^1.0.0", "@types/estree@^1.0.6": +"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.6", "@types/estree@1.0.8": version "1.0.8" resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz" integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== -"@types/http-proxy@^1.17.15": - version "1.17.16" - resolved "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.16.tgz" - integrity sha512-sdWoUajOB1cd0A8cRRQ1cfyWNbmFKLAqBB89Y8x5iYyG/mkJHc0YUH8pdWBy2omi9qtCpiIgGjuwO0dQST2l5w== - dependencies: - "@types/node" "*" - -"@types/http-proxy@^1.17.17": +"@types/http-proxy@^1.17.15", "@types/http-proxy@^1.17.17": version "1.17.17" resolved "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.17.tgz" integrity sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw== @@ -1167,16 +691,16 @@ resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== -"@types/node@*", "@types/node@>=20": +"@types/node@*", "@types/node@^18.0.0 || ^20.0.0 || >=22.0.0", "@types/node@^20.19.0 || >=22.12.0", "@types/node@>=18", "@types/node@>=20": version "24.3.0" resolved "https://registry.npmjs.org/@types/node/-/node-24.3.0.tgz" integrity sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow== dependencies: undici-types "~7.10.0" -"@types/parse-path@7.0.3", "@types/parse-path@^7.0.0": +"@types/parse-path@^7.0.0": version "7.0.3" - resolved "https://registry.yarnpkg.com/@types/parse-path/-/parse-path-7.0.3.tgz#cec2da2834ab58eb2eb579122d9a1fc13bd7ef36" + resolved "https://registry.npmjs.org/@types/parse-path/-/parse-path-7.0.3.tgz" integrity sha512-LriObC2+KYZD3FzCrgWGv/qufdUy4eXrxcLgQMfYXgPbLIecKIsVBaQgUPmxSSLcjmYbDTQbMgr6qr6l/eb7Bg== "@types/ps-list@^6.2.1": @@ -1191,7 +715,7 @@ resolved "https://registry.npmjs.org/@types/qrcode-terminal/-/qrcode-terminal-0.12.2.tgz" integrity sha512-v+RcIEJ+Uhd6ygSQ0u5YYY7ZM+la7GgPbs0V/7l/kFs2uO4S8BcIUEMoP7za4DNIqNnUD5npf0A/7kBhrCKG5Q== -"@types/react@^19.2.7": +"@types/react@^19.2.7", "@types/react@>=19.0.0": version "19.2.7" resolved "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz" integrity sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg== @@ -1210,7 +734,7 @@ "@vercel/oidc@3.0.5": version "3.0.5" - resolved "https://registry.yarnpkg.com/@vercel/oidc/-/oidc-3.0.5.tgz#bd8db7ee777255c686443413492db4d98ef49657" + resolved "https://registry.npmjs.org/@vercel/oidc/-/oidc-3.0.5.tgz" integrity sha512-fnYhv671l+eTTp48gB4zEsTW/YtRgRPnkI2nT7x6qw5rkI1Lq2hTmQIpHPgyThI0znLK+vX2n9XxKdXZ7BUbbw== "@vitest/expect@3.2.4": @@ -1233,7 +757,7 @@ estree-walker "^3.0.3" magic-string "^0.30.17" -"@vitest/pretty-format@3.2.4", "@vitest/pretty-format@^3.2.4": +"@vitest/pretty-format@^3.2.4", "@vitest/pretty-format@3.2.4": version "3.2.4" resolved "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz" integrity sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA== @@ -1299,7 +823,7 @@ acorn-walk@^8.1.1: dependencies: acorn "^8.11.0" -acorn@^8.11.0, acorn@^8.15.0, acorn@^8.4.1: +"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.11.0, acorn@^8.15.0, acorn@^8.4.1: version "8.15.0" resolved "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz" integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== @@ -1311,7 +835,7 @@ agent-base@^7.1.0, agent-base@^7.1.2: ai@^5.0.107: version "5.0.107" - resolved "https://registry.yarnpkg.com/ai/-/ai-5.0.107.tgz#8475fb5aee87c40586b3b8d0b1998116a8452108" + resolved "https://registry.npmjs.org/ai/-/ai-5.0.107.tgz" integrity sha512-laZlS9ZC/DZfSaxPgrBqI4mM+kxRvTPBBQfa74ceBFskkunZKEsaGVFNEs4cfyGa3nCCCl1WO/fjxixp4V8Zag== dependencies: "@ai-sdk/gateway" "2.0.18" @@ -1363,7 +887,14 @@ ansi-regex@^6.0.1: resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.0.tgz" integrity sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg== -ansi-styles@^4.0.0, ansi-styles@^4.1.0: +ansi-styles@^4.0.0: + version "4.3.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== @@ -1493,7 +1024,7 @@ bundle-name@^4.1.0: dependencies: run-applescript "^7.0.0" -bytes@3.1.2, bytes@^3.1.2: +bytes@^3.1.2, bytes@3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== @@ -1561,12 +1092,7 @@ chalk@^4.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^5.6.0: - version "5.6.0" - resolved "https://registry.npmjs.org/chalk/-/chalk-5.6.0.tgz" - integrity sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ== - -chalk@^5.6.2: +chalk@^5.6.0, chalk@^5.6.2: version "5.6.2" resolved "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz" integrity sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA== @@ -1765,14 +1291,21 @@ data-uri-to-buffer@^6.0.2: resolved "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz" integrity sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw== -debug@4, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.5, debug@^4.3.6, debug@^4.4.0, debug@^4.4.1: +debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.5, debug@^4.3.6, debug@^4.4.0, debug@^4.4.1, debug@4: version "4.4.1" resolved "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz" integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ== dependencies: ms "^2.1.3" -debug@~4.3.1, debug@~4.3.2: +debug@~4.3.1: + version "4.3.7" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz" + integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== + dependencies: + ms "^2.1.3" + +debug@~4.3.2: version "4.3.7" resolved "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz" integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== @@ -1831,7 +1364,7 @@ delayed-stream@~1.0.0: resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -depd@2.0.0, depd@^2.0.0: +depd@^2.0.0, depd@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== @@ -1953,7 +1486,7 @@ es-toolkit@^1.39.10: resolved "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.39.10.tgz" integrity sha512-E0iGnTtbDhkeczB0T+mxmoVlT4YNweEKBLq7oaU4p11mecdsZpNWOglI4895Vh4usbQ+LsJiuLuI2L0Vdmfm2w== -esbuild@^0.25.0, esbuild@~0.25.0: +esbuild@^0.25.0: version "0.25.9" resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz" integrity sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g== @@ -2017,6 +1550,38 @@ esbuild@^0.26.0: "@esbuild/win32-ia32" "0.26.0" "@esbuild/win32-x64" "0.26.0" +esbuild@~0.25.0: + version "0.25.9" + resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz" + integrity sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g== + optionalDependencies: + "@esbuild/aix-ppc64" "0.25.9" + "@esbuild/android-arm" "0.25.9" + "@esbuild/android-arm64" "0.25.9" + "@esbuild/android-x64" "0.25.9" + "@esbuild/darwin-arm64" "0.25.9" + "@esbuild/darwin-x64" "0.25.9" + "@esbuild/freebsd-arm64" "0.25.9" + "@esbuild/freebsd-x64" "0.25.9" + "@esbuild/linux-arm" "0.25.9" + "@esbuild/linux-arm64" "0.25.9" + "@esbuild/linux-ia32" "0.25.9" + "@esbuild/linux-loong64" "0.25.9" + "@esbuild/linux-mips64el" "0.25.9" + "@esbuild/linux-ppc64" "0.25.9" + "@esbuild/linux-riscv64" "0.25.9" + "@esbuild/linux-s390x" "0.25.9" + "@esbuild/linux-x64" "0.25.9" + "@esbuild/netbsd-arm64" "0.25.9" + "@esbuild/netbsd-x64" "0.25.9" + "@esbuild/openbsd-arm64" "0.25.9" + "@esbuild/openbsd-x64" "0.25.9" + "@esbuild/openharmony-arm64" "0.25.9" + "@esbuild/sunos-x64" "0.25.9" + "@esbuild/win32-arm64" "0.25.9" + "@esbuild/win32-ia32" "0.25.9" + "@esbuild/win32-x64" "0.25.9" + escape-html@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" @@ -2066,7 +1631,7 @@ eslint-visitor-keys@^4.2.1: resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz" integrity sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ== -eslint@^9: +"eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^8.40 || 9", eslint@^9, eslint@>=7.0.0: version "9.33.0" resolved "https://registry.npmjs.org/eslint/-/eslint-9.33.0.tgz" integrity sha512-TS9bTNIryDzStCpJN93aC5VRSW3uTx9sClUn4B87pwiCaJh220otoI0X8mJKr+VcPtniMdN8GKjlwgWGUv5ZKA== @@ -2177,14 +1742,9 @@ eventemitter3@^4.0.0: resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== -eventsource-parser@^3.0.0, eventsource-parser@^3.0.1: - version "3.0.5" - resolved "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.5.tgz" - integrity sha512-bSRG85ZrMdmWtm7qkF9He9TNRzc/Bm99gEJMaQoHJ9E6Kv9QBbsldh2oMj7iXmYNEAVvNgvv5vPorG6W+XtBhQ== - -eventsource-parser@^3.0.6: +eventsource-parser@^3.0.0, eventsource-parser@^3.0.1, eventsource-parser@^3.0.6: version "3.0.6" - resolved "https://registry.yarnpkg.com/eventsource-parser/-/eventsource-parser-3.0.6.tgz#292e165e34cacbc936c3c92719ef326d4aeb4e90" + resolved "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz" integrity sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg== eventsource@^3.0.2: @@ -2228,7 +1788,7 @@ express-rate-limit@^7.5.0: resolved "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.1.tgz" integrity sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw== -express@^5.0.1: +express@^5.0.1, "express@>= 4.11": version "5.1.0" resolved "https://registry.npmjs.org/express/-/express-5.1.0.tgz" integrity sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA== @@ -2334,7 +1894,7 @@ fastify-type-provider-zod@4.0.2: "@fastify/error" "^4.0.0" zod-to-json-schema "^3.23.3" -fastify@^5.6.2: +fastify@^5.0.0, fastify@^5.6.2: version "5.6.2" resolved "https://registry.npmjs.org/fastify/-/fastify-5.6.2.tgz" integrity sha512-dPugdGnsvYkBlENLhCgX8yhyGCsCPrpA8lFWbTNU428l+YOnLgYHR69hzV8HWPC79n536EqzqQtvhtdaCE0dKg== @@ -2362,7 +1922,12 @@ fastq@^1.17.1, fastq@^1.6.0: dependencies: reusify "^1.0.4" -fdir@^6.2.0, fdir@^6.4.4, fdir@^6.5.0: +fdir@^6.2.0: + version "6.5.0" + resolved "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz" + integrity sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg== + +fdir@^6.5.0: version "6.5.0" resolved "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz" integrity sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg== @@ -2454,26 +2019,16 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@~2.3.2, fsevents@~2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" - integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== - function-bind@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== -get-east-asian-width@^1.0.0: +get-east-asian-width@^1.0.0, get-east-asian-width@^1.3.0: version "1.3.0" resolved "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz" integrity sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ== -get-east-asian-width@^1.3.0: - version "1.4.0" - resolved "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz" - integrity sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q== - get-intrinsic@^1.2.5, get-intrinsic@^1.2.6, get-intrinsic@^1.3.0: version "1.3.0" resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz" @@ -2606,7 +2161,7 @@ hasown@^2.0.2: dependencies: function-bind "^1.1.2" -http-errors@2.0.0, http-errors@^2.0.0: +http-errors@^2.0.0, http-errors@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== @@ -2659,7 +2214,7 @@ human-signals@^5.0.0: resolved "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz" integrity sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ== -iconv-lite@0.6.3, iconv-lite@^0.6.3: +iconv-lite@^0.6.3, iconv-lite@0.6.3: version "0.6.3" resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== @@ -2761,16 +2316,16 @@ ip-address@^10.0.1: resolved "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz" integrity sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA== -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - ipaddr.js@^2.1.0: version "2.2.0" resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz" integrity sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA== +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + is-core-module@^2.16.0: version "2.16.1" resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz" @@ -2891,7 +2446,7 @@ issue-parser@7.0.1: lodash.isstring "^4.0.1" lodash.uniqby "^4.7.0" -jiti@^2.6.1: +jiti@*, jiti@^2.6.1, jiti@>=1.21.0: version "2.6.1" resolved "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz" integrity sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ== @@ -2932,7 +2487,7 @@ json-schema-traverse@^1.0.0: json-schema@^0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz" integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== json-stable-stringify-without-jsonify@^1.0.1: @@ -2991,7 +2546,7 @@ lodash.isstring@^4.0.1: resolved "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz" integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== -lodash.merge@4.6.2, lodash.merge@^4.6.2: +lodash.merge@^4.6.2, lodash.merge@4.6.2: version "4.6.2" resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== @@ -3029,14 +2584,7 @@ macos-release@^3.3.0: resolved "https://registry.npmjs.org/macos-release/-/macos-release-3.4.0.tgz" integrity sha512-wpGPwyg/xrSp4H4Db4xYSeAr6+cFQGHfspHzDUdYxswDnUW0L5Ov63UuJiSr8NMSpyaChO4u1n0MXUvVPtrN6A== -magic-string@^0.30.17, magic-string@^0.30.3: - version "0.30.17" - resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz" - integrity sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA== - dependencies: - "@jridgewell/sourcemap-codec" "^1.5.0" - -magic-string@^0.30.21: +magic-string@^0.30.17, magic-string@^0.30.21, magic-string@^0.30.3: version "0.30.21" resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz" integrity sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ== @@ -3081,22 +2629,15 @@ micromatch@^4.0.8: braces "^3.0.3" picomatch "^2.3.1" -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - mime-db@^1.54.0: version "1.54.0" resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz" integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== -mime-types@3.0.1, mime-types@^3.0.0, mime-types@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz" - integrity sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA== - dependencies: - mime-db "^1.54.0" +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== mime-types@^2.1.12: version "2.1.35" @@ -3105,6 +2646,13 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" +mime-types@^3.0.0, mime-types@^3.0.1, mime-types@3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz" + integrity sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA== + dependencies: + mime-db "^1.54.0" + mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" @@ -3266,7 +2814,7 @@ onetime@^7.0.0: dependencies: mimic-function "^5.0.0" -open@10.2.0, open@^10.2.0: +open@^10.2.0, open@10.2.0: version "10.2.0" resolved "https://registry.npmjs.org/open/-/open-10.2.0.tgz" integrity sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA== @@ -3354,9 +2902,9 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parse-path@7.0.3, parse-path@^7.0.0: +parse-path@^7.0.0: version "7.0.3" - resolved "https://registry.yarnpkg.com/parse-path/-/parse-path-7.0.3.tgz#f29d8942a3562aac561a1b77de6a56cc93dca489" + resolved "https://registry.npmjs.org/parse-path/-/parse-path-7.0.3.tgz" integrity sha512-0R71msgRgmkcZ5CWnzS+GPXJ1Fc+lbKyPDuA83Ej0QKCpf/Feieh813bF38My3CTNBzcQhtRRqvXNpCFF6FRMQ== dependencies: protocols "^2.0.0" @@ -3434,7 +2982,7 @@ picomatch@^2.3.1: resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -picomatch@^4.0.2, picomatch@^4.0.3: +"picomatch@^3 || ^4", picomatch@^4.0.2, picomatch@^4.0.3: version "4.0.3" resolved "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz" integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q== @@ -3484,7 +3032,7 @@ pkg-types@^2.2.0, pkg-types@^2.3.0: pkgroll@^2.14.2: version "2.21.4" - resolved "https://registry.yarnpkg.com/pkgroll/-/pkgroll-2.21.4.tgz#a1144b1c881481387decf31bec5151729b602114" + resolved "https://registry.npmjs.org/pkgroll/-/pkgroll-2.21.4.tgz" integrity sha512-A86a27/WRXDSJlsIwGbR3zOQsf4TP6+CGRVdBgCUSQ6BGzrmXrH0IIJ/TEOLT4z8FNbR+ALjwNqPgSHBMK1llA== dependencies: "@rollup/plugin-alias" "^6.0.0" @@ -3577,7 +3125,7 @@ ps-list@*, ps-list@^8.1.1: punycode@^2.1.0, punycode@^2.3.1: version "2.3.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz" integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== qrcode-terminal@^0.12.0: @@ -3632,7 +3180,7 @@ react-reconciler@^0.33.0: dependencies: scheduler "^0.27.0" -react@^19.2.0: +react@^19.2.0, react@>=19.0.0: version "19.2.0" resolved "https://registry.npmjs.org/react/-/react-19.2.0.tgz" integrity sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ== @@ -3733,16 +3281,16 @@ ret@~0.5.0: resolved "https://registry.npmjs.org/ret/-/ret-0.5.0.tgz" integrity sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw== -retry@0.13.1: - version "0.13.1" - resolved "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz" - integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== - retry@^0.12.0: version "0.12.0" resolved "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz" integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== +retry@0.13.1: + version "0.13.1" + resolved "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + reusify@^1.0.4: version "1.1.0" resolved "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz" @@ -3760,36 +3308,7 @@ rollup-pluginutils@^2.8.2: dependencies: estree-walker "^0.6.1" -rollup@^4.43.0: - version "4.46.3" - resolved "https://registry.npmjs.org/rollup/-/rollup-4.46.3.tgz" - integrity sha512-RZn2XTjXb8t5g13f5YclGoilU/kwT696DIkY3sywjdZidNSi3+vseaQov7D7BZXVJCPv3pDWUN69C78GGbXsKw== - dependencies: - "@types/estree" "1.0.8" - optionalDependencies: - "@rollup/rollup-android-arm-eabi" "4.46.3" - "@rollup/rollup-android-arm64" "4.46.3" - "@rollup/rollup-darwin-arm64" "4.46.3" - "@rollup/rollup-darwin-x64" "4.46.3" - "@rollup/rollup-freebsd-arm64" "4.46.3" - "@rollup/rollup-freebsd-x64" "4.46.3" - "@rollup/rollup-linux-arm-gnueabihf" "4.46.3" - "@rollup/rollup-linux-arm-musleabihf" "4.46.3" - "@rollup/rollup-linux-arm64-gnu" "4.46.3" - "@rollup/rollup-linux-arm64-musl" "4.46.3" - "@rollup/rollup-linux-loongarch64-gnu" "4.46.3" - "@rollup/rollup-linux-ppc64-gnu" "4.46.3" - "@rollup/rollup-linux-riscv64-gnu" "4.46.3" - "@rollup/rollup-linux-riscv64-musl" "4.46.3" - "@rollup/rollup-linux-s390x-gnu" "4.46.3" - "@rollup/rollup-linux-x64-gnu" "4.46.3" - "@rollup/rollup-linux-x64-musl" "4.46.3" - "@rollup/rollup-win32-arm64-msvc" "4.46.3" - "@rollup/rollup-win32-ia32-msvc" "4.46.3" - "@rollup/rollup-win32-x64-msvc" "4.46.3" - fsevents "~2.3.2" - -rollup@^4.53.1: +rollup@^1.20.0||^2.0.0||^3.0.0||^4.0.0, rollup@^2.68.0||^3.0.0||^4.0.0, rollup@^2.78.0||^3.0.0||^4.0.0, rollup@^4.43.0, rollup@^4.53.1, rollup@>=4.0.0: version "4.53.3" resolved "https://registry.npmjs.org/rollup/-/rollup-4.53.3.tgz" integrity sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA== @@ -3887,7 +3406,7 @@ secure-json-parse@^4.0.0: resolved "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-4.0.0.tgz" integrity sha512-dxtLJO6sc35jWidmLxo7ij+Eg48PM/kleBsxpC8QJE0qJICe+KawkDQmvCMZUr9u7WKVHgMW6vy3fQ7zMiFZMA== -semver@7.7.2, semver@^7.6.0: +semver@^7.6.0, semver@7.7.2: version "7.7.2" resolved "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz" integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== @@ -4095,16 +3614,16 @@ stackback@0.0.2: resolved "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz" integrity sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw== -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== - statuses@^2.0.1: version "2.0.2" resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz" integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw== +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + std-env@^3.9.0: version "3.9.0" resolved "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz" @@ -4148,14 +3667,7 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-ansi@^7.1.0: - version "7.1.0" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz" - integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== - dependencies: - ansi-regex "^6.0.1" - -strip-ansi@^7.1.2: +strip-ansi@^7.1.0, strip-ansi@^7.1.2: version "7.1.2" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz" integrity sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA== @@ -4224,7 +3736,7 @@ tinyexec@^1.0.1: resolved "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.1.tgz" integrity sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw== -tinyglobby@0.2.15: +tinyglobby@^0.2.14, tinyglobby@0.2.15: version "0.2.15" resolved "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz" integrity sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ== @@ -4232,14 +3744,6 @@ tinyglobby@0.2.15: fdir "^6.5.0" picomatch "^4.0.3" -tinyglobby@^0.2.14: - version "0.2.14" - resolved "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz" - integrity sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ== - dependencies: - fdir "^6.4.4" - picomatch "^4.0.2" - tinypool@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz" @@ -4279,7 +3783,7 @@ toidentifier@1.0.1: tr46@^5.1.0: version "5.1.1" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-5.1.1.tgz#96ae867cddb8fdb64a49cc3059a8d428bcf238ca" + resolved "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz" integrity sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw== dependencies: punycode "^2.3.1" @@ -4308,7 +3812,7 @@ tslib@^2.0.1, tslib@^2.1.0: resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== -tsx@^4.20.6: +tsx@^4.20.6, tsx@^4.8.1: version "4.20.6" resolved "https://registry.npmjs.org/tsx/-/tsx-4.20.6.tgz" integrity sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg== @@ -4349,7 +3853,7 @@ type-is@^2.0.0, type-is@^2.0.1: media-typer "^1.1.0" mime-types "^3.0.0" -typescript@^5: +"typescript@^4.1 || ^5.0", typescript@^5, typescript@>=2.7: version "5.9.2" resolved "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz" integrity sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A== @@ -4452,12 +3956,12 @@ vitest@^3.2.4: webidl-conversions@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" + resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz" integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== -whatwg-url@14.2.0, whatwg-url@^5.0.0: +whatwg-url@^5.0.0: version "14.2.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-14.2.0.tgz#4ee02d5d725155dae004f6ae95c73e7ef5d95663" + resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz" integrity sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw== dependencies: tr46 "^5.1.0" @@ -4552,7 +4056,7 @@ yallist@^5.0.0: resolved "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz" integrity sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw== -yaml@^2.8.1: +yaml@^2.4.2, yaml@^2.8.1: version "2.8.1" resolved "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz" integrity sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw== @@ -4592,7 +4096,7 @@ zod-to-json-schema@^3.23.3, zod-to-json-schema@^3.24.1: resolved "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.6.tgz" integrity sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg== -zod@^3.23.8: +zod@^3.14.2, zod@^3.23.8, zod@^3.24.1, "zod@^3.25.0 || ^4.0.0", "zod@^3.25.76 || ^4.1.8": version "3.25.76" resolved "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz" integrity sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ== From c439873c0ae181f0b9f235d0af933c2a9831a126 Mon Sep 17 00:00:00 2001 From: mw Date: Mon, 29 Dec 2025 15:00:24 -0500 Subject: [PATCH 2/2] chore: revert accidental yarn.lock format and registry changes --- yarn.lock | 776 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 636 insertions(+), 140 deletions(-) diff --git a/yarn.lock b/yarn.lock index dbfccaad..8491498f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4,12 +4,12 @@ "@agentclientprotocol/sdk@^0.8.0": version "0.8.0" - resolved "https://registry.npmjs.org/@agentclientprotocol/sdk/-/sdk-0.8.0.tgz" + resolved "https://registry.yarnpkg.com/@agentclientprotocol/sdk/-/sdk-0.8.0.tgz#79d39716461dc5ac544680ecaa695cb1b338849a" integrity sha512-RnYsrYqrGFNpPc/cgHgMPHjgn52F1tw5PWyr7UucQ2V1O72JWy3fCCkUgbbRgn7wbNVFsrEZMuBS186Mxgkhfg== "@ai-sdk/gateway@2.0.18": version "2.0.18" - resolved "https://registry.npmjs.org/@ai-sdk/gateway/-/gateway-2.0.18.tgz" + resolved "https://registry.yarnpkg.com/@ai-sdk/gateway/-/gateway-2.0.18.tgz#7e81bdedddb7363af2c38d2cf7f34ac2d5e5eaa7" integrity sha512-sDQcW+6ck2m0pTIHW6BPHD7S125WD3qNkx/B8sEzJp/hurocmJ5Cni0ybExg6sQMGo+fr/GWOwpHF1cmCdg5rQ== dependencies: "@ai-sdk/provider" "2.0.0" @@ -18,7 +18,7 @@ "@ai-sdk/provider-utils@3.0.18": version "3.0.18" - resolved "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-3.0.18.tgz" + resolved "https://registry.yarnpkg.com/@ai-sdk/provider-utils/-/provider-utils-3.0.18.tgz#fc7757ad7eb48a48ce1976da3025f0b9215b1aff" integrity sha512-ypv1xXMsgGcNKUP+hglKqtdDuMg68nWHucPPAhIENrbFAI+xCHiqPVN8Zllxyv1TNZwGWUghPxJXU+Mqps0YRQ== dependencies: "@ai-sdk/provider" "2.0.0" @@ -27,7 +27,7 @@ "@ai-sdk/provider@2.0.0": version "2.0.0" - resolved "https://registry.npmjs.org/@ai-sdk/provider/-/provider-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/@ai-sdk/provider/-/provider-2.0.0.tgz#b853c739d523b33675bc74b6c506b2c690bc602b" integrity sha512-6o7Y2SeO9vFKB8lArHXehNuusnpddKPk7xqL7T2/b+OvXMRIXUO1rR4wcv1hAFUAT9avGZshty3Wlua/XA7TvA== dependencies: json-schema "^0.4.0" @@ -52,16 +52,266 @@ resolved "https://registry.npmjs.org/@epic-web/invariant/-/invariant-1.0.0.tgz" integrity sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA== +"@esbuild/aix-ppc64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz#bef96351f16520055c947aba28802eede3c9e9a9" + integrity sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA== + +"@esbuild/aix-ppc64@0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.26.0.tgz#e1d4bed341913e20caf2c2cb3a77b9662a8e40f1" + integrity sha512-hj0sKNCQOOo2fgyII3clmJXP28VhgDfU5iy3GNHlWO76KG6N7x4D9ezH5lJtQTG+1J6MFDAJXC1qsI+W+LvZoA== + +"@esbuild/android-arm64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz#d2e70be7d51a529425422091e0dcb90374c1546c" + integrity sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg== + +"@esbuild/android-arm64@0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.26.0.tgz#0a871d1332467be244101f757213a4dfc32ee93c" + integrity sha512-DDnoJ5eoa13L8zPh87PUlRd/IyFaIKOlRbxiwcSbeumcJ7UZKdtuMCHa1Q27LWQggug6W4m28i4/O2qiQQ5NZQ== + +"@esbuild/android-arm@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.9.tgz#d2a753fe2a4c73b79437d0ba1480e2d760097419" + integrity sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ== + +"@esbuild/android-arm@0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.26.0.tgz#6615de6d8fe792f8abd752cf0118305a171e15cd" + integrity sha512-C0hkDsYNHZkBtPxxDx177JN90/1MiCpvBNjz1f5yWJo1+5+c5zr8apjastpEG+wtPjo9FFtGG7owSsAxyKiHxA== + +"@esbuild/android-x64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.9.tgz#5278836e3c7ae75761626962f902a0d55352e683" + integrity sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw== + +"@esbuild/android-x64@0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.26.0.tgz#c9e69f9389893392aed36824677c2594ae2445e2" + integrity sha512-bKDkGXGZnj0T70cRpgmv549x38Vr2O3UWLbjT2qmIkdIWcmlg8yebcFWoT9Dku7b5OV3UqPEuNKRzlNhjwUJ9A== + +"@esbuild/darwin-arm64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz#f1513eaf9ec8fa15dcaf4c341b0f005d3e8b47ae" + integrity sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg== + +"@esbuild/darwin-arm64@0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.26.0.tgz#62e27842256044d4a0d6ba810f407890c746ce6e" + integrity sha512-6Z3naJgOuAIB0RLlJkYc81An3rTlQ/IeRdrU3dOea8h/PvZSgitZV+thNuIccw0MuK1GmIAnAmd5TrMZad8FTQ== + +"@esbuild/darwin-x64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz#e27dbc3b507b3a1cea3b9280a04b8b6b725f82be" + integrity sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ== + +"@esbuild/darwin-x64@0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.26.0.tgz#ea6d99e8c706318ce0171e85eb61ebb6e1a3e8f3" + integrity sha512-OPnYj0zpYW0tHusMefyaMvNYQX5pNQuSsHFTHUBNp3vVXupwqpxofcjVsUx11CQhGVkGeXjC3WLjh91hgBG2xw== + +"@esbuild/freebsd-arm64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz#364e3e5b7a1fd45d92be08c6cc5d890ca75908ca" + integrity sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q== + +"@esbuild/freebsd-arm64@0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.26.0.tgz#9acd33e588d2e1edddf6ee0e5a5272336b6ffcc1" + integrity sha512-jix2fa6GQeZhO1sCKNaNMjfj5hbOvoL2F5t+w6gEPxALumkpOV/wq7oUBMHBn2hY2dOm+mEV/K+xfZy3mrsxNQ== + +"@esbuild/freebsd-x64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz#7c869b45faeb3df668e19ace07335a0711ec56ab" + integrity sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg== + +"@esbuild/freebsd-x64@0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.26.0.tgz#c187f1f56731ab17861b9d3b00a9ddd7fbf6e46d" + integrity sha512-tccJaH5xHJD/239LjbVvJwf6T4kSzbk6wPFerF0uwWlkw/u7HL+wnAzAH5GB2irGhYemDgiNTp8wJzhAHQ64oA== + +"@esbuild/linux-arm64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz#48d42861758c940b61abea43ba9a29b186d6cb8b" + integrity sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw== + +"@esbuild/linux-arm64@0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.26.0.tgz#e516c7062d0b7f19cd139a5b597cd827d1e843ee" + integrity sha512-IMJYN7FSkLttYyTbsbme0Ra14cBO5z47kpamo16IwggzzATFY2lcZAwkbcNkWiAduKrTgFJP7fW5cBI7FzcuNQ== + +"@esbuild/linux-arm@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz#6ce4b9cabf148274101701d112b89dc67cc52f37" + integrity sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw== + +"@esbuild/linux-arm@0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.26.0.tgz#f26b22a0c80ac1ea73afd33c4e5034c69ae9ab14" + integrity sha512-JY8NyU31SyRmRpuc5W8PQarAx4TvuYbyxbPIpHAZdr/0g4iBr8KwQBS4kiiamGl2f42BBecHusYCsyxi7Kn8UQ== + +"@esbuild/linux-ia32@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz#207e54899b79cac9c26c323fc1caa32e3143f1c4" + integrity sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A== + +"@esbuild/linux-ia32@0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.26.0.tgz#22b310b307f68b57a28d25c662758a865555b6dc" + integrity sha512-XITaGqGVLgk8WOHw8We9Z1L0lbLFip8LyQzKYFKO4zFo1PFaaSKsbNjvkb7O8kEXytmSGRkYpE8LLVpPJpsSlw== + +"@esbuild/linux-loong64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz#0ba48a127159a8f6abb5827f21198b999ffd1fc0" + integrity sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ== + +"@esbuild/linux-loong64@0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.26.0.tgz#39027e0050ec9b275432814f47d3325562c62565" + integrity sha512-MkggfbDIczStUJwq9wU7gQ7kO33d8j9lWuOCDifN9t47+PeI+9m2QVh51EI/zZQ1spZtFMC1nzBJ+qNGCjJnsg== + +"@esbuild/linux-mips64el@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz#a4d4cc693d185f66a6afde94f772b38ce5d64eb5" + integrity sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA== + +"@esbuild/linux-mips64el@0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.26.0.tgz#d30185dc4298bd2470b21e6358f4c0e42cd8ecfc" + integrity sha512-fUYup12HZWAeccNLhQ5HwNBPr4zXCPgUWzEq2Rfw7UwqwfQrFZ0SR/JljaURR8xIh9t+o1lNUFTECUTmaP7yKA== + +"@esbuild/linux-ppc64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz#0f5805c1c6d6435a1dafdc043cb07a19050357db" + integrity sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w== + +"@esbuild/linux-ppc64@0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.26.0.tgz#8df55e65fd98a4244aaea649ba9745998f82a2e8" + integrity sha512-MzRKhM0Ip+//VYwC8tialCiwUQ4G65WfALtJEFyU0GKJzfTYoPBw5XNWf0SLbCUYQbxTKamlVwPmcw4DgZzFxg== + +"@esbuild/linux-riscv64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz#6776edece0f8fca79f3386398b5183ff2a827547" + integrity sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg== + +"@esbuild/linux-riscv64@0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.26.0.tgz#406e26b21646d19bf2e58a187a53fec719465512" + integrity sha512-QhCc32CwI1I4Jrg1enCv292sm3YJprW8WHHlyxJhae/dVs+KRWkbvz2Nynl5HmZDW/m9ZxrXayHzjzVNvQMGQA== + +"@esbuild/linux-s390x@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz#3f6f29ef036938447c2218d309dc875225861830" + integrity sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA== + +"@esbuild/linux-s390x@0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.26.0.tgz#a3c55edb6f19b2ff737f3d5d238bbcaf58815652" + integrity sha512-1D6vi6lfI18aNT1aTf2HV+RIlm6fxtlAp8eOJ4mmnbYmZ4boz8zYDar86sIYNh0wmiLJEbW/EocaKAX6Yso2fw== + "@esbuild/linux-x64@0.25.9": version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz#831fe0b0e1a80a8b8391224ea2377d5520e1527f" integrity sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg== "@esbuild/linux-x64@0.26.0": version "0.26.0" - resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.26.0.tgz" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.26.0.tgz#d60f139897b12e5af37113d6a433a7ef27c6d87f" integrity sha512-rnDcepj7LjrKFvZkx+WrBv6wECeYACcFjdNPvVPojCPJD8nHpb3pv3AuR9CXgdnjH1O23btICj0rsp0L9wAnHA== +"@esbuild/netbsd-arm64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz#06f99d7eebe035fbbe43de01c9d7e98d2a0aa548" + integrity sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q== + +"@esbuild/netbsd-arm64@0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.26.0.tgz#a89594f82f8172b127d7a59988dbde1a56a4d03e" + integrity sha512-FSWmgGp0mDNjEXXFcsf12BmVrb+sZBBBlyh3LwB/B9ac3Kkc8x5D2WimYW9N7SUkolui8JzVnVlWh7ZmjCpnxw== + +"@esbuild/netbsd-x64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz#db99858e6bed6e73911f92a88e4edd3a8c429a52" + integrity sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g== + +"@esbuild/netbsd-x64@0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.26.0.tgz#22c396c61067d4057d3c8b1e0b7481422bcf70f5" + integrity sha512-0QfciUDFryD39QoSPUDshj4uNEjQhp73+3pbSAaxjV2qGOEDsM67P7KbJq7LzHoVl46oqhIhJ1S+skKGR7lMXA== + +"@esbuild/openbsd-arm64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz#afb886c867e36f9d86bb21e878e1185f5d5a0935" + integrity sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ== + +"@esbuild/openbsd-arm64@0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.26.0.tgz#302f9602161cf1556dfc3574f6ff895f92566221" + integrity sha512-vmAK+nHhIZWImwJ3RNw9hX3fU4UGN/OqbSE0imqljNbUQC3GvVJ1jpwYoTfD6mmXmQaxdJY6Hn4jQbLGJKg5Yw== + +"@esbuild/openbsd-x64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz#30855c9f8381fac6a0ef5b5f31ac6e7108a66ecf" + integrity sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA== + +"@esbuild/openbsd-x64@0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.26.0.tgz#2d702092fe56dcc9f77932733898900b077e195a" + integrity sha512-GPXF7RMkJ7o9bTyUsnyNtrFMqgM3X+uM/LWw4CeHIjqc32fm0Ir6jKDnWHpj8xHFstgWDUYseSABK9KCkHGnpg== + +"@esbuild/openharmony-arm64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz#2f2144af31e67adc2a8e3705c20c2bd97bd88314" + integrity sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg== + +"@esbuild/openharmony-arm64@0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.26.0.tgz#b23c269bfe5583f2ffecf2778200194756652262" + integrity sha512-nUHZ5jEYqbBthbiBksbmHTlbb5eElyVfs/s1iHQ8rLBq1eWsd5maOnDpCocw1OM8kFK747d1Xms8dXJHtduxSw== + +"@esbuild/sunos-x64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz#69b99a9b5bd226c9eb9c6a73f990fddd497d732e" + integrity sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw== + +"@esbuild/sunos-x64@0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.26.0.tgz#8579737e0e147af566070fdcf691b79cf508666c" + integrity sha512-TMg3KCTCYYaVO+R6P5mSORhcNDDlemUVnUbb8QkboUtOhb5JWKAzd5uMIMECJQOxHZ/R+N8HHtDF5ylzLfMiLw== + +"@esbuild/win32-arm64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz#d789330a712af916c88325f4ffe465f885719c6b" + integrity sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ== + +"@esbuild/win32-arm64@0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.26.0.tgz#6761aab78c8b7d397a82d73c545de0410e61a5f7" + integrity sha512-apqYgoAUd6ZCb9Phcs8zN32q6l0ZQzQBdVXOofa6WvHDlSOhwCWgSfVQabGViThS40Y1NA4SCvQickgZMFZRlA== + +"@esbuild/win32-ia32@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz#52fc735406bd49688253e74e4e837ac2ba0789e3" + integrity sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww== + +"@esbuild/win32-ia32@0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.26.0.tgz#22bef8d60489e4edd3646154ef23d0bdab54b12a" + integrity sha512-FGJAcImbJNZzLWu7U6WB0iKHl4RuY4TsXEwxJPl9UZLS47agIZuILZEX3Pagfw7I4J3ddflomt9f0apfaJSbaw== + +"@esbuild/win32-x64@0.25.9": + version "0.25.9" + resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz" + integrity sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ== + +"@esbuild/win32-x64@0.26.0": + version "0.26.0" + resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.26.0.tgz" + integrity sha512-WAckBKaVnmFqbEhbymrPK7M086DQMpL1XoRbpmN0iW8k5JSXjDRQBhcZNa0VweItknLq9eAeCL34jK7/CDcw7A== + "@eslint-community/eslint-utils@^4.2.0": version "4.7.0" resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz" @@ -342,11 +592,16 @@ "@inquirer/type" "^3.0.10" yoctocolors-cjs "^2.1.3" -"@inquirer/type@^3.0.10", "@inquirer/type@^3.0.8": +"@inquirer/type@^3.0.10": version "3.0.10" resolved "https://registry.npmjs.org/@inquirer/type/-/type-3.0.10.tgz" integrity sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA== +"@inquirer/type@^3.0.8": + version "3.0.8" + resolved "https://registry.npmjs.org/@inquirer/type/-/type-3.0.8.tgz" + integrity sha512-lg9Whz8onIHRthWaN1Q9EGLa/0LFJjyM8mEUbL1eTi6yMGvBf8gvyDLtxSXztQsxMvhxxNpJYrwa1YHdq+w4Jw== + "@isaacs/fs-minipass@^4.0.0": version "4.0.1" resolved "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz" @@ -359,7 +614,7 @@ resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz" integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== -"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.5.5": +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.5.0", "@jridgewell/sourcemap-codec@^1.5.5": version "1.5.5" resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz" integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== @@ -399,7 +654,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -424,7 +679,7 @@ resolved "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz" integrity sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w== -"@octokit/core@^7.0.2", "@octokit/core@>=6": +"@octokit/core@^7.0.2": version "7.0.6" resolved "https://registry.npmjs.org/@octokit/core/-/core-7.0.6.tgz" integrity sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q== @@ -527,7 +782,7 @@ "@opentelemetry/api@1.9.0": version "1.9.0" - resolved "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.9.0.tgz#d03eba68273dc0f7509e2a3d5cba21eae10379fe" integrity sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg== "@phun-ky/typeof@2.0.3": @@ -596,7 +851,16 @@ is-module "^1.0.0" resolve "^1.22.1" -"@rollup/pluginutils@^5.0.1", "@rollup/pluginutils@^5.1.0", "@rollup/pluginutils@^5.3.0": +"@rollup/pluginutils@^5.0.1", "@rollup/pluginutils@^5.1.0": + version "5.2.0" + resolved "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.2.0.tgz" + integrity sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw== + dependencies: + "@types/estree" "^1.0.0" + estree-walker "^2.0.2" + picomatch "^4.0.2" + +"@rollup/pluginutils@^5.3.0": version "5.3.0" resolved "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz" integrity sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q== @@ -605,11 +869,216 @@ estree-walker "^2.0.2" picomatch "^4.0.2" +"@rollup/rollup-android-arm-eabi@4.46.3": + version "4.46.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.46.3.tgz#8d8afcc5a79a3f190c5f855facde6e0da6a5b7ea" + integrity sha512-UmTdvXnLlqQNOCJnyksjPs1G4GqXNGW1LrzCe8+8QoaLhhDeTXYBgJ3k6x61WIhlHX2U+VzEJ55TtIjR/HTySA== + +"@rollup/rollup-android-arm-eabi@4.53.3": + version "4.53.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz#7e478b66180c5330429dd161bf84dad66b59c8eb" + integrity sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w== + +"@rollup/rollup-android-arm64@4.46.3": + version "4.46.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.46.3.tgz#bed8ee4c2b31fd255fb91c2f52949dffef16ecf1" + integrity sha512-8NoxqLpXm7VyeI0ocidh335D6OKT0UJ6fHdnIxf3+6oOerZZc+O7r+UhvROji6OspyPm+rrIdb1gTXtVIqn+Sg== + +"@rollup/rollup-android-arm64@4.53.3": + version "4.53.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.3.tgz#2b025510c53a5e3962d3edade91fba9368c9d71c" + integrity sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w== + +"@rollup/rollup-darwin-arm64@4.46.3": + version "4.46.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.46.3.tgz#ee2a75deb8786b394c7f1777cc0c2ae2c3680469" + integrity sha512-csnNavqZVs1+7/hUKtgjMECsNG2cdB8F7XBHP6FfQjqhjF8rzMzb3SLyy/1BG7YSfQ+bG75Ph7DyedbUqwq1rA== + +"@rollup/rollup-darwin-arm64@4.53.3": + version "4.53.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz#3577c38af68ccf34c03e84f476bfd526abca10a0" + integrity sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA== + +"@rollup/rollup-darwin-x64@4.46.3": + version "4.46.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.46.3.tgz#f5a01577c40830c423855492ecd8d3a7ae1b4836" + integrity sha512-r2MXNjbuYabSIX5yQqnT8SGSQ26XQc8fmp6UhlYJd95PZJkQD1u82fWP7HqvGUf33IsOC6qsiV+vcuD4SDP6iw== + +"@rollup/rollup-darwin-x64@4.53.3": + version "4.53.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.3.tgz#2bf5f2520a1f3b551723d274b9669ba5b75ed69c" + integrity sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ== + +"@rollup/rollup-freebsd-arm64@4.46.3": + version "4.46.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.46.3.tgz#d272eed9c14efc149bab316de364c04f236c544f" + integrity sha512-uluObTmgPJDuJh9xqxyr7MV61Imq+0IvVsAlWyvxAaBSNzCcmZlhfYcRhCdMaCsy46ccZa7vtDDripgs9Jkqsw== + +"@rollup/rollup-freebsd-arm64@4.53.3": + version "4.53.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.3.tgz#4bb9cc80252564c158efc0710153c71633f1927c" + integrity sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w== + +"@rollup/rollup-freebsd-x64@4.46.3": + version "4.46.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.46.3.tgz#4c793f86e2dc64e725370daa2bec103f5869b5a6" + integrity sha512-AVJXEq9RVHQnejdbFvh1eWEoobohUYN3nqJIPI4mNTMpsyYN01VvcAClxflyk2HIxvLpRcRggpX1m9hkXkpC/A== + +"@rollup/rollup-freebsd-x64@4.53.3": + version "4.53.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.3.tgz#2301289094d49415a380cf942219ae9d8b127440" + integrity sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q== + +"@rollup/rollup-linux-arm-gnueabihf@4.46.3": + version "4.46.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.46.3.tgz#28da78d3709262f0b7ef0ba7e8e6f77c1b2f30a6" + integrity sha512-byyflM+huiwHlKi7VHLAYTKr67X199+V+mt1iRgJenAI594vcmGGddWlu6eHujmcdl6TqSNnvqaXJqZdnEWRGA== + +"@rollup/rollup-linux-arm-gnueabihf@4.53.3": + version "4.53.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.3.tgz#1d03d776f2065e09fc141df7d143476e94acca88" + integrity sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw== + +"@rollup/rollup-linux-arm-musleabihf@4.46.3": + version "4.46.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.46.3.tgz#7e3309e6519eca1459038761aad44863e86fc497" + integrity sha512-aLm3NMIjr4Y9LklrH5cu7yybBqoVCdr4Nvnm8WB7PKCn34fMCGypVNpGK0JQWdPAzR/FnoEoFtlRqZbBBLhVoQ== + +"@rollup/rollup-linux-arm-musleabihf@4.53.3": + version "4.53.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.3.tgz#8623de0e040b2fd52a541c602688228f51f96701" + integrity sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg== + +"@rollup/rollup-linux-arm64-gnu@4.46.3": + version "4.46.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.46.3.tgz#bc18efe81022baac97566cc0ace04b359eb7cd16" + integrity sha512-VtilE6eznJRDIoFOzaagQodUksTEfLIsvXymS+UdJiSXrPW7Ai+WG4uapAc3F7Hgs791TwdGh4xyOzbuzIZrnw== + +"@rollup/rollup-linux-arm64-gnu@4.53.3": + version "4.53.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.3.tgz#ce2d1999bc166277935dde0301cde3dd0417fb6e" + integrity sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w== + +"@rollup/rollup-linux-arm64-musl@4.46.3": + version "4.46.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.46.3.tgz#3ac849b6c42591014b0cb8e25c9ba1ace8fe19ec" + integrity sha512-dG3JuS6+cRAL0GQ925Vppafi0qwZnkHdPeuZIxIPXqkCLP02l7ka+OCyBoDEv8S+nKHxfjvjW4OZ7hTdHkx8/w== + +"@rollup/rollup-linux-arm64-musl@4.53.3": + version "4.53.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.3.tgz#88c2523778444da952651a2219026416564a4899" + integrity sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A== + +"@rollup/rollup-linux-loong64-gnu@4.53.3": + version "4.53.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.3.tgz#578ca2220a200ac4226c536c10c8cc6e4f276714" + integrity sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g== + +"@rollup/rollup-linux-loongarch64-gnu@4.46.3": + version "4.46.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.46.3.tgz#10260ca0c3682c2904b04bb907163aca8bc5adef" + integrity sha512-iU8DxnxEKJptf8Vcx4XvAUdpkZfaz0KWfRrnIRrOndL0SvzEte+MTM7nDH4A2Now4FvTZ01yFAgj6TX/mZl8hQ== + +"@rollup/rollup-linux-ppc64-gnu@4.46.3": + version "4.46.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.46.3.tgz#36b002a84c04f2e18093f563896c95a6e687f28f" + integrity sha512-VrQZp9tkk0yozJoQvQcqlWiqaPnLM6uY1qPYXvukKePb0fqaiQtOdMJSxNFUZFsGw5oA5vvVokjHrx8a9Qsz2A== + +"@rollup/rollup-linux-ppc64-gnu@4.53.3": + version "4.53.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.3.tgz#aa338d3effd4168a20a5023834a74ba2c3081293" + integrity sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw== + +"@rollup/rollup-linux-riscv64-gnu@4.46.3": + version "4.46.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.46.3.tgz#ff1b3708624fc8b912e5341431751977b78be273" + integrity sha512-uf2eucWSUb+M7b0poZ/08LsbcRgaDYL8NCGjUeFMwCWFwOuFcZ8D9ayPl25P3pl+D2FH45EbHdfyUesQ2Lt9wA== + +"@rollup/rollup-linux-riscv64-gnu@4.53.3": + version "4.53.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.3.tgz#16ba582f9f6cff58119aa242782209b1557a1508" + integrity sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g== + +"@rollup/rollup-linux-riscv64-musl@4.46.3": + version "4.46.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.46.3.tgz#ab6f7ef69cdf812eccb318021a8f5c221bd0c048" + integrity sha512-7tnUcDvN8DHm/9ra+/nF7lLzYHDeODKKKrh6JmZejbh1FnCNZS8zMkZY5J4sEipy2OW1d1Ncc4gNHUd0DLqkSg== + +"@rollup/rollup-linux-riscv64-musl@4.53.3": + version "4.53.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.3.tgz#e404a77ebd6378483888b8064c703adb011340ab" + integrity sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A== + +"@rollup/rollup-linux-s390x-gnu@4.46.3": + version "4.46.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.46.3.tgz#60527b48dd84814fa5092a2eef1ac90e2b4bf825" + integrity sha512-MUpAOallJim8CsJK+4Lc9tQzlfPbHxWDrGXZm2z6biaadNpvh3a5ewcdat478W+tXDoUiHwErX/dOql7ETcLqg== + +"@rollup/rollup-linux-s390x-gnu@4.53.3": + version "4.53.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.3.tgz#92ad52d306227c56bec43d96ad2164495437ffe6" + integrity sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg== + +"@rollup/rollup-linux-x64-gnu@4.46.3": + version "4.46.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.46.3.tgz#c95698199820782b7420f5472e5d36b681728274" + integrity sha512-F42IgZI4JicE2vM2PWCe0N5mR5vR0gIdORPqhGQ32/u1S1v3kLtbZ0C/mi9FFk7C5T0PgdeyWEPajPjaUpyoKg== + "@rollup/rollup-linux-x64-gnu@4.53.3": version "4.53.3" - resolved "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz#fd0dea3bb9aa07e7083579f25e1c2285a46cb9fa" integrity sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w== +"@rollup/rollup-linux-x64-musl@4.46.3": + version "4.46.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.46.3.tgz#226eb081be8d6698a580022448197b01cb4193a2" + integrity sha512-oLc+JrwwvbimJUInzx56Q3ujL3Kkhxehg7O1gWAYzm8hImCd5ld1F2Gry5YDjR21MNb5WCKhC9hXgU7rRlyegQ== + +"@rollup/rollup-linux-x64-musl@4.53.3": + version "4.53.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz#37a3efb09f18d555f8afc490e1f0444885de8951" + integrity sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q== + +"@rollup/rollup-openharmony-arm64@4.53.3": + version "4.53.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.3.tgz#c489bec9f4f8320d42c9b324cca220c90091c1f7" + integrity sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw== + +"@rollup/rollup-win32-arm64-msvc@4.46.3": + version "4.46.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.46.3.tgz#e900bd51cfc20af2a1c828d999bb49da1bd497eb" + integrity sha512-lOrQ+BVRstruD1fkWg9yjmumhowR0oLAAzavB7yFSaGltY8klttmZtCLvOXCmGE9mLIn8IBV/IFrQOWz5xbFPg== + +"@rollup/rollup-win32-arm64-msvc@4.53.3": + version "4.53.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.3.tgz#152832b5f79dc22d1606fac3db946283601b7080" + integrity sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw== + +"@rollup/rollup-win32-ia32-msvc@4.46.3": + version "4.46.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.46.3.tgz#94652ba771a90bf2558c0a6c553857148d7ff8f4" + integrity sha512-vvrVKPRS4GduGR7VMH8EylCBqsDcw6U+/0nPDuIjXQRbHJc6xOBj+frx8ksfZAh6+Fptw5wHrN7etlMmQnPQVg== + +"@rollup/rollup-win32-ia32-msvc@4.53.3": + version "4.53.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.3.tgz#54d91b2bb3bf3e9f30d32b72065a4e52b3a172a5" + integrity sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA== + +"@rollup/rollup-win32-x64-gnu@4.53.3": + version "4.53.3" + resolved "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz" + integrity sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg== + +"@rollup/rollup-win32-x64-msvc@4.46.3": + version "4.46.3" + resolved "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.46.3.tgz" + integrity sha512-fi3cPxCnu3ZeM3EwKZPgXbWoGzm2XHgB/WShKI81uj8wG0+laobmqy5wbgEwzstlbLu4MyO8C19FyhhWseYKNQ== + +"@rollup/rollup-win32-x64-msvc@4.53.3": + version "4.53.3" + resolved "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz" + integrity sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ== + "@socket.io/component-emitter@~3.1.0": version "3.1.2" resolved "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz" @@ -627,7 +1096,7 @@ "@standard-schema/spec@^1.0.0": version "1.0.0" - resolved "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/@standard-schema/spec/-/spec-1.0.0.tgz#f193b73dc316c4170f2e82a881da0f550d551b9c" integrity sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA== "@tootallnate/quickjs-emscripten@^0.23.0": @@ -674,12 +1143,19 @@ resolved "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz" integrity sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw== -"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.6", "@types/estree@1.0.8": +"@types/estree@*", "@types/estree@1.0.8", "@types/estree@^1.0.0", "@types/estree@^1.0.6": version "1.0.8" resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz" integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== -"@types/http-proxy@^1.17.15", "@types/http-proxy@^1.17.17": +"@types/http-proxy@^1.17.15": + version "1.17.16" + resolved "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.16.tgz" + integrity sha512-sdWoUajOB1cd0A8cRRQ1cfyWNbmFKLAqBB89Y8x5iYyG/mkJHc0YUH8pdWBy2omi9qtCpiIgGjuwO0dQST2l5w== + dependencies: + "@types/node" "*" + +"@types/http-proxy@^1.17.17": version "1.17.17" resolved "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.17.tgz" integrity sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw== @@ -691,16 +1167,16 @@ resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== -"@types/node@*", "@types/node@^18.0.0 || ^20.0.0 || >=22.0.0", "@types/node@^20.19.0 || >=22.12.0", "@types/node@>=18", "@types/node@>=20": +"@types/node@*", "@types/node@>=20": version "24.3.0" resolved "https://registry.npmjs.org/@types/node/-/node-24.3.0.tgz" integrity sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow== dependencies: undici-types "~7.10.0" -"@types/parse-path@^7.0.0": +"@types/parse-path@7.0.3", "@types/parse-path@^7.0.0": version "7.0.3" - resolved "https://registry.npmjs.org/@types/parse-path/-/parse-path-7.0.3.tgz" + resolved "https://registry.yarnpkg.com/@types/parse-path/-/parse-path-7.0.3.tgz#cec2da2834ab58eb2eb579122d9a1fc13bd7ef36" integrity sha512-LriObC2+KYZD3FzCrgWGv/qufdUy4eXrxcLgQMfYXgPbLIecKIsVBaQgUPmxSSLcjmYbDTQbMgr6qr6l/eb7Bg== "@types/ps-list@^6.2.1": @@ -715,7 +1191,7 @@ resolved "https://registry.npmjs.org/@types/qrcode-terminal/-/qrcode-terminal-0.12.2.tgz" integrity sha512-v+RcIEJ+Uhd6ygSQ0u5YYY7ZM+la7GgPbs0V/7l/kFs2uO4S8BcIUEMoP7za4DNIqNnUD5npf0A/7kBhrCKG5Q== -"@types/react@^19.2.7", "@types/react@>=19.0.0": +"@types/react@^19.2.7": version "19.2.7" resolved "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz" integrity sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg== @@ -734,7 +1210,7 @@ "@vercel/oidc@3.0.5": version "3.0.5" - resolved "https://registry.npmjs.org/@vercel/oidc/-/oidc-3.0.5.tgz" + resolved "https://registry.yarnpkg.com/@vercel/oidc/-/oidc-3.0.5.tgz#bd8db7ee777255c686443413492db4d98ef49657" integrity sha512-fnYhv671l+eTTp48gB4zEsTW/YtRgRPnkI2nT7x6qw5rkI1Lq2hTmQIpHPgyThI0znLK+vX2n9XxKdXZ7BUbbw== "@vitest/expect@3.2.4": @@ -757,7 +1233,7 @@ estree-walker "^3.0.3" magic-string "^0.30.17" -"@vitest/pretty-format@^3.2.4", "@vitest/pretty-format@3.2.4": +"@vitest/pretty-format@3.2.4", "@vitest/pretty-format@^3.2.4": version "3.2.4" resolved "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz" integrity sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA== @@ -823,7 +1299,7 @@ acorn-walk@^8.1.1: dependencies: acorn "^8.11.0" -"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.11.0, acorn@^8.15.0, acorn@^8.4.1: +acorn@^8.11.0, acorn@^8.15.0, acorn@^8.4.1: version "8.15.0" resolved "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz" integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== @@ -835,7 +1311,7 @@ agent-base@^7.1.0, agent-base@^7.1.2: ai@^5.0.107: version "5.0.107" - resolved "https://registry.npmjs.org/ai/-/ai-5.0.107.tgz" + resolved "https://registry.yarnpkg.com/ai/-/ai-5.0.107.tgz#8475fb5aee87c40586b3b8d0b1998116a8452108" integrity sha512-laZlS9ZC/DZfSaxPgrBqI4mM+kxRvTPBBQfa74ceBFskkunZKEsaGVFNEs4cfyGa3nCCCl1WO/fjxixp4V8Zag== dependencies: "@ai-sdk/gateway" "2.0.18" @@ -887,14 +1363,7 @@ ansi-regex@^6.0.1: resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.0.tgz" integrity sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg== -ansi-styles@^4.0.0: - version "4.3.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansi-styles@^4.1.0: +ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== @@ -1024,7 +1493,7 @@ bundle-name@^4.1.0: dependencies: run-applescript "^7.0.0" -bytes@^3.1.2, bytes@3.1.2: +bytes@3.1.2, bytes@^3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== @@ -1092,7 +1561,12 @@ chalk@^4.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^5.6.0, chalk@^5.6.2: +chalk@^5.6.0: + version "5.6.0" + resolved "https://registry.npmjs.org/chalk/-/chalk-5.6.0.tgz" + integrity sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ== + +chalk@^5.6.2: version "5.6.2" resolved "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz" integrity sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA== @@ -1291,21 +1765,14 @@ data-uri-to-buffer@^6.0.2: resolved "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz" integrity sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw== -debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.5, debug@^4.3.6, debug@^4.4.0, debug@^4.4.1, debug@4: +debug@4, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.5, debug@^4.3.6, debug@^4.4.0, debug@^4.4.1: version "4.4.1" resolved "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz" integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ== dependencies: ms "^2.1.3" -debug@~4.3.1: - version "4.3.7" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz" - integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== - dependencies: - ms "^2.1.3" - -debug@~4.3.2: +debug@~4.3.1, debug@~4.3.2: version "4.3.7" resolved "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz" integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== @@ -1364,7 +1831,7 @@ delayed-stream@~1.0.0: resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -depd@^2.0.0, depd@2.0.0: +depd@2.0.0, depd@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== @@ -1486,7 +1953,7 @@ es-toolkit@^1.39.10: resolved "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.39.10.tgz" integrity sha512-E0iGnTtbDhkeczB0T+mxmoVlT4YNweEKBLq7oaU4p11mecdsZpNWOglI4895Vh4usbQ+LsJiuLuI2L0Vdmfm2w== -esbuild@^0.25.0: +esbuild@^0.25.0, esbuild@~0.25.0: version "0.25.9" resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz" integrity sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g== @@ -1550,38 +2017,6 @@ esbuild@^0.26.0: "@esbuild/win32-ia32" "0.26.0" "@esbuild/win32-x64" "0.26.0" -esbuild@~0.25.0: - version "0.25.9" - resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz" - integrity sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g== - optionalDependencies: - "@esbuild/aix-ppc64" "0.25.9" - "@esbuild/android-arm" "0.25.9" - "@esbuild/android-arm64" "0.25.9" - "@esbuild/android-x64" "0.25.9" - "@esbuild/darwin-arm64" "0.25.9" - "@esbuild/darwin-x64" "0.25.9" - "@esbuild/freebsd-arm64" "0.25.9" - "@esbuild/freebsd-x64" "0.25.9" - "@esbuild/linux-arm" "0.25.9" - "@esbuild/linux-arm64" "0.25.9" - "@esbuild/linux-ia32" "0.25.9" - "@esbuild/linux-loong64" "0.25.9" - "@esbuild/linux-mips64el" "0.25.9" - "@esbuild/linux-ppc64" "0.25.9" - "@esbuild/linux-riscv64" "0.25.9" - "@esbuild/linux-s390x" "0.25.9" - "@esbuild/linux-x64" "0.25.9" - "@esbuild/netbsd-arm64" "0.25.9" - "@esbuild/netbsd-x64" "0.25.9" - "@esbuild/openbsd-arm64" "0.25.9" - "@esbuild/openbsd-x64" "0.25.9" - "@esbuild/openharmony-arm64" "0.25.9" - "@esbuild/sunos-x64" "0.25.9" - "@esbuild/win32-arm64" "0.25.9" - "@esbuild/win32-ia32" "0.25.9" - "@esbuild/win32-x64" "0.25.9" - escape-html@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" @@ -1631,7 +2066,7 @@ eslint-visitor-keys@^4.2.1: resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz" integrity sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ== -"eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^8.40 || 9", eslint@^9, eslint@>=7.0.0: +eslint@^9: version "9.33.0" resolved "https://registry.npmjs.org/eslint/-/eslint-9.33.0.tgz" integrity sha512-TS9bTNIryDzStCpJN93aC5VRSW3uTx9sClUn4B87pwiCaJh220otoI0X8mJKr+VcPtniMdN8GKjlwgWGUv5ZKA== @@ -1742,9 +2177,14 @@ eventemitter3@^4.0.0: resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== -eventsource-parser@^3.0.0, eventsource-parser@^3.0.1, eventsource-parser@^3.0.6: +eventsource-parser@^3.0.0, eventsource-parser@^3.0.1: + version "3.0.5" + resolved "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.5.tgz" + integrity sha512-bSRG85ZrMdmWtm7qkF9He9TNRzc/Bm99gEJMaQoHJ9E6Kv9QBbsldh2oMj7iXmYNEAVvNgvv5vPorG6W+XtBhQ== + +eventsource-parser@^3.0.6: version "3.0.6" - resolved "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz" + resolved "https://registry.yarnpkg.com/eventsource-parser/-/eventsource-parser-3.0.6.tgz#292e165e34cacbc936c3c92719ef326d4aeb4e90" integrity sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg== eventsource@^3.0.2: @@ -1788,7 +2228,7 @@ express-rate-limit@^7.5.0: resolved "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.1.tgz" integrity sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw== -express@^5.0.1, "express@>= 4.11": +express@^5.0.1: version "5.1.0" resolved "https://registry.npmjs.org/express/-/express-5.1.0.tgz" integrity sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA== @@ -1894,7 +2334,7 @@ fastify-type-provider-zod@4.0.2: "@fastify/error" "^4.0.0" zod-to-json-schema "^3.23.3" -fastify@^5.0.0, fastify@^5.6.2: +fastify@^5.6.2: version "5.6.2" resolved "https://registry.npmjs.org/fastify/-/fastify-5.6.2.tgz" integrity sha512-dPugdGnsvYkBlENLhCgX8yhyGCsCPrpA8lFWbTNU428l+YOnLgYHR69hzV8HWPC79n536EqzqQtvhtdaCE0dKg== @@ -1922,12 +2362,7 @@ fastq@^1.17.1, fastq@^1.6.0: dependencies: reusify "^1.0.4" -fdir@^6.2.0: - version "6.5.0" - resolved "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz" - integrity sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg== - -fdir@^6.5.0: +fdir@^6.2.0, fdir@^6.4.4, fdir@^6.5.0: version "6.5.0" resolved "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz" integrity sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg== @@ -2019,16 +2454,26 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== +fsevents@~2.3.2, fsevents@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + function-bind@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== -get-east-asian-width@^1.0.0, get-east-asian-width@^1.3.0: +get-east-asian-width@^1.0.0: version "1.3.0" resolved "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz" integrity sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ== +get-east-asian-width@^1.3.0: + version "1.4.0" + resolved "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz" + integrity sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q== + get-intrinsic@^1.2.5, get-intrinsic@^1.2.6, get-intrinsic@^1.3.0: version "1.3.0" resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz" @@ -2161,7 +2606,7 @@ hasown@^2.0.2: dependencies: function-bind "^1.1.2" -http-errors@^2.0.0, http-errors@2.0.0: +http-errors@2.0.0, http-errors@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== @@ -2214,7 +2659,7 @@ human-signals@^5.0.0: resolved "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz" integrity sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ== -iconv-lite@^0.6.3, iconv-lite@0.6.3: +iconv-lite@0.6.3, iconv-lite@^0.6.3: version "0.6.3" resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== @@ -2316,16 +2761,16 @@ ip-address@^10.0.1: resolved "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz" integrity sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA== -ipaddr.js@^2.1.0: - version "2.2.0" - resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz" - integrity sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA== - ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== +ipaddr.js@^2.1.0: + version "2.2.0" + resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz" + integrity sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA== + is-core-module@^2.16.0: version "2.16.1" resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz" @@ -2446,7 +2891,7 @@ issue-parser@7.0.1: lodash.isstring "^4.0.1" lodash.uniqby "^4.7.0" -jiti@*, jiti@^2.6.1, jiti@>=1.21.0: +jiti@^2.6.1: version "2.6.1" resolved "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz" integrity sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ== @@ -2487,7 +2932,7 @@ json-schema-traverse@^1.0.0: json-schema@^0.4.0: version "0.4.0" - resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== json-stable-stringify-without-jsonify@^1.0.1: @@ -2546,7 +2991,7 @@ lodash.isstring@^4.0.1: resolved "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz" integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== -lodash.merge@^4.6.2, lodash.merge@4.6.2: +lodash.merge@4.6.2, lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== @@ -2584,7 +3029,14 @@ macos-release@^3.3.0: resolved "https://registry.npmjs.org/macos-release/-/macos-release-3.4.0.tgz" integrity sha512-wpGPwyg/xrSp4H4Db4xYSeAr6+cFQGHfspHzDUdYxswDnUW0L5Ov63UuJiSr8NMSpyaChO4u1n0MXUvVPtrN6A== -magic-string@^0.30.17, magic-string@^0.30.21, magic-string@^0.30.3: +magic-string@^0.30.17, magic-string@^0.30.3: + version "0.30.17" + resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz" + integrity sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + +magic-string@^0.30.21: version "0.30.21" resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz" integrity sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ== @@ -2629,15 +3081,22 @@ micromatch@^4.0.8: braces "^3.0.3" picomatch "^2.3.1" +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + mime-db@^1.54.0: version "1.54.0" resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz" integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== +mime-types@3.0.1, mime-types@^3.0.0, mime-types@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz" + integrity sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA== + dependencies: + mime-db "^1.54.0" mime-types@^2.1.12: version "2.1.35" @@ -2646,13 +3105,6 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" -mime-types@^3.0.0, mime-types@^3.0.1, mime-types@3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz" - integrity sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA== - dependencies: - mime-db "^1.54.0" - mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" @@ -2814,7 +3266,7 @@ onetime@^7.0.0: dependencies: mimic-function "^5.0.0" -open@^10.2.0, open@10.2.0: +open@10.2.0, open@^10.2.0: version "10.2.0" resolved "https://registry.npmjs.org/open/-/open-10.2.0.tgz" integrity sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA== @@ -2902,9 +3354,9 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parse-path@^7.0.0: +parse-path@7.0.3, parse-path@^7.0.0: version "7.0.3" - resolved "https://registry.npmjs.org/parse-path/-/parse-path-7.0.3.tgz" + resolved "https://registry.yarnpkg.com/parse-path/-/parse-path-7.0.3.tgz#f29d8942a3562aac561a1b77de6a56cc93dca489" integrity sha512-0R71msgRgmkcZ5CWnzS+GPXJ1Fc+lbKyPDuA83Ej0QKCpf/Feieh813bF38My3CTNBzcQhtRRqvXNpCFF6FRMQ== dependencies: protocols "^2.0.0" @@ -2982,7 +3434,7 @@ picomatch@^2.3.1: resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -"picomatch@^3 || ^4", picomatch@^4.0.2, picomatch@^4.0.3: +picomatch@^4.0.2, picomatch@^4.0.3: version "4.0.3" resolved "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz" integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q== @@ -3032,7 +3484,7 @@ pkg-types@^2.2.0, pkg-types@^2.3.0: pkgroll@^2.14.2: version "2.21.4" - resolved "https://registry.npmjs.org/pkgroll/-/pkgroll-2.21.4.tgz" + resolved "https://registry.yarnpkg.com/pkgroll/-/pkgroll-2.21.4.tgz#a1144b1c881481387decf31bec5151729b602114" integrity sha512-A86a27/WRXDSJlsIwGbR3zOQsf4TP6+CGRVdBgCUSQ6BGzrmXrH0IIJ/TEOLT4z8FNbR+ALjwNqPgSHBMK1llA== dependencies: "@rollup/plugin-alias" "^6.0.0" @@ -3125,7 +3577,7 @@ ps-list@*, ps-list@^8.1.1: punycode@^2.1.0, punycode@^2.3.1: version "2.3.1" - resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== qrcode-terminal@^0.12.0: @@ -3180,7 +3632,7 @@ react-reconciler@^0.33.0: dependencies: scheduler "^0.27.0" -react@^19.2.0, react@>=19.0.0: +react@^19.2.0: version "19.2.0" resolved "https://registry.npmjs.org/react/-/react-19.2.0.tgz" integrity sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ== @@ -3281,16 +3733,16 @@ ret@~0.5.0: resolved "https://registry.npmjs.org/ret/-/ret-0.5.0.tgz" integrity sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw== -retry@^0.12.0: - version "0.12.0" - resolved "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz" - integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== - retry@0.13.1: version "0.13.1" resolved "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz" integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz" + integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== + reusify@^1.0.4: version "1.1.0" resolved "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz" @@ -3308,7 +3760,36 @@ rollup-pluginutils@^2.8.2: dependencies: estree-walker "^0.6.1" -rollup@^1.20.0||^2.0.0||^3.0.0||^4.0.0, rollup@^2.68.0||^3.0.0||^4.0.0, rollup@^2.78.0||^3.0.0||^4.0.0, rollup@^4.43.0, rollup@^4.53.1, rollup@>=4.0.0: +rollup@^4.43.0: + version "4.46.3" + resolved "https://registry.npmjs.org/rollup/-/rollup-4.46.3.tgz" + integrity sha512-RZn2XTjXb8t5g13f5YclGoilU/kwT696DIkY3sywjdZidNSi3+vseaQov7D7BZXVJCPv3pDWUN69C78GGbXsKw== + dependencies: + "@types/estree" "1.0.8" + optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.46.3" + "@rollup/rollup-android-arm64" "4.46.3" + "@rollup/rollup-darwin-arm64" "4.46.3" + "@rollup/rollup-darwin-x64" "4.46.3" + "@rollup/rollup-freebsd-arm64" "4.46.3" + "@rollup/rollup-freebsd-x64" "4.46.3" + "@rollup/rollup-linux-arm-gnueabihf" "4.46.3" + "@rollup/rollup-linux-arm-musleabihf" "4.46.3" + "@rollup/rollup-linux-arm64-gnu" "4.46.3" + "@rollup/rollup-linux-arm64-musl" "4.46.3" + "@rollup/rollup-linux-loongarch64-gnu" "4.46.3" + "@rollup/rollup-linux-ppc64-gnu" "4.46.3" + "@rollup/rollup-linux-riscv64-gnu" "4.46.3" + "@rollup/rollup-linux-riscv64-musl" "4.46.3" + "@rollup/rollup-linux-s390x-gnu" "4.46.3" + "@rollup/rollup-linux-x64-gnu" "4.46.3" + "@rollup/rollup-linux-x64-musl" "4.46.3" + "@rollup/rollup-win32-arm64-msvc" "4.46.3" + "@rollup/rollup-win32-ia32-msvc" "4.46.3" + "@rollup/rollup-win32-x64-msvc" "4.46.3" + fsevents "~2.3.2" + +rollup@^4.53.1: version "4.53.3" resolved "https://registry.npmjs.org/rollup/-/rollup-4.53.3.tgz" integrity sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA== @@ -3406,7 +3887,7 @@ secure-json-parse@^4.0.0: resolved "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-4.0.0.tgz" integrity sha512-dxtLJO6sc35jWidmLxo7ij+Eg48PM/kleBsxpC8QJE0qJICe+KawkDQmvCMZUr9u7WKVHgMW6vy3fQ7zMiFZMA== -semver@^7.6.0, semver@7.7.2: +semver@7.7.2, semver@^7.6.0: version "7.7.2" resolved "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz" integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== @@ -3614,16 +4095,16 @@ stackback@0.0.2: resolved "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz" integrity sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw== -statuses@^2.0.1: - version "2.0.2" - resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz" - integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw== - statuses@2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== +statuses@^2.0.1: + version "2.0.2" + resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz" + integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw== + std-env@^3.9.0: version "3.9.0" resolved "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz" @@ -3667,7 +4148,14 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-ansi@^7.1.0, strip-ansi@^7.1.2: +strip-ansi@^7.1.0: + version "7.1.0" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + +strip-ansi@^7.1.2: version "7.1.2" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz" integrity sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA== @@ -3736,7 +4224,7 @@ tinyexec@^1.0.1: resolved "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.1.tgz" integrity sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw== -tinyglobby@^0.2.14, tinyglobby@0.2.15: +tinyglobby@0.2.15: version "0.2.15" resolved "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz" integrity sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ== @@ -3744,6 +4232,14 @@ tinyglobby@^0.2.14, tinyglobby@0.2.15: fdir "^6.5.0" picomatch "^4.0.3" +tinyglobby@^0.2.14: + version "0.2.14" + resolved "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz" + integrity sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ== + dependencies: + fdir "^6.4.4" + picomatch "^4.0.2" + tinypool@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz" @@ -3783,7 +4279,7 @@ toidentifier@1.0.1: tr46@^5.1.0: version "5.1.1" - resolved "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-5.1.1.tgz#96ae867cddb8fdb64a49cc3059a8d428bcf238ca" integrity sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw== dependencies: punycode "^2.3.1" @@ -3812,7 +4308,7 @@ tslib@^2.0.1, tslib@^2.1.0: resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== -tsx@^4.20.6, tsx@^4.8.1: +tsx@^4.20.6: version "4.20.6" resolved "https://registry.npmjs.org/tsx/-/tsx-4.20.6.tgz" integrity sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg== @@ -3853,7 +4349,7 @@ type-is@^2.0.0, type-is@^2.0.1: media-typer "^1.1.0" mime-types "^3.0.0" -"typescript@^4.1 || ^5.0", typescript@^5, typescript@>=2.7: +typescript@^5: version "5.9.2" resolved "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz" integrity sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A== @@ -3956,12 +4452,12 @@ vitest@^3.2.4: webidl-conversions@^7.0.0: version "7.0.0" - resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== -whatwg-url@^5.0.0: +whatwg-url@14.2.0, whatwg-url@^5.0.0: version "14.2.0" - resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-14.2.0.tgz#4ee02d5d725155dae004f6ae95c73e7ef5d95663" integrity sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw== dependencies: tr46 "^5.1.0" @@ -4056,7 +4552,7 @@ yallist@^5.0.0: resolved "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz" integrity sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw== -yaml@^2.4.2, yaml@^2.8.1: +yaml@^2.8.1: version "2.8.1" resolved "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz" integrity sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw== @@ -4096,7 +4592,7 @@ zod-to-json-schema@^3.23.3, zod-to-json-schema@^3.24.1: resolved "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.6.tgz" integrity sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg== -zod@^3.14.2, zod@^3.23.8, zod@^3.24.1, "zod@^3.25.0 || ^4.0.0", "zod@^3.25.76 || ^4.1.8": +zod@^3.23.8: version "3.25.76" resolved "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz" integrity sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==