From fd422b5d0de0ef56a812a6c9b47c94477b5a0990 Mon Sep 17 00:00:00 2001 From: Waleed Date: Tue, 16 Sep 2025 17:47:15 -0700 Subject: [PATCH] feat(sms): add generic sms sending block/tool (#1349) * update infra and remove railway * feat(sms): add generic sms sending block/tool * added docs * Revert "update infra and remove railway" This reverts commit abfa2f8d51901247acc6397960210569e84d72b1. * updated colors * remove fallbacks, stronger typing --- apps/docs/content/docs/en/tools/mail.mdx | 8 +- apps/docs/content/docs/en/tools/meta.json | 1 + apps/docs/content/docs/en/tools/sms.mdx | 53 +++++++ apps/sim/app/api/tools/mail/send/route.ts | 13 +- apps/sim/app/api/tools/sms/send/route.ts | 99 ++++++++++++ apps/sim/blocks/blocks/mail.ts | 2 +- apps/sim/blocks/blocks/sms.ts | 55 +++++++ apps/sim/blocks/registry.ts | 1 + apps/sim/components/icons.tsx | 13 ++ apps/sim/lib/env.ts | 5 + apps/sim/lib/sms/service.ts | 183 ++++++++++++++++++++++ apps/sim/tools/registry.ts | 2 + apps/sim/tools/sms/index.ts | 3 + apps/sim/tools/sms/send.ts | 55 +++++++ apps/sim/tools/sms/types.ts | 14 ++ bun.lock | 69 ++++++-- package.json | 3 +- 17 files changed, 566 insertions(+), 13 deletions(-) create mode 100644 apps/docs/content/docs/en/tools/sms.mdx create mode 100644 apps/sim/app/api/tools/sms/send/route.ts create mode 100644 apps/sim/blocks/blocks/sms.ts create mode 100644 apps/sim/lib/sms/service.ts create mode 100644 apps/sim/tools/sms/index.ts create mode 100644 apps/sim/tools/sms/send.ts create mode 100644 apps/sim/tools/sms/types.ts diff --git a/apps/docs/content/docs/en/tools/mail.mdx b/apps/docs/content/docs/en/tools/mail.mdx index 71b2822ec3..c1e9f1e1a8 100644 --- a/apps/docs/content/docs/en/tools/mail.mdx +++ b/apps/docs/content/docs/en/tools/mail.mdx @@ -7,7 +7,7 @@ import { BlockInfoCard } from "@/components/ui/block-info-card" `} /> +{/* MANUAL-CONTENT-START:intro */} +The Mail block allows you to send emails directly from your workflows using Sim's own mail sending infrastructure powered by [Resend](https://resend.com/). This integration enables you to programmatically deliver notifications, alerts, and other important information to users' email addresses without requiring any external configuration or OAuth. + +Our internal mail service is designed for reliability and ease of use, making it ideal for automating communications and ensuring your messages reach recipients efficiently. +{/* MANUAL-CONTENT-END */} + ## Usage Instructions Send emails directly using the internal mail service. Uses MAIL_BLOCK_FROM_ADDRESS if configured, otherwise falls back to FROM_EMAIL_ADDRESS. No external configuration or OAuth required. Perfect for sending notifications, alerts, or general purpose emails from your workflows. Supports HTML formatting. diff --git a/apps/docs/content/docs/en/tools/meta.json b/apps/docs/content/docs/en/tools/meta.json index 0f06f00475..d87043ba6a 100644 --- a/apps/docs/content/docs/en/tools/meta.json +++ b/apps/docs/content/docs/en/tools/meta.json @@ -52,6 +52,7 @@ "serper", "sharepoint", "slack", + "sms", "stagehand", "stagehand_agent", "supabase", diff --git a/apps/docs/content/docs/en/tools/sms.mdx b/apps/docs/content/docs/en/tools/sms.mdx new file mode 100644 index 0000000000..f63f10f607 --- /dev/null +++ b/apps/docs/content/docs/en/tools/sms.mdx @@ -0,0 +1,53 @@ +--- +title: SMS +description: Send SMS messages using the internal SMS service +--- + +import { BlockInfoCard } from "@/components/ui/block-info-card" + +`} +/> + +{/* MANUAL-CONTENT-START:intro */} +The SMS block allows you to send text messages directly from your workflows using Sim's own SMS sending infrastructure powered by Twilio. This integration enables you to programmatically deliver notifications, alerts, and other important information to users' mobile devices without requiring any external configuration or OAuth. + +Our internal SMS service is designed for reliability and ease of use, making it ideal for automating communications and ensuring your messages reach recipients efficiently. +{/* MANUAL-CONTENT-END */} + +## Usage Instructions + +Send SMS messages directly using the internal SMS service powered by Twilio. No external configuration or OAuth required. Perfect for sending notifications, alerts, or general purpose text messages from your workflows. Requires valid phone numbers with country codes. + + + +## Tools + +### `sms_send` + +Send an SMS message using the internal SMS service powered by Twilio + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `to` | string | Yes | Recipient phone number \(include country code, e.g., +1234567890\) | +| `body` | string | Yes | SMS message content | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `success` | boolean | Whether the SMS was sent successfully | +| `to` | string | Recipient phone number | +| `body` | string | SMS message content | + + + +## Notes + +- Category: `tools` +- Type: `sms` diff --git a/apps/sim/app/api/tools/mail/send/route.ts b/apps/sim/app/api/tools/mail/send/route.ts index 2d7e502243..f346d31407 100644 --- a/apps/sim/app/api/tools/mail/send/route.ts +++ b/apps/sim/app/api/tools/mail/send/route.ts @@ -40,7 +40,18 @@ export async function POST(request: NextRequest) { const body = await request.json() const validatedData = MailSendSchema.parse(body) - const fromAddress = env.MAIL_BLOCK_FROM_ADDRESS || env.FROM_EMAIL_ADDRESS || 'system default' + const fromAddress = env.MAIL_BLOCK_FROM_ADDRESS || env.FROM_EMAIL_ADDRESS + + if (!fromAddress) { + logger.error(`[${requestId}] Email sending failed: No from address configured`) + return NextResponse.json( + { + success: false, + message: 'Email sending failed: No from address configured.', + }, + { status: 500 } + ) + } logger.info(`[${requestId}] Sending email via internal mail API`, { to: validatedData.to, diff --git a/apps/sim/app/api/tools/sms/send/route.ts b/apps/sim/app/api/tools/sms/send/route.ts new file mode 100644 index 0000000000..e7fc14d7d5 --- /dev/null +++ b/apps/sim/app/api/tools/sms/send/route.ts @@ -0,0 +1,99 @@ +import { type NextRequest, NextResponse } from 'next/server' +import { z } from 'zod' +import { checkHybridAuth } from '@/lib/auth/hybrid' +import { env } from '@/lib/env' +import { createLogger } from '@/lib/logs/console/logger' +import { type SMSOptions, sendSMS } from '@/lib/sms/service' +import { generateRequestId } from '@/lib/utils' + +export const dynamic = 'force-dynamic' + +const logger = createLogger('SMSSendAPI') + +const SMSSendSchema = z.object({ + to: z.string().min(1, 'To phone number is required'), + body: z.string().min(1, 'SMS body is required'), +}) + +export async function POST(request: NextRequest) { + const requestId = generateRequestId() + + try { + const authResult = await checkHybridAuth(request, { requireWorkflowId: false }) + + if (!authResult.success) { + logger.warn(`[${requestId}] Unauthorized SMS send attempt: ${authResult.error}`) + return NextResponse.json( + { + success: false, + message: authResult.error || 'Authentication required', + }, + { status: 401 } + ) + } + + logger.info(`[${requestId}] Authenticated SMS request via ${authResult.authType}`, { + userId: authResult.userId, + }) + + const body = await request.json() + const validatedData = SMSSendSchema.parse(body) + + const fromNumber = env.TWILIO_PHONE_NUMBER + + if (!fromNumber) { + logger.error(`[${requestId}] SMS sending failed: No phone number configured`) + return NextResponse.json( + { + success: false, + message: 'SMS sending failed: No phone number configured.', + }, + { status: 500 } + ) + } + + logger.info(`[${requestId}] Sending SMS via internal SMS API`, { + to: validatedData.to, + bodyLength: validatedData.body.length, + from: fromNumber, + }) + + const smsOptions: SMSOptions = { + to: validatedData.to, + body: validatedData.body, + from: fromNumber, + } + + const result = await sendSMS(smsOptions) + + logger.info(`[${requestId}] SMS send result`, { + success: result.success, + message: result.message, + }) + + return NextResponse.json(result) + } catch (error) { + if (error instanceof z.ZodError) { + logger.warn(`[${requestId}] Invalid request data`, { errors: error.errors }) + return NextResponse.json( + { + success: false, + message: 'Invalid request data', + errors: error.errors, + }, + { status: 400 } + ) + } + + logger.error(`[${requestId}] Error sending SMS via API:`, error) + + return NextResponse.json( + { + success: false, + message: 'Internal server error while sending SMS', + data: {}, + }, + { status: 500 } + ) + } +} diff --git a/apps/sim/blocks/blocks/mail.ts b/apps/sim/blocks/blocks/mail.ts index 3e84549bd8..59683e3f57 100644 --- a/apps/sim/blocks/blocks/mail.ts +++ b/apps/sim/blocks/blocks/mail.ts @@ -9,7 +9,7 @@ export const MailBlock: BlockConfig = { longDescription: 'Send emails directly using the internal mail service. Uses MAIL_BLOCK_FROM_ADDRESS if configured, otherwise falls back to FROM_EMAIL_ADDRESS. No external configuration or OAuth required. Perfect for sending notifications, alerts, or general purpose emails from your workflows. Supports HTML formatting.', category: 'tools', - bgColor: '#FF6B35', + bgColor: '#E0E0E0', icon: MailIcon, subBlocks: [ diff --git a/apps/sim/blocks/blocks/sms.ts b/apps/sim/blocks/blocks/sms.ts new file mode 100644 index 0000000000..8652a0b442 --- /dev/null +++ b/apps/sim/blocks/blocks/sms.ts @@ -0,0 +1,55 @@ +import { SMSIcon } from '@/components/icons' +import type { BlockConfig } from '@/blocks/types' +import type { SMSSendResult } from '@/tools/sms/types' + +export const SMSBlock: BlockConfig = { + type: 'sms', + name: 'SMS', + description: 'Send SMS messages using the internal SMS service', + longDescription: + 'Send SMS messages directly using the internal SMS service powered by Twilio. No external configuration or OAuth required. Perfect for sending notifications, alerts, or general purpose text messages from your workflows. Requires valid phone numbers with country codes.', + category: 'tools', + bgColor: '#E0E0E0', + icon: SMSIcon, + + subBlocks: [ + { + id: 'to', + title: 'To', + type: 'short-input', + layout: 'full', + placeholder: '+1234567890', + required: true, + }, + { + id: 'body', + title: 'Message', + type: 'long-input', + layout: 'full', + placeholder: 'Your SMS message content...', + required: true, + }, + ], + + tools: { + access: ['sms_send'], + config: { + tool: () => 'sms_send', + params: (params) => ({ + to: params.to, + body: params.body, + }), + }, + }, + + inputs: { + to: { type: 'string', description: 'Recipient phone number (include country code)' }, + body: { type: 'string', description: 'SMS message content' }, + }, + + outputs: { + success: { type: 'boolean', description: 'Whether the SMS was sent successfully' }, + to: { type: 'string', description: 'Recipient phone number' }, + body: { type: 'string', description: 'SMS message content' }, + }, +} diff --git a/apps/sim/blocks/registry.ts b/apps/sim/blocks/registry.ts index 04362bc28e..d201dd8675 100644 --- a/apps/sim/blocks/registry.ts +++ b/apps/sim/blocks/registry.ts @@ -140,6 +140,7 @@ export const registry: Record = { s3: S3Block, serper: SerperBlock, sharepoint: SharepointBlock, + // sms: SMSBlock, stagehand: StagehandBlock, stagehand_agent: StagehandAgentBlock, slack: SlackBlock, diff --git a/apps/sim/components/icons.tsx b/apps/sim/components/icons.tsx index 5596f57114..a0eea8349e 100644 --- a/apps/sim/components/icons.tsx +++ b/apps/sim/components/icons.tsx @@ -3650,3 +3650,16 @@ export const HIPAABadgeIcon = (props: SVGProps) => ( ) + +export const SMSIcon = (props: SVGProps) => ( + + + +) diff --git a/apps/sim/lib/env.ts b/apps/sim/lib/env.ts index 2625df0c15..74c919da6e 100644 --- a/apps/sim/lib/env.ts +++ b/apps/sim/lib/env.ts @@ -57,6 +57,11 @@ export const env = createEnv({ MAIL_BLOCK_FROM_ADDRESS: z.string().min(1).optional(), // Custom from address for mail block tool (e.g., "Bot ") AZURE_ACS_CONNECTION_STRING: z.string().optional(), // Azure Communication Services connection string + // SMS & Messaging + TWILIO_ACCOUNT_SID: z.string().min(1).optional(), // Twilio Account SID for SMS sending + TWILIO_AUTH_TOKEN: z.string().min(1).optional(), // Twilio Auth Token for API authentication + TWILIO_PHONE_NUMBER: z.string().min(1).optional(), // Twilio phone number for sending SMS + // AI/LLM Provider API Keys OPENAI_API_KEY: z.string().min(1).optional(), // Primary OpenAI API key OPENAI_API_KEY_1: z.string().min(1).optional(), // Additional OpenAI API key for load balancing diff --git a/apps/sim/lib/sms/service.ts b/apps/sim/lib/sms/service.ts new file mode 100644 index 0000000000..6e410cc55c --- /dev/null +++ b/apps/sim/lib/sms/service.ts @@ -0,0 +1,183 @@ +import { Twilio } from 'twilio' +import { env } from '@/lib/env' +import { createLogger } from '@/lib/logs/console/logger' + +const logger = createLogger('SMSService') + +export interface SMSOptions { + to: string | string[] + body: string + from?: string +} + +export interface BatchSMSOptions { + messages: SMSOptions[] +} + +export interface SMSResponseData { + sid?: string + status?: string + to?: string + from?: string + id?: string + results?: SendSMSResult[] + count?: number +} + +export interface SendSMSResult { + success: boolean + message: string + data?: SMSResponseData +} + +export interface BatchSendSMSResult { + success: boolean + message: string + results: SendSMSResult[] + data?: SMSResponseData +} + +const twilioAccountSid = env.TWILIO_ACCOUNT_SID +const twilioAuthToken = env.TWILIO_AUTH_TOKEN +const twilioPhoneNumber = env.TWILIO_PHONE_NUMBER + +const twilioClient = + twilioAccountSid && + twilioAuthToken && + twilioAccountSid.trim() !== '' && + twilioAuthToken.trim() !== '' + ? new Twilio(twilioAccountSid, twilioAuthToken) + : null + +export async function sendSMS(options: SMSOptions): Promise { + try { + const { to, body, from } = options + const fromNumber = from || twilioPhoneNumber + + if (!fromNumber || fromNumber.trim() === '') { + logger.error('No Twilio phone number configured') + return { + success: false, + message: 'SMS sending failed: No from phone number configured', + } + } + + if (!twilioClient) { + logger.error('SMS sending failed: Twilio not configured', { + to, + body: `${body.substring(0, 50)}...`, + from: fromNumber, + }) + return { + success: false, + message: + 'SMS sending failed: Twilio credentials not configured. Please set TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, and TWILIO_PHONE_NUMBER in your environment variables.', + } + } + + if (typeof to === 'string') { + return await sendSingleSMS(to, body, fromNumber) + } + + const results: SendSMSResult[] = [] + for (const phoneNumber of to) { + try { + const result = await sendSingleSMS(phoneNumber, body, fromNumber) + results.push(result) + } catch (error) { + results.push({ + success: false, + message: error instanceof Error ? error.message : 'Failed to send SMS', + }) + } + } + + const successCount = results.filter((r) => r.success).length + return { + success: successCount === results.length, + message: + successCount === results.length + ? 'All SMS messages sent successfully' + : `${successCount}/${results.length} SMS messages sent successfully`, + data: { results, count: successCount }, + } + } catch (error) { + logger.error('Error sending SMS:', error) + return { + success: false, + message: 'Failed to send SMS', + } + } +} + +async function sendSingleSMS(to: string, body: string, from: string): Promise { + if (!twilioClient) { + throw new Error('Twilio client not configured') + } + + try { + const message = await twilioClient.messages.create({ + body, + from, + to, + }) + + logger.info('SMS sent successfully:', { + to, + from, + messageSid: message.sid, + status: message.status, + }) + + return { + success: true, + message: 'SMS sent successfully via Twilio', + data: { + sid: message.sid, + status: message.status, + to: message.to, + from: message.from, + }, + } + } catch (error) { + logger.error('Failed to send SMS via Twilio:', error) + throw error + } +} + +export async function sendBatchSMS(options: BatchSMSOptions): Promise { + try { + const results: SendSMSResult[] = [] + + logger.info('Sending batch SMS messages') + for (const smsOptions of options.messages) { + try { + const result = await sendSMS(smsOptions) + results.push(result) + } catch (error) { + results.push({ + success: false, + message: error instanceof Error ? error.message : 'Failed to send SMS', + }) + } + } + + const successCount = results.filter((r) => r.success).length + return { + success: successCount === results.length, + message: + successCount === results.length + ? 'All batch SMS messages sent successfully' + : `${successCount}/${results.length} SMS messages sent successfully`, + results, + data: { count: successCount }, + } + } catch (error) { + logger.error('Error in batch SMS sending:', error) + return { + success: false, + message: 'Failed to send batch SMS messages', + results: [], + } + } +} diff --git a/apps/sim/tools/registry.ts b/apps/sim/tools/registry.ts index a4b01a733e..4da8b01218 100644 --- a/apps/sim/tools/registry.ts +++ b/apps/sim/tools/registry.ts @@ -149,6 +149,7 @@ import { sharepointReadPageTool, } from '@/tools/sharepoint' import { slackCanvasTool, slackMessageReaderTool, slackMessageTool } from '@/tools/slack' +import { smsSendTool } from '@/tools/sms' import { stagehandAgentTool, stagehandExtractTool } from '@/tools/stagehand' import { supabaseDeleteTool, @@ -203,6 +204,7 @@ export const tools: Record = { jina_read_url: readUrlTool, linkup_search: linkupSearchTool, mail_send: mailSendTool, + sms_send: smsSendTool, jira_retrieve: jiraRetrieveTool, jira_update: jiraUpdateTool, jira_write: jiraWriteTool, diff --git a/apps/sim/tools/sms/index.ts b/apps/sim/tools/sms/index.ts new file mode 100644 index 0000000000..60cc59e072 --- /dev/null +++ b/apps/sim/tools/sms/index.ts @@ -0,0 +1,3 @@ +import { smsSendTool } from '@/tools/sms/send' + +export { smsSendTool } diff --git a/apps/sim/tools/sms/send.ts b/apps/sim/tools/sms/send.ts new file mode 100644 index 0000000000..38d2c92e1f --- /dev/null +++ b/apps/sim/tools/sms/send.ts @@ -0,0 +1,55 @@ +import type { SMSSendParams, SMSSendResult } from '@/tools/sms/types' +import type { ToolConfig } from '@/tools/types' + +export const smsSendTool: ToolConfig = { + id: 'sms_send', + name: 'Send SMS', + description: 'Send an SMS message using the internal SMS service powered by Twilio', + version: '1.0.0', + + params: { + to: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Recipient phone number (include country code, e.g., +1234567890)', + }, + body: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'SMS message content', + }, + }, + + request: { + url: '/api/tools/sms/send', + method: 'POST', + headers: () => ({ + 'Content-Type': 'application/json', + }), + body: (params: SMSSendParams) => ({ + to: params.to, + body: params.body, + }), + }, + + transformResponse: async (response: Response, params): Promise => { + const result = await response.json() + + return { + success: true, + output: { + success: result.success, + to: params?.to || '', + body: params?.body || '', + }, + } + }, + + outputs: { + success: { type: 'boolean', description: 'Whether the SMS was sent successfully' }, + to: { type: 'string', description: 'Recipient phone number' }, + body: { type: 'string', description: 'SMS message content' }, + }, +} diff --git a/apps/sim/tools/sms/types.ts b/apps/sim/tools/sms/types.ts new file mode 100644 index 0000000000..58bc13a700 --- /dev/null +++ b/apps/sim/tools/sms/types.ts @@ -0,0 +1,14 @@ +import type { ToolResponse } from '@/tools/types' + +export interface SMSSendParams { + to: string + body: string +} + +export interface SMSSendResult extends ToolResponse { + output: { + success: boolean + to: string + body: string + } +} diff --git a/bun.lock b/bun.lock index 247c4fa11f..34fad3d007 100644 --- a/bun.lock +++ b/bun.lock @@ -13,6 +13,7 @@ "react-colorful": "5.6.1", "remark-gfm": "4.0.1", "socket.io-client": "4.8.1", + "twilio": "5.9.0", }, "devDependencies": { "@biomejs/biome": "2.0.0-beta.5", @@ -1573,7 +1574,7 @@ "adler-32": ["adler-32@1.3.1", "", {}, "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A=="], - "agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + "agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="], "agentkeepalive": ["agentkeepalive@4.6.0", "", { "dependencies": { "humanize-ms": "^1.2.1" } }, "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ=="], @@ -1623,6 +1624,8 @@ "aws-ssl-profiles": ["aws-ssl-profiles@1.1.2", "", {}, "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g=="], + "axios": ["axios@1.12.2", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw=="], + "bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="], "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], @@ -1863,6 +1866,8 @@ "dateformat": ["dateformat@4.6.3", "", {}, "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA=="], + "dayjs": ["dayjs@1.11.18", "", {}, "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA=="], + "debounce": ["debounce@2.2.0", "", {}, "sha512-Xks6RUDLZFdz8LIdR6q0MTH44k7FikOmnh5xkSjMig6ch45afc8sjTjRQf3P6ax8dMgcQrYO/AR2RGWURrruqw=="], "debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="], @@ -2059,6 +2064,8 @@ "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="], + "follow-redirects": ["follow-redirects@1.15.11", "", {}, "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ=="], + "foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="], "form-data": ["form-data@4.0.4", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow=="], @@ -2189,7 +2196,7 @@ "http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="], - "https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], + "https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="], "human-signals": ["human-signals@5.0.0", "", {}, "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ=="], @@ -2307,11 +2314,13 @@ "jsondiffpatch": ["jsondiffpatch@0.6.0", "", { "dependencies": { "@types/diff-match-patch": "^1.0.36", "chalk": "^5.3.0", "diff-match-patch": "^1.0.5" }, "bin": { "jsondiffpatch": "bin/jsondiffpatch.js" } }, "sha512-3QItJOXp2AP1uv7waBkao5nCvhEv+QmJAd38Ybq7wNI74Q+BBmnLn4EDKz6yI9xGAIQoUF87qHt+kc1IVxB4zQ=="], + "jsonwebtoken": ["jsonwebtoken@9.0.2", "", { "dependencies": { "jws": "^3.2.2", "lodash.includes": "^4.3.0", "lodash.isboolean": "^3.0.3", "lodash.isinteger": "^4.0.4", "lodash.isnumber": "^3.0.3", "lodash.isplainobject": "^4.0.6", "lodash.isstring": "^4.0.1", "lodash.once": "^4.0.0", "ms": "^2.1.1", "semver": "^7.5.4" } }, "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ=="], + "jszip": ["jszip@3.10.1", "", { "dependencies": { "lie": "~3.3.0", "pako": "~1.0.2", "readable-stream": "~2.3.6", "setimmediate": "^1.0.5" } }, "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g=="], - "jwa": ["jwa@2.0.1", "", { "dependencies": { "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg=="], + "jwa": ["jwa@1.4.2", "", { "dependencies": { "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw=="], - "jws": ["jws@4.0.0", "", { "dependencies": { "jwa": "^2.0.0", "safe-buffer": "^5.0.1" } }, "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg=="], + "jws": ["jws@3.2.2", "", { "dependencies": { "jwa": "^1.4.1", "safe-buffer": "^5.0.1" } }, "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA=="], "jwt-decode": ["jwt-decode@4.0.0", "", {}, "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA=="], @@ -2367,10 +2376,24 @@ "lodash.defaults": ["lodash.defaults@4.2.0", "", {}, "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ=="], + "lodash.includes": ["lodash.includes@4.3.0", "", {}, "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="], + "lodash.isarguments": ["lodash.isarguments@3.1.0", "", {}, "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg=="], + "lodash.isboolean": ["lodash.isboolean@3.0.3", "", {}, "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="], + + "lodash.isinteger": ["lodash.isinteger@4.0.4", "", {}, "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="], + + "lodash.isnumber": ["lodash.isnumber@3.0.3", "", {}, "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="], + + "lodash.isplainobject": ["lodash.isplainobject@4.0.6", "", {}, "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="], + + "lodash.isstring": ["lodash.isstring@4.0.1", "", {}, "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="], + "lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="], + "lodash.once": ["lodash.once@4.1.1", "", {}, "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="], + "log-symbols": ["log-symbols@4.1.0", "", { "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" } }, "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg=="], "log-update": ["log-update@5.0.1", "", { "dependencies": { "ansi-escapes": "^5.0.0", "cli-cursor": "^4.0.0", "slice-ansi": "^5.0.0", "strip-ansi": "^7.0.1", "wrap-ansi": "^8.0.1" } }, "sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw=="], @@ -2933,6 +2956,8 @@ "schema-utils": ["schema-utils@4.3.2", "", { "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", "ajv-formats": "^2.1.1", "ajv-keywords": "^5.1.0" } }, "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ=="], + "scmp": ["scmp@2.1.0", "", {}, "sha512-o/mRQGk9Rcer/jEEw/yw4mwo3EU/NvYvp577/Btqrym9Qy5/MdWGBqipbALgd2lrdWTJ5/gqDusxfnQBxOxT2Q=="], + "scroll-into-view-if-needed": ["scroll-into-view-if-needed@3.1.0", "", { "dependencies": { "compute-scroll-into-view": "^3.0.2" } }, "sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ=="], "secure-json-parse": ["secure-json-parse@4.0.0", "", {}, "sha512-dxtLJO6sc35jWidmLxo7ij+Eg48PM/kleBsxpC8QJE0qJICe+KawkDQmvCMZUr9u7WKVHgMW6vy3fQ7zMiFZMA=="], @@ -3171,6 +3196,8 @@ "turbo-windows-arm64": ["turbo-windows-arm64@2.5.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-j/tWu8cMeQ7HPpKri6jvKtyXg9K1gRyhdK4tKrrchH8GNHscPX/F71zax58yYtLRWTiK04zNzPcUJuoS0+v/+Q=="], + "twilio": ["twilio@5.9.0", "", { "dependencies": { "axios": "^1.11.0", "dayjs": "^1.11.9", "https-proxy-agent": "^5.0.0", "jsonwebtoken": "^9.0.2", "qs": "^6.9.4", "scmp": "^2.1.0", "xmlbuilder": "^13.0.2" } }, "sha512-Ij+xT9MZZSjP64lsy+x6vYsCCb5m2Db9KffkMXBrN3zWbG3rbkXxl+MZVVzrvpwEdSbQD0vMuin+TTlQ6kR6Xg=="], + "type-fest": ["type-fest@0.7.1", "", {}, "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg=="], "typedarray": ["typedarray@0.0.6", "", {}, "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA=="], @@ -3285,7 +3312,7 @@ "xml-name-validator": ["xml-name-validator@5.0.0", "", {}, "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg=="], - "xmlbuilder": ["xmlbuilder@10.1.1", "", {}, "sha512-OyzrcFLL/nb6fMGHbiRDuPup9ljBycsdCypwuyg5AAHvyWzGfChJpCXMG88AGTIMFhGZ9RccFN1e6lhg3hkwKg=="], + "xmlbuilder": ["xmlbuilder@13.0.2", "", {}, "sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ=="], "xmlchars": ["xmlchars@2.2.0", "", {}, "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="], @@ -3625,8 +3652,6 @@ "@sentry/bundler-plugin-core/magic-string": ["magic-string@0.30.8", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" } }, "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ=="], - "@sentry/cli/https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="], - "@sentry/cli/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], "@sentry/nextjs/chalk": ["chalk@3.0.0", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg=="], @@ -3735,6 +3760,8 @@ "@types/webpack/@types/node": ["@types/node@24.2.1", "", { "dependencies": { "undici-types": "~7.10.0" } }, "sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ=="], + "@typespec/ts-http-runtime/https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], + "@vitejs/plugin-react/@babel/core": ["@babel/core@7.28.3", "", { "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.28.3", "@babel/helpers": "^7.28.3", "@babel/parser": "^7.28.3", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.3", "@babel/types": "^7.28.2", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ=="], "accepts/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], @@ -3793,22 +3820,30 @@ "fumadocs-ui/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], + "gaxios/https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], + "gaxios/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], "gaxios/uuid": ["uuid@9.0.1", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="], "glob/minimatch": ["minimatch@10.0.3", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw=="], + "google-auth-library/jws": ["jws@4.0.0", "", { "dependencies": { "jwa": "^2.0.0", "safe-buffer": "^5.0.1" } }, "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg=="], + "groq-sdk/@types/node": ["@types/node@18.19.123", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-K7DIaHnh0mzVxreCR9qwgNxp3MH9dltPNIEddW9MYUlcKAzm+3grKNSTe2vCJHI1FaLpvpL5JGJrz1UZDKYvDg=="], "groq-sdk/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], + "gtoken/jws": ["jws@4.0.0", "", { "dependencies": { "jwa": "^2.0.0", "safe-buffer": "^5.0.1" } }, "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg=="], + "hexer/process": ["process@0.10.1", "", {}, "sha512-dyIett8dgGIZ/TXKUzeYExt7WA6ldDzys9vTDU/cCA9L17Ypme+KzS+NjQCjpn9xsvi/shbMC+yP/BcFMBz0NA=="], "hoist-non-react-statics/react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="], "htmlparser2/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + "http-proxy-agent/agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + "isomorphic-unfetch/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], "istanbul-lib-report/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], @@ -3817,8 +3852,14 @@ "jest-worker/@types/node": ["@types/node@24.2.1", "", { "dependencies": { "undici-types": "~7.10.0" } }, "sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ=="], + "jsdom/https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], + "jsondiffpatch/chalk": ["chalk@5.6.0", "", {}, "sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ=="], + "jwa/safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], + + "jws/safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], + "linebreak/base64-js": ["base64-js@0.0.8", "", {}, "sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw=="], "lint-staged/chalk": ["chalk@5.6.0", "", {}, "sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ=="], @@ -3843,6 +3884,8 @@ "mammoth/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], + "mammoth/xmlbuilder": ["xmlbuilder@10.1.1", "", {}, "sha512-OyzrcFLL/nb6fMGHbiRDuPup9ljBycsdCypwuyg5AAHvyWzGfChJpCXMG88AGTIMFhGZ9RccFN1e6lhg3hkwKg=="], + "mdast-util-find-and-replace/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], @@ -4259,8 +4302,6 @@ "@sentry/bundler-plugin-core/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], - "@sentry/cli/https-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="], - "@sentry/cli/node-fetch/whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="], "@sentry/nextjs/chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], @@ -4319,6 +4360,8 @@ "@types/webpack/@types/node/undici-types": ["undici-types@7.10.0", "", {}, "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag=="], + "@typespec/ts-http-runtime/https-proxy-agent/agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + "@vitejs/plugin-react/@babel/core/@babel/parser": ["@babel/parser@7.28.3", "", { "dependencies": { "@babel/types": "^7.28.2" }, "bin": "./bin/babel-parser.js" }, "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA=="], "@vitejs/plugin-react/@babel/core/@babel/traverse": ["@babel/traverse@7.28.3", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.3", "@babel/template": "^7.27.2", "@babel/types": "^7.28.2", "debug": "^4.3.1" } }, "sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ=="], @@ -4335,16 +4378,24 @@ "form-data/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], + "gaxios/https-proxy-agent/agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + "gaxios/node-fetch/whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="], + "google-auth-library/jws/jwa": ["jwa@2.0.1", "", { "dependencies": { "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg=="], + "groq-sdk/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], "groq-sdk/node-fetch/whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="], + "gtoken/jws/jwa": ["jwa@2.0.1", "", { "dependencies": { "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg=="], + "isomorphic-unfetch/node-fetch/whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="], "jest-worker/@types/node/undici-types": ["undici-types@7.10.0", "", {}, "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag=="], + "jsdom/https-proxy-agent/agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + "lint-staged/listr2/cli-truncate": ["cli-truncate@4.0.0", "", { "dependencies": { "slice-ansi": "^5.0.0", "string-width": "^7.0.0" } }, "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA=="], "lint-staged/listr2/eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="], diff --git a/package.json b/package.json index 7615b5cb6e..efaf6e62c8 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,8 @@ "mongodb": "6.19.0", "react-colorful": "5.6.1", "remark-gfm": "4.0.1", - "socket.io-client": "4.8.1" + "socket.io-client": "4.8.1", + "twilio": "5.9.0" }, "devDependencies": { "@biomejs/biome": "2.0.0-beta.5",